钩子
在受支持生命周期事件中运行可审查的命令或 MCP 工具。
钩子的作用
钩子在指定事件发生时执行确定的检查或辅助操作,可用于拦截工具、附加上下文或运行项目检查。它是能执行代码的配置,不是普通说明文本;必须先审查来源、命令、输入和副作用。
发现位置与信任
当前发现器读取 LIME_HOME 下的 config.toml、项目 .lime/config.toml 中的 hooks 声明,以及已加载插件随附的钩子。这是钩子专用发现路径,不等于用户 YAML 配置支持同名字段。
用户、项目和插件的匹配处理器累加。非托管钩子需要持久化信任哈希;修改命令或关键配置后重新审查。禁用状态和信任状态分别管理,读取成功不能替代授权执行。
配置结构
按事件声明 matcher 分组,每组包含一个或多个 hooks 处理器。命令处理器使用 type = "command";插件 hooks.json 使用同一事件与处理器结构的 JSON 表达。
[[hooks.PreToolUse]]
matcher = "Bash"
[[hooks.PreToolUse.hooks]]
type = "command"
command = "python3 scripts/check-command.py"
timeout = 5
statusMessage = "检查命令范围"示例需要由你实现并审查 scripts/check-command.py。不要把未经检查的外部脚本直接加入可信钩子。
命令处理器字段
| 字段 | 含义 |
|---|---|
| command | 执行的命令。 |
| commandWindows | Windows 专用命令,可覆盖平台差异。 |
| timeout | 超时秒数;普通事件默认 600 秒。 |
| async | 后台运行,不能提供同步拦截决策。 |
| statusMessage | 运行期间的状态说明。 |
| additionalContextLimit | 支持的事件中附加上下文的长度限制。 |
SessionEnd 默认 1 秒,最多 3 秒,并在会话结束阶段同步执行。Interrupt 也使用受限执行时间,不应用来运行长期任务。
事件参考
| 事件 | 触发点与用途 |
|---|---|
| SessionStart | 会话开始,准备上下文。 |
| SessionEnd | 会话结束,做短时清理。 |
| UserPromptSubmit | 用户提示提交。 |
| PreToolUse | 工具执行前,可阻止或调整允许的输入。 |
| PermissionRequest | 权限请求期间,返回允许或拒绝。 |
| PostToolUse | 工具执行后观察结果,不能撤销副作用。 |
| PreCompact | 压缩前。 |
| PostCompact | 压缩后。 |
| SubagentStart | 子智能体启动。 |
| SubagentStop | 子智能体准备停止。 |
| Stop | 主智能体准备结束。 |
| Interrupt | 活动轮次取消后。 |
当前执行器不提供 PreModelRequest 或 PostModelRequest。prompt 和 agent 处理器虽可被配置解析,但不会执行;使用已支持的 command 或 mcp_tool。
匹配器
matcher 是针对事件匹配值的正则表达式。省略、空值或 * 表示匹配全部。先用精确工具名缩小范围,再增加必要模式,避免一个宽泛规则拦截所有任务。
命令工具可使用 Bash 等匹配名称,文件修改可使用适配器提供的 Edit、Write 别名,MCP 工具使用其实际工具标识。不要根据界面展示名称猜工具 ID;write_stdin 不是新的一次命令启动。
输入数据
命令从标准输入读取 JSON。通用字段包括 session_id、transcript_path、cwd、hook_event_name,并按事件提供 turn_id、permission_mode、工具名、输入、输出或中断信息。使用 JSON 解析器读取字段,不依赖文本拼接。
import json
import sys
payload = json.load(sys.stdin)
if payload.get("hook_event_name") == "PreToolUse":
tool_name = payload.get("tool_name", "")
# 在这里执行项目实际需要的确定性检查。
print(json.dumps({"continue": True}))只读取本次事件需要的信息。会话日志可能包含敏感上下文,不应默认上传或完整复制到其他日志。
输出与失败
标准输出可返回事件支持的 JSON 字段;标准错误用于诊断。退出码 2 可表达阻止,其他非零退出应显示为钩子错误。不要用普通成功退出掩盖检查未执行。
输出包含 additionalContext 时遵守长度限制。过长输出可能写入旁路文件;不要在输出中包含 Secret 或无关的用户内容。JSON 格式、事件字段和决策值必须匹配当前协议。
工具执行前后的决策
PreToolUse 可返回 deny 或 block 阻止本次调用;允许决策可在支持的结构中提供 updatedInput。改写后的输入仍应满足工具 Schema 和权限,钩子不能扩大授权。
PostToolUse 观察已完成工具结果。此时文件、消息或数据库可能已改变;阻止后续任务不能撤销它们。恢复需要使用相应系统的正式操作。
权限请求
PermissionRequest 使用事件定义的 allow 或 deny 决策;多个处理器中拒绝优先。不要返回该事件保留或不支持的 updatedInput 字段。钩子的允许判断也不能绕过操作系统权限或管理员约束。
结束与中断
Stop 和 SubagentStop 可通过结构化 block 与 reason 要求继续必要工作;continue: false 的停止要求优先。处理器应给出具体未完成条件,避免无限阻止结束。
Interrupt 发生在用户取消活动轮次之后,只用于有限记录与清理,不能重新启动已取消任务。SessionEnd 必须短小可靠,不能依赖它完成必须成功的业务写入。
MCP 工具钩子
{
"hooks": {
"PostToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "mcp_tool",
"server": "project_checks",
"tool": "record_result",
"input": {},
"timeout": 5
}]
}]
}
}服务器与工具名必须来自已连接、已批准的服务。钩子复用当前连接,不负责启动或重新登录服务器,不再触发递归审批或其他钩子;SessionEnd 不执行 MCP 工具钩子。
参数展开只使用该事件实际提供的字段,验证展开后的类型。检查失败时保留错误,不把未执行的远程记录当作已送达。
后台执行
async 命令适合不影响当前决策的辅助任务。它不能阻止工具、批准权限或改写输入,结果只会在后续安全时机提供给模型。完成顺序可能与启动顺序不同,会话结束时未完成任务可能被取消。
需要强制通过的检查使用同步钩子或项目测试入口,不能依赖后台任务恰好及时完成。
插件与组织管理
插件钩子保留插件来源与根目录信息,升级后需检查信任是否仍有效。插件的安装与其钩子的执行许可是不同决定。不要自动继承外部托管产品的组织钩子分发、云端编排或用户不可关闭策略。
验证钩子
- 使用不含敏感内容的最小输入检查脚本。
- 分别验证允许、拒绝、非法 JSON、超时与命令失败。
- 确认只匹配目标工具和事件。
- 验证修改后信任失效以及禁用行为。
- 检查并行与后台输出不会串入其他任务。