Zum Hauptinhalt springen
|7 min read|Hedinger-Digital

Claude Code Hooks: Event-basierte Automatisierung

Hooks automatisieren Aktionen bei bestimmten Events. Lernen Sie alle Hook-Types, Exit-Code-Verhalten und praktische Beispiele für Auto-Formatting, Testing und Security.

Claude CodeHooksAutomatisierungDevOps

Hooks sind das Enforcement-Feature in Claude Code. Während CLAUDE.md Empfehlungen gibt, garantieren Hooks, dass bestimmte Aktionen immer passieren - Auto-Formatting, Security-Checks, Tests.

Was sind Hooks?

Ein Hook ist ein Script oder Command, das bei einem bestimmten Event automatisch ausgeführt wird:

[Claude will Datei editieren]
        ↓
[PreToolUse Hook: Security Check]
        ↓
[Check OK → Edit wird ausgeführt]
        ↓
[PostToolUse Hook: Auto-Format]
        ↓
[Formatierte Datei gespeichert]

Der Unterschied zu CLAUDE.md:

CLAUDE.mdHooks
"Bitte formatiere nach dem Edit"Formatierung passiert garantiert
AdvisoryDeterministic
Claude kann vergessenSystem führt aus

Alle Hook-Events

Session-Events

EventWannTypische Nutzung
SessionStartSession beginntEnv-Setup, Logging
SessionEndSession endetCleanup, Reporting

User-Events

EventWannTypische Nutzung
UserPromptSubmitUser sendet PromptInput-Validierung, Logging

Tool-Events

EventWannTypische Nutzung
PreToolUseVor Tool-AusführungValidierung, Blocking, Modifikation
PostToolUseNach erfolgreicher AusführungFormatting, Testing, Notifications
PostToolUseFailureNach fehlgeschlagener AusführungError-Logging, Alerts
PermissionRequestBei Permission-DialogAuto-Accept/Deny Logik

Agent-Events

EventWannTypische Nutzung
SubagentStartSubagent wird gestartetLogging, Context-Setup
SubagentStopSubagent ist fertigValidierung, Cleanup
StopClaude ist fertigFinale Checks, Notifications

System-Events

EventWannTypische Nutzung
PreCompactVor Context-KomprimierungState-Saving
NotificationClaude sendet NotificationCustom Alerts

Konfiguration

Locations

Hooks können an verschiedenen Stellen konfiguriert werden:

LocationDateiScope
User~/.claude/settings.jsonAlle Projekte
Project.claude/settings.jsonDieses Projekt (committen)
Local.claude/settings.local.jsonPersönlich (nicht committen)

Grundstruktur

{
  "hooks": {
    "EventName": [
      {
        "matcher": "ToolPattern",
        "hooks": [
          {
            "type": "command",
            "command": "your-script.sh",
            "timeout": 60
          }
        ]
      }
    ]
  }
}

Matcher Patterns

PatternBedeutung
"Write"Exakt das Write-Tool
"Edit|Write"Edit ODER Write
"Notebook.*"Alle Notebook-Tools
"*"Alle Tools

Exit-Code Verhalten

Der Exit-Code Ihres Scripts bestimmt, was passiert:

Exit CodeVerhalten
0Erfolg. stdout wird im Verbose-Mode angezeigt
2Blocking Error. stderr wird an Claude zurückgegeben
AndereNon-blocking Error. stderr im Verbose-Mode

Exit Code 2 ist der Schlüssel - damit können Sie Aktionen blockieren und Claude informieren:

#!/bin/bash
# .claude/hooks/protect-production.sh

if [[ "$FILE" == *"production"* ]]; then
    echo "BLOCKED: Production files sind geschützt!" >&2
    exit 2
fi

exit 0

PreToolUse: Aktionen kontrollieren

Einfaches Blocking

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/protect-paths.sh"
          }
        ]
      }
    ]
  }
}

