Expand description
Where provider CLIs (claude, codex, …) are installed, shared by every
resolver: resolvecli, install.start / install.check, agent.open’s
launch path and the picker’s read-only lookup.
Shared, keyed by pinned CLI version:
<shared_dir>/cli/<provider>/<pinned_version>/. The install used to live
in <home>/instances/v<AGENTMUX_VERSION>/cli/<provider>/, i.e. inside the
AgentMux version dir, so every upgrade, portable or dev build started
with no CLI and the first open of each provider ran a blocking
npm install of the very same pinned CLI (~3 s, 16 times in a week of
logs — SPEC_AGENT_OPEN_LATENCY_2026_09_27.md F1). The CLI’s identity is its
pinned version, not AgentMux’s, so that is the key now.
Legacy fallback (read-only): an existing per-version install still resolves, so nothing breaks for a version that already has one; new installs always go to the shared dir.
Cross-instance safety: the shared dir is written by every AgentMux
instance on the machine, so installs into it serialize on an exclusive
lock file (<provider>/<pinned_version>.lock, blocking, both platforms —
the same primitive the agent registry uses) and re-check for a finished
install after acquiring it, so a second instance waits and then reuses
the first one’s result instead of running npm into the same directory.
A shared dir only counts as installed once COMPLETE_MARKER is written,
after npm succeeded and the shim was verified; an unmarked dir (a failed or
in-progress install), or a marked one whose shim is gone, is cleared —
marker and all — before the next attempt.
install.start waits for the lock with try_lock_install so the wait
stays cancellable.
Structs§
- Install
Guard - Held for the duration of an install into a shared dir; dropping it
releases the lock.
Noneinside for the legacy (per-instance) dir, which needs no cross-instance lock. - NpmInstall
Request - What to install:
npm_package@pinned_version, whose shim iscli_command. - NpmRun
- What
npm installproduced.
Enums§
- Ensure
Error - Why
ensure_installeddid not hand back a CLI. - Install
Error - Install
Outcome
Constants§
- AGENTMUX_
VERSION 🔒 - COMPLETE_
MARKER - Written into a shared install dir only after npm succeeded and the shim was
verified, under the install lock. npm creates
.binshims before its lifecycle scripts and the rest of the install finish, so a shim alone doesn’t mean “installed” — a reader could otherwise run a CLI another instance is still installing, and a failed install’s leftover shim would poison the shared cache for every later AgentMux version (Codex P2 on #3927). - WARM_
INSTALL_ DELAY - How long after srv start the warm-up begins: after the first IPC traffic, well before most users open an agent.
Functions§
- clear_
unless_ valid - Under the install lock, before (re)installing into
dir: unless it holds a valid install, remove it entirely — leftovers of a failed or interrupted install, and a stale completion marker whose shim is gone. Removing the marker is the point: a repair must not run with the old marker visible, or readers would accept the half-repaired install as soon as npm recreates the shim, and a failed repair would leave marker + shim accepted indefinitely (Codex P2 on #3927, second pass). No-op for a missing or valid dir. - ensure_
installed ensure_installed_withrunning the real npm install.- ensure_
installed_ with - The pinned CLI for a provider whose install is missing: install it, waiting
up to
wait.installis injected so tests don’t need npm. - find_
installed - The installed CLI binary, if any: the shared dir (only once marked complete), then the legacy per-version dir (which predates the marker, so its shim is enough).
- find_
installed_ for_ provider - Same, with the pinned version taken from the backend provider registry (the source of truth) rather than a caller-supplied string.
- install_
dir - The directory new installs go to: the shared dir when the provider is pinned, else the legacy one.
- install_
pinned_ cli - Install
reqinto its install dir, blocking — call it fromspawn_blockingor a plain thread. The one install routine forresolvecliand the startup warm-up (warm_used_providers): - install_
pinned_ cli_ with install_pinned_cliwith the npm runner injected (tests).- is_
complete - Whether
dirholds a finished, verified install. - is_
safe_ 🔒provider_ component - Same rule for the provider id, which is also a path component.
- is_
safe_ version_ component - A pinned version string is used as a path component, so it must be a
plain version: letters, digits and
.,-,_,+, no.., bounded. Anything else (including empty — an unpinned provider) has no shared dir and falls back to the legacy per-version location. - is_
valid_ install - Whether
dirholds a usable install: marked complete AND its shim is still there. A marker alone isn’t enough — a finished install can lose its shim later (corruption, antivirus cleanup). - legacy_
cli_ dir - The pre-2026-09-27 per-AgentMux-version location, kept for read-only fallback and for unpinned providers.
- lock_
install - Take the cross-instance install lock for
dirwhen it is a shared dir. Blocks until any other instance’s install into the same dir finishes — call it from a blocking context (spawn_blocking). The lock file sits next to the dir and is never deleted (deleting a locked file races waiters onto a different inode; seeregistry::leases::CriticalSection). - mark_
complete - Mark
dircomplete (write-then-rename, so a reader never sees a torn marker). Call under the install lock, after verifying the shim. - npm_bin
<dir>/node_modules/.bin/<cli>—.cmdon Windows, where npm writes a batch shim.- npm_
registry_ 🔒args - Registry flags for installing
package. AgentMux’s own packages (@agentmuxai/*) are published to the public npm registry, but a machine can route that scope elsewhere in its.npmrc(a@agentmuxai:registry=https://npm.pkg.github.comline, for internal packages), and the install then 404s. The flag pins the scope for this one command only; other packages use the user’s config as before. - open_
lock_ 🔒file - The shared dir’s lock file, opened (created if missing); None for a provider/pin with no shared dir.
- providers_
needing_ install - The npm-installed providers among
provider_idswhose pinned CLI has no install yet, deduplicated, in first-seen order. Pure over the registry and the filesystem. - run_
npm_ 🔒install - Run
npm install --prefix <dir> <package>to completion.packageis one or more space-separatedname@versionspecs. - shared_
cli_ dir <shared_dir>/cli/<provider>/<pinned_version>/, or None when either component isn’t safe to use as a path segment.- try_
lock_ install - Non-blocking
lock_install:Ok(None)while another instance holds the lock. For waiters that must stay cancellable (install.startpolls this and racesinstall.cancel, Codex P2 on #3927). - warm_
used_ providers - SPEC_AGENT_OPEN_LATENCY_2026_09_27.md §4.1: install the pinned CLI of every
provider the user’s agents use, in the background, so the first open
after a pin bump doesn’t wait on npm. Only providers in
provider_ids(the user’s own agent definitions — not every template’s), only pins with no install yet, one at a time, npm below normal priority. An open that arrives mid-install waits on the same lock and then reuses the result. Failures (no npm, offline) are logged and left for the open to report.