Für eine Schnellstartanleitung mit Beispielen siehe Erste Schritte mit Claude Code Hooks.

Konfiguration

Claude Code Hooks werden in Ihren Einstellungsdateien konfiguriert:

  • ~/.claude/settings.json - Benutzereinstellungen
  • .claude/settings.json - Projekteinstellungen
  • .claude/settings.local.json - Lokale Projekteinstellungen (nicht committed)
  • Enterprise verwaltete Richtlinieneinstellungen

Struktur

Hooks sind nach Matchern organisiert, wobei jeder Matcher mehrere Hooks haben kann:

{
  "hooks": {
    "EventName": [
      {
        "matcher": "ToolPattern",
        "hooks": [
          {
            "type": "command",
            "command": "your-command-here"
          }
        ]
      }
    ]
  }
}
  • matcher: Muster zum Abgleichen von Tool-Namen, groß-/kleinschreibungsabhängig (nur anwendbar für PreToolUse und PostToolUse)
    • Einfache Strings stimmen exakt überein: Write stimmt nur mit dem Write-Tool überein
    • Unterstützt Regex: Edit|Write oder Notebook.*
    • Verwenden Sie * um alle Tools zu matchen. Sie können auch einen leeren String ("") verwenden oder matcher leer lassen.
  • hooks: Array von Befehlen, die ausgeführt werden, wenn das Muster übereinstimmt
    • type: Derzeit wird nur "command" unterstützt
    • command: Der auszuführende Bash-Befehl (kann die Umgebungsvariable $CLAUDE_PROJECT_DIR verwenden)
    • timeout: (Optional) Wie lange ein Befehl laufen soll, in Sekunden, bevor dieser spezifische Befehl abgebrochen wird.

Für Events wie UserPromptSubmit, Notification, Stop und SubagentStop, die keine Matcher verwenden, können Sie das Matcher-Feld weglassen:

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/prompt-validator.py"
          }
        ]
      }
    ]
  }
}

Projektspezifische Hook-Skripte

Sie können die Umgebungsvariable CLAUDE_PROJECT_DIR (nur verfügbar, wenn Claude Code den Hook-Befehl spawnt) verwenden, um auf in Ihrem Projekt gespeicherte Skripte zu verweisen, wodurch sichergestellt wird, dass sie unabhängig von Claudes aktuellem Verzeichnis funktionieren:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/check-style.sh"
          }
        ]
      }
    ]
  }
}

Hook-Events

PreToolUse

Läuft nachdem Claude Tool-Parameter erstellt hat und vor der Verarbeitung des Tool-Aufrufs.

Häufige Matcher:

  • Task - Subagent-Aufgaben (siehe Subagents-Dokumentation)
  • Bash - Shell-Befehle
  • Glob - Dateimuster-Abgleich
  • Grep - Inhaltssuche
  • Read - Datei lesen
  • Edit, MultiEdit - Datei bearbeiten
  • Write - Datei schreiben
  • WebFetch, WebSearch - Web-Operationen

PostToolUse

Läuft unmittelbar nachdem ein Tool erfolgreich abgeschlossen wurde.

Erkennt dieselben Matcher-Werte wie PreToolUse.

Notification

Läuft wenn Claude Code Benachrichtigungen sendet. Benachrichtigungen werden gesendet wenn:

  1. Claude Ihre Erlaubnis benötigt, um ein Tool zu verwenden. Beispiel: “Claude needs your permission to use Bash”
  2. Die Prompt-Eingabe mindestens 60 Sekunden inaktiv war. “Claude is waiting for your input”

UserPromptSubmit

Läuft wenn der Benutzer einen Prompt einreicht, bevor Claude ihn verarbeitet. Dies ermöglicht es Ihnen, zusätzlichen Kontext basierend auf dem Prompt/der Unterhaltung hinzuzufügen, Prompts zu validieren oder bestimmte Arten von Prompts zu blockieren.

Stop

Läuft wenn der Haupt-Claude Code Agent seine Antwort beendet hat. Läuft nicht, wenn die Unterbrechung aufgrund einer Benutzerunterbrechung erfolgte.

SubagentStop

Läuft wenn ein Claude Code Subagent (Task-Tool-Aufruf) seine Antwort beendet hat.

SessionEnd

