From 38a989f8bb03d26ae38107080f4660f1e2981eb4 Mon Sep 17 00:00:00 2001 From: octane0411 Date: Tue, 3 Mar 2026 10:47:41 +0800 Subject: [PATCH] fix(cli): avoid killing background processes on successful exit --- packages/cli/src/index.ts | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 7d2af2a..5bcdb43 100755 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -2,6 +2,7 @@ import { prompt, FileStorage, convertToATIF, cleanupBackgroundProcesses } from 'open-agent-sdk'; const args = process.argv.slice(2); +type CleanupBackgroundMode = 'never' | 'on-error' | 'always'; function getFlag(name: string): string | undefined { const idx = args.indexOf(name); @@ -9,6 +10,20 @@ function getFlag(name: string): string | undefined { return undefined; } +function resolveCleanupBackgroundMode(): CleanupBackgroundMode { + const mode = (getFlag('--cleanup-background') ?? process.env.OAS_CLEANUP_BACKGROUND ?? 'on-error') + .toLowerCase(); + + if (mode === 'never' || mode === 'on-error' || mode === 'always') { + return mode; + } + + console.error( + `Invalid cleanup mode "${mode}". Expected one of: never, on-error, always. Falling back to on-error.` + ); + return 'on-error'; +} + const instruction = getFlag('-p'); const model = getFlag('--model') ?? process.env.OAS_MODEL; const provider = getFlag('--provider') as 'openai' | 'google' | 'anthropic' | undefined; @@ -19,9 +34,10 @@ const baseURL = getFlag('--base-url') ?? process.env.ANTHROPIC_BASE_URL ?? proce const saveTrajectory = getFlag('--save-trajectory'); const sessionDir = getFlag('--session-dir'); const noPersist = args.includes('--no-persist'); +const cleanupBackgroundMode = resolveCleanupBackgroundMode(); if (!instruction) { - console.error('Usage: oas -p [--model ] [--provider openai|google|anthropic] [--output-format text|json] [--max-turns ] [--cwd ] [--save-trajectory ] [--session-dir ] [--no-persist]'); + console.error('Usage: oas -p [--model ] [--provider openai|google|anthropic] [--output-format text|json] [--max-turns ] [--cwd ] [--save-trajectory ] [--session-dir ] [--cleanup-background never|on-error|always] [--no-persist]'); process.exit(1); } @@ -91,8 +107,15 @@ async function main() { } exitCode = 1; } finally { - // Best-effort cleanup to avoid background command handles blocking process exit. - await cleanupBackgroundProcesses(); + const shouldCleanupBackground = + cleanupBackgroundMode === 'always' || + (cleanupBackgroundMode === 'on-error' && exitCode !== 0); + + if (shouldCleanupBackground) { + // Best-effort cleanup during error paths or when explicitly requested. + await cleanupBackgroundProcesses(); + } + if (exitCode !== 0) process.exit(exitCode); } }