Skip to content

CLI Lifecycle

These commands install, run, inspect, repair, and update the local opencodex proxy and its Codex integration.

Interactive setup wizard (setup is an alias of init). Prompts for a provider (preset or custom), API key (literal or ${ENV}), default model, and proxy port; saves ~/.opencodex/config.json; optionally injects the proxy into $CODEX_HOME/config.toml (default ~/.codex/config.toml); and optionally installs the Codex autostart shim.

Start the proxy server (preferred port 10100). If that port is occupied, opencodex selects and records another available port. It writes PID/runtime-port state and refuses to start a second live instance. On start it syncs each provider’s models into Codex’s catalog. On shutdown it restores native Codex — unless it was launched as a managed service (OCX_SERVICE=1).

Terminal window
ocx start
ocx start --port 8080

Stop the running proxy (by PID), remove the PID file, and restore native Codex. If a managed background service is installed, ocx stop also stops it first so it cannot respawn the proxy. The same action is available from the web dashboard’s Stop button (POST /api/stop).

Run stop followed by ensure: stop the proxy/service, restore native Codex, start the proxy in the background, and sync the live port back into Codex.

Idempotently ensure a background proxy is running, then sync its live model catalog. If codexAutoStart is false, it prints that autostart is disabled and does nothing.

Restore native Codex without stopping the proxy — strips the injected config lines and routed catalog entries so plain codex works natively again. eject is an alias of restore.

Pass back to either spelling to re-point plain codex at an already-running proxy without changing the proxy lifecycle:

Terminal window
ocx restore back
ocx eject back

Explicit recovery for older development builds that remapped Codex App history before reversible backup support existed. Close Codex first if its history database is locked.

Stop the service and proxy, remove the service and Codex shim, restore native Codex, then remove opencodex local config only if all restore steps succeeded. remove is an alias of uninstall. Config cleanup requires ownership metadata created by a fresh install; legacy or shared directories are left in place.

Print a read-only diagnostic summary: proxy PID, /healthz reachability, dashboard URL, config path, default provider, Codex autostart setting, service state, shim state, and the redacted effective Codex home. Only the explicit, high-confidence Windows Orca runtime-home signature adds an actionable App-home mismatch warning; it never changes CODEX_HOME automatically.

Human output also includes an OAuth health block after the OAuth logins summary: OAuth health: ok when every known account is healthy, or OAuth health: warning with one redacted line per non-healthy account (provider, masked account id, status such as reauthentication required, rate or quota limited, or refresh conflict) plus an optional Action: hint. Account ids are redacted; tokens and emails are never printed. The --json contract does not currently include this health block.

Terminal window
ocx status
ocx status --json

Abbreviated example shape:

{
"schemaVersion": 1,
"proxy": {
"running": false,
"pid": null,
"health": {
"ok": false,
"url": "http://127.0.0.1:10100/healthz",
"message": "unreachable"
}
},
"dashboard": {
"url": "http://localhost:10100/"
},
"paths": {
"config": "/Users/example/.opencodex/config.json",
"pid": "/Users/example/.opencodex/ocx.pid",
"runtime": "/path/to/bun"
},
"runtime": {
"source": "bundled"
},
"codexHome": {
"effectiveCodexHome": "C:\\Users\\[USER]\\.codex",
"appCodexHome": "C:\\Users\\[USER]\\.codex",
"mismatch": false,
"warning": null,
"action": null
},
"codexAutostart": true,
"defaultProvider": "openai",
"service": {
"summary": "not installed (logs: /Users/example/.opencodex/service.log)"
},
"codexShim": {
"summary": "Codex autostart shim: not installed"
}
}

The real object also includes listen (port, hostname, runtime/config source), config load diagnostics, and bundled Codex plugin diagnostics. The JSON schema is additive-only: future versions may add fields, but existing fields should stay stable. It intentionally excludes API keys, OAuth tokens, authorization headers, request content, emails, and account identities.

Identity-check the live proxy. Human output reports PID/port; --json emits {ok, pid, port}. The command exits 0 only when healthy and 1 otherwise, making it suitable for service probes.

Run read-only environment and connectivity diagnostics: state paths and filesystem type, WSL dual installs, proxy environment/config, ChatGPT reachability, Codex plugin and project-config warnings, and pending history migration. The Codex app-home targeting section also detects the narrow Windows Orca runtime-home mismatch and explains service migration when applicable. Paths shown by this diagnostic redact the OS username. Doctor prints repair hints but does not apply them.

The OAuth reliability section reports whether credential storage is writable, whether refresh single-flight/lock files can be created under OPENCODEX_HOME, non-healthy OAuth or Codex pool accounts (redacted ids) with a recovery Action:, and a static OK that the Codex forward path does not fabricate official-client metadata. Doctor never mutates credentials or applies repairs.

Fetch the live model list from every configured provider and re-inject the merged catalog into Codex. Run it after adding a provider or to refresh available models.

If long-lived Codex app-server processes are still running, ocx sync warns that they may keep serving the previous in-memory model list even though opencodex-catalog.json / models_cache.json were updated. Pass --restart-codex to send SIGTERM only to matching codex … app-server and codex-code-mode-host processes owned by the current user (active turns may be interrupted). Broad pkill -f codex matching is intentionally avoided.

