erosolar-cli 1.7.421 → 1.7.422
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/statusCapability.d.ts +4 -0
- package/dist/capabilities/statusCapability.d.ts.map +1 -0
- package/dist/capabilities/statusCapability.js +92 -0
- package/dist/capabilities/statusCapability.js.map +1 -0
- package/dist/core/toolRuntime.d.ts +5 -0
- package/dist/core/toolRuntime.d.ts.map +1 -1
- package/dist/core/toolRuntime.js +25 -1
- package/dist/core/toolRuntime.js.map +1 -1
- package/dist/shell/interactiveShell.d.ts +2 -8
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +58 -73
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/shellApp.d.ts.map +1 -1
- package/dist/shell/shellApp.js +3 -0
- package/dist/shell/shellApp.js.map +1 -1
- package/dist/shell/terminalInput.d.ts +0 -5
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +0 -7
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/tools/localExplore.d.ts +1 -1
- package/dist/tools/localExplore.d.ts.map +1 -1
- package/dist/tools/localExplore.js +117 -46
- package/dist/tools/localExplore.js.map +1 -1
- package/dist/ui/ShellUIAdapter.d.ts +6 -0
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +78 -1
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/display.d.ts +0 -31
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +0 -42
- package/dist/ui/display.js.map +1 -1
- package/dist/ui/streamingFormatter.d.ts +6 -2
- package/dist/ui/streamingFormatter.d.ts.map +1 -1
- package/dist/ui/streamingFormatter.js +37 -23
- package/dist/ui/streamingFormatter.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,7 +6,6 @@ import { join } from 'node:path';
|
|
|
6
6
|
import { display } from '../ui/display.js';
|
|
7
7
|
import { isPlainOutputMode } from '../ui/outputMode.js';
|
|
8
8
|
import { theme } from '../ui/theme.js';
|
|
9
|
-
import { renderDivider } from '../ui/unified/layout.js';
|
|
10
9
|
import { StreamingResponseFormatter } from '../ui/streamingFormatter.js';
|
|
11
10
|
import { getContextWindowTokens } from '../core/contextWindow.js';
|
|
12
11
|
import { ensureSecretForProvider, getSecretDefinitionForProvider, getSecretValue, listSecretDefinitions, maskSecret, setSecretValue, } from '../core/secretStore.js';
|
|
@@ -33,7 +32,7 @@ import { addToolPattern } from '../core/learningPersistence.js';
|
|
|
33
32
|
import { classifyTaskType } from '../core/alphaZeroEngine.js';
|
|
34
33
|
import { analyzeImprovementOpportunities, runSelfImprovementCycle, getImprovementSummary, runAutonomousImprovement, requestAutoImprovementStop, getAutoImprovementState, emergencyRollback, } from '../core/selfImprovement.js';
|
|
35
34
|
import { listAvailablePlugins } from '../plugins/index.js';
|
|
36
|
-
import {
|
|
35
|
+
import { isValidSourceRepo, getRepoName, analyzeSource, runSelfEvolution, stopEvolution, getEvolutionStatus, emergencyEvolutionRollback, learnSourcePatterns, generateFix, } from '../core/selfEvolution.js';
|
|
37
36
|
import { analyzeTokenUsage, discoverModularTargets, getModularStatusDisplay, generateContextOptimizations, getGuidelines, deleteGuideline, getPendingActions, executeModularAction, } from '../core/alphaZeroModular.js';
|
|
38
37
|
import { startOffsecRun, resumeOffsecRun, recordOffsecOutcome, getOffsecNextActions, simulateOffsecRollout, formatOffsecStatus, listOffsecRuns, } from '../core/offsecAlphaZero.js';
|
|
39
38
|
import { generateTestFlows, detectBugs, detectUIUpdates, saveTestFlows, saveBugReports, saveUIUpdates, getTestFlowStatus, } from '../core/intelligentTestFlows.js';
|
|
@@ -77,7 +76,6 @@ const CONTEXT_AUTOCOMPACT_PERCENT = Math.round(CONTEXT_USAGE_THRESHOLD * 100);
|
|
|
77
76
|
const CONTEXT_AUTOCOMPACT_FLOOR = 0.6;
|
|
78
77
|
const MIN_COMPACTION_TOKEN_SAVINGS = 200;
|
|
79
78
|
const MIN_COMPACTION_PERCENT_SAVINGS = 0.5;
|
|
80
|
-
const CONTEXT_RECENT_MESSAGE_COUNT = 12;
|
|
81
79
|
const CONTEXT_CLEANUP_CHARS_PER_CHUNK = 6000;
|
|
82
80
|
const CONTEXT_CLEANUP_MAX_OUTPUT_TOKENS = 800;
|
|
83
81
|
const CONTEXT_CLEANUP_SYSTEM_PROMPT = `Summarize earlier IDE collaboration so the agent can keep working.
|
|
@@ -125,7 +123,6 @@ export class InteractiveShell {
|
|
|
125
123
|
planApprovalBridgeRegistered = false;
|
|
126
124
|
contextCompactionInFlight = false;
|
|
127
125
|
contextCompactionLog = [];
|
|
128
|
-
bannerShown = false;
|
|
129
126
|
lastContextWarningLevel = null;
|
|
130
127
|
sessionPreferences;
|
|
131
128
|
autosaveEnabled;
|
|
@@ -173,9 +170,9 @@ export class InteractiveShell {
|
|
|
173
170
|
statusMessageOverride = null;
|
|
174
171
|
promptRefreshTimer = null;
|
|
175
172
|
launchPaletteShown = false;
|
|
176
|
-
launchBannerText = null;
|
|
177
173
|
version;
|
|
178
174
|
alternateScreenEnabled;
|
|
175
|
+
welcomeShown = false;
|
|
179
176
|
constructor(config) {
|
|
180
177
|
this.profile = config.profile;
|
|
181
178
|
this.profileLabel = config.profileLabel;
|
|
@@ -379,29 +376,25 @@ export class InteractiveShell {
|
|
|
379
376
|
display.showInfo(this.sessionResumeNotice);
|
|
380
377
|
this.sessionResumeNotice = null;
|
|
381
378
|
}
|
|
382
|
-
|
|
383
|
-
|
|
379
|
+
showWelcomeBanner(force = false) {
|
|
380
|
+
if (this.welcomeShown && !force) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
const header = theme.gradient.primary('Erosolar CLI');
|
|
384
|
+
const modelLine = `${theme.fields.model(this.sessionState.model)} ${theme.ui.muted('@')} ${theme.fields.agent(this.providerLabel(this.sessionState.provider))}`;
|
|
384
385
|
const profileLine = `${theme.fields.profile(this.profileLabel)} ${theme.ui.muted(`(${this.profile})`)}`;
|
|
385
386
|
const workspaceLine = theme.fields.workspace(this.workingDir);
|
|
386
387
|
const versionLine = this.version ? theme.ui.muted(`v${this.version} · support@ero.solar`) : null;
|
|
387
388
|
const hintLine = theme.ui.muted('/help for commands · /model to switch · /secrets for keys');
|
|
388
|
-
const
|
|
389
|
-
const banner = [header, profileLine, workspaceLine, versionLine, hintLine, renderDivider(width)]
|
|
389
|
+
const message = [header, modelLine, profileLine, workspaceLine, versionLine, hintLine]
|
|
390
390
|
.filter(Boolean)
|
|
391
391
|
.join('\n');
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
}
|
|
395
|
-
if (this.launchBannerText === banner) {
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
display.stream(`${banner}\n`);
|
|
399
|
-
this.bannerShown = true;
|
|
400
|
-
this.launchBannerText = banner;
|
|
392
|
+
display.stream(`\n${message}\n\n`);
|
|
393
|
+
this.welcomeShown = true;
|
|
401
394
|
this.requestPromptRefresh(true);
|
|
402
395
|
}
|
|
403
396
|
async start(initialPrompt) {
|
|
404
|
-
this.
|
|
397
|
+
this.showWelcomeBanner();
|
|
405
398
|
if (initialPrompt) {
|
|
406
399
|
await this.processInputBlock(initialPrompt);
|
|
407
400
|
return;
|
|
@@ -579,11 +572,11 @@ export class InteractiveShell {
|
|
|
579
572
|
if (!changed && source === 'shortcut') {
|
|
580
573
|
return;
|
|
581
574
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
575
|
+
const modeLabel = this.autoContinueEnabled ? 'enabled' : 'disabled';
|
|
576
|
+
const behavior = this.autoContinueEnabled
|
|
577
|
+
? 'The model will be auto-prompted to continue when it expresses intent but does not use tools.'
|
|
578
|
+
: 'The model will not be auto-prompted to continue.';
|
|
579
|
+
display.showInfo(`Auto-continue ${modeLabel}. ${behavior} Toggle with Ctrl+Shift+C.`);
|
|
587
580
|
}
|
|
588
581
|
/**
|
|
589
582
|
* Cycle through thinking modes (Tab shortcut).
|
|
@@ -1384,7 +1377,10 @@ export class InteractiveShell {
|
|
|
1384
1377
|
// Emit a streaming note for stop/quit so the status stays inside the stream
|
|
1385
1378
|
if (reason === 'stop' || reason === 'quit') {
|
|
1386
1379
|
const note = reason === 'quit' ? 'Session closed.' : 'Stream stopped.';
|
|
1387
|
-
this.finishStreamingFormatter(note, {
|
|
1380
|
+
this.finishStreamingFormatter(note, {
|
|
1381
|
+
refreshPrompt: false,
|
|
1382
|
+
mode: reason,
|
|
1383
|
+
});
|
|
1388
1384
|
}
|
|
1389
1385
|
// Force refresh to update the input area now that streaming has ended
|
|
1390
1386
|
if (!quiet) {
|
|
@@ -1414,7 +1410,10 @@ export class InteractiveShell {
|
|
|
1414
1410
|
if (!this.streamingFormatter) {
|
|
1415
1411
|
return;
|
|
1416
1412
|
}
|
|
1417
|
-
const closing = this.streamingFormatter.finish(
|
|
1413
|
+
const closing = this.streamingFormatter.finish({
|
|
1414
|
+
note,
|
|
1415
|
+
mode: options?.mode ?? 'complete',
|
|
1416
|
+
});
|
|
1418
1417
|
if (closing) {
|
|
1419
1418
|
this.terminalInput.streamContent(closing);
|
|
1420
1419
|
}
|
|
@@ -1710,7 +1709,6 @@ export class InteractiveShell {
|
|
|
1710
1709
|
this.showAlphaZeroMetrics();
|
|
1711
1710
|
break;
|
|
1712
1711
|
case '/suggestions':
|
|
1713
|
-
case '/improve':
|
|
1714
1712
|
this.showImprovementSuggestions();
|
|
1715
1713
|
break;
|
|
1716
1714
|
case '/plugins':
|
|
@@ -2137,7 +2135,7 @@ export class InteractiveShell {
|
|
|
2137
2135
|
lines.push(theme.bold('Session File Changes'));
|
|
2138
2136
|
lines.push('');
|
|
2139
2137
|
lines.push(`${theme.info('•')} ${summary.files} file${summary.files === 1 ? '' : 's'} modified`);
|
|
2140
|
-
lines.push(`${theme.info('•')} ${theme.success(
|
|
2138
|
+
lines.push(`${theme.info('•')} ${theme.success(`+${summary.additions}`)} ${theme.error(`-${summary.removals}`)} lines`);
|
|
2141
2139
|
lines.push('');
|
|
2142
2140
|
// Group changes by file
|
|
2143
2141
|
const fileMap = new Map();
|
|
@@ -2161,7 +2159,7 @@ export class InteractiveShell {
|
|
|
2161
2159
|
if (stats.writes > 0)
|
|
2162
2160
|
operations.push(`${stats.writes} write${stats.writes === 1 ? '' : 's'}`);
|
|
2163
2161
|
const opsText = operations.join(', ');
|
|
2164
|
-
const diffText = `${theme.success(
|
|
2162
|
+
const diffText = `${theme.success(`+${stats.additions}`)} ${theme.error(`-${stats.removals}`)}`;
|
|
2165
2163
|
lines.push(` ${theme.dim(path)}`);
|
|
2166
2164
|
lines.push(` ${opsText} • ${diffText}`);
|
|
2167
2165
|
}
|
|
@@ -2618,7 +2616,7 @@ export class InteractiveShell {
|
|
|
2618
2616
|
if (!isValidSourceRepo(this.workingDir)) {
|
|
2619
2617
|
display.showWarning('Self-evolution requires a git repository with source code.');
|
|
2620
2618
|
display.showSystemMessage('');
|
|
2621
|
-
display.showSystemMessage(
|
|
2619
|
+
display.showSystemMessage(`Current directory: ${this.workingDir}`);
|
|
2622
2620
|
display.showSystemMessage('');
|
|
2623
2621
|
display.showSystemMessage('Requirements:');
|
|
2624
2622
|
display.showSystemMessage(' • Must be a git repository (.git folder)');
|
|
@@ -2628,7 +2626,6 @@ export class InteractiveShell {
|
|
|
2628
2626
|
return;
|
|
2629
2627
|
}
|
|
2630
2628
|
const repoName = getRepoName(this.workingDir);
|
|
2631
|
-
const isErosolar = isErosolarRepo(this.workingDir);
|
|
2632
2629
|
if (subcommand === 'analyze') {
|
|
2633
2630
|
display.showSystemMessage(theme.gradient.primary(`🔍 Analyzing ${repoName} Source Code...`));
|
|
2634
2631
|
display.showSystemMessage('');
|
|
@@ -3000,13 +2997,6 @@ export class InteractiveShell {
|
|
|
3000
2997
|
' /offsec win|fail|detect <actionId> [note]\n' +
|
|
3001
2998
|
' /offsec resume <runId>\n' +
|
|
3002
2999
|
' /offsec runs';
|
|
3003
|
-
const loadRun = (explicitId) => {
|
|
3004
|
-
const run = resumeOffsecRun(explicitId ?? this.offsecRunId);
|
|
3005
|
-
if (!run) {
|
|
3006
|
-
display.showWarning('No offsec run found. Start one with /offsec start "<objective>".');
|
|
3007
|
-
}
|
|
3008
|
-
return run;
|
|
3009
|
-
};
|
|
3010
3000
|
if (sub === 'start') {
|
|
3011
3001
|
const rest = args.slice(1);
|
|
3012
3002
|
const scope = [];
|
|
@@ -3445,8 +3435,7 @@ export class InteractiveShell {
|
|
|
3445
3435
|
const value = tokens[0]?.toLowerCase();
|
|
3446
3436
|
if (!value) {
|
|
3447
3437
|
// Show current status
|
|
3448
|
-
display.showInfo(`Auto-continue is ${this.autoContinueEnabled ? 'enabled' : 'disabled'}.
|
|
3449
|
-
`Use /autocontinue on|off or Ctrl+Shift+C to toggle.`);
|
|
3438
|
+
display.showInfo(`Auto-continue is ${this.autoContinueEnabled ? 'enabled' : 'disabled'}. Use /autocontinue on|off or Ctrl+Shift+C to toggle.`);
|
|
3450
3439
|
return;
|
|
3451
3440
|
}
|
|
3452
3441
|
if (value !== 'on' && value !== 'off') {
|
|
@@ -3456,7 +3445,7 @@ export class InteractiveShell {
|
|
|
3456
3445
|
this.setAutoContinueMode(value === 'on', 'command');
|
|
3457
3446
|
}
|
|
3458
3447
|
// ==================== Claude Code Style Commands ====================
|
|
3459
|
-
async handleRewindCommand(
|
|
3448
|
+
async handleRewindCommand(_input) {
|
|
3460
3449
|
const lines = [];
|
|
3461
3450
|
lines.push(theme.bold('Rewind / Checkpoint System'));
|
|
3462
3451
|
lines.push('');
|
|
@@ -3472,7 +3461,7 @@ export class InteractiveShell {
|
|
|
3472
3461
|
lines.push(theme.ui.muted('Press Esc+Esc for quick access to the rewind menu'));
|
|
3473
3462
|
display.showSystemMessage(lines.join('\n'));
|
|
3474
3463
|
}
|
|
3475
|
-
handleMemoryCommand(
|
|
3464
|
+
handleMemoryCommand(_input) {
|
|
3476
3465
|
const lines = [];
|
|
3477
3466
|
lines.push(theme.bold('Memory System (EROSOLAR.md)'));
|
|
3478
3467
|
lines.push('');
|
|
@@ -3513,7 +3502,7 @@ export class InteractiveShell {
|
|
|
3513
3502
|
lines.push(theme.ui.muted('Vim mode is experimental. Toggle with /vim'));
|
|
3514
3503
|
display.showSystemMessage(lines.join('\n'));
|
|
3515
3504
|
}
|
|
3516
|
-
handleOutputStyleCommand(
|
|
3505
|
+
handleOutputStyleCommand(_input) {
|
|
3517
3506
|
const lines = [];
|
|
3518
3507
|
lines.push(theme.bold('Output Styles'));
|
|
3519
3508
|
lines.push('');
|
|
@@ -3634,7 +3623,7 @@ export class InteractiveShell {
|
|
|
3634
3623
|
}
|
|
3635
3624
|
}
|
|
3636
3625
|
}
|
|
3637
|
-
handleExportCommand(
|
|
3626
|
+
handleExportCommand(_input) {
|
|
3638
3627
|
const lines = [];
|
|
3639
3628
|
lines.push(theme.bold('Export Conversation'));
|
|
3640
3629
|
lines.push('');
|
|
@@ -4227,7 +4216,7 @@ export class InteractiveShell {
|
|
|
4227
4216
|
const parts = tool.name.split('__');
|
|
4228
4217
|
const serverName = parts[1] || '';
|
|
4229
4218
|
const toolName = parts.slice(2).join('__') || tool.name;
|
|
4230
|
-
lines.push(` ${theme.info('•')} ${theme.ui.muted(serverName
|
|
4219
|
+
lines.push(` ${theme.info('•')} ${theme.ui.muted(`${serverName}:`)} ${toolName}`);
|
|
4231
4220
|
}
|
|
4232
4221
|
if (mcpTools.length > 15) {
|
|
4233
4222
|
lines.push(` ${theme.ui.muted(`... and ${mcpTools.length - 15} more`)}`);
|
|
@@ -4688,7 +4677,7 @@ export class InteractiveShell {
|
|
|
4688
4677
|
// Start streaming - no header needed, the input area already provides context
|
|
4689
4678
|
this.startStreamingHeartbeat('Streaming response');
|
|
4690
4679
|
responseText = await agent.send(request, true);
|
|
4691
|
-
this.finishStreamingFormatter(undefined, { refreshPrompt: false });
|
|
4680
|
+
this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
|
|
4692
4681
|
await this.awaitPendingCleanup();
|
|
4693
4682
|
this.captureHistorySnapshot();
|
|
4694
4683
|
this.autosaveIfEnabled();
|
|
@@ -4744,7 +4733,7 @@ export class InteractiveShell {
|
|
|
4744
4733
|
}
|
|
4745
4734
|
}
|
|
4746
4735
|
finally {
|
|
4747
|
-
this.finishStreamingFormatter(undefined, { refreshPrompt: false });
|
|
4736
|
+
this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
|
|
4748
4737
|
display.stopThinking(false);
|
|
4749
4738
|
this.uiUpdates.setMode('processing');
|
|
4750
4739
|
this.stopStreamingHeartbeat('complete', { quiet: true });
|
|
@@ -4753,7 +4742,6 @@ export class InteractiveShell {
|
|
|
4753
4742
|
this.terminalInput.setStreaming(false);
|
|
4754
4743
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
4755
4744
|
this.setIdleStatus();
|
|
4756
|
-
display.newLine();
|
|
4757
4745
|
this.updateStatusMessage(null);
|
|
4758
4746
|
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
4759
4747
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
@@ -4837,7 +4825,7 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
|
|
|
4837
4825
|
display.showThinking('Responding...');
|
|
4838
4826
|
this.refreshStatusLine(true);
|
|
4839
4827
|
const response = await agent.send(currentPrompt, true);
|
|
4840
|
-
this.finishStreamingFormatter(undefined, { refreshPrompt: false });
|
|
4828
|
+
this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
|
|
4841
4829
|
await this.awaitPendingCleanup();
|
|
4842
4830
|
this.captureHistorySnapshot();
|
|
4843
4831
|
this.autosaveIfEnabled();
|
|
@@ -4970,7 +4958,7 @@ What's the next action?`;
|
|
|
4970
4958
|
}
|
|
4971
4959
|
}
|
|
4972
4960
|
finally {
|
|
4973
|
-
this.finishStreamingFormatter(undefined, { refreshPrompt: false });
|
|
4961
|
+
this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
|
|
4974
4962
|
const totalElapsed = Date.now() - overallStartTime;
|
|
4975
4963
|
const minutes = Math.floor(totalElapsed / 60000);
|
|
4976
4964
|
const seconds = Math.floor((totalElapsed % 60000) / 1000);
|
|
@@ -4985,10 +4973,6 @@ What's the next action?`;
|
|
|
4985
4973
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
4986
4974
|
this.setIdleStatus();
|
|
4987
4975
|
this.updateStatusMessage(null);
|
|
4988
|
-
display.newLine();
|
|
4989
|
-
// Claude Code style: Show unified status bar before prompt
|
|
4990
|
-
// This creates consistent UI between startup and post-streaming
|
|
4991
|
-
this.showUnifiedStatusBar();
|
|
4992
4976
|
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
4993
4977
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
4994
4978
|
// Claude Code style: New prompt naturally appears at bottom
|
|
@@ -5182,7 +5166,14 @@ What's the next action?`;
|
|
|
5182
5166
|
return latest;
|
|
5183
5167
|
}
|
|
5184
5168
|
formatCommandError(error) {
|
|
5185
|
-
const
|
|
5169
|
+
const candidates = [];
|
|
5170
|
+
if (error && typeof error === 'object') {
|
|
5171
|
+
const stdout = error.stdout;
|
|
5172
|
+
const stderr = error.stderr;
|
|
5173
|
+
const message = error.message;
|
|
5174
|
+
candidates.push(stdout, stderr, message);
|
|
5175
|
+
}
|
|
5176
|
+
const parts = candidates.filter((part) => typeof part === 'string' && part.trim().length > 0);
|
|
5186
5177
|
return parts.join('\n').trim();
|
|
5187
5178
|
}
|
|
5188
5179
|
runAutoQualityChecks(trigger, assistantResponse, verificationContext) {
|
|
@@ -5515,7 +5506,6 @@ Return ONLY JSON array:
|
|
|
5515
5506
|
display.showThinking('Analyzing build errors');
|
|
5516
5507
|
this.refreshStatusLine(true);
|
|
5517
5508
|
const response = await this.agent.send(prompt, true);
|
|
5518
|
-
this.finishStreamingFormatter();
|
|
5519
5509
|
display.stopThinking();
|
|
5520
5510
|
this.refreshStatusLine(true);
|
|
5521
5511
|
if (response) {
|
|
@@ -5528,7 +5518,7 @@ Return ONLY JSON array:
|
|
|
5528
5518
|
display.showWarning('Agent could not automatically fix build errors. Please review manually.');
|
|
5529
5519
|
}
|
|
5530
5520
|
finally {
|
|
5531
|
-
this.finishStreamingFormatter();
|
|
5521
|
+
this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
|
|
5532
5522
|
}
|
|
5533
5523
|
}
|
|
5534
5524
|
rebuildAgent() {
|
|
@@ -5699,9 +5689,9 @@ Return ONLY JSON array:
|
|
|
5699
5689
|
* Ensures the input area is visible and ready for input, just like on startup.
|
|
5700
5690
|
*/
|
|
5701
5691
|
resetChatBoxAfterModelSwap() {
|
|
5702
|
-
this.renderWelcomeBanner(true);
|
|
5703
5692
|
this.updateStatusMessage(null);
|
|
5704
5693
|
this.terminalInput.setStreaming(false);
|
|
5694
|
+
this.requestPromptRefresh(true);
|
|
5705
5695
|
this.ensureReadlineReady();
|
|
5706
5696
|
}
|
|
5707
5697
|
/**
|
|
@@ -6254,7 +6244,7 @@ Return ONLY JSON array:
|
|
|
6254
6244
|
const reason = info.reason ? ` (${info.reason.replace(/-/g, ' ')})` : '';
|
|
6255
6245
|
const partialNote = info.partialResponse ? ' Received partial stream before failure.' : '';
|
|
6256
6246
|
display.showWarning(`Streaming failed${reason}, retrying without streaming.${detail}${partialNote}`);
|
|
6257
|
-
this.finishStreamingFormatter('Stream interrupted - retrying without streaming');
|
|
6247
|
+
this.finishStreamingFormatter('Stream interrupted - retrying without streaming', { mode: 'update' });
|
|
6258
6248
|
this.startStreamingHeartbeat('Fallback in progress');
|
|
6259
6249
|
this.requestPromptRefresh(true);
|
|
6260
6250
|
}
|
|
@@ -6355,7 +6345,7 @@ Return ONLY JSON array:
|
|
|
6355
6345
|
// Truncate to reasonable length
|
|
6356
6346
|
const maxLength = 50;
|
|
6357
6347
|
return cleaned.length > maxLength
|
|
6358
|
-
? cleaned.slice(0, maxLength - 3)
|
|
6348
|
+
? `${cleaned.slice(0, maxLength - 3)}...`
|
|
6359
6349
|
: cleaned;
|
|
6360
6350
|
}
|
|
6361
6351
|
splitThinkingResponse(content) {
|
|
@@ -6520,13 +6510,15 @@ Return ONLY JSON array:
|
|
|
6520
6510
|
await this.scanLocalProviders();
|
|
6521
6511
|
break;
|
|
6522
6512
|
case 'use':
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6513
|
+
{
|
|
6514
|
+
const provider = tokens[1]?.toLowerCase();
|
|
6515
|
+
if (!provider) {
|
|
6516
|
+
display.showWarning('Usage: /local use <provider>');
|
|
6517
|
+
display.showInfo('Example: /local use ollama');
|
|
6518
|
+
return;
|
|
6519
|
+
}
|
|
6520
|
+
await this.handleProviderCommand(`/provider ${provider}`);
|
|
6528
6521
|
}
|
|
6529
|
-
await this.handleProviderCommand(`/provider ${provider}`);
|
|
6530
6522
|
break;
|
|
6531
6523
|
default:
|
|
6532
6524
|
this.showLocalHelp();
|
|
@@ -6633,13 +6625,6 @@ Return ONLY JSON array:
|
|
|
6633
6625
|
setProviderStatus(providers) {
|
|
6634
6626
|
this.cachedProviderStatus = providers;
|
|
6635
6627
|
}
|
|
6636
|
-
/**
|
|
6637
|
-
* Show the unified status bar (Claude Code style).
|
|
6638
|
-
* Displays provider indicators and ready hints before the prompt.
|
|
6639
|
-
*/
|
|
6640
|
-
showUnifiedStatusBar() {
|
|
6641
|
-
display.showUnifiedStatusBar(this.cachedProviderStatus);
|
|
6642
|
-
}
|
|
6643
6628
|
}
|
|
6644
6629
|
function setsEqual(first, second) {
|
|
6645
6630
|
if (first.size !== second.size) {
|