Lifecycle hooks
在 Bob Shell 工作階段的關鍵節點自動執行 Shell 指令,用於記錄活動、注入上下文,或根據自訂邏輯阻止操作。
Lifecycle hooks 讓你在 Bob Shell 工作階段的特定時間點執行 Shell 指令。可用於記錄活動、向模型注入上下文、允許或阻止操作,或啟動後續自動化流程——無需修改 Bob Shell 本身。
支援的 hooks
| Hook | 觸發時機 | 是否阻塞 | stdout 行為 |
|---|---|---|---|
SessionStart | 工作階段開始時執行一次 | 否 | 注入為上下文 |
UserPromptSubmit | 每次提交 prompt 時 | 是(exit 2) | 注入為上下文 |
PreToolUse | 符合的工具執行之前 | 是(exit 2) | 忽略 |
PostToolUse | 符合的工具完成之後 | 否 | 忽略 |
Stop | Agent 停止時 | 否 | 忽略 |
設定
Hooks 在 settings.json 的 hooks 鍵下定義。Bob Shell 會從兩個位置合併 hooks:
| 範圍 | 檔案 |
|---|---|
| 全域(所有 workspace) | ~/.bob/settings/settings.json |
| Workspace(目前專案) | .bob/settings.json |
全域 hooks 始終執行。Workspace hooks 在全域 hooks 之上合併,僅適用於目前專案。
Workspace hooks 僅在受信任的資料夾中執行。如果目前資料夾不受信任,.bob/settings.json 檔案不會被載入,workspace hooks 會被靜默略過。~/.bob/settings/settings.json 中的全域 hooks 不受資料夾信任設定的影響。
有關設定檔如何定位和載入的詳細資訊,請參閱設定 Bob Shell。
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 執行。 |
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 Shell 顯示錯誤且 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 Shell 將該工具回報為已阻止並繼續工作階段。
在符合的工具完成之後執行,無論是否成功。
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 Shell 的日誌,但不影響 hook 結果。
- Shell:指令在 macOS 和 Linux 上透過
sh -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 Shell 工作階段並使用符合的工具。檢查 ~/.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 Shell session"目前限制
本版本僅支援 command hooks 和上述五種 hook 類型。以下功能尚未開放:
- 非
command類型的 hook:不支援 function hooks、inline script hooks 等。 - 排程 hooks:無法將 hook 設定為按排程或回應外部事件執行。
- 輸入改寫:hook 無法在 prompt 或工具輸入到達模型之前對其進行修改。
- 沙盒執行:hook 以你的完整使用者權限執行,不套用任何隔離。
- 專用 hook 遙測:hook 活動不會在工作階段分析中單獨追蹤。
- 從
PostToolUse或Stop阻塞:對這些 hooks,exit 代碼2無效。