fix: helpers honor --target for multi-app disambiguation

greptile-apps[bot] repro: the multi-app warning recommended --target,
but the helper CLIs never parsed it, so live-poll --target appB still
re-anchored onto the pointer's first choice. enterLiveRoot now consumes
a --target argument (removing it from argv so downstream flag parsers
never see it) and resolves roots against it, making the documented
escape hatch real on every helper. Regression test drives a two-live-app
repo through a child process and asserts both the chdir target and the
argv scrubbing.

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 16:52:01 -07:00
co-authored by Claude Code
parent f1d450e6ab
commit baed04a52b
2 changed files with 65 additions and 3 deletions
+30 -3
View File
@@ -393,14 +393,41 @@ export function resolveLiveRoots(cwd = process.cwd(), { targetPath = null } = {}
return { manifest: fresh.manifest, source: 'fresh' };
}
/**
* Consume a `--target <path>` / `--target=<path>` pair from an argv array,
* returning the value and removing the tokens so downstream flag parsers
* (which do not know the option) never see them.
*/
export function consumeTargetArg(argv = process.argv) {
for (let i = 0; i < argv.length; i++) {
const arg = argv[i];
if (arg === '--target' && typeof argv[i + 1] === 'string') {
const value = argv[i + 1];
argv.splice(i, 2);
return value;
}
if (typeof arg === 'string' && arg.startsWith('--target=')) {
const value = arg.slice('--target='.length);
argv.splice(i, 1);
return value;
}
}
return null;
}
/**
* Entry-point guard for live CLI scripts: resolve the governing roots and
* make appRoot the process cwd so every downstream path derivation agrees
* with the boot. Returns the manifest. Never throws; on selection ambiguity
* it stays in the current directory (the boot flow handles prompting).
* with the boot. An explicit `--target <path>` on the helper's command line
* overrides pointer resolution, which is what disambiguates a repo with
* several live apps (the multi-app warning names this escape hatch, so it
* has to actually work on every helper). Returns the manifest. Never
* throws; on selection ambiguity it stays in the current directory (the
* boot flow handles prompting).
*/
export function enterLiveRoot(cwd = process.cwd()) {
const resolved = resolveLiveRoots(cwd);
const targetPath = consumeTargetArg(process.argv);
const resolved = resolveLiveRoots(cwd, targetPath ? { targetPath } : {});
if (!resolved.manifest) return null;
const appRoot = resolved.manifest.appRoot;
if (path.resolve(cwd) !== path.resolve(appRoot) && isDir(appRoot)) {