erosolar-cli 1.7.162 → 1.7.165

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.
Files changed (39) hide show
  1. package/dist/contracts/unified-schema.json +6 -6
  2. package/dist/core/types.d.ts +1 -0
  3. package/dist/core/types.d.ts.map +1 -1
  4. package/dist/core/unified/tools.d.ts.map +1 -1
  5. package/dist/core/unified/tools.js +15 -37
  6. package/dist/core/unified/tools.js.map +1 -1
  7. package/dist/shell/interactiveShell.d.ts +25 -0
  8. package/dist/shell/interactiveShell.d.ts.map +1 -1
  9. package/dist/shell/interactiveShell.js +104 -50
  10. package/dist/shell/interactiveShell.js.map +1 -1
  11. package/dist/shell/shellApp.d.ts.map +1 -1
  12. package/dist/shell/shellApp.js +6 -2
  13. package/dist/shell/shellApp.js.map +1 -1
  14. package/dist/shell/unifiedChatBox.d.ts +178 -0
  15. package/dist/shell/unifiedChatBox.d.ts.map +1 -0
  16. package/dist/shell/unifiedChatBox.js +539 -0
  17. package/dist/shell/unifiedChatBox.js.map +1 -0
  18. package/dist/tools/codeQualityTools.d.ts.map +1 -1
  19. package/dist/tools/codeQualityTools.js +112 -0
  20. package/dist/tools/codeQualityTools.js.map +1 -1
  21. package/dist/tools/diffUtils.d.ts +1 -1
  22. package/dist/tools/diffUtils.d.ts.map +1 -1
  23. package/dist/tools/diffUtils.js +19 -3
  24. package/dist/tools/diffUtils.js.map +1 -1
  25. package/dist/tools/editTools.d.ts +11 -0
  26. package/dist/tools/editTools.d.ts.map +1 -1
  27. package/dist/tools/editTools.js +191 -119
  28. package/dist/tools/editTools.js.map +1 -1
  29. package/dist/tools/fileTools.js +1 -1
  30. package/dist/tools/fileTools.js.map +1 -1
  31. package/dist/tools/softwareEngineeringTools.d.ts +7 -0
  32. package/dist/tools/softwareEngineeringTools.d.ts.map +1 -0
  33. package/dist/tools/softwareEngineeringTools.js +338 -0
  34. package/dist/tools/softwareEngineeringTools.js.map +1 -0
  35. package/dist/ui/display.d.ts +17 -0
  36. package/dist/ui/display.d.ts.map +1 -1
  37. package/dist/ui/display.js +34 -0
  38. package/dist/ui/display.js.map +1 -1
  39. package/package.json +1 -1
@@ -24,6 +24,7 @@ import { formatShortcutsHelp } from '../ui/shortcutsHelp.js';
24
24
  import { MetricsTracker } from '../alpha-zero/index.js';
25
25
  import { listAvailablePlugins } from '../plugins/index.js';
26
26
  import { getClaudeCodeStreamHandler } from './claudeCodeStreamHandler.js';
