Hook siklus hidup

Jalankan command shell secara otomatis pada titik-titik penting dalam sesi Bob untuk mencatat aktivitas, menyuntikkan konteks, atau memblokir tindakan berdasarkan logikamu sendiri.

Hook siklus hidup memungkinkanmu menjalankan command shell pada titik tertentu dalam sesi Bob. Gunakan hook untuk mencatat aktivitas, menyuntikkan konteks ke model, mengatur atau memblokir tindakan, atau memulai automasi lanjutan, semuanya tanpa memodifikasi Bob itu sendiri.

Hook yang didukung

HookWaktu dijalankanBlockingPerilaku stdout
SessionStartSekali saat sesi dimulaiTidakDisuntikkan sebagai konteks
UserPromptSubmitSetiap kali kamu mengirim promptYa (exit 2)Disuntikkan sebagai konteks
PreToolUseSebelum tool yang cocok dijalankanYa (exit 2)Diabaikan
PostToolUseSetelah tool yang cocok selesaiTidakDiabaikan
StopSaat agen berhentiTidakDiabaikan

Konfigurasi

Hook didefinisikan di bawah key hooks dalam settings.json milikmu. Bob menggabungkan hook dari dua lokasi:

CakupanFile
Global (semua workspace)~/.bob/settings/settings.json
Workspace (proyek saat ini).bob/settings.json

Hook global selalu dijalankan. Hook workspace digabungkan di atas hook global dan hanya berlaku untuk proyek saat ini.

Skema hook

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "^write_file$",
        "hooks": [
          {
            "type": "command",
            "command": "sh .bob/hooks/check.sh",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

Field konfigurasi

FieldTipeDefaultDeskripsi
type"command"(tidak ada)Wajib. Hanya command yang didukung.
commandstring(tidak ada)Wajib. Command shell yang akan dijalankan. Berjalan lewat sh -c di macOS/Linux, cmd /c di Windows.
matcherstring(tidak ada)Opsional. Regex yang dicocokkan terhadap nama tool (PreToolUse, PostToolUse saja). Hilangkan untuk mencocokkan semua tool.
timeoutnumber10Jumlah detik sebelum hook dihentikan. Set 0 untuk menonaktifkan timeout.

Referensi hook

Berjalan sekali saat sesi baru dimulai, sebelum giliran pertama.

Skema stdin

{
  "event": "string",
  "session_id": "string"
}

Contoh payload

{
  "event": "SessionStart",
  "session_id": "ses_01abc123"
}

Stdout: Ditulis ke konteks model sebagai informasi sesi tambahan.

Blocking: Exit code 2 tidak didukung. Sesi akan selalu dimulai. Exit non-zero lainnya dicatat ke log dan diabaikan.

Berjalan setiap kali kamu mengirim prompt, sebelum prompt dikirim ke model.

Skema stdin

{
  "event": "string",
  "session_id": "string",
  "prompt": "string"
}

Contoh payload

{
  "event": "UserPromptSubmit",
  "session_id": "ses_01abc123",
  "prompt": "Refactor the auth module"
}

Stdout: Ditulis ke konteks model bersama prompt.

Blocking: Exit code 2 memblokir prompt agar tidak dikirim. Bob menampilkan error dan prompt tidak dikirim.

Berjalan sebelum tool yang cocok dijalankan, memberimu kesempatan untuk memeriksa atau memblokir tindakan.

Skema stdin

{
  "event": "string",
  "session_id": "string",
  "tool": "string",
  "input": "object"
}

Contoh payload

{
  "event": "PreToolUse",
  "session_id": "ses_01abc123",
  "tool": "write_file",
  "input": {
    "path": "src/index.ts",
    "content": "..."
  }
}

Stdout: Diabaikan.

Blocking: Exit code 2 mencegah tool dijalankan. Bob melaporkan tool sebagai diblokir dan melanjutkan sesi.

Berjalan setelah tool yang cocok selesai, baik berhasil maupun tidak.

Skema stdin

{
  "event": "string",
  "session_id": "string",
  "tool": "string",
  "input": "object",
  "output": "string"
}

Contoh payload

{
  "event": "PostToolUse",
  "session_id": "ses_01abc123",
  "tool": "write_file",
  "input": {
    "path": "src/index.ts",
    "content": "..."
  },
  "output": "File written successfully"
}

Stdout: Diabaikan.

Blocking: Exit code 2 tidak berpengaruh. Tool sudah dijalankan.

Berjalan saat agen berhenti, setelah giliran terakhir selesai.

Skema stdin

{
  "event": "string",
  "session_id": "string"
}

Contoh payload

{
  "event": "Stop",
  "session_id": "ses_01abc123"
}

Stdout: Diabaikan.

Blocking: Exit code 2 tidak berpengaruh. Sesi sudah berakhir.

Exit code dan blocking

Exit codePerilakuBerlaku untuk
0Berhasil: hook berjalan tanpa masalahSemua hook
2Blokir: hentikan tindakan saat iniUserPromptSubmit, PreToolUse
Non-zero lainnyaKegagalan non-blocking: dicatat ke log dan diabaikanSemua hook
Catatan:

Hanya UserPromptSubmit dan PreToolUse yang mendukung blocking. Exit code 2 dari SessionStart, PostToolUse, atau Stop diperlakukan sebagai kegagalan non-blocking.

Detail command

  • Working directory: Command berjalan dari working directory tugas saat ini (folder tempat Bob bekerja).
  • Default timeout: 10 detik. Override per hook dengan field timeout. Set timeout ke 0 untuk menonaktifkan timeout sepenuhnya.
  • Stderr: Ditulis ke log Bob tetapi tidak memengaruhi hasil hook.
  • Shell: Command dijalankan lewat sh -c di macOS dan Linux, serta cmd /c di Windows.

Memulai

Buka atau buat file settings globalmu di ~/.bob/settings/settings.json.

Tambahkan key hooks dengan hook yang ingin kamu gunakan. Contoh di bawah ini menjalankan script sebelum setiap pemanggilan write_file:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "^write_file$",
        "hooks": [
          {
            "type": "command",
            "command": "sh ~/.bob/hooks/log-write.sh"
          }
        ]
      }
    ]
  }
}

