Applied AI School
v0 · 規劃中
Anthropic

寫第一個 hook

settings.json 三層放 hook 的差別,從零寫一個 formatter hook。

TL;DR

  • Hook 配置寫在 settings.jsonhooks 區塊——三層 settings 都可以放,依誰要用選層級
  • 推薦用 /hooks interactive 命令新增,比手寫 JSON 不容易出格式錯誤
  • Hook command 是任何能執行的 binary / script,從 stdin 拿 tool call payload,用 exit code 回應

一個情境:改完 .ts 自動跑 prettier

你不想再手動 format。你希望——Claude 每次 EditWrite 動到 .ts 檔,自動幫你跑一次 prettier。

不用記得提醒它、不用 review 時抓格式 issue、不用為了這件事寫一條 CLAUDE.md rule(rule 不一定每次都被遵守)。

這就是 PostToolUse hook 的場景:tool 執行之後觸發一個你定義的 command。

hook 長什麼樣

最小可動的配置就三件事——何時觸發配對哪個 tool跑什麼 command

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "prettier --write \"$CLAUDE_FILE_PATHS\""
          }
        ]
      }
    ]
  }
}
  • PostToolUse:tool 跑完才觸發(PreToolUse 是執行前,可以擋下來)
  • matcher:regex 比對 tool name,這裡同時抓 WriteEdit
  • command:什麼都行——shell one-liner、CLI、Node script 都可以

stdin 拿到什麼

Hook command 啟動時,Claude Code 會把這次 tool call 的資料用 JSON 從 stdin 餵進來:

{
  "session_id": "2d6a1e4d-6...",
  "hook_event_name": "PostToolUse",
  "tool_name": "Edit",
  "tool_input": { "file_path": "/code/app.ts" }
}

你的 script 讀進來、parse、決定要做什麼。tool_input 的 shape 每個 tool 不一樣(Read / Edit 有 file_path、Bash 有 command、Grep 有 pattern)。

exit code 在講什麼

Hook 用 exit code 跟 Claude 對話:

exit code意思
0OK,繼續
2Block 這次 tool call(只在 PreToolUse 有效),stderr 內容會丟給 Claude 看
其他 non-zero視為 error,記 log 但不擋

對 formatter 來說 exit 0 就好——你只是順手 format,沒打算擋什麼。

三層 settings 怎麼選

Lesson 03 那三層一樣,hook 也是放在這三個地方:

層級路徑適合放
User~/.claude/settings.json個人習慣(自動 format、log)
Project shared<repo>/.claude/settings.json團隊規範(commit 前跑 lint),會 commit
Project local<repo>/.claude/settings.local.json個人偏好 / 機密路徑,不 commit

判斷很簡單——這個 hook 誰會想用? 只有你 → user;整個團隊 → project shared;只有你 + 不想推上 git → project local。

接下來

下一篇 → 實用 hook 範例集:format、log、擋讀 .env、commit message 檢查——挑一個直接抄來改。