dead-code-sweep について
dead-code-sweepは、コードベース内の未使用コード、重複実装、孤立した成果物を検出・整理するエージェントスキルです。到達可能性やCI・テストからの参照を確認し、確度付きで報告したうえで、承認後に削除します。
主な機能
- 01対象範囲とエントリーポイントの把握
- 02孤立コードと重複実装の検出
- 03CIとテスト内の参照確認
- 04確度別の調査結果レポート
- 05承認項目の削除と検証
活用シーン
- 01リファクタリング後の残存物の監査
- 02未使用と思われるファイルやエクスポートの確認
- 03承認を得たうえで死んだコードを整理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ petekp/ claude-code-setup --skill dead-code-sweepインストール後、Claude Code で/dead-code-sweepを入力して読み込まれたか確認します。
同梱ファイルreferences/cruft-patterns.md
詳細
デッドコードの一掃
コードベース内のデッドコード、冗長な実装、孤立したアーティファクトを体系的に特定して削除します。特に、限られたコンテキストウィンドウで動作するコーディングエージェントが保守するコードベースを対象とします。
エージェントが保守するコードベースに不要物が蓄積する理由
コーディングエージェントが扱えるコンテキストウィンドウは限られています。リファクタリングの際、次のようなことがよく起こります。
- 元の実装を見つけて削除せずに、機能を再実装する
- すでに存在しないインターフェースの互換性シムを残す
- ロジックをインライン化した後、ヘルパー関数を放置する
- 置き換えたファイルを削除せず、新しいファイルを作成する
- モジュール間で型定義を重複させる
- リファクタリングの途中で使わなくなったシンボルのインポートを残す
こうした不要物は積み重なります。孤立したアーティファクトは、次のエージェント(または人間)を惑わせ、何もしていないコードを読むためにコンテキストの予算を浪費させます。
ワークフロー
フェーズ 1:範囲と構成の把握
分析範囲を決定します。
ユーザーが範囲を指定した場合(ディレクトリ、ファイルパターン、モジュール)は、分析をその範囲に限定します。
範囲が指定されていない場合は、コードベース全体を分析します。まず、プロジェクト構成を確認します。
- 主な言語とフレームワークを特定します
- エントリーポイント(メインファイル、ルート定義、エクスポートされたモジュール、テストランナー)を把握します
- ビルドシステムと依存関係の設定を確認します
- モノレポ構成かどうかを確認し、各パッケージを単位として分析します
簡潔な構成一覧を作成します。
Language(s): TypeScript, Python
Entry points: src/index.ts, src/cli.ts
Build: esbuild via package.json scripts
Packages: 1 (single package)
Estimated LOC: ~4,200
フェーズ 2:検出
並列サブエージェントを起動し、さまざまなカテゴリのデッドコードをスキャンします。検出パターンの全一覧は references/cruft-patterns.md を参照してください。
検出は、次の並列トラックに分けて行います。
| トラック | 検出対象 |
|---|---|
| 孤立したファイル | ほかのファイルからインポート、読み込み、参照されていないファイル |
| 未使用のエクスポート | ほかの場所から一度もインポートされていない、エクスポート済みのシンボル(関数、クラス、型、定数) |
| 冗長な実装 | 異なる名前で同じ処理を行う複数の関数やクラス |
| 古くなった互換性コード | 異なる点がなくなったインターフェース間をつなぐシム、アダプター、ラッパー、再エクスポート |
| デッドブランチ | 実行されることのない条件分岐(常に真/偽となるガード、到達不能な戻り値) |
| 孤立したテスト | すでに存在しない関数やモジュールをテストするテストファイル |
| 孤立した依存関係 | ソース内のどこからもインポートされていない、依存関係マニフェスト内のパッケージ |
各トラックのサブエージェントは、次の手順に従います。
- そのトラックに固有の検出方法を確認するため、
references/cruft-patterns.mdを読みます - Grep と Glob を使ってコードベースを検索します
- 参照をたどって候補を検証します。シンボルがデッドであるのは、生きているコードパスから一切到達できない場合に限ります
3b. 候補へのパス参照が CI スクリプトやシェルのテストフィクスチャにないか検索します:
rg <filename> -- scripts/ tests/ .github/。ラチェットチェックの引数や Bats テストフィクスチャとして読み込まれるファイルは、ソースファイルからインポートされていなくてもデッドではありません。 - ファイルパス、行範囲、根拠を添えて検出結果を記録します
検証は非常に重要です。 次のような誤検出に注意してください。
- 動的ディスパッチ、リフレクション、文字列ベースの検索を通じて使われるシンボル
- フレームワークの規約によるエクスポート(例:Next.js のページコンポーネント、pytest のフィクスチャ、Rails の規約)
- 外部の利用者を想定した公開 API
- 機能フラグや環境チェックの背後にある条件付きインポート
- デコレーターやプラグインに登録されたハンドラー
- package.json の
binフィールドから参照される CLI エントリーポイント - テンプレートや JSX で動的な文字列として参照される CSS クラス名
- パスでファイルを参照する CI スクリプトやシェルのテストフィクスチャ。例:
scripts/ci/内のcheck_file_contains "name" "path/to/file"や、tests/**/*.bats内のcat "$PROJECT_ROOT/path/to/file"。これらは文字列引数であり、インポートではないため、インポート追跡ツールでは完全に見落とされます。
判断に迷う場合は「デッドと確認済み」ではなく「要レビュー」としてください。
フェーズ 3:レポート
すべての調査結果を .claude/dead-code-report.md に構造化レポートとしてまとめます。
調査結果は、確信度ごとに分類してからカテゴリ別に整理します。
# Dead Code Sweep Report
**Scope:** [full codebase | specific path]
**Date:** [date]
**Estimated removable lines:** [count]
## Confirmed Dead (high confidence)
### Orphaned Files
- `src/utils/old-parser.ts` — Not imported anywhere. Superseded by `src/parser/index.ts`.
- ...
### Unused Exports
- `formatDate()` in `src/helpers.ts:42-58` — Exported but zero imports across codebase.
- ...
[...other categories...]
## Needs Review (uncertain)
### Possibly Dynamic
- `handleLegacyEvent()` in `src/events.ts:91` — No static imports, but may be registered dynamically.
- ...
各調査結果には、以下を含めます。
- ファイルパスと行範囲
- 対象(関数、クラス、ファイル、型、定数、依存関係)
- 不要と思われる理由(インポートがない、参照がない、X に置き換えられている)
- 確信度(確認済み/要レビュー)
フェーズ 4:承認を得てクリーンアップ
レポートの概要をユーザーに提示し、削除する前に承認を求めます。
AskUserQuestion を使って、調査結果をカテゴリ別に提示します。
Found 12 confirmed dead items and 3 needing review.
Confirmed dead by category:
- 3 orphaned files (~280 lines)
- 5 unused exports (~120 lines)
- 2 redundant implementations (~90 lines)
- 2 orphaned dependencies
Which categories should I clean up?
選択肢:確認済みの項目をすべて削除/カテゴリを選択/各項目をレビュー/クリーンアップをスキップ
承認されたカテゴリごとに、次の手順を実行します。
- 不要なコードを削除する
- 削除したコードを参照していたインポートをクリーンアップする
- クリーンアップ後に残った空のファイルを削除する
- マニフェストから不要な依存関係を削除する
- プロジェクトの lint/型チェック/ビルドコマンドを実行し、問題がないことを確認する
削除によってビルドエラーまたは型エラーが発生した場合は、該当する削除を直ちに元に戻し、その項目を「要レビュー」に移します。
クリーンアップ後、削除した項目と残した項目をレポートに反映します。
検出の原則
疑わしいコードではなく、エントリーポイントからたどる
疑わしいシンボルから始めて使用されていることを証明しようとするのではなく、既知のエントリーポイントから開始し、そこから到達可能な範囲をたどります。到達可能性を調べるアプローチのほうが、見落としが少なくなります。
モジュール境界を尊重する
パッケージの公開 API からエクスポートされるシンボルは、このリポジトリからは見えない外部コードで使用されている可能性があります。外部の利用者がいるライブラリやパッケージを分析する場合、「確認済み」として指摘するのは内部の(公開 API ではない)不要なコードに限ります。公開 API の不要なコードは「要レビュー」として指摘します。
個々の項目だけでなく、まとまりを探す
エージェントが生成した不要なコードは、ひとかたまりになっている傾向があります。不要な関数を見つけたら、周辺も確認してください。エージェントがリファクタリング中に、そのセクション全体を放棄している可能性があります。不要なファイルの近くに、同じコミットで作成された不要なファイルが残っていることもよくあります。
git の履歴を判断材料として使う
利用できる場合は、疑わしいコードが最後に実質的な変更を受けた時期を確認します。複数回のリファクタリングコミットを経ても変更されていないコードは、不要である可能性が高くなります。git log --follow を使って名前変更の履歴を追跡し、置き換えられたファイルを検出します。
ソースコードだけでなく、CI とテスト基盤も確認する
ソースコードからの参照がゼロのファイルでも、CI スクリプト(scripts/ci/、.github/workflows/)、シェルテストのフィクスチャ(tests/**/*.bats)、検証ツール(.verifier/)から利用されている可能性があります。これらの参照はシェル関数への文字列引数として現れるため、インポートの追跡では見つかりません。ファイルを孤立していると分類する前に、必ず rg <filename> -- scripts/ tests/ .github/ を実行します。