Skip to content

Windows: plugin MCP bridge spawns visible empty console windows (daemon + cmd-wrapped codex app-server) — fixed locally with windowsHide: true #238

Description

@redsteinway

Summary

On native Windows, every Claude Code launch with the agentbridge plugin installed opens visible empty console windows that stay on screen for the daemon's lifetime. Closing them kills the daemon. Two spawn sites lack windowsHide: true; adding it at both sites fully resolves the problem (verified end to end on a real pair).

Related to the #231 Windows-support tracking issue (this is a concrete blocker in the "Runtime / launcher on Windows" category, but it isn't in that issue's blocker list yet).

Environment

  • agentbridge v0.1.30 (commit 55120e8), installed as Claude Code plugin (marketplace)
  • Claude Code 2.1.210, Windows 11 (26200), Windows Terminal as default terminal app
  • Bun 1.3.11, codex-cli 0.144.4 (npm global install)

Symptom

  1. Launch Claude Code normally (any project).
  2. The plugin MCP bridge starts and eagerly ensures the daemon: MCP server ready (push delivery) — ensuring AgentBridge daemon...Launching detached daemon on control port 4502.
  3. One or two empty terminal windows appear and remain open:
    • the daemon's own console (bun, detached: true without windowsHide), and
    • a window titled C:\WINDOWS\system32\cmd.exe hosting cmd.exe /c codex app-server --listen ws://127.0.0.1:4500.
  4. Closing either window kills the corresponding process (daemon / app-server).

The second window exists because on Windows, Bun/Node resolves the npm codex shim (codex.cmd) and wraps it in cmd.exe /c; since the parent daemon is detached/windowless, the cmd child gets a fresh visible console.

Root cause — two spawn sites lack windowsHide: true

Site 1: daemon launch (plugins/agentbridge/server/bridge-server.js, launch()):

const daemonProc = spawn(process.execPath, ["run", DAEMON_PATH], {
  cwd: process.cwd(),
  env: { ... },
  detached: true,
  stdio: "ignore"          // ← no windowsHide → visible console on win32
});

Site 2: codex app-server spawn (plugins/agentbridge/server/daemon.js, ~line 1057):

this.proc = spawn("codex", ["app-server", "--listen", listen], {
  stdio: ["pipe", "pipe", "pipe"]   // ← no windowsHide → visible cmd.exe wrapper console
});

Note: the bridge launches the daemon from the npm package copy of daemon.js (via AGENTBRIDGE_DAEMON_ENTRY), so patching only the plugin-cache copy of daemon.js has no effect — worth keeping in mind for where the fix lands.

Fix (verified)

Add windowsHide: true to both spawn option objects. windowsHide is a no-op on POSIX, so no platform branching is needed.

After patching both sites and restarting the daemon, all three processes run without any window (checked MainWindowHandle == 0 for the bun daemon, the cmd.exe wrapper, and codex.exe), and a full Claude→Codex→Claude round trip over the bridge still works.

The same treatment probably also applies to other spawn sites in dist/ used by the abg CLI launchers (retry loops there flash multiple console windows when daemon startup fails), but I've only verified the two plugin-path sites above.

Incidental observation (for #231)

While debugging this I also hit Codex error: ENOENT: no such file or directory, uv_spawn 'codex' from the daemon on Windows: the npm global bin dir contains only the codex sh-shim and codex.cmd, no codex.exe, so a shell-less spawn can't resolve it depending on runtime/version. Workaround was putting the platform package's vendor bin dir (which contains a real codex.exe) on PATH. Happy to file that separately if useful.

Thanks for the great tool — the bidirectional pair works nicely on Windows once these are patched. 🙌

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions