生活分享

Claude Code|建立第一個 Hook

設定事件與條件,確認 Hook 實際觸發。本篇會建立第一個 Hook:Claude 使用檔案編輯工具後,將事件名稱與工具名稱寫入練習專案的本機紀錄。你會先人工測試腳本,再接上 PostToolUse,最後用真實編輯確認觸發。這個起點能分清楚「程式可跑」與「Claude 真的呼叫過它」。

閱讀時間約 5 分鐘

建立第一個 Hook:文件、螢幕與完成記號的幾何插圖
圖片:Mokaair (© Mokaair)
本篇目錄
  1. 先定義事件與輸出
  2. 建立接收事件的程式
  3. 人工測試標準輸入
  4. 接上專案 Hook 設定
  5. 用真正編輯驗證觸發

本篇會建立第一個 Hook:Claude 使用檔案編輯工具後,將事件名稱與工具名稱寫入練習專案的本機紀錄。你會先人工測試腳本,再接上 PostToolUse,最後用真實編輯確認觸發。這個起點能分清楚「程式可跑」與「Claude 真的呼叫過它」。

先準備、Node.js 22 以上與可正常啟動的 CLI。設定使用;以下 args 執行形式依查證時官方文件撰寫,舊版若不支援,先更新並核對當前 Hooks 參考文件,不要直接改成未加引號的 shell 字串。

先定義事件與輸出

先定義事件與輸出 → 建立接收事件的程式 → 人工測試標準輸入
先定義事件與輸出 → 建立接收事件的程式 → 人工測試標準輸入 · 圖片:Mokaair (© Mokaair)
閱讀完整文字說明

建立第一個 Hook,以流程和文件圖形呈現教學重點。

檢查階段輸入成功證據
人工測試自建 JSON 事件程式正常退出且新增紀錄
真實觸發Claude 的 Write 或 Edit編輯差異與新的事件時間
停用測試移除 handler 後再編輯紀錄行數不再增加

PostToolUse 表示工具已執行完畢。matcher 用來比對工具名稱,本例只關心 Write 與 Edit;讀檔、一般聊天及手動在編輯器改檔不會因此觸發。Hook 不是檔案監控服務,也無法在事後撤銷已完成的工具操作。

輸出選擇專案內的 .claude/hook-events.jsonl,每行是一個 JSON 物件,只保存時間、事件與工具。刻意不記錄完整提示、檔案內容或工具,讓新手能查看觸發證據而不累積不必要資料。請把此紀錄加入專案的 Git 忽略清單。

建立接收事件的程式

在專案建立 scripts/log-edit.mjs。Hook 將 JSON 事件透過標準輸入交給程式,腳本讀取完再解析。cwd 來自事件,輸出位置固定在該專案的 .claude 資料夾;若缺少必要欄位,程式會清楚失敗。

寫入 scripts/log-edit.mjs · javascript
import { readFileSync, mkdirSync, appendFileSync } from 'node:fs';
import { join } from 'node:path';
try {
  const event = JSON.parse(readFileSync(0, 'utf8'));
  if (typeof event.cwd !== 'string') throw new Error('missing cwd');
  const directory = join(event.cwd, '.claude');
  mkdirSync(directory, { recursive: true });
  const record = {
    at: new Date().toISOString(),
    event: event.hook_event_name,
    tool: event.tool_name,
  };
  appendFileSync(join(directory, 'hook-events.jsonl'), JSON.stringify(record) + '\n');
} catch (error) {
  console.error(String(error));
  process.exitCode = 1;
}

這段程式只負責最小事件紀錄,不保證其他同時寫入程式的完整排序。第一個練習保持單一 session,先學會追蹤一次事件。需要大量並行紀錄時,再使用適合的儲存與輪替機制。

人工測試標準輸入

在專案根目錄建立 hook-input.json,cwd 請換成你實際的絕對路徑。Windows JSON 中的反斜線要寫成兩個,或使用正斜線。這份檔案是人工測試材料,不能當作真實 Claude 觸發證據。

寫入 hook-input.json:把 cwd 改成你的練習專案 · json
{"cwd":"C:/practice/todo","hook_event_name":"PostToolUse","tool_name":"Edit"}
PowerShell:在專案根目錄人工測試 · powershell
Get-Content -Raw hook-input.json | node scripts/log-edit.mjs
Get-Content .claude/hook-events.jsonl
macOS/Linux 終端機:在專案根目錄人工測試 · bash
node scripts/log-edit.mjs < hook-input.json
cat .claude/hook-events.jsonl

看到一行合法 JSON 後,記下目前行數與時間。接下來要確認真實事件會新增另一行,而不是把這一行誤認成設定已生效。若這一步失敗,先解決 Node、路徑或 JSON 格式問題。

接上專案 Hook 設定

