correction-tape 17136

Claude Code の Hooks で作業が終わった後にフォーマッターを実行する

Claude Code hooks は Claude Code のライフサイクルの特定のタイミングで実行されるユーザー定義のシェルスクリプトです。hooks を使用することで、コードのフォーマットを常に実行することができます。この記事では hooks を使用してコードの変更後に prettier が実行されるように設定してみましょう。

Claude Code hooks は Claude Code のライフサイクルの特定のタイミングで実行されるユーザー定義のシェルスクリプトです。hooks は LLM の実行判断に依存せずに特定のアクションが常に実行されることを保証します。

よくある例としては、コードのフォーマッターを実行することです。人間がコードを書いていた頃はエディタの自動フォーマット機能を使用していたため、フォーマットを実行するタイミングを意識することはなかったと思います。しかし LLM がコードを書く場合、フォーマットを実行するかどうかを LLM が判断するため、フォーマットが実行されずにコードがコミットされることが多々あります。hooks を使用することで、コードのフォーマットを常に実行できます。

Warning

hooks で実行されるシェルコマンドはユーザーの確認なしに実行されるため、予期せぬコマンドが実行される可能性があります。hooks の仕様ではユーザー自身が全責任を負うことが明記されています。https://docs.anthropic.com/en/docs/claude-code/hooks#security-considerations

この記事では hooks を使用してコードの変更後に prettier が実行されるように設定してみましょう。

hooks の設定

hooks を設定するために /hooks カスタムスラッシュコマンドを使用できます。もしくは Claude Code の設定ファイル(.claude/settings.json)を直接編集することも可能です。ここでは /hooks コマンドを使用して設定してみましょう。

hooks のイベントを選択する

始めにどのタイミングで hooks が実行されるのかを選択します。以下の 4 つの hooks event が用意されています。コードのフォーマットはファイルの編集が完了した後に実行したいので、PostToolUse を選択します。

  1. PreToolUse - Before tool execution
  2. PostToolUse - After tool execution
  3. Notification - When notifications are sent
  4. Stop - Right before Claude concludes its response

hooks の matcher を追加する

hooks のイベントを選択した後、matcher を追加します。matcher はどのツールが呼び出された後に hooks が実行されるかを指定します。Claude Code によってファイルが変更された場合に prettier を実行してもらいたいので、Write|Edit|MultiEdit を入力します。| で区切ることで複数の matcher を指定できます。これにより、ファイルの書き込み、編集、複数のファイルの編集が行われた場合に hooks が実行されます。

hooks のコマンドを入力する

続いて hooks が呼び出されたときに実行されるコマンドを入力します。hooks は stdin 経由で JSON 形式のデータを受け取ります。受け取るデータの形式は hooks のイベントによって異なります。PostToolUse の場合は以下のような形式になります。

{
  "session_id": "abc123",
  "transcript_path": "~/.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "tool_name": "Write",
  "tool_input": {
    "file_path": "/path/to/file.txt",
    "content": "file content"
  },
  "tool_response": {
    "filePath": "/path/to/file.txt",
    "success": true
  }
}

この JSON データを受け取って、ファイルのパスを取得し、prettier を実行するコマンドを入力します。JSON データをコマンドラインで扱うために jq コマンドを使用します。以下のようなコマンドを入力してみましょう。

jq -r '.tool_input.file_path | select(endswith(".js") or endswith(".ts") or endswith(".jsx") or endswith(".tsx"))' | xargs -r prettier --write

stdin から受け取った JSON データから tool_input.file_path を抽出し、JavaScript や TypeScript のファイルパスであれば、prettier --write コマンドを実行します。xargs -r は引数がない場合にコマンドを実行しないようにするためのオプションです。

最後に hooks をどの場所に保存するかを選択します。

  • .claude/settings.local.json: プロジェクト単位(ローカル)
  • .claude/settings.json: プロジェクト単位
  • ~/.claude/settings.json: ユーザー単位(グローバル)

設定が完了したら以下のような設定が保存されます。

.claude/settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path | select(endswith(\".js\") or endswith(\".ts\") or endswith(\".jsx\") or endswith(\".tsx\"))' | xargs -r npx prettier --write"
          }
        ]
      }
    ]
  }
}

実際に Claude Code を使用してファイルを変更してみましょう。確かに hooks が実行されたログが表示されていることが確認できます。終了コードが 0 であれば結果は折りたたまれて表示され、ctrl + r で展開できます。

まとめ

  • hooks を使用すると Claude Code のライフサイクルの特定のタイミングでユーザー定義のコマンドを実行できる
  • /hooks カスタムスラッシュコマンドを使用して hooks を設定できる
  • hooks のイベントには PreToolUse, PostToolUse, Notification, Stop がある
  • PostToolUse イベントを使用してツールの実行後にコマンドを実行する
  • matcher を使用して特定のツールが呼び出されたときに hooks を実行する
  • hooks のコマンドは stdin 経由で JSON データを受け取る

参考

記事の理解度チェック

以下の問題に答えて、記事の理解を深めましょう。

ファイルの編集時にコードのフォーマットを実行するために適切なhooks eventはどれですか?

  • PreToolUse

    もう一度考えてみましょう

    PreToolUseはツール実行前のイベントです

  • PostToolUse

    正解!

    PostToolUseはツール実行後のイベントで、ファイル変更後にフォーマッターを実行するのに適しています

  • Notification

    もう一度考えてみましょう

    Notificationは通知が送信されるときのイベントです

  • Stop

    もう一度考えてみましょう

    StopはClaudeが応答を終了する直前のイベントです