Lifecycle hooks

在 Bob Shell 工作階段的關鍵節點自動執行 Shell 指令,用於記錄活動、注入上下文,或根據自訂邏輯阻止操作。

Lifecycle hooks 讓你在 Bob Shell 工作階段的特定時間點執行 Shell 指令。可用於記錄活動、向模型注入上下文、允許或阻止操作,或啟動後續自動化流程——無需修改 Bob Shell 本身。

支援的 hooks

Hook觸發時機是否阻塞stdout 行為
SessionStart工作階段開始時執行一次注入為上下文
UserPromptSubmit每次提交 prompt 時是(exit 2注入為上下文
PreToolUse符合的工具執行之前是(exit 2忽略
PostToolUse符合的工具完成之後忽略
StopAgent 停止時忽略

設定

Hooks 在 settings.jsonhooks 鍵下定義。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
commandstring(無)必填。要執行的 Shell 指令。在 macOS/Linux 上透過 sh -c 執行。
matcherstring(無)選填。與工具名稱比對的正規表示式(僅 PreToolUsePostToolUse)。省略則符合所有工具。
timeoutnumber10Hook 被停止前的秒數。設為 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阻止:停止目前操作UserPromptSubmitPreToolUse
其他非零值非阻塞失敗:記錄並忽略所有 hooks
注意:

UserPromptSubmitPreToolUse 支援阻塞。來自 SessionStartPostToolUseStop 的 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 活動不會在工作階段分析中單獨追蹤。
  • PostToolUseStop 阻塞:對這些 hooks,exit 代碼 2 無效。
這個主題如何?