wormclaude 1.0.141 → 1.0.142

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.
package/dist/theme.js CHANGED
@@ -16,4 +16,4 @@ export const theme = {
16
16
  synType: '#a78bfa', // tip/sınıf adları, sabitler
17
17
  synProp: '#e0e0e0', // özellik/anahtar adları
18
18
  };
19
- export const VERSION = '1.0.141';
19
+ export const VERSION = '1.0.142';
package/dist/tui.js CHANGED
@@ -28,6 +28,20 @@ function fmtDur(ms) {
28
28
  const s = Math.max(0, Math.floor(ms / 1000));
29
29
  return s >= 60 ? `${Math.floor(s / 60)}m ${s % 60}s` : `${s}s`;
30
30
  }
31
+ // Kullanıcı mesajının dilini tespit et → UI etiketleri (Oluşturulacak/Create file, Yazıldı/Wrote…)
32
+ // konuşma diline uysun. Belirsizse null döner (mevcut dili koru).
33
+ const _TR_HINT = /[çğışöüÇĞİŞÖÜ]|\b(bir|bu|ve|ile|için|nasıl|nedir|var|olan|bana|beni|merhaba|selam|tamam|evet|hayır|değil|çok|yap|yapar|oluştur|kur|yaz|dosya|çalıştır|göster|aç|sil|ekle|değiştir|düzelt|kod|site|uygulama|sunucu|güvenlik|tarama|anlat|nerede|neden|hangisi)\b/i;
34
+ const _EN_HINT = /^(write|make|create|build|fix|add|remove|update|show|run|test|the|what|how|why|where|can you|could you|please|i want|i need|give|generate|implement|explain|tell me|help me)\b/i;
35
+ function _detectMsgLang(text) {
36
+ const s = (text || '').trim();
37
+ if (!s)
38
+ return null;
39
+ if (_TR_HINT.test(s))
40
+ return 'tr';
41
+ if (_EN_HINT.test(s))
42
+ return 'en';
43
+ return null;
44
+ }
31
45
  // Dosya yolunu çalışma alanına göreli göster (Claude tarzı: "todo/index.html"), yoksa olduğu gibi.
32
46
  function relWs(fp) {
33
47
  try {
@@ -95,6 +109,7 @@ export async function runTui() {
95
109
  ];
96
110
  const displayItems = [{ kind: 'banner' }];
97
111
  let inputBuf = '', inputCur = 0, busy = false, streamChars = 0, spin = 0;
112
+ let turnAbort = null; // ESC ile çalışan turu durdurma
98
113
  let taskStart = 0; // görev başlangıç zamanı (spinner'da geçen süre için)
99
114
  // Canlı akış artık FOOTER'da DEĞİL — içerik akışına (mesajın altından aşağı) satır-satır basılır.
100
115
  const SPIN = ['·', '✢', '✳', '✶', '✻', '✽', '✶', '✳', '✢'];
@@ -300,6 +315,11 @@ export async function runTui() {
300
315
  busy = true;
301
316
  streamChars = 0;
302
317
  taskStart = Date.now();
318
+ turnAbort = new AbortController(); // ESC ile durdurulabilsin
319
+ // UI dili konuşma diline uysun (etiketler: Oluşturulacak/Create file, Yazıldı/Wrote…)
320
+ const _ml = _detectMsgLang(userText);
321
+ if (_ml && _ml !== getLang())
322
+ setLang(_ml);
303
323
  if (displayText !== undefined)
304
324
  printItem({ kind: 'user', text: displayText }); // skill/@mention: gösterim farklı
305
325
  history.push({ role: 'user', content: userText });
@@ -310,6 +330,8 @@ export async function runTui() {
310
330
  let reactiveRetried = false; // bağlam taşmasında bir kez compact+retry
311
331
  try {
312
332
  for (let iter = 0; iter < 25; iter++) {
333
+ if (turnAbort?.signal.aborted)
334
+ break; // ESC ile durduruldu
313
335
  streamChars = 0;
314
336
  // Oto-compact: bağlam eşiği aşılınca otomatik özetle (uzun sohbet patlamasın)
315
337
  if (shouldAutoCompact(history)) {
@@ -358,7 +380,7 @@ export async function runTui() {
358
380
  refresh(); // footer'ı dibe yeniden sabitle
359
381
  };
360
382
  let gotCtxErr = false;
361
- for await (const ev of streamChat(history, allToolSchemas(), config)) {
383
+ for await (const ev of streamChat(history, allToolSchemas(), config, turnAbort?.signal)) {
362
384
  if (ev.type === 'text') {
363
385
  answer += ev.text;
364
386
  streamChars = answer.length;
@@ -378,6 +400,8 @@ export async function runTui() {
378
400
  }
379
401
  }
380
402
  flushStream(true); // kalan yarım satırı bas
403
+ if (turnAbort?.signal.aborted)
404
+ break; // ESC → araçları çalıştırma, dur
381
405
  // Reactive compact: bağlam taştıysa bir kez özetle ve turu tekrarla → "token bitti, yazılmıyor" olmaz.
382
406
  if (gotCtxErr && !reactiveRetried) {
383
407
  reactiveRetried = true;
@@ -468,6 +492,7 @@ export async function runTui() {
468
492
  busy = false;
469
493
  perm = null;
470
494
  ask = null;
495
+ turnAbort = null;
471
496
  refresh();
472
497
  // Web-öğrenme: web'de arayıp cevap ürettiyse {soru→cevap}'ı eğitim datasına ekle
473
498
  if (usedWeb && lastAnswer) {
@@ -814,6 +839,12 @@ export async function runTui() {
814
839
  return;
815
840
  }
816
841
  if (key && key.name === 'escape') {
842
+ // Tur çalışıyorsa ESC = modeli DURDUR (akış/araç döngüsünü kes). Boştaysa input'u temizle.
843
+ if (busy && turnAbort) {
844
+ turnAbort.abort();
845
+ printItem({ kind: 'note', text: getLang() === 'en' ? '■ Stopped (Esc). You can type a new message.' : '■ Durduruldu (Esc). Yeni mesaj yazabilirsin.' });
846
+ return;
847
+ }
817
848
  inputBuf = '';
818
849
  inputCur = 0;
819
850
  refresh();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wormclaude",
3
- "version": "1.0.141",
3
+ "version": "1.0.142",
4
4
  "description": "WormClaude CLI - uncensored security+code assistant (ink TUI, Claude-style)",
5
5
  "type": "module",
6
6
  "bin": {