Run a command on another machine you own, with your current working tree. Logs stream to your terminal, the exit code comes back, and changed files can be fetched or applied locally. No remote checkout to maintain.
Adapted from Figure 7.1 in Daniel P. Dern's The Internet Guide for New Users (1994).
One binary for macOS and Linux. Connect through Tailscale or SSH; each machine can send jobs, receive them, or both. Commands run directly on the runner, so install the tools your project needs there. Errand is for trusted code on machines you control. Interactive programs requiring a PTY are not supported.
With Homebrew:
brew install lydakis/errand/errand
errand versionOr download a macOS/Linux binary from GitHub Releases. To build from source, use the Go version in go.mod:
go build -trimpath -o errand ./cmd/errandInstall Errand on both machines. For this example, both should be connected to the same Tailscale network under your login.
On the machine that will run jobs:
errand setupSetup installs and starts the runner service. On your laptop, add that machine using its Tailscale hostname, then run a command from a Git worktree:
errand peers add buildbox YOUR_RUNNER_HOSTNAME
errand --on buildbox -- make testErrand sends the selected workspace, including uncommitted changes, streams
the logs, and returns the command's exit code. Git-ignored files are excluded
by default. Your local files stay unchanged unless you request application.
The first peer you add becomes the default, so subsequent commands can use
errand -- make test.
For SSH, use errand peers add buildbox YOUR_SSH_HOST --ssh. See
runner setup and access for other logins, custom paths,
and SSH-only runners.
Run in the background and reconnect later:
job=$(errand -d -- make build)
errand ps
errand status "$job"
errand attach "$job"While attached, Ctrl-D detaches and leaves the job running. Ctrl-C interrupts
the remote command. errand kill HANDLE stops a job you have detached from.
Bring changed files back:
errand fetch HANDLE # download into local staging
errand fetch --apply HANDLE # merge into the originating workspace
errand fetch -o ./results HANDLE # export remote files to a new directory
errand --apply -- gofmt -w . # apply automatically after clean successOrdinary workspace changes are retained automatically, including on failed jobs. Apply checks for local conflicts before changing your files. Attach only follows logs; it does not fetch or apply results.
Retain ignored outputs, or reuse a build cache on the runner:
errand --artifact reports -- make test
errand fetch -o ./test-results HANDLE reports
errand --cache compiler=target -- cargo testArtifacts add files to the results you can fetch. Caches stay on the runner
for later jobs and are excluded from uploads and results. Here compiler
is a name you choose and target is its workspace-relative directory.
Reach a remote development server through localhost:
errand -L 3000 -- pnpm devSave recurring choices in .errand.toml:
[profiles.test.run]
peer = "buildbox"
[profiles.test.artifacts]
paths = ["reports"]errand --profile test -- make test
errand config --profile test # explain effective settings and sources
errand doctor # check installation, runner, and connectionProfiles are explicitly selected. Personal settings live in
~/.config/errand/config.toml; CLI flags override configuration. See the
configuration guide for precedence, environment
forwarding, workspace roots, and all supported settings.
- Usage guide: command conventions, snapshots, sessions, fetch, and apply.
- Operations: setup, access, SSH, diagnostics, and cleanup.
- Named caches: reuse, ownership, leases, and removal.
- Design: admission, receipts, failure recovery, and trust boundaries.
- Performance: measurements and reproducible benchmarks.
- Releases and upgrades: packaging, publication, and runner migration.
Use errand --help or errand COMMAND --help for flags and examples.
MIT
