feat(delegation): add Claude Code CLI flag passthrough

Add explicit passthrough support for key Claude Code CLI flags:
- --max-turns: Limit agentic turns (prevents infinite loops)
- --fallback-model: Auto-fallback when model overloaded
- --agents: Dynamic subagent JSON injection
- --betas: Enable experimental features

Maintain extraArgs catch-all for future Claude Code flags.
Update help command with new "Delegation Flags" section.

Closes #89
This commit is contained in:
kaitranntt
2025-12-31 15:53:10 -05:00
parent a24ae6ab3b
commit 6b74243dc5
4 changed files with 78 additions and 4 deletions
+10
View File
@@ -214,6 +214,16 @@ Run ${color('ccs config', 'command')} for web dashboard`.trim();
['/ccs:continue "follow-up"', 'Continue last delegation session'],
]);
// Delegation CLI Flags (Claude Code passthrough)
printSubSection('Delegation Flags (Claude Code passthrough)', [
['--max-turns <n>', 'Limit agentic turns (prevents loops)'],
['--fallback-model <model>', 'Auto-fallback on overload (sonnet)'],
['--agents <json>', 'Inject dynamic subagents'],
['--betas <features>', 'Enable experimental features'],
['--allowedTools <list>', 'Restrict available tools'],
['--disallowedTools <list>', 'Block specific tools'],
]);
// Diagnostics
printSubSection('Diagnostics', [
['ccs setup', 'First-time setup wizard'],
+43 -2
View File
@@ -17,7 +17,12 @@ interface ParsedArgs {
timeout?: number;
resumeSession?: boolean;
sessionId?: string;
extraArgs?: string[]; // Passthrough args for Claude CLI
// Claude Code CLI passthrough flags (explicit)
maxTurns?: number;
fallbackModel?: string;
agents?: string;
betas?: string;
extraArgs?: string[]; // Catch-all for new/unknown flags
};
}
@@ -187,9 +192,45 @@ export class DelegationHandler {
options.timeout = parseInt(args[timeoutIndex + 1], 10);
}
// Parse --max-turns (limit agentic turns)
const maxTurnsIndex = args.indexOf('--max-turns');
if (maxTurnsIndex !== -1 && maxTurnsIndex < args.length - 1) {
const val = parseInt(args[maxTurnsIndex + 1], 10);
if (!isNaN(val) && val > 0) {
options.maxTurns = val;
}
}
// Parse --fallback-model (auto-fallback on overload)
const fallbackIndex = args.indexOf('--fallback-model');
if (fallbackIndex !== -1 && fallbackIndex < args.length - 1) {
options.fallbackModel = args[fallbackIndex + 1];
}
// Parse --agents (dynamic subagent JSON)
const agentsIndex = args.indexOf('--agents');
if (agentsIndex !== -1 && agentsIndex < args.length - 1) {
options.agents = args[agentsIndex + 1];
}
// Parse --betas (experimental features)
const betasIndex = args.indexOf('--betas');
if (betasIndex !== -1 && betasIndex < args.length - 1) {
options.betas = args[betasIndex + 1];
}
// Collect extra args to pass through to Claude CLI
// CCS-handled flags with values (skip these and their values):
const ccsFlagsWithValue = new Set(['-p', '--prompt', '--timeout', '--permission-mode']);
const ccsFlagsWithValue = new Set([
'-p',
'--prompt',
'--timeout',
'--permission-mode',
'--max-turns',
'--fallback-model',
'--agents',
'--betas',
]);
const extraArgs: string[] = [];
const profile = this._extractProfile(args);
+6 -1
View File
@@ -55,7 +55,12 @@ export interface ExecutionOptions {
resumeSession?: boolean;
sessionId?: string;
maxRetries?: number;
extraArgs?: string[]; // Passthrough args for Claude CLI
// Claude Code CLI passthrough flags (explicit)
maxTurns?: number; // --max-turns: Limit agentic turns (prevents infinite loops)
fallbackModel?: string; // --fallback-model: Auto-fallback when model overloaded
agents?: string; // --agents: Dynamic subagent JSON injection
betas?: string; // --betas: Enable experimental features
extraArgs?: string[]; // Catch-all for new/unknown flags (future-proof)
}
/**
+19 -1
View File
@@ -41,6 +41,10 @@ export class HeadlessExecutor {
permissionMode = 'acceptEdits',
resumeSession = false,
sessionId = null,
maxTurns,
fallbackModel,
agents,
betas,
extraArgs = [],
} = options;
@@ -116,7 +120,21 @@ export class HeadlessExecutor {
args.push('--disallowedTools', ...toolRestrictions.disallowedTools);
}
// Passthrough extra args
// Claude Code CLI passthrough flags (explicit, validated)
if (maxTurns !== undefined && maxTurns > 0) {
args.push('--max-turns', String(maxTurns));
}
if (fallbackModel) {
args.push('--fallback-model', fallbackModel);
}
if (agents) {
args.push('--agents', agents);
}
if (betas) {
args.push('--betas', betas);
}
// Passthrough extra args (catch-all for new/unknown flags)
if (extraArgs.length > 0) {
args.push(...extraArgs);
}