跳到主要內容
maxstudioNews
產品DEV Community (Claude Code)約 13 分鐘

Claude Code 2.1.299 至 2.1.301 版更新:Hooks 行為改變,七大重點待檢視

Claude Code 近期發布了 2.1.299 至 2.1.301 版本更新,這些變更深刻影響了現有 hooks 的行為方式。更新涉及提示詞處理、技能擴展、外掛程式互動等多個層面,可能導致既有設定失效。開發者應仔細檢查其配置,以確保程式碼正常運作並避免潛在問題。

Claude Code 2.1.299 至 2.1.301 版更新:Hooks 行為改變,七大重點待檢視
圖片來源:DEV Community (Claude Code)

自 Claude Code 2.1.299 版以來,UserPromptSubmit hook 現在會在你的技能擴展之前執行。這表示一個會阻擋提示詞的 hook,現在也會停止該技能的 shell 指令行。這些改變並非透過修改你的 hooks 檔案來實現。

2026 年 10 月 14 日和 15 日發布了三個版本:2.1.299、2.1.300 和 2.1.301(請參閱更新日誌)。其中「已變更」部分有七行內容,改變了你現有 hooks 的行為方式。這些變更涉及提示詞 hook 的執行時機、hook 重寫輸入的處理方式、代理程式工具清單選擇哪些 MCP 工具,以及外掛程式 hook 無法回應時的行為。

這些變更在你更新到新版本後立即生效,無需你進行任何編輯。以下每個項目都會引用更新日誌的內容,說明可能導致的問題,並提供一個指令來檢查你的設定是否受到影響。有兩個同週發布的 hook 變更(onFailure: "block" (2.1.295) 和更嚴格的 MCP 允許規則 (2.1.299))因篇幅限制而未列入,它們需要更詳細的說明。

首先,檢查你目前的版本:claude --version,然後執行 claude update。這七項變更都從 2.1.299 或更高版本開始生效。如果 claude --version 顯示的是舊版本號,則這些變更尚未對你生效,而 claude update 將是它們開始生效的時刻。

其中一個接近尾聲的修復可以追溯到更早的 2.1.294 版。如果你透過我開發的 Hermes IDE 運行 Claude Code,⌘N 面板中的代理程式選擇器會顯示每個已安裝代理程式的版本號,例如 Hermes 2.3.4 的代理程式選擇器會顯示已安裝的 Claude Code (2.1.299) 和 Codex (0.145.0),以及其他未安裝的支援代理程式。

1. UserPromptSubmit 現在在技能擴展之前執行

從 2.1.299 版開始:「已變更 UserPromptSubmit hooks,使其在技能或自訂斜線指令擴展之前執行,因此一個會阻擋提示詞的 hook 現在也會停止其內嵌的 shell 指令。」技能主體可以包含 shell 指令行,寫法是 ! 後面跟著反引號中的指令。技能文件中的入門範例就是以這種方式執行 git diff HEAD。

更新日誌中的「現在也會停止」表示舊的順序是:阻擋 hook 會停止提示詞,但不會停止那些指令行。可能導致的問題是:你的 hook 現在會在技能文字進入提示詞之前看到提示詞。如果你的 hook 搜尋提示詞中只出現在技能主體內的詞語,現在將找不到任何內容。對於擴展本身,有一個單獨的事件 UserPromptExpansion,它會匹配指令的名稱(請參閱 hooks 參考資料)。

要查看可能導致的問題,請印出你的 UserPromptSubmit hooks,並尋找只匹配技能擴展文字的模式:grep -n -A8 UserPromptSubmit .claude/settings.json ~/.claude/settings.json。

