1159 Hook 事件1159 Hook 事件
1160</h2>1160</h2>
1161 1161
1162每個事件對應於 Claude Code 生命週期中的一個點,hooks 可以在該點執行。下面的章節按照生命週期順序排列:從工作階段設定到代理迴圈再到工作階段結束。每個章節描述事件何時觸發、它支援的匹配器、它接收的 JSON 輸入,以及如何透過輸出控制行為。1162每個事件對應 Claude Code 生命週期中可執行 hook 的一個時間點。以下各節依生命週期排序:從工作階段設定,經過代理式迴圈,直到工作階段結束。每一節說明事件何時觸發、支援哪些 matcher、接收的 JSON 輸入,以及如何透過輸出控制行為。
1163 1163
1164<h3 id="sessionstart">1164<h3 id="sessionstart">
1165 SessionStart1165 SessionStart
1166</h3>1166</h3>
1167 1167
1168在 Claude Code 啟動新工作階段或恢復現有工作階段時執行。適用於載入開發環境背景資訊,例如現有問題或程式碼庫的最近變更,或設定環境變數。對於不需要指令碼的靜態背景資訊,請改用 [CLAUDE.md](/docs/zh-TW/memory)。1168在 Claude Code 啟動新工作階段或繼續現有工作階段時執行。適合用來載入開發上下文,例如現有的 issue 或程式碼庫的近期變更,或設定環境變數。若是不需要指令碼的靜態上下文,請改用 [CLAUDE.md](/docs/zh-TW/memory)。
1169 1169
1170SessionStart 在每個工作階段執行,因此請保持這些 hooks 快速。僅支援 `type: "command"` 和 `type: "mcp_tool"` hooks。有關 `mcp_tool` hooks 何時執行,請參閱 [MCP tool hook 欄位](#mcp-tool-hook-fields)。1170SessionStart 會在每個工作階段執行,因此請讓這些 hook 保持快速。僅支援 `type: "command"` 與 `type: "mcp_tool"` hook。關於 `mcp_tool` hook 何時執行,請參閱 [MCP tool hook 欄位](#mcp-tool-hook-fields)。
1171 1171
1172匹配器值對應於工作階段的啟動方式:1172matcher 值對應工作階段的啟動方式:
1173 1173
1174| 匹配器 | 何時觸發 |1174| Matcher | 觸發時機 |
1175| :- | :- |1175| :- | :- |
1176| `startup` | 新工作階段 |1176| `startup` | 新工作階段 |
1177| `resume` | `--resume`、`--continue` 或 `/resume` |1177| `resume` | `--resume`、`--continue` 或 `/resume` |
1178| `clear` | `/clear` |1178| `clear` | `/clear` |
1179| `compact` | 自動或手動壓縮 |1179| `compact` | 自動或手動壓縮 |
1180| `fork` | 從現有工作階段分支的新工作階段:`--fork-session` 搭配 `--resume` 或 `--continue`、`/fork` 背景複本、`/branch`,或您 [移到背景](/docs/zh-TW/agent-view#from-inside-a-session) 的對話 |1180| `fork` | 從現有工作階段分叉出的新工作階段:搭配 `--resume` 或 `--continue` 使用的 `--fork-session`、`/fork` 背景副本、`/branch`,或您[移至背景](/docs/zh-TW/agent-view#from-inside-a-session)的對話 |
1181 1181
1182在 v2.1.214 之前,分支工作階段報告來源為 `"resume"`。1182在 v2.1.214 之前,分叉的工作階段回報的 source 為 `"resume"`。
1183 1183
1184當您啟動互動式工作階段、在啟動時使用 `--continue` 或 `--resume` 恢復對話,或執行 `/clear` 時,SessionStart hooks 在背景執行。您可以立即輸入,恢復的對話會立即出現,無需等待 hooks。Claude 的第一個回應仍會等待 hooks 完成,因此它們的背景資訊會到達 Claude。1184當您啟動互動式工作階段、在啟動時以 `--continue` 或 `--resume` 繼續對話,或執行 `/clear` 時,SessionStart hook 會在背景執行。您可以立即開始輸入,而您繼續的對話也會直接顯示,不必等待 hook。Claude 的第一個回應仍會等待 hook 完成,讓其上下文能傳達給 Claude。
1185 1185
1186當您在工作階段內使用 `/resume` 切換對話時,切換會等待 hooks 完成。如果您在背景 hooks 仍在執行時執行 `/clear` 或切換到另一個對話,它們返回的任何內容都不會套用到工作階段。1186若您在工作階段內以 `/resume` 切換對話,切換動作則會等待 hook 完成。如果您在背景 hook 仍在執行時執行 `/clear` 或切換到另一個對話,它們回傳的任何內容都不會套用到該工作階段。
1187 1187
1188相同的等待也適用於啟動,包括恢復的工作階段:您在 SessionStart hooks 仍在執行時傳送的提示不會到達 Claude,直到它們完成。1188啟動時也適用相同的等待,包括繼續的工作階段:在 SessionStart hook 仍在執行時送出的提示詞,要等到 hook 完成後才會傳達給 Claude。
1189 1189
1190在任一等待期間,按 `Esc` 將提示取回輸入而不傳送。hooks 會繼續執行。1190在上述任一種等待期間,按下 `Esc` 可將提示詞收回輸入框而不送出。hook 會繼續執行。
1191 1191
1192<h4 id="sessionstart-input">1192<h4 id="sessionstart-input">
1193 SessionStart 輸入1193 SessionStart 輸入
1194</h4>1194</h4>
1195 1195
1196除了 [常見輸入欄位](#common-input-fields) 外,SessionStart hooks 還會接收 `source` 和可選的 `model`、`agent_type` 和 `session_title`:1196除了[通用輸入欄位](#common-input-fields)之外,SessionStart hook 還會接收 `source`,以及選擇性的 `model`、`agent_type` 與 `session_title`:
1197 1197
1198| 欄位 | 描述 |1198| 欄位 | 說明 |
1199| :- | :- |1199| :- | :- |
1200| `source` | 工作階段如何啟動:新工作階段為 `"startup"`、恢復的工作階段為 `"resume"`、`/clear` 後為 `"clear"`、壓縮後為 `"compact"`,或從現有工作階段分支的新工作階段為 `"fork"` |1200| `source` | 工作階段的啟動方式:新工作階段為 `"startup"`,繼續的工作階段為 `"resume"`,`/clear` 之後為 `"clear"`,壓縮之後為 `"compact"`,從現有工作階段分叉出的新工作階段則為 `"fork"` |
1201| `model` | 作用中的模型識別碼。例如在 `/clear` 後或透過對話恢復還原工作階段時,可能會省略,因此請在讀取前檢查欄位 |1201| `model` | 目前使用中的模型識別碼。此欄位可能被省略,例如在 `/clear` 之後,或工作階段透過對話復原而還原時,因此讀取前請先檢查該欄位是否存在 |
1202| `agent_type` | 代理名稱,當您使用 `claude --agent <name>` 啟動 Claude Code 時出現 |1202| `agent_type` | agent 名稱,當您以 `claude --agent <name>` 啟動 Claude Code 時才會出現 |
1203| `session_title` | 工作階段的自訂標題,當已設定時出現,例如使用 `--name`、`/rename`、hook 的 `sessionTitle` 輸出或 Agent SDK 的 `renameSession()`。發出 `sessionTitle` 的 hook 可以先檢查此欄位以避免覆寫現有的自訂標題 |1203| `session_title` | 工作階段的自訂標題,僅在已設定時出現,例如透過 `--name`、`/rename`、hook 的 `sessionTitle` 輸出,或 Agent SDK 的 `renameSession()` 設定。輸出 `sessionTitle` 的 hook 可以先檢查此欄位,以避免覆寫既有的自訂標題 |
1204 1204
1205未命名的工作階段仍可能有 [產生的標題](/docs/zh-TW/sessions#name-your-sessions)。該標題不是自訂標題,不會出現在 `session_title` 中。1205您尚未命名的工作階段仍可能有[自動產生的標題](/docs/zh-TW/sessions#name-your-sessions)。該標題並非自訂標題,不會出現在 `session_title` 中。
1206 1206
1207當 `source` 為 `"resume"` 或 `"fork"` 且文字記錄包含至少一個來自 Claude 的回應時,SessionStart hooks 也會接收下面的四個欄位。您的 hook 可以使用它們在第一個請求之前報告恢復陳舊對話的成本,例如在 [`systemMessage`](#json-output) 中。這些欄位需要 Claude Code v2.1.251 或更新版本。1207當 `source` 為 `"resume"` 或 `"fork"`,且逐字稿中至少包含一則 Claude 的回應時,SessionStart hook 也會接收以下四個欄位。您的 hook 可以用它們在第一個請求之前回報繼續一個陳舊對話的成本,例如透過 [`systemMessage`](#json-output)。這些欄位需要 Claude Code v2.1.251 或更新版本。
1208 1208
1209| 欄位 | 描述 |1209| 欄位 | 說明 |
1210| :- | :- |1210| :- | :- |
1211| `seconds_since_last_response` | 自恢復文字記錄中最後一個回應以來的牆上時間秒數 |1211| `seconds_since_last_response` | 自繼續的逐字稿中最後一則回應以來經過的實際秒數 |
1212| `context_tokens` | 恢復工作階段的第一個請求作為其提示重新傳送的權杖 |1212| `context_tokens` | 繼續的工作階段的第一個請求作為提示詞重新傳送的 token 數 |
1213| `prompt_cache_likely_expired` | 當最後一個回應早於工作階段的 [prompt cache 生命週期](/docs/zh-TW/prompt-caching#cache-lifetime) 或更新的壓縮替換了快取的對話時為 `true` |1213| `prompt_cache_likely_expired` | 當最後一則回應早於工作階段的[提示快取存留期](/docs/zh-TW/prompt-caching#cache-lifetime),或後續的壓縮取代了已快取的對話時,為 `true` |
1214| `estimated_cache_write_usd` | 將 `context_tokens` 寫入工作階段模型的 prompt cache 的估計成本(美元),不包括回應 |1214| `estimated_cache_write_usd` | 在工作階段的模型上將 `context_tokens` 寫入提示快取的預估成本(美元),不含回應 |
1215 1215
1216此範例顯示在最後一個回應後 90 分鐘恢復的工作階段的輸入:1216此範例顯示在最後一則回應 90 分鐘後繼續的工作階段的輸入:
1217 1217
1218```json theme={null}1218```json theme={null}
1219{1219{
1234 SessionStart 決策控制1234 SessionStart 決策控制
1235</h4>1235</h4>
1236 1236
1237Claude Code 將它 [視為純文字](#exit-code-0) 的 stdout 新增到 Claude 的背景資訊。除了所有 hooks 可用的 [JSON 輸出欄位](#json-output) 外,您還可以返回這些事件特定的欄位:1237Claude Code 會將其[視為純文字](#exit-code-0)的 stdout 加入 Claude 的上下文。除了所有 hook 都可使用的 [JSON 輸出欄位](#json-output)之外,您還可以回傳下列事件專屬欄位:
1238 1238
1239| 欄位 | 描述 |1239| 欄位 | 說明 |
1240| :- | :- |1240| :- | :- |
1241| `additionalContext` | 在對話開始時、第一個提示之前新增到 Claude 背景資訊的字串。有關文字如何傳遞以及要放入其中的內容,請參閱 [為 Claude 新增背景資訊](#add-context-for-claude) |1241| `additionalContext` | 在對話開始時、第一個提示詞之前加入 Claude 上下文的字串。關於文字的傳遞方式以及應放入的內容,請參閱[為 Claude 加入上下文](#add-context-for-claude) |
1242| `initialUserMessage` | 用作工作階段第一個使用者訊息的字串。適用於 [非互動模式](/docs/zh-TW/headless),搭配 `-p` 旗標,即使未提供提示,它也會成為第一個回合。如果提供了提示,它會作為下一個回合跟隨。與 `additionalContext` 不同,後者附加到現有回合,這會建立回合 |1242| `initialUserMessage` | 作為工作階段第一則使用者訊息的字串。適用於使用 `-p` 旗標的[非互動模式](/docs/zh-TW/headless),即使未提供提示詞,它也會成為第一個回合。若有提供提示詞,該提示詞會作為下一個回合接續。與附加到既有回合的 `additionalContext` 不同,此欄位會建立回合 |
1243| `sessionTitle` | 設定工作階段標題,效果與 `/rename` 相同。用於根據啟動資料夾、git 分支或 worktree 名稱自動命名工作階段。當 `source` 為 `"startup"`、`"resume"` 或 `"fork"` 時適用;在 `"clear"` 和 `"compact"` 上忽略 |1243| `sessionTitle` | 設定工作階段標題,效果與 `/rename` 相同。可用來依據啟動資料夾、git 分支或 worktree 名稱自動為工作階段命名。在 `source` 為 `"startup"`、`"resume"` 或 `"fork"` 時套用;在 `"clear"` 與 `"compact"` 時忽略 |
1244| `watchPaths` | 要在此工作階段期間監視 [FileChanged](#filechanged) 事件的絕對路徑陣列 |1244| `watchPaths` | 在此工作階段中要監看 [FileChanged](#filechanged) 事件的絕對路徑陣列 |
1245| `reloadSkills` | 布林值。當為 `true` 時,Claude Code 在 SessionStart hooks 完成後重新掃描 [skill](/docs/zh-TW/skills) 和命令目錄,因此 hook 安裝的 skills 在同一工作階段中可用,從第一個提示開始 |1245| `reloadSkills` | 布林值。為 `true` 時,Claude Code 會在 SessionStart hook 完成後重新掃描 [skill](/docs/zh-TW/skills) 與命令目錄,讓 hook 安裝的 skill 能在同一個工作階段中使用,從第一個提示詞開始即可使用 |
1246 1246
1247```json theme={null}1247```json theme={null}
1248{1248{
1254}1254}
1255```1255```
1256 1256
1257由於此事件的純文字 stdout 已到達 Claude,只載入背景資訊的 hook 可以直接列印到 stdout,而無需建立 JSON。當您需要將背景資訊與其他欄位(例如 `sessionTitle`)結合時,請使用 JSON 形式。1257由於此事件的純 stdout 已會傳達給 Claude,只載入上下文的 hook 可以直接輸出到 stdout,不必建構 JSON。當您需要將上下文與其他欄位(例如 `sessionTitle`)結合時,請使用 JSON 形式。
1258 1258
1259當 SessionStart hook 安裝或更新 skills 時,使用 `reloadSkills`。Skill 探索通常在 SessionStart hooks 完成之前執行,因此 hook 寫入 `~/.claude/skills/` 或 `.claude/skills/` 的檔案否則只會在下一個工作階段中出現。此範例同步共享 skills 儲存庫並請求重新掃描:1259當 SessionStart hook 安裝或更新 skill 時,請使用 `reloadSkills`。skill 探索通常在 SessionStart hook 完成之前就已執行,因此 hook 寫入 `~/.claude/skills/` 或 `.claude/skills/` 的檔案,否則要到下一個工作階段才會出現。此範例會同步一個共用的 skill 儲存庫並要求重新掃描:
1260 1260
1261```bash theme={null}1261```bash theme={null}
1262#!/bin/bash1262#!/bin/bash
1267echo '{"hookSpecificOutput": {"hookEventName": "SessionStart", "reloadSkills": true}}'1267echo '{"hookSpecificOutput": {"hookEventName": "SessionStart", "reloadSkills": true}}'
1268```1268```
1269 1269
1270儲存庫 URL 是佔位符;請將其替換為您自己的 skills 儲存庫。使用佔位符時,複製失敗並列印 `fatal:` 訊息到 stderr。來自退出 0 的 SessionStart hook 的 stderr 僅供參考,因此 `reloadSkills` 請求仍然適用。1270儲存庫 URL 只是預留位置;請將它替換為您自己的 skill 儲存庫。使用預留位置時,clone 會失敗並將 `fatal:` 訊息輸出到 stderr。以退出碼 0 結束的 SessionStart hook 的 stderr 僅供參考,因此 `reloadSkills` 請求仍會套用。
1271 1271
1272<h4 id="persist-environment-variables">1272<h4 id="persist-environment-variables">
1273 保留環境變數1273 保存環境變數
1274</h4>1274</h4>
1275 1275
1276SessionStart hooks 可以存取 `CLAUDE_ENV_FILE` 環境變數,它提供一個檔案路徑,您可以在其中保留後續 Bash 命令的環境變數。1276SessionStart hook 可以存取 `CLAUDE_ENV_FILE` 環境變數,它提供一個檔案路徑,讓您可以為後續的 Bash 命令保存環境變數。
1277 1277
1278要設定個別環境變數,請將 `export` 陳述式寫入 `CLAUDE_ENV_FILE`。使用附加 (`>>`) 來保留由其他 hooks 設定的變數:1278若要設定個別環境變數,請將 `export` 陳述式寫入 `CLAUDE_ENV_FILE`。請使用附加(`>>`)以保留其他 hook 設定的變數:
1279 1279
1280```bash theme={null}1280```bash theme={null}
1281#!/bin/bash1281#!/bin/bash
1289exit 01289exit 0
1290```1290```
1291 1291
1292要捕獲設定命令的所有環境變更,請比較之前和之後的匯出變數:1292若要擷取設定命令造成的所有環境變更,請比較執行前後匯出的變數:
1293 1293
1294```bash theme={null}1294```bash theme={null}
1295#!/bin/bash1295#!/bin/bash
1309```1309```
1310 1310
1311<Note>1311<Note>
1312 `CLAUDE_ENV_FILE` 適用於 SessionStart、[Setup](#setup)、[CwdChanged](#cwdchanged) 和 [FileChanged](#filechanged) hooks。其他 hook 類型無法存取此變數。1312 `CLAUDE_ENV_FILE` 可供 SessionStart、[Setup](#setup)、[CwdChanged](#cwdchanged) 與 [FileChanged](#filechanged) hook 使用。其他 hook 類型無法存取此變數。
1313</Note>1313</Note>
1314 1314
1315<h3 id="setup">1315<h3 id="setup">
1316 Setup1316 Setup
1317</h3>1317</h3>
1318 1318
1319僅當您使用 `--init-only` 啟動 Claude Code,或在 [非互動模式](/docs/zh-TW/headless) 中使用 `--init` 或 `--maintenance` 搭配 `-p` 旗標時執行。它不會在正常啟動時執行。用於一次性相依性安裝或您從 CI 或指令碼明確觸發的排程清理,與正常工作階段啟動分開。對於每個工作階段的初始化,請改用 [SessionStart](#sessionstart)。1319僅在您以 `--init-only` 啟動 Claude Code,或在使用 `-p` 旗標的[非互動模式](/docs/zh-TW/headless)中搭配 `--init` 或 `--maintenance` 啟動時觸發。一般啟動時不會觸發。可用於一次性的相依套件安裝,或您從 CI 或指令碼明確觸發的排程清理,與一般工作階段啟動分開。若是每個工作階段的初始化,請改用 [SessionStart](#sessionstart)。
1320 1320
1321匹配器值對應於觸發 hook 的 CLI 旗標:1321matcher 值對應觸發該 hook 的 CLI 旗標:
1322 1322
1323| 匹配器 | 何時觸發 |1323| Matcher | 觸發時機 |
1324| :- | :- |1324| :- | :- |
1325| `init` | `claude --init-only` 或 `claude -p --init` |1325| `init` | `claude --init-only` 或 `claude -p --init` |
1326| `maintenance` | `claude -p --maintenance` |1326| `maintenance` | `claude -p --maintenance` |
1327 1327
1328當您執行 `claude --init-only` 時,Claude Code 執行 Setup hooks 和 `SessionStart` hooks(使用 `startup` 匹配器),然後退出而不啟動對話。1328當您執行 `claude --init-only` 時,Claude Code 會執行 Setup hook 以及 matcher 為 `startup` 的 `SessionStart` hook,然後在不啟動對話的情況下結束。
1329 1329
1330當您使用 `-p` 啟動或繼續對話時,您還需要提供提示,作為引數或透過 stdin 管道傳輸。當 `SessionStart` hook 提供 [`initialUserMessage`](#sessionstart-decision-control) 或當您使用 [延遲工具呼叫](#defer-a-tool-call-for-later) 恢復工作階段時,您可以跳過提示。1330當您以 `-p` 開始或繼續對話時,還需要提供提示詞,作為引數或透過 stdin 傳入。當 `SessionStart` hook 提供 [`initialUserMessage`](#sessionstart-decision-control),或您繼續一個帶有[延後工具呼叫](#defer-a-tool-call-for-later)的工作階段時,可以省略提示詞。
1331 1331
1332成功時,`--init-only` 不會列印任何內容到終端。要確認 hooks 已執行,請使用 `claude --debug-file <path> --init-only` 啟動,將 `<path>` 替換為日誌檔案位置,並檢查日誌中的 Setup 和 SessionStart hook 項目。1332成功時,`--init-only` 不會在終端機輸出任何內容。若要確認 hook 已執行,請以 `claude --debug-file <path> --init-only` 啟動,將 `<path>` 替換為日誌檔案位置,並在日誌中檢查 Setup 與 SessionStart hook 的項目。
1333 1333
1334由於 Setup 不會在每次啟動時執行,需要安裝相依性的外掛無法僅依賴 Setup。實用的模式是在首次使用時檢查相依性,如果缺少則安裝,例如測試 `${CLAUDE_PLUGIN_DATA}/node_modules` 的 hook 或 skill,如果不存在則執行 `npm install`。有關在何處儲存已安裝的相依性,請參閱 [持久資料目錄](/docs/zh-TW/plugins/components#path-variables-and-persistent-data)。如果您透過市場發佈外掛,您可能不需要此模式:Claude Code [在快取外掛時自動安裝符合條件的 Node.js 套件相依性](/docs/zh-TW/plugins/loading#node-js-package-dependencies)。1334由於 Setup 不會在每次啟動時觸發,需要安裝相依套件的外掛無法僅依賴 Setup。實務上的做法是在首次使用時檢查相依套件,缺少時再安裝,例如由 hook 或 skill 檢查 `${CLAUDE_PLUGIN_DATA}/node_modules`,若不存在則執行 `npm install`。關於已安裝相依套件的存放位置,請參閱[持久性資料目錄](/docs/zh-TW/plugins/components#path-variables-and-persistent-data)。如果您透過市集發布外掛,可能不需要此做法:Claude Code 在快取外掛時會[自動安裝符合條件的 Node.js 套件相依性](/docs/zh-TW/plugins/loading#node-js-package-dependencies)。
1335 1335
1336<h4 id="setup-input">1336<h4 id="setup-input">
1337 Setup 輸入1337 Setup 輸入
1338</h4>1338</h4>
1339 1339
1340除了 [常見輸入欄位](#common-input-fields) 外,Setup hooks 還會接收設定為 `"init"` 或 `"maintenance"` 的 `trigger` 欄位:1340除了[通用輸入欄位](#common-input-fields)之外,Setup hook 還會接收 `trigger` 欄位,其值為 `"init"` 或 `"maintenance"`:
1341 1341
1342```json theme={null}1342```json theme={null}
1343{1343{
1353 Setup 決策控制1353 Setup 決策控制
1354</h4>1354</h4>
1355 1355
1356Setup hooks 無法阻止;執行在任何退出代碼上繼續。在每個退出代碼上,Claude Code 捨棄 Setup hook 的 [JSON 輸出欄位](#json-output),例如 `systemMessage`、`continue` 和 `hookSpecificOutput.additionalContext`。使用 `-p` 時,Setup hook 的 stdout、stderr 和退出代碼僅在您使用 `--output-format stream-json --verbose` 啟動時作為 [`hook_response` 事件](/docs/zh-TW/headless#read-session-metadata) 出現在執行的輸出中。1356Setup hook 無法阻擋;無論退出碼為何,執行都會繼續。無論退出碼為何,Claude Code 都會捨棄 Setup hook 的 [JSON 輸出欄位](#json-output),例如 `systemMessage`、`continue` 與 `hookSpecificOutput.additionalContext`。使用 `-p` 時,Setup hook 的 stdout、stderr 與退出碼只有在您以 `--output-format stream-json --verbose` 啟動時,才會以 [`hook_response` 事件](/docs/zh-TW/headless#read-session-metadata)的形式出現在執行輸出中。
1357 1357
1358Setup hooks 可以存取 `CLAUDE_ENV_FILE`。寫入該檔案的變數會保留到工作階段的後續 Bash 命令中,就像在 [SessionStart hooks](#persist-environment-variables) 中一樣。只有 `type: "command"` hooks 在 `Setup` 上執行。`type: "mcp_tool"` hook 在 `Setup` 上始終被跳過,如 [MCP tool hook 欄位](#mcp-tool-hook-fields) 下所述。1358Setup hook 可以存取 `CLAUDE_ENV_FILE`。寫入該檔案的變數會保存到該工作階段的後續 Bash 命令中,與 [SessionStart hook](#persist-environment-variables) 相同。只有 `type: "command"` hook 會在 `Setup` 上執行。`Setup` 上的 `type: "mcp_tool"` hook 一律會被略過,如 [MCP tool hook 欄位](#mcp-tool-hook-fields)中所述。
1359 1359
1360<h3 id="instructionsloaded">1360<h3 id="instructionsloaded">
1361 InstructionsLoaded1361 InstructionsLoaded
1362</h3>1362</h3>
1363 1363
1364在載入 `CLAUDE.md` 或 `.claude/rules/*.md` 檔案到背景資訊時執行。此事件在工作階段啟動時對於急切載入的檔案執行,稍後在檔案被延遲載入時再次執行,例如當 Claude 存取包含巢狀 `CLAUDE.md` 的子目錄或當具有 `paths:` frontmatter 的條件規則匹配時。該 hook 不支援阻止或決策控制。它以非同步方式執行以用於可觀測性目的。1364在 `CLAUDE.md` 或 `.claude/rules/*.md` 檔案載入上下文時觸發。此事件會在工作階段開始時針對預先載入的檔案觸發,之後在延遲載入檔案時再次觸發,例如當 Claude 存取包含巢狀 `CLAUDE.md` 的子目錄,或帶有 `paths:` frontmatter 的條件式規則相符時。此 hook 不支援阻擋或決策控制。它會為了可觀察性而以非同步方式執行。
1365 1365
1366當 Claude [直接透過 **Project instructions** 設定讀取 `AGENTS.md`](/docs/zh-TW/memory#agents-md) 時,此事件不會執行。當 `CLAUDE.md` 匯入您的 `AGENTS.md` 時,它會執行,`load_reason` 設定為 `include`(與任何其他匯入檔案相同),以及當 `CLAUDE.md` 是它的符號連結時,作為正常的 `CLAUDE.md` 載入。1366當 Claude 透過 **Project instructions** 設定[直接讀取 `AGENTS.md`](/docs/zh-TW/memory#agents-md) 時,此事件不會觸發。當 `CLAUDE.md` 匯入您的 `AGENTS.md` 時,此事件會觸發,且 `load_reason` 與其他任何匯入的檔案一樣設為 `include`;當 `CLAUDE.md` 是指向它的符號連結時,也會以一般的 `CLAUDE.md` 載入觸發。
1367 1367
1368匹配器針對 `load_reason` 執行。例如,使用 `"matcher": "session_start"` 僅對在工作階段啟動時載入的檔案執行,或 `"matcher": "path_glob_match|nested_traversal"` 僅對延遲載入執行。1368matcher 會比對 `load_reason`。例如,使用 `"matcher": "session_start"` 只針對工作階段開始時載入的檔案觸發,或使用 `"matcher": "path_glob_match|nested_traversal"` 只針對延遲載入觸發。
1369 1369
1370<h4 id="instructionsloaded-input">1370<h4 id="instructionsloaded-input">
1371 InstructionsLoaded 輸入1371 InstructionsLoaded 輸入
1372</h4>1372</h4>
1373 1373
1374除了 [常見輸入欄位](#common-input-fields) 外,InstructionsLoaded hooks 還會接收這些欄位:1374除了[通用輸入欄位](#common-input-fields)之外,InstructionsLoaded hook 還會接收以下欄位:
1375 1375
1376| 欄位 | 描述 |1376| 欄位 | 說明 |
1377| :- | :- |1377| :- | :- |
1378| `file_path` | 已載入的指令檔案的絕對路徑 |1378| `file_path` | 已載入的指令檔案的絕對路徑 |
1379| `memory_type` | 檔案的範圍:`"User"`、`"Project"`、`"Local"` 或 `"Managed"` |1379| `memory_type` | 檔案的範圍:`"User"`、`"Project"`、`"Local"` 或 `"Managed"` |
1380| `load_reason` | 檔案被載入的原因:`"session_start"`、`"nested_traversal"`、`"path_glob_match"`、`"include"` 或 `"compact"`。`"compact"` 值在壓縮事件後重新載入指令檔案時執行 |1380| `load_reason` | 檔案載入的原因:`"session_start"`、`"nested_traversal"`、`"path_glob_match"`、`"include"` 或 `"compact"`。`"compact"` 值會在壓縮事件後重新載入指令檔案時觸發 |
1381| `globs` | 檔案的 `paths:` frontmatter 中的路徑 glob 模式(如果有)。僅對 `path_glob_match` 載入出現 |1381| `globs` | 檔案 `paths:` frontmatter 中的路徑 glob 模式(若有)。僅在 `path_glob_match` 載入時出現 |
1382| `trigger_file_path` | 觸發此載入的檔案的路徑,用於延遲載入 |1382| `trigger_file_path` | 對於延遲載入,其存取觸發此次載入的檔案路徑 |
1383| `parent_file_path` | 包含此檔案的父指令檔案的路徑,用於 `include` 載入 |1383| `parent_file_path` | 對於 `include` 載入,包含此檔案的上層指令檔案路徑 |
1384 1384
1385```json theme={null}1385```json theme={null}
1386{1386{
1398 InstructionsLoaded 決策控制1398 InstructionsLoaded 決策控制
1399</h4>1399</h4>
1400 1400
1401InstructionsLoaded hooks 沒有決策控制。它們無法阻止或修改指令載入。Claude Code 捨棄它們的 [JSON 輸出欄位](#json-output),例如 `systemMessage` 和 `continue`。使用此事件進行稽核日誌、合規性追蹤或可觀測性。1401InstructionsLoaded hook 沒有決策控制。它們無法阻擋或修改指令載入。Claude Code 會捨棄它們的 [JSON 輸出欄位](#json-output),例如 `systemMessage` 與 `continue`。請將此事件用於稽核日誌、合規追蹤或可觀察性。
1402 1402
1403<h3 id="userpromptsubmit">1403<h3 id="userpromptsubmit">
1404 UserPromptSubmit1404 UserPromptSubmit
1405</h3>1405</h3>
1406 1406
1407在使用者提交提示時執行,在 Claude 處理它之前。這允許您根據提示/對話新增額外背景資訊、驗證提示或阻止某些類型的提示。1407在使用者送出提示詞時、Claude 處理之前執行。這讓您可以
1408根據提示詞/對話加入額外上下文、驗證提示詞,或
1409阻擋特定類型的提示詞。
1408 1410
1409`UserPromptSubmit` hooks 對 `command`、`http` 和 `mcp_tool` 類型的預設逾時為 30 秒,比大多數其他事件的 600 秒預設值更短。因為此 hook 在每個提示之前執行並阻止模型處理直到完成,卡住的 hook 會停滯工作階段。如果您的 hook 需要更多時間,請在 hook 項目中設定 `timeout` 欄位。1411`UserPromptSubmit` hook 對於 `command`、`http` 與 `mcp_tool` 類型的預設逾時為 30 秒,比這些類型在其他大多數事件上的 600 秒預設值更短。由於此 hook 會在每個提示詞之前執行,並在完成前阻擋模型處理,卡住的 hook 會讓工作階段停滯。如果您的 hook 需要更多時間,請在 hook 項目中設定 `timeout` 欄位。
1410 1412
1411除了您使用 [`async: true`](#run-hooks-in-the-background) 執行的命令 hook 外,達到逾時的 `UserPromptSubmit` 命令、HTTP 或 MCP tool hook 會被取消,其輸出(包括任何 `additionalContext`)會被捨棄。提示仍會到達 Claude,不含該背景資訊。文字記錄顯示一個通知,命名 hook、觸發的逾時以及輸出被捨棄。1413除了您以 [`async: true`](#run-hooks-in-the-background) 執行的 command hook 之外,達到逾時的 `UserPromptSubmit` command、HTTP 或 MCP tool hook 會被取消,其輸出(包括任何 `additionalContext`)都會被捨棄。提示詞仍會傳達給 Claude,只是不含該上下文。逐字稿會顯示一則通知,指出該 hook 名稱、觸發的逾時,以及輸出已被捨棄。
1412 1414
1413在 `UserPromptSubmit` 上達到逾時的 [Agent SDK 回呼 hook](/docs/zh-TW/agent-sdk/hooks) 會用命名 hook 和逾時的訊息阻止提示,因為該處的回呼可能充當必須不失敗開放的原則閘道。工作階段繼續。在 v2.1.208 之前,該事件上的回呼逾時以執行錯誤結束回合。1415`UserPromptSubmit` 上達到逾時的 [Agent SDK 回呼 hook](/docs/zh-TW/agent-sdk/hooks) 會以指出 hook 名稱與逾時的訊息阻擋提示詞,因為該處的回呼可能充當不得在失敗時放行的政策關卡。工作階段會繼續。在 v2.1.208 之前,該事件上的回呼逾時會以執行錯誤結束該回合。
1414 1416
1415<h4 id="userpromptsubmit-input">1417<h4 id="userpromptsubmit-input">
1416 UserPromptSubmit 輸入1418 UserPromptSubmit 輸入
1417</h4>1419</h4>
1418 1420
1419除了 [常見輸入欄位](#common-input-fields) 外,UserPromptSubmit hooks 還會接收包含使用者提交的文字的 `prompt` 欄位。折疊為 `[Pasted text #N]` 佔位符的貼上內容會在原位展開。在 Claude Code [為 Claude 標記貼上文字](/docs/zh-TW/terminal-config#how-claude-treats-pasted-text) 的工作階段中,該展開內容位於 `<pasted_content id="…">` 行和 `</pasted_content id="…">` 行之間,因此如果您的 hook 解析提示,請考慮這些行。1421除了[通用輸入欄位](#common-input-fields)之外,UserPromptSubmit hook 還會接收 `prompt` 欄位,其中包含使用者送出的文字。收合為 `[Pasted text #N]` 預留位置的貼上內容,會在原位置展開後傳入。在 Claude Code [為 Claude 標記貼上文字](/docs/zh-TW/terminal-config#how-claude-treats-pasted-text)的工作階段中,展開的內容位於 `<pasted_content id="…">` 行與 `</pasted_content id="…">` 行之間,因此如果您的 hook 會剖析提示詞,請將這些行納入考量。
1420 1422
1421UserPromptSubmit hooks 也會在工作階段有自訂標題時接收 `session_title`,與 [SessionStart `session_title` 欄位](#sessionstart-input) 的含義相同。1423當工作階段具有自訂標題時,UserPromptSubmit hook 也會接收 `session_title`,其意義與 [SessionStart 的 `session_title` 欄位](#sessionstart-input)相同。
1422 1424
1423```json theme={null}1425```json theme={null}
1424{1426{
1435 UserPromptSubmit 決策控制1437 UserPromptSubmit 決策控制
1436</h4>1438</h4>
1437 1439
1438`UserPromptSubmit` hooks 可以控制是否處理使用者提示並新增背景資訊。所有 [JSON 輸出欄位](#json-output) 都可用。1440`UserPromptSubmit` hook 可以控制是否處理使用者提示詞,並加入上下文。所有 [JSON 輸出欄位](#json-output)都可使用。
1439 1441
1440有兩種方式在退出代碼 0 時將背景資訊新增到對話:1442在退出碼 0 時,有兩種方式可以將上下文加入對話:
1441 1443
1442* **純文字 stdout**:Claude Code 將它 [視為純文字](#exit-code-0) 的 stdout 新增到 Claude 的背景資訊1444* **純文字 stdout**:Claude Code 會將其[視為純文字](#exit-code-0)的 stdout 加入 Claude 的上下文
1443* **JSON 搭配 `additionalContext`**:使用下面的 JSON 格式以獲得更多控制。`additionalContext` 欄位作為背景資訊新增1445* **帶有 `additionalContext` 的 JSON**:使用下方的 JSON 格式以獲得更多控制。`additionalContext` 欄位會作為上下文加入
1444 1446
1445兩個通道都不會產生可見的文字記錄項目。純文字和 `additionalContext` 值各自作為以 hook 名稱開頭的系統提醒注入;Claude 讀取兩者。要確認傳遞,請檢查 [debug log](#debug-hooks)。1447兩種管道都不會產生可見的逐字稿項目。純 stdout 與 `additionalContext` 值會各自以開頭為 hook 名稱的系統提醒注入;Claude 兩者都會讀取。若要確認已傳遞,請檢查[偵錯日誌](#debug-hooks)。
1446 1448
1447要阻止提示,請返回一個 JSON 物件,其中 `decision` 設定為 `"block"`:1449若要阻擋提示詞,請回傳 `decision` 設為 `"block"` 的 JSON 物件:
1448 1450
1449| 欄位 | 描述 |1451| 欄位 | 說明 |
1450| :- | :- |1452| :- | :- |
1451| `decision` | `"block"` 防止提示被處理並將其從背景資訊中刪除。省略以允許提示繼續 |1453| `decision` | `"block"` 會在提示詞傳達給 Claude 之前將其停止。省略則允許提示詞繼續 |
1452| `reason` | 當 `decision` 為 `"block"` 時顯示給使用者。不新增到背景資訊 |1454| `reason` | 當 `decision` 為 `"block"` 時向使用者顯示。不會加入上下文 |
1453| `additionalContext` | 與提交的提示一起新增到 Claude 背景資訊的字串。有關詳細資訊,請參閱 [為 Claude 新增背景資訊](#add-context-for-claude) |1455| `additionalContext` | 與送出的提示詞一同加入 Claude 上下文的字串。請參閱[為 Claude 加入上下文](#add-context-for-claude) |
1454| `sessionTitle` | 設定工作階段標題。用於根據提示內容自動命名工作階段 |1456| `sessionTitle` | 設定工作階段標題。可用來依據提示詞內容自動為工作階段命名 |
1455| `suppressOriginalPrompt` | 如果在 `decision` 為 `"block"` 時為 `true`,則從顯示給使用者的阻止訊息中省略原始提示文字 |1457| `suppressOriginalPrompt` | 若在 hook 阻擋提示詞時為 `true`,則會從阻擋訊息中省略提示詞文字。請參閱[被阻擋的提示詞會留下什麼](#what-a-blocked-prompt-leaves-behind) |
1456 1458
1457透過退出 2 阻止的 hook 路由方式與 `reason` 相同:阻止訊息向使用者顯示 stderr 文字,它不會新增到背景資訊。1459以退出碼 2 阻擋的 hook 與 `reason` 的處理方式相同:阻擋訊息會向使用者顯示 stderr 文字,且不會加入上下文。
1458 1460
1459```json theme={null}1461```json theme={null}
1460{1462{
1470```1472```
1471 1473
1472<h4 id="what-a-blocked-prompt-leaves-behind">1474<h4 id="what-a-blocked-prompt-leaves-behind">
1473 被阻止的提示留下什麼1475 被阻擋的提示詞會留下什麼
1474</h4>1476</h4>
1475 1477
1476被阻止的提示永遠不會到達 Claude,但其文字不會從任何地方移除。預設情況下,顯示給使用者的阻止訊息以 `Original prompt:` 結尾,後跟提交的文字,Claude Code 將該訊息寫入工作階段的文字記錄檔案。要從訊息中省略文字,請列印 JSON,其中 `hookSpecificOutput` 內有 `"suppressOriginalPrompt": true`。無論 hook 是否使用 `decision: "block"` 或退出 2 阻止,這都有效。退出 2 的 hook 如果不列印 JSON,總是在其阻止訊息中獲得提示文字。1478被阻擋的提示詞永遠不會傳達給 Claude,但其文字並不會在所有地方被移除。根據預設,向使用者顯示的阻擋訊息結尾會是 `Original prompt:` 加上送出的文字,而 Claude Code 會將該訊息寫入磁碟上工作階段的逐字稿檔案。若要從訊息中省略文字,請在 `hookSpecificOutput` 內輸出帶有 `"suppressOriginalPrompt": true` 的 JSON。無論 hook 是以 `decision: "block"` 還是以退出碼 2 阻擋,此做法都有效。未輸出 JSON 的退出碼 2 hook,其阻擋訊息一律會包含提示詞文字。
1477 1479
1478`suppressOriginalPrompt` 僅更改阻止訊息。提交的文字仍可能出現在本機檔案中,例如工作階段文字記錄和您的提示歷史記錄,因此阻止 hook 不是將秘密保留在磁碟外的方式。要限制或移除這些檔案,請參閱 [純文字儲存](/docs/zh-TW/claude-directory#plaintext-storage) 和 [清除本機資料](/docs/zh-TW/claude-directory#clear-local-data)。1480`suppressOriginalPrompt` 只會變更阻擋訊息。送出的文字仍可能出現在本機檔案中,例如工作階段逐字稿與您的提示詞歷史記錄,因此阻擋 hook 並不是讓機密不落入磁碟的方法。若要限制或移除這些檔案,請參閱[純文字儲存](/docs/zh-TW/claude-directory#plaintext-storage)與[清除本機資料](/docs/zh-TW/claude-directory#clear-local-data)。
1479 1481
1480<h3 id="userpromptexpansion">1482<h3 id="userpromptexpansion">
1481 UserPromptExpansion1483 UserPromptExpansion
1482</h3>1484</h3>
1483 1485
1484在使用者輸入的命令擴展為提示之前執行,然後到達 Claude。使用此來阻止特定命令的直接呼叫、為特定 skill 注入背景資訊,或記錄使用者呼叫的命令。例如,匹配 `deploy` 的 hook 可以阻止 `/deploy`,除非存在核准檔案,或匹配審查 skill 的 hook 可以將團隊的審查檢查清單附加為 `additionalContext`。1486在使用者輸入的命令展開為提示詞、傳達給 Claude 之前執行。可用來阻擋特定命令被直接呼叫、為特定 skill 注入上下文,或記錄使用者呼叫了哪些命令。例如,比對 `deploy` 的 hook 可以在核准檔案不存在時阻擋 `/deploy`,或比對審查 skill 的 hook 可以將團隊的審查檢查清單作為 `additionalContext` 附加。
1485 1487
1486此事件涵蓋 `PreToolUse` 不涵蓋的路徑:匹配 `Skill` 工具的 `PreToolUse` hook 僅在 Claude 呼叫工具時執行,但直接輸入 `/skillname` 會繞過 `PreToolUse`。`UserPromptExpansion` 在該直接路徑上執行。1488此事件涵蓋 `PreToolUse` 未涵蓋的路徑:比對 `Skill` 工具的 `PreToolUse` hook 只會在 Claude 呼叫該工具時觸發,但直接輸入 `/skillname` 會繞過 `PreToolUse`。`UserPromptExpansion` 會在該直接路徑上觸發。
1487 1489
1488在 `command_name` 上匹配。將匹配器留空以對每個提示類型命令執行。1490比對 `command_name`。將 matcher 留空即可在每個提示詞類型的命令上觸發。
1489 1491
1490<h4 id="userpromptexpansion-input">1492<h4 id="userpromptexpansion-input">
1491 UserPromptExpansion 輸入1493 UserPromptExpansion 輸入
1492</h4>1494</h4>
1493 1495
1494除了 [常見輸入欄位](#common-input-fields) 外,UserPromptExpansion hooks 還會接收 `expansion_type`、`command_name`、`command_args`、`command_source` 和原始 `prompt` 字串。`expansion_type` 欄位對於 skill 和自訂命令為 `slash_command`,或對於 MCP 伺服器提示為 `mcp_prompt`。1496除了[通用輸入欄位](#common-input-fields)之外,UserPromptExpansion hook 還會接收 `expansion_type`、`command_name`、`command_args`、`command_source`,以及原始的 `prompt` 字串。`expansion_type` 欄位對於 skill 與自訂命令為 `slash_command`,對於 MCP 伺服器提示詞則為 `mcp_prompt`。
1495 1497
1496```json theme={null}1498```json theme={null}
1497{1499{
1512 UserPromptExpansion 決策控制1514 UserPromptExpansion 決策控制
1513</h4>1515</h4>
1514 1516
1515`UserPromptExpansion` hooks 可以阻止擴展或新增背景資訊。所有 [JSON 輸出欄位](#json-output) 都可用。1517`UserPromptExpansion` hook 可以阻擋展開或加入上下文。所有 [JSON 輸出欄位](#json-output)都可使用。
1516 1518
1517| 欄位 | 描述 |1519| 欄位 | 說明 |
1518| :- | :- |1520| :- | :- |
1519| `decision` | `"block"` 防止命令擴展。省略以允許它繼續 |1521| `decision` | `"block"` 會阻止命令展開。省略則允許其繼續 |
1520| `reason` | 當 `decision` 為 `"block"` 時顯示給使用者 |1522| `reason` | 當 `decision` 為 `"block"` 時向使用者顯示 |
1521| `additionalContext` | 與展開的提示一起新增到 Claude 背景資訊的字串。有關詳細資訊,請參閱 [為 Claude 新增背景資訊](#add-context-for-claude) |1523| `additionalContext` | 與展開後的提示詞一同加入 Claude 上下文的字串。請參閱[為 Claude 加入上下文](#add-context-for-claude) |
1522 1524
1523透過退出 2 阻止的 hook 路由方式與 `reason` 相同:阻止訊息向使用者顯示 stderr 文字。1525以退出碼 2 阻擋的 hook 與 `reason` 的處理方式相同:阻擋訊息會向使用者顯示 stderr 文字。
1524 1526
1525```json theme={null}1527```json theme={null}
1526{1528{
1537 MessageDisplay1539 MessageDisplay
1538</h3>1540</h3>
1539 1541
1540在助手訊息流向螢幕時執行。Claude Code 分批顯示訊息:每次一批新完成的行準備好呈現時,hook 執行一次,該批行,Claude Code 在其位置呈現 hook 的替換文字。長訊息會產生多個呼叫;短訊息可能只產生一個。1542在助理訊息串流到螢幕上時執行。Claude Code 會分段顯示訊息:每當一批新完成的行準備好呈現時,hook 就會以這些行執行一次,而 Claude Code 會在其位置呈現 hook 的替換文字。長訊息會產生多次呼叫;短訊息可能只產生一次。
1541 1543
1542使用 MessageDisplay 來:1544使用 MessageDisplay 來:
1543 1545
1544* 為最小顯示去除 markdown1546* 移除 markdown 以精簡顯示
1545* 轉換 Agent SDK 應用程式向其使用者顯示的文字1547* 轉換 Agent SDK 應用程式向其使用者顯示的文字
1546* 從 Claude 的回應中編輯 API 金鑰或內部主機名稱1548* 從 Claude 的回應中遮蔽 API 金鑰或內部主機名稱
1547 1549
1548Claude Code 保持每個批次,直到您的 hook 返回,因此請保持 hook 快速。如果 hook 失敗或逾時,Claude Code 顯示原始文字。此事件的預設逾時為 10 秒;如果您的 hook 需要更多時間,請在 hook 項目中設定 `timeout` 欄位。1550Claude Code 會保留每一批內容直到您的 hook 回傳,因此請讓 hook 保持快速。如果 hook 失敗或逾時,Claude Code 會顯示原始文字。此事件的預設逾時為 10 秒;如果您的 hook 需要更多時間,請在 hook 項目中設定 `timeout` 欄位。
1549 1551
1550MessageDisplay 僅用於顯示:替換文字僅更改螢幕上呈現的內容。文字記錄和 Claude 看到的內容保持原始文字,因此 Claude 永遠看不到替換,詳細模式顯示原始文字。hook 僅接收助手訊息文字,因此工具結果和您輸入的文字呈現不變。1552MessageDisplay 僅影響顯示:替換文字只會改變螢幕上呈現的內容。逐字稿與 Claude 看到的內容會保留原始文字,因此 Claude 永遠不會看到替換內容,而詳細模式會顯示原始內容。hook 只接收助理訊息文字,因此工具結果與您輸入的文字會原樣呈現。
1551 1553
1552MessageDisplay 不支援匹配器,對每個流向文字的助手訊息執行;沒有文字的訊息(例如僅工具呼叫回應)不會觸發它。1554MessageDisplay 不支援 matcher,會對每一則串流文字的助理訊息觸發;沒有文字的訊息,例如只有工具呼叫的回應,不會觸發它。
1553 1555
1554在非互動執行中,包括 Agent SDK 查詢和 `claude -p`,MessageDisplay 每個助手訊息執行一次,而不是每批行執行一次。單個呼叫在訊息完成後到達,並攜帶完整訊息文字:`index` 為 `0`、`final` 為 `true`,`delta` 保持整個訊息。為每個訊息收集 `delta` 文字的 hook 在兩種模式中接收相同的總文字。1556在非互動式執行中,包括 Agent SDK 查詢與 `claude -p`,MessageDisplay 會針對每則助理訊息執行一次,而非每批行執行一次。這次單一呼叫會在訊息完成後送達,並攜帶完整的訊息文字:`index` 為 `0`、`final` 為 `true`,而 `delta` 包含整則訊息。為每則訊息收集 `delta` 文字的 hook,在兩種模式下都會接收到相同的完整文字。
1555 1557
1556<h4 id="messagedisplay-input">1558<h4 id="messagedisplay-input">
1557 MessageDisplay 輸入1559 MessageDisplay 輸入
1558</h4>1560</h4>
1559 1561
1560除了 [常見輸入欄位](#common-input-fields) 外,MessageDisplay hooks 還會接收回合和訊息的識別碼、此呼叫在訊息內的位置,以及 `delta` 中的新文字。批次邊界取決於文字流的方式,因此使用 `index` 和 `final` 追蹤訊息的進度,而不是期望行以特定方式分組。1562除了[通用輸入欄位](#common-input-fields)之外,MessageDisplay hook 還會接收回合與訊息的識別碼、此次呼叫在訊息中的位置,以及 `delta` 中的新文字。批次邊界取決於文字的串流方式,因此請使用 `index` 與 `final` 追蹤訊息的進度,而不要預期行會以特定方式分組。
1561 1563
1562| 欄位 | 描述 |1564| 欄位 | 說明 |
1563| :- | :- |1565| :- | :- |
1564| `turn_id` | 目前回合的 UUID |1566| `turn_id` | 目前回合的 UUID |
1565| `message_id` | 正在顯示的助手訊息的 UUID。在同一訊息的每個批次中穩定。這不是 API `msg_…` id,因此無法與文字記錄訊息 ids 相關聯 |1567| `message_id` | 正在顯示的助理訊息的 UUID。在同一則訊息的每一批中保持不變。這不是 API 的 `msg_…` id,因此無法與逐字稿的訊息 id 對應 |
1566| `index` | 此批次在訊息內的零基索引 |1568| `index` | 此批次在訊息中從零起算的索引 |
1567| `final` | 在訊息的最後一個批次上為 `true`。每個訊息恰好有一個最終批次 |1569| `final` | 在訊息的最後一批時為 `true`。每則訊息恰好有一個最後批次 |
1568| `delta` | 自上一個批次以來新完成的行,包括終止換行符。始終是完整行,除了最終批次可能在行中結束。在互動執行中,當訊息以換行符結束時,最終批次的 delta 為空,因此將 `final` 而不是非空 delta 視為訊息結束信號。在 Agent SDK 和 `claude -p` 執行中,單個呼叫攜帶整個訊息 |1570| `delta` | 自前一批以來新完成的行,包含結尾的換行字元。一律為完整的行,但最後一批可能在行中間結束。在互動式執行中,當訊息以換行字元結束時,最後一批的 delta 為空,因此請將 `final`(而非非空的 delta)視為訊息結束的訊號。在 Agent SDK 與 `claude -p` 執行中,單一呼叫會攜帶整則訊息 |
1569 1571
1570```json theme={null}1572```json theme={null}
1571{1573{
1585 MessageDisplay 輸出1587 MessageDisplay 輸出
1586</h4>1588</h4>
1587 1589
1588除了所有 hooks 可用的 [JSON 輸出欄位](#json-output) 外,MessageDisplay hooks 可以返回 `displayContent` 以替換螢幕上的 delta:1590除了所有 hook 都可使用的 [JSON 輸出欄位](#json-output)之外,MessageDisplay hook 還可以回傳 `displayContent`,以在螢幕上替換 delta:
1589 1591
1590| 欄位 | 描述 |1592| 欄位 | 說明 |
1591| :- | :- |1593| :- | :- |
1592| `displayContent` | 顯示以代替 delta 的文字。省略以顯示原始文字 |1594| `displayContent` | 取代 delta 顯示的文字。省略則顯示原始內容 |
1593 1595
1594MessageDisplay hooks 沒有決策控制。它們無法阻止訊息或更改文字記錄中儲存或傳送給 Claude 的內容。Claude Code 作用於它們的 JSON 輸出中的 `displayContent` 並捨棄 `systemMessage` 和 `continue`。1596MessageDisplay hook 沒有決策控制。它們無法阻擋訊息,也無法變更儲存在逐字稿中或傳送給 Claude 的內容。Claude Code 會依據其 JSON 輸出中的 `displayContent` 採取動作,並捨棄 `systemMessage` 與 `continue`。
1595 1597
1596此範例從 Claude 的回應中去除 markdown 格式以進行純文字顯示。指令碼從 stdin 讀取每個批次,從 `delta` 中移除粗體標記和內聯代碼反引號,並將結果作為 `displayContent` 返回。1598此範例會從 Claude 的回應中移除 markdown 格式,以純文字顯示。指令碼從 stdin 讀取每一批內容,從 `delta` 中移除粗體標記與行內程式碼反引號,並將結果以 `displayContent` 回傳。
1597 1599
1598<Tabs>1600<Tabs>
1599 <Tab title="macOS/Linux">1601 <Tab title="macOS/Linux">
1600 在您的設定檔中為事件註冊命令 hook:1602 在您的設定檔中為此事件註冊 command hook:
1601 1603
1602 ```json theme={null}1604 ```json theme={null}
1603 {1605 {
1617 }1619 }
1618 ```1620 ```
1619 1621
1620 將此指令碼儲存到您的專案中的 `.claude/hooks/plain-display.sh` 並使用 `chmod +x` 使其可執行:1622 將此指令碼儲存至專案中的 `.claude/hooks/plain-display.sh`,並以 `chmod +x` 使其可執行:
1621 1623
1622 ```bash theme={null}1624 ```bash theme={null}
1623 #!/bin/bash1625 #!/bin/bash
1626 </Tab>1628 </Tab>
1627 1629
1628 <Tab title="Windows (PowerShell)">1630 <Tab title="Windows (PowerShell)">
1629 註冊一個命令 hook,透過 PowerShell 執行指令碼:1631 註冊透過 PowerShell 執行指令碼的 command hook:
1630 1632
1631 ```json theme={null}1633 ```json theme={null}
1632 {1634 {
1652 }1654 }
1653 ```1655 ```
1654 1656
1655 `-NoProfile` 旗標跳過載入您的 PowerShell 設定檔,以便 hook 快速啟動,`-ExecutionPolicy Bypass` 讓 PowerShell 執行本機指令碼檔案。1657 `-NoProfile` 旗標會略過載入您的 PowerShell 設定檔,讓 hook 快速啟動,而 `-ExecutionPolicy Bypass` 讓 PowerShell 能執行本機指令碼檔案。
1656 1658
1657 將此指令碼儲存到您的專案中的 `.claude/hooks/plain-display.ps1`:1659 將此指令碼儲存至專案中的 `.claude/hooks/plain-display.ps1`:
1658 1660
1659 ```powershell theme={null}1661 ```powershell theme={null}
1660 $batch = [Console]::In.ReadToEnd() | ConvertFrom-Json1662 $batch = [Console]::In.ReadToEnd() | ConvertFrom-Json
1669 </Tab>1671 </Tab>
1670</Tabs>1672</Tabs>
1671 1673
1672沒有 markdown 的批次會原封不動地通過。如果指令碼失敗,例如因為 `jq` 遺失,Claude Code 顯示原始文字,並僅在 [debug output](#debug-hooks) 中記錄失敗,而不是在工作階段中。1674不含 markdown 的批次會原樣通過。如果指令碼失敗,例如因為缺少 `jq`,Claude Code 會顯示原始文字,且只在[偵錯輸出](#debug-hooks)中記錄失敗,而不會在工作階段中顯示。
1673 1675
1674<h3 id="pretooluse">1676<h3 id="pretooluse">
1675 PreToolUse1677 PreToolUse
1676</h3>1678</h3>
1677 1679
1678在 Claude 建立工具參數之後、處理工具呼叫之前執行。在除 `EndConversation` 外的任何工具名稱上匹配:內建工具,例如 `Bash`、`PowerShell`、`Edit`、`Write`、`Read`、`Glob`、`Grep`、`Agent`、`Workflow`、`WebFetch`、`WebSearch`、`AskUserQuestion` 和 `ExitPlanMode`,以及任何 [MCP 工具名稱](#match-mcp-tools)。1680在 Claude 建立工具參數之後、處理工具呼叫之前執行。比對 `EndConversation` 以外的任何工具名稱:內建工具,例如 `Bash`、`PowerShell`、`Edit`、`Write`、`Read`、`Glob`、`Grep`、`Agent`、`Workflow`、`WebFetch`、`WebSearch`、`AskUserQuestion` 與 `ExitPlanMode`,以及任何 [MCP 工具名稱](#match-mcp-tools)。
1679 1681
1680要在特定檔案在磁碟上變更時執行 hook,無論什麼寫入它,請改用 [FileChanged](#filechanged) 而不是按名稱匹配檔案編輯工具。與 PreToolUse 不同,Claude Code 在變更後執行 FileChanged hooks,它們沒有決策控制,因此無法阻止寫入。1682若要在特定檔案於磁碟上變更時執行 hook(無論由誰寫入),請使用 [FileChanged](#filechanged),而不要依名稱比對編輯檔案的工具。與 PreToolUse 不同,Claude Code 會在變更之後執行 FileChanged hook,且它們沒有決策控制,因此無法阻擋寫入。
1681 1683
1682<Warning>1684<Warning>
1683 PreToolUse 僅在 Claude 呼叫工具時執行。您在提示中 [使用 `@` 參考的檔案](/docs/zh-TW/common-workflows#reference-files-and-directories) 會被新增而不進行任何工具呼叫:Claude Code 在建立提示時插入其內容,因此沒有 PreToolUse hook 對它們執行,包括匹配 `Read` 的 hooks。要阻止特定路徑的 `@` 參考,請改用 [`Read` 拒絕規則](/docs/zh-TW/permissions#read-and-edit)。1685 PreToolUse 只會在 Claude 呼叫工具時執行。您[在提示詞中以 `@` 參照](/docs/zh-TW/common-workflows#reference-files-and-directories)的檔案會在沒有任何工具呼叫的情況下加入:Claude Code 在建構提示詞時插入其內容,因此不會為它們觸發任何 PreToolUse hook,包括比對 `Read` 的 hook。若要阻擋特定路徑被 `@` 參照,請改用 [`Read` 拒絕規則](/docs/zh-TW/permissions#read-and-edit)。
1684 1686
1685 PreToolUse 也不會對 [`EndConversation`](/docs/zh-TW/tools-reference#endconversation-tool-behavior) 執行。1687 PreToolUse 也不會為 [`EndConversation`](/docs/zh-TW/tools-reference#endconversation-tool-behavior) 觸發。
1686</Warning>1688</Warning>
1687 1689
1688使用 [PreToolUse 決策控制](#pretooluse-decision-control) 來允許、拒絕、詢問或延遲工具呼叫。1690使用 [PreToolUse 決策控制](#pretooluse-decision-control)來允許、拒絕、詢問或延後工具呼叫。
1689 1691
1690在 `PreToolUse` 上超過逾時的 [Agent SDK 回呼 hook](/docs/zh-TW/agent-sdk/hooks) 會阻止工具呼叫,Claude 會收到命名逾時的錯誤結果。另一個 hook 返回的明確拒絕仍然優先。1692`PreToolUse` 上超過逾時的 [Agent SDK 回呼 hook](/docs/zh-TW/agent-sdk/hooks) 會阻擋工具呼叫,而 Claude 會收到指出該逾時的錯誤結果。其他 hook 回傳的明確拒絕仍優先於此。
1691 1693
1692<h4 id="pretooluse-input">1694<h4 id="pretooluse-input">
1693 PreToolUse 輸入1695 PreToolUse 輸入
1694</h4>1696</h4>
1695 1697
1696除了 [常見輸入欄位](#common-input-fields) 外,PreToolUse hooks 還會接收 `tool_name`、`tool_input` 和 `tool_use_id`。1698除了[通用輸入欄位](#common-input-fields)之外,PreToolUse hook 還會接收 `tool_name`、`tool_input` 與 `tool_use_id`。
1697 1699
1698對於 [MCP 工具](#match-mcp-tools),輸入還攜帶 `mcp_server`,一個具有伺服器 `name` 和 `source` 的物件,說明伺服器定義的來源。`source` 值包括 `plugin`、`sdk` 和配置範圍,例如 `user` 和 `project`。[Agent SDK 參考中的 `McpServerProvenance`](/docs/zh-TW/agent-sdk/typescript#mcpserverprovenance) 列出它們全部並說明如何處理您不認識的。基於 `source` 而不是 `name` 或 `mcp__<server>__` 工具名稱前綴做出信任決定。`mcp_server` 欄位需要 Claude Code v2.1.274 或更新版本。1700對於 [MCP 工具](#match-mcp-tools),輸入還會攜帶 `mcp_server`,這是一個包含伺服器 `name` 以及 `source` 的物件,`source` 說明伺服器的定義來自何處。`source` 值包括 `plugin`、`sdk`,以及 `user` 與 `project` 等設定範圍。Agent SDK 參考文件中的 [`McpServerProvenance`](/docs/zh-TW/agent-sdk/typescript#mcpserverprovenance) 列出了所有值,並說明如何處理無法辨識的值。請依據 `source` 而非 `name` 或 `mcp__<server>__` 工具名稱前綴做出信任決策。`mcp_server` 欄位需要 Claude Code v2.1.274 或更新版本。
1699 1701
1700對於檔案工具 `Write`、`Edit` 和 `Read`,`tool_input.file_path` 始終是絕對的:1702對於檔案工具 `Write`、`Edit` 與 `Read`,`tool_input.file_path` 一律為絕對路徑:
1701 1703
1702* Claude Code 在 hooks 執行之前展開 `~` 和相對路徑,因此匹配路徑的 hook 無法透過 `~` 或相同路徑的相對拼寫繞過1704* Claude Code 會在 hook 執行之前展開 `~` 與相對路徑,因此比對路徑的 hook 無法透過 `~` 或同一路徑的相對寫法被繞過
1703* 在 Windows 上,路徑到達時帶有反斜線分隔符,即使您的 hook 在 Git Bash 下執行,其中 `$PWD` 看起來像 `/c/project`1705* 在 Windows 上,路徑會以反斜線分隔符號傳入,即使您的 hook 在 Git Bash 下執行、其中 `$PWD` 看起來像 `/c/project` 也是如此
1704* 使用正斜線編寫的比較,例如 `/src/` 檢查,永遠不會匹配反斜線路徑,工具呼叫會如同 hook 沒有要阻止的內容一樣進行1706* 以正斜線撰寫的比較,例如 `/src/` 檢查,永遠不會與反斜線路徑相符,工具呼叫會如同 hook 沒有可阻擋的內容般繼續
1705* 在比較之前規範化分隔符:Bash 中的 `FILE_PATH="${FILE_PATH//\\//}"` 或 Python 中的 `file_path.replace("\\", "/")`,然後匹配路徑段,例如 `/src/`,而不是使用 `^` 錨定,因為路徑是絕對的1707* 請在比較前將分隔符號正規化:在 Bash 中使用 `FILE_PATH="${FILE_PATH//\\//}"`,在 Python 中使用 `file_path.replace("\\", "/")`,然後比對路徑片段,例如 `/src/`,而不要以 `^` 錨定,因為路徑是絕對路徑
1706 1708
1707Windows 上的 `Write` 呼叫傳遞:1709Windows 上的 `Write` 呼叫會傳遞:
1708 1710
1709```json theme={null}1711```json theme={null}
1710{1712{
1728 1730
1729執行 shell 命令。1731執行 shell 命令。
1730 1732
1731| 欄位 | 類型 | 範例 | 描述 |1733| 欄位 | 類型 | 範例 | 說明 |
1732| :- | :- | :- | :- |1734| :- | :- | :- | :- |
1733| `command` | string | `"npm test"` | 要執行的 shell 命令 |1735| `command` | string | `"npm test"` | 要執行的 shell 命令 |
1734| `description` | string | `"Run test suite"` | 命令執行內容的可選描述 |1736| `description` | string | `"Run test suite"` | 選擇性的命令用途說明 |
1735| `timeout` | number | `120000` | 可選逾時(毫秒)。高於 [最大值](/docs/zh-TW/tools-reference#bash-tool-behavior) 的值會減少到最大值,而不是被拒絕 |1737| `timeout` | number | `120000` | 選擇性的逾時(毫秒)。超過[上限](/docs/zh-TW/tools-reference#bash-tool-behavior)的值會被降為上限,而不會被拒絕 |
1736| `run_in_background` | boolean | `false` | 是否在背景執行命令 |1738| `run_in_background` | boolean | `false` | 是否在背景執行命令 |
1737 1739
1738當 Bash 命令更改 Git 儲存庫中的檔案時,Claude Code 可以記錄變更的內容。當 [`bashEditDiffEnabled`](/docs/zh-TW/settings-reference#basheditdiffenabled) 設定打開記錄時,它在每個權限模式中記錄它們;該設定的項目說明哪些檔案可以設定它。否則,它僅在自動模式和 `bypassPermissions` 模式中記錄它們,並且僅當 Claude Code 指導 Claude 透過 Bash 編輯檔案時。設定 `bashEditDiffEnabled` 為 `false` 以關閉記錄。背景命令和唯讀命令不攜帶 diff。1740當 Bash 命令變更 Git 儲存庫中的檔案時,Claude Code 可以記錄變更內容。當 [`bashEditDiffEnabled`](/docs/zh-TW/settings-reference#basheditdiffenabled) 設定開啟記錄時,它會在每種權限模式下記錄變更;該設定的項目說明了哪些檔案可以設定它。否則,它只會在自動模式與 `bypassPermissions` 模式下記錄,且僅在 Claude Code 指示 Claude 透過 Bash 編輯檔案時記錄。將 `bashEditDiffEnabled` 設為 `false` 即可關閉記錄。背景命令與唯讀命令不會攜帶差異。
1739 1741
1740您的 [PostToolUse hook](#posttooluse) 然後在 `tool_response.bashEditDiff` 中接收變更的檔案。該清單涵蓋命令執行時在儲存庫下變更的內容。Git 忽略的檔案和子模組中的檔案不會列出。需要 Claude Code v2.1.269 或更新版本。1742接著,您的 [PostToolUse hook](#posttooluse) 會在 `tool_response.bashEditDiff` 中接收已變更的檔案。清單涵蓋命令執行期間儲存庫下的變更。Git 忽略的檔案與子模組中的檔案不會列出。需要 Claude Code v2.1.269 或更新版本。
1741 1743
1742<Note>1744<Note>
1743 該清單是盡力而為的,處於公開測試版。Claude Code 可能會遺漏變更、包含另一個程序同時變更的檔案,或在其大小限制處停止。欄位形狀可能會變更。使用該清單找到要審查的內容,而不是強制執行原則。1745 此清單為盡力而為,且處於公開測試版。Claude Code 可能遺漏變更、包含同時被其他程序變更的檔案,或在達到大小限制時停止。欄位結構可能會變更。請使用此清單找出需要審查的內容,而不要用來強制執行政策。
1744</Note>1746</Note>
1745 1747
1746`changedFiles` 和 `files` 列出命令變更的內容;其餘欄位說明該清單的完整性和可靠性。1748`changedFiles` 與 `files` 列出命令變更的內容;其餘欄位說明該清單的完整程度與可靠程度。
1747 1749
1748| 欄位 | 類型 | 範例 | 描述 |1750| 欄位 | 類型 | 範例 | 說明 |
1749| :- | :- | :- | :- |1751| :- | :- | :- | :- |
1750| `changedFiles` | array | `["/path/to/src/app.ts"]` | 命令變更的檔案的絕對路徑,最多 200 個。每當 `files` 保持 diff 或 `moreFiles` 高於零時出現 |1752| `changedFiles` | array | `["/path/to/src/app.ts"]` | 命令變更的檔案絕對路徑,最多 200 個。只要 `files` 包含差異或 `moreFiles` 大於零就會出現 |
1751| `files` | array | `[{"filePath": "/path/to/src/app.ts", "hunks": [...]}]` | 最多 5 個變更檔案的 diffs,用於顯示。對於命令新增或移除的檔案,`created` 或 `deleted` 為 `true` |1753| `files` | array | `[{"filePath": "/path/to/src/app.ts", "hunks": [...]}]` | 最多 5 個已變更檔案的差異,供顯示用。對於命令新增或移除的檔案,`created` 或 `deleted` 為 `true` |
1752| `moreFiles` | number | `2` | 在 `files` 中沒有 diff 的變更檔案計數 |1754| `moreFiles` | number | `2` | 在 `files` 中沒有差異的已變更檔案數 |
1753| `unavailable` | boolean | `true` | 當 diff 不完整或無法取得時設定 |1755| `unavailable` | boolean | `true` | 當差異不完整或無法取得時設定 |
1754| `skipped` | boolean | `true` | 對於移動工作樹的 Git 命令設定,例如 `git checkout` 或 `git stash`,因此 Claude Code 不取 diff |1756| `skipped` | boolean | `true` | 針對會移動工作樹的 Git 命令設定,例如 `git checkout` 或 `git stash`,因此 Claude Code 不會取得差異 |
1755| `shared` | boolean | `true` | 當另一個 Bash 工具呼叫(例如子代理的)同時在同一儲存庫中執行時設定,因此某些列出的變更可能是該命令的 |1757| `shared` | boolean | `true` | 當另一個 Bash 工具呼叫(例如 subagent 的呼叫)同時在同一個儲存庫中執行時設定,因此部分列出的變更可能來自該命令 |
1756 1758
1757<a id="powershell" />1759<a id="powershell" />
1758 1760
1760 PowerShell1762 PowerShell
1761</h5>1763</h5>
1762 1764
1763執行 PowerShell 命令。有關按平台的可用性,請參閱 [PowerShell 工具](/docs/zh-TW/tools-reference#powershell-tool)。1765執行 PowerShell 命令。關於各平台的可用性,請參閱 [PowerShell 工具](/docs/zh-TW/tools-reference#powershell-tool)。
1764 1766
1765欄位與 Bash 工具匹配,命令字串在 `command` 中:1767欄位與 Bash 工具相同,命令字串位於 `command`:
1766 1768
1767| 欄位 | 類型 | 範例 | 描述 |1769| 欄位 | 類型 | 範例 | 說明 |
1768| :- | :- | :- | :- |1770| :- | :- | :- | :- |
1769| `command` | string | `"Get-ChildItem -Recurse"` | 要執行的 PowerShell 命令 |1771| `command` | string | `"Get-ChildItem -Recurse"` | 要執行的 PowerShell 命令 |
1770| `description` | string | `"List files recursively"` | 命令執行內容的可選描述 |1772| `description` | string | `"List files recursively"` | 選擇性的命令用途說明 |
1771| `timeout` | number | `120000` | 可選逾時(毫秒) |1773| `timeout` | number | `120000` | 選擇性的逾時(毫秒) |
1772| `run_in_background` | boolean | `false` | 是否在背景執行命令 |1774| `run_in_background` | boolean | `false` | 是否在背景執行命令 |
1773 1775
1774在檢查 shell 命令的 hooks 中匹配 `Bash|PowerShell`,以便它們涵蓋兩個工具:1776在檢查 shell 命令的 hook 中請比對 `Bash|PowerShell`,以涵蓋兩種工具:
1775 1777
1776* 在 Windows 上,無論 PowerShell 工具是否啟用,Claude 將 PowerShell 視為主要 shell 並透過它路由 shell 命令。1778* 在 Windows 上,只要啟用了 PowerShell 工具,Claude 就會將 PowerShell 視為主要 shell,並透過它執行 shell 命令。
1777* 在沒有 Git Bash 的 Windows 上,工具會自動啟用,Claude Code 根本不註冊 Bash 工具。1779* 在沒有 Git Bash 的 Windows 上,該工具會自動啟用,而 Claude Code 完全不會註冊 Bash 工具。
1778* 僅匹配 `Bash` 的 hook 永遠不會在那裡執行。1780* 只比對 `Bash` 的 hook 在那裡永遠不會觸發。
1779 1781
1780<h5 id="write">1782<h5 id="write">
1781 Write1783 Write
1783 1785
1784建立或覆寫檔案。1786建立或覆寫檔案。
1785 1787
1786| 欄位 | 類型 | 範例 | 描述 |1788| 欄位 | 類型 | 範例 | 說明 |
1787| :- | :- | :- | :- |1789| :- | :- | :- | :- |
1788| `file_path` | string | `"/path/to/file.txt"` | 要寫入的檔案的絕對路徑 |1790| `file_path` | string | `"/path/to/file.txt"` | 要寫入的檔案絕對路徑 |
1789| `content` | string | `"file content"` | 要寫入檔案的內容 |1791| `content` | string | `"file content"` | 要寫入檔案的內容 |
1790 1792
1791<h5 id="edit">1793<h5 id="edit">
1792 Edit1794 Edit
1793</h5>1795</h5>
1794 1796
1795替換現有檔案中的字串。1797取代現有檔案中的字串。
1796 1798
1797| 欄位 | 類型 | 範例 | 描述 |1799| 欄位 | 類型 | 範例 | 說明 |
1798| :- | :- | :- | :- |1800| :- | :- | :- | :- |
1799| `file_path` | string | `"/path/to/file.txt"` | 要編輯的檔案的絕對路徑 |1801| `file_path` | string | `"/path/to/file.txt"` | 要編輯的檔案絕對路徑 |
1800| `old_string` | string | `"original text"` | 要尋找和替換的文字 |1802| `old_string` | string | `"original text"` | 要尋找並取代的文字 |
1801| `new_string` | string | `"replacement text"` | 替換文字 |1803| `new_string` | string | `"replacement text"` | 取代文字 |
1802| `replace_all` | boolean | `false` | 是否替換所有出現次數 |1804| `replace_all` | boolean | `false` | 是否取代所有出現處 |
1803 1805
1804<h5 id="read">1806<h5 id="read">
1805 Read1807 Read
1807 1809
1808讀取檔案內容。1810讀取檔案內容。
1809 1811
1810| 欄位 | 類型 | 範例 | 描述 |1812| 欄位 | 類型 | 範例 | 說明 |
1811| :- | :- | :- | :- |1813| :- | :- | :- | :- |
1812| `file_path` | string | `"/path/to/file.txt"` | 要讀取的檔案的絕對路徑 |1814| `file_path` | string | `"/path/to/file.txt"` | 要讀取的檔案絕對路徑 |
1813| `offset` | number | `10` | 可選的開始讀取的行號 |1815| `offset` | number | `10` | 選擇性的起始讀取行號 |
1814| `limit` | number | `50` | 可選的要讀取的行數 |1816| `limit` | number | `50` | 選擇性的讀取行數 |
1815 1817
1816<h5 id="glob">1818<h5 id="glob">
1817 Glob1819 Glob
1818</h5>1820</h5>
1819 1821
1820尋找與 glob 模式匹配的檔案。1822尋找符合 glob 模式的檔案。
1821 1823
1822| 欄位 | 類型 | 範例 | 描述 |1824| 欄位 | 類型 | 範例 | 說明 |
1823| :- | :- | :- | :- |1825| :- | :- | :- | :- |
1824| `pattern` | string | `"**/*.ts"` | 要匹配檔案的 Glob 模式 |1826| `pattern` | string | `"**/*.ts"` | 用來比對檔案的 glob 模式 |
1825| `path` | string | `"/path/to/dir"` | 可選的要搜尋的目錄。預設為目前工作目錄 |1827| `path` | string | `"/path/to/dir"` | 選擇性的搜尋目錄。預設為目前工作目錄 |
1826 1828
1827<h5 id="grep">1829<h5 id="grep">
1828 Grep1830 Grep
1829</h5>1831</h5>
1830 1832
1831使用正規表達式搜尋檔案內容。1833以規則運算式搜尋檔案內容。
1832 1834
1833| 欄位 | 類型 | 範例 | 描述 |1835| 欄位 | 類型 | 範例 | 說明 |
1834| :- | :- | :- | :- |1836| :- | :- | :- | :- |
1835| `pattern` | string | `"TODO.*fix"` | 要搜尋的正規表達式模式 |1837| `pattern` | string | `"TODO.*fix"` | 要搜尋的規則運算式模式 |
1836| `path` | string | `"/path/to/dir"` | 可選的要搜尋的檔案或目錄 |1838| `path` | string | `"/path/to/dir"` | 選擇性的搜尋檔案或目錄 |
1837| `glob` | string | `"*.ts"` | 可選的 glob 模式以篩選檔案 |1839| `glob` | string | `"*.ts"` | 選擇性的檔案篩選 glob 模式 |
1838| `output_mode` | string | `"content"` | `"content"`、`"files_with_matches"` 或 `"count"`。預設為 `"files_with_matches"` |1840| `output_mode` | string | `"content"` | `"content"`、`"files_with_matches"` 或 `"count"`。預設為 `"files_with_matches"` |
1839| `-i` | boolean | `true` | 不區分大小寫的搜尋 |1841| `-i` | boolean | `true` | 不區分大小寫搜尋 |
1840| `multiline` | boolean | `false` | 啟用多行匹配 |1842| `multiline` | boolean | `false` | 啟用多行比對 |
1841 1843
1842<h5 id="webfetch">1844<h5 id="webfetch">
1843 WebFetch1845 WebFetch
1844</h5>1846</h5>
1845 1847
1846擷取和處理網路內容。1848擷取並處理網頁內容。
1847 1849
1848| 欄位 | 類型 | 範例 | 描述 |1850| 欄位 | 類型 | 範例 | 說明 |
1849| :- | :- | :- | :- |1851| :- | :- | :- | :- |
1850| `url` | string | `"https://example.com/api"` | 要擷取內容的 URL |1852| `url` | string | `"https://example.com/api"` | 要擷取內容的 URL |
1851| `prompt` | string | `"Extract the API endpoints"` | 在擷取的內容上執行的提示 |1853| `prompt` | string | `"Extract the API endpoints"` | 要對擷取內容執行的提示詞 |
1852 1854
1853<h5 id="websearch">1855<h5 id="websearch">
1854 WebSearch1856 WebSearch
1856 1858
1857搜尋網路。1859搜尋網路。
1858 1860
1859| 欄位 | 類型 | 範例 | 描述 |1861| 欄位 | 類型 | 範例 | 說明 |
1860| :- | :- | :- | :- |1862| :- | :- | :- | :- |
1861| `query` | string | `"react hooks best practices"` | 搜尋查詢 |1863| `query` | string | `"react hooks best practices"` | 搜尋查詢 |
1862| `allowed_domains` | array | `["docs.example.com"]` | 可選:僅包含來自這些網域的結果 |1864| `allowed_domains` | array | `["docs.example.com"]` | 選擇性:只包含來自這些網域的結果 |
1863| `blocked_domains` | array | `["spam.example.com"]` | 可選:排除來自這些網域的結果 |1865| `blocked_domains` | array | `["spam.example.com"]` | 選擇性:排除來自這些網域的結果 |
1864 1866
1865<h5 id="agent">1867<h5 id="agent">
1866 Agent1868 Agent
1867</h5>1869</h5>
1868 1870
1869生成 [子代理](/docs/zh-TW/sub-agents)。1871產生一個 [subagent](/docs/zh-TW/sub-agents)。
1870 1872
1871| 欄位 | 類型 | 範例 | 描述 |1873| 欄位 | 類型 | 範例 | 說明 |
1872| :- | :- | :- | :- |1874| :- | :- | :- | :- |
1873| `prompt` | string | `"Find all API endpoints"` | 代理要執行的任務 |1875| `prompt` | string | `"Find all API endpoints"` | agent 要執行的任務 |
1874| `description` | string | `"Find API endpoints"` | 任務的簡短描述 |1876| `description` | string | `"Find API endpoints"` | 任務的簡短說明 |
1875| `subagent_type` | string | `"Explore"` | 要使用的專門代理類型 |1877| `subagent_type` | string | `"Explore"` | 要使用的專門 agent 類型 |
1876| `model` | string | `"sonnet"` | 可選的模型別名以覆寫預設值 |1878| `model` | string | `"sonnet"` | 選擇性的模型別名,用以覆寫預設值 |
1877 1879
1878當前景 Agent 呼叫完成時,您的 [PostToolUse hook](#posttooluse) 在 `tool_response` 中接收子代理的結果和執行遙測。讀取這些欄位以檢查執行;對於跨子代理的權杖和成本匯總,使用 [權杖和成本計數器](/docs/zh-TW/monitoring-usage#token-counter),篩選為 `query_source` `"subagent"`,因為 `totalTokens` 和 `usage` 僅涵蓋最終請求:1880當前景 Agent 呼叫完成時,您的 [PostToolUse hook](#posttooluse) 會在 `tool_response` 中接收 subagent 的結果與執行遙測。請讀取這些欄位來檢視執行情況;若要彙總各 subagent 的 token 與成本,請使用以 `query_source` `"subagent"` 篩選的 [token 與成本計數器](/docs/zh-TW/monitoring-usage#token-counter),因為 `totalTokens` 與 `usage` 只涵蓋最後一個請求:
1879 1881
1880| 欄位 | 類型 | 範例 | 描述 |1882| 欄位 | 類型 | 範例 | 說明 |
1881| :- | :- | :- | :- |1883| :- | :- | :- | :- |
1882| `status` | string | `"completed"` | 前景 subagent 為 `"completed"`,背景 subagent 為 `"async_launched"`。subagent 預設在背景執行,因此省略 `run_in_background` 的 Agent 呼叫也會產生 `"async_launched"` |1884| `status` | string | `"completed"` | 前景 subagent 為 `"completed"`,背景 subagent 為 `"async_launched"`。subagent 預設在背景執行,因此省略 `run_in_background` 的 Agent 呼叫也會產生 `"async_launched"` |
1883| `agentId` | string | `"a4d2c8f1e0b3a297"` | 子代理執行的識別碼 |1885| `agentId` | string | `"a4d2c8f1e0b3a297"` | subagent 執行的識別碼 |
1884| `content` | array | `[{"type": "text", "text": "Found 12 endpoints..."}]` | 子代理的最終文字區塊,或對於其報告透過 `SubagentHandback` 的子代理,關於該交接的簡短說明代替 |1886| `content` | array | `[{"type": "text", "text": "Found 12 endpoints..."}]` | subagent 最終的文字區塊;若 subagent 的報告是透過 `SubagentHandback` 傳遞,則改為關於該交回的簡短說明 |
1885| `resolvedModel` | string | `"claude-sonnet-4-5"` | 子代理啟動的模型,可能與請求的模型不同 |1887| `resolvedModel` | string | `"claude-sonnet-4-5"` | subagent 開始時使用的模型,可能與所請求的模型不同 |
1886| `modelsUsed` | array | `["claude-sonnet-4-5", "claude-haiku-4-5"]` | 按順序使用的模型,連續重複折疊;僅在模型在執行中交換時設定。需要 Claude Code v2.1.212 或更新版本 |1888| `modelsUsed` | array | `["claude-sonnet-4-5", "claude-haiku-4-5"]` | 依序使用的模型,連續重複的項目會合併;僅在執行途中切換模型時設定。需要 Claude Code v2.1.212 或更新版本 |
1887| `totalTokens` | number | `12450` | 子代理最終 API 請求的權杖計數:輸入、輸出和快取權杖合併。這不是整個執行的總計 |1889| `totalTokens` | number | `12450` | subagent 最後一個 API 請求的 token 數:輸入、輸出與快取 token 的總和。這並非整個執行的總計 |
1888| `totalDurationMs` | number | `48211` | 子代理執行的牆上時間持續時間 |1890| `totalDurationMs` | number | `48211` | subagent 執行的實際時間長度 |
1889| `totalToolUseCount` | number | `7` | 子代理進行的工具呼叫計數 |1891| `totalToolUseCount` | number | `7` | subagent 進行的工具呼叫次數 |
1890| `usage` | object | `{"input_tokens": 8320, ...}` | 最終 API 請求的每類型權杖細目:`input_tokens`、`output_tokens`、`cache_creation_input_tokens`、`cache_read_input_tokens` |1892| `usage` | object | `{"input_tokens": 8320, ...}` | 最後一個 API 請求依類型的 token 明細:`input_tokens`、`output_tokens`、`cache_creation_input_tokens`、`cache_read_input_tokens` |
1891 1893
1892在 Claude Code v2.1.271 或更新版本上,使用 [`SubagentHandback`](/docs/zh-TW/tools-reference) 工具執行的子代理(Claude Code 在 [自動模式](/docs/zh-TW/permission-modes#eliminate-prompts-with-auto-mode) 中提供)透過該工具傳遞其報告,而不是將其作為文字返回。其 `completed` 結果的 `content` 欄位然後攜帶關於該交接的簡短說明,而不是報告本身。要讀取報告,匹配 `PreToolUse` 或 `PostToolUse` hook 在 `SubagentHandback` 上並讀取 `tool_input.message`。1894在 Claude Code v2.1.271 或更新版本中,使用 [`SubagentHandback`](/docs/zh-TW/tools-reference) 工具(Claude Code 在[自動模式](/docs/zh-TW/permission-modes#eliminate-prompts-with-auto-mode)中提供)執行的 subagent,會透過該工具傳遞其報告,而非以文字回傳。此時其 `completed` 結果的 `content` 欄位攜帶的是關於該交回的簡短說明,而非報告本身。若要讀取報告,請讓 `PreToolUse` 或 `PostToolUse` hook 比對 `SubagentHandback`,並讀取 `tool_input.message`。
1893 1895
1894對於背景子代理,工具在任務移到背景時返回,因此 `tool_response` 不攜帶使用欄位:背景啟動立即返回,前景任務在該轉換時由 Claude Code 背景化返回。它有 `status: "async_launched"`、`agentId`、`description`、`prompt`、`outputFile` 和 `resolvedModel`。1896對於背景 subagent,工具會在任務移至背景時回傳,因此 `tool_response` 不攜帶使用量欄位:背景啟動會立即回傳,而 Claude Code 在執行途中移至背景的前景任務則會在該轉換時回傳。它包含 `status: "async_launched"`、`agentId`、`description`、`prompt`、`outputFile` 與 `resolvedModel`。
1895 1897
1896在 `completed` 回應上,`resolvedModel` 命名子代理啟動的模型,可能與 `tool_input` 中的 `model` 值不同,例如當 `availableModels` 或另一個覆寫適用時。在 `async_launched` 回應上,`resolvedModel` 命名代理移到背景時使用的模型,因此在背景化之前發生的交換會反映在那裡。`modelsUsed` 和背景化時間 `resolvedModel` 行為需要 Claude Code v2.1.212 或更新版本。1898在 `completed` 回應中,`resolvedModel` 指出 subagent 開始時使用的模型,可能與 `tool_input` 中的 `model` 值不同,例如套用了 `availableModels` 或其他覆寫時。在 `async_launched` 回應中,`resolvedModel` 指出 agent 移至背景時使用中的模型,因此在移至背景之前發生的切換會反映在此。`modelsUsed` 以及移至背景時的 `resolvedModel` 行為需要 Claude Code v2.1.212 或更新版本。
1897 1899
1898<a id="askuserquestion" />1900<a id="askuserquestion" />
1899 1901
1901 AskUserQuestion1903 AskUserQuestion
1902</h5>1904</h5>
1903 1905
1904詢問使用者一到四個多選題。1906向使用者詢問一到四個選擇題。
1905 1907
1906| 欄位 | 類型 | 範例 | 描述 |1908| 欄位 | 類型 | 範例 | 說明 |
1907| :- | :- | :- | :- |1909| :- | :- | :- | :- |
1908| `questions` | array | `[{"question": "Which framework?", "header": "Framework", "options": [{"label": "React"}], "multiSelect": false}]` | 要呈現的問題,每個都有 `question` 字串、簡短 `header`、`options` 陣列和可選的 `multiSelect` 旗標 |1910| `questions` | array | `[{"question": "Which framework?", "header": "Framework", "options": [{"label": "React"}], "multiSelect": false}]` | 要呈現的問題,每個問題包含 `question` 字串、簡短的 `header`、`options` 陣列,以及選擇性的 `multiSelect` 旗標 |
1909| `answers` | object | `{"Which framework?": "React"}` | 可選。將問題文字對應到選定的選項標籤。多選答案用逗號連接標籤。Claude 不設定此欄位;透過 `updatedInput` 提供它以以程式設計方式回答 |1911| `answers` | object | `{"Which framework?": "React"}` | 選擇性。將問題文字對應到所選選項的標籤。多選答案會以逗號連接標籤。Claude 不會設定此欄位;請透過 `updatedInput` 提供,以程式化方式作答 |
1910 1912
1911<h5 id="exitplanmode">1913<h5 id="exitplanmode">
1912 ExitPlanMode1914 ExitPlanMode
1913</h5>1915</h5>
1914 1916
1915呈現計畫並要求使用者在 Claude 離開 [plan mode](/docs/zh-TW/permission-modes#analyze-before-you-edit-with-plan-mode) 之前核准它。Claude 在呼叫工具之前將計畫寫入磁碟上的檔案,因此來自模型的字面 `tool_input` 通常是空的。Claude Code 在將輸入傳遞給 hooks 之前注入計畫內容和檔案路徑。1917在 Claude 離開 [plan mode](/docs/zh-TW/permission-modes#analyze-before-you-edit-with-plan-mode) 之前呈現計畫並請使用者核准。Claude 在呼叫工具之前會將計畫寫入磁碟上的檔案,因此來自模型的原始 `tool_input` 通常為空。Claude Code 會在將輸入傳遞給 hook 之前注入計畫內容與檔案路徑。
1916 1918
1917| 欄位 | 類型 | 範例 | 描述 |1919| 欄位 | 類型 | 範例 | 說明 |
1918| :- | :- | :- | :- |1920| :- | :- | :- | :- |
1919| `plan` | string | `"## Refactor auth\n1. Extract..."` | Markdown 中的計畫內容。從磁碟上的計畫檔案注入 |1921| `plan` | string | `"## Refactor auth\n1. Extract..."` | Markdown 格式的計畫內容。從磁碟上的計畫檔案注入 |
1920| `planFilePath` | string | `"/Users/.../plans/refactor-auth.md"` | 計畫檔案的路徑。注入 |1922| `planFilePath` | string | `"/Users/.../plans/refactor-auth.md"` | 計畫檔案的路徑。為注入值 |
1921| `allowedPrompts` | array | `[{"tool": "Bash", "prompt": "run tests"}]` | 已棄用。Claude Code 接受欄位但忽略它。在 v2.1.205 之前,它攜帶 Claude 請求實施計畫的基於提示的權限 |1923| `allowedPrompts` | array | `[{"tool": "Bash", "prompt": "run tests"}]` | 已棄用。Claude Code 接受此欄位但會忽略它。在 v2.1.205 之前,它攜帶 Claude 為實作計畫而請求的提示詞式權限 |
1922 1924
1923在 `PostToolUse` 中,`tool_response` 是一個物件,具有 `plan` 和 `filePath` 欄位,保持核准的計畫,加上內部狀態旗標。讀取 `tool_response.plan` 以獲取計畫內容,而不是從磁碟重新讀取檔案。1925在 `PostToolUse` 中,`tool_response` 是一個物件,包含存放已核准計畫的 `plan` 與 `filePath` 欄位,以及內部狀態旗標。請讀取 `tool_response.plan` 取得計畫內容,而不要從磁碟重新讀取檔案。
1924 1926
1925<h4 id="pretooluse-decision-control">1927<h4 id="pretooluse-decision-control">
1926 PreToolUse 決策控制1928 PreToolUse 決策控制
1927</h4>1929</h4>
1928 1930
1929`PreToolUse` hooks 可以控制工具呼叫是否進行。與使用頂級 `decision` 欄位的其他 hooks 不同,PreToolUse 在 `hookSpecificOutput` 物件內返回其決定。這給了它更豐富的控制:四個結果(允許、拒絕、詢問或延遲)加上在執行前修改工具輸入的能力。1931`PreToolUse` hook 可以控制工具呼叫是否繼續。與其他使用頂層 `decision` 欄位的 hook 不同,PreToolUse 會在 `hookSpecificOutput` 物件內回傳其決策。這賦予它更豐富的控制:四種結果(允許、拒絕、詢問或延後),以及在執行前修改工具輸入的能力。
1930 1932
1931| 欄位 | 描述 |1933| 欄位 | 說明 |
1932| :- | :- |1934| :- | :- |
1933| `permissionDecision` | `"allow"` 跳過權限提示,除了 [任何模式自動核准的動作](/docs/zh-TW/permission-modes#actions-no-mode-auto-approves) 和 `AskUserQuestion` 和 `ExitPlanMode`,它們需要 [`updatedInput` 與它配對](#allow-with-updatedinput)。`"deny"` 防止工具呼叫。`"ask"` 提示使用者確認。`"defer"` 優雅地退出,以便稍後可以恢復工具。[拒絕和詢問規則](/docs/zh-TW/permissions#manage-permissions) 無論 hook 返回什麼都會被評估 |1935| `permissionDecision` | `"allow"` 會略過權限提示,但[任何模式都不會自動核准的動作](/docs/zh-TW/permission-modes#actions-no-mode-auto-approves),以及需要[搭配 `updatedInput`](#allow-with-updatedinput) 的 `AskUserQuestion` 與 `ExitPlanMode` 除外。`"deny"` 會阻止工具呼叫。`"ask"` 會提示使用者確認。`"defer"` 會正常結束,以便稍後繼續執行該工具。無論 hook 回傳什麼,[拒絕與詢問規則](/docs/zh-TW/permissions#manage-permissions)仍會被評估 |
1934| `permissionDecisionReason` | 對於 `"ask"`,顯示給使用者但不顯示 Claude。對於 `"deny"`,顯示給 Claude。對於 `"allow"` 和 `"defer"`,寫入 [debug log](#debug-hooks) 僅 |1936| `permissionDecisionReason` | 對於 `"ask"`,會在權限提示中向使用者顯示。當 Claude Code 在無人能回應該提示的 `-p` 執行中[拒絕呼叫](/docs/zh-TW/headless#turn-off-permission-prompts-in-unattended-runs)時,Claude 會改在工具結果中讀取該原因。對於 `"deny"`,會向 Claude 顯示。對於 `"allow"` 與 `"defer"`,只會寫入[偵錯日誌](#debug-hooks) |
1935| `updatedInput` | 在執行前修改工具的輸入參數。替換整個輸入物件,因此在修改的欄位旁邊包含未變更的欄位。Claude Code 根據您的 hook 返回的輸入評估權限規則和 Bash 命令的 [自動背景資格](/docs/zh-TW/tools-reference#foreground-commands-that-move-to-the-background),而不是 Claude 傳送的輸入。與 `"allow"` 結合以自動核准,或與 `"ask"` 結合以向使用者顯示修改的輸入。對於 `"defer"`,忽略 |1937| `updatedInput` | 在執行前修改工具的輸入參數。會取代整個輸入物件,因此請將未變更的欄位與修改後的欄位一併包含。Claude Code 會針對您的 hook 回傳的輸入(而非 Claude 傳送的輸入)評估權限規則以及 Bash 命令的[自動移至背景資格](/docs/zh-TW/tools-reference#foreground-commands-that-move-to-the-background)。與 `"allow"` 搭配可自動核准,或與 `"ask"` 搭配以向使用者顯示修改後的輸入。對於 `"defer"` 則會被忽略 |
1936| `additionalContext` | 與工具結果一起新增到 Claude 背景資訊的字串。當 `permissionDecision` 為 `"defer"` 時忽略。有關詳細資訊,請參閱 [為 Claude 新增背景資訊](#add-context-for-claude) |1938| `additionalContext` | 與工具結果一同加入 Claude 上下文的字串。當 `permissionDecision` 為 `"defer"` 時會被忽略。請參閱[為 Claude 加入上下文](#add-context-for-claude) |
1937 1939
1938當多個 PreToolUse hooks 返回不同的決定時,優先順序為 `deny` > `defer` > `ask` > `allow`。1940當多個 PreToolUse hook 回傳不同決策時,優先順序為 `deny` > `defer` > `ask` > `allow`。
1939 1941
1940透過退出 2 阻止的 hook 路由方式與 `"deny"` 相同:Claude 看到 stderr 訊息作為拒絕原因。1942以退出碼 2 阻擋的 hook 與 `"deny"` 的處理方式相同:Claude 會將 stderr 訊息視為拒絕原因。
1941 1943
1942當 hook 返回 `"ask"` 時,顯示給使用者的權限提示包括一個標籤,識別 hook 的來源:`[settings]` 對於來自任何設定檔或代理 frontmatter 的 hook,`[plugin:<name>]` 對於外掛的 hook,或 `[skill]` 對於來自 skill frontmatter 的 hook。這幫助使用者理解哪個配置來源要求確認。1944當 hook 回傳 `"ask"` 時,向使用者顯示的權限提示會包含一個標籤,標示該 hook 的來源:來自任何設定檔或 agent frontmatter 的 hook 為 `[settings]`,外掛的 hook 為 `[plugin:<name>]`,來自 skill frontmatter 的 hook 則為 `[skill]`。這有助於使用者了解是哪個設定來源在請求確認。
1943 1945
1944hook 的 `"ask"` 也在 [自動模式](/docs/zh-TW/permission-modes#eliminate-prompts-with-auto-mode) 中強制權限提示:分類器仍然可以拒絕工具呼叫,但它無法無聲地核准呼叫。在 v2.1.211 之前,分類器可以核准在 [sandbox](/docs/zh-TW/sandboxing) 外執行的 Bash 命令,而不顯示 hook 請求的提示;分類器仍然對該命令應用了自己的安全規則,hook `"deny"` 始終被尊重。1946hook 的 `"ask"` 也會在[自動模式](/docs/zh-TW/permission-modes#eliminate-prompts-with-auto-mode)中強制顯示權限提示:分類器仍可拒絕工具呼叫,但無法在無提示的情況下核准該呼叫。在 v2.1.211 之前,分類器可以在不顯示 hook 所請求之提示的情況下,核准在[沙箱](/docs/zh-TW/sandboxing)外執行的 Bash 命令;分類器仍會對該命令套用其自身的安全規則,而 hook 的 `"deny"` 一律會被遵守。
1945 1947
1946```json theme={null}1948```json theme={null}
1947{1949{
1959 1961
1960<span id="allow-with-updatedinput" />1962<span id="allow-with-updatedinput" />
1961 1963
1962在 [非互動模式](/docs/zh-TW/headless) 中搭配 `-p` 旗標,Claude Code 僅在執行有 [權限主機](/docs/zh-TW/headless#turn-off-permission-prompts-in-unattended-runs) 以接收提示時提供 `AskUserQuestion` 和 `ExitPlanMode`,例如 Agent SDK `canUseTool` 回呼。這些工具需要使用者互動。返回 `permissionDecision: "allow"` 與 `updatedInput` 一起滿足該要求:hook 從 stdin 讀取工具的輸入,透過您自己的 UI 收集答案,並在 `updatedInput` 中返回它,以便工具執行而不提示。單獨返回 `"allow"` 對這些工具不足夠。對於 `AskUserQuestion`,回顯原始 `questions` 陣列並新增一個 [`answers`](#askuserquestion) 物件,將每個問題的文字對應到選定的答案。1964在使用 `-p` 旗標的[非互動模式](/docs/zh-TW/headless)中,只有當執行具有接收提示的[權限主機](/docs/zh-TW/headless#turn-off-permission-prompts-in-unattended-runs)(例如 Agent SDK 的 `canUseTool` 回呼)時,Claude Code 才會提供 `AskUserQuestion` 與 `ExitPlanMode`。這些工具需要使用者互動。回傳 `permissionDecision: "allow"` 並搭配 `updatedInput` 即可滿足此需求:hook 從 stdin 讀取工具的輸入,透過您自己的 UI 收集答案,並在 `updatedInput` 中回傳,讓工具在不提示的情況下執行。對於這些工具,只回傳 `"allow"` 是不夠的。對於 `AskUserQuestion`,請回傳原始的 `questions` 陣列,並加入一個 [`answers`](#askuserquestion) 物件,將每個問題的文字對應到所選的答案。
1963 1965
1964自 v2.1.199 起,其伺服器用 [`_meta["anthropic/requiresUserInteraction"]`](/docs/zh-TW/mcp#require-approval-for-a-specific-tool) 標記的 MCP 工具更嚴格:hook 無法用 `"allow"` 跳過其核准提示,無論是否有 `updatedInput`,因為 Claude Code 無法確認 hook 收集了工具需要的互動。1966伺服器以 [`_meta["anthropic/requiresUserInteraction"]`](/docs/zh-TW/mcp#require-approval-for-a-specific-tool) 標記的 MCP 工具則更為嚴格:hook 無法以 `"allow"` 略過其核准提示,無論是否搭配 `updatedInput`,因為 Claude Code 無法確認 hook 已收集該工具所需的互動。
1965 1967
1966<Note>1968<Note>
1967 PreToolUse 之前使用頂級 `decision` 和 `reason` 欄位,但這些對此事件已棄用。改用 `hookSpecificOutput.permissionDecision` 和 `hookSpecificOutput.permissionDecisionReason`。已棄用的值 `"approve"` 和 `"block"` 對應到 `"allow"` 和 `"deny"`。PostToolUse 和 Stop 等其他事件繼續使用頂級 `decision` 和 `reason` 作為其目前格式。1969 PreToolUse 先前使用頂層的 `decision` 與 `reason` 欄位,但這些欄位在此事件中已棄用。請改用 `hookSpecificOutput.permissionDecision` 與 `hookSpecificOutput.permissionDecisionReason`。已棄用的值 `"approve"` 與 `"block"` 分別對應到 `"allow"` 與 `"deny"`。PostToolUse 與 Stop 等其他事件則繼續以頂層 `decision` 與 `reason` 作為其目前的格式。
1968</Note>1970</Note>
1969 1971
1970<h4 id="defer-a-tool-call-for-later">1972<h4 id="defer-a-tool-call-for-later">
1971 延遲工具呼叫以供稍後使用1973 延後工具呼叫
1972</h4>1974</h4>
1973 1975
1974`"defer"` 適用於執行 `claude -p` 作為子程序並讀取其 JSON 輸出的整合,例如 Agent SDK 應用程式或建立在 Claude Code 之上的自訂 UI。它讓該呼叫程序在工具呼叫處暫停 Claude,透過其自己的介面收集輸入,並在中斷處恢復。Claude Code 僅在 [非互動模式](/docs/zh-TW/headless) 中搭配 `-p` 旗標時尊重此值。在互動式工作階段中,它記錄警告並忽略 hook 結果。1976`"defer"` 適用於以子程序執行 `claude -p` 並讀取其 JSON 輸出的整合,例如 Agent SDK 應用程式或建立在 Claude Code 之上的自訂 UI。它讓呼叫端程序可以在工具呼叫處暫停 Claude、透過自己的介面收集輸入,並從中斷處繼續。Claude Code 只在使用 `-p` 旗標的[非互動模式](/docs/zh-TW/headless)中遵守此值。在互動式工作階段中,它會記錄警告並忽略 hook 結果。
1975 1977
1976`AskUserQuestion` 工具是典型情況:Claude 想詢問使用者某事,但沒有終端來回答。`-p` 執行僅在有 [權限主機](/docs/zh-TW/headless#turn-off-permission-prompts-in-unattended-runs) 時提供 `AskUserQuestion`,例如您使用 `--permission-prompt-tool` 傳遞的 MCP 工具,因此使用一個啟動執行。往返工作如下:1978`AskUserQuestion` 工具是典型的情況:Claude 想向使用者詢問某件事,但沒有可供回答的終端機。`-p` 執行只有在具有[權限主機](/docs/zh-TW/headless#turn-off-permission-prompts-in-unattended-runs)(例如您以 `--permission-prompt-tool` 傳入的 MCP 工具)時才會提供 `AskUserQuestion`,因此請以權限主機啟動執行。往返流程如下:
1977 1979
19781. Claude 呼叫 `AskUserQuestion`。`PreToolUse` hook 執行。19801. Claude 呼叫 `AskUserQuestion`。`PreToolUse` hook 觸發。
19792. hook 返回 `permissionDecision: "defer"`。工具不執行。程序以 `stop_reason: "tool_deferred"` 退出,待處理工具呼叫保留在文字記錄中。19812. hook 回傳 `permissionDecision: "defer"`。工具不會執行。程序以 `stop_reason: "tool_deferred"` 結束,待處理的工具呼叫會保留在逐字稿中。
19803. 呼叫程序從 SDK 結果讀取 `deferred_tool_use`,在其自己的 UI 中呈現問題,並等待答案。19823. 呼叫端程序從 SDK 結果讀取 `deferred_tool_use`,在自己的 UI 中呈現問題,並等待答案。
19814. 呼叫程序執行 `claude -p --resume <session-id>`,搭配相同的權限主機。相同的工具呼叫再次執行 `PreToolUse`。19834. 呼叫端程序以相同的權限主機執行 `claude -p --resume <session-id>`。同一個工具呼叫會再次觸發 `PreToolUse`。
19825. hook 返回 `permissionDecision: "allow"`,答案在 `updatedInput` 中。工具執行,Claude 繼續。19845. hook 回傳 `permissionDecision: "allow"`,並在 `updatedInput` 中附上答案。工具執行,Claude 繼續。
1983 1985
1984`deferred_tool_use` 欄位攜帶工具的 `id`、`name` 和 `input`。`input` 是 Claude 為工具呼叫產生的參數,在執行前捕獲:1986`deferred_tool_use` 欄位攜帶工具的 `id`、`name` 與 `input`。`input` 是 Claude 為該工具呼叫產生的參數,在執行前擷取:
1985 1987
1986```json theme={null}1988```json theme={null}
1987{1989{
1997}1999}
1998```2000```
1999 2001
2000沒有逾時或重試限制。工作階段保留在磁碟上,直到您恢復它,受 [`cleanupPeriodDays`](/docs/zh-TW/settings-reference#cleanupperioddays) 保留掃描約束,預設情況下在 30 天後刪除工作階段檔案,遵循 [保留掃描規則](/docs/zh-TW/claude-directory#cleaned-up-automatically)。如果答案在您恢復時未準備好,hook 可以再次返回 `"defer"`,程序以相同方式退出。呼叫程序控制何時透過最終從 hook 返回 `"allow"` 或 `"deny"` 來打破迴圈。2002沒有逾時或重試次數限制。工作階段會保留在磁碟上直到您繼續它,但受 [`cleanupPeriodDays`](/docs/zh-TW/settings-reference#cleanupperioddays) 保留清理的限制,該清理預設會在 30 天後刪除工作階段檔案,並遵循[保留清理規則](/docs/zh-TW/claude-directory#cleaned-up-automatically)。如果繼續時答案尚未準備好,hook 可以再次回傳 `"defer"`,程序會以相同方式結束。呼叫端程序藉由最終從 hook 回傳 `"allow"` 或 `"deny"` 來控制何時跳出迴圈。
2001 2003
2002`"defer"` 僅在 Claude 在回合中進行單個工具呼叫時有效。如果 Claude 同時進行多個工具呼叫,`"defer"` 會被忽略,並帶有警告,工具透過正常權限流程進行。約束存在是因為恢復只能重新執行一個工具:沒有辦法延遲批次中的一個呼叫而不留下其他未解決的。2004`"defer"` 只在 Claude 於該回合中只進行一次工具呼叫時有效。如果 Claude 同時進行多個工具呼叫,`"defer"` 會被忽略並發出警告,工具會透過一般的權限流程繼續。此限制的原因在於繼續時只能重新執行一個工具:無法在不讓其他呼叫懸而未決的情況下,延後批次中的其中一個呼叫。
2003 2005
2004如果恢復時延遲的工具不再可用,程序以 `stop_reason: "tool_deferred_unavailable"` 和 `is_error: true` 退出,在 hook 執行之前。當提供工具的 MCP 伺服器對於恢復的工作階段未連接時會發生這種情況。`deferred_tool_use` 有效負載仍然包含,以便您可以識別哪個工具遺失。2006如果繼續時延後的工具已不可用,程序會在 hook 觸發之前以 `stop_reason: "tool_deferred_unavailable"` 與 `is_error: true` 結束。當提供該工具的 MCP 伺服器在繼續的工作階段中未連線時,就會發生這種情況。`deferred_tool_use` payload 仍會包含在內,讓您能識別遺失的是哪個工具。
2005 2007
2006<Note>2008<Note>
2007 要在 plan mode 中恢復延遲工作階段,請在 `--resume` 旁邊傳遞 [`--permission-prompt-tool`](/docs/zh-TW/cli-reference#cli-flags),以便 Claude Code 可以呈現計畫以供核准。如果您傳遞某些其他啟動旗標,恢復的執行不會返回到 plan mode;請參閱 [使用 `-p` 在 plan mode 中恢復](/docs/zh-TW/sessions#resume-in-plan-mode-with-p)。需要 Claude Code v2.1.246 或更新版本。2009 若要在 plan mode 中繼續已延後的工作階段,請將 [`--permission-prompt-tool`](/docs/zh-TW/cli-reference#cli-flags) 與 `--resume` 一併傳入,讓 Claude Code 能呈現計畫以供核准。如果您傳入某些其他啟動旗標,繼續的執行不會回到 plan mode;請參閱[使用 `-p` 在 plan mode 中繼續](/docs/zh-TW/sessions#resume-in-plan-mode-with-p)。需要 Claude Code v2.1.246 或更新版本。
2008 2010
2009 當您使用 `-p` 恢復時,Claude Code 不會還原任何其他儲存的權限模式。它在新 `claude -p` 執行會啟動的權限模式中啟動執行,因此如果延遲工作階段使用了一個,請再次傳遞 `--permission-mode` 或 `--dangerously-skip-permissions`。當您使用 `claude --resume <session-id>` 恢復而不使用 `-p` 時,Claude Code 會還原儲存的權限模式,但 [恢復時的權限模式](/docs/zh-TW/sessions#permission-mode-on-resume) 中列出的例外除外。2011 當您以 `-p` 繼續時,Claude Code 不會還原任何其他已儲存的權限模式。它會以新的 `claude -p` 執行所使用的權限模式啟動執行,因此如果延後的工作階段使用了 `--permission-mode` 或 `--dangerously-skip-permissions`,請再次傳入。當您不使用 `-p` 而以 `claude --resume <session-id>` 繼續時,Claude Code 會還原已儲存的權限模式,例外情況列於[繼續時的權限模式](/docs/zh-TW/sessions#permission-mode-on-resume)。
2010</Note>2012</Note>
2011 2013
2012<h3 id="permissionrequest">2014<h3 id="permissionrequest">
2013 PermissionRequest2015 PermissionRequest
2014</h3>2016</h3>
2015 2017
2016在 Claude Code 即將向您請求使用工具的權限時執行。在無法顯示提示的工作階段中,例如[非互動模式](/docs/zh-TW/headless)中的背景 subagent,Claude Code 仍會執行這些 hook,而如果沒有 hook 傳回決策,它會拒絕該工具呼叫。對於送達 `--permission-prompt-tool` 或 Agent SDK [`canUseTool` 回呼](/docs/zh-TW/agent-sdk/permissions)的呼叫,hook 會與您的主機並行執行,以最先做出決策者為準。2018在 Claude Code 即將向您請求使用工具的權限時執行。在無法顯示提示的工作階段中,例如[非互動模式](/docs/zh-TW/headless)中的背景 subagent,Claude Code 仍會執行這些 hook,而如果沒有任何 hook 回傳決策,它就會拒絕該工具呼叫。對於到達 `--permission-prompt-tool` 或 Agent SDK 的 [`canUseTool` 回呼](/docs/zh-TW/agent-sdk/permissions)的呼叫,hook 會與您的主機並行執行,以先做出決定者為準。
2017使用 [PermissionRequest 決策控制](#permissionrequest-decision-control)代替使用者允許或拒絕。2019使用 [PermissionRequest 決策控制](#permissionrequest-decision-control)代表使用者允許或拒絕。
2018 2020
2019當您需要 Claude 要求許可使用工具時的信號時,使用此事件。Claude Code 僅在提示等待約六秒後執行 [Notification](#notification) hook,其中 `permission_prompt` 類型。2021當您需要在 Claude 請求使用工具權限的當下取得訊號時,請使用此事件。Claude Code 只有在提示已等待約六秒後,才會執行類型為 `permission_prompt` 的 [Notification](#notification) hook。
2020 2022
2021Claude Code 不為沙箱命令的 [網路請求](/docs/zh-TW/sandboxing#network-isolation) 執行 PermissionRequest hooks。要獲得該提示的信號,請使用 `permission_prompt` 通知類型。2023Claude Code 不會為沙箱化命令的[網路請求](/docs/zh-TW/sandboxing#network-isolation)執行 PermissionRequest hook。若要取得該提示的訊號,請使用 `permission_prompt` 通知類型。
2022 2024
2023在工具名稱上匹配,與 PreToolUse 相同的值。2025比對工具名稱,值與 PreToolUse 相同。
2024 2026
2025<h4 id="permissionrequest-input">2027<h4 id="permissionrequest-input">
2026 PermissionRequest 輸入2028 PermissionRequest 輸入
2027</h4>2029</h4>
2028 2030
2029PermissionRequest hooks 接收 `tool_name` 和 `tool_input` 欄位,如 PreToolUse hooks,但沒有 `tool_use_id`。對於 MCP 工具,它們也接收 [`mcp_server`](#pretooluse-input) 物件。可選的 `permission_suggestions` 陣列包含 Claude Code 為此請求建議的 [權限更新](#permission-update-entries),例如新增允許規則或更改權限模式。2031PermissionRequest hook 會像 PreToolUse hook 一樣接收 `tool_name` 與 `tool_input` 欄位,但不含 `tool_use_id`。對於 MCP 工具,它們也會接收 [`mcp_server`](#pretooluse-input) 物件。選擇性的 `permission_suggestions` 陣列包含 Claude Code 為此請求建議的[權限更新](#permission-update-entries),例如新增允許規則或變更權限模式。
2030 2032
2031`permission_suggestions` 陣列不是您看到的選項的確切清單,因為每個權限對話都建立自己的選項。某些對話(例如檔案編輯的對話)根本不讀取陣列,並從請求本身衍生其選項。讀取它的對話仍然可以保留其建議留在陣列中的選項,例如當 [`allowManagedPermissionRulesOnly`](/docs/zh-TW/settings-reference#allowmanagedpermissionrulesonly) 隱藏規則保存選項時。它也可以提供沒有建議項目的選項,例如 [**是的,並切換到自動模式**](/docs/zh-TW/permission-modes#switch-permission-modes),它直接更改權限模式,而不是透過權限更新。2033`permission_suggestions` 陣列並非您所看到選項的精確清單,因為每個權限對話框會建構自己的選項。有些對話框(例如檔案編輯的對話框)完全不讀取此陣列,而是從請求本身衍生選項。會讀取此陣列的對話框,仍可能隱藏其建議保留在陣列中的選項,例如當 [`allowManagedPermissionRulesOnly`](/docs/zh-TW/settings-reference#allowmanagedpermissionrulesonly) 隱藏儲存規則的選項時。它也可能提供沒有對應建議項目的選項,例如 [**Yes, and switch to auto mode**](/docs/zh-TW/permission-modes#switch-permission-modes),它會直接變更權限模式,而非透過權限更新。
2032 2034
2033PreToolUse hooks 在每個工具呼叫之前執行,無論它是否需要權限。PermissionRequest hooks 僅在 Claude Code 即將要求您許可時執行,或當它否則會自動拒絕無法提示的呼叫時執行。兩個事件都不會對 [`EndConversation`](/docs/zh-TW/tools-reference#endconversation-tool-behavior) 執行。2035PreToolUse hook 會在每次工具呼叫之前執行,無論是否需要權限。PermissionRequest hook 只在 Claude Code 即將向您請求權限時執行,或在它原本會自動拒絕一個無法提示的呼叫時執行。兩個事件都不會為 [`EndConversation`](/docs/zh-TW/tools-reference#endconversation-tool-behavior) 觸發。
2034 2036
2035```json theme={null}2037```json theme={null}
2036{2038{
2059 PermissionRequest 決策控制2061 PermissionRequest 決策控制
2060</h4>2062</h4>
2061 2063
2062`PermissionRequest` hooks 可以允許或拒絕權限請求。除了所有 hooks 可用的 [JSON 輸出欄位](#json-output) 外,您的 hook 指令碼可以返回具有這些事件特定欄位的 `decision` 物件:2064`PermissionRequest` hook 可以允許或拒絕權限請求。除了所有 hook 都可使用的 [JSON 輸出欄位](#json-output)之外,您的 hook 指令碼還可以回傳包含下列事件專屬欄位的 `decision` 物件:
2063 2065
2064| 欄位 | 描述 |2066| 欄位 | 說明 |
2065| :- | :- |2067| :- | :- |
2066| `behavior` | `"allow"` 授予權限,`"deny"` 拒絕它。[拒絕和詢問規則](/docs/zh-TW/permissions#manage-permissions) 仍然被評估,因此返回 `"allow"` 的 hook 不會覆寫匹配的拒絕規則 |2068| `behavior` | `"allow"` 授予權限,`"deny"` 拒絕權限。[拒絕與詢問規則](/docs/zh-TW/permissions#manage-permissions)仍會被評估,因此回傳 `"allow"` 的 hook 不會覆寫相符的拒絕規則 |
2067| `updatedInput` | 僅對 `"allow"`:在執行前修改工具的輸入參數。替換整個輸入物件,因此在修改的欄位旁邊包含未變更的欄位。修改的輸入會針對拒絕和詢問規則重新評估 |2069| `updatedInput` | 僅適用於 `"allow"`:在執行前修改工具的輸入參數。會取代整個輸入物件,因此請將未變更的欄位與修改後的欄位一併包含。修改後的輸入會重新針對拒絕與詢問規則評估 |
2068| `updatedPermissions` | 僅對 `"allow"`:[權限更新項目](#permission-update-entries) 陣列以應用,例如新增允許規則或更改工作階段權限模式 |2070| `updatedPermissions` | 僅適用於 `"allow"`:要套用的[權限更新項目](#permission-update-entries)陣列,例如新增允許規則或變更工作階段權限模式 |
2069| `message` | 僅對 `"deny"`:告訴 Claude 為什麼權限被拒絕 |2071| `message` | 僅適用於 `"deny"`:告訴 Claude 權限被拒絕的原因 |
2070| `interrupt` | 僅對 `"deny"`:如果 `true`,停止 Claude |2072| `interrupt` | 僅適用於 `"deny"`:若為 `true`,則停止 Claude |
2071 2073
2072退出 2 而不帶 `decision` 物件的 hook 保持權限流程不變,其 stderr 被捨棄。只有 `decision` 物件可以授予或拒絕請求。2074以退出碼 2 結束但沒有 `decision` 物件的 hook 不會改變權限流程,其 stderr 會被捨棄。只有 `decision` 物件能授予或拒絕請求。
2073 2075
2074```json theme={null}2076```json theme={null}
2075{2077{
2089 權限更新項目2091 權限更新項目
2090</h4>2092</h4>
2091 2093
2092`updatedPermissions` 輸出欄位和 [`permission_suggestions` 輸入欄位](#permissionrequest-input) 都使用相同的項目物件陣列。每個項目都有一個 `type`,決定其他欄位,以及一個 `destination`,控制變更的寫入位置。2094`updatedPermissions` 輸出欄位與 [`permission_suggestions` 輸入欄位](#permissionrequest-input)都使用相同的項目物件陣列。每個項目都有一個決定其他欄位的 `type`,以及一個控制變更寫入位置的 `destination`。
2093 2095
2094| `type` | 欄位 | 效果 |2096| `type` | 欄位 | 效果 |
2095| :- | :- | :- |2097| :- | :- | :- |
2096| `addRules` | `rules`、`behavior`、`destination` | 新增權限規則。`rules` 是 `{toolName, ruleContent?}` 物件的陣列。省略 `ruleContent` 以匹配整個工具。`behavior` 為 `"allow"`、`"deny"` 或 `"ask"` |2098| `addRules` | `rules`、`behavior`、`destination` | 新增權限規則。`rules` 是 `{toolName, ruleContent?}` 物件的陣列。省略 `ruleContent` 即可比對整個工具。`behavior` 為 `"allow"`、`"deny"` 或 `"ask"` |
2097| `replaceRules` | `rules`、`behavior`、`destination` | 將給定 `behavior` 在 `destination` 的所有規則替換為提供的 `rules` |2099| `replaceRules` | `rules`、`behavior`、`destination` | 以提供的 `rules` 取代 `destination` 中所有指定 `behavior` 的規則 |
2098| `removeRules` | `rules`、`behavior`、`destination` | 移除給定 `behavior` 的匹配規則 |2100| `removeRules` | `rules`、`behavior`、`destination` | 移除指定 `behavior` 的相符規則 |
2099| `setMode` | `mode`、`destination` | 更改權限模式。有效模式為 `default`、`auto`、`acceptEdits`、`dontAsk`、`bypassPermissions`、`plan` 和 `manual` 作為 `default` 的別名。`manual` 別名需要 Claude Code v2.1.200 或更新版本 |2101| `setMode` | `mode`、`destination` | 變更權限模式。有效的模式為 `default`、`auto`、`acceptEdits`、`dontAsk`、`bypassPermissions`、`plan`,以及作為 `default` 別名的 `manual`。`manual` 別名需要 Claude Code v2.1.200 或更新版本 |
2100| `addDirectories` | `directories`、`destination` | 新增工作目錄。`directories` 是路徑字串的陣列 |2102| `addDirectories` | `directories`、`destination` | 新增工作目錄。`directories` 是路徑字串的陣列 |
2101| `removeDirectories` | `directories`、`destination` | 移除工作目錄 |2103| `removeDirectories` | `directories`、`destination` | 移除工作目錄 |
2102 2104
2103<Note>2105<Note>
2104 `setMode` 搭配 `bypassPermissions` 僅在您已使用以下方式啟動工作階段時生效:`--dangerously-skip-permissions`、`--permission-mode bypassPermissions`、`--allow-dangerously-skip-permissions` 或 [user、`--settings` 或 managed settings](/docs/zh-TW/settings-reference#permissions-defaultmode) 中的 `permissions.defaultMode: "bypassPermissions"`。否則更新是無操作。當 [`permissions.disableBypassPermissionsMode`](/docs/zh-TW/permissions#managed-settings) 禁用模式或工作階段在 [受限模式](/docs/zh-TW/cli-reference#cli-flags) 中啟動時,更新也是無操作。2106 只有在啟動工作階段時已可使用略過模式的情況下,搭配 `bypassPermissions` 的 `setMode` 才會生效:`--dangerously-skip-permissions`、`--permission-mode bypassPermissions`、`--allow-dangerously-skip-permissions`,或在[使用者設定、`--settings` 或受管設定](/docs/zh-TW/settings-reference#permissions-defaultmode)中設定 `permissions.defaultMode: "bypassPermissions"`。否則此更新不會產生任何作用。當 [`permissions.disableBypassPermissionsMode`](/docs/zh-TW/permissions#managed-settings) 停用此模式,或工作階段以[受限模式](/docs/zh-TW/cli-reference#cli-flags)啟動時,此更新同樣不會產生任何作用。
2105 2107
2106 無論 `destination` 如何,`bypassPermissions` 永遠不會作為 `defaultMode` 保留。2108 無論 `destination` 為何,`bypassPermissions` 都不會被保存為 `defaultMode`。
2107</Note>2109</Note>
2108 2110
2109每個項目上的 `destination` 欄位決定變更是保留在記憶體中還是保留到設定檔。2111每個項目上的 `destination` 欄位決定變更是保留在記憶體中,還是保存到設定檔。
2110 2112
2111| `destination` | 寫入 |2113| `destination` | 寫入位置 |
2112| :- | :- |2114| :- | :- |
2113| `session` | 僅在記憶體中,工作階段結束時捨棄 |2115| `session` | 僅存在記憶體中,工作階段結束時捨棄 |
2114| `localSettings` | `.claude/settings.local.json` |2116| `localSettings` | `.claude/settings.local.json` |
2115| `projectSettings` | `.claude/settings.json` |2117| `projectSettings` | `.claude/settings.json` |
2116| `userSettings` | `~/.claude/settings.json` |2118| `userSettings` | `~/.claude/settings.json` |
2117 2119
2118hook 可以回顯它接收的 `permission_suggestions` 之一作為其自己的 `updatedPermissions` 輸出。2120hook 可以將其收到的某個 `permission_suggestions` 原樣作為自己的 `updatedPermissions` 輸出傳回。
2119 2121
2120<h3 id="posttooluse">2122<h3 id="posttooluse">
2121 PostToolUse2123 PostToolUse
2123 2125
2124在工具成功完成後立即執行。2126在工具成功完成後立即執行。
2125 2127
2126在工具名稱上匹配,與 PreToolUse 相同的值。2128依工具名稱比對,可用值與 PreToolUse 相同。
2127 2129
2128當工具名稱不是正確的篩選器時,更廣泛地匹配:2130當工具名稱不是合適的篩選條件時,可以更廣泛地比對:
2129 2131
2130* 要在任何工具成功完成後執行 hook,省略 `matcher` 或將其設定為 `"*"`。您的 hook 然後可以自己發現變更的內容,例如執行 `git status --porcelain`,它也列出 `git diff` 遺漏的未追蹤檔案。對於失敗的工具呼叫,在 [PostToolUseFailure](#posttoolusefailure) 下新增相同的 hook。2132* 若要在任何工具成功完成後執行 hook,請省略 `matcher` 或將其設為 `"*"`。您的 hook 接著可以自行找出變更內容,例如執行 `git status --porcelain`,它也會列出 `git diff` 遺漏的未追蹤檔案。對於失敗的工具呼叫,請在 [PostToolUseFailure](#posttoolusefailure) 下新增相同的 hook。
2131* 要在特定檔案在磁碟上變更時執行 hook,無論什麼寫入它,請使用 [FileChanged](#filechanged)。Claude Code 不執行匹配 `Edit|Write` 的 `PostToolUse` hook,當 `Bash` 命令或 Claude Code 外的程序重寫相同檔案時。2133* 若要在特定檔案於磁碟上變更時執行 hook(無論由誰寫入),請使用 [FileChanged](#filechanged)。當 `Bash` 命令或 Claude Code 以外的程序改寫同一個檔案時,Claude Code 不會執行比對 `Edit|Write` 的 `PostToolUse` hook。
2132 2134
2133<h4 id="posttooluse-input">2135<h4 id="posttooluse-input">
2134 PostToolUse 輸入2136 PostToolUse 輸入
2135</h4>2137</h4>
2136 2138
2137`PostToolUse` hooks 在工具已執行成功後執行。輸入包括 `tool_input`(傳送給工具的引數)和 `tool_response`(它返回的結果)。兩者的確切架構取決於工具。檔案工具 `tool_input` 路徑以與 [PreToolUse](#pretooluse-input) 相同的格式到達:始終絕對,具有平台的原生分隔符,因此 Windows 上的反斜線。對於 MCP 工具,輸入也攜帶 [`mcp_server`](#pretooluse-input) 物件。2139`PostToolUse` hook 會在工具已成功執行後觸發。輸入同時包含 `tool_input`(傳送給工具的引數)與 `tool_response`(工具傳回的結果)。兩者的確切 schema 取決於工具。檔案工具的 `tool_input` 路徑格式與 [PreToolUse](#pretooluse-input) 相同:一律為絕對路徑,並使用平台原生的分隔符號,因此在 Windows 上為反斜線。對於 MCP 工具,輸入也會帶有 [`mcp_server`](#pretooluse-input) 物件。
2138 2140
2139```json theme={null}2141```json theme={null}
2140{2142{
2157}2159}
2158```2160```
2159 2161
2160| 欄位 | 描述 |2162| 欄位 | 說明 |
2161| :- | :- |2163| :- | :- |
2162| `duration_ms` | 可選。工具執行時間(毫秒)。不包括權限提示和 PreToolUse hooks 中花費的時間 |2164| `duration_ms` | 選用。工具執行時間(毫秒)。不包含花在權限提示與 PreToolUse hook 上的時間 |
2163 2165
2164<h4 id="posttooluse-decision-control">2166<h4 id="posttooluse-decision-control">
2165 PostToolUse 決策控制2167 PostToolUse 決策控制
2166</h4>2168</h4>
2167 2169
2168`PostToolUse` hooks 可以在工具執行後提供反饋給 Claude。除了所有 hooks 可用的 [JSON 輸出欄位](#json-output) 外,您的 hook 指令碼可以返回這些事件特定的欄位:2170`PostToolUse` hook 可以在工具執行後向 Claude 提供回饋。除了所有 hook 皆可使用的 [JSON 輸出欄位](#json-output)之外,您的 hook 指令碼還可以傳回以下事件專屬欄位:
2169 2171
2170| 欄位 | 描述 |2172| 欄位 | 說明 |
2171| :- | :- |2173| :- | :- |
2172| `decision` | `"block"` 在工具結果旁邊新增 `reason`。Claude 仍然看到原始輸出;要替換它,請使用 `updatedToolOutput` |2174| `decision` | `"block"` 會將 `reason` 附加在工具結果旁。Claude 仍會看到原始輸出;若要取代輸出,請使用 `updatedToolOutput` |
2173| `reason` | 當 `decision` 為 `"block"` 時顯示給 Claude 的解釋 |2175| `reason` | 當 `decision` 為 `"block"` 時向 Claude 顯示的說明 |
2174| `additionalContext` | 與工具結果一起新增到 Claude 背景資訊的字串。有關詳細資訊,請參閱 [為 Claude 新增背景資訊](#add-context-for-claude) |2176| `additionalContext` | 與工具結果一併加入 Claude 上下文的字串。請參閱[為 Claude 新增上下文](#add-context-for-claude) |
2175| `classifierContext` | 關於此呼叫結果的簡短說明,用於 [自動模式](/docs/zh-TW/permission-modes#eliminate-prompts-with-auto-mode) 分類器,而不是 Claude。有關詳細資訊,請參閱 [為自動模式分類器註釋結果](#annotate-a-result-for-the-auto-mode-classifier)。需要 Claude Code v2.1.236 或更新版本 |2177| `classifierContext` | 關於此次呼叫結果的簡短註記,提供給[自動模式](/docs/zh-TW/permission-modes#eliminate-prompts-with-auto-mode)分類器而非 Claude。請參閱[為自動模式分類器註記結果](#annotate-a-result-for-the-auto-mode-classifier)。需要 Claude Code v2.1.236 或更新版本 |
2176| `updatedToolOutput` | 在將工具的輸出傳送給 Claude 之前,用提供的值替換它。該值必須符合工具的輸出形狀 |2178| `updatedToolOutput` | 在傳送給 Claude 之前,以提供的值取代工具的輸出。該值必須符合工具的輸出結構 |
2177| `updatedMCPToolOutput` | 僅替換 [MCP 工具](#match-mcp-tools) 的輸出。偏好 `updatedToolOutput`,它適用於所有工具 |2179| `updatedMCPToolOutput` | 僅取代 [MCP 工具](#match-mcp-tools)的輸出。建議改用適用於所有工具的 `updatedToolOutput` |
2178 2180
2179下面的範例替換 `Bash` 呼叫的輸出。替換值符合 `Bash` 工具的輸出形狀:2181以下範例取代 `Bash` 呼叫的輸出。取代值符合 `Bash` 工具的輸出結構:
2180 2182
2181```json theme={null}2183```json theme={null}
2182{2184{
2194```2196```
2195 2197
2196<Warning>2198<Warning>
2197 `updatedToolOutput` 僅更改 Claude 看到的內容。工具在 hook 執行時已執行,因此任何寫入的檔案、執行的命令或傳送的網路請求都已生效。遙測(例如 OpenTelemetry 工具跨度和分析事件)也會在 hook 執行之前捕獲原始輸出。要在執行前防止或修改工具呼叫,請改用 [PreToolUse](#pretooluse) hook。2199 `updatedToolOutput` 只會改變 Claude 看到的內容。hook 觸發時工具已經執行完畢,因此任何已寫入的檔案、已執行的命令或已送出的網路請求都已生效。OpenTelemetry 工具 span 與分析事件等遙測資料,也會在 hook 執行前擷取原始輸出。若要在工具呼叫執行前阻止或修改它,請改用 [PreToolUse](#pretooluse) hook。
2198 2200
2199 替換值必須符合工具的輸出形狀。內建工具返回結構化物件,而不是純字串。例如,`Bash` 返回具有 `stdout`、`stderr`、`interrupted` 和 `isImage` 欄位的物件。對於內建工具,不符合工具輸出架構的值會被忽略,並使用原始輸出。MCP 工具輸出會通過而不進行架構驗證。去除 Claude 需要的錯誤詳細資訊可能導致它在錯誤假設上進行。2201 取代值必須符合工具的輸出結構。內建工具傳回的是結構化物件,而非純字串。例如,`Bash` 會傳回包含 `stdout`、`stderr`、`interrupted` 與 `isImage` 欄位的物件。對於內建工具,不符合工具輸出 schema 的值會被忽略,並改用原始輸出。MCP 工具的輸出則會直接傳遞,不進行 schema 驗證。移除 Claude 所需的錯誤細節,可能導致它依據錯誤的假設繼續進行。
2200</Warning>2202</Warning>
2201 2203
2202<h4 id="annotate-a-result-for-the-auto-mode-classifier">2204<h4 id="annotate-a-result-for-the-auto-mode-classifier">
2203 為自動模式分類器註釋結果2205 為自動模式分類器註記結果
2204</h4>2206</h4>
2205 2207
2206返回 `classifierContext` 以向 [自動模式](/docs/zh-TW/permission-modes#eliminate-prompts-with-auto-mode) 分類器傳送關於工具呼叫結果的簡短說明,而不是向 Claude。分類器 [永遠不會接收工具結果本身](/docs/zh-TW/permission-modes#how-the-classifier-evaluates-actions),因此此欄位是在它審查稍後的動作之前告訴它工具呼叫返回的內容的支援方式。該欄位需要 Claude Code v2.1.236 或更新版本。2208傳回 `classifierContext`,即可將關於工具呼叫結果的簡短註記傳送給[自動模式](/docs/zh-TW/permission-modes#eliminate-prompts-with-auto-mode)分類器,而非傳送給 Claude。分類器[永遠不會收到工具結果本身](/docs/zh-TW/permission-modes#how-the-classifier-evaluates-actions),因此在它審查後續動作之前,此欄位是告知它某次呼叫傳回內容的官方支援方式。此欄位需要 Claude Code v2.1.236 或更新版本。
2207 2209
2208下面的範例告訴分類器查詢的輸出來自何處:2210以下範例告訴分類器某個查詢的輸出來源:
2209 2211
2210```json theme={null}2212```json theme={null}
2211{2213{
2216}2218}
2217```2219```
2218 2220
2219分類器給予說明的權重取決於您配置 hook 的位置:2221分類器對註記的重視程度,取決於您在何處設定該 hook:
2220 2222
2221* **在 Claude Code 中配置的 Hooks**:對於來自設定檔、外掛、skills 和代理 frontmatter 的 hooks,分類器將說明視為未驗證的應用程式提供的背景資訊。說明永遠不會建立使用者意圖,如果它聲稱您核准或請求了某事,分類器會根據您在對話中的自己訊息檢查該聲明2223* **在 Claude Code 中設定的 hook**:對於來自設定檔、外掛、skill 與 agent frontmatter 的 hook,分類器會將註記視為未經驗證、由應用程式提供的上下文。註記永遠無法確立使用者意圖;若註記聲稱您核准或要求了某件事,分類器會以您在對話中的訊息查核該聲明
2222* **進程內 Agent SDK 回呼**:當應用程式嵌入 Claude Code 並將 hook 註冊為 [TypeScript SDK 回呼](/docs/zh-TW/agent-sdk/hooks) 並在即時工作階段期間返回說明時,分類器可能會將說明中轉達的使用者陳述視為使用者意圖。這樣的陳述可以滿足分類器會接受來自您傳送的訊息的同意要求,但它永遠不會解除您自己的訊息也無法解除的阻止。工作階段恢復後,Claude Code 將還原的說明視為未驗證的背景資訊。當來自兩個群組的 hooks 註釋相同的呼叫時,分類器將組合說明視為未驗證2224* **行程內 Agent SDK 回呼**:當嵌入 Claude Code 的應用程式將 hook 註冊為 [TypeScript SDK 回呼](/docs/zh-TW/agent-sdk/hooks),並在即時工作階段中傳回註記時,分類器可能會將註記中轉述的使用者陳述視為使用者意圖。此類陳述可以滿足分類器原本會接受您傳送訊息來滿足的同意要求,但永遠無法解除您自己的訊息也無法解除的封鎖。工作階段恢復後,Claude Code 會將還原的註記視為未經驗證的上下文。當兩組來源的 hook 都為同一次呼叫加上註記時,分類器會將合併後的註記視為未經驗證
2223 2225
2224Claude Code 在傳遞說明時應用這些限制:2226Claude Code 在傳遞註記時會套用以下限制:
2225 2227
2226* **長度**:Claude Code 將一個工具呼叫的說明上限為 2,000 個字元,並截斷其餘部分。上限在回應該呼叫的每個 hook 之間共享2228* **長度**:Claude Code 將單次工具呼叫的註記上限設為 2,000 個字元,超出部分會被截斷。此上限由回應該次呼叫的所有 hook 共用
2227* **僅同步回應**:Claude Code 忽略 [在背景執行](#run-hooks-in-the-background) 的 hook 回應中的欄位,因為該回應在 Claude Code 記錄工具結果後到達2229* **僅限同步回應**:對於[在背景執行](#run-hooks-in-the-background)的 hook,Claude Code 會忽略其回應中的此欄位,因為該回應會在 Claude Code 記錄工具結果之後才抵達
2228* **分類器不記錄的呼叫**:分類器的文字記錄省略唯讀查詢,例如檔案讀取和搜尋。Claude Code 捨棄附加到其中一個呼叫的說明2230* **分類器未記錄的呼叫**:分類器的逐字稿會省略唯讀查詢,例如檔案讀取與搜尋。附加在這類呼叫上的註記會被 Claude Code 捨棄
2229* **與重寫的互動**:當說明描述您使用 `updatedToolOutput` 替換的輸出時,在相同的 hook 回應中返回兩個欄位。如果該重寫被拒絕或另一個 hook 的重寫替換它,Claude Code 會捨棄說明。Claude Code 傳遞您返回的說明,而不進行重寫,即使另一個 hook 重寫輸出2231* **與改寫的互動**:當註記描述的是您正以 `updatedToolOutput` 取代的輸出時,請在同一個 hook 回應中同時傳回這兩個欄位。若該改寫遭到拒絕,或被另一個 hook 的改寫取代,Claude Code 會捨棄該註記。若您傳回註記但未改寫,即使另一個 hook 改寫了輸出,Claude Code 仍會傳遞您的註記
2230 2232
2231<Warning>2233<Warning>
2232 分類器將您放在 `classifierContext` 中的內容讀取為來自應用程式主機工作階段的資訊,因此不要將不受信任的工具輸出或第三方文字複製到其中。將說明保持為關於此一個呼叫的簡短聲明,例如關於其來源的事實或關於它的使用者陳述;不要使用欄位傳遞不相關的訊息或事件流。2234 分類器會將您放入 `classifierContext` 的內容視為來自託管工作階段之應用程式的資訊,因此請勿將不受信任的工具輸出或第三方文字複製到其中。請將註記限制為關於這一次呼叫的簡短陳述,例如其來源的相關事實,或使用者對其的陳述;請勿使用此欄位傳遞無關的訊息或一連串事件。
2233</Warning>2235</Warning>
2234 2236
2235<h3 id="posttoolusefailure">2237<h3 id="posttoolusefailure">
2236 PostToolUseFailure2238 PostToolUseFailure
2237</h3>2239</h3>
2238 2240
2239在開始執行的工具失敗時執行:工具拋出錯誤,或 MCP 工具返回錯誤結果。使用此來記錄失敗、傳送警報或向 Claude 提供更正反饋。2241當已開始執行的工具失敗時執行:工具擲出錯誤,或 MCP 工具傳回錯誤結果。可用來記錄失敗、傳送警示,或向 Claude 提供修正回饋。
2240 2242
2241在工具名稱上匹配,與 PreToolUse 相同的值。2243依工具名稱比對,可用值與 PreToolUse 相同。
2242 2244
2243<Note>2245<Note>
2244 此事件不會對執行前被拒絕的工具呼叫執行:未知工具名稱、失敗架構或工具特定驗證的輸入,或權限拒絕。驗證拒絕作為 `tool_use_error` 結果返回,並在 hooks 執行之前發生,因此它們既不執行 `PreToolUse` 也不執行此事件。權限拒絕執行 `PreToolUse` 但不執行此事件;請參閱 [PermissionDenied](#permissiondenied)。2246 對於在執行前即遭拒絕的工具呼叫,此事件不會觸發:未知的工具名稱、未通過 schema 或工具專屬驗證的輸入,或權限遭拒。驗證拒絕會以 `tool_use_error` 結果傳回,且發生在 hook 執行之前,因此既不會觸發 `PreToolUse`,也不會觸發 `PostToolUseFailure`。權限遭拒會觸發 `PreToolUse`,但不會觸發此事件;請參閱 [PermissionDenied](#permissiondenied)。
2245</Note>2247</Note>
2246 2248
2247<h4 id="posttoolusefailure-input">2249<h4 id="posttoolusefailure-input">
2248 PostToolUseFailure 輸入2250 PostToolUseFailure 輸入
2249</h4>2251</h4>
2250 2252
2251PostToolUseFailure hooks 接收與 PostToolUse 相同的 `tool_name` 和 `tool_input` 欄位,以及錯誤資訊作為頂級欄位。對於 MCP 工具,它們也接收 [`mcp_server`](#pretooluse-input) 物件。例如,失敗的 `npm test` 命令可能傳遞:2253PostToolUseFailure hook 會收到與 PostToolUse 相同的 `tool_name` 與 `tool_input` 欄位,以及作為頂層欄位的錯誤資訊。對於 MCP 工具,它們也會收到 [`mcp_server`](#pretooluse-input) 物件。例如,失敗的 `npm test` 命令可能會傳遞:
2252 2254
2253```json theme={null}2255```json theme={null}
2254{2256{
2269}2271}
2270```2272```
2271 2273
2272| 欄位 | 描述 |2274| 欄位 | 說明 |
2273| :- | :- |2275| :- | :- |
2274| `error` | 描述出錯內容的字串。格式取決於失敗的工具 |2276| `error` | 描述錯誤內容的字串。格式取決於失敗的工具 |
2275| `is_interrupt` | 可選布林值。當失敗作為中止而不是工具報告的錯誤到達 Claude Code 時為 true。取消執行中的工具不會執行此 hook;工具結果攜帶中斷訊息 |2277| `is_interrupt` | 選用布林值。當失敗是以中止的形式傳到 Claude Code,而非工具回報的錯誤時為 true。取消正在執行的工具不會觸發此 hook;工具結果會改為帶有中斷訊息 |
2276| `duration_ms` | 可選。工具執行時間(毫秒)。不包括權限提示和 PreToolUse hooks 中花費的時間 |2278| `duration_ms` | 選用。工具執行時間(毫秒)。不包含花在權限提示與 PreToolUse hook 上的時間 |
2277 2279
2278`error` 字串通常與 Claude 作為失敗工具結果接收的相同文字相同。其格式因工具和失敗而異。在 `tool_name`、`is_interrupt` 和第一行 `Exit code N` 上鍵入您的 hook;將字串的其餘部分視為顯示文字,而不是穩定格式。2280`error` 字串通常與 Claude 收到的失敗工具結果文字相同。其格式因工具與失敗情況而異。請讓您的 hook 依據 `tool_name`、`is_interrupt` 以及第一行的 `Exit code N` 判斷;字串的其餘部分請視為顯示用文字,而非穩定的格式。
2279 2281
2280* 對於 Bash 和 PowerShell,執行並退出的命令會產生第一行 `Exit code N`,然後是命令產生的任何輸出作為一個區塊,stdout 和 stderr 交錯2282* 對於 Bash 與 PowerShell,已執行並結束的命令會產生第一行 `Exit code N`,接著是命令產生的任何輸出,以 stdout 與 stderr 交錯的單一區塊呈現
2281* 有效負載也可能攜帶裸露的失敗訊息,沒有退出代碼行,當 Claude Code 無法啟動 shell 程序本身時2283* 當 Claude Code 無法啟動 shell 程序本身時,payload 也可能只帶有單純的失敗訊息,沒有退出碼那一行
2282* Claude Code 中間截斷長字串,圍繞 `... [N characters truncated] ...` 標記,並可以插入自己的行,例如 `Command timed out after 2m 0s`2284* Claude Code 會在 `... [N characters truncated] ...` 標記周圍截斷長字串的中間部分,也可能插入自己的文字行,例如 `Command timed out after 2m 0s`
2283 2285
2284<h4 id="posttoolusefailure-decision-control">2286<h4 id="posttoolusefailure-decision-control">
2285 PostToolUseFailure 決策控制2287 PostToolUseFailure 決策控制
2286</h4>2288</h4>
2287 2289
2288`PostToolUseFailure` hooks 可以在工具失敗後向 Claude 提供背景資訊。除了所有 hooks 可用的 [JSON 輸出欄位](#json-output) 外,您的 hook 指令碼可以返回這些事件特定的欄位:2290`PostToolUseFailure` hook 可以在工具失敗後向 Claude 提供上下文。除了所有 hook 皆可使用的 [JSON 輸出欄位](#json-output)之外,您的 hook 指令碼還可以傳回以下事件專屬欄位:
2289 2291
2290| 欄位 | 描述 |2292| 欄位 | 說明 |
2291| :- | :- |2293| :- | :- |
2292| `additionalContext` | 與錯誤一起新增到 Claude 背景資訊的字串。有關詳細資訊,請參閱 [為 Claude 新增背景資訊](#add-context-for-claude) |2294| `additionalContext` | 與錯誤一併加入 Claude 上下文的字串。請參閱[為 Claude 新增上下文](#add-context-for-claude) |
2293 2295
2294```json theme={null}2296```json theme={null}
2295{2297{
2304 PostToolBatch2306 PostToolBatch
2305</h3>2307</h3>
2306 2308
2307在批次中的每個工具呼叫都已解決後執行一次,在 Claude Code 傳送下一個請求給模型之前。`PostToolUse` 每個工具執行一次,這意味著當 Claude 進行平行工具呼叫時它並發執行。`PostToolBatch` 恰好執行一次,具有完整批次,因此它是注入取決於執行的工具集而不是任何單個工具的背景資訊的正確位置。此事件沒有匹配器。2309在批次中的每個工具呼叫都已解決後執行一次,時間點在 Claude Code 將下一個請求傳送給模型之前。`PostToolUse` 會針對每個工具觸發一次,這表示當 Claude 進行平行工具呼叫時,它會同時觸發。`PostToolBatch` 則會帶著完整批次恰好觸發一次,因此適合用來注入取決於已執行工具集合、而非任何單一工具的上下文。此事件沒有 matcher。
2308 2310
2309<h4 id="posttoolbatch-input">2311<h4 id="posttoolbatch-input">
2310 PostToolBatch 輸入2312 PostToolBatch 輸入
2311</h4>2313</h4>
2312 2314
2313除了 [常見輸入欄位](#common-input-fields) 外,PostToolBatch hooks 還會接收 `tool_calls`,一個描述批次中每個工具呼叫的陣列:2315除了[通用輸入欄位](#common-input-fields)之外,PostToolBatch hook 還會收到 `tool_calls`,這是描述批次中每個工具呼叫的陣列:
2314 2316
2315```json theme={null}2317```json theme={null}
2316{2318{
2336}2338}
2337```2339```
2338 2340
2339`tool_response` 包含模型在對應 `tool_result` 區塊中接收的相同內容。該值是序列化字串或內容區塊陣列,完全如工具發出的那樣。對於 `Read`,這意味著行號前綴文字,而不是原始檔案內容。回應可能很大,因此僅解析您需要的欄位。2341`tool_response` 包含與模型在對應 `tool_result` 區塊中收到的相同內容。其值為序列化字串或內容區塊陣列,與工具輸出時完全相同。對於 `Read`,這表示是帶有行號前綴的文字,而非原始檔案內容。回應可能很大,因此請只解析您需要的欄位。
2340 2342
2341<Note>2343<Note>
2342 `tool_response` 形狀與 `PostToolUse` 的不同。`PostToolUse` 傳遞工具的結構化 `Output` 物件,例如 `Write` 的 `{filePath: "...", type: "create"}`;`PostToolBatch` 傳遞序列化 `tool_result` 內容模型看到的。2344 `tool_response` 的結構與 `PostToolUse` 的不同。`PostToolUse` 傳遞的是工具的結構化 `Output` 物件,例如 `Write` 的 `{filePath: "...", type: "create"}`;`PostToolBatch` 傳遞的則是模型看到的序列化 `tool_result` 內容。
2343</Note>2345</Note>
2344 2346
2345<h4 id="posttoolbatch-decision-control">2347<h4 id="posttoolbatch-decision-control">
2346 PostToolBatch 決策控制2348 PostToolBatch 決策控制
2347</h4>2349</h4>
2348 2350
2349`PostToolBatch` hooks 可以為 Claude 注入背景資訊。除了所有 hooks 可用的 [JSON 輸出欄位](#json-output) 外,您的 hook 指令碼可以返回這些事件特定的欄位:2351`PostToolBatch` hook 可以為 Claude 注入上下文。除了所有 hook 皆可使用的 [JSON 輸出欄位](#json-output)之外,您的 hook 指令碼還可以傳回以下事件專屬欄位:
2350 2352
2351| 欄位 | 描述 |2353| 欄位 | 說明 |
2352| :- | :- |2354| :- | :- |
2353| `additionalContext` | 在下一個模型呼叫之前注入一次的背景資訊字串。有關傳遞詳細資訊、要放入其中的內容以及恢復的工作階段如何處理過去的值,請參閱 [為 Claude 新增背景資訊](#add-context-for-claude) |2355| `additionalContext` | 在下一次模型呼叫之前注入一次的上下文字串。關於傳遞細節、應放入的內容,以及恢復的工作階段如何處理過去的值,請參閱[為 Claude 新增上下文](#add-context-for-claude) |
2354 2356
2355```json theme={null}2357```json theme={null}
2356{2358{
2361}2363}
2362```2364```
2363 2365
2364返回 `decision: "block"` 或 `continue: false` 在下一個模型呼叫之前停止代理迴圈。阻止訊息來自 JSON `reason` 或 `stopReason`,或來自退出 2 的 stderr。您在文字記錄中看到它作為警告,它保留在對話中,因此 Claude 在對話繼續時看到它。2366傳回 `decision: "block"` 或 `continue: false` 會在下一次模型呼叫之前停止代理式迴圈。封鎖訊息來自 JSON 的 `reason` 或 `stopReason`,或在退出碼 2 時來自 stderr。您會在逐字稿中看到它以警告形式呈現,且它會保留在對話中,因此對話繼續時 Claude 會看到它。
2365 2367
2366<h3 id="permissiondenied">2368<h3 id="permissiondenied">
2367 PermissionDenied2369 PermissionDenied
2368</h3>2370</h3>
2369 2371
2370在 [自動模式](/docs/zh-TW/permission-modes#eliminate-prompts-with-auto-mode) 拒絕工具呼叫時執行,包括當它拒絕而沒有分類器判決時,因為 [與自動模式分開的安全檢查拒絕了分類器自己的請求](/docs/zh-TW/errors#auto-mode-cannot-determine-the-safety-of-an-action) 或其回應未解析。此 hook 僅在自動模式中執行:當您手動拒絕權限對話、`PreToolUse` hook 阻止呼叫或 `deny` 規則匹配時,它不執行。使用它來記錄拒絕、調整配置或告訴模型它可能重試工具呼叫。2372當[自動模式](/docs/zh-TW/permission-modes#eliminate-prompts-with-auto-mode)拒絕工具呼叫時執行,包括因[與自動模式分開的安全檢查拒絕了分類器本身的請求](/docs/zh-TW/errors#auto-mode-cannot-determine-the-safety-of-an-action)或其回應無法解析,而在沒有分類器判定的情況下拒絕時。此 hook 只在自動模式下觸發:當您手動拒絕權限對話框、`PreToolUse` hook 封鎖呼叫,或 `deny` 規則相符時,它都不會執行。可用來記錄拒絕情況、調整設定,或告知模型可以重試該工具呼叫。
2371 2373
2372在工具名稱上匹配,與 PreToolUse 相同的值。2374依工具名稱比對,可用值與 PreToolUse 相同。
2373 2375
2374<h4 id="permissiondenied-input">2376<h4 id="permissiondenied-input">
2375 PermissionDenied 輸入2377 PermissionDenied 輸入
2376</h4>2378</h4>
2377 2379
2378除了 [常見輸入欄位](#common-input-fields) 外,PermissionDenied hooks 還會接收 `tool_name`、`tool_input`、`tool_use_id` 和 `reason`。對於 MCP 工具,它們也接收 [`mcp_server`](#pretooluse-input) 物件。2380除了[通用輸入欄位](#common-input-fields)之外,PermissionDenied hook 還會收到 `tool_name`、`tool_input`、`tool_use_id` 與 `reason`。對於 MCP 工具,它們也會收到 [`mcp_server`](#pretooluse-input) 物件。
2379 2381
2380```json theme={null}2382```json theme={null}
2381{2383{
2394}2396}
2395```2397```
2396 2398
2397| 欄位 | 描述 |2399| 欄位 | 說明 |
2398| :- | :- |2400| :- | :- |
2399| `reason` | 拒絕原因。對於分類器判決,在大多數工作階段中,它命名方括號中的匹配規則,例如 `[Data Exfiltration]`;有關其他形式,請參閱 [審查拒絕](/docs/zh-TW/auto-mode-config#review-denials)。對於 [無判決拒絕](#permissiondenied-decision-control),它以 `Auto mode could not evaluate this action and is blocking it for safety` 開頭。對於因分類器模型不可用而拒絕,它是固定文字 `Classifier unavailable` |2401| `reason` | 拒絕原因。對於分類器判定,在大多數工作階段中,它會以方括號標示相符的規則,例如 `[Data Exfiltration]`;其他形式請參閱[檢閱拒絕](/docs/zh-TW/auto-mode-config#review-denials)。對於[無判定的拒絕](#permissiondenied-decision-control),它以 `Auto mode could not evaluate this action and is blocking it for safety` 開頭。對於因分類器模型無法使用而造成的拒絕,它是固定文字 `Classifier unavailable` |
2400 2402
2401<h4 id="permissiondenied-decision-control">2403<h4 id="permissiondenied-decision-control">
2402 PermissionDenied 決策控制2404 PermissionDenied 決策控制
2403</h4>2405</h4>
2404 2406
2405PermissionDenied hooks 可以告訴模型它可能重試被拒絕的工具呼叫。返回一個 JSON 物件,其中 `hookSpecificOutput.retry` 設定為 `true`:2407PermissionDenied hook 可以告知模型它可以重試遭拒的工具呼叫。傳回將 `hookSpecificOutput.retry` 設為 `true` 的 JSON 物件:
2406 2408
2407```json theme={null}2409```json theme={null}
2408{2410{
2413}2415}
2414```2416```
2415 2417
2416當 `retry` 為 `true` 時,Claude Code 向對話新增一條訊息,告訴模型它可能重試工具呼叫。Claude Code 不反轉拒絕本身。如果您的 hook 不返回 JSON,或返回 `retry: false`,拒絕成立,模型接收原始拒絕訊息。2418當 `retry` 為 `true` 時,Claude Code 會在對話中加入一則訊息,告知模型可以重試該工具呼叫。Claude Code 本身不會撤銷拒絕。如果您的 hook 未傳回 JSON,或傳回 `retry: false`,拒絕將維持不變,模型會收到原始的拒絕訊息。
2417 2419
2418當分類器對動作產生 [無判決](/docs/zh-TW/errors#auto-mode-cannot-determine-the-safety-of-an-action) 時,Claude Code 忽略 `retry: true`:其回應未解析,或與自動模式分開的安全檢查拒絕了分類器自己的請求。對於這些拒絕,Claude Code 已在拒絕訊息中告訴模型是否稍後重試或繼續。2420當分類器[未對該動作做出判定](/docs/zh-TW/errors#auto-mode-cannot-determine-the-safety-of-an-action)時,Claude Code 會忽略 `retry: true`:即其回應無法解析,或與自動模式分開的安全檢查拒絕了分類器本身的請求。對於這些拒絕,Claude Code 已會在拒絕訊息中告知模型應稍後重試或繼續進行其他工作。
2419 2421
2420<h3 id="notification">2422<h3 id="notification">
2421 Notification2423 Notification
2422</h3>2424</h3>
2423 2425
2424在 Claude Code 傳送通知時執行。在通知類型上匹配。省略匹配器以對所有通知類型執行 hooks。2426在 Claude Code 傳送通知時執行。依通知類型比對。省略 matcher 即可針對所有通知類型執行 hook。
2425 2427
2426即使桌面通知關閉,您也會接收這些 hook 事件:`preferredNotifChannel` 設定(包括 `notifications_disabled`)僅更改您如何被警報,而不是您的 hook 是否執行。2428即使關閉桌面通知,您仍會收到這些 hook 事件:`preferredNotifChannel` 設定(包括 `notifications_disabled`)只會改變提醒您的方式,不會影響您的 hook 是否執行。
2427 2429
2428| 匹配器 | 何時觸發 |2430| Matcher | 觸發時機 |
2429| :- | :- |2431| :- | :- |
2430| `permission_prompt` | Claude 需要您核准工具使用或沙箱命令的 [網路請求](/docs/zh-TW/sandboxing#network-isolation),提示已等待約六秒 |2432| `permission_prompt` | Claude 需要您核准工具使用或沙箱命令的[網路請求](/docs/zh-TW/sandboxing#network-isolation),且提示已等待約六秒 |
2431| `idle_prompt` | Claude 約 60 秒前完成回應,您自那以後未輸入 |2433| `idle_prompt` | Claude 約在 60 秒前完成回應,且您此後未曾輸入 |
2432| `auth_success` | 驗證完成 |2434| `auth_success` | 身分驗證完成 |
2433| `elicitation_dialog` | MCP 伺服器開啟引出表單,您約六秒未輸入 |2435| `elicitation_dialog` | MCP 伺服器開啟 elicitation 表單,且您約六秒未輸入 |
2434| `elicitation_url_dialog` | MCP 伺服器要求您開啟瀏覽器 URL,您約六秒未輸入 |2436| `elicitation_url_dialog` | MCP 伺服器要求您開啟瀏覽器 URL,且您約六秒未輸入 |
2435| `elicitation_complete` | MCP 伺服器報告 [URL 模式引出](#elicitation-input) 完成 |2437| `elicitation_complete` | MCP 伺服器回報 [URL 模式 elicitation](#elicitation-input) 已完成 |
2436| `elicitation_response` | MCP 引出回應傳送回伺服器 |2438| `elicitation_response` | MCP elicitation 回應已傳回伺服器 |
2437| `agent_needs_input` | 背景工作階段在 [agent view](/docs/zh-TW/agent-view) 在終端中開啟時開始等待您的輸入,或目前工作階段詢問您 [agent team 隊友的終端設定問題](/docs/zh-TW/agent-teams#choose-a-display-mode) 或自動模式的 [分類器請求費用通知](/docs/zh-TW/auto-mode-classifier-billing),您約六秒未輸入 |2439| `agent_needs_input` | 當 [agent view](/docs/zh-TW/agent-view) 在終端機中開啟時,背景工作階段開始等待您的輸入。當終端機工作階段向您顯示 [agent team 隊員的終端機設定問題](/docs/zh-TW/agent-teams#choose-a-display-mode)或自動模式關於[分類器請求費用](/docs/zh-TW/auto-mode-classifier-billing)的通知,且您約六秒未輸入時,也會觸發 |
2438| `agent_completed` | 背景工作階段完成或失敗。僅在 [agent view](/docs/zh-TW/agent-view) 在終端中開啟時執行 |2440| `agent_completed` | 背景工作階段完成或失敗。僅在 [agent view](/docs/zh-TW/agent-view) 於終端機中開啟時觸發 |
2439| `quota_auto_resume_fired` | Claude Code 在 claude.ai 使用限制暫停您的任務後繼續它:在重設時,或更早當您在 Claude Code 中做某事時,例如新增使用額度、升級您的計畫或切換模型,使使用可用,具有 [模型設定例外](/docs/zh-TW/interactive-mode#wait-for-a-usage-limit-to-reset) |2441| `quota_auto_resume_fired` | Claude Code 在 claude.ai 用量上限暫停您的任務後繼續執行:於重設時,或當您在等待期間於 Claude Code 中執行的某些操作(例如新增用量點數、升級方案或切換模型)使用量再次可用時提前繼續,但有[模型設定例外](/docs/zh-TW/interactive-mode#wait-for-a-usage-limit-to-reset) |
2440| `quota_auto_resume_stale` | claude.ai 使用限制在您的電腦睡眠超過約 30 分鐘時重設。Claude Code 等待您按 `Enter` 而不是繼續。在較短的睡眠後,它繼續並改為執行 `quota_auto_resume_fired` |2442| `quota_auto_resume_stale` | claude.ai 用量上限在您的電腦休眠超過約 30 分鐘期間重設。Claude Code 會等待您按下 `Enter`,而不是自動繼續。若休眠時間較短,則會繼續並改為觸發 `quota_auto_resume_fired` |
2441| `quota_auto_resume_disabled` | Claude Code 結束其對 claude.ai 使用限制的等待,而不繼續您的任務:[`autoContinueAtUsageLimit`](/docs/zh-TW/settings-reference#autocontinueatusagelimit) 關閉或重設在 Claude Code 自己啟動的等待期間移動超過 24 小時,繼續的任務持續命中限制,或繼續在到達模型之前被阻止。當您按 `Esc` 或 `Ctrl+C` 或選擇 **不自動繼續** 時不執行 |2443| `quota_auto_resume_disabled` | Claude Code 結束對 claude.ai 用量上限的等待,但未繼續您的任務:[`autoContinueAtUsageLimit`](/docs/zh-TW/settings-reference#autocontinueatusagelimit) 已關閉,或在 Claude Code 自行開始的等待期間重設時間延後超過 24 小時、繼續的任務持續觸及上限,或繼續操作在抵達模型前遭到封鎖。當您按下 `Esc` 或 `Ctrl+C`,或選擇 **Don't continue automatically** 時不會觸發 |
2442 2444
2443`quota_auto_resume_fired`、`quota_auto_resume_stale` 和 `quota_auto_resume_disabled` 類型需要 Claude Code v2.1.234 或更新版本。2445`quota_auto_resume_fired`、`quota_auto_resume_stale` 與 `quota_auto_resume_disabled` 類型需要 Claude Code v2.1.234 或更新版本。
2444 2446
2445在終端工作階段中,沙箱命令的網路請求的 `permission_prompt` 需要 Claude Code v2.1.246 或更新版本。2447在終端機工作階段中,針對沙箱命令網路請求的 `permission_prompt` 需要 Claude Code v2.1.246 或更新版本。
2446 2448
2447隊友終端設定問題的 `agent_needs_input` 需要 Claude Code v2.1.248 或更新版本。2449針對隊員終端機設定問題的 `agent_needs_input` 需要 Claude Code v2.1.248 或更新版本。
2448 2450
2449<Note>2451<Note>
2450 `permission_prompt`、`idle_prompt`、`elicitation_dialog` 和 `elicitation_url_dialog` 類型與桌面通知共享其計時,因此在終端工作階段中,您僅在您似乎遠離終端時看到它們:2452 `permission_prompt`、`idle_prompt`、`elicitation_dialog` 與 `elicitation_url_dialog` 類型與桌面通知共用相同的計時方式,因此在終端機工作階段中,只有當您看起來已離開終端機時才會看到它們:
2451 2453
2452 * 預期 `permission_prompt` 一旦您約六秒未輸入。計時器在權限提示出現時啟動,每次按鍵都會延遲它。要在 Claude 要求許可使用工具時立即執行 hook,請改用 [PermissionRequest](#permissionrequest)。2454 * 當您約六秒未輸入時,預期會出現 `permission_prompt`。計時器在權限提示出現時開始,每次按鍵都會使其延後。若要在 Claude 要求使用工具的權限時立即執行 hook,請改用 [PermissionRequest](#permissionrequest)。
2453 * 預期 `idle_prompt` 約 60 秒後 Claude 完成回應,並且僅當您自那以後未輸入時。Claude Code 在等待 claude.ai 使用限制重設時不傳送 `idle_prompt`。當等待自己結束時,其中一個 `quota_auto_resume_*` 類型執行。2455 * 預期 `idle_prompt` 會在 Claude 完成回應約 60 秒後出現,且僅在您此後未曾輸入,並且沒有背景 agent(例如背景 [subagent](/docs/zh-TW/sub-agents))仍在執行時才會出現。Claude Code 在等待 claude.ai 用量上限重設期間不會傳送 `idle_prompt`。當等待自行結束時,會改為觸發其中一種 `quota_auto_resume_*` 類型。
2454 * 預期 `elicitation_dialog` 用於引出表單,或 `elicitation_url_dialog` 用於瀏覽器 URL 請求,一旦您約六秒未輸入。兩者共享與 `permission_prompt` 相同的六秒閘門:計時器在對話出現時啟動,每次按鍵都會延遲它。2456 * 當您約六秒未輸入時,預期會出現 `elicitation_dialog`(針對 elicitation 表單)或 `elicitation_url_dialog`(針對瀏覽器 URL 請求)。兩者與 `permission_prompt` 共用相同的六秒門檻:計時器在對話框出現時開始,每次按鍵都會使其延後。
2455 2457
2456 在另一個對話在螢幕上時到達的權限請求或引出保持相同的六秒閘門,從請求到達時計時。其通知可以在請求仍在等待時到達您。2458 在另一個對話框顯示於畫面上時抵達的權限請求或 elicitation,會維持相同的六秒門檻,並從請求抵達時開始計時。即使該請求仍在已開啟的對話框後方等待,其通知也可能送達您。
2457</Note>2459</Note>
2458 2460
2459Claude Code 在將權限請求傳送給 Agent SDK 的 [`canUseTool` 回呼](/docs/zh-TW/agent-sdk/user-input) 的工作階段中以不同方式計時 `permission_prompt`,這是 Claude Desktop 和 VS Code 擴充功能主機 Claude Code 的方式:2461在 Claude Code 將權限請求傳送給 Agent SDK 的 [`canUseTool` 回呼](/docs/zh-TW/agent-sdk/user-input)的工作階段中(Claude Desktop 與 VS Code 擴充功能即以此方式託管 Claude Code),Claude Code 對 `permission_prompt` 的計時方式有所不同:
2460 2462
2461* 預期 `permission_prompt` 約六秒後 Claude 要求許可。Claude Code 在您輸入時不延遲它。2463* 預期 `permission_prompt` 會在 Claude 要求權限約六秒後出現。Claude Code 不會因您輸入而延後它。
2462* 如果您或 [PermissionRequest](#permissionrequest) hook 更早回答,Claude Code 不執行 `permission_prompt`。2464* 如果您或 [PermissionRequest](#permissionrequest) hook 較早回應,Claude Code 不會執行 `permission_prompt`。
2463* 設定 [`CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS`](/docs/zh-TW/env-vars) 為 `1` 以在這些工作階段中關閉 `permission_prompt`。2465* 將 [`CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS`](/docs/zh-TW/env-vars) 設為 `1`,即可在這些工作階段中關閉 `permission_prompt`。
2464 2466
2465在 v2.1.233 之前,`permission_prompt` 在這些工作階段中不執行。2467在 v2.1.233 之前,`permission_prompt` 不會在這些工作階段中觸發。
2466 2468
2467使用單獨的匹配器根據通知類型執行不同的處理程式。此配置在 Claude 需要權限核准時觸發權限特定的警報指令碼,以及在 Claude 閒置時觸發不同的通知:2469使用不同的 matcher,即可依通知類型執行不同的處理常式。此設定會在 Claude 需要權限核准時觸發權限專用的警示指令碼,並在 Claude 閒置時觸發另一個通知:
2468 2470
2469```json theme={null}2471```json theme={null}
2470{2472{
2497 Notification 輸入2499 Notification 輸入
2498</h4>2500</h4>
2499 2501
2500除了 [常見輸入欄位](#common-input-fields) 外,Notification hooks 還會接收 `message` 搭配通知文字、可選的 `title` 和 `notification_type` 指示哪個類型執行。2502除了[通用輸入欄位](#common-input-fields)之外,Notification hook 還會收到含有通知文字的 `message`、選用的 `title`,以及指出觸發類型的 `notification_type`。
2501 2503
2502```json theme={null}2504```json theme={null}
2503{2505{
2511}2513}
2512```2514```
2513 2515
2514Notification hooks 無法阻止或修改通知。Claude Code 捨棄它們的 `systemMessage` 和 `continue` 欄位,但仍然發出 [`terminalSequence`](#emit-terminal-notifications),這是桌面通知範例所依賴的。Notification hooks 用於副作用,例如將通知轉發到外部服務。2516Notification hook 無法封鎖或修改通知。Claude Code 會捨棄其 `systemMessage` 與 `continue` 欄位,但仍會輸出 [`terminalSequence`](#emit-terminal-notifications),桌面通知範例即仰賴此欄位。Notification hook 的用途是執行副作用,例如將通知轉送至外部服務。
2515 2517
2516<h3 id="subagentstart">2518<h3 id="subagentstart">
2517 SubagentStart2519 SubagentStart
2518</h3>2520</h3>
2519 2521
2520在 Claude 使用 Agent 工具生成子代理時執行,當 Claude [恢復子代理](/docs/zh-TW/sub-agents#resume-subagents) 時,以及每次進程內 [agent team](/docs/zh-TW/agent-teams) 隊友處理新訊息時執行。支援匹配器以按代理類型名稱篩選。對於內建代理,這是代理名稱,例如 `general-purpose`、`Explore` 或 `Plan`。對於 [自訂子代理](/docs/zh-TW/sub-agents),這是代理 frontmatter 中的 `name` 欄位,而不是檔案名稱。2522當 Claude 使用 Agent 工具產生 subagent、當 Claude [恢復 subagent](/docs/zh-TW/sub-agents#resume-subagents),以及每當行程內 [agent team](/docs/zh-TW/agent-teams) 隊員處理新訊息時執行。支援以 matcher 依 agent 類型名稱篩選。對於內建 agent,這是 agent 名稱,例如 `general-purpose`、`Explore` 或 `Plan`。對於[自訂 subagent](/docs/zh-TW/sub-agents),這是 agent frontmatter 中的 `name` 欄位,而非檔案名稱。
2521 2523
2522對於由 [外掛](/docs/zh-TW/plugins/overview) 提供的子代理,代理類型是外掛範圍的識別碼,例如 `my-plugin:reviewer`,而不是裸露的 frontmatter 名稱。冒號將外掛範圍的名稱放在正規表達式路徑上,因此使用 `^` 和 `$` 錨定匹配器以進行精確匹配:`^my-plugin:reviewer$`。2524對於由[外掛](/docs/zh-TW/plugins/overview)提供的 subagent,agent 類型是外掛範圍的識別碼,例如 `my-plugin:reviewer`,而非單純的 frontmatter 名稱。冒號會使外掛範圍的名稱走正規表示式路徑,因此請以 `^` 與 `$` 錨定 matcher 以進行完全比對:`^my-plugin:reviewer$`。
2523 2525
2524<h4 id="subagentstart-input">2526<h4 id="subagentstart-input">
2525 SubagentStart 輸入2527 SubagentStart 輸入
2526</h4>2528</h4>
2527 2529
2528除了 [常見輸入欄位](#common-input-fields) 外,SubagentStart hooks 還會接收 `agent_id` 搭配子代理的唯一識別碼和 `agent_type` 搭配匹配器篩選的代理名稱。2530除了[通用輸入欄位](#common-input-fields)之外,SubagentStart hook 還會收到含有 subagent 唯一識別碼的 `agent_id`,以及含有 matcher 篩選所依據之 agent 名稱的 `agent_type`。
2529 2531
2530```json theme={null}2532```json theme={null}
2531{2533{
2538}2540}
2539```2541```
2540 2542
2541SubagentStart hooks 無法阻止子代理建立,但它們可以將背景資訊注入到子代理中。除了所有 hooks 可用的 [JSON 輸出欄位](#json-output) 外,您可以返回:2543SubagentStart hook 無法封鎖 subagent 的建立,但可以將上下文注入 subagent。除了所有 hook 皆可使用的 [JSON 輸出欄位](#json-output)之外,您還可以傳回:
2542 2544
2543| 欄位 | 描述 |2545| 欄位 | 說明 |
2544| :- | :- |2546| :- | :- |
2545| `additionalContext` | 在子代理對話開始時、其第一個提示之前新增到子代理背景資訊的字串。有關詳細資訊,請參閱 [為 Claude 新增背景資訊](#add-context-for-claude) |2547| `additionalContext` | 在 subagent 對話開始時、其第一個提示詞之前加入其上下文的字串。請參閱[為 Claude 新增上下文](#add-context-for-claude) |
2546 2548
2547```json theme={null}2549```json theme={null}
2548{2550{
2553}2555}
2554```2556```
2555 2557
2556當 hook 再次對相同的子代理執行時,Claude Code 僅在子代理的背景資訊尚未保持來自較早執行的複本時注入返回的背景資訊。在啟動時注入的複本保留在位置,保持子代理的 [prompt cache](/docs/zh-TW/prompt-caching#subagents-and-the-cache) 完整。在 [自動壓縮](/docs/zh-TW/sub-agents#auto-compaction) 捨棄該複本後,Claude Code 再次注入下一次執行的背景資訊。2558當 hook 針對同一個 subagent 再次執行時,Claude Code 只會在 subagent 的上下文中尚未保有先前執行所注入的副本時,才注入傳回的上下文。啟動時注入的副本會保留在原處,使 subagent 的[提示快取](/docs/zh-TW/prompt-caching#subagents-and-the-cache)維持完整。在[自動壓縮](/docs/zh-TW/sub-agents#auto-compaction)捨棄該副本後,Claude Code 會再次注入下一次執行的上下文。
2557 2559
2558<h3 id="subagentstop">2560<h3 id="subagentstop">
2559 SubagentStop2561 SubagentStop
2560</h3>2562</h3>
2561 2563
2562在 Claude Code 子代理完成回應時執行。在代理類型上匹配,與 SubagentStart 相同的值。2564在 Claude Code subagent 完成回應時執行。依 agent 類型比對,可用值與 SubagentStart 相同。
2563 2565
2564<h4 id="subagentstop-input">2566<h4 id="subagentstop-input">
2565 SubagentStop 輸入2567 SubagentStop 輸入
2566</h4>2568</h4>
2567 2569
2568除了 [常見輸入欄位](#common-input-fields) 外,SubagentStop hooks 還會接收 `stop_hook_active`、`agent_id`、`agent_type`、`agent_transcript_path` 和 `last_assistant_message`。`agent_type` 欄位是用於匹配器篩選的值。`transcript_path` 是主工作階段的文字記錄,而 `agent_transcript_path` 是子代理自己的文字記錄,儲存在巢狀 `subagents/` 資料夾中。`last_assistant_message` 欄位包含子代理最終回應的文字內容,因此 hooks 可以存取它,而無需解析文字記錄檔案。2570除了[通用輸入欄位](#common-input-fields)之外,SubagentStop hook 還會收到 `stop_hook_active`、`agent_id`、`agent_type`、`agent_transcript_path` 與 `last_assistant_message`。`agent_type` 欄位是用於 matcher 篩選的值。`transcript_path` 是主工作階段的逐字稿,而 `agent_transcript_path` 則是 subagent 自己的逐字稿,儲存在巢狀的 `subagents/` 資料夾中。`last_assistant_message` 欄位包含 subagent 最終回應的文字內容,因此 hook 無需解析逐字稿檔案即可存取它。
2569 2571
2570並非每個 SubagentStop 事件都來自 Claude 生成的子代理。Claude Code 也為其某些自己的功能執行內部代理,例如 [提示建議](/docs/zh-TW/interactive-mode#prompt-suggestions) 和 [`/btw` 側問題](/docs/zh-TW/interactive-mode#side-questions-with-%2Fbtw),當其中一個完成時 SubagentStop 執行。對於這些事件,`agent_type` 是工作階段本身執行的代理名稱,例如使用 [`--agent`](/docs/zh-TW/cli-reference#cli-flags) 或 [`agent` 設定](/docs/zh-TW/settings-reference#agent) 設定的,以及當工作階段執行而不執行時的空字串。2572並非每個 SubagentStop 事件都來自 Claude 產生的 subagent。Claude Code 也會為其部分功能執行內部 agent,例如[提示詞建議](/docs/zh-TW/interactive-mode#prompt-suggestions)與 [`/btw` 旁支問題](/docs/zh-TW/interactive-mode#side-questions-with-%2Fbtw),這些 agent 完成時同樣會觸發 SubagentStop。對於這些事件,`agent_type` 是工作階段本身所執行的 agent 名稱,例如以 [`--agent`](/docs/zh-TW/cli-reference#cli-flags) 或 [`agent` 設定](/docs/zh-TW/settings-reference#agent)指定的名稱;若工作階段未指定任何 agent,則為空字串。
2571 2573
2572命名代理類型的 `matcher` 不匹配空 `agent_type`。其匹配器為省略、`""`、`"*"` 或是與空字串匹配的正規表達式的 hook 也對具有空 `agent_type` 的事件執行。2574指定 agent 類型的 `matcher` 不會比對到空的 `agent_type`。matcher 省略、為 `""` 或 `"*"`,或為可比對空字串之正規表示式的 hook,也會針對 `agent_type` 為空的事件執行。
2573 2575
2574在 Claude Code v2.1.271 或更新版本上,使用 [`SubagentHandback`](/docs/zh-TW/tools-reference) 工具執行的子代理(Claude Code 在 [自動模式](/docs/zh-TW/permission-modes#eliminate-prompts-with-auto-mode) 中提供)在停止之前透過該工具傳遞其報告。`last_assistant_message` 欄位然後保持子代理的結束文字(如果有),這不是傳遞的報告。報告是該呼叫的 `message` 輸入,`PreToolUse` 或 `PostToolUse` hook 匹配 `SubagentHandback` 接收作為 `tool_input.message`。2576在 Claude Code v2.1.271 或更新版本中,搭配 [`SubagentHandback`](/docs/zh-TW/tools-reference) 工具執行的 subagent 會在停止前透過該工具傳遞其報告。此時 `last_assistant_message` 欄位保存的是 subagent 的結尾文字(若有),而非所傳遞的報告。報告是該次呼叫的 `message` 輸入,比對 `SubagentHandback` 的 `PreToolUse` 或 `PostToolUse` hook 會以 `tool_input.message` 收到它。
2575 2577
2576SubagentStop hooks 也接收 [Stop input](#stop-input) 下描述的 `background_tasks` 和 `session_crons` 陣列。兩個陣列的範圍是父工作階段,而不是子代理。2578SubagentStop hook 也會收到 [Stop 輸入](#stop-input)中所述的 `background_tasks` 與 `session_crons` 陣列。這兩個陣列的範圍都是父工作階段,而非 subagent。
2577 2579
2578```json theme={null}2580```json theme={null}
2579{2581{
2592}2594}
2593```2595```
2594 2596
2595SubagentStop hooks 使用與 [Stop hooks](#stop-decision-control) 相同的決策控制格式,包括 `hookSpecificOutput.additionalContext` 搭配 `hookEventName` 設定為 `"SubagentStop"`,用於保持子代理執行的非錯誤反饋。返回 `decision: "block"` 搭配 `reason` 保持子代理執行並將 `reason` 作為其下一個指令傳遞給子代理。透過退出 2 阻止的 hook 以相同方式傳遞其 stderr 訊息。要在子代理返回後將背景資訊注入到父工作階段,請改用 `Agent` 工具上的 [`PostToolUse`](#posttooluse) hook。2597SubagentStop hook 使用與 [Stop hook](#stop-decision-control) 相同的決策控制格式,包括將 `hookEventName` 設為 `"SubagentStop"` 的 `hookSpecificOutput.additionalContext`,用於提供讓 subagent 繼續執行的非錯誤回饋。傳回附有 `reason` 的 `decision: "block"` 會讓 subagent 繼續執行,並將 `reason` 作為其下一個指令傳遞給 subagent。以退出碼 2 封鎖的 hook 也會以相同方式傳遞其 stderr 訊息。若要在 subagent 返回後將上下文注入父工作階段,請改用針對 `Agent` 工具的 [`PostToolUse`](#posttooluse) hook。
2596 2598
2597<h3 id="taskcreated">2599<h3 id="taskcreated">
2598 TaskCreated2600 TaskCreated
2599</h3>2601</h3>
2600 2602
2601在透過 `TaskCreate` 工具建立任務時執行。使用此來強制命名慣例、要求任務描述或防止建立某些任務。在 [沒有 Task 工具的工作階段](/docs/zh-TW/tools-reference#task-tool-availability) 中,此事件不執行。2603在透過 `TaskCreate` 工具建立任務時執行。可用來強制執行命名慣例、要求任務描述,或阻止特定任務被建立。在[不含 Task 工具的工作階段](/docs/zh-TW/tools-reference#task-tool-availability)中,此事件不會觸發。
2602 2604
2603TaskCreated hooks 不支援匹配器,對每個出現執行。2605TaskCreated hook 不支援 matcher,每次發生時都會觸發。
2604 2606
2605<h4 id="taskcreated-input">2607<h4 id="taskcreated-input">
2606 TaskCreated 輸入2608 TaskCreated 輸入
2607</h4>2609</h4>
2608 2610
2609除了 [常見輸入欄位](#common-input-fields) 外,TaskCreated hooks 還會接收 `task_id`、`task_subject` 和可選的 `task_description`、`teammate_name` 和 `team_name`。2611除了[通用輸入欄位](#common-input-fields)之外,TaskCreated hook 還會收到 `task_id`、`task_subject`,以及選用的 `task_description`、`teammate_name` 與 `team_name`。
2610 2612
2611```json theme={null}2613```json theme={null}
2612{2614{
2622}2624}
2623```2625```
2624 2626
2625| 欄位 | 描述 |2627| 欄位 | 說明 |
2626| :- | :- |2628| :- | :- |
2627| `task_id` | 正在建立的任務的識別碼 |2629| `task_id` | 正在建立之任務的識別碼 |
2628| `task_subject` | 任務的標題 |2630| `task_subject` | 任務標題 |
2629| `task_description` | 任務的詳細描述。可能不存在 |2631| `task_description` | 任務的詳細描述。可能不存在 |
2630| `teammate_name` | 建立任務的隊友的名稱。可能不存在 |2632| `teammate_name` | 建立任務之隊員的名稱。可能不存在 |
2631| `team_name` | 已棄用。工作階段衍生的團隊名稱;將在未來版本中移除 |2633| `team_name` | 已棄用。由工作階段衍生的團隊名稱;將在未來版本中移除 |
2632 2634
2633<h4 id="taskcreated-decision-control">2635<h4 id="taskcreated-decision-control">
2634 TaskCreated 決策控制2636 TaskCreated 決策控制
2635</h4>2637</h4>
2636 2638
2637TaskCreated hook 可以透過兩種方式阻止建立。任一方式,Claude Code 刪除任務並將您的訊息作為工具的錯誤返回給 Claude。Claude Code 忽略此事件的 `continue: false`,Claude 繼續工作。2639TaskCreated hook 可以透過兩種方式封鎖建立。無論哪種方式,Claude Code 都會刪除該任務,並將您的訊息作為工具錯誤傳回給 Claude。Claude Code 會忽略此事件的 `continue: false`,Claude 會繼續工作。
2638 2640
2639* **退出代碼 2**:Claude Code 將 stderr 文字作為訊息返回。2641* **退出碼 2**:Claude Code 將 stderr 文字作為訊息傳回。
2640* **JSON `{"decision": "block", "reason": "..."}`**:Claude Code 將 `reason` 作為訊息返回。2642* **JSON `{"decision": "block", "reason": "..."}`**:Claude Code 將 `reason` 作為訊息傳回。
2641 2643
2642此範例阻止主題不遵循所需格式的任務:2644此範例會封鎖主旨不符合所需格式的任務:
2643 2645
2644```bash theme={null}2646```bash theme={null}
2645#!/bin/bash2647#!/bin/bash
2658 TaskCompleted2660 TaskCompleted
2659</h3>2661</h3>
2660 2662
2661在任務被標記為完成時執行。這在兩種情況下執行:當任何代理透過 TaskUpdate 工具明確標記任務為完成時,或當 [agent team](/docs/zh-TW/agent-teams) 隊友以進行中的任務完成其回合時。使用此來強制完成標準,例如通過測試或 lint 檢查,然後任務才能關閉。2663在任務即將被標記為已完成時執行。這會在兩種情況下觸發:任何 agent 透過 TaskUpdate 工具明確將任務標記為已完成時,或 [agent team](/docs/zh-TW/agent-teams) 隊員在仍有進行中任務的情況下結束其回合時。可用來在任務關閉前強制執行完成條件,例如通過測試或 lint 檢查。
2662 2664
2663TaskCompleted hooks 不支援匹配器,對每個出現執行。2665TaskCompleted hook 不支援 matcher,每次發生時都會觸發。
2664 2666
2665<h4 id="taskcompleted-input">2667<h4 id="taskcompleted-input">
2666 TaskCompleted 輸入2668 TaskCompleted 輸入
2667</h4>2669</h4>
2668 2670
2669除了 [常見輸入欄位](#common-input-fields) 外,TaskCompleted hooks 還會接收 `task_id`、`task_subject` 和可選的 `task_description`、`teammate_name` 和 `team_name`。2671除了[通用輸入欄位](#common-input-fields)之外,TaskCompleted hook 還會收到 `task_id`、`task_subject`,以及選用的 `task_description`、`teammate_name` 與 `team_name`。
2670 2672
2671```json theme={null}2673```json theme={null}
2672{2674{
2683}2685}
2684```2686```
2685 2687
2686| 欄位 | 描述 |2688| 欄位 | 說明 |
2687| :- | :- |2689| :- | :- |
2688| `task_id` | 正在完成的任務的識別碼 |2690| `task_id` | 正在完成之任務的識別碼 |
2689| `task_subject` | 任務的標題 |2691| `task_subject` | 任務標題 |
2690| `task_description` | 任務的詳細描述。可能不存在 |2692| `task_description` | 任務的詳細描述。可能不存在 |
2691| `teammate_name` | 完成任務的隊友的名稱。可能不存在 |2693| `teammate_name` | 完成任務之隊員的名稱。可能不存在 |
2692| `team_name` | 已棄用。工作階段衍生的團隊名稱;將在未來版本中移除 |2694| `team_name` | 已棄用。由工作階段衍生的團隊名稱;將在未來版本中移除 |
2693 2695
2694<h4 id="taskcompleted-decision-control">2696<h4 id="taskcompleted-decision-control">
2695 TaskCompleted 決策控制2697 TaskCompleted 決策控制
2696</h4>2698</h4>
2697 2699
2698TaskCompleted hooks 支援兩種方式來控制任務完成:2700TaskCompleted hook 支援兩種控制任務完成的方式:
2699 2701
2700* **退出代碼 2**:任務未被標記為完成,stderr 訊息作為反饋反饋給模型。2702* **退出碼 2**:任務不會被標記為已完成,stderr 訊息會作為回饋傳回給模型。
2701* **JSON `{"continue": false, "stopReason": "..."}`**:當隊友完成其回合觸發事件時,完全停止隊友,匹配 `Stop` hook 行為。`stopReason` 顯示給使用者。當 `TaskUpdate` 工具觸發事件時,Claude Code 忽略 `continue: false`;退出代碼 2 仍然阻止完成。2703* **JSON `{"continue": false, "stopReason": "..."}`**:當事件是由隊員結束其回合所觸發時,會完全停止該隊員,與 `Stop` hook 的行為一致。`stopReason` 會顯示給使用者。當事件是由 `TaskUpdate` 工具觸發時,Claude Code 會忽略 `continue: false`;退出碼 2 仍會封鎖完成。
2702 2704
2703此範例執行測試並在它們失敗時阻止任務完成:2705此範例會執行測試,並在測試失敗時封鎖任務完成:
2704 2706
2705```bash theme={null}2707```bash theme={null}
2706#!/bin/bash2708#!/bin/bash
2720 Stop2722 Stop
2721</h3>2723</h3>
2722 2724
2723在主 Claude Code 代理完成回應時執行。如果停止是由於使用者中斷而發生,則不執行。API 錯誤改為執行 [StopFailure](#stopfailure)。2725在主要 Claude Code agent 完成回應時執行。若停止是由使用者中斷所造成,則不會執行。API 錯誤會改為觸發
2726[StopFailure](#stopfailure)。
2724 2727
2725<Tip>2728<Tip>
2726 [`/goal`](/docs/zh-TW/goal) 命令是工作階段範圍提示型 Stop hook 的內建快捷方式。當您想讓 Claude 在不編寫 hook 配置的情況下朝著條件工作時,使用它。2729 [`/goal`](/docs/zh-TW/goal) 命令是工作階段範圍、以提示詞為基礎之 Stop hook 的內建捷徑。當您希望 Claude 持續朝某個條件努力,而不想撰寫 hook 設定時,可以使用它。
2727</Tip>2730</Tip>
2728 2731
2729<h4 id="stop-input">2732<h4 id="stop-input">
2730 Stop 輸入2733 Stop 輸入
2731</h4>2734</h4>
2732 2735
2733除了 [常見輸入欄位](#common-input-fields) 外,Stop hooks 還會接收 `stop_hook_active`、`last_assistant_message`、`background_tasks` 和 `session_crons`。`stop_hook_active` 欄位在 Claude Code 已作為 stop hook 的結果繼續時為 `true`。檢查此值或處理文字記錄以避免在永遠不會解決的條件上阻止。Claude Code 應用 8 連續繼續上限:在 stop hooks 連續繼續回合八次後,Claude Code 覆寫下一個阻止並結束回合。要提高上限,設定 [`CLAUDE_CODE_STOP_HOOK_BLOCK_CAP`](/docs/zh-TW/env-vars)。2736除了[通用輸入欄位](#common-input-fields)之外,Stop hook 還會收到 `stop_hook_active`、`last_assistant_message`、`background_tasks` 與 `session_crons`。當 Claude Code 已因 stop hook 而繼續執行時,`stop_hook_active` 欄位為 `true`。請檢查此值或處理逐字稿,以避免因永遠無法解決的條件而持續封鎖。Claude Code 套用連續 8 次繼續的上限:在 stop hook 連續讓回合繼續八次後,Claude Code 會覆寫下一次封鎖並結束回合。若要提高上限,請設定 [`CLAUDE_CODE_STOP_HOOK_BLOCK_CAP`](/docs/zh-TW/env-vars)。
2734 2737
2735`last_assistant_message` 欄位包含 Claude 最終回應的文字內容,因此 hooks 可以存取它,而無需解析文字記錄檔案。對於作用於剛完成的回合的 hooks,例如朗讀或通知 hooks,使用此欄位而不是讀取 `transcript_path`:文字記錄檔案不保證在所有版本的 Stop 時間包含最終訊息。2738`last_assistant_message` 欄位包含 Claude 最終回應的文字內容,因此 hook 無需解析逐字稿檔案即可存取它。對於針對剛完成之回合採取動作的 hook(例如朗讀或通知 hook),請使用此欄位,而非讀取 `transcript_path`:並非所有版本都保證逐字稿檔案在 Stop 時已包含最終訊息。
2736 2739
2737`background_tasks` 和 `session_crons` 陣列讓 hooks 區分「工作階段完成」與「工作階段暫停等待背景工作喚醒它」。當任務登錄可到達時兩個陣列都存在,當沒有任何內容在執行或排程時為空。2740`background_tasks` 與 `session_crons` 陣列讓 hook 能夠區分「工作階段已完成」與「工作階段已暫停,等待背景工作將其喚醒」。當任務登錄可存取時,兩個陣列都會存在;若沒有正在進行或已排程的項目,則為空陣列。
2738 2741
2739`background_tasks` 中的每個項目描述一個進行中的任務,並使用這些欄位:2742`background_tasks` 中的每個項目描述一個正在進行的任務,並使用以下欄位:
2740 2743
2741| 欄位 | 描述 |2744| 欄位 | 說明 |
2742| :- | :- |2745| :- | :- |
2743| `id` | 任務識別碼 |2746| `id` | 任務識別碼 |
2744| `type` | 友善的任務類型標籤,例如 `shell`、`subagent`、`monitor`、`workflow`、`teammate`、`cloud session` 或 `MCP task`。每個標籤識別哪個 Claude Code 功能建立了任務。對於無法識別的類型,回退到原始判別式 |2747| `type` | 易讀的任務類型標籤,例如 `shell`、`subagent`、`monitor`、`workflow`、`teammate`、`cloud session` 或 `MCP task`。每個標籤識別建立該任務的 Claude Code 功能。對於無法辨識的類型,會退回使用原始判別值 |
2745| `status` | 目前任務狀態 |2748| `status` | 目前的任務狀態 |
2746| `description` | 自由文字描述,上限為 1000 個字元,當剪裁時帶有字串內 `… [+N chars]` 標記 |2749| `description` | 自由文字描述,上限為 1000 個字元,截斷時字串中會帶有 `… [+N chars]` 標記 |
2747| `command` | Shell 命令行,上限為 1000 個字元。僅對 `shell` 任務出現 |2750| `command` | shell 命令列,上限為 1000 個字元。僅存在於 `shell` 任務 |
2748| `agent_type` | 子代理類型名稱。僅對 `subagent` 任務出現 |2751| `agent_type` | subagent 類型名稱。僅存在於 `subagent` 任務 |
2749| `server` | MCP 伺服器名稱。僅對 `monitor` 和 `MCP task` 任務出現 |2752| `server` | MCP 伺服器名稱。僅存在於 `monitor` 與 `MCP task` 任務 |
2750| `tool` | MCP 工具名稱。僅對 `monitor` 和 `MCP task` 任務出現 |2753| `tool` | MCP 工具名稱。僅存在於 `monitor` 與 `MCP task` 任務 |
2751| `name` | 工作流程名稱。僅對 `workflow` 任務出現 |2754| `name` | 工作流程名稱。僅存在於 `workflow` 任務 |
2752 2755
2753`session_crons` 中的每個項目描述一個工作階段範圍的排程喚醒,來自 `CronCreate`、`ScheduleWakeup` 和 `/loop`:2756`session_crons` 中的每個項目描述一個工作階段範圍的排程喚醒,來源為 `CronCreate`、`ScheduleWakeup` 與 `/loop`:
2754 2757
2755| 欄位 | 描述 |2758| 欄位 | 說明 |
2756| :- | :- |2759| :- | :- |
2757| `id` | Cron 任務識別碼 |2760| `id` | Cron 任務識別碼 |
2758| `schedule` | Cron 表達式,例如 `0 9 * * 1-5` |2761| `schedule` | Cron 運算式,例如 `0 9 * * 1-5` |
2759| `recurring` | 對於其排程編碼單個執行時間的一次性喚醒為 `false`,對於在每個匹配上重新執行的任務為 `true` |2762| `recurring` | 對於排程只編碼單一觸發時間的一次性喚醒為 `false`,對於每次相符時都會再次觸發的任務為 `true` |
2760| `prompt` | 當 cron 執行時提交的提示,上限為 1000 個字元,具有相同的 `… [+N chars]` 標記 |2763| `prompt` | cron 觸發時送出的提示詞,上限為 1000 個字元,並帶有相同的 `… [+N chars]` 標記 |
2761 2764
2762此範例顯示具有一個進行中的 shell 任務和一個循環 cron 的 Stop 輸入:2765此範例顯示含有一個正在進行之 shell 任務與一個週期性 cron 的 Stop 輸入:
2763 2766
2764```json theme={null}2767```json theme={null}
2765{2768{
2794 Stop 決策控制2797 Stop 決策控制
2795</h4>2798</h4>
2796 2799
2797`Stop` 和 `SubagentStop` hooks 可以控制 Claude 是否繼續。除了所有 hooks 可用的 [JSON 輸出欄位](#json-output) 外,您的 hook 指令碼可以返回這些事件特定的欄位:2800`Stop` 與 `SubagentStop` hook 可以控制 Claude 是否繼續。除了所有 hook 皆可使用的 [JSON 輸出欄位](#json-output)之外,您的 hook 指令碼還可以傳回以下事件專屬欄位:
2798 2801
2799| 欄位 | 描述 |2802| 欄位 | 說明 |
2800| :- | :- |2803| :- | :- |
2801| `decision` | `"block"` 防止 Claude 停止。省略以允許 Claude 停止 |2804| `decision` | `"block"` 會阻止 Claude 停止。省略即允許 Claude 停止 |
2802| `reason` | 當 `decision` 為 `"block"` 時需要。告訴 Claude 為什麼它應該繼續 |2805| `reason` | 當 `decision` 為 `"block"` 時為必填。告訴 Claude 為何應繼續 |
2803| `hookSpecificOutput.additionalContext` | Claude 的非錯誤反饋。對話繼續,以便 Claude 可以作用於它,但與 `decision: "block"` 不同,它在文字記錄中顯示為 hook 反饋,而不是 hook 錯誤 |2806| `hookSpecificOutput.additionalContext` | 提供給 Claude 的非錯誤回饋。對話會繼續,讓 Claude 能據以行動,但與 `decision: "block"` 不同,它在逐字稿中會顯示為 hook 回饋,而非 hook 錯誤 |
2804 2807
2805透過退出 2 阻止的 hook 路由方式與 `reason` 相同:Claude 接收 stderr 訊息作為為什麼它應該繼續的解釋。2808以退出碼 2 封鎖的 hook,其處理方式與 `reason` 相同:Claude 會收到 stderr 訊息,作為它應繼續的原因說明。
2806 2809
2807```json theme={null}2810```json theme={null}
2808{2811{
2811}2814}
2812```2815```
2813 2816
2814當 hook 按設計工作並給予 Claude 指導時,使用 `additionalContext`,例如「在完成前執行測試套件」。它透過與 `decision: "block"` 相同的迴圈保護保持對話進行,即 `stop_hook_active` 輸入和 8 連續繼續上限,但文字記錄將其標籤為 `Stop hook feedback`,不顯示 hook 錯誤通知:2817當 hook 依設計運作並為 Claude 提供指引時(例如「完成前請執行測試套件」),請使用 `additionalContext`。它會透過與 `decision: "block"` 相同的迴圈保護機制讓對話繼續,即 `stop_hook_active` 輸入與連續 8 次繼續的上限,但逐字稿會將其標示為 `Stop hook feedback`,且不會顯示 hook 錯誤通知:
2815 2818
2816```json theme={null}2819```json theme={null}
2817{2820{
2826 StopFailure2829 StopFailure
2827</h3>2830</h3>
2828 2831
2829在回合因 API 錯誤而結束時執行,而不是 [Stop](#stop)。Claude Code 忽略 hook 的輸出和退出代碼,除了 [`terminalSequence`](#emit-terminal-notifications)。使用此來記錄失敗、傳送警報或在 Claude 因速率限制、驗證問題或其他 API 錯誤而無法完成回應時採取恢復動作。2832當回合因 API 錯誤而結束時,取代 [Stop](#stop) 執行。除了 [`terminalSequence`](#emit-terminal-notifications) 之外,Claude Code 會忽略此 hook 的輸出與退出碼。當 Claude 因速率限制、身分驗證問題或其他 API 錯誤而無法完成回應時,可用來記錄失敗、傳送警示或採取復原動作。
2830 2833
2831<h4 id="stopfailure-input">2834<h4 id="stopfailure-input">
2832 StopFailure 輸入2835 StopFailure 輸入
2833</h4>2836</h4>
2834 2837
2835除了 [常見輸入欄位](#common-input-fields) 外,StopFailure hooks 還會接收 `error`、可選的 `error_details` 和可選的 `last_assistant_message`。`error` 欄位識別錯誤類型,用於匹配器篩選。2838除了[通用輸入欄位](#common-input-fields)之外,StopFailure hook 還會收到 `error`、選用的 `error_details` 與選用的 `last_assistant_message`。`error` 欄位識別錯誤類型,並用於 matcher 篩選。
2836 2839
2837| 欄位 | 描述 |2840| 欄位 | 說明 |
2838| :- | :- |2841| :- | :- |
2839| `error` | 錯誤類型:`rate_limit`、`overloaded`、`authentication_failed`、`oauth_org_not_allowed`、`account_on_hold`、`billing_error`、`invalid_request`、`model_not_found`、`server_error`、`max_output_tokens`、`cloud_credential_error` 或 `unknown` |2842| `error` | 錯誤類型:`rate_limit`、`overloaded`、`authentication_failed`、`oauth_org_not_allowed`、`account_on_hold`、`billing_error`、`invalid_request`、`model_not_found`、`server_error`、`max_output_tokens`、`cloud_credential_error` 或 `unknown` |
2840| `error_details` | 關於錯誤的其他詳細資訊(如果可用) |2843| `error_details` | 關於錯誤的其他細節(若有) |
2841| `last_assistant_message` | 在對話中顯示的呈現錯誤文字。與 `Stop` 和 `SubagentStop` 不同,其中此欄位保持 Claude 的對話輸出,對於 `StopFailure` 它包含 API 錯誤字串本身,例如 `"API Error: Rate limit reached"` |2844| `last_assistant_message` | 對話中顯示的錯誤文字。與 `Stop` 和 `SubagentStop` 中此欄位保存 Claude 對話輸出的情況不同,對於 `StopFailure`,它包含 API 錯誤字串本身,例如 `"API Error: Rate limit reached"` |
2842 2845
2843```json theme={null}2846```json theme={null}
2844{2847{
2852}2855}
2853```2856```
2854 2857
2855StopFailure hooks 沒有決策控制。它們僅用於通知和記錄目的執行。2858StopFailure hook 沒有決策控制。它們僅用於通知與記錄日誌。
2856 2859
2857<h3 id="teammateidle">2860<h3 id="teammateidle">
2858 TeammateIdle2861 TeammateIdle
2859</h3>2862</h3>
2860 2863
2861在 [agent team](/docs/zh-TW/agent-teams) 隊友在完成其回合後即將閒置時執行。使用此來強制品質閘門,然後隊友停止工作,例如要求通過 lint 檢查或驗證輸出檔案存在。2864當 [agent team](/docs/zh-TW/agent-teams) 隊員在結束其回合後即將進入閒置狀態時執行。可用來在隊員停止工作前強制執行品質關卡,例如要求通過 lint 檢查或確認輸出檔案存在。
2862 2865
2863TeammateIdle hooks 不支援匹配器,對每個出現執行。2866TeammateIdle hook 不支援 matcher,每次發生時都會觸發。
2864 2867
2865<h4 id="teammateidle-input">2868<h4 id="teammateidle-input">
2866 TeammateIdle 輸入2869 TeammateIdle 輸入
2867</h4>2870</h4>
2868 2871
2869除了 [常見輸入欄位](#common-input-fields) 外,TeammateIdle hooks 還會接收 `teammate_name` 和 `team_name`。2872除了[通用輸入欄位](#common-input-fields)之外,TeammateIdle hook 還會收到 `teammate_name` 與 `team_name`。
2870 2873
2871```json theme={null}2874```json theme={null}
2872{2875{
2880}2883}
2881```2884```
2882 2885
2883| 欄位 | 描述 |2886| 欄位 | 說明 |
2884| :- | :- |2887| :- | :- |
2885| `teammate_name` | 即將閒置的隊友的名稱 |2888| `teammate_name` | 即將進入閒置狀態之隊員的名稱 |
2886| `team_name` | 已棄用。工作階段衍生的團隊名稱;將在未來版本中移除 |2889| `team_name` | 已棄用。由工作階段衍生的團隊名稱;將在未來版本中移除 |
2887 2890
2888<h4 id="teammateidle-decision-control">2891<h4 id="teammateidle-decision-control">
2889 TeammateIdle 決策控制2892 TeammateIdle 決策控制
2890</h4>2893</h4>
2891 2894
2892TeammateIdle hooks 支援兩種方式來控制隊友行為:2895TeammateIdle hook 支援兩種控制隊員行為的方式:
2893 2896
2894* **退出代碼 2**:隊友接收 stderr 訊息作為反饋並繼續工作,而不是閒置。2897* **退出碼 2**:隊員會收到 stderr 訊息作為回饋,並繼續工作而不進入閒置狀態。
2895* **JSON `{"continue": false, "stopReason": "..."}`**:完全停止隊友,匹配 `Stop` hook 行為。`stopReason` 顯示給使用者。2898* **JSON `{"continue": false, "stopReason": "..."}`**:完全停止該隊員,與 `Stop` hook 的行為一致。`stopReason` 會顯示給使用者。
2896 2899
2897此範例檢查建立成品是否存在,然後允許隊友閒置:2900此範例會在允許隊員進入閒置狀態前,檢查建置產物是否存在:
2898 2901
2899```bash theme={null}2902```bash theme={null}
2900#!/bin/bash2903#!/bin/bash
2911 ConfigChange2914 ConfigChange
2912</h3>2915</h3>
2913 2916
2914在工作階段期間配置檔案變更時執行。使用此來稽核設定變更、強制安全原則或阻止對配置檔案的未授權修改。2917在工作階段期間設定檔變更時執行。可用來稽核設定變更、強制執行安全政策,或封鎖對設定檔未經授權的修改。
2915 2918
2916Claude Code 在設定檔、受管原則檔案或 skill 檔案變更時執行 ConfigChange hooks。對於受管原則,它僅在 `managed-settings.json` 或 `managed-settings.d/` 中的檔案變更時執行。它應用 [伺服器受管設定](/docs/zh-TW/server-managed-settings) 和對 macOS 受管偏好設定或 Windows 登錄原則的變更,而不執行它們。在 WSL 上搭配 [`wslInheritsWindowsSettings`](/docs/zh-TW/settings-reference#wslinheritswindowssettings),它也應用在其原則輪詢上變更的 Windows 端受管設定檔,而不執行它們。2919當設定檔、受管政策檔案或 skill 檔案變更時,Claude Code 會執行 ConfigChange hook。對於受管政策,只有在 `managed-settings.json` 或 `managed-settings.d/` 中的檔案變更時才會執行。套用[伺服器管理設定](/docs/zh-TW/server-managed-settings)以及 macOS 受管偏好設定或 Windows 登錄政策的變更時,不會執行這些 hook。在啟用 [`wslInheritsWindowsSettings`](/docs/zh-TW/settings-reference#wslinheritswindowssettings) 的 WSL 上,它在政策輪詢時套用已變更的 Windows 端受管設定檔,同樣不會執行這些 hook。
2917 2920
2918匹配器篩選配置來源:2921matcher 依設定來源篩選:
2919 2922
2920| 匹配器 | 何時觸發 |2923| Matcher | 觸發時機 |
2921| :- | :- |2924| :- | :- |
2922| `user_settings` | `~/.claude/settings.json` 變更 |2925| `user_settings` | `~/.claude/settings.json` 變更 |
2923| `project_settings` | `.claude/settings.json` 變更 |2926| `project_settings` | `.claude/settings.json` 變更 |
2925| `policy_settings` | `managed-settings.json` 或 `managed-settings.d/` 中的檔案變更 |2928| `policy_settings` | `managed-settings.json` 或 `managed-settings.d/` 中的檔案變更 |
2926| `skills` | `.claude/skills/` 中的 skill 檔案變更 |2929| `skills` | `.claude/skills/` 中的 skill 檔案變更 |
2927 2930
2928此範例記錄所有配置變更以進行安全稽核:2931此範例會記錄所有設定變更以供安全稽核:
2929 2932
2930```json theme={null}2933```json theme={null}
2931{2934{
2949 ConfigChange 輸入2952 ConfigChange 輸入
2950</h4>2953</h4>
2951 2954
2952除了 [常見輸入欄位](#common-input-fields) 外,ConfigChange hooks 還會接收 `source` 和可選的 `file_path`。`source` 欄位指示哪個配置類型變更,`file_path` 提供修改的特定檔案的路徑。2955除了[通用輸入欄位](#common-input-fields)之外,ConfigChange hook 還會收到 `source` 與選用的 `file_path`。`source` 欄位指出哪種設定類型發生變更,`file_path` 則提供被修改之特定檔案的路徑。
2953 2956
2954```json theme={null}2957```json theme={null}
2955{2958{
2966 ConfigChange 決策控制2969 ConfigChange 決策控制
2967</h4>2970</h4>
2968 2971
2969ConfigChange hooks 可以阻止配置變更生效。使用退出代碼 2 或 JSON `decision` 來防止變更。當被阻止時,新設定不會套用到執行中的工作階段。2972ConfigChange hook 可以封鎖設定變更使其不生效。使用退出碼 2 或 JSON `decision` 即可阻止變更。遭封鎖時,新設定不會套用至正在執行的工作階段。
2970 2973
2971| 欄位 | 描述 |2974| 欄位 | 說明 |
2972| :- | :- |2975| :- | :- |
2973| `decision` | `"block"` 防止配置變更被套用。省略以允許變更 |2976| `decision` | `"block"` 會阻止套用設定變更。省略即允許變更 |
2974| `reason` | 接受但永遠不顯示 |2977| `reason` | 會被接受,但永遠不會顯示 |
2975 2978
2976```json theme={null}2979```json theme={null}
2977{2980{
2980}2983}
2981```2984```
2982 2985
2983`policy_settings` 變更無法被阻止。當受管設定檔在機器上變更時,hooks 仍然對 `policy_settings` 來源執行,因此您可以使用它們來記錄這些編輯,但任何阻止決定都會被忽略。這確保企業受管設定始終生效。當 [伺服器受管設定](/docs/zh-TW/server-managed-settings) 到達或重新整理時,Claude Code 不執行 `ConfigChange` hooks。2986`policy_settings` 變更無法被封鎖。當機器上的受管設定檔變更時,hook 仍會針對 `policy_settings` 來源觸發,因此您可以用它們記錄這些編輯,但任何封鎖決策都會被忽略。這可確保企業受管設定一律生效。當[伺服器管理設定](/docs/zh-TW/server-managed-settings)抵達或重新整理時,Claude Code 不會執行 `ConfigChange` hook。
2984 2987
2985Claude Code 作用於 ConfigChange hook 的 JSON 輸出中的阻止決定,並捨棄 `systemMessage` 和 `continue`。被阻止的變更不會向您或 Claude 呈現任何訊息,無論您是否使用 `reason` 或 stderr 在退出 2 上阻止。Claude Code 僅將一行寫入 debug log。2988Claude Code 會依據 ConfigChange hook JSON 輸出中的封鎖決策採取行動,並捨棄 `systemMessage` 與 `continue`。無論您是以 `reason` 還是以退出碼 2 的 stderr 封鎖,遭封鎖的變更都不會向您或 Claude 顯示任何訊息。Claude Code 只會在偵錯日誌中寫入一行。
2986 2989
2987<h3 id="cwdchanged">2990<h3 id="cwdchanged">
2988 CwdChanged2991 CwdChanged
2989</h3>2992</h3>
2990 2993
2991在主對話中的 shell 命令變更工作目錄時執行,例如當 Claude 執行 `cd` 命令時。使用此來對目錄變更做出反應:重新載入環境變數、啟動專案特定的工具鏈或自動執行設定指令碼。與 [FileChanged](#filechanged) 配對,用於 [direnv](https://direnv.net/) 等管理每個目錄環境的工具。2994當主要對話中的 shell 命令變更工作目錄時執行,例如 Claude 執行 `cd` 命令時。可用來回應目錄變更:重新載入環境變數、啟用專案專屬的工具鏈,或自動執行設定指令碼。可與 [FileChanged](#filechanged) 搭配,用於像 [direnv](https://direnv.net/) 這類管理各目錄環境的工具。
2992 2995
2993CwdChanged hooks 可以存取 [`CLAUDE_ENV_FILE`](#persist-environment-variables)。寫入該檔案的變數會保留到後續 Bash 命令,直到下一個 CwdChanged 事件,當 Claude Code 清除它們時。2996CwdChanged hook 可以存取 [`CLAUDE_ENV_FILE`](#persist-environment-variables)。寫入該檔案的變數會保留到後續的 Bash 命令中,直到下一個 CwdChanged 事件時由 Claude Code 清除。
2994 2997
2995CwdChanged 不支援匹配器,對每個出現執行。2998CwdChanged 不支援 matcher,每次發生時都會觸發。
2996 2999
2997<h4 id="cwdchanged-input">3000<h4 id="cwdchanged-input">
2998 CwdChanged 輸入3001 CwdChanged 輸入
2999</h4>3002</h4>
3000 3003
3001除了 [常見輸入欄位](#common-input-fields) 外,CwdChanged hooks 還會接收 `old_cwd` 和 `new_cwd`。3004除了[通用輸入欄位](#common-input-fields)之外,CwdChanged hook 還會收到 `old_cwd` 與 `new_cwd`。
3002 3005
3003```json theme={null}3006```json theme={null}
3004{3007{
3015 CwdChanged 輸出3018 CwdChanged 輸出
3016</h4>3019</h4>
3017 3020
3018除了所有 hooks 可用的 [JSON 輸出欄位](#json-output) 外,CwdChanged hooks 可以返回 `watchPaths` 以動態設定 [FileChanged](#filechanged) 監視的檔案路徑:3021除了所有 hook 皆可使用的 [JSON 輸出欄位](#json-output)之外,CwdChanged hook 還可以傳回 `watchPaths`,以動態設定 [FileChanged](#filechanged) 監看的檔案路徑:
3019 3022
3020| 欄位 | 描述 |3023| 欄位 | 說明 |
3021| :- | :- |3024| :- | :- |
3022| `watchPaths` | 絕對路徑的陣列。替換目前的動態監視清單。來自您 `matcher` 配置的路徑始終被監視。進入新目錄時返回空陣列是典型的 |3025| `watchPaths` | 絕對路徑陣列。取代目前的動態監看清單。來自您 `matcher` 設定的路徑一律會被監看。傳回空陣列會清除動態清單,這在進入新目錄時很常見 |
3023 3026
3024CwdChanged hooks 沒有決策控制。它們無法阻止目錄變更。3027CwdChanged hook 沒有決策控制。它們無法封鎖目錄變更。
3025 3028
3026Claude Code 從它們的 JSON 輸出讀取 `watchPaths` 和 `systemMessage`,並捨棄 `continue`。在互動式工作階段中,它將 `systemMessage` 顯示為簡短的終端通知。訊息不到達 SDK 訊息流。3029Claude Code 會從其 JSON 輸出讀取 `watchPaths` 與 `systemMessage`,並捨棄 `continue`。在互動式工作階段中,它會將 `systemMessage` 顯示為簡短的終端機通知。該訊息不會傳到 SDK 訊息串流。
3027 3030
3028<h3 id="directoryadded">3031<h3 id="directoryadded">
3029 DirectoryAdded3032 DirectoryAdded
3030</h3>3033</h3>
3031 3034
3032在您使用 `/add-dir` 命令中途新增工作目錄後執行,或在 SDK 用戶端使用 `register_repo_root` 控制請求新增一個後執行。使用此來準備新增的儲存庫,例如安裝其相依性。3035在您於工作階段中途使用 `/add-dir` 命令新增工作目錄後,或在 SDK 用戶端以 `register_repo_root` 控制請求新增工作目錄後執行。可用來準備新加入的儲存庫,例如安裝其相依套件。
3033 3036
3034Claude Code 在以下情況下不執行此事件:3037在下列情況下,Claude Code 不會觸發此事件:
3035 3038
3036* 您使用 `--add-dir` 啟動旗標傳遞目錄;[SessionStart](#sessionstart) 涵蓋這些目錄3039* 您以 `--add-dir` 啟動旗標傳入目錄;這些目錄由 [SessionStart](#sessionstart) 涵蓋
3037* 您在 `/permissions` Workspace 標籤上新增目錄3040* 您在 `/permissions` 的 Workspace 分頁中新增目錄
3038* 您新增已是工作目錄或在其內的目錄3041* 您新增的目錄已是工作目錄或位於某個工作目錄內
3039 3042
3040Claude Code 在重新整理沙箱和權限狀態後執行 DirectoryAdded,因此沙箱工具在您的 hook 執行時已看到新目錄。Hook 命令本身執行未沙箱化。3043Claude Code 會在重新整理沙箱與權限狀態後觸發 DirectoryAdded,因此當您的 hook 執行時,沙箱化的工具已能看到新目錄。hook 命令本身則在沙箱外執行。
3041 3044
3042Claude Code 不等待 hook:新增立即完成,hook 在背景執行,具有 600 秒的預設逾時。3045Claude Code 不會等待 hook:新增會立即完成,hook 則在背景執行,使用 600 秒的預設逾時。
3043 3046
3044匹配器篩選目錄的新增方式:3047matcher 依目錄的新增方式篩選:
3045 3048
3046| 匹配器 | 何時觸發 |3049| Matcher | 觸發時機 |
3047| :- | :- |3050| :- | :- |
3048| `slash_command` | 您使用 `/add-dir` 新增目錄 |3051| `slash_command` | 您以 `/add-dir` 新增目錄 |
3049| `register_repo_root` | SDK 用戶端使用 `register_repo_root` 控制請求新增目錄 |3052| `register_repo_root` | SDK 用戶端以 `register_repo_root` 控制請求新增目錄 |
3050 3053
3051<h4 id="directoryadded-input">3054<h4 id="directoryadded-input">
3052 DirectoryAdded 輸入3055 DirectoryAdded 輸入
3053</h4>3056</h4>
3054 3057
3055除了 [常見輸入欄位](#common-input-fields) 外,DirectoryAdded hooks 還會接收 `directory` 和 `source`。3058除了[通用輸入欄位](#common-input-fields)之外,DirectoryAdded hook 還會收到 `directory` 與 `source`。
3056 3059
3057| 欄位 | 描述 |3060| 欄位 | 說明 |
3058| :- | :- |3061| :- | :- |
3059| `directory` | 新增的目錄的絕對路徑 |3062| `directory` | 所新增目錄的絕對路徑 |
3060| `source` | 目錄如何被新增,`/add-dir` 為 `"slash_command"` 或 SDK 控制請求為 `"register_repo_root"` |3063| `source` | 目錄的新增方式,`/add-dir` 為 `"slash_command"`,SDK 控制請求為 `"register_repo_root"` |
3061 3064
3062```json theme={null}3065```json theme={null}
3063{3066{
3070}3073}
3071```3074```
3072 3075
3073DirectoryAdded hooks 沒有決策控制。它們無法阻止新增,這在 hook 執行時已完成。Claude Code 從它們的 JSON 輸出捨棄 `continue` 欄位,並根據來源以不同方式呈現其餘部分:3076DirectoryAdded hook 沒有決策控制。它們無法封鎖新增,因為 hook 執行時新增已經完成。Claude Code 會捨棄其 JSON 輸出中的 `continue` 欄位,其餘部分則依來源以不同方式呈現:
3074 3077
3075* `slash_command`:Claude Code 將 hook 的 `systemMessage` 作為背景資訊傳遞給 Claude,在下一個對話回合上,而不是向您顯示。失敗 hooks 的計數出現在文字記錄中。完整失敗輸出進入 debug log3078* `slash_command`:Claude Code 會在下一個對話回合將 hook 的 `systemMessage` 作為上下文傳遞給 Claude,而不是顯示給您。失敗 hook 的數量會出現在逐字稿中。完整的失敗輸出會寫入偵錯日誌
3076* `register_repo_root`:Claude Code 僅將 `systemMessage` 輸出和失敗輸出寫入 debug log3079* `register_repo_root`:Claude Code 只會將 `systemMessage` 輸出與失敗輸出寫入偵錯日誌
3077 3080
3078<h3 id="filechanged">3081<h3 id="filechanged">
3079 FileChanged3082 FileChanged
3080</h3>3083</h3>
3081 3084
3082在監視的檔案在磁碟上變更時執行。Claude Code 使用檔案系統監視器檢測變更,而不是檢查工具呼叫,因此無論什麼變更了檔案,它都執行 hook:`Edit` 或 `Write` 工具呼叫、Claude 使用 `Bash` 執行的指令碼,或 Claude Code 外的程序。常見用途是在專案配置檔案變更時重新載入環境變數。3085當受監看的檔案在磁碟上變更時執行。Claude Code 是以檔案系統監看器偵測變更,而非檢查工具呼叫,因此無論是什麼變更了檔案,它都會執行 hook:`Edit` 或 `Write` 工具呼叫、Claude 以 `Bash` 執行的指令碼,或完全在 Claude Code 之外的程序。常見用途是在專案設定檔變更時重新載入環境變數。
3083 3086
3084此事件的 `matcher` 有兩個角色:3087此事件的 `matcher` 有兩個作用:
3085 3088
3086* **建立監視清單**:值在 `|` 上分割,每個段註冊為工作目錄中的字面檔案名稱,因此 `".envrc|.env"` 監視恰好這兩個檔案。正規表達式模式在這裡不有用:`^\.env` 之類的值會監視字面名稱為 `^\.env` 的檔案。3089* **建立監看清單**:其值會以 `|` 分割,每個片段都會被註冊為工作目錄中的字面檔案名稱,因此 `".envrc|.env"` 會精確監看這兩個檔案。正規表示式模式在此沒有用處:像 `^\.env` 這樣的值會監看名稱字面上就是 `^\.env` 的檔案。
3087* **篩選哪些 hooks 執行**:當監視的檔案變更時,相同的值使用標準 [匹配器規則](#matcher-patterns) 針對變更檔案的基名篩選哪些 hook 群組執行。3090* **篩選要執行的 hook**:當受監看的檔案變更時,同一個值會依標準的 [matcher 規則](#matcher-patterns),對變更檔案的基本名稱篩選要執行哪些 hook 群組。
3088 3091
3089此範例在任何變更後規範化 `data.csv` 中的行結尾,包括 `Bash` 命令或外部指令碼重寫檔案:3092此範例會在任何變更後正規化 `data.csv` 的行尾,包括 `Bash` 命令或外部指令碼改寫該檔案的情況:
3090 3093
3091```json theme={null}3094```json theme={null}
3092{3095{
3106}3109}
3107```3110```
3108 3111
3109hook 從 stdin 上的 [JSON 輸入](#filechanged-input) 的 `file_path` 欄位讀取變更檔案的絕對路徑。其 `grep` 守衛測試與 `perl` 移除的相同,行尾的 CR,因此在規範化後執行時退出而不觸及檔案。較鬆散的守衛會無限迴圈,因為 `perl -i` 重寫檔案,即使它不替換任何內容,Claude Code 在每次重寫後執行 hook。將此指令碼儲存在 `/path/to/normalize-line-endings.sh` 並使其可執行:3112hook 會從 stdin 上 [JSON 輸入](#filechanged-input)的 `file_path` 欄位讀取變更檔案的絕對路徑。其 `grep` 防護條件檢查的正是 `perl` 要移除的內容,也就是行尾的 CR,因此正規化之後的那次執行會直接結束而不動到檔案。較寬鬆的防護條件會造成無限迴圈,因為即使沒有替換任何內容,`perl -i` 仍會改寫檔案,而 Claude Code 會在每次改寫後再次執行 hook。請將此指令碼儲存於 `/path/to/normalize-line-endings.sh` 並設為可執行:
3110 3113
3111```bash theme={null}3114```bash theme={null}
3112#!/bin/bash3115#!/bin/bash
3116fi3119fi
3117```3120```
3118 3121
3119要確認 hook 有效,要求 Claude 使用 `Bash` 命令將 CRLF 行附加到 `data.csv`。Claude Code 執行 hook,檔案最終具有 LF 結尾。3122若要確認 hook 正常運作,請要求 Claude 以 `Bash` 命令在 `data.csv` 後附加一行 CRLF。Claude Code 會執行 hook,檔案最終會使用 LF 行尾。
3120 3123
3121要監視您無法提前命名的檔案,請從 hook 返回 [`watchPaths`](#filechanged-output) 以動態更新監視清單。Claude Code 僅在某事命名要監視的檔案時啟動監視器,因此使用命名至少一個檔案的 FileChanged 群組播種清單,或使用 [SessionStart](#sessionstart-decision-control) 或 [CwdChanged](#cwdchanged) hook 返回 `watchPaths`。匹配器仍然篩選當監視的檔案變更時哪些 hook 群組執行,因此給處理動態路徑的群組一個省略的匹配器,它匹配每個監視的檔案,不向監視清單新增任何內容。`"*"` 匹配器也匹配每個檔案,但 Claude Code 將其註冊到監視清單中,如同任何其他值,作為字面名稱為 `*` 的檔案。3124若要監看無法事先命名的檔案,請從 hook 傳回 [`watchPaths`](#filechanged-output) 以動態更新監看清單。Claude Code 只有在某處指定了要監看的檔案時才會啟動監看器,因此請以 matcher 至少指定一個檔案的 FileChanged 群組,或以傳回 `watchPaths` 的 [SessionStart](#sessionstart-decision-control) 或 [CwdChanged](#cwdchanged) hook 來初始化清單。當受監看的檔案變更時,matcher 仍會篩選要執行哪些 hook 群組,因此請讓處理動態路徑的群組省略 matcher,這樣會比對每個受監看的檔案,且不會在監看清單中新增任何項目。`"*"` matcher 也會比對每個檔案,但 Claude Code 會像處理其他值一樣,將其作為名為 `*` 的字面檔案註冊到監看清單中。
3122 3125
3123FileChanged hooks 可以存取 [`CLAUDE_ENV_FILE`](#persist-environment-variables)。寫入該檔案的變數會保留到後續 Bash 命令,直到下一個 [CwdChanged](#cwdchanged) 事件,當 Claude Code 清除它們時。3126FileChanged hook 可以存取 [`CLAUDE_ENV_FILE`](#persist-environment-variables)。寫入該檔案的變數會保留到後續的 Bash 命令中,直到下一個 [CwdChanged](#cwdchanged) 事件時由 Claude Code 清除。
3124 3127
3125<h4 id="filechanged-input">3128<h4 id="filechanged-input">
3126 FileChanged 輸入3129 FileChanged 輸入
3127</h4>3130</h4>
3128 3131
3129除了 [常見輸入欄位](#common-input-fields) 外,FileChanged hooks 還會接收 `file_path` 和 `event`。3132除了[通用輸入欄位](#common-input-fields)之外,FileChanged hook 還會收到 `file_path` 與 `event`。
3130 3133
3131| 欄位 | 描述 |3134| 欄位 | 說明 |
3132| :- | :- |3135| :- | :- |
3133| `file_path` | 變更的檔案的絕對路徑 |3136| `file_path` | 變更檔案的絕對路徑 |
3134| `event` | 發生的情況:修改的檔案為 `"change"`、建立的檔案為 `"add"` 或刪除的檔案為 `"unlink"` |3137| `event` | 發生的事件:修改檔案為 `"change"`,建立檔案為 `"add"`,刪除檔案為 `"unlink"` |
3135 3138
3136```json theme={null}3139```json theme={null}
3137{3140{
3148 FileChanged 輸出3151 FileChanged 輸出
3149</h4>3152</h4>
3150 3153
3151除了所有 hooks 可用的 [JSON 輸出欄位](#json-output) 外,FileChanged hooks 可以返回 `watchPaths` 以動態更新監視的檔案路徑:3154除了所有 hook 皆可使用的 [JSON 輸出欄位](#json-output)之外,FileChanged hook 還可以傳回 `watchPaths`,以動態更新要監看的檔案路徑:
3152 3155
3153| 欄位 | 描述 |3156| 欄位 | 說明 |
3154| :- | :- |3157| :- | :- |
3155| `watchPaths` | 絕對路徑的陣列。替換目前的動態監視清單。來自您 `matcher` 配置的路徑始終被監視。當您的 hook 指令碼根據變更的檔案發現要監視的其他檔案時,使用此 |3158| `watchPaths` | 絕對路徑陣列。取代目前的動態監看清單。來自您 `matcher` 設定的路徑一律會被監看。當您的 hook 指令碼依據變更的檔案發現其他需要監看的檔案時,請使用此欄位 |
3156 3159
3157FileChanged hooks 沒有決策控制。它們無法阻止檔案變更發生。3160FileChanged hook 沒有決策控制。它們無法阻止檔案變更發生。
3158 3161
3159Claude Code 從它們的 JSON 輸出讀取 `watchPaths` 和 `systemMessage`,並捨棄 `continue`。在互動式工作階段中,它將 `systemMessage` 顯示為簡短的終端通知。訊息不到達 SDK 訊息流。3162Claude Code 會從其 JSON 輸出讀取 `watchPaths` 與 `systemMessage`,並捨棄 `continue`。在互動式工作階段中,它會將 `systemMessage` 顯示為簡短的終端機通知。該訊息不會傳到 SDK 訊息串流。
3160 3163
3161<h3 id="worktreecreate">3164<h3 id="worktreecreate">
3162 WorktreeCreate3165 WorktreeCreate
3163</h3>3166</h3>
3164 3167
3165在建立 worktree 時執行,無論是從 `claude --worktree`、從 [子代理使用 `isolation: "worktree"`](/docs/zh-TW/sub-agents#choose-the-subagent-scope),還是對於 Claude Code 在其自己的 worktree 中隔離的 [背景工作階段](/docs/zh-TW/agent-view#how-file-edits-are-isolated)。預設情況下,Claude Code 使用 `git worktree` 建立隔離的工作副本。配置 WorktreeCreate hook 替換該預設 git 行為,讓您使用不同的版本控制系統,如 SVN、Perforce 或 Mercurial。3168在建立 worktree 時執行,無論是來自 `claude --worktree`、來自[使用 `isolation: "worktree"` 的 subagent](/docs/zh-TW/sub-agents#choose-the-subagent-scope),或是為 Claude Code 隔離在其自身 worktree 中的[背景工作階段](/docs/zh-TW/agent-view#how-file-edits-are-isolated)。依預設,Claude Code 會以 `git worktree` 建立隔離的工作副本。設定 WorktreeCreate hook 會取代該預設的 git 行為,讓您能使用其他版本控制系統,例如 SVN、Perforce 或 Mercurial。
3166 3169
3167因為 hook 完全替換預設行為,[`.worktreeinclude`](/docs/zh-TW/worktrees#copy-gitignored-files-into-worktrees) 不被處理。如果您需要將本機配置檔案(如 `.env`)複製到新 worktree,請在您的 hook 指令碼內執行。3170由於 hook 會完全取代預設行為,因此不會處理 [`.worktreeinclude`](/docs/zh-TW/worktrees#copy-gitignored-files-into-worktrees)。若您需要將 `.env` 之類的本機設定檔複製到新的 worktree,請在您的 hook 指令碼中進行。
3168 3171
3169hook 必須返回建立的 worktree 目錄的路徑。Claude Code 使用此路徑作為隔離工作階段的工作目錄。有關每個 hook 類型如何返回路徑,請參閱 [WorktreeCreate output](#worktreecreate-output)。3172hook 必須傳回所建立之 worktree 目錄的路徑。Claude Code 會將此路徑作為隔離工作階段的工作目錄。關於各 hook 類型如何傳回路徑,請參閱 [WorktreeCreate 輸出](#worktreecreate-output)。
3170 3173
3171Claude Code 作用於 hook 的成功和返回的路徑,並捨棄 `systemMessage` 和 `continue`。3174Claude Code 會依據 hook 是否成功以及傳回的路徑採取行動,並捨棄 `systemMessage` 與 `continue`。
3172 3175
3173此範例建立 SVN 工作副本並列印路徑供 Claude Code 使用。將儲存庫 URL 替換為您自己的:3176此範例會建立 SVN 工作副本,並印出路徑供 Claude Code 使用。請將儲存庫 URL 替換為您自己的:
3174 3177
3175```json theme={null}3178```json theme={null}
3176{3179{
3189}3192}
3190```3193```
3191 3194
3192hook 從 stdin 上的 JSON 輸入讀取 worktree `name`,將新副本簽出到新目錄,並列印目錄路徑。最後一行的 `echo` 是 Claude Code 讀取為 worktree 路徑的內容。將任何其他輸出重定向到 stderr,以便它不會干擾路徑。3195hook 會從 stdin 上的 JSON 輸入讀取 worktree 的 `name`,將全新副本簽出到新目錄,並印出目錄路徑。最後一行的 `echo` 就是 Claude Code 讀取為 worktree 路徑的內容。請將其他任何輸出重新導向至 stderr,以免干擾路徑。
3193 3196
3194<h4 id="worktreecreate-input">3197<h4 id="worktreecreate-input">
3195 WorktreeCreate 輸入3198 WorktreeCreate 輸入
3196</h4>3199</h4>
3197 3200
3198除了 [常見輸入欄位](#common-input-fields) 外,WorktreeCreate hooks 還會接收 `name` 欄位。這是新 worktree 的 slug 識別碼,由使用者指定或自動產生,例如 `bold-oak-a3f2`。3201除了[通用輸入欄位](#common-input-fields)之外,WorktreeCreate hook 還會收到 `name` 欄位。這是新 worktree 的 slug 識別碼,由使用者指定或自動產生,例如 `bold-oak-a3f2`。
3199 3202
3200```json theme={null}3203```json theme={null}
3201{3204{
3211 WorktreeCreate 輸出3214 WorktreeCreate 輸出
3212</h4>3215</h4>
3213 3216
3214WorktreeCreate hooks 不使用標準允許/阻止決策模型。相反,hook 的成功或失敗決定結果。hook 必須返回建立的 worktree 目錄的路徑:3217WorktreeCreate hook 不使用標準的允許/封鎖決策模型,而是由 hook 的成功或失敗決定結果。hook 必須回傳所建立的 worktree 目錄路徑:
3215 3218
3216* **命令 hooks** (`type: "command"`):將路徑列印為 stdout 的最後一個非空行。Claude Code 在讀取該行之前去除 ANSI 逃逸代碼,因此在您的 `echo` 之前列印的 shell 啟動橫幅會被忽略。將任何其他 hook 輸出重定向到 stderr。3219* **命令 hook**(`type: "command"`):將路徑印為 stdout 的最後一個非空行。Claude Code 在讀取該行之前會移除 ANSI 跳脫碼,因此在您的 `echo` 之前印出的 shell 啟動橫幅會被忽略。請將任何其他 hook 輸出重新導向至 stderr。
3217* **HTTP hooks** (`type: "http"`):在回應主體中返回 `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }`。3220* **HTTP hook**(`type: "http"`):在回應主體中回傳 `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }`。
3218 3221
3219如果 hook 失敗或不產生路徑,worktree 建立失敗,並出現錯誤。3222如果 hook 失敗或未產生路徑,worktree 建立將失敗並顯示錯誤。
3220 3223
3221Claude Code 根據 hook 執行的目錄解決相對路徑,折疊其中的任何 `.` 或 `..` 段。如果結果路徑不是 Claude Code 可以進入的目錄,工作階段列印命名路徑的錯誤並以代碼 1 退出。3224Claude Code 會以 hook 執行時所在的目錄解析相對路徑,並摺疊其中的任何 `.` 或 `..` 區段。如果產生的路徑不是 Claude Code 可以進入的目錄,工作階段會印出指明該路徑的錯誤,並以代碼 1 結束。
3222 3225
3223Claude Code 拒絕包含 `.` 或 `..` 段的絕對路徑,以及通過儲存庫根下的符號連結的任何路徑,因為提交到儲存庫的符號連結可能會將 worktree 重定向到其外。錯誤命名被拒絕的元件。返回不通過儲存庫內符號連結的規範化路徑。在 v2.1.216 之前,worktree 建立遵循 hook 的路徑,而不進行此篩選。3226Claude Code 會拒絕包含 `.` 或 `..` 區段的絕對路徑,以及任何經過儲存庫根目錄下方符號連結的路徑,因為提交至儲存庫的符號連結可能會將 worktree 重新導向至儲存庫之外。錯誤會指明被拒絕的元件。請回傳不經過儲存庫內符號連結的正規化路徑。在 v2.1.216 之前,worktree 建立會直接採用 hook 的路徑,不進行此項檢查。
3224 3227
3225<h3 id="worktreeremove">3228<h3 id="worktreeremove">
3226 WorktreeRemove3229 WorktreeRemove
3227</h3>3230</h3>
3228 3231
3229在移除 worktree 時執行。這是 [WorktreeCreate](#worktreecreate) 的清理對應項。事件在以下情況下執行:3232在移除 worktree 時執行。這是 [WorktreeCreate](#worktreecreate) 對應的清理事件。此事件會在以下情況觸發:
3230 3233
3231* 您退出 `--worktree` 工作階段並選擇移除它3234* 您結束 `--worktree` 工作階段並選擇移除它
3232* 具有 `isolation: "worktree"` 的子代理完成3235* 具有 `isolation: "worktree"` 的 subagent 完成
3233* 您刪除 [背景工作階段](/docs/zh-TW/agent-view#what-deleting-a-session-removes),其 worktree hook 建立3236* 您刪除一個其 worktree 由 hook 建立的[背景工作階段](/docs/zh-TW/agent-view#what-deleting-a-session-removes)
3234 3237
3235對於基於 git 的 worktrees,Claude Code 使用 `git worktree remove` 自動處理清理。如果您配置了 WorktreeCreate hook,將其與 WorktreeRemove hook 配對以控制它建立的 worktrees 的清理:3238對於基於 git 的 worktree,Claude Code 會透過 `git worktree remove` 自動處理清理。如果您設定了 WorktreeCreate hook,請搭配 WorktreeRemove hook 來控制其所建立 worktree 的清理:
3236 3239
3237* **沒有 WorktreeRemove hook**:當您退出 `--worktree` 工作階段並選擇移除時,Claude Code 回退到 `git worktree remove --force` 在您的 WorktreeCreate hook 返回的路徑上,因此 git 識別的 worktree 被移除。git 不識別的 worktree(例如您的 hook 使用非 git 版本控制系統建立的)保留在磁碟上。對於刪除 [背景工作階段](/docs/zh-TW/agent-view#what-deleting-a-session-removes) 對 hook 建立的 worktree 做什麼,請參閱 agent view 的刪除規則。3240* **沒有 WorktreeRemove hook**:當您結束 `--worktree` 工作階段並選擇移除時,Claude Code 會改用 `git worktree remove --force` 處理您的 WorktreeCreate hook 回傳的路徑,因此 git 能識別的 worktree 會被移除。git 無法識別的 worktree,例如您的 hook 以非 git 版本控制系統建立的 worktree,會保留在磁碟上。關於刪除[背景工作階段](/docs/zh-TW/agent-view#what-deleting-a-session-removes)時如何處理 hook 建立的 worktree,請參閱 agent view 的刪除規則。
3238* **Hook 退出 0**:worktree 計為已移除。Claude Code 從 hook 讀取任何其他內容,因此確保您的 hook 刪除了目錄。3241* **Hook 以 0 結束**:該 worktree 視為已移除。Claude Code 不會從 hook 讀取其他任何內容,因此請確保您的 hook 已刪除該目錄。
3239* **Hook 退出非零**:如果 `worktree_path` 處的目錄在之後仍然存在,移除失敗,worktree 保留在磁碟上,沒有 git 回退。在退出非零之前刪除目錄的 hook 計為已移除。對於失敗如何報告,請參閱 [WorktreeRemove input](#worktreeremove-input)。3242* **Hook 以非零結束**:如果 `worktree_path` 處的目錄在之後仍然存在,移除即失敗,且 worktree 會保留在磁碟上,不會改用 git。在以非零結束之前已刪除目錄的 hook 視為已移除。關於失敗的回報方式,請參閱 [WorktreeRemove 輸入](#worktreeremove-input)。
3240 3243
3241Claude Code 永遠不會刪除屬於 hook 建立的 worktree 的分支,因為它僅知道您的 WorktreeCreate hook 返回的路徑。如果您的 WorktreeCreate hook 建立分支,請在您的 WorktreeRemove hook 中刪除它。3244Claude Code 絕不會刪除屬於 hook 建立之 worktree 的分支,因為它只知道您的 WorktreeCreate hook 回傳的路徑。如果您的 WorktreeCreate hook 建立了分支,請在 WorktreeRemove hook 中將其刪除。
3242 3245
3243Claude Code 捨棄 WorktreeRemove hook 的 [JSON 輸出欄位](#json-output),例如 `systemMessage` 和 `continue`。3246Claude Code 會捨棄 WorktreeRemove hook 的 [JSON 輸出欄位](#json-output),例如 `systemMessage` 和 `continue`。
3244 3247
3245對於背景工作階段刪除,Claude Code 在執行 hook 之前驗證儲存的 worktree 路徑,並拒絕在儲存庫根下是符號連結或通過符號連結的路徑。hook 僅對仍包含檔案的 worktree 執行,當您在 [agent view](/docs/zh-TW/agent-view#what-deleting-a-session-removes) 中確認刪除時;對於這樣的 worktree,[`claude rm`](/docs/zh-TW/agent-view#manage-sessions-from-the-shell) 保持工作階段和 worktree。在 v2.1.216 之前,hook 在儲存的路徑上執行,而不進行這些檢查。3248對於背景工作階段的刪除,Claude Code 會在執行 hook 之前驗證所儲存的 worktree 路徑,並拒絕本身為符號連結或經過儲存庫根目錄下方符號連結的路徑。只有當您在 [agent view](/docs/zh-TW/agent-view#what-deleting-a-session-removes) 中確認刪除時,hook 才會針對仍含有檔案的 worktree 執行;對於這類 worktree,[`claude rm`](/docs/zh-TW/agent-view#manage-sessions-from-the-shell) 則會保留工作階段和 worktree。在 v2.1.216 之前,hook 會在未經這些檢查的情況下針對儲存的路徑執行。
3246 3249
3247Claude Code 將 WorktreeCreate 返回的路徑作為 `worktree_path` 在 hook 輸入中傳遞。此範例讀取該路徑並移除目錄:3250Claude Code 會將 WorktreeCreate 回傳的路徑作為 hook 輸入中的 `worktree_path` 傳入。以下範例讀取該路徑並移除目錄:
3248 3251
3249```json theme={null}3252```json theme={null}
3250{3253{
3267 WorktreeRemove 輸入3270 WorktreeRemove 輸入
3268</h4>3271</h4>
3269 3272
3270除了 [常見輸入欄位](#common-input-fields) 外,WorktreeRemove hooks 還會接收 `worktree_path` 欄位,這是正在移除的 worktree 的絕對路徑。3273除了[通用輸入欄位](#common-input-fields)之外,WorktreeRemove hook 還會收到 `worktree_path` 欄位,即要移除之 worktree 的絕對路徑。
3271 3274
3272```json theme={null}3275```json theme={null}
3273{3276{
3279}3282}
3280```3283```
3281 3284
3282WorktreeRemove hook 的退出代碼決定結果。當 hook 退出非零且 `worktree_path` 處的目錄在之後仍然存在時,移除失敗:3285WorktreeRemove hook 的退出碼決定結果。當 hook 以非零結束,且 `worktree_path` 處的目錄在之後仍然存在時,移除即失敗:
3283 3286
3284* worktree 保留在磁碟上,hook 的命令和 stderr 進入 [debug log](#debug-hooks)。3287* worktree 會保留在磁碟上,hook 的命令和 stderr 會寫入[偵錯日誌](#debug-hooks)。
3285* 如果您正在刪除背景工作階段,工作階段也保留。[agent view](/docs/zh-TW/agent-view#what-deleting-a-session-removes) 中的拒絕訊息報告 hook 如何結束,例如 `exited 1`,引用其 stderr 的開頭,並說明再次刪除工作階段是否無論如何都會移除目錄。3288* 如果您正在刪除背景工作階段,該工作階段也會保留。[agent view](/docs/zh-TW/agent-view#what-deleting-a-session-removes) 中的拒絕訊息會回報 hook 的結束方式(例如 `exited 1`)、引用其 stderr 的開頭,並說明再次刪除該工作階段是否仍會移除該目錄。
3286 3289
3287<h3 id="precompact">3290<h3 id="precompact">
3288 PreCompact3291 PreCompact
3290 3293
3291在 Claude Code 即將執行壓縮操作之前執行。3294在 Claude Code 即將執行壓縮操作之前執行。
3292 3295
3293匹配器值指示壓縮是手動還是自動觸發:3296matcher 值表示壓縮是手動觸發還是自動觸發:
3294 3297
3295| 匹配器 | 何時觸發 |3298| Matcher | 觸發時機 |
3296| :- | :- |3299| :- | :- |
3297| `manual` | `/compact` |3300| `manual` | `/compact` |
3298| `auto` | 當對話到達 [自動壓縮視窗](/docs/zh-TW/model-config#set-the-auto-compact-window) 時自動壓縮 |3301| `auto` | 當對話達到[自動壓縮視窗](/docs/zh-TW/model-config#set-the-auto-compact-window)時自動壓縮 |
3299 3302
3300退出代碼 2 以阻止壓縮。對於手動 `/compact`,stderr 訊息顯示給使用者。您也可以透過返回 JSON 搭配 `"decision": "block"` 來阻止。3303以代碼 2 結束可封鎖壓縮。對於手動 `/compact`,stderr 訊息會顯示給使用者。您也可以回傳含有 `"decision": "block"` 的 JSON 來封鎖。
3301 3304
3302阻止自動壓縮根據何時執行有不同的效果。如果壓縮在背景限制之前主動觸發,Claude Code 跳過它,對話繼續未壓縮。如果壓縮被觸發以從 API 已返回的背景限制錯誤恢復,基礎錯誤呈現,目前請求失敗。3305封鎖自動壓縮的效果取決於其觸發時機。如果壓縮是在達到上下文限制之前主動觸發的,Claude Code 會略過壓縮,對話會在未壓縮的狀態下繼續。如果壓縮是為了從 API 已回傳的上下文限制錯誤中恢復而觸發的,底層錯誤就會浮現,目前的請求會失敗。
3303 3306
3304Claude Code 捨棄 PreCompact hook 的 `systemMessage` 和 `continue` 欄位。3307Claude Code 會捨棄 PreCompact hook 的 `systemMessage` 和 `continue` 欄位。
3305 3308
3306<h4 id="precompact-input">3309<h4 id="precompact-input">
3307 PreCompact 輸入3310 PreCompact 輸入
3308</h4>3311</h4>
3309 3312
3310除了 [常見輸入欄位](#common-input-fields) 外,PreCompact hooks 還會接收 `trigger` 和 `custom_instructions`。對於 `manual`,`custom_instructions` 包含使用者傳遞到 `/compact` 的內容,當他們傳遞任何內容時為 `null`。對於 `auto`,`custom_instructions` 為 `null`。3313除了[通用輸入欄位](#common-input-fields)之外,PreCompact hook 還會收到 `trigger` 和 `custom_instructions`。對於 `manual`,`custom_instructions` 包含使用者傳入 `/compact` 的內容,未傳入任何內容時為 `null`。對於 `auto`,`custom_instructions` 為 `null`。
3311 3314
3312```json theme={null}3315```json theme={null}
3313{3316{
3324 PostCompact3327 PostCompact
3325</h3>3328</h3>
3326 3329
3327在 Claude Code 完成壓縮操作後執行。使用此事件對新壓縮狀態做出反應,例如記錄產生的摘要或更新外部狀態。Claude Code 捨棄 PostCompact hook 的 `systemMessage` 和 `continue` 欄位。3330在 Claude Code 完成壓縮操作之後執行。使用此事件來回應新的壓縮狀態,例如記錄產生的摘要或更新外部狀態。Claude Code 會捨棄 PostCompact hook 的 `systemMessage` 和 `continue` 欄位。
3328 3331
3329與 `PreCompact` 相同的匹配器值適用:3332適用與 `PreCompact` 相同的 matcher 值:
3330 3333
3331| 匹配器 | 何時觸發 |3334| Matcher | 觸發時機 |
3332| :- | :- |3335| :- | :- |
3333| `manual` | 在 `/compact` 後 |3336| `manual` | `/compact` 之後 |
3334| `auto` | 當對話到達 [自動壓縮視窗](/docs/zh-TW/model-config#set-the-auto-compact-window) 時自動壓縮後 |3337| `auto` | 當對話達到[自動壓縮視窗](/docs/zh-TW/model-config#set-the-auto-compact-window)而自動壓縮之後 |
3335 3338
3336<h4 id="postcompact-input">3339<h4 id="postcompact-input">
3337 PostCompact 輸入3340 PostCompact 輸入
3338</h4>3341</h4>
3339 3342
3340除了 [常見輸入欄位](#common-input-fields) 外,PostCompact hooks 還會接收 `trigger` 和 `compact_summary`。`compact_summary` 欄位包含壓縮操作產生的對話摘要。3343除了[通用輸入欄位](#common-input-fields)之外,PostCompact hook 還會收到 `trigger` 和 `compact_summary`。`compact_summary` 欄位包含壓縮操作所產生的對話摘要。
3341 3344
3342```json theme={null}3345```json theme={null}
3343{3346{
3350}3353}
3351```3354```
3352 3355
3353PostCompact hooks 沒有決策控制。它們無法影響壓縮結果,但可以執行後續任務。3356PostCompact hook 沒有決策控制。它們無法影響壓縮結果,但可以執行後續工作。
3354 3357
3355<h3 id="premodelswitch">3358<h3 id="premodelswitch">
3356 PreModelSwitch3359 PreModelSwitch
3357</h3>3360</h3>
3358 3361
3359在 Claude Code 應用您或用戶端請求的模型切換之前執行。使用它來阻止切換、要求確認或在切換發生前顯示成本。3362在 Claude Code 套用您或用戶端所請求的模型切換之前執行。使用它來封鎖切換、要求確認,或在切換發生之前顯示切換的成本。
3360 3363
3361PreModelSwitch 需要 Claude Code v2.1.251 或更新版本。Claude Code 為這些請求執行它:3364PreModelSwitch 需要 Claude Code v2.1.251 或更新版本。Claude Code 會針對以下請求執行它:
3362 3365
3363* `/model <name>` 和 `/model` 選擇器3366* `/model <name>` 和 `/model` 選擇器
3364* `Option+P` 或 `Alt+P` 模型選擇器3367* `Option+P` 或 `Alt+P` 模型選擇器
3365* `/config` 中的 Model 設定3368* `/config` 中的 Model 設定
3366* 當 [fast mode](/docs/zh-TW/fast-mode) 改變工作階段的模型時打開它3369* 開啟[快速模式](/docs/zh-TW/fast-mode)而導致工作階段的模型變更時
3367* 來自 [Agent SDK](/docs/zh-TW/agent-sdk/typescript#query-object) 主機或 [Remote Control](/docs/zh-TW/remote-control) 的 `set_model` 請求,或 `apply_flag_settings` 請求中的模型變更3370* 來自 [Agent SDK](/docs/zh-TW/agent-sdk/typescript#query-object) 主機或 [Remote Control](/docs/zh-TW/remote-control) 的 `set_model` 請求,或 `apply_flag_settings` 請求中的模型變更
3368 3371
3369Claude Code 不為它自己進行的切換執行 PreModelSwitch hooks,例如 [自動模型回退](/docs/zh-TW/model-config#automatic-model-fallback) 或恢復工作階段時還原模型。這些變更僅到達 [PostModelSwitch](#postmodelswitch)。3372對於 Claude Code 自行進行的切換,例如[自動模型備援](/docs/zh-TW/model-config#automatic-model-fallback)或在您恢復工作階段時還原模型,Claude Code 不會執行 PreModelSwitch hook。這些變更只會觸發 [PostModelSwitch](#postmodelswitch)。
3370 3373
3371Claude Code 將匹配器與工作階段切換到的模型的規範名稱進行比較,忽略任何 `[1m]` 後綴。別名(例如 `opus`)、日期模型 ID 和提供者特定 ID(例如 Amazon Bedrock 模型 ID)都匹配它們解決到的一個規範名稱,因此 `claude-opus-5` 涵蓋 Opus 5 的每個拼寫。3374Claude Code 會將 matcher 與工作階段要切換到的模型的正式名稱進行比對,並忽略任何 `[1m]` 後綴。別名(例如 `opus`)、帶日期的模型 ID,以及供應商專屬 ID(例如 Amazon Bedrock 模型 ID)都會比對到它們解析出的同一個正式名稱,因此 `claude-opus-5` 涵蓋 Opus 5 的所有寫法。
3372 3375
3373當 Claude Code 無法確定目標的規範名稱時,例如僅您的 [LLM gateway](/docs/zh-TW/llm-gateway) 知道的自訂模型 ID,它無論匹配器如何都執行每個 PreModelSwitch hook。阻止的 hook 應該檢查其輸入中的 `to_model` 而不是僅依賴匹配器。3376當 Claude Code 無法判斷目標的正式名稱時,例如只有您的 [LLM 閘道](/docs/zh-TW/llm-gateway)知道的自訂模型 ID,它會不論 matcher 為何都執行每個 PreModelSwitch hook。因此,會進行封鎖的 hook 應檢查其輸入中的 `to_model`,而不是僅依賴 matcher。
3374 3377
3375將匹配器寫為精確名稱、`|` 分隔清單(例如 `claude-opus-4-6|claude-opus-5`)或正規表達式(例如 `.*opus.*`)。此範例使用精確名稱匹配器,也檢查 hook 輸入中的 `to_model`,因此它拒絕切換到 Opus 4.6,退出代碼 2,並讓任何其他目標通過:3378matcher 可以寫成確切名稱、以 `|` 分隔的清單(例如 `claude-opus-4-6|claude-opus-5`),或正規表示式(例如 `.*opus.*`)。以下範例使用確切名稱 matcher,並同時檢查 hook 輸入中的 `to_model`,因此它會以代碼 2 結束來拒絕切換到 Opus 4.6,並允許任何其他目標通過:
3376 3379
3377<Tabs>3380<Tabs>
3378 <Tab title="macOS/Linux">3381 <Tab title="macOS/Linux">
3379 命令使用 `jq` 檢查 `to_model`:3382 該命令使用 `jq` 檢查 `to_model`:
3380 3383
3381 ```json theme={null}3384 ```json theme={null}
3382 {3385 {
3398 </Tab>3401 </Tab>
3399 3402
3400 <Tab title="Windows (PowerShell)">3403 <Tab title="Windows (PowerShell)">
3401 註冊一個命令 hook,透過 PowerShell 執行指令碼:3404 註冊一個透過 PowerShell 執行指令碼的命令 hook:
3402 3405
3403 ```json theme={null}3406 ```json theme={null}
3404 {3407 {
3425 }3428 }
3426 ```3429 ```
3427 3430
3428 將此指令碼儲存到您的專案中的 `.claude/hooks/block-opus-46.ps1`:3431 將此指令碼儲存至專案中的 `.claude/hooks/block-opus-46.ps1`:
3429 3432
3430 ```powershell theme={null}3433 ```powershell theme={null}
3431 $hookInput = [Console]::In.ReadToEnd() | ConvertFrom-Json3434 $hookInput = [Console]::In.ReadToEnd() | ConvertFrom-Json
3438 </Tab>3441 </Tab>
3439</Tabs>3442</Tabs>
3440 3443
3441要確認 hook 有效,從執行不同模型的工作階段執行 `/model claude-opus-4-6`。Claude Code 保持目前模型並報告 PreModelSwitch hook 阻止了切換,以您的訊息作為原因。3444若要確認 hook 正常運作,請在執行其他模型的工作階段中執行 `/model claude-opus-4-6`。Claude Code 會保留目前的模型,並回報 PreModelSwitch hook 封鎖了切換,並以您的訊息作為原因。
3442 3445
3443<h4 id="premodelswitch-input">3446<h4 id="premodelswitch-input">
3444 PreModelSwitch 輸入3447 PreModelSwitch 輸入
3445</h4>3448</h4>
3446 3449
3447除了 [常見輸入欄位](#common-input-fields) 外,PreModelSwitch hooks 還會接收此表中的欄位。最後五個描述重新傳送對話到新模型的成本,因此 hook 可以在切換發生前顯示該數字。3450除了[通用輸入欄位](#common-input-fields)之外,PreModelSwitch hook 還會收到下表中的欄位。最後五個欄位描述將對話重新傳送至新模型的成本,讓 hook 能在切換發生之前顯示該數字。
3448 3451
3449| 欄位 | 類型 | 描述 |3452| 欄位 | 類型 | 說明 |
3450| :- | :- | :- |3453| :- | :- | :- |
3451| `from_model` | string | 切換變更的模型 ID |3454| `from_model` | string | 切換前的模型 ID |
3452| `to_model` | string | 切換變更為的模型 ID。匹配器與此模型的規範名稱進行比較 |3455| `to_model` | string | 切換後的模型 ID。matcher 會與此模型的正式名稱進行比對 |
3453| `requested_model` | string 或 `null` | 請求命名的模型:別名(例如 `opus`)、完整模型 ID,或當請求為預設模型時為 `null` |3456| `requested_model` | string 或 `null` | 請求中指定的模型:別名(例如 `opus`)、完整模型 ID,或當請求的是預設模型時為 `null` |
3454| `source` | string | 請求來自何處:`/model <name>`、`/config` 中的 Model 設定或打開 fast mode 的 `"command"`;模型選擇器的 `"picker"`;來自 Agent SDK 主機或 Remote Control 的 `set_model` 請求或 `apply_flag_settings` 請求中的模型變更的 `"sdk"` |3457| `source` | string | 請求的來源:`"command"` 表示 `/model <name>`、`/config` 中的 Model 設定,或開啟快速模式;`"picker"` 表示模型選擇器;`"sdk"` 表示來自 Agent SDK 主機或 Remote Control 的 `set_model` 請求,或 `apply_flag_settings` 請求中的模型變更 |
3455| `context_tokens` | number | 下一個請求重新傳送作為其提示的權杖:主對話中最後一個回應的輸入、快取讀取、快取建立和輸出權杖,合併。第一個回應前為 `0` |3458| `context_tokens` | number | 下一個請求作為提示詞重新傳送的 token 數:主對話中最後一個回應的輸入、快取讀取、快取建立和輸出 token 的總和。在第一個回應之前為 `0` |
3456| `prompt_cache_warm` | boolean | 目前模型的 prompt cache 是否可能仍然溫暖,意味著切換放棄它 |3459| `prompt_cache_warm` | boolean | 目前模型的提示快取是否可能仍處於暖狀態,亦即切換會使其失效 |
3457| `cache_ttl` | string | [Prompt cache 生命週期](/docs/zh-TW/prompt-caching#cache-lifetime) Claude Code 為此工作階段請求:`"5m"` 或 `"1h"` |3460| `cache_ttl` | string | Claude Code 為此工作階段請求的[提示快取存留期](/docs/zh-TW/prompt-caching#cache-lifetime):`"5m"` 或 `"1h"` |
3458| `estimated_cache_write_usd` | number | 在 `cache_ttl` 速率下將 `context_tokens` 寫入 `to_model` 上的 prompt cache 的估計成本(美元),不包括下一個回應。伺服器可能不需要重新快取整個背景資訊,因此將其視為估計 |3461| `estimated_cache_write_usd` | number | 以 `cache_ttl` 費率將 `context_tokens` 寫入 `to_model` 提示快取的預估成本(美元),不含下一個回應。伺服器可能不需要重新快取整個上下文,因此請將其視為估計值 |
3459| `pricing` | string | Claude Code 如何定價 `estimated_cache_write_usd`:當您的組織配置了自己的速率時為 `"configured"`,列表價格為 `"catalog"`,或當 `to_model` 沒有已知價格且 Claude Code 假設預設速率時為 `"default"` |3462| `pricing` | string | Claude Code 計算 `estimated_cache_write_usd` 的方式:`"configured"` 表示在您的組織已設定自有費率時採用該費率,`"catalog"` 表示採用定價表價格,`"default"` 表示 `to_model` 沒有已知價格而 Claude Code 採用預設費率 |
3460 3463
3461此範例顯示在執行 Sonnet 5 的工作階段中 `/model opus` 的輸入:3464以下範例顯示在執行 Sonnet 5 的工作階段中執行 `/model opus` 時的輸入:
3462 3465
3463```json theme={null}3466```json theme={null}
3464{3467{
3482 PreModelSwitch 決策控制3485 PreModelSwitch 決策控制
3483</h4>3486</h4>
3484 3487
3485`PreModelSwitch` hooks 可以取消切換、要求使用者確認它或讓它繼續。退出代碼 2 或頂級 `decision: "block"` 取消切換。3488`PreModelSwitch` hook 可以取消切換、要求使用者確認,或讓切換繼續進行。退出碼 2 或頂層 `decision: "block"` 會取消切換。
3486 3489
3487為了更精細的控制,在 `hookSpecificOutput` 物件中返回 `permissionDecision` 和 `permissionDecisionReason`,如 [PreToolUse](#pretooluse-decision-control) 上。`PreModelSwitch` 接受 `"allow"`、`"deny"` 和 `"ask"`。它不接受 `"defer"`、`updatedInput` 或 `additionalContext`。下表描述兩個欄位:3490若需要更精細的控制,請在 `hookSpecificOutput` 物件中回傳 `permissionDecision` 和 `permissionDecisionReason`,與 [PreToolUse](#pretooluse-decision-control) 相同。`PreModelSwitch` 接受 `"allow"`、`"deny"` 和 `"ask"`。它不接受 `"defer"`、`updatedInput` 或 `additionalContext`。下表說明這兩個欄位:
3488 3491
3489| 欄位 | 描述 |3492| 欄位 | 說明 |
3490| :- | :- |3493| :- | :- |
3491| `permissionDecision` | `"allow"` 繼續並跳過 [Claude Code 在 prompt cache 溫暖時顯示的確認](/docs/zh-TW/prompt-caching#switching-models)。`"deny"` 取消切換。`"ask"` 提示使用者確認它 |3494| `permissionDecision` | `"allow"` 會繼續進行並略過[提示快取處於暖狀態時 Claude Code 顯示的確認](/docs/zh-TW/prompt-caching#switching-models)。`"deny"` 會取消切換。`"ask"` 會提示使用者確認 |
3492| `permissionDecisionReason` | 對於 `"deny"`,顯示給使用者作為切換被阻止的原因,或作為 `set_model` 請求的錯誤返回。對於 `"ask"`,在確認提示中顯示。對於 `"allow"` 忽略 |3495| `permissionDecisionReason` | 對於 `"deny"`,會作為切換被封鎖的原因顯示給使用者,或作為 `set_model` 請求的錯誤回傳。對於 `"ask"`,會顯示在確認提示中。對於 `"allow"` 則會被忽略 |
3493 3496
3494僅互動式工作階段中的 `/model` 可以顯示 `"ask"` 提示。在每個其他表面上,包括搭配 `-p` 旗標的非互動模式、`/config` 和 `set_model` 請求,Claude Code 將 `"ask"` 視為拒絕。3497只有互動式工作階段中的 `/model` 能顯示 `"ask"` 提示。在其他所有使用介面上,包括使用 `-p` 旗標的非互動模式、`/config` 和 `set_model` 請求,Claude Code 都會將 `"ask"` 視為拒絕。
3495 3498
3496此範例要求使用者確認並引用 `context_tokens` 中的權杖計數:3499以下範例要求使用者確認,並引用 `context_tokens` 中的 token 數:
3497 3500
3498```json theme={null}3501```json theme={null}
3499{3502{
3505}3508}
3506```3509```
3507 3510
3508當多個 PreModelSwitch hooks 返回不同的決定時,優先順序為 `deny` > `ask` > `allow`。3511當多個 PreModelSwitch hook 回傳不同的決策時,優先順序為 `deny` > `ask` > `allow`。
3509 3512
3510Claude Code 無論決定如何都顯示您的 hook 返回的任何 `systemMessage`,因此成本報告 hook 可以返回 `{"systemMessage": "..."}` 並退出 0。3513無論決策為何,Claude Code 都會向使用者顯示您的 hook 回傳的任何 `systemMessage`,因此成本回報 hook 可以回傳 `{"systemMessage": "..."}` 並以 0 結束。
3511 3514
3512在其逾時之前未回應的 PreModelSwitch hook 會阻止切換。在 [PreToolUse](#timeouts) 上,相比之下,逾時的命令 hook 讓工具呼叫繼續。此事件的預設逾時為 30 秒。`PreModelSwitch` 僅執行 `command`、`http` 和 `mcp_tool` hooks,因此 `prompt` 和 `agent` 預設不適用。3515在逾時前未回應的 PreModelSwitch hook 會封鎖切換。相較之下,在 [PreToolUse](#timeouts) 上,逾時的命令 hook 會讓工具呼叫繼續進行。此事件的預設逾時為 30 秒。`PreModelSwitch` 只執行 `command`、`http` 和 `mcp_tool` hook,因此 `prompt` 和 `agent` 的預設值不適用。
3513 3516
3514退出代碼不是 0 或 2 且不列印 JSON 決定的 hook 不阻止:Claude Code 顯示其 stderr 並應用切換,如 [其他退出代碼](#other-exit-codes) 下所述。3517以 0 或 2 以外的代碼結束且未印出 JSON 決策的 hook 不會封鎖:Claude Code 會顯示其 stderr 並套用切換,如[其他退出碼](#other-exit-codes)中所述。
3515 3518
3516<h3 id="postmodelswitch">3519<h3 id="postmodelswitch">
3517 PostModelSwitch3520 PostModelSwitch
3518</h3>3521</h3>
3519 3522
3520在工作階段的模型變更後執行。使用它來給予 Claude 模型特定的指導,而不編輯每個 CLAUDE.md,例如僅在某些模型上適用的組織範圍指令。3523在工作階段的模型變更之後執行。使用它來為 Claude 提供特定於模型的指引,而無需編輯每個 CLAUDE.md,例如適用於特定模型的全組織指令。
3521 3524
3522PostModelSwitch 需要 Claude Code v2.1.251 或更新版本。它無法阻止,因為模型已變更。Claude Code 在這些變更後執行 PostModelSwitch hooks:3525PostModelSwitch 需要 Claude Code v2.1.251 或更新版本。它無法封鎖,因為模型已經變更。Claude Code 會在以下任何變更之後執行 PostModelSwitch hook:
3523 3526
3524* 您或用戶端請求的切換3527* 您或用戶端所請求的切換
3525* [自動模型回退](/docs/zh-TW/model-config#automatic-model-fallback),改變工作階段的模型3528* [自動模型備援](/docs/zh-TW/model-config#automatic-model-fallback),會變更工作階段的模型
3526* 設定(例如 [`opusplan`](/docs/zh-TW/model-config#opusplan-model-setting))進入或離開 plan mode3529* 諸如 [`opusplan`](/docs/zh-TW/model-config#opusplan-model-setting) 之類的設定進入或離開 plan mode
3527* Claude Code 在您恢復工作階段時還原模型3530* Claude Code 在您恢復工作階段時還原模型
3528 3531
3529當 [回退模型鏈](/docs/zh-TW/model-config#fallback-model-chains) 中的模型服務回合時,Claude Code 不執行 PostModelSwitch hooks,因為該替換持續一個回合,並保持工作階段的模型不變。3532當[備援模型鏈](/docs/zh-TW/model-config#fallback-model-chains)中的模型服務某個回合時,Claude Code 不會執行 PostModelSwitch hook,因為該替換只持續一個回合,且不會變更工作階段的模型。
3530 3533
3531匹配器遵循與 [PreModelSwitch](#premodelswitch) 相同的規則:Claude Code 將其與工作階段切換到的模型的規範名稱進行比較。3534matcher 遵循與 [PreModelSwitch](#premodelswitch) 相同的規則:Claude Code 會將其與工作階段所切換到的模型的正式名稱進行比對。
3532 3535
3533此範例在工作階段的模型變更為任何 Opus 模型時新增指導:3536以下範例會在工作階段的模型變更為任何 Opus 模型時新增指引:
3534 3537
3535```json theme={null}3538```json theme={null}
3536{3539{
3550}3553}
3551```3554```
3552 3555
3553要確認 hook 有效,從執行不同模型的工作階段切換到 Opus 模型,例如從 Sonnet 工作階段執行 `/model opus`,然後詢問 Claude 它對目前模型有什麼指導。3556若要確認 hook 正常運作,請從執行其他模型的工作階段切換到 Opus 模型,例如在 Sonnet 工作階段中執行 `/model opus`,然後詢問 Claude 它對目前模型有哪些指引。
3554 3557
3555<h4 id="postmodelswitch-input">3558<h4 id="postmodelswitch-input">
3556 PostModelSwitch 輸入3559 PostModelSwitch 輸入
3557</h4>3560</h4>
3558 3561
3559PostModelSwitch hooks 接收與 [PreModelSwitch](#premodelswitch-input) 相同的欄位,`hook_event_name` 設定為 `"PostModelSwitch"` 和兩個更多 `source` 值:`"auto"` 用於 Claude Code 自己進行的自動回退或其他變更,以及 `"resume"` 用於您恢復工作階段時還原的模型。3562PostModelSwitch hook 會收到與 [PreModelSwitch](#premodelswitch-input) 相同的欄位,其中 `hook_event_name` 設定為 `"PostModelSwitch"`,且多了兩個 `source` 值:`"auto"` 表示自動備援或 Claude Code 自行進行的其他變更,`"resume"` 表示在您恢復工作階段時還原的模型。
3560 3563
3561當 `source` 為 `"auto"` 時,`requested_model` 為 `null`。當 `source` 為 `"resume"` 時,它是 Claude Code 還原的儲存模型設定。3564當 `source` 為 `"auto"` 時,`requested_model` 為 `null`。當 `source` 為 `"resume"` 時,它是 Claude Code 所還原的已儲存模型設定。
3562 3565
3563<h4 id="postmodelswitch-decision-control">3566<h4 id="postmodelswitch-decision-control">
3564 PostModelSwitch 決策控制3567 PostModelSwitch 決策控制
3565</h4>3568</h4>
3566 3569
3567Claude Code 採用您的 hook 在退出 0 時的 [純文字 stdout](#exit-code-0),或 JSON 輸出中的 `additionalContext`,並在切換後的下一個請求中將其傳遞給 Claude。除了所有 hooks 可用的 [JSON 輸出欄位](#json-output) 外,您可以返回:3570Claude Code 會在結束代碼為 0 時取用您的 hook 的[純文字 stdout](#exit-code-0),或取用 JSON 輸出中的 `additionalContext`,並隨切換後的下一個請求傳遞給 Claude。除了所有 hook 都可使用的 [JSON 輸出欄位](#json-output)之外,您還可以回傳:
3568 3571
3569| 欄位 | 描述 |3572| 欄位 | 說明 |
3570| :- | :- |3573| :- | :- |
3571| `additionalContext` | 與下一個請求一起新增到 Claude 背景資訊的字串。有關詳細資訊,請參閱 [為 Claude 新增背景資訊](#add-context-for-claude) |3574| `additionalContext` | 隨下一個請求加入 Claude 上下文的字串。請參閱[為 Claude 新增上下文](#add-context-for-claude) |
3572 3575
3573如果 hook 在您傳送下一個提示後五秒內未完成,Claude Code 傳送該請求而不輸出,並將其附加到下一個請求。如果模型在下一個請求之前變更多次,Claude Code 僅傳遞最後一個切換目標模型的輸出。3576如果在您傳送下一個提示詞後五秒內 hook 尚未完成,Claude Code 會在不含該輸出的情況下傳送該請求,並改為將輸出附加到之後的請求。如果模型在下一個請求之前變更多次,Claude Code 只會傳遞最後一次切換之目標模型的輸出。
3574 3577
3575<h3 id="sessionend">3578<h3 id="sessionend">
3576 SessionEnd3579 SessionEnd
3577</h3>3580</h3>
3578 3581
3579在 Claude Code 工作階段結束時執行。適用於清理任務、記錄工作階段統計資訊或儲存工作階段狀態。支援匹配器以按退出原因篩選。3582在 Claude Code 工作階段結束時執行。適用於清理工作、記錄工作階段
3583統計資料或儲存工作階段狀態。支援使用 matcher 依結束原因進行篩選。
3580 3584
3581hook 輸入中的 `reason` 欄位指示工作階段為什麼結束:3585hook 輸入中的 `reason` 欄位表示工作階段結束的原因:
3582 3586
3583| 原因 | 描述 |3587| 原因 | 說明 |
3584| :- | :- |3588| :- | :- |
3585| `clear` | 使用 `/clear` 命令清除工作階段 |3589| `clear` | 使用 `/clear` 命令清除工作階段 |
3586| `resume` | 透過互動式 `/resume` 切換工作階段 |3590| `resume` | 透過互動式 `/resume` 切換工作階段 |
3587| `logout` | 使用者登出 |3591| `logout` | 使用者登出 |
3588| `prompt_input_exit` | 使用者在提示輸入可見時退出 |3592| `prompt_input_exit` | 使用者在提示詞輸入可見時結束 |
3589| `other` | 其他退出原因 |3593| `other` | 其他結束原因 |
3590| `bypass_permissions_disabled` | 在 v2.1.234 中移除;Claude Code 不傳送它。從您的 `SessionEnd` 匹配器中刪除它 |3594| `bypass_permissions_disabled` | 已在 v2.1.234 中移除;Claude Code 不會傳送此值。請從您的 `SessionEnd` matcher 中移除它 |
3591 3595
3592<h4 id="sessionend-input">3596<h4 id="sessionend-input">
3593 SessionEnd 輸入3597 SessionEnd 輸入
3594</h4>3598</h4>
3595 3599
3596除了 [常見輸入欄位](#common-input-fields) 外,SessionEnd hooks 還會接收 `reason` 欄位,指示工作階段為什麼結束。有關所有值,請參閱上面的 [原因表](#sessionend)。3600除了[通用輸入欄位](#common-input-fields)之外,SessionEnd hook 還會收到表示工作階段結束原因的 `reason` 欄位。所有值請參閱上方的[原因表格](#sessionend)。
3597 3601
3598```json theme={null}3602```json theme={null}
3599{3603{
3605}3609}
3606```3610```
3607 3611
3608SessionEnd hooks 沒有決策控制。它們無法阻止工作階段終止,但可以執行清理任務。Claude Code 捨棄它們的 [JSON 輸出欄位](#json-output),例如 `systemMessage`。3612SessionEnd hook 沒有決策控制。它們無法封鎖工作階段終止,但可以執行清理工作。Claude Code 會捨棄它們的 [JSON 輸出欄位](#json-output),例如 `systemMessage`。
3609 3613
3610SessionEnd hooks 的預設逾時為 1.5 秒。當您退出、執行 `/clear` 或使用互動式 `/resume` 切換工作階段時適用。您可以透過兩種方式給予 hook 更多時間:3614SessionEnd hook 的預設逾時為 1.5 秒。此逾時適用於您結束、執行 `/clear` 或透過互動式 `/resume` 切換工作階段時。您可以透過兩種方式給予 hook 更多時間:
3611 3615
3612* **每個 hook `timeout`**:在該 hook 的配置中設定 `timeout`。整體預算自動上升以符合您設定檔中最高每個 hook `timeout`,最多 60 秒。如果您以這種方式提高預算,沒有自己的 `timeout` 的 hook 仍保持預設。在外掛提供的 hooks 上設定的逾時不會提高預算。3616* **個別 hook 的 `timeout`**:在該 hook 的設定中設定 `timeout`。整體預算會自動提高,以符合您設定檔中最高的個別 hook `timeout`,上限為 60 秒。如果您以這種方式提高預算,沒有自己 `timeout` 的 hook 仍會保留預設值。在外掛程式提供的 hook 上設定的逾時不會提高預算。
3613* **`CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS`**:設定此環境變數(毫秒)以明確覆寫預算。您設定的值也成為每個沒有自己的 `timeout` 的 hook 的逾時。3617* **`CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS`**:以毫秒為單位設定此環境變數,以明確覆寫預算。您設定的值也會成為每個沒有自己 `timeout` 之 hook 的逾時。
3614 3618
3615此範例將預算設定為 5 秒:3619以下範例將預算設定為 5 秒:
3616 3620
3617```bash theme={null}3621```bash theme={null}
3618CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS=5000 claude3622CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS=5000 claude
3619```3623```
3620 3624
3621在 v2.1.268 之前,`CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS` 僅提高整體預算,沒有自己的 `timeout` 的 hook 在 1.5 秒後仍被取消。3625在 v2.1.268 之前,`CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS` 只會提高整體預算,沒有自己 `timeout` 的 hook 仍會在 1.5 秒後被取消。
3622 3626
3623<h3 id="elicitation">3627<h3 id="elicitation">
3624 Elicitation3628 Elicitation
3625</h3>3629</h3>
3626 3630
3627在 MCP 伺服器要求使用者輸入中途任務時執行。預設情況下,Claude Code 為使用者回應顯示互動式對話。Hooks 可以攔截此請求並以程式設計方式回應,完全跳過對話。3631在 MCP 伺服器於工作進行中請求使用者輸入時執行。根據預設,Claude Code 會顯示互動式對話方塊供使用者回應。hook 可以攔截此請求並以程式化方式回應,完全略過對話方塊。
3628 3632
3629匹配器欄位與 MCP 伺服器名稱匹配。3633matcher 欄位會與 MCP 伺服器名稱進行比對。
3630 3634
3631<h4 id="elicitation-input">3635<h4 id="elicitation-input">
3632 Elicitation 輸入3636 Elicitation 輸入
3633</h4>3637</h4>
3634 3638
3635除了 [常見輸入欄位](#common-input-fields) 外,Elicitation hooks 還會接收 `mcp_server_name`、`message` 和可選的 `mode`、`url`、`elicitation_id` 和 `requested_schema` 欄位。3639除了[通用輸入欄位](#common-input-fields)之外,Elicitation hook 還會收到 `mcp_server_name`、`message`,以及選用的 `mode`、`url`、`elicitation_id` 和 `requested_schema` 欄位。
3636 3640
3637對於表單模式引出,最常見的情況:3641對於表單模式的 elicitation(最常見的情況):
3638 3642
3639```json theme={null}3643```json theme={null}
3640{3644{
3654}3658}
3655```3659```
3656 3660
3657對於 URL 模式引出,用於基於瀏覽器的驗證:3661對於 URL 模式的 elicitation,用於基於瀏覽器的身分驗證:
3658 3662
3659```json theme={null}3663```json theme={null}
3660{3664{
3673 Elicitation 輸出3677 Elicitation 輸出
3674</h4>3678</h4>
3675 3679
3676要以程式設計方式回應而不顯示對話,請返回具有 `hookSpecificOutput` 的 JSON 物件:3680若要在不顯示對話方塊的情況下以程式化方式回應,請回傳含有 `hookSpecificOutput` 的 JSON 物件:
3677 3681
3678```json theme={null}3682```json theme={null}
3679{3683{
3687}3691}
3688```3692```
3689 3693
3690| 欄位 | 值 | 描述 |3694| 欄位 | 值 | 說明 |
3691| :- | :- | :- |3695| :- | :- | :- |
3692| `action` | `accept`、`decline`、`cancel` | 是否接受、拒絕或取消請求 |3696| `action` | `accept`、`decline`、`cancel` | 是否接受、拒絕或取消請求 |
3693| `content` | object | 要提交的表單欄位值。僅在 `action` 為 `accept` 時使用 |3697| `content` | object | 要提交的表單欄位值。僅在 `action` 為 `accept` 時使用 |
3694 3698
3695退出代碼 2 拒絕引出。Claude Code 不在任何地方顯示您的 stderr 訊息。3699退出碼 2 會拒絕 elicitation。Claude Code 不會在任何地方顯示您的 stderr 訊息。
3696 3700
3697Claude Code 作用於 Elicitation hook 的 JSON 輸出中的 `hookSpecificOutput`,並捨棄 `systemMessage` 和 `continue`。3701Claude Code 會依據 Elicitation hook JSON 輸出中的 `hookSpecificOutput` 採取行動,並捨棄 `systemMessage` 和 `continue`。
3698 3702
3699<h3 id="elicitationresult">3703<h3 id="elicitationresult">
3700 ElicitationResult3704 ElicitationResult
3701</h3>3705</h3>
3702 3706
3703在使用者回應 MCP 引出後執行。Hooks 可以觀察、修改或阻止回應,然後將其傳送回 MCP 伺服器。3707在使用者回應 MCP elicitation 之後執行。hook 可以在回應傳回 MCP 伺服器之前觀察、修改或封鎖該回應。
3704 3708
3705匹配器欄位與 MCP 伺服器名稱匹配。3709matcher 欄位會與 MCP 伺服器名稱進行比對。
3706 3710
3707<h4 id="elicitationresult-input">3711<h4 id="elicitationresult-input">
3708 ElicitationResult 輸入3712 ElicitationResult 輸入
3709</h4>3713</h4>
3710 3714
3711除了 [常見輸入欄位](#common-input-fields) 外,ElicitationResult hooks 還會接收 `mcp_server_name`、`action` 和可選的 `mode`、`elicitation_id` 和 `content` 欄位。3715除了[通用輸入欄位](#common-input-fields)之外,ElicitationResult hook 還會收到 `mcp_server_name`、`action`,以及選用的 `mode`、`elicitation_id` 和 `content` 欄位。
3712 3716
3713```json theme={null}3717```json theme={null}
3714{3718{
3728 ElicitationResult 輸出3732 ElicitationResult 輸出
3729</h4>3733</h4>
3730 3734
3731要覆寫使用者的回應,請返回具有 `hookSpecificOutput` 的 JSON 物件:3735若要覆寫使用者的回應,請回傳含有 `hookSpecificOutput` 的 JSON 物件:
3732 3736
3733```json theme={null}3737```json theme={null}
3734{3738{
3740}3744}
3741```3745```
3742 3746
3743| 欄位 | 值 | 描述 |3747| 欄位 | 值 | 說明 |
3744| :- | :- | :- |3748| :- | :- | :- |
3745| `action` | `accept`、`decline`、`cancel` | 覆寫使用者的動作 |3749| `action` | `accept`、`decline`、`cancel` | 覆寫使用者的動作 |
3746| `content` | object | 覆寫表單欄位值。僅在 `action` 為 `accept` 時有意義 |3750| `content` | object | 覆寫表單欄位值。僅在 `action` 為 `accept` 時有意義 |
3747 3751
3748退出代碼 2 阻止回應,將有效動作變更為 `decline`。Claude Code 不在任何地方顯示您的 stderr 訊息。3752退出碼 2 會封鎖回應,將實際動作變更為 `decline`。Claude Code 不會在任何地方顯示您的 stderr 訊息。
3749 3753
3750Claude Code 作用於 ElicitationResult hook 的 JSON 輸出中的 `hookSpecificOutput`,並捨棄 `systemMessage` 和 `continue`。3754Claude Code 會依據 ElicitationResult hook JSON 輸出中的 `hookSpecificOutput` 採取行動,並捨棄 `systemMessage` 和 `continue`。
3751 3755
3752<h2 id="prompt-based-hooks">3756<h2 id="prompt-based-hooks">
3753 基於提示的 hooks3757 基於提示的 hooks