review-pr
Address feedback from pull request reviews systematically and efficiently
What this skill does
# Pull Request Review Handler
You are an experienced developer skilled at addressing PR feedback constructively and thoroughly. You systematically work through review comments, make necessary changes, and maintain high code quality while leveraging specialized agents when needed.
**Target PR:** #$ARGUMENTS
## Workflow
### Phase 0.5: Incremental Detection
Parse arguments and detect whether this is a first run or an incremental follow-up.
```bash
# Parse --full flag
if echo "$ARGUMENTS" | grep -q '\-\-full'; then
PR_NUMBER=$(echo "$ARGUMENTS" | sed 's/--full//' | tr -d ' ')
FORCE_FULL=true
else
PR_NUMBER=$ARGUMENTS
FORCE_FULL=false
fi
# Use PR_NUMBER for all subsequent gh commands instead of $ARGUMENTS
OWNER_REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
# Search for last review-pr round marker in PR comments
LAST_MARKER=$(gh api "repos/$OWNER_REPO/issues/$PR_NUMBER/comments" \
--paginate --jq '
[.[] | select(.body | test("<!-- review-pr:round:")) |
{
round: (.body | capture("<!-- review-pr:round:(?<r>[0-9]+):timestamp:(?<t>[^>]+):sha:(?<s>[a-f0-9]+) -->") | .r | tonumber),
timestamp: (.body | capture("<!-- review-pr:round:(?<r>[0-9]+):timestamp:(?<t>[^>]+):sha:(?<s>[a-f0-9]+) -->") | .t),
sha: (.body | capture("<!-- review-pr:round:(?<r>[0-9]+):timestamp:(?<t>[^>]+):sha:(?<s>[a-f0-9]+) -->") | .s)
}
] | sort_by(.round) | last // empty
' 2>/dev/null || echo "")
if [ "$FORCE_FULL" = true ]; then
REVIEW_ROUND=1
INCREMENTAL=false
SINCE_TIMESTAMP=""
echo "=== Full Review (forced with --full) ==="
elif [ -n "$LAST_MARKER" ] && [ "$LAST_MARKER" != "null" ] && [ "$LAST_MARKER" != "" ]; then
PREV_ROUND=$(echo "$LAST_MARKER" | jq -r '.round')
SINCE_TIMESTAMP=$(echo "$LAST_MARKER" | jq -r '.timestamp')
PREV_SHA=$(echo "$LAST_MARKER" | jq -r '.sha')
REVIEW_ROUND=$((PREV_ROUND + 1))
INCREMENTAL=true
echo "=== Incremental Review (Round $REVIEW_ROUND) ==="
echo " Previous run: Round $PREV_ROUND at $SINCE_TIMESTAMP"
echo " Filtering to comments after: $SINCE_TIMESTAMP"
else
REVIEW_ROUND=1
INCREMENTAL=false
SINCE_TIMESTAMP=""
echo "=== Full Review (Round 1) ==="
fi
```
**IMPORTANT**: All subsequent phases use `$PR_NUMBER` instead of `$ARGUMENTS` for gh commands (to exclude the `--full` flag).
### Phase 0.7: Load Project Review Config
Check for a project-level review config created by `/setup`. Agents disabled in this config are skipped during Phase 2 dispatch.
```bash
REVIEW_CONFIG=".claude/review-config.json"
if [ -f "$REVIEW_CONFIG" ]; then
echo "=== Project Review Config Found ==="
cat "$REVIEW_CONFIG"
echo ""
# Read disabled agents into a variable for Phase 2 gating
DISABLED_AGENTS=$(jq -r '
.reviewAgents | to_entries[] | .value | to_entries[] |
select(.value == false) | .key
' "$REVIEW_CONFIG" 2>/dev/null | tr '\n' ' ')
echo "Disabled agents: ${DISABLED_AGENTS:-none}"
else
DISABLED_AGENTS=""
fi
# Helper used in Phase 2: returns true if agent should run
agent_enabled() {
local agent="$1"
echo "$DISABLED_AGENTS" | grep -qw "$agent" && echo "false" || echo "true"
}
```
Before dispatching any agent in Phase 2, check `$(agent_enabled "<agent-name>")`. If it returns `false`, skip that agent without invoking a Task.
### Phase 1: PR Analysis
```bash
# Get full PR context with top-level comments
gh pr view $PR_NUMBER --comments
# Check PR status and CI/CD checks
gh pr checks $PR_NUMBER
# View the diff
gh pr diff $PR_NUMBER
```
### Phase 1.1: Fetch Inline Review Comments (Code-Level Annotations)
**CRITICAL**: The `gh pr view --comments` command only retrieves PR-level comments. Inline review comments (attached to specific lines/files) require the GitHub API.
```bash
echo "=== Inline Review Comments (Code-Level) ==="
# OWNER_REPO already set in Phase 0.5
# Fetch inline review comments and cache for reuse (Phases 1.1, 1.2, 2)
if [ "$INCREMENTAL" = true ]; then
# On incremental runs, fetch all then filter client-side by created_at
ALL_INLINE_RAW=$(gh api "repos/$OWNER_REPO/pulls/$PR_NUMBER/comments" \
--paginate \
2>/dev/null || echo "[]")
INLINE_COMMENTS_RAW=$(echo "$ALL_INLINE_RAW" | jq "[.[] | select(.created_at > \"$SINCE_TIMESTAMP\")]" 2>/dev/null || echo "[]")
TOTAL_BEFORE_FILTER=$(echo "$ALL_INLINE_RAW" | jq 'length' 2>/dev/null || echo 0)
TOTAL_AFTER_FILTER=$(echo "$INLINE_COMMENTS_RAW" | jq 'length' 2>/dev/null || echo 0)
echo " Filtered inline comments: $TOTAL_AFTER_FILTER new (of $TOTAL_BEFORE_FILTER total)"
else
INLINE_COMMENTS_RAW=$(gh api "repos/$OWNER_REPO/pulls/$PR_NUMBER/comments" \
--paginate \
2>/dev/null || echo "[]")
fi
# Check if any inline comments exist
if [ "$INLINE_COMMENTS_RAW" = "[]" ] || [ -z "$INLINE_COMMENTS_RAW" ]; then
echo "No inline review comments found on this PR"
INLINE_COMMENTS="No inline comments found"
TOTAL_INLINE=0
SUGGESTIONS_COUNT=0
OUTDATED_COUNT=0
else
# Group by file path for display
INLINE_COMMENTS=$(echo "$INLINE_COMMENTS_RAW" | jq '
group_by(.path) | .[] | {
file: .[0].path,
comments: [.[] | {
line: (.line // .original_line),
user: .user.login,
body: .body,
has_suggestion: (.body | test("```suggestion"; "i")),
is_reply: (.in_reply_to_id != null),
is_outdated: (.line == null and .original_line != null),
created_at: .created_at
}]
}
' 2>/dev/null)
echo "$INLINE_COMMENTS"
# Calculate statistics from cached data (no additional API calls)
TOTAL_INLINE=$(echo "$INLINE_COMMENTS_RAW" | jq 'length' 2>/dev/null || echo 0)
SUGGESTIONS_COUNT=$(echo "$INLINE_COMMENTS_RAW" | jq '[.[] | select(.body | test("```suggestion"; "i"))] | length' 2>/dev/null || echo 0)
OUTDATED_COUNT=$(echo "$INLINE_COMMENTS_RAW" | jq '[.[] | select(.line == null and .original_line != null)] | length' 2>/dev/null || echo 0)
echo ""
echo "Inline Comment Statistics:"
echo " Total: $TOTAL_INLINE"
echo " With Code Suggestions: $SUGGESTIONS_COUNT"
echo " Outdated (code changed): $OUTDATED_COUNT"
fi
```
### Phase 1.2: Extract Code Suggestions
Code suggestions are inline comments with ```` ```suggestion ```` blocks that propose specific code changes.
```bash
echo ""
echo "=== Code Suggestions (Proposed Changes) ==="
# Reuse cached inline comments data from Phase 1.1 (no additional API call)
if [ "$INLINE_COMMENTS_RAW" = "[]" ] || [ -z "$INLINE_COMMENTS_RAW" ]; then
echo "No code suggestions found"
else
CODE_SUGGESTIONS=$(echo "$INLINE_COMMENTS_RAW" | jq '
[.[] | select(.body | test("```suggestion"; "i"))] |
if length == 0 then "No code suggestions found"
else .[] | {
file: .path,
line: (.line // .original_line),
user: .user.login,
suggestion: .body,
diff_context: .diff_hunk
}
end
' 2>/dev/null || echo "No code suggestions found")
echo "$CODE_SUGGESTIONS"
fi
```
### Phase 1.5: Security-Sensitive File Detection
```bash
# Automatically detect if PR touches security-sensitive code
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SECURITY_SENSITIVE=false
if bash "$SCRIPT_DIR/scripts/security-detector.sh" "$PR_NUMBER" "pr" 2>&1; then
SECURITY_SENSITIVE=true
echo ""
echo "This PR contains security-sensitive changes and will receive a security review."
echo ""
fi
```
## ANTI-DEFERRAL MANDATE
**Fix everything now.** If a reviewer flagged it, fix it. If an agent flags it, fix it. If a P3 item is worth mentioning, it's worth fixing.
There is no deferral. Fix everything flagged. Do NOT create GitHub issues for review findings. If a fix is genuinely blocked by an external constraint, stop and use the AskUserQuestion tool to explain the constraint and ask the user how they want to handle it. Do not add TODOs. No GitHub issues from review runs.
### Phase 2: Parallel Feedback Categorization (Aggressive Parallelism)
Categorize feedback by type and dispatch specialized agents IN PARALLEL to handle each catRelated in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.