Sync code and run commands on remote machines. Use when running tests, builds, or commands remotely, syncing files to hosts, setting up remote development, or troubleshooting rr configuration.
rr syncs code to remote machines and runs commands there. Handles host failover, file sync with rsync, distributed locking, and test output formatting.
rr run "make test" # Sync files + run command
rr exec "git status" # Run command without syncing
rr sync # Just sync files
rr <taskname> # Run named task from config
rr provision # Install missing tools on hosts
rr doctor # Diagnose issues
rr monitor # TUI dashboard for host metrics
rr uses two config files:
| Config | Location | Purpose |
|--------|----------|---------|
| Global | ~/.rr/config.yaml | Personal host definitions (SSH, directories) |
| Project | .rr.yaml | Shareable project settings (tasks, sync rules) |
See config.md for complete config reference.
version: 1
hosts:
mini:
ssh: [mac-mini.local, mac-mini-tailscale]
dir: ${HOME}/projects/${PROJECT}
version: 1
hosts: [mini]
sync:
exclude: [.git/, node_modules/, .venv/]
tasks:
test:
run: pytest -v
| Command | Purpose |
|---------|---------|
| rr run "cmd" | Sync files, then run command |
| rr exec "cmd" | Run command without syncing |
| rr sync | Just sync files |
| rr <taskname> | Run named task |
| rr tasks | List available tasks |
| rr provision | Install missing tools on hosts |
| rr doctor | Diagnose issues |
| rr host list/add/remove | Manage hosts |
See commands.md for full command reference.
--pretty / -p - Opt into human-readable output (spinners, colors). Default is structured JSON.--host <name> - Target specific host--tag <tag> - Select host by tag--local - Force local execution--skip-requirements - Skip requirement checksRun rr --help or rr <command> --help for complete flag reference.
Define reusable commands in .rr.yaml:
tasks:
test:
description: Run tests
run: pytest -v
deploy:
steps:
- name: Build
run: make build
- name: Deploy
run: ./deploy.sh
Run with: rr test, rr deploy
Extra arguments append to single-command tasks: rr test -k "test_login"
See tasks.md for parallel tasks, multi-step tasks, and advanced configuration.
Tasks come in three types. The type determines whether extra args work:
| Type | Config field | Accepts args? | Example |
|------|-------------|---------------|---------|
| Single-command | run: | YES | rr test -k "test_foo" |
| Multi-step | steps: | NO (errors) | rr deploy |
| Parallel | parallel: | NO unless forward_args: true | rr test-all |
When you need custom args on a parallel task, bypass it:
# Preferred: use --cwd for subdirectory execution (path-traversal safe)
rr run --cwd backend "uv run pytest tests/bond/ -v"
# Fallback: manual cd pattern (avoid — quoting errors are common)
rr run "cd backend && uv run pytest tests/bond/ -v"
To check which type a task is: rr <task> --help
To forward args to all subtasks in a parallel task, set forward_args: true in the task config:
tasks:
test-backend:
parallel: [test-backend-api, test-backend-services]
forward_args: true # rr test-backend -k bond works
Need to run something remotely?
├── Named task exists? → rr <task>
│ ├── Single-command task → rr <task> <args> (args forwarded)
│ ├── Parallel task (forward_args: true) → rr <task> <args>
│ └── Parallel task (default) → rr run "cd <dir> && <cmd> <args>"
├── No task, files may have changed → rr run "<command>" (syncs first)
└── Files already synced → rr exec "<command>" (faster, skips sync)
Never nest rr inside rr exec — rr may not be installed on the remote:
# Wrong: rr exec "rr sync && pytest"
# Right: rr run "pytest"
rr sends phase events (connect, sync, exec) to stderr and command output to stdout.
rr test-opendata 2>/dev/null # suppress all phase events
rr test-opendata --no-phases # suppress intermediate events, keep final result JSON
rr test-opendata 2>&1 # capture everything (mixes phase JSON into output stream)
The final result is always a JSON line on stderr with "type":"result" containing exit code, host, and duration.
Declare required tools with require: - rr verifies they exist before running commands:
# .rr.yaml
require:
- go
- node
tasks:
build:
run: make build
require: [cargo] # Task-specific requirement
# ~/.rr/config.yaml
hosts:
gpu-box:
ssh: [gpu.local]
require: [nvidia-smi, python3] # Host-specific requirements
Run with: rr test-all, rr quick-check
Avoid redundant setup work (dependency sync, migrations) when multiple subtasks run on the same host:
tasks:
test-all:
setup: pip install -r requirements.txt # Runs once per host
parallel:
- test-unit
- test-integration
- test-e2e
Setup runs exactly once per host before any subtasks execute. If a host runs 3 subtasks, setup runs once (not 3 times).
| Flag | Purpose |
|------|---------|
| --stream | Show real-time interleaved output with [host:task] prefixes |
| --verbose | Show full output per task on completion |
| --quiet | Summary only |
| --fail-fast | Stop on first failure (overrides config) |
| --max-parallel N | Limit concurrent tasks |
| --dry-run | Show plan without executing |
| --local | Force local execution (no remote hosts) |
Define task execution order with depends. Tasks run their dependencies first, then execute their own command:
tasks:
lint:
run: golangci-lint run
test:
run: go test ./...
build:
run: go build ./...
# Linear chain: lint -> test -> build
ci:
description: Full CI pipeline
depends:
- lint
- test
- build
Run with: rr ci
Run multiple dependencies simultaneously:
tasks:
lint:
run: golangci-lint run
typecheck:
run: mypy .
test:
run: pytest
ci:
depends:
- parallel: [lint, typecheck] # Run simultaneously
- test # Run after parallel completes
Executes: [lint, typecheck] (parallel) -> test
Tasks with only depends orchestrate without running their own command:
tasks:
lint:
run: golangci-lint run
test:
run: go test ./...
verify:
description: Run all checks
depends: [lint, test]
# No 'run' - just orchestrates
| Flag | Purpose |
|------|---------|
| --skip-deps | Skip dependencies, run only the target task |
| --from <task> | Start from a specific task in the chain |
rr ci # Full dependency chain
rr ci --skip-deps # Only run ci task itself
rr ci --from test # Start from test, skip lint
fail_fast: truetimeout field for entire dependency chain[host:task] prefixesExample:
rr test-all --stream # See all output in real-time
rr test-all --dry-run # Preview what would run
rr test-all --local # Run locally without remote hosts
Missing tools trigger actionable error messages. Tools with built-in installers (40+) can be auto-installed.
See requirements.md for complete requirements reference.
| Problem | Fix |
|---------|-----|
| SSH fails | Check ssh <alias> manually, verify ~/.ssh/config |
| "handshake failed" but ssh works | Key not in agent: ssh-add ~/.ssh/id_rsa, add AddKeysToAgent yes to SSH config |
| "command not found" | Add setup_commands or check require config |
| Sync slow | Add large dirs to sync.exclude |
| Lock stuck | rr unlock |
| Lock timeout after crash or cancel | rr unlock --all — stale locks from sessions that didn't exit cleanly |
When you're unsure about a task's type, subtasks, or flags, run rr <task> --help before executing it. The help output shows whether the task is parallel (and lists subtasks), what flags it accepts, and whether it takes extra arguments. This is faster than reading .rr.yaml and avoids the silent-arg-drop problem.
See troubleshooting.md for detailed diagnostics.
rr defaults to structured output (agent-first). No flags needed. Phase events are emitted as JSON lines to stderr, command stdout/stderr passes through undecorated.
# Default behavior - structured JSON events on stderr, raw output on stdout
rr run "make test"
rr test
# Opt into human-readable spinners/colors
rr run --pretty "make test"
The --machine / -m flag still works but is a no-op (structured is already the default).
See machine-interface.md for JSON event format and error codes.
# 1. Add a host
rr host add
# 2. Initialize project
cd your-project && rr init
# 3. Verify
rr doctor
# 4. Run
rr run "make test"
| Situation | Command |
|-----------|---------|
| Run tests with latest code | rr run "make test" |
| Quick check on remote | rr exec "git log -1" |
| Prep remote before multiple runs | rr sync |
| Install missing tools on hosts | rr provision |
| Debug connection issues | rr doctor |
| Watch resource usage | rr monitor |
| First time setup | rr init |
| Add new machine | rr host add |
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer