tillerhand 3.48.1 → 3.49.1

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.
Files changed (108) hide show
  1. package/.claude/agents/board-chair.md +1 -1
  2. package/.claude/agents/security-auditor.md +1 -1
  3. package/.claude/agents/test-writer.md +1 -1
  4. package/.claude/board/board-product.md +1 -1
  5. package/.claude/board/council.md +1 -1
  6. package/.claude/board/rules.md +6 -6
  7. package/.claude/commands/adopt.md +3 -3
  8. package/.claude/commands/ask-mode.md +4 -4
  9. package/.claude/commands/board.md +1 -1
  10. package/.claude/commands/build.md +1 -1
  11. package/.claude/commands/design.md +4 -4
  12. package/.claude/commands/findings-business.md +1 -1
  13. package/.claude/commands/findings-legal.md +1 -1
  14. package/.claude/commands/findings-perf.md +1 -1
  15. package/.claude/commands/findings-security.md +2 -2
  16. package/.claude/commands/findings-tech.md +1 -1
  17. package/.claude/commands/findings-ux.md +1 -1
  18. package/.claude/commands/fix-bug.md +2 -2
  19. package/.claude/commands/handoff.md +2 -2
  20. package/.claude/commands/kit-update.md +2 -2
  21. package/.claude/commands/qa.md +1 -1
  22. package/.claude/commands/release.md +2 -2
  23. package/.claude/commands/research.md +3 -3
  24. package/.claude/commands/retro.md +1 -1
  25. package/.claude/commands/rollback.md +3 -3
  26. package/.claude/commands/start.md +4 -4
  27. package/.claude/commands/tools.md +1 -1
  28. package/.claude/commands/user-feedback.md +1 -1
  29. package/.claude/findings/lenses/business.md +1 -1
  30. package/.claude/findings/protocol.md +2 -2
  31. package/.claude/hooks/budget.mjs +1 -1
  32. package/.claude/hooks/checkpoint.mjs +2 -2
  33. package/.claude/hooks/commit-gate.mjs +18 -17
  34. package/.claude/hooks/council.mjs +37 -52
  35. package/.claude/hooks/dashboard-data.mjs +34 -42
  36. package/.claude/hooks/dashboard.mjs +18 -20
  37. package/.claude/hooks/destructive-guard.mjs +2 -2
  38. package/.claude/hooks/flow.mjs +1 -1
  39. package/.claude/hooks/freeze-guard.mjs +2 -2
  40. package/.claude/hooks/gate.mjs +21 -13
  41. package/.claude/hooks/labels.mjs +92 -152
  42. package/.claude/hooks/lang.mjs +25 -9
  43. package/.claude/hooks/messages.mjs +497 -494
  44. package/.claude/hooks/notify.mjs +1 -1
  45. package/.claude/hooks/prefs.mjs +10 -18
  46. package/.claude/hooks/preview.mjs +1 -1
  47. package/.claude/hooks/progress.mjs +7 -9
  48. package/.claude/hooks/qa-report.mjs +1 -3
  49. package/.claude/hooks/session-start.mjs +2 -3
  50. package/.claude/hooks/status-read.mjs +5 -5
  51. package/.claude/hooks/statusline.mjs +4 -4
  52. package/.claude/hooks/tools.mjs +3 -7
  53. package/.claude/hooks/usage.mjs +2 -2
  54. package/.claude/i18n/tr.json +496 -0
  55. package/.claude/security-patterns.json +1 -1
  56. package/.claude/skills/logo-design/SKILL.md +2 -2
  57. package/.claude/skills/motion-video/SKILL.md +1 -1
  58. package/.claude/skills/source-research/SKILL.md +1 -1
  59. package/.claude/skills/ui-motion/SKILL.md +1 -1
  60. package/AGENTS.md +1 -1
  61. package/CHANGELOG.md +1 -1
  62. package/README.md +2 -2
  63. package/README.tr.md +2 -2
  64. package/docs/architecture/overview.md +1 -1
  65. package/docs/decisions/log.md +1 -1
  66. package/docs/legal/privacy-kvkk.md +35 -35
  67. package/docs/operations/deploy-setup.md +1 -1
  68. package/docs/operations/feature-flags.md +1 -1
  69. package/docs/product/glossary.md +3 -3
  70. package/docs/product/launch.md +1 -1
  71. package/docs/product/prd.md +2 -2
  72. package/docs/product/roadmap.md +1 -1
  73. package/docs/product/specs/_template.md +1 -1
  74. package/docs/product/unit-economics.md +1 -1
  75. package/docs/quality/test-plan.md +5 -5
  76. package/docs/workflow/decision-protocol.md +1 -2
  77. package/docs/workflow/mcp-catalog.md +1 -1
  78. package/docs/workflow/skills.md +2 -2
  79. package/docs/workflow/usage-limits.md +1 -1
  80. package/kit/CHANGELOG.md +34 -0
  81. package/kit/VERSION +1 -1
  82. package/kit/guide.html +56 -56
  83. package/kit/guide.tr.html +10 -10
  84. package/kit/kit.mjs +7 -42
  85. package/kit/templates/addons/ai/.env.example.append +3 -3
  86. package/kit/templates/addons/tr/docs/legal/turkiye.md +55 -55
  87. package/kit/templates/addons/tr/types/backend/.env.example.append +2 -2
  88. package/kit/templates/addons/tr/types/backend/app/shared/payments.py +1 -1
  89. package/kit/templates/addons/tr/types/backend/tests/security/test_payment_webhook.py +3 -3
  90. package/kit/templates/addons/tr/types/web-saas/.env.example.append +2 -2
  91. package/kit/templates/addons/tr/types/web-saas/.github/workflows/payment-webhook.yml +3 -3
  92. package/kit/templates/addons/tr/types/web-saas/src/lib/payments/webhook-signature.ts +1 -1
  93. package/kit/templates/addons/tr/types/web-saas/tests/security/payment-webhook.mjs +4 -4
  94. package/kit/templates/backend/.github/dependabot.yml +1 -1
  95. package/kit/templates/backend/.github/workflows/live-monitoring.yml +1 -1
  96. package/kit/templates/backend/docs/architecture/stack.md +3 -3
  97. package/kit/templates/mobile/.github/dependabot.yml +1 -1
  98. package/kit/templates/mobile/.github/workflows/ci.yml +2 -2
  99. package/kit/templates/mobile/docs/architecture/stack.md +4 -4
  100. package/kit/templates/mobile/docs/architecture/structure.md +1 -1
  101. package/kit/templates/mobile/docs/design/design-guide.md +1 -1
  102. package/kit/templates/web-saas/.github/dependabot.yml +1 -1
  103. package/kit/templates/web-saas/.github/workflows/ci.yml +2 -2
  104. package/kit/templates/web-saas/.github/workflows/live-monitoring.yml +1 -1
  105. package/kit/templates/web-saas/docs/architecture/stack.md +4 -4
  106. package/kit/templates/web-saas/docs/design/design-guide.md +1 -1
  107. package/kit/tools/antigravity/.agents/hooks.json +5 -5
  108. package/package.json +1 -1
