* Windows has no POSIX process groups: ChildProcess#kill reaches only the * direct child (e.g. the uvx wrapper), leaving grandchildren — the actual * python agent-server holding its port — running. `taskkill /t` walks the * child tree instead. Windows also has no graceful tree signal (taskkill *
(proc, signal)
| 116 | * a failure to spawn taskkill itself falls back to the direct kill. |
| 117 | */ |
| 118 | function killWindowsProcessTree(proc, signal) { |
| 119 | const result = spawnSync( |
| 120 | "taskkill", |
| 121 | ["/pid", String(proc.pid), "/t", "/f"], |
| 122 | // windowsHide avoids a console window flash when invoked from the |
| 123 | // packaged (GUI) Electron process. |
| 124 | { stdio: "ignore", windowsHide: true }, |
| 125 | ); |
| 126 | if (result.error) { |
| 127 | proc.kill(signal); |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | export function createShutdownHookRegistry(onError) { |
| 132 | const hooks = new Set(); |