Lifecycle hooks
在 Bob 会话的关键节点自动运行 Shell 命令,用于记录活动、注入上下文,或根据自定义逻辑阻止操作。
Lifecycle hooks 让你在 Bob 会话的特定时间点执行 Shell 命令。可用于记录活动、向模型注入上下文、允许或阻止操作,或启动后续自动化流程——无需修改 Bob 本身。
支持的 hooks
| Hook | 触发时机 | 是否阻塞 | stdout 行为 |
|---|---|---|---|
SessionStart | 会话开始时执行一次 | 否 | 注入为上下文 |
UserPromptSubmit | 每次提交 prompt 时 | 是(exit 2) | 注入为上下文 |
PreToolUse | 匹配工具运行之前 | 是(exit 2) | 忽略 |
PostToolUse | 匹配工具完成之后 | 否 | 忽略 |
Stop | Agent 停止时 | 否 | 忽略 |
配置
Hooks 在 settings.json 的 hooks 键下定义。Bob 会从两个位置合并 hooks:
| 范围 | 文件 |
|---|---|
| 全局(所有 workspace) | ~/.bob/settings/settings.json |
| Workspace(当前项目) | .bob/settings.json |
全局 hooks 始终运行。Workspace hooks 在全局 hooks 之上合并,仅适用于当前项目。
Hook 结构示例
{
"hooks": {
"PreToolUse": [
{
"matcher": "^write_file$",
"hooks": [
{
"type": "command",
"command": "sh .bob/hooks/check.sh",
"timeout": 5
}
]
}
]
}
}配置字段
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type | "command" | (无) | 必填。仅支持 command。 |
command | string | (无) | 必填。要执行的 Shell 命令。在 macOS/Linux 上通过 sh -c 运行,在 Windows 上通过 cmd /c 运行。 |
matcher | string | (无) | 可选。与工具名匹配的正则表达式(仅 PreToolUse、PostToolUse)。省略则匹配所有工具。 |
timeout | number | 10 | Hook 被停止前的秒数。设为 0 可禁用超时。 |
Hook 参考
在新会话开始时,第一轮之前执行一次。
stdin 结构
{
"event": "string",
"session_id": "string"
}示例 payload
{
"event": "SessionStart",
"session_id": "ses_01abc123"
}Stdout:作为额外会话信息写入模型上下文。
阻塞:不支持 exit 代码 2,会话始终启动。其他非零退出会被记录并忽略。
每次提交 prompt 时,在发送给模型之前执行。
stdin 结构
{
"event": "string",
"session_id": "string",
"prompt": "string"
}示例 payload
{
"event": "UserPromptSubmit",
"session_id": "ses_01abc123",
"prompt": "Refactor the auth module"
}Stdout:与 prompt 一起写入模型上下文。
阻塞:exit 代码 2 会阻止 prompt 发送,Bob 显示错误且 prompt 不会提交。
在匹配的工具运行之前执行,让你有机会检查或阻止该操作。
stdin 结构
{
"event": "string",
"session_id": "string",
"tool": "string",
"input": "object"
}示例 payload
{
"event": "PreToolUse",
"session_id": "ses_01abc123",
"tool": "write_file",
"input": {
"path": "src/index.ts",
"content": "..."
}
}Stdout:忽略。
阻塞:exit 代码 2 会阻止工具运行,Bob 将该工具报告为已阻止并继续会话。
在匹配的工具完成之后执行,无论是否成功。
stdin 结构
{
"event": "string",
"session_id": "string",
"tool": "string",
"input": "object",
"output": "string"
}示例 payload
{
"event": "PostToolUse",
"session_id": "ses_01abc123",
"tool": "write_file",
"input": {
"path": "src/index.ts",
"content": "..."
},
"output": "File written successfully"
}Stdout:忽略。
阻塞:exit 代码 2 无效,工具已经运行完成。
当 agent 停止时,在最后一轮完成后执行。
stdin 结构
{
"event": "string",
"session_id": "string"
}示例 payload
{
"event": "Stop",
"session_id": "ses_01abc123"
}Stdout:忽略。
阻塞:exit 代码 2 无效,会话已经结束。
Exit 代码与阻塞
| Exit 代码 | 行为 | 适用范围 |
|---|---|---|
0 | 成功:hook 正常执行 | 所有 hooks |
2 | 阻止:停止当前操作 | UserPromptSubmit、PreToolUse |
| 其他非零值 | 非阻塞失败:记录并忽略 | 所有 hooks |
仅 UserPromptSubmit 和 PreToolUse 支持阻塞。来自 SessionStart、PostToolUse 或 Stop 的 exit 代码 2 被视为非阻塞失败。
命令详情
- 工作目录:命令从任务工作目录(Bob 正在操作的文件夹)运行。
- 默认超时:10 秒。可通过
timeout字段为每个 hook 单独覆盖。将timeout设为0可完全禁用超时。 - Stderr:写入 Bob 的日志,但不影响 hook 结果。
- Shell:命令在 macOS 和 Linux 上通过
sh -c运行,在 Windows 上通过cmd /c运行。
快速开始
打开或创建全局设置文件,路径为 ~/.bob/settings/settings.json。
添加 hooks 键以及你要使用的 hook。以下示例在每次 write_file 调用之前运行一个脚本:
{
"hooks": {
"PreToolUse": [
{
"matcher": "^write_file$",
"hooks": [
{
"type": "command",
"command": "sh ~/.bob/hooks/log-write.sh"
}
]
}
]
}
}创建脚本文件。以下最简脚本会记录收到的 JSON payload:
#!/bin/sh
# ~/.bob/hooks/log-write.sh
cat >> ~/.bob/hooks/write-log.txt启动 Bob 会话并使用匹配的工具。检查 ~/.bob/hooks/write-log.txt,确认 hook 已运行且 payload 已写入。
示例
记录所有 hook 输入
将每个 hook 的 stdin 写入文件用于调试:
#!/bin/sh
# 带时间戳追加收到的 JSON payload
echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> ~/.bob/hooks/debug.log
cat >> ~/.bob/hooks/debug.log
echo "" >> ~/.bob/hooks/debug.log在任意 hook 下配置:
{
"hooks": {
"SessionStart": [
{
"hooks": [{ "type": "command", "command": "sh ~/.bob/hooks/debug.sh" }]
}
]
}
}注入会话上下文
从 SessionStart hook 返回文本,将其添加到模型上下文:
#!/bin/sh
# 输出项目元数据供模型使用
echo "Project: $(basename $PWD)"
echo "Git branch: $(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')"
echo "Node version: $(node --version 2>/dev/null || echo 'not installed')"阻止 prompt
从 UserPromptSubmit hook 以 exit 代码 2 退出,阻止 prompt 被发送:
#!/bin/sh
# 阻止包含 "delete" 单词的 prompt
PROMPT=$(cat | python3 -c "import sys,json; print(json.load(sys.stdin)['prompt'])")
case "$PROMPT" in
*delete*|*DELETE*)
echo "Prompt blocked: contains 'delete'" >&2
exit 2
;;
esac阻止匹配的工具
从 PreToolUse hook 以 exit 代码 2 退出,阻止特定工具运行:
#!/bin/sh
# 阻止 src/ 目录以外的文件的 write_file 操作
PATH_VAL=$(cat | python3 -c "import sys,json; print(json.load(sys.stdin)['input'].get('path',''))")
case "$PATH_VAL" in
src/*) ;;
*)
echo "Blocked: writes outside src/ are not allowed" >&2
exit 2
;;
esac从 Stop 运行后续自动化
使用 Stop 在会话结束后启动清理或报告:
#!/bin/sh
# Agent 完成后提交已暂存的变更
cd "$PWD"
git diff --cached --quiet || git commit -m "chore: auto-commit from Bob session"当前限制
本版本仅支持 command hooks 和上述五种 hook 类型。以下功能尚未开放:
- 非
command类型的 hook:不支持 function hooks、inline script hooks 等。 - 定时 hooks:无法将 hook 设置为按计划或响应外部事件运行。
- 输入改写:hook 无法在 prompt 或工具输入到达模型之前对其进行修改。
- 沙盒运行:hook 以你的完整用户权限运行,不应用任何隔离。
- 专用 hook 遥测:hook 活动不会在会话分析中单独追踪。
- 从
PostToolUse或Stop阻塞:对这些 hooks,exit 代码2无效。