erosolar-cli 1.7.373 → 1.7.379
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/capabilities/agentSpawningCapability.d.ts.map +1 -1
- package/dist/capabilities/agentSpawningCapability.js +29 -1
- package/dist/capabilities/agentSpawningCapability.js.map +1 -1
- package/dist/contracts/agent-schemas.json +105 -0
- package/dist/core/alphaZeroModular.d.ts +186 -0
- package/dist/core/alphaZeroModular.d.ts.map +1 -0
- package/dist/core/alphaZeroModular.js +755 -0
- package/dist/core/alphaZeroModular.js.map +1 -0
- package/dist/core/alphaZeroOrchestrator.d.ts +140 -0
- package/dist/core/alphaZeroOrchestrator.d.ts.map +1 -0
- package/dist/core/alphaZeroOrchestrator.js +418 -0
- package/dist/core/alphaZeroOrchestrator.js.map +1 -0
- package/dist/core/checkpoint.d.ts +76 -0
- package/dist/core/checkpoint.d.ts.map +1 -0
- package/dist/core/checkpoint.js +278 -0
- package/dist/core/checkpoint.js.map +1 -0
- package/dist/core/claudeCodeFeatures.d.ts +64 -0
- package/dist/core/claudeCodeFeatures.d.ts.map +1 -0
- package/dist/core/claudeCodeFeatures.js +163 -0
- package/dist/core/claudeCodeFeatures.js.map +1 -0
- package/dist/core/costTracker.d.ts +87 -0
- package/dist/core/costTracker.d.ts.map +1 -0
- package/dist/core/costTracker.js +285 -0
- package/dist/core/costTracker.js.map +1 -0
- package/dist/core/failureRecovery.d.ts +122 -0
- package/dist/core/failureRecovery.d.ts.map +1 -0
- package/dist/core/failureRecovery.js +477 -0
- package/dist/core/failureRecovery.js.map +1 -0
- package/dist/core/intelligentTestFlows.d.ts +126 -0
- package/dist/core/intelligentTestFlows.d.ts.map +1 -0
- package/dist/core/intelligentTestFlows.js +678 -0
- package/dist/core/intelligentTestFlows.js.map +1 -0
- package/dist/core/learningPersistence.d.ts +145 -0
- package/dist/core/learningPersistence.d.ts.map +1 -0
- package/dist/core/learningPersistence.js +477 -0
- package/dist/core/learningPersistence.js.map +1 -0
- package/dist/core/memorySystem.d.ts +67 -0
- package/dist/core/memorySystem.d.ts.map +1 -0
- package/dist/core/memorySystem.js +334 -0
- package/dist/core/memorySystem.js.map +1 -0
- package/dist/core/outputStyles.d.ts +48 -0
- package/dist/core/outputStyles.d.ts.map +1 -0
- package/dist/core/outputStyles.js +270 -0
- package/dist/core/outputStyles.js.map +1 -0
- package/dist/core/selfEvolution.d.ts +155 -0
- package/dist/core/selfEvolution.d.ts.map +1 -0
- package/dist/core/selfEvolution.js +1000 -0
- package/dist/core/selfEvolution.js.map +1 -0
- package/dist/core/selfImprovement.d.ts +141 -0
- package/dist/core/selfImprovement.d.ts.map +1 -0
- package/dist/core/selfImprovement.js +700 -0
- package/dist/core/selfImprovement.js.map +1 -0
- package/dist/core/updateManager.d.ts +62 -0
- package/dist/core/updateManager.d.ts.map +1 -0
- package/dist/core/updateManager.js +266 -0
- package/dist/core/updateManager.js.map +1 -0
- package/dist/shell/interactiveShell.d.ts +67 -0
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +1546 -3
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/keyboardShortcuts.d.ts +53 -0
- package/dist/shell/keyboardShortcuts.d.ts.map +1 -0
- package/dist/shell/keyboardShortcuts.js +163 -0
- package/dist/shell/keyboardShortcuts.js.map +1 -0
- package/dist/shell/terminalInput.d.ts +51 -1
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +223 -12
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/terminalInputAdapter.d.ts +7 -1
- package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
- package/dist/shell/terminalInputAdapter.js +7 -0
- package/dist/shell/terminalInputAdapter.js.map +1 -1
- package/dist/shell/vimMode.d.ts +66 -0
- package/dist/shell/vimMode.d.ts.map +1 -0
- package/dist/shell/vimMode.js +434 -0
- package/dist/shell/vimMode.js.map +1 -0
- package/dist/subagents/parallelAgentManager.d.ts +99 -0
- package/dist/subagents/parallelAgentManager.d.ts.map +1 -0
- package/dist/subagents/parallelAgentManager.js +249 -0
- package/dist/subagents/parallelAgentManager.js.map +1 -0
- package/dist/subagents/taskRunner.d.ts +6 -1
- package/dist/subagents/taskRunner.d.ts.map +1 -1
- package/dist/subagents/taskRunner.js +57 -2
- package/dist/subagents/taskRunner.js.map +1 -1
- package/dist/tools/planningTools.d.ts +9 -0
- package/dist/tools/planningTools.d.ts.map +1 -1
- package/dist/tools/planningTools.js +90 -0
- package/dist/tools/planningTools.js.map +1 -1
- package/dist/ui/display.d.ts +5 -0
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +14 -0
- package/dist/ui/display.js.map +1 -1
- package/dist/ui/shortcutsHelp.d.ts.map +1 -1
- package/dist/ui/shortcutsHelp.js +43 -12
- package/dist/ui/shortcutsHelp.js.map +1 -1
- package/dist/ui/unified/layout.d.ts.map +1 -1
- package/dist/ui/unified/layout.js +9 -9
- package/dist/ui/unified/layout.js.map +1 -1
- package/package.json +1 -1
|
@@ -127,6 +127,11 @@ export class TerminalInput extends EventEmitter {
|
|
|
127
127
|
lastStreamingRender = 0;
|
|
128
128
|
streamingRenderInterval = 250; // ms between renders during streaming
|
|
129
129
|
streamingRenderTimer = null;
|
|
130
|
+
// Command autocomplete state
|
|
131
|
+
commandSuggestions = [];
|
|
132
|
+
showingSuggestions = false;
|
|
133
|
+
selectedSuggestionIndex = 0;
|
|
134
|
+
maxVisibleSuggestions = 10;
|
|
130
135
|
constructor(writeStream = process.stdout, config = {}) {
|
|
131
136
|
super();
|
|
132
137
|
this.out = writeStream;
|
|
@@ -356,6 +361,8 @@ export class TerminalInput extends EventEmitter {
|
|
|
356
361
|
this.historyIndex = -1;
|
|
357
362
|
this.tempInput = '';
|
|
358
363
|
this.pastePlaceholders = [];
|
|
364
|
+
this.showingSuggestions = false;
|
|
365
|
+
this.selectedSuggestionIndex = 0;
|
|
359
366
|
this.scheduleRender();
|
|
360
367
|
}
|
|
361
368
|
/**
|
|
@@ -379,6 +386,148 @@ export class TerminalInput extends EventEmitter {
|
|
|
379
386
|
this.queue = [];
|
|
380
387
|
this.scheduleRender();
|
|
381
388
|
}
|
|
389
|
+
// ===========================================================================
|
|
390
|
+
// COMMAND AUTOCOMPLETE
|
|
391
|
+
// ===========================================================================
|
|
392
|
+
/**
|
|
393
|
+
* Set available commands for autocomplete.
|
|
394
|
+
* Call this once during initialization with all slash commands.
|
|
395
|
+
*/
|
|
396
|
+
setAvailableCommands(commands) {
|
|
397
|
+
this.commandSuggestions = commands;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Check if command suggestions are currently being shown
|
|
401
|
+
*/
|
|
402
|
+
isShowingSuggestions() {
|
|
403
|
+
return this.showingSuggestions;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Get filtered commands based on current input
|
|
407
|
+
*/
|
|
408
|
+
getFilteredCommands() {
|
|
409
|
+
const input = this.buffer.trim().toLowerCase();
|
|
410
|
+
// Only show suggestions if buffer starts with "/"
|
|
411
|
+
if (!input.startsWith('/')) {
|
|
412
|
+
return [];
|
|
413
|
+
}
|
|
414
|
+
// If just "/", show all commands
|
|
415
|
+
if (input === '/') {
|
|
416
|
+
return this.commandSuggestions;
|
|
417
|
+
}
|
|
418
|
+
// Filter commands that match the typed prefix
|
|
419
|
+
return this.commandSuggestions.filter(cmd => cmd.command.toLowerCase().startsWith(input));
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Update suggestion visibility based on current buffer
|
|
423
|
+
*/
|
|
424
|
+
updateSuggestionVisibility() {
|
|
425
|
+
const filtered = this.getFilteredCommands();
|
|
426
|
+
const shouldShow = filtered.length > 0 && this.buffer.startsWith('/');
|
|
427
|
+
if (shouldShow !== this.showingSuggestions) {
|
|
428
|
+
this.showingSuggestions = shouldShow;
|
|
429
|
+
this.selectedSuggestionIndex = 0;
|
|
430
|
+
this.scheduleRender();
|
|
431
|
+
}
|
|
432
|
+
else if (shouldShow) {
|
|
433
|
+
// Clamp selection index
|
|
434
|
+
this.selectedSuggestionIndex = Math.min(this.selectedSuggestionIndex, Math.max(0, filtered.length - 1));
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Handle selecting a suggestion (Enter key or click)
|
|
439
|
+
*/
|
|
440
|
+
selectSuggestion() {
|
|
441
|
+
if (!this.showingSuggestions)
|
|
442
|
+
return false;
|
|
443
|
+
const filtered = this.getFilteredCommands();
|
|
444
|
+
if (filtered.length === 0)
|
|
445
|
+
return false;
|
|
446
|
+
const selected = filtered[this.selectedSuggestionIndex];
|
|
447
|
+
if (!selected)
|
|
448
|
+
return false;
|
|
449
|
+
// Replace buffer with selected command
|
|
450
|
+
this.buffer = selected.command + ' ';
|
|
451
|
+
this.cursor = this.buffer.length;
|
|
452
|
+
this.showingSuggestions = false;
|
|
453
|
+
this.scheduleRender();
|
|
454
|
+
return true;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Move selection up in suggestions list
|
|
458
|
+
*/
|
|
459
|
+
moveSuggestionUp() {
|
|
460
|
+
if (!this.showingSuggestions)
|
|
461
|
+
return false;
|
|
462
|
+
const filtered = this.getFilteredCommands();
|
|
463
|
+
if (filtered.length === 0)
|
|
464
|
+
return false;
|
|
465
|
+
this.selectedSuggestionIndex = Math.max(0, this.selectedSuggestionIndex - 1);
|
|
466
|
+
this.scheduleRender();
|
|
467
|
+
return true;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Move selection down in suggestions list
|
|
471
|
+
*/
|
|
472
|
+
moveSuggestionDown() {
|
|
473
|
+
if (!this.showingSuggestions)
|
|
474
|
+
return false;
|
|
475
|
+
const filtered = this.getFilteredCommands();
|
|
476
|
+
if (filtered.length === 0)
|
|
477
|
+
return false;
|
|
478
|
+
this.selectedSuggestionIndex = Math.min(filtered.length - 1, this.selectedSuggestionIndex + 1);
|
|
479
|
+
this.scheduleRender();
|
|
480
|
+
return true;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Cancel suggestion display (Escape)
|
|
484
|
+
*/
|
|
485
|
+
cancelSuggestions() {
|
|
486
|
+
if (!this.showingSuggestions)
|
|
487
|
+
return false;
|
|
488
|
+
this.showingSuggestions = false;
|
|
489
|
+
this.scheduleRender();
|
|
490
|
+
return true;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Build command suggestion display lines
|
|
494
|
+
*/
|
|
495
|
+
buildSuggestionLines(width) {
|
|
496
|
+
if (!this.showingSuggestions)
|
|
497
|
+
return [];
|
|
498
|
+
const filtered = this.getFilteredCommands();
|
|
499
|
+
if (filtered.length === 0)
|
|
500
|
+
return [];
|
|
501
|
+
const lines = [];
|
|
502
|
+
const maxDisplay = Math.min(filtered.length, this.maxVisibleSuggestions);
|
|
503
|
+
// Header with navigation hint
|
|
504
|
+
const headerText = theme.ui.muted(`─── Commands (↑↓ navigate, Tab/Enter select, Esc cancel) ───`);
|
|
505
|
+
lines.push(headerText);
|
|
506
|
+
// Render visible suggestions
|
|
507
|
+
for (let i = 0; i < maxDisplay; i++) {
|
|
508
|
+
const cmd = filtered[i];
|
|
509
|
+
const isSelected = i === this.selectedSuggestionIndex;
|
|
510
|
+
// Format: [indicator] /command description
|
|
511
|
+
const indicator = isSelected ? theme.accent('▸') : ' ';
|
|
512
|
+
const cmdText = isSelected
|
|
513
|
+
? theme.accent(cmd.command.padEnd(18))
|
|
514
|
+
: theme.primary(cmd.command.padEnd(18));
|
|
515
|
+
// Truncate description to fit
|
|
516
|
+
const descMaxLen = Math.max(10, width - 22);
|
|
517
|
+
const desc = cmd.description.length > descMaxLen
|
|
518
|
+
? cmd.description.slice(0, descMaxLen - 2) + '..'
|
|
519
|
+
: cmd.description;
|
|
520
|
+
const descText = isSelected
|
|
521
|
+
? theme.info(desc)
|
|
522
|
+
: theme.ui.muted(desc);
|
|
523
|
+
lines.push(`${indicator} ${cmdText} ${descText}`);
|
|
524
|
+
}
|
|
525
|
+
// Show "more" indicator if truncated
|
|
526
|
+
if (filtered.length > maxDisplay) {
|
|
527
|
+
lines.push(theme.ui.muted(` ... ${filtered.length - maxDisplay} more commands`));
|
|
528
|
+
}
|
|
529
|
+
return lines;
|
|
530
|
+
}
|
|
382
531
|
/**
|
|
383
532
|
* Update the inline status message shown before the prompt (e.g., streaming heartbeat).
|
|
384
533
|
*/
|
|
@@ -638,10 +787,19 @@ export class TerminalInput extends EventEmitter {
|
|
|
638
787
|
this.write(' '.repeat(padding));
|
|
639
788
|
this.write(ESC.RESET);
|
|
640
789
|
}
|
|
790
|
+
// Command suggestions (shown above controls when "/" is typed)
|
|
791
|
+
const suggestionLines = this.buildSuggestionLines(cols - 2);
|
|
792
|
+
let suggestionRow = currentRow + visibleLines.length;
|
|
793
|
+
for (const suggestionLine of suggestionLines) {
|
|
794
|
+
this.write(ESC.TO(suggestionRow, 1));
|
|
795
|
+
this.write(' '); // Indent to match input
|
|
796
|
+
this.write(suggestionLine);
|
|
797
|
+
suggestionRow += 1;
|
|
798
|
+
}
|
|
641
799
|
// Mode controls lines with all keyboard shortcuts
|
|
642
800
|
// Can be multiple lines during streaming (status + toggles)
|
|
643
801
|
const controlLines = this.buildModeControls(cols);
|
|
644
|
-
let controlRow =
|
|
802
|
+
let controlRow = suggestionRow;
|
|
645
803
|
for (const controlLine of controlLines) {
|
|
646
804
|
this.write(ESC.TO(controlRow, 1));
|
|
647
805
|
this.write(controlLine);
|
|
@@ -762,27 +920,28 @@ export class TerminalInput extends EventEmitter {
|
|
|
762
920
|
// === LINE 2: MODE TOGGLES (always visible, same as before streaming) ===
|
|
763
921
|
const toggleParts = [];
|
|
764
922
|
// Claude Code style mode indicator: "⏵⏵ accept edits on (shift+tab to cycle)"
|
|
765
|
-
const editModeLabel = this.editMode === 'display-edits' ? 'auto' :
|
|
766
|
-
|
|
923
|
+
const editModeLabel = this.editMode === 'display-edits' ? 'auto' :
|
|
924
|
+
this.editMode === 'ask-permission' ? 'ask' : 'plan';
|
|
925
|
+
toggleParts.push({ text: formatEditModeIndicator(editModeLabel), tone: editModeLabel === 'plan' ? 'info' : undefined });
|
|
767
926
|
// Context usage (show percentage remaining)
|
|
768
927
|
if (this.contextUsage !== null) {
|
|
769
928
|
const remaining = 100 - this.contextUsage;
|
|
770
929
|
const contextTone = this.contextUsage > 80 ? 'warn' : this.contextUsage > 60 ? 'info' : 'muted';
|
|
771
930
|
toggleParts.push({ text: `ctx:${remaining}%`, tone: contextTone });
|
|
772
931
|
}
|
|
773
|
-
// Verification toggle (
|
|
932
|
+
// Verification toggle (Alt+V)
|
|
774
933
|
const verifyStatus = this.verificationEnabled ? '✓' : '○';
|
|
775
934
|
toggleParts.push({
|
|
776
935
|
text: `⌥V:${verifyStatus}verify`,
|
|
777
936
|
tone: this.verificationEnabled ? 'success' : 'muted'
|
|
778
937
|
});
|
|
779
|
-
// Auto-continue toggle (
|
|
938
|
+
// Auto-continue toggle (Alt+C)
|
|
780
939
|
const autoStatus = this.autoContinueEnabled ? '↻' : '○';
|
|
781
940
|
toggleParts.push({
|
|
782
941
|
text: `⌥C:${autoStatus}auto`,
|
|
783
942
|
tone: this.autoContinueEnabled ? 'info' : 'muted'
|
|
784
943
|
});
|
|
785
|
-
// Thinking mode toggle (
|
|
944
|
+
// Thinking mode toggle (Alt+T)
|
|
786
945
|
if (this.thinkingModeLabel) {
|
|
787
946
|
const shortThinking = this.thinkingModeLabel.length > 10
|
|
788
947
|
? this.thinkingModeLabel.slice(0, 8) + '..'
|
|
@@ -1047,6 +1206,7 @@ export class TerminalInput extends EventEmitter {
|
|
|
1047
1206
|
* - Meta lines (model, elapsed, tokens)
|
|
1048
1207
|
* - Divider
|
|
1049
1208
|
* - Input line(s) - expands for multi-line/wrapped input
|
|
1209
|
+
* - Command suggestions (when showing)
|
|
1050
1210
|
* - Control lines (wraps as needed to fit all toggles)
|
|
1051
1211
|
* - Buffer
|
|
1052
1212
|
*/
|
|
@@ -1064,10 +1224,18 @@ export class TerminalInput extends EventEmitter {
|
|
|
1064
1224
|
// Meta line only if we have model/elapsed info
|
|
1065
1225
|
const hasMetaInfo = this.modelLabel || this.metaElapsedSeconds !== null || this.metaTokensUsed !== null;
|
|
1066
1226
|
const metaLines = hasMetaInfo ? 1 : 0;
|
|
1067
|
-
//
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1227
|
+
// Command suggestion lines (when showing)
|
|
1228
|
+
let suggestionLines = 0;
|
|
1229
|
+
if (this.showingSuggestions) {
|
|
1230
|
+
const filtered = this.getFilteredCommands();
|
|
1231
|
+
suggestionLines = Math.min(filtered.length, this.maxVisibleSuggestions) + 1; // +1 for header
|
|
1232
|
+
}
|
|
1233
|
+
// Total: meta + divider + input lines + suggestions + controls + buffer
|
|
1234
|
+
// Limit total height to leave room for content (max ~50% of terminal when showing suggestions)
|
|
1235
|
+
const totalHeight = metaLines + 1 + inputLines + suggestionLines + controlLineCount + 1;
|
|
1236
|
+
const maxHeight = this.showingSuggestions
|
|
1237
|
+
? Math.max(12, Math.floor(rows * 0.5))
|
|
1238
|
+
: Math.max(6, Math.floor(rows * 0.4));
|
|
1071
1239
|
return Math.min(totalHeight, maxHeight);
|
|
1072
1240
|
}
|
|
1073
1241
|
/**
|
|
@@ -1324,10 +1492,21 @@ export class TerminalInput extends EventEmitter {
|
|
|
1324
1492
|
if (key.shift || key.meta) {
|
|
1325
1493
|
this.insertNewline();
|
|
1326
1494
|
}
|
|
1495
|
+
else if (this.showingSuggestions) {
|
|
1496
|
+
// Select suggestion and don't submit yet
|
|
1497
|
+
this.selectSuggestion();
|
|
1498
|
+
}
|
|
1327
1499
|
else {
|
|
1328
1500
|
this.submit();
|
|
1329
1501
|
}
|
|
1330
1502
|
return true;
|
|
1503
|
+
case 'escape':
|
|
1504
|
+
// Cancel suggestions first, or emit interrupt
|
|
1505
|
+
if (this.cancelSuggestions()) {
|
|
1506
|
+
return true;
|
|
1507
|
+
}
|
|
1508
|
+
this.emit('interrupt');
|
|
1509
|
+
return true;
|
|
1331
1510
|
case 'backspace':
|
|
1332
1511
|
this.deleteBackward();
|
|
1333
1512
|
return true;
|
|
@@ -1335,12 +1514,25 @@ export class TerminalInput extends EventEmitter {
|
|
|
1335
1514
|
this.deleteForward();
|
|
1336
1515
|
return true;
|
|
1337
1516
|
case 'left':
|
|
1517
|
+
// Cancel suggestions on cursor movement
|
|
1518
|
+
if (this.showingSuggestions) {
|
|
1519
|
+
this.cancelSuggestions();
|
|
1520
|
+
}
|
|
1338
1521
|
this.moveCursorLeft();
|
|
1339
1522
|
return true;
|
|
1340
1523
|
case 'right':
|
|
1524
|
+
// Cancel suggestions on cursor movement
|
|
1525
|
+
if (this.showingSuggestions) {
|
|
1526
|
+
this.cancelSuggestions();
|
|
1527
|
+
}
|
|
1341
1528
|
this.moveCursorRight();
|
|
1342
1529
|
return true;
|
|
1343
1530
|
case 'up':
|
|
1531
|
+
// When showing suggestions, navigate up
|
|
1532
|
+
if (this.showingSuggestions) {
|
|
1533
|
+
this.moveSuggestionUp();
|
|
1534
|
+
return true;
|
|
1535
|
+
}
|
|
1344
1536
|
// Ctrl+Shift+Up or Shift+Up: Quick scroll up in scrollback
|
|
1345
1537
|
if ((key.ctrl && key.shift) || key.shift) {
|
|
1346
1538
|
this.scrollUp(5);
|
|
@@ -1350,6 +1542,11 @@ export class TerminalInput extends EventEmitter {
|
|
|
1350
1542
|
}
|
|
1351
1543
|
return true;
|
|
1352
1544
|
case 'down':
|
|
1545
|
+
// When showing suggestions, navigate down
|
|
1546
|
+
if (this.showingSuggestions) {
|
|
1547
|
+
this.moveSuggestionDown();
|
|
1548
|
+
return true;
|
|
1549
|
+
}
|
|
1353
1550
|
// Ctrl+Shift+Down or Shift+Down: Quick scroll down in scrollback
|
|
1354
1551
|
if ((key.ctrl && key.shift) || key.shift) {
|
|
1355
1552
|
this.scrollDown(5);
|
|
@@ -1384,6 +1581,11 @@ export class TerminalInput extends EventEmitter {
|
|
|
1384
1581
|
// Scrollback disabled in alternate screen mode
|
|
1385
1582
|
return true;
|
|
1386
1583
|
case 'tab':
|
|
1584
|
+
// Tab can select suggestion too
|
|
1585
|
+
if (this.showingSuggestions && !key.shift) {
|
|
1586
|
+
this.selectSuggestion();
|
|
1587
|
+
return true;
|
|
1588
|
+
}
|
|
1387
1589
|
if (key.shift) {
|
|
1388
1590
|
this.toggleEditMode();
|
|
1389
1591
|
return true;
|
|
@@ -1406,6 +1608,8 @@ export class TerminalInput extends EventEmitter {
|
|
|
1406
1608
|
this.insertPlainText(chunk, insertPos);
|
|
1407
1609
|
this.cursor = insertPos + chunk.length;
|
|
1408
1610
|
this.emit('change', this.buffer);
|
|
1611
|
+
// Update command autocomplete visibility
|
|
1612
|
+
this.updateSuggestionVisibility();
|
|
1409
1613
|
this.scheduleRender();
|
|
1410
1614
|
}
|
|
1411
1615
|
insertNewline() {
|
|
@@ -1430,6 +1634,7 @@ export class TerminalInput extends EventEmitter {
|
|
|
1430
1634
|
this.cursor = Math.max(0, this.cursor - 1);
|
|
1431
1635
|
}
|
|
1432
1636
|
this.emit('change', this.buffer);
|
|
1637
|
+
this.updateSuggestionVisibility();
|
|
1433
1638
|
this.scheduleRender();
|
|
1434
1639
|
}
|
|
1435
1640
|
deleteForward() {
|
|
@@ -1443,6 +1648,7 @@ export class TerminalInput extends EventEmitter {
|
|
|
1443
1648
|
this.removeRange(this.cursor, this.cursor + 1);
|
|
1444
1649
|
}
|
|
1445
1650
|
this.emit('change', this.buffer);
|
|
1651
|
+
this.updateSuggestionVisibility();
|
|
1446
1652
|
this.scheduleRender();
|
|
1447
1653
|
}
|
|
1448
1654
|
deleteToStart() {
|
|
@@ -1451,6 +1657,7 @@ export class TerminalInput extends EventEmitter {
|
|
|
1451
1657
|
this.removeRange(0, this.cursor);
|
|
1452
1658
|
this.cursor = 0;
|
|
1453
1659
|
this.emit('change', this.buffer);
|
|
1660
|
+
this.updateSuggestionVisibility();
|
|
1454
1661
|
this.scheduleRender();
|
|
1455
1662
|
}
|
|
1456
1663
|
deleteToEnd() {
|
|
@@ -1458,6 +1665,7 @@ export class TerminalInput extends EventEmitter {
|
|
|
1458
1665
|
return;
|
|
1459
1666
|
this.removeRange(this.cursor, this.buffer.length);
|
|
1460
1667
|
this.emit('change', this.buffer);
|
|
1668
|
+
this.updateSuggestionVisibility();
|
|
1461
1669
|
this.scheduleRender();
|
|
1462
1670
|
}
|
|
1463
1671
|
deleteWord() {
|
|
@@ -2050,8 +2258,11 @@ export class TerminalInput extends EventEmitter {
|
|
|
2050
2258
|
this.scheduleRender();
|
|
2051
2259
|
}
|
|
2052
2260
|
toggleEditMode() {
|
|
2053
|
-
|
|
2054
|
-
|
|
2261
|
+
// Cycle through: display-edits → ask-permission → plan → display-edits
|
|
2262
|
+
const cycle = ['display-edits', 'ask-permission', 'plan'];
|
|
2263
|
+
const currentIndex = cycle.indexOf(this.editMode);
|
|
2264
|
+
const nextIndex = (currentIndex + 1) % cycle.length;
|
|
2265
|
+
this.setEditMode(cycle[nextIndex]);
|
|
2055
2266
|
}
|
|
2056
2267
|
scheduleStreamingRender(delayMs) {
|
|
2057
2268
|
if (this.streamingRenderTimer)
|