メインコンテンツへスキップ
8 / 26|6分で読めます

Hooks — イベント駆動の自動化エンジン

PreToolUse、PostToolUse、Stop。Claude Codeのイベントにフックして自動フォーマット、セキュリティチェック、品質保証を実現する。

Hooksは、Claude Codeの「行動」に対して自動的にトリガーされるスクリプトだ。人間が忘れがちな品質チェックを、仕組みで担保する。


Hooksとは何か

Claude Codeがツールを使うたびに、特定のタイミングでシェルコマンドを自動実行できる仕組みがHooksである。

医療に例えれば、「処方箋を書くたびにアレルギーチェックを自動で走らせる」ようなものだ。人間の意志力や記憶に頼るのではなく、仕組みで品質を担保する。


3つのフックタイプ

PreToolUse — ツール実行の「前」

ツールが実行される前にトリガーされる。バリデーション、パラメータの検証、特定操作のブロックに使う。

ユースケース:

  • 特定のファイルの編集をブロックする
  • 長時間コマンドの前にtmuxの使用を促す
  • git push の前にレビューを挟む
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "command": "if echo \"$TOOL_INPUT\" | grep -q 'git push'; then echo 'BLOCK: git pushの前にレビューしてください'; fi"
      }
    ]
  }
}

PreToolUseフックが BLOCK: で始まるメッセージを出力すると、そのツール実行はブロックされる。

PostToolUse — ツール実行の「後」

ツールが実行された後にトリガーされる。フォーマット、型チェック、警告の表示に使う。

ユースケース:

  • ファイル編集後にPrettierで自動フォーマット
  • TypeScriptファイル編集後に型チェック
  • console.logが含まれていたら警告
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "command": "if echo \"$FILE_PATH\" | grep -qE '\\.(ts|tsx|js|jsx)$'; then npx prettier --write \"$FILE_PATH\"; fi"
      },
      {
        "matcher": "Edit",
        "command": "if echo \"$FILE_PATH\" | grep -qE '\\.tsx?$'; then npx tsc --noEmit 2>&1 | head -20; fi"
      }
    ]
  }
}

Stop — セッション終了時

Claude Codeのセッションが終了する際にトリガーされる。最終チェックに使う。

{
  "hooks": {
    "Stop": [
      {
        "command": "git diff --name-only | xargs grep -l 'console.log' 2>/dev/null && echo '警告: console.logが残っています'"
      }
    ]
  }
}

matcher — フックの対象を絞る

matcher を指定すると、特定のツールに対してのみフックが発動する。

matcher値対象
"Edit"Editツールの使用時
"Write"Writeツールの使用時
"Bash"Bashツールの使用時
"Read"Readツールの使用時
省略すべてのツール使用時

実践レシピ集

レシピ1: 自動フォーマット

TypeScript/JavaScriptファイルの編集後にPrettierを実行する。

{
  "PostToolUse": [
    {
      "matcher": "Edit",
      "command": "if echo \"$FILE_PATH\" | grep -qE '\\.(ts|tsx|js|jsx)$'; then npx prettier --write \"$FILE_PATH\" 2>/dev/null; fi"
    }
  ]
}

レシピ2: console.log 警告

編集したファイルにconsole.logが含まれていたら警告する。

{
  "PostToolUse": [
    {
      "matcher": "Edit",
      "command": "if grep -n 'console\\.log' \"$FILE_PATH\" 2>/dev/null; then echo '⚠ console.logが検出されました'; fi"
    }
  ]
}

レシピ3: git push 前のレビュー

git pushの前に確認を促す。

{
  "PreToolUse": [
    {
      "matcher": "Bash",
      "command": "if echo \"$TOOL_INPUT\" | grep -q 'git push'; then echo '📋 pushする前に変更内容を確認してください'; fi"
    }
  ]
}

レシピ4: 長時間コマンドの tmux リマインダー

npm、pnpm、cargo等の長時間コマンド実行時にtmuxの使用を促す。

{
  "PreToolUse": [
    {
      "matcher": "Bash",
      "command": "if echo \"$TOOL_INPUT\" | grep -qE '^(npm|pnpm|yarn|cargo) (install|build|test)'; then echo 'ℹ 長時間コマンドです。tmux内での実行を検討してください'; fi"
    }
  ]
}

デバッグとトラブルシューティング

フックが期待通りに動かない場合のチェックポイント。

  1. シェルコマンドを直接実行してみる: フックのコマンドをターミナルで手動実行し、正しく動作するか確認
  2. 環境変数を確認: $FILE_PATH$TOOL_INPUT 等が正しく渡されているか
  3. matcherを確認: ツール名が正しいか(大文字小文字に注意)
  4. 出力を確認: PreToolUseで BLOCK: を使う場合、正確にこのプレフィックスで始まっているか

Hooksの設計哲学

Hooksは「強制」ではなく「支援」のためのものだ。開発者の作業を妨げるのではなく、見落としがちな品質チェックを自動化することが目的。フックを追加しすぎると作業が遅くなるため、本当に必要なものだけを設定する。

この章のポイント

  • Hooksには PreToolUse(実行前)、PostToolUse(実行後)、Stop(セッション終了時)の3タイプがある
  • PreToolUseでBLOCK:を出力すると操作をブロックできる
  • matcherでフックの対象ツールを絞り込める
  • 代表的な用途: 自動フォーマット、型チェック、console.log警告、push前レビュー
  • フックは「強制」ではなく「支援」。必要最小限に絞ることが重要