# Claude Code Hooks: Pre-Commit ve Post-Commit Otomasyonu
Claude Code'un gerçek güçu sadece kod yazmak değil — workflow'unu otomatiklestirmek. Hook sistemi, Claude Code'un her adimina mudahale edebilmeni, güvenlik katmanlari ekleyebilmeni ve CI/CD pipeline'inla entegre edebilmeni sagliyor. Bu yazida hook mimarisinden production-ready örneklere kadar her seyi kesfedecegiz.
Not: Bu rehber Claude Code resmi dokumantasyonu, Claude Code GitHub reposu ve gerçek proje deneyimlerine dayanmaktadir.
İçindekiler
- Hook Sistemi Nedir?
- EventType ve Yasam Dongusu
- Hook Tipleri: Command vs Prompt
- settings.json Yapilandirmasi
- PreToolUse: Arac Oncesi Mudahale
- PostToolUse: Arac Sonrasi İşlem
- Güvenlik Hook Örnekleri
- CI/CD Entegrasyonu
- Gerçek Dunya Örnekleri
- Sonuç ve Öneriler
1. Hook Sistemi Nedir?
Claude Code hook sistemi, AI agent'in yasam dongusundeki belirli noktalara mudahale edebilmeni sağlayan bir mekanizmadir. Git hook'larindan ilham almis ama çok daha güçlü:
Özellik | Git Hooks | Claude Code Hooks |
|---|---|---|
Tetikleme | git commit/push | Tool use, dosya işlem, her adım |
Tür | Shell script | Command + Prompt |
AI entegrasyon | Yok | AI ile karar verme |
Kapsam | Repo bazli | Proje + global |
Matcher | Yok | Regex pattern matching |
Neden Hook Kullanmalisin?
- Güvenlik — Tehlikeli işlemleri engellemen veya onay istemen
- Kalite — Her degisiklikten sonra lint/test çalıştırma
- Otomasyon — Tekrarlayan işlemleri otomatiklestirme
- Loglama — Tum AI işlemlerini kayit altina alma
- Egitim — AI'in belirli pattern'leri ogrenip uygulamasi
2. EventType ve Yasam Dongusu
Claude Code su event'leri destekler:
PreToolUse
Tool cagrilmadan önce tetiklenir. Tool cagirisini onaylayabilir, reddedebilir veya degistirebilirsin:
swift
1Kullanıcı istegi > AI karar > PreToolUse > [Onay/Red] > Tool çalışırPostToolUse
Tool calistiktan sonra tetiklenir. Sonuçu inceleyebilir, loglayabilir veya ek işlem tetikleyebilirsin:
swift
1Tool çalışır > PostToolUse > [Log/Aksiyon] > AI sonuçu yorumlarNotification
Claude Code bildirim gonderdiginde tetiklenir. Uzun sureli işlemlerde kullanıcıya bilgi verebilirsin.
Stop
Claude Code calismasini bitirdiginde tetiklenir. Özet oluşturma, cleanup veya rapor gönderme için idealdir.
Pro Tip: PreToolUse en kritik hook tipidir — tehlikeli işlemleri çalışmadan önce yakalayabilirsin. PostToolUse ise audit logging ve otomasyon için mukemmeldir.
3. Hook Tipleri: Command vs Prompt
Command Hook
Shell komutu calistirir. stdin'den JSON alir, stdout'a JSON yazar:
json
1{2 "type": "command",3 "command": "node ./hooks/validate-tool.js"4}Hook'a gelen JSON yapısı:
typescript
1interface HookInput {2 session_id: string;3 tool_name: string;4 tool_input: Record<string, unknown>;5}Hook'un dondurebilecegi yanitlar:
typescript
1// Onayla2{ "decision": "approve" }3 4// Reddet (açıklama ile)5{ "decision": "block", "reason": "Production branch'e push yasak!" }6 7// AI'a sor8{ "decision": "ask", "message": "Bu dosyayi silmek istediginizden emin misiniz?" }Prompt Hook
Bir AI prompt'u calistirir ve AI'in karar vermesini sağlar:
json
1{2 "type": "prompt",3 "prompt": "Bu değişiklik güvenli mi? Production veritabanini etkiler mi? approve veya block don."4}4. settings.json Yapilandirmasi
Hook'lar .claude/settings.json dosyasinda tanimlanir:
json
1{2 "hooks": {3 "PreToolUse": [4 {5 "matcher": "Bash",6 "hooks": [7 {8 "type": "command",9 "command": "node .claude/hooks/validate-bash.js"10 }11 ]12 },13 {14 "matcher": "Edit|Write",15 "hooks": [16 {17 "type": "command",18 "command": "node .claude/hooks/validate-file-edit.js"19 }20 ]21 },22 {23 "matcher": "mcp__.*__delete.*",24 "hooks": [25 {26 "type": "prompt",27 "prompt": "Silme islemi tespit edildi. Bu işlem geri alinamaz. Güvenli mi?"28 }29 ]30 }31 ],32 "PostToolUse": [33 {34 "matcher": "Edit|Write",35 "hooks": [36 {37 "type": "command",38 "command": "node .claude/hooks/post-edit-lint.js"39 }40 ]41 }42 ],43 "Stop": [44 {45 "hooks": [46 {47 "type": "command",48 "command": "node .claude/hooks/session-summary.js"49 }50 ]51 }52 ]53 }54}Matcher Pattern Örnekleri
Matcher regex destekler:
Pattern | Eslestigi Araclar | |
|---|---|---|
`Bash` | Bash komutu çalıştırma | |
`Edit\ | Write` | Dosya düzenleme ve yazma |
`mcp__.*` | Tum MCP tool'lari | |
`mcp__playwright__.*` | Sadece Playwright MCP | |
`.*delete.*` | Adi delete iceren tum tool'lar |
5. PreToolUse: Arac Oncesi Mudahale
En güçlü hook tipi. Örnek: Tehlikeli bash komutlarini engelleme:
typescript
1// .claude/hooks/validate-bash.js2import { readFileSync } from 'fs';3 4const input = JSON.parse(readFileSync('/dev/stdin', 'utf8'));5 6const DANGEROUS_PATTERNS = [7 'rm -rf /',8 'git push --force',9 'git reset --hard',10 'DROP TABLE',11 'DELETE FROM',12 'chmod 777'13];14 15const command = input.tool_input?.command || '';16 17const isDangerous = DANGEROUS_PATTERNS.some(pattern =>18 command.toLowerCase().includes(pattern.toLowerCase())19);20 21if (isDangerous) {22 const output = {23 decision: 'block',24 reason: 'Tehlikeli komut engellendi: ' + command25 };26 console.log(JSON.stringify(output));27} else if (command.includes('sudo')) {28 const output = {29 decision: 'ask',30 message: 'sudo komutu tespit edildi: ' + command31 };32 console.log(JSON.stringify(output));33} else {34 console.log(JSON.stringify({ decision: 'approve' }));35}Bu yaklaşım iOS Security Best Practices yazimizda anlattigimiz "defense in depth" prensibinin AI araclarina uygulanmis halidir.
6. PostToolUse: Arac Sonrasi İşlem
Her dosya degisikliginden sonra otomatik lint çalıştırma:
typescript
1// .claude/hooks/post-edit-lint.js2import { readFileSync } from 'fs';3import { execFileSync } from 'child_process';4 5const input = JSON.parse(readFileSync('/dev/stdin', 'utf8'));6const filePath = input.tool_input?.file_path || '';7 8if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {9 try {10 const result = execFileSync(11 'npx', ['eslint', '--fix', filePath],12 { encoding: 'utf8', timeout: 10000 }13 );14 console.log(JSON.stringify({15 decision: 'approve',16 message: 'Lint tamamlandi: ' + filePath17 }));18 } catch (error) {19 console.log(JSON.stringify({20 decision: 'approve',21 message: 'Lint uyarisi mevcut'22 }));23 }24} else {25 console.log(JSON.stringify({ decision: 'approve' }));26}CI/CD Pipeline yazimizda anlattigimiz otomatik kalite kontrol adımlarini Claude Code hook'lariyla da uygulayabilirsin.
7. Güvenlik Hook Örnekleri
Secret Detection Hook
typescript
1// .claude/hooks/secret-detection.js2import { readFileSync } from 'fs';3 4const input = JSON.parse(readFileSync('/dev/stdin', 'utf8'));5const content = input.tool_input?.new_string ||6 input.tool_input?.content || '';7 8const SECRET_PATTERNS = [9 /api[_-]?key.*[:=].*['"][A-Za-z0-9]{20,}['"]/i,10 /secret.*[:=].*['"][^'"]{8,}['"]/i,11 /-----BEGIN (?:RSA |EC )?PRIVATE KEY-----/,12 /ghp_[A-Za-z0-9]{36}/,13 /sk-[A-Za-z0-9]{48}/,14 /AKIA[A-Z0-9]{16}/15];16 17const hasSecret = SECRET_PATTERNS.some(pattern =>18 pattern.test(content)19);20 21if (hasSecret) {22 console.log(JSON.stringify({23 decision: 'block',24 reason: 'Potansiyel secret tespit edildi! .env dosyasini kullanin.'25 }));26} else {27 console.log(JSON.stringify({ decision: 'approve' }));28}Dosya Koruma Hook'u
typescript
1// .claude/hooks/protect-files.js2import { readFileSync } from 'fs';3 4const input = JSON.parse(readFileSync('/dev/stdin', 'utf8'));5const filePath = input.tool_input?.file_path || '';6 7const PROTECTED = [8 '.env', '.env.local', 'firebase-adminsdk',9 'service-account.json', 'credentials.json', 'id_rsa'10];11 12const isProtected = PROTECTED.some(pf => filePath.includes(pf));13 14if (isProtected) {15 console.log(JSON.stringify({16 decision: 'block',17 reason: 'Korunmus dosya: ' + filePath18 }));19} else {20 console.log(JSON.stringify({ decision: 'approve' }));21}Pro Tip: Secret detection hook'unu PreToolUse'da hem Edit hem Write matcher'lariyla kullan. Tek bir satir bile sizdirabilir.
8. CI/CD Entegrasyonu
GitHub Actions ile Claude Code
yaml
1# .github/workflows/claude-code.yml2name: Claude Code CI3on:4 push:5 branches: [main]6 7jobs:8 claude-review:9 runs-on: ubuntu-latest10 steps:11 - uses: actions/checkout@v412 - name: Claude Code Review13 run: |14 claude --print "Bu PR degisikliklerini review et" \15 --model claude-sonnet-4-5 \16 --output-format json > review.json17 - name: Post Review Comment18 run: node scripts/post-review.js review.jsonSession Özet Hook'u
typescript
1// .claude/hooks/session-summary.js — Stop event'inde çalışır2import { readFileSync, appendFileSync } from 'fs';3 4const input = JSON.parse(readFileSync('/dev/stdin', 'utf8'));5 6const summary = [7 '## Session: ' + new Date().toISOString(),8 '- ID: ' + input.session_id,9 '- Dosya: ' + (input.files_changed?.length || 0),10 '- Sure: ' + Math.round((input.duration_seconds || 0) / 60) + ' dk',11 ''12].join('\n');13 14appendFileSync('worklog.md', summary);15console.log(JSON.stringify({ decision: 'approve' }));Bu yaklaşım Mobile DevOps Best Practices yazimizda ele aldigimiz otomasyon prensibinin AI versiyonudur.
9. Gerçek Dunya Örnekleri
Örnek 1: Conventional Commits Zorunlulugu
typescript
1// Pre-commit hook: commit mesaji format kontrolu2const input = JSON.parse(readFileSync('/dev/stdin', 'utf8'));3const command = input.tool_input?.command || '';4 5if (command.startsWith('git commit')) {6 const messageMatch = command.match(/-m ["'](.+?)["']/);7 if (messageMatch) {8 const message = messageMatch[1];9 const pattern = /^(feat|fix|docs|style|refactor|test|chore)(\(.+))?: .{10,}/;10 11 if (!pattern.test(message)) {12 console.log(JSON.stringify({13 decision: 'block',14 reason: 'Conventional Commits formatinda olmali: type(scope): description'15 }));16 } else {17 console.log(JSON.stringify({ decision: 'approve' }));18 }19 } else {20 console.log(JSON.stringify({ decision: 'approve' }));21 }22} else {23 console.log(JSON.stringify({ decision: 'approve' }));24}Örnek 2: Dosya Boyutu Kontrolu
typescript
1// Post-edit hook: 800 satir kontrolu2const input = JSON.parse(readFileSync('/dev/stdin', 'utf8'));3const filePath = input.tool_input?.file_path || '';4 5if (filePath) {6 try {7 const content = readFileSync(filePath, 'utf8');8 const lineCount = content.split('\n').length;9 10 if (lineCount > 800) {11 console.log(JSON.stringify({12 decision: 'approve',13 message: 'UYARI: ' + filePath + ' ' + lineCount + ' satir. Dosyayi bolmeyi düşün.'14 }));15 } else {16 console.log(JSON.stringify({ decision: 'approve' }));17 }18 } catch {19 console.log(JSON.stringify({ decision: 'approve' }));20 }21} else {22 console.log(JSON.stringify({ decision: 'approve' }));23}Örnek 3: MCP Tool Loglama
json
1{2 "hooks": {3 "PreToolUse": [4 {5 "matcher": "mcp__github__.*",6 "hooks": [7 {8 "type": "command",9 "command": "echo \"GitHub tool called: $(jq -r '.tool_name')\" >&2"10 }11 ]12 }13 ]14 }15}Claude Code MCP yazimizdaki MCP tool'larini hook'larla izleyerek kapsamli bir audit log olusturabilirsin.
10. Sonuç ve Öneriler
Claude Code hook sistemi, AI destekli gelistirmeyi kontrol altinda tutmanin en etkili yoludur. Doğru yapılandırilmis hook'lar ile güvenlik, kalite ve otomasyon saglarsin. Hook'lari multi-agent team'lerle birlestirdiginde otomasyon güçunu katlayabilirsin.
Başlangıç Önerileri:
- Secret detection — İlk gun ekle, hayat kurtarir
- Dosya koruma — .env ve credential dosyalarini koru
- Post-edit lint — Otomatik kalite kontrolu
- Session summary — Her çalışma sonunda özet
- Conventional commits — Commit mesaji standartlastirma
ALTIN İPUCU
Bu yazının en değerli bilgisi
Bu ipucu, yazının en önemli çıkarımını içeriyor.
Easter Egg
Gizli bir bilgi buldun!
Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?
Okuyucu Ödülü
🎉 **Sonuna Kadar Okuyan Kahraman!** Tebrikler! Iste sana özel bir kaynak: [Claude Code Hook SDK](https://github.com/mizunashi-mana/claude-code-hook-sdk) — TypeScript ile tip-güvenliği olan hook'lar yazmak için community SDK. Zod validasyon, test helper'lar ve dependency injection dahil.

