Lifecycle hooks

Bob Shell セッションの重要なタイミングでシェルコマンドを自動実行し、アクティビティのログ記録、コンテキストの注入、独自のロジックによるアクションのブロックを行います。

Lifecycle hooks を使うと、Bob Shell セッションの特定のタイミングでシェルコマンドを実行できます。アクティビティのログ記録、モデルへのコンテキスト注入、アクションの許可・ブロック、フォローアップ自動化の起動など、Bob Shell 自体を変更せずに実現できます。

サポートされている hooks

Hook実行タイミングブロッキングstdout の動作
SessionStartセッション開始時に1回なしコンテキストとして注入
UserPromptSubmitプロンプト送信のたびにあり (exit 2)コンテキストとして注入
PreToolUse対象ツール実行前あり (exit 2)無視
PostToolUse対象ツール完了後なし無視
Stopエージェント停止時なし無視

設定

Hooks は settings.jsonhooks キー以下に定義します。Bob Shell は2つの場所から 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(なし)必須。実行するシェルコマンド。macOS/Linux では sh -c で実行されます。
matcherstring(なし)任意。ツール名に対してマッチさせる regex (PreToolUsePostToolUse のみ)。省略すると全ツールにマッチします。
timeoutnumber10Hook を停止するまでの秒数。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 Shell はエラーを表示し、プロンプトは送信されません。

対象ツールが実行される前に実行され、アクションを検査またはブロックする機会を与えます。

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 Shell はツールがブロックされたと報告し、セッションを続行します。

対象ツールが完了した後、成功・失敗に関わらず実行されます。

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ブロック: 現在のアクションを停止UserPromptSubmitPreToolUse
その他の非ゼロ非ブロッキング失敗: ログに記録され無視される全 hooks
注意:

ブロッキングをサポートするのは UserPromptSubmitPreToolUse のみです。SessionStartPostToolUseStop からの Exit コード 2 は非ブロッキング失敗として扱われます。

コマンドの詳細

  • 作業ディレクトリ: コマンドはタスクの作業ディレクトリ (Bob が作業しているフォルダ) から実行されます。
  • デフォルトタイムアウト: 10秒。timeout フィールドで hook ごとに上書きできます。timeout0 に設定するとタイムアウトを完全に無効化します。
  • Stderr: Bob Shell のログに書き込まれますが、hook の結果には影響しません。
  • Shell: macOS と Linux では sh -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.txt

Bob Shell セッションを開始し、対象ツールを使用します。~/.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
    ;;
esac

Stop からフォローアップ自動化を実行する

Stop を使ってセッション終了後にクリーンアップやレポートを開始します:

#!/bin/sh
# エージェント終了後にステージング済みの変更をコミット
cd "$PWD"
git diff --cached --quiet || git commit -m "chore: auto-commit from Bob Shell session"

現在の制限事項

このリリースでは command hooks と上記5つの hook タイプのみがサポートされています。以下はまだ利用できません:

  • command 以外の hook タイプ: function hooks、インラインスクリプト hooks などはサポートされていません。
  • スケジュール hooks: タイマーや外部イベントへの応答で実行するよう hook を設定することはできません。
  • 入力の書き換え: hooks はモデルに到達する前にプロンプトやツール入力を変更できません。
  • サンドボックス実行: hooks はユーザーのフル権限で実行されます。分離は適用されません。
  • 専用 hook テレメトリ: hook のアクティビティはセッションアナリティクスで個別に追跡されません。
  • PostToolUse または Stop からのブロッキング: これらの hooks では Exit コード 2 は効果がありません。
このトピックはいかがですか?