How-to: self-update
Keep the crm CLI current. See the CLI reference for every flag.
Check for a newer release
crm self-update --check
--json it emits the standard envelope (data.current, data.latest,
data.update_available); if the release server is unreachable it returns a clean
error envelope rather than hanging or crashing.
Upgrade a frozen binary in place
crm self-update
SHA256SUMS (the same integrity check
the install script uses), and swaps the bundle in place — the crm launcher on
your PATH keeps working. A checksum mismatch or download failure leaves the
existing install untouched and exits non-zero.
For pip / uv / source installs, self-update does not touch the binary and
points you at pip install -U crm (or re-running uv tool install).
Keeping installed skills in sync
Every non---check self-update re-syncs the agent skills you installed with
crm skill install, so the shipped SKILL.md never lags the CLI. It
reads the install registry (${CRM_HOME:-~/.crm}/installed-skills.json) and, for
each recorded destination whose version is stale, re-copies the bundled skill
tree. This fires on both install types — after a frozen bundle swap, and on a
pip/uv install once the upgraded wheel is in place.
The per-destination outcome is reported under data.skills (a list of
{dest, from_version, to_version, status}, status ∈ refreshed | skipped |
pruned | error):
- refreshed — the skill was re-copied to the current version.
- skipped — already current; no copy.
- pruned — the folder was deleted out-of-band, so its registry entry is dropped (the folder is not recreated).
- error — copying that destination failed (e.g. permissions); the entry is kept for a later retry.
A skill-refresh failure never aborts the binary update — the command still
reports ok:true when the upgrade itself succeeded.
The passive update notice
On an interactive terminal, crm checks at most once every 24 hours whether a
newer release exists and prints a one-line notice on stderr after a command
finishes — at most once per 24 hours (tracked via notified_at in the cache),
so it does not reprint on every command. A newly discovered version resets that
gate so the new release is surfaced promptly. The probe runs in the background
and never delays a command.
It is silent — and skips the network entirely — in any of these cases:
--jsonoutput mode (machine-readable output is never polluted),- stderr is not a terminal (pipes, redirects, agents),
- the
CIenvironment variable is set, - the
CRM_NO_UPDATE_CHECKenvironment variable is set, - the command being run is
self-updateitself (it owns its own update messaging; the running process still reports the pre-update version, so the notice would otherwise tell you to upgrade to the release you just installed).
Set CRM_NO_UPDATE_CHECK=1 to opt out permanently:
export CRM_NO_UPDATE_CHECK=1
The last check result is cached under ${CRM_HOME:-~/.crm}/update-check.json.