erosolar-cli 1.7.401 โ†’ 1.7.403

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 (41) hide show
  1. package/README.md +6 -6
  2. package/dist/contracts/agent-profiles.schema.json +5 -5
  3. package/dist/contracts/agent-schemas.json +5 -5
  4. package/dist/contracts/unified-schema.json +3 -3
  5. package/dist/core/modelDiscovery.js +3 -3
  6. package/dist/core/modelDiscovery.js.map +1 -1
  7. package/dist/core/secretStore.d.ts.map +1 -1
  8. package/dist/core/secretStore.js +0 -31
  9. package/dist/core/secretStore.js.map +1 -1
  10. package/dist/plugins/providers/google/index.js +2 -3
  11. package/dist/plugins/providers/google/index.js.map +1 -1
  12. package/dist/shell/interactiveShell.d.ts +4 -0
  13. package/dist/shell/interactiveShell.d.ts.map +1 -1
  14. package/dist/shell/interactiveShell.js +58 -21
  15. package/dist/shell/interactiveShell.js.map +1 -1
  16. package/dist/shell/terminalInput.d.ts +3 -1
  17. package/dist/shell/terminalInput.d.ts.map +1 -1
  18. package/dist/shell/terminalInput.js +17 -11
  19. package/dist/shell/terminalInput.js.map +1 -1
  20. package/dist/shell/terminalInputAdapter.d.ts +3 -1
  21. package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
  22. package/dist/shell/terminalInputAdapter.js +2 -2
  23. package/dist/shell/terminalInputAdapter.js.map +1 -1
  24. package/dist/tools/editTools.js +1 -1
  25. package/dist/tools/editTools.js.map +1 -1
  26. package/dist/ui/ShellUIAdapter.d.ts +22 -13
  27. package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
  28. package/dist/ui/ShellUIAdapter.js +272 -65
  29. package/dist/ui/ShellUIAdapter.js.map +1 -1
  30. package/dist/ui/assistantBlockRenderer.d.ts +1 -0
  31. package/dist/ui/assistantBlockRenderer.d.ts.map +1 -1
  32. package/dist/ui/assistantBlockRenderer.js +17 -2
  33. package/dist/ui/assistantBlockRenderer.js.map +1 -1
  34. package/dist/ui/orchestration/UIUpdateCoordinator.d.ts.map +1 -1
  35. package/dist/ui/orchestration/UIUpdateCoordinator.js +5 -3
  36. package/dist/ui/orchestration/UIUpdateCoordinator.js.map +1 -1
  37. package/dist/ui/shortcutsHelp.d.ts +0 -10
  38. package/dist/ui/shortcutsHelp.d.ts.map +1 -1
  39. package/dist/ui/shortcutsHelp.js +0 -52
  40. package/dist/ui/shortcutsHelp.js.map +1 -1
  41. package/package.json +1 -1
