Lifecycle hooks
Bob セッションの重要なタイミングでシェルコマンドを自動実行し、アクティビティのログ記録、コンテキストの注入、独自のロジックによるアクションのブロックを行います。
Lifecycle hooks を使うと、Bob セッションの特定のタイミングでシェルコマンドを実行できます。アクティビティのログ記録、モデルへのコンテキスト注入、アクションの許可・ブロック、フォローアップ自動化の起動など、Bob 自体を変更せずに実現できます。
サポートされている hooks
| Hook | 実行タイミング | ブロッキング | stdout の動作 |
|---|---|---|---|
SessionStart | セッション開始時に1回 | なし | コンテキストとして注入 |
UserPromptSubmit | プロンプト送信のたびに | あり (exit 2) | コンテキストとして注入 |
PreToolUse | 対象ツール実行前 | あり (exit 2) | 無視 |
PostToolUse | 対象ツール完了後 | なし | 無視 |
Stop | エージェント停止時 | なし | 無視 |
設定
Hooks は settings.json の hooks キー以下に定義します。Bob は2つの場所から 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 | (なし) | 必須。実行するシェルコマンド。macOS/Linux では sh -c、Windows では cmd /c で実行されます。 |
matcher | string | (なし) | 任意。ツール名に対してマッチさせる regex (PreToolUse、PostToolUse のみ)。省略すると全ツールにマッチします。 |
timeout | number | 10 | Hook を停止するまでの秒数。0 に設定するとタイムアウトを無効にします。 |
Hook リファレンス
新しいセッションが開始されると、最初のターンの前に1回実行されます。
stdin スキーマ
{
"event": "string",
"session_id": "string"
}ペイロード例
{
"event": "SessionStart",
"session_id": "ses_01abc123"
}Stdout: 追加のセッション情報としてモデルのコンテキストに書き込まれます。
ブロッキング: Exit コード 2 はサポートされていません。セッションは常に開始されます。その他の非ゼロ終了はログに記録され、無視されます。
プロンプトを送信するたびに、モデルへ送信される前に実行されます。
stdin スキーマ
{
"event": "string",
"session_id": "string",
"prompt": "string"
}ペイロード例
{
"event": "UserPromptSubmit",
"session_id": "ses_01abc123",
"prompt": "Refactor the auth module"
}Stdout: プロンプトと共にモデルのコンテキストに書き込まれます。
ブロッキング: Exit コード 2 でプロンプトの送信をブロックします。Bob はエラーを表示し、プロンプトは送信されません。
対象ツールが実行される前に実行され、アクションを検査またはブロックする機会を与えます。
stdin スキーマ
{
"event": "string",
"session_id": "string",
"tool": "string",
"input": "object"
}ペイロード例
{
"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"
}ペイロード例
{
"event": "PostToolUse",
"session_id": "ses_01abc123",
"tool": "write_file",
"input": {
"path": "src/index.ts",
"content": "..."
},
"output": "File written successfully"
}Stdout: 無視されます。
ブロッキング: Exit コード 2 は効果がありません。ツールはすでに実行されています。
エージェントが停止したとき、最終ターン完了後に実行されます。
stdin スキーマ
{
"event": "string",
"session_id": "string"
}ペイロード例
{
"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 にあるグローバル設定ファイルを開くか作成します。
使用したい hook の hooks キーを追加します。以下の例は write_file の呼び出しごとにスクリプトを実行します:
{
"hooks": {
"PreToolUse": [
{
"matcher": "^write_file$",
"hooks": [
{
"type": "command",
"command": "sh ~/.bob/hooks/log-write.sh"
}
]
}
]
}
}スクリプトファイルを作成します。この最小限のスクリプトは受信 JSON ペイロードをログに記録します:
#!/bin/sh
# ~/.bob/hooks/log-write.sh
cat >> ~/.bob/hooks/write-log.txtBob セッションを開始し、対象ツールを使用します。~/.bob/hooks/write-log.txt を確認して、hook が実行されペイロードが書き込まれたことを確認してください。
例
全 hook の入力をログに記録する
デバッグのために各 hook の stdin をファイルに書き込みます:
#!/bin/sh
# タイムスタンプ付きで受信 JSON ペイロードを追記
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')"プロンプトをブロックする
UserPromptSubmit hook から Exit コード 2 で終了してプロンプトの送信を防ぎます:
#!/bin/sh
# "delete" という単語を含むプロンプトをブロック
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
;;
esacStop からフォローアップ自動化を実行する
Stop を使ってセッション終了後にクリーンアップやレポートを開始します:
#!/bin/sh
# エージェント終了後にステージング済みの変更をコミット
cd "$PWD"
git diff --cached --quiet || git commit -m "chore: auto-commit from Bob session"現在の制限事項
このリリースでは command hooks と上記5つの hook タイプのみがサポートされています。以下はまだ利用できません:
command以外の hook タイプ: function hooks、インラインスクリプト hooks などはサポートされていません。- スケジュール hooks: タイマーや外部イベントへの応答で実行するよう hook を設定することはできません。
- 入力の書き換え: hooks はモデルに到達する前にプロンプトやツール入力を変更できません。
- サンドボックス実行: hooks はユーザーのフル権限で実行されます。分離は適用されません。
- 専用 hook テレメトリ: hook のアクティビティはセッションアナリティクスで個別に追跡されません。
PostToolUseまたはStopからのブロッキング: これらの hooks では Exit コード2は効果がありません。