钩子是在会话的特定生命周期节点执行的外部命令,用于实现自定义自动化、安全控制和集成。 挂钩配置文件会自动从 .github/hooks/*.json 存储库中加载。
钩子配置格式
挂钩配置文件使用 JSON 格式和版本 1。
指令钩
命令挂钩运行 shell 脚本,在所有挂钩类型上都受支持。
{
"version": 1,
"hooks": {
"preToolUse": [
{
"type": "command",
"bash": "your-bash-command",
"powershell": "your-powershell-command",
"cwd": "optional/working/directory",
"env": { "VAR": "value" },
"timeoutSec": 30
}
]
}
}
| 领域 | 类型 | 必需 | Description |
|---|---|---|---|
bash | 字符串 | 其中一个 bash/powershell | Unix 的 Shell 命令。 |
cwd | 字符串 | 否 | 命令的工作目录(相对于存储库根目录或绝对目录)。 |
env | 对象 | 否 | 要设置的环境变量(支持变量扩展)。 |
powershell | 字符串 | 其中一个 bash/powershell | 适用于 Windows 的 Shell 命令。 |
timeoutSec | 数字 | 否 | 超时时间(以秒为单位) 默认值:30。 |
type | "command" | 是的 | 必须是 "command"。 |
提示钩子
提示挂钩自动提交文本,就好像用户键入了它一样。 这些仅在 sessionStart 上受支持,并且仅为 新的交互式会话触发。 它们不会在恢复时触发,也不会在非交互式提示模式下触发(-p)。 文本可以是自然语言提示或斜杠命令。
{
"version": 1,
"hooks": {
"sessionStart": [
{
"type": "prompt",
"prompt": "Your prompt text or /slash-command"
}
]
}
}
| 领域 | 类型 | 必需 | Description |
|---|---|---|---|
type | "prompt" | 是的 | 必须是 "prompt"。 |
prompt | 字符串 | 是的 | 要提交的文本可以是自然语言消息或斜杠命令。 |
挂钩事件
| 事件 | 触发时间 | 已处理的输出 |
|---|---|---|
agentStop | 主代理完成回合。 | 是 — 可以阻止和强制继续。 |
errorOccurred | 执行期间发生错误。 | 否 |
notification | 每当 CLI 发出系统通知(如 shell 完成、代理完成或空闲状态、权限提示、引发对话框)时,都会异步触发。 触发和忘记:从不阻止会话。 支持 matcher 正则表达式适用于 notification_type. | 可选:可以将 additionalContext 注入到会话中。 |
permissionRequest | 在权限服务运行之前触发(规则引擎、会话审批、自动允许/自动拒绝和用户提示)。 如果合并挂钩输出返回 behavior: "allow" 或 "deny",该决策会使正常权限流短路。 支持 matcher 正则表达式适用于 toolName. | 是 — 可以以编程方式允许或拒绝。 |
postToolUse | 每个工具成功完成操作后。 | 是 — 可以替换成功的结果(仅 SDK 编程挂钩)。 |
postToolUseFailure | 工具以失败告终。 | 是 — 可以通过(命令挂钩的退出代码additionalContext)提供恢复指导2。 |
preCompact | 上下文压缩即将开始(手动或自动)。 支持 matcher 按触发器("manual" 或 "auto") 进行筛选。 | 否 - 仅通知。 |
preToolUse | 在每个工具执行之前。 | 是 — 可以允许、拒绝或修改。 |
sessionEnd | 会话终止。 | 否 |
sessionStart | 新的或已恢复的会话开始。 | 否 |
subagentStart | 子代理在运行之前生成。 返回子智能体提示符前的 additionalContext。 支持 matcher 按代理名称进行筛选。 | 否 — 无法阻止创建。 |
subagentStop | 子代理完成。 | 是 — 可以阻止和强制继续。 |
userPromptSubmitted | 用户提交提示。 | 否 |
钩子事件输入负载
每个挂钩事件将 JSON 有效负载传递到挂钩处理程序。 支持两种负载格式,可根据挂钩配置中使用的事件名称进行选择。
- camelCase 格式 - 在 camelCase 中配置事件名称(例如)。
sessionStart字段使用 camelCase。
VS Code兼容格式** - 在 PascalCase 中配置事件名称(例如)。 `SessionStart` 字段使用snake_case来匹配 VS CodeCopilot 扩展格式。
sessionStart / SessionStart
**camelCase 输入:**
{
sessionId: string;
timestamp: number; // Unix timestamp in milliseconds
cwd: string;
source: "startup" | "resume" | "new";
initialPrompt?: string;
}
**
VS Code 兼容的输入:**
{
hook_event_name: "SessionStart";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
source: "startup" | "resume" | "new";
initial_prompt?: string;
}
sessionEnd / SessionEnd
**camelCase 输入:**
{
sessionId: string;
timestamp: number;
cwd: string;
reason: "complete" | "error" | "abort" | "timeout" | "user_exit";
}
**
VS Code 兼容的输入:**
{
hook_event_name: "SessionEnd";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
reason: "complete" | "error" | "abort" | "timeout" | "user_exit";
}
userPromptSubmitted / UserPromptSubmit
**camelCase 输入:**
{
sessionId: string;
timestamp: number;
cwd: string;
prompt: string;
}
**
VS Code 兼容的输入:**
{
hook_event_name: "UserPromptSubmit";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
prompt: string;
}
preToolUse / PreToolUse
**camelCase 输入:**
{
sessionId: string;
timestamp: number;
cwd: string;
toolName: string;
toolArgs: unknown;
}
**
VS Code 兼容的输入:**
配置使用 PascalCase 事件名称PreToolUse时,数据载荷使用 snake_case 字段名称以匹配 VS CodeCopilot 扩展格式。
{
hook_event_name: "PreToolUse";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
tool_name: string;
tool_input: unknown; // Tool arguments (parsed from JSON string when possible)
}
postToolUse / PostToolUse
**camelCase 输入:**
{
sessionId: string;
timestamp: number;
cwd: string;
toolName: string;
toolArgs: unknown;
toolResult: {
resultType: "success";
textResultForLlm: string;
}
}
**
VS Code 兼容的输入:**
{
hook_event_name: "PostToolUse";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
tool_name: string;
tool_input: unknown;
tool_result: {
result_type: "success" | "failure" | "denied" | "error";
text_result_for_llm: string;
}
}
postToolUseFailure / PostToolUseFailure
**camelCase 输入:**
{
sessionId: string;
timestamp: number;
cwd: string;
toolName: string;
toolArgs: unknown;
error: string;
}
**
VS Code 兼容的输入:**
{
hook_event_name: "PostToolUseFailure";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
tool_name: string;
tool_input: unknown;
error: string;
}
agentStop / Stop
**camelCase 输入:**
{
sessionId: string;
timestamp: number;
cwd: string;
transcriptPath: string;
stopReason: "end_turn";
}
**
VS Code 兼容的输入:**
{
hook_event_name: "Stop";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
transcript_path: string;
stop_reason: "end_turn";
}
subagentStart
**输入:**
{
sessionId: string;
timestamp: number;
cwd: string;
transcriptPath: string;
agentName: string;
agentDisplayName?: string;
agentDescription?: string;
}
subagentStop / SubagentStop
**camelCase 输入:**
{
sessionId: string;
timestamp: number;
cwd: string;
transcriptPath: string;
agentName: string;
agentDisplayName?: string;
stopReason: "end_turn";
}
**
VS Code 兼容的输入:**
{
hook_event_name: "SubagentStop";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
transcript_path: string;
agent_name: string;
agent_display_name?: string;
stop_reason: "end_turn";
}
errorOccurred / ErrorOccurred
**camelCase 输入:**
{
sessionId: string;
timestamp: number;
cwd: string;
error: {
message: string;
name: string;
stack?: string;
};
errorContext: "model_call" | "tool_execution" | "system" | "user_input";
recoverable: boolean;
}
**
VS Code 兼容的输入:**
{
hook_event_name: "ErrorOccurred";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
error: {
message: string;
name: string;
stack?: string;
};
error_context: "model_call" | "tool_execution" | "system" | "user_input";
recoverable: boolean;
}
preCompact / PreCompact
**camelCase 输入:**
{
sessionId: string;
timestamp: number;
cwd: string;
transcriptPath: string;
trigger: "manual" | "auto";
customInstructions: string;
}
**
VS Code 兼容的输入:**
{
hook_event_name: "PreCompact";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
transcript_path: string;
trigger: "manual" | "auto";
custom_instructions: string;
}
`preToolUse` 决策控制
挂钩 preToolUse 可以通过将 JSON 对象写入 stdout 来控制工具执行。
| 领域 | 价值观 | Description |
|---|---|---|
permissionDecision |
`"allow"`、`"deny"`、`"ask"` | 工具是否已执行? 空输出使用默认行为。 |
| permissionDecisionReason | 字符串 | 显示给代理的原因。 决策 "deny"时是必要的。 |
| modifiedArgs | 对象 | 替换工具参数以使用,而不是使用原始参数。 |
`agentStop`
/
`subagentStop` 决策控制
| 领域 | 价值观 | Description |
|---|---|---|
decision |
`"block"`、`"allow"` |
`"block"` 强制另一个代理将 `reason` 作为提示。 |
| reason | 字符串 | 当decision是"block"时,提示下一轮。 |
`permissionRequest` 决策控制
该 permissionRequest 挂钩在权限服务运行前触发—在规则检查、会话审批、自动允许/自动拒绝和用户提示之前触发。 如果挂钩返回 behavior: "allow" 或 "deny",该决策会使正常权限流短路。 不返回任何结果时,将继续执行正常的权限处理。 使用它以编程方式批准或拒绝工具调用-在管道模式(-p)和 CI 环境中特别有用,其中没有交互式提示可用。
所有配置的permissionRequest挂钩都针对每个请求运行(权限类型除外read``hook,这些挂钩在挂钩前短路)。 钩子输出会合并,后续钩子输出会覆盖早期的钩子输出。
**匹配器:** 可选正则表达式针对 `toolName` 进行测试。 定位为 `^(?:pattern)$`;必须与完整的工具名称匹配。 设置时,挂钩仅针对匹配的工具名称触发。
将 JSON 输出到 stdout 以控制权限决策:
| 领域 | 价值观 | Description |
|---|---|---|
behavior |
`"allow"`、`"deny"` | 是否批准或拒绝工具调用请求。 |
| message | 字符串 | 拒绝时,原因会反馈给 LLM。 |
| interrupt | 布尔 | 当true与"deny"结合使用时,将完全停止代理。 |
返回空输出或{}以继续正常权限流程。 对于命令钩子,退出代码 2 被视为拒绝执行,stdout JSON(如果有)与 {"behavior":"deny"} 合并,而 stderr 会被忽略。
`notification` 钩子
当 notification CLI 发出系统通知时,挂钩会异步触发。 这些挂钩是即发即弃型的:它们永远不会阻塞会话,并且记录并跳过任何错误。
**输入:**
{
sessionId: string;
timestamp: number;
cwd: string;
hook_event_name: "Notification";
message: string; // Human-readable notification text
title?: string; // Short title (e.g., "Permission needed", "Shell completed")
notification_type: string; // One of the types listed below
}
**通知类型:**
| 类型 | 当它触发时 |
|---|---|
shell_completed | 后台异步 shell 命令完成 |
shell_detached_completed | 断开连接的 shell 会话完成 |
agent_completed | 后台子代理完成(已完成或失败) |
agent_idle | 后台代理完成一个循环并进入空闲状态(正在等待 write_agent) |
permission_prompt | 代理请求执行工具的权限 |
elicitation_dialog | 代理从用户请求其他信息 |
**输出:**
{
additionalContext?: string; // Injected into the session as a user message
}
如果 additionalContext 返回,文本将作为追加的用户消息注入到会话中。 如果会话处于空闲状态,可能会触发进一步的代理处理。 返回 {} 或空输出以不执行任何操作。
**匹配器:** 在 `notification_type` 上可选的正则表达式。 该模式被定位为 `^(?:pattern)$`。 省略 `matcher` 以接收所有通知类型。
挂钩匹配工具名称
| 工具名称 | Description |
|---|---|
ask_user | 询问用户一个澄清的问题。 |
bash | 执行 shell 命令(Unix)。 |
create | 创建新文件。 |
edit | 修改文件内容。 |
glob | 按模式查找文件。 |
grep | 搜索文件内容。 |
powershell | 执行 shell 命令(Windows)。 |
task | 运行子代理任务。 |
view | 读取文件内容。 |
web_fetch | 抓取网页。 |
如果配置了同一类型的多个挂钩,则它们按顺序执行。 对于 preToolUse,如果任何挂钩返回 "deny",则阻止该工具。 对于 postToolUseFailure 命令挂钩,退出代码 2 会导致 stderr 被返回,用于指导助手恢复。 挂钩故障(非零退出代码或超时)会记录并跳过,它们永远不会阻止代理执行。