@@ -190,6 +190,7 @@ export class InteractiveShell {
190
190
  assistantStreamHeaderShown = false;
191
191
  assistantStreamBuffer = '';
192
192
  assistantStreamMetadata;
193
+ assistantStreamHadContent = false;
193
194
  lastRequestStartedAt = null;
194
195
  lastToolSummaryRenderedAt = null;
195
196
  constructor(config) {
@@ -329,7 +330,6 @@ export class InteractiveShell {
329
330
  }
330
331
  // Stream banner first - this sets up scroll region dynamically
331
332
  const banner = this.buildBanner();
332
- this.terminalInput.setSessionFrame(this.getSessionFrameProps());
333
333
  this.terminalInput.streamContent(banner + '\n\n');
334
334
  this.rebuildAgent();
335
335
  this.setupHandlers();
@@ -913,7 +913,7 @@ export class InteractiveShell {
913
913
  // Clear any pending cleanup to prevent hanging
914
914
  this.pendingCleanup = null;
915
915
  // Reset terminal state before disposing adapters
916
- this.terminalInput.exitStreamingScrollRegion();
916
+ this.terminalInput.exitStreamingScrollRegion({ skipRender: true });
917
917
  if (this.alternateScreenEnabled) {
918
918
  this.terminalInput.exitAlternateScreen();
919
919
  }
@@ -1361,6 +1361,14 @@ export class InteractiveShell {
1361
1361
  // Route through display stream so scroll regions and streaming locks stay in sync
1362
1362
  display.stream(content);
1363
1363
  }
1364
+ resetAssistantStreamTracking() {
1365
+ this.assistantStreamActive = false;
1366
+ this.assistantStreamPhase = null;
1367
+ this.assistantStreamHeaderShown = false;
1368
+ this.assistantStreamBuffer = '';
1369
+ this.assistantStreamMetadata = undefined;
1370
+ this.assistantStreamHadContent = false;
1371
+ }
1364
1372
  startAssistantStream(metadata) {
1365
1373
  if (this.assistantStreamActive) {
1366
1374
  this.assistantStreamMetadata = metadata ?? this.assistantStreamMetadata;
@@ -1371,6 +1379,7 @@ export class InteractiveShell {
1371
1379
  this.assistantStreamHeaderShown = false;
1372
1380
  this.assistantStreamBuffer = '';
1373
1381
  this.assistantStreamMetadata = metadata;
1382
+ this.assistantStreamHadContent = false;
1374
1383
  }
1375
1384
  streamAssistantChunk(chunk) {
1376
1385
  if (!chunk) {
@@ -1395,7 +1404,6 @@ export class InteractiveShell {
1395
1404
  this.assistantStreamPhase = null;
1396
1405
  this.assistantStreamHeaderShown = false;
1397
1406
  this.assistantStreamMetadata = undefined;
1398
- this.enqueueAssistantStream('\n\n');
1399
1407
  }
1400
1408
  processAssistantStreamChunk(chunk) {
1401
1409
  this.assistantStreamBuffer += chunk;
@@ -1435,6 +1443,9 @@ export class InteractiveShell {
1435
1443
  if (!content) {
1436
1444
  return;
1437
1445
  }
1446
+ if (content.trim().length > 0) {
1447
+ this.assistantStreamHadContent = true;
1448
+ }
1438
1449
  if (!this.assistantStreamPhase) {
1439
1450
  this.setAssistantStreamPhase('response');
1440
1451
  }
@@ -1528,31 +1539,57 @@ export class InteractiveShell {
1528
1539
  }
1529
1540
  renderAssistantFallback(type, content, metadata) {
1530
1541
  const header = this.formatAssistantHeader(type, metadata);
1531
- const block = `\n${header}\n${content.trimEnd()}\n\n`;
1542
+ const compact = content.trimEnd().replace(/\n{3,}/g, '\n\n');
1543
+ const block = `\n${header}\n${compact}\n\n`;
1532
1544
  this.enqueueAssistantStream(block);
1533
1545
  }
1534
1546
  formatAssistantHeader(type, metadata) {
1535
1547
  if (this.assistantBlocksEnabled && this.assistantBlockRenderer) {
1536
1548
  return this.assistantBlockRenderer.formatHeader(type, metadata);
1537
1549
  }
1538
- const label = type === 'thought' ? 'Thought' : type === 'tools' ? 'Tools' : 'Response';
1550
+ const badges = [];
1551
+ badges.push(this.buildAssistantTypeBadge(type));
1539
1552
  const timestamp = new Date().toLocaleTimeString('en-US', {
1540
1553
  hour12: false,
1541
1554
  hour: '2-digit',
1542
1555
  minute: '2-digit',
1543
1556
  second: '2-digit',
1544
1557
  });
1545
- const parts = [`${label} ยท ${timestamp}`];
1558
+ badges.push({ text: timestamp, style: 'muted', icon: '๐Ÿ•‘' });
1546
1559
  const total = metadata?.usage ? this.totalTokens(metadata.usage) : null;
1547
- if (total) {
1548
- parts.push(`${total} tok`);
1549
- }
1550
1560
  const windowTokens = metadata?.contextWindowTokens;
1551
- if (total && windowTokens) {
1561
+ if (typeof total === 'number') {
1562
+ badges.push({ text: `${total} tok`, style: 'muted', icon: 'โŽ' });
1563
+ }
1564
+ if (typeof total === 'number' && typeof windowTokens === 'number' && windowTokens > 0) {
1552
1565
  const percentage = Math.round((total / windowTokens) * 100);
1553
- parts.push(`${percentage}% ctx`);
1566
+ const style = percentage > 85 ? 'error' : percentage > 70 ? 'warning' : 'info';
1567
+ badges.push({ text: `${percentage}% ctx`, style, icon: 'โŠ›' });
1568
+ }
1569
+ const elapsedBadge = this.buildElapsedBadge(metadata);
1570
+ if (elapsedBadge) {
1571
+ badges.push(elapsedBadge);
1572
+ }
1573
+ return compactRenderer.formatBadges(badges, theme.ui.muted(' โ”‚ '));
1574
+ }
1575
+ buildAssistantTypeBadge(type) {
1576
+ switch (type) {
1577
+ case 'thought':
1578
+ return { text: 'Thought', style: 'info', icon: '๐Ÿ’ญ' };
1579
+ case 'tools':
1580
+ return { text: 'Tools', style: 'primary', icon: '๐Ÿ› ' };
1581
+ case 'response':
1582
+ default:
1583
+ return { text: 'Response', style: 'success', icon: '๐Ÿ’ฌ' };
1554
1584
  }
1555
- return parts.join(' โ€ข ');
1585
+ }
1586
+ buildElapsedBadge(metadata) {
1587
+ const elapsed = metadata?.elapsedMs;
1588
+ if (typeof elapsed !== 'number' || elapsed <= 0) {
1589
+ return null;
1590
+ }
1591
+ const formatted = elapsed < 1000 ? `${Math.round(elapsed)}ms` : `${Math.round(elapsed / 1000)}s`;
1592
+ return { text: formatted, style: 'muted', icon: 'โฑ' };
1556
1593
  }
1557
1594
  isStreamingUiActive() {
1558
1595
  return this.streamingHeartbeatStart !== null;
@@ -1714,6 +1751,7 @@ export class InteractiveShell {
1714
1751
  if (this.isStreamingUiActive()) {
1715
1752
  return run();
1716
1753
  }
1754
+ this.resetAssistantStreamTracking();
1717
1755
  this.terminalInput.setStreaming(true);
1718
1756
  this.startStreamingHeartbeat(label);
1719
1757
  try {
@@ -4042,7 +4080,6 @@ export class InteractiveShell {
4042
4080
  lines.push(' /rewind code Rewind code only (keep conversation)');
4043
4081
  lines.push(' /rewind conv Rewind conversation only (keep code)');
4044
4082
  lines.push('');
4045
- lines.push(theme.ui.muted('Tip: Press Esc+Esc for quick access to rewind menu'));
4046
4083
  display.showSystemMessage(lines.join('\n'));
4047
4084
  }
4048
4085
  handleMemoryCommand(input) {
@@ -4061,7 +4098,6 @@ export class InteractiveShell {
4061
4098
  lines.push(' - Use # prefix to quickly add notes to project memory');
4062
4099
  lines.push(' - Import other files with @./relative/path syntax');
4063
4100
  lines.push('');
4064
- lines.push(theme.ui.muted('Tip: Create EROSOLAR.md with project coding standards for better results'));
4065
4101
  display.showSystemMessage(lines.join('\n'));
4066
4102
  }
4067
4103
  handleVimCommand() {
@@ -5218,6 +5254,7 @@ export class InteractiveShell {
5218
5254
  return;
5219
5255
  }
5220
5256
  this.hasShownThoughtProcess = false;
5257
+ this.resetAssistantStreamTracking();
5221
5258
  const alphaZeroEngaged = this.alphaZeroModeEnabled;
5222
5259
  const alphaZeroDifficult = alphaZeroEngaged ? this.isDifficultProblem(userRequest) : false;
5223
5260
  const requestForAgent = alphaZeroEngaged
@@ -5441,6 +5478,7 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
5441
5478
  while (iteration < MAX_ITERATIONS) {
5442
5479
  iteration++;
5443
5480
  this.hasShownThoughtProcess = false;
5481
+ this.resetAssistantStreamTracking();
5444
5482
  display.showSystemMessage(`\n๐Ÿ“ Iteration ${iteration}/${MAX_ITERATIONS}`);
5445
5483
  this.updateStatusMessage(`Working on iteration ${iteration}...`);
5446
5484
  try {
@@ -5986,10 +6024,11 @@ What's the next action?`;
5986
6024
  const thinking = parsed?.thinking ?? null;
5987
6025
  const responseContent = parsed ? parsed.response?.trim() ?? '' : content.trim();
5988
6026
  const narrativeContent = (parsed?.response ?? content).trim();
6027
+ const streamRendered = metadata.wasStreamed && this.assistantStreamHadContent;
5989
6028
  if (thinking) {
5990
6029
  this.presentThoughtProcess(thinking, enriched, {
5991
6030
  wasStreamed: metadata.wasStreamed,
5992
- renderWhenStreamed: blocksActive && Boolean(metadata.wasStreamed),
6031
+ renderWhenStreamed: !blocksActive && Boolean(metadata.wasStreamed),
5993
6032
  });
5994
6033
  }
5995
6034
  if (metadata.isFinal) {
@@ -5997,7 +6036,7 @@ What's the next action?`;
5997
6036
  this.finalizeAssistantStream();
5998
6037
  }
5999
6038
  const body = responseContent || content;
6000
- const shouldRenderResponse = body && (blocksActive || !metadata.wasStreamed);
6039
+ const shouldRenderResponse = Boolean(body && (!metadata.wasStreamed || !blocksActive || !streamRendered));
6001
6040
  if (shouldRenderResponse) {
6002
6041
  this.renderAssistantContent('response', body, { ...enriched, isFinal: true });
6003
6042
  }
@@ -6023,7 +6062,7 @@ What's the next action?`;
6023
6062
  if (metadata.wasStreamed) {
6024
6063
  this.finalizeAssistantStream();
6025
6064
  }
6026
- const shouldRenderNarrative = narrativeContent && (blocksActive || !metadata.wasStreamed);
6065
+ const shouldRenderNarrative = Boolean(narrativeContent && (!metadata.wasStreamed || !blocksActive || !streamRendered));
6027
6066
  if (shouldRenderNarrative) {
6028
6067
  this.renderAssistantContent('thought', narrativeContent, {
6029
6068
  ...enriched,
@@ -6682,7 +6721,7 @@ What's the next action?`;
6682
6721
  else {
6683
6722
  lines.push(`Update the stored value for ${secret.label} or type "cancel".`);
6684
6723
  }
6685
- lines.push(`Tip: run "/secrets" anytime to manage credentials or export ${secret.envVar}=<value> before launching the CLI.`);
6724
+ lines.push(`Run "/secrets" anytime to manage credentials or export ${secret.envVar}=<value> before launching the CLI.`);
6686
6725
  display.showSystemMessage(lines.join('\n'));
6687
6726
  }
6688
6727
  colorizeDropdownLine(text, index) {
@@ -6831,9 +6870,7 @@ What's the next action?`;
6831
6870
  return;
6832
6871
  }
6833
6872
  this.refreshContextGauge();
6834
- this.terminalInput.setSessionFrame(this.getSessionFrameProps());
6835
- // Banner is no longer stored in display - it was streamed as content
6836
- // Model/provider changes are visible in the control bar
6873
+ // Banner is streamed once at launch; keep the control bar up to date without re-rendering it
6837
6874
  if (!this.isProcessing) {
6838
6875
  this.setIdleStatus();
6839
6876
  }