Claude CodeにCLIツールを渡して精度と効率を上げる
Claude Codeを使い始めたときに驚いたのは、ファイルを探索して構造や問題点を探し当てるのが上手なことでした。詳細なコマンドを指示しなくても、grepやfindを自ら実行して、コードベースを読み解いて回答を返してくれます。
でも、精度が期待よりも低かったり、何かよくわからない処理を延々と繰り返していることもあります。たとえば次のようなことです。
- 直前のやり取りや自分の回答に引っ張られて、遠回りなやり方に固執する
- 会話が長くなるにつれて、途中の情報を見落としたり最初に渡した指示を忘れたりして精度が下がる
その一方、CLIツールはAIエージェントのような柔軟性は高くありませんが、機械的に処理されるので再現性の高さが長所です。つまり、「探索と分析はCLIツールを優先して使い、LLMにはその結果の解釈と判断を任せる」という使いわけが効果的なのではないかと考えています。
この記事では、わたしがClaude Codeに使ってもらっているCLIツールを紹介します。
1. 未使用コード・デッドコードの検出
Knip
未使用ファイル・未使用エクスポート・未使用依存関係を検出するツールです。プロジェクト全体をASTレベルで解析するため、grepでは見つけられない「エクスポートされているが、インポートしていない関数」を確実に検出できます。
# コンパクトな出力で未使用コードを検出
knip --reporter compact
Claude Codeとの組み合わせ方
「不要なコードを整理したい」という依頼に対して、まずknipを実行してくれます。
Claude Codeが自力でファイル間の参照を追うと時間がかかるうえに、複雑な構造だと見落としも出ます。
Knipの結果を元にすれば「この20個のエクスポートは未使用」「この5つの依存パッケージはインストールされているが使われていない」と確定的なリストが得られます。Claude Codeはそのリストを元に、安全に削除できるものとできないものを判断してくれます。
2. 依存関係の分析
Madge
JavaScriptとTypeScriptを対象に、モジュール依存関係をグラフ化するツールです。循環参照の検出がとくに便利です。
# 循環参照を検出
madge --circular --ts-config tsconfig.json src/
# 依存数のサマリー(依存が多い順)
madge --summary src/ | sort -t: -k2 -nr | head -20
# 孤立ファイル(どこからも参照されていないファイル)
madge --orphans src/
Claude Codeとの組み合わせ方
「このモジュールの依存関係を整理して」という依頼で、Claude Codeがimport文を1つずつ追うのは非効率です。madge --circularで循環参照を検出して、madge --summaryで依存数の多い「ハブ」ファイルを特定してくれます。
構造の全体像がデータとして得られるので、Claude Codeはそれを元に「この循環を解消するにはモジュールAからBへの依存を切ればいい」といった具体的な提案ができます。
dependency-cruiser(depcruise)
依存関係をルールベースでバリデーション・可視化するツールです。Madgeより高機能で、アーキテクチャの制約をルールとして定義できるのも特徴です。
# 不安定性メトリクス(モジュールの安定度を数値化)
depcruise --metrics -T metrics src/ | head -40
Claude Codeとの組み合わせ方
不安定性メトリクスは「そのモジュールがどれだけ変更の影響を受けやすいか」を数値化したものです。逆依存(他から参照される数)が多いのに不安定性指数が高いモジュールは、アーキテクチャ上の問題を抱えている可能性が高いです。
たとえば、認証の仕様が固まりきらず、hooks/useAuth.tsが修正されるたびに参照している多数のモジュールにも影響が波及する状態です。
こうした数値をClaude Codeに渡すと「安定させるべきモジュール」と「自由に変更していいモジュール」の区分を判断してくれます。
3. バンドルサイズ・パッケージ管理
bundle-phobia(CLI版)
npmパッケージのバンドルサイズをCLIから確認するツールです。
# パッケージのサイズを確認
npx bundle-phobia lodash date-fns dayjs
Claude Codeとの組み合わせ方
「lodashを軽い代替に置き換えたい」という依頼で、まず候補とその特徴をリストアップしてくれて、bundle-phobiaで候補にあげたパッケージのサイズを比較してくれます。
数値データがあれば、Claude Codeは「lodashからlodash-esに置き換えることで、gzippedで26.34KB削減」のような定量的な提案ができます。GitHubリポジトリを見にいく必要もありません(最終更新日などは別途確認したくなるかもですが)。
Bundle Analyzer(Next.js / Vite)
ビルド済みバンドルの中身をツリーマップで可視化するツールです。どのモジュールがどれだけの容量を占めているかを視覚的に把握でき、HTMLファイルとして出力されます。フレームワークごとにツールが異なります。
Next.jsの場合:@next/bundle-analyzerを使います。
npm install -D @next/bundle-analyzer
ANALYZE=true npm run build
v15以降では、Turbopackと統合された実験的なBundle Analyzerも利用できます。next.config.jsの変更は不要で、インポートチェーンの追跡やルート別・環境別のフィルタリングが可能です。
next experimental-analyze
// next.config.js(CommonJS)または next.config.mjs(ESM)
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
})
module.exports = withBundleAnalyzer({})
Viteの場合:vite-bundle-analyzerを使います。
npm install -D vite-bundle-analyzer
npm run build
// vite.config.ts
import { analyzer } from 'vite-bundle-analyzer'
export default defineConfig({
plugins: [analyzer()],
})
Claude Codeとの組み合わせ方
bundle-phobiaがインストール前の「パッケージ単体のサイズ」を調べるツールだとすれば、Bundle Analyzerは「実際にビルドされたバンドルの中身」を調べるツールです。
「実装内容のパフォーマンスに問題がないか確認して」「バンドルサイズが大きい原因を特定して」といった依頼に対して、まずBundle Analyzerを実行してもらってレポートを生成します。
Claude Codeにはレポートの内容(どのモジュールが何KBを占めているか)を読んでもらって、問題の有無や原因を特定してくれます。その結果をもとに、より具体的な改善提案もしてくれます。HTMLのツリーマップはClaude Codeが直接読めないため、@next/bundle-analyzerではanalyzerMode: 'json'を指定してJSONファイルに出力するのが実用的です。
npm-check-updates(ncu)
package.jsonの依存関係を最新バージョンに更新するツールです。メジャー・マイナー・パッチの選択的更新やフィルタリングもできます。
# 更新可能なパッケージを確認(変更はしない)
ncu
# マイナー・パッチのみ更新
ncu -u --target minor
# 特定のパッケージだけ確認
ncu --filter "react,react-dom,next"
# インタラクティブに選択して更新
ncu -i
Claude Codeとの組み合わせ方
「依存パッケージを最新にしたい」という依頼で、Claude Codeがpackage.jsonを読んで1つずつnpmのバージョンを調べるのは非効率です。
ncuを実行すれば、更新可能なパッケージとバージョン差分の一覧が一瞬で得られます。
Claude Codeにはその結果を元に、「メジャーアップデートのあるパッケージは破壊的変更の確認が必要」「パッチアップデートのみの10パッケージはまとめて更新して問題ない」といった判断をしてくれます。ncu --doctorを使えば、パッケージを1つずつ更新しながらテストを実行し、壊れるパッケージを特定できます。
4. Git 履歴分析
ホットスポット分析
Gitの変更履歴から「頻繁に変更され、かつ大きいファイル」を特定する分析です。静的解析では見えない、コードの「動き」から問題箇所を浮かび上がらせます。
変更頻度×ファイル行数でスコアを算出します。「頻繁に変更され、かつ大きいファイル」はリファクタリングの効果が高い箇所と判断できます。
git log --format=format: --name-only --since=12.month -- src/ \
| grep -v '^$' | sort | uniq -c | sort -nr | head -50 \ # 変更回数を集計
| while read count file; do
# ファイルが存在する場合のみ「スコア 変更回数 行数 ファイル名」を出力
[ -f "$file" ] && echo "$((count * $(wc -l < "$file"))) $count $(wc -l < "$file") $file"
done | sort -nr | head -20 # スコア順にソートして上位20件
バグ修正集中ファイル
コミットメッセージに "fix" や "bug" を含む変更が集中しているファイルを特定します。
git log --grep="fix\|bug" -i --format=format: --name-only --since=12.month -- src/ \
| grep -v '^$' | sort | uniq -c | sort -nr | head -20
Claude Codeとの組み合わせ方
「リファクタリングの優先度を決めたい」という依頼に対して、ホットスポット分析とバグ修正集中ファイルの結果を両方取得してくれます。ホットスポット上位かつバグ修正が集中しているファイルは「変更のたびにバグが出る壊れやすい構造」を持っている可能性が高いです。
Claude Codeはコードの中身を読んで、なぜそのファイルが壊れやすいのかを分析し、構造的な改善策を提案できます。
5. GitHub CLI・Gitワークフロー
GitHub CLI(gh)
GitHubの操作をターミナルから行う公式CLIです。PRの作成・参照・レビューやIssue管理をブラウザを開かずに完結できます。
# PR の一覧を確認
gh pr list
# PR の詳細を確認(diff、レビューコメント含む)
gh pr view 123
gh pr diff 123
# PR を作成
gh pr create --title "feat: add user profile" --body "## 概要\n..."
# PR をチェックアウト(ローカルで確認)
gh pr checkout 123
# Issue の一覧と作成
gh issue list --label "bug"
gh issue create --title "Fix: ログイン画面のバリデーション" --body "..."
Claude Codeとの組み合わせ方
Claude Codeにコードレビューを依頼するとき、gh pr diff 123で差分を取得してくれれば、PRの変更内容を把握してくれます。
「このPRをレビューして」という依頼に対して、ブラウザからコピペする必要がありません。また、Claude CodeにPRの作成まで任せる場合も、gh pr createでタイトル・本文・ラベルを指定してくれれば、一連の作業をターミナル内で完結できます。レビューの提出(gh pr review)や、CIのステータス確認(gh pr checks)も組み合わせると、PRのライフサイクル全体をClaude Codeと協業できます。
ghコマンドではなくgitコマンドの話になりますが「なぜこの実装方法になっているんだろう?」と疑問に感じたときに、そのファイルや関連ファイルのコミット履歴を探索すると背景が見えてくることもあります。
ホットスポット分析もそうですが、Git履歴はかなりパワフルな情報なのだなと感じます。
wtp
git worktreeの操作を効率化するラッパーツールです。
# 既存ブランチのワークツリーを作成
wtp add feature/new-component
# 新規ブランチを作成してワークツリーを作成
wtp add -b feature/new-component
# ワークツリーの一覧
wtp list
# 不要なワークツリーを削除
wtp remove feature/new-component
Claude Codeとの組み合わせ方
Claude Codeでは、回答を待っている時間で別の作業を並列でおこなうと効率化できます。Git Worktreeはそのための便利な方法です。
わたしはClaude CodeのWorktreeCreate hooksをカスタマイズして、worktree作成時に.envrcなどのgitignoredファイルのコピー、ロックファイルから検出したパッケージマネージャーのインストールコマンド生成、VS Codeでの起動を自動化しています。
gh-poi
マージ済みローカルブランチを安全に一括削除するGitHub CLI拡張です。squashマージやリベースマージにも対応しています。
# マージ済みブランチを確認(ドライラン)
gh poi --dry-run
# マージ済みブランチを削除
gh poi
Claude Codeとの組み合わせ方
Claude Codeにブランチの整理を頼むと、git branch --mergedで判定しようとしますが、これはsquashマージされたブランチを検出できません。gh-poiはGitHubのAPIを使ってマージ状態を判定するため、squashマージやリベースマージで取り込まれたブランチも正しく検出します。「ローカルブランチを整理して」と頼むとき、gh poi --dry-runで安全に確認してから削除させると確実です。
6. セキュリティ・品質スキャン
Semgrep
パターンベースの静的解析・セキュリティスキャンツールです。OWASP Top 10等のルールセットで脆弱性やアンチパターンを検出します。
# TypeScript/React のアンチパターンとセキュリティ問題を検出
semgrep scan --config p/typescript --config p/react \
--severity=ERROR --severity=WARNING \
src/
Claude Codeとの組み合わせ方
「セキュリティ上の問題がないか確認して」という依頼に対して、Claude Codeがコードを目視でレビューするのには限界があります。Semgrepのルールセットは既知の脆弱性パターンを網羅しているため、検出された問題を元にClaude Codeが修正コードを提案するほうが確実です。
type-coverage
TypeScriptの型カバレッジを計測するツールです。any型や型推論が不十分な箇所を検出します。
# any が残っている箇所を詳細表示
type-coverage --detail --strict \
--ignore-catch --ignore-nested --ignore-as-assertion \
--show-relative-path | head -50
Claude Codeとの組み合わせ方
「型安全性を上げたい」という依頼で、rg "any"だけでは型注釈のanyしか拾えません。type-coverageは推論結果も含めて「実際にanyとして扱われている箇所」を検出するため、修正すべき箇所の正確なリストが得られます。
Claude Codeはそのリストを元に、適切な型定義を提案してくれます。
型の穴はセキュリティリスクにもつながるため、Semgrepのセキュリティスキャンと合わせてコード品質の底上げに使います。
7. React コードレビュー
react-doctor
Reactコードベースの品質診断ツールです。60以上のルールによる静的解析とデッドコード検出でコードベース全体をスコアリングします。
# インストール不要で実行
npx -y react-doctor@latest .
# 詳細表示
npx -y react-doctor@latest . --verbose
# main ブランチとの差分のみ
npx -y react-doctor@latest . --diff main
Claude Codeとの組み合わせ方
リファクタリングの起点として使います。「このプロジェクトの品質を診断して」と依頼するとき、react-doctorのスコアと検出された問題一覧を最初に取得してくれます。
スコアと問題一覧が得られると、Claude Codeが「何から手をつけるべきか」を優先度付きで提案してくれます。
--diff mainを使えばPRで変更した範囲だけに絞った診断もできます。
Vercel React Best Practices
Vercel Engineeringが管理するReactとNext.jsのパフォーマンス最適化ガイドラインです。
57ルールと8カテゴリで構成され、インパクト順に優先度が付けられています。
CLIツールではなくルールセットですが、Claude Codeの判断基準として非常に有効です。
優先度の高い順に、主要なカテゴリを紹介します。
- Eliminating Waterfalls(CRITICAL):
awaitを実際に必要な分岐に移動する、独立した処理はPromise.all()で並列実行する、Suspenseでコンテンツをストリーミングするなど、直列の非同期処理を排除するルール群です。 - Bundle Size Optimization(CRITICAL):バレルファイルを経由せず直接パスでインポートする、重いコンポーネントは
next/dynamicで遅延読み込みする、サードパーティはハイドレーション後に読み込むなど、初期バンドルサイズを削減するルール群です。 - Re-render Optimization(MEDIUM):コールバック内でしか使わないstateを購読しない、重い処理はメモ化コンポーネントに切り出す、派生stateはeffectではなくrender中に計算するなど、不要な再レンダリングを防ぐルール群です。
Claude Codeとの組み合わせ方
このルールセットの真価は、CLAUDE.mdやスキルファイルに記述してClaude Codeに読ませることで発揮されます。たとえば「このコンポーネントをレビューして」と依頼するとき、ルールセットがなければClaude Codeは一般的な観点でしかレビューできません。「Vercel React Best PracticesのCRITICALルールに違反していないかチェックして」と指示すれば、「このawaitはPromise.all()で並列化できる」「このインポートはバレルファイル経由なので直接パスに変更すべき」といった具体的で優先度の明確な指摘が返ってきます。
react-doctorがコードベース全体の「健康診断」だとすれば、このルールセットは個々のコンポーネントに対する「精密検査の基準書」です。両方を組み合わせることで、マクロとミクロの両面からReactコードの品質を管理できます。
8. ドキュメント・図表
mermaid-cli
Mermaid記法のダイアグラムをSVG・PNG・PDFに変換するCLIです。.mmdファイルやMarkdown内のmermaidブロックを一括変換できます。
Claude Codeとの組み合わせ方
Claude CodeはMermaid記法のダイアグラムを生成するのが得意ですが、構文エラーを含むコードを出力することがあります。ここで活きるのがClaude CodeのHooksとの連携です。
PostToolUse hookを使えば、次のループが人間の介入なしに回ります。
- MarkdownファイルをWrite/Editするたびにmermaidコードブロックを自動検知
- ブロックごとに一時的な
.mmdファイルとして書き出し - mermaid-cliで構文チェック
- エラーが検出された場合は
permissionDecision: "deny"でClaude Codeに返し、編集をブロックしてエラー内容をフィードバック - Claude Codeが修正を試み、再びWriteした時点で1に戻る
CLAUDE.mdは確実性が薄く、プロンプトで都度指示するのは手間がかかります。
CLIツールの再現性とHooksの自動化を組み合わせることで、品質チェックをセッションや指示へ依存しない構造にできます。
9. 文章校正
textlint
Markdown・テキストファイルの文章校正ツールです。日本語向けプリセットとprhによる表記ゆれ統一を組み合わせて使います。
# Markdown ファイルの校正
npx textlint docs/**/*.md
使用しているプリセット・ルール:
-
preset-ja-technical-writing:技術文書向けの日本語ルールセット -
preset-ja-spacing:日本語と英数字間のスペースや句読点の統一 -
@textlint-ja/preset-ai-writing:AI生成文書特有の表現パターンを検出 -
prh:表記ゆれ統一(独自辞書を使用)
prhの辞書は ICS media のものを流用させてもらっています。ルール設定は SmartHR の構成も参考にしています。
Claude Codeとの組み合わせ方
ドキュメントの作成をClaude Codeに任せることが多くなりました。
ただし、AI特有の冗長な文章やクセが気になります。textlintを実行すれば問題点を指摘してくれるので、その情報を拾って自動的に文章を調整してくれます。
まとめ
紹介したツールを確実に使ってもらうには、Claude Codeがツールの存在を「知っている」状態を作る必要があります。
ツールごとにドキュメントを用意してCLAUDE.mdで参照する
Dotfilesにインストールしているツールのドキュメントを、コマンドや使いどころを記したMarkdownとして管理しておきます。
dotfiles/
docs/
tools/
README.md
knip.md
madge.md
semgrep.md
...
個人用のCLAUDE.mdでその場所を指示しておけば、どのプロジェクトでも参照してくれます。
`~/Documents/MY/dotfiles/docs/tools/README.md` に記載されたCLIツールはインストール済みなので、対応するツールがある場合は積極的に活用する。各ツールの使い方は `~/Documents/MY/dotfiles/docs/tools/` 内の個別ドキュメントを参照する
よく使う組み合わせをSkillにまとめる
複数のツールを組み合わせた分析はSkillとして定義しておくと、「リファクタリングを提案して」のような自然な依頼で一連のフローを起動できます。たとえばhotspot-refactoringというSkillでは、次のように定義しています。
hotspot-refactoring
name: hotspot-refactoring
description: >
git logのhotspot分析・循環参照・デッドコード・不安定性メトリクスを組み合わせて
リファクタリング優先候補を提案する。「hotspot」「リファクタリング提案して」
「どこを直すべき」「技術的負債を調べて」のように使う。
context: fork
allowed-tools:
- Bash
- Read
- Glob
- Grep
- AskUserQuestion
hotspot-refactoring
git履歴・静的解析・依存関係分析を組み合わせ、リファクタリング投資対効果がもっとも高い箇所を特定して提案する。
フロー: スコープ確認 → 観点確認 → 分析実行 → クロスリファレンス → 優先度付き提案出力
実行手順
Step 1: スコープを確認する
プロジェクトの構成を把握する。
# 言語・フレームワークの自動検出
ls package.json tsconfig.json pyproject.toml Cargo.toml go.mod 2>/dev/null
AskUserQuestionツールで対象範囲を質問する。
{
"question": "リファクタリング分析の対象範囲を選択してください",
"options": [
{ "label": "プロジェクト全体", "description": "すべてのソースコードを分析する" },
{ "label": "特定のディレクトリ", "description": "Otherから対象パスを入力(例: src/features/)" }
]
}
回答と自動検出の結果から以下の変数を決定する。
-
TARGET_DIR: 分析対象ディレクトリ(未指定の場合は.) -
IS_TS: TypeScript/JSプロジェクトか(Madge・Knip・type-coverageの使用可否) -
SINCE: git分析の期間(デフォルト:12.month)
Step 2: リファクタリングの観点を確認する
AskUserQuestionツールの multiSelect: true で質問する。
{
"question": "どの観点で分析しますか?(複数選択可。気になることがあればOtherに自由記述も可)",
"multiSelect": true,
"options": [
{ "label": "ホットスポット", "description": "頻繁に変更される・複雑なファイルを特定する" },
{ "label": "構造・依存関係", "description": "循環参照・隠れた結合・アーキテクチャ違反" },
{ "label": "デッドコード削減", "description": "未使用ファイル・未使用エクスポート" },
{ "label": "お任せ", "description": "すべての観点で分析する" }
]
}
AskUserQuestionは最大4選択肢のため、IS_TSがtrueの場合は追加でもう1回質問する。
{
"question": "TypeScriptプロジェクト向けの追加分析も行いますか?(複数選択可)",
"multiSelect": true,
"options": [
{ "label": "型安全性", "description": "any型が残っている箇所を検出する" },
{ "label": "コード品質", "description": "アンチパターン・フレームワーク固有の問題" }
]
}
Otherで自由記述が入った場合の解釈
| キーワード例 | 対応する観点 |
|---|---|
| 重たい・遅い・パフォーマンス | ホットスポット |
| テストが書きにくい・テストできない | 構造・依存関係 |
| 特定ファイルに変更が集中・繰り返し直している | ホットスポット + temporal coupling |
| 不要・使われていない・ゴミが多い | デッドコード削減 |
| any・型・TypeScript | 型安全性 |
| 読みにくい・わかりにくい・命名 | コード品質 |
| 依存関係・import・循環・複雑 | 構造・依存関係 |
解釈した結果を「〇〇と〇〇の観点で分析します」と明示してからStep 3に進む。
Step 3: Phase 1 — どこに問題があるかを特定する(git履歴分析)
観点に 1・6 が含まれる場合、または自由記述から関連すると判断した場合に実行する。
3-1. 変更頻度 × ファイルサイズ(ホットスポットスコア)
git log --format=format: --name-only --since=<SINCE> -- <TARGET_DIR> \
| grep -v '^\s*$' | sort | uniq -c | sort -nr | head -50 \
| while read count file; do
if [ -f "$file" ]; then
lines=$(wc -l < "$file")
score=$((count * lines))
echo "$score $count $lines $file"
fi
done | sort -nr | head -20
出力形式: スコア 変更回数 行数 ファイルパス
3-2. 書き換え率が高いファイル(設計の不安定性)
git log --numstat --format=format: --since=<SINCE> -- <TARGET_DIR> \
| grep -v '^\s*$' \
| awk '{add[$3]+=$1; del[$3]+=$2} END {
for(f in add) {
total=add[f]+del[f];
if(total>20 && del[f]>0)
printf "%.0f%% %d %d %d %s\n", del[f]/total*100, total, add[f], del[f], f
}
}' \
| sort -nr | head -20
出力形式: 削除率 総変更行数 追加行数 削除行数 ファイルパス
削除率50%超は「書いては消す」が繰り返されている設計の不安定シグナル。
3-3. バグ修正が集中するファイル
git log --grep="fix\|bug" -i --format=format: --name-only --since=<SINCE> -- <TARGET_DIR> \
| grep -v '^\s*$' | sort | uniq -c | sort -nr | head -20
3-4. Temporal Coupling(常にペアで変更されるファイル)
git log --format=format: --name-only --since=6.month -- <TARGET_DIR> \
| 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
出力形式: 共変更回数 ファイルA <-> ファイルB
常にペアで変更されるのに静的依存がないファイルは隠れた結合のシグナル。
結果を「ホットスポットランキング」として内部に保持する。
Step 4: Phase 2 — 構造的問題を検出する
4-1. 循環参照(IS_TSの場合)
観点に 2・6 が含まれる場合は実行する。
# tsconfig.jsonが存在する場合
madge --circular --ts-config tsconfig.json <TARGET_DIR> 2>/dev/null
# tsconfig.jsonが存在しない場合
madge --circular <TARGET_DIR> 2>/dev/null
tsconfig.jsonの有無は Glob で確認してから実行する。
4-2. 依存数サマリー(依存数が多いファイル)
観点に 2・6 が含まれる場合は実行する。
madge --summary <TARGET_DIR> 2>/dev/null | sort -t: -k2 -nr | head -20
依存数が多いファイルは変更リスクが高く、分割検討対象。
4-3. デッドコード検出
観点に 3・6 が含まれる場合は実行する。IS_TSの場合はKnipを優先し、失敗した場合はMadgeで代替する。
# IS_TSの場合: Knip優先
knip --reporter compact 2>/dev/null
# Knipが失敗した場合、またはIS_TSでない場合: Madgeで孤立ファイルを検出
madge --orphans <TARGET_DIR> 2>/dev/null
Knipはプロジェクトに設定ファイル(knip.config.* または package.json の knip フィールド)がないと誤検知が多い。大量出力またはエラーの場合はMadgeに切り替える。
4-4. 安定性メトリクス(不安定モジュールの検出)
観点に 2・6 が含まれる場合は実行する。
depcruise --metrics -T metrics <TARGET_DIR> 2>/dev/null | head -40
不安定性指数(I = Ce/(Ca+Ce))が高いのに多くから依存されているモジュールはもっともリスクが高い。
Step 5: Phase 3 — コード品質を検出する
5-1. アンチパターン検出(Semgrep)
観点に 5・6 が含まれる場合は実行する。IS_TSに応じてルールセットを選択する。
# TypeScript/JSの場合
semgrep scan --config p/typescript --config p/react \
--severity=ERROR --severity=WARNING \
--no-rewrite-rule-ids \
<TARGET_DIR> 2>/dev/null
# その他の場合
semgrep scan --config auto \
--severity=ERROR --severity=WARNING \
<TARGET_DIR> 2>/dev/null
Semgrepはルールセット取得にネットワークアクセスが必要。失敗した場合はスキップしてその旨を記載する。
5-2. 型カバレッジ(type-coverage)
観点に 4・6 が含まれ、IS_TSがtrueの場合に実行する。
type-coverage --detail --strict \
--ignore-catch --ignore-nested --ignore-as-assertion \
--show-relative-path 2>/dev/null | head -50
Step 6: クロスリファレンスして優先度付きで提案を出力する
収集したすべての分析結果を突き合わせ、以下の優先度で分類する。
優先度の判定基準
| Priority | 条件 |
|---|---|
| P1: 最優先 | 複数のシグナルが重なるファイル(例: ホットスポット上位 かつ 循環参照あり) |
| P2: 高優先 | 単一のシグナルだが深刻(例: 循環参照があるが変更頻度は低い) |
| P3: Quick Win | 削除・整理だけで完結するもの(未使用ファイル・未使用エクスポート) |
クロスリファレンスの例
- ホットスポット上位 × 循環参照あり →「頻繁に変更されるのにテストが書きにくい」最悪のケース
- Temporal Coupling(A↔Bが常にペア)× Madgeで依存なし →「静的には独立しているのに行動的には結合している」
- 不安定性指数が高い × 多くのモジュールから依存される →「安定しているべきモジュールが不安定」
- バグ修正集中 × Semgrepでアンチパターン検出 →「設計の問題がバグとして出続けている」
出力フォーマット
## リファクタリング提案
### 分析サマリー
- 対象: <TARGET_DIR>
- 期間: 過去<SINCE>
- 観点: <指定された観点(自由記述の場合は解釈結果も記載)>
---
### P1: 最優先候補
**<ファイルパス>**
- シグナル: <検出されたシグナルを列挙(例: ホットスポットスコア 1240 / 循環参照あり / バグ修正5回)>
- 問題: <何が問題か、なぜ問題か>
- 提案: <具体的なリファクタリング手法(責務分割・インターフェース抽出・循環解消の方向性など)>
...
---
### P2: 高優先候補
...
---
### P3: Quick Win(削除・整理で即完結)
- `<ファイルパス>` — 未使用ファイル(knip検出)
- `<エクスポート名>` in `<ファイルパス>` — 未使用エクスポート
...
---
### 観点別の補足
<指定された観点ごとの追加所見・注意点>
---
### 免責事項
上記はコードの変更履歴と静的解析に基づく機械的な候補です。
ビジネスコンテキスト・チームの優先事項・リリース計画に照らして判断してください。
注意事項
- Madge・Knip・type-coverageはJS/TSプロジェクト専用。他の言語ではPhase 2のこれらをスキップし、git分析とSemgrepのみで対応する
- git履歴が浅いリポジトリ(shallow clone)では変更頻度分析の精度が低下する。その場合は
git log --oneline | wc -lでコミット数を確認してユーザーに伝える - Semgrepはネットワークアクセスが必要。オフライン環境では
--config autoが失敗するためスキップする - Knipは設定ファイルがないプロジェクトでは誤検知が多い。大量出力(100件超)またはエラーの場合はMadge
--orphansに切り替える - 提案はリファクタリングの候補であり、実施の判断はユーザーに委ねる
ここで紹介したツールの多くはClaude Codeと壁打ちをして提案してくれたものです。きっとまだまだ便利なツールはあると思います。
ツールを探したり組み合わせたり、SkillsやHooksで確実に起動できるようにしたりと、これからも改善していこうと思っています。
ちょっと株式会社(chot-inc.com)のエンジニアブログです。 フロントエンドエンジニア募集中! カジュアル面接申し込みはこちらから chot-inc.com/recruit/iuj62owig
Discussion