mcpField
A
antfu-simplify

antfu-simplify

github.com/antfu開発6.0k137 回インストール3 日前に更新
リポジトリ

antfu-simplify について

現在の PR または作業ツリーの差分を、動作を変えずに最小限の正しい変更へ整理するコードレビュー用スキルです。削除を小分けに検証し、残した箇所と除いた箇所、差分量、チェック結果を報告します。

主な機能

  1. 01現在の変更差分をレビュー
  2. 02冗長または推測的な要素を削除
  3. 03動作と対象範囲を維持
  4. 04各バッチ後にチェックを実行
  5. 05判断内容と差分量を報告

活用シーン

  1. 01PR の抽象化を減らす
  2. 02追加した分岐やヘルパーの必要性を確認
  3. 03レビュー前に作業ツリーの変更を縮小

インストール

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

$npx skills add https://github.com/antfu/skills --skill antfu-simplify

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

詳細

変更を簡素化する

現在の変更(PR ブランチまたは作業ツリー)を確認し、熟練した開発者のように、正しさを保ちながら差分を最小限に絞り込みます。手法はアブレーションスタディです。各要素を取り除き、重要なものが壊れないかを確かめ、残す価値のあるものだけを残します。

目標は、ちょうどよい抽象化を備え、堅牢(実際に起こり得るエッジケースに対応)で、汎用的(変更のきっかけとなったケースだけでなく、一般的なケースを解決)な、クリーンで最小限のコードです。

厳守事項

  • 動作は変えません。 簡素化のみを行います。機能の追加、公開 API の変更、無関係な問題の修正はしないでください。無関係な指摘事項は別途報告してください。
  • 対象は差分です。 変更で追加または修正されたコードと、それを削除するために変更が必要なコードのみを編集してください。周辺のコードベースをリファクタリングしないでください。
  • 削除はすべて検証します。 各まとまりの変更後に、リポジトリのテスト、型チェック、リンターを実行してください。削除した部分がチェックの対象になっていない場合は、明示的に検討するか、その部分を残してください。
  • 周囲のコードのスタイル、命名、コメントの密度に合わせてください。

ワークフロー

  1. 差分を取得します。 基点を選びます。PR の場合は対象ブランチとのマージベース(git merge-base HEAD origin/<default>)、未コミットの作業の場合は git diff HEAD を使います。差分全体と、その周辺のファイルを読みます。変更の目的を一文で記します。以降のすべての判断基準にします。
  2. 要素を洗い出します。 差分で追加された各要素を列挙します。関数、パラメーター、オプション、分岐、型、ファイル、依存関係、抽象化レイヤー、コメント、テストを確認します。アブレーションスタディを参照してください。
  3. アブレーションします。 各要素について、削除、インライン化、統合を試します。残すか削るかに基づいて判断します。
  4. 変更を適用します。 小さなまとまりごとに削除し、そのつど対象を絞ったチェック(テスト、型チェック、リンター)を実行します。動作に問題が生じたら削除を元に戻します。その要素には必要性があると確認できたことになります。
  5. 結果を確認します。 レビュアーの視点で最終差分を読み直します。残した各行は、一文で示した目的によって説明できますか? 堅牢性と汎用性は保たれていますか?
  6. 報告します。 削除または維持した内容とその理由を短い表にまとめ、変更前と変更後の差分サイズ(git diff --stat)も示します。依頼がない限り、コミットはしないでください。

アブレーションスタディ

差分に含まれる各要素について、次のように問いかけます。これを削除すると、具体的に何が壊れますか?

