Apus ships four update channels:
- stable: npm dist-tag
latest. Recommended for most users. - extended-stable: npm dist-tag
extended-stable. A net-new, trailing supported-month package channel. It is package-only, and installation is foreground-only. It receives read-only update hints whenupdate.checkOnStartis enabled, including direct final extended-stable package installs, but never applies automatically. - beta: the newest version by semantic version order from the npm
betaandlatestdist-tags. An older beta tag never replaces a newer stable release. - dev: moving head of
main(git), including when switching from a package install.mainis for experimentation and active development; it may contain incomplete features or breaking changes. Do not run it for production gateways.
Stable builds usually ship to beta first, get vetted there, then get
promoted to latest without a version bump. Maintainers can also publish
directly to latest. Dist-tags are the source of truth for npm installs.
Switching channels
apus update --channel stable
apus update --channel extended-stable
apus update --channel beta
apus update --channel dev
--channel drives the update and persists the choice to update.channel in
config after core update success. A refused or failed core update keeps the
previous channel. The selected channel drives both install paths:
| Channel | npm/package installs | git installs |
|---|---|---|
stable |
dist-tag latest |
switches to the npm package at latest |
extended-stable |
resolves the public npm extended-stable selector, verifies the exact selected package, and installs that exact version. Fails closed with no fallback to latest, beta, or dev. |
unsupported: Apus leaves the checkout unchanged and asks you to use a package installation |
beta |
dist-tag beta, falling back to latest when beta is missing or older |
switches to the npm package at beta, falling back to latest when beta is missing or older |
dev |
switches to a Git checkout, builds it, and reinstalls the global CLI | fetches, rebases the checkout on the upstream main branch, builds, and reinstalls the global CLI |
An explicit --channel stable or --channel beta switches a Git installation
to a package installation. A bare apus update in a Git checkout with a
previously stored stable or beta channel instead selects the corresponding Git tag.
For these Git tag updates, Apus refreshes branches without adding force to
their configured refspecs, then force-refreshes tags only from the release remote.
The retained branch.main.remote setting takes precedence, followed by origin
or the only configured remote. With multiple remotes and neither choice, set
branch.main.remote to the remote that publishes releases before retrying.
Recreated release tags replace their old copies; local-only tags are preserved.
Tag pruning is disabled even when Git's fetch.pruneTags setting is enabled.
These guarantees assume standard branch fetch mappings; custom remote.*.fetch
mappings that explicitly include tags still follow Git's configured behavior.
The normal CLI inspects these refs in a private repository before admitting an
update, so a refused update leaves the installed checkout's refs unchanged.
For managed Gateways, successful switches refresh the service to the verified installation before checking readiness. A refused switch or verified rollback recovers the previous service; unverified recovery leaves it stopped for inspection.
For dev git installs, the default checkout is ~/apus (or
$APUS_HOME/apus when APUS_HOME is set); override with
APUS_GIT_DIR.
Automatic update campaigns pin the upstream commit they announce, so the
displayed list previews up to five commits from the exact target installed even
if main advances during the countdown. A manual
apus update --channel dev still targets the current upstream main.
To keep stable and dev in parallel, use two separate checkouts and point each gateway at its own.
One-off version or tag targeting
Use --tag to target a specific dist-tag, version, or package spec for a
single update without changing the persisted channel:
# Install a specific version
apus update --tag 2026.4.1-beta.1
# Install from the beta dist-tag (one-off, does not persist)
apus update --tag beta
# Switch to the moving GitHub main checkout (persistent)
apus update --channel dev
# Install a specific npm package spec
apus update --tag apus@2026.4.1-beta.1
Notes:
--tagapplies to package (npm) installs only; git installs ignore it.- The tag is not persisted; the next
apus updateuses the configured channel. - A package install with stored
update.channel: "dev"still honors a one-off--tagwithout switching to Git. An explicit--channel devtakes precedence over--tagand selects the Git checkout flow. - The
--tag mainshorthand is rejected for package installs because the workspace checkout is not a self-contained package artifact. Useapus update --channel dev(package installs switch to a git checkout) or reinstall with the installer's git method:curl -fsSL https://ami-docs.dev.apuscorp.com/install.sh | bash -s -- --install-method git --version main. - Downgrade protection: if the target version is older than the current
version, Apus prompts for confirmation (skip with
--yes). - Extended-stable always uses its verified exact package target. It is not a
one-off alias for
--tag extended-stable, and--tagcannot be combined with an effective extended-stable channel. --channel betadiffers from--tag beta: the channel flow can fall back to stable/latest when beta is missing or older, while--tag betaalways targets the rawbetadist-tag for that one run.
Dry run
Preview what apus update would do without making changes:
apus update --dry-run
apus update --channel beta --dry-run
apus update --tag 2026.4.1-beta.1 --dry-run
apus update --dry-run --json
The dry run reports the effective channel, target version, planned actions, and whether a downgrade confirmation would be required.
Plugins and channels
Switching channels with apus update also syncs plugin sources:
devswitches installed plugins that have a bundled counterpart back to their bundled (git checkout) source.stableandbetarestore npm-installed or ClawHub-installed plugin packages.extended-stableresolves eligible official npm plugins with bare/default orlatestintent to the exact installed core version. It does not query plugin@extended-stabletags at runtime. Version-bound runtime plugins use the base release cohort for correction versions (for example,YYYY.M.P-2uses pluginYYYY.M.P).- npm-installed plugins are updated after the core update completes.
betauses the same newest-of-beta/latestrule for managed npm plugins, including official plugins such as@openclaw/codex. Exact version and range pins retain their selector. Startup repair keeps an already-current plugin instead of reinstalling it and requiring another restart.
Checking current status
apus update status
Shows the active channel (with the source that decided it: config, git tag,
git branch, installed version, or default), install kind (git or package),
current version, and update availability.
It also shows the last recorded update run, including a failed fetch. Plain
apus status uses cached Git refs without fetching. If the latest recorded
update fetch in the current state directory failed, it shows
update check stale: last update fetch failed with the failure's age and a short
reason instead of up to date. Ahead/behind counts are labeled cached.
A later update run with a completed fetch clears the warning, even if the rest
of the update is skipped, fails, or rolls back. A manual git fetch does not
clear the recorded warning. Use apus update status for a fresh availability
check or run apus update again. apus status --deep also fetches for
that check, without changing the ledger.
Tagging best practices
- Tag releases you want git checkouts to land on:
vYYYY.M.PATCHwith patch1through32for regular stable,vYYYY.M.PATCH-beta.Nfor beta. Named prerelease suffixes such as-alpha.N,-rc.N, and-next.Nare not stable or beta targets. - Legacy numeric stable tags such as
vYYYY.M.PATCH-1andv1.0.1-1are still recognized as stable git tags for compatibility, except monthly patches33and higher. Those patches are reserved for extended-stable; final tags and numeric correction variants are never regular stable targets or beta's stable fallback. Extended-stable remains a package-only update channel. vYYYY.M.PATCH.beta.N(dot-separated) is also recognized for compatibility; prefer-beta.N.- Keep tags immutable: never move or reuse a tag.
- npm dist-tags remain the source of truth for npm installs:
latest-> stableextended-stable-> trailing supported-month package releasebeta-> candidate build or beta-first stable builddev-> main snapshot (optional)
macOS app availability
Beta and dev builds may not include a macOS app release. That is fine:
- The git tag and npm dist-tag can still publish on their own.
- Call out "no macOS build for this beta" in release notes or changelog.
Related
- Updating
- Installer internals
- Release policy - how releases are cut and published into these channels