把以下 hooks 欄位合併到 .claude/settings.local.json。若已有其他設定,保留原欄位並正確合併 JSON,不要整份覆蓋。local 檔適合先做個人練習,驗證後才考慮是否成為團隊共享設定。

合併至 .claude/settings.local.json · json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "node",
            "args": ["${CLAUDE_PROJECT_DIR}/scripts/log-edit.mjs"],
            "timeout": 10
          }
        ]
      }
    ]
  }
}

args 會直接傳遞參數,不經 shell 解讀,路徑中的空白不需要另行拆分。Windows 要能找到真正的 node.exe;npm.cmd 等包裝檔不能直接套用同一規則。新增後確認設定已載入,必要時重啟 session,並依產品提示檢視新增 Hook。

不要讓 Hook 程式在成功時任意輸出除錯文字。本例只寫本機紀錄,因此成功可以沒有 stdout;需要向 Claude 回饋時,改用官方定義的 JSON 欄位。一般診斷文字放在 stderr,才能避免與協定輸出混在一起。

接上設定前,另用一份缺少 cwd 的人工輸入測試失敗分支。預期退出碼為非零,且不新增紀錄。這能證明腳本不只在正常情況有效,也能在事件資料不完整時留下可辨認的錯誤。分享錯誤前仍要檢查其中是否包含私人路徑。

真實觸發測試可以連續做兩次不同主標題修改,每次都記錄差異與新增行數。若一個工具呼叫產生多個事件或重試,應查看實際紀錄,不能先假設一次提示只會對應一行。這份紀錄是工具事件清單,不是完整任務清單。

準備團隊共享時,把腳本與設定一併審查,附上 Node 前提、輸出位置與停用方法。只提交 JSON 卻漏掉腳本,會讓其他人的每次編輯都遇到找不到檔案的錯誤。

用真正編輯驗證觸發

要求 Claude 透過檔案編輯工具,把 index.html 的主標題改為「Hook 練習」,只改這一段文字。完成後看差異與紀錄,新行的時間應晚於人工測試,工具名稱應對應實際工具。若 Claude 用 shell 改檔,Write|Edit matcher 不會因此匹配。

Claude Code 對話框:驗證真實工具事件 · text
請使用檔案編輯工具,只把 index.html 的主標題改成「Hook 練習」。
完成後列出差異;先不要執行其他修改或提交。

成功判準同時需要檔案差異與新增事件紀錄。只有設定檔存在、腳本退出碼為零,或 Claude 說「已設定」都不足以證明 Hook 已觸發。若沒有新行,查看 /hooks 與偵錯紀錄,核對事件名稱、matcher 大小寫及腳本路徑。

停用時從 settings.local.json 移除這一個 Hook handler,保留其他設定;重新載入後再做一次小編輯,紀錄行數應不再增加。移除腳本卻留下 handler 只會造成每次觸發都報錯,不是完整停用。

小練習是記錄人工測試、真實觸發與停用後測試三個結果。完成後可前往,在同樣可觀察的基礎上加入檢查與提醒。

準備好練習完整流程時,接著閱讀,使用獨立材料進行故障重現與成果驗證。

回總目錄

  • 生活分享

    Claude Code|建立第一個 mod:在 Claude Code 行程內數工具呼叫

    寫一個三檔案的 mod,用驗證器與測試確認它掛上的事件。文件把 mod 定義成多了入口檔的 plugin:入口檔叫 hooks module,Claude Code 在事件發生時呼叫裡面的函式,函式可以觀察、改寫或接手事件。

  • 生活分享

    Claude Code|Git Worktree 平行工作

    隔離多個任務的檔案與分支。Git Worktree 讓同一儲存庫擁有多個工作目錄,各自使用分支與檔案。本篇會把待辦篩選與文件整理分開,確認兩個 session 不會直接改到彼此的檔案,再把其中一個成果整合回主分支。你也會知道何時可以安全清理工作目錄。

  • 生活分享

    Claude Code|雙 Worktree 實作與衝突整合

    隔離兩項功能,最後完成整合與回歸。兩個 Claude 工作階段同時編輯專案,最容易出現的問題是互相改到同一份檔案,或各自測試通過、整合後卻失敗。本篇用兩個 Worktree 分別處理篩選預設值與介面文字,故意製造一次小衝突,再完成整合、驗證與清理。你不需要先啟用 Agent Teams。

  • 生活分享

    Claude Code|比較流程品質、用量與執行時間

    以同一資料集比較兩種工作方法。比較兩種 Claude 工作方法時,不能只挑成功那一次,也不能只看第一個答案有多快。本篇用固定案例、原始紀錄和一致判準,比較品質、重試、等待與人工整合時間,最後寫出有樣本數與限制的報告,而不是保證某個方法一定省錢。

最新旅遊情報攻略

資料來源

生活分享