Claude Code Hooks mekanizmasının tam analizi: beş olay türü, çıkış kodu kontrolü ve dört gerçek yapılandırma ile AI eylemlerini denetlenebilir, engellenebilir ve otomatik hale getirme.
Claude Code her dosya okuduğunda, kod yazdığında veya komut çalıştırdığında arka planda bir olay sistemi çalışmaktadır. Hooks, bu sisteme bağlanmak için kullanılan arayüzdür — istediğiniz an kendi mantığınızı enjekte edebilir, otomatik kod kontrolü yapabilir, işlemleri kaydedebilir, tehlikeli işlemleri engelleyebilir veya herhangi bir shell komutunu tetikleyebilirsiniz.
Bu makale, Hooks mekanizmasını, yapılandırmasını ve gerçek dünya kullanımını eksiksiz biçimde ele almaktadır.
Hooks, settings.json'da yapılandırılmış shell komutlarıdır ve Claude Code belirli olaylar gerçekleştiğinde bunları otomatik olarak çalıştırır.
En doğrudan benzetme: git hooks. Git, commit, push gibi işlemlerden önce ve sonra script tetikleyebilir. Claude Code Hooks da aynı mantıkla çalışır — fark, tetikleme noktalarının AI'nın araç çağrıları olmasıdır.
Bu neden önemli?
Claude Code'un yetenekleri arttıkça, deterministik bir kontrol katmanına daha fazla ihtiyaç duyarsınız. Hooks şunları sağlar:
- Prompt'a bağımlı olmayan çalışma garantisi (Claude talimatları görmezden gelebilir, ama hook her zaman çalışır)
- Denetlenebilir işlem kayıtları
- Otomatik kalite kontrolleri
| Tür | Tetikleyici | Tipik Kullanım |
|---|---|---|
PreToolUse |
Araç çağrısından önce | Tehlikeli işlemleri engelleme, niyet kaydetme |
PostToolUse |
Araç çağrısından sonra | Otomatik lint, test çalıştırma |
PreCompact |
Bağlam sıkıştırmadan önce | Mevcut durumu anlık görüntü olarak kaydetme |
Notification |
Claude bir bildirim gönderdiğinde | Masaüstü bildirimleri, Slack mesajları |
Stop |
Claude yanıtı tamamladığında | Log özeti, sonraki akışları tetikleme |
En çok kullanılanlar PreToolUse ve PostToolUse'dur — araç çağrılarını kesme ve sonradan işleme için kullanılır.
Hooks, ~/.claude/settings.json (genel) veya proje kök dizinindeki .claude/settings.json (proje düzeyi) dosyasına yazılır:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "npm run lint --silent"
}
]
}
]
}
}
Üç temel alan:
matcher: Araç adlarıyla eşleşen regex, bu hook'un hangi araç çağrılarından sonra tetikleneceğini belirler. "Write|Edit" dosya yazma veya düzenleme sırasında tetiklenir. Boş bırakın veya tüm araçlarla eşleşmek için ".*" kullanın.type: Şu an için yalnızca "command".command: Herhangi bir shell komutu.matcher yazarken bilmeniz gereken araç adları:
| Araç Adı | İşlem |
|---|---|
Write |
Yeni dosya yazma |
Edit |
Dosya düzenleme |
Bash |
Shell komutu çalıştırma |
Read |
Dosya okuma |
Glob |
Dosya arama |
Grep |
İçerik arama |
TodoWrite |
Görev listesini güncelleme |
Çalışma sırasında stdin üzerinden JSON olarak veri iletilir:
{
"tool_name": "Write",
"tool_input": {
"file_path": "/path/to/file.rb",
"content": "..."
},
"tool_response": "..."
}
PreToolUse, tool_input'u (çağrıdan önceki argümanlar) alır. PostToolUse ayrıca tool_response'u (aracın dönüş değeri) da alır.
Koşul mantığı olan bir hook örneği:
#!/bin/bash
input=$(cat)
file=$(echo "$input" | jq -r '.tool_input.file_path')
# Yalnızca .rb dosyaları için rubocop çalıştır
if [[ "$file" == *.rb ]]; then
rubocop "$file" --autocorrect-all --no-color
fi
Hook'un çıkış kodu, Claude Code'un sonraki davranışını kontrol eder:
| Çıkış Kodu | Anlam |
|---|---|
0 |
Başarılı, çalışmaya devam et |
2 |
Engelle: mevcut araç çağrısını iptal et, stderr çıktısını Claude'a gönder |
| Diğer sıfır olmayan | Hatayı kaydet ama çalışmaya devam et |
2 çıkış kodu en kullanışlısıdır — PreToolUse'da kesme mantığı yazarak Claude'un bir işlem yapmasını engelleyebilir ve nedenini açıklayabilirsiniz.
{
"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": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash -c 'cmd=$(echo \"$CLAUDE_TOOL_INPUT\" | jq -r .command); if echo \"$cmd\" | grep -qE \"rm.*/(migrations|seeds)\"; then echo \"migrations veya seeds dizinlerinin silinmesine izin verilmiyor\" >&2; exit 2; fi'"
}
]
}
]
}
}
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|Bash",
"hooks": [
{
"type": "command",
"command": "echo \"$(date '+%Y-%m-%d %H:%M:%S') $CLAUDE_TOOL_NAME: $(echo $CLAUDE_TOOL_INPUT | jq -c .)\" >> ~/.claude/audit.log"
}
]
}
]
}
}
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude tamamladı\" with title \"Claude Code\"'"
}
]
}
]
}
}
Hooks iki yere konulabilir:
Genel (~/.claude/settings.json): Tüm projeler için geçerli kurallar — log, bildirimler.
Proje düzeyi (.claude/settings.json): Projeye özgü kontroller. Proje düzeyi ve genel hooks birleştirilerek ikisi de çalıştırılır.
Takım projelerinde, proje düzeyi settings.json'ı git'e commit edin; böylece herkes aynı hooks'ları çalıştırır.
Hook çalışmadığında sorun giderme adımları:
write ile Write farklıdırecho "hook triggered" >> /tmp/hook.log ile tetiklemeyi doğrulayınHooks'un temel değeri tahmin edilemeyen AI davranışını deterministik mühendislik standartlarıyla birleştirmektir. Claude testleri çalıştırmayı unutabilir, ama PostToolUse hook unutmaz. Claude yanlışlıkla dosyaları silebilir, ama PreToolUse engelleyici geçirmez.
Tek bir hook ile başlayın: dosya yazdıktan sonra otomatik lint. Bu çalıştıktan sonra diğerlerini ekleyin.