27
+ import { getUnifiedChatBox } from './unifiedChatBox.js';
27
28
  const DROPDOWN_COLORS = [
28
29
  theme.primary,
29
30
  theme.info,
@@ -116,6 +117,9 @@ export class InteractiveShell {
116
117
  readlineOutputSuppressed = false;
117
118
  originalStdoutWrite = null;
118
119
  streamHandler;
120
+ unifiedChatBox;
121
+ // Cached provider status for unified status bar display after streaming
122
+ cachedProviderStatus = [];
119
123
  constructor(config) {
120
124
  this.profile = config.profile;
121
125
  this.profileLabel = config.profileLabel;
@@ -232,6 +236,13 @@ export class InteractiveShell {
232
236
  // Key insight: No cursor manipulation during streaming - output just appends
233
237
  this.streamHandler = getClaudeCodeStreamHandler();
234
238
  this.streamHandler.attachToReadline(this.rl);
239
+ // Initialize UnifiedChatBox - Claude Code exact style
240
+ // The chat box is always at the bottom naturally through readline
241
+ // During streaming: output flows up, typed input queued invisibly
242
+ // After streaming: new prompt appears at bottom naturally
243
+ this.unifiedChatBox = getUnifiedChatBox();
244
+ this.unifiedChatBox.attachToReadline(this.rl);
245
+ this.unifiedChatBox.setPrompt(formatUserPrompt(this.profileLabel || this.profile));
235
246
  // Initialize Alpha Zero 2 metrics tracking
236
247
  this.alphaZeroMetrics = new MetricsTracker(`${this.profile}-${Date.now()}`);
237
248
  this.setupStatusTracking();
@@ -284,15 +295,16 @@ export class InteractiveShell {
284
295
  this.sessionResumeNotice = null;
285
296
  }
286
297
  async start(initialPrompt) {
287
- // Always render the pinned chat box at startup so it's visible from the beginning
288
- this.pinnedChatBox.show();
289
- this.pinnedChatBox.forceRender();
298
+ // Claude Code style: Just use readline's prompt
299
+ // The prompt naturally appears at the bottom
300
+ // No complex UI rendering needed - terminal handles it naturally
290
301
  if (initialPrompt) {
291
302
  display.newLine();
292
303
  console.log(`${formatUserPrompt(this.profileLabel || this.profile)}${initialPrompt}`);
293
304
  await this.processInputBlock(initialPrompt);
294
305
  return;
295
306
  }
307
+ // Show readline prompt - naturally at bottom of terminal
296
308
  this.rl.prompt();
297
309
  }
298
310
  async handleToolSettingsInput(input) {
@@ -490,6 +502,8 @@ export class InteractiveShell {
490
502
  this.persistentPrompt.dispose();
491
503
  // Dispose Claude Code stream handler
492
504
  this.streamHandler.dispose();
505
+ // Dispose unified chat box
506
+ this.unifiedChatBox.dispose();
493
507
  // Dispose unified UI adapter
494
508
  this.uiAdapter.dispose();
495
509
  display.newLine();
@@ -1105,7 +1119,10 @@ export class InteractiveShell {
1105
1119
  * Process any inputs that were queued during streaming.
1106
1120
  * Claude Code style: User can type while streaming, input is stored in queue,
1107
1121
  * processed after streaming ends.
1122
+ *
1123
+ * @deprecated Use processUnifiedChatBoxQueue() instead
1108
1124
  */
1125
+ // @ts-expect-error - Legacy method kept for backwards compatibility
1109
1126
  processQueuedInputs() {
1110
1127
  if (!this.streamHandler.hasQueuedInput()) {
1111
1128
  return;
@@ -1134,6 +1151,36 @@ export class InteractiveShell {
1134
1151
  display.showInfo(`šŸ“ ${summary}`);
1135
1152
  }
1136
1153
  }
1154
+ /**
1155
+ * Process any inputs that were queued in UnifiedChatBox during streaming.
1156
+ * Claude Code style: User can type while streaming, input is stored invisibly,
1157
+ * processed after streaming ends.
1158
+ */
1159
+ processUnifiedChatBoxQueue() {
1160
+ if (!this.unifiedChatBox.hasQueuedInput()) {
1161
+ return;
1162
+ }
1163
+ // Transfer queued inputs from unified chat box to follow-up queue
1164
+ while (this.unifiedChatBox.hasQueuedInput()) {
1165
+ const input = this.unifiedChatBox.dequeue();
1166
+ if (!input) {
1167
+ break;
1168
+ }
1169
+ // Handle interrupts specially - they cancel current operation
1170
+ if (input.type === 'interrupt') {
1171
+ // Request cancellation if agent is running
1172
+ if (this.agent) {
1173
+ this.agent.requestCancellation();
1174
+ }
1175
+ continue;
1176
+ }
1177
+ // Add to follow-up queue for processing
1178
+ this.followUpQueue.push({
1179
+ type: 'request',
1180
+ text: input.text,
1181
+ });
1182
+ }
1183
+ }
1137
1184
  async processQueuedActions() {
1138
1185
  if (this.isDrainingQueue || this.isProcessing || !this.followUpQueue.length) {
1139
1186
  return;
@@ -2469,26 +2516,20 @@ export class InteractiveShell {
2469
2516
  }
2470
2517
  this.isProcessing = true;
2471
2518
  const requestStartTime = Date.now(); // Alpha Zero 2 timing
2472
- // Keep persistent prompt visible during processing so users can type follow-up requests
2473
- // The prompt will show a "processing" indicator but remain interactive
2474
- this.persistentPrompt.updateStatusBar({ message: 'ā³ Processing... (type to queue follow-up)' });
2475
- // Update pinned chat box to show processing state
2476
- // Clear the input display since the request was already submitted
2477
- // Note: Don't set statusMessage here - the isProcessing flag already shows "ā³ Processing..."
2478
- this.pinnedChatBox.setProcessing(true);
2479
- this.pinnedChatBox.setStatusMessage(null); // Clear any previous status to avoid duplication
2480
- this.pinnedChatBox.clearInput();
2519
+ // Claude Code style: Update status (optional, won't interfere with streaming)
2520
+ this.persistentPrompt.updateStatusBar({ message: 'ā³ Processing...' });
2481
2521
  this.uiAdapter.startProcessing('Working on your request');
2482
2522
  this.setProcessingStatus();
2483
2523
  try {
2484
2524
  // Add visual separator between user prompt and AI response
2485
2525
  display.newLine();
2486
2526
  display.newLine();
2487
- // Claude Code style: Start streaming mode
2488
- // - Output flows naturally to stdout (no cursor manipulation)
2489
- // - User input is queued in memory, not rendered
2490
- // - After streaming ends, new prompt is shown at bottom
2491
- this.streamHandler.startStreaming();
2527
+ // Claude Code style: Start streaming mode using UnifiedChatBox
2528
+ // - Output flows naturally to stdout (NO cursor manipulation)
2529
+ // - User input is captured invisibly and queued
2530
+ // - Prompt scrolls up naturally with output
2531
+ // - After streaming ends, new prompt appears at bottom
2532
+ this.unifiedChatBox.startStreaming();
2492
2533
  // Enable streaming for real-time text output (Claude Code style)
2493
2534
  await agent.send(request, true);
2494
2535
  await this.awaitPendingCleanup();
@@ -2506,25 +2547,27 @@ export class InteractiveShell {
2506
2547
  }
2507
2548
  }
2508
2549
  finally {
2509
- // Claude Code style: End streaming mode
2510
- // This restores readline output and processes any queued input
2511
- this.streamHandler.endStreaming();
2550
+ // Claude Code style: End streaming mode using UnifiedChatBox
2551
+ // This restores readline echo and returns queue info
2552
+ const streamResult = this.unifiedChatBox.endStreaming();
2512
2553
  // Process any queued inputs that came in during streaming
2513
- this.processQueuedInputs();
2554
+ this.processUnifiedChatBoxQueue();
2555
+ // Show queue indicator if there were queued inputs
2556
+ if (streamResult.queuedCount > 0) {
2557
+ this.unifiedChatBox.showQueueIndicator();
2558
+ }
2514
2559
  display.stopThinking(false);
2515
2560
  this.isProcessing = false;
2516
2561
  this.uiAdapter.endProcessing('Ready for prompts');
2517
2562
  this.setIdleStatus();
2518
2563
  display.newLine();
2519
- // Clear the processing status and ensure persistent prompt is visible
2564
+ // Clear the processing status
2520
2565
  this.persistentPrompt.updateStatusBar({ message: undefined });
2521
- this.persistentPrompt.show();
2522
- // Update pinned chat box to show ready state and force render
2523
- this.pinnedChatBox.setProcessing(false);
2524
- this.pinnedChatBox.setStatusMessage(null);
2525
- this.pinnedChatBox.forceRender();
2566
+ // Claude Code style: Show unified status bar before prompt
2567
+ // This creates consistent UI between startup and post-streaming
2568
+ this.showUnifiedStatusBar();
2526
2569
  // CRITICAL: Ensure readline prompt is active for user input
2527
- // Call ensureReadlineReady to resume stdin if paused and re-enable keypress
2570
+ // Claude Code style: New prompt naturally appears at bottom
2528
2571
  this.ensureReadlineReady();
2529
2572
  this.rl.prompt();
2530
2573
  this.scheduleQueueProcessing();
@@ -2562,21 +2605,17 @@ export class InteractiveShell {
2562
2605
  // Initialize the task completion detector
2563
2606
  const completionDetector = getTaskCompletionDetector();
2564
2607
  completionDetector.reset();
2565
- // Keep persistent prompt visible during processing so users can type follow-up requests
2566
- this.persistentPrompt.updateStatusBar({ message: 'šŸ”„ Continuous mode... (type to queue follow-up)' });
2567
- // Update pinned chat box for continuous mode
2568
- // Clear the input display since the request was already submitted
2569
- this.pinnedChatBox.setProcessing(true);
2570
- this.pinnedChatBox.setStatusMessage('Continuous execution mode...');
2571
- this.pinnedChatBox.clearInput();
2608
+ // Claude Code style: Update status
2609
+ this.persistentPrompt.updateStatusBar({ message: 'šŸ”„ Continuous mode...' });
2572
2610
  display.showSystemMessage(`šŸ”„ Starting continuous execution mode. Press Ctrl+C to stop.`);
2573
2611
  display.showSystemMessage(`šŸ“Š Using intelligent task completion detection with AI verification.`);
2574
2612
  this.uiAdapter.startProcessing('Continuous execution mode');
2575
2613
  this.setProcessingStatus();
2576
- // Claude Code style: Start streaming mode
2577
- // - Output flows naturally to stdout (no cursor manipulation)
2578
- // - User input is queued in memory, not rendered
2579
- this.streamHandler.startStreaming();
2614
+ // Claude Code style: Start streaming mode using UnifiedChatBox
2615
+ // - Output flows naturally to stdout (NO cursor manipulation)
2616
+ // - User input is captured invisibly and queued
2617
+ // - Prompt scrolls up naturally with output
2618
+ this.unifiedChatBox.startStreaming();
2580
2619
  let iteration = 0;
2581
2620
  let lastResponse = '';
2582
2621
  let consecutiveNoProgress = 0;
@@ -2738,24 +2777,25 @@ What's the next action?`;
2738
2777
  display.showSystemMessage(`\nšŸ Continuous execution completed: ${iteration} iterations, ${minutes}m ${seconds}s total`);
2739
2778
  // Reset completion detector for next task
2740
2779
  resetTaskCompletionDetector();
2741
- // Claude Code style: End streaming mode
2742
- // This restores readline output and processes any queued input
2743
- this.streamHandler.endStreaming();
2780
+ // Claude Code style: End streaming mode using UnifiedChatBox
2781
+ const streamResult = this.unifiedChatBox.endStreaming();
2744
2782
  // Process any queued inputs that came in during streaming
2745
- this.processQueuedInputs();
2783
+ this.processUnifiedChatBoxQueue();
2784
+ // Show queue indicator if there were queued inputs
2785
+ if (streamResult.queuedCount > 0) {
2786
+ this.unifiedChatBox.showQueueIndicator();
2787
+ }
2746
2788
  this.isProcessing = false;
2747
2789
  this.uiAdapter.endProcessing('Ready for prompts');
2748
2790
  this.setIdleStatus();
2749
2791
  display.newLine();
2750
- // Clear the processing status and ensure persistent prompt is visible
2792
+ // Clear the processing status
2751
2793
  this.persistentPrompt.updateStatusBar({ message: undefined });
2752
- this.persistentPrompt.show();
2753
- // Update pinned chat box to show ready state and force render
2754
- this.pinnedChatBox.setProcessing(false);
2755
- this.pinnedChatBox.setStatusMessage(null);
2756
- this.pinnedChatBox.forceRender();
2794
+ // Claude Code style: Show unified status bar before prompt
2795
+ // This creates consistent UI between startup and post-streaming
2796
+ this.showUnifiedStatusBar();
2757
2797
  // CRITICAL: Ensure readline prompt is active for user input
2758
- // Call ensureReadlineReady to resume stdin if paused and re-enable keypress
2798
+ // Claude Code style: New prompt naturally appears at bottom
2759
2799
  this.ensureReadlineReady();
2760
2800
  this.rl.prompt();
2761
2801
  this.scheduleQueueProcessing();
@@ -3747,6 +3787,20 @@ What's the next action?`;
3747
3787
  this.bracketedPaste.reset();
3748
3788
  }
3749
3789
  }
3790
+ /**
3791
+ * Set the cached provider status for unified status bar display.
3792
+ * Called once at startup after checking providers.
3793
+ */
3794
+ setProviderStatus(providers) {
3795
+ this.cachedProviderStatus = providers;
3796
+ }
3797
+ /**
3798
+ * Show the unified status bar (Claude Code style).
3799
+ * Displays provider indicators and ready hints before the prompt.
3800
+ */
3801
+ showUnifiedStatusBar() {
3802
+ display.showUnifiedStatusBar(this.cachedProviderStatus);
3803
+ }
3750
3804
  }
3751
3805
  function setsEqual(first, second) {
3752
3806
  if (first.size !== second.size) {