Files
architecture/commands/spawn-issues.md
Hugo Nijhuis 81c2a90ce1 Spawn agents with cwd set to their worktree
Resolves issue #86 by having the spawn-issues orchestrator create worktrees
upfront and pass the worktree paths to agents, instead of having agents
create their own worktrees in sibling directories outside the sandbox.

Changes:
- spawn-issues orchestrator creates all worktrees before spawning agents
- issue-worker, pr-fixer, code-reviewer accept optional WORKTREE_PATH
- When WORKTREE_PATH is provided, agents work directly in that directory
- Backward compatible: agents still support creating their own worktrees
  if WORKTREE_PATH is not provided
- Orchestrator handles all worktree cleanup after agents complete
- Eliminates permission denied errors from agents trying to access
  sibling worktree directories

This ensures agents operate within their sandbox while still being able to
work with isolated git worktrees for parallel implementation.

Closes #86

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 00:12:14 +01:00

8.7 KiB

allowed-tools, model, description, argument-hint
allowed-tools model description argument-hint
Bash, Task, Read, TaskOutput haiku Orchestrate parallel issue implementation with review cycles <issue-number> [<issue-number>...]

Spawn Issues (Orchestrator)

Orchestrate parallel issue implementation: spawn workers, review PRs, fix feedback, until all approved.

Arguments

One or more issue numbers separated by spaces: $ARGUMENTS

Example: /spawn-issues 42 43 44

Orchestration Flow

Concurrent Pipeline - each issue flows independently:

  Issue #42 ──► worker ──► PR #55 ──► review ──► fix? ──► ✓
  Issue #43 ──► worker ──► PR #56 ──► review ──► ✓
  Issue #44 ──► worker ──► PR #57 ──► review ──► fix ──► ✓

As each step completes, immediately:
1. Print a status update
2. Start the next step for that issue

Don't wait for all workers before reviewing - pipeline each issue.

Status Updates

Print a brief status update whenever any step completes:

[#42] Worker completed → PR #55 created
[#43] Worker completed → PR #56 created
[#42] Review: needs work → spawning fixer
[#43] Review: approved ✓
[#42] Fix completed → re-reviewing
[#44] Worker completed → PR #57 created
[#42] Review: approved ✓
[#44] Review: approved ✓

All done! Final summary:
| Issue | PR  | Status   |
|-------|-----|----------|
| #42   | #55 | approved |
| #43   | #56 | approved |
| #44   | #57 | approved |

Implementation

Step 1: Parse and Validate

Parse $ARGUMENTS into a list of issue numbers. If empty, inform the user:

Usage: /spawn-issues <issue-number> [<issue-number>...]
Example: /spawn-issues 42 43 44

Step 2: Get Repository Info and Setup Worktrees

REPO_PATH=$(pwd)
REPO_NAME=$(basename $REPO_NAME)

# Create parent worktrees directory
mkdir -p "${REPO_PATH}/../worktrees"
WORKTREES_DIR="${REPO_PATH}/../worktrees"

For each issue, create the worktree upfront:

# Fetch latest from origin
cd "${REPO_PATH}"
git fetch origin

# Get issue details for branch naming
ISSUE_TITLE=$(tea issues <ISSUE_NUMBER> | grep "TITLE" | head -1)
BRANCH_NAME="issue-<ISSUE_NUMBER>-<kebab-title>"

# Create worktree for this issue
git worktree add "${WORKTREES_DIR}/${REPO_NAME}-issue-<ISSUE_NUMBER>" \
  -b "${BRANCH_NAME}" origin/main

Track the worktree path for each issue.

Step 3: Spawn All Issue Workers

For each issue number, spawn a background issue-worker agent and track its task_id:

Task tool with:
  - subagent_type: "issue-worker"
  - run_in_background: true
  - prompt: <issue-worker prompt below>

Track state for each issue:

issues = {
  42: { task_id: "xxx", stage: "implementing", pr: null, branch: null, review_iterations: 0 },
  43: { task_id: "yyy", stage: "implementing", pr: null, branch: null, review_iterations: 0 },
  44: { task_id: "zzz", stage: "implementing", pr: null, branch: null, review_iterations: 0 },
}

Print initial status:

Spawned 3 issue workers:
  [#42] implementing...
  [#43] implementing...
  [#44] implementing...

Issue Worker Prompt:

You are an issue-worker agent. Implement issue #<NUMBER> autonomously.

Context:
- Repository path: <REPO_PATH>
- Repository name: <REPO_NAME>
- Issue number: <NUMBER>
- Worktree path: <WORKTREE_PATH>

Process:
1. Setup worktree:
   cd <WORKTREE_PATH>

2. Get issue: tea issues <NUMBER> --comments

3. Plan with TodoWrite, implement the changes

4. Commit: git add -A && git commit -m "...\n\nCloses #<NUMBER>\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>"

5. Push: git push -u origin <branch-name>

6. Create PR: tea pulls create --title "[Issue #<NUMBER>] <title>" --description "Closes #<NUMBER>\n\n..."
   Capture the PR number.

7. Cleanup: No cleanup needed - orchestrator handles worktree removal

8. Output EXACTLY this format (orchestrator parses it):
   ISSUE_WORKER_RESULT
   issue: <NUMBER>
   pr: <PR_NUMBER>
   branch: <branch-name>
   status: <success|partial|failed>
   title: <issue title>
   summary: <1-2 sentence description>

Work autonomously. If blocked, note it in PR description and report status as partial/failed.

Step 4: Event-Driven Pipeline

Do NOT poll. Wait for <task-notification> messages that arrive automatically when background tasks complete.

When a notification arrives:

  1. Read the output file to get the result
  2. Parse the result and print status update
  3. Spawn the next stage (reviewer/fixer) in background
  4. Continue waiting for more notifications
On <task-notification> for task_id X:
  - Find which issue this task belongs to
  - Read output file, parse result
  - Print status update
  - If not terminal state, spawn next agent in background
  - Update issue state
  - If all issues terminal, print final summary

State transitions:

implementing → (worker done) → reviewing → (approved) → DONE
                             → (needs-work) → fixing → reviewing...
                             → (3 iterations) → needs-manual-review
           → (worker failed) → FAILED

On each notification, print status:

[#42] Worker completed → PR #55 created, starting review
[#43] Worker completed → PR #56 created, starting review
[#42] Review: needs work → spawning fixer
[#43] Review: approved ✓
[#42] Fix completed → re-reviewing
[#44] Worker completed → PR #57 created, starting review
[#42] Review: approved ✓
[#44] Review: approved ✓

Step 5: Spawn Reviewers and Fixers

When spawning reviewers/fixers, create worktrees for them and pass the path.

For review, create a review worktree from the PR branch:

cd "${REPO_PATH}"
git fetch origin
git worktree add "${WORKTREES_DIR}/${REPO_NAME}-review-<PR_NUMBER>" \
  origin/<BRANCH_NAME>

Pass this worktree path to the reviewer/fixer agents.

Code Reviewer:

Task tool with:
  - subagent_type: "code-reviewer"
  - run_in_background: true
  - prompt: <code-reviewer prompt below>

Code Reviewer Prompt:

You are a code-reviewer agent. Review PR #<PR_NUMBER> autonomously.

Context:
- Repository path: <REPO_PATH>
- PR number: <PR_NUMBER>
- Worktree path: <WORKTREE_PATH>

Process:
1. Move to worktree:
   cd <WORKTREE_PATH>

2. Get PR details: tea pulls <PR_NUMBER> --comments

3. Review the diff: git diff origin/main...HEAD

4. Analyze changes for:
   - Code quality and style
   - Potential bugs or logic errors
   - Test coverage
   - Documentation

5. Post review comment: tea comment <PR_NUMBER> "<review summary>"

6. Cleanup: No cleanup needed - orchestrator handles worktree removal

7. Output EXACTLY this format:
   REVIEW_RESULT
   pr: <PR_NUMBER>
   verdict: <approved|needs-work>
   summary: <1-2 sentences>

Work autonomously. Be constructive but thorough.

PR Fixer Prompt: (see below)

Step 6: Final Report

When all issues reach terminal state, display summary:

All done!

| Issue | PR  | Status              |
|-------|-----|---------------------|
| #42   | #55 | approved            |
| #43   | #56 | approved            |
| #44   | #57 | approved            |

3 PRs created and approved

PR Fixer

When spawning pr-fixer for a PR that needs work:

Task tool with:
  - subagent_type: "pr-fixer"
  - run_in_background: true
  - prompt: <pr-fixer prompt below>

PR Fixer Prompt:

You are a pr-fixer agent. Address review feedback on PR #<NUMBER>.

Context:
- Repository path: <REPO_PATH>
- PR number: <NUMBER>
- Worktree path: <WORKTREE_PATH>

Process:
1. Move to worktree:
   cd <WORKTREE_PATH>

2. Get feedback: tea pulls <NUMBER> --comments

3. Address each piece of feedback

4. Commit and push:
   git add -A && git commit -m "Address review feedback\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>"
   git push

5. Cleanup: No cleanup needed - orchestrator handles worktree removal

6. Output EXACTLY:
   PR_FIXER_RESULT
   pr: <NUMBER>
   status: <fixed|partial|failed>
   changes: <summary of fixes>

Work autonomously. If feedback is unclear, make reasonable judgment calls.

Worktree Cleanup

After all issues reach terminal state, clean up all worktrees:

# Remove all worktrees created for this run
for worktree in "${WORKTREES_DIR}"/*; do
  if [ -d "$worktree" ]; then
    cd "${REPO_PATH}"
    git worktree remove "$worktree" --force
  fi
done

# Remove worktrees directory if empty
rmdir "${WORKTREES_DIR}" 2>/dev/null || true

Important: Always clean up worktrees, even if the orchestration failed partway through.

Error Handling

  • If an issue-worker fails, continue with others
  • If a review fails, mark as "review-failed" and continue
  • If pr-fixer fails after 3 iterations, mark as "needs-manual-review"
  • Always report final status even if some items failed
  • Always clean up all worktrees before exiting