@@ -1,80 +1,80 @@
1
- # Türkiye Paketi
1
+ # Turkey Pack
2
2
 
3
- > `tr` ekiyle gelir (`--addons tr`). Türkiye'de satış yapan veya Türk kullanıcısı olan ürün için.
4
- > **Hukuki görüş değildir.** Her madde birincil kaynağa bağlı ve kontrol tarihli; mevzuat değişir. Yayından önce bir avukata veya mali müşavire danış.
5
- > Kullanmadan önce kaynakları `source-research` ile yeniden aç; değişen varsa bu dosyayı güncelle ve tarihi değiştir.
6
- > `/findings-legal` ve `/findings-business` bu dosyayı okur.
3
+ > Comes with the `tr` add-on (`--addons tr`). For a product that sells in Turkey or has Turkish users.
4
+ > **Not legal advice.** Every item links to a primary source and has a check date; legislation changes. Ask a lawyer or an accountant before launch.
5
+ > Before use, reopen the sources with `source-research`; if something changed, update this file and change the date.
6
+ > `/findings-legal` and `/findings-business` read this file.
7
7
 
8
- ## 1. KVKK: yurt dışına aktarım
8
+ ## 1. KVKK: transfer abroad
9
9
 
10
- Kontrol: 2026-10-25. Kaynak: [6698 sayılı KVKK, m.9](https://www.mevzuat.gov.tr/MevzuatMetin/1.5.6698.pdf) (7499 sayılı Kanunla değişik, 2/3/2024)
10
+ Checked: 2026-10-25. Source: [Law no. 6698 (KVKK), art. 9](https://www.mevzuat.gov.tr/MevzuatMetin/1.5.6698.pdf) (as amended by Law no. 7499, 2/3/2024)
11
11
 
12
- Yurt dışındaki bir servise kişisel veri gitmesi aktarımdır: AI sağlayıcısı (istem metninde kullanıcı verisi), barındırma ve veritabanı bölgesi, e-posta, analitik, hata takibi. Sıra:
12
+ Personal data going to a service abroad is a transfer: AI provider (user data in the prompt text), hosting and database region, email, analytics, error tracking. Order:
13
13
 
14
- 1. **Yeterlilik kararı** var mı (m.9/1-3)? Kurul verir, Resmî Gazete'de yayımlanır. Varsa m.5 veya m.6'daki bir şartla aktarılabilir.
15
- 2. Yoksa **uygun güvence** (m.9/4): Kurul'un ilan ettiği **standart sözleşme**, onaylı bağlayıcı şirket kuralları, Kurul izinli taahhütname veya (kamu kurumları arasında) Kurul izinli anlaşma. Burada da m.5 veya m.6'daki bir şart gerekir ve ilgili kişinin o ülkede haklarını kullanabilmesi şarttır.
16
- - **Standart sözleşme imzalandıktan sonra 5 iş günü içinde Kuruma bildirilir** (m.9/5).
17
- 3. İkisi de yoksa sadece **arızi** (tekrarlanmayan) hallerde (m.9/6): bilgilendirilmiş açık rıza, sözleşmenin ifası için zorunluluk ve maddede sayılan diğer haller. Sürekli çalışan bir AI veya barındırma servisi "arızi" değildir.
14
+ 1. Is there an **adequacy decision** (art. 9/1-3)? The Personal Data Protection Board (KVKK Board) issues it; it is published in the Official Gazette. If there is one, transfer is allowed under a condition in art. 5 or art. 6.
15
+ 2. If not, **appropriate safeguards** (art. 9/4): the **standard contract** announced by the Board, approved binding corporate rules, an undertaking permitted by the Board or (between public bodies) an agreement permitted by the Board. A condition in art. 5 or art. 6 is still required here, and the data subject must be able to exercise their rights in that country.
16
+ - **After the standard contract is signed, notify the Personal Data Protection Authority (KVKK Authority) within 5 business days** (art. 9/5).
17
+ 3. If neither exists, only in **incidental** (non-repeated) cases (art. 9/6): informed explicit consent, necessity for performing a contract and the other cases listed in the article. An AI or hosting service that runs continuously is not "incidental".
18
18
 
19
- Projede yapılacaklar:
20
- - [ ] `docs/operations/accounts.md`'deki her dış servis için: veri hangi ülkede, aktarım dayanağı ne (yeterlilik / standart sözleşme / yok)?
21
- - [ ] Standart sözleşme gerekiyorsa sağlayıcıyla imzalandı ve 5 iş günü içinde Kuruma bildirildi; tarih `accounts.md` → Not sütununda.
22
- - [ ] Aydınlatma metni (`docs/legal/privacy-kvkk.md`) yurt dışına aktarımı, alıcı grubunu ve amacını söylüyor (m.10).
23
- - [ ] AI istemine gerekmeyen kişisel veri gitmiyor (veri en aza indirme); mümkünse kimlik bilgisi maskeleniyor.
19
+ Project to-do:
20
+ - [ ] For each external service in `docs/operations/accounts.md`: which country is the data in, what is the transfer basis (adequacy / standard contract / none)?
21
+ - [ ] If a standard contract is needed, it is signed with the provider and notified to the Authority within 5 business days; the date is in `accounts.md` → Note column.
22
+ - [ ] The privacy notice (`docs/legal/privacy-kvkk.md`) states the transfer abroad, the recipient group and the purpose (art. 10).
23
+ - [ ] No unneeded personal data goes into the AI prompt (data minimization); identity data is masked where possible.
24
24
 
25
- ## 2. e-Fatura ve e-Arşiv Fatura
25
+ ## 2. e-Fatura and e-Arşiv Fatura
26
26
 
27
- Kontrol: 2026-10-25. Kaynak: [509 Sıra No.lu VUK Genel Tebliği, güncel hali](https://cdn.gib.gov.tr/api/gibportal-file/file/getFile?objectKey=MEVZUAT_TEBLIGLER%2FUNIVERSAL%2F2026%2FMEVZUAT_TEBLIGLER_2026_VukTeb509_Guncel.pdf) (GİB, 589 Sıra No.lu Tebliğ değişiklikleri işlenmiş) · [e-Belge](https://ebelge.gib.gov.tr/)
27
+ Checked: 2026-10-25. Source: [General Communiqué on the Tax Procedure Law no. 509 (VUK General Communiqué No. 509), current version](https://cdn.gib.gov.tr/api/gibportal-file/file/getFile?objectKey=MEVZUAT_TEBLIGLER%2FUNIVERSAL%2F2026%2FMEVZUAT_TEBLIGLER_2026_VukTeb509_Guncel.pdf) (GİB, with the amendments of Communiqué no. 589 applied) · [e-Belge](https://ebelge.gib.gov.tr/)
28
28
 
29
- - **e-Fatura zorunluluğu** (IV.1.4): 2022 veya sonraki hesap dönemlerinde brüt satış hasılatı **3 milyon TL** ve üzeri olanlar. Kendi sitesinde veya başka elektronik ortamda mal/hizmet satanlar, aracı hizmet sağlayıcılar ve internet ilan/reklam aracıları için eşik **500 bin TL**. Eşiği aşan, izleyen yılın yedinci ayının başına kadar geçer (IV.1.5).
30
- - **e-Arşiv**: e-Fatura'ya dahil olan e-Arşiv'e de geçer (IV.2.4.1). e-Arşiv'e dahil olmayanların faturaları 1/1/2026'dan itibaren tutarından bağımsız olarak e-Arşiv Fatura olarak (GİB portalı veya özel entegratör üzerinden) düzenlenir. Basit usul ve işletme hesabı esasında bu tarih 1/1/2027'dir (IV.2.4.3).
31
- - **İnternet satışı faturası** (IV.2.4.5): Fatura elektronik ortamda iletilir. Üzerinde "Bu satış internet üzerinden yapılmıştır." ifadesi, satışın yapıldığı web adresi, ödeme şekli ve tarihi, gönderen kargo bilgisi, gönderim tarihi ve iade bölümü yer alır.
29
+ - **e-Fatura obligation** (IV.1.4): those whose gross sales revenue was **3 million TL** or more in accounting periods of 2022 or later. For those selling goods/services on their own site or in another electronic medium, intermediary service providers and internet listing/advertising intermediaries, the threshold is **500 thousand TL**. Those who exceed the threshold switch by the start of the seventh month of the following year (IV.1.5).
30
+ - **e-Arşiv**: those in e-Fatura also switch to e-Arşiv (IV.2.4.1). Invoices of those not in e-Arşiv are issued as e-Arşiv Fatura (through the GİB portal or a private integrator) from 1/1/2026, regardless of amount. For the simplified procedure and the business account basis this date is 1/1/2027 (IV.2.4.3).
31
+ - **Internet sales invoice** (IV.2.4.5): The invoice is delivered electronically. It carries the statement "Bu satış internet üzerinden yapılmıştır.", the web address where the sale was made, the payment method and date, the shipping carrier's information, the shipping date and a return section.
32
32
 
33
- Projede yapılacaklar:
34
- - [ ] Fatura kesme yöntemi seçildi: GİB portalı (elle, küçük hacim) veya özel entegratör API'si (otomatik). Seçim `docs/decisions/log.md`'de.
35
- - [ ] Ödeme başarılı olunca fatura akışı tetikleniyor; fatura kesilemezse sipariş kaybolmuyor (yeniden deneme kuyruğu).
36
- - [ ] Mali müşavir eşik ve yöntem için onay verdi.
33
+ Project to-do:
34
+ - [ ] Invoicing method chosen: GİB portal (manual, small volume) or a private integrator API (automatic). The choice is in `docs/decisions/log.md`.
35
+ - [ ] The invoice flow is triggered when payment succeeds; if the invoice cannot be issued, the order is not lost (retry queue).
36
+ - [ ] The accountant approved the threshold and the method.
37
37
 
38
- ## 3. Ödeme bildirimleri (iyzico, PayTR)
38
+ ## 3. Payment notifications (iyzico, PayTR)
39
39
 
40
- Kontrol: 2026-10-25. Kaynaklar: [iyzico webhook](https://docs.iyzico.com/en/advanced/webhook) · [iyzico Retrieve Payment](https://docs.iyzico.com/en/advanced/retrieve-payment) · [iyzico CF Retrieve](https://docs.iyzico.com/en/payment-methods/checkoutform/cf-implementation/cf-retrieve) · [iyzico live / sandbox](https://docs.iyzico.com/en/getting-started/preliminaries/live-vs-sandbox) · [PayTR iFrame API 2. adım](https://dev.paytr.com/en/iframe-api/iframe-api-2-adim) (sayfalarda tarih yok)
40
+ Checked: 2026-10-25. Sources: [iyzico webhook](https://docs.iyzico.com/en/advanced/webhook) · [iyzico Retrieve Payment](https://docs.iyzico.com/en/advanced/retrieve-payment) · [iyzico CF Retrieve](https://docs.iyzico.com/en/payment-methods/checkoutform/cf-implementation/cf-retrieve) · [iyzico live / sandbox](https://docs.iyzico.com/en/getting-started/preliminaries/live-vs-sandbox) · [PayTR iFrame API step 2](https://dev.paytr.com/en/iframe-api/iframe-api-2-adim) (the pages have no date)
41
41
 
42
- Ödeme sonucu tarayıcı yönlendirmesine değil, sağlayıcının sunucudan gönderdiği bildirime göre işlenir. Bildirim imzası doğrulanmadan sipariş onaylanmaz. Kod hazır:
43
- - web-saas: `src/lib/payments/webhook-signature.ts` → `verifyIyzico`, `verifyPaytr`; saldırgan testi `tests/security/payment-webhook.mjs` (CI: `payment-webhook` iş akışı; yerelde Node 22.18 veya üstü)
44
- - backend: `app/shared/payments.py` → `verify_iyzico`, `verify_paytr`; saldırgan testi `tests/security/test_payment_webhook.py`
45
- - mobil: ödeme bildirimi sunucuya gelir; backend şablonunu veya Supabase Edge Function'ı kullan. Kartı uygulama içinde alma; sağlayıcının ödeme sayfasına yönlendir.
42
+ A payment result is processed from the notification the provider sends from its server, not from the browser redirect. An order is not confirmed before the notification signature is verified. The code is ready:
43
+ - web-saas: `src/lib/payments/webhook-signature.ts` → `verifyIyzico`, `verifyPaytr`; adversarial test `tests/security/payment-webhook.mjs` (CI: `payment-webhook` workflow; locally Node 22.18 or later)
44
+ - backend: `app/shared/payments.py` → `verify_iyzico`, `verify_paytr`; adversarial test `tests/security/test_payment_webhook.py`
45
+ - mobile: the payment notification comes to the server; use the backend template or a Supabase Edge Function. Do not take the card inside the app; redirect to the provider's payment page.
46
46
 
47
- Akış:
48
- 1. Sandbox hesabı aç (iyzico: sandbox-merchant.iyzipay.com, API `https://sandbox-api.iyzipay.com`; PayTR: mağaza panelinde test modu). Anahtarlar `.env.example`'daki adlarla **sadece sunucuda**; değerleri sen girersin.
49
- 2. Ödeme başlatma sunucuda yapılır; tutar ve sipariş numarası istemciden değil veritabanındaki siparişten alınır. iyzico'da her ödemeye sipariş numarasını `conversationId` olarak ver: imza bu alanı da kapsar, boşsa doğrulama reddeder.
50
- 3. Bildirim ucu (route) önce imzayı doğrular. `false` dönerse 4xx dön ve logla; isteğin gövdesini loglama (kişisel veri).
51
- - iyzico: `X-IYZ-SIGNATURE-V3` başlığı. İmza özelliği hesapta açık olmalı (iyzico'dan istenir). Abonelik bildirimleri bu kodun kapsamında değil.
52
- - PayTR: POST'taki `hash` alanı; yanıt düz metin `OK`, oturum kontrolü yok. Alanları form gövdesinden metin olarak al; `total_amount`'u sayıya çevirip geri yazma (imza bozulur).
53
- 4. **Geçerli imza, ödemenin başarılı olduğu demek değildir.** Başarısız ödeme de imzalı gelir. Sadece sonuç başarılıysa siparişi onayla: PayTR `status` = `success`, iyzico `status` = `SUCCESS` ve `iyziEventType` beklediğin tür. Diğerlerinde onaylama, sağlayıcıya yine başarı yanıtı dön.
54
- 5. Tutarı ve para birimini siparişle karşılaştır:
55
- - PayTR: bildirimdeki `total_amount` (kuruş: 34,56 TL → 3456).
56
- - iyzico: bildirimde tutar yok. Sunucudan sorgula: checkout formunda `token` ile CF Retrieve, diğerlerinde `paymentId` ile Retrieve Payment. Dönen `paymentStatus`, `paidPrice`, `currency` ve `conversationId` siparişle aynı olmalı.
57
- 6. **Tekrar gelen bildirim** (sağlayıcı yeniden dener, saldırgan eski bildirimi yeniden gönderebilir; iyzico imzasında zaman damgası yok): siparişi tek bir atomik güncellemeyle onayla (`UPDATE … SET durum='odendi' WHERE id=… AND durum='bekliyor'`) veya ödeme kimliğine (`merchant_oid` / `paymentId`) benzersiz kısıt koy. Önce okuyup sonra yazma; iki eşzamanlı bildirim ikisi de geçer. Tekrar gelene de başarı yanıtı dön.
58
- 7. Ödeme özelliği bayrak arkasında yayınlanır (`docs/operations/feature-flags.md`); canlıya almadan önce `/findings-security`.
47
+ Flow:
48
+ 1. Open a sandbox account (iyzico: sandbox-merchant.iyzipay.com, API `https://sandbox-api.iyzipay.com`; PayTR: test mode in the merchant panel). Keys use the names in `.env.example` and live **on the server only**; you enter the values.
49
+ 2. Payment is started on the server; the amount and order number come from the order in the database, not from the client. In iyzico, give the order number as `conversationId` on every payment: the signature covers this field too, and verification rejects it if empty.
50
+ 3. The notification endpoint (route) verifies the signature first. If it returns `false`, return 4xx and log; do not log the request body (personal data).
51
+ - iyzico: `X-IYZ-SIGNATURE-V3` header. The signature feature must be on in the account (request it from iyzico). Subscription notifications are outside the scope of this code.
52
+ - PayTR: the `hash` field in the POST; the response is plain text `OK`, no session check. Take the fields from the form body as text; do not convert `total_amount` to a number and write it back (this breaks the signature).
53
+ 4. **A valid signature does not mean the payment succeeded.** A failed payment also arrives signed. Confirm the order only if the result is a success: PayTR `status` = `success`, iyzico `status` = `SUCCESS` and `iyziEventType` the type you expect. In the other cases do not confirm; still return a success response to the provider.
54
+ 5. Compare the amount and currency with the order:
55
+ - PayTR: `total_amount` in the notification (kuruş: 34.56 TL → 3456).
56
+ - iyzico: the notification has no amount. Query the server: CF Retrieve with `token` for the checkout form, Retrieve Payment with `paymentId` for the others. The returned `paymentStatus`, `paidPrice`, `currency` and `conversationId` must match the order.
57
+ 6. **A repeated notification** (the provider retries, an attacker can resend an old notification; the iyzico signature has no timestamp): confirm the order with a single atomic update (`UPDATE … SET status='paid' WHERE id=… AND status='pending'`) or put a unique constraint on the payment id (`merchant_oid` / `paymentId`). Do not read first and write after; two concurrent notifications would both pass. Return a success response to the repeated one too.
58
+ 7. The payment feature ships behind a flag (`docs/operations/feature-flags.md`); run `/findings-security` before going live.
59
59
 
60
- - [ ] İmza saldırgan testi yeşil (imzasız ve değiştirilmiş bildirim reddediliyor).
61
- - [ ] Bildirim ucu testinde: başarısız ödeme bildirimi siparişi onaylamıyor; aynı bildirim iki kez (ve eşzamanlı) gelince sipariş bir kez işleniyor; tutarı farklı ödeme onaylanmıyor. Bu testler projenin kendi rotası için yazılır.
62
- - [ ] Prod anahtarları sadece barındırma panelinde; sandbox ve prod ayrı.
60
+ - [ ] The signature adversarial test is green (unsigned and altered notifications are rejected).
61
+ - [ ] The notification endpoint test shows: a failed-payment notification does not confirm the order; when the same notification arrives twice (and concurrently), the order is processed once; a payment with a different amount is not confirmed. These tests are written for the project's own route.
62
+ - [ ] Prod keys are only in the hosting panel; sandbox and prod are separate.
63
63
 
64
- ## 4. Türkçe metin: İ/ı
64
+ ## 4. Turkish text: İ/ı
65
65
 
66
- `"I".toLowerCase()` → `"i"`, ama Türkçede `"ı"`. `"i".toUpperCase()` → `"I"`, Türkçede `"İ"`. Varsayılan sıralama `ç, ğ, ı, ö, ş, ü` harflerini alfabenin sonuna atar. Arama, sıralama, büyük harfe çevirme ve e-posta karşılaştırması yapan her özelliğin testine şu durumları ekle:
66
+ `"I".toLowerCase()` → `"i"`, but in Turkish it is `"ı"`. `"i".toUpperCase()` → `"I"`, in Turkish it is `"İ"`. The default sort puts the letters `ç, ğ, ı, ö, ş, ü` at the end of the alphabet. Add these cases to the tests of every feature that does search, sorting, uppercasing and email comparison:
67
67
 
68
68
  ```js
69
- // Türkçe görünen metin: dil açıkça verilir
69
+ // Text shown as Turkish: the language is given explicitly
70
70
  expect('ISPARTA'.toLocaleLowerCase('tr')).toBe('ısparta');
71
71
  expect('istanbul'.toLocaleUpperCase('tr')).toBe('İSTANBUL');
72
72
  expect(['Zeynep', 'Çağla', 'Ali', 'Ömer'].sort(new Intl.Collator('tr').compare)).toEqual(['Ali', 'Çağla', 'Ömer', 'Zeynep']);
73
- // Büyük/küçük harf duyarsız arama: "İstanbul" araması "istanbul"u bulur
73
+ // Case-insensitive search: searching "İstanbul" finds "istanbul"
74
74
  expect(new Intl.Collator('tr', { sensitivity: 'base' }).compare('İstanbul', 'istanbul')).toBe(0);
75
- // Makine metni (e-posta, kod, URL, anahtar): dile bağlı çevirme yok
76
- expect('INFO@ORNEK.COM'.toLowerCase()).toBe('info@ornek.com');
75
+ // Machine text (email, code, URL, key): no language-dependent conversion
76
+ expect('INFO@EXAMPLE.COM'.toLowerCase()).toBe('info@example.com');
77
77
  ```
78
78
 
79
- - [ ] Kullanıcıya görünen metinde `toLocaleLowerCase('tr')` / `Intl.Collator('tr')`; e-posta, kullanıcı adı ve kod gibi makine metninde dile bağlı olmayan `toLowerCase()`.
80
- - [ ] Veritabanı sıralaması: Postgres'te Türkçe collation (ör. ICU `tr-TR-x-icu`) veya sıralama uygulamada.
79
+ - [ ] In text shown to the user use `toLocaleLowerCase('tr')` / `Intl.Collator('tr')`; in machine text such as email, username and code use the language-independent `toLowerCase()`.
80
+ - [ ] Database sorting: a Turkish collation in Postgres (e.g. ICU `tr-TR-x-icu`) or sorting in the application.
@@ -1,7 +1,7 @@
1
- # Türkiye eki: ödeme sağlayıcısı (sadece sunucu; kullanmadığını silebilirsin). Ayrıntı: docs/legal/turkiye.md
1
+ # Turkey add-on: payment provider (server only; you can delete the one you do not use). Details: docs/legal/turkiye.md
2
2
  IYZICO_API_KEY=
3
3
  IYZICO_SECRET_KEY=
4
- IYZICO_BASE_URL=https://sandbox-api.iyzipay.com # canlı: https://api.iyzipay.com
4
+ IYZICO_BASE_URL=https://sandbox-api.iyzipay.com # live: https://api.iyzipay.com
5
5
  PAYTR_MERCHANT_ID=
6
6
  PAYTR_MERCHANT_KEY=
7
7
  PAYTR_MERCHANT_SALT=
@@ -1,7 +1,7 @@
1
1
  """Payment provider notification signatures (iyzico, PayTR).
2
2
 
3
3
  Verify before reading anything else from the request; an unverified notification is rejected.
4
- Steps and sources: docs/legal/turkiye.md -> "Ödeme bildirimleri".
4
+ Steps and sources: docs/legal/turkiye.md -> "Payment notifications".
5
5
  Sources (checked 2026-10-25): docs.iyzico.com/en/advanced/webhook · dev.paytr.com/en/iframe-api/iframe-api-2-adim
6
6
  """
7
7
 
@@ -19,14 +19,14 @@ SALT = "test-merchant-salt"
19
19
  DIRECT = {
20
20
  "iyziEventType": "API_AUTH",
21
21
  "paymentId": "22416750",
22
- "paymentConversationId": "siparis-42",
22
+ "paymentConversationId": "order-42",
23
23
  "status": "SUCCESS",
24
24
  }
25
25
  CHECKOUT = {
26
26
  "iyziEventType": "CHECKOUT_FORM_AUTH",
27
27
  "iyziPaymentId": "22416751",
28
28
  "token": "tok-abc",
29
- "paymentConversationId": "siparis-43",
29
+ "paymentConversationId": "order-43",
30
30
  "status": "SUCCESS",
31
31
  }
32
32
  PAYTR = {"merchant_oid": "SIP42", "status": "success", "total_amount": "3456"}
@@ -66,7 +66,7 @@ class IyzicoTest(unittest.TestCase):
66
66
  self.assertFalse(verify_iyzico({**DIRECT, "status": "FAILURE"}, sig, SECRET))
67
67
  self.assertFalse(
68
68
  verify_iyzico(
69
- {**DIRECT, "paymentConversationId": "siparis-99"}, sig, SECRET
69
+ {**DIRECT, "paymentConversationId": "order-99"}, sig, SECRET
70
70
  )
71
71
  )
72
72
  self.assertFalse(
@@ -1,7 +1,7 @@
1
- # Türkiye eki: ödeme sağlayıcısı (sadece sunucu; kullanmadığını silebilirsin). Ayrıntı: docs/legal/turkiye.md
1
+ # Turkey add-on: payment provider (server only; you can delete the one you do not use). Details: docs/legal/turkiye.md
2
2
  IYZICO_API_KEY=
3
3
  IYZICO_SECRET_KEY=
4
- IYZICO_BASE_URL=https://sandbox-api.iyzipay.com # canlı: https://api.iyzipay.com
4
+ IYZICO_BASE_URL=https://sandbox-api.iyzipay.com # live: https://api.iyzipay.com
5
5
  PAYTR_MERCHANT_ID=
6
6
  PAYTR_MERCHANT_KEY=
7
7
  PAYTR_MERCHANT_SALT=
@@ -1,5 +1,5 @@
1
- # Ödeme bildirimi imza saldırgan testi (tr eki). Sahte anahtarlarla çalışır; sır gerekmez.
2
- # Kırmızıysa merge etme: sahte veya değiştirilmiş ödeme bildirimi kabul ediliyor olabilir.
1
+ # Payment notification signature adversarial test (tr add-on). Runs with fake keys; no secret needed.
2
+ # If red, do not merge: a fake or altered payment notification may be accepted.
3
3
  name: payment-webhook
4
4
 
5
5
  on:
@@ -18,5 +18,5 @@ jobs:
18
18
  - uses: actions/setup-node@v7
19
19
  with:
20
20
  node-version: 22
21
- # Node 22.18+ .ts modülünü doğrudan çalıştırır; bağımlılık kurulumu gerekmez
21
+ # Node 22.18+ runs a .ts module directly; no dependency install needed
22
22
  - run: node --test tests/security/payment-webhook.mjs
@@ -1,5 +1,5 @@
1
1
  // Payment provider notification signatures (iyzico, PayTR). Verify before reading anything else from the request;
2
- // an unverified notification is rejected. Steps and sources: docs/legal/turkiye.md → "Ödeme bildirimleri".
2
+ // an unverified notification is rejected. Steps and sources: docs/legal/turkiye.md → "Payment notifications".
3
3
  // Sources (checked 2026-10-25): docs.iyzico.com/en/advanced/webhook · dev.paytr.com/en/iframe-api/iframe-api-2-adim
4
4
  import { createHmac, timingSafeEqual } from 'node:crypto';
5
5
 
@@ -17,8 +17,8 @@ const iyzicoSign = (b, secret = SECRET) => {
17
17
  };
18
18
  const paytrSign = (f, key = KEY, salt = SALT) => createHmac('sha256', key).update(f.merchant_oid + salt + f.status + f.total_amount).digest('base64');
19
19
 
20
- const direct = { iyziEventType: 'API_AUTH', paymentId: '22416750', paymentConversationId: 'siparis-42', status: 'SUCCESS' };
21
- const checkout = { iyziEventType: 'CHECKOUT_FORM_AUTH', iyziPaymentId: '22416751', token: 'tok-abc', paymentConversationId: 'siparis-43', status: 'SUCCESS' };
20
+ const direct = { iyziEventType: 'API_AUTH', paymentId: '22416750', paymentConversationId: 'order-42', status: 'SUCCESS' };
21
+ const checkout = { iyziEventType: 'CHECKOUT_FORM_AUTH', iyziPaymentId: '22416751', token: 'tok-abc', paymentConversationId: 'order-43', status: 'SUCCESS' };
22
22
  const paytr = { merchant_oid: 'SIP42', status: 'success', total_amount: '3456' };
23
23
 
24
24
  test('iyzico: a correctly signed notification is accepted (direct and checkout form)', () => {
@@ -30,7 +30,7 @@ test('iyzico: a correctly signed notification is accepted (direct and checkout f
30
30
  });
31
31
 
32
32
  test('iyzico: a payment id rounded by JSON.parse (above 2^53) is rejected', () => {
33
- const body = JSON.parse('{"iyziEventType":"CHECKOUT_FORM_AUTH","iyziPaymentId":9007199254740993,"token":"tok-abc","paymentConversationId":"siparis-43","status":"SUCCESS"}');
33
+ const body = JSON.parse('{"iyziEventType":"CHECKOUT_FORM_AUTH","iyziPaymentId":9007199254740993,"token":"tok-abc","paymentConversationId":"order-43","status":"SUCCESS"}');
34
34
  const sent = { ...body, iyziPaymentId: '9007199254740993' };
35
35
  assert.equal(verifyIyzico(body, iyzicoSign(sent), SECRET), false);
36
36
  assert.equal(verifyIyzico(body, iyzicoSign(body), SECRET), false, 'even when signed over the rounded value');
@@ -39,7 +39,7 @@ test('iyzico: a payment id rounded by JSON.parse (above 2^53) is rejected', () =
39
39
  test('iyzico: forged, altered or unsigned notifications are rejected', () => {
40
40
  const sig = iyzicoSign(direct);
41
41
  assert.equal(verifyIyzico({ ...direct, status: 'FAILURE' }, sig, SECRET), false, 'status changed after signing');
42
- assert.equal(verifyIyzico({ ...direct, paymentConversationId: 'siparis-99' }, sig, SECRET), false, 'order switched');
42
+ assert.equal(verifyIyzico({ ...direct, paymentConversationId: 'order-99' }, sig, SECRET), false, 'order switched');
43
43
  assert.equal(verifyIyzico(direct, iyzicoSign(direct, 'attacker-key'), SECRET), false, 'signed with another key');
44
44
  assert.equal(verifyIyzico(direct, undefined, SECRET), false, 'no header');
45
45
  assert.equal(verifyIyzico(direct, '', SECRET), false, 'empty header');
@@ -6,7 +6,7 @@ updates:
6
6
  schedule:
7
7
  interval: weekly
8
8
  groups:
9
- kucuk-guncellemeler:
9
+ minor-updates:
10
10
  update-types: [minor, patch]
11
11
  ignore:
12
12
  - dependency-name: "*"
@@ -3,7 +3,7 @@
3
3
  # It also raises an alarm if the /health response takes longer than LIVE_MAX_SECONDS (Variables, default 2) seconds.
4
4
  # If something breaks it opens an issue labeled "live-monitoring" (it does not open a new one if one is already open).
5
5
  # To enable:
6
- # 1. Settings > Variables > LIVE_URL = https://api.alanadin.com
6
+ # 1. Settings > Variables > LIVE_URL = https://api.example.com
7
7
  # 2. Critical endpoint tests (that delete no data, limited to a test account): as pytest under tests/live/
8
8
  # 3. If needed, Settings > Secrets > LIVE_TEST_TOKEN (a test account with restricted rights in prod)
9
9
  name: Live monitoring
@@ -41,7 +41,7 @@
41
41
  | Error tracking | Sentry | |
42
42
  | Cron monitoring | Healthchecks.io (dead man's switch) | Alarm if a job does not run |
43
43
 
44
- ## Commands (commands)
44
+ ## Commands
45
45
 
46
46
  ```bash
47
47
  uv sync # install dependencies
@@ -68,7 +68,7 @@ app/
68
68
  │ ├── router.py # HTTP endpoints (thin)
69
69
  │ ├── service.py # business logic
70
70
  │ ├── repository.py # database access
71
- │ ├── models.py # SQLAlchemy modelleri
71
+ │ ├── models.py # SQLAlchemy models
72
72
  │ ├── schemas.py # Pydantic input/output schemas
73
73
  │ ├── dependencies.py
74
74
  │ └── exceptions.py
@@ -76,7 +76,7 @@ app/
76
76
  └── jobs/ # scheduled and background jobs (idempotent)
77
77
  alembic/ # migration'lar
78
78
  tests/
79
- ├── <feature>/ # tests by feature (test_AC_01_1_... kabul testleri dahil)
79
+ ├── <feature>/ # tests by feature (test_AC_01_1_... acceptance tests included)
80
80
  └── live/ # live monitoring tests
81
81
  Dockerfile pyproject.toml uv.lock
82
82
  ```
@@ -7,7 +7,7 @@ updates:
7
7
  schedule:
8
8
  interval: weekly
9
9
  groups:
10
- kucuk-guncellemeler:
10
+ minor-updates:
11
11
  update-types: [minor, patch]
12
12
  ignore:
13
13
  - dependency-name: "expo"
@@ -66,8 +66,8 @@ jobs:
66
66
  if: hashFiles('supabase/config.toml') != ''
67
67
  run: |
68
68
  # Only the needed keys are taken; the output is not run as a shell command
69
- anahtarlar=$(npx -y supabase@2.120.0 status -o env | grep -E '^(API_URL|ANON_KEY|SERVICE_ROLE_KEY|DB_URL|PUBLISHABLE_KEY|SECRET_KEY)=')
70
- while IFS="=" read -r ad deger; do deger="${deger%\"}"; export "$ad=${deger#\"}"; done <<< "$anahtarlar"
69
+ keys=$(npx -y supabase@2.120.0 status -o env | grep -E '^(API_URL|ANON_KEY|SERVICE_ROLE_KEY|DB_URL|PUBLISHABLE_KEY|SECRET_KEY)=')
70
+ while IFS="=" read -r name value; do value="${value%\"}"; export "$name=${value#\"}"; done <<< "$keys"
71
71
  node --test tests/security/rls.mjs
72
72
 
73
73
  semgrep:
@@ -36,14 +36,14 @@
36
36
  | Error tracking | Sentry (`@sentry/react-native`) | |
37
37
  | Test | Jest + React Native Testing Library, Maestro (e2e) | |
38
38
 
39
- ## Commands (commands)
39
+ ## Commands
40
40
 
41
41
  ```bash
42
42
  npx expo start # development
43
43
  npx expo lint
44
44
  npx tsc --noEmit
45
45
  npm run test # jest
46
- npx expo install [paket] # add a package (picks the SDK-compatible version, not npm install)
46
+ npx expo install [package] # add a package (picks the SDK-compatible version, not npm install)
47
47
  npx expo-doctor # dependency compatibility check
48
48
  eas build --profile preview --platform all # test build
49
49
  eas build --profile production --platform all # store build
@@ -72,7 +72,7 @@ src/
72
72
  │ ├── types.ts
73
73
  │ └── index.ts
74
74
  ├── components/ # shared components: Button, TextField, Screen, EmptyState...
75
- ├── hooks/ # shared hooks (useBayrak etc.)
75
+ ├── hooks/ # shared hooks (useFlag etc.)
76
76
  ├── lib/ # supabase, sentry, secure storage, analytics clients
77
77
  ├── theme/ # design tokens (from DESIGN.md)
78
78
  ├── config/ # environment variables, constants
@@ -124,7 +124,7 @@ maestro test .maestro/ --format junit --output test-results/junit-e2e.xml
124
124
 
125
125
  **Feature flags** (`docs/operations/feature-flags.md`): It must be possible to turn a feature off without a store update. The app reads the flag remotely at launch and caches the last known value; with no network, the safe default (off) is used:
126
126
  - PostHog feature flags or Firebase Remote Config; or a Supabase `feature_flags` table.
127
- - Reading goes through a single hook: `hooks/useBayrak.ts`. Features that take payments, use AI or send notifications are not released without a flag.
127
+ - Reading goes through a single hook: `hooks/useFlag.ts`. Features that take payments, use AI or send notifications are not released without a flag.
128
128
 
129
129
  ## Common AI mistakes (watch for these)
130
130
 
@@ -22,7 +22,7 @@ src/
22
22
  │ ├── types.ts
23
23
  │ └── index.ts
24
24
  ├── components/ # shared components: Button, TextField, Screen, EmptyState...
25
- ├── hooks/ # shared hooks (useBayrak etc.)
25
+ ├── hooks/ # shared hooks (useFlag etc.)
26
26
  ├── lib/ # supabase, sentry, secure storage, analytics clients
27
27
  ├── theme/ # design tokens (from DESIGN.md)
28
28
  ├── config/ # environment variables, constants
@@ -8,7 +8,7 @@
8
8
  > Decisions are made with `/design` using **visual previews** (`docs/workflow/decision-protocol.md` §5). If a new color, size or component
9
9
  > is needed, it is asked as a decision first, then added to DESIGN.md. No raw colors or arbitrary sizes in code.
10
10
 
11
- ## 1. Chosen direction (Chosen direction)
11
+ ## 1. Chosen direction
12
12
 
13
13
  | Area | Choice | Skill | Preview | Date |
14
14
  |---|---|---|---|---|
@@ -7,7 +7,7 @@ updates:
7
7
  schedule:
8
8
  interval: weekly
9
9
  groups:
10
- kucuk-guncellemeler:
10
+ minor-updates:
11
11
  update-types: [minor, patch]
12
12
  ignore:
13
13
  - dependency-name: "*"
@@ -82,8 +82,8 @@ jobs:
82
82
  if: hashFiles('supabase/config.toml') != ''
83
83
  run: |
84
84
  # Only the needed keys are taken; the output is not run as a shell command
85
- anahtarlar=$(npx -y supabase@2.120.0 status -o env | grep -E '^(API_URL|ANON_KEY|SERVICE_ROLE_KEY|DB_URL|PUBLISHABLE_KEY|SECRET_KEY)=')
86
- while IFS="=" read -r ad deger; do deger="${deger%\"}"; export "$ad=${deger#\"}"; done <<< "$anahtarlar"
85
+ keys=$(npx -y supabase@2.120.0 status -o env | grep -E '^(API_URL|ANON_KEY|SERVICE_ROLE_KEY|DB_URL|PUBLISHABLE_KEY|SECRET_KEY)=')
86
+ while IFS="=" read -r name value; do value="${value%\"}"; export "$name=${value#\"}"; done <<< "$keys"
87
87
  node --test tests/security/rls.mjs
88
88
 
89
89
  semgrep:
@@ -2,7 +2,7 @@
2
2
  # Why 3 hours: GitHub Free gives 2,000 Actions minutes a month in a private repo; an hourly run (~3 min) would cost ~2,160 min (docs.github.com, 2026-10-25).
3
3
  # If something breaks it opens an issue labeled "live-monitoring" (it does not open a new one if one is already open).
4
4
  # To enable:
5
- # 1. Settings > Variables > LIVE_URL = https://alanadin.com
5
+ # 1. Settings > Variables > LIVE_URL = https://example.com
6
6
  # 2. Create a separate test account with restricted rights in prod: Settings > Secrets > LIVE_TEST_EMAIL, LIVE_TEST_PASSWORD
7
7
  # 3. Write the tests under tests/live/*.spec.ts (flows that delete no data, limited to the test account). smoke.spec.ts comes ready:
8
8
  # does the home page open, is it within LIVE_MAX_MS (Variables, default 3000), are there errors in the console.
@@ -19,7 +19,7 @@
19
19
  | 8 | Email | **Resend** (recommended: developer friendly, React email templates; free plan gives 3,000 emails per month, 100 per day (source: https://resend.com/pricing, 2026-10-26)) · Postmark (very high deliverability) · Amazon SES (cheapest, hard to set up) |
20
20
  | 9 | Analytics | **Plausible** (cookieless, KVKK friendly; no free plan, starts at 9 dollars per month, 30-day trial (source: https://plausible.io/docs/billing, 2026-10-26)) · PostHog (product analytics, funnels, feature flags) · Umami (self-host, free) · None |
21
21
  | 10 | Error tracking | **Sentry** (recommended) · Highlight / Better Stack |
22
- | 11 | Language support | **Turkish only** (recommended for the MVP) · Turkish + English (next-intl; setting it up from the start is cheaper than adding it later) |
22
+ | 11 | Language support | **One language: the users' language** (recommended for the MVP) · Two or more languages (next-intl; setting it up from the start is cheaper than adding it later) |
23
23
  | 12 | Test | **Vitest + Playwright** (recommended) · Playwright only (little logic, mostly UI) |
24
24
 
25
25
  ## Chosen technologies
@@ -41,7 +41,7 @@
41
41
  | Analytics | Plausible / PostHog | Watch cookie consent |
42
42
  | Test | Vitest (unit), Playwright (e2e) | |
43
43
 
44
- ## Commands (commands)
44
+ ## Commands
45
45
 
46
46
  ```bash
47
47
  npm run dev # development
@@ -98,7 +98,7 @@ supabase/migrations/ # database changes ONLY here
98
98
  - Every new table has RLS on, a written policy, and an entry in the `tests/security/rls.mjs` → `TABLES` list (the `rls` job in CI turns red on an unregistered table).
99
99
  - On every page, think about `loading.tsx` / empty state / `error.tsx`.
100
100
  - Images with `next/image`, links with `next/link`.
101
- - Texts are in Turkish; format date/money with `Intl` and `tr-TR`.
101
+ - Texts are in the UI language (`docs/product/glossary.md`); format date/money with `Intl` and that locale.
102
102
  - Before UI work, read `DESIGN.md` and `docs/design/design-guide.md`; do not go outside the tokens and rules. If a new design decision is needed, use `/design`.
103
103
 
104
104
  ## Verification (evidence before a task is done)
@@ -152,7 +152,7 @@ npx vitest run --reporter=default --reporter=junit --outputFile.junit=test-resul
152
152
 
153
153
  - [ ] Vercel prod environment variables entered (Preview and Production separate)
154
154
  - [ ] Supabase prod project is separate; prod domain and redirect URLs in Auth → URL Configuration
155
- - [ ] Supabase email templates in Turkish and a custom SMTP (the default SMTP limit is very low)
155
+ - [ ] Supabase email templates in the UI language and a custom SMTP (the default SMTP limit is very low)
156
156
  - [ ] Payment: live keys, live webhook endpoint and signing secret
157
157
  - [ ] SEO: `metadata` (title, description), Open Graph image, `sitemap.ts`, `robots.ts`, favicon
158
158
  - [ ] Lighthouse (mobile): Performance ≥ 90, Accessibility ≥ 90, SEO ≥ 90
@@ -8,7 +8,7 @@
8
8
  > Decisions are made with `/design` using **visual previews** (`docs/workflow/decision-protocol.md` §5). If a new color, size or component
9
9
  > is needed, it is asked as a decision first, then added to DESIGN.md. No raw colors or arbitrary sizes in code.
10
10
 
11
- ## 1. Chosen direction (Chosen direction)
11
+ ## 1. Chosen direction
12
12
 
13
13
  | Area | Choice | Skill | Preview | Date |
14
14
  |---|---|---|---|---|
@@ -1,10 +1,10 @@
1
1
  {
2
- "kit-oturum": {
2
+ "kit-session": {
3
3
  "SessionStart": [
4
4
  { "type": "command", "command": "node .claude/hooks/session-start.mjs" }
5
5
  ]
6
6
  },
7
- "kit-dosya-korumalari": {
7
+ "kit-file-guards": {
8
8
  "PreToolUse": [
9
9
  {
10
10
  "matcher": "write_to_file|replace_file_content|multi_replace_file_content",
@@ -17,7 +17,7 @@
17
17
  }
18
18
  ]
19
19
  },
20
- "kit-duzenleme-turu": {
20
+ "kit-edit-rounds": {
21
21
  "PostToolUse": [
22
22
  {
23
23
  "matcher": "write_to_file|replace_file_content|multi_replace_file_content",
@@ -30,7 +30,7 @@
30
30
  { "type": "command", "command": "node .claude/hooks/edit-rounds.mjs --inject" }
31
31
  ]
32
32
  },
33
- "kit-okuma-korumasi": {
33
+ "kit-read-guard": {
34
34
  "PreToolUse": [
35
35
  {
36
36
  "matcher": "*",
@@ -40,7 +40,7 @@
40
40
  }
41
41
  ]
42
42
  },
43
- "kit-komut-korumalari": {
43
+ "kit-command-guards": {
44
44
  "PreToolUse": [
45
45
  {
46
46
  "matcher": "run_command",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tillerhand",
3
- "version": "3.48.1",
3
+ "version": "3.49.1",
4
4
  "description": "Vibe coding kit for Claude Code, Codex and Antigravity: rules, commands, guards and project templates.",
5
5
  "license": "MIT",
6
6
  "type": "module",