Läuft wenn eine Claude Code Sitzung endet. Nützlich für Aufräumaufgaben, Protokollierung von Sitzungsstatistiken oder Speichern des Sitzungsstatus.

Das reason-Feld in der Hook-Eingabe wird eines der folgenden sein:

  • clear - Sitzung mit /clear-Befehl gelöscht
  • logout - Benutzer hat sich abgemeldet
  • prompt_input_exit - Benutzer ist ausgestiegen, während die Prompt-Eingabe sichtbar war
  • other - Andere Ausstiegsgründe

PreCompact

Läuft bevor Claude Code eine Compact-Operation ausführen wird.

Matcher:

  • manual - Aufgerufen von /compact
  • auto - Aufgerufen von Auto-Compact (aufgrund eines vollen Kontextfensters)

SessionStart

Läuft wenn Claude Code eine neue Sitzung startet oder eine bestehende Sitzung fortsetzt (was derzeit unter der Haube eine neue Sitzung startet). Nützlich zum Laden von Entwicklungskontext wie bestehende Issues oder kürzliche Änderungen an Ihrer Codebasis.

Matcher:

  • startup - Aufgerufen beim Startup
  • resume - Aufgerufen von --resume, --continue oder /resume
  • clear - Aufgerufen von /clear

Hook-Eingabe

Hooks erhalten JSON-Daten über stdin, die Sitzungsinformationen und event-spezifische Daten enthalten:

{
  // Gemeinsame Felder
  session_id: string
  transcript_path: string  // Pfad zur Unterhaltungs-JSON
  cwd: string              // Das aktuelle Arbeitsverzeichnis, wenn der Hook aufgerufen wird

  // Event-spezifische Felder
  hook_event_name: string
  ...
}

PreToolUse-Eingabe

Das genaue Schema für tool_input hängt vom Tool ab.

{
  "session_id": "abc123",
  "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "hook_event_name": "PreToolUse",
  "tool_name": "Write",
  "tool_input": {
    "file_path": "/path/to/file.txt",
    "content": "file content"
  }
}

PostToolUse-Eingabe

Das genaue Schema für tool_input und tool_response hängt vom Tool ab.

{
  "session_id": "abc123",
  "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "hook_event_name": "PostToolUse",
  "tool_name": "Write",
  "tool_input": {
    "file_path": "/path/to/file.txt",
    "content": "file content"
  },
  "tool_response": {
    "filePath": "/path/to/file.txt",
    "success": true
  }
}

Notification-Eingabe

{
  "session_id": "abc123",
  "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "hook_event_name": "Notification",
  "message": "Task completed successfully"
}

UserPromptSubmit-Eingabe

{
  "session_id": "abc123",
  "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "hook_event_name": "UserPromptSubmit",
  "prompt": "Write a function to calculate the factorial of a number"
}

Stop- und SubagentStop-Eingabe

stop_hook_active ist true, wenn Claude Code bereits als Ergebnis eines Stop-Hooks fortsetzt. Überprüfen Sie diesen Wert oder verarbeiten Sie das Transkript, um zu verhindern, dass Claude Code unendlich läuft.

{
  "session_id": "abc123",
  "transcript_path": "~/.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "hook_event_name": "Stop",
  "stop_hook_active": true
}

PreCompact-Eingabe

Für manual kommt custom_instructions von dem, was der Benutzer in /compact übergibt. Für auto ist custom_instructions leer.

{
  "session_id": "abc123",
  "transcript_path": "~/.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "hook_event_name": "PreCompact",
  "trigger": "manual",
  "custom_instructions": ""
}

SessionStart-Eingabe

{
  "session_id": "abc123",
  "transcript_path": "~/.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "hook_event_name": "SessionStart",
  "source": "startup"
}

SessionEnd-Eingabe

{
  "session_id": "abc123",
  "transcript_path": "~/.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "hook_event_name": "SessionEnd",
  "reason": "exit"
}

Hook-Ausgabe

Es gibt zwei Möglichkeiten für Hooks, Ausgaben an Claude Code zurückzugeben. Die Ausgabe kommuniziert, ob blockiert werden soll und welches Feedback Claude und dem Benutzer gezeigt werden soll.

Einfach: Exit-Code

Hooks kommunizieren Status über Exit-Codes, stdout und stderr:

  • Exit-Code 0: Erfolg. stdout wird dem Benutzer im Transkript-Modus gezeigt (CTRL-R), außer für UserPromptSubmit und SessionStart, wo stdout zum Kontext hinzugefügt wird.
  • Exit-Code 2: Blockierender Fehler. stderr wird an Claude zurückgegeben, um automatisch verarbeitet zu werden. Siehe Verhalten pro Hook-Event unten.
  • Andere Exit-Codes: Nicht-blockierender Fehler. stderr wird dem Benutzer gezeigt und die Ausführung wird fortgesetzt.

Erinnerung: Claude Code sieht stdout nicht, wenn der Exit-Code 0 ist, außer für den UserPromptSubmit-Hook, wo stdout als Kontext injiziert wird.

Exit-Code 2 Verhalten

Hook EventVerhalten
PreToolUseBlockiert den Tool-Aufruf, zeigt stderr Claude
PostToolUseZeigt stderr Claude (Tool ist bereits gelaufen)
NotificationN/A, zeigt stderr nur dem Benutzer
UserPromptSubmitBlockiert Prompt-Verarbeitung, löscht Prompt, zeigt stderr nur dem Benutzer
StopBlockiert Stopp, zeigt stderr Claude
SubagentStopBlockiert Stopp, zeigt stderr Claude Subagent
PreCompactN/A, zeigt stderr nur dem Benutzer
SessionStartN/A, zeigt stderr nur dem Benutzer
SessionEndN/A, zeigt stderr nur dem Benutzer

Erweitert: JSON-Ausgabe

Hooks können strukturiertes JSON in stdout für anspruchsvollere Kontrolle zurückgeben:

Gemeinsame JSON-Felder

Alle Hook-Typen können diese optionalen Felder enthalten:

{
  "continue": true, // Ob Claude nach Hook-Ausführung fortfahren soll (Standard: true)
  "stopReason": "string", // Nachricht, die gezeigt wird, wenn continue false ist

  "suppressOutput": true, // stdout vom Transkript-Modus verbergen (Standard: false)
  "systemMessage": "string" // Optionale Warnmeldung, die dem Benutzer gezeigt wird
}

Wenn continue false ist, stoppt Claude die Verarbeitung nach dem Ausführen der Hooks.

  • Für PreToolUse ist dies anders als "permissionDecision": "deny", was nur einen spezifischen Tool-Aufruf blockiert und automatisches Feedback an Claude liefert.
  • Für PostToolUse ist dies anders als "decision": "block", was automatisiertes Feedback an Claude liefert.
  • Für UserPromptSubmit verhindert dies, dass der Prompt verarbeitet wird.
  • Für Stop und SubagentStop hat dies Vorrang vor jeder "decision": "block"-Ausgabe.
  • In allen Fällen hat "continue" = false Vorrang vor jeder "decision": "block"-Ausgabe.

stopReason begleitet continue mit einem Grund, der dem Benutzer gezeigt wird, nicht Claude gezeigt wird.

PreToolUse Entscheidungskontrolle

PreToolUse-Hooks können kontrollieren, ob ein Tool-Aufruf fortgesetzt wird.

  • "allow" umgeht das Berechtigungssystem. permissionDecisionReason wird dem Benutzer gezeigt, aber nicht Claude.
  • "deny" verhindert, dass der Tool-Aufruf ausgeführt wird. permissionDecisionReason wird Claude gezeigt.
  • "ask" bittet den Benutzer, den Tool-Aufruf in der UI zu bestätigen. permissionDecisionReason wird dem Benutzer gezeigt, aber nicht Claude.
{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow" | "deny" | "ask",
    "permissionDecisionReason": "My reason here"
  }
}

Die Felder decision und reason sind für PreToolUse-Hooks veraltet. Verwenden Sie stattdessen hookSpecificOutput.permissionDecision und hookSpecificOutput.permissionDecisionReason. Die veralteten Felder "approve" und "block" werden auf "allow" bzw. "deny" abgebildet.

PostToolUse Entscheidungskontrolle

PostToolUse-Hooks können nach Tool-Ausführung Feedback an Claude liefern.

  • "block" fordert Claude automatisch mit reason auf.
  • undefined tut nichts. reason wird ignoriert.
  • "hookSpecificOutput.additionalContext" fügt Kontext für Claude hinzu.
{
  "decision": "block" | undefined,
  "reason": "Explanation for decision",
  "hookSpecificOutput": {
    "hookEventName": "PostToolUse",
    "additionalContext": "Additional information for Claude"
  }
}