Script .claude/hooks/protect-paths.sh:

#!/bin/bash

PROTECTED_PATHS=(
    ".env"
    "credentials"
    "secrets"
    "production.config"
)

for pattern in "${PROTECTED_PATHS[@]}"; do
    if [[ "$FILE_PATH" == *"$pattern"* ]]; then
        echo "BLOCKED: $FILE_PATH ist geschützt!" >&2
        exit 2
    fi
done

exit 0

JSON-Output für erweiterte Kontrolle

PreToolUse Hooks können JSON zurückgeben für feinere Kontrolle:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow",
    "permissionDecisionReason": "Docs-Datei auto-approved",
    "updatedInput": {
      "file_path": "/corrected/path/file.ts"
    },
    "additionalContext": "Hinweis: Dies ist eine Docs-Datei."
  }
}
FeldWerteBeschreibung
permissionDecisionallow, deny, askAutomatische Entscheidung
permissionDecisionReasonStringGrund für die Entscheidung
updatedInputObjectModifizierte Tool-Parameter
additionalContextStringExtra-Info für Claude

Beispiel: Auto-Approve für Docs

#!/bin/bash
# .claude/hooks/auto-approve-docs.sh

if [[ "$FILE_PATH" == *.md ]] || [[ "$FILE_PATH" == *"/docs/"* ]]; then
    cat << EOF
{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow",
    "permissionDecisionReason": "Documentation auto-approved"
  }
}
EOF
fi

exit 0

PostToolUse: Nach Aktionen reagieren

Auto-Formatting

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/auto-format.sh"
          }
        ]
      }
    ]
  }
}

Script:

#!/bin/bash
# .claude/hooks/auto-format.sh

FILE="$FILE_PATH"

case "$FILE" in
    *.ts|*.tsx|*.js|*.jsx)
        npx prettier --write "$FILE" 2>/dev/null
        ;;
    *.py)
        black "$FILE" 2>/dev/null
        ;;
    *.go)
        gofmt -w "$FILE" 2>/dev/null
        ;;
esac

exit 0

Auto-Testing

#!/bin/bash
# .claude/hooks/auto-test.sh

FILE="$FILE_PATH"

# Finde zugehörige Test-Datei
TEST_FILE="${FILE%.ts}.test.ts"

if [[ -f "$TEST_FILE" ]]; then
    npm test -- "$TEST_FILE" --passWithNoTests 2>&1
fi

exit 0

Prompt-based Hooks

Für Stop und SubagentStop Events können Sie LLM-basierte Hooks nutzen:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "prompt",
            "prompt": "Prüfe ob alle Aufgaben erledigt sind: $ARGUMENTS",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

Das LLM (Haiku) evaluiert und gibt zurück:

{
  "ok": true,
  "reason": "Alle Tasks wurden erfolgreich abgeschlossen."
}

Oder bei Problemen:

{
  "ok": false,
  "reason": "Tests wurden nicht ausgeführt."
}

Environment Variables

Hooks erhalten Kontext über Umgebungsvariablen:

VariableBeschreibung
CLAUDE_PROJECT_DIRAbsoluter Pfad zum Projekt-Root
CLAUDE_CODE_REMOTEtrue wenn Remote/Web-Session
CLAUDE_ENV_FILE(SessionStart) Pfad für persistente Env-Vars

Tool-spezifische Variablen

Je nach Tool sind zusätzliche Variablen verfügbar:

Edit/Write:

  • FILE_PATH - Pfad zur bearbeiteten Datei

Bash:

  • COMMAND - Ausgeführter Befehl

Praktische Hook-Sammlung

1. Branch Protection

#!/bin/bash
# Verhindere Commits auf main/master

BRANCH=$(git branch --show-current)

if [[ "$BRANCH" == "main" || "$BRANCH" == "master" ]]; then
    echo "BLOCKED: Direkte Commits auf $BRANCH nicht erlaubt!" >&2
    exit 2
