wormclaude 1.0.43 → 1.0.44
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 +109 -24
- package/package.json +1 -1
package/dist/theme.js
CHANGED
package/dist/tui.js
CHANGED
|
@@ -11,6 +11,7 @@ import { sanitizeOutput } from './errorsan.js';
|
|
|
11
11
|
import { itemAnsi } from './ansi.js';
|
|
12
12
|
import { theme, VERSION } from './theme.js';
|
|
13
13
|
import { cleanModelText } from './textclean.js';
|
|
14
|
+
import { COMMANDS, runSlashCommand } from './commands.js';
|
|
14
15
|
const RESET = '\x1b[0m';
|
|
15
16
|
const hex = (h) => { const m = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(h); return m ? `\x1b[38;2;${parseInt(m[1], 16)};${parseInt(m[2], 16)};${parseInt(m[3], 16)}m` : ''; };
|
|
16
17
|
const paint = (s, c, bold = false) => `${bold ? '\x1b[1m' : ''}${c ? hex(c) : ''}${s}${RESET}`;
|
|
@@ -59,13 +60,52 @@ export async function runTui() {
|
|
|
59
60
|
const allowAll = new Set(); // "Tümüne izin" denen araçlar (oturum boyu)
|
|
60
61
|
const inputHistory = []; // gönderilen mesajlar (↑/↓ ile geri çağrılır)
|
|
61
62
|
let histIdx = -1; // -1 = geçmişte gezinmiyor
|
|
62
|
-
|
|
63
|
+
let cmdSel = 0; // slash menüde seçili komut
|
|
64
|
+
// Slash menü: "/" ile başlayan girişe uyan komutlar
|
|
65
|
+
const cmdMatches = () => {
|
|
66
|
+
if (busy || !inputBuf.startsWith('/'))
|
|
67
|
+
return [];
|
|
68
|
+
const tok = inputBuf.split(' ')[0];
|
|
69
|
+
return COMMANDS.filter((c) => c.name.startsWith(tok));
|
|
70
|
+
};
|
|
71
|
+
// Slash komutları için bağlam (cli.tsx ile aynı arayüz) — /clear,/config,/model,/memory,/program…
|
|
72
|
+
const cmdCtx = {
|
|
73
|
+
config,
|
|
74
|
+
getHistory: () => history,
|
|
75
|
+
setHistory: (h) => { history.length = 0; history.push(...h); },
|
|
76
|
+
note: (text) => printItem({ kind: 'note', text }),
|
|
77
|
+
assistant: (text) => printItem({ kind: 'assistant', text }),
|
|
78
|
+
clearConv: () => { history.length = 1; displayItems.length = 1; redrawAll(); }, // sistem msg + banner kalır
|
|
79
|
+
exit: () => quit(),
|
|
80
|
+
};
|
|
81
|
+
async function runCommand(v) {
|
|
82
|
+
busy = true;
|
|
83
|
+
drawFooter();
|
|
84
|
+
const timer = setInterval(() => { spin++; if (busy && !perm)
|
|
85
|
+
drawFooter(); }, 120);
|
|
86
|
+
try {
|
|
87
|
+
await runSlashCommand(v, cmdCtx);
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
printItem({ kind: 'note', text: 'Komut hatası: ' + (e?.message || e) });
|
|
91
|
+
}
|
|
92
|
+
clearInterval(timer);
|
|
93
|
+
busy = false;
|
|
94
|
+
drawFooter();
|
|
95
|
+
}
|
|
96
|
+
// ── Hizalı bilgi başlığı (Version/Model/Plan/Context/Workspace) — responsive ──
|
|
63
97
|
function headerLines(W) {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
98
|
+
const ctx = (Number(process.env.WORMCLAUDE_CTX) || 12288).toLocaleString('tr-TR');
|
|
99
|
+
const rows = [
|
|
100
|
+
['Version', 'v' + VERSION, theme.red],
|
|
101
|
+
['Model', config.model, theme.redBright],
|
|
102
|
+
['Plan', (account.plan || '—').toUpperCase(), theme.white],
|
|
103
|
+
];
|
|
104
|
+
if (account.email)
|
|
105
|
+
rows.push(['Account', account.email, theme.grey]);
|
|
106
|
+
rows.push(['Context', ctx + ' tokens', theme.grey]);
|
|
107
|
+
rows.push(['Workspace', process.cwd(), theme.grey]);
|
|
108
|
+
return rows.map(([label, val, col]) => fit(' ' + paint(label.padEnd(11), theme.greyDim) + paint(val, col), W));
|
|
69
109
|
}
|
|
70
110
|
// ── Scroll region: üst = içerik (kayar), alt = sabit footer ──
|
|
71
111
|
function setRegion() {
|
|
@@ -91,10 +131,20 @@ export async function runTui() {
|
|
|
91
131
|
if (vis(shown) > avail)
|
|
92
132
|
shown = '…' + shown.slice(-(avail - 1));
|
|
93
133
|
const inputLine = paint('❯ ', theme.redBright, true) + paint(shown, theme.white) + paint('▌', theme.greyDim);
|
|
94
|
-
// Durum satırı KUTUNUN ÜSTÜNDE
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
134
|
+
// Durum satırı KUTUNUN ÜSTÜNDE: slash menü > spinner > ipucu.
|
|
135
|
+
const m = cmdMatches();
|
|
136
|
+
let status;
|
|
137
|
+
if (m.length) {
|
|
138
|
+
const sel = Math.min(cmdSel, m.length - 1);
|
|
139
|
+
const names = m.slice(0, 8).map((c, i) => i === sel ? paint(c.name, theme.redBright, true) : paint(c.name, theme.greyDim)).join(' ');
|
|
140
|
+
status = ' ' + names + paint(' ↹ tamamla · ↑↓ seç', theme.greyDim);
|
|
141
|
+
}
|
|
142
|
+
else if (busy) {
|
|
143
|
+
status = paint(` ${SPIN[spin % SPIN.length]} çalışıyor…${streamChars ? ' ' + streamChars + ' karakter' : ''}`, theme.grey);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
status = paint(' / komutlar · ↑↓ geçmiş · /kopyala · Ctrl+C çıkış', theme.greyDim);
|
|
147
|
+
}
|
|
98
148
|
body = [status, line, inputLine, line];
|
|
99
149
|
}
|
|
100
150
|
let out = '\x1b7'; // imleci kaydet
|
|
@@ -250,8 +300,14 @@ export async function runTui() {
|
|
|
250
300
|
if (key && key.ctrl && key.name === 'd') {
|
|
251
301
|
quit();
|
|
252
302
|
}
|
|
253
|
-
// ↑/↓ —
|
|
303
|
+
// ↑/↓ — slash menü açıksa komut seç, değilse geçmiş mesajlarda gezin
|
|
254
304
|
if (key && key.name === 'up') {
|
|
305
|
+
const m = cmdMatches();
|
|
306
|
+
if (m.length) {
|
|
307
|
+
cmdSel = (cmdSel - 1 + m.length) % m.length;
|
|
308
|
+
drawFooter();
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
255
311
|
if (inputHistory.length) {
|
|
256
312
|
histIdx = histIdx < 0 ? inputHistory.length - 1 : Math.max(0, histIdx - 1);
|
|
257
313
|
inputBuf = inputHistory[histIdx];
|
|
@@ -260,6 +316,12 @@ export async function runTui() {
|
|
|
260
316
|
return;
|
|
261
317
|
}
|
|
262
318
|
if (key && key.name === 'down') {
|
|
319
|
+
const m = cmdMatches();
|
|
320
|
+
if (m.length) {
|
|
321
|
+
cmdSel = (cmdSel + 1) % m.length;
|
|
322
|
+
drawFooter();
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
263
325
|
if (histIdx >= 0) {
|
|
264
326
|
histIdx++;
|
|
265
327
|
if (histIdx >= inputHistory.length) {
|
|
@@ -272,37 +334,59 @@ export async function runTui() {
|
|
|
272
334
|
}
|
|
273
335
|
return;
|
|
274
336
|
}
|
|
337
|
+
// Tab — seçili slash komutunu tamamla
|
|
338
|
+
if (key && key.name === 'tab') {
|
|
339
|
+
const m = cmdMatches();
|
|
340
|
+
if (m.length) {
|
|
341
|
+
inputBuf = m[Math.min(cmdSel, m.length - 1)].name + ' ';
|
|
342
|
+
cmdSel = 0;
|
|
343
|
+
drawFooter();
|
|
344
|
+
}
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
275
347
|
if (key && key.name === 'return') {
|
|
276
348
|
if (busy)
|
|
277
349
|
return; // tur sürerken Enter beklemede; yazılan metin durur (type-ahead)
|
|
278
|
-
|
|
350
|
+
let v = inputBuf.trim();
|
|
279
351
|
inputBuf = '';
|
|
280
352
|
histIdx = -1;
|
|
281
353
|
if (!v) {
|
|
282
354
|
drawFooter();
|
|
283
355
|
return;
|
|
284
356
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
if (
|
|
293
|
-
|
|
294
|
-
|
|
357
|
+
// Slash komutu: tam eşleşme yoksa menüde SEÇİLİ olanı kullan
|
|
358
|
+
if (v.startsWith('/')) {
|
|
359
|
+
const tok = v.split(' ')[0];
|
|
360
|
+
const matches = COMMANDS.filter((c) => c.name.startsWith(tok));
|
|
361
|
+
if (!COMMANDS.some((c) => c.name === tok) && matches.length)
|
|
362
|
+
v = matches[Math.min(cmdSel, matches.length - 1)].name;
|
|
363
|
+
cmdSel = 0;
|
|
364
|
+
if (v === '/cikis' || v === '/exit' || v === '/quit') {
|
|
365
|
+
quit();
|
|
366
|
+
return;
|
|
295
367
|
}
|
|
296
|
-
|
|
297
|
-
|
|
368
|
+
if (v === '/kopyala' || v === '/copy') {
|
|
369
|
+
const last = [...history].reverse().find((mm) => mm.role === 'assistant');
|
|
370
|
+
if (last) {
|
|
371
|
+
process.stdout.write(`\x1b]52;c;${Buffer.from(last.content, 'utf8').toString('base64')}\x07`);
|
|
372
|
+
printItem({ kind: 'note', text: `✓ Panoya kopyalandı (${last.content.length} karakter).` });
|
|
373
|
+
}
|
|
374
|
+
else
|
|
375
|
+
printItem({ kind: 'note', text: 'Kopyalanacak yanıt yok.' });
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
inputHistory.push(v);
|
|
379
|
+
runCommand(v);
|
|
298
380
|
return;
|
|
299
381
|
}
|
|
382
|
+
inputHistory.push(v); // geçmişe ekle (↑ ile geri çağrılır)
|
|
300
383
|
printItem({ kind: 'user', text: v });
|
|
301
384
|
runTurn(v);
|
|
302
385
|
return;
|
|
303
386
|
}
|
|
304
387
|
if (key && key.name === 'backspace') {
|
|
305
388
|
inputBuf = inputBuf.slice(0, -1);
|
|
389
|
+
cmdSel = 0;
|
|
306
390
|
drawFooter();
|
|
307
391
|
return;
|
|
308
392
|
}
|
|
@@ -314,6 +398,7 @@ export async function runTui() {
|
|
|
314
398
|
// sadece gerçek yazdırılabilir karakter (her zaman → cevap üretilirken bile type-ahead)
|
|
315
399
|
if (str && !key?.ctrl && !key?.meta && !str.startsWith('\x1b') && !/[\x00-\x1f]/.test(str)) {
|
|
316
400
|
inputBuf += str;
|
|
401
|
+
cmdSel = 0;
|
|
317
402
|
drawFooter();
|
|
318
403
|
}
|
|
319
404
|
});
|