Install-Channel Detection
Detection runs locally (no network) by combining the binary’s real path, the Go build metadata and the version stamp injected by the release CI:The Homebrew check runs first on purpose: the bottle installed by the tap is the same stamped asset published on the GitHub release, so only the
Cellar path distinguishes the two channels.Why source builds are never auto-updated
A locally compiled binary may carry uncommitted patches. Replacing it with a release artifact would silently destroy that work, so ChatCLI only prints the way forward:The /update Command
Bare/update is an explicit request: when a newer release exists on an automatable channel, it applies immediately — the same semantics as brew upgrade.
/update check reports the same status but never applies anything.
The command is also available from the interactive command palette and the tab completer, and /config update shows the resolved policy at any time.
Verified Self-Replace
When the binary came straight from a GitHub release, ChatCLI updates it in place with a hardened pipeline:- Downloads
checksums.txtfrom the target release. - Streams the platform asset to a staging file in the same directory as the binary (guaranteeing an atomic rename on the same filesystem) while computing its SHA-256.
- Refuses the install on any checksum mismatch — the download is discarded and the current binary is never touched.
- Swaps atomically: a plain rename on macOS/Linux (the running process keeps its old inode), or the rename-to-
.olddance on Windows with automatic rollback if activation fails. Leftover artifacts are cleaned on the next boot.
/usr/local/bin owned by root), the updater degrades to a copy-paste command:
Background Auto-Update (Staging)
SetCHATCLI_AUTO_UPDATE to control the boot-time behavior:
Auto mode uses staging, the same model as Claude Code: the running process is never restarted or interrupted. The new binary lands on disk while you work, and the next start opens on the new version — announced once on the welcome screen:
notify mode (the default) the welcome screen shows the invitation instead:
Homebrew is deliberately excluded from silent background updates.
brew upgrade takes Homebrew’s global lock and can trigger a full brew update; ChatCLI only drives it when you explicitly run /update. Concurrent ChatCLI processes coordinate through a lock file, so only one performs the background update.