İçeriğe geç
ceaksan

Hook'lar Neden Önemli: 4 Katmanlı Workflow Otomasyonu

Claude Code hook sistemiyle tekrarlayan işleri nasıl otomatize edersiniz? Auto-format, context enrichment, WIP persistence ve standalone agent bridge. Problem-driven yaklaşım, gerçek sonuçlar.

7 Şub 2026 5 dk okuma
TL;DR

Claude Code'un hook sistemi, AI coding agent'ınızı pasif bir executor'dan aktif bir workflow ortağına dönüştürür. 4 katmanlı yaklaşım: (1) PostToolUse ile auto-format, format hataları sıfıra iner. (2) PreToolUse ile context enrichment, her dosya okumasında ilgili knowledge base chunk'ları otomatik enjekte edilir. (3) PreCompact/SessionStart ile WIP persistence, context compaction öncesi çalışma durumu kaydedilir ve yeni session'da restore edilir. (4) Axe CLI ile standalone agent bridge, hook'lardan bağımsız LLM agent'ları tetiklenir. Her katman somut bir sorunu çözer, her çözümün arkasında akademik veya community referansı vardır.

Claude Code ile her gün çalışırken üç sorun sürekli tekrarlıyor: her düzenlemeden sonra format kontrolü, uzun session’larda context kaybı ve context compaction sonrası yarım kalan işlerin kaybolması. Bu sorunların ortak noktası, hepsinin manuel müdahale gerektirmesi. “Format şu dosyayı”, “şu context’i hatırlat”, “nerede kalmıştık” gibi komutları tekrar tekrar yazmak, otomasyon değil yeni bir iş.

Claude Code’un hook sistemi bu tekrarlayan işleri otomatize ediyor. Ama önemli olan hook’ların kendisi değil, hangi sorunu çözdükleri. Bu yazıda 4 katmanlı bir yaklaşımı, her katmanın çözdüğü sorunu ve sonuçları paylaşacağım.

Hızlı Referans
KapsamClaude Code hook sistemiyle workflow otomasyonu
YaklaşımProblem-driven: her katman bir sorunu çözer
ReferanslarMeta-RL (ICLR 2026), GrapeRoot benchmark, SashiDo boring agent, Axe CLI
İlişkili kavramlarContext Yönetimi, LLM Bozulma Modları

Hook Sistemi: 30 Saniyede

Claude Code’un event lifecycle’ı beş ana olaydan oluşur: PreToolUse (tool çağrısından önce), PostToolUse (tool çağrısından sonra), PreCompact (context compaction öncesi), SessionStart (session başlangıcı) ve Stop (session bitişi). Her olay bir hook tetikleyebilir: shell komutu, script veya HTTP çağrısı.

Hook’lar settings.json içinde tanımlanır. matcher alanı hangi tool’larda çalışacağını belirler:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [{ "type": "command", "command": "ruff format $FILEPATH" }]
      }
    ]
  }
}

23 hook event’inin tamamını kapsayan bir referans için shanraisshan’ın claude-code-hooks reposuna bakabilirsiniz. Bu yazıda referans listesi yerine, her hook’un hangi sorunu çözdüğüne odaklanacağım.

Neden Hook? CLAUDE.md Yetmiyor mu?

LLM Bozulma Modları yazısında ele aldığım instruction attenuation ve ceremonialization kavramları burada kritik.

CLAUDE.md’ye “her değişiklikten sonra test çalıştır” yazdığınızda, bu bir probabilistik kural. Model buna uyma olasılığı context uzunluğuna, session süresine ve konuya göre değişir. İlk birkaç değişiklikte çalıştırır, onuncu değişiklikte “test çalıştırdım, geçti” yazar. Belki çalıştırmıştır, belki çalıştırmamıştır. Kuralın kabuğu kaldı, içi boşaldı: ceremonialization.

Hook’lar deterministik kural. Her seferinde aynı şekilde çalışır, istisna tanımaz, ceremonialize olmaz. Probabilistik kurallarla deterministik kontrollerin birlikte çalışması gerekir. CLAUDE.md niyeti tanımlar, hook’lar uygulamayı garanti eder.

Katman 1: Auto-Format (PostToolUse)

Sorun

Claude Code bazen format bozuk kod üretir. Python’da indent tutarsızlığı, JavaScript’te eksik noktalı virgül, import sıralaması karışıklığı. Kod çalışır ama linter kızar. “Format şu dosyayı” demek tekrarlayan ve gereksiz bir iş.

Çözüm

