Installation
The one-liner
Section titled “The one-liner”curl -fsSL https://agentarivm.com/install.sh | shThis is the recommended path on both macOS and Linux. It detects the platform and architecture, downloads the matching tarball, verifies it, and installs the agentarivm command. It never overwrites an existing configuration. It is not how you upgrade, though — re-running it moves the agentarivm command but leaves the running service on the old release, because the service definition records absolute versioned paths. agentarivm upgrade is the command for that.
Manual installation
Section titled “Manual installation”Grab the tarball for your platform from the download page:
https://dl.agentarivm.com/releases/latest/agentarivm-<platform>-<arch>.tar.gzwhere <platform> is darwin or linux and <arch> is arm64 or x64. Each tarball has a .sha256 checksum file next to it; verify before unpacking:
curl -fsSLO https://dl.agentarivm.com/releases/latest/agentarivm-linux-x64.tar.gzcurl -fsSLO https://dl.agentarivm.com/releases/latest/agentarivm-linux-x64.tar.gz.sha256sha256sum -c agentarivm-linux-x64.tar.gz.sha256 # shasum -a 256 -c on macOStar -xzf agentarivm-linux-x64.tar.gzPut the agentarivm command somewhere on your PATH, then run agentarivm init to write a starter configuration and agentarivm doctor to check the machine. init comes first: every other command validates the configuration at boot, so until that file exists there is nothing to run.
Prerequisites the installer does not install
Section titled “Prerequisites the installer does not install”The manager orchestrates tools you must set up yourself, because each involves an account or a credential:
-
gh— authenticate withgh auth loginas the account the manager should act as. Everything the manager does on GitHub happens under this identity. Pin it in the config (github.expectedAccount) so a wrong login is refused at boot rather than silently doing everything under the wrong name. -
At least one agent engine — Claude Code, Codex, or both. Each needs its own credential, installed into the manager rather than left in your shell: the agents inherit the manager’s environment and nothing else’s.
Claude Code. Generate a subscription credential with
claude setup-tokenand install it withagentarivm agent-token install, which reads it from stdin only, never from an argument, so it never lands in shell history:Terminal window claude setup-tokenpbpaste | agentarivm agent-token installIt refuses an
sk-ant-api…API key on purpose: an API key bills pay-as-you-go credits and outranks the subscription token in Claude Code’s precedence, so installing one is worse than installing nothing.Codex. Two doors, and the subscription is the one to prefer — it spends ChatGPT plan quota instead of metered API credits:
Terminal window agentarivm engine-login codex # device code, entered in any browserpbpaste | agentarivm agent-token install --engine codex # or an OpenAI API key, stdin onlyengine-loginprints a code and waits; you enter it in a browser on any machine, which is what makes it work on a headless box. The credential lands in the manager’s ownCODEX_HOME(~/.config/agentarivm/codex), isolated from any personal~/.codexlogin, and Codex refreshes it from then on. If both a login and an API key exist, the login wins —agentarivm doctorreports the shadowed key rather than letting the difference show up on a bill.Configure the engines you installed in
engines:— an entry existing is what enables one.agentarivm initwritesengines.claude.executableas an absolute path resolved from your ownPATH; keep every engine’s path absolute, because a daemon’s PATH will not find a bare name. See the configuration reference.
Running as a service
Section titled “Running as a service”A manager that only runs while a terminal is open is not a manager. agentarivm service generates and loads the right unit for the platform:
agentarivm service install # write the service definition and (re)load itagentarivm service status # loaded? running? what was the last exit?agentarivm service uninstall # unload it and remove the definitionservice install --dry-run prints the definition and touches nothing.
macOS: launchd
Section titled “macOS: launchd”service install writes a LaunchAgent at ~/Library/LaunchAgents/com.agentarivm.manager.plist and loads it. The job is KeepAlive — launchd restarts the manager if it crashes — and RunAtLoad, so it starts when the user logs in.
Two macOS realities worth knowing up front:
- A LaunchAgent needs its user logged in. After a reboot with FileVault on, nothing runs until the disk is unlocked and the user logs in. For a machine that reboots rarely, this is fine; the alternatives (a LaunchDaemon, or disabling FileVault) trade away either simplicity or disk encryption.
- launchd gives jobs a minimal PATH. This is the single most common deployment failure — see Troubleshooting.
Linux: systemd user units
Section titled “Linux: systemd user units”On Linux, service install manages a systemd user unit — the manager runs as your user, not as root, matching the security model. The usual commands apply:
systemctl --user status agentarivmjournalctl --user -u agentarivmBy default, systemd user units only run while that user has a session. On a headless box where nobody logs in, enable lingering once:
sudo loginctl enable-linger <user>With lingering on, the user’s units start at boot and keep running with no login — which is exactly what an always-on manager wants.
Upgrading
Section titled “Upgrading”agentarivm upgradeIt fetches the release manifest, tells you what would change, installs the new version beside the current one and switches a symlink, then reinstalls the service so the daemon runs the new code. Every other command prints a one-line notice when a newer release exists, so you find out without having to check.
It stops before doing anything in three cases:
- A task is running. Upgrading restarts the manager, so it refuses rather than interrupting work in flight. Wait, or
--force. - Your configuration would not load in the new version. The new binary is asked before the switch, not after, so a release that renamed a setting is a refusal with nothing changed instead of a manager that will not start.
- The API contract changes in a way that breaks your phone. The app ships separately, through a store, so a manager can move to a contract an installed app does not speak. That needs a yes; a merely additive change does not, and says so.
Re-running the installer also works and does the same download — but it does not reinstall the service, so the daemon keeps running the old release until you run agentarivm service install yourself. Prefer agentarivm upgrade.
What an upgrade keeps
Section titled “What an upgrade keeps”agentarivm upgrade installs beside the current version rather than over it, and regenerating the service definition no longer means losing what is in it:
- The Claude credential you installed with
agentarivm agent-token installis carried across. So is anything else you added to the job’s environment. - Your config is migrated if the new release needs it, and the previous copy is kept beside it as
agentarivm.yml.before-<version>. If the new build cannot read your config even after that, the upgrade stops with nothing changed. - The previous version stays on disk, so the switch is a symlink move and the rollback is one too.
One thing is not kept: keys you hand-added to the launchd plist yourself, outside EnvironmentVariables. service install names them as it drops them, so you can put them back.
With or without sudo
Section titled “With or without sudo”The installer never asks for admin, and neither does anything else by default. Everything lives under your home directory, and the blast radius is one account — which is what makes curl … | sh reasonable, and what lets Agentarivm run on a managed Mac where you are not an admin at all.
Sudo decides, and nothing else does. There is no flag to opt in:
agentarivm service install # a service that is yourssudo agentarivm service install # a service the machine startsA system service still runs as a person, never as root — UserName on macOS, User= on Linux, taken from SUDO_USER. If the account that owns the manager cannot sudo itself (the usual shape for a dedicated agent account), name it:
sudo agentarivm service install --user agent --config /Users/agent/.config/agentarivm/agentarivm.ymlWhat each gives you
Section titled “What each gives you”| without sudo | with sudo | |
|---|---|---|
| macOS | LaunchAgent in ~/Library/LaunchAgents. Starts at login, dies with the session. |
LaunchDaemon in /Library/LaunchDaemons. Starts once the disk is unlocked, with nobody logged in. |
| Linux | systemd user unit in ~/.config/systemd/user. Starts with your session. |
systemd system unit in /etc/systemd/system. Starts at boot. |
| Windows (WSL2) | as Linux | as Linux, but see below |
Later upgrade |
no sudo | needs sudo — it rewrites a root-owned definition |
Later agent-token install |
no sudo | no sudo — the credential lives in its own file, not in the service |
The macOS/Linux asymmetry
Section titled “The macOS/Linux asymmetry”On Linux you probably do not want sudo at all. A user unit plus lingering already starts at boot and keeps running with nobody logged in:
sudo loginctl enable-linger <user>That is one privileged command, once. Every file stays owned by you, and agentarivm upgrade never needs root. A system unit exists for people who want the manager administered like any other system service — not because Linux needs it.
macOS has no equivalent. A LaunchAgent fundamentally requires a login session, so surviving a reboot means either a LaunchDaemon (and sudo for every upgrade thereafter), or arranging for the manager’s account to be the one that logs in. With FileVault, whoever unlocks the disk at boot is logged in — so if that account is the one running Agentarivm, its LaunchAgent starts and nothing else is needed.
Windows
Section titled “Windows”WSL2 does not boot with Windows. Even a system unit will not start until the distribution is running, so keep it up with Task Scheduler at logon — see Windows via WSL2.
Which one is installed
Section titled “Which one is installed”agentarivm service status looks for both and says scope system when it finds one. Asking without sudo about a system service names it and tells you to use sudo, rather than reporting that nothing is installed.
Uninstalling
Section titled “Uninstalling”agentarivm uninstallStops and removes the service, every installed release, and the agentarivm command.
It keeps your data: the configuration, the database, the device CA and the logs stay exactly where they are, and it prints the paths. Reinstalling later picks up an unchanged machine, with paired phones still paired.
It never touches your repositories or worktrees — with or without --purge. Those are your code; the uninstaller prints where they are and leaves them alone.
To remove the data too:
agentarivm uninstall --purge--purge asks a different question — it names the config, database and CA in the prompt itself — because “remove the program” and “destroy the CA that pairs your phones” answered by the same reflex is how people lose things.
That destroys the device CA, which un-pairs every device: the certificates on your phones stop being trusted, and re-pairing is a fresh QR scan. It asks before doing any of it — add --yes in a script.
If the installation is too broken to run its own command — a runtime that will not start, a half-extracted release — the script is still reachable directly:
curl -fsSL https://agentarivm.com/uninstall.sh | shIt is the same script agentarivm uninstall runs; the command just finds the copy that shipped with your release.
The one thing it leaves behind on purpose is the export PATH="$HOME/.local/bin:$PATH" line the installer suggested for your shell profile. It is harmless, and yours to remove.