Files
codex --version when codex was on PATH, ~/.local/bin or Homebrew's — nvm, mise, fnm, npm prefixes, pnpm and Volta were out of reach, above all in magpie serve — while the client's own version header was relayed: one turn saying two versions, the older in the User-Agent. Now codexSign writes one version in both, never older than the relayed one; the gateway notes the newest version a Codex client (originator or codex… User-Agent) has come with (SawCodexClient) and codexVersion, also asked by the accounts' model lists, takes it; the fallback is 0.159.0; the models cache is read from CODEX_HOME when set; codexExecutable also looks in proc.UserBinDirs() (every Node of nvm, mise and fnm, ~/.npmrc's prefix, pnpm, bun, Volta; %APPDATA%\npm and the like on Windows; codex.cmd/.exe there). Tested with TestCodexPoolSaysTheClientsVersion against a fake backend refusing gpt-6.1-sol below 0.161.0: Codex CLI 0.161.0 through the pool failed on main with codex_cli_rs/0.154.0 and passes; TestCodexVersionSeen (Claude Code's User-Agent ignored, CLI and Desktop versions read, never lowered, the model list asked with it), TestCodexVersion with CODEX_HOME, TestCodexExecutableOffPath (nvm, mise, an .npmrc prefix with PATH /usr/bin:/bin). go vet ./internal/..., go build -tags nogui (and GOOS=linux, GOOS=windows) and go test -tags nogui ./... pass. Not tried against the real backend: the version gating is read from the error and the models cache, not seen on the wire.
windows: the desktop app no longer opens a console window for every command it runs (#54) — it is linked as a GUI program and has no console, so each console CLI it started (devin auth status and models list, devin acp for every Devin turn, claude, codex, cursor-agent and grok probes and runs, grok login) was given a new console by Windows, and a Windows Terminal window with it, some every few seconds while the app sat idle. Every command magpie runs is now made through internal/proc, which starts it with CREATE_NO_WINDOW when magpie has no console of its own: the child gets a console without a window, and its output, which magpie always pipes back, arrives as before. A magpie run in a terminal (magpie serve, the TUI, the desktop app started from one with a command) has one, and its children share it as they did, so Ctrl+C there still reaches them. The relaunch after an update keeps its DETACHED_PROCESS, added to rather than replacing the flags it was made with, and a test fails on any command made with os/exec directly, so a new one can't bring the windows back
windows: the desktop app no longer opens a console window for every command it runs (#54) — it is linked as a GUI program and has no console, so each console CLI it started (devin auth status and models list, devin acp for every Devin turn, claude, codex, cursor-agent and grok probes and runs, grok login) was given a new console by Windows, and a Windows Terminal window with it, some every few seconds while the app sat idle. Every command magpie runs is now made through internal/proc, which starts it with CREATE_NO_WINDOW when magpie has no console of its own: the child gets a console without a window, and its output, which magpie always pipes back, arrives as before. A magpie run in a terminal (magpie serve, the TUI, the desktop app started from one with a command) has one, and its children share it as they did, so Ctrl+C there still reaches them. The relaunch after an update keeps its DETACHED_PROCESS, added to rather than replacing the flags it was made with, and a test fails on any command made with os/exec directly, so a new one can't bring the windows back
windows: the desktop app no longer opens a console window for every command it runs (#54) — it is linked as a GUI program and has no console, so each console CLI it started (devin auth status and models list, devin acp for every Devin turn, claude, codex, cursor-agent and grok probes and runs, grok login) was given a new console by Windows, and a Windows Terminal window with it, some every few seconds while the app sat idle. Every command magpie runs is now made through internal/proc, which starts it with CREATE_NO_WINDOW when magpie has no console of its own: the child gets a console without a window, and its output, which magpie always pipes back, arrives as before. A magpie run in a terminal (magpie serve, the TUI, the desktop app started from one with a command) has one, and its children share it as they did, so Ctrl+C there still reaches them. The relaunch after an update keeps its DETACHED_PROCESS, added to rather than replacing the flags it was made with, and a test fails on any command made with os/exec directly, so a new one can't bring the windows back
windows: the desktop app no longer opens a console window for every command it runs (#54) — it is linked as a GUI program and has no console, so each console CLI it started (devin auth status and models list, devin acp for every Devin turn, claude, codex, cursor-agent and grok probes and runs, grok login) was given a new console by Windows, and a Windows Terminal window with it, some every few seconds while the app sat idle. Every command magpie runs is now made through internal/proc, which starts it with CREATE_NO_WINDOW when magpie has no console of its own: the child gets a console without a window, and its output, which magpie always pipes back, arrives as before. A magpie run in a terminal (magpie serve, the TUI, the desktop app started from one with a command) has one, and its children share it as they did, so Ctrl+C there still reaches them. The relaunch after an update keeps its DETACHED_PROCESS, added to rather than replacing the flags it was made with, and a test fails on any command made with os/exec directly, so a new one can't bring the windows back
accounts: a slow or hanging agent CLI no longer holds the providers page (#123) — its timeout now ends the call (a CLI that is a script running node left node holding the output, and the call waited for it however long, the 10s timeouts notwithstanding: a CLI's pipes are closed 2s after); a CLI never answered before is waited for 3s, once, then served as nobody signed in until its answer comes behind; and a CLI saying nobody is signed in is kept like any answer, where before it wasn't and every start waited for it again. Tried with cursor-agent and devin hanging 20s and the network black-holed: the first providers call went from 40.6s to 6s on a first start, and to 13ms on the next
accounts: a slow or hanging agent CLI no longer holds the providers page (#123) — its timeout now ends the call (a CLI that is a script running node left node holding the output, and the call waited for it however long, the 10s timeouts notwithstanding: a CLI's pipes are closed 2s after); a CLI never answered before is waited for 3s, once, then served as nobody signed in until its answer comes behind; and a CLI saying nobody is signed in is kept like any answer, where before it wasn't and every start waited for it again. Tried with cursor-agent and devin hanging 20s and the network black-holed: the first providers call went from 40.6s to 6s on a first start, and to 13ms on the next