deepseek-coder-agent-cli 1.0.39 โ 1.0.40
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/bin/deepseek.d.ts +0 -3
- package/dist/bin/deepseek.d.ts.map +1 -1
- package/dist/bin/deepseek.js +6 -6
- package/dist/bin/deepseek.js.map +1 -1
- package/dist/bin/lean.js +5 -4
- package/dist/bin/lean.js.map +1 -1
- package/dist/core/episodicMemory.d.ts.map +1 -1
- package/dist/core/episodicMemory.js +3 -2
- package/dist/core/episodicMemory.js.map +1 -1
- package/dist/core/flowProtection.d.ts.map +1 -1
- package/dist/core/flowProtection.js +2 -1
- package/dist/core/flowProtection.js.map +1 -1
- package/dist/core/guardrails.d.ts +0 -4
- package/dist/core/guardrails.d.ts.map +1 -1
- package/dist/core/guardrails.js +2 -1
- package/dist/core/guardrails.js.map +1 -1
- package/dist/core/inputProtection.d.ts.map +1 -1
- package/dist/core/inputProtection.js +2 -1
- package/dist/core/inputProtection.js.map +1 -1
- package/dist/core/revenueEnvValidator.d.ts.map +1 -1
- package/dist/core/revenueEnvValidator.js +8 -5
- package/dist/core/revenueEnvValidator.js.map +1 -1
- package/dist/core/shutdown.d.ts.map +1 -1
- package/dist/core/shutdown.js +3 -2
- package/dist/core/shutdown.js.map +1 -1
- package/dist/core/types/utilityTypes.d.ts +0 -9
- package/dist/core/types/utilityTypes.d.ts.map +1 -1
- package/dist/core/types/utilityTypes.js +2 -1
- package/dist/core/types/utilityTypes.js.map +1 -1
- package/dist/headless/interactiveShell.d.ts.map +1 -1
- package/dist/headless/interactiveShell.js +89 -43
- package/dist/headless/interactiveShell.js.map +1 -1
- package/dist/headless/quickMode.d.ts.map +1 -1
- package/dist/headless/quickMode.js +5 -4
- package/dist/headless/quickMode.js.map +1 -1
- package/dist/tools/emailTools.d.ts.map +1 -1
- package/dist/tools/emailTools.js +3 -2
- package/dist/tools/emailTools.js.map +1 -1
- package/dist/ui/UnifiedUIRenderer.d.ts +0 -16
- package/dist/ui/UnifiedUIRenderer.d.ts.map +1 -1
- package/dist/ui/UnifiedUIRenderer.js +16 -218
- package/dist/ui/UnifiedUIRenderer.js.map +1 -1
- package/dist/utils/statusReporter.d.ts +6 -0
- package/dist/utils/statusReporter.d.ts.map +1 -0
- package/dist/utils/statusReporter.js +26 -0
- package/dist/utils/statusReporter.js.map +1 -0
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +4 -3
- package/dist/workspace.js.map +1 -1
- package/package.json +1 -1
|
@@ -18,6 +18,7 @@ import { ContextMeter, disposeAnimations } from './animatedStatus.js';
|
|
|
18
18
|
import { clampPercentage, getContextColor, } from './uiConstants.js';
|
|
19
19
|
import { formatInlineText } from './richText.js';
|
|
20
20
|
import { initializeInputProtection } from '../core/inputProtection.js';
|
|
21
|
+
import { reportStatus, reportStatusError } from '../utils/statusReporter.js';
|
|
21
22
|
// UI helper methods for security components
|
|
22
23
|
export function createBanner(title, subtitle) {
|
|
23
24
|
const lines = [];
|
|
@@ -208,8 +209,7 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
208
209
|
suggestionIndex = -1;
|
|
209
210
|
availableCommands = [];
|
|
210
211
|
hotkeysInToggleLine = new Set();
|
|
211
|
-
//
|
|
212
|
-
pasteRegions = [];
|
|
212
|
+
// Note: collapsed paste functionality removed - pasted content is displayed directly
|
|
213
213
|
mode = 'idle';
|
|
214
214
|
/** Queue for input received during streaming - processed after streaming ends */
|
|
215
215
|
streamingInputQueue = [];
|
|
@@ -356,125 +356,6 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
356
356
|
sanitized = sanitized.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
|
|
357
357
|
return sanitized;
|
|
358
358
|
}
|
|
359
|
-
/** Detect likely programming language from pasted content */
|
|
360
|
-
detectPasteLanguage(text) {
|
|
361
|
-
const patterns = {
|
|
362
|
-
javascript: /\b(const|let|var|function|async|await|import|export|=>)\b/,
|
|
363
|
-
typescript: /\b(interface|type|enum|namespace|declare|as const)\b/,
|
|
364
|
-
python: /\b(def|class|import|from|if __name__|async def)\b/,
|
|
365
|
-
json: /^\s*(?:\{|\[)[\s\S]*(?:\}|\])\s*$/,
|
|
366
|
-
html: /^<[a-z]/i,
|
|
367
|
-
css: /^\s*[.#[]?[\w-]+\s*\{/,
|
|
368
|
-
sql: /\b(SELECT|FROM|WHERE|INSERT|UPDATE|DELETE|CREATE|TABLE)\b/i,
|
|
369
|
-
bash: /^#!/,
|
|
370
|
-
yaml: /^[\w-]+:\s*\S/m,
|
|
371
|
-
};
|
|
372
|
-
for (const [lang, pattern] of Object.entries(patterns)) {
|
|
373
|
-
if (pattern.test(text)) {
|
|
374
|
-
return lang;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
return undefined;
|
|
378
|
-
}
|
|
379
|
-
/** Minimum chars/lines to trigger condensed display */
|
|
380
|
-
pasteCondenseMinChars = 200;
|
|
381
|
-
pasteCondenseMinLines = 4;
|
|
382
|
-
/** Record a paste region for condensed display */
|
|
383
|
-
recordPasteRegion(insertPos, content) {
|
|
384
|
-
const lines = content.split('\n');
|
|
385
|
-
const nonEmptyLines = lines.filter(line => line.trim().length > 0);
|
|
386
|
-
const charCount = content.length;
|
|
387
|
-
const lineCount = nonEmptyLines.length;
|
|
388
|
-
// Only condense if paste is large enough
|
|
389
|
-
if (charCount < this.pasteCondenseMinChars && lineCount < this.pasteCondenseMinLines) {
|
|
390
|
-
return;
|
|
391
|
-
}
|
|
392
|
-
// Create preview: first line truncated to 50 chars
|
|
393
|
-
let preview = nonEmptyLines[0]?.substring(0, 50) || '';
|
|
394
|
-
if ((nonEmptyLines[0]?.length ?? 0) > 50) {
|
|
395
|
-
preview += 'โฆ';
|
|
396
|
-
}
|
|
397
|
-
const language = this.detectPasteLanguage(content);
|
|
398
|
-
// Shift existing regions that come after the insertion point
|
|
399
|
-
for (const region of this.pasteRegions) {
|
|
400
|
-
if (region.start >= insertPos) {
|
|
401
|
-
region.start += content.length;
|
|
402
|
-
region.end += content.length;
|
|
403
|
-
}
|
|
404
|
-
else if (region.end > insertPos) {
|
|
405
|
-
// Insertion in the middle of a region - extend it
|
|
406
|
-
region.end += content.length;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
// Add new region
|
|
410
|
-
this.pasteRegions.push({
|
|
411
|
-
start: insertPos,
|
|
412
|
-
end: insertPos + content.length,
|
|
413
|
-
lineCount,
|
|
414
|
-
charCount,
|
|
415
|
-
preview,
|
|
416
|
-
language,
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
/** Clear paste regions (called when buffer is cleared) */
|
|
420
|
-
clearPasteRegions() {
|
|
421
|
-
this.pasteRegions = [];
|
|
422
|
-
}
|
|
423
|
-
/** Adjust paste regions when characters are deleted from the buffer */
|
|
424
|
-
adjustPasteRegionsForDeletion(deleteStart, deleteEnd) {
|
|
425
|
-
const deleteLen = deleteEnd - deleteStart;
|
|
426
|
-
if (deleteLen <= 0)
|
|
427
|
-
return;
|
|
428
|
-
// Filter out regions that are fully deleted, and adjust others
|
|
429
|
-
this.pasteRegions = this.pasteRegions.filter(region => {
|
|
430
|
-
// Region is fully before deletion - no change
|
|
431
|
-
if (region.end <= deleteStart) {
|
|
432
|
-
return true;
|
|
433
|
-
}
|
|
434
|
-
// Region is fully after deletion - shift left
|
|
435
|
-
if (region.start >= deleteEnd) {
|
|
436
|
-
region.start -= deleteLen;
|
|
437
|
-
region.end -= deleteLen;
|
|
438
|
-
return true;
|
|
439
|
-
}
|
|
440
|
-
// Region is fully within deletion - remove it
|
|
441
|
-
if (region.start >= deleteStart && region.end <= deleteEnd) {
|
|
442
|
-
return false;
|
|
443
|
-
}
|
|
444
|
-
// Partial overlap - adjust bounds
|
|
445
|
-
if (region.start < deleteStart && region.end > deleteEnd) {
|
|
446
|
-
// Deletion is inside region - shrink region
|
|
447
|
-
region.end -= deleteLen;
|
|
448
|
-
return true;
|
|
449
|
-
}
|
|
450
|
-
if (region.start < deleteStart) {
|
|
451
|
-
// Deletion overlaps end of region
|
|
452
|
-
region.end = deleteStart;
|
|
453
|
-
return region.end > region.start;
|
|
454
|
-
}
|
|
455
|
-
// Deletion overlaps start of region
|
|
456
|
-
region.start = deleteStart;
|
|
457
|
-
region.end -= (deleteEnd - region.start);
|
|
458
|
-
return region.end > region.start;
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
/** Adjust paste regions when characters are inserted (not paste - regular typing) */
|
|
462
|
-
adjustPasteRegionsForInsertion(insertPos, insertLen) {
|
|
463
|
-
if (insertLen <= 0)
|
|
464
|
-
return;
|
|
465
|
-
for (const region of this.pasteRegions) {
|
|
466
|
-
if (region.start >= insertPos) {
|
|
467
|
-
// Region is after insertion point - shift right
|
|
468
|
-
region.start += insertLen;
|
|
469
|
-
region.end += insertLen;
|
|
470
|
-
}
|
|
471
|
-
else if (region.end > insertPos) {
|
|
472
|
-
// Insertion is inside region - extend the region
|
|
473
|
-
region.end += insertLen;
|
|
474
|
-
}
|
|
475
|
-
// Regions before insertion point are unaffected
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
359
|
formatHotkey(combo) {
|
|
479
360
|
if (!combo?.trim())
|
|
480
361
|
return null;
|
|
@@ -554,7 +435,7 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
554
435
|
// Set up error handling for EventEmitter
|
|
555
436
|
this.on('error', (err) => {
|
|
556
437
|
// Log errors but don't crash
|
|
557
|
-
|
|
438
|
+
reportStatusError(err, '[UnifiedUIRenderer] Error');
|
|
558
439
|
});
|
|
559
440
|
this.output = output;
|
|
560
441
|
this.input = input;
|
|
@@ -584,7 +465,7 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
584
465
|
}
|
|
585
466
|
catch (err) {
|
|
586
467
|
// If readline creation fails, create a minimal fallback
|
|
587
|
-
|
|
468
|
+
reportStatusError(err, '[UnifiedUIRenderer] Failed to create readline interface');
|
|
588
469
|
this.rl = readline.createInterface({
|
|
589
470
|
input: process.stdin,
|
|
590
471
|
output: process.stdout,
|
|
@@ -637,7 +518,6 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
637
518
|
this.buffer = '';
|
|
638
519
|
this.cursor = 0;
|
|
639
520
|
this.inputRenderOffset = 0;
|
|
640
|
-
this.clearPasteRegions();
|
|
641
521
|
this.pasteBuffer = '';
|
|
642
522
|
this.pasteBufferOverflow = false;
|
|
643
523
|
this.inPlainPaste = false;
|
|
@@ -1133,7 +1013,6 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
1133
1013
|
this.buffer = '';
|
|
1134
1014
|
this.cursor = 0;
|
|
1135
1015
|
this.inputRenderOffset = 0;
|
|
1136
|
-
this.clearPasteRegions();
|
|
1137
1016
|
this.resetSuggestions();
|
|
1138
1017
|
this.renderPrompt();
|
|
1139
1018
|
this.emitInputChange();
|
|
@@ -1189,12 +1068,9 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
1189
1068
|
// Insert paste content directly into buffer (supports multi-line)
|
|
1190
1069
|
// Insert at cursor position
|
|
1191
1070
|
this.clampCursor();
|
|
1192
|
-
const insertPos = this.cursor;
|
|
1193
1071
|
this.buffer = this.buffer.slice(0, this.cursor) + sanitized + this.buffer.slice(this.cursor);
|
|
1194
1072
|
this.cursor += sanitized.length;
|
|
1195
1073
|
this.clampCursor();
|
|
1196
|
-
// Record paste region for condensed display
|
|
1197
|
-
this.recordPasteRegion(insertPos, sanitized);
|
|
1198
1074
|
this.updateSuggestions();
|
|
1199
1075
|
this.resetPlainPasteBurst();
|
|
1200
1076
|
this.forceNextRender = true;
|
|
@@ -1225,12 +1101,9 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
1225
1101
|
// Insert paste content directly into buffer (supports multi-line)
|
|
1226
1102
|
// Insert at cursor position
|
|
1227
1103
|
this.clampCursor();
|
|
1228
|
-
const insertPos = this.cursor;
|
|
1229
1104
|
this.buffer = this.buffer.slice(0, this.cursor) + sanitized + this.buffer.slice(this.cursor);
|
|
1230
1105
|
this.cursor += sanitized.length;
|
|
1231
1106
|
this.clampCursor();
|
|
1232
|
-
// Record paste region for condensed display
|
|
1233
|
-
this.recordPasteRegion(insertPos, sanitized);
|
|
1234
1107
|
this.updateSuggestions();
|
|
1235
1108
|
this.resetPlainPasteBurst();
|
|
1236
1109
|
this.forceNextRender = true;
|
|
@@ -1303,7 +1176,6 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
1303
1176
|
this.buffer = '';
|
|
1304
1177
|
this.cursor = 0;
|
|
1305
1178
|
this.inputRenderOffset = 0;
|
|
1306
|
-
this.clearPasteRegions();
|
|
1307
1179
|
this.resetSuggestions();
|
|
1308
1180
|
this.renderPrompt();
|
|
1309
1181
|
this.emitInputChange();
|
|
@@ -1481,11 +1353,8 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
1481
1353
|
// Skip word characters
|
|
1482
1354
|
while (pos > 0 && this.buffer[pos - 1] !== ' ')
|
|
1483
1355
|
pos--;
|
|
1484
|
-
|
|
1485
|
-
const deleteEnd = this.cursor;
|
|
1486
|
-
this.buffer = this.buffer.slice(0, deleteStart) + this.buffer.slice(deleteEnd);
|
|
1356
|
+
this.buffer = this.buffer.slice(0, pos) + this.buffer.slice(this.cursor);
|
|
1487
1357
|
this.cursor = pos;
|
|
1488
|
-
this.adjustPasteRegionsForDeletion(deleteStart, deleteEnd);
|
|
1489
1358
|
this.updateSuggestions();
|
|
1490
1359
|
this.renderPrompt();
|
|
1491
1360
|
this.emitInputChange();
|
|
@@ -1495,10 +1364,7 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
1495
1364
|
// Ctrl+K: Delete from cursor to end of line
|
|
1496
1365
|
if (key.ctrl && key.name === 'k') {
|
|
1497
1366
|
if (this.cursor < this.buffer.length) {
|
|
1498
|
-
const deleteStart = this.cursor;
|
|
1499
|
-
const deleteEnd = this.buffer.length;
|
|
1500
1367
|
this.buffer = this.buffer.slice(0, this.cursor);
|
|
1501
|
-
this.adjustPasteRegionsForDeletion(deleteStart, deleteEnd);
|
|
1502
1368
|
this.updateSuggestions();
|
|
1503
1369
|
this.renderPrompt();
|
|
1504
1370
|
this.emitInputChange();
|
|
@@ -1567,11 +1433,8 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
1567
1433
|
pos--;
|
|
1568
1434
|
while (pos > 0 && this.buffer[pos - 1] !== ' ')
|
|
1569
1435
|
pos--;
|
|
1570
|
-
|
|
1571
|
-
const deleteEnd = this.cursor;
|
|
1572
|
-
this.buffer = this.buffer.slice(0, deleteStart) + this.buffer.slice(deleteEnd);
|
|
1436
|
+
this.buffer = this.buffer.slice(0, pos) + this.buffer.slice(this.cursor);
|
|
1573
1437
|
this.cursor = pos;
|
|
1574
|
-
this.adjustPasteRegionsForDeletion(deleteStart, deleteEnd);
|
|
1575
1438
|
this.updateSuggestions();
|
|
1576
1439
|
this.renderPrompt();
|
|
1577
1440
|
this.emitInputChange();
|
|
@@ -1610,11 +1473,8 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
1610
1473
|
this.resetPlainPasteBurst();
|
|
1611
1474
|
this.cancelPlainPasteCapture();
|
|
1612
1475
|
if (this.cursor > 0) {
|
|
1613
|
-
|
|
1614
|
-
const deleteEnd = this.cursor;
|
|
1615
|
-
this.buffer = this.buffer.slice(0, deleteStart) + this.buffer.slice(deleteEnd);
|
|
1476
|
+
this.buffer = this.buffer.slice(0, this.cursor - 1) + this.buffer.slice(this.cursor);
|
|
1616
1477
|
this.cursor--;
|
|
1617
|
-
this.adjustPasteRegionsForDeletion(deleteStart, deleteEnd);
|
|
1618
1478
|
this.updateSuggestions();
|
|
1619
1479
|
this.forceNextRender = true;
|
|
1620
1480
|
this.renderPrompt();
|
|
@@ -1627,10 +1487,7 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
1627
1487
|
this.resetPlainPasteBurst();
|
|
1628
1488
|
this.cancelPlainPasteCapture();
|
|
1629
1489
|
if (this.cursor < this.buffer.length) {
|
|
1630
|
-
|
|
1631
|
-
const deleteEnd = this.cursor + 1;
|
|
1632
|
-
this.buffer = this.buffer.slice(0, deleteStart) + this.buffer.slice(deleteEnd);
|
|
1633
|
-
this.adjustPasteRegionsForDeletion(deleteStart, deleteEnd);
|
|
1490
|
+
this.buffer = this.buffer.slice(0, this.cursor) + this.buffer.slice(this.cursor + 1);
|
|
1634
1491
|
this.updateSuggestions();
|
|
1635
1492
|
this.forceNextRender = true;
|
|
1636
1493
|
this.renderPrompt();
|
|
@@ -1707,7 +1564,6 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
1707
1564
|
}
|
|
1708
1565
|
this.cursor = this.buffer.length;
|
|
1709
1566
|
this.inputRenderOffset = 0; // Reset render offset for new buffer
|
|
1710
|
-
this.clearPasteRegions(); // History entries don't have paste regions
|
|
1711
1567
|
this.updateSuggestions();
|
|
1712
1568
|
this.renderPrompt();
|
|
1713
1569
|
this.emitInputChange();
|
|
@@ -1734,7 +1590,6 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
1734
1590
|
}
|
|
1735
1591
|
this.cursor = this.buffer.length;
|
|
1736
1592
|
this.inputRenderOffset = 0; // Reset render offset for new buffer
|
|
1737
|
-
this.clearPasteRegions(); // History entries don't have paste regions
|
|
1738
1593
|
this.updateSuggestions();
|
|
1739
1594
|
this.renderPrompt();
|
|
1740
1595
|
this.emitInputChange();
|
|
@@ -1974,12 +1829,9 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
1974
1829
|
// Insert paste content directly into buffer (supports multi-line)
|
|
1975
1830
|
// Insert at cursor position
|
|
1976
1831
|
this.clampCursor();
|
|
1977
|
-
const insertPos = this.cursor;
|
|
1978
1832
|
this.buffer = this.buffer.slice(0, this.cursor) + content + this.buffer.slice(this.cursor);
|
|
1979
1833
|
this.cursor += content.length;
|
|
1980
1834
|
this.clampCursor();
|
|
1981
|
-
// Record paste region for condensed display
|
|
1982
|
-
this.recordPasteRegion(insertPos, content);
|
|
1983
1835
|
this.updateSuggestions();
|
|
1984
1836
|
this.forceNextRender = true;
|
|
1985
1837
|
this.renderPrompt();
|
|
@@ -2156,12 +2008,9 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
2156
2008
|
// Insert paste content directly into buffer (supports multi-line)
|
|
2157
2009
|
// Insert at cursor position
|
|
2158
2010
|
this.clampCursor();
|
|
2159
|
-
const insertPos = this.cursor;
|
|
2160
2011
|
this.buffer = this.buffer.slice(0, this.cursor) + content + this.buffer.slice(this.cursor);
|
|
2161
2012
|
this.cursor += content.length;
|
|
2162
2013
|
this.clampCursor();
|
|
2163
|
-
// Record paste region for condensed display
|
|
2164
|
-
this.recordPasteRegion(insertPos, content);
|
|
2165
2014
|
this.updateSuggestions();
|
|
2166
2015
|
this.forceNextRender = true;
|
|
2167
2016
|
this.renderPrompt();
|
|
@@ -2225,12 +2074,9 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
2225
2074
|
return;
|
|
2226
2075
|
// Ensure cursor is valid before slicing
|
|
2227
2076
|
this.clampCursor();
|
|
2228
|
-
const insertPos = this.cursor;
|
|
2229
2077
|
this.buffer = this.buffer.slice(0, this.cursor) + text + this.buffer.slice(this.cursor);
|
|
2230
2078
|
this.cursor += text.length;
|
|
2231
2079
|
this.clampCursor(); // Ensure cursor remains valid after modification
|
|
2232
|
-
// Adjust paste regions for the insertion
|
|
2233
|
-
this.adjustPasteRegionsForInsertion(insertPos, text.length);
|
|
2234
2080
|
this.updateSuggestions();
|
|
2235
2081
|
// Suppress render during paste detection to prevent visual leak
|
|
2236
2082
|
const inEmitPaste = this.emitPasteBuffer.length > 0 || this.emitPasteTimer !== null;
|
|
@@ -2258,7 +2104,6 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
2258
2104
|
this.buffer = '';
|
|
2259
2105
|
this.cursor = 0;
|
|
2260
2106
|
this.inputRenderOffset = 0;
|
|
2261
|
-
this.clearPasteRegions();
|
|
2262
2107
|
this.resetSuggestions();
|
|
2263
2108
|
this.renderPrompt();
|
|
2264
2109
|
this.emitInputChange();
|
|
@@ -2277,7 +2122,6 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
2277
2122
|
// Prompt blocked - don't submit
|
|
2278
2123
|
this.buffer = '';
|
|
2279
2124
|
this.cursor = 0;
|
|
2280
|
-
this.clearPasteRegions();
|
|
2281
2125
|
this.renderPrompt();
|
|
2282
2126
|
return;
|
|
2283
2127
|
}
|
|
@@ -2302,7 +2146,6 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
2302
2146
|
}
|
|
2303
2147
|
this.buffer = '';
|
|
2304
2148
|
this.cursor = 0;
|
|
2305
|
-
this.clearPasteRegions();
|
|
2306
2149
|
this.resetSuggestions();
|
|
2307
2150
|
this.renderPrompt();
|
|
2308
2151
|
this.emitInputChange();
|
|
@@ -2398,6 +2241,10 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
2398
2241
|
addEvent(type, content) {
|
|
2399
2242
|
if (!content)
|
|
2400
2243
|
return;
|
|
2244
|
+
if (type === 'error') {
|
|
2245
|
+
reportStatus(content);
|
|
2246
|
+
return;
|
|
2247
|
+
}
|
|
2401
2248
|
const normalized = this.normalizeEventType(type);
|
|
2402
2249
|
if (!normalized)
|
|
2403
2250
|
return;
|
|
@@ -5166,11 +5013,9 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
5166
5013
|
const maxWidth = this.safeWidth();
|
|
5167
5014
|
const continuationIndent = ' '; // 2 spaces for continuation lines
|
|
5168
5015
|
const continuationWidth = continuationIndent.length;
|
|
5169
|
-
// Build display buffer with paste regions condensed
|
|
5170
|
-
const { displayBuffer, cursorDisplayPos } = this.buildCondensedDisplayBuffer();
|
|
5171
5016
|
// Handle multi-line input - split buffer on newlines first
|
|
5172
5017
|
// In secret mode, mask all characters with bullets
|
|
5173
|
-
const rawBuffer =
|
|
5018
|
+
const rawBuffer = this.buffer.replace(/\r/g, '\n');
|
|
5174
5019
|
const normalized = this.secretMode ? 'โข'.repeat(rawBuffer.length) : rawBuffer;
|
|
5175
5020
|
const bufferLines = normalized.split('\n');
|
|
5176
5021
|
// Wrap each logical line to fit terminal width, expanding vertically
|
|
@@ -5201,13 +5046,13 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
5201
5046
|
else {
|
|
5202
5047
|
displayLine = `${continuationIndent}${chunk}`;
|
|
5203
5048
|
}
|
|
5204
|
-
// Track cursor position
|
|
5049
|
+
// Track cursor position
|
|
5205
5050
|
if (!foundCursor) {
|
|
5206
5051
|
const chunkStart = lineStartChar + (line.length - remaining.length - chunk.length);
|
|
5207
5052
|
const chunkEnd = chunkStart + chunk.length;
|
|
5208
|
-
if (
|
|
5053
|
+
if (this.cursor >= chunkStart && this.cursor <= chunkEnd) {
|
|
5209
5054
|
cursorLine = result.length;
|
|
5210
|
-
const offsetInChunk =
|
|
5055
|
+
const offsetInChunk = this.cursor - chunkStart;
|
|
5211
5056
|
cursorCol = ((isFirstLogicalLine && isFirstDisplayLine) ? promptWidth : continuationWidth) + offsetInChunk;
|
|
5212
5057
|
foundCursor = true;
|
|
5213
5058
|
}
|
|
@@ -5244,50 +5089,6 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
5244
5089
|
this.cursorVisibleColumn = cursorCol + 1;
|
|
5245
5090
|
return result.join('\n');
|
|
5246
5091
|
}
|
|
5247
|
-
/** Build a display buffer with paste regions condensed to summaries */
|
|
5248
|
-
buildCondensedDisplayBuffer() {
|
|
5249
|
-
// If no paste regions, return original buffer
|
|
5250
|
-
if (this.pasteRegions.length === 0) {
|
|
5251
|
-
return { displayBuffer: this.buffer, cursorDisplayPos: this.cursor };
|
|
5252
|
-
}
|
|
5253
|
-
// Sort regions by start position
|
|
5254
|
-
const sortedRegions = [...this.pasteRegions].sort((a, b) => a.start - b.start);
|
|
5255
|
-
let displayBuffer = '';
|
|
5256
|
-
let bufferPos = 0;
|
|
5257
|
-
let cursorDisplayPos = this.cursor;
|
|
5258
|
-
let displayOffset = 0; // Track cumulative offset between buffer and display positions
|
|
5259
|
-
for (const region of sortedRegions) {
|
|
5260
|
-
// Add text before this region
|
|
5261
|
-
if (region.start > bufferPos) {
|
|
5262
|
-
displayBuffer += this.buffer.slice(bufferPos, region.start);
|
|
5263
|
-
}
|
|
5264
|
-
// Build condensed summary for this paste region
|
|
5265
|
-
const langLabel = region.language ? `${region.language.toUpperCase()} ` : '';
|
|
5266
|
-
const summary = `[๐ ${langLabel}${region.lineCount} lines ยท ${region.charCount} chars: ${region.preview}]`;
|
|
5267
|
-
// Update cursor position if it's within or after this region
|
|
5268
|
-
if (this.cursor >= region.start && this.cursor < region.end) {
|
|
5269
|
-
// Cursor is inside paste region - position at start of summary
|
|
5270
|
-
cursorDisplayPos = displayBuffer.length;
|
|
5271
|
-
}
|
|
5272
|
-
else if (this.cursor >= region.end) {
|
|
5273
|
-
// Cursor is after this region - adjust by the difference
|
|
5274
|
-
const regionLength = region.end - region.start;
|
|
5275
|
-
const summaryLength = summary.length;
|
|
5276
|
-
displayOffset += regionLength - summaryLength;
|
|
5277
|
-
}
|
|
5278
|
-
displayBuffer += summary;
|
|
5279
|
-
bufferPos = region.end;
|
|
5280
|
-
}
|
|
5281
|
-
// Add remaining text after last region
|
|
5282
|
-
if (bufferPos < this.buffer.length) {
|
|
5283
|
-
displayBuffer += this.buffer.slice(bufferPos);
|
|
5284
|
-
}
|
|
5285
|
-
// Adjust cursor position for regions that came before it
|
|
5286
|
-
if (this.cursor >= bufferPos || displayOffset > 0) {
|
|
5287
|
-
cursorDisplayPos = Math.max(0, this.cursor - displayOffset);
|
|
5288
|
-
}
|
|
5289
|
-
return { displayBuffer, cursorDisplayPos };
|
|
5290
|
-
}
|
|
5291
5092
|
buildInputWindow(available) {
|
|
5292
5093
|
if (available <= 0) {
|
|
5293
5094
|
return { text: '', cursor: 0 };
|
|
@@ -5340,7 +5141,6 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
5340
5141
|
this.buffer = '';
|
|
5341
5142
|
this.cursor = 0;
|
|
5342
5143
|
this.inputRenderOffset = 0;
|
|
5343
|
-
this.clearPasteRegions();
|
|
5344
5144
|
this.resetSuggestions();
|
|
5345
5145
|
this.renderPrompt();
|
|
5346
5146
|
this.emitInputChange();
|
|
@@ -5454,7 +5254,6 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
5454
5254
|
// Validate cursor position to prevent out-of-bounds issues
|
|
5455
5255
|
const requestedCursor = cursorPos ?? text.length;
|
|
5456
5256
|
this.cursor = Math.max(0, Math.min(requestedCursor, text.length));
|
|
5457
|
-
this.clearPasteRegions(); // External buffer replacement clears paste tracking
|
|
5458
5257
|
this.inputRenderOffset = 0;
|
|
5459
5258
|
this.updateSuggestions();
|
|
5460
5259
|
this.renderPrompt();
|
|
@@ -5469,7 +5268,6 @@ export class UnifiedUIRenderer extends EventEmitter {
|
|
|
5469
5268
|
this.buffer = '';
|
|
5470
5269
|
this.cursor = 0;
|
|
5471
5270
|
this.inputRenderOffset = 0;
|
|
5472
|
-
this.clearPasteRegions();
|
|
5473
5271
|
this.suggestions = [];
|
|
5474
5272
|
this.suggestionIndex = -1;
|
|
5475
5273
|
this.renderPrompt();
|