閉ループで直す
計測して終わりではなく、直して、検証して、効果を実測するところまでを 1 コマンドで行います。
なぜ実測するのか
「hotspot を直すと ROI が高い」というのは仮説です。実際に直してみて複雑度がどれだけ下がったかを測らなければ、その主張は検証されません。
dowse は修正前後の複雑度を計測して差分を返します。
packages/cli/src/analyze.ts
cognitive -41 / cyclomatic -22 / LoC -111
検証: 型チェック ✓ / テスト ✓
コスト: $1.86必要なもの
Claude Code がインストールされ、ログイン済みであること。
claude --versionAPI キーの設定は要りません。既存の認証・権限設定にそのまま乗ります。Claude Code がない環境では ANTHROPIC_API_KEY があれば診断のみ動きます(修正の実行にはファイル編集のハーネスが必要なため)。
診断だけする
dowse diagnose --top 3hotspot 上位を LLM が実際に読み、「なぜ危険か・どう直すか・どれくらいかかるか」を返します。
packages/cli/src/analyze.ts
なぜ危険か: 5つのサブコマンド実行関数が、共通オプションのパース・
JSON/人間向け出力の二重分岐・表示整形を1ファイル内で重複して抱えており、
表示ロジックとコマンド制御が分離されていない
見積もり: 中(半日)
手順:
1. couplingFilters と asProxy を純関数として切り出す
テストが書けるようになり、以後の出力変更が集計を壊さないことを確認できる
リスク:
- CLI の標準出力そのものが利用者向けの契約であり、列順の変更でも下流が壊れるこれは所見であって計測値ではありません
決定的メトリクス(hotspot、health)とは明確に分離して扱ってください。LLM の読解に基づく意見です。
コストは件数に比例します。--top で制御してください(1 ファイルあたり数十円程度)。
実際に直させる
dowse fix最上位の hotspot を対象に、診断 → 修正 → 検証 → 効果計測を行います。ファイルを指定することもできます。
dowse fix packages/core/src/foo.ts既定は dry-run
変更は必ず破棄されます。検証と計測だけを行い、「もし直したらこうなる」を確認するモードです。
実際に残すには --apply を付けます。
dowse fix --apply検証を通過した変更が作業ブランチに残ります。
安全弁
閉ループはファイルを書き換えるため、複数の安全弁を設けています。
| 安全弁 | 動作 |
|---|---|
| 未コミット変更の検出 | 作業ツリーが汚れていたら実行を拒否します |
| ブランチ隔離 | 作業は dowse/fix-<target>-<sha> ブランチで行います |
| 独立した検証 | 型チェックとテストを dowse 側で実行します |
| diff 上限 | 既定 400 行を超える変更は破棄します |
| dry-run 既定 | --apply を明示しない限り変更は残りません |
検証はエージェント任せにしません
エージェントの「直りました」という自己申告は根拠にしません。dowse が型チェックとテストを直接実行し、終了コードで判定します。
実行系はリポジトリから判定します(packageManager フィールド → ロックファイルの順。 どちらも無ければ npm)。pnpm でも bun でも yarn でも、そのリポジトリのやり方で走ります。
失敗した変更は破棄され、失敗内容が表示されます。
packages/foo.ts: 型チェック が失敗したため変更を破棄しました
検証: 型チェック ✗ / テスト ✓
src/foo.ts(42,10): error TS2322: Type 'string' is not assignable to 'number'.検証スクリプトがない場合
package.json に typecheck / test スクリプトがないワークスペースでは、検証が 1 つも実行できません。この場合 dowse は「合格」とは報告せず、変更を破棄します。検証していないものを通してしまわないためです。
変更しないこともある
エージェントが「改善の余地がない」と判断すれば、何も変更しません。
packages/core/src/metrics/churn.ts: エージェントは変更を加えませんでした
合計: 1 件中 0 件で複雑度が改善 / コスト $0.56無理に変更しないのは正しい挙動です。すでに単純なファイルを機械的にいじっても価値はありません。
結果の見方
┌────────────────────┬──────┬───────────┬────────────┬──────┬────────┬───────┐
│ target │ 結果 │ cognitive │ cyclomatic │ LoC │ diff行 │ cost │
├────────────────────┼──────┼───────────┼────────────┼──────┼────────┼───────┤
│ src/analyze.ts │ 適用 │ -41 │ -22 │ -111 │ 439 │ $1.86 │
└────────────────────┴──────┴───────────┴────────────┴──────┴────────┴───────┘| 結果 | 意味 |
|---|---|
| 適用 | 検証を通過(dry-run なら計測後に破棄) |
| 検証失敗 → 破棄 | 型チェックまたはテストが落ちた |
| 変更過大 → 破棄 | diff 上限を超えた |
| 変更なし | エージェントが改善不要と判断 |
| 中断 | 未コミットの変更があった |
負の値が改善です。改善しなかった場合も、そのまま報告されます。