mcpField
G
github-pr-review

github-pr-review

github.com/openhandsテスト・品質17684 回インストール1 日前に更新
リポジトリ

github-pr-review について

GitHub APIを使い、構造化されたPull Requestレビューと行内コメントを投稿するスキルです。フィードバックを1回のレビューにまとめ、行範囲や修正提案を正確に指定する方法も示します。

主な機能

  1. 01GitHub APIでレビューを投稿
  2. 02コメントを1回のレビューに集約
  3. 03差分行に行内コメントを追加
  4. 04提案ブロックに対応
  5. 05Windows PowerShell向けの代替手順

活用シーン

  1. 01Pull Requestレビューの投稿
  2. 02変更行への具体的なコメント
  3. 03小規模なコード修正の提案
  4. 04Windows PowerShellからのレビュー投稿

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/openhands/extensions --skill github-pr-review

インストール後、Claude Code で/github-pr-reviewを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
.plugin/
plugin.json
commands/
github-pr-review.md
references/
windows.md

詳細

GitHub PR レビュー

GitHub API を使用して、特定の行にインラインコメントを付けた構造化コードレビューのフィードバックを投稿します。 JSON ファイルの作成、一時パス、行の検索、フォールバックの curl に相当する Windows PowerShell の手順は、references/windows.md にあります。

重要なルール:API 呼び出しは 1 回

すべてのコメントを1 回のレビュー API 呼び出しにまとめます。コメントを個別に投稿しないでください。

レビューの投稿

GitHub CLI(gh)を JSON 入力ファイルとともに使用します。GITHUB_TOKEN は自動的に利用できます。

重要:-F フラグではなく、必ず JSON ファイルを指定して --input を使用してください。これにより、コメント本文の特殊文字(引用符、バッククォート、改行など)に関するシェルの引用符処理の問題を回避でき、複雑なヒアドキュメントスクリプトも不要になります。

手順 1:JSON ファイルを作成する
cat > /tmp/review.json << 'EOF'
{
  "commit_id": "{commit_sha}",
  "event": "COMMENT",
  "body": "Brief 1-3 sentence summary.",
  "comments": [
    {
      "path": "path/to/file.py",
      "line": 42,
      "side": "RIGHT",
      "body": "🟠 Important: Your comment here."
    },
    {
      "path": "another/file.js",
      "line": 15,
      "side": "RIGHT",
      "body": "🟡 Suggestion: Another comment."
    }
  ]
}
EOF
手順 2:レビューを投稿する
gh api -X POST repos/{owner}/{repo}/pulls/{pr_number}/reviews --input /tmp/review.json
パラメーター
パラメーター説明
commit_idコメント対象のコミット SHA(git rev-parse HEAD を使用)
eventAPPROVE、COMMENT、または REQUEST_CHANGES(下記を参照)
pathdiff に表示されているファイルパス
line新しいバージョンの行番号(diff の右側)
side新規または追加された行には RIGHT、削除された行には LEFT
body優先度ラベルを付けたコメント本文
event の値の選び方
イベント使用する場合
APPROVE問題が見つからない場合、またはブロック要因ではない 🟡 提案のみの場合
COMMENT🟠 重要なフィードバックがあるものの、マージを妨げるものではない場合
REQUEST_CHANGESマージ前に必ず修正すべき 🔴 重大な問題がある場合

コードに問題がなく、マージ可能な状態であれば、デフォルトでは APPROVE を使用してください。対応が必要な問題がある場合に限り、COMMENT または REQUEST_CHANGES を使用してください。

複数行コメント

複数行にまたがるコメントの場合は、対象範囲を指定する start_line を追加します。

{
  "path": "path/to/file.py",
  "start_line": 10,
  "line": 12,
  "side": "RIGHT",
  "body": "🟡 Suggestion: Refactor this block:\n\n```suggestion\nline_one = \"new\"\nline_two = \"code\"\nline_three = \"here\"\n```"
}

start_line と line は、置き換えられる範囲を定義します。 提案ブロックの行数はいくつでもよく、範囲の行数と一致させる必要はありません。正確な動作については次のセクションを参照してください。ここを誤ると、提案によってコードが気付かないうちに削除されたり、重複したりすることがあります。

優先度ラベル

各コメントは優先度ラベルで始めてください。細かな指摘は最小限にし、軽微なスタイルの問題はリンターに任せてください。

ラベル使用する場合
🔴 重大必ず修正:セキュリティの脆弱性、バグ、データ損失のリスク
🟠 重要修正すべき:ロジックエラー、パフォーマンスの問題、エラーハンドリングの不足
🟡 提案検討する価値あり:明確さや保守性の大幅な改善

