PostToolUse Hooks lösen den Linter nach jedem Schreibvorgang von Claude automatisch aus. Exit-Code 2 meldet Fehler zurück für automatische Korrektur.
Claude Code schreibt Code schnell, aber er vergisst nicht selten, den Linter auszuführen. Sie bitten ihn "dabei gleich zu prüfen" — manchmal macht er's, manchmal nicht. Hooks lösen dieses Problem: Sie verlagern die Verantwortung für die Code-Prüfung von Claude auf das System.
Dieser Artikel konzentriert sich auf eine Sache: PostToolUse Hooks einsetzen, um nach jedem Schreibvorgang automatisch Prüfungen auszulösen, sodass jede Dateiänderung Ihren Standards entspricht.
Die Logik eines Code-Prüf-Hooks ist einfach:
Write oder Edit auf, um eine Datei zu schreibenExit-Code 2 ist entscheidend: Claude empfängt den Fehler und korrigiert ihn automatisch, womit ein Zyklus "schreiben→prüfen→korrigieren" entsteht.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash -c 'file=$(echo \"$CLAUDE_TOOL_INPUT\" | jq -r .file_path 2>/dev/null); [[ \"$file\" == *.rb ]] && rubocop -A \"$file\" --no-color -q || true'"
}
]
}
]
}
}
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash -c 'file=$(echo \"$CLAUDE_TOOL_INPUT\" | jq -r .file_path 2>/dev/null); [[ \"$file\" =~ \\.(js|ts|jsx|tsx)$ ]] && npx eslint --fix \"$file\" || true'"
}
]
}
]
}
}
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash -c 'file=$(echo \"$CLAUDE_TOOL_INPUT\" | jq -r .file_path 2>/dev/null); [[ \"$file\" == *.py ]] && ruff check --fix \"$file\" && ruff format \"$file\" || true'"
}
]
}
]
}
}
Die Prüflogik in ein eigenständiges Skript auszulagern ist wartbarer als Befehle im JSON zu stapeln.
.claude/hooks/lint.sh erstellen:
#!/bin/bash
set -e
input=$(cat)
file=$(echo "$input" | jq -r '.tool_input.file_path // empty')
[[ -z "$file" ]] && exit 0
[[ ! -f "$file" ]] && exit 0
ext="${file##*.}"
case "$ext" in
rb) rubocop -A "$file" --no-color -q ;;
js|ts|jsx|tsx) npx eslint --fix "$file" --quiet ;;
py) ruff check --fix "$file"; ruff format "$file" ;;
go) gofmt -w "$file"; golangci-lint run "$file" 2>&1 ;;
*) exit 0 ;;
esac
Das Skript in settings.json referenzieren:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [{ "type": "command", "command": "bash .claude/hooks/lint.sh" }]
}
]
}
}
Exit-Code 2 + stderr löst die automatische Korrektur durch Claude aus:
run_lint() {
local output exit_code
output=$(rubocop "$file" --no-color 2>&1)
exit_code=$?
if [[ $exit_code -ne 0 ]]; then
echo "$output" >&2
exit 2
fi
rubocop -A "$file" --no-color -q
}
skip_patterns=("vendor/" "node_modules/" "db/schema.rb" ".min.js" "_test.go")
for pattern in "${skip_patterns[@]}"; do
[[ "$file" == *"$pattern"* ]] && exit 0
done
Nach der Konfiguration sieht der Ablauf so aus:
Write-Werkzeugrubocop -A automatisch aus — findet 3 ProblemeSie müssen niemals manuell einen Prüfbefehl ausführen.
Global (~/.claude/settings.json): Wenn Sie dieselben Regeln in allen Projekten verwenden.
Projektebene (.claude/settings.json in git): Empfohlen für Teams. Wer das Repository öffnet, erhält automatisch die richtige Konfiguration.
Beide können koexistieren; Projekt-Hooks werden mit globalen zusammengeführt.
Automatische Code-Prüfung mit Hooks läuft auf drei Schritte hinaus:
PostToolUse + Matcher "Write|Edit", um Datei-Schreibvorgänge abzufangenBeginnen Sie mit einer Sprache. Sobald es läuft, fügen Sie weitere hinzu. Committen Sie die Skripte in .claude/hooks/ und teilen Sie sie mit dem Team.