Lifecycle hooks
Führe Shell-Befehle automatisch an wichtigen Punkten einer Bob Shell-Session aus, um Aktivitäten zu protokollieren, Kontext bereitzustellen oder Aktionen basierend auf deiner eigenen Logik zu blockieren.
Lifecycle hooks ermöglichen es dir, Shell-Befehle an bestimmten Punkten einer Bob Shell-Session auszuführen. Nutze sie, um Aktivitäten zu protokollieren, Kontext in das Modell zu injizieren, Aktionen zu erlauben oder zu blockieren oder Folgeautomatisierungen zu starten – alles ohne Bob Shell selbst zu verändern.
Unterstützte hooks
| Hook | Wann er ausgeführt wird | Blockierend | Stdout-Verhalten |
|---|---|---|---|
SessionStart | Einmal beim Start einer Session | Nein | Als Kontext injiziert |
UserPromptSubmit | Jedes Mal, wenn du einen Prompt absendest | Ja (Exit 2) | Als Kontext injiziert |
PreToolUse | Vor dem Ausführen eines passenden Tools | Ja (Exit 2) | Ignoriert |
PostToolUse | Nach Abschluss eines passenden Tools | Nein | Ignoriert |
Stop | Wenn der Agent stoppt | Nein | Ignoriert |
Konfiguration
Hooks werden unter dem Schlüssel hooks in deiner settings.json definiert. Bob Shell führt Hooks aus zwei Speicherorten zusammen:
| Geltungsbereich | Datei |
|---|---|
| Global (alle Workspaces) | ~/.bob/settings/settings.json |
| Workspace (aktuelles Projekt) | .bob/settings.json |
Globale Hooks werden immer ausgeführt. Workspace-Hooks werden über die globalen Hooks gelegt und gelten nur für das aktuelle Projekt.
Workspace-Hooks werden nur in vertrauenswürdigen Ordnern ausgeführt. Wenn der aktuelle Ordner nicht vertrauenswürdig ist, wird die .bob/settings.json nicht geladen und Workspace-Hooks werden stillschweigend übersprungen. Globale Hooks in ~/.bob/settings/settings.json sind von der Ordner-Vertrauensstellung nicht betroffen.
Weitere Informationen zum Speicherort und Laden von Einstellungsdateien findest du unter Bob Shell konfigurieren.
Hook-Schema
{
"hooks": {
"PreToolUse": [
{
"matcher": "^write_file$",
"hooks": [
{
"type": "command",
"command": "sh .bob/hooks/check.sh",
"timeout": 5
}
]
}
]
}
}Konfigurationsfelder
| Feld | Typ | Standard | Beschreibung |
|---|---|---|---|
type | "command" | (kein) | Pflichtfeld. Nur command wird unterstützt. |
command | string | (kein) | Pflichtfeld. Der auszuführende Shell-Befehl. Läuft über sh -c auf macOS/Linux. |
matcher | string | (kein) | Optional. Ein Regex, der gegen den Tool-Namen abgeglichen wird (nur PreToolUse, PostToolUse). Weglassen, um alle Tools zu erfassen. |
timeout | number | 10 | Sekunden, bevor der Hook abgebrochen wird. Auf 0 setzen, um den Timeout zu deaktivieren. |
Hook-Referenz
Wird einmal ausgeführt, wenn eine neue Session beginnt, vor dem ersten Durchgang.
Stdin-Schema
{
"event": "string",
"session_id": "string"
}Beispiel-Payload
{
"event": "SessionStart",
"session_id": "ses_01abc123"
}Stdout: Wird als zusätzliche Session-Information in den Kontext des Modells geschrieben.
Blockierend: Exit-Code 2 wird nicht unterstützt. Die Session startet immer. Andere Nicht-Null-Exits werden protokolliert und ignoriert.
Wird jedes Mal ausgeführt, wenn du einen Prompt absendest, bevor er an das Modell gesendet wird.
Stdin-Schema
{
"event": "string",
"session_id": "string",
"prompt": "string"
}Beispiel-Payload
{
"event": "UserPromptSubmit",
"session_id": "ses_01abc123",
"prompt": "Refactor the auth module"
}Stdout: Wird zusammen mit dem Prompt in den Kontext des Modells geschrieben.
Blockierend: Exit-Code 2 verhindert, dass der Prompt gesendet wird. Bob Shell zeigt einen Fehler an und der Prompt wird nicht übermittelt.
Wird ausgeführt, bevor ein passendes Tool läuft, und gibt dir die Möglichkeit, die Aktion zu prüfen oder zu blockieren.
Stdin-Schema
{
"event": "string",
"session_id": "string",
"tool": "string",
"input": "object"
}Beispiel-Payload
{
"event": "PreToolUse",
"session_id": "ses_01abc123",
"tool": "write_file",
"input": {
"path": "src/index.ts",
"content": "..."
}
}Stdout: Ignoriert.
Blockierend: Exit-Code 2 verhindert die Ausführung des Tools. Bob Shell meldet das Tool als blockiert und setzt die Session fort.
Wird ausgeführt, nachdem ein passendes Tool abgeschlossen hat, unabhängig davon, ob es erfolgreich war.
Stdin-Schema
{
"event": "string",
"session_id": "string",
"tool": "string",
"input": "object",
"output": "string"
}Beispiel-Payload
{
"event": "PostToolUse",
"session_id": "ses_01abc123",
"tool": "write_file",
"input": {
"path": "src/index.ts",
"content": "..."
},
"output": "File written successfully"
}Stdout: Ignoriert.
Blockierend: Exit-Code 2 hat keine Wirkung. Das Tool wurde bereits ausgeführt.
Wird ausgeführt, wenn der Agent stoppt, nachdem der letzte Durchgang abgeschlossen ist.
Stdin-Schema
{
"event": "string",
"session_id": "string"
}Beispiel-Payload
{
"event": "Stop",
"session_id": "ses_01abc123"
}Stdout: Ignoriert.
Blockierend: Exit-Code 2 hat keine Wirkung. Die Session ist bereits beendet.
Exit-Codes und Blockierung
| Exit-Code | Verhalten | Gilt für |
|---|---|---|
0 | Erfolg: Hook wurde ohne Problem ausgeführt | Alle Hooks |
2 | Blockieren: aktuelle Aktion stoppen | UserPromptSubmit, PreToolUse |
| Jeder andere Nicht-Null-Wert | Nicht-blockierender Fehler: protokolliert und ignoriert | Alle Hooks |
Nur UserPromptSubmit und PreToolUse unterstützen Blockierung. Exit-Code 2 von SessionStart, PostToolUse oder Stop wird als nicht-blockierender Fehler behandelt.
Befehlsdetails
- Arbeitsverzeichnis: Befehle werden aus dem Task-Arbeitsverzeichnis heraus ausgeführt (dem Ordner, in dem Bob arbeitet).
- Standard-Timeout: 10 Sekunden. Pro Hook mit dem Feld
timeoutüberschreibbar. Setzetimeoutauf0, um den Timeout vollständig zu deaktivieren. - Stderr: Wird in Bob Shells Logs geschrieben, hat aber keinen Einfluss auf das Hook-Ergebnis.
- Shell: Befehle werden über
sh -cauf macOS und Linux ausgeführt.
Erste Schritte
Öffne oder erstelle deine globale Einstellungsdatei unter ~/.bob/settings/settings.json.
Füge einen hooks-Schlüssel mit dem gewünschten Hook hinzu. Das folgende Beispiel führt ein Skript vor jedem write_file-Aufruf aus:
{
"hooks": {
"PreToolUse": [
{
"matcher": "^write_file$",
"hooks": [
{
"type": "command",
"command": "sh ~/.bob/hooks/log-write.sh"
}
]
}
]
}
}Erstelle die Skript-Datei. Dieses minimale Skript protokolliert den eingehenden JSON-Payload:
#!/bin/sh
# ~/.bob/hooks/log-write.sh
cat >> ~/.bob/hooks/write-log.txtStarte eine Bob Shell-Session und nutze das passende Tool. Prüfe ~/.bob/hooks/write-log.txt, um zu bestätigen, dass der Hook ausgeführt wurde und der Payload geschrieben wurde.
Beispiele
Alle Hook-Eingaben protokollieren
Schreibe den Stdin jedes Hooks zur Fehlersuche in eine Datei:
#!/bin/sh
# Eingehenden JSON-Payload mit Zeitstempel anfügen
echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> ~/.bob/hooks/debug.log
cat >> ~/.bob/hooks/debug.log
echo "" >> ~/.bob/hooks/debug.logKonfiguriere dies unter einem beliebigen Hook:
{
"hooks": {
"SessionStart": [
{
"hooks": [{ "type": "command", "command": "sh ~/.bob/hooks/debug.sh" }]
}
]
}
}Session-Kontext injizieren
Gib Text aus einem SessionStart-Hook zurück, um ihn zum Kontext des Modells hinzuzufügen:
#!/bin/sh
# Projekt-Metadaten für das Modell ausgeben
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')"Einen Prompt blockieren
Beende mit Exit-Code 2 aus einem UserPromptSubmit-Hook, um zu verhindern, dass ein Prompt gesendet wird:
#!/bin/sh
# Prompts blockieren, die das Wort "delete" enthalten
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
;;
esacEin passendes Tool blockieren
Beende mit Exit-Code 2 aus einem PreToolUse-Hook, um ein bestimmtes Tool an der Ausführung zu hindern:
#!/bin/sh
# write_file-Operationen auf Dateien außerhalb des src/-Verzeichnisses blockieren
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
;;
esacFolgeautomatisierung mit Stop ausführen
Nutze Stop, um nach dem Ende einer Session Bereinigung oder Reporting zu starten:
#!/bin/sh
# Gestaggte Änderungen nach Abschluss des Agents committen
cd "$PWD"
git diff --cached --quiet || git commit -m "chore: auto-commit from Bob Shell session"Aktuelle Einschränkungen
In diesem Release werden nur command-Hooks und die fünf oben aufgeführten Hook-Typen unterstützt. Folgendes ist noch nicht verfügbar:
- Andere Hook-Typen als
command: Funktions-Hooks, Inline-Skript-Hooks und ähnliche werden nicht unterstützt. - Geplante Hooks: Hooks können nicht auf einen Timer oder als Reaktion auf ein externes Ereignis gesetzt werden.
- Eingabe-Rewriting: Hooks können den Prompt oder die Tool-Eingabe nicht ändern, bevor sie das Modell erreichen.
- Isolierte Ausführung: Hooks laufen mit deinen vollen Benutzerberechtigungen; keine Isolierung wird angewendet.
- Dedizierte Hook-Telemetrie: Hook-Aktivität wird in der Session-Analyse nicht separat erfasst.
- Blockierung von
PostToolUseoderStop: Exit-Code2hat für diese Hooks keine Wirkung.