Hooks sind externe Befehle, die während einer Sitzung an bestimmten Lebenszykluspunkten ausgeführt werden und benutzerdefinierte Automatisierung, Sicherheitssteuerelemente und Integrationen ermöglichen. Hook-Konfigurationsdateien werden automatisch von .github/hooks/*.json in Ihrem Repository geladen.
Hook-Konfigurationsformat
Hook-Konfigurationsdateien verwenden JSON-Format mit Version 1.
Befehlshaken
Befehlshaken führen Shellskripts aus und werden für alle Hooktypen unterstützt.
{
"version": 1,
"hooks": {
"preToolUse": [
{
"type": "command",
"bash": "your-bash-command",
"powershell": "your-powershell-command",
"cwd": "optional/working/directory",
"env": { "VAR": "value" },
"timeoutSec": 30
}
]
}
}
| Feld | Typ | Erforderlich | Description |
|---|---|---|---|
bash | Schnur | Einer von bash/powershell | Shell-Befehl für Unix. |
cwd | Schnur | No | Arbeitsverzeichnis für den Befehl (relativ zum Repositorystamm oder absolut). |
env | Objekt | No | Festzulegende Umgebungsvariablen (unterstützt variable Erweiterung). |
powershell | Schnur | Einer von bash/powershell | Shellbefehl für Windows. |
timeoutSec | Zahl | No | Timeout in Sekunden. Standardwert: 30. |
type | "command" | Ja | Muss "command" sein. |
Eingabeaufforderungshaken
Prompt-Hooks senden automatisch Text, als hätte der Benutzer ihn selbst eingegeben. Sie werden nur auf sessionStart unterstützt und nur für neue interaktive Sitzungen ausgelöst. Sie werden beim Fortsetzen nicht ausgelöst, und sie werden nicht im nicht interaktiven Eingabeaufforderungsmodus (-p) ausgelöst. Der Text kann eine Aufforderung in natürlicher Sprache oder ein Slash-Befehl sein.
{
"version": 1,
"hooks": {
"sessionStart": [
{
"type": "prompt",
"prompt": "Your prompt text or /slash-command"
}
]
}
}
| Feld | Typ | Erforderlich | Description |
|---|---|---|---|
type | "prompt" | Ja | Muss "prompt" sein. |
prompt | Schnur | Ja | Text zum Einreichen – kann eine Nachricht in natürlicher Sprache oder ein Slash-Befehl sein. |
Hook-Ereignisse
| Event | Wird ausgelöst, wenn | Verarbeitete Ausgabe |
|---|---|---|
agentStop | Der Hauptagent beendet eine Runde. | Ja – kann die Fortsetzung blockieren und erzwingen. |
errorOccurred | Während der Ausführung tritt ein Fehler auf. | No |
notification | Wird asynchron ausgelöst, wenn die CLI eine Systembenachrichtigung ausgibt (Shell-Abschluss, Agentabschluss oder Leerlauf, Berechtigungsaufforderungen, Elicitationsdialoge). Fire-and-Forget: blockiert die Sitzung nie. Unterstützt matcher regex bei notification_type. | Optional — kann additionalContext in die Sitzung einfügen. |
permissionRequest | Wird ausgelöst, bevor der Berechtigungsdienst ausgeführt wird (Regelmodul, Sitzungsgenehmigungen, automatische Genehmigung/Automatische Ablehnung und Benutzeraufforderung). Wenn die zusammengeführte Hook-Ausgabe behavior: "allow" oder "deny" zurückgibt, wird der normale Berechtigungsfluss unterbrochen. Unterstützt matcher regex bei toolName. | Ja – kann programmgesteuert zulassen oder verweigern. |
postToolUse | Nachdem jedes Tool erfolgreich abgeschlossen hat. | Ja - kann das erfolgreiche Ergebnis ersetzen (nur programmgesteuerte SDK-Hooks). |
postToolUseFailure | Nach Abschluss eines Tools mit einem Fehler. | Ja – kann Anleitungen zur Wiederherstellung über additionalContext (Exit-Code 2 für Befehlshaken) bereitstellen. |
preCompact | Die Kontextkomprimierung beginnt (manuell oder automatisch). Unterstützt matcher das Filtern nach Trigger ("manual" oder "auto"). | Nein – nur Benachrichtigung. |
preToolUse | Bevor jedes Tool ausgeführt wird. | Ja – kann zulassen, ablehnen oder ändern. |
sessionEnd | Die Sitzung wird beendet. | No |
sessionStart | Eine neue oder fortgesetzte Sitzung beginnt. | No |
subagentStart | Ein Subagent wird erzeugt, bevor er ausgeführt wird. Gibt additionalContext an die Eingabeaufforderung des Subagents zurück. Unterstützt matcher zum Filtern nach Agentennamen. | Nein – die Erstellung kann nicht blockiert werden. |
subagentStop | Ein Subagent schließt ab. | Ja – kann die Fortsetzung blockieren und erzwingen. |
userPromptSubmitted | Der Benutzer sendet eine Eingabeaufforderung. | No |
Hook-Ereigniseingabenutzlasten
Jedes Hook-Event liefert eine JSON-Nutzlast an den Hook-Handler. Zwei Nutzlastformate werden unterstützt, ausgewählt durch den Ereignisnamen, der in der Hook-Konfiguration verwendet wird:
- camelCase-Format – Konfigurieren Sie den Ereignisnamen in camelCase (z. B
sessionStart. ). Felder verwenden camelCase.
VS Code kompatibles Format** – Konfigurieren Sie den Ereignisnamen in PascalCase (z. B `SessionStart`. ). Felder verwenden snake_case, um dem Erweiterungsformat VS CodeCopilot zu entsprechen.
sessionStart / SessionStart
**camelCase-Eingabe:**
{
sessionId: string;
timestamp: number; // Unix timestamp in milliseconds
cwd: string;
source: "startup" | "resume" | "new";
initialPrompt?: string;
}
**
VS Code kompatible Eingabe:**
{
hook_event_name: "SessionStart";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
source: "startup" | "resume" | "new";
initial_prompt?: string;
}
sessionEnd / SessionEnd
**camelCase-Eingabe:**
{
sessionId: string;
timestamp: number;
cwd: string;
reason: "complete" | "error" | "abort" | "timeout" | "user_exit";
}
**
VS Code kompatible Eingabe:**
{
hook_event_name: "SessionEnd";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
reason: "complete" | "error" | "abort" | "timeout" | "user_exit";
}
userPromptSubmitted / UserPromptSubmit
**camelCase-Eingabe:**
{
sessionId: string;
timestamp: number;
cwd: string;
prompt: string;
}
**
VS Code kompatible Eingabe:**
{
hook_event_name: "UserPromptSubmit";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
prompt: string;
}
preToolUse / PreToolUse
**camelCase-Eingabe:**
{
sessionId: string;
timestamp: number;
cwd: string;
toolName: string;
toolArgs: unknown;
}
**
VS Code kompatible Eingabe:**
Bei der Konfiguration mit dem Namen des PascalCase-Ereignisses PreToolUseverwendet die Nutzlast snake_case Feldnamen, um dem Erweiterungsformat VS CodeCopilot zu entsprechen:
{
hook_event_name: "PreToolUse";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
tool_name: string;
tool_input: unknown; // Tool arguments (parsed from JSON string when possible)
}
postToolUse / PostToolUse
**camelCase-Eingabe:**
{
sessionId: string;
timestamp: number;
cwd: string;
toolName: string;
toolArgs: unknown;
toolResult: {
resultType: "success";
textResultForLlm: string;
}
}
**
VS Code kompatible Eingabe:**
{
hook_event_name: "PostToolUse";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
tool_name: string;
tool_input: unknown;
tool_result: {
result_type: "success" | "failure" | "denied" | "error";
text_result_for_llm: string;
}
}
postToolUseFailure / PostToolUseFailure
**camelCase-Eingabe:**
{
sessionId: string;
timestamp: number;
cwd: string;
toolName: string;
toolArgs: unknown;
error: string;
}
**
VS Code kompatible Eingabe:**
{
hook_event_name: "PostToolUseFailure";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
tool_name: string;
tool_input: unknown;
error: string;
}
agentStop / Stop
**camelCase-Eingabe:**
{
sessionId: string;
timestamp: number;
cwd: string;
transcriptPath: string;
stopReason: "end_turn";
}
**
VS Code kompatible Eingabe:**
{
hook_event_name: "Stop";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
transcript_path: string;
stop_reason: "end_turn";
}
subagentStart
**Eingabe**:
{
sessionId: string;
timestamp: number;
cwd: string;
transcriptPath: string;
agentName: string;
agentDisplayName?: string;
agentDescription?: string;
}
subagentStop / SubagentStop
**camelCase-Eingabe:**
{
sessionId: string;
timestamp: number;
cwd: string;
transcriptPath: string;
agentName: string;
agentDisplayName?: string;
stopReason: "end_turn";
}
**
VS Code kompatible Eingabe:**
{
hook_event_name: "SubagentStop";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
transcript_path: string;
agent_name: string;
agent_display_name?: string;
stop_reason: "end_turn";
}
errorOccurred / ErrorOccurred
**camelCase-Eingabe:**
{
sessionId: string;
timestamp: number;
cwd: string;
error: {
message: string;
name: string;
stack?: string;
};
errorContext: "model_call" | "tool_execution" | "system" | "user_input";
recoverable: boolean;
}
**
VS Code kompatible Eingabe:**
{
hook_event_name: "ErrorOccurred";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
error: {
message: string;
name: string;
stack?: string;
};
error_context: "model_call" | "tool_execution" | "system" | "user_input";
recoverable: boolean;
}
preCompact / PreCompact
**camelCase-Eingabe:**
{
sessionId: string;
timestamp: number;
cwd: string;
transcriptPath: string;
trigger: "manual" | "auto";
customInstructions: string;
}
**
VS Code kompatible Eingabe:**
{
hook_event_name: "PreCompact";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
transcript_path: string;
trigger: "manual" | "auto";
custom_instructions: string;
}
`preToolUse` Entscheidungssteuerung
Der preToolUse Hook kann die Toolausführung steuern, indem ein JSON-Objekt in stdout geschrieben wird.
| Feld | Werte | Description |
|---|---|---|
permissionDecision |
`"allow"`, `"deny"``"ask"` | Gibt an, ob das Tool ausgeführt wird. Leere Ausgabe verwendet Standardverhalten. |
| permissionDecisionReason | Schnur | Grund, der dem Agenten angezeigt wird. Erforderlich, wenn die Entscheidung lautet "deny". |
| modifiedArgs | Objekt | Ersetzen Sie Toolargumente, die anstelle der Originale verwendet werden sollen. |
`agentStop`
/
`subagentStop` Entscheidungssteuerung
| Feld | Werte | Description |
|---|---|---|
decision |
`"block"`, `"allow"` |
`"block"` erzwingt, dass ein anderer Agent die Verwendung `reason` als Eingabeaufforderung einfordert. |
| reason | Schnur | Aufforderung für den nächsten Schritt, wenn decision``"block" ist. |
`permissionRequest` Entscheidungssteuerung
Der permissionRequest Hook wird ausgelöst, bevor der Berechtigungsdienst ausgeführt wird – vor Regelüberprüfungen, Sitzungsgenehmigungen, automatisches Zulassen/automatisches Verweigern und bevor Benutzeraufforderungen erfolgen. Wenn Hooks behavior: "allow" oder "deny" zurückgeben, übergeht diese Entscheidung den normalen Berechtigungsfluss. Wenn nichts zurückgegeben wird, geht es in die normale Berechtigungsbehandlung über. Verwenden Sie sie, um Toolaufrufe programmgesteuert zu genehmigen oder zu verweigern – besonders nützlich im Pipemodus (-p) und CI-Umgebungen, in denen keine interaktive Eingabeaufforderung verfügbar ist.
Für jede Anforderung werden alle konfigurierten permissionRequest Hooks ausgeführt (mit Ausnahme von read und hook Berechtigungsarten, die vor den Hooks kurzschließen). Spätere Hook-Ausgaben haben Vorrang vor früheren bei der Zusammenführung.
**Matcher:** Ein optionaler Regex, getestet gegen `toolName`. Verankert als `^(?:pattern)$`; muss mit dem vollständigen Toolnamen übereinstimmen. Wenn festgelegt, wird der Hook nur bei übereinstimmenden Werkzeugnamen ausgelöst.
Ausgabe von JSON an stdout, um die Berechtigungsentscheidung zu steuern.
| Feld | Werte | Description |
|---|---|---|
behavior |
`"allow"`, `"deny"` | Gibt an, ob der Toolaufruf genehmigt oder verweigert werden soll. |
| message | Schnur | Grund, der beim Verweigern wieder zur LLM zurückgespeist wird. |
| interrupt | Boolean | Wenn true mit "deny" kombiniert wird, stoppt der Agent vollständig. |
Geben Sie eine leere Ausgabe zurück oder {} gehen Sie in den normalen Berechtigungsfluss um. Bei Befehls-Hooks wird der Beendigungscode 2 als Verweigerung behandelt; stdout JSON (falls vorhanden) wird mit {"behavior":"deny"} zusammengeführt, und stderr wird ignoriert.
`notification` Haken
Der notification Hook wird asynchron ausgelöst, wenn die CLI eine Systembenachrichtigung ausgibt. Diese Hooks funktionieren nach dem Prinzip "fire-and-forget": Sie blockieren niemals die Sitzung, und alle Fehler werden protokolliert und übersprungen.
**Eingabe**:
{
sessionId: string;
timestamp: number;
cwd: string;
hook_event_name: "Notification";
message: string; // Human-readable notification text
title?: string; // Short title (e.g., "Permission needed", "Shell completed")
notification_type: string; // One of the types listed below
}
**Benachrichtigungstypen:**
| Typ | Wenn es ausgelöst wird |
|---|---|
shell_completed | Ein Hintergrund-Shellbefehl (asynchron) wird beendet. |
shell_detached_completed | Eine getrennte Shell-Sitzung ist beendet. |
agent_completed | Ein Unteragent im Hintergrund wird abgeschlossen (abgeschlossen oder fehlgeschlagen) |
agent_idle | Ein Hintergrund-Agent beendet einen Umlauf und wechselt in den Leerlaufmodus (wartend auf write_agent) |
permission_prompt | Der Agent fordert die Berechtigung zum Ausführen eines Tools an. |
elicitation_dialog | Der Agent fordert zusätzliche Informationen vom Benutzer an. |
**Ausgabe:**
{
additionalContext?: string; // Injected into the session as a user message
}
Wenn der Text additionalContext zurückgegeben wird, wird er als vorangestellte Benutzernachricht in die Sitzung gespritzt. Dies kann die weitere Agentverarbeitung auslösen, wenn die Sitzung im Leerlauf ist. Geben Sie {} oder eine leere Ausgabe zurück, um keine Aktion auszuführen.
**Matcher:** Optionales Regex für `notification_type`. Das Muster ist als `^(?:pattern)$`verankert. Um alle Benachrichtigungstypen zu erhalten, lassen Sie `matcher` weg.
Toolnamen für den Hook-Abgleich
| Toolname | Description |
|---|---|
ask_user | Stellen Sie dem Benutzer eine klarstellende Frage. |
bash | Ausführen von Shellbefehlen (Unix). |
create | Erstellen Sie neue Dateien. |
edit | Dateiinhalte ändern. |
glob | Suchen Sie Dateien nach Mustern. |
grep | Dateiinhalte durchsuchen. |
powershell | Ausführen von Shellbefehlen (Windows). |
task | Führen Sie Subagent-Aufgaben aus. |
view | Dateiinhalte lesen. |
web_fetch | Webseiten abrufen. |
Wenn mehrere Hooks desselben Typs konfiguriert sind, werden sie in der reihenfolge ausgeführt. Wenn preToolUseirgendein Hook "deny"zurückgibt, wird das Tool blockiert. Für postToolUseFailure Befehlshaken führt das Beenden mit Code 2 dazu, dass stderr als Wiederherstellungsleitfaden für den Assistenten zurückgegeben wird. Hook-Fehler (Nicht-Null-Beendigungscodes oder Timeouts) werden protokolliert und übersprungen – sie blockieren niemals die Ausführung des Agents.