mirror of
https://github.com/garrytan/gstack.git
synced 2026-07-06 08:07:53 +02:00
fix: Windows browse — health-check-first ensureServer, detached startServer, Windows process mgmt (v0.11.11.0) (#431)
* fix: Windows browse — health-check-first ensureServer, detached startServer, Windows process mgmt
Three compounding bugs made browse completely broken on Windows:
1. Bun.spawn().unref() doesn't truly detach on Windows — server dies when
CLI exits. Fix: use Node's child_process.spawn with { detached: true }
via a launcher script. Credit: PR #191 by @fqueiro for the approach.
2. process.kill(pid, 0) is broken in Bun's compiled binary on Windows —
ensureServer() never reaches the health check. Fix: restructure to
health-check-first (HTTP is definitive proof on all platforms). Extract
isServerHealthy() helper for DRY (4 call sites).
3. Windows process management: isProcessAlive() falls back to tasklist,
killServer() uses taskkill /T /F (kills process tree including Chromium),
cleanupLegacyState() skips on Windows (no /tmp, no ps).
Also: hard-fail on Windows if server-node.mjs is missing instead of
silently falling back to the known-broken Bun path.
Fixes #342.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: disable Chromium sandbox on Windows
Chromium's sandbox fails when the server is spawned through the
Bun→Node process chain on Windows (GitHub #276). Disable
chromiumSandbox on Windows at both launch sites (headless + headed).
Safe: local daemon browsing user-specified URLs, Playwright docs
recommend disabling in CI/container environments.
Fixes #276.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: startup error log + Windows exit handler for browse server
On Windows, the CLI can't capture stderr from the server (stdio: 'ignore'
required for process detachment). Write startup errors to
.gstack/browse-startup-error.log so the CLI can report them on timeout.
Also add process.on('exit') handler on Windows as defense-in-depth for
state file cleanup (primary mechanism is CLI's stale-state detection).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add isServerHealthy + startup error log tests
Tests for the new cross-platform health check helper (isServerHealthy)
that replaces PID-based liveness checks in all polling loops. Covers
healthy, unhealthy, unreachable, and error response cases.
Also tests the startup error log write/read format used on Windows.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: bump version and changelog (v0.11.11.0)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: sync ARCHITECTURE.md with health-check-first ensureServer
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -286,6 +286,13 @@ async function shutdown() {
|
||||
// Handle signals
|
||||
process.on('SIGTERM', shutdown);
|
||||
process.on('SIGINT', shutdown);
|
||||
// Windows: taskkill /F bypasses SIGTERM, but 'exit' fires for some shutdown paths.
|
||||
// Defense-in-depth — primary cleanup is the CLI's stale-state detection via health check.
|
||||
if (process.platform === 'win32') {
|
||||
process.on('exit', () => {
|
||||
try { fs.unlinkSync(config.stateFile); } catch {}
|
||||
});
|
||||
}
|
||||
|
||||
// ─── Start ─────────────────────────────────────────────────────
|
||||
async function start() {
|
||||
@@ -365,5 +372,14 @@ async function start() {
|
||||
|
||||
start().catch((err) => {
|
||||
console.error(`[browse] Failed to start: ${err.message}`);
|
||||
// Write error to disk for the CLI to read — on Windows, the CLI can't capture
|
||||
// stderr because the server is launched with detached: true, stdio: 'ignore'.
|
||||
try {
|
||||
const errorLogPath = path.join(config.stateDir, 'browse-startup-error.log');
|
||||
fs.mkdirSync(config.stateDir, { recursive: true });
|
||||
fs.writeFileSync(errorLogPath, `${new Date().toISOString()} ${err.message}\n${err.stack || ''}\n`);
|
||||
} catch {
|
||||
// stateDir may not exist — nothing more we can do
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user