erosolar-cli 1.7.420 → 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 -9
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +60 -83
- 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;
|
|
@@ -169,14 +166,13 @@ export class InteractiveShell {
|
|
|
169
166
|
aiRuntimeTotalMs = 0;
|
|
170
167
|
streamingFormatter = null;
|
|
171
168
|
streamingThoughtBuffer = '';
|
|
172
|
-
streamingThoughtRecorded = false;
|
|
173
169
|
statusLineState = null;
|
|
174
170
|
statusMessageOverride = null;
|
|
175
171
|
promptRefreshTimer = null;
|
|
176
172
|
launchPaletteShown = false;
|
|
177
|
-
launchBannerText = null;
|
|
178
173
|
version;
|
|
179
174
|
alternateScreenEnabled;
|
|
175
|
+
welcomeShown = false;
|
|
180
176
|
constructor(config) {
|
|
181
177
|
this.profile = config.profile;
|
|
182
178
|
this.profileLabel = config.profileLabel;
|
|
@@ -380,29 +376,25 @@ export class InteractiveShell {
|
|
|
380
376
|
display.showInfo(this.sessionResumeNotice);
|
|
381
377
|
this.sessionResumeNotice = null;
|
|
382
378
|
}
|
|
383
|
-
|
|
384
|
-
|
|
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))}`;
|
|
385
385
|
const profileLine = `${theme.fields.profile(this.profileLabel)} ${theme.ui.muted(`(${this.profile})`)}`;
|
|
386
386
|
const workspaceLine = theme.fields.workspace(this.workingDir);
|
|
387
387
|
const versionLine = this.version ? theme.ui.muted(`v${this.version} · support@ero.solar`) : null;
|
|
388
388
|
const hintLine = theme.ui.muted('/help for commands · /model to switch · /secrets for keys');
|
|
389
|
-
const
|
|
390
|
-
const banner = [header, profileLine, workspaceLine, versionLine, hintLine, renderDivider(width)]
|
|
389
|
+
const message = [header, modelLine, profileLine, workspaceLine, versionLine, hintLine]
|
|
391
390
|
.filter(Boolean)
|
|
392
391
|
.join('\n');
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
if (this.launchBannerText === banner) {
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
display.stream(`${banner}\n`);
|
|
400
|
-
this.bannerShown = true;
|
|
401
|
-
this.launchBannerText = banner;
|
|
392
|
+
display.stream(`\n${message}\n\n`);
|
|
393
|
+
this.welcomeShown = true;
|
|
402
394
|
this.requestPromptRefresh(true);
|
|
403
395
|
}
|
|
404
396
|
async start(initialPrompt) {
|
|
405
|
-
this.
|
|
397
|
+
this.showWelcomeBanner();
|
|
406
398
|
if (initialPrompt) {
|
|
407
399
|
await this.processInputBlock(initialPrompt);
|
|
408
400
|
return;
|
|
@@ -580,11 +572,11 @@ export class InteractiveShell {
|
|
|
580
572
|
if (!changed && source === 'shortcut') {
|
|
581
573
|
return;
|
|
582
574
|
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
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.`);
|
|
588
580
|
}
|
|
589
581
|
/**
|
|
590
582
|
* Cycle through thinking modes (Tab shortcut).
|
|
@@ -1385,7 +1377,10 @@ export class InteractiveShell {
|
|
|
1385
1377
|
// Emit a streaming note for stop/quit so the status stays inside the stream
|
|
1386
1378
|
if (reason === 'stop' || reason === 'quit') {
|
|
1387
1379
|
const note = reason === 'quit' ? 'Session closed.' : 'Stream stopped.';
|
|
1388
|
-
this.finishStreamingFormatter(note, {
|
|
1380
|
+
this.finishStreamingFormatter(note, {
|
|
1381
|
+
refreshPrompt: false,
|
|
1382
|
+
mode: reason,
|
|
1383
|
+
});
|
|
1389
1384
|
}
|
|
1390
1385
|
// Force refresh to update the input area now that streaming has ended
|
|
1391
1386
|
if (!quiet) {
|
|
@@ -1415,15 +1410,17 @@ export class InteractiveShell {
|
|
|
1415
1410
|
if (!this.streamingFormatter) {
|
|
1416
1411
|
return;
|
|
1417
1412
|
}
|
|
1418
|
-
const closing = this.streamingFormatter.finish(
|
|
1413
|
+
const closing = this.streamingFormatter.finish({
|
|
1414
|
+
note,
|
|
1415
|
+
mode: options?.mode ?? 'complete',
|
|
1416
|
+
});
|
|
1419
1417
|
if (closing) {
|
|
1420
1418
|
this.terminalInput.streamContent(closing);
|
|
1421
1419
|
}
|
|
1422
|
-
if (
|
|
1420
|
+
if (this.streamingThoughtBuffer.trim()) {
|
|
1423
1421
|
this.ui.controller.recordAssistantThought(this.streamingThoughtBuffer.trim());
|
|
1424
1422
|
}
|
|
1425
1423
|
this.streamingThoughtBuffer = '';
|
|
1426
|
-
this.streamingThoughtRecorded = false;
|
|
1427
1424
|
this.streamingFormatter = null;
|
|
1428
1425
|
if (options?.refreshPrompt ?? true) {
|
|
1429
1426
|
this.requestPromptRefresh(true);
|
|
@@ -1436,18 +1433,14 @@ export class InteractiveShell {
|
|
|
1436
1433
|
return `${prefix} ${label}`.trim();
|
|
1437
1434
|
}
|
|
1438
1435
|
captureStreamingThought(chunk) {
|
|
1439
|
-
if (this.streamingThoughtRecorded) {
|
|
1440
|
-
return;
|
|
1441
|
-
}
|
|
1442
1436
|
const normalized = chunk.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
1443
1437
|
for (const char of normalized) {
|
|
1444
1438
|
if (char === '\n') {
|
|
1445
1439
|
const thought = this.streamingThoughtBuffer.trim();
|
|
1446
1440
|
if (thought) {
|
|
1447
1441
|
this.ui.controller.recordAssistantThought(thought);
|
|
1448
|
-
this.streamingThoughtRecorded = true;
|
|
1449
1442
|
this.streamingThoughtBuffer = '';
|
|
1450
|
-
|
|
1443
|
+
continue;
|
|
1451
1444
|
}
|
|
1452
1445
|
this.streamingThoughtBuffer = '';
|
|
1453
1446
|
continue;
|
|
@@ -1455,9 +1448,7 @@ export class InteractiveShell {
|
|
|
1455
1448
|
this.streamingThoughtBuffer += char;
|
|
1456
1449
|
if (this.streamingThoughtBuffer.length > 240) {
|
|
1457
1450
|
this.ui.controller.recordAssistantThought(this.streamingThoughtBuffer.trim());
|
|
1458
|
-
this.streamingThoughtRecorded = true;
|
|
1459
1451
|
this.streamingThoughtBuffer = '';
|
|
1460
|
-
return;
|
|
1461
1452
|
}
|
|
1462
1453
|
}
|
|
1463
1454
|
}
|
|
@@ -1718,7 +1709,6 @@ export class InteractiveShell {
|
|
|
1718
1709
|
this.showAlphaZeroMetrics();
|
|
1719
1710
|
break;
|
|
1720
1711
|
case '/suggestions':
|
|
1721
|
-
case '/improve':
|
|
1722
1712
|
this.showImprovementSuggestions();
|
|
1723
1713
|
break;
|
|
1724
1714
|
case '/plugins':
|
|
@@ -2145,7 +2135,7 @@ export class InteractiveShell {
|
|
|
2145
2135
|
lines.push(theme.bold('Session File Changes'));
|
|
2146
2136
|
lines.push('');
|
|
2147
2137
|
lines.push(`${theme.info('•')} ${summary.files} file${summary.files === 1 ? '' : 's'} modified`);
|
|
2148
|
-
lines.push(`${theme.info('•')} ${theme.success(
|
|
2138
|
+
lines.push(`${theme.info('•')} ${theme.success(`+${summary.additions}`)} ${theme.error(`-${summary.removals}`)} lines`);
|
|
2149
2139
|
lines.push('');
|
|
2150
2140
|
// Group changes by file
|
|
2151
2141
|
const fileMap = new Map();
|
|
@@ -2169,7 +2159,7 @@ export class InteractiveShell {
|
|
|
2169
2159
|
if (stats.writes > 0)
|
|
2170
2160
|
operations.push(`${stats.writes} write${stats.writes === 1 ? '' : 's'}`);
|
|
2171
2161
|
const opsText = operations.join(', ');
|
|
2172
|
-
const diffText = `${theme.success(
|
|
2162
|
+
const diffText = `${theme.success(`+${stats.additions}`)} ${theme.error(`-${stats.removals}`)}`;
|
|
2173
2163
|
lines.push(` ${theme.dim(path)}`);
|
|
2174
2164
|
lines.push(` ${opsText} • ${diffText}`);
|
|
2175
2165
|
}
|
|
@@ -2626,7 +2616,7 @@ export class InteractiveShell {
|
|
|
2626
2616
|
if (!isValidSourceRepo(this.workingDir)) {
|
|
2627
2617
|
display.showWarning('Self-evolution requires a git repository with source code.');
|
|
2628
2618
|
display.showSystemMessage('');
|
|
2629
|
-
display.showSystemMessage(
|
|
2619
|
+
display.showSystemMessage(`Current directory: ${this.workingDir}`);
|
|
2630
2620
|
display.showSystemMessage('');
|
|
2631
2621
|
display.showSystemMessage('Requirements:');
|
|
2632
2622
|
display.showSystemMessage(' • Must be a git repository (.git folder)');
|
|
@@ -2636,7 +2626,6 @@ export class InteractiveShell {
|
|
|
2636
2626
|
return;
|
|
2637
2627
|
}
|
|
2638
2628
|
const repoName = getRepoName(this.workingDir);
|
|
2639
|
-
const isErosolar = isErosolarRepo(this.workingDir);
|
|
2640
2629
|
if (subcommand === 'analyze') {
|
|
2641
2630
|
display.showSystemMessage(theme.gradient.primary(`🔍 Analyzing ${repoName} Source Code...`));
|
|
2642
2631
|
display.showSystemMessage('');
|
|
@@ -3008,13 +2997,6 @@ export class InteractiveShell {
|
|
|
3008
2997
|
' /offsec win|fail|detect <actionId> [note]\n' +
|
|
3009
2998
|
' /offsec resume <runId>\n' +
|
|
3010
2999
|
' /offsec runs';
|
|
3011
|
-
const loadRun = (explicitId) => {
|
|
3012
|
-
const run = resumeOffsecRun(explicitId ?? this.offsecRunId);
|
|
3013
|
-
if (!run) {
|
|
3014
|
-
display.showWarning('No offsec run found. Start one with /offsec start "<objective>".');
|
|
3015
|
-
}
|
|
3016
|
-
return run;
|
|
3017
|
-
};
|
|
3018
3000
|
if (sub === 'start') {
|
|
3019
3001
|
const rest = args.slice(1);
|
|
3020
3002
|
const scope = [];
|
|
@@ -3453,8 +3435,7 @@ export class InteractiveShell {
|
|
|
3453
3435
|
const value = tokens[0]?.toLowerCase();
|
|
3454
3436
|
if (!value) {
|
|
3455
3437
|
// Show current status
|
|
3456
|
-
display.showInfo(`Auto-continue is ${this.autoContinueEnabled ? 'enabled' : 'disabled'}.
|
|
3457
|
-
`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.`);
|
|
3458
3439
|
return;
|
|
3459
3440
|
}
|
|
3460
3441
|
if (value !== 'on' && value !== 'off') {
|
|
@@ -3464,7 +3445,7 @@ export class InteractiveShell {
|
|
|
3464
3445
|
this.setAutoContinueMode(value === 'on', 'command');
|
|
3465
3446
|
}
|
|
3466
3447
|
// ==================== Claude Code Style Commands ====================
|
|
3467
|
-
async handleRewindCommand(
|
|
3448
|
+
async handleRewindCommand(_input) {
|
|
3468
3449
|
const lines = [];
|
|
3469
3450
|
lines.push(theme.bold('Rewind / Checkpoint System'));
|
|
3470
3451
|
lines.push('');
|
|
@@ -3480,7 +3461,7 @@ export class InteractiveShell {
|
|
|
3480
3461
|
lines.push(theme.ui.muted('Press Esc+Esc for quick access to the rewind menu'));
|
|
3481
3462
|
display.showSystemMessage(lines.join('\n'));
|
|
3482
3463
|
}
|
|
3483
|
-
handleMemoryCommand(
|
|
3464
|
+
handleMemoryCommand(_input) {
|
|
3484
3465
|
const lines = [];
|
|
3485
3466
|
lines.push(theme.bold('Memory System (EROSOLAR.md)'));
|
|
3486
3467
|
lines.push('');
|
|
@@ -3521,7 +3502,7 @@ export class InteractiveShell {
|
|
|
3521
3502
|
lines.push(theme.ui.muted('Vim mode is experimental. Toggle with /vim'));
|
|
3522
3503
|
display.showSystemMessage(lines.join('\n'));
|
|
3523
3504
|
}
|
|
3524
|
-
handleOutputStyleCommand(
|
|
3505
|
+
handleOutputStyleCommand(_input) {
|
|
3525
3506
|
const lines = [];
|
|
3526
3507
|
lines.push(theme.bold('Output Styles'));
|
|
3527
3508
|
lines.push('');
|
|
@@ -3642,7 +3623,7 @@ export class InteractiveShell {
|
|
|
3642
3623
|
}
|
|
3643
3624
|
}
|
|
3644
3625
|
}
|
|
3645
|
-
handleExportCommand(
|
|
3626
|
+
handleExportCommand(_input) {
|
|
3646
3627
|
const lines = [];
|
|
3647
3628
|
lines.push(theme.bold('Export Conversation'));
|
|
3648
3629
|
lines.push('');
|
|
@@ -4235,7 +4216,7 @@ export class InteractiveShell {
|
|
|
4235
4216
|
const parts = tool.name.split('__');
|
|
4236
4217
|
const serverName = parts[1] || '';
|
|
4237
4218
|
const toolName = parts.slice(2).join('__') || tool.name;
|
|
4238
|
-
lines.push(` ${theme.info('•')} ${theme.ui.muted(serverName
|
|
4219
|
+
lines.push(` ${theme.info('•')} ${theme.ui.muted(`${serverName}:`)} ${toolName}`);
|
|
4239
4220
|
}
|
|
4240
4221
|
if (mcpTools.length > 15) {
|
|
4241
4222
|
lines.push(` ${theme.ui.muted(`... and ${mcpTools.length - 15} more`)}`);
|
|
@@ -4696,7 +4677,7 @@ export class InteractiveShell {
|
|
|
4696
4677
|
// Start streaming - no header needed, the input area already provides context
|
|
4697
4678
|
this.startStreamingHeartbeat('Streaming response');
|
|
4698
4679
|
responseText = await agent.send(request, true);
|
|
4699
|
-
this.finishStreamingFormatter(undefined, { refreshPrompt: false });
|
|
4680
|
+
this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
|
|
4700
4681
|
await this.awaitPendingCleanup();
|
|
4701
4682
|
this.captureHistorySnapshot();
|
|
4702
4683
|
this.autosaveIfEnabled();
|
|
@@ -4752,7 +4733,7 @@ export class InteractiveShell {
|
|
|
4752
4733
|
}
|
|
4753
4734
|
}
|
|
4754
4735
|
finally {
|
|
4755
|
-
this.finishStreamingFormatter(undefined, { refreshPrompt: false });
|
|
4736
|
+
this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
|
|
4756
4737
|
display.stopThinking(false);
|
|
4757
4738
|
this.uiUpdates.setMode('processing');
|
|
4758
4739
|
this.stopStreamingHeartbeat('complete', { quiet: true });
|
|
@@ -4761,7 +4742,6 @@ export class InteractiveShell {
|
|
|
4761
4742
|
this.terminalInput.setStreaming(false);
|
|
4762
4743
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
4763
4744
|
this.setIdleStatus();
|
|
4764
|
-
display.newLine();
|
|
4765
4745
|
this.updateStatusMessage(null);
|
|
4766
4746
|
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
4767
4747
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
@@ -4845,7 +4825,7 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
|
|
|
4845
4825
|
display.showThinking('Responding...');
|
|
4846
4826
|
this.refreshStatusLine(true);
|
|
4847
4827
|
const response = await agent.send(currentPrompt, true);
|
|
4848
|
-
this.finishStreamingFormatter(undefined, { refreshPrompt: false });
|
|
4828
|
+
this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
|
|
4849
4829
|
await this.awaitPendingCleanup();
|
|
4850
4830
|
this.captureHistorySnapshot();
|
|
4851
4831
|
this.autosaveIfEnabled();
|
|
@@ -4978,7 +4958,7 @@ What's the next action?`;
|
|
|
4978
4958
|
}
|
|
4979
4959
|
}
|
|
4980
4960
|
finally {
|
|
4981
|
-
this.finishStreamingFormatter(undefined, { refreshPrompt: false });
|
|
4961
|
+
this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
|
|
4982
4962
|
const totalElapsed = Date.now() - overallStartTime;
|
|
4983
4963
|
const minutes = Math.floor(totalElapsed / 60000);
|
|
4984
4964
|
const seconds = Math.floor((totalElapsed % 60000) / 1000);
|
|
@@ -4993,10 +4973,6 @@ What's the next action?`;
|
|
|
4993
4973
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
4994
4974
|
this.setIdleStatus();
|
|
4995
4975
|
this.updateStatusMessage(null);
|
|
4996
|
-
display.newLine();
|
|
4997
|
-
// Claude Code style: Show unified status bar before prompt
|
|
4998
|
-
// This creates consistent UI between startup and post-streaming
|
|
4999
|
-
this.showUnifiedStatusBar();
|
|
5000
4976
|
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
5001
4977
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
5002
4978
|
// Claude Code style: New prompt naturally appears at bottom
|
|
@@ -5190,7 +5166,14 @@ What's the next action?`;
|
|
|
5190
5166
|
return latest;
|
|
5191
5167
|
}
|
|
5192
5168
|
formatCommandError(error) {
|
|
5193
|
-
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);
|
|
5194
5177
|
return parts.join('\n').trim();
|
|
5195
5178
|
}
|
|
5196
5179
|
runAutoQualityChecks(trigger, assistantResponse, verificationContext) {
|
|
@@ -5523,7 +5506,6 @@ Return ONLY JSON array:
|
|
|
5523
5506
|
display.showThinking('Analyzing build errors');
|
|
5524
5507
|
this.refreshStatusLine(true);
|
|
5525
5508
|
const response = await this.agent.send(prompt, true);
|
|
5526
|
-
this.finishStreamingFormatter();
|
|
5527
5509
|
display.stopThinking();
|
|
5528
5510
|
this.refreshStatusLine(true);
|
|
5529
5511
|
if (response) {
|
|
@@ -5536,7 +5518,7 @@ Return ONLY JSON array:
|
|
|
5536
5518
|
display.showWarning('Agent could not automatically fix build errors. Please review manually.');
|
|
5537
5519
|
}
|
|
5538
5520
|
finally {
|
|
5539
|
-
this.finishStreamingFormatter();
|
|
5521
|
+
this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
|
|
5540
5522
|
}
|
|
5541
5523
|
}
|
|
5542
5524
|
rebuildAgent() {
|
|
@@ -5707,9 +5689,9 @@ Return ONLY JSON array:
|
|
|
5707
5689
|
* Ensures the input area is visible and ready for input, just like on startup.
|
|
5708
5690
|
*/
|
|
5709
5691
|
resetChatBoxAfterModelSwap() {
|
|
5710
|
-
this.renderWelcomeBanner(true);
|
|
5711
5692
|
this.updateStatusMessage(null);
|
|
5712
5693
|
this.terminalInput.setStreaming(false);
|
|
5694
|
+
this.requestPromptRefresh(true);
|
|
5713
5695
|
this.ensureReadlineReady();
|
|
5714
5696
|
}
|
|
5715
5697
|
/**
|
|
@@ -6262,7 +6244,7 @@ Return ONLY JSON array:
|
|
|
6262
6244
|
const reason = info.reason ? ` (${info.reason.replace(/-/g, ' ')})` : '';
|
|
6263
6245
|
const partialNote = info.partialResponse ? ' Received partial stream before failure.' : '';
|
|
6264
6246
|
display.showWarning(`Streaming failed${reason}, retrying without streaming.${detail}${partialNote}`);
|
|
6265
|
-
this.finishStreamingFormatter('Stream interrupted - retrying without streaming');
|
|
6247
|
+
this.finishStreamingFormatter('Stream interrupted - retrying without streaming', { mode: 'update' });
|
|
6266
6248
|
this.startStreamingHeartbeat('Fallback in progress');
|
|
6267
6249
|
this.requestPromptRefresh(true);
|
|
6268
6250
|
}
|
|
@@ -6363,7 +6345,7 @@ Return ONLY JSON array:
|
|
|
6363
6345
|
// Truncate to reasonable length
|
|
6364
6346
|
const maxLength = 50;
|
|
6365
6347
|
return cleaned.length > maxLength
|
|
6366
|
-
? cleaned.slice(0, maxLength - 3)
|
|
6348
|
+
? `${cleaned.slice(0, maxLength - 3)}...`
|
|
6367
6349
|
: cleaned;
|
|
6368
6350
|
}
|
|
6369
6351
|
splitThinkingResponse(content) {
|
|
@@ -6528,13 +6510,15 @@ Return ONLY JSON array:
|
|
|
6528
6510
|
await this.scanLocalProviders();
|
|
6529
6511
|
break;
|
|
6530
6512
|
case 'use':
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
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}`);
|
|
6536
6521
|
}
|
|
6537
|
-
await this.handleProviderCommand(`/provider ${provider}`);
|
|
6538
6522
|
break;
|
|
6539
6523
|
default:
|
|
6540
6524
|
this.showLocalHelp();
|
|
@@ -6641,13 +6625,6 @@ Return ONLY JSON array:
|
|
|
6641
6625
|
setProviderStatus(providers) {
|
|
6642
6626
|
this.cachedProviderStatus = providers;
|
|
6643
6627
|
}
|
|
6644
|
-
/**
|
|
6645
|
-
* Show the unified status bar (Claude Code style).
|
|
6646
|
-
* Displays provider indicators and ready hints before the prompt.
|
|
6647
|
-
*/
|
|
6648
|
-
showUnifiedStatusBar() {
|
|
6649
|
-
display.showUnifiedStatusBar(this.cachedProviderStatus);
|
|
6650
|
-
}
|
|
6651
6628
|
}
|
|
6652
6629
|
function setsEqual(first, second) {
|
|
6653
6630
|
if (first.size !== second.size) {
|