這個指令會列出那些其 shell 指令行現在可能被阻擋 hook 停止的技能和指令:grep -rlF '!' .claude/skills .claude/commands ~/.claude/skills ~/.claude/commands`。

2. 技能本身的 UserPromptSubmit hook 會等待一個提示詞

從 2.1.299 版開始:「已變更技能本身的 front-matter UserPromptSubmit hook,使其在呼叫該技能的提示詞之後的下一個提示詞上首次執行。」技能可以在其 frontmatter 中聲明 hooks。Claude Code 會在技能被呼叫時註冊它們,並在會話的其餘時間繼續執行它們(請參閱 hooks 參考資料)。

如果你的技能的 UserPromptSubmit hook 檢查了呼叫它的提示詞,例如 /deploy prod,它將不再看到該提示詞,而是從下一個提示詞開始。如果檢查必須在呼叫時發生,請將其移至設定中的 UserPromptExpansion。hooks 參考資料提供了這個確切的案例:一個匹配 deploy 的 hook,除非存在批准檔案,否則會阻擋 /deploy。

範例程式碼:{ "hooks" : { "UserPromptExpansion" : [ { "matcher" : "deploy" , "hooks" : [ { "type" : "command" , "command" : "$CLAUDE_PROJECT_DIR/.claude/hooks/deploy.sh" } ] } ] } }

要找到聲明此 hook 的技能:grep -rln UserPromptSubmit .claude/skills ~/.claude/skills。

3. updatedInput 會被驗證,未知鍵會被捨棄

從 2.1.300 版開始:「已變更 hooks:來自 PreToolUse 和 PermissionRequest hooks 的 updatedInput 現在會像 Claude 自己的輸入一樣被驗證:未知鍵會被捨棄,並且工具拒絕的輸入會導致呼叫被拒絕。」hooks 參考資料已經說明 updatedInput「替換整個輸入物件,因此請包含未更改的欄位以及已修改的欄位。」現在這條規則變得更嚴格。

如果一個 hook 只返回它更改的欄位而遺漏了必需的欄位,或者拼錯了欄位名稱,它將向工具提供被拒絕的輸入,導致呼叫被拒絕。你為自己的簿記添加的鍵會在工具看到它之前被捨棄。安全的格式是從 Claude 發送的輸入開始,然後只更改一個欄位。在命令 hook 中,使用 jq:jq '{hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "allow", updatedInput: (.tool_input + {command: "npm run lint"}) }}'

這個檢查會向你的 hook 提供一個範例事件,並印出它作為 updatedInput 返回的內容,無論它在輸出中的哪個位置。替換你自己的腳本路徑:echo '{"hook_event_name": "PreToolUse", "tool_name": "Bash", "tool_input": {"command": "ls"}}' \ | .claude/hooks/rewrite.sh \ | jq '.. | .updatedInput? // empty'

它印出的物件中的每個鍵都應該是工具接受的,並且該物件應該是整個輸入,而不僅僅是你更改的欄位。

4. Cowork 雲端會話中 PermissionRequest hook 的 setMode 會被忽略

從 2.1.300 版開始:「已變更 Cowork 雲端會話中的 PermissionRequest hooks:hook 的 allow 中的 setMode 更新現在會被忽略;批准的其餘部分仍然適用。」一個允許呼叫的 PermissionRequest hook 也可以發送 updatedPermissions,其中一種條目類型 setMode 會更改權限模式,例如變更為 acceptEdits(請參閱 hooks 參考資料)。

Cowork 可以在 Anthropic 的伺服器上執行雲端任務。在這些會話中,批准仍然有效,但模式不再改變。如果一個 hook 批准了第一次編輯並將會話切換到接受編輯模式,它將繼續看到權限請求。2.1.299 版中有一條相關的內容對 Cowork 雲端會話中的自動模式更進一步:「PermissionRequest hook 不再能批准 shell 指令或子代理程式;這些提示詞會等待或被拒絕。」這兩行都沒有提及本地終端機會話。

這個檢查會找到發送模式更改的 hooks:grep -rn setMode .claude ~/.claude/settings.json ~/.claude/hooks。

5. 代理程式工具清單只會選取其指定伺服器的工具

從 2.1.299 版開始:「已變更代理程式工具清單,使其只選取指定 MCP 伺服器的工具;如果伺服器名稱包含 __,則將其列為 mcp__<完整名稱>__。」子代理程式文件說明 mcp__<server> 或 mcp__<server>__ 在 tools: 中會授予指定伺服器的所有工具。

同一版本中的允許規則行闡明了舊的漏洞:mcp__a 過去也能存取名為 a__b 或 a_ 的伺服器。代理程式工具清單也受到了相同的限制。如果一個代理程式過去透過共享前綴悄悄地選取了第二個伺服器的工具,現在將會失去它們。如果其清單中沒有任何條目再解析到工具,文件說明子代理程式通常會啟動失敗。

比較你的代理程式檔案中的 MCP 條目與實際的伺服器名稱:grep -rn 'mcp__' .claude/agents ~/.claude/agents,然後執行 claude mcp list。

6. 無法回應的外掛程式 hook 現在會拒絕動作

從 2.1.299 版開始:「已變更外掛程式 hook 無法接收動作或無法返回其回應時,其可阻擋的動作會被拒絕,而不是放行;如果工具已執行,其結果將被保留。」這項變更將失敗從開放轉為關閉。當外掛程式 hook 無法接收動作或無法返回其回應時,動作過去會被放行。現在動作會被拒絕。如果工具已經執行,它會保持執行狀態,但 Claude 永遠看不到其結果。

hooks 參考資料說明 claude --debug 會將日誌寫入 ~/.claude/debug/<session-id>.txt。從 2.1.296 版開始,工具事件、提示詞、SessionStart、Stop 和其他幾個事件上的命令 hooks 會留下一個 Hooks: 行,其中包含命令、來源外掛程式(如果有的話),以及結果,結尾是持續時間或 timed out after <N>ms、cancelled 或 failed to start。

使用 --debug 運行一個會話,然後從這裡開始檢查:grep -hE 'timed out|failed to start' ~/.claude/debug/*.txt。只有提及外掛程式的行才算數,並且匹配只會告訴你在哪裡尋找。

來自你自己的設定的 hook 與此變更無關,而 /hooks 會標記每個 hook 的來源,以便你可以區分兩者。作為 mods 構建的外掛程式不會寫入 Hooks: 行,因此對於這些,請從 /plugin 中的「錯誤」選項卡開始檢查。

7. mod 的 .catch 不再接收重入事件

從 2.1.301 版開始:「已變更 mod hook 的 .catch 處理器,使其僅在 hook 拋出錯誤或超時時執行;在 hook 自己的呼叫下引發的事件現在會跳過該 hook,而不會詢問其 .catch。」mods 參考資料列出了 .catch 處理器中 next.error.kind 的三個值:throw、timeout 和 re-entry,其中 re-entry 用於來自你自己的 hook 所做的 mods API 呼叫內部的事件。

從 2.1.301 版開始,這些內部事件會跳過你的 hook,你的處理器永遠不會收到它們。用於 re-entry 的 .catch 分支現在是無效程式碼。你的守護程式透過 $.tool.call 自己進行的工具呼叫將不會被該守護程式或其 .catch 檢查。

這個檢查會找到仍然測試它的處理器,然後驗證 mod:grep -rn 're-entry' ./my-mod/hooks,然後執行 claude plugin validate ./my-mod。

三個現在會阻擋過去會通過的修復

並非所有行為變更都歸類在「已變更」之下。在 2.1.294 版中,以指令形式編寫的提示詞和代理程式 hooks,例如「阻擋這些指令...」,停止允許它們應該阻擋的內容。在 2.1.299 版中,當未安裝 Git for Windows 時,未設定 shell 的 PreToolUse 和 PermissionRequest hooks 在 Windows 上不再開放失敗。

在 2.1.300 版中,如果代理程式 hook 的模型不可用,它會回退到呼叫者的模型,而不是允許該動作(請參閱更新日誌)。如果你的某個守護程式從未觸發過,它現在可能會開始觸發。

先在分支上測試變更

我開發 Hermes IDE,因此請考量到這一點。Hermes 在真實終端機中運行 Claude Code 自己的介面,因此 /hooks、/plugin 和 claude --debug 的行為與其他任何地方都一樣。Hermes 額外提供的是一個測試 hook 變更的地方,而無需觸碰你的主要程式碼庫。

⌘N(Windows 和 Linux 上為 Ctrl+Shift+N)會在自己的工作樹中啟動每個任務,並在 hermes/<name> 分支上。該工作樹有自己的每個追蹤檔案副本,包括 .claude/settings.json、.claude/skills/ 和 .claude/agents/。在那裡編輯一個 hook,在該會話的終端機中運行上述檢查,並在它行為正常後再合併。

有兩個限制:~/.claude/ 中的 hooks 會被所有工作樹共享,而且 Git 會從追蹤檔案構建工作樹,因此在信任測試運行之前,請檢查是否存在未追蹤的 .claude/settings.local.json。每個會話上方的「指令」清單顯示了釘選和內建指令,從 2.3.4 版開始也顯示了你自己的指令和技能,每個都有簡短說明。這使得它成為快速清點項目 1 和 2 影響的清單。

Claude Code 會話上方的動作欄(提示詞、上下文 4%、模型、計畫、審查、/指令)開啟了指令清單:釘選的上下文、模型、計畫和審查,然後是內建指令,例如精簡、使用情況和差異。Hermes 絕不會替你回答權限提示詞,也絕不會自行在終端機中輸入,因此它沒有自己的決策者:你的 hooks、你的權限規則和你仍然是最終決策者。

它是免費的,在 BSL 1.1 下開源,並可在 macOS、Windows 和 Linux 上運行。它不隸屬於 Anthropic、Nous Research 或任何代理程式供應商。

如果這篇文章對你有幫助

前兩項變更以及 2.1.294 版對提示詞 hooks 的修復,都位於一個界線:到達模型的提示詞文字,以及誰可以在輸入過程中重寫它。阻擋提示詞、擴展技能以及將提示詞 hook 編寫為指令,都是在設定檔中完成的提示詞工程。

Share

覺得值得一看?分享給朋友。

以上為 AI 自動翻譯導讀。原文版權歸 DEV Community (Claude Code) 所有, 建議透過「閱讀原文」前往原始網站,以取得最完整資訊並支持原作者。

Newsletter

不用每天追,AI 重點每週寄給你

43 個來源、每 2 小時更新,太多看不完。電子報每週挑最值得看的幾則,附上 Max 的看法。

每週一封。Email 只用來寄電子報,每封信都能一鍵退訂。