fi

exit 0

2. Commit Message Validation

#!/bin/bash
# Prüfe Conventional Commits Format

MESSAGE="$1"
PATTERN="^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: .{1,50}"

if ! [[ "$MESSAGE" =~ $PATTERN ]]; then
    echo "BLOCKED: Commit Message muss Conventional Commits Format folgen!" >&2
    echo "Format: type(scope): description" >&2
    exit 2
fi

exit 0

3. Security Scanning

#!/bin/bash
# Scanne auf Secrets

if grep -r "PRIVATE_KEY\|API_KEY\|SECRET" "$FILE_PATH" 2>/dev/null; then
    echo "WARNING: Mögliche Secrets gefunden in $FILE_PATH" >&2
    # exit 2  # Uncomment um zu blockieren
fi

exit 0

4. Dependency Check

#!/bin/bash
# Prüfe auf bekannte Vulnerabilities nach package.json Änderung

if [[ "$FILE_PATH" == *"package.json"* ]]; then
    npm audit --audit-level=high 2>&1
    if [[ $? -ne 0 ]]; then
        echo "WARNING: npm audit hat Vulnerabilities gefunden" >&2
    fi
fi

exit 0

5. Documentation Reminder

#!/bin/bash
# Erinnere an Docs-Updates bei API-Änderungen

if [[ "$FILE_PATH" == *"/api/"* ]]; then
    echo "REMINDER: API geändert - bitte auch Docs aktualisieren" >&2
fi

exit 0

Debugging Hooks

Verbose Mode

claude --verbose

Zeigt stdout aller Hooks (auch bei Exit 0).

Logging in Hooks

#!/bin/bash
# Logging zu File

LOG_FILE="$CLAUDE_PROJECT_DIR/.claude/hooks.log"
echo "[$(date)] Hook ausgeführt: $0" >> "$LOG_FILE"
echo "  FILE_PATH: $FILE_PATH" >> "$LOG_FILE"

Häufige Fehler

ProblemLösung
Hook wird nicht ausgeführtPfad prüfen, chmod +x
Exit 2 blockiert nichtstderr nutzen, nicht stdout
Env-Vars leerPrüfen ob Event sie bereitstellt
Timeouttimeout Feld erhöhen

Best Practices

1. Schnelle Hooks

Hooks sollten schnell sein (< 5 Sekunden). Lange Hooks blockieren den Workflow.

2. Fail-Safe

#!/bin/bash
# Nicht blockieren bei eigenem Fehler

if ! command -v prettier &> /dev/null; then
    # Prettier nicht installiert - nicht blockieren
    exit 0
fi

prettier --write "$FILE_PATH"

3. Klare Fehlermeldungen

echo "BLOCKED: .env Dateien dürfen nicht committet werden!" >&2
echo "Hinweis: Nutze .env.example als Template" >&2
exit 2

4. Dokumentation

Dokumentieren Sie Ihre Hooks für das Team:

## Konfigurierte Hooks

| Event | Hook | Zweck |
|-------|------|-------|
| PreToolUse (Edit) | protect-paths.sh | Schützt kritische Dateien |
| PostToolUse (Edit) | auto-format.sh | Formatiert Code |
| Stop | verify-tests.sh | Prüft Test-Coverage |

Fazit

Hooks transformieren "sollte" in "muss". Auto-Formatting, Security-Checks, Test-Execution - was früher Disziplin erforderte, passiert jetzt automatisch.

Starten Sie mit einem einfachen PostToolUse Hook für Formatting. Wenn Sie den Workflow verinnerlicht haben, erweitern Sie auf Security und Testing.


Weiterführende Artikel:

Nächster Schritt: Sie möchten Hooks für Ihr CI/CD-Setup entwickeln? Wir helfen bei Konzeption und Implementierung. Mehr über unsere DevOps-Dienstleistungen.

Mehr

Ähnliche Artikel