diff --git a/docs/en/customization/hooks.md b/docs/en/customization/hooks.md index 1f966e341..e0c039254 100644 --- a/docs/en/customization/hooks.md +++ b/docs/en/customization/hooks.md @@ -98,7 +98,7 @@ Only **blockable events** (`PreToolUse`, `Stop`, `UserPromptSubmit`) have return | Event | Matcher matches | Supports blocking? | Description | | --- | --- | --- | --- | -| `UserPromptSubmit` | The text submitted by the user | ✓ | Triggered when the user sends a message; returned text is appended to context; if blocked, the model is not called for this turn | +| `UserPromptSubmit` | Text extracted from the submitted content parts | ✓ | Triggered when the user sends a message; returned text is appended to context; if blocked, the model is not called for this turn | | `PreToolUse` | Tool name | ✓ | Triggered before a tool call (before permission checks); the tool will not execute if blocked | | `Stop` | Empty string | ✓ | Triggered when the model is about to end the current turn; if blocked, a message can be appended to let the model continue | | `PostToolUse` | Tool name | — | Triggered after a tool executes successfully (observation only) | @@ -115,6 +115,31 @@ Only **blockable events** (`PreToolUse`, `Stop`, `UserPromptSubmit`) have return | `PostCompact` | `manual` or `auto` | — | Triggered after context compaction completes (observation only) | | `Notification` | Notification type (e.g. `task.completed`) | — | Triggered when a background task status changes (observation only) | +### Per-event payload fields + +Every hook receives `hook_event_name`, `session_id`, and `cwd`. These event-specific fields are added when available; fields without a value are omitted from stdin. + +| Event | Extra stdin fields | +| --- | --- | +| `UserPromptSubmit` | `prompt` (`ContentPart[]`) | +| `PreToolUse` | `tool_name`, `tool_input`, `tool_call_id` | +| `PermissionRequest` | `turn_id`, `tool_call_id`, `tool_name`, `action`, `tool_input`, `display` | +| `PermissionResult` | `turn_id`, `tool_call_id`, `tool_name`, `action`, `decision`; may also include `scope`, `feedback`, `selected_label`, or `error` | +| `PostToolUse` | `tool_name`, `tool_input`, `tool_call_id`, `tool_output` (truncated to 2000 characters) | +| `PostToolUseFailure` | `tool_name`, `tool_input`, `tool_call_id`, `error` | +| `Stop` | `stop_hook_active` | +| `StopFailure` | `error_type`, `error_message` | +| `Interrupt` | `turn_id`, `reason` | +| `SessionStart` | `source` (`startup` or `resume`) | +| `SessionEnd` | `reason` (`exit`) | +| `SubagentStart` | `agent_name`, `prompt` (preview-truncated) | +| `SubagentStop` | `agent_name`, `response` (preview-truncated) | +| `PreCompact` | `trigger`, `token_count` | +| `PostCompact` | `trigger`, `estimated_token_count` | +| `Notification` | `notification_type`, `title`, `body`, `severity`, `source_kind`, `source_id`, `sink` | + +For `UserPromptSubmit`, the hook receives the submitted message as `prompt: ContentPart[]` on stdin. Text-only prompts are represented as `[{"type":"text","text":"..."}]`; prompts with images or other media include additional content-part objects. The matcher still runs against the text extracted from those content parts. + ## Example: Blocking Dangerous Shell Commands The following hook checks the command content before the Agent calls the `Bash` tool and blocks it if `rm -rf` is detected: diff --git a/docs/zh/customization/hooks.md b/docs/zh/customization/hooks.md index a506923b9..00be42e00 100644 --- a/docs/zh/customization/hooks.md +++ b/docs/zh/customization/hooks.md @@ -98,7 +98,7 @@ Hook 命令的工作目录是当前会话的项目目录。非 Windows 平台上 | 事件 | Matcher 匹配的是 | 会触发阻断? | 说明 | | --- | --- | --- | --- | -| `UserPromptSubmit` | 用户提交的文本内容 | ✓ | 用户发送消息时触发;返回文本会附加到上下文;若阻断,本轮不调用模型 | +| `UserPromptSubmit` | 从提交的 content part 中提取的文本 | ✓ | 用户发送消息时触发;返回文本会附加到上下文;若阻断,本轮不调用模型 | | `PreToolUse` | 工具名 | ✓ | 工具调用前触发(权限检查前);阻断后工具不会执行 | | `Stop` | 空字符串 | ✓ | 模型准备结束本轮时触发;阻断后可追加一条消息让模型继续 | | `PostToolUse` | 工具名 | — | 工具成功执行后触发(观察用) | @@ -115,6 +115,31 @@ Hook 命令的工作目录是当前会话的项目目录。非 Windows 平台上 | `PostCompact` | `manual` 或 `auto` | — | 上下文压缩完成后触发(观察用) | | `Notification` | 通知类型(如 `task.completed`) | — | 后台任务状态变化时触发(观察用) | +### 各事件的 payload 字段 + +每个 hook 都会收到 `hook_event_name`、`session_id` 和 `cwd`。下表列出各事件额外加入的字段;没有值的字段会从 stdin 中省略。 + +| 事件 | 额外 stdin 字段 | +| --- | --- | +| `UserPromptSubmit` | `prompt`(`ContentPart[]`) | +| `PreToolUse` | `tool_name`、`tool_input`、`tool_call_id` | +| `PermissionRequest` | `turn_id`、`tool_call_id`、`tool_name`、`action`、`tool_input`、`display` | +| `PermissionResult` | `turn_id`、`tool_call_id`、`tool_name`、`action`、`decision`;也可能包含 `scope`、`feedback`、`selected_label` 或 `error` | +| `PostToolUse` | `tool_name`、`tool_input`、`tool_call_id`、`tool_output`(截断到 2000 个字符) | +| `PostToolUseFailure` | `tool_name`、`tool_input`、`tool_call_id`、`error` | +| `Stop` | `stop_hook_active` | +| `StopFailure` | `error_type`、`error_message` | +| `Interrupt` | `turn_id`、`reason` | +| `SessionStart` | `source`(`startup` 或 `resume`) | +| `SessionEnd` | `reason`(`exit`) | +| `SubagentStart` | `agent_name`、`prompt`(预览内容会被截断) | +| `SubagentStop` | `agent_name`、`response`(预览内容会被截断) | +| `PreCompact` | `trigger`、`token_count` | +| `PostCompact` | `trigger`、`estimated_token_count` | +| `Notification` | `notification_type`、`title`、`body`、`severity`、`source_kind`、`source_id`、`sink` | + +对于 `UserPromptSubmit`,hook 在 stdin 中收到的 `prompt` 是 `ContentPart[]` 数组。纯文本 prompt 会表示为 `[{"type":"text","text":"..."}]`;带图片或其他媒体的 prompt 会包含额外的 content part 对象。matcher 仍然匹配从这些 content part 中提取出的文本。 + ## 示例:阻断危险 Shell 命令 下面的 hook 在 Agent 调用 `Bash` 工具前检查命令内容,发现 `rm -rf` 就阻断: