fix(dispatcher): treat --print as non-subcommand Claude session (#1341)

* fix(dispatcher): treat --print as non-subcommand Claude session

* style: apply prettier formatting

* fix(dispatcher): correct return type in subcommand detector

getClaudeSubcommandName returns string | null; return false (boolean)
was invalid after dev refactored isClaudeSubcommandInvocation to
delegate to it. Change to return null to preserve the --print safety
fix intent.
This commit is contained in:
Kai (Tam Nhu) Tran
2026-05-23 16:54:30 -04:00
committed by GitHub
parent f0ec820054
commit fd561b59bc
2 changed files with 20 additions and 3 deletions
+7 -3
View File
@@ -119,9 +119,11 @@ const SUBCOMMAND_ALLOWED_SESSION_FLAGS: Record<string, ReadonlySet<string>> = {
*
* Heuristic:
* 1. Walk args until the `--` terminator or end.
* 2. Skip known value-taking flags together with their next token.
* 3. Skip unknown `--flag=value` forms and bare `--flag` / `-x` tokens.
* 4. The first remaining positional token is the candidate.
* 2. If `--print` is present before the first positional token, treat as
* prompt/headless session mode (never a subcommand launch).
* 3. Skip known value-taking flags together with their next token.
* 4. Skip unknown `--flag=value` forms and bare `--flag` / `-x` tokens.
* 5. The first remaining positional token is the candidate.
* 5. Match against CLAUDE_SUBCOMMANDS.
*
* Anything after the candidate is irrelevant — once a subcommand is in play,
@@ -142,6 +144,8 @@ export function getClaudeSubcommandName(args: readonly string[]): string | null
const arg = args[i];
if (arg === '--') return null;
if (arg === '--print') return null;
if (arg.startsWith('-')) {
if (VALUE_TAKING_FLAGS.has(arg)) {
// Skip the next token as the flag's value (when present and not another flag).
@@ -56,6 +56,12 @@ describe('isClaudeSubcommandInvocation', () => {
expect(isClaudeSubcommandInvocation(['--name', 'auth'])).toBe(false);
});
it('treats --print prompt mode as non-subcommand even with subcommand-like prompt text', () => {
expect(isClaudeSubcommandInvocation(['--print', 'agents'])).toBe(false);
expect(isClaudeSubcommandInvocation(['--print', 'doctor'])).toBe(false);
});
it('handles --flag=value forms', () => {
expect(isClaudeSubcommandInvocation(['--model=sonnet', 'agents'])).toBe(true);
});
@@ -201,6 +207,13 @@ describe('subcommand passthrough — injectors short-circuit', () => {
expect(appendBrowserToolArgs(['remote-control'])).toEqual(['remote-control']);
});
it('injectors still inject in --print prompt mode with subcommand-like prompt text', () => {
const out = appendThirdPartyWebSearchToolArgs(['--print', 'agents']);
expect(out).toContain('--append-system-prompt');
expect(out).toContain('--disallowedTools');
});
it('injectors still inject for non-subcommand interactive launches', () => {
const out = appendThirdPartyWebSearchToolArgs(['fix the bug']);
expect(out).toContain('--append-system-prompt');