Buat file script-nya. Script minimal ini mencatat payload JSON yang masuk:

#!/bin/sh
# ~/.bob/hooks/log-write.sh
cat >> ~/.bob/hooks/write-log.txt

Mulai sesi Bob lalu gunakan tool yang cocok. Periksa ~/.bob/hooks/write-log.txt untuk memastikan hook berjalan dan payload sudah ditulis.

Contoh

Catat semua input hook

Tulis stdin setiap hook ke file untuk debugging:

#!/bin/sh
# Append payload JSON yang masuk dengan timestamp
echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> ~/.bob/hooks/debug.log
cat >> ~/.bob/hooks/debug.log
echo "" >> ~/.bob/hooks/debug.log

Konfigurasikan ini di bawah hook mana pun:

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [{ "type": "command", "command": "sh ~/.bob/hooks/debug.sh" }]
      }
    ]
  }
}

Menyuntikkan konteks sesi

Kembalikan teks dari hook SessionStart untuk menambahkannya ke konteks model:

#!/bin/sh
# Output metadata proyek agar bisa dipakai model
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')"

Memblokir prompt

Keluar dengan code 2 dari hook UserPromptSubmit untuk mencegah prompt dikirim:

#!/bin/sh
# Blok prompt yang berisi kata "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

Memblokir tool yang cocok

Keluar dengan code 2 dari hook PreToolUse untuk mencegah tool tertentu dijalankan:

#!/bin/sh
# Blok operasi write_file pada file di luar direktori src/
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

Menjalankan automasi lanjutan dari Stop

Gunakan Stop untuk memulai cleanup atau pelaporan setelah sesi berakhir:

#!/bin/sh
# Commit semua staged changes setelah agen selesai
cd "$PWD"
git diff --cached --quiet || git commit -m "chore: auto-commit from Bob session"

Keterbatasan saat ini

Hanya hook command dan lima jenis hook yang tercantum di atas yang didukung pada rilis ini. Hal berikut belum tersedia:

  • Jenis hook selain command: function hook, inline script hook, dan sejenisnya belum didukung.
  • Hook terjadwal: hook tidak bisa diatur untuk berjalan berdasarkan timer atau sebagai respons terhadap event eksternal.
  • Penulisan ulang input: hook tidak bisa memodifikasi prompt atau input tool sebelum mencapai model.
  • Eksekusi tersandbox: hook berjalan dengan izin penuh user-mu; tidak ada isolasi yang diterapkan.
  • Telemetry hook khusus: aktivitas hook tidak dilacak terpisah dalam analytics sesi.
  • Blocking dari PostToolUse atau Stop: exit code 2 tidak berpengaruh untuk hook ini.
Bagaimana topik ini?