一键导入
github-pr-review
Review a GitHub PR and create a pending (draft) review. Takes an optional PR number; defaults to the PR for the current branch.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Review a GitHub PR and create a pending (draft) review. Takes an optional PR number; defaults to the PR for the current branch.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | github-pr-review |
| description | Review a GitHub PR and create a pending (draft) review. Takes an optional PR number; defaults to the PR for the current branch. |
| disable-model-invocation | true |
Review a GitHub pull request and create a pending (draft) review using gh api. The draft review is only visible to the authenticated user until they submit it from the GitHub UI, where they can edit comments and choose the event type (Approve, Request Changes, or Comment).
Multi-Agent Review: Launch 5 specialized agents (SOLID, Security, Performance, Error Handling, Boundaries) in parallel for comprehensive PR analysis with consistent P0-P3 severity labeling.
/github-pr-review [PR_NUMBER] [--offline]
Parse $ARGUMENTS as follows:
123). If absent, resolve from the current branch.--offline — write review JSON and MD files locally but do NOT post to GitHub. The user can review the output and then publish later by re-running without --offline.Examples:
/github-pr-review — review current branch's PR, post draft/github-pr-review 123 — review PR #123, post draft/github-pr-review --offline — review current branch's PR, write files only/github-pr-review 123 --offline — review PR #123, write files only/github-pr-review 123 (after a previous --offline run) — find existing review and post itgh pr view --json number --jq '.number'
If this fails (no PR for the current branch), stop immediately and tell the user:
No PR found for the current branch. Please provide a PR number:
/github-pr-review <PR_NUMBER>
NEW in v2.0.0: This skill now supports parallel multi-agent review using 5 specialized reviewers.
| Agent | Focus Area | Examples |
|---|---|---|
| solid-reviewer | SOLID Principles + Architecture | SRP violations, god classes, OCP violations |
| security-reviewer | Security Vulnerabilities | SQL injection, XSS, IDOR, hardcoded secrets |
| performance-reviewer | Performance Issues | N+1 queries, O(n²) algorithms, missing cache |
| error-handling-reviewer | Error Handling | Swallowed exceptions, missing error boundaries |
| boundary-reviewer | Boundary Conditions | Null dereference, empty arrays, off-by-one |
All agents use a consistent P0-P3 severity system:
| Level | Name | Action | Event Type |
|---|---|---|---|
| P0 | Critical | Must fix, blocks merge | REQUEST_CHANGES |
| P1 | High | Should fix before merge | REQUEST_CHANGES |
| P2 | Medium | Fix or create follow-up | COMMENT |
| P3 | Low | Optional improvement | APPROVE with notes |
The multi-agent system suggests an appropriate event type in the human-readable summary. The user chooses the actual event type when submitting the review in the GitHub UI:
if (any P0 or P1 findings exist) {
suggested_event = "REQUEST_CHANGES";
} else if (any P2 findings exist) {
suggested_event = "COMMENT";
} else if (any P3 findings exist) {
suggested_event = "APPROVE"; // with notes about P3 issues
} else {
suggested_event = "APPROVE"; // clean PR
}
Note: The event field is never included in the JSON payload. The review is always created as PENDING. The suggested event type is only shown in the .md summary for the user's reference.
gh --version$ARGUMENTS or current branch (see PR Resolution above)event field (always creates PENDING review)/tmp/pr-review-<PR_NUMBER>.json and summary to /tmp/pr-review-<PR_NUMBER>.mdEach agent produces structured findings:
## [Agent Name] Review
### Critical (P0) - Must Fix
- **[File:Line]** Issue description
- Confidence: 95
- Fix: [Suggestion]
### High (P1) - Should Fix
...
The orchestrator combines all agent outputs:
# Consolidated PR Review
## Summary
- **P0 (Critical)**: 2 issues from security-reviewer
- **P1 (High)**: 5 issues from solid-reviewer, performance-reviewer
- **P2 (Medium)**: 8 issues across all agents
- **P3 (Low)**: 3 optional improvements
## 🔴 Critical (P0) - Must Fix
### From Security Review
- **app/auth.ts:45** - Hardcoded API key
- Confidence: 100
- Fix: Move to environment variable
### From Performance Review
- **app/api/users.ts:78** - N+1 query in user list
- Confidence: 90
- Fix: Use eager loading with JOIN
## 🟠 High (P1) - Should Fix
...
Use the orchestrator script:
./commands/multi-agent-review.sh <pr_number> <commit_sha> [output_dir]
Example:
# Get commit SHA first
COMMIT_SHA=$(gh pr view 6 --json commits --jq '.commits[-1].oid')
# Run multi-agent review
./commands/multi-agent-review.sh 6 $COMMIT_SHA /tmp/pr-review-6
# Review the consolidated output
cat /tmp/pr-review-6/consolidated-review.md
All agents use 80+ confidence threshold:
| Score | Meaning | Reported? |
|---|---|---|
| 0-49 | Not confident (false positive) | ❌ No |
| 50-79 | Somewhat confident (nitpick) | ❌ No |
| 80-89 | Confident (real issue) | ✅ Yes |
| 90-100 | Very confident (critical) | ✅ Yes |
The consolidated review maintains agent attribution so reviewers understand:
Example attribution:
- **src/auth.ts:45** - Hardcoded API key (security-reviewer, P0, 100% confidence)
Use Multi-Agent (v2.0.0) for:
Use Manual (v1.x) for:
⚠️ IMPORTANT: Always use JSON payload for reviews with code suggestions.
When using the -f flag with array syntax, backslashes and special characters get escaped, breaking markdown code blocks:
# ❌ PROBLEMATIC: -f flag breaks markdown
gh api .../reviews \
-f 'comments[][body]=Fix this:\n\n```suggestion\nconst x = 1;\n```'
# Result: Backslashes get escaped (\\n\\n instead of \n\n)
# Markdown breaks, suggestions appear as plain text
✅ RECOMMENDED: Always use JSON payload with --input flag
# Create JSON file with proper newlines (no "event" field — creates PENDING review)
cat > /tmp/review.json <<'EOF'
{
"commit_id": "abc123",
"body": "Found 2 issues",
"comments": [
{
"path": "src/file.ts",
"line": 13,
"body": "Fix the import:\n\n```suggestion\nimport { foo } from './bar';\n```"
}
]
}
EOF
# Post with --input (creates pending/draft review)
gh api .../reviews --input /tmp/review.json
| Aspect | Array Syntax (-f) | JSON Payload (--input) |
|---|---|---|
| Markdown rendering | ❌ Breaks with special chars | ✅ Works correctly |
| Type handling | ❌ Numbers become strings | ✅ Types preserved |
| Multiple comments | ❌ Fragile, mixed flags | ✅ Reliable |
| Validation | ❌ Hard to validate | ✅ Can validate first |
| File reuse | ❌ Must recreate each time | ✅ Can save and reuse |
The skill includes helper commands for reliable review posting:
# Validate review JSON before posting
./commands/validate-review.sh <pr_number> <json_file>
# Post review with proper handling
./commands/post-review.sh <pr_number> <json_file>
# Dry run to test
./commands/post-review.sh <pr_number> <json_file> dry_run
Stop if you're thinking:
-f 'body=```suggestion...'" - This will break-f flag should work fine" - It breaks with backticks/github-pr-review or /github-pr-review 123)CRITICAL: Check if gh CLI is installed before attempting to use this skill.
Before starting any PR review workflow, verify the gh CLI is available:
gh --version
If gh is not installed:
The GitHub CLI (gh) is required for this skill but is not installed.
Please install it from: https://cli.github.com/
Installation options:
- macOS: brew install gh
- Windows: winget install GitHub.cli
- Linux: See https://cli.github.com/ for your distro
After installing, authenticate with:
gh auth login
Then try your PR review request again.
Once gh is installed, users must authenticate:
gh auth login
REQUIRED STEPS (do not skip):
gh --version$ARGUMENTS for PR number and --offline/tmp/pr-review-<PR_NUMBER>.json
--offline is NOT set: skip to step 8 (post the existing review)/tmp/pr-review-<PR_NUMBER>.json/tmp/pr-review-<PR_NUMBER>.mdFor small PRs or when the user asks for a focused review on a specific aspect:
gh --version$ARGUMENTS for PR number and --offline/tmp/pr-review-<PR_NUMBER>.json
--offline is NOT set: skip to step 7 (post the existing review)/tmp/pr-review-<PR_NUMBER>.json/tmp/pr-review-<PR_NUMBER>.mdIf --offline is NOT set (default):
~/.claude/skills/github-pr-review/commands/post-review.sh <PR_NUMBER> /tmp/pr-review-<PR_NUMBER>.json no_confirmDraft review created on PR #<PR_NUMBER> with <N> comments.
<severity summary, e.g.: 1 Critical (P0), 3 High (P1), 2 Medium (P2)>
Open the PR on GitHub to review your pending comments and submit the review.
If --offline IS set:
post-review.sh. Do NOT call gh api.mcp__ide__openFile tool is available, use it to open /tmp/pr-review-<PR_NUMBER>.md in the IDE.idea <current_project_dir> /tmp/pr-review-<PR_NUMBER>.md (falls back to open /tmp/pr-review-<PR_NUMBER>.md if idea is not available). The project dir ensures IntelliJ opens the file in the correct window.Review generated for PR #<PR_NUMBER> with <N> comments (offline mode).
<severity summary>
Files written:
/tmp/pr-review-<PR_NUMBER>.md (human-readable summary)
/tmp/pr-review-<PR_NUMBER>.json (API payload)
To publish as a pending draft review:
/github-pr-review <PR_NUMBER>
Use the line and side parameters to specify where a review comment should appear. The position parameter is deprecated (closing down) — do NOT use it.
Per the GitHub docs: "The position parameter is closing down. If you use position, the line, side, start_line, and start_side parameters are not required."
| Parameter | Type | Required | Description |
|---|---|---|---|
line | integer | Yes | The line number in the diff that the comment applies to. For added/modified lines, this is the line number in the new file. For deleted lines, this is the line number in the old file. |
side | string | No | RIGHT (default) for additions and unchanged lines, LEFT for deletions. |
start_line | integer | No | For multi-line comments, the first line of the range. |
start_side | string | No | For multi-line comments, the side of the first line. |
line valuegh pr diff <PR_NUMBER> -- path/to/file.ts@@ hunk header — e.g., @@ -20,9 +22,13 @@ means the old file chunk starts at line 20, the new file chunk starts at line 22+) and context ( ) lines: use the line number from the new file (the + side of the hunk header), counting down-) lines: use the line number from the old file (the - side of the hunk header) and set "side": "LEFT"Example:
@@ -20,9 +20,13 @@ export class AuthManager {
private token: string | null = null; // line 21 (new file)
+ validateToken() { // line 23 (new file)
+ if (!this.token) { // line 24
+ throw new Error('No token'); // line 25
+ } // line 26
+ } // line 27
+
login() { // line 29
To comment on throw new Error('No token'): "line": 25, "side": "RIGHT"
line must fall within a hunk that is part of the PR diff. You cannot comment on lines outside the diff."side": "RIGHT" or omit side entirely (it defaults to RIGHT)."side": "LEFT" when commenting on a deleted line that no longer exists in the new file.CRITICAL: Once a pending review is created, you CANNOT add more comments to it.
Include ALL comments when creating the review. If a batch post fails, fall back to posting comments individually via POST /repos/{owner}/{repo}/pulls/{pull_number}/comments using line/side.
Before posting any review, verify:
commit_id is set to the latest commit SHAcomments[][path] values are non-empty stringscomments[][line] values are positive integers matching lines within the diffcomments[][body] values are non-empty stringsside is "RIGHT" for added/context lines, "LEFT" for deleted lines (or omitted to default to RIGHT)Accept and X-GitHub-Api-Version| Error Message | Cause | Fix |
|---|---|---|
Expected value to not be null (line) | Missing or invalid line value | Ensure line is a positive integer within the diff |
Expected value to not be null (path) | Empty or null path value | Ensure all comments have valid file paths |
Expected value to not be null (body) | Empty or null comment body | Ensure all comments have non-empty text |
Field is not defined on DraftPullRequestReviewComment (side) | Using invalid side parameter | Remove side from all comments |
"comments", "commit_id" are not permitted keys | Trying to update pending review | Delete and recreate, or use individual comments |
Pull request review thread line must be part of the diff | line is outside the diff range | Check gh pr diff to find valid line numbers |
invalid key: "body@-" | Using --raw-field body@- syntax | Use -F body@- or file-based approach |
| Shell command not found errors | Special characters in body causing shell interpretation | Use file-based approach for complex bodies |
Could not comment pull request review | Calling events API on already-submitted review | Review was auto-submitted (you included event in payload) - don't call events API again |
Always use JSON payloads with --input — this avoids all shell escaping issues with backticks, quotes, and code blocks. In JSON, use \n for newlines and escape inner double quotes with \".
# Get commit SHA
gh pr view <PR_NUMBER> --json commits --jq '.commits[-1].oid'
# Get the diff to determine line numbers
gh pr diff <PR_NUMBER>
# Get diff for specific file
gh pr diff <PR_NUMBER> -- path/to/file.ts
commit_id: Latest commit SHA from the PRcomments[][path]: File path relative to repo root (must be non-empty)comments[][line]: Line number in the diff (the file line number from the new file for additions/context, from the old file for deletions)comments[][body]: Comment text with optional ```suggestion block (must be non-empty)comments[][side]: RIGHT (default) for additions/context, LEFT for deleted linescomments[][start_line]: For multi-line comments, the first line of the rangecomments[][start_side]: For multi-line comments, the side of the first lineevent: Omit for PENDING, or use COMMENT/APPROVE/REQUEST_CHANGES--input — never -f/-F array syntaxline/side — never the deprecated position parameterevent in JSON — always create PENDING reviewspath, line, and bodyline must fall within a diff hunkIMPORTANT: When a concrete code fix is available, ALWAYS include a GitHub suggestion block in the comment body. This lets the PR author apply the fix with one click.
In the comment body, use a suggestion code block:
{
"path": "src/file.ts",
"line": 45,
"side": "RIGHT",
"body": "**P1 | Security** Fix the import:\n\n```suggestion\nimport { foo } from './bar';\n```\n\nThe path was incorrect."
}
suggestion block replaces the line specified by line. Make sure the suggested code is complete and correct for that line.start_line and start_side to specify the range, and include all replacement lines in the suggestion block.| Mistake | Fix |
|---|---|
| Re-running full review when JSON already exists | If /tmp/pr-review-<PR>.json exists and --offline is not set, just post it |
| "Only one comment so no need for pending" | Use pending anyway - consistent workflow, allows adding more later |
Forgetting single quotes around comments[][] | Always quote: 'comments[][path]' not comments[][path] |
Using deprecated position parameter | Use line/side instead — position is closing down |
| Not getting commit SHA | Run gh pr view <NUMBER> --json commits --jq '.commits[-1].oid' |
| Using wrong event type | Security/bugs → REQUEST_CHANGES, Style → APPROVE, Questions → COMMENT |
| Null/empty body values | Ensure all comments have non-empty body text |
| Null/empty path values | Ensure all comments have valid file paths |
| Invalid line values | Ensure line falls within a diff hunk — you can only comment on lines in the diff |
| Missing API headers | Always include -H "Accept: application/vnd.github+json" and -H "X-GitHub-Api-Version: 2022-11-28" |
| Trying to update pending review | Cannot update - must include all comments when creating |
Using -f/-F array syntax | Use JSON payload with --input instead |
Including event in JSON then calling events API | Review auto-submits - don't call events API again, or omit event for two-call pattern |
Stop if you're thinking:
event in the JSON" — No. Omit it. Always PENDING.gh api directly instead of post-review.sh" — Use the script; it strips event and handles errors.position parameter" — No. Use line/side.line must fall within a diff hunk./tmp/pr-review-<PR_NUMBER>.json exists and --offline is not set, just post it.ALL of these are wrong. Never include event in the JSON. The review is always PENDING — the user submits from the GitHub UI.
Why PENDING? The review is a draft visible only to the authenticated user:
--dangerously-skip-permissions since nothing is publishedWhy line/side instead of position? GitHub's docs say position is closing down:
line uses the actual file line number — intuitive and less error-proneside specifies LEFT (deletions) or RIGHT (additions/context, default)position required counting lines from @@ hunk headers — fragile and model-unfriendly# 1. Resolve PR and get details
PR_NUMBER=123 # or from: gh pr view --json number --jq '.number'
COMMIT_SHA=$(gh pr view $PR_NUMBER --json commits --jq '.commits[-1].oid')
# 2. Get diff to identify line numbers
gh pr diff $PR_NUMBER > /tmp/pr-diff-$PR_NUMBER.txt
# 3. Build review JSON (no "event" field — always PENDING; use "line"/"side" not "position")
cat > /tmp/pr-review-$PR_NUMBER.json <<'EOF'
{
"commit_id": "<COMMIT_SHA>",
"body": "Found 2 issues.",
"comments": [
{
"path": "src/components/Button.tsx",
"line": 17,
"side": "RIGHT",
"body": "Missing loading state..."
},
{
"path": "src/auth.ts",
"line": 25,
"side": "RIGHT",
"body": "Token validation is missing..."
}
]
}
EOF
# 4. Post as draft review
~/.claude/skills/github-pr-review/commands/post-review.sh $PR_NUMBER /tmp/pr-review-$PR_NUMBER.json no_confirm
# 5. User opens GitHub, reviews pending comments, and clicks "Submit review"
If the API rejects a comment due to its line number:
Verify the line is within the diff:
gh pr diff <PR_NUMBER> -- path/to/file.ts
The line value must fall within a hunk in the diff. You cannot comment on lines outside changed hunks.
Check side is correct:
RIGHT for added/context lines (new file line number)LEFT for deleted lines (old file line number)Use the fallback strategy:
/comments endpointIf creating the pending review fails with multiple comments:
Check for null/empty values:
path values must be non-emptybody values must be non-emptyline values must be positive integers within the diffTry with fewer comments:
Use individual comment posting:
# Create a simple review
gh api repos/:owner/:repo/pulls/123/reviews \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-f commit_id="$COMMIT_SHA" \
-f event="COMMENT" \
-f body="Please see inline comments."
# Add comments individually using line/side
gh api repos/:owner/:repo/pulls/123/comments \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-f commit_id="$COMMIT_SHA" \
-f path="src/file.ts" \
-F line=15 \
-f side="RIGHT" \
-f body="Comment text..."
--dangerously-skip-permissions — pending reviews are private drafts--offline to review generated files before publishing, then re-run without the flag to post