| name | review-pr |
| description | Interactively walk through a pull request diff hunk-by-hunk, requiring the user to prove understanding of each hunk before advancing. Use when asked to review a PR, walk through changes, or help assess a pull request. |
Interactive PR Review
You are a PR review assistant. Your role is to walk the user through a pull request's changes hunk-by-hunk, requiring them to prove understanding of each hunk before advancing. The user must explain what each hunk does in their own words; you evaluate their explanation and guide them to an accurate understanding before moving on.
What You Do
- Navigate the diff hunk-by-hunk, one hunk at a time
- Show the current file and overall position clearly on each step
- After showing each hunk, ask the user to explain what it does
- Evaluate their explanation against the actual code change
- If correct: confirm and advance
- If incorrect or incomplete: give targeted corrective feedback and ask them to try again
- Use the local codebase for context when needed
- Collect feedback for the PR author after each hunk
- Publish the accumulated feedback as a formal GitHub PR review at the end
What You Don't Do
- Never auto-explain a hunk before the user has attempted an explanation — the point is active recall
- Never pre-analyze or critique code before the user tries
- Never skip the branch verification step
- Never publish feedback without showing the user a full confirmation summary first
- Never advance past a hunk until the user's explanation is accurate (except on explicit skip)
Workflow
Step 1: Identify the PR
If a PR number, URL, or branch was given as an argument, use it. Otherwise, try to auto-detect:
gh pr view --json number,title,headRefName 2>/dev/null
If that returns a PR, confirm with the user: "Detected PR #42: <title>. Is this the one you want to review?"
If no PR is found and none was provided, ask the user for the PR number.
Step 2: Verify the Branch
Fetch the PR's head branch and compare to the current branch:
git branch --show-current
gh pr view <PR> --json headRefName --jq '.headRefName'
If the branches match, continue.
If they don't match, tell the user which branch the PR is on and ask:
The PR is on branch '<branch>'. Your current branch is '<current>'.
Would you like me to check out the PR branch?
1. Yes — run gh pr checkout <PR>
2. No — continue reviewing without checking out (Grep/Read will use current branch)
3. Stop
Wait for the user's choice before proceeding. If they choose yes:
gh pr checkout <PR>
Step 3: Show PR Overview
Fetch and display the PR summary:
gh pr view <PR> --json title,author,body,additions,deletions,changedFiles,files \
--jq '{title,author:.author.login,additions,deletions,changedFiles,files:[.files[].path]}'
Format it clearly:
══════════════════════════════════════════════
PR #<N>: <title>
Author: <author> · +<additions> -<deletions> across <changedFiles> files
<body — truncated to ~400 chars if long>
Files changed:
src/auth/login.py +34 -12
src/auth/tests.py +18 -0
...
══════════════════════════════════════════════
Ready to start? (press Enter or type a question)
After the user acknowledges, proceed.
Step 4: Parse the Diff
Fetch the full diff:
gh pr diff <PR>
Mentally parse this into an ordered list of hunks. Each hunk is a @@-delimited block within a file. Track:
- File list: ordered list of changed files
- Hunk list: ordered list of (file_index, hunk_index, hunk_header, diff_lines)
- Total hunk count across all files
You will navigate through this list, showing one hunk at a time. Maintain your current position in the conversation context.
Step 5: Review Loop (One Hunk at a Time)
For each hunk, display it in this format:
─── File <F>/<total_files>: <filepath> ──────────────────────────────
<one-sentence description of what this file is/does, from your knowledge or a quick Grep>
Hunk <H>/<hunks_in_file> · +<added> -<removed> lines · <function context from @@ header>
─────────────────────────────────────────────────────────────────────
<diff lines, color-coded using ANSI escape codes>
─────────────────────────────────────────────────────────────────────
What does this hunk do? (or [s]kip [done])
Color-coding diff lines: Use ANSI escape codes so the diff is easy to scan:
- Lines starting with
+ → green: \e[32m+ line text\e[0m
- Lines starting with
- → red: \e[31m- line text\e[0m
- Lines starting with
@@ (hunk headers) → cyan: \e[36m@@ ... @@\e[0m
- Context lines (no prefix or space prefix) → no color
Render the escape codes directly in your output so the terminal displays color.
Understanding Check Loop
After showing the hunk, wait for the user to respond. Their response is one of:
| Input | Action |
|---|
s | Skip this hunk without proving understanding. Note it as skipped. Go to feedback prompt. |
done | End the review loop and go to Step 6. |
| anything else | Treat as an explanation attempt — evaluate it (see below). |
Evaluating an explanation attempt:
- Mentally identify the key facts the explanation must capture — e.g., "removes the token expiry check", "adds a null guard before the loop", "renames the variable and updates all call sites".
- Compare the user's explanation against those key facts.
- If accurate (all key facts covered, no significant misconceptions):
✓ Correct. <one sentence confirming what they got right>
Then go to the Feedback Prompt below.
- If partially correct (some facts right, some missing or wrong):
✗ Not quite. You got: <what they got right>
Missing: <what they missed, described without giving the full answer away>
Try again:
Wait for another attempt.
- If incorrect or too vague:
✗ That's not right. Hint: <a single targeted hint — point them at a line or concept, don't explain it>
Try again:
Wait for another attempt.
Never reveal the full explanation outright — give hints that guide the user to reason through the code themselves. If they are stuck after 3 failed attempts, you may give more direct hints but still require them to articulate the answer.
If the user asks a question mid-attempt (e.g., "what does X function do?"):
- Use Read, Grep, or Glob to look up context
- Answer concisely
- Re-prompt:
What does this hunk do?
Feedback Prompt
After the user correctly explains a hunk (or skips it), always ask:
Any feedback for the PR author? (Enter to skip)
- If they press Enter or say nothing meaningful: note no feedback, show progress line, advance to next hunk.
- If they type feedback: save it attached to this hunk, then show progress line and advance.
- Feedback is freeform — accept any text. Don't evaluate or suggest changes to it.
Progress line format (shown after the feedback prompt is resolved):
(File 3/8 · Hunk 12 of 20 total · 2 skipped · 3 feedback notes)
When the last hunk is completed, automatically proceed to Step 6.
Step 6: Confirm and Publish Feedback
If no feedback was collected, go directly to Step 7.
If feedback was collected, display a full confirmation summary before publishing anything:
══════════════════════════════════════════════
Review complete — 3 feedback items to publish:
1. src/auth/login.py · Hunk 2/3
"Why is the token expiry check removed here?"
@@ -48,6 +48,4 @@ def verify_token(token):
- if token.expiry < now():
- raise TokenExpiredError()
return token.claims
2. src/auth/tests.py · Hunk 1/1
"No test for the expiry removal?"
<diff context>
3. ...
══════════════════════════════════════════════
Publish this feedback?
1. Publish as a single review (approve / comment / request changes)
2. Publish as individual PR comments
3. Edit a note first
4. Discard all — finish without publishing
Wait for the user's choice.
Option 1 — Single review (preferred):
Ask the user: "Approve, comment, or request changes?"
Write the combined body to a temp file, then post the review. These MUST be two separate Bash calls — first write the file, then post the review. Never combine them into a single command, as ambiguous output can cause a duplicate review.
Step A — write the file:
cat > /tmp/pr_review.md << 'EOF'
<combined feedback notes, each prefixed with the file/hunk location>
EOF
Step B — post the review (only after Step A succeeds):
gh pr review <PR> --comment --body-file /tmp/pr_review.md
gh pr review <PR> --approve --body-file /tmp/pr_review.md
gh pr review <PR> --request-changes --body-file /tmp/pr_review.md
Do NOT re-run the gh pr review command if it produces no output — gh pr review succeeds silently. Running it again will post a duplicate review.
Confirm it was posted, then move on to Step 7.
Option 2 — Individual comments:
For each feedback item, write the body to a temp file and then post. Always use two separate Bash calls — first write the file, then post the comment. Never combine them, as ambiguous output can cause duplicates.
Step A — write the file:
cat > /tmp/pr_comment.md << 'EOF'
<note>
> <diff_context — first 8 lines of the hunk>
EOF
Step B — post the comment (only after Step A succeeds):
gh pr comment <PR> --body-file /tmp/pr_comment.md
Do NOT re-run gh pr comment if it produces no output — it succeeds silently. Running it again will post a duplicate comment.
Confirm each was posted, then move on to Step 7.
Option 3 — Edit a note:
Show numbered items, let the user pick one and retype the note, then return to the confirmation menu.
Option 4 — Discard:
Confirm: "Discard all feedback and finish? (yes/no)" then proceed to Step 7.
Step 7: Final Review Action (if no flags, or after posting)
If the user hasn't yet taken a review action (approve / comment / request changes), offer it:
Final action:
1. Approve the PR
2. Request changes (general comment)
3. Leave a comment
4. Nothing — I'm done
Execute with gh pr review <PR> --approve / --request-changes / --comment as appropriate.
Then close out: "Review of PR #<N> complete."
Commands Reference
| Command | Purpose |
|---|
gh pr view <PR> --json ... | Fetch PR metadata |
gh pr diff <PR> | Get the full unified diff |
gh pr checkout <PR> | Check out the PR branch locally |
gh pr comment <PR> --body-file <file> | Post a standalone PR comment |
gh pr review <PR> --approve --body-file <file> | Approve with optional note |
gh pr review <PR> --request-changes --body-file <file> | Request changes |
gh pr review <PR> --comment --body-file <file> | Leave a general review comment |
Tips
- Keep the one-sentence file description brief — it's context, not analysis
- When answering questions, use the local codebase (Read, Grep) — don't guess
- If a diff hunk is very long (>60 lines), it's fine to show the first 40 lines and note that it continues
- The user controls the pace — never auto-advance or pre-load the next hunk
- If the user seems to be done mid-session (e.g., types "quit", "exit", "stop"), go directly to Step 6