Agent Skills: PR Review Tour Guide

|

UncategorizedID: jontsai/claude-plugins/review-pr

Install this agent skill to your local

pnpm dlx add-skill https://github.com/jontsai/claude-plugins/tree/HEAD/plugins/review-pr/skills/review-pr

Skill Files

Browse the full folder contents for review-pr.

Download Skill

Loading file tree…

plugins/review-pr/skills/review-pr/SKILL.md

Skill Metadata

Name
review-pr
Description
|

PR Review Tour Guide

Generate a structured, guided tour of a Pull Request that helps reviewers understand changes efficiently. Acts as a knowledgeable guide walking someone through a codebase change.

Automatic Invocation Triggers

Claude will invoke this skill when you:

  • Ask to "review PR #123" or "review this PR"
  • Say "walk me through this PR"
  • Request "PR tour guide" or "explain this PR"
  • Ask "what should I look for in this PR"
  • Say "create a PR review walkthrough"
  • Request "review and approve PR #123" (triggers review with approval workflow)

Overview

This skill creates a guided tour of PR changes that:

  • Orders files logically (as GitHub UI shows - depth-first with folders before files)
  • Groups review points into digestible stops (no more than ~25 lines per stop)
  • Provides context about why code exists and its history
  • Highlights review priorities (what needs rigorous review vs. rubber-stamp)
  • Uses landmarks (line numbers, class/function names) for easy navigation

Input Requirements

The skill needs:

  1. PR number and repository (e.g., "PR #3091 in altimate-backend")
  2. OR a PR URL (e.g., "https://github.com/owner/repo/pull/3091")
  3. Optionally, a linked issue/ticket for context comparison (GitHub Issues, Jira, Linear, etc.)

Operation Mode Detection

Before starting the review, detect the operation context to determine default behavior:

Detecting Operation Mode

CLI Mode Indicators (weight toward local display first):

  • Running in Claude Code CLI directly
  • User is interactively typing commands
  • Terminal/TTY is available
  • No delegation context detected

Pass-Through/Delegated Mode Indicators (weight toward inline GitHub comments):

  • Request came via OpenClaw or similar delegation tool
  • Request came from automation/CI context
  • Request mentions "post comments" or "leave feedback on PR"
  • No interactive terminal available

Default Behavior by Mode

| Mode | Default Action | Rationale | |------|---------------|-----------| | CLI (interactive) | Display review locally first, then offer to post | User can review and edit before posting | | Pass-through/Delegated | Post inline comments directly (if confident) | Automation context benefits from persistent comments |

If unsure about mode: Ask the user: "Would you like me to display the review here first, or post comments directly on the PR?"

Workflow

Step 1: Gather PR Information

# Get PR metadata
gh pr view <PR_NUMBER> --repo <OWNER/REPO> --json title,body,additions,deletions,changedFiles,files,commits

# Get the full diff
gh pr diff <PR_NUMBER> --repo <OWNER/REPO>

# If linked issue/ticket provided, fetch details based on tracker type:
# - GitHub Issues: gh issue view <ISSUE_NUMBER> --repo <OWNER/REPO>
# - Jira: Use mcp__atlassian__getJiraIssue or API
# - Linear: Use Linear MCP or API
# - Other trackers: Use appropriate MCP or API

Step 2: Analyze and Order Files

Order files using depth-first traversal (folders before files):

  1. At each directory level, process subdirectories first (alphabetically), recursively
  2. Then process files in the current directory (alphabetically)
  3. This ensures reviewers see related nested changes together before sibling files

Example ordering:

app/
  models/
    user.py          # 1. Deepest nested first
    account.py       # 2. Same level, alphabetical
  services/
    auth.py          # 3. Next subdirectory
  utils.py           # 4. Files in app/ after all subdirectories
config/
  settings.py        # 5. Next root subdirectory
main.py              # 6. Root-level files last

Create a summary table:

