From 689894b4c8320bb697dbc4100e74e575f9fc4ad4 Mon Sep 17 00:00:00 2001 From: umi008 Date: Fri, 10 Jul 2026 20:23:18 -0600 Subject: [PATCH 1/2] fix(terminal): tell model when user pressed Abort on a running command When the user clicks Abort on a running shell command, the terminal previously emitted shell_execution_complete with exitCode: 0 and no indication of user intervention. The model would see a successful exit code or SIGKILL and suspect the Linux OOM-killer, leading to incorrect diagnosis and wrong follow-up actions. Now the ExitCodeDetails interface carries an aborted: true flag when the user explicitly stopped the process. formatExitStatus() checks this first and returns 'Command was aborted by the user.' so the model immediately knows what happened and doesn't speculate about OOM-killer. Closes #833 --- src/core/tools/ExecuteCommandTool.ts | 4 ++++ src/integrations/terminal/ExecaTerminalProcess.ts | 2 +- src/integrations/terminal/types.ts | 6 ++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/core/tools/ExecuteCommandTool.ts b/src/core/tools/ExecuteCommandTool.ts index 58b0055b4c..5066ee166a 100644 --- a/src/core/tools/ExecuteCommandTool.ts +++ b/src/core/tools/ExecuteCommandTool.ts @@ -571,6 +571,10 @@ function formatExitStatus(exitDetails: ExitCodeDetails | undefined): string { return "Exit code: " } + if (exitDetails.aborted) { + return "Command was aborted by the user." + } + if (exitDetails.signalName) { let status = `Process terminated by signal ${exitDetails.signalName}` if (exitDetails.coreDumpPossible) { diff --git a/src/integrations/terminal/ExecaTerminalProcess.ts b/src/integrations/terminal/ExecaTerminalProcess.ts index cde5a1251f..bec0b01082 100644 --- a/src/integrations/terminal/ExecaTerminalProcess.ts +++ b/src/integrations/terminal/ExecaTerminalProcess.ts @@ -130,7 +130,7 @@ export class ExecaTerminalProcess extends BaseTerminalProcess { } } - this.emit("shell_execution_complete", { exitCode: 0 }) + this.emit("shell_execution_complete", { exitCode: 0, aborted: this.aborted }) } catch (error) { if (error instanceof ExecaError) { console.error(`[ExecaTerminalProcess#run] shell execution error: ${error.message}`) diff --git a/src/integrations/terminal/types.ts b/src/integrations/terminal/types.ts index 8224875b60..be494a1e2f 100644 --- a/src/integrations/terminal/types.ts +++ b/src/integrations/terminal/types.ts @@ -72,4 +72,10 @@ export interface ExitCodeDetails { signal?: number | undefined signalName?: string coreDumpPossible?: boolean + /** + * Set to true when the user explicitly pressed the Abort button + * to terminate the command, as opposed to the process exiting on its own + * or being killed by the OS (e.g., OOM-killer). + */ + aborted?: boolean } From 5f21e21f3a85c4dc9cc57869d3e0a88fcc9feb8c Mon Sep 17 00:00:00 2001 From: umi008 Date: Fri, 10 Jul 2026 20:43:24 -0600 Subject: [PATCH 2/2] test(terminal): update ExecaTerminalProcess test for aborted field The shell_execution_complete emission now includes aborted: false for normal process exits. Update the test expectation to match. --- .../terminal/__tests__/ExecaTerminalProcess.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/integrations/terminal/__tests__/ExecaTerminalProcess.spec.ts b/src/integrations/terminal/__tests__/ExecaTerminalProcess.spec.ts index c7f3ee2145..331d9864e0 100644 --- a/src/integrations/terminal/__tests__/ExecaTerminalProcess.spec.ts +++ b/src/integrations/terminal/__tests__/ExecaTerminalProcess.spec.ts @@ -129,7 +129,7 @@ describe("ExecaTerminalProcess", () => { const spy = vitest.fn() terminalProcess.on("shell_execution_complete", spy) await terminalProcess.run("echo test") - expect(spy).toHaveBeenCalledWith({ exitCode: 0 }) + expect(spy).toHaveBeenCalledWith({ exitCode: 0, aborted: false }) }) it("should emit completed event with full output", async () => {