Claude Codeのhooks:ファイル保存のたびに自動フォーマット、自動テスト、自己修復

Dev.to / 2026/4/5

💬 オピニオンDeveloper Stack & InfrastructureTools & Practical Usage

要点

  • Claude Codeの「hooks」は、Claudeがファイルを読み書きする前(PreToolUse)または後(PostToolUse)にシェルコマンドを自動実行でき、これにより自動化されたエンジニアリング・ループになります。
  • hooksはプロジェクトルートの .claude/settings.json で設定し、「Write|Edit」のようなマッチャを使って、Claudeが修正するファイルのみを対象にします。
  • 基本的な例では、PostToolUseを連結して、影響を受けたファイルパスに対してlintの自動修正(例:npm run lint -- --fix on the affected file path)を実行し、反復的な「ついでにフォーマットも直して」という往復を減らします。
  • この記事では、hooksを連鎖させて「テスト→失敗→修正」のループをファイル保存のたびに実装することで、“自己修復(self-healing)”のワークフローを強調しています。
  • このアプローチは、品質ゲート(フォーマットとテスト)を編集ライフサイクルそのものに組み込むことで、Claudeによるコード変更の信頼性を高めます。

Claude Code hooks: auto-format, auto-test, and self-heal on every file save

Claude Code hooks を使うと、Claude が任意のファイルに触る前または後にシェルコマンドを自動で実行できます。これにより Claude は、完全に自動化されたエンジニアリングループになります — 単なるエディタではなく、出力をフォーマットし、テストし、そして自分自身で修正まで行う仕組みです。

設定方法と、実際に役立つようにする方法を紹介します。

What hooks do

フックは次の2つのタイミングで発火します:

  • PreToolUse — Claude がファイルを読み取る前、または書き込む前
  • PostToolUse — Claude がファイルを書き込んだ後

プロジェクトのルートにある .claude/settings.json で定義します。

Basic setup

.claude/settings.json を作成します:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npm run lint -- --fix $CLAUDE_TOOL_INPUT_FILE_PATH 2>&1 | tail -5"
          }
        ]
      }
    ]
  }
}
{
}

これで、Claude がファイルを書き込むたびに ESLint が自動で修正します。もはや「フォーマットも直してくれる?」といった追跡確認は不要です。

The self-healing loop

本当の力は、フックを連結してテスト → 失敗 → 修正のサイクルを作ることです:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "cd $(dirname $CLAUDE_TOOL_INPUT_FILE_PATH) && npm test -- --testPathPattern=$(basename $CLAUDE_TOOL_INPUT_FILE_PATH .js) 2>&1 | tail -20"
          }
        ]
      }
    ]
  }
}

Claude がファイルを書き込む → テストが実行される → テストが失敗したら、Claude は出力を見てコードを修正する → テストをもう一度実行する → 緑(成功)になるまで繰り返します。

Auto-lint on write (Python)

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "if [[ $CLAUDE_TOOL_INPUT_FILE_PATH == *.py ]]; then black $CLAUDE_TOOL_INPUT_FILE_PATH && ruff check $CLAUDE_TOOL_INPUT_FILE_PATH --fix; fi"
          }
        ]
      }
    ]
  }
}

Black がフォーマットし、ruff が lint の問題を修正します — すべて自動で、あなたが Claude の出力を確認する前に行われます。

Auto-typecheck on write (TypeScript)

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "if [[ $CLAUDE_TOOL_INPUT_FILE_PATH == *.ts || $CLAUDE_TOOL_INPUT_FILE_PATH == *.tsx ]]; then npx tsc --noEmit 2>&1 | head -20; fi"
          }
        ]
      }
    ]
  }
}

TypeScript のエラーは、書き込みの直後にすぐに表面化します。Claude は tsc の出力を見て、自動で自己修正します。

PreToolUse: validate before Claude reads sensitive files

返却形式: {"translated": "翻訳されたHTML"}
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Read",
        "hooks": [
          {
            "type": "command",
            "command": "if [[ $CLAUDE_TOOL_INPUT_FILE_PATH == *.env* ]]; then echo 'BLOCKED: .env files excluded from Claude context'; exit 1; fi"
          }
        ]
      }
    ]
  }
}

これは、Claude が .env ファイルを読むことをブロックします。Claude に尋ねられてもコンテキストから秘密情報を除外しておきたい場合に便利です。

自動パイロット設定の完全版

こちらが Node.js プロジェクト用の .claude/settings.json の全文です。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Read",
        "hooks": [
          {
            "type": "command",
            "command": "if [[ $CLAUDE_TOOL_INPUT_FILE_PATH == *.env* ]]; then echo 'BLOCKED'; exit 1; fi"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "eslint --fix $CLAUDE_TOOL_INPUT_FILE_PATH 2>&1 | tail -3"
          },
          {
            "type": "command",
            "command": "npm test -- --testPathPattern=$(basename $CLAUDE_TOOL_INPUT_FILE_PATH .js) --passWithNoTests 2>&1 | tail -10"
          }
        ]
      }
    ]
  }
}

Claude が書き込むすべてのファイルは、lint(静的解析)とテストが自動で実行されます。失敗した場合は、自己修正のためにその結果が Claude にループバックされます。

重要な環境変数

$CLAUDE_TOOL_INPUT_FILE_PATH — Claude が直前に書き込んだファイルの絶対パスです。これにより、ターゲットを絞ったフックが可能になります(変更されたファイルだけをテストし、テスト全体スイートを回さない)。

これが最も効く場面

Claude を長い自律タスクで実行しているとき、フックは欠かせなくなります。モジュールのリファクタリング、機能をエンドツーエンドで作成、複数ファイルにまたがる型の更新などです。フックがない場合、Claude はコードを書いて次へ進みます。フックがある場合、Claude は「書く → 検証する → 自己修正する」を、あなたの介入なしで行えます。

Claude Code セッションがレート制限にぶつかるほど重い場合:ANTHROPIC_BASE_URL=https://simplylouie.com は、セッションごとの上限を取り除く月 $2 のプロキシ経由でルーティングします。フック + レート制限なし = 完全に自律したセッション。

ワークフローが変わったフック設定、ありますか?コメントに投下してください。