Anthropic 的 Hooks 文件說明,Hook 命令會透過標準輸入接收 JSON 資料;因此看不到效果時,先確認事件有沒有觸發、腳本有沒有啟動,再查回傳內容,而不是先重裝 Claude Code。(官方 Hooks 文件)

症狀:格式檢查、命令攔截或測試檢查沒有反應。
最快解法:先核對實際載入的設定檔與事件、matcher,再檢查遠端執行帳戶、腳本環境和輸出格式。

這篇適合在遠端 Mac 上使用 Claude Code、但 Hook 效果不如預期的開發者。
如果你維護 CI 或共用節點,也能用以下流程區分設定問題、執行失敗與驗收責任。

先定位 Claude Code Hooks 的故障層

不要一開始就刪除設定或重裝。先用一個可重複的最小動作,例如對指定檔案執行一次預期會觸發檢查的修改,並觀察會話紀錄和 Hook 的診斷輸出。

將現象分成幾層,能避免把不同問題混在一起:

  • 事件未觸發:操作沒有走到你設定的事件。例如,你期待工具開始前執行檢查,實際設定卻是工作階段結束時才觸發。
  • matcher 未匹配:事件已發生,但設定篩選的工具名稱或條件不符合實際呼叫。
  • 腳本未啟動:Hook 已被選中,但檔案路徑、可執行權限或解譯器有問題。
  • 腳本已執行、效果未生效:輸出格式、退出狀態或決策欄位不符合該事件的契約。
  • Hook 通過、後續失敗:Hook 有執行,但後續工具、建置或 CI 步驟失敗。這不是「Hook 沒觸發」。

記下測試動作、啟動 Claude Code 的方式、工作目錄,以及看到的紀錄。診斷資料不要包含 Token、簽署憑據或其他機密。

核對遠端 Mac 實際讀取的設定來源

Hooks 的設定可能放在不同範圍。先比對正在執行 Claude Code 的帳戶與工作目錄,再確認該環境實際可讀取的設定檔。不要只檢查你登入桌面時使用的帳戶。

Claude Code 設定文件列出使用者、專案、本機專案與受管理設定的用途。可先用下表整理檢查範圍:

設定來源 常見用途 排查時確認
使用者設定 該使用者的個人偏好 SSH、互動式終端或服務程序是否以同一帳戶執行
專案設定 隨專案共用的設定 工作目錄是否位於預期專案,設定檔是否存在且可讀
專案本機設定 只供本機工作目錄使用的設定 CI 或其他帳戶是否根本看不到這份本機檔案
受管理設定 組織管理的政策 是否有受管規則影響可用設定或執行行為

在遠端 Mac 開發環境中,桌面終端、SSH 工作階段和 Runner 服務程序可能使用不同帳戶、工作目錄或啟動環境。逐一在實際執行 Claude Code 的環境核對設定,不要假設本機設定會同步到另一個帳戶。

如果你要把這套檢查放進正式流程,先確認團隊使用的遠端 Mac 方案與使用方式,再以實際執行帳戶做驗收。

對齊事件、matcher 與實際工具呼叫

依照操作發生的時間點選事件。工具呼叫前的檢查、工具執行後的檢查,以及工作階段結束時的處理,不是可互換的設定。Anthropic 的Hooks 事件與 matcher 說明可用來比對事件名稱、篩選條件與傳入資料。

實際排查時,先把設定縮到單一事件與單一工具呼叫。若要確認工具呼叫前的攔截,就觀察對應的前置事件;不要用結束事件來推斷前置事件是否生效。接著查看 matcher 是否針對實際工具名稱,而不是你以為 Claude Code 會呼叫的工具。

保留一份「預期動作 → 預期事件 → 實際工具 → Hook 紀錄」的對照。若事件有紀錄但沒有腳本輸出,問題可能在啟動;若腳本有輸出但未阻止操作,則應轉查回傳契約。這比一次加入多個 matcher 更容易定位。

比對 SSH 與 Runner 的腳本環境

Hook 腳本能啟動,不代表它擁有你互動式終端中的環境。尤其要比較 SSH 登入 Shell 與 Runner 服務帳戶的 PATH、工作目錄、解譯器路徑、依賴程式和檔案寫入權限。

可在腳本開頭加入短期診斷輸出,只記錄必要的非敏感資訊,例如目前帳戶、工作目錄、PATH,以及必要命令是否可找到。不要列印整份環境變數;其中可能包含憑據。也不要把「本機 Shell 找得到命令」當成服務程序也能找到的證明。

