Lifecycle hooks
Uruchamiaj polecenia shell automatycznie w kluczowych momentach sesji Bob, aby rejestrować aktywność, wstrzykiwać kontekst lub blokować działania na podstawie własnej logiki.
Lifecycle hooks pozwalają uruchamiać polecenia shell w określonych momentach sesji Bob. Użyj ich do rejestrowania aktywności, wstrzykiwania kontekstu do modelu, zezwalania lub blokowania działań albo uruchamiania automatyzacji — bez modyfikowania Bob.
Obsługiwane hooks
| Hook | Kiedy się wykonuje | Blokujący | Zachowanie stdout |
|---|---|---|---|
SessionStart | Raz przy starcie sesji | Nie | Wstrzykiwany jako kontekst |
UserPromptSubmit | Za każdym razem, gdy wysyłasz prompt | Tak (exit 2) | Wstrzykiwany jako kontekst |
PreToolUse | Przed uruchomieniem pasującego narzędzia | Tak (exit 2) | Ignorowany |
PostToolUse | Po zakończeniu pasującego narzędzia | Nie | Ignorowany |
Stop | Gdy agent się zatrzymuje | Nie | Ignorowany |
Konfiguracja
Hooks są definiowane pod kluczem hooks w pliku settings.json. Bob łączy hooks z dwóch lokalizacji:
| Zakres | Plik |
|---|---|
| Globalny (wszystkie workspace) | ~/.bob/settings/settings.json |
| Workspace (bieżący projekt) | .bob/settings.json |
Globalne hooks zawsze się wykonują. Workspace hooks są nakładane na globalne i obowiązują tylko dla bieżącego projektu.
Schemat hook
{
"hooks": {
"PreToolUse": [
{
"matcher": "^write_file$",
"hooks": [
{
"type": "command",
"command": "sh .bob/hooks/check.sh",
"timeout": 5
}
]
}
]
}
}Pola konfiguracji
| Pole | Typ | Domyślnie | Opis |
|---|---|---|---|
type | "command" | (brak) | Wymagane. Obsługiwany jest tylko typ command. |
command | string | (brak) | Wymagane. Polecenie shell do wykonania. Uruchamiane przez sh -c na macOS/Linux, cmd /c na Windows. |
matcher | string | (brak) | Opcjonalne. Regex dopasowywany do nazwy narzędzia (tylko PreToolUse, PostToolUse). Pomiń, aby dopasować wszystkie narzędzia. |
timeout | number | 10 | Sekundy przed zatrzymaniem hook. Ustaw 0, aby wyłączyć timeout. |
Referencja hooków
Wykonuje się raz przy starcie nowej sesji, przed pierwszą turą.
Schemat stdin
{
"event": "string",
"session_id": "string"
}Przykładowy payload
{
"event": "SessionStart",
"session_id": "ses_01abc123"
}Stdout: Zapisywany do kontekstu modelu jako dodatkowe informacje o sesji.
Blokujący: Kod wyjścia 2 nie jest obsługiwany. Sesja zawsze się uruchamia. Inne kody niezerowe są logowane i ignorowane.
Wykonuje się za każdym razem, gdy wysyłasz prompt, zanim zostanie przesłany do modelu.
Schemat stdin
{
"event": "string",
"session_id": "string",
"prompt": "string"
}Przykładowy payload
{
"event": "UserPromptSubmit",
"session_id": "ses_01abc123",
"prompt": "Refactor the auth module"
}Stdout: Zapisywany do kontekstu modelu razem z promptem.
Blokujący: Kod wyjścia 2 blokuje wysłanie promptu. Bob wyświetla błąd i prompt nie jest przesyłany.
Wykonuje się przed uruchomieniem pasującego narzędzia, dając możliwość inspekcji lub zablokowania działania.
Schemat stdin
{
"event": "string",
"session_id": "string",
"tool": "string",
"input": "object"
}Przykładowy payload
{
"event": "PreToolUse",
"session_id": "ses_01abc123",
"tool": "write_file",
"input": {
"path": "src/index.ts",
"content": "..."
}
}Stdout: Ignorowany.
Blokujący: Kod wyjścia 2 uniemożliwia uruchomienie narzędzia. Bob zgłasza narzędzie jako zablokowane i kontynuuje sesję.
Wykonuje się po zakończeniu pasującego narzędzia, niezależnie od tego, czy się powiodło.
Schemat stdin
{
"event": "string",
"session_id": "string",
"tool": "string",
"input": "object",
"output": "string"
}Przykładowy payload
{
"event": "PostToolUse",
"session_id": "ses_01abc123",
"tool": "write_file",
"input": {
"path": "src/index.ts",
"content": "..."
},
"output": "File written successfully"
}Stdout: Ignorowany.
Blokujący: Kod wyjścia 2 nie ma efektu. Narzędzie zostało już uruchomione.
Wykonuje się gdy agent się zatrzymuje, po zakończeniu ostatniej tury.
Schemat stdin
{
"event": "string",
"session_id": "string"
}Przykładowy payload
{
"event": "Stop",
"session_id": "ses_01abc123"
}Stdout: Ignorowany.
Blokujący: Kod wyjścia 2 nie ma efektu. Sesja już się zakończyła.
Kody wyjścia i blokowanie
| Kod wyjścia | Zachowanie | Dotyczy |
|---|---|---|
0 | Sukces: hook wykonał się bez problemu | Wszystkie hooks |
2 | Blokada: zatrzymaj bieżące działanie | UserPromptSubmit, PreToolUse |
| Dowolny inny niezerowy | Nieblokujące niepowodzenie: logowane i ignorowane | Wszystkie hooks |
Blokowanie obsługują tylko UserPromptSubmit i PreToolUse. Kod wyjścia 2 z SessionStart, PostToolUse lub Stop jest traktowany jako nieblokujące niepowodzenie.
Szczegóły poleceń
- Katalog roboczy: Polecenia są wykonywane z katalogu roboczego zadania (folderu, w którym pracuje Bob).
- Domyślny timeout: 10 sekund. Można go nadpisać dla każdego hook za pomocą pola
timeout. Ustawtimeoutna0, aby całkowicie wyłączyć timeout. - Stderr: Zapisywany do logów Bob, ale nie wpływa na wynik hook.
- Shell: Polecenia są uruchamiane przez
sh -cna macOS i Linux orazcmd /cna Windows.
Pierwsze kroki
Otwórz lub utwórz globalny plik ustawień pod ścieżką ~/.bob/settings/settings.json.
Dodaj klucz hooks z hookiem, którego chcesz użyć. Poniższy przykład uruchamia skrypt przed każdym wywołaniem write_file:
{
"hooks": {
"PreToolUse": [
{
"matcher": "^write_file$",
"hooks": [
{
"type": "command",
"command": "sh ~/.bob/hooks/log-write.sh"
}
]
}
]
}
}Utwórz plik skryptu. Ten minimalny skrypt loguje przychodzący payload JSON:
#!/bin/sh
# ~/.bob/hooks/log-write.sh
cat >> ~/.bob/hooks/write-log.txtUruchom sesję Bob i użyj pasującego narzędzia. Sprawdź ~/.bob/hooks/write-log.txt, aby potwierdzić, że hook się wykonał i payload został zapisany.
Przykłady
Logowanie wszystkich danych wejściowych hooków
Zapisuj stdin każdego hooka do pliku w celach debugowania:
#!/bin/sh
# Dołącz przychodzący payload JSON ze znacznikiem czasu
echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> ~/.bob/hooks/debug.log
cat >> ~/.bob/hooks/debug.log
echo "" >> ~/.bob/hooks/debug.logSkonfiguruj to pod dowolnym hookiem:
{
"hooks": {
"SessionStart": [
{
"hooks": [{ "type": "command", "command": "sh ~/.bob/hooks/debug.sh" }]
}
]
}
}Wstrzykiwanie kontekstu sesji
Zwróć tekst z hooka SessionStart, aby dodać go do kontekstu modelu:
#!/bin/sh
# Wyświetl metadane projektu dla modelu
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')"Blokowanie promptu
Zakończ z kodem 2 z hooka UserPromptSubmit, aby uniemożliwić wysłanie promptu:
#!/bin/sh
# Blokuj prompty zawierające słowo "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
;;
esacBlokowanie pasującego narzędzia
Zakończ z kodem 2 z hooka PreToolUse, aby uniemożliwić uruchomienie konkretnego narzędzia:
#!/bin/sh
# Blokuj operacje write_file na plikach poza katalogiem 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
;;
esacUruchamianie automatyzacji po zatrzymaniu agenta
Użyj Stop, aby uruchomić czyszczenie lub raportowanie po zakończeniu sesji:
#!/bin/sh
# Zatwierdź zmiany w stage po zakończeniu agenta
cd "$PWD"
git diff --cached --quiet || git commit -m "chore: auto-commit from Bob session"Aktualne ograniczenia
W tej wersji obsługiwane są tylko hooki typu command oraz pięć wymienionych typów hooków. Następujące funkcje nie są jeszcze dostępne:
- Typy hooków inne niż
command: function hooks, inline script hooks i podobne nie są obsługiwane. - Zaplanowane hooki: hooków nie można ustawiać do uruchamiania według timera ani w odpowiedzi na zdarzenie zewnętrzne.
- Przepisywanie danych wejściowych: hooki nie mogą modyfikować promptu ani danych wejściowych narzędzia przed dotarciem do modelu.
- Uruchamianie w piaskownicy: hooki są wykonywane z pełnymi uprawnieniami użytkownika; izolacja nie jest stosowana.
- Dedykowana telemetria hooków: aktywność hooków nie jest śledzona oddzielnie w analityce sesji.
- Blokowanie z
PostToolUselubStop: kod wyjścia2nie ma efektu dla tych hooków.