#2918·stagehand

browse CLI: headless daemon spawn flashes a console window on Windows and steals focus (missing windowsHide)

Author: localhedgeCreated Sep 10, 2026Updated Sep 10, 2026

Environment

  • browse 0.9.6 from npm (npm install -g browse), Windows 11, Node 24.13
  • Local mode, headless: browse open <url> --local; browse doctor reports managed-local

Symptom

Every time the CLI starts its background daemon (the first browse open of a session, and again after browse stop), a console window flashes on the desktop for a moment. It takes keyboard focus while it is up, so anything typed in the terminal or editor at that instant lands in the flashed window and is lost. In headless mode there is no reason for any window to appear.

This is distinct from #2148, which is about the Chromium window in --headed mode on macOS. Here the browser is headless and the window that appears is the Node console of the daemon process.

Cause

spawnDaemon in dist/lib/driver/daemon/client.js starts the daemon with:

javascript
const child = spawn(process.execPath, [entrypoint, "daemon", "--session", session, "--target", JSON.stringify(target)], {
    detached: true,
    env: process.env,
    stdio: "ignore",
});
child.unref();

On Windows, detached: true without windowsHide: true gives the child its own console window. The update worker in dist/lib/update.js already passes windowsHide: true for its detached spawn, so the daemon spawn is the one place missing it.

Fix

Add windowsHide: true to the spawn options in spawnDaemon. Verified locally by patching the installed 0.9.6 package: browse open https://example.com --local followed by browse eval "document.title" returns Example Domain, the daemon runs as before, and no window appears. The flag is a no-op on macOS and Linux.

Workaround until fixed

Patch the installed file (<global npm prefix>/node_modules/browse/dist/lib/driver/daemon/client.js) with the flag; it is lost on the next npm update -g browse.