Zum Inhalt springen

Hook-Events & Handler

Wissen

Die wichtigsten Hook-Events

Claude Code feuert an 24 Stellen im Workflow Events. Jedes Event ist ein Eingriffspunkt, an dem du deterministisches Verhalten erzwingen kannst. Hier die wichtigsten:

EventWann feuert es?Typischer Einsatz
PreToolUseVor jeder Tool-AusführungValidierung, Blockieren gefährlicher Aktionen
PostToolUseNach jeder Tool-AusführungAuto-Formatierung, Linting, Type-Checks
SessionStartBeim Start einer neuen SessionKontext laden, Environment prüfen
StopClaude ist fertig mit der AufgabeQualitätsgates, finale Prüfungen
UserPromptSubmitBevor ein Prompt verarbeitet wirdKontext-Injection, Prompt-Enrichment
SubagentStartSubagent wird gestartetMonitoring, Konfiguration
SubagentStopSubagent hat ErgebnisErgebnis-Validierung
TaskCreatedNeue Task in Agent-TeamsKoordination, Logging
TaskCompletedTask abgeschlossenQualitätskontrolle
PreCompactVor Context-KomprimierungWichtige Infos sichern
PostCompactNach Context-KomprimierungKontext wiederherstellen
WorktreeCreateGit-Worktree erstelltSetup, Initialisierung
WorktreeRemoveGit-Worktree entferntCleanup, Aufräumen
NotificationClaude wartet auf EingabeDesktop-Benachrichtigung

iPreToolUse und PostToolUse sind die Stars

Diese beiden Events decken 80% aller Anwendungsfälle ab. PreToolUse blockiert gefährliche Aktionen, PostToolUse sorgt für automatische Qualitätssicherung nach jeder Änderung.

Die 4 Handler-Typen

Jeder Hook braucht einen Handler -- die Logik, die beim Event ausgeführt wird:

1. Command-Handler (Standard)

Der häufigste Typ. Führt ein Shell-Script aus und empfängt den Event-Kontext als JSON über stdin.

{
  "type": "command",
  "command": "npx prettier --write $TOOL_INPUT_FILE_PATH"
}

Das Script erhält alle relevanten Informationen: welches Tool aufgerufen wurde, mit welchen Argumenten, und was das Ergebnis war. Perfekt für Linting, Tests, Formatierung und Sicherheitschecks.

2. HTTP-Handler

Sendet einen POST-Request an einen HTTP-Endpoint. Ideal für Logging, Webhooks oder die Integration mit externen Systemen.

{
  "type": "http",
  "url": "https://your-server.com/hooks/log",
  "headers": { "Authorization": "Bearer $TOKEN" }
}

3. Prompt-Handler

Nutzt ein leichtgewichtiges LLM (Haiku) für einen einzelnen Evaluations-Turn. Gut für Entscheidungen, die menschliches Urteil simulieren.

{
  "type": "prompt",
  "prompt": "Prüfe ob dieser Code-Änderung die bestehende API bricht. Antworte nur mit PASS oder FAIL."
}

!Prompt-Handler sind nicht deterministisch

Der Prompt-Handler nutzt ein LLM -- das heißt, seine Antworten können variieren. Für harte Regeln wie "kein force push" ist ein Command-Handler besser geeignet.

4. Agent-Handler

Der mächtigste Typ: Ein Multi-Turn LLM mit Tool-Zugriff, der bis zu 50 Turns ausführen kann. Für komplexe Prüfungen wie "Hat diese Änderung alle Tests aktualisiert?"

{
  "type": "agent",
  "prompt": "Prüfe ob die geänderten Dateien entsprechende Test-Updates haben. Führe die Tests aus und berichte.",
  "maxTurns": 10
}

Exit-Codes: Die Sprache der Hooks

Hooks kommunizieren über Exit-Codes mit Claude Code:

Exit-CodeBedeutungVerhalten
0Alles OKAktion fortsetzen. stdout wird dem Context hinzugefügt
2BlockierenAktion wird VERHINDERT. stderr wird als Feedback an Claude zurückgegeben
AndererNicht-blockierender FehlerAktion wird fortgesetzt. stderr wird im Verbose-Modus (Ctrl+O) angezeigt

Das ist elegant: Exit-Code 0 heißt "weitermachen", Exit-Code 2 heißt "stopp". Alles andere wird als nicht-kritischer Fehler behandelt und läuft weiter.

#!/bin/bash
# Beispiel: Blockiere force-push
if echo "$1" | grep -q "push.*--force"; then
  echo "Force-push ist nicht erlaubt!" >&2
  exit 2
fi
exit 0

Matcher und if-Filter

Nicht jeder Hook soll bei jedem Tool-Aufruf feuern. Dafür gibt es zwei Filtermechanismen:

Matcher: Regex auf den Tool-Namen

{
  "matcher": "Edit|Write",
  "hooks": [{ "type": "command", "command": "npx prettier --write" }]
}

Dieser Hook feuert nur bei Edit- und Write-Aufrufen, nicht bei Bash oder Read.

if-Filter: Tool + Argument

{
  "matcher": "Bash",
  "if": "Bash(git commit*)",
  "hooks": [{ "type": "command", "command": "npm test" }]
}

Der if-Filter ist mächtig: Er matcht nicht nur den Tool-Namen, sondern auch die Argumente. Bash(git commit*) feuert nur, wenn Claude einen git commit-Befehl ausführen will -- nicht bei jedem Bash-Aufruf.

*Matcher + if kombinieren

Der matcher filtert grob nach Tool-Typ, der if-Filter verfeinert nach Argumenten. Zusammen ergibt das präzise Kontrolle ohne Overhead.

Wo Hooks gespeichert werden

Hooks können an vier Orten definiert werden, mit aufsteigender Priorität:

  1. Global (~/.claude/settings.json) -- Gilt für alle Projekte. Ideal für persönliche Präferenzen wie Formatierung oder Notifications.
  2. Projekt (.claude/settings.json) -- Gilt für das gesamte Team. Wird ins Git-Repository committed.
  3. Lokal (.claude/settings.local.json) -- Persönliche Projekt-Overrides. Wird NICHT committed (in .gitignore).
  4. Skill/Agent Frontmatter -- Hooks innerhalb eines Skills oder Agent-Definitions. Gilt nur für diesen Skill.

iTeam-Hooks vs. persönliche Hooks

Qualitäts-Hooks wie Linting und Tests gehören in die Projekt-Settings (.claude/settings.json), damit das ganze Team davon profitiert. Desktop-Notifications oder persönliche Formatierungs-Präferenzen gehören in die lokale oder globale Config.

Verstehen

Probiere den Hook-Event-Simulator aus: Wähle ein Szenario und beobachte, welche Events in welcher Reihenfolge feuern. Klicke auf einzelne Events, um Details und Beispiel-Konfigurationen zu sehen.

Claude Code schreibt eine Datei mit dem Write-Tool.

AktionDatei wird geschrieben

Klicke auf einen Hook-Event, um Details zu sehen. Pfeiltasten zur Navigation.

Anwenden

Überlege für dein aktuelles Projekt: Welche Aktionen sollen IMMER nach einer Dateiänderung laufen? Welche Befehle sollen NIEMALS ohne Prüfung ausgeführt werden? Die Antworten darauf zeigen dir, welche Events und Handler du brauchst. Im nächsten Abschnitt bekommst du fertige Rezepte zum Kopieren.