🟢 軽微な指摘や 🟢 問題なしのコメントは投稿しないでください。 コードに問題がなければ、コメントしないでください。「問題ありません」や「妥当なトレードオフです」といったインラインコメントはノイズです。対応可能な価値を提供しないまま、解決が必要なレビューのスレッドを生み出します。

例:

🟠 Important: This function doesn't handle None, which could cause an AttributeError.

```suggestion
if user is None:
    raise ValueError("User cannot be None")

## GitHub Suggestions

For small code changes, use the suggestion syntax for one-click apply:

~~~
```suggestion
improved_code_here()

Use suggestions for: renaming, typos, small refactors (1-5 lines), type hints, docstrings.

Avoid for: large refactors, architectural changes, ambiguous improvements.

### How Suggestions Actually Work (READ THIS BEFORE WRITING ONE)

A suggestion block **replaces** the targeted range with its contents. The replaced range is:

- `line` only → the single line `line` (replaces 1 line)
- `start_line` + `line` → the inclusive range `start_line..line` (replaces `line - start_line + 1` lines)

The suggestion content can be **any number of lines** — 0 (deletion), 1, or many. It does not have to match the range size. Whatever is between the ` ```suggestion ` and closing ` ``` ` fences becomes the new content of those lines.

Writing the wrong combination of `start_line`/`line` and suggestion body is what causes accepted suggestions to **duplicate** or **delete** code. Use the table below as your contract:

| Intent | `start_line` | `line` | Suggestion body must contain |
|--------|--------------|--------|-------------------------------|
| Change line N | omit | N | the new content for line N |
| Change lines N..M | N | M | the new content for the whole block |
| **Add** a line **after** line N (keep line N) | omit | N | line N's exact current text, then the new line(s) |
| **Add** a line **before** line N (keep line N) | omit | N | the new line(s), then line N's exact current text |
| **Insert** lines inside range N..M (keep N..M) | N | M | every original line in N..M plus the new lines, in the final desired order |
| **Delete** line N | omit | N | empty body (just an empty ` ```suggestion ``` ` block) |
| **Delete** lines N..M | N | M | empty body |

### Common Mistakes That Break Code

1. **Duplicated lines.** You copy a neighboring line (N-1 or N+1) into the suggestion body as context — that line is still present in the file outside the replaced range, so accepting the suggestion inserts a second copy of it. Fix: only include lines that fall within the targeted range, plus any genuinely new content.
2. **Disappearing lines.** You target `start_line=10, line=12` to comment on a 3-line block, but your suggestion body only contains 1 line because you "only want to change line 11". Accepting that suggestion deletes lines 10 and 12. Fix: either narrow the range to just line 11, or include lines 10 and 12 verbatim in the body.
3. **Description does not match the suggestion.** The prose says "rename this variable" but the suggestion replaces an entire function. Or the prose says "add a None check" but the suggestion only contains the check (deleting the original code). Fix: after writing the suggestion, re-read the prose and confirm the resulting file would match it line-for-line.

### Mandatory Verification Before Posting

For every comment that contains a ` ```suggestion ``` ` block, do this check before adding it to the review JSON:

1. Read the actual file lines that will be replaced: `sed -n '<start_line>,<line>p' <path>` (or `sed -n '<line>p' <path>` for a single-line target).
2. Mentally apply the suggestion: drop those lines, splice in the suggestion body, and look at the result in context.
3. Confirm the resulting code matches **exactly** what your prose description promises — no extra duplicated line above/below, no original line accidentally dropped, no off-by-one.
4. If the change cannot be expressed cleanly as a contiguous replacement (e.g., it touches non-adjacent lines, or it depends on edits elsewhere in the file), do **not** use a suggestion block — describe the change in prose instead.

If you are not 100% sure the suggestion will produce the exact code you described, drop the ` ```suggestion ``` ` block and leave a regular inline comment. A correct prose comment is always better than a one-click suggestion that silently corrupts the file.

## Finding Line Numbers

```bash
# From diff header: @@ -old_start,old_count +new_start,new_count @@
# Count from new_start for added/modified lines

grep -n "pattern" filename     # Find line number
head -n 42 filename | tail -1  # Verify line content
```

## Fallback: curl

If `gh` is unavailable, use curl with the JSON file:

```bash
curl -X POST \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}/reviews" \
  -d @/tmp/review.json
```

## Summary

1. Analyze the code and identify important issues (minimize nits)
2. Write review data to a JSON file (e.g., `/tmp/review.json`)
3. Post **ONE** review using `gh api --input /tmp/review.json`
4. Use priority labels (🔴🟠🟡) on every comment
5. Do NOT post comments for code that is acceptable — only comment when action is needed
6. Use suggestion syntax for concrete code changes, but only after verifying the resulting code matches your description (see "How Suggestions Actually Work")
7. Keep the review body brief (details go in inline comments)
8. If no issues: use `"event": "APPROVE"` with a short approval message and no inline comments

コメント