UserPromptSubmit Entscheidungskontrolle

UserPromptSubmit-Hooks können kontrollieren, ob ein Benutzer-Prompt verarbeitet wird.

  • "block" verhindert, dass der Prompt verarbeitet wird. Der eingereichte Prompt wird aus dem Kontext gelöscht. "reason" wird dem Benutzer gezeigt, aber nicht zum Kontext hinzugefügt.
  • undefined erlaubt dem Prompt, normal fortzufahren. "reason" wird ignoriert.
  • "hookSpecificOutput.additionalContext" fügt den String zum Kontext hinzu, wenn nicht blockiert.
{
  "decision": "block" | undefined,
  "reason": "Explanation for decision",
  "hookSpecificOutput": {
    "hookEventName": "UserPromptSubmit",
    "additionalContext": "My additional context here"
  }
}

Stop/SubagentStop Entscheidungskontrolle

Stop- und SubagentStop-Hooks können kontrollieren, ob Claude fortfahren muss.

  • "block" verhindert, dass Claude stoppt. Sie müssen reason für Claude ausfüllen, damit er weiß, wie er fortfahren soll.
  • undefined erlaubt Claude zu stoppen. reason wird ignoriert.
{
  "decision": "block" | undefined,
  "reason": "Must be provided when Claude is blocked from stopping"
}

SessionStart Entscheidungskontrolle

SessionStart-Hooks ermöglichen es Ihnen, Kontext zu Beginn einer Sitzung zu laden.

  • "hookSpecificOutput.additionalContext" fügt den String zum Kontext hinzu.
  • Mehrere Hooks’ additionalContext-Werte werden verkettet.
{
  "hookSpecificOutput": {
    "hookEventName": "SessionStart",
    "additionalContext": "My additional context here"
  }
}

SessionEnd Entscheidungskontrolle

SessionEnd-Hooks laufen, wenn eine Sitzung endet. Sie können die Sitzungsbeendigung nicht blockieren, aber Aufräumaufgaben durchführen.

Exit-Code Beispiel: Bash-Befehl-Validierung

#!/usr/bin/env python3
import json
import re
import sys

# Define validation rules as a list of (regex pattern, message) tuples
VALIDATION_RULES = [
    (
        r"\bgrep\b(?!.*\|)",
        "Use 'rg' (ripgrep) instead of 'grep' for better performance and features",
    ),
    (
        r"\bfind\s+\S+\s+-name\b",
        "Use 'rg --files | rg pattern' or 'rg --files -g pattern' instead of 'find -name' for better performance",
    ),
]


def validate_command(command: str) -> list[str]:
    issues = []
    for pattern, message in VALIDATION_RULES:
        if re.search(pattern, command):
            issues.append(message)
    return issues


try:
    input_data = json.load(sys.stdin)
except json.JSONDecodeError as e:
    print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
    sys.exit(1)

tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input", {})
command = tool_input.get("command", "")

if tool_name != "Bash" or not command:
    sys.exit(1)

# Validate the command
issues = validate_command(command)

if issues:
    for message in issues:
        print(f"• {message}", file=sys.stderr)
    # Exit code 2 blocks tool call and shows stderr to Claude
    sys.exit(2)

JSON-Ausgabe Beispiel: UserPromptSubmit zum Hinzufügen von Kontext und Validierung

Für UserPromptSubmit-Hooks können Sie Kontext mit beiden Methoden injizieren:

  • Exit-Code 0 mit stdout: Claude sieht den Kontext (Sonderfall für UserPromptSubmit)
  • JSON-Ausgabe: Bietet mehr Kontrolle über das Verhalten
#!/usr/bin/env python3
import json
import sys
import re
import datetime

# Load input from stdin
try:
    input_data = json.load(sys.stdin)
except json.JSONDecodeError as e:
    print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
    sys.exit(1)

prompt = input_data.get("prompt", "")

# Check for sensitive patterns
sensitive_patterns = [
    (r"(?i)\b(password|secret|key|token)\s*[:=]", "Prompt contains potential secrets"),
]

for pattern, message in sensitive_patterns:
    if re.search(pattern, prompt):
        # Use JSON output to block with a specific reason
        output = {
            "decision": "block",
            "reason": f"Security policy violation: {message}. Please rephrase your request without sensitive information."
        }
        print(json.dumps(output))
        sys.exit(0)