PostToolUse hook’u Edit veya Write tool’u çalıştıktan sonra otomatik tetiklenir:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "ruff format --quiet $FILEPATH"
          },
          {
            "type": "command",
            "command": "eslint --fix --quiet $FILEPATH 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

ruff Python dosyalarında, eslint JavaScript/TypeScript dosyalarında çalışır. --quiet flag’i gereksiz çıktıyı bastırır. || true ile eslint’in JS olmayan dosyalarda hata vermesi engellenir.

Sonuç

Format hataları sıfır. PR review’larda “format düzelt” yorumu yok. Claude Code’un ürettiği her dosya proje standartlarına uygun çıkıyor.

Katman 2: Context Enrichment (PreToolUse)

Sorun

Claude Code bir dosyayı okuduğunda, o dosyanın proje içindeki bağlamını bilmez. Hangi modülle ilişkili, hangi API’yi kullanıyor, hangi convention’lara uyması gerekiyor. Her seferinde “bu dosya X modülünün parçası, Y convention’ını kullan” demek gerekiyor.

Çözüm

PreToolUse hook’u Read veya Grep tool’u çalışmadan önce tetiklenir. İlgili knowledge base chunk’larını context’e enjekte eder:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Read|Grep",
        "hooks": [
          {
            "type": "command",
            "command": "path/to/enrich-context.sh"
          }
        ]
      }
    ]
  }
}

Bu yaklaşım, GrapeRoot benchmark’ının ortaya koyduğu pre-injection stratejisiyle uyumlu. MCP tool call döngüsüne kıyasla pre-injection %31 daha ucuz ve %24 daha az turn kullanıyor1. Dosya okunmadan önce ilgili bilgiyi context’e enjekte etmek, MCP üzerinden ayrı bir tool call yapmaktan daha verimli.

Sonuç

“Bu dosya ne işe yarıyor?” sorusu ortadan kalkıyor. Claude Code her dosyayı proje bağlamıyla birlikte okuyor. Tekrarlayan context açıklamaları eliminate ediliyor.

Katman 3: WIP Persistence (PreCompact + SessionStart)

Sorun

Uzun session’larda Claude Code context compaction yapıyor: eski mesajları özetleyip token tasarrufu sağlıyor. Bu süreçte aktif çalışma durumu (hangi branch, hangi dosyalar değişti, hangi task’lar açık) kaybolabiliyor. Yeni session başladığında “nerede kalmıştık?” sorusuyla başlamak, önceki session’ın son 30 dakikasını tekrar harcamak demek.

Çözüm

İki hook birlikte çalışıyor:

PreCompact (compaction öncesi checkpoint kaydet):

#!/bin/bash
# checkpoint-wip.sh
INPUT=$(cat)
CWD=$(echo "$INPUT" | jq -r '.cwd // empty')
PROJECT_NAME=$(basename "$CWD")

BRANCH=$(cd "$CWD" && git branch --show-current 2>/dev/null)
MODIFIED=$(cd "$CWD" && git diff --name-only 2>/dev/null | head -20)
STATUS=$(cd "$CWD" && git diff --stat 2>/dev/null | tail -1)
LAST_COMMITS=$(cd "$CWD" && git log --oneline -3 2>/dev/null)

jq -n \
  --arg branch "$BRANCH" \
  --arg modified "$MODIFIED" \
  --arg status "$STATUS" \
  --arg reflection "$LAST_COMMITS" \
  --arg time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  '{branch: $branch, modified_files: ($modified | split("\n")),
    git_status: $status, reflection: $reflection, timestamp: $time}' \
  > "$HOME/.claude/state/wip-${PROJECT_NAME}.json"

SessionStart (yeni session’da restore):

#!/bin/bash
# restore-wip.sh
INPUT=$(cat)
CWD=$(echo "$INPUT" | jq -r '.cwd // empty')
PROJECT_NAME=$(basename "$CWD")
CHECKPOINT="$HOME/.claude/state/wip-${PROJECT_NAME}.json"

[ ! -f "$CHECKPOINT" ] && exit 0

# 24 saat kontrolu
FILE_AGE=$(( $(date +%s) - $(stat -f %m "$CHECKPOINT") ))
[ "$FILE_AGE" -gt 86400 ] && rm -f "$CHECKPOINT" && exit 0

BRANCH=$(jq -r '.branch' "$CHECKPOINT")
MODIFIED=$(jq -r '.modified_files | join(", ")' "$CHECKPOINT")
REFLECTION=$(jq -r '.reflection' "$CHECKPOINT")

