erosolar-cli 2.1.50 → 2.1.52

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 (37) hide show
  1. package/dist/capabilities/askUserCapability.d.ts +3 -10
  2. package/dist/capabilities/askUserCapability.d.ts.map +1 -1
  3. package/dist/capabilities/askUserCapability.js +29 -33
  4. package/dist/capabilities/askUserCapability.js.map +1 -1
  5. package/dist/core/agent.d.ts +1 -1
  6. package/dist/core/agent.d.ts.map +1 -1
  7. package/dist/core/agent.js +14 -4
  8. package/dist/core/agent.js.map +1 -1
  9. package/dist/runtime/agentController.js +2 -2
  10. package/dist/runtime/agentController.js.map +1 -1
  11. package/dist/shell/interactiveShell.d.ts +5 -0
  12. package/dist/shell/interactiveShell.d.ts.map +1 -1
  13. package/dist/shell/interactiveShell.js +291 -217
  14. package/dist/shell/interactiveShell.js.map +1 -1
  15. package/dist/tools/grepTools.d.ts.map +1 -1
  16. package/dist/tools/grepTools.js +51 -8
  17. package/dist/tools/grepTools.js.map +1 -1
  18. package/dist/tools/interactionTools.d.ts +3 -10
  19. package/dist/tools/interactionTools.d.ts.map +1 -1
  20. package/dist/tools/interactionTools.js +32 -32
  21. package/dist/tools/interactionTools.js.map +1 -1
  22. package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
  23. package/dist/ui/ShellUIAdapter.js +4 -0
  24. package/dist/ui/ShellUIAdapter.js.map +1 -1
  25. package/dist/ui/UnifiedUIRenderer.d.ts +5 -2
  26. package/dist/ui/UnifiedUIRenderer.d.ts.map +1 -1
  27. package/dist/ui/UnifiedUIRenderer.js +43 -29
  28. package/dist/ui/UnifiedUIRenderer.js.map +1 -1
  29. package/dist/ui/display.d.ts +8 -0
  30. package/dist/ui/display.d.ts.map +1 -1
  31. package/dist/ui/display.js +43 -0
  32. package/dist/ui/display.js.map +1 -1
  33. package/dist/utils/askUserPrompt.d.ts +21 -0
  34. package/dist/utils/askUserPrompt.d.ts.map +1 -0
  35. package/dist/utils/askUserPrompt.js +76 -0
  36. package/dist/utils/askUserPrompt.js.map +1 -0
  37. package/package.json +1 -1
@@ -6,6 +6,7 @@ import { existsSync, readFileSync, statSync, writeFileSync } from 'node:fs';
6
6
  import { join, resolve } from 'node:path';
7
7
  import { display } from '../ui/display.js';
8
8
  import { theme } from '../ui/theme.js';
9
+ import { getTerminalColumns } from '../ui/layout.js';
9
10
  import { StreamingResponseFormatter } from '../ui/streamingFormatter.js';
10
11
  import { getContextWindowTokens } from '../core/contextWindow.js';
11
12
  import { ensureSecretForProvider, getSecretDefinitionForProvider, getSecretValue, listSecretDefinitions, maskSecret, setSecretValue, } from '../core/secretStore.js';
