- docs
- Settings and trust
- Update OCX
Update OCX
Update the OCX binary in one command, choose how OCX tells you about new releases, or remove OCX from a machine.
Update to the most recent release
Section titled “Update to the most recent release”OCX updates itself, with no index refresh, reinstall or reselect step. ocx self update queries the published index and registry live for the most recent stable release and downloads it. It then re-executes the new binary as its own ocx self setup, the same command a bare-binary install runs by hand. The swap, the shim refresh and the profile healing form one continuous step:
ocx self updateConfirm the new binary is active with ocx version. Its first line is the installed version, which matches the release the update reported.
To report whether a later version exists without installing anything, add --check:
ocx self update --checkVersion discovery always queries live. --frozen has no effect on it, and --offline skips the check instead of falling back to the local index. The freshest upstream ocx is the whole point. --remote is redundant because it is already the default, but OCX accepts it.
Alternatively, re-run the installer. It always fetches the most recent release:
curl -fsSL https://setup.ocx.sh/sh | shInvoke-RestMethod 'https://setup.ocx.sh/pwsh' | Invoke-ExpressionHow the update works
Section titled “How the update works”OCX is itself an OCX-managed package. The binary lives at $OCX_HOME/symlinks/ocx.sh/ocx/cli/current/content/bin/ocx. Unlike other packages, ocx self update only swaps the current symlink. It creates no candidate symlink for the new version.
Both ocx self update and ocx self update --check bypass the background throttle and always query the published index and registry live. The command considers only stable major.minor.patch release tags. It filters out rolling tags (1, 1.2), pre-releases (1.2.3-rc1) and build-tagged versions (1.2.3_build).
Downloading and activating a release are two separate steps. ocx self update pulls the new binary first. It then re-executes that binary as its own ocx self setup, which selects the release and rewrites every setup surface. That inner setup swaps current. The $OCX_HOME/symlinks/…/current/content/bin entry that ocx self activate puts on PATH picks up the new binary only once the hand-off reaches its select.
If the hand-off cannot finish, the download stands and current keeps naming the old binary. ocx self update then exits 75, and a stderr line says to run ocx self setup. A profile that carries edits OCX will not overwrite is the usual cause.
If the hand-off reaches the select but a later phase hits a snag, the update still counts as installed and exits 0. The binary you asked for is the one current names. The advisory names what is left to do.
Get notified of new releases
Section titled “Get notified of new releases”Two background checks run on an interactive terminal, outside CI, and online. One asks whether a later ocx exists. The other asks whether a tag pinned in a project’s ocx.lock has moved. Each runs at most once per interval, one day by default.
The check runs before your command and waits for one registry round trip. A failed check never fails a command.
When either check finds something, OCX prints one notice to stderr before your command’s output. Each toolchain lists at most three tools by name. The last line names the commands that show what moved:
ocx: updates available ocx 1.1.0, run `ocx self update` project (~/work/proj): cmake, ninja, uv and 6 more, run `ocx update` global: shellcheck, run `ocx --global update` details: `ocx update --check`, `ocx --global update --check`The [update] section of config.toml chooses what each check does. With no section, both checks print a notice at most once a day and install or rewrite nothing. Every key is optional:
[update]self = "apply"interval = "1d"| Key | Values (default notify) | Environment override |
|---|---|---|
self | notify prints a notice naming ocx self update. apply installs the later ocx after the command has finished, on success and failure alike, without changing its exit code. manual never checks and never touches the throttle state file | OCX_SELF_UPDATE |
toolchain | notify prints one stderr line per toolchain file with drift, naming ocx update (ocx --global update for the global toolchain). manual never checks. apply behaves as notify with one warning, so a value written for self does not break the file, because only ocx update moves a pin | OCX_TOOLCHAIN_UPDATE |
interval | \d+[smhd]? (bare digits are seconds, default 1d). 0 or 0s checks on every eligible command. Both checks share it | OCX_UPDATE_CHECK_INTERVAL |
The [update] reference lists the keys. Set OCX_NO_UPDATE_CHECK=1 to disable both checks. OCX also suppresses them in CI environments and when stderr is not a TTY.
Automatic updates
Section titled “Automatic updates”self = "apply" installs through the same path as ocx self update, so the trust policy that covers an explicit install covers this one. The new binary takes effect on the next run. Stderr gets one line that describes the outcome. If the install fails, the line says so and names ocx self update as the retry. OCX does not retry a failed apply until the next interval.
An ocx that ocx self setup did not install has no managed copy to replace, and apply does nothing for it.
What the toolchain check reads
Section titled “What the toolchain check reads”The toolchain check compares the platform digests recorded in the lock with what the registry serves and never writes the local index. A project toolchain is probed only when the project is consented. The global toolchain needs no consent. With no lock, a stale lock, a registry error or a check running past five seconds in total, the check stays silent.
Where the settings live
Section titled “Where the settings live”[update] is a personal preference, so OCX reads it from the local config.toml tiers only (system, user, $OCX_HOME, OCX_CONFIG and --config). The [managed] tier drops it before the merge, with a debug log. A fleet publisher therefore cannot switch on binary replacement for hosts that sync the payload. ocx.toml refuses the section: a project file with an [update] table fails to parse (exit 78) and the message says the section belongs in config.toml.
[update] never fails a command. OCX ignores an invalid or unknown value and falls back to the next source, then to the built-in default. A bad value in a config.toml prints one stderr warning that names the key. A bad value in an environment variable is logged at debug level.
Tiers merge field by field and the nearest wins. Each key’s environment variable beats the file, unlike the weakest-tier variables. The checks never run for ocx version, ocx about or ocx shell completion. The toolchain notice also skips the commands that move a lock.
The throttle state lives under $OCX_HOME/state/update-check/. It holds one zero-byte file for the ocx check (ocx_sh_ocx_cli) and one marker per toolchain under toolchain/, where the file’s modification time is the data. An interval of 6h or 90s is valid, while 1w and bogus are not, and OCX trims surrounding whitespace. Values are lowercase and case-sensitive, and an empty variable reads as unset.
The two update variables and the interval are not forwarded to child ocx processes. A package’s env or an ocx.toml [env] table cannot set them either, because OCX refuses them as reserved OCX_* keys. OCX_NO_UPDATE_CHECK is forwarded, so a --clean child keeps the checks off instead of probing a registry the parent was told not to contact.
Report a bug with build details
Section titled “Report a bug with build details”Run ocx version --verbose to capture the commit, build timestamp, target and CI run URL. For dev-channel builds the output also shows channel: dev.
Uninstall OCX
Section titled “Uninstall OCX”To remove ocx and all installed packages, delete the data directory. The default is ~/.ocx, or whatever OCX_HOME points to:
rm -rf "${OCX_HOME:-$HOME/.ocx}"Remove-Item -Recurse -Force $(if ($env:OCX_HOME) { $env:OCX_HOME } else { "$env:USERPROFILE\.ocx" })Then remove the managed activation that ocx self setup added to your shell. POSIX shells, Elvish and PowerShell get a fenced block that opens with # >>> ocx v1 <hash> >>> and closes with # <<< ocx <<<. Fish and Nushell get a dedicated file. Remove whichever applies:
- bash / zsh / sh / dash / ksh: delete the
# >>> ocx v1 … >>>…# <<< ocx <<<block from~/.profile,~/.bash_profile,~/.bashrc,~/.zprofileand~/.zshrc(whichever exist) - fish: delete
~/.config/fish/conf.d/ocx.fish - Nushell: delete
~/.local/share/nushell/vendor/autoload/ocx.nu - Elvish: delete the
# >>> ocx v1 … >>>…# <<< ocx <<<block from~/.config/elvish/rc.elv - PowerShell: delete the
# >>> ocx v1 … >>>…# <<< ocx <<<block from your$PROFILE - every platform: also remove the session-level
PATHregistration, with one location each and the exact commands, in Removing the session PATH by hand