From 0db7bb18ef2862f4e2e0bb657350aa4518cfe395 Mon Sep 17 00:00:00 2001 From: Priyanshu Choudhary <57816400+Priyanchew@users.noreply.github.com> Date: Thu, 9 Apr 2026 00:10:57 +0530 Subject: [PATCH] fix(cli): clear SIGKILL fallback timer when child exits cleanly If the child exits before the 5-second escalation window, the fallback setTimeout would still fire and call process.exit(1). Track the timer in the outer scope so the child.once("exit") handler can cancel it. Co-Authored-By: Claude Sonnet 4.6 --- packages/cli/src/lib/shell.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/lib/shell.ts b/packages/cli/src/lib/shell.ts index 19a8b236f..1362c2b60 100644 --- a/packages/cli/src/lib/shell.ts +++ b/packages/cli/src/lib/shell.ts @@ -64,12 +64,14 @@ export async function getTmuxSessions(): Promise { * handlers registered. Cleans up automatically when the child exits normally. */ export function forwardSignalsToChild(pid: number, child: ChildProcess): void { + let fallback: ReturnType | undefined; + const forward = (): void => { process.off("SIGINT", forward); process.off("SIGTERM", forward); void killProcessTree(pid, "SIGTERM"); // If the child ignores SIGTERM, force-kill after 5 s so the parent exits. - const fallback = setTimeout(() => { + fallback = setTimeout(() => { void killProcessTree(pid, "SIGKILL").finally(() => process.exit(1)); }, 5000); fallback.unref(); @@ -79,6 +81,7 @@ export function forwardSignalsToChild(pid: number, child: ChildProcess): void { child.once("exit", () => { process.off("SIGINT", forward); process.off("SIGTERM", forward); + if (fallback !== undefined) clearTimeout(fallback); }); }