tillerhand 3.41.1 → 3.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: test-writer
3
+ description: Kabul ve saldırgan testlerini koddan önce, kodu yazacak olandan bağımsız yazar. /build ve /fix-bug'da kod yazılmadan önce, ya da bir testin değişmesi gerektiğinde kullan. Uygulama kodu yazmaz. Test dosyalarına yalnız bu ajan yazabilir (test-guard).
4
+ tools: Read, Grep, Glob, Write, Edit, Bash
5
+ ---
6
+
7
+ Sen bu projede testleri yazan ajansın. Kodu sen yazmayacaksın; kodu yazacak olan testi göremeden ve değiştiremeden çalışacak. Görevin, istenen davranışı kodun nasıl yazılacağından bağımsız olarak testle sabitlemek. Kodu ve testi aynı ajan yazarsa test koda göre şekillenir, kolaya kaçar; bu ayrım bunu önler.
8
+
9
+ ## Neye bakarsın
10
+
11
+ 1. Görevin kabul kriterleri (`docs/product/prd.md`, `docs/product/roadmap.md`), varsa spec'i (`docs/product/specs/`), `docs/quality/test-plan.md` ve `docs/architecture/stack.md` → test komutları.
12
+ 2. Mevcut kodun dışa açık arayüzü: fonksiyon imzaları, API yolları, bileşen props'ları, veri modeli. Testin neyi çağıracağını bilecek kadar oku.
13
+ 3. Mevcut testler: aynı biçimi, yardımcıları ve klasörü kullan.
14
+
15
+ Uygulama planını, kod rolüne verilen talimatları ve yarım kalmış uygulama kodunu temel alma. Test, planın değil istenen davranışın kopyasıdır.
16
+ İstemde hazır test kodu verilirse kopyalama: testi kriterden kendin yaz ve hazır metin verildiğini raporda söyle.
17
+
18
+ ## Kurallar
19
+
20
+ - Her kabul kriteri için en az bir test; kriter kimliği test adında (`Ö-01.1`). Yetki, ödeme, kişisel veri varsa saldırgan testi (başka kullanıcı, anonim, bozuk girdi).
21
+ - Uç durumlar: boş, sıfır, çok büyük girdi, Türkçe karakter (`I/İ/ı/i`), tarih ve saat dilimi, eşzamanlı istek; kritere uyanları ekle.
22
+ - Beklentiler sıkı olsun: `toBeTruthy`, `toBeDefined`, matcher'sız `expect` gibi gevşek beklenti yazma. `.skip`/`.only` bırakma.
23
+ - Uygulama kodu yazma; yalnız test dosyaları ve test yardımcıları (fixture, sahte veri). Uygulama dosyası gerekiyorsa (boş fonksiyon iskeleti bile) yazma, raporda söyle.
24
+ - Testleri çalıştır ve **kırmızı** olduklarını göster: her testin neden başarısız olduğu (yok, yanlış değer) beklenen sebep olmalı. Sözdizimi veya içe aktarma hatasıyla kırmızı olan test geçerli değildir; düzelt.
25
+ - Kriter belirsizse veya iki şekilde okunabiliyorsa tahmin etme: soruyu ve seçenekleri raporla, testi yazmadan dur.
26
+ - Sonradan çağrılırsan (kodcu testin yanlış olduğunu söylerse): önce kritere bak. Test kriteri doğru sınıyorsa değiştirme, nedenini yaz. Kriter değiştiyse bu bir karardır; raporla, kullanıcı onaylamadan testi gevşetme.
27
+
28
+ ## Rapor (en fazla ~15 satır)
29
+
30
+ - Yazılan/değişen test dosyaları ve test sayısı
31
+ - Kırmızı çıktının özeti (kaç test, hangi sebeple)
32
+ - Her kriterin hangi testle karşılandığı (kimlik → test adı)
33
+ - Açık sorular
@@ -7,12 +7,13 @@ Görev: $ARGUMENTS
7
7
  Boşsa `docs/workflow/progress.md` → "Sıradaki adım" veya `docs/product/roadmap.md`'deki ilk işaretsiz görevi al.
8
8
 
