From 40c19a28af06493a54487183d50f796471c396a1 Mon Sep 17 00:00:00 2001 From: kevinWangSheng Date: Wed, 25 Mar 2026 08:09:04 -0700 Subject: [PATCH] fix: use process.exitCode instead of process.exit() so runner finally blocks clean up temp files process.exit() terminates the Node.js process immediately without executing pending finally blocks. All five runners (claude, openai, crewai, nanobot, openclaw) write temporary files or directories then call process.exit() inside a try block, so the finally cleanup is always skipped. Replace process.exit(N) with process.exitCode = N; return so the finally block executes and removes temporary files before the process exits naturally. This prevents system prompt content, agent configs, and API key material written to /tmp from persisting on disk indefinitely. --- src/runners/claude.ts | 5 +++-- src/runners/crewai.ts | 5 +++-- src/runners/nanobot.ts | 5 +++-- src/runners/openai.ts | 5 +++-- src/runners/openclaw.ts | 5 +++-- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/runners/claude.ts b/src/runners/claude.ts index 36b5689..5c5d6b3 100644 --- a/src/runners/claude.ts +++ b/src/runners/claude.ts @@ -96,10 +96,11 @@ export function runWithClaude(agentDir: string, manifest: AgentManifest, options if (result.error) { error(`Failed to launch Claude Code: ${result.error.message}`); info('Make sure Claude Code CLI is installed: npm install -g @anthropic-ai/claude-code'); - process.exit(1); + process.exitCode = 1; + return; } - process.exit(result.status ?? 0); + process.exitCode = result.status ?? 0; } finally { for (const f of tmpFiles) { try { unlinkSync(f); } catch { /* ignore */ } diff --git a/src/runners/crewai.ts b/src/runners/crewai.ts index 3f8e95a..8947331 100644 --- a/src/runners/crewai.ts +++ b/src/runners/crewai.ts @@ -25,10 +25,11 @@ export function runWithCrewAI(agentDir: string, _manifest: AgentManifest): void if (result.error) { error(`Failed to run CrewAI: ${result.error.message}`); info('Make sure the crewai CLI is installed: pip install crewai'); - process.exit(1); + process.exitCode = 1; + return; } - process.exit(result.status ?? 0); + process.exitCode = result.status ?? 0; } finally { try { unlinkSync(tmpFile); } catch { /* ignore */ } } diff --git a/src/runners/nanobot.ts b/src/runners/nanobot.ts index 92f1841..713737f 100644 --- a/src/runners/nanobot.ts +++ b/src/runners/nanobot.ts @@ -58,10 +58,11 @@ export function runWithNanobot(agentDir: string, manifest: AgentManifest, option error(`Failed to launch Nanobot: ${result.error.message}`); info('Install Nanobot with: pip install nanobot-ai'); info('Or: uv tool install nanobot-ai'); - process.exit(1); + process.exitCode = 1; + return; } - process.exit(result.status ?? 0); + process.exitCode = result.status ?? 0; } finally { try { rmSync(tmpConfigDir, { recursive: true, force: true }); } catch { /* ignore */ } } diff --git a/src/runners/openai.ts b/src/runners/openai.ts index 722e235..7f289e7 100644 --- a/src/runners/openai.ts +++ b/src/runners/openai.ts @@ -32,10 +32,11 @@ export function runWithOpenAI(agentDir: string, _manifest: AgentManifest): void if (result.error) { error(`Failed to run Python: ${result.error.message}`); info('Make sure python3 is installed and the openai-agents package is available'); - process.exit(1); + process.exitCode = 1; + return; } - process.exit(result.status ?? 0); + process.exitCode = result.status ?? 0; } finally { try { unlinkSync(tmpFile); } catch { /* ignore */ } } diff --git a/src/runners/openclaw.ts b/src/runners/openclaw.ts index a162b96..b38e180 100644 --- a/src/runners/openclaw.ts +++ b/src/runners/openclaw.ts @@ -118,10 +118,11 @@ export function runWithOpenClaw(agentDir: string, manifest: AgentManifest, optio if (result.error) { error(`Failed to launch OpenClaw: ${result.error.message}`); info('Make sure OpenClaw is installed: npm install -g openclaw@latest'); - process.exit(1); + process.exitCode = 1; + return; } - process.exit(result.status ?? 0); + process.exitCode = result.status ?? 0; } finally { // Cleanup temp workspace try { rmSync(workspaceDir, { recursive: true, force: true }); } catch { /* ignore */ }