fix(gateway): self-heal state file PID on server startup
After /restart on Windows, the gateway process gets a new PID (os.execv
creates a new process on Windows), but the state file at
run/gateway.<suffix>.json still contains the old PID from the initial
background spawn. Nothing rewrites it, leaving state inconsistent.
Add GatewayRuntime.refresh_state_pid() — a classmethod that reads the
existing state file, updates the PID and identity to the current
process, and writes atomically. Call it early in _run_gateway() so the
state file is always correct regardless of how the process was started
(initial spawn, os.execv, or subprocess.Popen).
On POSIX os.execv preserves the PID, so this is a no-op in normal
operation there, but still beneficial after any unusual restart path.
Fixes#4511
@
fix(exec): default Windows commands to PowerShell and allow shell parameter
Single-line commands on Windows were routed through cmd.exe
(asyncio.create_subprocess_shell) while multi-line commands used
PowerShell. This caused cross-drive cd failures, missing $VAR expansion,
and inconsistent behavior depending on whether a command contained a
newline. The shell parameter was also rejected on Windows.
- Route all Windows commands through PowerShell by default so single-line
and multi-line commands share the same shell semantics.
- Allow the shell parameter on Windows: accepts powershell, pwsh, or cmd.
- cmd.exe remains reachable via shell="cmd" as an explicit escape hatch.
- Update tests to cover the new default and shell-parameter paths.
Fixes#4544
@
feat(api): require api_key when binding to all interfaces (parity with WS gateway)
The OpenAI-compatible API server had no authentication option, unlike the
WebSocket gateway which already refuses wildcard binds without a token.
When bound to 0.0.0.0, any caller who could reach the port could drive
the agent with its default tool posture.
- Add api_key field to ApiConfig (schema.py).
- Add wildcard_host_requires_auth validator that rejects wildcard binds
without api_key, mirroring the WS gateway pattern.
- Add Bearer-token auth middleware to the API server (server.py).
/health remains unauthenticated.
- Replace the wildcard-host CLI warning with a hard error when api_key
is unset, and pass api_key to create_app.
Fixes#4490
@