tillerhand 3.39.3 → 3.39.4

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.
@@ -6,14 +6,10 @@ Bu oturumu kapatıyoruz. Bir sonraki oturum (veya `/clear` sonrası) sıfır ba
6
6
 
7
7
  1. `git status` ve `git diff --stat` ile bu oturumdaki değişiklikleri gör.
8
8
  2. `docs/workflow/progress.md`'yi güncelle (40 satırı geçmesin):
9
- - Son güncelleme tarihi, aktif faz, aktif görev
10
- - Şu anki durum: ne çalışıyor, ne yarım
11
- - Son oturumda yapılanlar (eskileri sil, sadece bu oturum)
12
- - Sıradaki adım: tek, net, hemen başlanabilir
13
- - Bekleyen kararlar (sorulup cevap alınamayanlar)
14
- - Açık sorunlar ve "AI için notlar"
15
- - Kalın etiketli satırların biçimini bozma (durum çubuğu ve pano okur)
16
- 3. `docs/product/roadmap.md`: biten görevler işaretli mi? Görev bittiyse ve kapsam kalkanı açık kaldıysa (`node .claude/hooks/freeze-guard.mjs --status`) kapat: `--plan-end`. Görev sürüyorsa açık kalsın.
9
+ - Tarih, aktif görev, sıradaki adım betikle yazılır (biçim bozulmaz): `node .claude/hooks/progress.mjs --task "<aktif görev veya ->" --next "<tek, net, hemen başlanabilir adım>"`. `/build` dışında yapılan bir iş varsa aynı çağrıya `--did "<tek satır>"` ekle (`/build` kendi satırını zaten yazdı).
10
+ - Elle: "Son oturumda yapılanlar"dan önceki oturumların satırlarını sil; aktif faz, şu anki durum (ne çalışıyor, ne yarım), bekleyen kararlar (sorulup cevap alınamayanlar), açık sorunlar ve "AI için notlar"
11
+ - En sonda `node .claude/hooks/progress.mjs --check`: kalın etiketli satırlar bozulduysa söyler (durum çubuğu ve pano okur)
12
+ 3. `docs/product/roadmap.md`: biten görevler işaretli mi? İşaretsizse `node .claude/hooks/progress.mjs --done G-NNN`. Görev bittiyse ve kapsam kalkanı açık kaldıysa (`node .claude/hooks/freeze-guard.mjs --status`) kapat: `--plan-end`. Görev sürüyorsa açık kalsın.
17
13
  4. `CHANGELOG.md` → "Yayınlanmamış" bölümüne kullanıcıya görünen değişiklikleri ekle.
18
14
  5. Bu oturumdaki tüm kararlar `docs/decisions/log.md` günlüğünde mi? Eksik olanları ekle.
19
15
  6. Yapı değiştiyse (yeni tablo, servis, klasör) `docs/architecture/overview.md`'yi güncelle.
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.39.3-2a78d6?style=flat-square"></a>
9
+ <a href="kit/CHANGELOG.md"><img alt="Version" src="https://img.shields.io/badge/version-3.39.4-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.39.3-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.39.4-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">
package/kit/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
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.39.4] - 2026-10-27
7
+
8
+ ### Düzeltilen
9
+ - **Türkiye eki: iyzico ödeme kimliği 2^53 üstünde reddedilir.** `iyziPaymentId` JSON sayısı olarak gelir; JavaScript bu büyüklükte sayıyı yuvarlar ve yanlış kimlikle sipariş sorgulanabilirdi. Web SaaS imza doğrulaması artık yalnız güvenli tamsayıları kabul eder; saldırgan testine iki kontrol eklendi. Elle uyarla: projedeki `src/lib/payments/webhook-signature.ts` ve `tests/security/payment-webhook.mjs`.
10
+
11
+ ### Değişen
12
+ - **`/wrap-up` ilerleme dosyasını betikle yazar.** Tarih, aktif görev, sıradaki adım ve yol haritası işareti `progress.mjs` ile; sonda `--check` etiket biçimini doğrular.
13
+
6
14
  ## [3.39.3] - 2026-10-26
