Client or integration
Codex App
Area
Service lifecycle
Summary
ocx system codex-restart quits and relaunches the whole Codex desktop shell. Upstream's own restart operation does not: codex app-server daemon restart stops and starts only the app-server process it manages, refuses to act when the responding app-server is not daemon-managed, and waits for the replacement to pass a readiness probe. Upstream treats a server restart as something clients survive — SIGTERM means "graceful restart drain", the acceptor stops once running turns reach zero, and connected clients reconnect.
Because we terminate the desktop shell instead, everything that lived only in the client is discarded: an unsaved model-picker selection, an in-progress composer draft, and any approval prompt waiting for the user. The desktop restart path finds root Codex shell processes, asks them to quit, force-stops survivors, and relaunches the app; it never starts or readiness-probes an app-server itself and relies on the relaunched desktop to create replacements.
This is not a regression and not a defect in the current implementation. That code is careful: it revalidates process start times before signalling, refuses uncertain app-server identities, and is gated behind an explicit --yes. The scope is not gratuitous either — model_catalog_json is startup-only upstream, so a catalog change genuinely cannot be picked up by a running desktop without restarting it, and config/batchWrite.reloadUserConfig reapplies only reloadable settings and is documented as neither a process restart nor a catalog reload.
The debt is that the only tool offered for "pick up the new catalog" is the most destructive one available, and the user pays unsaved client state for it every time. Worth considering: detect whether the catalog actually changed and skip the desktop restart when it did not; restart app-servers alone when that suffices; or name the specific unsaved desktop state at risk before quitting rather than describing the scope generically.
Expected: refreshing the catalog should not cost the user their unsaved desktop state unless that is genuinely the only way to apply the change, and the command should say so when it is.
Reproduction
- Start the proxy and connect Codex desktop:
ocx start --port 10100.
- In the Codex desktop app, open a thread and leave unsaved client-side state: type a composer draft without sending it, change the model in the picker without starting a turn, and leave an approval prompt open.
- Run
ocx system codex-restart --yes.
- The desktop app fully quits and relaunches. The draft, the unsent picker selection, and the pending approval are gone.
Compare with upstream codex app-server daemon restart, which restarts only the managed app-server and leaves the desktop client running to reconnect.
Observed against the current restart path in src/codex/app-server-restart-service.ts, src/codex/desktop-app-restart.ts, and src/server/management/system-routes.ts. The upstream contract is in codex-rs/app-server-daemon/src/lib.rs and codex-rs/app-server/src/lib.rs.
Version
dev at 3070d64
Operating system
macOS 27.0 arm64 (the desktop-restart path is macOS and Windows specific)
Provider and model
No response
Logs or error output
Screenshots and supporting files
No response
Redacted configuration
Checks
Client or integration
Codex App
Area
Service lifecycle
Summary
ocx system codex-restartquits and relaunches the whole Codex desktop shell. Upstream's own restart operation does not:codex app-server daemon restartstops and starts only the app-server process it manages, refuses to act when the responding app-server is not daemon-managed, and waits for the replacement to pass a readiness probe. Upstream treats a server restart as something clients survive — SIGTERM means "graceful restart drain", the acceptor stops once running turns reach zero, and connected clients reconnect.Because we terminate the desktop shell instead, everything that lived only in the client is discarded: an unsaved model-picker selection, an in-progress composer draft, and any approval prompt waiting for the user. The desktop restart path finds root Codex shell processes, asks them to quit, force-stops survivors, and relaunches the app; it never starts or readiness-probes an app-server itself and relies on the relaunched desktop to create replacements.
This is not a regression and not a defect in the current implementation. That code is careful: it revalidates process start times before signalling, refuses uncertain app-server identities, and is gated behind an explicit
--yes. The scope is not gratuitous either —model_catalog_jsonis startup-only upstream, so a catalog change genuinely cannot be picked up by a running desktop without restarting it, andconfig/batchWrite.reloadUserConfigreapplies only reloadable settings and is documented as neither a process restart nor a catalog reload.The debt is that the only tool offered for "pick up the new catalog" is the most destructive one available, and the user pays unsaved client state for it every time. Worth considering: detect whether the catalog actually changed and skip the desktop restart when it did not; restart app-servers alone when that suffices; or name the specific unsaved desktop state at risk before quitting rather than describing the scope generically.
Expected: refreshing the catalog should not cost the user their unsaved desktop state unless that is genuinely the only way to apply the change, and the command should say so when it is.
Reproduction
ocx start --port 10100.ocx system codex-restart --yes.Compare with upstream
codex app-server daemon restart, which restarts only the managed app-server and leaves the desktop client running to reconnect.Observed against the current restart path in
src/codex/app-server-restart-service.ts,src/codex/desktop-app-restart.ts, andsrc/server/management/system-routes.ts. The upstream contract is incodex-rs/app-server-daemon/src/lib.rsandcodex-rs/app-server/src/lib.rs.Version
dev at 3070d64
Operating system
macOS 27.0 arm64 (the desktop-restart path is macOS and Windows specific)
Provider and model
No response
Logs or error output
Screenshots and supporting files
No response
Redacted configuration
Checks