review-gitlab について
review-gitlabはGitLabのマージリクエスト向けコードレビュースキルです。投稿前に指摘内容を確認したい開発者を対象とし、分析は読み取り専用で行い、承認後にコメントを投稿する二段階方式を採用しています。指摘にはClaude Code向けの修正プロンプトも含まれます。
主な機能
- 01変更規模に応じた分割レビュー
- 02バグ・セキュリティ・性能・型の確認
- 03既存コメントを参照して重複を回避
- 04指摘ごとの修正プロンプト作成
- 05承認後のGitLabコメント投稿
活用シーン
- 01大規模なマージリクエストを詳細にレビュー
- 02投稿前に指摘内容を確認・承認
- 03既出の問題と修正状況を追跡
- 04Claude Code向けの修正指針を用意
MCP 対応
このスキルはGitLab MCPサーバーを使用せず、同梱CLIを通じてGitLabとやり取りします。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ thisfrontenddev/ skills --skill review-gitlabインストール後、Claude Code で/review-gitlabを入力して読み込まれたか確認します。
同梱ファイルscripts/gitlab.mjs
詳細
GitLab のマージリクエストを対象に、詳細なコードレビューを行います。厳格な2 フェーズのワークフローに従ってください。まずローカルで分析して指摘事項を提示し、その後、ユーザーが承認したコメントのみを GitLab に投稿します。
大規模な MR は、綿密にレビューするためチャンクに分けて確認します。すべての指摘事項には、Claude Code 用の修正プロンプトを含めます。
GitLab へのアクセス — 組み込み CLI
GitLab とのやり取りはすべて、このスキル専用のディレクトリに同梱されている CLI scripts/gitlab.mjs を通じて行います。Bash から node <skill-dir>/scripts/gitlab.mjs <command> [flags] として実行してください。<skill-dir> は、このスキルがインストールされている場所です。
- プロジェクトレベルのインストール(リポジトリのルートから実行):
node .claude/skills/review-gitlab/scripts/gitlab.mjs … - ユーザーレベルのインストール:
node ~/.claude/skills/review-gitlab/scripts/gitlab.mjs …
以下では、gitlab.mjs <command> は完全な node <skill-dir>/scripts/gitlab.mjs <command> の実行を省略した表記です。CLI は環境変数 MR_MCP_GITLAB_TOKEN と、任意の環境変数 MR_MCP_GITLAB_HOST(デフォルトは https://gitlab.com)を読み込みます。各コマンドは JSON を標準出力に出力します。エラー時は {"error": "..."} を標準エラー出力に出力し、ゼロ以外の終了コードで終了します。
GitLab MCP サーバーはありません。 mcp__gitlab-mr__* または mcp__gitlab-mr-edit__* ツールは呼び出さず、代わりに以下の CLI コマンドを使用してください。
| 旧 MCP ツール | CLI コマンド | 必須フラグ |
|---|---|---|
get_projects | get_projects | —(任意で --verbose) |
list_open_merge_requests | list_open_mrs | --project-id N |
get_merge_request_details | get_mr | --project-id N --mr IID |
get_merge_request_diff | get_mr_diff | --project-id N --mr IID |
get_merge_request_comments | get_mr_comments | --project-id N --mr IID |
add_merge_request_comment | add_mr_comment | --project-id N --mr IID --body-file F |
add_merge_request_diff_comment | add_diff_comment | --project-id N --mr IID --base-sha S --start-sha S --head-sha S --file P --line L --body-file F |
get_issue_details | get_issue | --project-id N --issue IID |
set_merge_request_description | set_mr_description | --project-id N --mr IID --body-file F |
set_merge_request_title | set_mr_title | --project-id N --mr IID --title "…" |
create_merge_request_comment(Notes API、通常のノート) | create_note | --project-id N --mr IID --body-file F |
edit_merge_request_comment | edit_note | --project-id N --mr IID --note-id ID --body-file F |
delete_merge_request_comment | delete_note | --project-id N --mr IID --note-id ID |
コメント本文の受け渡し: コメント、スコアカード、説明文は、バッククォートや改行、コードフェンスを含む長い Markdown テキストであり、コマンドラインでは扱いにくい場合があります。すべての書き込みコマンドでは、まず本文を一時ファイル(例:/tmp/claude-review-<short>.md)に書き込み、--body-file <path> で渡してください。簡単な一行のテキストには --body "text" フラグも使用できます。また、set_mr_title には --body-file に対応する --title-file があります。読み取りコマンドに --verbose を追加すると、フィルタリングされていない GitLab の完全なペイロードを取得できます。
入力
ユーザーから提供された内容:$ARGUMENTS
指定できる形式は次のとおりです。
- GitLab MR の完全な URL:
https://gitlab.com/group/project/-/merge_requests/42 - MR IID 付きのパス:
group/project !42 - MR IID のみ。プロジェクトが文脈から明らかな場合:
!42
フェーズ 0 — セットアップ
ステップ 1:入力を解析する
入力からプロジェクトパス(例:group/project)と MR IID(例:42)を抽出します。
完全な URL が指定されている場合は、解析します。
https://gitlab.com/group/subgroup/project/-/merge_requests/42→ プロジェクトパス =group/subgroup/project、IID =42
ステップ 2:プロジェクト ID を取得する
gitlab.mjs get_projects を実行してプロジェクト一覧を取得します。プロジェクトパス(path_with_namespace)が一致するプロジェクトを探し、数値の id(--project-id)を特定します。
$ARGUMENTS に MR IID のみ(例:!42)が含まれている場合は、ユーザーにプロジェクトパスを尋ねます。
ステップ 3:MR データを取得する(並列で 3 回呼び出す)
以下を並列で実行します(1 つのメッセージ内で独立した Bash 呼び出しを行います)。
gitlab.mjs get_mr --project-id N --mr IID— メタデータと、Phase 2 で必要なbase_sha、start_sha、head_shaを含むdiff_refsgitlab.mjs get_mr_diff --project-id N --mr IID— コード差分全体gitlab.mjs get_mr_comments --project-id N --mr IID— 既存のレビューコメント(重複排除用)
Phase 1 — 分析(読み取り専用、GitLab への書き込みは禁止)
重要:Phase 1 では書き込みコマンドを実行しないでください。add_mr_comment、create_note、add_diff_comment、edit_note、delete_note、set_mr_* は実行しないでください。Phase 1 は厳密に読み取り専用です。
ステップ 4:トリアージとチャンク計画
変更されたファイルの合計数を数え、差分全体の文字数を見積もります。MR を分類します。
| サイズ | しきい値 | 戦略 |
|---|---|---|
| 小 | 15 ファイル未満、または 50K 文字未満 | 一括レビュー — すべての差分をまとめてレビュー |
| 中 | 15~50 ファイル、または 50K~150K 文字 | 3~5 チャンク |
| 大 | 50 ファイル以上、または 150K 文字以上 | 5~10 チャンク、各チャンクは約 15~25 ファイル |
グループ化のヒューリスティック(優先順位順に適用します)。
- 機能コホート — 連携して動作するファイル(例:ブロックの
block.ts+Component.tsx+index.ts) - ディレクトリ —
payload/blocks/**、components/**、app/[locale]/**、packages/** - 設定/インフラ —
package.json、CI 設定、マイグレーション、Docker ファイル → 1 つのチャンクにまとめる - 生成/ロックファイル —
payload-types.ts、pnpm-lock.yaml、*.gen.ts→ 完全にスキップ(「スキップしたファイル」セクションに記載)
レビューを開始する前に、チャンク計画を出力します。
Review plan: [Single-pass | N chunks]
- Chunk 1: [Label] ([N] files) — file1.ts, file2.ts, ...
- Chunk 2: [Label] ([N] files) — ...
- Skipped: [N] files (generated/lock)
ステップ 5:既存コメントをインデックス化する
get_mr_comments の結果から、既存のレビューコメントすべてのインデックスを作成します。
note_id(各ノートのidフィールド — 編集/削除操作に必要です)- ファイルパス + 行番号(差分コメントの場合)
- 指摘内容/何に関するものか
- 解決済みか、未解決か
- 投稿者名
レビュー中のルール:
- 既存のコメントで指摘済みの問題は → スキップし、「以前の指摘」セクションに記載します
- 既存のコメントが指摘する問題が現在の差分で修正されているように見える場合は、「修正されたようです」と記載します
- `` を含むコメントも確認し、見つかった場合はスコアカード更新戦略のために、その
note_idと日付を記録します
修正プロンプトがない以前の Claude Code レビューコメントを補完する:
- `` マーカーを含む差分コメント(このスキルの以前の実行で投稿されたもの)のうち、
💡 **修正プロンプト:**ブロックがまだ含まれていないものを探します - 問題が引き続き該当する場合(現在の差分で修正されていない場合)、修正プロンプトを作成します
- これらは下書きの専用「補完したコメント」セクションに記載します
note_idを使用して、元のコメントを編集し、修正プロンプトのブロックを追記します- 注:このマーカーが導入される前に投稿されたコメントは検出されません。これは想定どおりです
Step 6: チャンクごとの詳細レビュー
各チャンクについて(または小規模な MR の場合は一度に):
- 進捗ヘッダーを表示:「
"Reviewing chunk 2/5: Design system components..."」 - 差分データから、そのチャンクの差分を抽出します(このチャンクに属するファイルパスでフィルタリングします)。
- 重要な変更がある各ファイルについて、Read ツールを使ってローカルファイル全体を読み、変更箇所のより広い文脈を確認します。
- 差分とローカルの文脈を分析して、以下を確認します。
- バグ:ロジックエラー、オフバイワン、null/undefined のリスク、競合状態
- セキュリティ:インジェクションの脆弱性、認証の問題、データ漏えい、OWASP Top 10
- パフォーマンス:N+1 クエリ、不要な再レンダリング、メモ化の不足、大きなペイロード
- スタイル:プロジェクト規約への違反(CLAUDE.md/AGENTS.md を参照してください。ネイティブ HTML タグの使用禁止、インラインスタイルの禁止、PandaCSS のみ使用、厳密なインポート規則など)
- ロジック:ビジネスロジックの誤り、エッジケースの不足、不完全なエラーハンドリング
- 型:TypeScript の型安全性の問題、広すぎる型、型ガードの不足
- ファイル、行、重大度、カテゴリ、説明、修正プロンプトとともに指摘事項を記録します。
- チャンクごとに指摘事項を提示してはいけません。すべての指摘事項を蓄積し、最後に一度だけ提示します。
Step 7: 信頼度スコアを算出
7/10から開始し、次の5つの評価軸に基づいて調整します。
1. 網羅性
| 調整 | 条件 |
|---|---|
| +1 | 変更されたすべてのファイルを、十分なローカルの文脈とともに確認した |
| 0 | ほとんどのファイルを確認し、一部をスキップした(生成ファイル/ロックファイル) |
| -1 | チャンクごとのレビューで、チャンク間の文脈が不足している |
| -2 | 多くのファイルをスキップした、または差分のみを確認した(ローカルファイルを確認していない) |
2. コードの複雑さ
| 調整 | 条件 |
|---|---|
| +1 | 単純明快 — 宣言的な記述、設定、UI コンポーネント、翻訳 |
| 0 | 標準的 — 制御フローが明確で、機能の実装が適切に構成されている |
| -1 | 複雑 — アルゴリズム、ステートマシン、複雑なデータ変換 |
| -2 | 非常に複雑 — 動的なコード生成、深くネストされた非同期処理、複雑なキャッシュ |
3. セキュリティ上の指摘事項
| 調整 | 条件 |
|---|---|
| +1 | セキュリティ上重要な領域を確認し、問題が見つからなかった |
| 0 | MR にセキュリティ上重要なコードがない |
| -1 | 軽微なセキュリティ上の懸念が見つかった |
| -2 | 重大なセキュリティ上の問題が見つかった |
4. テストカバレッジの兆候
| 調整 | 条件 |
|---|---|
| +1 | MR に、新規または変更されたロジックを網羅するテストが含まれている |
| 0 | 既存のテストで変更内容がカバーされている可能性が高い |
| -1 | テストがなく、変更がビジネスロジックまたはデータフローに影響する |
5. ドメインへの精通度
| 調整 | 条件 |
|---|---|
| +1 | 文書が整備され、パターンが明確な領域(例:Payload blocks) |
| 0 | 標準的なプロジェクト領域 |
| -1 | 不慣れなドメイン、サードパーティとの連携、文書化されていない API |
最終スコア = clamp(7 + 調整値の合計, 1, 10)
スコアカード形式の以下の表と同じ評価軸を使い、各軸につき1行ずつ、点数と説明を記載して内訳を提示します。
Step 8: レビューの草案を提示
すべてのチャンクの指摘事項をまとめ、重複を除き、重大度の高い順(重大なものを先頭)に並べて、レビュー全文を提示します。
重大度を示す絵文字:
- 🔴 重大 — バグ、セキュリティ上の脆弱性、データ損失のリスク
- 🟠 警告 — パフォーマンスの問題、潜在的なバグ、ロジック上の懸念
- 🟡 提案 — スタイル上の問題、軽微な改善、ベストプラクティス
- 🟢 軽微 — 見た目上の問題、任意の改善、純粋にスタイル上の指摘
以下の厳密な形式を使用します。
## MR Review Draft: group/project !IID
**Title:** [MR title]
**Author:** [MR author]
**Branch:** [source_branch] → [target_branch]
**Review method:** [Single-pass | Chunked (N chunks)]
**Files reviewed:** X/Y (Z skipped)
---
### Review Scorecard (will be posted as MR comment)
## 🔍 Review Scorecard
# Confidence Score: [N]/10
| Criteria | Points | Explanation |
|----------|--------|-------------|
| Base | 7 | — |
| Read coverage | [+1/0/-1/-2] | [One-line reason] |
| Code complexity | [+1/0/-1/-2] | [One-line reason] |
| Security | [+1/0/-1/-2] | [One-line reason] |
| Test coverage | [+1/0/-1/-2] | [One-line reason] |
| Familiarity | [+1/0/-1] | [One-line reason] |
**Reviewed:** [X]/[Y] files ([Z] skipped: [reason])
**Method:** [Single-pass review | Chunked deep review (N chunks)]
### Summary
[2-4 sentence assessment. Is it ready to merge? What are the main themes?]
### Findings Breakdown
| Severity | Count | Key Areas |
|----------|-------|-----------|
| Critical | N | [areas or —] |
| Warning | N | [areas or —] |
| Suggestion | N | [areas or —] |
| Nit | N | [areas or —] |
### Verdict
[APPROVE / APPROVE WITH SUGGESTIONS / REQUEST CHANGES / NEEDS DISCUSSION]
[One sentence explaining the verdict]
---
*Automated review by Claude Code — [N] inline comments posted, [M] existing comments edited with fix prompts*
---
### Previously Raised (will NOT be re-posted)
- `src/foo.tsx:12` — Missing null check (by @author, still open)
- `src/bar.tsx:45` — Unused import (by @author, appears fixed)
*[Or: "No existing review comments found."]*
---
### Augmented Comments (fix prompts for previous Claude Code review comments)
These will be edited into previous `/review-gitlab` comments that lacked a fix prompt:
A1. ✏️ Edit previous review on `[file_path]:[line_number]` (note_id: [id]) — "[original comment summary]"
💡 **Fix prompt:** "[Imperative fix description referencing exact file paths,
line numbers, current code, and expected replacement.]"
A2. ✏️ Edit previous review on `[file_path]:[line_number]` (note_id: [id]) — "[original comment summary]"
💡 **Fix prompt:** "[...]"
*[Or: "No existing comments need augmentation."]*
---
### New Findings
1. 🔴 **Bug** — `[file_path]:[line_number]`
> [Clear description of the issue]
💡 **Fix prompt:** "[Imperative description of what to change, referencing exact
file paths, line numbers, current code, and expected replacement. Specific enough
to execute without further searching.]"
2. 🟠 **Performance** — `[file_path]:[line_number]`
> [Clear description of the issue]
💡 **Fix prompt:** "[...]"
3. 🟡 **Convention** — `[file_path]:[line_number]`
> [Clear description of the issue]
💡 **Fix prompt:** "[...]"
[...more findings sorted by severity...]
---
### Skipped Files
- `apps/nextjs/payload-types.ts` — Generated
- `pnpm-lock.yaml` — Lock file
[Or: "No files skipped."]
続けて、次のように質問します。
**What would you like to post to GitLab?**
- `all` — scorecard + all findings + all augmented comments
- `none` — discard everything
- `scorecard only` — just the scorecard comment
- `1, 3, 5` — scorecard + these numbered findings only
- `all except 2` — scorecard + all findings except these
- `augments only` — scorecard + augmented comment edits only (no new findings)
- `A1, A2` — specific augmented comments only
- `edit 3` — edit an existing posted finding's comment (by note_id from Step 5)
- `delete 3` — delete an existing posted finding's comment (by note_id from Step 5)
- `dry-run <selection>` — preview what would be posted without posting (e.g. `dry-run all`, `dry-run 1, 3`)
- Or edit any finding/prompt before posting
問題が見つからなかった場合も、肯定的な評価とスコアカードを提示し、投稿するかユーザーに確認します。
フェーズ 2 — 投稿(ユーザーの承認後のみ)
ユーザーが選択を回答するまで待ちます。その後:
ステップ 9:承認されたコメントを投稿する
ドライランモード: ユーザーの選択が dry-run で始まる場合、書き込みコマンドは実行しないでください。代わりに、dry-run プレフィックスの後の選択内容を解析し(例:dry-run all → all として扱う、dry-run 1, 3 → 1, 3 として扱う)、実行されるはずの各アクションについて、概要ブロックを出力してください。
## Dry Run — Actions Preview
The following actions would be taken (nothing was posted):
1. 📝 **Create scorecard comment** (plain note)
- Command: `gitlab.mjs create_note`
- Body preview: [first 200 chars of scorecard]...
2. 💬 **Post diff comment** on `src/foo.tsx:42`
- Command: `gitlab.mjs add_diff_comment`
- Severity: 🔴 Critical — [category]
- Body preview: [first 150 chars]...
3. ✏️ **Edit existing comment** (note_id: 12345) — append fix prompt
- Command: `gitlab.mjs edit_note`
- Appending: 💡 Fix prompt for [description]
4. ✏️ **Update existing scorecard** (note_id: 67890)
- Command: `gitlab.mjs edit_note`
- Body preview: [first 200 chars]...
---
Total: N new comments, M edits, D deletes
Ready to post? Reply with your selection (without `dry-run`) to execute.
その後、停止してユーザーの次の応答を待ってください。投稿には進まないでください。
通常の投稿モード: ユーザーの選択に基づいて処理します。書き込みを行うたびに、コメント本文を一時ファイル(例:/tmp/claude-review-<n>.md)に書き込み、--body-file に渡してください。
-
スコアカードコメント: スコアカード(`` と閉じる
---の間のすべての内容)を、MR の一般コメントとして投稿します。スコアカードの更新方法:
- ステップ 5 で `` を含む既存コメントが見つかった場合は、その場で編集します:
gitlab.mjs edit_note --project-id N --mr IID --note-id <recorded id> --body-file <file>。新しいスコアカード本文の末尾に\n\n> ℹ️ Updated from previous scorecardを追加してください。 - 既存のスコアカードが見つからなかった場合は、新しいコメントを投稿します:
gitlab.mjs create_note --project-id N --mr IID --body-file <file>(Notes API — 解決可能なスレッドではなく、通常のコメントを作成します)。
- ステップ 5 で `` を含む既存コメントが見つかった場合は、その場で編集します:
-
行単位の指摘: 承認された各指摘を、差分コメントとして投稿します:
gitlab.mjs add_diff_comment --project-id N --mr IID --base-sha <base> --start-sha <start> --head-sha <head> --file <path> --line <line> --body-file <file>。ここで:--base-sha/--start-sha/--head-sha:ステップ 3 で取得したdiff_refsから指定します--file:差分に表示されているファイルパス--line:行番号(GitLab API のnew_lineに対応し、ファイルの新しいバージョンを対象とします)- 本文ファイルの内容:
\n**[Severity emoji] [Category]**: [description]\n\n💡 **Fix prompt:**\n\``\n[fix prompt text]\n````
可能な場合は、差分コメントのコマンドを並列実行してください(1 つのメッセージ内で独立した Bash 呼び出しを実行します)。
-
拡張コメント: 承認された各拡張コメント(A1、A2 など)について、元のコメントをその場で編集します:
gitlab.mjs edit_note --project-id N --mr IID --note-id <original id> --body-file <file>。修正プロンプトのブロックを追加した元のコメント本文を設定します:- 追加内容:
\n\n💡 **Fix prompt:**\n\``\n[fix prompt text]\n```\n\n*— Fix prompt added by Claude Code review*`
可能な場合は、これらの編集を並列実行してください。
- 追加内容:
-
ユーザーがコメントのテキストを編集した場合は、投稿時に編集後の内容を使用してください。
-
既存コメントの編集/削除: ユーザーが
edit Nまたはdelete Nを選択した場合:edit N— 新しいテキストをユーザーに尋ねる(または、ユーザーがその場で入力できるようにする)と、gitlab.mjs edit_note --project-id N --mr IID --note-id <finding #N の id> --body-file <file>を実行します。delete N— ユーザーに確認してから、gitlab.mjs delete_note --project-id N --mr IID --note-id <finding #N の id>を実行します。
ステップ 10:結果を報告する
投稿後、次の内容を報告してください:
## Review Posted ✓
Posted to [MR URL]:
- Scorecard comment [posted | edited in place] (confidence: N/10, verdict: [VERDICT])
- [N] inline comments on [files list]
- [M] existing comments edited with fix prompts
- [D] comments deleted (if any)
[Any errors that occurred during posting]
コメントの投稿に失敗した場合(例:削除済みファイルの無効な行番号)、エラーを報告し、残りのコメントの投稿を続けてください。
修正プロンプトのガイドライン
指摘に対する修正プロンプトを書く際は、次のルールに従ってください:
- 差分に記載された正確なファイルパスと行番号を参照してください
- 現在のコードと期待される置き換え内容を明確に説明してください
- 同じ根本原因に関係する複数ファイルの修正は、1 つのプロンプトにまとめてください
- 命令形を使用してください:「置き換える」「削除する」「追加する」「リファクタリングする」
- コードベースをさらに検索しなくても実行できるよう、十分に具体的にしてください
- Claude Opus/Sonnet 向けに最適化し、明確かつ曖昧さのない表現にしてください。コードへの参照に代名詞を使わないでください
- 新しいインポートが必要な場合は、インポートパスを含めてください