7
15
 
8
16
  ### Düzeltilen
package/kit/VERSION CHANGED
@@ -1 +1 @@
1
- 3.39.3
1
+ 3.39.4
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.39.3</b> Claude Code için başlangıç kiti · MIT</span>
290
+ <span class="pill"><b>v3.39.4</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>
@@ -1055,7 +1055,7 @@ Sıradaki: G-013 şifre sıfırlama · bekleyen karar: e-posta servisi</pre>
1055
1055
  <footer>
1056
1056
  <div class="container">
1057
1057
  <a class="brand" href="#top" style="font-size:16px"><svg class="mark" style="width:22px;height:22px"><use href="#mark"/></svg>TillerHand</a>
1058
- <span>Sürüm 3.39.3 · <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>
1058
+ <span>Sürüm 3.39.4 · <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>
1059
1059
  </div>
1060
1060
  </footer>
1061
1061
 
@@ -21,7 +21,8 @@ IYZICO_CHECKOUT = (
21
21
 
22
22
 
23
23
  def _text(value: object) -> str | None:
24
- # Only non-empty strings and integers are signed values; anything else fails the check
24
+ # Only non-empty strings and integers are signed values; anything else fails the check.
25
+ # json.loads keeps big integers exact, so unlike the TypeScript copy there is no 2^53 limit here.
25
26
  if isinstance(value, bool) or not isinstance(value, (str, int)):
26
27
  return None
27
28
  return str(value) or None
@@ -9,8 +9,10 @@ const same = (a: string, b: string): boolean => {
9
9
  return x.length === y.length && timingSafeEqual(x, y);
10
10
  };
11
11
  const hmac = (key: string, text: string, encoding: 'hex' | 'base64'): string => createHmac('sha256', key).update(text).digest(encoding);
12
- // Only non-empty strings and numbers are signed values; anything else (missing, object, boolean) fails the check
13
- const text = (v: unknown): string | null => ((typeof v === 'string' || typeof v === 'number') && String(v) !== '' ? String(v) : null);
12
+ // Only non-empty strings and safe integers are signed values; anything else (missing, object, boolean) fails the check.
13
+ // iyziPaymentId is a JSON number (long): above 2^53 JSON.parse has already rounded it, so the id is wrong and is rejected.
14
+ // shortcut: such a notification is refused (ids are ~8 digits today); if ids near 2^53, read it with a JSON.parse reviver's context.source.
15
+ const text = (v: unknown): string | null => (typeof v === 'string' ? v || null : Number.isSafeInteger(v) ? String(v) : null);
14
16
 
15
17
  const IYZICO_DIRECT = ['iyziEventType', 'paymentId', 'paymentConversationId', 'status'];
16
18
  const IYZICO_CHECKOUT = ['iyziEventType', 'iyziPaymentId', 'token', 'paymentConversationId', 'status'];
@@ -25,6 +25,15 @@ test('iyzico: a correctly signed notification is accepted (direct and checkout f
25
25
  assert.equal(verifyIyzico(direct, iyzicoSign(direct), SECRET), true);
26
26
  assert.equal(verifyIyzico(checkout, iyzicoSign(checkout), SECRET), true);
27
27
  assert.equal(verifyIyzico(direct, iyzicoSign(direct).toUpperCase(), SECRET), true, 'hex case does not matter');
28
+ const numeric = { ...checkout, iyziPaymentId: 22416751 };
29
+ assert.equal(verifyIyzico(numeric, iyzicoSign(numeric), SECRET), true, 'iyziPaymentId as a JSON number (long)');
30
+ });
31
+
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"}');
34
+ const sent = { ...body, iyziPaymentId: '9007199254740993' };
35
+ assert.equal(verifyIyzico(body, iyzicoSign(sent), SECRET), false);
36
+ assert.equal(verifyIyzico(body, iyzicoSign(body), SECRET), false, 'even when signed over the rounded value');
28
37
  });
29
38
 
30
39
  test('iyzico: forged, altered or unsigned notifications are rejected', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tillerhand",
3
- "version": "3.39.3",
3
+ "version": "3.39.4",
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",