erosolar-cli 1.7.261 → 1.7.262
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/README.md +22 -148
- package/dist/core/customCommands.d.ts +1 -0
- package/dist/core/customCommands.d.ts.map +1 -1
- package/dist/core/customCommands.js +3 -0
- package/dist/core/customCommands.js.map +1 -1
- package/dist/core/hooks.d.ts +113 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +267 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/metricsTracker.d.ts +122 -0
- package/dist/core/metricsTracker.d.ts.map +1 -0
- package/dist/{alpha-zero → core}/metricsTracker.js +2 -5
- package/dist/core/metricsTracker.js.map +1 -0
- package/dist/core/toolPreconditions.d.ts.map +1 -1
- package/dist/core/toolPreconditions.js +0 -14
- package/dist/core/toolPreconditions.js.map +1 -1
- package/dist/core/toolRuntime.d.ts.map +1 -1
- package/dist/core/toolRuntime.js +0 -5
- package/dist/core/toolRuntime.js.map +1 -1
- package/dist/core/toolValidation.d.ts.map +1 -1
- package/dist/core/toolValidation.js +14 -3
- package/dist/core/toolValidation.js.map +1 -1
- package/dist/core/validationRunner.d.ts +1 -3
- package/dist/core/validationRunner.d.ts.map +1 -1
- package/dist/core/validationRunner.js.map +1 -1
- package/dist/mcp/sseClient.d.ts.map +1 -1
- package/dist/mcp/sseClient.js +9 -18
- package/dist/mcp/sseClient.js.map +1 -1
- package/dist/plugins/tools/build/buildPlugin.d.ts +0 -6
- package/dist/plugins/tools/build/buildPlugin.d.ts.map +1 -1
- package/dist/plugins/tools/build/buildPlugin.js +4 -10
- package/dist/plugins/tools/build/buildPlugin.js.map +1 -1
- package/dist/shell/interactiveShell.d.ts +10 -2
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +182 -36
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/terminalInput.d.ts +68 -140
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +448 -667
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/terminalInputAdapter.d.ts +20 -15
- package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
- package/dist/shell/terminalInputAdapter.js +14 -22
- package/dist/shell/terminalInputAdapter.js.map +1 -1
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +13 -12
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/display.d.ts +19 -0
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +131 -33
- package/dist/ui/display.js.map +1 -1
- package/dist/ui/theme.d.ts.map +1 -1
- package/dist/ui/theme.js +6 -8
- package/dist/ui/theme.js.map +1 -1
- package/dist/ui/toolDisplay.d.ts +0 -158
- package/dist/ui/toolDisplay.d.ts.map +1 -1
- package/dist/ui/toolDisplay.js +0 -348
- package/dist/ui/toolDisplay.js.map +1 -1
- package/dist/ui/unified/layout.d.ts +1 -0
- package/dist/ui/unified/layout.d.ts.map +1 -1
- package/dist/ui/unified/layout.js +15 -25
- package/dist/ui/unified/layout.js.map +1 -1
- package/package.json +1 -1
- package/dist/alpha-zero/agentWrapper.d.ts +0 -84
- package/dist/alpha-zero/agentWrapper.d.ts.map +0 -1
- package/dist/alpha-zero/agentWrapper.js +0 -171
- package/dist/alpha-zero/agentWrapper.js.map +0 -1
- package/dist/alpha-zero/codeEvaluator.d.ts +0 -25
- package/dist/alpha-zero/codeEvaluator.d.ts.map +0 -1
- package/dist/alpha-zero/codeEvaluator.js +0 -273
- package/dist/alpha-zero/codeEvaluator.js.map +0 -1
- package/dist/alpha-zero/competitiveRunner.d.ts +0 -66
- package/dist/alpha-zero/competitiveRunner.d.ts.map +0 -1
- package/dist/alpha-zero/competitiveRunner.js +0 -224
- package/dist/alpha-zero/competitiveRunner.js.map +0 -1
- package/dist/alpha-zero/index.d.ts +0 -67
- package/dist/alpha-zero/index.d.ts.map +0 -1
- package/dist/alpha-zero/index.js +0 -99
- package/dist/alpha-zero/index.js.map +0 -1
- package/dist/alpha-zero/introspection.d.ts +0 -128
- package/dist/alpha-zero/introspection.d.ts.map +0 -1
- package/dist/alpha-zero/introspection.js +0 -300
- package/dist/alpha-zero/introspection.js.map +0 -1
- package/dist/alpha-zero/metricsTracker.d.ts +0 -71
- package/dist/alpha-zero/metricsTracker.d.ts.map +0 -1
- package/dist/alpha-zero/metricsTracker.js.map +0 -1
- package/dist/alpha-zero/security/core.d.ts +0 -125
- package/dist/alpha-zero/security/core.d.ts.map +0 -1
- package/dist/alpha-zero/security/core.js +0 -271
- package/dist/alpha-zero/security/core.js.map +0 -1
- package/dist/alpha-zero/security/google.d.ts +0 -125
- package/dist/alpha-zero/security/google.d.ts.map +0 -1
- package/dist/alpha-zero/security/google.js +0 -311
- package/dist/alpha-zero/security/google.js.map +0 -1
- package/dist/alpha-zero/security/googleLoader.d.ts +0 -17
- package/dist/alpha-zero/security/googleLoader.d.ts.map +0 -1
- package/dist/alpha-zero/security/googleLoader.js +0 -41
- package/dist/alpha-zero/security/googleLoader.js.map +0 -1
- package/dist/alpha-zero/security/index.d.ts +0 -29
- package/dist/alpha-zero/security/index.d.ts.map +0 -1
- package/dist/alpha-zero/security/index.js +0 -32
- package/dist/alpha-zero/security/index.js.map +0 -1
- package/dist/alpha-zero/security/simulation.d.ts +0 -124
- package/dist/alpha-zero/security/simulation.d.ts.map +0 -1
- package/dist/alpha-zero/security/simulation.js +0 -277
- package/dist/alpha-zero/security/simulation.js.map +0 -1
- package/dist/alpha-zero/selfModification.d.ts +0 -109
- package/dist/alpha-zero/selfModification.d.ts.map +0 -1
- package/dist/alpha-zero/selfModification.js +0 -233
- package/dist/alpha-zero/selfModification.js.map +0 -1
- package/dist/alpha-zero/types.d.ts +0 -170
- package/dist/alpha-zero/types.d.ts.map +0 -1
- package/dist/alpha-zero/types.js +0 -31
- package/dist/alpha-zero/types.js.map +0 -1
- package/dist/core/aiFlowOptimizer.d.ts +0 -26
- package/dist/core/aiFlowOptimizer.d.ts.map +0 -1
- package/dist/core/aiFlowOptimizer.js +0 -31
- package/dist/core/aiFlowOptimizer.js.map +0 -1
- package/dist/core/aiOptimizationEngine.d.ts +0 -158
- package/dist/core/aiOptimizationEngine.d.ts.map +0 -1
- package/dist/core/aiOptimizationEngine.js +0 -428
- package/dist/core/aiOptimizationEngine.js.map +0 -1
- package/dist/core/aiOptimizationIntegration.d.ts +0 -93
- package/dist/core/aiOptimizationIntegration.d.ts.map +0 -1
- package/dist/core/aiOptimizationIntegration.js +0 -250
- package/dist/core/aiOptimizationIntegration.js.map +0 -1
- package/dist/core/enhancedErrorRecovery.d.ts +0 -100
- package/dist/core/enhancedErrorRecovery.d.ts.map +0 -1
- package/dist/core/enhancedErrorRecovery.js +0 -345
- package/dist/core/enhancedErrorRecovery.js.map +0 -1
- package/dist/core/unified/errors.d.ts +0 -189
- package/dist/core/unified/errors.d.ts.map +0 -1
- package/dist/core/unified/errors.js +0 -497
- package/dist/core/unified/errors.js.map +0 -1
- package/dist/core/unified/index.d.ts +0 -19
- package/dist/core/unified/index.d.ts.map +0 -1
- package/dist/core/unified/index.js +0 -68
- package/dist/core/unified/index.js.map +0 -1
- package/dist/core/unified/schema.d.ts +0 -101
- package/dist/core/unified/schema.d.ts.map +0 -1
- package/dist/core/unified/schema.js +0 -350
- package/dist/core/unified/schema.js.map +0 -1
- package/dist/core/unified/toolRuntime.d.ts +0 -179
- package/dist/core/unified/toolRuntime.d.ts.map +0 -1
- package/dist/core/unified/toolRuntime.js +0 -517
- package/dist/core/unified/toolRuntime.js.map +0 -1
- package/dist/core/unified/tools.d.ts +0 -127
- package/dist/core/unified/tools.d.ts.map +0 -1
- package/dist/core/unified/tools.js +0 -1333
- package/dist/core/unified/tools.js.map +0 -1
- package/dist/core/unified/types.d.ts +0 -352
- package/dist/core/unified/types.d.ts.map +0 -1
- package/dist/core/unified/types.js +0 -12
- package/dist/core/unified/types.js.map +0 -1
- package/dist/core/unified/version.d.ts +0 -209
- package/dist/core/unified/version.d.ts.map +0 -1
- package/dist/core/unified/version.js +0 -454
- package/dist/core/unified/version.js.map +0 -1
- package/dist/security/active-stack-security.d.ts +0 -112
- package/dist/security/active-stack-security.d.ts.map +0 -1
- package/dist/security/active-stack-security.js +0 -296
- package/dist/security/active-stack-security.js.map +0 -1
- package/dist/security/advanced-persistence-research.d.ts +0 -92
- package/dist/security/advanced-persistence-research.d.ts.map +0 -1
- package/dist/security/advanced-persistence-research.js +0 -195
- package/dist/security/advanced-persistence-research.js.map +0 -1
- package/dist/security/advanced-targeting.d.ts +0 -119
- package/dist/security/advanced-targeting.d.ts.map +0 -1
- package/dist/security/advanced-targeting.js +0 -233
- package/dist/security/advanced-targeting.js.map +0 -1
- package/dist/security/assessment/vulnerabilityAssessment.d.ts +0 -104
- package/dist/security/assessment/vulnerabilityAssessment.d.ts.map +0 -1
- package/dist/security/assessment/vulnerabilityAssessment.js +0 -315
- package/dist/security/assessment/vulnerabilityAssessment.js.map +0 -1
- package/dist/security/authorization/securityAuthorization.d.ts +0 -88
- package/dist/security/authorization/securityAuthorization.d.ts.map +0 -1
- package/dist/security/authorization/securityAuthorization.js +0 -172
- package/dist/security/authorization/securityAuthorization.js.map +0 -1
- package/dist/security/comprehensive-targeting.d.ts +0 -85
- package/dist/security/comprehensive-targeting.d.ts.map +0 -1
- package/dist/security/comprehensive-targeting.js +0 -438
- package/dist/security/comprehensive-targeting.js.map +0 -1
- package/dist/security/global-security-integration.d.ts +0 -91
- package/dist/security/global-security-integration.d.ts.map +0 -1
- package/dist/security/global-security-integration.js +0 -218
- package/dist/security/global-security-integration.js.map +0 -1
- package/dist/security/index.d.ts +0 -38
- package/dist/security/index.d.ts.map +0 -1
- package/dist/security/index.js +0 -47
- package/dist/security/index.js.map +0 -1
- package/dist/security/persistence-analyzer.d.ts +0 -56
- package/dist/security/persistence-analyzer.d.ts.map +0 -1
- package/dist/security/persistence-analyzer.js +0 -187
- package/dist/security/persistence-analyzer.js.map +0 -1
- package/dist/security/persistence-cli.d.ts +0 -36
- package/dist/security/persistence-cli.d.ts.map +0 -1
- package/dist/security/persistence-cli.js +0 -160
- package/dist/security/persistence-cli.js.map +0 -1
- package/dist/security/persistence-research.d.ts +0 -92
- package/dist/security/persistence-research.d.ts.map +0 -1
- package/dist/security/persistence-research.js +0 -364
- package/dist/security/persistence-research.js.map +0 -1
- package/dist/security/research/persistenceResearch.d.ts +0 -97
- package/dist/security/research/persistenceResearch.d.ts.map +0 -1
- package/dist/security/research/persistenceResearch.js +0 -282
- package/dist/security/research/persistenceResearch.js.map +0 -1
- package/dist/security/security-integration.d.ts +0 -74
- package/dist/security/security-integration.d.ts.map +0 -1
- package/dist/security/security-integration.js +0 -137
- package/dist/security/security-integration.js.map +0 -1
- package/dist/security/security-testing-framework.d.ts +0 -112
- package/dist/security/security-testing-framework.d.ts.map +0 -1
- package/dist/security/security-testing-framework.js +0 -364
- package/dist/security/security-testing-framework.js.map +0 -1
- package/dist/security/simulation/attackSimulation.d.ts +0 -93
- package/dist/security/simulation/attackSimulation.d.ts.map +0 -1
- package/dist/security/simulation/attackSimulation.js +0 -341
- package/dist/security/simulation/attackSimulation.js.map +0 -1
- package/dist/security/strategic-operations.d.ts +0 -100
- package/dist/security/strategic-operations.d.ts.map +0 -1
- package/dist/security/strategic-operations.js +0 -276
- package/dist/security/strategic-operations.js.map +0 -1
- package/dist/security/tool-security-wrapper.d.ts +0 -58
- package/dist/security/tool-security-wrapper.d.ts.map +0 -1
- package/dist/security/tool-security-wrapper.js +0 -156
- package/dist/security/tool-security-wrapper.js.map +0 -1
- package/dist/shell/claudeCodeStreamHandler.d.ts +0 -145
- package/dist/shell/claudeCodeStreamHandler.d.ts.map +0 -1
- package/dist/shell/claudeCodeStreamHandler.js +0 -322
- package/dist/shell/claudeCodeStreamHandler.js.map +0 -1
- package/dist/shell/inputQueueManager.d.ts +0 -144
- package/dist/shell/inputQueueManager.d.ts.map +0 -1
- package/dist/shell/inputQueueManager.js +0 -290
- package/dist/shell/inputQueueManager.js.map +0 -1
- package/dist/shell/streamingOutputManager.d.ts +0 -115
- package/dist/shell/streamingOutputManager.d.ts.map +0 -1
- package/dist/shell/streamingOutputManager.js +0 -225
- package/dist/shell/streamingOutputManager.js.map +0 -1
- package/dist/ui/persistentPrompt.d.ts +0 -50
- package/dist/ui/persistentPrompt.d.ts.map +0 -1
- package/dist/ui/persistentPrompt.js +0 -92
- package/dist/ui/persistentPrompt.js.map +0 -1
- package/dist/ui/terminalUISchema.d.ts +0 -195
- package/dist/ui/terminalUISchema.d.ts.map +0 -1
- package/dist/ui/terminalUISchema.js +0 -113
- package/dist/ui/terminalUISchema.js.map +0 -1
- package/scripts/deploy-security-capabilities.js +0 -178
|
@@ -2,7 +2,7 @@ import { stdin as input, stdout as output, exit } from 'node:process';
|
|
|
2
2
|
import { exec } from 'node:child_process';
|
|
3
3
|
import { promisify } from 'node:util';
|
|
4
4
|
import { display } from '../ui/display.js';
|
|
5
|
-
import { theme
|
|
5
|
+
import { theme } from '../ui/theme.js';
|
|
6
6
|
import { getContextWindowTokens } from '../core/contextWindow.js';
|
|
7
7
|
import { ensureSecretForProvider, getSecretDefinitionForProvider, getSecretValue, listSecretDefinitions, maskSecret, setSecretValue, } from '../core/secretStore.js';
|
|
8
8
|
import { saveActiveProfilePreference, saveModelPreference, loadToolSettings, saveToolSettings, clearToolSettings, clearActiveProfilePreference, loadSessionPreferences, saveSessionPreferences, } from '../core/preferences.js';
|
|
@@ -19,7 +19,7 @@ import { SkillRepository } from '../skills/skillRepository.js';
|
|
|
19
19
|
import { createSkillTools } from '../tools/skillTools.js';
|
|
20
20
|
import { FileChangeTracker } from './fileChangeTracker.js';
|
|
21
21
|
import { formatShortcutsHelp } from '../ui/shortcutsHelp.js';
|
|
22
|
-
import { MetricsTracker } from '../
|
|
22
|
+
import { MetricsTracker } from '../core/metricsTracker.js';
|
|
23
23
|
import { listAvailablePlugins } from '../plugins/index.js';
|
|
24
24
|
import { TerminalInputAdapter } from './terminalInputAdapter.js';
|
|
25
25
|
import { isUpdateInProgress } from './updateManager.js';
|
|
@@ -34,6 +34,7 @@ const DROPDOWN_COLORS = [
|
|
|
34
34
|
theme.success,
|
|
35
35
|
theme.warning,
|
|
36
36
|
];
|
|
37
|
+
const STREAMING_SPINNER_FRAMES = ['◐', '◓', '◑', '◒'];
|
|
37
38
|
// Load MODEL_PRESETS from centralized schema
|
|
38
39
|
const MODEL_PRESETS = getModels().map((model) => ({
|
|
39
40
|
id: model.id,
|
|
@@ -48,11 +49,13 @@ const MODEL_PRESETS = getModels().map((model) => ({
|
|
|
48
49
|
const BASE_SLASH_COMMANDS = getSlashCommands().map((cmd) => ({
|
|
49
50
|
command: cmd.command,
|
|
50
51
|
description: cmd.description,
|
|
52
|
+
category: cmd.category,
|
|
51
53
|
}));
|
|
52
54
|
// Load PROVIDER_LABELS from centralized schema
|
|
53
55
|
const PROVIDER_LABELS = Object.fromEntries(getProviders().map((provider) => [provider.id, provider.label]));
|
|
54
56
|
// Allow enough time for paste detection to kick in before flushing buffered lines
|
|
55
57
|
const CONTEXT_USAGE_THRESHOLD = 0.9;
|
|
58
|
+
const CONTEXT_AUTOCOMPACT_PERCENT = Math.round(CONTEXT_USAGE_THRESHOLD * 100);
|
|
56
59
|
const CONTEXT_RECENT_MESSAGE_COUNT = 12;
|
|
57
60
|
const CONTEXT_CLEANUP_CHARS_PER_CHUNK = 6000;
|
|
58
61
|
const CONTEXT_CLEANUP_MAX_OUTPUT_TOKENS = 800;
|
|
@@ -98,6 +101,7 @@ export class InteractiveShell {
|
|
|
98
101
|
followUpQueue = [];
|
|
99
102
|
isDrainingQueue = false;
|
|
100
103
|
activeContextWindowTokens = null;
|
|
104
|
+
latestTokenUsage = { used: null, limit: null };
|
|
101
105
|
sessionPreferences;
|
|
102
106
|
autosaveEnabled;
|
|
103
107
|
autoContinueEnabled;
|
|
@@ -128,6 +132,7 @@ export class InteractiveShell {
|
|
|
128
132
|
statusLineState = null;
|
|
129
133
|
statusMessageOverride = null;
|
|
130
134
|
promptRefreshTimer = null;
|
|
135
|
+
launchPaletteShown = false;
|
|
131
136
|
constructor(config) {
|
|
132
137
|
this.profile = config.profile;
|
|
133
138
|
this.profileLabel = config.profileLabel;
|
|
@@ -161,6 +166,7 @@ export class InteractiveShell {
|
|
|
161
166
|
this.slashCommands.push({
|
|
162
167
|
command: '/agents',
|
|
163
168
|
description: 'Select the default agent profile (applies on next launch)',
|
|
169
|
+
category: 'configuration',
|
|
164
170
|
});
|
|
165
171
|
}
|
|
166
172
|
this.customCommands = loadCustomSlashCommands();
|
|
@@ -169,18 +175,21 @@ export class InteractiveShell {
|
|
|
169
175
|
this.slashCommands.push({
|
|
170
176
|
command: custom.command,
|
|
171
177
|
description: `${custom.description} (custom)`,
|
|
178
|
+
category: custom.category ?? 'other',
|
|
172
179
|
});
|
|
173
180
|
}
|
|
174
181
|
if (!this.slashCommands.some((cmd) => cmd.command === '/exit')) {
|
|
175
182
|
this.slashCommands.push({
|
|
176
183
|
command: '/exit',
|
|
177
184
|
description: 'Quit the CLI immediately',
|
|
185
|
+
category: 'other',
|
|
178
186
|
});
|
|
179
187
|
}
|
|
180
188
|
// Add /plugins command
|
|
181
189
|
this.slashCommands.push({
|
|
182
190
|
command: '/plugins',
|
|
183
191
|
description: 'Show available and loaded plugins',
|
|
192
|
+
category: 'configuration',
|
|
184
193
|
});
|
|
185
194
|
this.statusTracker = config.statusTracker;
|
|
186
195
|
this.ui = config.ui;
|
|
@@ -215,9 +224,6 @@ export class InteractiveShell {
|
|
|
215
224
|
});
|
|
216
225
|
// Register output interceptor for cursor positioning during streaming
|
|
217
226
|
this.terminalInput.registerOutputInterceptor(display);
|
|
218
|
-
// Use flow mode: input renders inline after content for a unified layout
|
|
219
|
-
// This eliminates the blank space between banner and input area
|
|
220
|
-
this.terminalInput.setFlowMode(true);
|
|
221
227
|
// Initialize Alpha Zero 2 metrics tracking
|
|
222
228
|
this.alphaZeroMetrics = new MetricsTracker(`${this.profile}-${Date.now()}`);
|
|
223
229
|
this.setupStatusTracking();
|
|
@@ -275,9 +281,15 @@ export class InteractiveShell {
|
|
|
275
281
|
await this.processInputBlock(initialPrompt);
|
|
276
282
|
return;
|
|
277
283
|
}
|
|
284
|
+
this.showLaunchCommandPalette();
|
|
278
285
|
// Ensure the terminal input is visible
|
|
279
286
|
this.terminalInput.render();
|
|
280
287
|
}
|
|
288
|
+
showLaunchCommandPalette() {
|
|
289
|
+
// Disabled: Quick commands palette takes up too much space
|
|
290
|
+
// Users can type /help to see available commands
|
|
291
|
+
this.launchPaletteShown = true;
|
|
292
|
+
}
|
|
281
293
|
/**
|
|
282
294
|
* TerminalInputAdapter submit handler
|
|
283
295
|
*/
|
|
@@ -291,9 +303,8 @@ export class InteractiveShell {
|
|
|
291
303
|
this.handleInputChange('');
|
|
292
304
|
return;
|
|
293
305
|
}
|
|
294
|
-
//
|
|
295
|
-
//
|
|
296
|
-
this.terminalInput.setStreaming(true);
|
|
306
|
+
// DON'T clear the input here - keep it visible while streaming.
|
|
307
|
+
// The input will be cleared after streaming completes in the finally block.
|
|
297
308
|
this.logUserPrompt(approved);
|
|
298
309
|
void this.processInputBlock(approved).catch((err) => {
|
|
299
310
|
display.showError(err instanceof Error ? err.message : String(err), err);
|
|
@@ -495,10 +506,9 @@ export class InteractiveShell {
|
|
|
495
506
|
// Dispose unified UI adapter
|
|
496
507
|
this.uiAdapter.dispose();
|
|
497
508
|
display.newLine();
|
|
498
|
-
console.log(theme.
|
|
499
|
-
console.log(
|
|
500
|
-
console.log(
|
|
501
|
-
console.log(theme.gradient.warm('━'.repeat(50)));
|
|
509
|
+
console.log(theme.ui.muted('━'.repeat(44)));
|
|
510
|
+
console.log(theme.ui.muted(' Goodbye! · support@ero.solar'));
|
|
511
|
+
console.log(theme.ui.muted('━'.repeat(44)));
|
|
502
512
|
exit(0);
|
|
503
513
|
}
|
|
504
514
|
/**
|
|
@@ -668,13 +678,14 @@ export class InteractiveShell {
|
|
|
668
678
|
});
|
|
669
679
|
}
|
|
670
680
|
setProcessingStatus(detail) {
|
|
681
|
+
this.latestTokenUsage = { used: null, limit: this.latestTokenUsage.limit };
|
|
671
682
|
this.statusTracker.setBase('Working on your request', {
|
|
672
683
|
detail: this.describeStatusDetail(detail),
|
|
673
684
|
tone: 'info',
|
|
674
685
|
});
|
|
675
686
|
}
|
|
676
687
|
describeStatusDetail(detail) {
|
|
677
|
-
const parts =
|
|
688
|
+
const parts = detail?.trim() ? [detail.trim()] : [];
|
|
678
689
|
const queued = this.followUpQueue.length;
|
|
679
690
|
if (queued > 0) {
|
|
680
691
|
parts.push(`${queued} follow-up${queued === 1 ? '' : 's'} queued`);
|
|
@@ -687,12 +698,18 @@ export class InteractiveShell {
|
|
|
687
698
|
}
|
|
688
699
|
refreshContextGauge() {
|
|
689
700
|
const tokens = getContextWindowTokens(this.sessionState.model);
|
|
690
|
-
|
|
691
|
-
|
|
701
|
+
const normalizedTokens = typeof tokens === 'number' && Number.isFinite(tokens) ? tokens : null;
|
|
702
|
+
this.activeContextWindowTokens = normalizedTokens;
|
|
703
|
+
if (normalizedTokens !== null) {
|
|
704
|
+
this.latestTokenUsage = {
|
|
705
|
+
used: this.latestTokenUsage.used,
|
|
706
|
+
limit: normalizedTokens,
|
|
707
|
+
};
|
|
708
|
+
}
|
|
692
709
|
}
|
|
693
710
|
updateContextUsage(percentage) {
|
|
694
711
|
this.uiAdapter.updateContextUsage(percentage);
|
|
695
|
-
this.terminalInput.setContextUsage(percentage);
|
|
712
|
+
this.terminalInput.setContextUsage(percentage, CONTEXT_AUTOCOMPACT_PERCENT);
|
|
696
713
|
}
|
|
697
714
|
refreshControlBar() {
|
|
698
715
|
this.terminalInput.setModeToggles({
|
|
@@ -700,6 +717,8 @@ export class InteractiveShell {
|
|
|
700
717
|
autoContinueEnabled: this.autoContinueEnabled,
|
|
701
718
|
verificationHotkey: 'alt+v',
|
|
702
719
|
autoContinueHotkey: 'alt+c',
|
|
720
|
+
thinkingModeLabel: this.thinkingMode,
|
|
721
|
+
thinkingHotkey: '/thinking',
|
|
703
722
|
});
|
|
704
723
|
this.refreshStatusLine();
|
|
705
724
|
this.terminalInput.render();
|
|
@@ -731,6 +750,25 @@ export class InteractiveShell {
|
|
|
731
750
|
// Set main status (tool execution, etc.) - shown when not overridden
|
|
732
751
|
const statusText = this.formatStatusLine(this.statusLineState);
|
|
733
752
|
this.terminalInput.setStatusMessage(statusText);
|
|
753
|
+
// Surface meta header (elapsed + context usage) above the divider
|
|
754
|
+
const elapsedSeconds = this.statusLineState
|
|
755
|
+
? Math.max(0, Math.floor((Date.now() - this.statusLineState.startedAt) / 1000))
|
|
756
|
+
: null;
|
|
757
|
+
const thinkingMs = display.isSpinnerActive() ? display.getThinkingElapsedMs() : null;
|
|
758
|
+
const tokensUsed = this.latestTokenUsage.used;
|
|
759
|
+
const tokenLimit = this.latestTokenUsage.limit ?? this.activeContextWindowTokens;
|
|
760
|
+
this.terminalInput.setMetaStatus({
|
|
761
|
+
elapsedSeconds,
|
|
762
|
+
tokensUsed,
|
|
763
|
+
tokenLimit,
|
|
764
|
+
thinkingMs,
|
|
765
|
+
thinkingHasContent: display.isSpinnerActive(),
|
|
766
|
+
});
|
|
767
|
+
// Keep model/provider visible in the controls bar
|
|
768
|
+
this.terminalInput.setModelContext({
|
|
769
|
+
model: this.sessionState.model,
|
|
770
|
+
provider: this.providerLabel(this.sessionState.provider),
|
|
771
|
+
});
|
|
734
772
|
if (forceRender) {
|
|
735
773
|
this.terminalInput.render();
|
|
736
774
|
}
|
|
@@ -790,13 +828,11 @@ export class InteractiveShell {
|
|
|
790
828
|
this.terminalInput.render();
|
|
791
829
|
}
|
|
792
830
|
/**
|
|
793
|
-
*
|
|
794
|
-
*
|
|
831
|
+
* Keep submissions out of the transcript to preserve the persistent input area.
|
|
832
|
+
* The chat box already holds the user's prompt, so avoid echoing it into output.
|
|
795
833
|
*/
|
|
796
|
-
logUserPrompt(
|
|
797
|
-
//
|
|
798
|
-
const prefix = formatUserPrompt();
|
|
799
|
-
display.stream(`\n${prefix}${text}\n\n`);
|
|
834
|
+
logUserPrompt(_text) {
|
|
835
|
+
// Intentionally no-op to keep the input area persistent and uncluttered.
|
|
800
836
|
}
|
|
801
837
|
requestPromptRefresh(force = false) {
|
|
802
838
|
if (force) {
|
|
@@ -824,9 +860,29 @@ export class InteractiveShell {
|
|
|
824
860
|
this.uiUpdates.setMode('streaming');
|
|
825
861
|
this.streamingHeartbeatStart = Date.now();
|
|
826
862
|
this.streamingHeartbeatFrame = 0;
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
863
|
+
const initialFrame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
|
|
864
|
+
this.streamingStatusLabel = this.buildStreamingStatus(`${initialFrame} ${label}`, 0);
|
|
865
|
+
display.updateStreamingStatus(this.streamingStatusLabel);
|
|
866
|
+
this.refreshStatusLine(true);
|
|
867
|
+
// Periodically refresh the pinned input/status region while streaming so
|
|
868
|
+
// elapsed time remains visible without interrupting the scroll region.
|
|
869
|
+
this.uiUpdates.startHeartbeat('streaming', {
|
|
870
|
+
intervalMs: 1000,
|
|
871
|
+
lane: 'heartbeat',
|
|
872
|
+
mode: ['streaming', 'processing'],
|
|
873
|
+
coalesceKey: 'streaming:heartbeat',
|
|
874
|
+
run: () => {
|
|
875
|
+
const elapsedSeconds = this.streamingHeartbeatStart
|
|
876
|
+
? Math.max(0, Math.floor((Date.now() - this.streamingHeartbeatStart) / 1000))
|
|
877
|
+
: 0;
|
|
878
|
+
this.streamingHeartbeatFrame =
|
|
879
|
+
(this.streamingHeartbeatFrame + 1) % STREAMING_SPINNER_FRAMES.length;
|
|
880
|
+
const frame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
|
|
881
|
+
this.streamingStatusLabel = this.buildStreamingStatus(`${frame} ${label}`, elapsedSeconds);
|
|
882
|
+
display.updateStreamingStatus(this.streamingStatusLabel);
|
|
883
|
+
this.refreshStatusLine(true);
|
|
884
|
+
},
|
|
885
|
+
});
|
|
830
886
|
}
|
|
831
887
|
stopStreamingHeartbeat() {
|
|
832
888
|
// Exit global streaming mode - allows UI to render again
|
|
@@ -842,10 +898,28 @@ export class InteractiveShell {
|
|
|
842
898
|
// Force refresh to update the input area now that streaming has ended
|
|
843
899
|
this.refreshStatusLine(true);
|
|
844
900
|
}
|
|
845
|
-
buildStreamingStatus(label) {
|
|
901
|
+
buildStreamingStatus(label, elapsedSeconds) {
|
|
846
902
|
const detail = this.describeModelDetail();
|
|
847
|
-
const
|
|
848
|
-
|
|
903
|
+
const elapsedLabel = typeof elapsedSeconds === 'number' && elapsedSeconds >= 0
|
|
904
|
+
? theme.ui.muted(this.formatElapsedShort(elapsedSeconds))
|
|
905
|
+
: null;
|
|
906
|
+
const prefix = theme.info('⏺');
|
|
907
|
+
const parts = [label];
|
|
908
|
+
if (detail) {
|
|
909
|
+
parts.push(theme.ui.muted('·'), detail);
|
|
910
|
+
}
|
|
911
|
+
if (elapsedLabel) {
|
|
912
|
+
parts.push(theme.ui.muted('·'), elapsedLabel);
|
|
913
|
+
}
|
|
914
|
+
return `${prefix} ${parts.join(' ')}`.trim();
|
|
915
|
+
}
|
|
916
|
+
formatElapsedShort(seconds) {
|
|
917
|
+
if (seconds < 60) {
|
|
918
|
+
return `${seconds}s`;
|
|
919
|
+
}
|
|
920
|
+
const minutes = Math.floor(seconds / 60);
|
|
921
|
+
const remaining = seconds % 60;
|
|
922
|
+
return remaining > 0 ? `${minutes}m ${remaining}s` : `${minutes}m`;
|
|
849
923
|
}
|
|
850
924
|
refreshQueueIndicators() {
|
|
851
925
|
if (this.isProcessing) {
|
|
@@ -1739,6 +1813,75 @@ export class InteractiveShell {
|
|
|
1739
1813
|
}
|
|
1740
1814
|
return `${warning.label}: ${warning.reason}.`;
|
|
1741
1815
|
}
|
|
1816
|
+
buildLaunchCommandPalette() {
|
|
1817
|
+
const entries = [];
|
|
1818
|
+
const secretsSummary = this.summarizeSecretsForPalette();
|
|
1819
|
+
const toolSummary = this.getToolSelectionSummary();
|
|
1820
|
+
const autosaveLabel = this.autosaveEnabled ? 'on' : 'off';
|
|
1821
|
+
for (const command of this.slashCommands) {
|
|
1822
|
+
const entry = {
|
|
1823
|
+
command: command.command,
|
|
1824
|
+
description: command.description,
|
|
1825
|
+
category: command.category ?? 'other',
|
|
1826
|
+
};
|
|
1827
|
+
switch (command.command) {
|
|
1828
|
+
case '/secrets':
|
|
1829
|
+
if (secretsSummary.text) {
|
|
1830
|
+
entry.description = `${command.description} (${secretsSummary.text})`;
|
|
1831
|
+
entry.tone = secretsSummary.tone;
|
|
1832
|
+
}
|
|
1833
|
+
break;
|
|
1834
|
+
case '/tools':
|
|
1835
|
+
if (toolSummary) {
|
|
1836
|
+
entry.description = `${command.description} (${toolSummary})`;
|
|
1837
|
+
}
|
|
1838
|
+
break;
|
|
1839
|
+
case '/sessions':
|
|
1840
|
+
entry.description = `${command.description} (autosave ${autosaveLabel})`;
|
|
1841
|
+
break;
|
|
1842
|
+
case '/model':
|
|
1843
|
+
entry.description = `${command.description} (current: ${this.sessionState.model})`;
|
|
1844
|
+
break;
|
|
1845
|
+
case '/provider':
|
|
1846
|
+
entry.description = `${command.description} (current: ${this.providerLabel(this.sessionState.provider)})`;
|
|
1847
|
+
break;
|
|
1848
|
+
default:
|
|
1849
|
+
break;
|
|
1850
|
+
}
|
|
1851
|
+
entries.push(entry);
|
|
1852
|
+
}
|
|
1853
|
+
return entries;
|
|
1854
|
+
}
|
|
1855
|
+
summarizeSecretsForPalette() {
|
|
1856
|
+
const definitions = listSecretDefinitions();
|
|
1857
|
+
if (!definitions.length) {
|
|
1858
|
+
return { text: null };
|
|
1859
|
+
}
|
|
1860
|
+
const missing = definitions.filter((definition) => !getSecretValue(definition.id));
|
|
1861
|
+
if (missing.length === 0) {
|
|
1862
|
+
return { text: 'all configured', tone: 'success' };
|
|
1863
|
+
}
|
|
1864
|
+
const labels = missing.map((definition) => definition.label ?? definition.id);
|
|
1865
|
+
return { text: `missing ${this.formatList(labels)}`, tone: 'warn' };
|
|
1866
|
+
}
|
|
1867
|
+
getToolSelectionSummary() {
|
|
1868
|
+
const toolSettings = loadToolSettings();
|
|
1869
|
+
const selection = buildEnabledToolSet(toolSettings);
|
|
1870
|
+
const options = getToolToggleOptions();
|
|
1871
|
+
if (!options.length) {
|
|
1872
|
+
return null;
|
|
1873
|
+
}
|
|
1874
|
+
const enabledCount = options.filter((option) => selection.has(option.id)).length;
|
|
1875
|
+
return `${enabledCount}/${options.length} enabled`;
|
|
1876
|
+
}
|
|
1877
|
+
formatList(values, maxItems = 3) {
|
|
1878
|
+
if (!values.length) {
|
|
1879
|
+
return '';
|
|
1880
|
+
}
|
|
1881
|
+
const shown = values.slice(0, maxItems);
|
|
1882
|
+
const suffix = values.length > maxItems ? ', …' : '';
|
|
1883
|
+
return `${shown.join(', ')}${suffix}`;
|
|
1884
|
+
}
|
|
1742
1885
|
buildSlashCommandList(header) {
|
|
1743
1886
|
const lines = [theme.gradient.primary(header), ''];
|
|
1744
1887
|
for (const command of this.slashCommands) {
|
|
@@ -2229,9 +2372,6 @@ export class InteractiveShell {
|
|
|
2229
2372
|
this.setIdleStatus();
|
|
2230
2373
|
display.newLine();
|
|
2231
2374
|
this.updateStatusMessage(null);
|
|
2232
|
-
// Claude Code style: Show unified status bar before prompt
|
|
2233
|
-
// This creates consistent UI between startup and post-streaming
|
|
2234
|
-
this.showUnifiedStatusBar();
|
|
2235
2375
|
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
2236
2376
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
2237
2377
|
// Claude Code style: New prompt naturally appears at bottom
|
|
@@ -2308,6 +2448,7 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
|
|
|
2308
2448
|
try {
|
|
2309
2449
|
// Send the request and capture the response (streaming disabled)
|
|
2310
2450
|
display.showThinking('Responding...');
|
|
2451
|
+
this.refreshStatusLine(true);
|
|
2311
2452
|
const response = await agent.send(currentPrompt, true);
|
|
2312
2453
|
await this.awaitPendingCleanup();
|
|
2313
2454
|
this.captureHistorySnapshot();
|
|
@@ -2807,8 +2948,10 @@ What's the next action?`;
|
|
|
2807
2948
|
try {
|
|
2808
2949
|
// Send the error to the agent for fixing
|
|
2809
2950
|
display.showThinking('Analyzing build errors');
|
|
2951
|
+
this.refreshStatusLine(true);
|
|
2810
2952
|
const response = await this.agent.send(prompt, true);
|
|
2811
2953
|
display.stopThinking();
|
|
2954
|
+
this.refreshStatusLine(true);
|
|
2812
2955
|
if (response) {
|
|
2813
2956
|
display.showAssistantMessage(response, { isFinal: true });
|
|
2814
2957
|
}
|
|
@@ -2858,18 +3001,16 @@ What's the next action?`;
|
|
|
2858
3001
|
display.showAssistantMessage(finalContent, enriched);
|
|
2859
3002
|
}
|
|
2860
3003
|
}
|
|
2861
|
-
//
|
|
3004
|
+
// Status shown in mode controls bar - no separate status line needed
|
|
2862
3005
|
display.stopThinking();
|
|
2863
|
-
//
|
|
2864
|
-
let contextInfo;
|
|
3006
|
+
// Update context usage for mode controls display
|
|
2865
3007
|
if (enriched.contextWindowTokens && metadata.usage) {
|
|
2866
3008
|
const total = this.totalTokens(metadata.usage);
|
|
2867
3009
|
if (total && total > 0) {
|
|
2868
3010
|
const percentage = Math.round((total / enriched.contextWindowTokens) * 100);
|
|
2869
|
-
|
|
3011
|
+
this.updateContextUsage(percentage);
|
|
2870
3012
|
}
|
|
2871
3013
|
}
|
|
2872
|
-
display.showStatusLine('Ready for prompts', enriched.elapsedMs, contextInfo);
|
|
2873
3014
|
// Auto-verify changes: build first (catches type errors), then tests
|
|
2874
3015
|
void this.enforceAutoBuild('final-response');
|
|
2875
3016
|
void this.enforceAutoTests('final-response');
|
|
@@ -3039,9 +3180,14 @@ What's the next action?`;
|
|
|
3039
3180
|
return null;
|
|
3040
3181
|
}
|
|
3041
3182
|
const usageRatio = total / windowTokens;
|
|
3183
|
+
this.latestTokenUsage = {
|
|
3184
|
+
used: total,
|
|
3185
|
+
limit: windowTokens,
|
|
3186
|
+
};
|
|
3042
3187
|
// Always update context usage in the UI
|
|
3043
3188
|
const percentUsed = Math.round(usageRatio * 100);
|
|
3044
3189
|
this.updateContextUsage(percentUsed);
|
|
3190
|
+
this.refreshStatusLine(true);
|
|
3045
3191
|
if (usageRatio < CONTEXT_USAGE_THRESHOLD) {
|
|
3046
3192
|
return null;
|
|
3047
3193
|
}
|