Updating the CLI
How to update the ch CLI manually, how the device server keeps itself up to date automatically, and how to diagnose a device that's stuck on an old version.
There are two ch binaries to keep in mind: the one installed on your own machine (used for the CLI), and the one inside each running device server (which manages itself). This page covers both.
Check your current version
ch --version
ch version and ch -v do the same thing. This prints the installed version (and build commit for stamped releases).
Update manually
Run ch self-update to download and install the latest release in one step:
ch self-update
Note:
ch updateis not a valid command. If you type it by mistake, the CLI will suggestch self-updatefor you.
CodeHerder downloads the new binary for your platform, verifies it by SHA-256, and atomically replaces your existing ch binary. If you are already on the latest version, the command says so and exits.
Updating your machine’s ch does not update running device servers. Each device server manages its own binary independently. After a successful update, ch prints a reminder: “Any running ch device-server will auto-restart on its next update check.”
Check for an update without applying it
ch self-update --check
Reports the installed version versus the latest available, then exits with code 0 if you are up to date or non-zero if a newer version is available. No changes are made to your binary. Unlike a plain ch self-update, --check reports this even from an unstamped dev build — it never needs --force.
This exit-code contract makes it straightforward to use in CI or a cron job:
# Example: daily cron that alerts when ch is behind
# 0 9 * * * /usr/local/bin/ch self-update --check || echo "ch update available — run ch self-update"
ch self-update --check
if [ $? -ne 0 ]; then
echo "ch is behind the latest release."
fi
Add --json to get the same result as a machine-readable current/available/needsUpdate/updated object instead of exit-code-only — see Using the ch CLI for the JSON conventions every command shares.
Update a dev build
If you built ch from source, it is an unstamped dev build. ch self-update refuses to replace an unstamped build by default. Pass --force to override:
ch self-update --force
The device server keeps itself current automatically
When you run ch device-server, auto-update is on by default. Roughly once an hour, the server checks whether a newer ch release is available. When it finds one, it downloads and verifies the binary and then restarts itself with the new version.
By default, in-flight agent sessions are not interrupted. The device server detaches any running agent processes before it restarts, and the new process adopts them automatically. Tasks continue without any action from you. Start the device server with --kill-agents-on-shutdown (or set CH_DS_KILL_ON_STOP=1) if you’d rather it stop running agents on any shutdown or restart — including one triggered by auto-update — instead of carrying them across.
Scope: auto-update keeps only the device server’s own ch binary current — it does not change the agent harness (for example, the Claude Code installation the agent uses to do its work).
If a device is stuck on an old version
A few situations commonly strand a device behind the latest release. None of them need you to watch closely — each is either self-healing or a one-line fix:
- A
chbuilt from source never auto-updates. If you’re running an unstamped dev build, the device server’s auto-updater skips its check entirely, and the Version current readiness check (see Managing your devices) reports healthy rather than warning — there’s no separate signal telling you it’s behind. Install a releasedchbinary on that machine, or runch self-update --force, then restart the device server. - Restarting the device server does not, by itself, pull a newer version in immediately. The auto-updater’s first check happens a full interval after startup, not right away — so on the default hourly cadence, a fresh restart can be up to an hour away from checking. To move a device onto a new version right now: run
ch self-update(add--forceon a dev build) to replace the binary on disk, then restartch device-server— it starts up already on the new version. - The update needs write access to the directory the
chbinary lives in, since both manual and automatic updates replace it in place. Ifchis installed somewhere only another account can write to, a manualch self-updatereports the failure directly; the device server’s background updater instead logs a warning and quietly retries at the next check. Installchsomewhere your own user owns, or run the update as the account that owns the install directory. - A failed check is not something to worry about. A transient failure — a network blip, or a brief mismatch right after a new release goes out — is retried automatically, several times, within the same check window. If every retry in that window still fails, the device server keeps running its current binary and tries again at the next interval; no session is lost and nothing needs your attention.
- A laptop that’s asleep through a check doesn’t miss its turn. The device server tracks wall-clock time rather than a fixed timer, so it picks the check back up within about a minute of the machine waking.
- On a proxied network, both
ch self-updateand the device server’s auto-updater fetch releases over HTTPS and honor the standardHTTPS_PROXYandNO_PROXYenvironment variables in whatever environment the command runs in.HTTP_PROXYhas no effect here, since the download itself is always HTTPS.
Tuning or disabling auto-update
Pass these flags when starting the device server:
| Flag | Default | Description |
|---|---|---|
--auto-update=false |
on | Disable automatic updates entirely. |
--auto-update-interval <duration> |
1h |
How often to check for a newer version. |
The same settings are available as environment variables — convenient when the device server runs as a background service:
| Variable | Description |
|---|---|
CH_DS_AUTO_UPDATE=0 |
Disable automatic updates. |
CH_DS_AUTO_UPDATE_INTERVAL=<duration> |
Override the check cadence (e.g. 6h). |
Examples:
ch device-server --auto-update-interval 6h # check every six hours
ch device-server --auto-update=false # never auto-update
For the full ch device-server reference, see Managing your devices.
Related guides
- Managing your devices — device health and troubleshooting an Offline device
- Running the device server as a service — tune auto-update under a service manager
- Monitoring your agents — watch fleet health after an update