CONTEXT="[WIP RECOVERED] Branch: $BRANCH | Degisen: $MODIFIED | Son aktivite: $REFLECTION"
jq -n --arg ctx "$CONTEXT" '{additionalContext: $ctx}'

rm -f "$CHECKPOINT"

Checkpoint’teki reflection field’ı, Meta-RL araştırmasının kritik bir bulgusunu pratiğe taşıyor. 2026’da üç bağımsız araştırma grubu (AI2, EPFL, Tsinghua) aynı sonuca ulaştı: agent’a birden fazla deneme hakkı verip her başarısızlık sonrası reflection yaptırmak, performansı önemli ölçüde artırıyor. LaMer (EPFL, ICLR 2026) özellikle ilginç bir bulgu ortaya koydu: sadece reflection text tutmak, full trajectory + reflection’dan daha iyi sonuç veriyor (%80.5 vs %74.4)2.

Bu bulgu WIP checkpoint tasarımını doğrudan etkiliyor: tüm conversation history’yi kaydetmek yerine, son 3 commit mesajını “reflection” olarak tutmak yeterli. Daha az token, daha iyi context.

SashiDo’nun “AI-Assisted Programming That Actually Ships” yaklaşımı da benzer bir felsefe: feature_list.json, progress file, init script ile her session aynı döngüyü izler3. WIP persistence hook’umuz bu yaklaşımın hafif versiyonu.

Sonuç

Context compaction sonrası kayıp sıfıra yakın. Yeni session otomatik olarak önceki durumla başlıyor. 24 saat sonra checkpoint otomatik temizleniyor.

Katman 4: Standalone Agent Bridge (Axe + Docker)

Sorun

Claude Code’un hook sistemi güçlü ama tek bir ekosisteme bağlı. Bazen farklı bir LLM’i farklı bir görev için kullanmak isteyebilirsiniz: kod review, log analizi, commit mesajı üretme. Bu görevler için ayrı bir tool’a ihtiyaç var ama hook’larla entegre çalışması gerekiyor.

Çözüm

Axe, J.R. Swab’ın geliştirdiği Go tabanlı CLI aracı. Unix felsefesiyle tasarlanmış: her agent tek bir iş yapar, stdin/stdout üzerinden compose edilebilir, cron/git hooks/pipe’larla tetiklenebilir4.

Axe’i Docker üzerinden çalıştırıp Claude Code hook’larından tetiklemek, iki ekosistemi birbirine bağlıyor:

# Axe agent config (~/.config/axe/agents/code-reviewer.toml)
name = "code-reviewer"
description = "Reviews git diffs for bugs and security issues"
model = "anthropic/claude-haiku-4-5-20251001"
system_prompt = "You are a concise code reviewer. Focus on bugs, security issues, and logic errors. Max 5 bullet points."
skill = "skills/code-review/SKILL.md"

[params]
temperature = 0.2
max_tokens = 1024

On-demand kullanım:

git diff | docker run --rm -i \
  -v ~/.config/axe:/home/axe/.config/axe:ro \
  axe run code-reviewer

Test Sonuçları

İlk test, kasıtlı olarak güvenlik açığı içeren bir diff üzerinde:

def get_user(user_id):
    conn = sqlite3.connect(os.environ["DB_PATH"])
    return conn.execute(f"SELECT * FROM users WHERE id = {user_id}").fetchone()

Axe’in code-reviewer agent’ı 3 issue tespit etti:

  • SQL injection: user_id doğrudan query’ye interpolate ediliyor
  • Resource leak: database connection kapatılmıyor
  • Missing error handling: DB_PATH env var eksikse crash

İkinci test, gerçek bir proje diff’i üzerinde (content-intelligence pipeline): 4 legitimate issue tespit edildi. JSON parsing error handling eksikliği, hash lookup validation, unbounded query, file I/O race condition.

Trade-off

Bu yaklaşım tool-agnostic ve composable. Ama her çağrıda Docker container + LLM call maliyeti var. Bu nedenle her edit sonrası otomatik çalıştırmak yerine on-demand script olarak tutuyorum. Her edit sonrası tetiklemek isteyenler için throttling (son review’dan 5 dakika geçmişse çalıştır) eklenebilir.

Axe maintainer’ı J.R. Swab ile Dev.to’da bu entegrasyonu tartıştık. Swab, OpenClaw ile Axe agent’ları skill step’lerinde tetiklemeyi çalışıyormuş. Editor hook’larından tetikleme henüz denenmemiş, bu yazı ilk documented use case.

