From 4b2298e8cbcb9181e0ab699a4fa45bbcb8f34413 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sun, 21 Jun 2026 07:33:04 +0200 Subject: [PATCH] fix(package): force taskkill candidate runner trees on windows --- .../resolve-openclaw-package-candidate.mjs | 6 +++++ ...resolve-openclaw-package-candidate.test.ts | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/scripts/resolve-openclaw-package-candidate.mjs b/scripts/resolve-openclaw-package-candidate.mjs index 94511e5818a6..6e632833d6d0 100644 --- a/scripts/resolve-openclaw-package-candidate.mjs +++ b/scripts/resolve-openclaw-package-candidate.mjs @@ -328,6 +328,12 @@ export function signalChildProcessTree( if (!result?.error && result?.status === 0) { return; } + if (signal !== "SIGKILL") { + const forceResult = runTaskkill("taskkill", [...args, "/F"], { stdio: "ignore" }); + if (!forceResult?.error && forceResult?.status === 0) { + return; + } + } } child.kill(signal); } diff --git a/test/scripts/resolve-openclaw-package-candidate.test.ts b/test/scripts/resolve-openclaw-package-candidate.test.ts index ce1bf54362ae..61531947fa22 100644 --- a/test/scripts/resolve-openclaw-package-candidate.test.ts +++ b/test/scripts/resolve-openclaw-package-candidate.test.ts @@ -240,6 +240,30 @@ describe("resolve-openclaw-package-candidate", () => { expect(child.kill).not.toHaveBeenCalled(); }); + it("force-kills Windows package runner process trees when graceful taskkill fails", () => { + const child = { + kill: vi.fn(), + pid: 12345, + }; + const runTaskkill = vi + .fn() + .mockReturnValueOnce({ error: undefined, status: 1 }) + .mockReturnValueOnce({ error: undefined, status: 0 }); + + signalChildProcessTree(child, "SIGTERM", { + platform: "win32", + runTaskkill, + }); + + expect(runTaskkill).toHaveBeenNthCalledWith(1, "taskkill", ["/PID", "12345", "/T"], { + stdio: "ignore", + }); + expect(runTaskkill).toHaveBeenNthCalledWith(2, "taskkill", ["/PID", "12345", "/T", "/F"], { + stdio: "ignore", + }); + expect(child.kill).not.toHaveBeenCalled(); + }); + it("keeps npm pack filenames inside the package candidate output directory", async () => { const dir = await mkdtemp(path.join(tmpdir(), "openclaw-package-npm-pack-")); tempDirs.push(dir);