erosolar-cli 1.7.262 → 1.7.263
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 +148 -22
- package/dist/alpha-zero/agentWrapper.d.ts +84 -0
- package/dist/alpha-zero/agentWrapper.d.ts.map +1 -0
- package/dist/alpha-zero/agentWrapper.js +171 -0
- package/dist/alpha-zero/agentWrapper.js.map +1 -0
- package/dist/alpha-zero/codeEvaluator.d.ts +25 -0
- package/dist/alpha-zero/codeEvaluator.d.ts.map +1 -0
- package/dist/alpha-zero/codeEvaluator.js +273 -0
- package/dist/alpha-zero/codeEvaluator.js.map +1 -0
- package/dist/alpha-zero/competitiveRunner.d.ts +66 -0
- package/dist/alpha-zero/competitiveRunner.d.ts.map +1 -0
- package/dist/alpha-zero/competitiveRunner.js +224 -0
- package/dist/alpha-zero/competitiveRunner.js.map +1 -0
- package/dist/alpha-zero/index.d.ts +67 -0
- package/dist/alpha-zero/index.d.ts.map +1 -0
- package/dist/alpha-zero/index.js +99 -0
- package/dist/alpha-zero/index.js.map +1 -0
- package/dist/alpha-zero/introspection.d.ts +128 -0
- package/dist/alpha-zero/introspection.d.ts.map +1 -0
- package/dist/alpha-zero/introspection.js +300 -0
- package/dist/alpha-zero/introspection.js.map +1 -0
- package/dist/alpha-zero/metricsTracker.d.ts +71 -0
- package/dist/alpha-zero/metricsTracker.d.ts.map +1 -0
- package/dist/{core → alpha-zero}/metricsTracker.js +5 -2
- package/dist/alpha-zero/metricsTracker.js.map +1 -0
- package/dist/alpha-zero/security/core.d.ts +125 -0
- package/dist/alpha-zero/security/core.d.ts.map +1 -0
- package/dist/alpha-zero/security/core.js +271 -0
- package/dist/alpha-zero/security/core.js.map +1 -0
- package/dist/alpha-zero/security/google.d.ts +125 -0
- package/dist/alpha-zero/security/google.d.ts.map +1 -0
- package/dist/alpha-zero/security/google.js +311 -0
- package/dist/alpha-zero/security/google.js.map +1 -0
- package/dist/alpha-zero/security/googleLoader.d.ts +17 -0
- package/dist/alpha-zero/security/googleLoader.d.ts.map +1 -0
- package/dist/alpha-zero/security/googleLoader.js +41 -0
- package/dist/alpha-zero/security/googleLoader.js.map +1 -0
- package/dist/alpha-zero/security/index.d.ts +29 -0
- package/dist/alpha-zero/security/index.d.ts.map +1 -0
- package/dist/alpha-zero/security/index.js +32 -0
- package/dist/alpha-zero/security/index.js.map +1 -0
- package/dist/alpha-zero/security/simulation.d.ts +124 -0
- package/dist/alpha-zero/security/simulation.d.ts.map +1 -0
- package/dist/alpha-zero/security/simulation.js +277 -0
- package/dist/alpha-zero/security/simulation.js.map +1 -0
- package/dist/alpha-zero/selfModification.d.ts +109 -0
- package/dist/alpha-zero/selfModification.d.ts.map +1 -0
- package/dist/alpha-zero/selfModification.js +233 -0
- package/dist/alpha-zero/selfModification.js.map +1 -0
- package/dist/alpha-zero/types.d.ts +170 -0
- package/dist/alpha-zero/types.d.ts.map +1 -0
- package/dist/alpha-zero/types.js +31 -0
- package/dist/alpha-zero/types.js.map +1 -0
- package/dist/capabilities/securityTestingCapability.d.ts +13 -0
- package/dist/capabilities/securityTestingCapability.d.ts.map +1 -0
- package/dist/capabilities/securityTestingCapability.js +25 -0
- package/dist/capabilities/securityTestingCapability.js.map +1 -0
- package/dist/contracts/agent-schemas.json +15 -0
- package/dist/contracts/tools.schema.json +9 -0
- package/dist/core/aiFlowOptimizer.d.ts +26 -0
- package/dist/core/aiFlowOptimizer.d.ts.map +1 -0
- package/dist/core/aiFlowOptimizer.js +31 -0
- package/dist/core/aiFlowOptimizer.js.map +1 -0
- package/dist/core/aiOptimizationEngine.d.ts +158 -0
- package/dist/core/aiOptimizationEngine.d.ts.map +1 -0
- package/dist/core/aiOptimizationEngine.js +428 -0
- package/dist/core/aiOptimizationEngine.js.map +1 -0
- package/dist/core/aiOptimizationIntegration.d.ts +93 -0
- package/dist/core/aiOptimizationIntegration.d.ts.map +1 -0
- package/dist/core/aiOptimizationIntegration.js +250 -0
- package/dist/core/aiOptimizationIntegration.js.map +1 -0
- package/dist/core/customCommands.d.ts +0 -1
- package/dist/core/customCommands.d.ts.map +1 -1
- package/dist/core/customCommands.js +0 -3
- package/dist/core/customCommands.js.map +1 -1
- package/dist/core/enhancedErrorRecovery.d.ts +100 -0
- package/dist/core/enhancedErrorRecovery.d.ts.map +1 -0
- package/dist/core/enhancedErrorRecovery.js +345 -0
- package/dist/core/enhancedErrorRecovery.js.map +1 -0
- package/dist/core/hooksSystem.d.ts +65 -0
- package/dist/core/hooksSystem.d.ts.map +1 -0
- package/dist/core/hooksSystem.js +273 -0
- package/dist/core/hooksSystem.js.map +1 -0
- package/dist/core/memorySystem.d.ts +48 -0
- package/dist/core/memorySystem.d.ts.map +1 -0
- package/dist/core/memorySystem.js +271 -0
- package/dist/core/memorySystem.js.map +1 -0
- package/dist/core/toolPreconditions.d.ts.map +1 -1
- package/dist/core/toolPreconditions.js +14 -0
- package/dist/core/toolPreconditions.js.map +1 -1
- package/dist/core/toolRuntime.d.ts.map +1 -1
- package/dist/core/toolRuntime.js +5 -0
- package/dist/core/toolRuntime.js.map +1 -1
- package/dist/core/toolValidation.d.ts.map +1 -1
- package/dist/core/toolValidation.js +3 -14
- package/dist/core/toolValidation.js.map +1 -1
- package/dist/core/unified/errors.d.ts +189 -0
- package/dist/core/unified/errors.d.ts.map +1 -0
- package/dist/core/unified/errors.js +497 -0
- package/dist/core/unified/errors.js.map +1 -0
- package/dist/core/unified/index.d.ts +19 -0
- package/dist/core/unified/index.d.ts.map +1 -0
- package/dist/core/unified/index.js +68 -0
- package/dist/core/unified/index.js.map +1 -0
- package/dist/core/unified/schema.d.ts +101 -0
- package/dist/core/unified/schema.d.ts.map +1 -0
- package/dist/core/unified/schema.js +350 -0
- package/dist/core/unified/schema.js.map +1 -0
- package/dist/core/unified/toolRuntime.d.ts +179 -0
- package/dist/core/unified/toolRuntime.d.ts.map +1 -0
- package/dist/core/unified/toolRuntime.js +517 -0
- package/dist/core/unified/toolRuntime.js.map +1 -0
- package/dist/core/unified/tools.d.ts +127 -0
- package/dist/core/unified/tools.d.ts.map +1 -0
- package/dist/core/unified/tools.js +1333 -0
- package/dist/core/unified/tools.js.map +1 -0
- package/dist/core/unified/types.d.ts +352 -0
- package/dist/core/unified/types.d.ts.map +1 -0
- package/dist/core/unified/types.js +12 -0
- package/dist/core/unified/types.js.map +1 -0
- package/dist/core/unified/version.d.ts +209 -0
- package/dist/core/unified/version.d.ts.map +1 -0
- package/dist/core/unified/version.js +454 -0
- package/dist/core/unified/version.js.map +1 -0
- package/dist/core/validationRunner.d.ts +3 -1
- 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 +18 -9
- package/dist/mcp/sseClient.js.map +1 -1
- package/dist/plugins/tools/build/buildPlugin.d.ts +6 -0
- package/dist/plugins/tools/build/buildPlugin.d.ts.map +1 -1
- package/dist/plugins/tools/build/buildPlugin.js +10 -4
- package/dist/plugins/tools/build/buildPlugin.js.map +1 -1
- package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -1
- package/dist/plugins/tools/nodeDefaults.js +2 -0
- package/dist/plugins/tools/nodeDefaults.js.map +1 -1
- package/dist/plugins/tools/security/securityPlugin.d.ts +3 -0
- package/dist/plugins/tools/security/securityPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/security/securityPlugin.js +12 -0
- package/dist/plugins/tools/security/securityPlugin.js.map +1 -0
- package/dist/security/active-stack-security.d.ts +112 -0
- package/dist/security/active-stack-security.d.ts.map +1 -0
- package/dist/security/active-stack-security.js +296 -0
- package/dist/security/active-stack-security.js.map +1 -0
- package/dist/security/advanced-persistence-research.d.ts +92 -0
- package/dist/security/advanced-persistence-research.d.ts.map +1 -0
- package/dist/security/advanced-persistence-research.js +195 -0
- package/dist/security/advanced-persistence-research.js.map +1 -0
- package/dist/security/advanced-targeting.d.ts +119 -0
- package/dist/security/advanced-targeting.d.ts.map +1 -0
- package/dist/security/advanced-targeting.js +233 -0
- package/dist/security/advanced-targeting.js.map +1 -0
- package/dist/security/assessment/vulnerabilityAssessment.d.ts +104 -0
- package/dist/security/assessment/vulnerabilityAssessment.d.ts.map +1 -0
- package/dist/security/assessment/vulnerabilityAssessment.js +315 -0
- package/dist/security/assessment/vulnerabilityAssessment.js.map +1 -0
- package/dist/security/authorization/securityAuthorization.d.ts +88 -0
- package/dist/security/authorization/securityAuthorization.d.ts.map +1 -0
- package/dist/security/authorization/securityAuthorization.js +172 -0
- package/dist/security/authorization/securityAuthorization.js.map +1 -0
- package/dist/security/comprehensive-targeting.d.ts +85 -0
- package/dist/security/comprehensive-targeting.d.ts.map +1 -0
- package/dist/security/comprehensive-targeting.js +438 -0
- package/dist/security/comprehensive-targeting.js.map +1 -0
- package/dist/security/global-security-integration.d.ts +91 -0
- package/dist/security/global-security-integration.d.ts.map +1 -0
- package/dist/security/global-security-integration.js +218 -0
- package/dist/security/global-security-integration.js.map +1 -0
- package/dist/security/index.d.ts +38 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +47 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/persistence-analyzer.d.ts +56 -0
- package/dist/security/persistence-analyzer.d.ts.map +1 -0
- package/dist/security/persistence-analyzer.js +187 -0
- package/dist/security/persistence-analyzer.js.map +1 -0
- package/dist/security/persistence-cli.d.ts +36 -0
- package/dist/security/persistence-cli.d.ts.map +1 -0
- package/dist/security/persistence-cli.js +160 -0
- package/dist/security/persistence-cli.js.map +1 -0
- package/dist/security/persistence-research.d.ts +92 -0
- package/dist/security/persistence-research.d.ts.map +1 -0
- package/dist/security/persistence-research.js +364 -0
- package/dist/security/persistence-research.js.map +1 -0
- package/dist/security/research/persistenceResearch.d.ts +97 -0
- package/dist/security/research/persistenceResearch.d.ts.map +1 -0
- package/dist/security/research/persistenceResearch.js +282 -0
- package/dist/security/research/persistenceResearch.js.map +1 -0
- package/dist/security/security-integration.d.ts +74 -0
- package/dist/security/security-integration.d.ts.map +1 -0
- package/dist/security/security-integration.js +137 -0
- package/dist/security/security-integration.js.map +1 -0
- package/dist/security/security-testing-framework.d.ts +112 -0
- package/dist/security/security-testing-framework.d.ts.map +1 -0
- package/dist/security/security-testing-framework.js +364 -0
- package/dist/security/security-testing-framework.js.map +1 -0
- package/dist/security/simulation/attackSimulation.d.ts +93 -0
- package/dist/security/simulation/attackSimulation.d.ts.map +1 -0
- package/dist/security/simulation/attackSimulation.js +341 -0
- package/dist/security/simulation/attackSimulation.js.map +1 -0
- package/dist/security/strategic-operations.d.ts +100 -0
- package/dist/security/strategic-operations.d.ts.map +1 -0
- package/dist/security/strategic-operations.js +276 -0
- package/dist/security/strategic-operations.js.map +1 -0
- package/dist/security/tool-security-wrapper.d.ts +58 -0
- package/dist/security/tool-security-wrapper.d.ts.map +1 -0
- package/dist/security/tool-security-wrapper.js +156 -0
- package/dist/security/tool-security-wrapper.js.map +1 -0
- package/dist/shell/claudeCodeStreamHandler.d.ts +145 -0
- package/dist/shell/claudeCodeStreamHandler.d.ts.map +1 -0
- package/dist/shell/claudeCodeStreamHandler.js +322 -0
- package/dist/shell/claudeCodeStreamHandler.js.map +1 -0
- package/dist/shell/inputQueueManager.d.ts +144 -0
- package/dist/shell/inputQueueManager.d.ts.map +1 -0
- package/dist/shell/inputQueueManager.js +290 -0
- package/dist/shell/inputQueueManager.js.map +1 -0
- package/dist/shell/interactiveShell.d.ts +7 -11
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +153 -190
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/metricsTracker.d.ts +60 -0
- package/dist/shell/metricsTracker.d.ts.map +1 -0
- package/dist/shell/metricsTracker.js +119 -0
- package/dist/shell/metricsTracker.js.map +1 -0
- package/dist/shell/shellApp.d.ts +0 -2
- package/dist/shell/shellApp.d.ts.map +1 -1
- package/dist/shell/shellApp.js +0 -16
- package/dist/shell/shellApp.js.map +1 -1
- package/dist/shell/streamingOutputManager.d.ts +115 -0
- package/dist/shell/streamingOutputManager.d.ts.map +1 -0
- package/dist/shell/streamingOutputManager.js +225 -0
- package/dist/shell/streamingOutputManager.js.map +1 -0
- package/dist/shell/systemPrompt.d.ts.map +1 -1
- package/dist/shell/systemPrompt.js +4 -1
- package/dist/shell/systemPrompt.js.map +1 -1
- package/dist/shell/terminalInput.d.ts +147 -68
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +689 -451
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/terminalInputAdapter.d.ts +20 -20
- package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
- package/dist/shell/terminalInputAdapter.js +29 -14
- package/dist/shell/terminalInputAdapter.js.map +1 -1
- package/dist/tools/securityTools.d.ts +22 -0
- package/dist/tools/securityTools.d.ts.map +1 -0
- package/dist/tools/securityTools.js +448 -0
- package/dist/tools/securityTools.js.map +1 -0
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +12 -13
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/display.d.ts +0 -19
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +33 -131
- package/dist/ui/display.js.map +1 -1
- package/dist/ui/persistentPrompt.d.ts +50 -0
- package/dist/ui/persistentPrompt.d.ts.map +1 -0
- package/dist/ui/persistentPrompt.js +92 -0
- package/dist/ui/persistentPrompt.js.map +1 -0
- package/dist/ui/terminalUISchema.d.ts +195 -0
- package/dist/ui/terminalUISchema.d.ts.map +1 -0
- package/dist/ui/terminalUISchema.js +113 -0
- package/dist/ui/terminalUISchema.js.map +1 -0
- package/dist/ui/theme.d.ts.map +1 -1
- package/dist/ui/theme.js +8 -6
- package/dist/ui/theme.js.map +1 -1
- package/dist/ui/toolDisplay.d.ts +158 -0
- package/dist/ui/toolDisplay.d.ts.map +1 -1
- package/dist/ui/toolDisplay.js +348 -0
- package/dist/ui/toolDisplay.js.map +1 -1
- package/dist/ui/unified/layout.d.ts +0 -1
- package/dist/ui/unified/layout.d.ts.map +1 -1
- package/dist/ui/unified/layout.js +25 -15
- package/dist/ui/unified/layout.js.map +1 -1
- package/package.json +1 -1
- package/scripts/deploy-security-capabilities.js +178 -0
- package/dist/core/hooks.d.ts +0 -113
- package/dist/core/hooks.d.ts.map +0 -1
- package/dist/core/hooks.js +0 -267
- package/dist/core/hooks.js.map +0 -1
- package/dist/core/metricsTracker.d.ts +0 -122
- package/dist/core/metricsTracker.d.ts.map +0 -1
- package/dist/core/metricsTracker.js.map +0 -1
|
@@ -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 } from '../ui/theme.js';
|
|
5
|
+
import { theme, formatUserPrompt } 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,8 +19,9 @@ 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 './metricsTracker.js';
|
|
23
23
|
import { listAvailablePlugins } from '../plugins/index.js';
|
|
24
|
+
import { loadMemory, listMemoryPaths, getDefaultProjectMemoryPath, getUserMemoryEditPath, } from '../core/memorySystem.js';
|
|
24
25
|
import { TerminalInputAdapter } from './terminalInputAdapter.js';
|
|
25
26
|
import { isUpdateInProgress } from './updateManager.js';
|
|
26
27
|
import { writeLock } from '../ui/writeLock.js';
|
|
@@ -34,7 +35,6 @@ const DROPDOWN_COLORS = [
|
|
|
34
35
|
theme.success,
|
|
35
36
|
theme.warning,
|
|
36
37
|
];
|
|
37
|
-
const STREAMING_SPINNER_FRAMES = ['◐', '◓', '◑', '◒'];
|
|
38
38
|
// Load MODEL_PRESETS from centralized schema
|
|
39
39
|
const MODEL_PRESETS = getModels().map((model) => ({
|
|
40
40
|
id: model.id,
|
|
@@ -49,13 +49,11 @@ const MODEL_PRESETS = getModels().map((model) => ({
|
|
|
49
49
|
const BASE_SLASH_COMMANDS = getSlashCommands().map((cmd) => ({
|
|
50
50
|
command: cmd.command,
|
|
51
51
|
description: cmd.description,
|
|
52
|
-
category: cmd.category,
|
|
53
52
|
}));
|
|
54
53
|
// Load PROVIDER_LABELS from centralized schema
|
|
55
54
|
const PROVIDER_LABELS = Object.fromEntries(getProviders().map((provider) => [provider.id, provider.label]));
|
|
56
55
|
// Allow enough time for paste detection to kick in before flushing buffered lines
|
|
57
56
|
const CONTEXT_USAGE_THRESHOLD = 0.9;
|
|
58
|
-
const CONTEXT_AUTOCOMPACT_PERCENT = Math.round(CONTEXT_USAGE_THRESHOLD * 100);
|
|
59
57
|
const CONTEXT_RECENT_MESSAGE_COUNT = 12;
|
|
60
58
|
const CONTEXT_CLEANUP_CHARS_PER_CHUNK = 6000;
|
|
61
59
|
const CONTEXT_CLEANUP_MAX_OUTPUT_TOKENS = 800;
|
|
@@ -96,12 +94,11 @@ export class InteractiveShell {
|
|
|
96
94
|
uiAdapter;
|
|
97
95
|
uiUpdates;
|
|
98
96
|
_fileChangeTracker = new FileChangeTracker(); // Reserved for future file tracking features
|
|
99
|
-
|
|
97
|
+
sessionMetrics; // Session performance tracking
|
|
100
98
|
statusSubscription = null;
|
|
101
99
|
followUpQueue = [];
|
|
102
100
|
isDrainingQueue = false;
|
|
103
101
|
activeContextWindowTokens = null;
|
|
104
|
-
latestTokenUsage = { used: null, limit: null };
|
|
105
102
|
sessionPreferences;
|
|
106
103
|
autosaveEnabled;
|
|
107
104
|
autoContinueEnabled;
|
|
@@ -132,7 +129,6 @@ export class InteractiveShell {
|
|
|
132
129
|
statusLineState = null;
|
|
133
130
|
statusMessageOverride = null;
|
|
134
131
|
promptRefreshTimer = null;
|
|
135
|
-
launchPaletteShown = false;
|
|
136
132
|
constructor(config) {
|
|
137
133
|
this.profile = config.profile;
|
|
138
134
|
this.profileLabel = config.profileLabel;
|
|
@@ -166,7 +162,6 @@ export class InteractiveShell {
|
|
|
166
162
|
this.slashCommands.push({
|
|
167
163
|
command: '/agents',
|
|
168
164
|
description: 'Select the default agent profile (applies on next launch)',
|
|
169
|
-
category: 'configuration',
|
|
170
165
|
});
|
|
171
166
|
}
|
|
172
167
|
this.customCommands = loadCustomSlashCommands();
|
|
@@ -175,21 +170,18 @@ export class InteractiveShell {
|
|
|
175
170
|
this.slashCommands.push({
|
|
176
171
|
command: custom.command,
|
|
177
172
|
description: `${custom.description} (custom)`,
|
|
178
|
-
category: custom.category ?? 'other',
|
|
179
173
|
});
|
|
180
174
|
}
|
|
181
175
|
if (!this.slashCommands.some((cmd) => cmd.command === '/exit')) {
|
|
182
176
|
this.slashCommands.push({
|
|
183
177
|
command: '/exit',
|
|
184
178
|
description: 'Quit the CLI immediately',
|
|
185
|
-
category: 'other',
|
|
186
179
|
});
|
|
187
180
|
}
|
|
188
181
|
// Add /plugins command
|
|
189
182
|
this.slashCommands.push({
|
|
190
183
|
command: '/plugins',
|
|
191
184
|
description: 'Show available and loaded plugins',
|
|
192
|
-
category: 'configuration',
|
|
193
185
|
});
|
|
194
186
|
this.statusTracker = config.statusTracker;
|
|
195
187
|
this.ui = config.ui;
|
|
@@ -224,8 +216,13 @@ export class InteractiveShell {
|
|
|
224
216
|
});
|
|
225
217
|
// Register output interceptor for cursor positioning during streaming
|
|
226
218
|
this.terminalInput.registerOutputInterceptor(display);
|
|
219
|
+
// Use flow mode: input renders inline after content for a unified layout
|
|
220
|
+
// This eliminates the blank space between banner and input area
|
|
221
|
+
this.terminalInput.setFlowMode(true);
|
|
222
|
+
// Set content end row so input renders right after startup content
|
|
223
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
227
224
|
// Initialize Alpha Zero 2 metrics tracking
|
|
228
|
-
this.
|
|
225
|
+
this.sessionMetrics = new MetricsTracker(`${this.profile}-${Date.now()}`);
|
|
229
226
|
this.setupStatusTracking();
|
|
230
227
|
this.refreshContextGauge();
|
|
231
228
|
this.terminalInput.start();
|
|
@@ -281,15 +278,9 @@ export class InteractiveShell {
|
|
|
281
278
|
await this.processInputBlock(initialPrompt);
|
|
282
279
|
return;
|
|
283
280
|
}
|
|
284
|
-
this.showLaunchCommandPalette();
|
|
285
281
|
// Ensure the terminal input is visible
|
|
286
282
|
this.terminalInput.render();
|
|
287
283
|
}
|
|
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
|
-
}
|
|
293
284
|
/**
|
|
294
285
|
* TerminalInputAdapter submit handler
|
|
295
286
|
*/
|
|
@@ -303,8 +294,9 @@ export class InteractiveShell {
|
|
|
303
294
|
this.handleInputChange('');
|
|
304
295
|
return;
|
|
305
296
|
}
|
|
306
|
-
//
|
|
307
|
-
//
|
|
297
|
+
// Enter streaming mode BEFORE logging prompt - this positions cursor correctly
|
|
298
|
+
// so content appears right after the banner, not at bottom with blank space above
|
|
299
|
+
this.terminalInput.setStreaming(true);
|
|
308
300
|
this.logUserPrompt(approved);
|
|
309
301
|
void this.processInputBlock(approved).catch((err) => {
|
|
310
302
|
display.showError(err instanceof Error ? err.message : String(err), err);
|
|
@@ -506,9 +498,10 @@ export class InteractiveShell {
|
|
|
506
498
|
// Dispose unified UI adapter
|
|
507
499
|
this.uiAdapter.dispose();
|
|
508
500
|
display.newLine();
|
|
509
|
-
console.log(theme.
|
|
510
|
-
console.log(theme.
|
|
511
|
-
console.log(theme.ui.muted('
|
|
501
|
+
console.log(theme.gradient.warm('━'.repeat(50)));
|
|
502
|
+
console.log(` ${theme.gradient.cool('✨ Goodbye!')} ${theme.ui.muted('·')} ${theme.info('support@ero.solar')}`);
|
|
503
|
+
console.log(` ${theme.ui.muted('Read:')} ${theme.accent('anthropic.com/news/disrupting-AI-espionage')}`);
|
|
504
|
+
console.log(theme.gradient.warm('━'.repeat(50)));
|
|
512
505
|
exit(0);
|
|
513
506
|
}
|
|
514
507
|
/**
|
|
@@ -678,14 +671,13 @@ export class InteractiveShell {
|
|
|
678
671
|
});
|
|
679
672
|
}
|
|
680
673
|
setProcessingStatus(detail) {
|
|
681
|
-
this.latestTokenUsage = { used: null, limit: this.latestTokenUsage.limit };
|
|
682
674
|
this.statusTracker.setBase('Working on your request', {
|
|
683
675
|
detail: this.describeStatusDetail(detail),
|
|
684
676
|
tone: 'info',
|
|
685
677
|
});
|
|
686
678
|
}
|
|
687
679
|
describeStatusDetail(detail) {
|
|
688
|
-
const parts = detail?.trim()
|
|
680
|
+
const parts = [detail?.trim() || this.describeModelDetail()];
|
|
689
681
|
const queued = this.followUpQueue.length;
|
|
690
682
|
if (queued > 0) {
|
|
691
683
|
parts.push(`${queued} follow-up${queued === 1 ? '' : 's'} queued`);
|
|
@@ -698,18 +690,12 @@ export class InteractiveShell {
|
|
|
698
690
|
}
|
|
699
691
|
refreshContextGauge() {
|
|
700
692
|
const tokens = getContextWindowTokens(this.sessionState.model);
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
if (normalizedTokens !== null) {
|
|
704
|
-
this.latestTokenUsage = {
|
|
705
|
-
used: this.latestTokenUsage.used,
|
|
706
|
-
limit: normalizedTokens,
|
|
707
|
-
};
|
|
708
|
-
}
|
|
693
|
+
this.activeContextWindowTokens =
|
|
694
|
+
typeof tokens === 'number' && Number.isFinite(tokens) ? tokens : null;
|
|
709
695
|
}
|
|
710
696
|
updateContextUsage(percentage) {
|
|
711
697
|
this.uiAdapter.updateContextUsage(percentage);
|
|
712
|
-
this.terminalInput.setContextUsage(percentage
|
|
698
|
+
this.terminalInput.setContextUsage(percentage);
|
|
713
699
|
}
|
|
714
700
|
refreshControlBar() {
|
|
715
701
|
this.terminalInput.setModeToggles({
|
|
@@ -717,8 +703,6 @@ export class InteractiveShell {
|
|
|
717
703
|
autoContinueEnabled: this.autoContinueEnabled,
|
|
718
704
|
verificationHotkey: 'alt+v',
|
|
719
705
|
autoContinueHotkey: 'alt+c',
|
|
720
|
-
thinkingModeLabel: this.thinkingMode,
|
|
721
|
-
thinkingHotkey: '/thinking',
|
|
722
706
|
});
|
|
723
707
|
this.refreshStatusLine();
|
|
724
708
|
this.terminalInput.render();
|
|
@@ -750,25 +734,6 @@ export class InteractiveShell {
|
|
|
750
734
|
// Set main status (tool execution, etc.) - shown when not overridden
|
|
751
735
|
const statusText = this.formatStatusLine(this.statusLineState);
|
|
752
736
|
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
|
-
});
|
|
772
737
|
if (forceRender) {
|
|
773
738
|
this.terminalInput.render();
|
|
774
739
|
}
|
|
@@ -828,11 +793,13 @@ export class InteractiveShell {
|
|
|
828
793
|
this.terminalInput.render();
|
|
829
794
|
}
|
|
830
795
|
/**
|
|
831
|
-
*
|
|
832
|
-
*
|
|
796
|
+
* Log the user's prompt as a visible message in the conversation.
|
|
797
|
+
* This creates a persistent log entry that remains visible during and after streaming.
|
|
833
798
|
*/
|
|
834
|
-
logUserPrompt(
|
|
835
|
-
//
|
|
799
|
+
logUserPrompt(text) {
|
|
800
|
+
// Display the user's prompt with the standard prefix
|
|
801
|
+
const prefix = formatUserPrompt();
|
|
802
|
+
display.stream(`\n${prefix}${text}\n\n`);
|
|
836
803
|
}
|
|
837
804
|
requestPromptRefresh(force = false) {
|
|
838
805
|
if (force) {
|
|
@@ -860,29 +827,9 @@ export class InteractiveShell {
|
|
|
860
827
|
this.uiUpdates.setMode('streaming');
|
|
861
828
|
this.streamingHeartbeatStart = Date.now();
|
|
862
829
|
this.streamingHeartbeatFrame = 0;
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
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
|
+
// Note: We don't start a heartbeat during streaming anymore
|
|
831
|
+
// because the UI shouldn't be rendering during streaming.
|
|
832
|
+
// The streaming status is shown in the streaming header instead.
|
|
886
833
|
}
|
|
887
834
|
stopStreamingHeartbeat() {
|
|
888
835
|
// Exit global streaming mode - allows UI to render again
|
|
@@ -898,28 +845,10 @@ export class InteractiveShell {
|
|
|
898
845
|
// Force refresh to update the input area now that streaming has ended
|
|
899
846
|
this.refreshStatusLine(true);
|
|
900
847
|
}
|
|
901
|
-
buildStreamingStatus(label
|
|
848
|
+
buildStreamingStatus(label) {
|
|
902
849
|
const detail = this.describeModelDetail();
|
|
903
|
-
const
|
|
904
|
-
|
|
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`;
|
|
850
|
+
const prefix = theme.info('●');
|
|
851
|
+
return detail ? `${prefix} ${label} ${theme.ui.muted('·')} ${detail}` : `${prefix} ${label}`;
|
|
923
852
|
}
|
|
924
853
|
refreshQueueIndicators() {
|
|
925
854
|
if (this.isProcessing) {
|
|
@@ -1167,6 +1096,17 @@ export class InteractiveShell {
|
|
|
1167
1096
|
case '/discover':
|
|
1168
1097
|
await this.discoverModelsCommand();
|
|
1169
1098
|
break;
|
|
1099
|
+
case '/memory':
|
|
1100
|
+
this.handleMemoryCommand(input);
|
|
1101
|
+
break;
|
|
1102
|
+
case '/clear':
|
|
1103
|
+
display.clear();
|
|
1104
|
+
this.cachedHistory = [];
|
|
1105
|
+
display.showInfo('Conversation cleared.');
|
|
1106
|
+
break;
|
|
1107
|
+
case '/help':
|
|
1108
|
+
this.showHelp();
|
|
1109
|
+
break;
|
|
1170
1110
|
default:
|
|
1171
1111
|
if (!(await this.tryCustomSlashCommand(command, input))) {
|
|
1172
1112
|
display.showWarning(`Unknown command "${command}".`);
|
|
@@ -1475,6 +1415,99 @@ export class InteractiveShell {
|
|
|
1475
1415
|
// Display keyboard shortcuts help (Claude Code style)
|
|
1476
1416
|
display.showSystemMessage(formatShortcutsHelp());
|
|
1477
1417
|
}
|
|
1418
|
+
handleMemoryCommand(input) {
|
|
1419
|
+
const tokens = input.trim().split(/\s+/).slice(1);
|
|
1420
|
+
const action = (tokens.shift() ?? 'show').toLowerCase();
|
|
1421
|
+
switch (action) {
|
|
1422
|
+
case '':
|
|
1423
|
+
case 'show':
|
|
1424
|
+
case 'list': {
|
|
1425
|
+
this.showMemoryStatus();
|
|
1426
|
+
break;
|
|
1427
|
+
}
|
|
1428
|
+
case 'paths': {
|
|
1429
|
+
this.showMemoryPaths();
|
|
1430
|
+
break;
|
|
1431
|
+
}
|
|
1432
|
+
case 'edit': {
|
|
1433
|
+
const level = (tokens[0] ?? 'project').toLowerCase();
|
|
1434
|
+
this.openMemoryForEdit(level);
|
|
1435
|
+
break;
|
|
1436
|
+
}
|
|
1437
|
+
default:
|
|
1438
|
+
display.showWarning('Usage: /memory [show|paths|edit <user|project>]');
|
|
1439
|
+
break;
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
showMemoryStatus() {
|
|
1443
|
+
const memory = loadMemory(this.workingDir);
|
|
1444
|
+
const lines = [];
|
|
1445
|
+
lines.push(theme.bold('Persistent Memory'));
|
|
1446
|
+
lines.push('');
|
|
1447
|
+
if (memory.sources.length === 0) {
|
|
1448
|
+
lines.push(theme.secondary('No memory files found.'));
|
|
1449
|
+
lines.push('');
|
|
1450
|
+
lines.push(`Create ${theme.info('EROSOLAR.md')} in your project to add persistent context.`);
|
|
1451
|
+
lines.push(`Use ${theme.info('/memory edit project')} to create one.`);
|
|
1452
|
+
}
|
|
1453
|
+
else {
|
|
1454
|
+
for (const source of memory.sources) {
|
|
1455
|
+
const levelLabel = source.level === 'enterprise' ? 'Enterprise' :
|
|
1456
|
+
source.level === 'user' ? 'User' : 'Project';
|
|
1457
|
+
const preview = source.content.slice(0, 200).replace(/\n/g, ' ').trim();
|
|
1458
|
+
const truncated = source.content.length > 200 ? '...' : '';
|
|
1459
|
+
lines.push(`${theme.success('●')} ${theme.bold(levelLabel)}: ${source.path}`);
|
|
1460
|
+
lines.push(` ${theme.dim(preview + truncated)}`);
|
|
1461
|
+
lines.push('');
|
|
1462
|
+
}
|
|
1463
|
+
if (memory.importedPaths.length > memory.sources.length) {
|
|
1464
|
+
lines.push(theme.secondary(`Imported ${memory.importedPaths.length - memory.sources.length} additional files via @imports.`));
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
display.showSystemMessage(lines.join('\n'));
|
|
1468
|
+
}
|
|
1469
|
+
showMemoryPaths() {
|
|
1470
|
+
const paths = listMemoryPaths(this.workingDir);
|
|
1471
|
+
const lines = [];
|
|
1472
|
+
lines.push(theme.bold('Memory File Locations'));
|
|
1473
|
+
lines.push('');
|
|
1474
|
+
for (const { level, path, exists } of paths) {
|
|
1475
|
+
const icon = exists ? theme.success('✓') : theme.dim('○');
|
|
1476
|
+
const levelLabel = level.charAt(0).toUpperCase() + level.slice(1);
|
|
1477
|
+
lines.push(`${icon} ${levelLabel}: ${path}`);
|
|
1478
|
+
}
|
|
1479
|
+
lines.push('');
|
|
1480
|
+
lines.push(theme.secondary('Create any of these files to add persistent memory.'));
|
|
1481
|
+
lines.push(theme.secondary('Use @path/to/file.md syntax to import other files.'));
|
|
1482
|
+
display.showSystemMessage(lines.join('\n'));
|
|
1483
|
+
}
|
|
1484
|
+
openMemoryForEdit(level) {
|
|
1485
|
+
let targetPath;
|
|
1486
|
+
if (level === 'user') {
|
|
1487
|
+
targetPath = getUserMemoryEditPath();
|
|
1488
|
+
}
|
|
1489
|
+
else if (level === 'project') {
|
|
1490
|
+
targetPath = getDefaultProjectMemoryPath(this.workingDir);
|
|
1491
|
+
}
|
|
1492
|
+
else {
|
|
1493
|
+
display.showWarning('Specify "user" or "project" to edit. Enterprise memory is read-only.');
|
|
1494
|
+
return;
|
|
1495
|
+
}
|
|
1496
|
+
display.showInfo(`Memory file: ${targetPath}`);
|
|
1497
|
+
display.showInfo('Create or edit this file to add persistent context for the AI.');
|
|
1498
|
+
display.showInfo('');
|
|
1499
|
+
display.showInfo('Example EROSOLAR.md content:');
|
|
1500
|
+
display.showInfo('');
|
|
1501
|
+
display.showInfo(theme.dim(`# Project Guidelines
|
|
1502
|
+
|
|
1503
|
+
When working in this codebase:
|
|
1504
|
+
- Follow TypeScript strict mode conventions
|
|
1505
|
+
- Use functional patterns where appropriate
|
|
1506
|
+
- Run tests before committing
|
|
1507
|
+
|
|
1508
|
+
@./docs/coding-standards.md
|
|
1509
|
+
`));
|
|
1510
|
+
}
|
|
1478
1511
|
showFileChangeSummary() {
|
|
1479
1512
|
const summary = this._fileChangeTracker.getSummary();
|
|
1480
1513
|
const changes = this._fileChangeTracker.getAllChanges();
|
|
@@ -1517,11 +1550,11 @@ export class InteractiveShell {
|
|
|
1517
1550
|
display.showSystemMessage(lines.join('\n'));
|
|
1518
1551
|
}
|
|
1519
1552
|
showAlphaZeroMetrics() {
|
|
1520
|
-
const summary = this.
|
|
1553
|
+
const summary = this.sessionMetrics.getPerformanceSummary();
|
|
1521
1554
|
display.showSystemMessage(summary);
|
|
1522
1555
|
}
|
|
1523
1556
|
showImprovementSuggestions() {
|
|
1524
|
-
const suggestions = this.
|
|
1557
|
+
const suggestions = this.sessionMetrics.getImprovementSuggestions();
|
|
1525
1558
|
if (suggestions.length === 0) {
|
|
1526
1559
|
display.showInfo('No improvement suggestions at this time. Keep using the shell to generate metrics!');
|
|
1527
1560
|
return;
|
|
@@ -1567,9 +1600,7 @@ export class InteractiveShell {
|
|
|
1567
1600
|
}
|
|
1568
1601
|
}
|
|
1569
1602
|
lines.push(theme.secondary('CLI Flags:'));
|
|
1570
|
-
lines.push(' --alpha-zero Enable Alpha Zero 2 RL framework');
|
|
1571
1603
|
lines.push(' --coding Enable enhanced coding tools');
|
|
1572
|
-
lines.push(' --security Enable security research tools');
|
|
1573
1604
|
lines.push(' --all-plugins Enable all optional plugins');
|
|
1574
1605
|
display.showSystemMessage(lines.join('\n'));
|
|
1575
1606
|
}
|
|
@@ -1813,75 +1844,6 @@ export class InteractiveShell {
|
|
|
1813
1844
|
}
|
|
1814
1845
|
return `${warning.label}: ${warning.reason}.`;
|
|
1815
1846
|
}
|
|
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
|
-
}
|
|
1885
1847
|
buildSlashCommandList(header) {
|
|
1886
1848
|
const lines = [theme.gradient.primary(header), ''];
|
|
1887
1849
|
for (const command of this.slashCommands) {
|
|
@@ -2350,7 +2312,7 @@ export class InteractiveShell {
|
|
|
2350
2312
|
this.autosaveIfEnabled();
|
|
2351
2313
|
// Track metrics with Alpha Zero 2
|
|
2352
2314
|
const elapsedMs = Date.now() - requestStartTime;
|
|
2353
|
-
this.
|
|
2315
|
+
this.sessionMetrics.recordMessage(elapsedMs);
|
|
2354
2316
|
if (!responseText?.trim()) {
|
|
2355
2317
|
display.showWarning('The provider returned an empty response. Check your API key/provider selection or retry the prompt.');
|
|
2356
2318
|
}
|
|
@@ -2368,10 +2330,14 @@ export class InteractiveShell {
|
|
|
2368
2330
|
this.stopStreamingHeartbeat();
|
|
2369
2331
|
this.isProcessing = false;
|
|
2370
2332
|
this.terminalInput.setStreaming(false);
|
|
2333
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2371
2334
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2372
2335
|
this.setIdleStatus();
|
|
2373
2336
|
display.newLine();
|
|
2374
2337
|
this.updateStatusMessage(null);
|
|
2338
|
+
// Claude Code style: Show unified status bar before prompt
|
|
2339
|
+
// This creates consistent UI between startup and post-streaming
|
|
2340
|
+
this.showUnifiedStatusBar();
|
|
2375
2341
|
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
2376
2342
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
2377
2343
|
// Claude Code style: New prompt naturally appears at bottom
|
|
@@ -2448,14 +2414,13 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
|
|
|
2448
2414
|
try {
|
|
2449
2415
|
// Send the request and capture the response (streaming disabled)
|
|
2450
2416
|
display.showThinking('Responding...');
|
|
2451
|
-
this.refreshStatusLine(true);
|
|
2452
2417
|
const response = await agent.send(currentPrompt, true);
|
|
2453
2418
|
await this.awaitPendingCleanup();
|
|
2454
2419
|
this.captureHistorySnapshot();
|
|
2455
2420
|
this.autosaveIfEnabled();
|
|
2456
2421
|
// Track metrics
|
|
2457
2422
|
const elapsedMs = Date.now() - overallStartTime;
|
|
2458
|
-
this.
|
|
2423
|
+
this.sessionMetrics.recordMessage(elapsedMs);
|
|
2459
2424
|
if (!response?.trim()) {
|
|
2460
2425
|
display.showWarning('Model returned an empty response. Retrying this iteration...');
|
|
2461
2426
|
consecutiveNoProgress++;
|
|
@@ -2592,6 +2557,7 @@ What's the next action?`;
|
|
|
2592
2557
|
this.stopStreamingHeartbeat();
|
|
2593
2558
|
this.isProcessing = false;
|
|
2594
2559
|
this.terminalInput.setStreaming(false);
|
|
2560
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2595
2561
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2596
2562
|
this.setIdleStatus();
|
|
2597
2563
|
this.updateStatusMessage(null);
|
|
@@ -2948,10 +2914,8 @@ What's the next action?`;
|
|
|
2948
2914
|
try {
|
|
2949
2915
|
// Send the error to the agent for fixing
|
|
2950
2916
|
display.showThinking('Analyzing build errors');
|
|
2951
|
-
this.refreshStatusLine(true);
|
|
2952
2917
|
const response = await this.agent.send(prompt, true);
|
|
2953
2918
|
display.stopThinking();
|
|
2954
|
-
this.refreshStatusLine(true);
|
|
2955
2919
|
if (response) {
|
|
2956
2920
|
display.showAssistantMessage(response, { isFinal: true });
|
|
2957
2921
|
}
|
|
@@ -3001,16 +2965,18 @@ What's the next action?`;
|
|
|
3001
2965
|
display.showAssistantMessage(finalContent, enriched);
|
|
3002
2966
|
}
|
|
3003
2967
|
}
|
|
3004
|
-
//
|
|
2968
|
+
// Show status line at end (Claude Code style: "• Context X% used • Ready for prompts (2s)")
|
|
3005
2969
|
display.stopThinking();
|
|
3006
|
-
//
|
|
2970
|
+
// Calculate context usage
|
|
2971
|
+
let contextInfo;
|
|
3007
2972
|
if (enriched.contextWindowTokens && metadata.usage) {
|
|
3008
2973
|
const total = this.totalTokens(metadata.usage);
|
|
3009
2974
|
if (total && total > 0) {
|
|
3010
2975
|
const percentage = Math.round((total / enriched.contextWindowTokens) * 100);
|
|
3011
|
-
|
|
2976
|
+
contextInfo = { percentage, tokens: total };
|
|
3012
2977
|
}
|
|
3013
2978
|
}
|
|
2979
|
+
display.showStatusLine('Ready for prompts', enriched.elapsedMs, contextInfo);
|
|
3014
2980
|
// Auto-verify changes: build first (catches type errors), then tests
|
|
3015
2981
|
void this.enforceAutoBuild('final-response');
|
|
3016
2982
|
void this.enforceAutoTests('final-response');
|
|
@@ -3080,6 +3046,7 @@ What's the next action?`;
|
|
|
3080
3046
|
this.stopStreamingHeartbeat();
|
|
3081
3047
|
this.updateStatusMessage(null);
|
|
3082
3048
|
this.terminalInput.setStreaming(false);
|
|
3049
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3083
3050
|
this.terminalInput.render();
|
|
3084
3051
|
},
|
|
3085
3052
|
onVerificationNeeded: () => {
|
|
@@ -3116,6 +3083,7 @@ What's the next action?`;
|
|
|
3116
3083
|
resetChatBoxAfterModelSwap() {
|
|
3117
3084
|
this.updateStatusMessage(null);
|
|
3118
3085
|
this.terminalInput.setStreaming(false);
|
|
3086
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3119
3087
|
this.terminalInput.render();
|
|
3120
3088
|
this.ensureReadlineReady();
|
|
3121
3089
|
}
|
|
@@ -3180,14 +3148,9 @@ What's the next action?`;
|
|
|
3180
3148
|
return null;
|
|
3181
3149
|
}
|
|
3182
3150
|
const usageRatio = total / windowTokens;
|
|
3183
|
-
this.latestTokenUsage = {
|
|
3184
|
-
used: total,
|
|
3185
|
-
limit: windowTokens,
|
|
3186
|
-
};
|
|
3187
3151
|
// Always update context usage in the UI
|
|
3188
3152
|
const percentUsed = Math.round(usageRatio * 100);
|
|
3189
3153
|
this.updateContextUsage(percentUsed);
|
|
3190
|
-
this.refreshStatusLine(true);
|
|
3191
3154
|
if (usageRatio < CONTEXT_USAGE_THRESHOLD) {
|
|
3192
3155
|
return null;
|
|
3193
3156
|
}
|