要素アブレーション維持する条件
新しい関数/ヘルパー呼び出し元にインライン化する2 か所以上から呼び出されている、または名前が自明でない処理を説明している
ラッパー/抽象化レイヤー内部の処理を直接呼び出す実際の複雑さを隠している、または変更される可能性の高い境界を分離している
パラメーター/オプション/設定唯一使用されている値をハードコードする現在、異なる値を必要とする実際の呼び出し元がある
型/インターフェース/ジェネリック推論された型または既存の型を使うエクスポートされている、または型推論では型が悪化するか誤った型になる
分岐/ガード/try-catch削除してテストを実行する到達可能なケース(実際の入力、実際の失敗)を防いでいる。起こり得ないケースではない
新しいファイル/モジュール唯一の利用元に統合する利用元が複数ある、または独立した責務がある
依存関係数行のコードまたは既存の依存関係で置き換えるほかの方法では誤りやすい難しいエッジケースに対応している
重複したロジックリポジトリ内の既存ユーティリティを再利用する同等のものがない(先に検索する)
コメント削除する「何を」ではなく「なぜ」を説明している(制約、回避策、意外な選択など)
テスト削除して、何が保護されなくなるかを確認するほかのテストではカバーされない動作またはリグレッションを検証している
目的に無関係な変更行元に戻すついでに行った変更は残さない

残すものと削るもの

次のような要素は削除します。

  • 推測に基づくもの:誰も必要としていない将来のニーズに備えて作られたもの(余分なオプション、フック、プラグイン用の拡張ポイント、「念のため」のジェネリクスなど)。
  • 重複するもの:言語、フレームワーク、型、既存のユーティリティがすでに提供している機能を繰り返すもの。
  • 起こり得ない事態への防御:型や呼び出し元によって保証されている値への null チェック、実行されないフォールバック、エラーを握りつぶす catch ブロック。
  • 効果のない間接化:一度しか使わないヘルパー、単に処理を受け渡すだけのラッパー、関数で済むのにクラスを使うこと、一つのものだけを構築するファクトリー。
  • ノイズ:コメントアウトされたコード、内容を説明するだけのコメント、未使用のインポートやエクスポート、書式だけを変更する差分。

次のような要素は残します(必要であれば追加します)。

  • 堅牢性: 現実に起こり得るエッジケースに対応するもの(空の入力、並行処理、クリーンアップ、クロスプラットフォームのパス、コンテキストを伴うエラーの伝播)。
  • 汎用性: 報告された問題だけに特化せず、一般的な問題を解決するもの。修正でバグ報告にある名前、パス、値をハードコードしている場合は、汎用化します。
  • 適切な規模の抽象化: 同じ処理が3回目に現れたら抽出します。通常、1回目と2回目では抽出しません。良い抽象化は、追加するコードより多くのコードを削減します。

抽象化が小さすぎる場合は統合し、一つの関数が無関係な処理を複数行う場合は分割します。目指すのは、行数を最小にすることでも、レイヤーを最大にすることでもなく、読者が把握しなければならない概念を最小限にすることです。

注意すべきコードの兆候

  • 原因ではなく、呼び出し箇所で症状を修正するパッチ。
  • 一般的なルールで対応できる特殊ケース(if (name === 'foo'))。
  • わずかな違いで同じ処理を行う2つのコードパス。統合します。
  • 既存のデータから導出できる状態、フラグ、キャッシュ。
  • 長いパラメーターリストやオプションの詰め合わせ。ほとんどの値が変更されないもの。
  • typeof、ReturnType、Parameters、ユーティリティ型で導出できるのに、手作業で重複して定義された型。
  • リポジトリ、ランタイム、既存の依存関係がすでに提供しているのに、独自に実装したユーティリティ。
  • 実装の詳細を検証するテストや、コードを一行ずつそのままなぞるテスト。

レポート形式

| # | Piece | Action | Why |
|---|-------|--------|-----|
| 1 | `parseOptions()` in src/cli.ts | inlined | one caller, 3 lines |
| 2 | `retry` option | removed | no caller passes it; default is enough |
| 3 | `try/catch` in fetchData | kept | network errors reach users; test covers it |

Diff: +142 -8 -> +61 -8. Tests, typecheck, lint pass.

範囲外の気づいた点(無関係なバグ、より広範なリファクタリングなど)は分けて記載し、手を加えないでください。

コメント