large update

This commit is contained in:
ZacharyZhang-NY committed 2026-03-29 14:08:15 -04:00
1 parent 2ed952f19c
commit 65e85135c1
111 files changed
+3936 -2933

No files matched your search

+33 -1
View File
@@ -1,4 +1,4 @@
import { spawn, type ChildProcess } from "node:child_process";
import { spawn, execSync, type ChildProcess } from "node:child_process";
import { constants as fsConstants, promises as fs, type Dirent } from "node:fs";
import path from "node:path";
import { StringDecoder } from "node:string_decoder";
@@ -354,6 +354,7 @@ export async function runChildProcess(
cwd: opts.cwd,
env: mergedEnv,
shell: false,
windowsHide: true,
stdio: [opts.stdin != null ? "pipe" : "ignore", "pipe", "pipe"],
}) as ChildProcessWithEvents;
@@ -468,6 +469,37 @@ export async function runChildProcess(
});
}
/**
* Kill a process and all its descendants.
* Windows: `taskkill /T /F` kills the full process tree.
* Unix: SIGKILL the process directly (CLI tools are leaf processes).
*/
function killProcessTree(pid: number): void {
if (process.platform === "win32") {
try {
execSync(`taskkill /T /F /PID ${pid}`, { stdio: "ignore", timeout: 5000 });
} catch { /* process already exited */ }
} else {
try {
process.kill(pid, "SIGKILL");
} catch { /* already dead */ }
}
}
/**
* Force-kill every child process tracked in `runningProcesses` and clear the map.
* Called by the worker during shutdown to ensure no CLI processes survive app quit.
*/
export function shutdownAllRunning(): void {
for (const [runId, entry] of runningProcesses) {
const pid = entry.child.pid;
if (pid != null) {
killProcessTree(pid);
}
runningProcesses.delete(runId);
}
}
/**
* Create symlinks for managed skills in the target directory.
* Per D-13: uses 'junction' type on Windows to avoid Developer Mode requirement.