From metaswarm
Monitors pull requests through to merge by automatically handling CI failures, review comments, and thread resolution until all checks pass. Invoke after PR creation or via /pr-shepherd.
npx claudepluginhub dsifry/metaswarmThis skill uses the workspace's default tool permissions.
Use when a PR has been created and needs to be monitored through to merge - handles CI failures, review comments, and thread resolution automatically until all checks pass and all threads are resolved.
Monitors PR health on recurring schedules: merge conflicts, CI/CD failures in GitHub Actions/Buildkite/Vercel/Fly.io, review comment triage/resolution, merge readiness. One-shot triage mode.
Iteratively shepherds published PRs through CI checks and code reviews to merge readiness. Uses assess_stack for health checks and automatically fixes failures.
Resolves GitHub PR issues including review comments, CI failures via triage-dispatch workflow with code edits, replies, and verification.
Share bugs, ideas, or general feedback.
Use when a PR has been created and needs to be monitored through to merge - handles CI failures, review comments, and thread resolution automatically until all checks pass and all threads are resolved.
IMPORTANT: This skill is designed for the agent working in a worktree, NOT the orchestrator. The agent handles its own PR monitoring so the orchestrator remains free for other work.
This skill supports both coordination modes:
Task() with run_in_background: true. Orchestrator checks via TaskOutput(block: false).shepherd teammate in the issue-{number} team. Sends async status updates via SendMessage (CI failure, review comments, all-green, PR merged). Orchestrator can respond with instructions (e.g., "defer that comment, create an issue instead"). Responds to shutdown_request for graceful exit.All monitoring, fixing, and review handling logic is identical in both modes. See ./guides/agent-coordination.md for mode detection.
Activate this skill when ANY of these conditions are true:
gh pr create/pr-shepherd <pr-number>bin/create-pr-with-shepherd.sh was used (outputs shepherd instructions)When bin/create-pr-with-shepherd.sh creates a PR, it outputs shepherd instructions:
==========================================
PR Shepherd Active for PR #123
==========================================
The pr-shepherd skill will:
- Monitor CI/CD status
- Auto-fix lint, type, and test issues
- Handle review comments
- Resolve threads after addressing feedback
- Report when PR is ready to merge
To manually invoke shepherd later:
/pr-shepherd 123
When you see this output, immediately invoke the pr-shepherd skill with the PR number shown.
"I'm using the pr-shepherd skill to monitor this PR through to merge. I'll watch CI/CD, handle review comments, and fix issues as they arise."
When spawning an agent to work in a worktree, include PR shepherding in the task prompt:
Work in worktree at /path/to/worktree on branch feature/xyz.
Task: [describe the implementation task]
After creating the PR:
1. Use the pr-shepherd skill to monitor it through to merge
2. Handle CI failures and review comments autonomously
3. Only escalate to orchestrator for complex issues requiring user input
4. Report back when PR is ready to merge or if blocked
Run in background so I can continue other work.
Key principle: The agent owns its PR lifecycle. The orchestrator spawns and forgets, checking back via AgentOutputTool when needed.
The agent operates in one of these states:
MONITORING → FIXING → MONITORING → WAITING_FOR_USER → FIXING → MONITORING → DONE
| State | What Happens | Exit When |
|---|---|---|
MONITORING | Poll CI and reviews every 60s in background | CI fails, new comments, all done, or need help |
FIXING | Fix issues using TDD, run local validation | Local validation passes OR need user guidance |
HANDLING_REVIEWS | Invoke handling-pr-comments skill | Comments handled OR need user input |
WAITING_FOR_USER | Present options, wait for user decision | User responds |
DONE | All CI green + all threads resolved | Exit successfully |
# Get PR info
PR_NUMBER=$(gh pr view --json number -q .number 2>/dev/null)
OWNER=$(gh repo view --json owner -q .owner.login)
REPO=$(gh repo view --json name -q .name)
# If no PR on current branch, check if number was provided
if [ -z "$PR_NUMBER" ]; then
echo "No PR found for current branch. Provide PR number."
exit 1
fi
echo "Shepherding PR #$PR_NUMBER"
Run GTG every 60 seconds as the single source of truth for PR readiness:
GTG consolidates CI status, comment classification, and thread resolution into one call. Use it instead of separate API queries.
# Primary readiness check — structured JSON output
GTG_RESULT=$(gtg $PR_NUMBER --repo "$OWNER/$REPO" --format json \
--exclude-checks "Merge Ready (gtg)" \
--exclude-checks "CodeRabbit" \
--exclude-checks "Cursor Bugbot" \
--exclude-checks "claude" 2>&1)
STATUS=$(echo "$GTG_RESULT" | jq -r '.status')
ACTION_ITEMS=$(echo "$GTG_RESULT" | jq -r '.action_items[]?' 2>/dev/null)
CI_STATE=$(echo "$GTG_RESULT" | jq -r '.ci_status.state')
GTG statuses:
| Status | Meaning | Agent Action |
|---|---|---|
READY | All CI green, all threads resolved | → DONE |
ACTION_REQUIRED | Actionable comments need fixes | → HANDLING_REVIEWS (use action_items) |
UNRESOLVED_THREADS | Review threads still open | → HANDLING_REVIEWS |
CI_FAILING | One or more CI checks failing | → FIXING |
ERROR | Couldn't fetch PR data | Retry after 60s, escalate after 3 retries |
GTG reports, agents act: GTG does not resolve threads or fix code — it only tells you what's blocking. After addressing feedback, you must resolve threads yourself using the GraphQL mutation in handle-pr-comments.md (Section 3). GTG will report READY on the next poll once threads are resolved.
if STATUS == "READY":
→ DONE
if STATUS == "CI_FAILING":
→ Parse action_items for specific failures
→ if is_simple_failure(failure): FIXING
→ else: WAITING_FOR_USER
if STATUS == "ACTION_REQUIRED" or STATUS == "UNRESOLVED_THREADS":
→ HANDLING_REVIEWS (action_items tells you exactly what to fix)
if STATUS == "ERROR":
→ Retry, then escalate
If GTG is unavailable (e.g., not installed in environment), fall back to manual queries:
# CI status
FAILED_CHECKS=$(gh pr checks $PR_NUMBER --json name,conclusion --jq '[.[] | select(.conclusion == "FAILURE")] | length')
# Unresolved threads
UNRESOLVED=$(gh api graphql -f query='
query($owner: String!, $repo: String!, $pr: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $pr) {
reviewThreads(first: 100) {
nodes { isResolved }
}
}
}
}
' -f owner="$OWNER" -f repo="$REPO" -F pr="$PR_NUMBER" \
--jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)] | length')
When threads are resolved but the Merge Ready (gtg) GitHub Actions check is stale:
gh workflow run gtg.yml -f pr_number=$PR_NUMBER
These can be fixed without user approval:
These require user input BEFORE fixing:
superpowers:test-driven-development for code changespkill -f vitest 2>/dev/null || true before test runspnpm lint && pnpm typecheck && pnpm test --run && pnpm test:coverage all pass# Kill stale vitest processes before running tests
pkill -f vitest 2>/dev/null || true
# After fixing, always validate locally (including coverage)
pnpm lint && pnpm typecheck && pnpm test --run && pnpm test:coverage
# Only push if all pass (including coverage thresholds)
git add -A && git commit -m "fix: <description>" && git push
When new review comments are detected:
handling-pr-comments skillTHE #1 FAILURE MODE: Returning to MONITORING after one pass without checking for new comments.
The handling-pr-comments skill's Phase 7 (Post-Push Iteration Check) MUST complete successfully before exiting HANDLING_REVIEWS state. The skill will iterate automatically:
HANDLING_REVIEWS:
→ handling-pr-comments skill (Phases 1-7)
→ IF Phase 7 finds new comments: skill re-runs Phases 1-7
→ IF Phase 7 confirms no new comments: exit to MONITORING
DO NOT manually override or skip Phase 7. If you find yourself tempted to skip iteration, you're about to make the #1 mistake.
Reviewers may leave comments on code outside the PR diff. The handling-pr-comments skill handles these, but key points:
When user input is needed, ALWAYS:
[Describe what happened]
**Options:**
1. **[Option name]** (Recommended)
- [What it involves]
- Pros: [benefits]
- Cons: [drawbacks]
2. **[Option name]**
- [What it involves]
- Pros: [benefits]
- Cons: [drawbacks]
3. **[Option name]**
- [What it involves]
- Pros: [benefits]
- Cons: [drawbacks]
Which approach would you like? (Or describe a different approach)
At 4 hours elapsed, pause and checkpoint:
**PR Shepherd Checkpoint** (4 hours elapsed)
Current status:
- CI: [status]
- Threads: [X] resolved, [Y] unresolved
- Commits: [N] fix commits pushed
**Options:**
1. **Keep monitoring** (Recommended)
- Continue for another 4 hours
- Pros: PR may get reviewed soon
- Cons: Ties up agent resources
2. **Exit with handoff**
- Save status report, exit cleanly
- Pros: Frees resources
- Cons: Must manually re-invoke later
3. **Set shorter check-in**
- Check back in 1 hour instead of 4
- Pros: More frequent checkpoints
- Cons: More interruptions
What would you like to do? (Or describe a different approach)
Exit successfully when ALL are true:
Report:
**PR #[number] Ready to Merge**
- CI: All checks passing
- Reviews: All threads resolved
- Commits: [N] total ([M] fix commits)
The PR is ready for final approval and merge.
After the PR is merged and knowledge extraction tasks are created, invoke automatic RAM cleanup to free resources:
/auto-ram-cleanup
Why: Development processes (test runners, build watchers, language servers) accumulate during PR work. Cleaning up after merge frees memory for the next task.
What stays running:
What gets cleaned:
Primary path: Self-reflect should have already run pre-PR (see orchestrated-execution section 8.5), with knowledge base changes committed as part of the PR. This phase verifies that happened and handles the fallback case.
Fallback: If self-reflect was NOT run pre-PR (e.g., PR was created outside the orchestrated workflow), create a blocking task for knowledge extraction after merge.
After detecting that the PR has been merged (or after user merges it):
# Check if PR was merged
MERGED=$(gh pr view $PR_NUMBER --json merged -q .merged)
if [ "$MERGED" = "true" ]; then
# Create a task for knowledge curation
# Use your project's task tracking system
echo "Create task: Curate learnings from PR #$PR_NUMBER"
# If there's an associated epic, add this task as a blocker
# (The epic can't close until learnings are extracted)
fi
Note: Self-reflect (/self-reflect) should have already run BEFORE the PR was created (see orchestrated-execution skill, section 8.5). If it was skipped, run it now as a fallback — but the preferred time is pre-PR while implementation context is freshest.
When creating the curation task:
**PR #[number] Merged Successfully**
Created blocking task: [CURATION_TASK_ID]
- Title: "Curate learnings from PR #[number]"
- Status: pending
- Blocker for: [epic if applicable]
To extract learnings, invoke:
```
/curate-pr-learnings [number]
```
The command will:
1. Fetch PR comments (deterministic script)
2. AI analyzes and extracts learnings (your job)
3. Store validated learnings (deterministic script)
Then close the task.
When this PR completes an epic (closes the last blocking task), you MUST also extract learnings from conversation history. Feature work often contains the richest architectural discussions.
Detect epic completion:
Note: This pattern assumes single-epic workflows. If multiple epics are in-progress,
.[0]selects the first one, which may not be the epic related to this PR. For multi-epic projects, correlate the PR's task to its blocking epic manually.
# Check if this PR closes an epic (assumes single in-progress epic)
# Use your project's task tracking system to check epic status
If epic is completing:
Create a task for conversation extraction
Report the task to user:
**Epic Completion Detected**
This PR completes the epic. Created conversation extraction task.
Before closing the epic, extract learnings from conversations.
Why extract from conversations?
These learnings are often NOT in code review comments - they're in the back-and-forth conversation.
If user chooses to exit at checkpoint:
**PR #[number] Shepherd Handoff**
Status at exit:
- CI: [status]
- Threads: [X] resolved, [Y] unresolved
- Last activity: [timestamp]
To resume: `/pr-shepherd [number]`
| Situation | Skill |
|---|---|
| New review comments | handling-pr-comments |
| Code changes needed | superpowers:test-driven-development |
| Complex debugging | superpowers:systematic-debugging |
BLOCKING: You MUST run this script and show its output before declaring ANY PR ready:
bin/pr-comments-check.sh <PR_NUMBER>
This script:
If the script shows ANY unaddressed comments, you are NOT done. Address each unaddressed comment:
For EACH top-level comment (where in_reply_to_id is null) without a reply:
A PR is NOT ready until every top-level comment has been addressed with a reply.
Before exiting DONE state:
After PR is merged (Phase 7):
/self-reflect ran pre-PR (if not, run it now as fallback)After all post-merge tasks complete:
/auto-ram-cleanup to free development resourcesPushing without local validation
pnpm lint && pnpm typecheck && pnpm test --run && pnpm test:coverageAuto-fixing complex issues
Forgetting to invoke handling-pr-comments
Not presenting options to user
Leaving FIXING state early
Skipping the handling-pr-comments iteration loop