| # | File | +/- | Purpose |
|---|------|-----|---------|
| 1 | `path/to/file1.py` | +50/-10 | Brief purpose |
| 2 | `path/to/file2.py` | +20/-5 | Brief purpose |

Step 3: Generate Tour Stops

For each significant change, create a "tour stop" with:

### Stop N: [Descriptive Title] (Lines X-Y)

[Code snippet or reference]

**Context:** Why this code exists, what problem it solves

**Notice:** What the reviewer should observe about this change

**Review:**
- [Checkbox] Items that need careful review
- [Warning] Potential issues or risks
- [Check] Items that look good

Step 4: Prioritize Review Areas

Use these markers:

  • RIGOROUSLY REVIEW - Security, data integrity, breaking changes
  • Notice - Important but straightforward changes
  • Context - Background information
  • Warning - Potential issues or edge cases

Step 5: Create Summary Checklist

End with actionable review checklist:

## Summary Checklist

| Area | Status | Action |
|------|--------|--------|
| Core logic | [Status] | [Action needed] |
| Error handling | [Status] | [Action needed] |
| Tests | [Status] | [Action needed] |

Output Format

# PR #[NUMBER] Review Tour Guide

## File Order (as shown in GitHub UI)

| # | File | +/- | Purpose |
|---|------|-----|---------|
| 1 | `file1.py` | +50 | Description |

---

## File 1: `path/to/file1.py`

**This is the [main/supporting] file. [Brief overview].**

---

### Stop 1: [Section Title] (Lines X-Y)

```python
# Relevant code snippet (abbreviated)

Context: [Why this exists]

Notice: [What to observe]

Review:

  • [Review point]
  • [Warning if any]

Stop 2: [Next Section] (Lines A-B)

[Continue pattern...]


Summary Checklist

| Area | Status | Action | |------|--------|--------| | Item | Status | Action |


## Tour Stop Guidelines

### Grouping Rules

1. **One function/class per stop** - Don't mix unrelated changes
2. **Max ~25 lines of code** - Keep stops digestible
3. **Group related small changes** - Multiple one-liners can share a stop
4. **Separate concerns** - Config changes vs. logic changes vs. tests

### What to Call Out

**Always mention:**
- Breaking changes to public APIs
- Security-sensitive code (auth, crypto, user input)
- Database schema changes
- External service integrations
- Error handling patterns
- Performance implications

**Highlight patterns:**
- Code that duplicates existing functionality
- Missing error handling
- Hardcoded values that should be configurable
- Tests that don't actually test the change

### Context Sources

Provide context from:
- Linked issue/ticket description (GitHub Issues, Jira, Linear, etc.)
- PR description and commits
- Related code in the codebase
- Previous implementations being replaced

## Example Tour Stop

```markdown
### Stop 7: Row Processor - Column Count (Lines 802-830) - CRITICAL BUG FIX

```python
def _process_column_count_row(self, row: dict) -> dict:
    table_rk = _get_snowflake_table_rk(
        table, self.is_instance_default, self.instance_id
    )
    column_rk = _get_column_rk_from_table_rk(table_rk, column) if table_rk else None
    #                                                         ^^^^^^^^^^^^^^^^^^^^^^

Context: This is the bug fix from commit a187cd4c. Previously, when table_rk was None, _get_column_rk_from_table_rk(None, column) would return "none/column_name" - a string that bypassed skip logic.

Review:

  • Good fix - now column_rk is None when table_rk is None
  • Verify: Does the original class have this same bug? If so, should it be fixed there too?

## Comparison with Linked Issue/Ticket

When a linked issue or ticket is provided (GitHub Issue, Jira, Linear, etc.):

### Step 1: Detect and Fetch Ticket Details

**GitHub Issues:**
```bash
gh issue view <ISSUE_NUMBER> --repo <OWNER/REPO> --json title,body,labels,assignees

Jira:

  • Use Atlassian MCP: mcp__atlassian__getJiraIssue
  • Or Jira REST API

Linear:

  • Use Linear MCP or GraphQL API
  • Extract issue details from Linear URL

