wormclaude 1.0.51 → 1.0.53
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 +37 -35
- package/package.json +1 -1
package/dist/theme.js
CHANGED
package/dist/tui.js
CHANGED
|
@@ -67,8 +67,8 @@ export async function runTui() {
|
|
|
67
67
|
let streamPreview = ''; // canlı akış önizlemesi (footer'da)
|
|
68
68
|
const PREVIEW_LINES = 6; // akışta sabit önizleme satırı (yükseklik stabil → titreme yok)
|
|
69
69
|
const SPIN = ['·', '✢', '✳', '✶', '✻', '✽', '✶', '✳', '✢'];
|
|
70
|
-
// Giriş kutusunu genişliğe göre ÇOK SATIRA sar
|
|
71
|
-
const MAX_INPUT_LINES =
|
|
70
|
+
// Giriş kutusunu genişliğe göre ÇOK SATIRA sar; çok uzunsa (yapıştırma) KISALTIP özet gösterir.
|
|
71
|
+
const MAX_INPUT_LINES = 6;
|
|
72
72
|
const inputBoxLines = (W) => {
|
|
73
73
|
const inner = Math.max(4, W - 2); // "✶ " önek payı
|
|
74
74
|
const wrapped = [];
|
|
@@ -82,28 +82,26 @@ export async function runTui() {
|
|
|
82
82
|
cur += ch;
|
|
83
83
|
}
|
|
84
84
|
wrapped.push(cur);
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
if (wrapped.length <= MAX_INPUT_LINES) {
|
|
86
|
+
return wrapped.map((ln, i) => (i === 0 ? paint('✶ ', theme.redBright, true) : ' ') + paint(ln, theme.white) + (i === wrapped.length - 1 ? paint('▌', theme.greyDim) : ''));
|
|
87
|
+
}
|
|
88
|
+
// Çok uzun (büyük yapıştırma): son birkaç satır + üstte özet — footer'ı doldurmaz.
|
|
89
|
+
const extra = wrapped.length - (MAX_INPUT_LINES - 1);
|
|
90
|
+
const tail = wrapped.slice(-(MAX_INPUT_LINES - 1));
|
|
91
|
+
const head = paint(`✶ …(+${extra} satır · ${inputBuf.length} karakter, Enter ile gönder)`, theme.greyDim);
|
|
92
|
+
return [head, ...tail.map((ln, i) => ' ' + paint(ln, theme.white) + (i === tail.length - 1 ? paint('▌', theme.greyDim) : ''))];
|
|
87
93
|
};
|
|
88
94
|
// Footer yüksekliği DİNAMİK: izin=4; değilse (durum/menü) + çizgi + giriş-satırları + çizgi.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const statusLines = m.length ? Math.min(8, m.length) : 1;
|
|
100
|
-
return statusLines + 2 + il;
|
|
101
|
-
};
|
|
102
|
-
// Yükseklik değiştiyse scroll-region'ı + içeriği yeniden bas; değişmediyse sadece footer'ı çiz.
|
|
103
|
-
const refresh = () => { const fh = footerHeight(); if (fh !== prevFH)
|
|
104
|
-
redrawAll();
|
|
105
|
-
else
|
|
106
|
-
drawFooter(); };
|
|
95
|
+
// SABİT rezerve footer alanı (scroll region bir kez ayarlanır → churn/duplicate yok). Footer bu
|
|
96
|
+
// alanın DİBİNE sabitlenir; küçükse üstü boşaltılır. Menü/önizleme/giriş bu sınıra göre kırpılır.
|
|
97
|
+
const FOOTER_MAX = () => Math.min(11, Math.max(5, rows() - 6));
|
|
98
|
+
// refresh = sadece footer'ı çiz (region sabit; içerik yeniden BASILMAZ → duplicate olmaz).
|
|
99
|
+
const refresh = () => drawFooter();
|
|
100
|
+
// DEBOUNCE: hızlı yazma/yapıştırma akınında her tuşta DEĞİL, tick başına BİR KEZ çiz. Yoksa
|
|
101
|
+
// her karakter tam footer redraw'u tetikleyip render'ı kuyruğa biriktiriyor (elini çeksen de gidiyor).
|
|
102
|
+
let _fpending = false;
|
|
103
|
+
const scheduleFooter = () => { if (_fpending)
|
|
104
|
+
return; _fpending = true; setImmediate(() => { _fpending = false; drawFooter(); }); };
|
|
107
105
|
setToolConfig(config); // araçlar (Write/Bash/Edit…) aynı config'i kullansın
|
|
108
106
|
// İzin (araç onayı) + soru (AskUserQuestion) durumu
|
|
109
107
|
let perm = null;
|
|
@@ -171,16 +169,15 @@ export async function runTui() {
|
|
|
171
169
|
return [...L, ...R].map((r) => fit(cell(r), W)); // dar ekran → alt alta
|
|
172
170
|
return [0, 1, 2].map((i) => fit(padVis(cell(L[i]), colW) + cell(R[i]), W)); // geniş → 2 sütun
|
|
173
171
|
}
|
|
174
|
-
// ── Scroll region: üst
|
|
172
|
+
// ── Scroll region: üst=içerik, alt=SABİT rezerve footer alanı. İmleci koru (DECSTBM home'a alır). ──
|
|
175
173
|
function setRegion() {
|
|
176
|
-
const bottom = Math.max(1, rows() -
|
|
177
|
-
process.stdout.write(`\x1b[1;${bottom}r`);
|
|
174
|
+
const bottom = Math.max(1, rows() - FOOTER_MAX() - 1);
|
|
175
|
+
process.stdout.write(`\x1b7\x1b[1;${bottom}r\x1b8`); // save · region · restore (içerik imleci bozulmaz)
|
|
178
176
|
}
|
|
179
|
-
// ──
|
|
177
|
+
// ── Footer'ı rezerve alanın DİBİNE çiz; rezerve alanın geri kalanını boşalt (eski menü kalmaz). ──
|
|
180
178
|
function drawFooter() {
|
|
181
179
|
const W = Math.max(8, cols());
|
|
182
|
-
const
|
|
183
|
-
const start = rows() - fh + 1;
|
|
180
|
+
const R = rows(), FM = FOOTER_MAX();
|
|
184
181
|
const line = paint('─'.repeat(W), theme.red);
|
|
185
182
|
let body;
|
|
186
183
|
if (perm) {
|
|
@@ -227,14 +224,19 @@ export async function runTui() {
|
|
|
227
224
|
body = [status, line, ...inputLines, line];
|
|
228
225
|
}
|
|
229
226
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
227
|
+
if (body.length > FM)
|
|
228
|
+
body = body.slice(body.length - FM); // rezerve alanı aşma (giriş hep görünür)
|
|
229
|
+
const bodyStart = R - body.length + 1; // footer'ı ekranın DİBİNE sabitle
|
|
230
|
+
const reservedTop = R - FM + 1;
|
|
231
|
+
let out = '\x1b7'; // imleci kaydet (içerik alanı)
|
|
232
|
+
for (let r = reservedTop; r < bodyStart; r++)
|
|
233
|
+
out += `\x1b[${r};1H\x1b[2K`; // üst rezerve satırları boşalt
|
|
234
|
+
body.forEach((l, i) => { out += `\x1b[${bodyStart + i};1H\x1b[2K` + fit(l, W); });
|
|
235
|
+
out += '\x1b8'; // imleci geri yükle
|
|
233
236
|
process.stdout.write(out);
|
|
234
237
|
}
|
|
235
|
-
// ── Her şeyi yeni boyutta yeniden bas (
|
|
238
|
+
// ── Her şeyi yeni boyutta yeniden bas (SADECE açılış/resize/clear; footer değişiminde DEĞİL). ──
|
|
236
239
|
function redrawAll() {
|
|
237
|
-
prevFH = footerHeight(); // mevcut footer yüksekliğini kaydet (refresh karşılaştırması için)
|
|
238
240
|
setRegion();
|
|
239
241
|
process.stdout.write('\x1b[2J\x1b[3J\x1b[H');
|
|
240
242
|
const W = cols();
|
|
@@ -567,7 +569,7 @@ export async function runTui() {
|
|
|
567
569
|
if (key && key.name === 'backspace') {
|
|
568
570
|
inputBuf = inputBuf.slice(0, -1);
|
|
569
571
|
cmdSel = 0;
|
|
570
|
-
|
|
572
|
+
scheduleFooter();
|
|
571
573
|
return;
|
|
572
574
|
}
|
|
573
575
|
if (key && key.name === 'escape') {
|
|
@@ -579,7 +581,7 @@ export async function runTui() {
|
|
|
579
581
|
if (str && !key?.ctrl && !key?.meta && !str.startsWith('\x1b') && !/[\x00-\x1f]/.test(str)) {
|
|
580
582
|
inputBuf += str;
|
|
581
583
|
cmdSel = 0;
|
|
582
|
-
|
|
584
|
+
scheduleFooter();
|
|
583
585
|
}
|
|
584
586
|
});
|
|
585
587
|
// resize → settle sonrası her şeyi yeni boyutta yeniden bas (region + banner + footer)
|