# Add current time to context
context = f"Current time: {datetime.datetime.now()}"
print(context)

"""
The following is also equivalent:
print(json.dumps({
  "hookSpecificOutput": {
    "hookEventName": "UserPromptSubmit",
    "additionalContext": context,
  },
}))
"""

# Allow the prompt to proceed with the additional context
sys.exit(0)

JSON-Ausgabe Beispiel: PreToolUse mit Genehmigung

#!/usr/bin/env python3
import json
import sys

# Load input from stdin
try:
    input_data = json.load(sys.stdin)
except json.JSONDecodeError as e:
    print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
    sys.exit(1)

tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input", {})

# Example: Auto-approve file reads for documentation files
if tool_name == "Read":
    file_path = tool_input.get("file_path", "")
    if file_path.endswith((".md", ".mdx", ".txt", ".json")):
        # Use JSON output to auto-approve the tool call
        output = {
            "decision": "approve",
            "reason": "Documentation file auto-approved",
            "suppressOutput": True  # Don't show in transcript mode
        }
        print(json.dumps(output))
        sys.exit(0)

# For other cases, let the normal permission flow proceed
sys.exit(0)

Arbeiten mit MCP-Tools

Claude Code Hooks funktionieren nahtlos mit Model Context Protocol (MCP) Tools. Wenn MCP-Server Tools bereitstellen, erscheinen sie mit einem speziellen Benennungsmuster, das Sie in Ihren Hooks matchen können.

MCP-Tool-Benennung

MCP-Tools folgen dem Muster mcp__<server>__<tool>, zum Beispiel:

  • mcp__memory__create_entities - Memory-Server’s Create-Entities-Tool
  • mcp__filesystem__read_file - Filesystem-Server’s Read-File-Tool
  • mcp__github__search_repositories - GitHub-Server’s Search-Tool

Konfigurieren von Hooks für MCP-Tools

Sie können spezifische MCP-Tools oder ganze MCP-Server anvisieren:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "mcp__memory__.*",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Memory operation initiated' >> ~/mcp-operations.log"
          }
        ]
      },
      {
        "matcher": "mcp__.*__write.*",
        "hooks": [
          {
            "type": "command",
            "command": "/home/user/scripts/validate-mcp-write.py"
          }
        ]
      }
    ]
  }
}

Beispiele

Für praktische Beispiele einschließlich Code-Formatierung, Benachrichtigungen und Dateischutz siehe Weitere Beispiele in der Erste-Schritte-Anleitung.

Sicherheitsüberlegungen

Haftungsausschluss

VERWENDUNG AUF EIGENE GEFAHR: Claude Code Hooks führen beliebige Shell-Befehle auf Ihrem System automatisch aus. Durch die Verwendung von Hooks erkennen Sie an, dass:

  • Sie sind allein verantwortlich für die Befehle, die Sie konfigurieren
  • Hooks können alle Dateien ändern, löschen oder darauf zugreifen, auf die Ihr Benutzerkonto zugreifen kann
  • Bösartige oder schlecht geschriebene Hooks können Datenverlust oder Systemschäden verursachen
  • Anthropic bietet keine Garantie und übernimmt keine Haftung für Schäden, die aus der Hook-Verwendung resultieren
  • Sie sollten Hooks gründlich in einer sicheren Umgebung testen, bevor Sie sie produktiv verwenden

Überprüfen und verstehen Sie immer alle Hook-Befehle, bevor Sie sie zu Ihrer Konfiguration hinzufügen.

Sicherheits-Best-Practices

Hier sind einige wichtige Praktiken zum Schreiben sichererer Hooks:

  1. Eingaben validieren und bereinigen - Vertrauen Sie niemals blind Eingabedaten
  2. Shell-Variablen immer in Anführungszeichen setzen - Verwenden Sie "$VAR" nicht $VAR
  3. Pfad-Traversal blockieren - Prüfen Sie auf .. in Dateipfaden
  4. Absolute Pfade verwenden - Geben Sie vollständige Pfade für Skripte an (verwenden Sie $CLAUDE_PROJECT_DIR für den Projektpfad)
  5. Sensible Dateien überspringen - Vermeiden Sie .env, .git/, Schlüssel, etc.

