Autonomous multi-task development loops powered by Beads issue tracking and subagent isolation.
Reeds connects Beads (git-based issue tracker) with Claude's Task tool for autonomous task execution. It provides:
- Task Orchestration: Main agent queries Beads for ready tasks
- Subagent Isolation: Each task is implemented by a fresh subagent (no context pollution)
- Iteration Control: Own stop hook handles looping
- Dependency Awareness: Respects Beads' dependency system
Main Agent (orchestrator)
│
├─→ bd ready --limit 1 (get next task)
│
├─→ bd show <task-id> (get details)
│
├─→ Task tool → task-implementer agent
│ │
│ └─→ Implements task in isolated context
│ Returns summary when done
│
├─→ bd close <task-id> --reason "summary"
│
├─→ Output: <promise>TASK COMPLETE: <id></promise>
│
└─→ Claude attempts to stop...
│
└─→ Stop Hook intercepts
│
├─→ Parses transcript for promises
├─→ Increments iteration counter
├─→ Re-injects prompt: "Get next task"
│
└─→ Loop continues until REEDS COMPLETE
- Claude Code CLI installed
- Beads initialized in your project (
bd init) bdCLI available in PATHjqfor JSON processing
cd ~/.claude/plugins
git clone https://github.com/rikdc/reedsRestart Claude Code to load the plugin.
/reeds:reeds-start [--max-iterations N]
This will:
- Validate Beads is initialized
- Show ready task count
- Start the autonomous task loop
Options:
--max-iterations N- Stop after N iterations (default: 30)
/reeds:reeds-status
Shows Reeds loop state and Beads task statistics.
/reeds:reeds-cancel
Stops the autonomous loop by setting the state file to inactive.
- Setup:
/reeds:reeds-startcreates.claude/reeds-state.local.mdwith iteration tracking - Orchestration: Main agent runs
bd readyto get tasks - Delegation: Each task is passed to the
task-implementersubagent - Isolation: Subagent runs in clean context, implements task, returns summary
- Closure: Main agent runs
bd closewith the summary - Iteration: Stop hook detects when Claude tries to stop, re-injects loop prompt
- Completion: Loop ends when
bd readyreturns nothing
Reeds uses a promise protocol and a stop hook to maintain the autonomous loop across multiple agent turns.
The orchestrator outputs special markers that the stop hook detects:
| Marker | Meaning |
|---|---|
<promise>TASK COMPLETE: <id></promise> |
Current task finished, get next task |
<promise>REEDS COMPLETE</promise> |
No more tasks, terminate loop |
When Claude attempts to stop, the stop hook (scripts/stop-hook.sh) intercepts:
- Parses the transcript for promise markers
- If TASK COMPLETE: Clears current task, re-injects prompt to get next task
- If REEDS COMPLETE: Sets state to inactive, allows exit
- If neither: Re-injects prompt to continue current task
- Increments iteration counter and checks against max
┌─────────────┐
│ No Task │◄───────────────────────────────┐
└──────┬──────┘ │
│ bd ready returns task │
▼ │
┌─────────────┐ │
│ Implementing│──── TASK COMPLETE ────────────►│
└──────┬──────┘ │
│ bd ready returns nothing │
▼ │
┌─────────────┐ │
│ Complete │ REEDS COMPLETE → exit │
└─────────────┘
# Initialize a project with Beads
cd my-project
bd init
# Create some tasks
bd create "Set up project structure" --priority 1
bd create "Implement core feature" --priority 2
bd create "Add tests" --priority 3
# Open in Claude Code
claude
# Start the autonomous loop
/reeds:reeds-start --max-iterations 20Claude will work through each task using subagents, closing them as completed, until no ready tasks remain.
Convert a PRD (Product Requirements Document) to Beads tasks:
/prd-to-beads path/to/prd.md
Creates an epic with child tasks for each user story, with proper dependencies.
reeds/
├── .claude-plugin/
│ └── plugin.json # Plugin manifest
├── agents/
│ └── task-implementer.md # Subagent for task implementation
├── commands/
│ ├── reeds-start.md # Start command
│ ├── reeds-status.md # Status command
│ └── reeds-cancel.md # Cancel command
├── skills/
│ └── prd-to-beads/ # PRD to Beads conversion skill
├── hooks/
│ └── hooks.json # Stop hook for iteration control
├── scripts/
│ ├── setup-reeds.sh # Prerequisites validation & state setup
│ ├── stop-hook.sh # Iteration control hook
│ └── set-current-task.sh # Updates state with current task ID
└── README.md
Reeds maintains state in .claude/reeds-state.local.md with YAML frontmatter:
---
active: true # Loop is running (true/false)
iteration: 5 # Current iteration count
max_iterations: 30 # Stop after this many iterations
current_task_id: "reeds-123" # Task currently being worked on
started_at: 2024-01-15T10:30:00Z # When the loop started (ISO 8601)
---| Field | Type | Description |
|---|---|---|
active |
boolean | Whether the loop is running |
iteration |
integer | Current iteration (incremented by stop hook) |
max_iterations |
integer | Safety limit to prevent runaway loops |
current_task_id |
string | Beads task ID being implemented (empty between tasks) |
started_at |
ISO 8601 | Timestamp when /reeds:reeds-start was invoked |
- Ensure Beads is initialized:
bd init - Check for ready tasks:
bd ready - Verify
bdis in PATH:which bd
- Ensure tasks are in
openstatus:bd list - Check for dependency blocks:
bd blocked
- Check Reeds state:
cat .claude/reeds-state.local.md - Max iterations may have been reached
- Run
/reeds:reeds-statusfor diagnostics
If a subagent reports test or build failures:
- The task remains open in Beads (not closed)
- Run
/reeds:reeds-cancelto stop the loop - Manually fix the issue
- Resume with
/reeds:reeds-start
If the loop keeps iterating on the same task:
- Check if
current_task_idis set:cat .claude/reeds-state.local.md - Manually close the problematic task:
bd close <task-id> --reason "manually resolved" - Resume with
/reeds:reeds-start
To reset Reeds state completely:
rm .claude/reeds-state.local.mdTo manually adjust iteration count:
# Edit the state file directly
vim .claude/reeds-state.local.md
# Change iteration: N to a lower numberMIT