Sonuç

İki ekosistem (Claude Code hooks + standalone Axe agents) birlikte çalışıyor. Hook’lar otomatik işleri, Axe on-demand review’ları hallediyor.

Genel Sonuçlar

SorunHookSonuç
Format hatalarıPostToolUse (ruff, eslint)Sıfır manuel format müdahalesi
Context eksikliğiPreToolUse (knowledge enrichment)Otomatik bağlam enjeksiyonu
Context compaction kaybıPreCompact + SessionStartWIP otomatik kayıt/restore
Tek ekosisteme bağımlılıkAxe + Docker bridgeTool-agnostic agent tetikleme

Tam Setup

settings.json

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          { "type": "command", "command": "ruff format --quiet $FILEPATH" },
          {
            "type": "command",
            "command": "eslint --fix --quiet $FILEPATH 2>/dev/null || true"
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Read|Grep",
        "hooks": [
          {
            "type": "command",
            "command": "path/to/enrich-context.sh"
          }
        ]
      }
    ],
    "PreCompact": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "path/to/checkpoint-wip.sh"
          }
        ]
      }
    ],
    "SessionStart": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "path/to/restore-wip.sh"
          }
        ]
      }
    ]
  }
}

Test

Her hook’u test etmek için:

  1. Auto-format: Bir Python dosyasını Edit tool ile düzenle, ruff’un otomatik çalıştığını kontrol et
  2. WIP persistence: Birkaç dosya değiştir, /compact çalıştır, yeni session başlat, checkpoint’in restore edildiğini kontrol et
  3. Axe bridge: git diff | docker run --rm -i -v ~/.config/axe:/home/axe/.config/axe:ro axe run code-reviewer

İlgili Yazılar

Footnotes

  1. GrapeRoot vs CodeGraphContext Benchmark (2026). Pre-injection: $0.17/prompt, 8.9 turn. MCP tool call: $0.27/prompt, 11.7 turn. %31 maliyet azalması, %24 daha az turn.
  2. Meta-RL with Self-Reflection: (1) Gao, Z., et al. (2026). MR-Search. arXiv. (2) Xie, T., et al. (2025). LaMer. ICLR 2026. Reflection-only %80.5 vs full history %74.4. (3) Xu, C., et al. (2026). MAGE. arXiv.
  3. SashiDo (2026). AI-Assisted Programming That Actually Ships: The Long-Running Agent Harness. Dev.to.
  4. J.R. Swab (2026). How to Stop Babysitting Your AI Agents. Dev.to.
Önemli Noktalar
  • 01 Hook'lar CLAUDE.md talimatlarının deterministik versiyonudur: probabilistik kurallar zamanla ceremonialize olur, hook'lar her seferinde aynı şekilde çalışır
  • 02 PostToolUse auto-format ile format hataları sıfıra iner, ruff ve eslint her edit sonrası otomatik çalışır
  • 03 PreCompact ile WIP persistence, Meta-RL araştırmasının 'reflection-only > full trajectory' bulgusunu pratiğe taşır
  • 04 Axe CLI stdin/stdout composability ile hook'lardan bağımsız LLM agent'ları tetiklenebilir, Docker üzerinden izole çalışır
  • 05 Hook sistemi Claude Code'u diğer CLI agent'lardan (Codex, Gemini CLI) ayıran temel özelliktir
Sık Sorulan Sorular (FAQ)
+ Claude Code hook nedir?

Claude Code'un belirli olaylarda (dosya düzenleme, tool çağrısı, context compaction, session başlangıcı) otomatik olarak çalıştırdığı shell komutları veya script'lerdir. settings.json içinde tanımlanır.

+ Hook'lar CLAUDE.md kurallarından ne farkı var?

CLAUDE.md kuralları probabilistiktir: model bunlara uyma olasılığı context'e ve session uzunluğuna göre değişir. Hook'lar deterministiktir: her seferinde aynı şekilde çalışır, istisna tanımaz.

+ WIP persistence neden gerekli?

Uzun session'larda context compaction eski bilgileri siler. PreCompact hook'u compaction öncesi çalışma durumunu kaydeder, SessionStart hook'u yeni session'da bu durumu restore eder. 24 saat sonra otomatik temizlenir.

+ Axe CLI nedir?

Go ile yazılmış, Unix felsefesine uygun, single-purpose LLM agent'ları çalıştıran bir CLI aracıdır. TOML config + SKILL.md ile tanımlanan agent'lar stdin/stdout üzerinden compose edilebilir.