Auto-Update Manager
July 10, 2026 ยท View on GitHub
Default native packages install codex-update-manager, a companion
systemd --user service.
It:
- checks upstream
Codex.dmgon daemon startup, every 6 hours, and in the background on app launch when stale - rebuilds a local native package with
/opt/codex-desktop/update-builder - waits for Electron to exit before installing a ready update
- runs unprivileged; the final package install uses
pkexecwhen a graphical polkit authentication agent is available, or keeps the package ready and reports a terminalsudo /usr/bin/codex-update-manager ... --path ...command when no auth agent is available - performs best-effort Codex CLI preflight from the launcher
Codex CLI preflight preserves the detected CLI install type. npm-managed
installs continue to update through npm, while official standalone installs
under ~/.codex/packages/standalone are updated with the official standalone
installer instead of being replaced through npm.
System-package-managed CLI installs are reused but not mutated through npm or
the standalone installer flow. On Arch-like hosts, when the resolved CLI lives
under a system bin directory and pacman -Qo confirms package ownership, the
updater tracks two separate version signals in state:
cli_official_latest_version for the latest published @openai/codex npm
release and cli_package_manager_latest_version for the latest package version
currently known to pacman.
For pacman-managed installs, cli_status follows the package-manager-actionable
result, not the npm result:
- if pacman currently offers a newer package,
cli_statusbecomesUpdateRequiredand the stored status message tells the user to update through pacman instead (for example:sudo pacman -Syu) - if pacman does not currently offer a newer package but npm upstream is newer,
cli_statusstaysUpToDateand the stored status message explains that the distro package and official upstream have diverged so the user can decide whether to stay on the distro-managed CLI or switch installation channels
If the CLI resolves to a system-path binary but pacman -Qo cannot determine
ownership, the updater still skips npm auto-updates and reports that ownership
verification failed so the user can inspect the CLI source manually.
The launcher does not choose the newest installed CLI. It resolves an explicit
CODEX_CLI_PATH first, then falls back to the usual PATH, nvm, and known
user/system locations. Startup logs include the resolved path plus a
best-effort CLI version probe; set CODEX_CLI_PATH=/path/to/codex when you
need to pin a particular binary from a GUI-launched session. CODEX_CLI_PATH
does not bypass install-type detection; if it points at a pacman-managed CLI,
the same non-npm guidance applies.
Inspect State
systemctl --user status codex-update-manager.service
codex-update-manager status --json
codex-update-manager diagnose --json
sed -n '1,160p' ~/.local/state/codex-update-manager/state.json
sed -n '1,160p' ~/.local/state/codex-update-manager/service.log
diagnose is read-only and intended for post-update support reports. It checks
the persisted updater state, installed app executable, launcher app.pid and
webview.pid, local webview HTTP endpoint, warm-start handoff socket, and
Linux build metadata without starting, stopping, installing, or repairing
anything.
Runtime files:
~/.config/codex-update-manager/config.toml
~/.local/state/codex-update-manager/state.json
~/.local/state/codex-update-manager/service.log
~/.cache/codex-update-manager/
~/.cache/codex-desktop/launcher.log
~/.local/state/codex-desktop/app.pid
Generated Artifact Cleanup
The updater always prunes unreferenced updater workspaces under
~/.cache/codex-update-manager/workspaces. Local checkout build output such as
dist/, target/, and codex-app/ is cleaned only when explicitly enabled.
Example:
[generated_artifact_cleanup]
enabled = true
min_free_bytes = 10737418240 # 10 GiB
roots = ["/home/mohit/Github/codex-desktop-linux"]
entries = ["dist", "target", "codex-app"]
If roots is omitted, the updater uses builder_bundle_root. Cleanup only runs
when the filesystem containing a root has less than min_free_bytes available.
Every entry must be a relative top-level name, and the updater only cleans roots
that look like this wrapper repository or packaged update-builder.
Rollback
If a rebuilt update installs but the previous retained package was better, close ChatGPT Desktop and run:
codex-update-manager rollback
Rollback uses the last retained known-good package and refuses to run when no rollback package is available.
Manual-Update Packages
Build a native package without the resident updater:
PACKAGE_WITH_UPDATER=0 make package
make install
That package omits codex-update-manager, the user service unit, updater
polkit policy, /opt/codex-desktop/update-builder, desktop updater actions,
and launcher updater startup checks.
Installing a no-updater package over a default package also stops and disables
existing codex-update-manager.service instances for active user managers and
removes stale per-user enablement links for inactive users.
Manual updates should come from a checkout you trust:
PACKAGE_WITH_UPDATER=0 make update-native
make update-native runs git pull --ff-only, regenerates codex-app/ from a
fresh upstream Codex.dmg, builds the native package, and installs it.
Service Controls
make service-enable
make service-status
codex-update-manager status --json
make service-enable is meant for installed packages, not repo-only generated
apps.
To temporarily pause automatic package rebuilds and installs while keeping Codex Desktop usable, disable the user service:
systemctl --user disable --now codex-update-manager.service
Launching ChatGPT Desktop and upgrading the package will not re-enable a disabled updater service. Re-enable updater behavior explicitly when you want automatic checks again:
systemctl --user enable --now codex-update-manager.service
Wrapper Updates
Optional wrapper-update tracking can watch this repository's own Linux wrapper changes with:
enable_wrapper_updates = true
in ~/.config/codex-update-manager/config.toml.
This is intended for git-checkout/dev update-builder installs. Frozen
native-package builders without a .git directory report no wrapper candidate
and receive wrapper changes through normal package upgrades.