with one click
process-pr
// Process PR based on code review - if approved, create follow-up issues, merge, close; if changes requested, re-run implement-issue
// Process PR based on code review - if approved, create follow-up issues, merge, close; if changes requested, re-run implement-issue
Bulletproof CSS and frontend design principles from "Handcrafted CSS" by Dan Cederholm. Apply when writing CSS, HTML, Blade templates, or reviewing frontend code. CSS is king — refactor Tailwind when encountered.
Batch process GitHub issues via batch-orchestrator.sh with rate limit handling and session resumption
Use when given a GitHub issue number and base branch to implement end-to-end
Use when creating new skills, editing existing skills, or verifying skills work before deployment
Use when adapting the generic .claude pipeline folder to a specific codebase - adjusting skills, agents, hooks, scripts, prompts, and settings for the target project's tech stack and workflows
Use when you have a written implementation plan to execute in a separate session with review checkpoints
| name | process-pr |
| description | Process PR based on code review - if approved, create follow-up issues, merge, close; if changes requested, re-run implement-issue |
| argument-hint | <pr_number> <issue_number> <base_branch> |
Read PR review comments and act accordingly: if approved, create follow-up issues and merge; if changes requested, re-run implementation.
Announce at start: "Using process-pr to process PR #$1 for issue #$2"
Arguments:
$1 — PR number (required)$2 — Issue number that the PR addresses (required)$3 — Base branch for re-implementation if needed (required)Examples:
/process-pr 142 130 aw-next/process-pr 456 123 maindigraph process_pr {
rankdir=TB;
node [shape=box];
validate [label="1. Validate inputs"];
fetch [label="2. Fetch PR & review comments"];
check [label="3. Check review status"];
approved [label="Approved path"];
changes [label="Changes requested path"];
merge [label="4a. Squash merge PR"];
comment [label="4b. Comment on issue"];
close [label="4c. Close issue"];
delete [label="4d. Delete branch"];
parse [label="4e. Parse comments for follow-ups"];
create_issues [label="4f. Create follow-up issues"];
rerun [label="5. Re-run /implement-issue"];
output_success [label="Output: Success summary"];
output_rerun [label="Output: Re-implementation started"];
validate -> fetch -> check;
check -> approved [label="approved"];
check -> changes [label="changes requested"];
approved -> merge -> comment -> close -> delete -> parse -> create_issues -> output_success;
changes -> rerun -> output_rerun;
}
Why merge first: Follow-up issues should only be created if the merge succeeds. Creating issues before merge can leave orphaned issues if merge fails (conflict, permissions, etc.). Merging first ensures we only create follow-ups for work that actually landed.
# Verify PR exists and is open
gh pr view $PR_NUMBER --json state,number,title,headRefName,reviews
# Verify issue exists and is open
gh issue view $ISSUE_NUMBER --json state,number,title
If validation fails: Stop and report error.
# Get PR with comments
gh pr view $PR_NUMBER --json number,title,state,headRefName,comments
# Also get the full PR view with comments for parsing
gh pr view $PR_NUMBER --repo OWNER/REPO --comments
Extract:
IMPORTANT: Review status is embedded in PR comments by the implement-issue skill. Use this explicit algorithm:
Step 3a: Fetch all PR comments
# Get comments as JSON array
COMMENTS=$(gh pr view $PR_NUMBER --json comments --jq '.comments[].body')
Step 3b: Extract status from comments (most recent wins)
# Parse status using explicit algorithm
parse_review_status() {
local comments="$1"
local status=""
# Process comments in order (last one wins)
while IFS= read -r comment; do
# Check for markdown bold format first (preferred)
if echo "$comment" | grep -q '\*\*Status: APPROVED\*\*'; then
status="APPROVED"
elif echo "$comment" | grep -q '\*\*Status: CHANGES_REQUESTED\*\*'; then
status="CHANGES_REQUESTED"
# Fallback to plain text format
elif echo "$comment" | grep -q 'Status: APPROVED'; then
status="APPROVED"
elif echo "$comment" | grep -q 'Status: CHANGES_REQUESTED'; then
status="CHANGES_REQUESTED"
fi
done <<< "$comments"
echo "$status"
}
REVIEW_STATUS=$(parse_review_status "$COMMENTS")
Step 3c: Validate status
if [ -z "$REVIEW_STATUS" ]; then
echo "ERROR: No review status found in PR #$PR_NUMBER comments"
echo "Expected: Comment containing '**Status: APPROVED**' or '**Status: CHANGES_REQUESTED**'"
exit 1
fi
echo "Review status: $REVIEW_STATUS"
Status priority:
**Status: APPROVED** (markdown bold - preferred)**Status: CHANGES_REQUESTED** (markdown bold - preferred)Status: APPROVED (plain text - fallback)Status: CHANGES_REQUESTED (plain text - fallback)Multiple reviews: The algorithm processes comments in chronological order. The LAST status found wins, representing the most recent review.
gh pr merge $PR_NUMBER \
--squash \
--delete-branch
If merge fails:
gh issue comment $ISSUE_NUMBER --body "$(cat <<'EOF'
## Completed
Resolved via PR #$PR_NUMBER (squash merged).
### Follow-up issues created:
- #XXX - Description
- #YYY - Description
(Or "No follow-up issues needed.")
EOF
)"
gh issue close $ISSUE_NUMBER
Verify closure:
gh issue view $ISSUE_NUMBER --json state
The --delete-branch flag handles this. Verify:
git ls-remote --heads origin $BRANCH_NAME
If still exists:
git push origin --delete $BRANCH_NAME
Scan all review comments for indicators of follow-up work:
Trigger phrases:
Extract for each:
For each extracted issue:
gh issue create \
--repo OWNER/REPO \
--title "$ISSUE_TITLE" \
--body "$(cat <<'EOF'
## Context
Created from code review of PR #$PR_NUMBER (Issue #$ISSUE_NUMBER)
## Description
$EXTRACTED_DESCRIPTION
## References
- Parent Issue: #$ISSUE_NUMBER
- PR: #$PR_NUMBER
- Reviewer: @$REVIEWER
EOF
)" \
--label "$LABELS"
Log each: Created follow-up issue #XXX: "$TITLE"
When the code reviewer requests changes, spawn a new implementation session:
claude --dangerously-skip-permissions \
--print \
"/implement-issue $ISSUE_NUMBER $BASE_BRANCH" \
2>&1 | tee -a logs/process-pr-rerun-$(date +%Y%m%d-%H%M%S).log
Notes:
/process-pr again to check the new reviewLog:
Changes requested on PR #$PR_NUMBER. Re-running implementation for issue #$ISSUE_NUMBER...
## Process PR Complete
**PR:** #$PR_NUMBER
**Issue:** #$ISSUE_NUMBER
**Status:** ✅ Merged
### Actions Taken
- [x] Review status: APPROVED
- [x] Created N follow-up issues
- [x] PR squash merged
- [x] Issue #$ISSUE_NUMBER closed
- [x] Branch deleted
### Follow-up Issues Created
| Issue | Title | Labels |
|-------|-------|--------|
| #XXX | Description | enhancement |
## Process PR: Changes Requested
**PR:** #$PR_NUMBER
**Issue:** #$ISSUE_NUMBER
**Status:** 🔄 Re-implementing
### Review Feedback
$REVIEW_COMMENTS_SUMMARY
### Action
Re-running /implement-issue $ISSUE_NUMBER $BASE_BRANCH to address requested changes.
| Failure Point | Action |
|---|---|
| Validation fails | Stop, report error |
| No review status in comments | Stop, report - need code review comment with Status line first |
| Issue creation fails | Log warning, continue |
| Merge fails | Stop, return failure, do NOT close issue |
| Issue close fails | Log warning (merge succeeded) |
| Branch delete fails | Log warning (best-effort) |
| Re-implementation fails | Log error, include in output |
Called by:
handle-issues skill (after implement-issue creates PR)/process-pr <pr> <issue> <branch>Calls:
/implement-issue (when changes requested)Requires:
gh CLI authenticated**Status: APPROVED** or **Status: CHANGES_REQUESTED**User: /process-pr 142 130 aw-next
Claude: Using process-pr to process PR #142 for issue #130
Validating... PR #142 open, Issue #130 open
Parsing comments... Status: APPROVED, 1 follow-up found
Creating issue #145: "Add rate limiting to auth endpoint"
Merging PR #142... Squash merge successful
Closing issue #130... done
Deleting branch issue-130-auth-redirect... done
## Process PR Complete
PR: #142 | Issue: #130 | Status: Merged
Follow-up: #145 - Add rate limiting to auth endpoint
User: /process-pr 142 130 aw-next
Claude: Using process-pr to process PR #142 for issue #130
Validating... PR #142 open, Issue #130 open
Parsing comments... Status: CHANGES_REQUESTED
Feedback: "Need to handle edge case when session expires"
Re-running /implement-issue 130 aw-next...
[spawns headless session]
When invoked via batch-orchestrator.sh with --json-schema, this skill's output is parsed for structured data. To ensure reliable extraction, always end your execution with a clear result statement.
At the very end of execution, output a clear status summary. This helps --json-schema reliably extract the structured output.
On successful merge:
## Result
Status: merged
Follow-up issues: #145, #146
On merge with no follow-ups:
## Result
Status: merged
Follow-up issues: none
On changes requested:
## Result
Status: changes_requested
On error:
## Result
Status: error
Error: Merge failed - conflict with base branch
On rate limit:
## Result
Status: rate_limit
Error: GitHub API rate limit exceeded
The batch-orchestrator.sh uses this JSON schema to extract results:
{
"type": "object",
"properties": {
"status": {"enum": ["merged", "changes_requested", "error", "rate_limit"]},
"follow_up_issues": {"type": "array", "items": {"type": "integer"}},
"error": {"type": "string"}
},
"required": ["status"]
}
Important: The final result section must be the last significant output. The --json-schema flag asks Claude to summarize the execution according to this schema, so ending with a clear status makes extraction reliable.