wormclaude 1.0.135 → 1.0.137
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 +21 -5
- package/dist/i18n.js +8 -0
- package/dist/theme.js +1 -1
- package/dist/tui.js +65 -5
- package/package.json +1 -1
package/dist/ansi.js
CHANGED
|
@@ -170,12 +170,28 @@ export function itemAnsi(it, cols) {
|
|
|
170
170
|
return '\n' + md.map((ln, i) => (i === 0 ? paint('✶ ', theme.redBright, true) + ln : ' ' + ln)).join('\n');
|
|
171
171
|
}
|
|
172
172
|
if (it.kind === 'tool') {
|
|
173
|
-
const
|
|
173
|
+
const word = t('tui.linesWord') || 'satır';
|
|
174
174
|
const head = paint('✶ ', theme.redBright, true) + paint(it.label || '', theme.white);
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
175
|
+
if (!it.ok) {
|
|
176
|
+
return '\n' + head + '\n' + paint(' ⎿ ', theme.greyDim) + paint('✗ ' + (it.result || '').slice(0, 200), theme.errorRed);
|
|
177
|
+
}
|
|
178
|
+
// Write/Edit: Claude tarzı içerik önizlemesi (özet satırı + ilk birkaç satır + "… +N satır").
|
|
179
|
+
const pv = it.preview;
|
|
180
|
+
if (pv && Array.isArray(pv.lines) && pv.lines.length) {
|
|
181
|
+
const PREV = 8;
|
|
182
|
+
const summary = paint(' ⎿ ', theme.greyDim) + paint(`${pv.verb} ${pv.lines.length} ${word} → ${pv.file}`, theme.grey);
|
|
183
|
+
const body = pv.lines.slice(0, PREV).map((ln, i) => paint(` ${String(i + 1).padStart(3, ' ')} `, theme.greyDim) + paint(ln.replace(/\t/g, ' ').slice(0, Math.max(8, W - 8)), theme.greyDim));
|
|
184
|
+
const more = pv.lines.length > PREV
|
|
185
|
+
? '\n' + paint(` … +${pv.lines.length - PREV} ${word}`, theme.greyDim) : '';
|
|
186
|
+
return '\n' + head + '\n' + summary + '\n' + body.join('\n') + more;
|
|
187
|
+
}
|
|
188
|
+
// Diğer araçlar (Bash/Read/Grep…): ilk anlamlı satır + kalan sayısı (kısa, gürültüsüz).
|
|
189
|
+
const lines = (it.result || '').split('\n').filter((l) => l.trim());
|
|
190
|
+
if (!lines.length)
|
|
191
|
+
return '\n' + head + '\n' + paint(' ⎿ ', theme.greyDim) + paint(t('tui.toolDone') || 'tamam', theme.grey);
|
|
192
|
+
const first = lines[0].slice(0, Math.max(8, W - 8));
|
|
193
|
+
const extra = lines.length > 1 ? paint(` (+${lines.length - 1} ${word})`, theme.greyDim) : '';
|
|
194
|
+
return '\n' + head + '\n' + paint(' ⎿ ', theme.greyDim) + paint(first, theme.grey) + extra;
|
|
179
195
|
}
|
|
180
196
|
if (it.kind === 'note')
|
|
181
197
|
return '\n' + wrap(it.text || '', W).map((ln) => paint(ln, theme.greyDim)).join('\n');
|
package/dist/i18n.js
CHANGED
|
@@ -76,6 +76,10 @@ const STR = {
|
|
|
76
76
|
'tui.footerHint': '/ komutlar · ↑↓ geçmiş · /kopyala · Ctrl+C çıkış',
|
|
77
77
|
'tui.working': 'çalışıyor…',
|
|
78
78
|
'tui.chars': 'karakter',
|
|
79
|
+
'tui.linesWord': 'satır',
|
|
80
|
+
'tui.wrote': 'Yazıldı:',
|
|
81
|
+
'tui.edited': 'Düzenlendi:',
|
|
82
|
+
'tui.toolDone': 'tamam',
|
|
79
83
|
'tui.pasteSummary': '…(+{0} satır · {1} karakter, Enter ile gönder)',
|
|
80
84
|
'tui.permLabel': 'İZİN',
|
|
81
85
|
'tui.permRun': 'çalıştırılsın mı?',
|
|
@@ -136,6 +140,10 @@ const STR = {
|
|
|
136
140
|
'tui.footerHint': '/ commands · ↑↓ history · /copy · Ctrl+C exit',
|
|
137
141
|
'tui.working': 'working…',
|
|
138
142
|
'tui.chars': 'chars',
|
|
143
|
+
'tui.linesWord': 'lines',
|
|
144
|
+
'tui.wrote': 'Wrote',
|
|
145
|
+
'tui.edited': 'Edited',
|
|
146
|
+
'tui.toolDone': 'done',
|
|
139
147
|
'tui.pasteSummary': '…(+{0} lines · {1} chars, Enter to send)',
|
|
140
148
|
'tui.permLabel': 'PERMISSION',
|
|
141
149
|
'tui.permRun': 'run it?',
|
package/dist/theme.js
CHANGED
package/dist/tui.js
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
import readline from 'node:readline';
|
|
7
7
|
import stringWidth from 'string-width';
|
|
8
8
|
import { loadConfig, streamChat, fetchAccount } from './api.js';
|
|
9
|
-
import { allToolSchemas, executeToolCalls, executeTool, toolLabel, setToolConfig } from './tools.js';
|
|
9
|
+
import { allToolSchemas, executeToolCalls, executeTool, toolLabel, setToolConfig, getBashCwd } from './tools.js';
|
|
10
|
+
import * as path from 'node:path';
|
|
10
11
|
import { sanitizeOutput } from './errorsan.js';
|
|
11
12
|
import { itemAnsi, markdownAnsi } from './ansi.js';
|
|
12
13
|
import { theme, VERSION } from './theme.js';
|
|
@@ -27,6 +28,18 @@ function fmtDur(ms) {
|
|
|
27
28
|
const s = Math.max(0, Math.floor(ms / 1000));
|
|
28
29
|
return s >= 60 ? `${Math.floor(s / 60)}m ${s % 60}s` : `${s}s`;
|
|
29
30
|
}
|
|
31
|
+
// Dosya yolunu çalışma alanına göreli göster (Claude tarzı: "todo/index.html"), yoksa olduğu gibi.
|
|
32
|
+
function relWs(fp) {
|
|
33
|
+
try {
|
|
34
|
+
const cwd = getBashCwd();
|
|
35
|
+
const abs = path.isAbsolute(fp) ? fp : path.resolve(cwd, fp);
|
|
36
|
+
const rel = path.relative(cwd, abs);
|
|
37
|
+
return (!rel || rel.startsWith('..')) ? fp : rel;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return fp;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
30
43
|
function capToolOut(name, out) {
|
|
31
44
|
const s = out || '';
|
|
32
45
|
const isCmd = name === 'Bash' || name === 'PowerShell';
|
|
@@ -405,8 +418,19 @@ export async function runTui() {
|
|
|
405
418
|
refresh();
|
|
406
419
|
}),
|
|
407
420
|
ask: (q) => new Promise((resolve) => { ask = { question: q.question, options: q.options.length ? q.options : [{ label: t('tui.ok') }], sel: 0, resolve }; refresh(); }),
|
|
408
|
-
onResult: (c, _i, res) => {
|
|
409
|
-
|
|
421
|
+
onResult: (c, _i, res) => {
|
|
422
|
+
if ((c.name === 'WebSearch' || c.name === 'WebFetch') && res.ok)
|
|
423
|
+
usedWeb = true;
|
|
424
|
+
// Claude tarzı önizleme: Write/Edit dosya içeriğini özetli göster (ham JSON/uzun çıktı yerine).
|
|
425
|
+
let preview;
|
|
426
|
+
if (res.ok && c.name === 'Write' && res.args?.content != null) {
|
|
427
|
+
preview = { verb: t('tui.wrote') || 'Yazıldı', file: relWs(res.args.file_path), lines: String(res.args.content).split('\n') };
|
|
428
|
+
}
|
|
429
|
+
else if (res.ok && c.name === 'Edit' && res.args?.new_string != null) {
|
|
430
|
+
preview = { verb: t('tui.edited') || 'Düzenlendi', file: relWs(res.args.file_path), lines: String(res.args.new_string).split('\n') };
|
|
431
|
+
}
|
|
432
|
+
printItem({ kind: 'tool', label: toolLabel(c.name, res.args), result: sanitizeOutput(res.output), ok: res.ok, preview });
|
|
433
|
+
},
|
|
410
434
|
});
|
|
411
435
|
for (let i = 0; i < toolCalls.length; i++)
|
|
412
436
|
history.push({ role: 'tool', tool_call_id: toolCalls[i].id, content: capToolOut(toolCalls[i].name, results[i].output || '') });
|
|
@@ -451,6 +475,10 @@ export async function runTui() {
|
|
|
451
475
|
process.stdout.write('\x1b[?1000l\x1b[?1002l\x1b[?1003l\x1b[?1006l\x1b[?1015l\x1b[?1007l');
|
|
452
476
|
}
|
|
453
477
|
catch { }
|
|
478
|
+
try {
|
|
479
|
+
process.stdout.write('\x1b[?2004h');
|
|
480
|
+
}
|
|
481
|
+
catch { } // bracketed paste AÇ (çok-satırlı yapıştırma)
|
|
454
482
|
process.stdout.write('\x1b[?25l'); // gerçek imleci gizle (kendi ▌ bloğumuzu çiziyoruz)
|
|
455
483
|
redrawAll();
|
|
456
484
|
// Açılış: Claude tarzı GÜVEN ekranı — trust metni (içerik) + ok-tuşlu Evet/Hayır seçici (ask modal).
|
|
@@ -478,13 +506,45 @@ export async function runTui() {
|
|
|
478
506
|
} }).catch(() => { });
|
|
479
507
|
connectMcpServers().then((srv) => { if (srv && srv.length)
|
|
480
508
|
printItem({ kind: 'note', text: t('tui.mcpConnected', srv.length) }); }).catch(() => { }); // MCP araçları (varsa)
|
|
481
|
-
const quit = () => { process.stdout.write('\x1b[r\x1b[?25h\x1b[2J\x1b[3J\x1b[H'); process.exit(0); };
|
|
509
|
+
const quit = () => { process.stdout.write('\x1b[?2004l\x1b[r\x1b[?25h\x1b[2J\x1b[3J\x1b[H'); process.exit(0); };
|
|
482
510
|
process.on('exit', () => { try {
|
|
483
|
-
process.stdout.write('\x1b[r\x1b[?25h');
|
|
511
|
+
process.stdout.write('\x1b[?2004l\x1b[r\x1b[?25h');
|
|
484
512
|
}
|
|
485
513
|
catch { } });
|
|
486
514
|
let ctrlcAt = 0;
|
|
515
|
+
let pasting = false; // bracketed-paste içinde miyiz (ESC[200~ … ESC[201~)
|
|
487
516
|
process.stdin.on('keypress', (str, key) => {
|
|
517
|
+
// ── BRACKETED PASTE ────────────────────────────────────────────────────
|
|
518
|
+
// Terminal yapıştırmayı ESC[200~ … ESC[201~ ile sarar. İşaretçiler arasında
|
|
519
|
+
// gelen 'return' = SATIR SONU (submit DEĞİL) → çok-satırlı metin tek seferde
|
|
520
|
+
// input'a girer. Enter'a SADECE gerçek işaretçi gelince dokunur; işaretçi yoksa
|
|
521
|
+
// normal Enter davranışı AYNEN korunur (asla bozulmaz).
|
|
522
|
+
const _seq = (key && key.sequence) || str || '';
|
|
523
|
+
if (_seq.indexOf('[200~') !== -1) {
|
|
524
|
+
pasting = true;
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
if (_seq.indexOf('[201~') !== -1) {
|
|
528
|
+
pasting = false;
|
|
529
|
+
scheduleFooter();
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
if (pasting) {
|
|
533
|
+
if (key && (key.name === 'return' || key.name === 'enter')) {
|
|
534
|
+
inputBuf = inputBuf.slice(0, inputCur) + '\n' + inputBuf.slice(inputCur);
|
|
535
|
+
inputCur++;
|
|
536
|
+
cmdSel = 0;
|
|
537
|
+
scheduleFooter();
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
if (str && !str.startsWith('\x1b') && !/[\x00-\x08\x0e-\x1f]/.test(str)) {
|
|
541
|
+
inputBuf = inputBuf.slice(0, inputCur) + str + inputBuf.slice(inputCur);
|
|
542
|
+
inputCur += str.length;
|
|
543
|
+
cmdSel = 0;
|
|
544
|
+
scheduleFooter();
|
|
545
|
+
}
|
|
546
|
+
return; // paste sırasında diğer tüm tuş işlemlerini atla
|
|
547
|
+
}
|
|
488
548
|
// Soru dialogu (AskUserQuestion) aktifse: ↑↓ / 1-9 seç, Enter onayla, Esc/Ctrl+C ilk seçenek
|
|
489
549
|
if (ask) {
|
|
490
550
|
const n = ask.options.length;
|