home/dot_agents/skills/multi-review/SKILL.md
3つのレビューツール(cc-code-review / cc-security-review / Codex)を並列でバックグラウンド実行し、 結果を統合サマリーにまとめた上で、GitHub PR にレビュー(body サマリー + インラインコメント)として投稿する。 PRの包括的レビューを一度に実行したい場合に使用する。 トリガー: "multi-review", "マルチレビュー", "全レビュー", "並列レビュー", "フルレビュー", "3ツールレビュー" 使用場面: PRのコードレビュー・セキュリティレビュー・Codexレビューを一括で実行したい場合
npx skillsauth add kryota-dev/dotfiles multi-reviewInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
3つのレビューツールを並列でバックグラウンド実行し、結果を統合サマリーにまとめる。 既存レビュー(CodeRabbit / Devin / claude[bot] / 人間レビュアー)と重複する指摘を除外したうえで、 統合結果をユーザーに提示し、承認があれば GitHub PR にレビュー(body サマリー + インラインコメント、または インラインのみ)を投稿する(投稿方法はユーザーが選択)。
引数解析 → 差分取得 → 既存レビュー取得 + 3ツール並列実行 → 結果収集 → 統合サマリー
→ 既存レビューとの重複除外 → ユーザー確認(投稿方法を選択)→ 投稿
重複除外の意義: 既存レビュアーが既に同じ指摘をしている場合、再投稿は冗長でレビュアーの認知負荷を増やす。 重複を除外することで、新規視点・追加価値のある指摘のみが投稿される。
以下の優先順で判定する:
^\d+$ または ^#\d+$): gh pr diff <番号> で差分取得github.com を含む URL): URL から PR 番号を抽出し、gh pr diff で差分取得gh pr view --json number --jq '.number' で自動検出レビューの実体(ペルソナ・観点・出力形式・「(未確認)」ルール)は各ツール側に集約し、multi-review 側で重複定義しない。
| ツール | 実行方式 | SSOT |
|--------|---------|------|
| cc-code-review | カスタムサブエージェント(Agent ツール、subagent_type: cc-code-review) | エージェント定義 ~/.claude/agents/cc-code-review.md(レビュー観点・出力形式)/ skill ~/.agents/skills/cc-code-review/SKILL.md(対象解決・起動方法) |
| cc-security-review | カスタムサブエージェント(Agent ツール、subagent_type: cc-security-review) | エージェント定義 ~/.claude/agents/cc-security-review.md(OWASP チェックリスト・出力形式)/ skill(対象解決・起動方法) |
| codex | CLI(codex exec、バックグラウンド Bash) | skill ~/.agents/skills/codex/SKILL.md(実行コマンド・-o 出力・stdin 堅牢化・プロンプトルール) |
~/.agents/skills/codex/SKILL.md を Read し、-o <FILE> 出力・stdin 堅牢化・タイムアウト・「(未確認)」ルールに従ってコマンドを組み立てる。gh pr diff <PR番号> を実行。差分が空の場合は「レビュー対象の差分がありません」と報告して終了。差分は変数に確保しておく(DIFF=$(gh pr diff <PR番号>))。これは codex 用(codex は sandbox 内で gh pr diff できないためプロンプトに埋め込む)。サブエージェント(cc-code-review / cc-security-review)はセッション内で自分で差分を取得するため埋め込み不要。gh repo view --json nameWithOwner --jq '.nameWithOwner' で owner/repo を取得Phase 4 の重複除外で使用する。3 種類の API レスポンスと、対応状況の機械的判定をここで揃える。
既存レビュー・コメントを取得する:
# a. レビュー本体(state, body)
gh api repos/{owner}/{repo}/pulls/<PR番号>/reviews --paginate \
--jq '[.[] | select(.body | length > 0) | {user: .user.login, state: .state, body: .body, submitted_at: .submitted_at}]'
# b. インラインレビューコメント(path, line, body, in_reply_to_id)
gh api repos/{owner}/{repo}/pulls/<PR番号>/comments --paginate \
--jq '[.[] | {user: .user.login, path: .path, line: .line, body: .body, in_reply_to_id: .in_reply_to_id}]'
# c. PR 全体への issue コメント
gh api repos/{owner}/{repo}/issues/<PR番号>/comments --paginate \
--jq '[.[] | {user: .user.login, body: .body}]'
既存スレッドの対応状況を取得する。comments API では resolved 状態が取れないため、GraphQL reviewThreads を使う:
gh api graphql -f query='
{
repository(owner: "{owner}", name: "{repo}") {
pullRequest(number: <PR番号>) {
reviewThreads(first: 100) {
nodes {
id
isResolved
path
line
comments(first: 20) {
nodes {
author { login }
body
createdAt
}
}
}
}
}
}
}'
このレスポンスを基に、各既存指摘の対応状況を 3 つに分類する:
| 判定 | 条件 |
|------|------|
| resolved | isResolved == true |
| fixed-replied | スレッド内子コメントに Fixed in [0-9a-f]{7,40} または addressed in [0-9a-f]{7,40} の正規表現マッチ |
| open | 上記いずれでもない(未対応) |
resolved と fixed-replied は 対応済み として扱い、open は 未対応 として扱う。
3 ツールを 同一メッセージ内で並列起動する。cc-code-review / cc-security-review は Agent ツール(run_in_background: true)、codex は バックグラウンド Bash(run_in_background: true)。
| ツール | 起動方法 | 渡すもの |
|--------|---------|---------|
| cc-code-review | Agent ツール subagent_type: cc-code-review, run_in_background: true | プロンプト = 「PR #<番号>(owner/repo)のレビュー依頼 + 差分取得コマンド(gh pr diff <番号>)+ 作業ディレクトリ絶対パス」。差分はエージェント自身が取得するため埋め込まない。観点・出力形式はエージェント定義に内蔵のため再掲しない |
| cc-security-review | Agent ツール subagent_type: cc-security-review, run_in_background: true | 同上(セキュリティ観点)。差分はエージェント自身が取得。OWASP チェックリストはエージェント定義に内蔵 |
| codex | バックグラウンド Bash run_in_background: true | codex skill「PR 差分のレビュー」コマンド(-o <RESULT_FILE> で結果のみファイル出力、差分は事前変数 ${DIFF} を埋め込み。codex は sandbox 内で gh pr diff できないため) |
run_in_background: true。プロンプトに差分取得コマンド・作業ディレクトリ絶対パス・(多ラウンド時は)棄却台帳を含める(差分そのものは埋め込まず、エージェントに取得させる)。run_in_background: true、-o <RESULT_FILE> 形式で事前確保した ${DIFF} を埋め込む。RESULT_FILE パスを記録する。No prompt provided via stdin. の場合は事前変数確保パターンで再実行(codex skill 参照)。再失敗なら該当ツールをスキップして Phase 3 へ。同一 PR を複数ラウンドでレビューする場合、ツール(特に codex)は 前ラウンドで棄却した誤指摘を繰り返し再提起することがある(差分とリポジトリ全体しか見ておらず、過去の棄却判断を知らないため)。実例として、ある PR では codex が同一の誤指摘(ルートグループ独立を誤認した <html lang> 汚染)を 6 ラウンド連続で再提起した。
対策: 過去ラウンドで棄却した指摘を「棄却台帳」としてプロンプト冒頭に明示注入する。
## 過去ラウンドで棄却済みの誤指摘(再提起禁止)
1. [禁止] <誤指摘の要約>
- 棄却理由: <一次情報に基づく根拠>
...
| 項目 | 内容 |
|------|------|
| プロンプトの内容 | cc-code-review / cc-security へは「対象説明 + 差分取得コマンド + 作業ディレクトリ + 棄却台帳」のみ(差分はエージェントが取得)。観点・出力形式・チェックリストはエージェント定義が SSOT。codex は codex skill のコマンドをそのまま使う(差分は埋め込み) |
| 統合・検証は親の責務 | 統合・重複除外・事実確認は Phase 3〜4 で親 Claude が行う。サブエージェントには fact-check 用 MCP を持たせず、検証は親に集約する |
| stdin パイプ問題 | codex の No prompt provided via stdin. 回避(事前変数確保)は codex skill 側で SSOT 化済み |
## PR #<番号> 統合レビュー結果
### 総合評価
| カテゴリ | cc-code-review | cc-security-review | codex |
|---------|-----------|-------------------|-------|
| MUST | N件 | N件 | N件 |
| SHOULD | N件 | N件 | N件 |
| NITS | N件 | N件 | N件 |
| GOOD | N件 | N件 | N件 |
### セキュリティ
- 総合リスクレベル: <Level>
- 検出された脆弱性数: N件
### [MUST] 修正必須(全ツール統合)
{ファイル:行番号でグループ化した指摘一覧}
### [SHOULD] 修正推奨(全ツール統合)
{ファイル:行番号でグループ化した指摘一覧}
### [NITS] 軽微な提案
{指摘一覧}
### [GOOD] 良い実装
{称賛すべき点の一覧}
### 横断まとめ
| 観点 | 結果 |
|------|------|
| バグ・論理エラー | ... |
| 設計・アーキテクチャ | ... |
| セキュリティ | ... |
| 後方互換性 | ... |
| テスト | ... |
レビューツール(cc-code-review / cc-security-review サブエージェント / codex)が出力する 断定的な主張 は、親 Claude(multi-review 実行者)が必ず一次情報で検証する。サブエージェント/codex は差分中心の限定コンテキストで動くため、検証責務は親側に集約 する(fact-check 用の context7 等の MCP は親が持つ。サブエージェントには意図的に持たせず、「生成はサブエージェント・検証は親」の分業を明確にしている)。誤情報を自信満々に PR コメントとして投稿してしまうリスクを防ぐ。
mcp__context7__resolve-library-id → mcp__context7__query-docs): 公式ドキュメントの最新版を直接照会node_modules 直接確認で実装の有無を判定
find node_modules/.pnpm -maxdepth 1 -name "<lib>@*" -type d で実体パスを特定し、export ファイル(*.d.ts / index.js)を Read / lsnode_modules/<lib> を直接確認/docs/foo での記述を拾ったと思い込み、実際は /docs/foo-legacy にしか記載がなかったnode_modules には実装ファイルが存在したこれらは 読み手から「裏取りしていない」と即座に見抜かれる 誤りで、レビュー全体の信頼を損なう。URL を引用する際は引用元ページの該当箇所を WebFetch で必ず確認する。
レビューツールが「保持期間が未定義」「retention policy が無い」「ADR が無い」のような 「無いことを根拠とする指摘」 を出す場合、サブセッションは PR 差分しか見ていない ため、すでに別ドキュメントで定義されているのを見落としている可能性が高い。
gh pr view <PR番号> --json body で PR 本文を取得し、ADR / Design Doc / docs/ 配下のリンクを抽出するdocs/design/adr/*.md) / Design Doc (docs/design/design-docs/*/) を実際に読み、関連キーワード(「保持」「retention」「削除」「migration」等)を Grep で確認する| 検証結果 | 反映方法 | |---------|---------| | 誤りが判明(無いと言っているが実在する/否定的断定が事実誤認) | 統合サマリーから当該指摘を 削除 | | 部分的に正しい(趣旨は合うが詳細に誤りあり) | 訂正版に書き換え。誤主張を出した tool 名と訂正の根拠 URL / ドキュメントパスを本文に明記 | | 裏が取れた | 主張をそのまま採用。根拠 URL / ドキュメントパスを本文に追加すると説得力が増す | | 検証不能 | コメント本文に「(未確認の可能性あり)」と明示、または投稿候補から外す |
Phase 1.5 で取得した既存レビュー・コメントと、Phase 3 の統合サマリーを突き合わせ、重複指摘を除外する。
ファイル:行番号と指摘内容の 両方 を比較する。「同じ趣旨」かどうかは LLM の意味解釈で判定する(語の一致率ではない):
| 既存指摘の状態 | 対応状況の判定(Phase 1.5 の手順 2) | multi-review の扱い |
|--------------|----------------------------------|-------------------|
| 同じファイル:行番号 + 同じ趣旨 | resolved または fixed-replied | 除外(再指摘は冗長) |
| 同じファイル:行番号 + 同じ趣旨 | open(未対応) | 除外(multi-review は新規 review コメントの投稿のみ担う。既存スレッドへの reply 投稿は責務外。補強が必要なら別 skill review-resolve-loop 等を使う) |
| 同じファイル:行番号 + 異なる視点(深堀り・反対意見・新たな根拠) | 問わない | 残す(新規価値あり、本文に「既存指摘への補足/反論」テンプレを付与。下記参照) |
| 異なるファイル:行番号 | 問わない | 残す |
| [GOOD] で既存レビュアーが言及済み | 問わない | 除外(重複称賛は冗長) |
| [GOOD] で未言及 | 問わない | 残す |
「同じファイル:行番号 + 異なる視点」を 残す ケースでは、コメント本文の冒頭に以下のテンプレを付ける(読み手が既存スレッドとの関係を理解できるようにするため):
**既存指摘への補足/反論** (@<reviewer-login> による <ファイル>:<行> での「<既存指摘の要約 1 行>」)
[MUST] / [SHOULD] / [NITS] のいずれか — 本文...
<reviewer-login> には bot を含む実 login(例: coderabbitai[bot]、sasamuku)を入れる。<既存指摘の要約 1 行> は既存指摘本文を 30〜60 字に圧縮する。
注意: テンプレに署名は含めない。投稿時に「PR コメント投稿手順」の署名ルールが自動で末尾に付与されるため、テンプレ側で署名を書くと 二重署名 になる。
以下の login と本文パターンの組合せに合致するレビュー・コメントは 重複判定の対象から外す(中身がないため):
| login | 除外パターン(本文に含まれる文字列、いずれか) |
|-------|---------------------------------------|
| coderabbitai[bot] | Walkthrough、Reviews paused、auto-pause_after_reviewed_commits、✅ Addressed in commit 単独 |
| devin-ai-integration[bot] | No Issues Found、No potential bugs to report |
| claude[bot] | (除外なし。本文を中身として扱う) |
| github-actions[bot] | (内容に応じて。CI 通知のみなら除外) |
判定の進め方: login が上記リストにマッチし、かつ本文が除外パターンに一致する場合のみ除外。coderabbitai[bot] の Actionable comments 等の実質的な指摘は除外せず、Phase 4 の重複判定対象に含める。
統合サマリーの末尾に以下を追記:
### 既存レビュー指摘との重複チェック
| 既存指摘(要約) | 既存レビュアー | 対応状況 | multi-review との重複 | 判定 |
|----------------|--------------|---------|--------------------|------|
| <指摘要約 1> | sasamuku (self-review) | Fixed in c6c81c4 | cc-code-review SHOULD #1 と同趣旨 | 除外 |
| <指摘要約 2> | claude[bot] | 未対応 | cc-security Info と同趣旨 | 除外 |
| <指摘要約 3> | (対応する既存指摘なし) | - | - | 残す |
### 投稿候補(重複除外後)
| カテゴリ | 件数(除外前 → 除外後) |
|---------|---------------------|
| MUST | N → M |
| SHOULD | N → M |
| NITS | N → M |
| GOOD | N → M |
重複除外後の統合サマリーをユーザーに表示する
AskUserQuestion で投稿方法を確認する(notify で通知音。存在しない環境ではスキップ)。質問文には投稿対象のインライン件数(重複除外後の N 件)を明示し、以下の 3 択を提示する:
| 選択肢 | 内容 |
|--------|------|
| サマリーを body に含めて投稿 | レビュー本体の body に統合サマリー(セキュリティ評価・事実検証で棄却した指摘・GOOD・重複チェック等)を記載し、インラインコメント(重複除外後の MUST/SHOULD/NITS)を付けて投稿(submit)する |
| body なしで投稿 | インラインコメントのみ投稿。body は付けない |
| 投稿しない | 統合サマリーの表示のみで終了 |
「サマリーを body に含めて投稿」/「body なしで投稿」が選ばれた場合: 下記「PR コメント投稿手順」の対応する方法で投稿する。
「投稿しない」が選ばれた場合: 統合サマリーの表示のみで終了。
Claude がレビューコメントを作成する際は、コメント末尾に必ず署名を付与する:
コメント本文
---
*Co-Authored-By: Claude {モデル名} <[email protected]>*
{モデル名} には現在実行中のモデルを 山括弧なしで 入れる(例: Opus 4.8 (1M context)、Sonnet 4.6 (1M context))。会話冒頭のシステム情報に記載のモデル名を採用する。{モデル名} プレースホルダーをそのまま残してはならない。
重要(markdown レンダリングのバグ回避): モデル名を <Sonnet 4.6> のように 山括弧で囲まないこと。< > は markdown/HTML でタグとして解釈され、表示時にモデル名が消える。正しくは Co-Authored-By: Claude Sonnet 4.6 (1M context) <[email protected]>(モデル名は裸、メールアドレスのみ山括弧)。
| Phase 5 の選択 | 投稿方法 | submit |
|---------------|---------|--------|
| サマリーを body に含めて投稿 | 下記「A. サマリー付きで submit」。event: "COMMENT" + body(統合サマリー)+ comments(インライン) | 即時 submit(body が即表示される) |
| body なしで投稿 | 下記「B. Pending Review 作成」または「A」で body を空にする。デフォルトは Pending(event 省略)でユーザーに submit を委ねる | Pending(ユーザーが GitHub UI で submit) |
event: "COMMENT" を指定すると即座に submit される(body とインラインが即表示)。body には Phase 3〜4 の統合サマリーを記載する。
cat <<'PAYLOAD' | gh api repos/{owner}/{repo}/pulls/{PR番号}/reviews --method POST --input -
{
"event": "COMMENT",
"body": "## 🤖 Multi-Review 統合レビュー結果\n\n(セキュリティ評価・事実検証で棄却した指摘・GOOD・既存レビュー重複チェック等のサマリー)\n\n---\n*Co-Authored-By: Claude {モデル名} <[email protected]>*",
"comments": [
{
"path": "src/example.ts",
"line": 10,
"side": "RIGHT",
"body": "[SHOULD] コメント本文\n\n---\n*Co-Authored-By: Claude {モデル名} <[email protected]>*"
}
]
}
PAYLOAD
body の末尾にも署名を付ける(インライン各コメントとは別に 1 つ)。gh api repos/{owner}/{repo}/pulls/{PR番号}/reviews \
--jq '.[] | select(.state == "PENDING") | {id, state, user: .user.login}'
event フィールドを 省略 すると pending 状態になる(event: "PENDING" を明示的に指定すると 422 エラー)。
cat <<'PAYLOAD' | gh api repos/{owner}/{repo}/pulls/{PR番号}/reviews --method POST --input -
{
"comments": [
{
"path": "src/example.ts",
"line": 10,
"side": "RIGHT",
"body": "[SHOULD] コメント本文\n\n---\n*Co-Authored-By: Claude {モデル名} <[email protected]>*"
}
]
}
PAYLOAD
REST API では既存の pending review にコメントを追加できないため、GraphQL API を使用する。
gh api graphql -f query='
{
repository(owner: "{owner}", name: "{repo}") {
pullRequest(number: {PR番号}) {
reviews(states: PENDING, first: 5) {
nodes {
id
state
author { login }
}
}
}
}
}'
cat <<'GQL' | gh api graphql --input -
{
"query": "mutation($input: AddPullRequestReviewThreadInput!) { addPullRequestReviewThread(input: $input) { thread { id comments(first: 1) { nodes { id body } } } } }",
"variables": {
"input": {
"pullRequestReviewId": "PRR_kwDOxxxxxxx",
"path": "src/example.ts",
"line": 10,
"side": "RIGHT",
"body": "[SHOULD] コメント本文\n\n---\n*Co-Authored-By: Claude {モデル名} <[email protected]>*"
}
}
}
GQL
multi-review が投稿するインラインコメントの本文先頭には、必ず Phase 3 の統合分類に対応するプレフィクスを付ける:
| 統合分類 | プレフィクス | 用途 |
|---------|-----------|------|
| MUST | [MUST] | 修正必須(バグ・セキュリティ・設計違反) |
| SHOULD | [SHOULD] | 修正推奨 |
| NITS | [NITS] | 軽微な提案 |
| GOOD | [GOOD] | 称賛 |
プロジェクト独自 prefix の自動判定: PR 本文に独自のレビュー prefix 規約(例: <!-- for AI code review rule --> ブロックや「以下の prefix をつけてください」という記述で [must]/[imo]/[nits]/[typo]/[ask]/[fyi] 等が指定されている場合)があれば、Phase 1.5 で取得した PR 本文から検出し、そのプロジェクト規約に合わせて投稿する。統合分類との対応例: MUST→[must]、SHOULD→[imo]、NITS→[nits]、GOOD→[fyi] または称賛。検出した規約はユーザーへの提示時に「PR 規約の prefix([must]/[imo] 等)に合わせる」と明示する。
デフォルト: 独自規約が検出できない場合は [MUST]/[SHOULD]/[NITS]/[GOOD] の 4 種に統一する。Conventional Comments 記法([imo] [ask] [fyi] 等)はデフォルトでは使わない。判断に迷う場合はユーザーに確認する。
| シナリオ | 対応 |
|---------|------|
| cc-code-review / cc-security サブエージェントの失敗・スキップ | 1回リトライ。再失敗なら該当ツールをスキップして残りで続行 |
| cc-code-review / cc-security-review サブエージェント未定義 | ~/.claude/agents/ に定義があるか確認を案内(chezmoi apply 済みか)。該当ツールをスキップ |
| codex コマンド未発見 | 警告を出力し、残り2ツール(cc-code-review, cc-security-review サブエージェント)のみで続行 |
| codex が No prompt provided via stdin. で終了 | 差分を事前変数確保するパターンで1回リトライ(codex skill 参照) |
| codex 結果ファイルにログ混入 | -o <FILE> 形式になっているか確認(> file 2>&1 併合をやめる) |
| 個別ツールのタイムアウト | 1回リトライ。2回目も失敗なら該当ツールをスキップ |
| 空の差分 | 「レビュー対象の差分がありません」と報告して終了 |
| PR番号が無効 | エラーメッセージを表示して終了 |
| Pending Review 作成失敗 | エラー内容を表示してユーザーに報告 |
| 全ツール失敗 | エラーサマリーを出力して終了 |
model: inherit)。コストを抑えたい場合は Agent 呼び出し時に model: "sonnet" を指定、または個別スキル(cc-code-review 等)を直接使用するClaude Code の Bash ツールでは ! が履歴展開として解釈されるため、jq の否定比較演算子は使用できない。代わりに select(.user.login | startswith("coderabbitai") | not) パターンを使用する。
development
`cc-code-review` エージェントを起動して独立したコンテキストでコードレビューを実行する。 現在のセッションのバイアスのないフレッシュな視点で、プロジェクトの CLAUDE.md を踏まえたレビューを行う。 トリガー: "cc-code-review", "ccでレビュー", "別の視点でレビュー", "セカンドオピニオン" 使用場面: (1) PRのコードレビュー (2) ブランチ差分のレビュー (3) 特定ファイルのレビュー (4) 現在の変更のレビュー
tools
Comprehensive guide for the `wtp` (Worktree Plus) CLI by satococoa — an enhanced Git worktree manager. Use this whenever the user wants to create, list, remove, or navigate Git worktrees with wtp, mentions `wtp add`/`wtp cd`/`wtp list`/`wtp remove`/`wtp exec`, asks about automatic worktree paths from branch names, post-create hooks (copy/symlink/command) in `.wtp.yml`, branch tracking for worktrees, or shell integration (`wtp shell-init`, `wtp hook`, tab completion, auto-cd). Trigger this even when the user just describes the workflow — e.g. 'spin up a worktree for this feature branch', 'jump to my auth worktree', 'clean up the worktree and its branch' — without naming wtp explicitly, as long as wtp is the available tool.
tools
Use when doing ANY task involving Supabase. Triggers: Supabase products (Database, Auth, Edge Functions, Realtime, Storage, Vectors, Cron, Queues); client libraries and SSR integrations (supabase-js, @supabase/ssr) in Next.js, React, SvelteKit, Astro, Remix; auth issues (login, logout, sessions, JWT, cookies, getSession, getUser, getClaims, RLS); Supabase CLI or MCP server; schema changes, migrations, security audits, Postgres extensions (pg_graphql, pg_cron, pg_vector).
data-ai
Postgres performance optimization and best practices from Supabase. Use this skill when writing, reviewing, or optimizing Postgres queries, schema designs, or database configurations.