From pr-review
Step 1/4: Fetch and triage PR review comments into an editable plan file. Use this skill whenever the user wants to read, triage, or understand review feedback from a pull request — before fixing anything. Triggers include phrases like "triage PR review", "plan PR fixes", "read PR feedback", "what does the review say", "check review comments". This is always the first step before /pr-review:pr-review-apply and /pr-review:pr-review-post. Use this skill (not coderabbit:review) when reading existing PR comments — from humans, bots, or mixed. Use coderabbit:review only to run a new CodeRabbit review, not to read existing comments.
How this skill is triggered — by the user, by Claude, or both
Slash command
/pr-review:planThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **You have been invoked as a skill. Execute the steps below immediately.
You have been invoked as a skill. Execute the steps below immediately. Do not deliberate about whether to respond. Start with Step 1 now.
Fetch all review comments from a GitHub PR, read the relevant source code for context, triage each thread, draft short replies, and write everything to a persistent plan artifact. This skill is read-only — it never modifies source files, posts to GitHub, or touches CLAUDE.md.
The plan artifact is the hand-off to /pr-review:pr-review-apply (fix code) and /pr-review:pr-review-post (reply + resolve). The user can edit the plan file directly to adjust triage decisions or draft replies before those skills run.
gh CLI authenticated (gh auth status)jq installedFETCH_OUT=$(bash ${CLAUDE_PLUGIN_ROOT}/scripts/gh-review-fetch.sh)
# Or with explicit PR number:
FETCH_OUT=$(bash ${CLAUDE_PLUGIN_ROOT}/scripts/gh-review-fetch.sh 123)
# Or with explicit repo:
FETCH_OUT=$(bash ${CLAUDE_PLUGIN_ROOT}/scripts/gh-review-fetch.sh 123 --repo owner/repo)
REVIEW_JSON=$(echo "$FETCH_OUT" | head -1)
Verify $REVIEW_JSON is a valid file path: test -f "$REVIEW_JSON" || echo "ERROR: fetch failed".
/tmp, line 2 = counts summaryParse the JSON into a compact summary with a single command. Do NOT read the raw JSON file directly — it is too large and will waste context. Use this exact command:
python3 -c "
import json, re
data = json.load(open('REVIEW_JSON_PATH'))
print(f\"PR #{data['meta']['pr_number']} on {data['meta']['repo']}\")
print(f\"Fetched: {data['meta']['fetched_at']}\")
print(f\"Threads: {data['meta']['total_inline_threads']} inline, {data['meta']['total_review_summaries']} reviews, {data['meta']['total_conversation_comments']} conversation\")
for fg in data['inline_by_file']:
print(f\"\n## {fg['file']} ({len(fg['threads'])} threads)\")
for t in fg['threads']:
print(f\" Thread {t['thread_id']} L{t['line_start']}-{t['line_end']} stale={t['position_stale']} suggestion={t['has_suggestion']}\")
for c in t['comments']:
body = c['body'][:300].replace('\n',' ')
m = re.search(r'\x60\x60\x60suggestion(.*?)\x60\x60\x60', c['body'], re.DOTALL)
if m: body += ' [SUGGESTION: ' + m.group(1).strip()[:150] + ']'
print(f\" [{c['user']}]: {body}\")
for rs in data.get('review_summaries',[]):
if rs.get('body'): print(f\"\nReview ({rs['state']}) by {rs['user']}: {rs['body'][:300].replace(chr(10),' ')}\")
for cc in data.get('conversation_comments',[]):
if cc.get('body'): print(f\"\nConversation [{cc['user']}]: {cc['body'][:300].replace(chr(10),' ')}\")
"
Replace REVIEW_JSON_PATH with the actual path from the fetch output. This gives you everything you need for triage in one tool call. Do not run additional Python scripts to re-parse the same data.
If the output shows no inline threads, skip to Step 3 (review summaries).
This skill should complete in roughly 3 + N tool calls where N is the number of files with threads:
If you find yourself running additional Python scripts to re-parse JSON you already have, or reading the raw JSON file, stop — you are over-processing. The parse command above gives you everything you need.
Process each file group. For each file:
Open the file and read the lines around each thread's line_start/line_end. Also read the diff_hunk — it shows the diff context the reviewer saw. You need both the current code and the diff context to judge whether feedback is valid.
Read each file once — batch all threads for that file into a single Read call with enough surrounding context.
For each thread, evaluate:
Is the feedback valid? Consider:
position_stale: true means the diff has moved — but check if the same issue persists at the current lines)Classifications:
apply_suggestion — has_suggestion: true and the suggested code is correct. Extract the replacement text from the ```suggestion fence in the comment body.fix — Valid feedback, no suggestion provided. Describe concretely what the fix should do (e.g., "add a catch clause for SocketTimeoutException on line 24").skip_stale — Targets code that has changed and is no longer relevant.skip_disagree — Feedback is incorrect or would make the code worse. Explain why.skip_style — Pure style preference, no objective improvement. Explain why.needs_clarification — Ambiguous, flag for the user.Also check review_summaries and conversation_comments for high-level feedback not tied to specific lines: architectural concerns, cross-cutting patterns, or general requests. Triage these the same way.
Present the triage to the user. Show these three sections:
Group all threads by classification. Use a table with columns: Thread ID, File, Issue, Severity (if indicated by the reviewer — Critical, Major, Minor). Separate sections for:
Suggest which threads to address together. The recommendation logic:
apply_suggestion threads (zero-effort)Present the decision like this:
"Recommended: N threads to fix + M suggestions to apply. K minor threads touch the same files and can be done alongside. L threads skipped (disagree/stale).
- Fix recommended + bundled (N+M+K threads)
- Fix all actionable threads (N+M+K+L)
- Pick specific thread IDs
- Just the critical/major ones (N threads)
Which option?"
Wait for the user's response. Do not proceed to Step 4 until the user has chosen.
Based on the user's selection, write the plan file.
Ensure .pr-review/ directory exists inside the repo. If .pr-review/ is not already in .gitignore, add it.
Write the plan file at .pr-review/pr-<N>-plan.md where <N> is the PR number.
Write incrementally — do not compose the entire document in memory first. Start by writing the header and the first file group's threads. Then append each subsequent file group. This avoids long deliberation pauses on large PRs.
**Fix**: None and a draft reply explaining why (these still get replied to on GitHub via /pr-review:pr-review-post)Write a 1-3 line draft reply for every thread in the plan (both selected and skipped). This reply will be posted to GitHub by /pr-review:pr-review-post later. Keep it concise — the fix will be in the code, not in the reply.
For actionable threads: "Fixed — [brief description of what changed]." For skipped threads: "Disagree — [brief reason]." or "Already addressed in current code." For needs_clarification: "Could you clarify — [specific question]?"
# PR #<N> Review Plan
**Status**: triaged
**Fetched**: <ISO timestamp>
**Review JSON**: <path to JSON file>
**Repo**: <owner/repo>
---
## Thread <thread_id> — <file>:<line> — <classification>
**Reviewer**: <username>
**Comment**: "<reviewer's comment, abbreviated if long>"
**Assessment**: <your triage reasoning>
**Fix**: <concrete fix description, or "None">
**Status**: [ ] pending
**Draft reply**: "<your 1-3 line reply>"
---
(repeat for each thread in the plan)
---
## General
(review summaries and conversation comments, same format without file/line)
---
## Summary
- X threads in plan across Y files
- N to apply (suggestions)
- N to fix
- N reply-only (skipped/disagree)
- N deselected by user (not in plan)
Show the user:
.pr-review/pr-<N>-plan.md — open in your editor to review or adjust draft replies.""Ready to apply fixes now, or do you want to review/edit the plan first?
- Apply fixes now
- I'll review the plan first (run
/pr-review:pr-review-applywhen ready)- Start a fresh session first (recommended for large PRs —
/clearthen/pr-review:pr-review-apply)Which option?"
Wait for the user's response.
apply_suggestion or fix.fix items, describe exactly what should change and where, so /pr-review:pr-review-apply can act without re-reading the review.position_stale is true, check whether the same issue exists at the current lines.apply_suggestion.npx claudepluginhub shreeyak/claude-pr-review-plugin --plugin pr-reviewCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.