(pid: number)
| 136 | |
| 137 | // ─── Process Management ───────────────────────────────────────── |
| 138 | async function killServer(pid: number): Promise<void> { |
| 139 | if (!isProcessAlive(pid)) return; |
| 140 | |
| 141 | if (IS_WINDOWS) { |
| 142 | // taskkill /T /F kills the process tree (Node + Chromium) |
| 143 | try { |
| 144 | Bun.spawnSync( |
| 145 | ['taskkill', '/PID', String(pid), '/T', '/F'], |
| 146 | { stdout: 'pipe', stderr: 'pipe', timeout: 5000 } |
| 147 | ); |
| 148 | } catch (err: any) { |
| 149 | if (err?.code !== 'ENOENT') throw err; |
| 150 | } |
| 151 | const deadline = Date.now() + 2000; |
| 152 | while (Date.now() < deadline && isProcessAlive(pid)) { |
| 153 | await Bun.sleep(100); |
| 154 | } |
| 155 | return; |
| 156 | } |
| 157 | |
| 158 | safeKill(pid, 'SIGTERM'); |
| 159 | |
| 160 | // Wait up to 2s for graceful shutdown |
| 161 | const deadline = Date.now() + 2000; |
| 162 | while (Date.now() < deadline && isProcessAlive(pid)) { |
| 163 | await Bun.sleep(100); |
| 164 | } |
| 165 | |
| 166 | // Force kill if still alive |
| 167 | if (isProcessAlive(pid)) { |
| 168 | safeKill(pid, 'SIGKILL'); |
| 169 | } |
| 170 | } |
| 171 | |
| 172 | /** |
| 173 | * Clean up legacy /tmp/browse-server*.json files from before project-local state. |
no test coverage detected