Invalidate Codex’s local model picker cache so it is rebuilt from the active opencodex catalog. The same stale-app-server warning and optional --restart-codex behavior as ocx sync apply.

ocx service [install|start|stop|status|uninstall|remove]

Section titled “ocx service [install|start|stop|status|uninstall|remove]”

Run opencodex as a login-managed background service (macOS launchd, Linux systemd user unit, Windows Task Scheduler) that auto-starts on login and auto-restarts on crash. Service runs set OCX_SERVICE=1 so a restart does not churn the Codex config.

Subcommand Action
none Create/update and start the service.
install Create and start the service.
start Start an installed service.
stop Stop the service and restore native Codex.
status Report service and proxy diagnostics plus log paths.
uninstall Remove the service and restore native Codex.
remove Alias of uninstall.
Terminal window
ocx service
ocx service install
ocx service status
ocx service uninstall

install, start, and repair confirm that a proxy actually answers on the port baked into the installed service before reporting success — on all three platforms. They wait up to 20 seconds and then print the serving port:

✅ opencodex service installed and serving on port 10100.

If nothing answers, they warn and exit non-zero:

⚠️ Service installed, but no proxy answered on port 10100 within 20s.
The manager registered the job; that is not the same as serving.
Log: ~/.opencodex/service.log
Meanwhile: ocx start (serves in the foreground)

A non-zero exit here means registered but not serving — not not installed. The service manager accepted the job; the proxy behind it never bound the port. Read the log named in the message, and use ocx start to serve in the foreground meanwhile.

ocx service status reports the same three states rather than raw manager output:

✅ installed and loaded (launchd; logs: …)
Serving on port 10100.
⚠️ installed and loaded (launchd; logs: …)
Registered, but no proxy is answering on port 10100.
launchd is running an OLDER plist than the one on disk.
Fix: launchctl bootout gui/$(id -u)/com.opencodex.proxy && ocx service install
Log: ~/.opencodex/service.log
Repair: ocx service install
Meanwhile: ocx start (serves in the foreground)

It no longer prints the raw launchctl list / systemctl status line, which reported a registered job identically whether it was serving, bound to nothing, or running a previous definition. The Diagnostics: line still carries the log path and any stale-baked-path finding.

On Windows the scheduler backend keeps its own richer status output, which already reported Task Scheduler registration separately from proxy reachability.

On macOS this also covers a subtler failure: launchctl load reports failure on stderr while exiting 0, so a load that did not take used to leave launchd running a previous version of the service definition while the command printed a checkmark. install now fails loudly in that case and names the launchctl bootout command that clears the stale job.

On Windows, ocx service status reports Task Scheduler registration separately from identity-verified OpenCodex proxy reachability. It does not print the localized schtasks table, so the summary remains readable across Windows code pages.

On Windows, creating the Task Scheduler entry requires elevation. Recognized localized access-denied text keeps the existing guidance path. If that text is unreadable, the fallback requires the owned command shape /create /tn opencodex-proxy /xml <non-empty-path> /f, status 1, and a confirmed non-elevated token; the dashboard’s Startup Safety action can then request UAC automatically. If that fallback cannot determine the token state, it retains the original scheduler error. Foreign tasks and operations can never emit the automatic-elevation marker. Approve the dashboard UAC prompt or rerun ocx service install in an elevated PowerShell window.

ocx codex-shim <install|status|uninstall|remove>

Section titled “ocx codex-shim <install|status|uninstall|remove>”

Wrap a script-based codex launcher on PATH with a lightweight autostart script. Real codex.exe targets are left untouched to avoid breaking exact executable invocations.

If a completed external Codex update overwrites an installed shim, the next ordinary ocx command backs up the stable new launcher and restores the shim before dispatch. A launcher that is still changing is left untouched and retried later. Repair failures warn without failing the requested command; manual fallback: ocx codex-shim install. Set codexShimAutoRestore to false, or set OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0 for a process-level opt-out.

Subcommand Action
install Install the shim (or repair if stale).
uninstall Remove the shim and restore the original Codex binary.
remove Alias of uninstall.
status Report shim state (installed, stale, or missing).
Terminal window
ocx codex-shim install
ocx codex-shim status
ocx codex-shim uninstall

ocx tray <install|start|stop|status|uninstall|remove> [--json] [--no-start]

Section titled “ocx tray <install|start|stop|status|uninstall|remove> [--json] [--no-start]”

Install and control the Windows status tray icon. It starts at Windows login and provides one-click proxy controls. start and stop control the icon only; use its menu to control the proxy. --no-start applies to install and installs the tray without launching it immediately.

Open the web dashboard at http://localhost:<port>, auto-starting the proxy if it is not running.

Self-update opencodex from npm. Stable installs use @latest; preview installs stay on @preview unless you pass --tag latest|preview. It detects a source checkout and tells you to git pull && bun install instead, and is a no-op if you are already on the newest version for that tag. A running proxy is stopped before files are replaced; an installed service is rebuilt and started automatically, while a foreground installation prints ocx start as the next step.

Terminal window
ocx update
ocx update --tag preview

New versions become available when the Release workflow publishes them to npm.