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 +1 -1
- package/dist/tui.js +32 -1
- package/package.json +1 -1
package/dist/theme.js
CHANGED
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();
|