Konfigurationssicherheit

Direkte Bearbeitungen von Hooks in Einstellungsdateien werden nicht sofort wirksam. Claude Code:

  1. Erfasst einen Snapshot von Hooks beim Start
  2. Verwendet diesen Snapshot während der gesamten Sitzung
  3. Warnt, wenn Hooks extern geändert werden
  4. Erfordert Überprüfung im /hooks-Menü, damit Änderungen angewendet werden

Dies verhindert, dass bösartige Hook-Änderungen Ihre aktuelle Sitzung beeinträchtigen.

Hook-Ausführungsdetails

  • Timeout: 60-Sekunden-Ausführungslimit standardmäßig, pro Befehl konfigurierbar.
    • Ein Timeout für einen einzelnen Befehl beeinflusst die anderen Befehle nicht.
  • Parallelisierung: Alle passenden Hooks laufen parallel
  • Deduplizierung: Mehrere identische Hook-Befehle werden automatisch dedupliziert
  • Umgebung: Läuft im aktuellen Verzeichnis mit Claude Codes Umgebung
    • Die Umgebungsvariable CLAUDE_PROJECT_DIR ist verfügbar und enthält den absoluten Pfad zum Projekt-Root-Verzeichnis (wo Claude Code gestartet wurde)
  • Eingabe: JSON über stdin
  • Ausgabe:
    • PreToolUse/PostToolUse/Stop/SubagentStop: Fortschritt im Transkript gezeigt (Ctrl-R)
    • Notification/SessionEnd: Nur in Debug protokolliert (--debug)
    • UserPromptSubmit/SessionStart: stdout als Kontext für Claude hinzugefügt

Debugging

Grundlegende Fehlerbehebung

Wenn Ihre Hooks nicht funktionieren:

  1. Konfiguration prüfen - Führen Sie /hooks aus, um zu sehen, ob Ihr Hook registriert ist
  2. Syntax überprüfen - Stellen Sie sicher, dass Ihre JSON-Einstellungen gültig sind
  3. Befehle testen - Führen Sie Hook-Befehle zuerst manuell aus
  4. Berechtigungen prüfen - Stellen Sie sicher, dass Skripte ausführbar sind
  5. Logs überprüfen - Verwenden Sie claude --debug, um Hook-Ausführungsdetails zu sehen

Häufige Probleme:

  • Anführungszeichen nicht escaped - Verwenden Sie \" innerhalb von JSON-Strings
  • Falscher Matcher - Prüfen Sie, ob Tool-Namen exakt übereinstimmen (groß-/kleinschreibungsabhängig)
  • Befehl nicht gefunden - Verwenden Sie vollständige Pfade für Skripte

Erweiterte Fehlerbehebung

Für komplexe Hook-Probleme:

  1. Hook-Ausführung inspizieren - Verwenden Sie claude --debug, um detaillierte Hook- Ausführung zu sehen
  2. JSON-Schemas validieren - Testen Sie Hook-Ein-/Ausgabe mit externen Tools
  3. Umgebungsvariablen prüfen - Überprüfen Sie, ob Claude Codes Umgebung korrekt ist
  4. Edge-Cases testen - Probieren Sie Hooks mit ungewöhnlichen Dateipfaden oder Eingaben
  5. Systemressourcen überwachen - Prüfen Sie auf Ressourcenerschöpfung während Hook- Ausführung
  6. Strukturierte Protokollierung verwenden - Implementieren Sie Protokollierung in Ihren Hook-Skripten

Debug-Ausgabe Beispiel

Verwenden Sie claude --debug, um Hook-Ausführungsdetails zu sehen:

[DEBUG] Executing hooks for PostToolUse:Write
[DEBUG] Getting matching hook commands for PostToolUse with query: Write
[DEBUG] Found 1 hook matchers in settings
[DEBUG] Matched 1 hooks for query "Write"
[DEBUG] Found 1 hook commands to execute
[DEBUG] Executing hook command: <Your command> with timeout 60000ms
[DEBUG] Hook command completed with status 0: <Your stdout>

Fortschrittsmeldungen erscheinen im Transkript-Modus (Ctrl-R) und zeigen:

  • Welcher Hook läuft
  • Befehl, der ausgeführt wird
  • Erfolg-/Fehlerstatus
  • Ausgabe- oder Fehlermeldungen