Hook tanımlamak
Defining hooks
Bu derste neler öğreneceksin
- settings.json içinde hook bloğunu doğru yazmak
- matcher pattern'leriyle hangi tool'a uygulanacağını sınırlamak
- Hook script'inin stdin/stdout/exit code protokolünü anlamak
Bu derste kuru kuruya hook formatı: JSON şeması, matcher, exit code ve JSON çıktı protokolü.
1. settings.json yapısı
{
"hooks": {
"<EventName>": [
{
"matcher": "<opsiyonel regex>",
"hooks": [
{
"type": "command",
"command": "<komut çalıştırılacak>"
}
]
}
]
}
}
İç içe hooks görmek kafa karıştırır ama yapısı şu:
- Dış
hooks: tüm event tanımlarının kökü <EventName>: PreToolUse / PostToolUse / vs.- Liste: aynı event için birden çok grup
- İç
hooks: aynı matcher için sıralı komutlar
2. Matcher pattern’leri
Tool-bağlı event’lerde (PreToolUse, PostToolUse) matcher hangi tool’a uygulanacağını sınırlar.
| Matcher | Tetiklenir |
|---|---|
"Edit" | Sadece Edit tool |
"Edit|Write" | Edit veya Write |
"Edit|MultiEdit|Write" | Üçü de |
".*" veya boş | Tüm tool’lar |
"Bash" | Sadece shell komutları |
Regex destekli — daha karmaşık şablonlar mümkün, ama basit tut, debug kolay olur.
3. Komut nasıl çalıştırılır?
Komut shell’de çalışır. İçinde $CLAUDE_PROJECT_DIR env variable kullanırsan repo köküne mutlak yol verirsin:
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/scripts/format.sh"
}
Tek satır komut da kabul:
{ "type": "command", "command": "npx prettier --write" }
4. Hook’a giren input
Komuda stdin üzerinden JSON verilir. Yapı:
{
"session_id": "abc-123",
"tool_name": "Edit",
"tool_input": {
"file_path": "src/index.ts",
"old_string": "...",
"new_string": "..."
}
}
Script bunu okuyabilir:
#!/usr/bin/env bash
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path')
# ...
5. Exit code anlamları
| Exit code | Anlamı |
|---|---|
| 0 | Başarılı, akış devam eder |
| 2 | Aksiyonu blokla — PreToolUse’da tool çağrısı iptal olur; stderr Claude’a feedback olarak geri verilir |
| Diğer | Non-blocking error — sana gösterilir ama akış durmaz |
6. JSON çıktı protokolü (gelişmiş)
Komut stdout’a JSON yazarsa Claude Code’un davranışını programatik kontrol edebilirsin:
{
"decision": "block",
"reason": "Production config dosyasına yazma denemesi"
}
Veya context enjekte etme:
{
"additionalContext": "Son commit: feat: add pagination (yusuf, 2 saat önce)"
}
Tüm field listesi resmi docs’ta. Tipik üç field:
| Field | İşi |
|---|---|
decision | "block" / "allow" |
reason | Engelleme/onay nedeni |
additionalContext | Konuşmaya enjekte edilecek metin |
7. Birden çok hook
Aynı event için birden çok grup ekleyebilirsin; sırayla çalışırlar:
"PostToolUse": [
{ "matcher": "Edit", "hooks": [{ "type": "command", "command": "format.sh" }] },
{ "matcher": "Edit", "hooks": [{ "type": "command", "command": "lint.sh" }] }
]
Bir hook exit 2 verirse sonrakiler çalışmaz (bloklama durumunda).
Özet
- Event + matcher + komut üçlüsü
- stdin’den JSON al, stdout/exit code ile yanıtla
- Exit 2 → blokla, stderr → feedback
- JSON çıktı protokolü ile gelişmiş kontrol
Sırada ne var?
Bir sonraki derste gerçek bir hook’u baştan sona yazıp deneyeceğiz.