mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-05 01:50:27 +08:00
refactor: 移除 ccw cli 内部超时参数,改由外部 bash 控制
- 移除 --timeout 命令行选项和内部超时处理逻辑 - 进程生命周期跟随父进程(bash)状态 - 简化代码,超时控制交由外部调用者管理
This commit is contained in:
@@ -177,7 +177,7 @@ export function run(argv: string[]): void {
|
||||
.option('--model <model>', 'Model override')
|
||||
.option('--cd <path>', 'Working directory')
|
||||
.option('--includeDirs <dirs>', 'Additional directories (--include-directories for gemini/qwen, --add-dir for codex/claude)')
|
||||
.option('--timeout <ms>', 'Timeout in milliseconds (0=disabled, controlled by external caller)', '0')
|
||||
// --timeout removed - controlled by external caller (bash timeout)
|
||||
.option('--stream', 'Enable streaming output (default: non-streaming with caching)')
|
||||
.option('--limit <n>', 'History limit')
|
||||
.option('--status <status>', 'Filter by status')
|
||||
|
||||
@@ -116,7 +116,7 @@ interface CliExecOptions {
|
||||
model?: string;
|
||||
cd?: string;
|
||||
includeDirs?: string;
|
||||
timeout?: string;
|
||||
// timeout removed - controlled by external caller (bash timeout)
|
||||
stream?: boolean; // Enable streaming (default: false, caches output)
|
||||
resume?: string | boolean; // true = last, string = execution ID, comma-separated for merge
|
||||
id?: string; // Custom execution ID (e.g., IMPL-001-step1)
|
||||
@@ -535,7 +535,7 @@ async function statusAction(debug?: boolean): Promise<void> {
|
||||
* @param {Object} options - CLI options
|
||||
*/
|
||||
async function execAction(positionalPrompt: string | undefined, options: CliExecOptions): Promise<void> {
|
||||
const { prompt: optionPrompt, file, tool = 'gemini', mode = 'analysis', model, cd, includeDirs, timeout, stream, resume, id, noNative, cache, injectMode, debug } = options;
|
||||
const { prompt: optionPrompt, file, tool = 'gemini', mode = 'analysis', model, cd, includeDirs, stream, resume, id, noNative, cache, injectMode, debug } = options;
|
||||
|
||||
// Enable debug mode if --debug flag is set
|
||||
if (debug) {
|
||||
@@ -842,7 +842,7 @@ async function execAction(positionalPrompt: string | undefined, options: CliExec
|
||||
model,
|
||||
cd,
|
||||
includeDirs,
|
||||
timeout: timeout ? parseInt(timeout, 10) : 0, // 0 = no internal timeout, controlled by external caller
|
||||
// timeout removed - controlled by external caller (bash timeout)
|
||||
resume,
|
||||
id, // custom execution ID
|
||||
noNative,
|
||||
@@ -1221,7 +1221,7 @@ export async function cliCommand(
|
||||
console.log(chalk.gray(' --model <model> Model override'));
|
||||
console.log(chalk.gray(' --cd <path> Working directory'));
|
||||
console.log(chalk.gray(' --includeDirs <dirs> Additional directories'));
|
||||
console.log(chalk.gray(' --timeout <ms> Timeout (default: 0=disabled)'));
|
||||
// --timeout removed - controlled by external caller (bash timeout)
|
||||
console.log(chalk.gray(' --resume [id] Resume previous session'));
|
||||
console.log(chalk.gray(' --cache <items> Cache: comma-separated @patterns and text'));
|
||||
console.log(chalk.gray(' --inject-mode <m> Inject mode: none, full, progressive'));
|
||||
|
||||
@@ -356,7 +356,7 @@ const ParamsSchema = z.object({
|
||||
model: z.string().optional(),
|
||||
cd: z.string().optional(),
|
||||
includeDirs: z.string().optional(),
|
||||
timeout: z.number().default(0), // 0 = no internal timeout, controlled by external caller (e.g., bash timeout)
|
||||
// timeout removed - controlled by external caller (bash timeout)
|
||||
resume: z.union([z.boolean(), z.string()]).optional(), // true = last, string = single ID or comma-separated IDs
|
||||
id: z.string().optional(), // Custom execution ID (e.g., IMPL-001-step1)
|
||||
noNative: z.boolean().optional(), // Force prompt concatenation instead of native resume
|
||||
@@ -388,7 +388,7 @@ async function executeCliTool(
|
||||
throw new Error(`Invalid params: ${parsed.error.message}`);
|
||||
}
|
||||
|
||||
const { tool, prompt, mode, format, model, cd, includeDirs, timeout, resume, id: customId, noNative, category, parentExecutionId, outputFormat } = parsed.data;
|
||||
const { tool, prompt, mode, format, model, cd, includeDirs, resume, id: customId, noNative, category, parentExecutionId, outputFormat } = parsed.data;
|
||||
|
||||
// Validate and determine working directory early (needed for conversation lookup)
|
||||
let workingDir: string;
|
||||
@@ -862,7 +862,6 @@ async function executeCliTool(
|
||||
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
let timedOut = false;
|
||||
|
||||
// Handle stdout
|
||||
child.stdout!.on('data', (data: Buffer) => {
|
||||
@@ -924,18 +923,14 @@ async function executeCliTool(
|
||||
debugLog('CLOSE', `Process closed`, {
|
||||
exitCode: code,
|
||||
duration: `${duration}ms`,
|
||||
timedOut,
|
||||
stdoutLength: stdout.length,
|
||||
stderrLength: stderr.length,
|
||||
outputUnitsCount: allOutputUnits.length
|
||||
});
|
||||
|
||||
// Determine status - prioritize output content over exit code
|
||||
let status: 'success' | 'error' | 'timeout' = 'success';
|
||||
if (timedOut) {
|
||||
status = 'timeout';
|
||||
debugLog('STATUS', `Execution timed out after ${duration}ms`);
|
||||
} else if (code !== 0) {
|
||||
let status: 'success' | 'error' = 'success';
|
||||
if (code !== 0) {
|
||||
// Non-zero exit code doesn't always mean failure
|
||||
// Check if there's valid output (AI response) - treat as success
|
||||
const hasValidOutput = stdout.trim().length > 0;
|
||||
@@ -1169,25 +1164,8 @@ async function executeCliTool(
|
||||
reject(new Error(`Failed to spawn ${tool}: ${error.message}\n Command: ${command} ${args.join(' ')}\n Working Dir: ${workingDir}`));
|
||||
});
|
||||
|
||||
// Timeout handling (timeout=0 disables internal timeout, controlled by external caller)
|
||||
let timeoutId: NodeJS.Timeout | null = null;
|
||||
if (timeout > 0) {
|
||||
timeoutId = setTimeout(() => {
|
||||
timedOut = true;
|
||||
child.kill('SIGTERM');
|
||||
setTimeout(() => {
|
||||
if (!child.killed) {
|
||||
child.kill('SIGKILL');
|
||||
}
|
||||
}, 5000);
|
||||
}, timeout);
|
||||
}
|
||||
|
||||
child.on('close', () => {
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
});
|
||||
// Timeout controlled by external caller (bash timeout)
|
||||
// When parent process terminates, child will be cleaned up via process exit handler
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1228,12 +1206,8 @@ Modes:
|
||||
includeDirs: {
|
||||
type: 'string',
|
||||
description: 'Additional directories (comma-separated). Maps to --include-directories for gemini/qwen, --add-dir for codex'
|
||||
},
|
||||
timeout: {
|
||||
type: 'number',
|
||||
description: 'Timeout in milliseconds (default: 0 = disabled, controlled by external caller)',
|
||||
default: 0
|
||||
}
|
||||
// timeout removed - controlled by external caller (bash timeout)
|
||||
},
|
||||
required: ['tool', 'prompt']
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user