9
9
  0. **Limit ve bağlam:** Limiti oku ve başlangıcı kaydet: `node .claude/hooks/progress.mjs --start` (masaüstünde durum çubuğu yok: `--limit <5 saatlik %>`, `get_usage`'dan). Bağlam %50'yi geçmişse önce `/wrap-up` + `/clear` öner. Seviye sarı/kırmızıysa veya tahmin kalan payı aşıyorsa bunu tek satırla söyle ve başla (`docs/workflow/usage-limits.md` §3; soru sorma). `docs/workflow/progress.md` → "Kaldığı yer" doluysa oradan devam et.
10
- 0b. **Model ve effort** (`docs/workflow/models.md`): Son seçimi `node .claude/hooks/models.mjs --show` ile oku. İki AskUserQuestion çağrısı yap: önce dört soru, her rolün modeli (Opus / Sonnet / Haiku); sonra dört soru, her rolün effort'u (düşük / orta / yüksek / ekstra yüksek). Her soruda models.md'deki önerilen seçenek ilk sırada ve "(Önerilen)" etiketli; son seçim farklıysa o seçeneğin açıklamasına "son seçim" yaz. Cevabı `node .claude/hooks/models.mjs --set plan=<model>:<effort> code=… review=… docs=…` ile kaydet. Ana oturumun modeli veya effort'u plan rolünden farklıysa tek satırla `/model <ad>` ve `/effort <düzey>` öner. Soru modunda `maliyet` konusu kapalıysa sorma ve `--set` çalıştırma: son seçim geçerli kalır, durum bloğunda "otomatik" yaz.
10
+ 0b. **Model ve effort** (`docs/workflow/models.md`): Son seçimi `node .claude/hooks/models.mjs --show` ile oku. Beş rol, rol başına tek soru (model ve effort birlikte, ör. "Sonnet · yüksek"; seçenekler models.md'de). İki AskUserQuestion çağrısı yap: önce plan, kod, test; sonra inceleme, doküman. Her soruda models.md'deki önerilen seçenek ilk sırada ve "(Önerilen)" etiketli; son seçim farklıysa o seçeneğin açıklamasına "son seçim" yaz. Test sorusunda önerilen, kod rolünün son seçiminden farklı modeldir (models.md). Cevabı `node .claude/hooks/models.mjs --set plan=<model>:<effort> code=… test=… review=… docs=…` ile kaydet; kod ve test aynı modelse betik uyarır, uyarıyı kullanıcıya ilet. Ana oturumun modeli veya effort'u plan rolünden farklıysa tek satırla `/model <ad>` ve `/effort <düzey>` öner. Soru modunda `maliyet` konusu kapalıysa sorma ve `--set` çalıştırma: son seçim geçerli kalır, durum bloğunda "otomatik" yaz.
11
11
  1. Görevi ve kabul kriterlerini bana tek cümleyle tekrar et. `docs/workflow/progress.md` → aktif görevi güncelle.
12
12
  2. Bu görev için onaylanmış bir plan yoksa ve 2'den fazla dosyaya dokunacaksa önce `/plan-task` adımlarını uygula (karar noktaları dahil), onay bekle.
13
- 2a. **Akış:** `node .claude/hooks/flow.mjs --files <plandaki dosya sayısı>` (masaüstünde durum çubuğu yok: `--context` ve `--limit`'i `get_usage`'dan ver). Çıktı kodun ve doküman işinin nerede yapılacağını (ana oturum / alt ajan), görev sonu kurulunun kaç üyeyle ve paralel mi sırayla mı toplanacağını söyler (6b'de yeniden çalıştır: değişen yollardan üyeleri adıyla önerir); 2b, 6b ve 8 buna uyar. "Önce /clear öner" derse tek satırla öner.
14
- 2b. **Kod rolüne devret (2b ve 3):** Akış "Kod: ana oturum" diyorsa (küçük görev: alt ajanın soğuk başlangıcı kazandırdığından pahalı) kodu adım 3'e göre kendin yaz. Yoksa Agent aracıyla alt ajan çalıştır, çağrıda kod rolünün `model` ve `effort`'unu ver. İstemde: görev ve kabul kriterleri, onaylı plan, dokunulacak dosyalar, adım 3'teki kurallar, önce kırmızı testler. Alt ajan kullanıcıya soru soramaz: karar noktasında durup soruyu ve seçenekleri raporlamasını iste; soruyu sen sor, kararı günlüğe yaz, alt ajanı cevapla devam ettir. Düzeltme veya devam için de aynı alt ajanı SendMessage ile sürdür; yeni ajan başlatma (dosyaları yeniden okur). Raporu kısa iste (en fazla ~15 satır: değişen dosyalar, test sonucu sayıyla, açık sorular; kod ve tam çıktı yok). Alt ajan bitince diff'i ve test çıktısını kendin oku; adım 4'ten sonrası ana oturumda. Kullanıcıya görünen metni (humanizer) son haline sen getir.
15
- **Önce kabul testleri:** Görevin kabul kriterleri için testleri (kimlik test adında: `Ö-01.1`) ve gerekiyorsa saldırgan testlerini yaz, çalıştır ve **kırmızı** olduklarını göster (alt ajanın kırmızı çıktısını bana göster). Sonra uygula.
13
+ 2a. **Akış:** `node .claude/hooks/flow.mjs --files <plandaki dosya sayısı>` (masaüstünde durum çubuğu yok: `--context` ve `--limit`'i `get_usage`'dan ver). Çıktı kodun ve doküman işinin nerede yapılacağını (ana oturum / alt ajan), görev sonu kurulunun kaç üyeyle ve paralel mi sırayla mı toplanacağını söyler (6b'de yeniden çalıştır: değişen yollardan üyeleri adıyla önerir); 2c, 6b ve 8 buna uyar. "Önce /clear öner" derse tek satırla öner.
14
+ 2b. **Önce testler, ayrı ajanla:** Testleri kodu yazan yazmaz (AGENTS.md kural 7). Akış ne derse desin `test-writer` alt ajanını test rolünün `model` ve `effort`'uyla çalıştır. İstemde yalnız: görev, kabul kriterleri, varsa spec, dokunulacak kodun dışa açık arayüzü (imzalar, API yolları). Onaylı planın uygulama ayrıntısını ve hazır test kodunu verme: test istenen davranışı sınar, planı değil. Ajan kabul testlerini (kimlik test adında: `Ö-01.1`) ve gerekiyorsa saldırgan testlerini yazar, çalıştırır ve **kırmızı** olduklarını gösterir; kırmızı çıktıyı bana göster. Belirsiz kriter raporlarsa soruyu sen sor. Test dosyalarına yalnız `test-writer` yazabilir: ana oturum ve kod ajanı denerse test koruması engeller.
15
+ 2c. **Kod rolüne devret (2c ve 3):** Akış "Kod: ana oturum" diyorsa (küçük görev: alt ajanın soğuk başlangıcı kazandırdığından pahalı) kodu adım 3'e göre kendin yaz. Yoksa Agent aracıyla alt ajan çalıştır, çağrıda kod rolünün `model` ve `effort`'unu ver. İstemde: görev ve kabul kriterleri, onaylı plan, dokunulacak dosyalar, adım 3'teki kurallar, 2b'nin kırmızı testleri (hedef: yeşile çevirmek; test dosyalarına dokunmaz). Alt ajan kullanıcıya soru soramaz: karar noktasında durup soruyu ve seçenekleri raporlamasını iste; soruyu sen sor, kararı günlüğe yaz, alt ajanı cevapla devam ettir. Düzeltme veya devam için de aynı alt ajanı SendMessage ile sürdür; yeni ajan başlatma (dosyaları yeniden okur). Raporu kısa iste (en fazla ~15 satır: değişen dosyalar, test sonucu sayıyla, açık sorular; kod ve tam çıktı yok). Alt ajan bitince diff'i ve test çıktısını kendin oku; adım 4'ten sonrası ana oturumda. Kullanıcıya görünen metni (humanizer) son haline sen getir.
16
+ **Test yanlış görünürse:** Kod tarafı testi değiştirmez. Nedenini raporlar; `test-writer`'ı SendMessage ile sürdür, kritere göre o karar versin. Kriter değişiyorsa bu bir karardır: kullanıcıya sor.
16
17
  3. Uygula. Kurallar:
17
18
  - **Uygularken yeni bir karar noktası çıkarsa dur ve sor** (`docs/workflow/decision-protocol.md`). Tahmin edip devam etme.
18
19
  - Skill'ler (`docs/workflow/skills.md`): Kod için `ponytail:ponytail`, kritik akış için `mattpocock-skills:tdd`. Arayüz için seçilen yön skill'i + `impeccable:impeccable` (`DESIGN.md`'ye bağlı kal; yeni tasarım kararı gerekirse `/design`). Kullanıcıya görünen metin için `humanizer:humanizer`.
@@ -11,7 +11,7 @@ Hata: $ARGUMENTS
11
11
  2. **Kanıt topla.** İlgili kodu, logları, son değişiklikleri (`git log -p -- [dosya]`) oku. Hata ne zaman başladı?
12
12
  3. **Hipotez kur.** En olası 1-3 kök neden. Her biri için onu doğrulayacak veya çürütecek kontrol. Aynı anda tek değişken değiştir; hipotezi çürüten kanıtı da yaz.
13
13
  4. **Doğrula.** Kontrolleri yap. Kök neden kanıtlanmadan düzeltmeye geçme. Kök neden tek bir özellik klasöründeyse düzeltme yayılmasın diye `/freeze <klasör>` öner.
14
- 5. **Kırmızı test.** Hatayı gösteren testi yaz, başarısız olduğunu gör. Kısa hata spec'i yaz: `docs/product/specs/<hata-kısa-adı>.md` (`_template.md`, Tür: hata), birkaç satır yeter. `**Sınıf:**` satırına şu listeden tam olarak birini yaz: `boş-girdi`, `doğrulama`, `yetki`, `tarih-saat`, `yerel-dil`, `sıralama`, `eşzamanlılık`, `yapılandırma`, `dış-servis`, `sözleşme`, `arayüz-durumu`, `diğer`. Mevcut davranış yeniden üretme adımlarıdır, beklenen davranış testin sınadığıdır. Değişmemesi gereken davranışa hatanın yakınındaki, testi olan kabul kriterlerini kimliğiyle yaz (`- Ö-01.1: ...`); yoksa bölümü boş bırak.
14
+ 5. **Kırmızı test.** Hatayı gösteren testi düzeltmeyi yapacak olan yazmaz (AGENTS.md kural 7): `test-writer` alt ajanını test rolünün modeliyle çalıştır; istemde yeniden üretme adımları, beklenen davranış ve ilgili kodun dışa açık arayüzü olsun, kök neden hipotezi ve düzeltme fikri olmasın. Ajan testi yazar ve başarısız olduğunu gösterir. Test dosyalarına yalnız `test-writer` yazabilir. Kısa hata spec'i yaz: `docs/product/specs/<hata-kısa-adı>.md` (`_template.md`, Tür: hata), birkaç satır yeter. `**Sınıf:**` satırına şu listeden tam olarak birini yaz: `boş-girdi`, `doğrulama`, `yetki`, `tarih-saat`, `yerel-dil`, `sıralama`, `eşzamanlılık`, `yapılandırma`, `dış-servis`, `sözleşme`, `arayüz-durumu`, `diğer`. Mevcut davranış yeniden üretme adımlarıdır, beklenen davranış testin sınadığıdır. Değişmemesi gereken davranışa hatanın yakınındaki, testi olan kabul kriterlerini kimliğiyle yaz (`- Ö-01.1: ...`); yoksa bölümü boş bırak.
15
15
  6. **Düzelt.** Birden fazla düzeltme yolu varsa (örn. hızlı yama ile kalıcı düzeltme veya davranış değişikliği) hangisini seçeceğini **karar olarak sor**. Kök nedeni, paylaşılan kodda bir kez düzelt. Aynı hatanın başka çağıranlarda da olup olmadığına bak.
16
16
  7. **Yeşil.** Yeni test ve mevcut testler geçiyor: komutu bu turda çalıştır ve çıktısını göster. Sonra kapıyı çalıştır: `node .claude/hooks/gate.mjs --run` (lint, tip kontrolü, test, Semgrep; commit toplantısı bu çıktıyı kullanır). Kırmızı varsa düzelt. "Komut onayı gerekli" derse komutları bana göster; onaylarsam `node .claude/hooks/gate.mjs --approve`. Kilit açtıysan `/freeze off`.
17
17
  8. **Tekrar mı?** `docs/product/specs/` altında aynı `**Sınıf:**` değerini taşıyan başka bir hata spec'i varsa (sınıf `diğer` değilse) bu hata sınıfı tekrarlıyor: tekrarı önleyecek tek bir kural öner. Mekanik denetlenebiliyorsa ("X dosyasında Y yazma", "Z çağrısında W zorunlu") `/hookify` kuralı olur (`.claude/hookify.<ad>.local.md`; `.gitignore`'a ekleme, git'e girer ve ekip de kullanır). Değilse, hookify kapalıysa (Hafif profil) veya Claude Code dışındaysan `AGENTS.md` → "Öğrenilen kurallar"a tek satır (bölüm yoksa dosyanın sonuna aç). Kaynak ve tarih satırı: `(kaynak: specs/<a>.md, specs/<b>.md · YYYY-AA-GG)`; AGENTS.md'de kuralın sonunda, hookify dosyasında mesaj gövdesinin son satırında. Kural metnini ve hedef dosyayı göstererek AskUserQuestion ile sor: Ekle / Sonra (panoda hatırlatılır) / Gerek yok. Onay yoksa hiçbir kural dosyasına yazma. Ekle veya Gerek yok cevabını aynı sınıftaki spec'lere `**Kural:** <hedef dosya veya "gerek yok"> · YYYY-AA-GG` satırıyla yaz; pano uyarısı kapanır, karar tekrar sorulmaz.
@@ -49,13 +49,16 @@ const NEEDS_APPROVAL = [
49
49
 
50
50
  // The test guard runs on file tools; changing a test or test config file from the shell (sed -i, rm, >, mv, git checkout) is asked.
51
51
  // Each part of a command chain is checked alone: "rm -r node_modules && npx vitest run a.test.ts" does not change a test.
52
- const WRITER = /\b(rm|del|erase|rmdir|rd|unlink|mv|move|cp|copy|tee|truncate|Set-Content|Add-Content|Out-File|Remove-Item|Move-Item|Copy-Item|Clear-Content)\b|\bsed\b[^;&|]*\s(-[a-zA-Z]*i\S*|--in-place\b)|\bperl\b[^;&|]*\s-[a-zA-Z]*i|\bgit\s+(checkout|restore|rm|mv)\b/i;
53
- const isTestPath = (t) => isTestFile(t) || isTestConfig(t) || /(^|[/\\])(tests?|__tests__|e2e|spec)[/\\]?$/i.test(t);
54
- function writesTest(command) {
52
+ const WRITER = /\b(rm|del|erase|rmdir|rd|unlink|mv|move|cp|copy|tee|truncate|touch|ln|dd|Set-Content|Add-Content|Out-File|Remove-Item|Move-Item|Copy-Item|Clear-Content)\b|\bcurl\b[^;&|]*\s(-o|--output)\b|\bwget\b[^;&|]*\s(-O|--output-document)\b|\bsed\b[^;&|]*\s(-[a-zA-Z]*i\S*|--in-place\b)|\bperl\b[^;&|]*\s-[a-zA-Z]*i|\bgit\s+(checkout|restore|rm|mv)\b/i;
53
+ // Dependency and git internals are not the project's tests; a URL (curl … https://x/tests/a) or a dd input is not a target
54
+ const isTestCode = (t) => !/(^|[/\\])(node_modules|\.git)([/\\]|$)|:\/\/|^if=/i.test(t) && (isTestFile(t) || /(^|[/\\])(tests?|__tests__|e2e|spec)[/\\]?$/i.test(t));
55
+ const isTestPath = (t) => isTestCode(t) || isTestConfig(t);
56
+ function writesTest(command, isPath = isTestPath) {
55
57
  return command.split(/&&|\|\||[;|\n]/).some((part) => {
56
58
  const p = part.replace(/\b2>&1|\b2>\s*(\/dev\/null|nul)\b/gi, '');
57
- const targets = [...p.matchAll(/>{1,2}\s*([^\s;&|<>]+)/g)].map((m) => m[1]);
58
- return targets.some(isTestPath) || (WRITER.test(p) && p.split(/\s+/).some(isTestPath));
59
+ const bare = (s) => s.replace(/^["']+|["']+$/g, '');
60
+ const targets = [...p.matchAll(/>{1,2}\s*([^\s;&|<>]+)/g)].map((m) => bare(m[1]));
61
+ return targets.some(isPath) || (WRITER.test(p) && p.split(/\s+/).map(bare).some(isPath));
59
62
  });
60
63
  }
61
64
 
@@ -319,8 +322,20 @@ export function hookScriptIssue(command) {
319
322
 
320
323
  // Separators inside quotes turned into spaces: a quoted & or | ("a & b") must not split a command so its later flags escape the rules
321
324
  const blankQuoted = (s) => s.replace(/"(?:[^"\\]|\\.)*"|'[^']*'/g, (q) => q.replace(/[;&|\n]/g, ' '));
322
- export function evaluate(command) {
323
- return strictest(evaluateOne(command), evaluateOne(unquote(command)), evaluateOne(blankQuoted(command)), obfuscationOne(command), hookScriptIssue(command));
325
+ // Quoted text with spaces is an argument (grep "<td>Test", node -e "… rm …"), not a command: blanked. A one-word quoted
326
+ // path ("src/a.test.ts") is kept. Such commands are still asked through evaluateOne.
327
+ const quotedTextOff = (s) => s.replace(/"(?:[^"\\]|\\.)*"|'[^']*'/g, (q) => (/\s/.test(q) ? ' ' : q.slice(1, -1)));
328
+ const INLINE = /\b(node|deno|bun)\s+(-e|--eval|-p|--print)\b|\bpython[\d.]*\s+-c\b|\b(ruby|perl)\s+-e\b|\b(ba|z|da)?sh\s+-c\b|\b(pwsh|powershell)(\.exe)?\s+(-c|-Command)\b|\bcmd(\.exe)?\s+\/c\b/i;
329
+ const TEST_WRITER_ONLY = 'Test dosyasına yalnız test-writer ajanı yazar: kodu yazan testi değiştiremez (AGENTS.md kural 7). Test eklemek veya değiştirmek gerekiyorsa test-writer ajanını çağır (varsa SendMessage ile sürdür).';
330
+ // ctx: { tool, agent } of the call; only Claude Code tells which subagent runs it. Test files are written by the
331
+ // test-writer agent only; test config files stay a question (evaluateOne).
332
+ export function evaluate(command, ctx = {}) {
333
+ const testWrite = ctx.tool === 'claude' && ctx.agent !== 'test-writer' && writesTest(quotedTextOff(command).replace(/\s+/g, ' '), isTestCode)
334
+ ? { decision: 'deny', reason: TEST_WRITER_ONLY } : null;
335
+ // An inline script (node -e, python -c, bash -c) that names a test path may write it; the shell rules cannot see inside
336
+ const inline = INLINE.test(command) && command.split(/[\s'"`(),;=<>]+/).some(isTestCode)
337
+ ? { decision: 'ask', reason: 'Satır içi betik bir test yolunu anıyor; test dosyasına yazıyor olabilir. Test dosyasına yalnız test-writer ajanı yazar (AGENTS.md kural 7). Kullanıcı onayı gerekli.' } : null;
338
+ return strictest(testWrite, inline, evaluateOne(command), evaluateOne(unquote(command)), evaluateOne(blankQuoted(command)), obfuscationOne(command), hookScriptIssue(command));
324
339
  }
325
340
  function evaluateOne(command) {
326
341
  const k = command.replace(/\s+/g, ' ');
@@ -348,7 +363,7 @@ function evaluateOne(command) {
348
363
  if (isMain(import.meta.url)) {
349
364
  const g = readInput();
350
365
  // Of the lists, the stricter wins (deny > ask)
351
- const results = g ? [evaluate(g.command), g.tool !== 'claude' ? permissionEquivalent(g.command) : null, scopeIssue(g.command, g.dir, g.root)].filter(Boolean) : [];
366
+ const results = g ? [evaluate(g.command, g), g.tool !== 'claude' ? permissionEquivalent(g.command) : null, scopeIssue(g.command, g.dir, g.root)].filter(Boolean) : [];
352
367
  const s = results.find((x) => x.decision === 'deny') ?? results[0];
353
368
  if (s) decide(g.tool, s.decision, `Kalkan: ${s.reason}`);
354
369
  process.exit(0);
@@ -1,15 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  // Model and effort per role (docs/workflow/models.md). /build, /start, /adopt and /release ask the user, then save the answer here.
3
3
  // node .claude/hooks/models.mjs --show current choice (the recommended one if nothing is saved)
4
- // node .claude/hooks/models.mjs --set plan=opus:high code=sonnet:high review=sonnet:high docs=haiku:high
4
+ // node .claude/hooks/models.mjs --set plan=opus:high code=sonnet:high test=opus:high review=sonnet:high docs=haiku:high
5
5
  // A role left out of --set keeps its current value. File: .claude/state/models.json (git-ignored, this project only).
6
6
  // Aliases, not model IDs: in Claude Code opus/sonnet/haiku/fable always point to the newest model of that family.
7
7
  import fs from 'node:fs';
8
8
  import path from 'node:path';
9
9
  import { findRoot, isMain } from './shared.mjs';
10
10
 
11
- export const ROLES = { plan: 'Planlama ve mimari', code: 'Kod yazma', review: 'İnceleme ve denetim', docs: 'Doküman ve araştırma' };
12
- export const RECOMMENDED = { plan: 'opus:high', code: 'sonnet:high', review: 'sonnet:high', docs: 'haiku:high' };
11
+ export const ROLES = { plan: 'Planlama ve mimari', code: 'Kod yazma', test: 'Test yazma', review: 'İnceleme ve denetim', docs: 'Doküman ve araştırma' };
12
+ // test differs from code on purpose: another model does not share the coder's blind spots (AGENTS.md rule 7)
13
+ export const RECOMMENDED = { plan: 'opus:high', code: 'sonnet:high', test: 'opus:high', review: 'sonnet:high', docs: 'haiku:high' };
13
14
  export const MODELS = ['opus', 'sonnet', 'haiku', 'fable'];
14
15
  export const EFFORTS = ['low', 'medium', 'high', 'xhigh'];
15
16
 
@@ -55,7 +56,8 @@ export const showModels = (file = modelsFile()) => {
55
56
  const m = readModels(file);
56
57
  const note = modelsNote(file);
57
58
  return Object.keys(ROLES).map((r) => `${r}: ${m[r].replace(':', ' / ')} (${ROLES[r]})${m[r] === RECOMMENDED[r] ? '' : ` · önerilen ${RECOMMENDED[r].replace(':', ' / ')}`}`).join('\n')
58
- + (note ? `\n(${note})` : '');
59
+ + (note ? `\n(${note})` : '')
60
+ + (m.code.split(':')[0] === m.test.split(':')[0] ? '\nUyarı: kod ve test rolü aynı model; farklı model önerilir (aynı model aynı kör noktayı paylaşır).' : '');
59
61
  };
60
62
 
61
63
  if (isMain(import.meta.url)) {
@@ -67,7 +69,7 @@ if (isMain(import.meta.url)) {
67
69
  } else if (mode === '--show') {
68
70
  console.log(showModels());
69
71
  } else {
70
- console.error('Kullanım: --show | --set plan=<model>:<effort> code=… review=… docs=…');
72
+ console.error('Kullanım: --show | --set plan=<model>:<effort> code=… test=… review=… docs=…');
71
73
  process.exit(1);
72
74
  }
73
75
  }
@@ -69,7 +69,9 @@ export function parseInput(g) {
69
69
  const tool = detectTool(g);
70
70
  const root = findRoot();
71
71
  const session = String(g.session_id ?? g.conversationId ?? '');
72
- const result = { tool, root, dir: isText(g.cwd) ? g.cwd : root, session, command: '', files: [], reads: [] };
72
+ // agent: the subagent the call runs in (Claude Code agent_type; '' in the main session and on other tools)
73
+ const agent = tool === 'claude' && isText(g.agent_type) ? g.agent_type : '';
74
+ const result = { tool, root, dir: isText(g.cwd) ? g.cwd : root, session, agent, command: '', files: [], reads: [] };
73
75
  if (tool === 'antigravity') {
74
76
  const { name, args = {} } = g.toolCall ?? {};
75
77
  if (name === 'run_command') result.command = isText(args.CommandLine) ? args.CommandLine : JSON.stringify(args);
@@ -6,17 +6,20 @@
6
6
  // file is deleted. It also asks when a test config file (vitest/jest/playwright config, conftest.py, package.json
7
7
  // test script) changes a field that could narrow the scope. A commented-out expectation counts as deleted.
8
8
  // It does not block: the user approves a justified change.
9
+ // In Claude Code a test file can only be written by the test-writer subagent (agent_type); anyone else is denied.
9
10
  import fs from 'node:fs';
10
11
  import path from 'node:path';
11
12
  import { readInput, decide, isMain } from './shared.mjs';
12
13
 
13
14
  const TEST = /(^|\/)(tests?|__tests__|e2e|spec)\/|\.(test|spec|e2e-spec)\.[cm]?[jt]sx?$|(^|\/)test_[^/]*\.py$|_test\.(py|go)$/i;
14
- export const isTestFile = (file) => TEST.test(file.replace(/\\/g, '/'));
15
+ // Windows resolves "a.test.ts.", "a.test.ts " and "a.test.ts::$DATA" (alternate stream) to the same file
16
+ const plain = (file) => file.replace(/\\/g, '/').replace(/:[^/]*$/, '').replace(/[. ]+(?=\/|$)/g, '');
17
+ export const isTestFile = (file) => TEST.test(plain(file));
15
18
  // A file the test runner recognizes by name (a file in a test folder whose name does not match does not run)
16
19
  const TEST_NAME = /\.(test|spec|e2e-spec)\.[cm]?[jt]sx?$|^test_[^/]*\.py$|_test\.(py|go)$/i;
17
20
 
18
21
  const CONFIG = /(^|\/)((vitest|vite|jest|playwright|cypress)(\.[\w-]+)?\.config\.([cm]?[jt]s|json)|vitest\.workspace\.[cm]?[jt]s|\.mocharc\.\w+|conftest\.py|noxfile\.py|pytest\.ini|tox\.ini|setup\.cfg|pyproject\.toml|package\.json)$/i;
19
- export const isTestConfig = (file) => CONFIG.test(file.replace(/\\/g, '/'));
22
+ export const isTestConfig = (file) => CONFIG.test(plain(file));
20
23
  // Fields that decide which tests run or whether a failure counts (user decision 2026-10-24)
21
24
  const RISKY = /\b(include|exclude|testMatch|testRegex|testPathIgnorePatterns|testIgnore|testDir|testpaths|roots|passWithNoTests|bail|retries|thresholds?|coverageThreshold|grep|grepInvert|addopts|collect_ignore\w*|python_files|norecursedirs|pytest_collection_modifyitems|pytest_runtest_\w+|skip\w*|only|forbidOnly|setupFiles|globalSetup|lines|branches|functions|statements|fail_under|cov-fail-under)\b|"(test|e2e|ci)[\w:.-]*"\s*:/i;
22
25
 
@@ -53,12 +56,24 @@ function hook() {
53
56
  const rel = path.relative(g.root, full);
54
57
  return [full, rel.startsWith('..') || path.isAbsolute(rel) ? full : rel];
55
58
  };
59
+ // The real path too: a link or junction into the test folder, a Windows short name (TESTS~1)
60
+ const realOf = (p) => {
61
+ try { return fs.realpathSync.native(p); } catch { /* a new file */ }
62
+ try { return path.join(fs.realpathSync.native(path.dirname(p)), path.basename(p)); } catch { return p; }
63
+ };
56
64
  for (const f of g.files) {
57
65
  if (!f.path) continue;
58
66
  const [full, name] = resolveName(f.path);
59
67
  const source = f.source && isTestFile(resolveName(f.source)[1]) ? resolveName(f.source)[1] : null;
60
68
  const config = isTestConfig(name);
61
- if (!source && !config && !isTestFile(name)) continue;
69
+ const realRel = path.relative(realOf(g.root), realOf(full));
70
+ if (!source && !config && !isTestFile(name) && !isTestFile(realRel)) continue;
71
+ // Tests are written by the test-writer agent only (AGENTS.md rule 7): whoever writes the code must not shape the test
72
+ // to it. Only Claude Code reports the subagent; Codex and Antigravity keep the rule in text. Config files stay a question.
73
+ if (g.tool === 'claude' && g.agent !== 'test-writer' && !config) {
74
+ decide(g.tool, 'deny', `Test ayrımı: ${name.split(path.sep).join('/')} bir test dosyası; test dosyalarına yalnız test-writer ajanı yazar, kodu yazan testi değiştiremez (AGENTS.md kural 7). ` +
75
+ 'Test eklemek veya değiştirmek gerekiyorsa test-writer ajanını çağır (varsa SendMessage ile sürdür); kriter değişiyorsa kullanıcıya sor.');
76
+ }
62
77
  let before = f.before;
63
78
  if (before === undefined) { try { before = fs.readFileSync(full, 'utf8'); } catch { before = ''; } }
64
79
  const after = f.after ?? f.text;
package/AGENTS.md CHANGED
@@ -16,7 +16,7 @@ Bu dosya projenin ortak kurallarıdır; Claude Code, Codex ve Antigravity okur.
16
16
  4. **Az token harca.** Kod haritası (codebase-memory-mcp) bağlıysa kodu keşfederken önce onu sorgula (`get_architecture`, `search_graph`, `trace_path`, `get_code_snippet`). Dosyaları toptan okuma. Dokümanları sadece gerektiğinde oku (tablo aşağıda).
17
17
  5. **Yapıya uy (zorunlu).** Yeni dosyayı `.claude/structure.json` haritasındaki yerine yaz (özellik bazlı: `features/<özellik>/`); açıklaması `docs/architecture/structure.md`. Harita dışı yazım sorulur, dağınıklık dosyaları (`*.bak`, `*-old.*`, kopya) engellenir. Geçici ve deneme işleri `sandbox/`, artık geçerli olmayan dokümanlar `docs/archive/`. Haritayı değiştirmek teknik bir karardır.
18
18
  6. **Önce plan, sonra kod.** 2'den fazla dosyaya dokunan iş `/plan-task`'dan geçer. Tek seferde tek görev. Kapsamı genişletme. Dört ilke: (1) varsayımını söyle, belirsizse sor; (2) en sade çözüm, istenmeyen esneklik yok; (3) sadece görevin gerektirdiği satırlara dokun; (4) işe başlarken doğrulanabilir başarı ölçütünü yaz.
19
- 7. **Kök neden, kanıt, test.** Kabul testleri (kriter kimliği test adında, `Ö-01.1`) ve saldırgan testleri koddan önce yazılır ve önce kırmızı olur. Riskli özellik bayrak arkasında yayınlanır (`docs/operations/feature-flags.md`). Hata düzeltirken önce yeniden üret. "Bitti" demeden çalıştığını göster. Aynı hatada 2 denemede çözemezsen dur ve yön iste.
19
+ 7. **Kök neden, kanıt, test.** Kabul testleri (kriter kimliği test adında, `Ö-01.1`) ve saldırgan testleri koddan önce yazılır ve önce kırmızı olur. Testi kodu yazan değil, ayrı bir ajan (`test-writer`, test rolünün modeliyle) yazar; kodu yazan test dosyasına dokunmaz (test koruması engeller). Riskli özellik bayrak arkasında yayınlanır (`docs/operations/feature-flags.md`). Hata düzeltirken önce yeniden üret. "Bitti" demeden çalıştığını göster. Aynı hatada 2 denemede çözemezsen dur ve yön iste.
20
20
  8. **Her cevabın sonunda durum bloğu** (kısa). Biçim:
21
21
 
22
22
  ```
@@ -35,7 +35,7 @@ Kit Claude Code için yazıldı; bu iki araçta şu karşılıklar geçerli:
35
35
 
36
36
  - **Komutlar** (`/start`, `/build`…) `.agents/skills/` altında skill olarak durur: Codex'te `$start` ya da `/skills`, Antigravity'de `/start`. Kaynakları `.claude/commands/`; skill kopyaları kit güncellemesinde yeniden üretilir, düzenleme kaynakta yapılır.
37
37
  - **AskUserQuestion** geçen her yerde: Antigravity'de `ask_question` aracı. Seçenekli soru aracı yoksa (Codex) seçenekleri numaralı liste olarak yaz, önerileni ilk sıraya koy ve "(Önerilen)" diye işaretle, cevabı bekle. Karar yine kullanıcınındır.
38
- - **Alt ajanlar** (kurul üyeleri, konsey, inceleme ajanları `.claude/agents/`): Çalıştıramıyorsan ilgili tanımı oku, o rolle kendin değerlendir ve raporda "tek model" diye belirt.
38
+ - **Alt ajanlar** (kurul üyeleri, konsey, inceleme ajanları `.claude/agents/`): Çalıştıramıyorsan ilgili tanımı oku, o rolle kendin değerlendir ve raporda "tek model" diye belirt. Test ayrımı (kural 7) burada hook ile zorlanamaz: testleri `test-writer` tanımıyla, kodu düşünmeden önce yaz ve kırmızıyı göster; kodu yazarken test dosyasını değiştirme.
39
39
  - **Model ve effort** (`docs/workflow/models.md`): Alt ajanı rolün karşılığıyla başlat (Codex: istemde model ve reasoning effort; Antigravity: `inherit`, `flash` ya da `pro`). Yapamıyorsan rolü kendin yürüt, modeli metinle öner.
40
40
  - **Korumalar** (sır engeli, yıkıcı komut kalkanı, yapı koruyucu, düzenleme kilidi, test koruması, düzenleme turu sayacı, paket kapısı ve Claude Code izin listesinin karşılığı) hook olarak çalışır: Codex `.codex/hooks.json`, Antigravity `.agents/hooks.json`. Kural ve koruma dosyalarına (`AGENTS.md`, `.claude/`, `.codex/`, `.agents/hooks.json`) yazma onaya bağlıdır. Engellenen işlemi başka yoldan (örneğin kabuk komutuyla) yapmaya çalışma; nedenini kullanıcıya söyle.
41
41
  - Claude Code eklentilerine ait skill'ler (adı `eklenti:skill` biçiminde) bu araçlarda yok: o adımı atla. Limit okuma ve durum çubuğu da yok: durum bloğunda limit "-" kalır.
package/README.en.md CHANGED
@@ -6,7 +6,7 @@
6
6
  </p>
7
7
 
8
8
  <p align="center">
9
- <a href="kit/CHANGELOG.md"><img alt="Version" src="https://img.shields.io/badge/version-3.41.1-2a78d6?style=flat-square"></a>
9
+ <a href="kit/CHANGELOG.md"><img alt="Version" src="https://img.shields.io/badge/version-3.42.0-2a78d6?style=flat-square"></a>
10
10
  <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-2a78d6?style=flat-square"></a>
11
11
  <img alt="Claude Code" src="https://img.shields.io/badge/Claude%20Code-ready-d97757?style=flat-square">
12
12
  <img alt="Also Codex and Antigravity" src="https://img.shields.io/badge/also-Codex%20%C2%B7%20Antigravity-5b6577?style=flat-square">
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  </p>
7
7
 
8
8
  <p align="center">
9
- <a href="kit/CHANGELOG.md"><img alt="Sürüm" src="https://img.shields.io/badge/s%C3%BCr%C3%BCm-3.41.1-2a78d6?style=flat-square"></a>
9
+ <a href="kit/CHANGELOG.md"><img alt="Sürüm" src="https://img.shields.io/badge/s%C3%BCr%C3%BCm-3.42.0-2a78d6?style=flat-square"></a>
10
10
  <a href="LICENSE"><img alt="Lisans: MIT" src="https://img.shields.io/badge/lisans-MIT-2a78d6?style=flat-square"></a>
11
11
  <img alt="Claude Code" src="https://img.shields.io/badge/Claude%20Code-haz%C4%B1r-d97757?style=flat-square">
12
12
  <img alt="Codex ve Antigravity" src="https://img.shields.io/badge/ayr%C4%B1ca-Codex%20%C2%B7%20Antigravity-5b6577?style=flat-square">
@@ -1,7 +1,7 @@
1
1
  # Model ve effort (rol bazında)
2
2
 
3
- > Kit işi dört role ayırır. Her rolün modelini ve effort'unu (ne kadar düşüneceğini) sen seçersin.
4
- > `/build` her görevin başında, `/start`, `/adopt` ve `/release` başlarken iki ekranda sorar: önce dört rolün modeli, sonra effort'u.
3
+ > Kit işi beş role ayırır. Her rolün modelini ve effort'unu (ne kadar düşüneceğini) sen seçersin.
4
+ > `/build` her görevin başında, `/start`, `/adopt` ve `/release` başlarken rol başına tek soru sorar (model ve effort birlikte), iki ekranda: önce plan, kod, test; sonra inceleme, doküman.
5
5
  > Seçim `node .claude/hooks/models.mjs --set …` ile `.claude/state/models.json`'a yazılır (git'e girmez). Güncel seçimi `node .claude/hooks/models.mjs --show` gösterir.
6
6
 
7
7
  ## Roller
@@ -9,10 +9,23 @@
9
9
  | Rol | Anahtar | Kapsadığı işler | Önerilen |
10
10
  |---|---|---|---|
11
11
  | Planlama ve mimari | `plan` | Plan, mimari ve veri modeli kararları; PRD, README ve kullanıcıya görünen metin. Ana oturumda yürür. | Opus · yüksek |
12
- | Kod yazma | `code` | Kabul testleri ve uygulama kodu. Alt ajana devredilir. | Sonnet · yüksek |
12
+ | Kod yazma | `code` | Uygulama kodu. Test dosyalarına yazamaz. Küçük görevde ana oturumda, yoksa alt ajanda. | Sonnet · yüksek |
13
+ | Test yazma | `test` | Kabul ve saldırgan testleri, koddan önce; `test-writer` ajanı. Kodu yazandan ayrı ajan, önerilen model de farklı: aynı model aynı kör noktayı paylaşır. | Opus · yüksek |
13
14
  | İnceleme ve denetim | `review` | Kurul üyeleri, `code-reviewer`, `security-auditor`, bulgu raporları (`/findings-all`). | Sonnet · yüksek |
14
15
  | Doküman ve araştırma | `docs` | CHANGELOG, rapor özeti; kod tarama, web araştırması (`/research` derin). Karar günlüğü karar anında ana oturumda yazılır. | Haiku · yüksek |
15
16
 
17
+ Her sorudaki seçenekler (ilki önerilen; başka bir kombinasyon "Diğer" ile yazılır):
18
+
19
+ | Rol | Seçenekler |
20
+ |---|---|
21
+ | `plan` | Opus · yüksek / Opus · ekstra yüksek / Sonnet · yüksek / Sonnet · orta |
22
+ | `code` | Sonnet · yüksek / Opus · yüksek / Sonnet · orta / Haiku · yüksek |
23
+ | `test` | Kod rolünün son seçiminden farklı model ilk sırada: kod Sonnet ise Opus · yüksek, kod Opus ise Sonnet · yüksek, kod Haiku ise Sonnet · yüksek. Sonra öteki iki model ve aynı modelin orta effort'u |
24
+ | `review` | Sonnet · yüksek / Opus · yüksek / Sonnet · orta / Haiku · yüksek |
25
+ | `docs` | Haiku · yüksek / Haiku · orta / Sonnet · yüksek / Sonnet · orta |
26
+
27
+ Kod ve test aynı modele alınırsa `models.mjs` uyarır ama engellemez (limit darken ikisi de ucuz modele alınabilir).
28
+
16
29
  Effort ölçeği: düşük = `low`, orta = `medium`, yüksek = `high`, ekstra yüksek = `xhigh`. Effort arttıkça cevap yavaşlar ve limitten daha çok yer.
17
30
 
18
31
  Opus en pahalı, Haiku en ucuz modeldir. Limit sarı veya kırmızıya döndüğünde en büyük tasarruf kod rolünü bir alt modele almaktır (`docs/workflow/usage-limits.md` §3). Güvenlik, veri modeli ve mimari kararlar planlama rolünde kalır.
@@ -139,7 +139,7 @@ Açık her plugin'in skill açıklamaları her oturumda bağlama yüklenir. Skil
139
139
  | Durum | Skill |
140
140
  |---|---|
141
141
  | Her kod değişikliği (en küçük tam çözüm, gereksiz soyutlama yok) | `ponytail:ponytail` |
142
- | Kritik akış (auth, ödeme, veri yazma; `docs/quality/test-plan.md` K1-K5) | `mattpocock-skills:tdd` |
142
+ | Kritik akış (auth, ödeme, veri yazma; `docs/quality/test-plan.md` K1-K5) | `mattpocock-skills:tdd` (kırmızı testi `test-writer` ajanı yazar, yeşile kod tarafı çevirir) |
143
143
  | Bozulan projeyi son çalışan hale döndürmek | `/rollback` (`checkpoint.mjs`) |
144
144
  | Yeni başlayan kullanıcıya her adımı anlatmak | Anlatıcı mod: `.claude/output-styles/anlatici.md` (`outputStyle: anlatici`) |
145
145
  | Hata ayıklama (`/fix-bug`) | `mattpocock-skills:diagnosing-bugs` + `/freeze <klasör>` |
package/kit/CHANGELOG.md CHANGED
@@ -3,6 +3,19 @@
3
3
  Kit sürümü `kit/VERSION` dosyasında. Bir projeyi güncellemek: projede `/kit-update`.
4
4
  "Elle uyarla" notu olan maddeler projeye ait dosyalardadır; güncelleme bunlara dokunmaz.
5
5
 
6
+ ## [3.42.0] - 2026-10-27
7
+
8
+ ### Eklenen
9
+ - **Testi kodu yazan değil, ayrı bir ajan yazar.** Yeni `test-writer` ajanı kabul ve saldırgan testlerini koddan önce, yalnız kabul kriterlerine, spec'e ve dış arayüze bakarak yazar; uygulama planını görmez. Kodu ve testi aynı ajan yazarsa test koda göre şekillenir; bu ayrım bunu önler.
10
+ - **Test dosyasına yalnız `test-writer` yazabilir.** Claude Code'da ana oturum veya başka bir ajan test dosyasına dosya aracıyla ya da kabukla yazmaya çalışırsa test koruması engeller (test ayar dosyaları eskisi gibi sorulur). Codex ve Antigravity ajan kimliği bildirmediği için orada kural metinde kalır.
11
+ - **Test korumasında atlatma yolları kapandı.** Windows'un aynı dosyaya çözdüğü yazımlar (sonda nokta veya boşluk, `::$DATA`), kısa adlar ve test klasörüne giden bağlar gerçek yoluyla denetlenir. Kabukta `touch`, `ln`, `dd`, `curl -o`, `wget -O` ile test yazımı da engellenir; test yolu anan satır içi betikler (`node -e`, `python -c`, `bash -c`) sorulur. `node_modules/` ve `.git/` altındaki test klasörleri sayılmaz.
12
+ - **Plugin dizin bilgileri.** Plugin'e görünen ad, sürüm, dokümantasyon ve destek bağlantısı eklendi.
13
+ - **Beşinci rol: test.** `docs/workflow/models.md`'ye test rolü eklendi, önerilen model kod rolünden farklı (kod Sonnet, test Opus). Kod ve test aynı modele alınırsa `models.mjs` uyarır.
14
+
15
+ ### Değişen
16
+ - **Görev başındaki model soruları rol başına tek soru.** Model ve effort birlikte sorulur, iki ekranda: önce plan, kod, test; sonra inceleme, doküman. Elle uyarla: yok.
17
+ - **`/build` adımları:** 2b testler (`test-writer`), 2c kod. `/fix-bug` 5. adımda kırmızı testi `test-writer` yazar.
18
+
6
19
  ## [3.41.1] - 2026-10-27
7
20
 
8
21
  ### Değişen
package/kit/VERSION CHANGED
@@ -1 +1 @@
1
- 3.41.1
1
+ 3.42.0
package/kit/guide.html CHANGED
@@ -287,7 +287,7 @@ footer .container { display: flex; flex-wrap: wrap; gap: 16px; justify-content:
287
287
  <section class="hero">
288
288
  <div class="container">
289
289
  <div>
290
- <span class="pill"><b>v3.41.1</b> Claude Code için başlangıç kiti · MIT</span>
290
+ <span class="pill"><b>v3.42.0</b> Claude Code için başlangıç kiti · MIT</span>
291
291
  <h1>Kodu AI yazar.<br><em>Dümen sende.</em></h1>
292
292
  <p class="sub">TillerHand, Claude Code ile bir ürünü fikirden canlıya ve bakıma kadar götürür. Her önemli kararda AI sana seçenekleri, önerisini ve her seçeneğin bedelini sunar. Bir uzman kurulu işi denetler, korumalar hatayı daha olmadan durdurur.</p>
293
293
  <div class="install"><span id="cmd">npx tillerhand init</span><button class="copy" type="button" data-copy="cmd">Kopyala</button></div>
@@ -776,6 +776,7 @@ node vibe-kit/kit/kit.mjs init</pre>
776
776
  <tr><td>Paket kapısı</td><td>Kurulan ya da <code>npx</code>, <code>uvx</code> ile indirilip çalıştırılan paket kayıt defterinden doğrulanır: yoksa engellenir; çok yeni, az indirilmiş veya popüler bir pakete benziyorsa sorulur</td></tr>
777
777
  <tr><td>Yapı koruyucu</td><td>Harita dışı yeni dosya sorulur; <code>*.bak</code>, <code>*-old.*</code>, kopya ve <code>temp/</code> gibi dağınıklıklar engellenir</td></tr>
778
778
  <tr><td>Yapılandırma onayı</td><td><code>CLAUDE.md</code>, <code>AGENTS.md</code>, <code>.claude/</code>, <code>.codex/</code>, <code>.mcp.json</code> ve iş akışı dosyaları onayın olmadan değişmez</td></tr>
779
+ <tr><td>Test ayrımı</td><td>Testleri kodu yazan değil, ayrı bir ajan (<code>test-writer</code>, farklı model önerilir) koddan önce yazar. Test dosyasına bu ajan dışında kimse yazamaz: ana oturum ve kod ajanı denerse engellenir. Böylece kodu yazan testi kendi koduna göre şekillendiremez</td></tr>
779
780
  <tr><td>Test koruması</td><td>Beklenti silmek veya yoruma almak, <code>.skip</code>/<code>.only</code>, gevşek beklenti, test dosyasını silmek veya taşımak ve test ayarında kapsamı daraltmak sorulur; kabukla test dosyasına yazmak da</td></tr>
780
781
  <tr><td>Deterministik kapı</td><td><code>gate.mjs --run</code>: lint, tip kontrolü, test ve Semgrep çalışır; çıktı kurula girdi olur, kırmızı kontrol RET sayılır. Spec'teki "değişmemesi gereken" davranışların testi yoksa veya kırmızıysa kapı kırmızıdır. Eklenen bir satırda bu makineye özel bir yol (proje klasörünün ya da ev klasörünün tam yolu) varsa da kırmızıdır. Yeni veya değişen komut önce sana gösterilip onaylatılır</td></tr>
781
782
  <tr><td>Commit kapısı</td><td>Kurul denetimi ve aynı değişiklikler için yeşil kapı olmadan commit atılmaz; görev sonu onayı commit için de geçerli, aynı değişiklik iki kez denetlenmez; denetimi atlamak (<code>--skip</code>) her seferinde sorulur</td></tr>
@@ -908,7 +909,7 @@ Sıradaki: G-013 şifre sıfırlama · bekleyen karar: e-posta servisi</pre>
908
909
  <article class="tile"><h3>Dağıtım kurulumu</h3><p class="stack">/release first · deploy-setup.md</p><ul><li>Hosting, ortam değişkenleri, alan adı ve DNS, yedek, geri alma provası</li><li>Vercel, Supabase, Railway, EAS; adımlar kaynaklı ve tarihli</li><li>Sırrı sen panelde girersin; sohbete ve dosyaya yazılmaz</li></ul></article>
909
910
  <article class="tile"><h3>Öğrenen kurallar</h3><p class="stack">/fix-bug · /retro · hookify · AGENTS.md</p><ul><li>Aynı hata sınıfı ikinci kez gelince /fix-bug kural önerir; panoda da uyarı çıkar</li><li>Mekanik kural hookify'a, gerisi AGENTS.md'ye; sen onaylamadan yazılmaz</li><li>Her kuralda kaynak ve tarih; /maintain 90 günden eskileri sorar</li><li>Auto memory /start'ta sorulur, önerilen kapalı</li></ul></article>
910
911
  <article class="tile"><h3>Kişisel tercihler</h3><p class="stack">~/.vibe-kit/tercihler.md · prefs.mjs</p><ul><li>Bir davranışı düzelttiğinde ya da nasıl çalışmak istediğini söylediğinde AI not alır</li><li>Görev ve oturum sonunda "tercih olarak kaydedeyim mi?" diye sorar; onaylamadığın yazılmaz</li><li>Tercihler tüm projelerinde geçerli, her oturumda yüklenir; git'e girmez</li><li>Listele: <code>node .claude/hooks/prefs.mjs --list</code>, sil: <code>--remove &lt;no&gt;</code></li></ul></article>
911
- <article class="tile"><h3>Rol bazlı model</h3><p class="stack">docs/workflow/models.md · models.mjs</p><ul><li>Dört rol: planlama, kod yazma, inceleme, doküman ve araştırma</li><li>Her görevin başında iki ekran: önce rollerin modeli, sonra effort'u</li><li>Önerilen: Opus yüksek, Sonnet yüksek, Sonnet yüksek, Haiku yüksek</li><li>Kod, inceleme ve doküman işleri seçilen modelle alt ajanda; plan ana oturumda</li><li>Roadmap işareti, maliyet satırı ve progress etiketleri <code>progress.mjs</code> ile yazılır; model çağrısı harcanmaz, biçim bozulmaz</li><li>Alt ajan yalnız karlıysa: <code>flow.mjs</code> görev büyüklüğüne, bağlama ve limite bakar; küçük görev ana oturumda kalır, kurul üyeleri değişen yollardan seçilir, sayısı limite göre azalır; üye en fazla 5 bulgu yazar</li></ul></article>
912
+ <article class="tile"><h3>Rol bazlı model</h3><p class="stack">docs/workflow/models.md · models.mjs</p><ul><li>Beş rol: planlama, kod yazma, test yazma, inceleme, doküman ve araştırma</li><li>Her görevin başında rol başına tek soru (model ve effort birlikte), iki ekranda</li><li>Önerilen: plan Opus, kod Sonnet, test Opus, inceleme Sonnet, doküman Haiku; hepsi yüksek effort. Test, koddan farklı model: aynı kör noktayı paylaşmaz</li><li>Test, inceleme ve doküman işleri seçilen modelle alt ajanda; plan ana oturumda</li><li>Roadmap işareti, maliyet satırı ve progress etiketleri <code>progress.mjs</code> ile yazılır; model çağrısı harcanmaz, biçim bozulmaz</li><li>Alt ajan yalnız karlıysa: <code>flow.mjs</code> görev büyüklüğüne, bağlama ve limite bakar; küçük görev ana oturumda kalır, kurul üyeleri değişen yollardan seçilir, sayısı limite göre azalır; üye en fazla 5 bulgu yazar</li></ul></article>
912
913
  <article class="tile"><h3>Türkiye eki</h3><p class="stack">--addons tr · docs/legal/turkiye.md</p><ul><li>KVKK yurt dışı aktarım: standart sözleşme, 5 iş günü bildirim</li><li>e-Fatura ve e-Arşiv eşikleri (GİB)</li><li>iyzico ve PayTR bildirim imzası kodu ve saldırgan testi</li><li>İ/ı ve Türkçe sıralama testleri; hukuki görüş değildir</li></ul></article>
913
914
  <article class="tile"><h3>Tarayıcıda QA ve önizleme</h3><p class="stack">/qa · preview.mjs · Playwright CLI</p><ul><li>Arayüz kriterleri gerçek tarayıcıda test olarak koşar</li><li>Rapor test sonucundan yazılır, panoda kart</li><li>/build arayüz görevinde masaüstü ve mobil ekran görüntüsü</li></ul></article>
914
915
  <article class="tile"><h3>Spec ve sapma kontrolü</h3><p class="stack">docs/product/specs/ · gate.mjs</p><ul><li>Mevcut, beklenen ve değişmemesi gereken davranış</li><li>"Değişmemesi gereken" satırların testi kapıda denetlenir</li><li>3+ dosyalık işte /plan-task, her hatada /fix-bug yazar</li></ul></article>
@@ -1069,7 +1070,7 @@ Sıradaki: G-013 şifre sıfırlama · bekleyen karar: e-posta servisi</pre>
1069
1070
  <footer>
1070
1071
  <div class="container">
1071
1072
  <a class="brand" href="#top" style="font-size:16px"><svg class="mark" style="width:22px;height:22px"><use href="#mark"/></svg>TillerHand</a>
1072
- <span>Sürüm 3.41.1 · <a href="https://github.com/burakdogrul/TillerHand">GitHub</a> · <a href="https://github.com/burakdogrul/TillerHand/blob/main/LICENSE">MIT lisansı</a> · KVKK bölümü kontrol listesidir, hukuki görüş değildir.</span>
1073
+ <span>Sürüm 3.42.0 · <a href="https://github.com/burakdogrul/TillerHand">GitHub</a> · <a href="https://github.com/burakdogrul/TillerHand/blob/main/LICENSE">MIT lisansı</a> · KVKK bölümü kontrol listesidir, hukuki görüş değildir.</span>
1073
1074
  </div>
1074
1075
  </footer>
1075
1076
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tillerhand",
3
- "version": "3.41.1",
3
+ "version": "3.42.0",
4
4
  "description": "Claude Code, Codex ve Antigravity için Türkçe vibe coding kiti: kurallar, komutlar, korumalar ve proje şablonları.",
5
5
  "license": "MIT",
6
6
  "type": "module",