若找不到命令,先使用明確的解譯器或工具路徑,再確認服務帳戶具備讀取專案、執行腳本與寫入預期輸出位置的權限。若腳本依賴登入 Shell 才載入的環境,應明確設定所需路徑,而不是期待非互動程序沿用登入設定。

核對回傳契約與阻斷效果

Hook 有執行結果,不表示 Claude Code 一定會依你預期採取動作。先查事件文件對標準輸入、JSON 輸出、退出狀態與決策欄位的要求,再分別測試一般完成與明確阻斷。不同事件支援的控制方式可能不同,不能只靠「程式有印字」判斷成功。

Claude Code 的權限文件也要一併檢查:Hook 的控制結果和權限政策是不同層次。把它們分開驗證,才能知道是 Hook 回傳錯誤、設定沒有匹配,還是權限規則在起作用。

觀察到的結果 優先核對 下一步
沒有 Hook 紀錄 設定來源、事件是否觸發、matcher 條件 縮小成單一工具呼叫重測
有啟動紀錄、沒有預期輸出 解譯器、依賴、標準輸入解析與權限 在目標帳戶下單獨執行腳本
有輸出但未阻斷 事件支援的決策欄位、JSON 格式、退出狀態 依官方契約測試允許與阻斷兩種結果
Hook 顯示完成、CI 仍失敗 後續命令與 CI 判定 查看建置、測試工作本身的結果

文件對 Hook 退出狀態有明確區分:0 表示命令成功;2 用於阻斷錯誤,其他非零狀態的處理則需依 Hook 類型查看文件。不要把任意非零狀態都當成阻斷成功。(官方 Hooks 輸出與退出狀態說明)

分開驗收 Xcode、CI 與主機安全

Stop Hook 可用於工作階段結束時的檢查,但它不能單獨證明 Xcode 測試通過。把檔案修改後的格式檢查、工作階段結束時的檢查,以及 CI 中正式執行的建置與測試分開記錄。

Apple 的執行測試與解讀結果文件說明了測試結果的檢視方式;需要命令列驗收時,另核對 Xcode 命令列工具參考。測試命令、結果資料和 CI 對成功或失敗的判定應能互相追溯。Apple 亦提供透過 SSH 自動化 Xcode 測試的歸檔指南,可作為遠端執行流程的補充參考。

需求 Hook 可負責的部分 不應交給 Hook 單獨承擔的部分
修改後快速檢查 觸發格式或靜態檢查 保證完整建置與測試通過
工具呼叫控制 依事件契約回傳允許、詢問或阻斷結果 隔離主機、帳戶或檔案系統權限
Xcode 自動化測試 提醒、啟動或輔助檢查流程 取代 CI 保存測試結果與判定工作狀態
敏感操作保護 配合權限設定做額外檢查 取代人工審批、作業系統權限或簽署憑據保護

修復後,以預期通過和預期失敗的動作分別驗收,並確認節點重新啟動後仍能由目標帳戶執行。若要判斷失敗,需分清 Hook 錯誤、Hook 未匹配、腳本執行失敗與 CI 後續步驟失敗;這些情況應留下不同證據。

若你目前靠本機終端或共用 Linux 伺服器排查,常見代價是環境與帳戶不一致、無法直接完成 macOS 專屬的 Xcode 驗收,以及長期購置設備卻未必持續使用。需要真實 macOS 環境做短期重現或驗證時,可了解 MACCOME 遠端 Mac 使用方案;但若工作長期穩定佔用節點,或必須連接實體設備,自購 Mac 可能更合適。

常見問題

Claude Code Hooks 為什麼在遠端 Mac 上沒有反應?
先確認實際讀取的設定檔與執行帳戶,再比對事件和 matcher。只有確認 Hook 已被選中後,才查腳本路徑、依賴與輸出。

PreToolUse matcher 沒有命中,如何縮小問題?
只保留一個前置事件和一種工具呼叫,核對 matcher 的工具名稱及輸入條件,再查看會話與 Hook 紀錄。

SSH 環境找不到腳本命令,應先檢查什麼?
比對服務帳戶與互動式 Shell 的 PATH、工作目錄、解譯器和依賴;不要假設登入 Shell 的設定會套用到 Runner。

Stop Hook 能驗收 Xcode 自動化測試嗎?
它能協助執行結束時的檢查,但不能取代 Xcode 測試結果及 CI 的正式成功判定。

Hook 可以取代作業系統權限或人工審批嗎?
不可以。Hook 是流程控制的一環,不是主機隔離或憑據保護機制;敏感操作仍須由權限政策、人工審批與受控 CI 負責。