fix: app discovery uses the same criterion as the upward walk

cursor[bot]: discoverAppCandidates only matched dev-config markers while
the upward walk also honors an existing .impeccable/live/config.json,
so booting from a repo root without --target missed a nested
live-configured static site and fell through to the wrong root. Both
paths now share isAppRoot; regression test covers the static-site shape.

This work was produced with AI assistance (Claude Code).

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
Paul Bakaus
2026-07-27 19:38:56 -07:00
co-authored by Claude Code
parent 880199697e
commit da68678e7e
2 changed files with 21 additions and 1 deletions
+4 -1
View File
@@ -141,7 +141,10 @@ export function discoverAppCandidates(rootDir, depth = CANDIDATE_SCAN_DEPTH) {
if (!entry.isDirectory()) continue;
if (entry.name.startsWith('.') || CANDIDATE_SCAN_IGNORED.has(entry.name)) continue;
const abs = path.join(dir, entry.name);
if (hasDevConfig(abs)) {
// Same criterion as the upward walk (isAppRoot): a live-configured
// plain-static site with no bundler markers is still an app, and
// missing it here would silently fall back to the wrong root.
if (isAppRoot(abs)) {
found.push(abs);
continue; // nested apps below an app root are that app's business
}
+17
View File
@@ -341,3 +341,20 @@ describe('review regressions: pid reuse', () => {
}
});
});
describe('review regressions: discovery parity', () => {
it('discovers a live-configured static site with no bundler markers', () => {
const repo = realpathSync(mkdtempSync(join(tmpdir(), 'impeccable-roots-static-')));
try {
mkdirSync(join(repo, '.git'), { recursive: true });
write(repo, 'package.json', '{"name":"cli"}');
write(repo, 'docs-site/.impeccable/live/config.json', '{"files":["index.html"]}');
write(repo, 'docs-site/index.html', '<html></html>');
const { manifest, selection } = resolveRoots({ cwd: repo });
assert.equal(selection, undefined);
assert.equal(manifest.appRoot, join(repo, 'docs-site'));
} finally {
rmSync(repo, { recursive: true, force: true });
}
});
});