@shippedbuild/runner
v0.0.36
Published
Shipped runner daemon (runnerd): executes leased Shipped jobs on your own machine and stays in sync with the Shipped control plane.
Downloads
5,267
Readme
@shippedbuild/runner
runnerd is the Shipped runner daemon. It executes one leased Shipped job at a time on your own machine and stays in sync with the Shipped control plane (job claim, lease, heartbeats, git checkpoints, session sync).
Install from npm:
npm install -g @shippedbuild/runnerRequirements:
- Node.js
>=22.23.0 <23 - git
>=2.20.0(shipped macOS Xcode CLT git 2.39.5 is fine) - outbound network access to your control plane (production:
https://shipped.build)
Quick start
- In the web app open Settings → Runners and create a runner. The dialog shows a one-time token (valid for 10 minutes, single use).
- On the machine that should run jobs, run the single registration command:
runnerd start --token <code>That is the whole machine-side lifecycle. start --token validates the token against the control plane, replaces any previous instance on this machine (the old runner is revoked server-side and its local data deleted), and installs the persistent daemon service. A token that matches the machine's current registration keeps all local data and only ensures the daemon is running.
Host execution boundary: by registering, you accept that runnerd, the agent worker, and model-generated commands run with the permissions of the OS user that installed the runner. They can access that user's home, files, network, processes, runner state, and reachable credentials. Shipped provides no sandbox, VM, network, or resource isolation and cannot undo effects outside the job worktree. If you need isolation, isolate the whole runner (dedicated machine, container, or low-privilege user).
The data directory defaults to ~/.local/share/shipped-runner/ (override with --home DIR). Identity keys and config are stored with 0600 permissions.
Commands
runnerd start --token CODE [--home DIR]The single registration entry point:
- token digest matches the local registration → keep ALL local data, only ensure the daemon service is installed and running;
- no local registration or a different token → the token is validated against the control plane FIRST (a new runner is only created if the token is real, unconsumed and unexpired); only then is the previous instance replaced: old runner best-effort revoked server-side, local data physically deleted, fresh enrollment, daemon service installed;
- an invalid token is rejected with the local data untouched.
The enrollment token is one-shot (the server keeps only its digest and consumes it on enrollment). Its local sha256 is stored in the runner config as the match key; the token itself is never kept.
runnerd start [--home DIR]Daemon mode — run the runner in the foreground. This is also the command the systemd/launchd unit executes; you normally never type it.
runnerd stopStop the daemon process. The service unit stays installed and enabled; local data is untouched.
runnerd uninstallRevoke the runner on the server (best effort, outcome reported), stop the daemon, remove the service unit, and physically delete the local data directory.
runnerd logs [--lines N] [--follow]The daemon journal (journalctl --user -u shipped-runner.service on Linux).
runnerd statusExactly one signal: RUNNING or NOT_RUNNING (daemon process liveness).
runnerd doctor | versionEnvironment checks (SQLite, git) | version.
Security model
- The enrollment token is a one-time bootstrap code (short TTL). The runner generates its own Ed25519 identity key pair locally; only the public key is ever sent.
- Runner→control plane authentication is a challenge–signature scheme over the locally stored Ed25519 private key (never leaves the machine,
0600file). - The control URL must be HTTPS (HTTP is accepted only for loopback), may not contain credentials, queries, or paths, and the enroll request's
control_originis checked by the control service. - Job results are written to a durable local outbox before being reported, and the daemon reconciles on restart: execution is at-least-once, reporting is idempotent.
- Protocol and host-execution contract versions are pinned in the local config; a mismatched version refuses to start rather than degrading silently.
Development
corepack pnpm install
corepack pnpm --filter @shippedbuild/runner build
node runner/dist/cli.js doctorReleases are published from the repository by scripts/publish-runner-release.mjs, which also populates the control plane release directory served at GET /releases/runner/latest.json and GET /releases/runner/{version}/runner.tgz.
License
MIT
升级
网页设置页对每台 runner 显示「升级到 X」按钮,点击后服务端登记,runner 在空闲心跳时经 npm 自动换装并重启服务。两条通道同源(latest.json + npm registry);机器端不再有独立的手动升级命令——需要强制时重启服务即可:systemctl --user restart shipped-runner。
