| name | x-thorough-code-review |
| description | コードレビューを実施する。GitHubのPRをレビューするか、ローカルブランチの変更をレビューするかを選択できる。「PRレビューして」「#123をレビュー」「このブランチをレビューして」「変更内容を見て」のように使う。PR番号が引数にない場合も起動してよい。 |
| context | fork |
| allowed-tools | ["Bash","Read","Glob","Grep","AskUserQuestion","Skill","WebFetch","TaskCreate","TaskUpdate","TaskList"] |
コードレビュー
コード差分・変更の意図・設計書をもとにレビューを実施します。
フローは以下の通りです。
- Step 1: レビューモードを決定する
- Step 2A / 2B: 情報を取得する
- Step 2C: 設計書を確認する
- Step 3: レビュースコープを定義する
- Step 4: 自動解析する
- Step 5: コードレビューを実施する
- Step 6: 結果を統合して出力する
- Step 7: レビュー後のアクション
タスク登録(実行開始時に必ず実施)
フローを開始する前に、全ステップをTaskCreateで登録します。各ステップを開始するときTaskUpdateでin_progressへ、完了したときcompletedへ更新します。
| # | subject | blockedBy |
|---|
| 1 | Step 1: レビューモードを決定する | — |
| 2 | Step 2: 情報を取得する | 1 |
| 3 | Step 2C: 設計書を確認する | 2 |
| 4 | Step 3: レビュースコープを定義する | 3 |
| 5 | Step 4: 自動解析を実行する | 4 |
| 6 | Step 5: コードレビューを実施する | 5 |
| 7 | Step 6: 結果を統合して出力する | 6 |
| 8 | Step 7: レビュー後のアクション | 7 |
変数
実行を通じて以下の変数を使い回します。各ステップで設定し、後続のステップで参照します。
| 変数 | 説明 | 設定タイミング |
|---|
REVIEW_MODE | pr / local | Step 1 |
PR_NUMBER | PR番号 | Step 1 |
OWNER | リポジトリオーナー名 | Step 2A |
REPO | リポジトリ名 | Step 2A |
CURRENT_BRANCH | 現在のブランチ名 | Step 2A / 2B |
BASE_BRANCH | ベースブランチ名 | Step 2A / 2B |
CHANGED_FILES | 変更ファイル一覧(改行区切り) | Step 3 |
Step 1: レビューモードを決定する
1-1. 引数からPR番号を読み取る(あれば)
引数中の数字、GitHub PR URL、またはブランチ名からPR番号を特定し、PR_NUMBERに格納します。見つからなくてもかまいません。
1-2. AskUserQuestionでレビューモードを選択する
{
"question": "どちらをレビューしますか?",
"options": [
{ "label": "PRベース", "description": "GitHub PRの差分・説明・コメント履歴を取得してレビュー" },
{ "label": "ローカル", "description": "現在のブランチのローカル変更をレビュー(PR未作成でも可)" }
]
}
PR番号が引数で渡されていた場合は「PRベース」をデフォルト選択肢として提示します。選択結果をREVIEW_MODEに格納します(pr / local)。
1-3. REVIEW_MODE=prかつPR_NUMBERが未設定の場合
AskUserQuestionでPR番号を確認します。
{
"question": "レビューするPRの番号またはURLを教えてください",
"options": [
{ "label": "現在ブランチのPR", "description": "gh pr viewで現在ブランチに紐付くPRを自動検索する" }
]
}
「現在ブランチのPR」が選択された場合は以下のコマンドを実行します。
PR_NUMBER=$(gh pr view --json number --jq '.number')
Step 2A: PR情報を取得する(REVIEW_MODE=prの場合)
OWNER=$(gh repo view --json owner --jq '.owner.login')
REPO=$(gh repo view --json name --jq '.name')
PRの基本情報を取得します。
gh pr view $PR_NUMBER --json number,title,body,baseRefName,headRefName,files,author,state
- タイトル・説明・ベースブランチ・ヘッドブランチ・変更ファイル一覧を把握します
- PRの状態がOPEN以外の場合はユーザーに通知します(レビュー自体は続行してかまいません)
コード差分を取得します。
gh pr diff $PR_NUMBER
既存のレビューコメントを取得します。
gh api repos/$OWNER/$REPO/pulls/$PR_NUMBER/comments \
--jq '.[] | {path: .path, line: .original_line, body: .body, user: .user.login}'
会話コメントを取得します。
gh api repos/$OWNER/$REPO/issues/$PR_NUMBER/comments \
--jq '.[] | {body: .body, user: .user.login}'
ベースブランチを設定します。
CURRENT_BRANCH=$(git branch --show-current)
BASE_BRANCH=$(gh pr view $PR_NUMBER --json baseRefName --jq '.baseRefName')
取得した情報をもとに、PRの目的・背景・これまでの議論を整理してユーザーに提示します。
Step 2B: ローカル情報を取得する(REVIEW_MODE=localの場合)
CURRENT_BRANCH=$(git branch --show-current)
BASE_BRANCH=$(git remote show origin | awk '/HEAD branch/ {print $NF}')
コミット一覧を取得します(変更の意図を把握)。
git log origin/$BASE_BRANCH..HEAD --oneline
ブランチ全体の差分を取得します(コミット済み変更)。
git diff origin/$BASE_BRANCH...HEAD
未コミット変更を取得します(あれば含めます)。
git status --short
git diff HEAD
Step 2C: 設計書を確認する
AskUserQuestionでファイルパスまたはURLを尋ねます。
{
"question": "レビューの判断基準にする設計書はありますか?",
"options": [
{ "label": "ファイルパスまたはURLを入力する", "description": "Design Doc・ADR・仕様書など" },
{ "label": "なし", "description": "設計書なしでレビューする" }
]
}
ファイルパスが入力された場合はそのファイルを読み、URLが入力された場合は内容を取得して、変更の意図・制約・設計方針をコンテキストに加えます。
Step 3: レビュースコープを定義する
3-1. 変更ファイルを確定する
CHANGED_FILES=$(git diff --name-only origin/${BASE_BRANCH}...HEAD)
echo "$CHANGED_FILES"
3-1-b. 隣接テストファイルをスコープに追加する
実装ファイルと同じディレクトリにある .test.ts / .test.tsx / .spec.ts / .spec.tsx を CHANGED_FILES に追加します。e2e/ 配下は対象外です。
EXTRA_TESTS=""
for f in $CHANGED_FILES; do
DIR=$(dirname "$f")
BASE=$(basename "$f" | sed 's/\.[^.]*$//')
for EXT in .test.ts .test.tsx .spec.ts .spec.tsx; do
CANDIDATE="${DIR}/${BASE}${EXT}"
if [ -f "$CANDIDATE" ] && ! echo "$CHANGED_FILES" | grep -qF "$CANDIDATE"; then
EXTRA_TESTS="$EXTRA_TESTS $CANDIDATE"
fi
done
done
if [ -n "$EXTRA_TESTS" ]; then
CHANGED_FILES="$CHANGED_FILES"$'\n'"$(echo $EXTRA_TESTS | tr ' ' '\n')"
echo "テストファイルをスコープに追加: $EXTRA_TESTS"
fi
3-2. 直接依存するファイルを探索する
変更ファイルのベース名(拡張子除く)を使って、importしているファイルをgrepで検索します。
for f in $CHANGED_FILES; do
BASENAME=$(basename "$f" | sed 's/\.[^.]*$//')
grep -rl "from.*['\"].*${BASENAME}['\"]" \
--include="*.ts" --include="*.tsx" \
--exclude-dir=node_modules --exclude-dir=.git \
. 2>/dev/null
done | sort -u | grep -v -F -f <(echo "$CHANGED_FILES")
3-3. 変更した関数・コンポーネントの使用箇所を探索する
差分から追加・変更された関数名・コンポーネント名を抽出し、使用箇所を最大10件探索します。意図しない使われ方・設計的に問題のある使われ方がないかを確認します。
CHANGED_NAMES=$(git diff origin/${BASE_BRANCH}...HEAD | \
grep '^+' | sed 's/^+//' | \
grep -oE '(export (function|const|class) [A-Za-z][A-Za-z0-9]+|function [A-Za-z][A-Za-z0-9]+)' | \
sed 's/export \(function\|const\|class\) //' | sort -u | head -10)
for name in $CHANGED_NAMES; do
echo "=== ${name} の使用箇所 ==="
grep -rn "\b${name}\b" \
--include="*.ts" --include="*.tsx" \
--exclude-dir=node_modules --exclude-dir=.git \
. 2>/dev/null | head -10
done
探索の成功条件は、CHANGED_NAMESに1件以上の名前が抽出でき、かつそれぞれの使用箇所が1件以上見つかることです。
CHANGED_NAMESが空の場合 — 差分にexport function / export const / functionの形式が含まれていない(クラスメソッド・アロー関数の再代入・型定義のみの変更など)。このときは差分を直接読んで関数名・コンポーネント名を手動で特定し、同様にgrep -rnで使用箇所を検索します
- 使用箇所が0件の場合 — 新規追加で未使用、またはバレルエクスポート経由で参照されている可能性があります。
knip --exportsの結果と照合して判断します
Step 4: 自動解析を実行する
変更ファイルの種類に応じて該当するCLIを実行します。ツール未インストール・コマンドエラーの場合はスキップして次に進みます。
使用するCLIツール
各コマンドはローカルインストール(node_modules/.bin/)→ グローバルインストール → npx -y(一時実行)の順に解決して実行します。
| ツール | 用途 | 解決方法 |
|---|
madge | 循環参照・依存数サマリー | ローカル → グローバル → npx -y |
knip | 未使用エクスポート検出 | ローカル → グローバル → npx -y |
markuplint | アクセシビリティ静的解析 | ローカル → グローバル → npx -y |
react-doctor | Reactコンポーネント診断 | ローカル → グローバル → npx -y |
socket | サプライチェーンリスク検出 | ローカル → グローバル → npx -y |
semgrep | セキュリティ静的解析 | インストール必須(brew install semgrep) |
npm audit | CVE検出 | npmに同梱(インストール不要) |
semgrepはPythonツールのためnpxで実行できません(brew install semgrep / mise use semgrep等でインストールが必要です)。
git履歴コンテキスト(.ts / .tsx / .js / .jsxが含まれる場合)
git履歴はファイルの「設計的な不安定さの蓄積」を示します。変更ファイルがもともとホットスポットかどうかを把握することで、レビューの深度・[設計]指摘の優先度を正しく判断できます。
各分析には一定のコミット数が必要です。最低ラインに満たない場合はその分析をスキップし、最低ライン以上・信頼できるライン未満の場合は結果に[低精度]を付加して出力します。
| 分析 | 最低ライン | 信頼できるライン | 対象単位 |
|---|
| ホットスポットスコア | 5回 | 10回 | ファイルごとのコミット回数 |
| 書き換え率 | 10回 | 20回 | ファイルごとのコミット回数 |
| Temporal Coupling | 10件 | 20件 | 変更ファイルを含むコミット総数 |
ホットスポットスコア(変更頻度 × 行数)
変更頻度が高く行数も多いファイルは「複雑なのに頻繁に触られる」ホットスポットです。今回の変更が問題をさらに悪化させていないかを重点的にレビューする判断材料にします。
for f in $CHANGED_FILES; do
[ -f "$f" ] || continue
count=$(git log --format=format: --name-only --since=12.month -- "$f" | grep -v '^\s*$' | wc -l | tr -d ' ')
lines=$(wc -l < "$f" | tr -d ' ')
if [ "$count" -lt 5 ]; then
continue
elif [ "$count" -lt 10 ]; then
echo "$((count * lines)) $count $lines $f [低精度: 変更回数${count}回]"
else
echo "$((count * lines)) $count $lines $f"
fi
done | grep -v '^$' | sort -nr
出力形式はスコア 変更回数 行数 ファイルパスです。
書き換え率(削除率)
削除率が50%超のファイルは「書いては消す」が繰り返されている設計の不安定シグナルです。今回の変更がその傾向をさらに強めていないかを確認します。
最低ライン(10回)以上のファイルのみを対象にし、信頼できるライン(20回)未満のファイルは注意付きで出力します。
REWRITE_TARGET=""
REWRITE_WARN=""
for f in $CHANGED_FILES; do
[ -f "$f" ] || continue
count=$(git log --format=format: --name-only --since=12.month -- "$f" | grep -v '^\s*$' | wc -l | tr -d ' ')
if [ "$count" -ge 10 ]; then
REWRITE_TARGET="$REWRITE_TARGET $f"
[ "$count" -lt 20 ] && REWRITE_WARN="$REWRITE_WARN $f(${count}回)"
fi
done
if [ -n "$REWRITE_TARGET" ]; then
git log --numstat --format=format: --since=12.month -- $REWRITE_TARGET \
| grep -v '^\s*$' \
| awk '{add[$3]+=$1; del[$3]+=$2} END {
for(f in add) {
total=add[f]+del[f];
if(total>0)
print int(del[f]/total*100) "% " total " " del[f] " " f
}
}' \
| sort -nr
[ -n "$REWRITE_WARN" ] && echo "[低精度] 信頼できるライン(20回)未満: $REWRITE_WARN"
else
echo "# 書き換え率: スキップ(最低ライン10回を満たすファイルなし)"
fi
出力形式は削除率 総変更行数 削除行数 ファイルパスです。
Temporal Coupling(暗黙の結合検出)
変更ファイルを起点に「常にペアで変更されるファイル」を検出します。今回のPRに含まれていないファイルがペアとして出現した場合、変更の見落とし(または暗黙の結合)の可能性があります。静的依存がなくても行動的に結合しているファイルを発見できます。
TC_COUNT=$(git log --format="%H" --since=6.month -- $CHANGED_FILES | sort -u | wc -l | tr -d ' ')
if [ "$TC_COUNT" -lt 10 ]; then
echo "# Temporal Coupling: スキップ(変更ファイルを含むコミット数 ${TC_COUNT}件: 最低ライン10件未満)"
else
git log --format=format: --name-only --since=6.month -- $CHANGED_FILES \
| awk '
/^$/ { for(i in files) for(j in files) if(i<j) pairs[i" <-> "j]++; delete files; next }
/[^ ]/ { files[$0]=1 }
END { for(p in pairs) if(pairs[p]>2) print pairs[p], p }
' | sort -nr | head -20
[ "$TC_COUNT" -lt 20 ] && echo "[低精度] 変更ファイルを含むコミット数 ${TC_COUNT}件(信頼できるライン: 20件以上)"
fi
出力形式は共変更回数 ファイルA <->ファイルBです。
出力されたペアのうち、CHANGED_FILESに含まれないファイルが片方に現れた場合は「変更漏れ候補」としてStep 5の[設計]レビューで確認します。
循環参照・依存数(.ts / .tsx / .js / .jsxが含まれる場合)
if [ -f node_modules/.bin/madge ]; then MADGE=node_modules/.bin/madge
elif command -v madge >/dev/null 2>&1; then MADGE=madge
else MADGE="npx -y madge@latest"; fi
CHANGED_DIRS=$(echo "$CHANGED_FILES" | xargs -I{} dirname {} | sort -u)
echo "$CHANGED_DIRS" | xargs -I{} sh -c "$MADGE --circular --ts-config tsconfig.json \"\$1\"" -- {} 2>/dev/null
echo "$CHANGED_FILES" | grep -E '\.(ts|tsx|js|jsx)$' | xargs sh -c "$MADGE --summary \"\$@\"" -- 2>/dev/null
未使用エクスポート(.ts / .tsx / .js / .jsxが含まれる場合)
if [ -f node_modules/.bin/knip ]; then KNIP=node_modules/.bin/knip
elif command -v knip >/dev/null 2>&1; then KNIP=knip
else KNIP="npx -y knip@latest"; fi
eval "$KNIP --exports" 2>/dev/null | head -30
セキュリティ静的解析(.ts / .tsx / .js / .jsxが含まれる場合)
CHANGED_JS=$(echo "$CHANGED_FILES" | grep -E '\.(ts|tsx|js|jsx)$' | xargs echo)
[ -n "$CHANGED_JS" ] && semgrep scan \
--config p/typescript --config p/react --config p/owasp-top-ten \
--severity=ERROR --severity=WARNING --no-rewrite-rule-ids \
$CHANGED_JS 2>/dev/null
ドメイン層純粋性チェック(domain/**/*.tsが含まれる場合)
CHANGED_DOMAIN=$(echo "$CHANGED_FILES" | grep -E 'domain/.*\.ts$' | xargs echo)
[ -n "$CHANGED_DOMAIN" ] && grep -n "import.*[Rr]eact\|JSX\.Element\|React\.ReactNode\|useState\|useEffect\|useCallback\|useMemo" \
$CHANGED_DOMAIN 2>/dev/null
CVE・サプライチェーンリスク(package.jsonが変更された場合)
npm audit --audit-level=moderate 2>/dev/null | head -30
if [ -f node_modules/.bin/socket ]; then SOCKET=node_modules/.bin/socket
elif command -v socket >/dev/null 2>&1; then SOCKET=socket
else SOCKET="npx -y @socketsecurity/cli@latest"; fi
eval "$SOCKET ci" 2>/dev/null | head -30
バンドルサイズ(package.jsonが変更された場合)
ビルドツールを検出してバンドルアナライザーを実行します。アナライザーが未インストールの場合はスキップします。
if grep -q '"next"' package.json 2>/dev/null; then
BUILD_TOOL="nextjs"
elif grep -q '"vite"' package.json 2>/dev/null; then
BUILD_TOOL="vite"
else
BUILD_TOOL="unknown"
fi
case "$BUILD_TOOL" in
nextjs)
if grep -q '"@next/bundle-analyzer"' package.json 2>/dev/null; then
ANALYZE=true npm run build 2>/dev/null | tail -30
else
echo "bundle-analyzer未設定(@next/bundle-analyzerをインストールして設定することで有効化できます)"
fi
;;
vite)
if grep -q '"rollup-plugin-visualizer"' package.json 2>/dev/null; then
npm run build 2>/dev/null | tail -20
else
echo "bundle-analyzer未設定(rollup-plugin-visualizerをインストールしてvite.configに追加することで有効化できます)"
fi
;;
esac
アクセシビリティ静的解析(.tsx / .jsxが含まれる場合)
CHANGED_JSX=$(echo "$CHANGED_FILES" | grep -E '\.(tsx|jsx)$' | xargs echo)
if [ -f node_modules/.bin/markuplint ]; then MARKUPLINT=node_modules/.bin/markuplint
elif command -v markuplint >/dev/null 2>&1; then MARKUPLINT=markuplint
else MARKUPLINT="npx -y markuplint@latest"; fi
[ -n "$CHANGED_JSX" ] && eval "$MARKUPLINT $CHANGED_JSX" 2>/dev/null
React診断(.tsx / .jsxが含まれる場合)
react-doctorによる自動診断
if [ -f node_modules/.bin/react-doctor ]; then RDOCTOR=node_modules/.bin/react-doctor
elif command -v react-doctor >/dev/null 2>&1; then RDOCTOR=react-doctor
else RDOCTOR="npx -y react-doctor@latest"; fi
eval "$RDOCTOR $CHANGED_JSX --verbose" 2>/dev/null | head -120
コマンドが失敗した場合はスキップします。
Vercel React Best Practices
Skillツールでvercel-react-best-practicesを適用します。スキルが起動できない場合はvercel-labsにあるファイルを参照して実行します。
Skill: vercel-react-best-practices
引数: 以下のコードをVercelのReactベストプラクティスの観点でレビューしてください。<対象コード>
Vercel Composition Patterns
Skillツールでvercel-composition-patternsを適用します。スキルが起動できない場合はvercel-labsにあるファイルを参照して実行します。
Skill: vercel-composition-patterns
引数: 以下のコードをVercelのCompositionパターンの観点でレビューしてください。<対象コード>
Step 5: コードレビューを実施する
Step 4が完了してから着手します。
「コードレビュー」はClaude Codeが差分を直接読んで行う評価を指します。Step 4の「自動解析」(CLIツール出力)とは区別して使用します。
カテゴリ
指摘に紐づけるカテゴリは以下の8つです。1つの指摘に複数のカテゴリを付与してかまいません。
| カテゴリ | 判断基準 |
|---|
[ロジック] | 実行時に正しく動くか。null参照・await忘れ・競合状態など、動作が誤っているまたはクラッシュする可能性がある問題 |
[設計] | コードの構造・責務の分担が適切か。UIとロジックの混在・コンポーネントの肥大化・依存関係のもつれなど、正しく動いていても将来の変更が難しくなる問題 |
[型] | TypeScriptの型で正しくモデル化されているか。asの乱用・暗黙的any・Union型の網羅漏れなど、型システムが実際の値の形を正確に表現していない問題(コンパイルは通っても型が嘘をついている状態) |
[パフォーマンス] | 不要な処理・再レンダリングが発生していないか。インライン生成・ループ内検索・バンドルサイズ増加など |
[セキュリティ] | 攻撃に悪用できる実装になっていないか。XSS・認証情報の漏洩・フロントのみの権限チェックなど |
[テスト] | 変更に対してテストが十分か。テスト不足・実装詳細への依存・エッジケース漏れなど |
[A11Y] | すべてのユーザーが操作できるか。セマンティクス不足・aria属性漏れ・キーボード操作の欠如など |
[その他] | 上記いずれにも当てはまらない指摘 |
5-1. 自動解析結果の整理
Step 4で取得した全ツール・全スキルの出力から指摘を抽出し、同一または実質同じ内容はひとつの項目に集約します。各項目には該当するカテゴリを複数付与してかまいません。出力がない場合は省略します。
- <指摘内容> [`[カテゴリ1]` `[カテゴリ2]`]
出典: <madge / knip / semgrep / npm audit / socket / バンドルアナライザー / react-doctor / markuplint / Vercel React Best Practices / Vercel Composition Patterns>
5-2. コードレビュー
差分・スコープファイルを読み、自動解析では検出できない問題を中心にコードレビューを実施します。条件に該当するカテゴリはスキップします。読み込んだルールを基準にコードレビューを実施します。
適用ルールの読み込み
CHANGED_FILESのパターンに応じて以下のルールファイルを読み込み、レビュー基準に加えます。各ルールファイルのフロントマターに記載されたpaths:が適用条件です。
.claude/rules/writing-style.md
.claude/rules/frontend-architecture.md
.claude/rules/frontend-coding-guidelines.md
.claude/rules/frontend-security.md
.claude/rules/frontend-a11y.md
.claude/rules/frontend-styling.md
.claude/rules/frontend-testing.md
.claude/rules/frontend-api.md
条件に合致するルールファイルをReadツールで読み込みます。読み込んだルールは後続のチェック項目と合わせてレビュー基準として使用します。読み込んだルールファイルの一覧を以下の形式で出力します。
**適用ルール**
- `.claude/rules/writing-style.md`(すべてのファイルに適用)
- `.claude/rules/frontend-testing.md`(テストファイルが含まれるため適用)
…
適用条件
| カテゴリ | 適用条件 |
|---|
[ロジック] | .ts / .tsx / .js / .jsxが含まれる |
[設計] | .ts / .tsx / .js / .jsxが含まれる |
[型] | .ts / .tsxが含まれる |
[パフォーマンス] | .ts / .tsx / .js / .jsxが含まれ、かつテスト・設定ファイルのみでない |
[セキュリティ] | テストファイル以外が含まれる |
[テスト] | 設定ファイル・型定義以外が含まれる |
[A11Y] | .tsx / .jsx / .htmlが含まれる |
チェック項目
Step 4の自動解析で検知できないもの、およびプロジェクト固有の判断が必要なものに絞って確認します。
[ロジック]
なし。
[設計]
- ホットスポットスコアが高いファイルへの変更 — 変更頻度が高く行数も多いファイルに新たにロジックを追加している場合、責務が肥大化していないかを確認します。分割・抽出を提案する判断材料にします
- 書き換え率が50%超のファイルへの変更 — 今回の変更が同じ「書いては消す」パターンの繰り返しになっていないかを確認します。設計レベルで解決できる根本原因がないかを検討します
- Temporal Couplingで未含ファイルが検出された場合 — 常にペアで変更されるはずのファイルが今回のPRに含まれていない場合、変更の見落としか意図的な除外かを確認し、意図的でなければ指摘します
[型]
なし。
[パフォーマンス]
なし。
[セキュリティ]
なし。
[テスト]
なし。
[A11Y]
なし。
Step 6: 結果を統合して出力する
サマリー(モード別)
REVIEW_MODE=prの場合
## PRサマリー
- **タイトル**: <タイトル>
- **作成者**: <作成者>
- **ベースブランチ**: <base> ← <head>
- **変更ファイル数**: <N>ファイル
REVIEW_MODE=localの場合
## ブランチサマリー
- **ブランチ**: <current-branch>
- **ベース**: <base-branch>
- **コミット数**: <N>件
- **変更ファイル数**: <N>ファイル
- **未コミット変更**: あり / なし
レビュー指摘事項
各指摘をファイルパスでソートして統合します。同じファイルへの複数の指摘はファイルごとにまとめます。既存のレビューコメントと重複する指摘は除外します。
## レビュー指摘事項
### <ファイルパス>
**L<行番号>** [<重要度>] `[<カテゴリ>]` <指摘内容>
> <該当コードの引用>
<理由と改善案>
重要度は以下の通りです。
must — バグ・セキュリティリスクなど、マージ前に修正が必要
should — 設計・可読性の改善など、強く推奨
nit — 些細な改善提案、好みの範囲
カテゴリはStep 5で定義したカテゴリを使用します。
git履歴コンテキスト(TS/JSファイルが含まれる場合)
git履歴コンテキストの分析結果から、レビューに影響する情報のみを出力します。シグナルが何もない場合は省略してかまいません。
## git履歴コンテキスト
**ホットスポット**(変更頻度が高く行数も多いファイル)
- <ファイルパス>: スコア<N>(変更<N>回 / <N>行)
**書き換え率が高いファイル**(削除率50%超)
- <ファイルパス>: 削除率<N>%
**Temporal Coupling(変更漏れ候補)**
- <ファイルA> <-> <ファイルB>: <N>回のコミットで共変更 ※今回のPRに<ファイルB>が含まれていない
総評
## 総評
<変更全体の評価>
<REVIEW_MODE=prの場合: approve / request changes / commentの推奨>
Step 7: レビュー後のアクション(REVIEW_MODE=prのみ)
REVIEW_MODE=localの場合はこのステップをスキップします。
AskUserQuestionで次のアクションを選択してもらいます。
{
"question": "レビュー結果をどうしますか?",
"options": [
{ "label": "approve", "description": "gh pr review --approveで承認する" },
{ "label": "request changes", "description": "gh pr review --request-changesで変更リクエストする" },
{ "label": "comment", "description": "gh pr review --commentでコメントのみ投稿する" },
{ "label": "何もしない", "description": "GitHubへの投稿はしない" }
]
}
「何もしない」以外が選択された場合、投稿内容を表示してユーザーの承認を得てから実行します。
注意事項
- PRの差分が大きい場合は、変更ファイルをカテゴリ別に整理して段階的にレビューします
- CLIツールがエラーになった場合はスキップしてコードレビューを優先します
- PRの作成者への敬意を忘れず、建設的なフィードバックを心がけます