Skip to content
Alpha — private preview. Expect rough edges and breaking changes between releases.

Installation

Terminal window
curl -fsSL https://agentarivm.com/install.sh | sh

This 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.

Grab the tarball for your platform from the download page:

https://dl.agentarivm.com/releases/latest/agentarivm-<platform>-<arch>.tar.gz

where <platform> is darwin or linux and <arch> is arm64 or x64. Each tarball has a .sha256 checksum file next to it; verify before unpacking:

Terminal window
curl -fsSLO https://dl.agentarivm.com/releases/latest/agentarivm-linux-x64.tar.gz
curl -fsSLO https://dl.agentarivm.com/releases/latest/agentarivm-linux-x64.tar.gz.sha256
sha256sum -c agentarivm-linux-x64.tar.gz.sha256 # shasum -a 256 -c on macOS
tar -xzf agentarivm-linux-x64.tar.gz

Put 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 with gh auth login as 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-token and install it with agentarivm agent-token install, which reads it from stdin only, never from an argument, so it never lands in shell history:

    Terminal window
    claude setup-token
    pbpaste | agentarivm agent-token install

    It 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 browser
    pbpaste | agentarivm agent-token install --engine codex # or an OpenAI API key, stdin only

    engine-login prints 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 own CODEX_HOME (~/.config/agentarivm/codex), isolated from any personal ~/.codex login, and Codex refreshes it from then on. If both a login and an API key exist, the login wins — agentarivm doctor reports 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 init writes engines.claude.executable as an absolute path resolved from your own PATH; keep every engine’s path absolute, because a daemon’s PATH will not find a bare name. See the configuration reference.

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:

Terminal window
agentarivm service install # write the service definition and (re)load it
agentarivm service status # loaded? running? what was the last exit?
agentarivm service uninstall # unload it and remove the definition

service install --dry-run prints the definition and touches nothing.

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.

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:

Terminal window
systemctl --user status agentarivm
journalctl --user -u agentarivm

By default, systemd user units only run while that user has a session. On a headless box where nobody logs in, enable lingering once:

Terminal window
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.

Terminal window
agentarivm upgrade

It 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.

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 install is 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.

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:

Terminal window
agentarivm service install # a service that is yours
sudo agentarivm service install # a service the machine starts

A 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:

Terminal window
sudo agentarivm service install --user agent --config /Users/agent/.config/agentarivm/agentarivm.yml
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

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:

Terminal window
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.

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.

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.

Terminal window
agentarivm uninstall

Stops 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:

Terminal window
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:

Terminal window
curl -fsSL https://agentarivm.com/uninstall.sh | sh

It 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.