@@ -177,6 +178,8 @@ export class InteractiveShell {
177
178
  statusLineState = null;
178
179
  statusMessageOverride = null;
179
180
  lastPromptBlockNotice = null;
181
+ inlineCommandActive = false;
182
+ inlinePanelScopeActive = false;
180
183
  promptRefreshTimer = null;
181
184
  launchPaletteShown = false;
182
185
  version;
@@ -296,6 +299,17 @@ export class InteractiveShell {
296
299
  // Share renderer with Display so all output flows through the unified queue
297
300
  this.renderer = this.terminalInput.getRenderer();
298
301
  display.setRenderer(this.renderer);
302
+ display.setInlinePanelHandler((content) => {
303
+ if (!this.shouldCaptureInlinePanel()) {
304
+ return false;
305
+ }
306
+ const lines = content
307
+ .split('\n')
308
+ .map((line) => line.trimEnd())
309
+ .filter((line) => line.trim().length > 0);
310
+ this.showInlinePanel(lines);
311
+ return true;
312
+ });
299
313
  // Initialize Alpha Zero 2 metrics tracking
300
314
  this.alphaZeroMetrics = new MetricsTracker(`${this.profile}-${Date.now()}`);
301
315
  this.setupStatusTracking();
@@ -395,32 +409,47 @@ export class InteractiveShell {
395
409
  const stripAnsi = (value) => value.replace(/\u001B\[[0-?]*[ -/]*[@-~]/g, '');
396
410
  const padCenter = (text, width) => {
397
411
  const len = stripAnsi(text).length;
398
- const left = Math.max(0, Math.floor((width - len) / 2));
399
- const right = Math.max(0, width - len - left);
412
+ if (len >= width)
413
+ return text;
414
+ const left = Math.floor((width - len) / 2);
415
+ const right = width - len - left;
400
416
  return ' '.repeat(left) + text + ' '.repeat(right);
401
417
  };
402
- const width = 62;
403
- const top = `╭─${' Claude Code '.padEnd(width - 2, '─')}╮`;
404
- const bottom = `╰${'─'.repeat(width)}╯`;
418
+ const targetWidth = 62;
419
+ const terminalWidth = getTerminalColumns();
420
+ const availableWidth = Number.isFinite(terminalWidth) && terminalWidth > 0
421
+ ? Math.max(28, terminalWidth - 4)
422
+ : targetWidth;
423
+ const contentWidth = Math.max(28, Math.min(targetWidth, Math.min(availableWidth, 84)));
424
+ const clamp = (value) => {
425
+ const normalized = stripAnsi(value);
426
+ if (normalized.length <= contentWidth)
427
+ return value;
428
+ if (contentWidth <= 1)
429
+ return normalized.slice(0, contentWidth);
430
+ return `${normalized.slice(0, contentWidth - 1)}…`;
431
+ };
432
+ const brand = 'Erosolar CLI';
433
+ const label = ` ${brand} `;
434
+ const labelLength = stripAnsi(label).length;
435
+ const labelFill = Math.max(0, contentWidth - labelLength);
436
+ const labelLeft = Math.floor(labelFill / 2);
437
+ const labelRight = labelFill - labelLeft;
438
+ const top = `╭${'─'.repeat(labelLeft)}${label}${'─'.repeat(labelRight)}╮`;
439
+ const bottom = `╰${'─'.repeat(contentWidth)}╯`;
405
440
  const userName = process.env['USER'] || 'there';
406
- const logoLines = [
407
- '╭╼─╾╮ ╭╼─╾╮',
408
- '╰╮✺╭╯ ╰╮✺╭╯',
409
- '╭╯✹╰╮ ╭╯✹╰╮',
410
- '╰╼─╾╯ ╰╼─╾╯',
411
- ];
412
- const framedLogo = logoLines.map((line) => frame(`│${padCenter(line, width)}│`));
441
+ const logo = clamp('⟣╍◎╍⟢');
442
+ const versionLabel = version ? clamp(`${brand} · v${version}`) : brand;
443
+ const modelLine = clamp(model);
444
+ const workspaceLine = clamp(workspace);
445
+ const welcomeLine = clamp(`Welcome back ${userName}!`);
413
446
  const lines = [
414
447
  frame(top),
415
- frame(`│${padCenter('', width)}│`),
416
- frame(`│${padCenter(`Welcome back ${userName}!`, width)}│`),
417
- frame(`│${padCenter('', width)}│`),
418
- ...framedLogo,
419
- frame(`│${padCenter('', width)}│`),
420
- frame(`│${padCenter(model, width)}│`),
421
- frame(`│${padCenter('Erosolar CLI', width)}│`),
422
- frame(`│${padCenter(workspace, width)}│`),
423
- frame(`│${padCenter('', width)}│`),
448
+ frame(`│${padCenter(welcomeLine, contentWidth)}│`),
449
+ frame(`│${padCenter(logo, contentWidth)}│`),
450
+ frame(`│${padCenter(modelLine, contentWidth)}│`),
451
+ frame(`│${padCenter(versionLabel, contentWidth)}│`),
452
+ frame(`│${padCenter(workspaceLine, contentWidth)}│`),
424
453
  frame(bottom),
425
454
  ].join('\n');
426
455
  if (this.renderer) {
@@ -992,6 +1021,7 @@ export class InteractiveShell {
992
1021
  if (normalized === 'cancel') {
993
1022
  this.pendingInteraction = null;
994
1023
  display.showInfo('Tool selection cancelled.');
1024
+ this.clearInlinePanel();
995
1025
  this.syncRendererInput();
996
1026
  return;
997
1027
  }
@@ -1004,6 +1034,7 @@ export class InteractiveShell {
1004
1034
  if (normalized === 'save') {
1005
1035
  await this.persistToolSelection(pending);
1006
1036
  this.pendingInteraction = null;
1037
+ this.clearInlinePanel();
1007
1038
  this.syncRendererInput();
1008
1039
  return;
1009
1040
  }
@@ -1071,6 +1102,7 @@ export class InteractiveShell {
1071
1102
  if (trimmed.toLowerCase() === 'cancel') {
1072
1103
  this.pendingInteraction = null;
1073
1104
  display.showInfo('Agent selection cancelled.');
1105
+ this.clearInlinePanel();
1074
1106
  this.syncRendererInput();
1075
1107
  return;
1076
1108
  }
@@ -1088,6 +1120,7 @@ export class InteractiveShell {
1088
1120
  }
1089
1121
  await this.persistAgentSelection(option.name);
1090
1122
  this.pendingInteraction = null;
1123
+ this.clearInlinePanel();
1091
1124
  this.syncRendererInput();
1092
1125
  }
1093
1126
  async persistAgentSelection(profileName) {
@@ -1768,13 +1801,16 @@ export class InteractiveShell {
1768
1801
  this.refreshStatusLine();
1769
1802
  }
1770
1803
  }
1771
- handleStreamChunk(chunk) {
1804
+ handleStreamChunk(chunk, type = 'content') {
1772
1805
  if (!chunk) {
1773
1806
  return;
1774
1807
  }
1808
+ const isReasoning = type === 'reasoning';
1809
+ // Keep pinned status updated for all streaming chunks
1810
+ this.updateStreamingStatusFromChunk(chunk);
1775
1811
  // Suppress raw streaming output in scrollback; keep only status + final message.
1776
- if (this.streamingOutputSuppressed) {
1777
- this.updateStreamingStatusFromChunk(chunk);
1812
+ // Reasoning chunks bypass this so the thought process stays visible.
1813
+ if (this.streamingOutputSuppressed && !isReasoning) {
1778
1814
  this.captureStreamingThought(chunk);
1779
1815
  this.streamingContentSeen = true;
1780
1816
  return;
@@ -1783,8 +1819,10 @@ export class InteractiveShell {
1783
1819
  this.streamingFormatter = new StreamingResponseFormatter(output.columns ?? undefined);
1784
1820
  this.pushUiEvent('streaming', this.streamingFormatter.header());
1785
1821
  }
1786
- this.updateStreamingStatusFromChunk(chunk);
1787
- const formatted = this.streamingFormatter.formatChunk(chunk);
1822
+ this.streamingFormatter.setMode(isReasoning ? 'reasoning' : 'content');
1823
+ const formatted = isReasoning
1824
+ ? this.streamingFormatter.formatReasoningChunk(chunk)
1825
+ : this.streamingFormatter.formatChunk(chunk);
1788
1826
  this.captureStreamingThought(chunk);
1789
1827
  if (formatted) {
1790
1828
  if (formatted.trim().length > 0) {
@@ -2085,184 +2123,195 @@ export class InteractiveShell {
2085
2123
  this.syncRendererInput();
2086
2124
  return;
2087
2125
  }
2088
- switch (command) {
2089
- case '/help':
2090
- case '/?':
2091
- this.showHelp();
2092
- break;
2093
- case '/features':
2094
- this.showFeaturesMenu(input);
2095
- break;
2096
- case '/approvals':
2097
- this.handleApprovalsCommand(input);
2098
- break;
2099
- case '/learn':
2100
- this.showLearningStatus(input);
2101
- break;
2102
- case '/improve':
2103
- void this.handleImprovementCommand(input);
2104
- break;
2105
- case '/model':
2106
- this.showModelMenu();
2107
- break;
2108
- case '/exit':
2109
- case '/quit':
2110
- case '/q':
2111
- this.shutdown();
2112
- break;
2113
- case '/secrets':
2114
- this.showSecretsMenu();
2115
- break;
2116
- case '/tools':
2117
- this.showToolsMenu();
2118
- break;
2119
- case '/mcp':
2120
- await this.showMcpStatus();
2121
- break;
2122
- case '/doctor':
2123
- this.runDoctor();
2124
- break;
2125
- case '/checks':
2126
- await this.runRepoChecksCommand();
2127
- break;
2128
- case '/attach':
2129
- await this.handleAttachCommand(input);
2130
- break;
2131
- case '/context':
2132
- await this.refreshWorkspaceContextCommand(input);
2133
- break;
2134
- case '/agents':
2135
- this.showAgentsMenu();
2136
- break;
2137
- case '/sessions':
2138
- await this.handleSessionCommand(input);
2139
- break;
2140
- case '/skills':
2141
- await this.handleSkillsCommand(input);
2142
- break;
2143
- case '/thinking':
2144
- this.handleThinkingCommand(input);
2145
- break;
2146
- case '/autocontinue':
2147
- this.handleAutoContinueCommand(input);
2148
- break;
2149
- case '/shortcuts':
2150
- case '/keys':
2151
- this.handleShortcutsCommand();
2152
- break;
2153
- case '/changes':
2154
- case '/summary':
2155
- this.showFileChangeSummary();
2156
- break;
2157
- case '/metrics':
2158
- case '/stats':
2159
- case '/perf':
2160
- this.showAlphaZeroMetrics();
2161
- break;
2162
- case '/suggestions':
2163
- this.showImprovementSuggestions();
2164
- break;
2165
- case '/plugins':
2166
- this.showPluginStatus();
2167
- break;
2168
- case '/evolve':
2169
- void this.handleEvolveCommand(input);
2170
- break;
2171
- case '/modular':
2172
- case '/a0':
2173
- void this.handleModularCommand(input);
2174
- break;
2175
- case '/offsec':
2176
- void this.handleOffsecCommand(input);
2177
- break;
2178
- case '/test':
2179
- case '/tests':
2180
- void this.handleTestCommand(input);
2181
- break;
2182
- case '/provider':
2183
- await this.handleProviderCommand(input);
2184
- break;
2185
- case '/providers':
2186
- this.showConfiguredProviders();
2187
- break;
2188
- case '/local':
2189
- await this.handleLocalCommand(input);
2190
- break;
2191
- case '/discover':
2192
- await this.discoverModelsCommand();
2193
- break;
2194
- // Erosolar-CLI style commands
2195
- case '/rewind':
2196
- await this.handleRewindCommand(input);
2197
- break;
2198
- case '/memory':
2199
- this.handleMemoryCommand(input);
2200
- break;
2201
- case '/vim':
2202
- this.handleVimCommand();
2203
- break;
2204
- case '/output-style':
2205
- this.handleOutputStyleCommand(input);
2206
- break;
2207
- case '/cost':
2208
- this.handleCostCommand();
2209
- break;
2210
- case '/usage':
2211
- this.handleUsageCommand(input);
2212
- break;
2213
- case '/clear':
2214
- this.handleClearCommand();
2215
- break;
2216
- case '/resume':
2217
- await this.handleResumeCommand(input);
2218
- break;
2219
- case '/export':
2220
- this.handleExportCommand(input);
2221
- break;
2222
- case '/review':
2223
- await this.handleReviewCommand();
2224
- break;
2225
- case '/security-review':
2226
- await this.handleSecurityReviewCommand();
2227
- break;
2228
- case '/new':
2229
- this.handleClearCommand();
2230
- break;
2231
- case '/undo':
2232
- await this.handleRewindCommand(input);
2233
- break;
2234
- case '/diff':
2235
- await this.handleDiffCommand();
2236
- break;
2237
- case '/mention':
2238
- this.handleMentionCommand();
2239
- break;
2240
- case '/status':
2241
- this.handleStatusCommand();
2242
- break;
2243
- case '/bug':
2244
- this.handleBugCommand();
2245
- break;
2246
- case '/terminal-setup':
2247
- this.handleTerminalSetupCommand();
2248
- break;
2249
- case '/permissions':
2250
- this.handlePermissionsCommand();
2251
- break;
2252
- case '/init':
2253
- this.handleInitCommand(input);
2254
- break;
2255
- case '/compact':
2256
- await this.handleCompactCommand();
2257
- break;
2258
- case '/logout':
2259
- this.handleLogoutCommand();
2260
- break;
2261
- default:
2262
- if (!(await this.tryCustomSlashCommand(command, input))) {
2263
- display.showWarning(`Unknown command "${command}".`);
2264
- }
2265
- break;
2126
+ this.clearInlinePanel();
2127
+ this.inlinePanelScopeActive = true;
2128
+ this.inlineCommandActive = true;
2129
+ try {
2130
+ switch (command) {
2131
+ case '/help':
2132
+ case '/?':
2133
+ this.showHelp();
2134
+ break;
2135
+ case '/features':
2136
+ this.showFeaturesMenu(input);
2137
+ break;
2138
+ case '/approvals':
2139
+ this.handleApprovalsCommand(input);
2140
+ break;
2141
+ case '/learn':
2142
+ this.showLearningStatus(input);
2143
+ break;
2144
+ case '/improve':
2145
+ void this.handleImprovementCommand(input);
2146
+ break;
2147
+ case '/model':
2148
+ this.showModelMenu();
2149
+ break;
2150
+ case '/exit':
2151
+ case '/quit':
2152
+ case '/q':
2153
+ this.shutdown();
2154
+ break;
2155
+ case '/secrets':
2156
+ this.showSecretsMenu();
2157
+ break;
2158
+ case '/tools':
2159
+ this.showToolsMenu();
2160
+ break;
2161
+ case '/mcp':
2162
+ await this.showMcpStatus();
2163
+ break;
2164
+ case '/doctor':
2165
+ this.runDoctor();
2166
+ break;
2167
+ case '/checks':
2168
+ await this.runRepoChecksCommand();
2169
+ break;
2170
+ case '/attach':
2171
+ await this.handleAttachCommand(input);
2172
+ break;
2173
+ case '/context':
2174
+ await this.refreshWorkspaceContextCommand(input);
2175
+ break;
2176
+ case '/agents':
2177
+ this.showAgentsMenu();
2178
+ break;
2179
+ case '/sessions':
2180
+ await this.handleSessionCommand(input);
2181
+ break;
2182
+ case '/skills':
2183
+ await this.handleSkillsCommand(input);
2184
+ break;
2185
+ case '/thinking':
2186
+ this.handleThinkingCommand(input);
2187
+ break;
2188
+ case '/autocontinue':
2189
+ this.handleAutoContinueCommand(input);
2190
+ break;
2191
+ case '/shortcuts':
2192
+ case '/keys':
2193
+ this.handleShortcutsCommand();
2194
+ break;
2195
+ case '/changes':
2196
+ case '/summary':
2197
+ this.showFileChangeSummary();
2198
+ break;
2199
+ case '/metrics':
2200
+ case '/stats':
2201
+ case '/perf':
2202
+ this.showAlphaZeroMetrics();
2203
+ break;
2204
+ case '/suggestions':
2205
+ this.showImprovementSuggestions();
2206
+ break;
2207
+ case '/plugins':
2208
+ this.showPluginStatus();
2209
+ break;
2210
+ case '/evolve':
2211
+ void this.handleEvolveCommand(input);
2212
+ break;
2213
+ case '/modular':
2214
+ case '/a0':
2215
+ void this.handleModularCommand(input);
2216
+ break;
2217
+ case '/offsec':
2218
+ void this.handleOffsecCommand(input);
2219
+ break;
2220
+ case '/test':
2221
+ case '/tests':
2222
+ void this.handleTestCommand(input);
2223
+ break;
2224
+ case '/provider':
2225
+ await this.handleProviderCommand(input);
2226
+ break;
2227
+ case '/providers':
2228
+ this.showConfiguredProviders();
2229
+ break;
2230
+ case '/local':
2231
+ await this.handleLocalCommand(input);
2232
+ break;
2233
+ case '/discover':
2234
+ await this.discoverModelsCommand();
2235
+ break;
2236
+ // Erosolar-CLI style commands
2237
+ case '/rewind':
2238
+ await this.handleRewindCommand(input);
2239
+ break;
2240
+ case '/memory':
2241
+ this.handleMemoryCommand(input);
2242
+ break;
2243
+ case '/vim':
2244
+ this.handleVimCommand();
2245
+ break;
2246
+ case '/output-style':
2247
+ this.handleOutputStyleCommand(input);
2248
+ break;
2249
+ case '/cost':
2250
+ this.handleCostCommand();
2251
+ break;
2252
+ case '/usage':
2253
+ this.handleUsageCommand(input);
2254
+ break;
2255
+ case '/clear':
2256
+ this.handleClearCommand();
2257
+ break;
2258
+ case '/resume':
2259
+ await this.handleResumeCommand(input);
2260
+ break;
2261
+ case '/export':
2262
+ this.handleExportCommand(input);
2263
+ break;
2264
+ case '/review':
2265
+ await this.handleReviewCommand();
2266
+ break;
2267
+ case '/security-review':
2268
+ await this.handleSecurityReviewCommand();
2269
+ break;
2270
+ case '/new':
2271
+ this.handleClearCommand();
2272
+ break;
2273
+ case '/undo':
2274
+ await this.handleRewindCommand(input);
2275
+ break;
2276
+ case '/diff':
2277
+ await this.handleDiffCommand();
2278
+ break;
2279
+ case '/mention':
2280
+ this.handleMentionCommand();
2281
+ break;
2282
+ case '/status':
2283
+ this.handleStatusCommand();
2284
+ break;
2285
+ case '/bug':
2286
+ this.handleBugCommand();
2287
+ break;
2288
+ case '/terminal-setup':
2289
+ this.handleTerminalSetupCommand();
2290
+ break;
2291
+ case '/permissions':
2292
+ this.handlePermissionsCommand();
2293
+ break;
2294
+ case '/init':
2295
+ this.handleInitCommand(input);
2296
+ break;
2297
+ case '/compact':
2298
+ await this.handleCompactCommand();
2299
+ break;
2300
+ case '/logout':
2301
+ this.handleLogoutCommand();
2302
+ break;
2303
+ default:
2304
+ if (!(await this.tryCustomSlashCommand(command, input))) {
2305
+ display.showWarning(`Unknown command "${command}".`);
2306
+ }
2307
+ break;
2308
+ }
2309
+ }
2310
+ finally {
2311
+ this.inlineCommandActive = false;
2312
+ if (!this.pendingInteraction) {
2313
+ this.inlinePanelScopeActive = false;
2314
+ }
2266
2315
  }
2267
2316
  this.syncRendererInput();
2268
2317
  }
@@ -4625,6 +4674,16 @@ export class InteractiveShell {
4625
4674
  const suffix = values.length > maxItems ? ', …' : '';
4626
4675
  return `${shown.join(', ')}${suffix}`;
4627
4676
  }
4677
+ showInlinePanel(lines) {
4678
+ display.showInlinePanel(lines);
4679
+ }
4680
+ clearInlinePanel() {
4681
+ display.clearInlinePanel();
4682
+ }
4683
+ shouldCaptureInlinePanel() {
4684
+ return (this.inlinePanelScopeActive &&
4685
+ (this.inlineCommandActive || Boolean(this.pendingInteraction)));
4686
+ }
4628
4687
  buildSlashCommandList(header) {
4629
4688
  const lines = [theme.gradient.primary(header), ''];
4630
4689
  for (const command of this.slashCommands) {
@@ -4635,7 +4694,7 @@ export class InteractiveShell {
4635
4694
  async showModelMenu() {
4636
4695
  // Hold input immediately so numeric selections don't get queued as prompts while we fetch
4637
4696
  this.pendingInteraction = { type: 'model-loading' };
4638
- display.showSystemMessage(theme.ui.muted('Fetching latest models from providers...'));
4697
+ this.showInlinePanel([theme.ui.muted('Fetching latest models from providers...')]);
4639
4698
  try {
4640
4699
  // Fetch live models from all configured providers
4641
4700
  const providerStatuses = await quickCheckProviders();
@@ -4643,6 +4702,7 @@ export class InteractiveShell {
4643
4702
  if (!providerOptions.length) {
4644
4703
  display.showWarning('No providers are available.');
4645
4704
  this.pendingInteraction = null;
4705
+ this.clearInlinePanel();
4646
4706
  this.syncRendererInput();
4647
4707
  return;
4648
4708
  }
@@ -4658,12 +4718,13 @@ export class InteractiveShell {
4658
4718
  }),
4659
4719
  'Type the number of the provider to continue, or type "cancel".',
4660
4720
  ];
4661
- display.showSystemMessage(lines.join('\n'));
4721
+ this.showInlinePanel(lines);
4662
4722
  this.pendingInteraction = { type: 'model-provider', options: providerOptions };
4663
4723
  }
4664
4724
  catch (error) {
4665
4725
  display.showError('Failed to load model list. Try again in a moment.', error);
4666
4726
  this.pendingInteraction = null;
4727
+ this.clearInlinePanel();
4667
4728
  this.syncRendererInput();
4668
4729
  }
4669
4730
  }
@@ -4796,6 +4857,7 @@ export class InteractiveShell {
4796
4857
  if (!allModels.length) {
4797
4858
  display.showWarning(`No models available for ${option.label}.`);
4798
4859
  this.pendingInteraction = null;
4860
+ this.clearInlinePanel();
4799
4861
  return;
4800
4862
  }
4801
4863
  const lines = [
@@ -4811,7 +4873,7 @@ export class InteractiveShell {
4811
4873
  }),
4812
4874
  'Type the number of the model to select it, type "back" to change provider, or type "cancel".',
4813
4875
  ];
4814
- display.showSystemMessage(lines.join('\n'));
4876
+ this.showInlinePanel(lines);
4815
4877
  this.pendingInteraction = { type: 'model', provider: option.provider, options: allModels };
4816
4878
  }
4817
4879
  showSecretsMenu() {
@@ -4827,7 +4889,7 @@ export class InteractiveShell {
4827
4889
  }),
4828
4890
  'Enter the number to update a key, or type "cancel".',
4829
4891
  ];
4830
- display.showSystemMessage(lines.join('\n'));
4892
+ this.showInlinePanel(lines);
4831
4893
  this.pendingInteraction = { type: 'secret-select', options: definitions };
4832
4894
  }
4833
4895
  showToolsMenu() {
@@ -4853,7 +4915,7 @@ export class InteractiveShell {
4853
4915
  '',
4854
4916
  'Enter the number to toggle, "save" to persist, "defaults" to restore recommended tools, or "cancel".',
4855
4917
  ];
4856
- display.showSystemMessage(lines.join('\n'));
4918
+ this.showInlinePanel(lines);
4857
4919
  }
4858
4920
  formatToolOptionLine(option, index, selection) {
4859
4921
  const enabled = selection.has(option.id);
@@ -4965,7 +5027,7 @@ export class InteractiveShell {
4965
5027
  }
4966
5028
  lines.push('');
4967
5029
  lines.push(theme.ui.muted('Use /tools to enable/disable individual MCP tools.'));
4968
- display.showSystemMessage(lines.join('\n'));
5030
+ this.showInlinePanel(lines);
4969
5031
  }
4970
5032
  showMcpSetupGuide() {
4971
5033
  const lines = [];
@@ -5041,7 +5103,7 @@ export class InteractiveShell {
5041
5103
  lines.push(` ${theme.info('description')} - Human-readable description`);
5042
5104
  lines.push('');
5043
5105
  lines.push(`Run ${theme.primary('/mcp examples')} to see example configurations.`);
5044
- display.showSystemMessage(lines.join('\n'));
5106
+ this.showInlinePanel(lines);
5045
5107
  }
5046
5108
  showMcpExamples() {
5047
5109
  const lines = [];
@@ -5172,7 +5234,7 @@ export class InteractiveShell {
5172
5234
  lines.push(` ${theme.info('@anthropic/mcp-server-github')} - GitHub API`);
5173
5235
  lines.push('');
5174
5236
  lines.push(`More servers: ${theme.primary('https://github.com/modelcontextprotocol/servers')}`);
5175
- display.showSystemMessage(lines.join('\n'));
5237
+ this.showInlinePanel(lines);
5176
5238
  }
5177
5239
  showAgentsMenu() {
5178
5240
  if (!this.agentMenu) {
@@ -5185,7 +5247,7 @@ export class InteractiveShell {
5185
5247
  '',
5186
5248
  'Enter the number to save it, or type "cancel".',
5187
5249
  ];
5188
- display.showSystemMessage(lines.join('\n'));
5250
+ this.showInlinePanel(lines);
5189
5251
  this.pendingInteraction = { type: 'agent-selection', options: this.agentMenu.options };
5190
5252
  }
5191
5253
  formatAgentOptionLine(option, index) {
@@ -5225,6 +5287,7 @@ export class InteractiveShell {
5225
5287
  if (trimmed.toLowerCase() === 'cancel') {
5226
5288
  this.pendingInteraction = null;
5227
5289
  display.showInfo('Model selection cancelled.');
5290
+ this.clearInlinePanel();
5228
5291
  this.syncRendererInput();
5229
5292
  return;
5230
5293
  }
@@ -5262,6 +5325,7 @@ export class InteractiveShell {
5262
5325
  if (trimmed.toLowerCase() === 'cancel') {
5263
5326
  this.pendingInteraction = null;
5264
5327
  display.showInfo('Model selection cancelled.');
5328
+ this.clearInlinePanel();
5265
5329
  this.syncRendererInput();
5266
5330
  return;
5267
5331
  }
@@ -5303,6 +5367,7 @@ export class InteractiveShell {
5303
5367
  this.persistSessionPreference();
5304
5368
  this.resetChatBoxAfterModelSwap();
5305
5369
  }
5370
+ this.clearInlinePanel();
5306
5371
  }
5307
5372
  async handleSecretSelection(input) {
5308
5373
  const pending = this.pendingInteraction;
@@ -5318,6 +5383,7 @@ export class InteractiveShell {
5318
5383
  if (trimmed.toLowerCase() === 'cancel') {
5319
5384
  this.pendingInteraction = null;
5320
5385
  display.showInfo('Secret management cancelled.');
5386
+ this.clearInlinePanel();
5321
5387
  this.syncRendererInput();
5322
5388
  return;
5323
5389
  }
@@ -5333,7 +5399,7 @@ export class InteractiveShell {
5333
5399
  this.syncRendererInput();
5334
5400
  return;
5335
5401
  }
5336
- display.showSystemMessage(`Enter a new value for ${secret.label} or type "cancel".`);
5402
+ this.showInlinePanel([`Enter a new value for ${secret.label} or type "cancel".`]);
5337
5403
  this.pendingInteraction = { type: 'secret-input', secret };
5338
5404
  this.syncRendererInput();
5339
5405
  }
@@ -5352,6 +5418,7 @@ export class InteractiveShell {
5352
5418
  this.pendingInteraction = null;
5353
5419
  this.pendingSecretRetry = null;
5354
5420
  display.showInfo('Secret unchanged.');
5421
+ this.clearInlinePanel();
5355
5422
  this.syncRendererInput();
5356
5423
  return;
5357
5424
  }
@@ -5376,6 +5443,7 @@ export class InteractiveShell {
5376
5443
  this.pendingInteraction = null;
5377
5444
  this.pendingSecretRetry = null;
5378
5445
  }
5446
+ this.clearInlinePanel();
5379
5447
  this.syncRendererInput();
5380
5448
  }
5381
5449
  async processRequest(request) {
@@ -5387,6 +5455,8 @@ export class InteractiveShell {
5387
5455
  display.showWarning('Configure an API key via /secrets before sending requests.');
5388
5456
  return;
5389
5457
  }
5458
+ this.inlinePanelScopeActive = false;
5459
+ this.clearInlinePanel();
5390
5460
  const agent = this.agent;
5391
5461
  if (!agent) {
5392
5462
  return;
@@ -5526,6 +5596,8 @@ export class InteractiveShell {
5526
5596
  display.showWarning('Configure an API key via /secrets before sending requests.');
5527
5597
  return;
5528
5598
  }
5599
+ this.inlinePanelScopeActive = false;
5600
+ this.clearInlinePanel();
5529
5601
  const agent = this.agent;
5530
5602
  if (!agent) {
5531
5603
  return;
@@ -6317,8 +6389,8 @@ Return ONLY JSON array:
6317
6389
  autoContinue: this.autoContinueEnabled,
6318
6390
  };
6319
6391
  this.agent = this.runtimeSession.createAgent(selection, {
6320
- onStreamChunk: (chunk) => {
6321
- this.handleStreamChunk(chunk);
6392
+ onStreamChunk: (chunk, type) => {
6393
+ this.handleStreamChunk(chunk, type ?? 'content');
6322
6394
  },
6323
6395
  onStreamFallback: (info) => this.handleStreamingFallback(info),
6324
6396
  onAssistantMessage: (content, metadata) => {
@@ -7041,7 +7113,9 @@ Return ONLY JSON array:
7041
7113
  const detailText = info.message?.trim() ?? '';
7042
7114
  const detail = detailText ? ` ${detailText}` : '';
7043
7115
  const reason = info.reason ? ` (${info.reason.replace(/-/g, ' ')})` : '';
7044
- const partialNote = info.partialResponse ? ' Partial stream captured before failure.' : '';
7116
+ const partialNote = info.partialResponse
7117
+ ? ' Partial stream captured before failure; continuing from it without restarting.'
7118
+ : '';
7045
7119
  const baseMessage = 'Streaming interrupted, retrying without streaming';
7046
7120
  display.showWarning(`${baseMessage}${reason}.${detail}${partialNote}`.trim());
7047
7121
  this.finishStreamingFormatter('Stream interrupted - retrying without streaming', { mode: 'update' });