PostToolUse Hooks ile Claude dosya yazdıktan sonra lint otomatik çalışır. Çıkış kodu 2, hataları Claude'a geri göndererek otomatik düzeltme sağlar.
Claude Code kod yazarken hızlıdır, ancak lint çalıştırmayı her zaman hatırlamaz. "Yazarken bir de kontrol et" diyorsunuz, bazen yapıyor bazen atlamıyor. Hooks bu sorunu çözüyor — kod denetimini "Claude'un sorumluluğu"ndan "sistemin sorumluluğu"na taşıyor.
Bu makale tek bir şeye odaklanıyor: Claude kod yazdıktan sonra otomatik olarak denetim başlatmak için PostToolUse Hooks kullanmak ve her dosya değişikliğinin standartlarınızı karşılamasını sağlamak.
Kod denetimi Hook'unun mantığı basittir:
Write veya Edit çağırırÇıkış kodu 2 kilit noktadır — Claude hatayı alır ve otomatik düzelterek "yaz→denetle→düzelt" döngüsü oluşur.
{
"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'"
}
]
}
]
}
}
Denetim mantığını bağımsız bir betiğe taşımak, JSON'a komut yığmaktan daha kolay yönetilir.
.claude/hooks/lint.sh oluşturun:
#!/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
settings.json'da betiği referans alın:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [{ "type": "command", "command": "bash .claude/hooks/lint.sh" }]
}
]
}
}
Çıkış kodu 2 + stderr, Claude'un otomatik düzeltmesinin anahtarıdır:
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
Yapılandırıldıktan sonra iş akışı şöyle görünür:
Write aracıyla yazarrubocop -A çalıştırır — 3 sorun bulurHiçbir zaman manuel olarak denetim komutu çalıştırmanız gerekmez.
Global (~/.claude/settings.json): Tüm projelerde aynı kuralları kullandığınızda uygundur.
Proje düzeyi (git'e commit edilen .claude/settings.json): Ekipler için önerilir. Depoyu açan herkes otomatik olarak doğru yapılandırmayı alır.
İkisi bir arada bulunabilir; proje düzeyi hook'lar globallerle birleşerek ikisi de çalışır.
Hooks ile otomatik kod denetimi üç adıma iner:
PostToolUse + "Write|Edit" matcher ile dosya yazmalarını yakalamakBir dille başlayın. Çalışınca diğerlerini ekleyin. Betikleri .claude/hooks/'a commit edin ve ekiple paylaşın.