unity-code-review について
unity-code-reviewは、Gitのステージ済み変更を対象に、リポジトリの規約と元の仕様を別々に確認するコードレビュー用スキルです。2つのレビュー用サブエージェントを並行実行し、指摘を集約します。
主な機能
- 01ステージ済み変更のレビュー
- 02規約と仕様の個別確認
- 032つのサブエージェントの並行実行
- 04レビュー指摘の集約
- 05仕様がない場合の処理
活用シーン
- 01コミット前のステージ済みコード確認
- 02実装とタスク仕様の照合
- 03規約違反やコードスメルの検出
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ icarealot/ dotfiles --skill unity-code-reviewインストール後、Claude Code で/unity-code-reviewを入力して読み込まれたか確認します。
詳細
翻訳後に原文が更新されています。最新の内容は原文をご確認ください。
現在の Git インデックス(ステージ済みの変更)を 2 つの軸でレビューします。
- 標準:コードはこのリポジトリで文書化されているコーディング標準に準拠していますか?
- 仕様:コードは元となるタスク/仕様を忠実に実装していますか?
2 つの軸は、互いのコンテキストを汚染しないよう並列のサブエージェントとして実行され、その後、このスキルが調査結果を集約します。
プロセス
1. ステージ済みのレビュー対象を確定する
git status --short を確認し、git diff --cached でステージ済みの追加、変更、削除、名前変更を含むレビュー用差分を取得します。git diff --cached --name-status でステージ済みファイルの一覧を記録します。
ステージ済みの変更がない場合は、No staged changes to review. と正確に報告し、サブエージェントを起動する前に終了します。
ステージ済みの差分がレビューの対象範囲です。ステージ済みファイルの内容は git show :<path> で読み込み、作業ツリーではなくインデックスにある状態をレビューします。関連ファイルはコンテキストとしてのみ読み込みます。ステージされていない変更と未追跡の変更はレビュー対象外です。
2. 仕様の出典を特定する
次の順で元となる仕様を探します。
- ユーザーが引数として渡したパス。
- ブランチ名または機能に一致する、
docs/、specs/、.scratch/以下の仕様ファイル。 - 見つからない場合は、仕様の場所をユーザーに尋ねます。仕様がないとの回答があれば、仕様サブエージェントはレビューをスキップし、「no spec available」と報告します。
3. 標準の出典を特定する
コードの書き方を説明するリポジトリ内の文書(CODING_STANDARDS.md や CONTRIBUTING.md など)を確認します。
リポジトリで文書化されている内容に加え、標準の軸では、以下の臭いの基準を常に適用します。これは Fowler のコードの臭い(Refactoring 第 3 章)から定めたもので、リポジトリに文書がなくても適用されます。これには、次の 2 つのルールがあります。
- リポジトリの規約を優先します。 文書化されたリポジトリ規約は常に優先されます。基準で指摘される内容がリポジトリで推奨されている場合、その臭いは指摘対象から除外します。
- 常に判断を伴います。 各臭いは「Feature Envy の可能性」のようにラベル付けされたヒューリスティックであり、確定的な違反ではありません。この軸の他の標準と同様に、ツールで既に強制されているものは指摘しません。
各臭いは、内容 → 修正方法の順に示されています。差分と照らし合わせて確認してください。
- 不可解な名前(Mysterious Name):何をするのか、何を保持するのかが名前から分からない関数、変数、型です。→ 名前を変更します。適切な名前が思いつかない場合は、設計が曖昧です。
- コードの重複(Duplicated Code):変更内の複数のハンクまたはファイルに、同じ形のロジックが現れます。→ 共通の形を抽出し、両方から呼び出します。
- Feature Envy:自身のデータよりも他のオブジェクトのデータを多く参照するメソッドです。→ 参照先のデータを持つオブジェクトにメソッドを移します。
- データのかたまり(Data Clumps):同じ少数のフィールドやパラメーターが何度も一緒に使われています(専用の型を作るべき状態です)。→ それらを 1 つの型にまとめて渡します。
- プリミティブへの執着(Primitive Obsession):独自の型にする価値のあるドメイン概念を、プリミティブ型や文字列で表しています。→ その概念を表す小さな型を作ります。
- 繰り返される switch(Repeated Switches):同じ型に対する
switch/ifの連鎖が、変更内の複数箇所で繰り返されています。→ ポリモーフィズムに置き換えるか、両方の箇所で共有する 1 つのマップにまとめます。 - ショットガン手術(Shotgun Surgery):1 つの論理的な変更によって、差分内の多くのファイルに散在する編集が必要になります。→ 変更される箇所を 1 つのモジュールにまとめます。
- 発散する変更(Divergent Change):1 つのファイルまたはモジュールが、互いに無関係な複数の理由で編集されています。→ 各モジュールが 1 つの理由で変更されるよう分割します。
- 投機的一般化(Speculative Generality):仕様で必要とされていない抽象化、パラメーター、フックが追加されています。→ 削除します。実際に必要になるまではインライン化します。
- メッセージチェーン(Message Chains):呼び出し元が依存すべきでない、長い
a.b().c().d()のような連鎖です。→ 最初のオブジェクトに処理を隠すメソッドを用意します。 - 仲介人(Middle Man):主に別の処理へ委譲するだけのクラスまたは関数です。→ 取り除き、実際の対象を直接呼び出します。
- 継承の拒否(Refused Bequest):継承した機能の大部分を無視またはオーバーライドするサブクラスや実装クラスです。→ 継承をやめ、コンポジションを使います。
4. 両方のサブエージェントを並列で起動する
両方のサブエージェント呼び出しをまとめてフォアグラウンドで実行し、返されたレポートを集約します。
Standards サブエージェントのプロンプトには、以下を含めます。
- ステップ 1 のステージ済み差分コマンドとファイル一覧、およびレビュー範囲とインデックスの読み取りに関する指示。
- ステップ 3 で見つけた標準の参照ファイル一覧に加えて、ステップ 3 の臭いのベースラインを全文で貼り付けます(サブエージェントはそれ以外の方法でこれにアクセスできません)。
- 次の依頼文:「該当する場合はファイル/ハンクごとに、(a)文書化された標準に違反している箇所をすべて報告し、その標準(ファイル+ルール)を引用してください。(b)見つかったベースラインの臭いを報告し、その名前と該当ハンクを引用してください。ハード違反と判断を要する指摘を区別してください。文書化された標準への違反はハード違反になり得ますが、ベースラインの臭いは常に判断を要する指摘です。また、文書化されたリポジトリの標準はベースラインより優先されます。ツールによって強制される事項は除外してください。400 語未満で回答してください。」
Spec サブエージェントのプロンプトには、以下を含めます。
- ステップ 1 のステージ済み差分コマンドとファイル一覧、およびレビュー範囲とインデックスの読み取りに関する指示。
- 仕様のパスまたは取得した内容。
- 次の依頼文:「以下を報告してください。(a)仕様で求められているのに未実装、または一部しか実装されていない要件。(b)差分に含まれているが、仕様では求められていない動作(スコープクリープ)。(c)実装済みに見えるものの、実装が誤っているように見える要件。それぞれの指摘について、仕様の該当行を引用してください。400 語未満で回答してください。」
仕様が見つからない場合は Spec サブエージェントを省略し、最終レポートにその旨を記載します。
5. 集約する
2 つのレポートを ## Standards と ## Spec の見出しの下に、原文のまま、または軽く整えて掲載します。指摘を統合したり、順位付けし直したりしないでください。2 つの評価軸は意図的に分けられています(「2 つの評価軸を設ける理由」を参照)。
最後に、各評価軸の指摘の合計数と、それぞれの評価軸で最も重大な問題(あれば)を 1 行でまとめます。評価軸をまたいで最優先の問題を選ばないでください。評価軸を分けている目的に反するためです。
2 つの評価軸を設ける理由
変更は、一方の評価軸では問題がなくても、もう一方では問題がある場合があります。
- すべての標準に従っているコードが、要求と異なる内容を実装している場合 → Standards は合格、Spec は不合格。
- タスクの要求どおりに実装されているコードが、プロジェクトの規約に違反している場合 → Spec は合格、Standards は不合格。
別々に報告することで、一方の評価軸がもう一方の評価軸の問題を覆い隠すのを防げます。