wormclaude 1.0.57 → 1.0.59
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/ansi.js +10 -3
- package/dist/highlight.js +7 -0
- package/dist/i18n.js +56 -8
- package/dist/theme.js +1 -1
- package/dist/tui.js +31 -25
- package/package.json +1 -1
package/dist/ansi.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// stdout'a BİR KEZ yazılır; ink yalnız canlı footer'ı yönetir. Böylece doğal kaydırma +
|
|
4
4
|
// metin seçip kopyalama çalışır. Markdown + sözdizimi vurgusu burada ANSI'ye çevrilir.
|
|
5
5
|
import { theme } from './theme.js';
|
|
6
|
-
import { highlight } from './highlight.js';
|
|
6
|
+
import { highlight, isHighlightable } from './highlight.js';
|
|
7
7
|
import { t } from './i18n.js';
|
|
8
8
|
const RESET = '\x1b[0m';
|
|
9
9
|
function hexAnsi(hex) {
|
|
@@ -90,8 +90,15 @@ export function markdownAnsi(text, cols) {
|
|
|
90
90
|
const flushCode = () => {
|
|
91
91
|
if (lang)
|
|
92
92
|
out.push(paint(' ' + lang, theme.greyDim));
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
if (isHighlightable(lang)) {
|
|
94
|
+
for (const toks of highlight(code.join('\n'), lang)) {
|
|
95
|
+
out.push(paint('│ ', theme.greyDim) + (toks.length ? toks.map((tk) => paint(tk.text, tk.color)).join('') : ' '));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// Dilsiz/düz-metin blok: çubuk + nötr renk, sözdizimi-vurgusu YOK (saçma renk olmaz).
|
|
100
|
+
for (const ln of code)
|
|
101
|
+
out.push(paint('│ ', theme.greyDim) + paint(ln || ' ', theme.grey));
|
|
95
102
|
}
|
|
96
103
|
code = [];
|
|
97
104
|
lang = '';
|
package/dist/highlight.js
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
// Kod bloklarını dile göre token'lara böler; her token'a tema rengi atar. Asla patlamaz —
|
|
3
3
|
// tanımadığı dilde ortak kurallarla (string/sayı/yorum/anahtar kelime) renklendirir.
|
|
4
4
|
import { theme } from './theme.js';
|
|
5
|
+
// Sözdizimi-vurgusu YALNIZ gerçek programlama dili etiketli bloklarda yapılır.
|
|
6
|
+
// Dil yoksa/düz-metin/markdown ise → renklendirme YOK (yoksa düz nesir "kod" sanılıp
|
|
7
|
+
// büyük-harfli kelimeler "tip", `in` gibi kelimeler "keyword" diye saçma renklenir).
|
|
8
|
+
const NON_CODE = new Set(['', 'text', 'txt', 'plain', 'plaintext', 'markdown', 'md', 'prose', 'none', 'output', 'log', 'console', 'raw']);
|
|
9
|
+
export function isHighlightable(lang) {
|
|
10
|
+
return !NON_CODE.has((lang || '').trim().toLowerCase());
|
|
11
|
+
}
|
|
5
12
|
// Dil bazlı anahtar kelime setleri (ortak + spesifik).
|
|
6
13
|
const KW = {
|
|
7
14
|
js: ['const', 'let', 'var', 'function', 'return', 'if', 'else', 'for', 'while', 'do', 'switch', 'case', 'break', 'continue', 'new', 'class', 'extends', 'super', 'this', 'typeof', 'instanceof', 'in', 'of', 'await', 'async', 'yield', 'try', 'catch', 'finally', 'throw', 'import', 'export', 'from', 'default', 'delete', 'void', 'null', 'undefined', 'true', 'false'],
|
package/dist/i18n.js
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
// Çoklu dil (TR/EN) — arayüz metinleri. İlk açılışta dil seçilir, .wormclaude/settings.json'a yazılır.
|
|
2
2
|
import * as fs from 'node:fs';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
|
-
|
|
4
|
+
import * as os from 'node:os';
|
|
5
|
+
let current = 'en'; // varsayılan: İngilizce (ilk kurulum). loadLang() kayıtlıysa onu uygular.
|
|
5
6
|
export function setLang(l) { current = l; }
|
|
6
7
|
export function getLang() { return current; }
|
|
7
|
-
//
|
|
8
|
-
|
|
8
|
+
// GLOBAL ayar: bir kez seçilince TÜM klasörlerde geçerli (~/.wormclaude/settings.json).
|
|
9
|
+
// (Önceden process.cwd()'ye yazılıyordu → her klasörde sıfırlanıyordu. Artık ev dizini.)
|
|
10
|
+
const SETTINGS = path.join(os.homedir(), '.wormclaude', 'settings.json');
|
|
11
|
+
// Geriye-uyum: eski proje-yerel ayar varsa onu da oku (yalnız global yoksa).
|
|
12
|
+
const LEGACY_SETTINGS = path.join(process.cwd(), '.wormclaude', 'settings.json');
|
|
9
13
|
export function loadLang() {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
for (const p of [SETTINGS, LEGACY_SETTINGS]) {
|
|
15
|
+
try {
|
|
16
|
+
const j = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
17
|
+
if (j.lang === 'tr' || j.lang === 'en')
|
|
18
|
+
return j.lang;
|
|
19
|
+
}
|
|
20
|
+
catch { }
|
|
14
21
|
}
|
|
15
|
-
catch { }
|
|
16
22
|
return null;
|
|
17
23
|
}
|
|
18
24
|
export function saveLang(l) {
|
|
@@ -67,6 +73,27 @@ const STR = {
|
|
|
67
73
|
'mcp.errors': ' · {0} hata ({1})',
|
|
68
74
|
'pill.running': '⏳ {0} çalışıyor',
|
|
69
75
|
'pill.done': '✓ {0} görev bitti',
|
|
76
|
+
'tui.footerHint': '/ komutlar · ↑↓ geçmiş · /kopyala · Ctrl+C çıkış',
|
|
77
|
+
'tui.working': 'çalışıyor…',
|
|
78
|
+
'tui.chars': 'karakter',
|
|
79
|
+
'tui.pasteSummary': '…(+{0} satır · {1} karakter, Enter ile gönder)',
|
|
80
|
+
'tui.permLabel': 'İZİN',
|
|
81
|
+
'tui.permRun': 'çalıştırılsın mı?',
|
|
82
|
+
'tui.permYes': '[E] Evet',
|
|
83
|
+
'tui.permAll': '[T] Tümüne izin',
|
|
84
|
+
'tui.permNo': '[H] Hayır',
|
|
85
|
+
'tui.ok': 'Tamam',
|
|
86
|
+
'tui.ctrlcExit': 'Çıkmak için tekrar Ctrl+C (veya /cikis). Kopyalama Ctrl+C\'yi etkilemez.',
|
|
87
|
+
'tui.copied': '✓ Panoya kopyalandı ({0} karakter).',
|
|
88
|
+
'tui.nothingCopy': 'Kopyalanacak yanıt yok.',
|
|
89
|
+
'tui.mcpConnected': '🔌 {0} MCP sunucusu bağlandı',
|
|
90
|
+
'tui.autoCompacted': '✎ bağlam otomatik özetlendi',
|
|
91
|
+
'tui.loopStop': 'Aynı adım tekrarlandı, döngü önlemek için durduruldu.',
|
|
92
|
+
'tui.connErr': '[bağlantı hatası: {0}]',
|
|
93
|
+
'tui.learned': '✎ eğitim datasına eklendi',
|
|
94
|
+
'tui.userCancel': 'kullanıcı iptal etti',
|
|
95
|
+
'tui.cmdErr': 'Komut hatası: {0}',
|
|
96
|
+
'tui.langSet': 'Dil değiştirildi: Türkçe',
|
|
70
97
|
},
|
|
71
98
|
en: {
|
|
72
99
|
'lang.title': 'Select language / Dil seçin',
|
|
@@ -106,6 +133,27 @@ const STR = {
|
|
|
106
133
|
'mcp.errors': ' · {0} error ({1})',
|
|
107
134
|
'pill.running': '⏳ {0} running',
|
|
108
135
|
'pill.done': '✓ {0} task(s) done',
|
|
136
|
+
'tui.footerHint': '/ commands · ↑↓ history · /copy · Ctrl+C exit',
|
|
137
|
+
'tui.working': 'working…',
|
|
138
|
+
'tui.chars': 'chars',
|
|
139
|
+
'tui.pasteSummary': '…(+{0} lines · {1} chars, Enter to send)',
|
|
140
|
+
'tui.permLabel': 'PERMISSION',
|
|
141
|
+
'tui.permRun': 'run it?',
|
|
142
|
+
'tui.permYes': '[Y] Yes',
|
|
143
|
+
'tui.permAll': '[A] Allow all',
|
|
144
|
+
'tui.permNo': '[N] No',
|
|
145
|
+
'tui.ok': 'OK',
|
|
146
|
+
'tui.ctrlcExit': 'Press Ctrl+C again to exit (or /quit). Copying does not trigger Ctrl+C.',
|
|
147
|
+
'tui.copied': '✓ Copied to clipboard ({0} chars).',
|
|
148
|
+
'tui.nothingCopy': 'No response to copy.',
|
|
149
|
+
'tui.mcpConnected': '🔌 {0} MCP server(s) connected',
|
|
150
|
+
'tui.autoCompacted': '✎ context auto-summarized',
|
|
151
|
+
'tui.loopStop': 'Same step repeated, stopped to avoid a loop.',
|
|
152
|
+
'tui.connErr': '[connection error: {0}]',
|
|
153
|
+
'tui.learned': '✎ added to training data',
|
|
154
|
+
'tui.userCancel': 'user cancelled',
|
|
155
|
+
'tui.cmdErr': 'Command error: {0}',
|
|
156
|
+
'tui.langSet': 'Language changed: English',
|
|
109
157
|
},
|
|
110
158
|
};
|
|
111
159
|
// Komut açıklamaları (slash menüsü + /help)
|
package/dist/theme.js
CHANGED
package/dist/tui.js
CHANGED
|
@@ -12,7 +12,7 @@ import { itemAnsi, markdownAnsi } from './ansi.js';
|
|
|
12
12
|
import { theme, VERSION } from './theme.js';
|
|
13
13
|
import { cleanModelText } from './textclean.js';
|
|
14
14
|
import { COMMANDS, runSlashCommand } from './commands.js';
|
|
15
|
-
import { cmdDesc } from './i18n.js';
|
|
15
|
+
import { cmdDesc, t, setLang, loadLang } from './i18n.js';
|
|
16
16
|
import { getSkill, getSkills, buildSkillPrompt } from './skills.js';
|
|
17
17
|
import { getExtCommand, getExtCommands, buildExtCommandPrompt } from './extensions.js';
|
|
18
18
|
import { resolveAtMentions } from './atmention.js';
|
|
@@ -49,6 +49,7 @@ function fit(line, max) {
|
|
|
49
49
|
const vis = (s) => stringWidth(s.replace(/\x1b\[[0-9;]*m/g, ''));
|
|
50
50
|
const padVis = (s, w) => s + ' '.repeat(Math.max(0, w - vis(s))); // görünür genişliğe boşluk doldur
|
|
51
51
|
export async function runTui() {
|
|
52
|
+
setLang(loadLang() || 'en'); // kayıtlı dil varsa onu, yoksa İngilizce (ilk kurulum)
|
|
52
53
|
const config = loadConfig();
|
|
53
54
|
let account = { plan: '', email: '', name: '' };
|
|
54
55
|
// Ortam bağlamı (Windows/cwd) — model DOĞRU yol/komut kullansın (yoksa /home/user gibi yanlış yol yazar).
|
|
@@ -92,7 +93,7 @@ export async function runTui() {
|
|
|
92
93
|
// Çok uzun (büyük yapıştırma): son birkaç satır + üstte özet — footer'ı doldurmaz.
|
|
93
94
|
const extra = wrapped.length - (MAX_INPUT_LINES - 1);
|
|
94
95
|
const tail = wrapped.slice(-(MAX_INPUT_LINES - 1));
|
|
95
|
-
const head = paint(
|
|
96
|
+
const head = paint('✶ ' + t('tui.pasteSummary', extra, inputBuf.length), theme.greyDim);
|
|
96
97
|
return [head, ...tail.map((ln, i) => ' ' + paint(ln, theme.white) + (i === tail.length - 1 ? paint('▌', theme.greyDim) : ''))];
|
|
97
98
|
};
|
|
98
99
|
// Footer yüksekliği DİNAMİK: izin=4; değilse (durum/menü) + çizgi + giriş-satırları + çizgi.
|
|
@@ -146,7 +147,7 @@ export async function runTui() {
|
|
|
146
147
|
await runSlashCommand(v, cmdCtx);
|
|
147
148
|
}
|
|
148
149
|
catch (e) {
|
|
149
|
-
printItem({ kind: 'note', text: '
|
|
150
|
+
printItem({ kind: 'note', text: t('tui.cmdErr', e?.message || e) });
|
|
150
151
|
}
|
|
151
152
|
clearInterval(timer);
|
|
152
153
|
busy = false;
|
|
@@ -186,9 +187,9 @@ export async function runTui() {
|
|
|
186
187
|
let body;
|
|
187
188
|
if (perm) {
|
|
188
189
|
// İzin dialogu: araç adı + Evet/Tümü/Hayır
|
|
189
|
-
const q = paint('
|
|
190
|
-
const opts = paint('
|
|
191
|
-
+ paint('
|
|
190
|
+
const q = paint(' ' + t('tui.permLabel') + ' ', theme.redBright, true) + paint(perm.label, theme.white) + paint(' ' + t('tui.permRun'), theme.grey);
|
|
191
|
+
const opts = paint(' ' + t('tui.permYes'), theme.redBright, true) + paint(' · ', theme.greyDim)
|
|
192
|
+
+ paint(t('tui.permAll'), theme.grey) + paint(' · ', theme.greyDim) + paint(t('tui.permNo'), theme.grey);
|
|
192
193
|
body = [line, q, opts, line];
|
|
193
194
|
}
|
|
194
195
|
else if (ask) {
|
|
@@ -215,8 +216,8 @@ export async function runTui() {
|
|
|
215
216
|
else {
|
|
216
217
|
const g = ctxUsed ? paint(' ' + ctxGauge(), theme.greyDim) : '';
|
|
217
218
|
const status = busy
|
|
218
|
-
? paint(` ${SPIN[spin % SPIN.length]}
|
|
219
|
-
: paint('
|
|
219
|
+
? paint(` ${SPIN[spin % SPIN.length]} ${t('tui.working')}${streamChars ? ' ' + streamChars + ' ' + t('tui.chars') : ''}`, theme.grey) + g
|
|
220
|
+
: paint(' ' + t('tui.footerHint'), theme.greyDim) + g;
|
|
220
221
|
body = [status, line, ...inputLines, line];
|
|
221
222
|
}
|
|
222
223
|
}
|
|
@@ -265,7 +266,7 @@ export async function runTui() {
|
|
|
265
266
|
const { history: nh } = await runCompact(history, config);
|
|
266
267
|
history.length = 0;
|
|
267
268
|
history.push(...nh);
|
|
268
|
-
printItem({ kind: 'note', text: '
|
|
269
|
+
printItem({ kind: 'note', text: t('tui.autoCompacted') });
|
|
269
270
|
}
|
|
270
271
|
catch { }
|
|
271
272
|
}
|
|
@@ -339,7 +340,7 @@ export async function runTui() {
|
|
|
339
340
|
lastSig = sig;
|
|
340
341
|
}
|
|
341
342
|
if (sameCount >= 2) {
|
|
342
|
-
printItem({ kind: 'note', text: '
|
|
343
|
+
printItem({ kind: 'note', text: t('tui.loopStop') });
|
|
343
344
|
break;
|
|
344
345
|
}
|
|
345
346
|
const results = await executeToolCalls(toolCalls, {
|
|
@@ -349,7 +350,7 @@ export async function runTui() {
|
|
|
349
350
|
perm = { label: toolLabel(c.name, args), name: c.name, resolve };
|
|
350
351
|
refresh();
|
|
351
352
|
}),
|
|
352
|
-
ask: (q) => new Promise((resolve) => { ask = { question: q.question, options: q.options.length ? q.options : [{ label: '
|
|
353
|
+
ask: (q) => new Promise((resolve) => { ask = { question: q.question, options: q.options.length ? q.options : [{ label: t('tui.ok') }], sel: 0, resolve }; refresh(); }),
|
|
353
354
|
onResult: (c, _i, res) => { if ((c.name === 'WebSearch' || c.name === 'WebFetch') && res.ok)
|
|
354
355
|
usedWeb = true; printItem({ kind: 'tool', label: toolLabel(c.name, res.args), result: sanitizeOutput(res.output), ok: res.ok }); },
|
|
355
356
|
});
|
|
@@ -358,7 +359,7 @@ export async function runTui() {
|
|
|
358
359
|
}
|
|
359
360
|
}
|
|
360
361
|
catch (e) {
|
|
361
|
-
printItem({ kind: 'note', text:
|
|
362
|
+
printItem({ kind: 'note', text: t('tui.connErr', e?.message || e) });
|
|
362
363
|
}
|
|
363
364
|
clearInterval(timer);
|
|
364
365
|
busy = false;
|
|
@@ -369,7 +370,7 @@ export async function runTui() {
|
|
|
369
370
|
if (usedWeb && lastAnswer) {
|
|
370
371
|
const sources = (lastAnswer.match(/https?:\/\/[^\s<>"')\]]+/g) || []).slice(0, 8);
|
|
371
372
|
if (recordLearned(userText, lastAnswer, sources, config))
|
|
372
|
-
printItem({ kind: 'note', text: '
|
|
373
|
+
printItem({ kind: 'note', text: t('tui.learned') });
|
|
373
374
|
}
|
|
374
375
|
// Oto-hafıza: eşik geçildiyse arka planda hafızayı güncelle
|
|
375
376
|
if (shouldExtract(history))
|
|
@@ -390,7 +391,7 @@ export async function runTui() {
|
|
|
390
391
|
redrawAll();
|
|
391
392
|
} }).catch(() => { });
|
|
392
393
|
connectMcpServers().then((srv) => { if (srv && srv.length)
|
|
393
|
-
printItem({ kind: 'note', text:
|
|
394
|
+
printItem({ kind: 'note', text: t('tui.mcpConnected', srv.length) }); }).catch(() => { }); // MCP araçları (varsa)
|
|
394
395
|
const quit = () => { process.stdout.write('\x1b[r\x1b[?25h\x1b[2J\x1b[3J\x1b[H'); process.exit(0); };
|
|
395
396
|
process.on('exit', () => { try {
|
|
396
397
|
process.stdout.write('\x1b[r\x1b[?25h');
|
|
@@ -438,26 +439,26 @@ export async function runTui() {
|
|
|
438
439
|
const r = perm.resolve, nm = perm.name;
|
|
439
440
|
if (key && key.ctrl && key.name === 'c') {
|
|
440
441
|
perm = null;
|
|
441
|
-
r({ deny: '
|
|
442
|
+
r({ deny: t('tui.userCancel') });
|
|
442
443
|
refresh();
|
|
443
444
|
return;
|
|
444
445
|
}
|
|
445
|
-
if (k === 'e' || k === '1' || (key && key.name === 'return')) {
|
|
446
|
+
if (k === 'e' || k === 'y' || k === '1' || (key && key.name === 'return')) {
|
|
446
447
|
perm = null;
|
|
447
448
|
r('allow');
|
|
448
449
|
refresh();
|
|
449
|
-
}
|
|
450
|
-
else if (k === 't' || k === '2') {
|
|
450
|
+
} // Evet / Yes
|
|
451
|
+
else if (k === 't' || k === 'a' || k === '2') {
|
|
451
452
|
allowAll.add(nm);
|
|
452
453
|
perm = null;
|
|
453
454
|
r('allow');
|
|
454
455
|
refresh();
|
|
455
|
-
}
|
|
456
|
-
else if (k === 'h' || k === '3' || (key && key.name === 'escape')) {
|
|
456
|
+
} // Tümü / Allow all
|
|
457
|
+
else if (k === 'h' || k === 'n' || k === '3' || (key && key.name === 'escape')) {
|
|
457
458
|
perm = null;
|
|
458
459
|
r({ deny: '' });
|
|
459
460
|
refresh();
|
|
460
|
-
}
|
|
461
|
+
} // Hayır / No
|
|
461
462
|
return;
|
|
462
463
|
}
|
|
463
464
|
if (key && key.ctrl && key.name === 'c') {
|
|
@@ -471,7 +472,7 @@ export async function runTui() {
|
|
|
471
472
|
quit();
|
|
472
473
|
}
|
|
473
474
|
ctrlcAt = now;
|
|
474
|
-
printItem({ kind: 'note', text:
|
|
475
|
+
printItem({ kind: 'note', text: t('tui.ctrlcExit') });
|
|
475
476
|
return;
|
|
476
477
|
}
|
|
477
478
|
if (key && key.ctrl && key.name === 'd') {
|
|
@@ -541,7 +542,7 @@ export async function runTui() {
|
|
|
541
542
|
executeTool('Bash', { command: cmd }).then((res) => {
|
|
542
543
|
printItem({ kind: 'tool', label: `! ${cmd.slice(0, 60)}`, result: sanitizeOutput(res.output), ok: res.ok });
|
|
543
544
|
history.push({ role: 'user', content: `Şu shell komutunu çalıştırdım:\n\`\`\`\n${cmd}\n\`\`\`\nÇıktı:\n\`\`\`\n${(res.output || '').slice(0, 4000)}\n\`\`\`` });
|
|
544
|
-
}).catch((e) => printItem({ kind: 'note', text: '
|
|
545
|
+
}).catch((e) => printItem({ kind: 'note', text: t('tui.cmdErr', e?.message || e) }))
|
|
545
546
|
.finally(() => { busy = false; refresh(); });
|
|
546
547
|
return;
|
|
547
548
|
}
|
|
@@ -563,10 +564,10 @@ export async function runTui() {
|
|
|
563
564
|
const last = [...history].reverse().find((mm) => mm.role === 'assistant');
|
|
564
565
|
if (last) {
|
|
565
566
|
process.stdout.write(`\x1b]52;c;${Buffer.from(last.content, 'utf8').toString('base64')}\x07`);
|
|
566
|
-
printItem({ kind: 'note', text:
|
|
567
|
+
printItem({ kind: 'note', text: t('tui.copied', last.content.length) });
|
|
567
568
|
}
|
|
568
569
|
else
|
|
569
|
-
printItem({ kind: 'note', text: '
|
|
570
|
+
printItem({ kind: 'note', text: t('tui.nothingCopy') });
|
|
570
571
|
return;
|
|
571
572
|
}
|
|
572
573
|
const builtin = COMMANDS.some((c) => c.name === tok);
|
|
@@ -582,6 +583,11 @@ export async function runTui() {
|
|
|
582
583
|
runTurn(buildExtCommandPrompt(ext, a), `/${ext.name}${a ? ' ' + a : ''}`);
|
|
583
584
|
return;
|
|
584
585
|
}
|
|
586
|
+
// /lang|/dil: dil değişince banner alt-yazısı + footer yeni dilde olsun → tüm ekranı yeniden çiz
|
|
587
|
+
if (tok === '/lang') {
|
|
588
|
+
runCommand(v).then(() => redrawAll());
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
585
591
|
runCommand(v);
|
|
586
592
|
return;
|
|
587
593
|
}
|