Rivets
Documentation

Background service

A standalone worker normally runs as a background service, so it keeps running after you close the terminal and starts again after a restart. The service runs as your user, needs no administrator rights, and opens no listening ports.

Install the service

You usually do not need to install it yourself. The one-line installer from Add worker and rivets connect both save the connection and start the service. See Connect a worker.

To reinstall the service from the saved connection, for example after you stopped or uninstalled it:

rivets install

install is safe to run again. It only updates service definitions that Rivets created, and it leaves unrelated files alone. If the service is already running, it restarts it with the current settings, but only while the worker is idle (see Idle protection). If creating or starting the service fails, Rivets restores the previous definition and state.

The service runs rivets run, the same foreground worker you can start by hand. The token is never written into the service definition. The worker reads ~/.rivets/config.json at start and loads the token from the OS credential store.

Service types

Platform Service Location
macOS User LaunchAgent ~/Library/LaunchAgents/com.rivets.worker.plist
Linux systemd user unit ${XDG_CONFIG_HOME:-~/.config}/systemd/user/rivets-worker.service
Windows Task Scheduler task named Rivets Worker, runs at logon Task and runner files under ~/.rivets/service

Windows uses Task Scheduler rather than a Windows Service because the worker needs your signed-in CLI credentials and your developer tools on PATH.

On macOS and Linux, the service does not read your shell’s startup files. It runs with a fixed PATH: ~/.bun/bin, ~/.local/bin, ~/.cargo/bin, /opt/homebrew/bin, /usr/local/bin, /usr/bin, /bin, /usr/sbin, and /sbin. If claude, codex, or a tool your scripts need is installed somewhere else, for example by a Node version manager, link it into ~/.local/bin so the service can find it. rivets doctor run from your shell can find tools the service cannot, so check Settings › Workers to see which agents the worker offers.

A session to run in

A per-user service needs a user session, and install says so plainly when there is none:

  • macOS needs someone logged in to the desktop. On a Mac you reach only over SSH, such as a headless Mac mini, turn on automatic login in System Settings › Users & Groups and restart. Automatic login also unlocks the keychain that holds the token.
  • Linux needs a systemd user manager. Containers and sudo shells have none. Run the worker there with rivets run under your own supervisor, or install it while logged in as the user who should run it.

On Linux, a user’s services normally stop when they log out. install turns on lingering (loginctl enable-linger) so the worker keeps running. Where the distribution does not let a user do that, install and rivets status print the sudo loginctl enable-linger <user> command to run.

Commands

Command What it does
rivets connect Save the connection and install, or update, and start the service.
rivets install Install, or safely update, and start the service from the saved connection.
rivets status Show the connection, the service state, and the worker’s health.
rivets restart Restart only when the worker is idle.
rivets logs Print a redacted, bounded tail of the service log.
rivets stop Stop the service when idle and keep it from starting at login. It stays installed.
rivets uninstall Stop and remove the Rivets-managed service when idle.

Status

rivets status reports whether the service is installed, enabled, and running, plus the worker’s health: protocol compatibility, last heartbeat, active jobs, open terminals and previews, events waiting to be delivered, and any degraded reason. If the worker restarted after an error in the last day, it shows that too. On Linux it also says whether the worker keeps running after you log out.

The worker refreshes this health snapshot every 30 seconds and on every meaningful change. A snapshot older than two minutes is reported as stale.

rivets status --json prints only the service state and health, as a JSON object.

Stop and start again

stop stops the service and disables it at login, but keeps the definition in place. Run install to start it again. On macOS this avoids the “App Background Activity” notification that re-creating a LaunchAgent would trigger each time.

Uninstall

uninstall removes only the service definition (and on Windows, its runner). The saved connection, logs, signing keys, repositories, worktrees, and health history are kept, so rivets connect or rivets install sets the service up again. To remove everything, see Cleaning up.

Idle protection and –force

install (when a service is already running), restart, stop, and uninstall refuse to interrupt work. If the worker’s health shows active jobs, terminals, or previews, or events still waiting to be delivered, they stop and say what is running.

They only trust a fresh health snapshot. If the snapshot is missing or stale, there is no running worker reporting work to protect, so they go ahead. This lets you repair or remove a service that never started without --force.

Pass --force when you intend to interrupt active work:

rivets restart --force

Logs

rivets logs --lines 200

--lines defaults to 100 and is capped at 1,000. Log lines are redacted when written and again when printed: bearer tokens, worker tokens, credential URLs, and the configured token are stripped.

The combined log is ~/.rivets/logs/worker.log and rotates to worker.log.1. worker.out.log and worker.err.log capture anything the service manager writes directly, such as a crash before logging starts.

Several workers on one machine

Each worker home is its own worker with its own service. Set RIVETS_HOME to run another worker from a different directory:

RIVETS_HOME=~/rivets-second rivets connect --token-stdin

The default home, ~/.rivets, uses the names in Service types. Any other home gets the same names with a suffix derived from its path, so workers never install over, stop, or report each other. Pass the same RIVETS_HOME to status, logs, and the other commands to manage that worker. The Mac app uses this to run one worker per organization.

Provision with a script

rivets configure saves a connection without starting anything, which is useful for provisioning machines with a script. It reads a JSON object from stdin, so the token never appears in command-line arguments:

rivets configure --name build-box-1 --max-workers 4 < worker-config.json
rivets install

--name is required, up to 200 characters. --max-workers is optional, from 1 to 32.

Key Type Meaning
url string, required The Rivets URL. Must be https://.
token string, required The one-time rvw_ worker token.
directTransport boolean true enables the Tailscale direct transport.
loopbackTransport boolean false sends same-machine terminal traffic through the relay.
autoUpdate boolean false turns off unattended updates.
projectScripts boolean false stops the worker running repository scripts.
{
  "url": "https://app.rivets.dev",
  "token": "rvw_...",
  "autoUpdate": true
}

The token is stored in the OS credential store. The input is capped at 16 KB. The one-line installer uses configure and install in the same way.

Type to search the docs.