relay
Runs a task unattended using claude-relay: drives claude -p in a headless loop, writes a
handoff summary when one account's limit approaches, and switches to the next account automatically.
You watch logs; relay handles the rest.
Binary: claude-relay (alias relay if added to shell). Config: ~/.claude-relay/relay.config.json.
Step 1: Decide: relay or inline?
Use relay when:
- Task will take many turns or hours (big refactor, migration, research + implementation)
- The user wants to hand it off and walk away
- Rate limits are a real concern (long-running or token-heavy)
Stay inline when:
- Task is quick (< ~10 turns)
- User wants to review each step
- Task needs interactive input that relay can't provide
Step 2: Write the goal
A relay goal is a self-contained spec a fresh Claude agent can execute cold. Write it to
/tmp/relay-goal-<short-name>.md. It must include:
- What to do: concrete deliverables, not vague intent
- How to verify: the exact command proving success (
npm test,curl /api/health, etc.) - Scope: explicit list of what NOT to do (no commits, no PRs, no migrations, unless stated)
- Key files: paths the agent should read first if the context isn't obvious
Template:
## Goal
<1-3 sentences: the deliverable>
## Success criteria
Run `<command>` and confirm it exits 0 / returns the expected result.
## Scope
- DO: <explicit list>
- DO NOT: open PRs / push commits / run migrations / touch unrelated files
## Key files
- <path>: <why it matters>
Good goals are specific. "Add input validation to all POST routes in app/api/" beats "improve the API".
Step 3: Pick flags
| Situation | Flag |
|---|---|
Task needs uncommitted changes, local .env, or a local database |
--in-place |
| Everything is committed; task is self-contained | (default, isolated git worktree) |
When in doubt: if the repo has a .env or node_modules the task depends on, use --in-place.
Step 4: Run
claude-relay run /tmp/relay-goal-<name>.md <absolute-path-to-repo> [--in-place]
Relay logs stream to stderr. The run ends when the agent outputs RELAY_TASK_COMPLETE on its own
line, or hits a hard cap (400 turns / 48h wall clock).
Step 5: Tell the user
After starting, report:
- The exact command you ran
- What to watch for:
RELAY_TASK_COMPLETEin logs, orclaude-relay status --config ~/.claude-relay/relay.config.json - The flag you picked and why (especially if you chose
--in-place)
Health check
If anything seems misconfigured:
claude-relay doctor --config ~/.claude-relay/relay.config.json
Should show ✓ for both account slots. If a slot shows ✗, tell the user to run:
claude-relay login <email> # must have claude.ai open in browser as that account first