Other Trackers:

  • Use appropriate MCP integration if available
  • Fall back to URL/description provided by user

Step 2: Extract and Compare Requirements

  1. Parse requirements from issue/ticket description
  2. Create comparison table:
### Issue vs. Implementation Comparison

| Requirement | Status | Notes |
|-------------|--------|-------|
| Item from issue | Implemented/Missing/Partial | Details |
  1. Call out discrepancies between issue requirements and implementation
  2. Note any scope changes - features added or removed from original spec

Review Modes

The skill supports three modes, with defaults based on operation context and confidence:

Mode Selection Logic

1. Detect operation mode (CLI vs pass-through)
2. Assess confidence in review findings
3. Select mode based on:
   - High confidence + Pass-through → Post inline comments directly
   - High confidence + CLI → Display locally, offer to post
   - Low confidence (any mode) → Display locally, discuss before posting

Mode 1: CLI Display (Default for interactive CLI)

Display the tour guide in the Claude session. User reviews in terminal.

Use when:

  • Running in Claude Code CLI interactively
  • Low confidence in findings (need discussion)
  • User wants to review before posting

Mode 2: Inline PR Comments (Default for pass-through when confident)

Post inline comments directly on the PR using conventional comment labels.

Use when:

  • High confidence in findings
  • Running via pass-through tool (OpenClaw, automation)
  • User explicitly requests inline comments

Mode 3: PR Comments ("Tour Guide" Mode)

Leave # Reviewer Note comments on the PR to guide human reviewers through the UI.

Use when: Team collaboration, asynchronous review, onboarding reviewers.

Confidence-Based Behavior

High Confidence (post directly in pass-through mode):

  • Clear, well-scoped changes
  • Familiar patterns and codebase conventions
  • No ambiguous or risky areas
  • Comments are objective observations or standard suggestions

Low Confidence (always discuss locally first):

  • Complex or unfamiliar code patterns
  • Potential security or architectural concerns
  • Ambiguous requirements or unclear intent
  • Comments that might need human judgment on tone/priority

Posting Inline PR Comments

Workflow Based on Confidence and Mode

The workflow varies based on confidence level and operation mode:

High Confidence + Pass-Through Mode: Post Directly

When running via delegation (OpenClaw, automation) AND confident in findings:

1. COMPLETE REVIEW
   - Generate full tour guide (all files, all stops)
   - Assess confidence in each finding

2. POST COMMENTS DIRECTLY
   - Batch post all comments at once
   - Verify each landed on correct line
   - Report summary of posted comments

Low Confidence OR CLI Mode: Discuss First

When confidence is low OR running interactively in CLI:

1. COMPLETE LOCAL REVIEW
   - Generate full tour guide (all files, all stops)
   - Identify all issues, suggestions, and considerations
   - Compile into a summary for human review

2. PRESENT FINDINGS TO HUMAN
   - Show summary of all proposed comments
   - Include: file, line, label, message for each
   - Flag any low-confidence items
   - Ask: "Would you like me to post these as inline
          comments on the PR?"

3. HUMAN APPROVAL
   - Human reviews proposed comments
   - Human may: approve all, modify some, reject some
   - Human confirms which comments to post

4. BATCH POST APPROVED COMMENTS
   - Post all approved comments at once
   - Verify each landed on correct line
   - Report back with links to posted comments

Why discuss first for low confidence:

  • Prevents posting comments the human might disagree with
  • Allows human to adjust tone, wording, or priorities
  • Ensures comments represent the human reviewer's voice
  • Batch posting is less noisy for PR author

Prerequisites

# Get PR head commit SHA (required for comments)
gh pr view <PR_NUMBER> --json headRefOid --jq '.headRefOid'

# Save diff to temp file for analysis
gh pr diff <PR_NUMBER> > /tmp/pr_diff_<PR_NUMBER>.txt

Conventional Comment Labels

Use these prefixes for professional code review comments:

| Label | Use Case | Example | |-------|----------|---------| | suggestion: | Improvements, refactoring ideas | "suggestion: Extract to shared constants file" | | thought: | Considerations, questions for discussion | "thought: Verify backend API compatibility" | | nit: | Minor style/formatting issues | "nit: Use Tailwind classes instead of inline styles" | | question: | Clarification needed | "question: Is this intentional behavior?" | | praise: | Good patterns worth noting | "praise: Nice use of early returns" | | issue: | Bugs or problems found | "issue: This will throw if array is empty" |

Calculating Diff Positions

The GitHub API uses position (line number within the file's diff section), NOT the actual file line number.

Strategy:

  1. Save diff to temp file:

    gh pr diff <PR_NUMBER> > /tmp/pr_diff_<PR_NUMBER>.txt
    
  2. Find where file starts in diff:

    grep -n "^diff --git.*<filename>" /tmp/pr_diff_<PR_NUMBER>.txt
    # Example: Returns "38:" meaning file diff starts at line 38
    
  3. Find target line in diff:

    grep -n "<search_pattern>" /tmp/pr_diff_<PR_NUMBER>.txt
    # Example: Returns "81:" meaning target is at diff line 81
    
  4. Calculate position:

    position = target_diff_line - file_start_diff_line
    # Example: position = 81 - 38 = 43
    

Posting Comments via gh api

JSON payload approach (handles complex comment bodies):

cat > /tmp/review_comment.json << 'EOF'
{
  "body": "**suggestion:** Consider extracting `PRODUCT_COLORS` to a shared constants file.\n\nThis configuration is duplicated in 4 files.",
  "commit_id": "<HEAD_COMMIT_SHA>",
  "path": "src/path/to/file.tsx",
  "position": 43
}
EOF

gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/comments --input /tmp/review_comment.json

Verify comment placement:

# Check which line the comment landed on
gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/comments \
  --jq '.[] | {file: .path, line: .line, body: .body[0:50]}'

Common Position Calculation Examples

For a file like api.ts with multiple hunks:

Diff structure:
Line 1:  diff --git a/src/api.ts
Line 5:  @@ -36,6 +36,8 @@   <- First hunk
Line 14: @@ -185,6 +187,14 @@ <- Second hunk
Line 29: @@ -602,6 +612,8 @@   <- Third hunk
Line 34: +    sort_order?: string;  <- Target line

Position for sort_order = 34 - 4 (header lines) = 30

Cleanup

# Delete duplicate/incorrect comments
gh api -X DELETE repos/<OWNER>/<REPO>/pulls/comments/<COMMENT_ID>

# List your comments to verify
gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/comments \
  --jq '.[] | select(.user.login == "<YOUR_USERNAME>") | {id, file: .path, line: .line}'

Fetching File Content from PR Branch

When local files don't exist (PR not checked out), fetch from GitHub:

# Get PR branch name
BRANCH=$(gh pr view <PR_NUMBER> --json headRefName --jq '.headRefName')

# Fetch file content and find line numbers
gh api repos/<OWNER>/<REPO>/contents/<FILE_PATH>?ref=<BRANCH> \
  --jq '.content' | base64 -d | grep -n "<SEARCH_PATTERN>"

This is useful for:

  • Verifying exact line numbers in the new code
  • Finding additional context not visible in the diff
  • Confirming patterns exist in multiple files

Complete Workflow Example

# 1. Get commit SHA
COMMIT=$(gh pr view 1999 --json headRefOid --jq '.headRefOid')

# 2. Save diff
gh pr diff 1999 > /tmp/pr_diff_1999.txt

# 3. Find position (example: PRODUCT_COLORS in DatabricksCostChartTooltip.tsx)
FILE_START=$(grep -n "^diff --git.*DatabricksCostChartTooltip" /tmp/pr_diff_1999.txt | cut -d: -f1)
TARGET=$(grep -n "PRODUCT_COLORS" /tmp/pr_diff_1999.txt | head -1 | cut -d: -f1)
POSITION=$((TARGET - FILE_START))

# 4. Post comment
cat > /tmp/comment.json << EOF
{
  "body": "**suggestion:** This configuration is duplicated in 4 files. Consider extracting to shared constants.",
  "commit_id": "$COMMIT",
  "path": "src/pages/databricks/components/DatabricksCostChartTooltip.tsx",
  "position": $POSITION
}
EOF

gh api repos/<OWNER>/<REPO>/pulls/1999/comments --input /tmp/comment.json

Troubleshooting

Comment lands on wrong line:

  • Position calculation was off
  • Delete incorrect comment: gh api -X DELETE repos/.../pulls/comments/<ID>
  • Recalculate position and retry

"position" not found error:

  • The line may not be in the diff (unchanged code)
  • Can only comment on lines that appear in the diff
  • Try finding a nearby changed line

Multiple hunks in file:

  • Position is cumulative across all hunks
  • Count from diff --git line, not from each @@ hunk header

Approval Workflow

When user requests "review and approve" or similar:

CRITICAL: Never Auto-Approve

Do NOT automatically approve a PR. Even if the user says "review and approve", follow this workflow:

  1. Complete the full review using the tour guide process
  2. Assess the PR for red flags, risks, and correctness
  3. Present findings to the user with your confidence assessment
  4. Ask for user's confidence level before approving

Approval Decision Tree

1. Complete review
   ↓
2. Any red flags found?
   → YES: Present concerns, do NOT approve, recommend changes
   → NO: Continue to step 3
   ↓
3. Assess risk level and correctness confidence
   ↓
4. Present to user:
   "No red flags found. [Summary of changes].
    Risk level: [low/medium/high]
    My confidence: [high/medium/low]

    Would you like me to approve? Please confirm your confidence level."
   ↓
5. User confirms confidence
   ↓
6. Approve with appropriate semantic message

Semantic Approval Messages

Use these approval messages based on confidence level:

| Message | Meaning | When to Use | |---------|---------|-------------| | LGTM | Looks Good To Me | High confidence. Code is correct, well-written, follows best practices. Would approve without hesitation. | | lgtm | looks good to me | Lower confidence/less emphatic. Code appears correct but haven't verified exhaustively. Quieter approval. | | LFTM | Looks Fine To Me | High confidence shipping won't break anything. No major concerns, but not necessarily exceptional code. Pragmatic approval. | | lftm | looks fine to me | Lower confidence. No red flags visible, but recommend user has fully tested and is confident before merging. |

Approval Criteria

Approve (LGTM/lgtm) when:

  • Code logic is verifiably correct
  • Tests cover the changes adequately
  • No security concerns
  • Follows codebase conventions
  • PR description matches implementation

Approve (LFTM/lftm) when:

  • No red flags or obvious issues
  • Unable to fully verify correctness without running tests
  • Changes are low-risk (config, copy, minor refactors)
  • User has context you don't have

Do NOT approve when:

  • Any security concerns exist
  • Logic errors are present
  • Tests are missing for critical paths
  • Breaking changes aren't documented
  • You have unresolved questions about intent

Posting Approval

# Approve with comment
gh pr review <PR_NUMBER> --approve --body "LGTM - [brief summary of why]"

# Or with more detail
gh pr review <PR_NUMBER> --approve --body "$(cat <<'EOF'
LGTM

✓ Logic looks correct
✓ Tests cover the changes
✓ Follows existing patterns

Ship it!
EOF
)"

Quality Guidelines

DO:

  • Lead with the most important/risky changes
  • Provide enough context for someone unfamiliar with the code
  • Use specific line numbers and function names
  • Highlight both good patterns and concerns
  • End with actionable next steps
  • Use conventional comment labels for consistency
  • Verify comment positions landed correctly

DON'T:

  • List every line changed
  • Provide context without review guidance
  • Skip over complex logic
  • Assume reviewer knows the codebase
  • Leave concerns without suggested actions
  • Use scary language like "Risk" - prefer neutral terms like "Consideration"

Version: 1.0.0