erosolar-cli 1.7.333 → 1.7.334
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 -24
- 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/bin/erosolar.js +21 -5
- package/dist/bin/erosolar.js.map +1 -1
- package/dist/capabilities/agentSpawningCapability.d.ts.map +1 -1
- package/dist/capabilities/agentSpawningCapability.js +31 -56
- package/dist/capabilities/agentSpawningCapability.js.map +1 -1
- 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/agent.d.ts +2 -2
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js.map +1 -1
- 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 +1 -22
- 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/headless/headlessApp.d.ts.map +1 -1
- package/dist/headless/headlessApp.js +0 -21
- package/dist/headless/headlessApp.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/runtime/agentSession.d.ts +2 -2
- package/dist/runtime/agentSession.d.ts.map +1 -1
- package/dist/runtime/agentSession.js +2 -2
- package/dist/runtime/agentSession.js.map +1 -1
- 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 -16
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +166 -235
- 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 +9 -40
- 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 +118 -149
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +532 -689
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/terminalInputAdapter.d.ts +21 -79
- package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
- package/dist/shell/terminalInputAdapter.js +30 -99
- package/dist/shell/terminalInputAdapter.js.map +1 -1
- package/dist/subagents/taskRunner.d.ts +1 -7
- package/dist/subagents/taskRunner.d.ts.map +1 -1
- package/dist/subagents/taskRunner.js +47 -180
- package/dist/subagents/taskRunner.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 +45 -24
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +259 -140
- 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 +4 -4
- 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
- package/dist/core/securityAssessment.d.ts +0 -91
- package/dist/core/securityAssessment.d.ts.map +0 -1
- package/dist/core/securityAssessment.js +0 -580
- package/dist/core/securityAssessment.js.map +0 -1
- package/dist/core/verification.d.ts +0 -137
- package/dist/core/verification.d.ts.map +0 -1
- package/dist/core/verification.js +0 -323
- package/dist/core/verification.js.map +0 -1
- package/dist/subagents/agentConfig.d.ts +0 -27
- package/dist/subagents/agentConfig.d.ts.map +0 -1
- package/dist/subagents/agentConfig.js +0 -89
- package/dist/subagents/agentConfig.js.map +0 -1
- package/dist/subagents/agentRegistry.d.ts +0 -33
- package/dist/subagents/agentRegistry.d.ts.map +0 -1
- package/dist/subagents/agentRegistry.js +0 -162
- package/dist/subagents/agentRegistry.js.map +0 -1
- package/dist/utils/frontmatter.d.ts +0 -10
- package/dist/utils/frontmatter.d.ts.map +0 -1
- package/dist/utils/frontmatter.js +0 -78
- package/dist/utils/frontmatter.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,11 +19,11 @@ 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
|
-
import {
|
|
26
|
-
import { isUpdateInProgress, maybeOfferCliUpdate } from './updateManager.js';
|
|
26
|
+
import { isUpdateInProgress } from './updateManager.js';
|
|
27
27
|
import { writeLock } from '../ui/writeLock.js';
|
|
28
28
|
import { enterStreamingMode, exitStreamingMode } from '../ui/globalWriteLock.js';
|
|
29
29
|
const execAsync = promisify(exec);
|
|
@@ -35,7 +35,6 @@ const DROPDOWN_COLORS = [
|
|
|
35
35
|
theme.success,
|
|
36
36
|
theme.warning,
|
|
37
37
|
];
|
|
38
|
-
const STREAMING_SPINNER_FRAMES = ['◐', '◓', '◑', '◒'];
|
|
39
38
|
// Load MODEL_PRESETS from centralized schema
|
|
40
39
|
const MODEL_PRESETS = getModels().map((model) => ({
|
|
41
40
|
id: model.id,
|
|
@@ -50,13 +49,11 @@ const MODEL_PRESETS = getModels().map((model) => ({
|
|
|
50
49
|
const BASE_SLASH_COMMANDS = getSlashCommands().map((cmd) => ({
|
|
51
50
|
command: cmd.command,
|
|
52
51
|
description: cmd.description,
|
|
53
|
-
category: cmd.category,
|
|
54
52
|
}));
|
|
55
53
|
// Load PROVIDER_LABELS from centralized schema
|
|
56
54
|
const PROVIDER_LABELS = Object.fromEntries(getProviders().map((provider) => [provider.id, provider.label]));
|
|
57
55
|
// Allow enough time for paste detection to kick in before flushing buffered lines
|
|
58
56
|
const CONTEXT_USAGE_THRESHOLD = 0.9;
|
|
59
|
-
const CONTEXT_AUTOCOMPACT_PERCENT = Math.round(CONTEXT_USAGE_THRESHOLD * 100);
|
|
60
57
|
const CONTEXT_RECENT_MESSAGE_COUNT = 12;
|
|
61
58
|
const CONTEXT_CLEANUP_CHARS_PER_CHUNK = 6000;
|
|
62
59
|
const CONTEXT_CLEANUP_MAX_OUTPUT_TOKENS = 800;
|
|
@@ -97,12 +94,11 @@ export class InteractiveShell {
|
|
|
97
94
|
uiAdapter;
|
|
98
95
|
uiUpdates;
|
|
99
96
|
_fileChangeTracker = new FileChangeTracker(); // Reserved for future file tracking features
|
|
100
|
-
|
|
97
|
+
sessionMetrics; // Session performance tracking
|
|
101
98
|
statusSubscription = null;
|
|
102
99
|
followUpQueue = [];
|
|
103
100
|
isDrainingQueue = false;
|
|
104
101
|
activeContextWindowTokens = null;
|
|
105
|
-
latestTokenUsage = { used: null, limit: null };
|
|
106
102
|
sessionPreferences;
|
|
107
103
|
autosaveEnabled;
|
|
108
104
|
autoContinueEnabled;
|
|
@@ -133,8 +129,6 @@ export class InteractiveShell {
|
|
|
133
129
|
statusLineState = null;
|
|
134
130
|
statusMessageOverride = null;
|
|
135
131
|
promptRefreshTimer = null;
|
|
136
|
-
launchPaletteShown = false;
|
|
137
|
-
version;
|
|
138
132
|
constructor(config) {
|
|
139
133
|
this.profile = config.profile;
|
|
140
134
|
this.profileLabel = config.profileLabel;
|
|
@@ -148,7 +142,6 @@ export class InteractiveShell {
|
|
|
148
142
|
this.autoContinueEnabled = this.sessionPreferences.autoContinue;
|
|
149
143
|
this.sessionRestoreConfig = config.sessionRestore ?? { mode: 'none' };
|
|
150
144
|
this._enabledPlugins = config.enabledPlugins ?? [];
|
|
151
|
-
this.version = config.version ?? '0.0.0';
|
|
152
145
|
this.initializeSessionHistory();
|
|
153
146
|
this.sessionState = {
|
|
154
147
|
provider: config.initialModel.provider,
|
|
@@ -169,7 +162,6 @@ export class InteractiveShell {
|
|
|
169
162
|
this.slashCommands.push({
|
|
170
163
|
command: '/agents',
|
|
171
164
|
description: 'Select the default agent profile (applies on next launch)',
|
|
172
|
-
category: 'configuration',
|
|
173
165
|
});
|
|
174
166
|
}
|
|
175
167
|
this.customCommands = loadCustomSlashCommands();
|
|
@@ -178,21 +170,18 @@ export class InteractiveShell {
|
|
|
178
170
|
this.slashCommands.push({
|
|
179
171
|
command: custom.command,
|
|
180
172
|
description: `${custom.description} (custom)`,
|
|
181
|
-
category: custom.category ?? 'other',
|
|
182
173
|
});
|
|
183
174
|
}
|
|
184
175
|
if (!this.slashCommands.some((cmd) => cmd.command === '/exit')) {
|
|
185
176
|
this.slashCommands.push({
|
|
186
177
|
command: '/exit',
|
|
187
178
|
description: 'Quit the CLI immediately',
|
|
188
|
-
category: 'other',
|
|
189
179
|
});
|
|
190
180
|
}
|
|
191
181
|
// Add /plugins command
|
|
192
182
|
this.slashCommands.push({
|
|
193
183
|
command: '/plugins',
|
|
194
184
|
description: 'Show available and loaded plugins',
|
|
195
|
-
category: 'configuration',
|
|
196
185
|
});
|
|
197
186
|
this.statusTracker = config.statusTracker;
|
|
198
187
|
this.ui = config.ui;
|
|
@@ -225,21 +214,19 @@ export class InteractiveShell {
|
|
|
225
214
|
onToggleVerify: () => this.toggleVerificationMode(),
|
|
226
215
|
onToggleAutoContinue: () => this.toggleAutoContinueMode(),
|
|
227
216
|
});
|
|
217
|
+
// Register output interceptor for cursor positioning during streaming
|
|
218
|
+
this.terminalInput.registerOutputInterceptor(display);
|
|
219
|
+
// Set banner content to be written during unified UI initialization
|
|
220
|
+
this.terminalInput.setBannerContent(display.getBannerContent());
|
|
221
|
+
// Initialize unified UI - clears screen, sets up scroll region, writes banner,
|
|
222
|
+
// and renders input area at bottom
|
|
223
|
+
this.terminalInput.initializeUnifiedUI();
|
|
228
224
|
// Initialize Alpha Zero 2 metrics tracking
|
|
229
|
-
this.
|
|
225
|
+
this.sessionMetrics = new MetricsTracker(`${this.profile}-${Date.now()}`);
|
|
230
226
|
this.setupStatusTracking();
|
|
231
227
|
this.refreshContextGauge();
|
|
232
|
-
// Start terminal input (sets up handlers)
|
|
233
228
|
this.terminalInput.start();
|
|
234
|
-
// Enter alternate screen buffer for clean UI control
|
|
235
|
-
// This preserves user's terminal history when they exit
|
|
236
|
-
this.terminalInput.enterAlternateScreen();
|
|
237
|
-
// Stream banner first - this sets up scroll region dynamically
|
|
238
|
-
const banner = this.buildBanner();
|
|
239
|
-
this.terminalInput.streamContent(banner + '\n\n');
|
|
240
|
-
// Render chat box after banner is streamed
|
|
241
229
|
this.refreshControlBar();
|
|
242
|
-
this.terminalInput.forceRender();
|
|
243
230
|
this.rebuildAgent();
|
|
244
231
|
this.setupHandlers();
|
|
245
232
|
this.refreshBannerSessionInfo();
|
|
@@ -286,24 +273,14 @@ export class InteractiveShell {
|
|
|
286
273
|
this.sessionResumeNotice = null;
|
|
287
274
|
}
|
|
288
275
|
async start(initialPrompt) {
|
|
289
|
-
// Check for updates in background (non-blocking)
|
|
290
|
-
if (this.version) {
|
|
291
|
-
void maybeOfferCliUpdate(this.version);
|
|
292
|
-
}
|
|
293
276
|
if (initialPrompt) {
|
|
294
277
|
this.logUserPrompt(initialPrompt);
|
|
295
278
|
await this.processInputBlock(initialPrompt);
|
|
296
279
|
return;
|
|
297
280
|
}
|
|
298
|
-
this.showLaunchCommandPalette();
|
|
299
281
|
// Ensure the terminal input is visible
|
|
300
282
|
this.terminalInput.render();
|
|
301
283
|
}
|
|
302
|
-
showLaunchCommandPalette() {
|
|
303
|
-
// Disabled: Quick commands palette takes up too much space
|
|
304
|
-
// Users can type /help to see available commands
|
|
305
|
-
this.launchPaletteShown = true;
|
|
306
|
-
}
|
|
307
284
|
/**
|
|
308
285
|
* TerminalInputAdapter submit handler
|
|
309
286
|
*/
|
|
@@ -317,8 +294,9 @@ export class InteractiveShell {
|
|
|
317
294
|
this.handleInputChange('');
|
|
318
295
|
return;
|
|
319
296
|
}
|
|
320
|
-
//
|
|
321
|
-
//
|
|
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);
|
|
322
300
|
this.logUserPrompt(approved);
|
|
323
301
|
void this.processInputBlock(approved).catch((err) => {
|
|
324
302
|
display.showError(err instanceof Error ? err.message : String(err), err);
|
|
@@ -519,12 +497,12 @@ export class InteractiveShell {
|
|
|
519
497
|
this.terminalInput.dispose();
|
|
520
498
|
// Dispose unified UI adapter
|
|
521
499
|
this.uiAdapter.dispose();
|
|
522
|
-
// Exit alternate screen buffer before printing goodbye
|
|
523
|
-
this.terminalInput.exitAlternateScreen();
|
|
524
500
|
display.newLine();
|
|
525
|
-
|
|
526
|
-
console.log(theme.
|
|
527
|
-
console.log(theme.ui.muted('
|
|
501
|
+
const version = display.getVersion() || 'unknown';
|
|
502
|
+
console.log(theme.gradient.warm('━'.repeat(50)));
|
|
503
|
+
console.log(` ${theme.gradient.cool('✨ Goodbye!')} ${theme.ui.muted('·')} ${theme.info(`erosolar-cli v${version}`)}`);
|
|
504
|
+
console.log(` ${theme.ui.muted('Support:')} ${theme.info('support@ero.solar')}`);
|
|
505
|
+
console.log(theme.gradient.warm('━'.repeat(50)));
|
|
528
506
|
exit(0);
|
|
529
507
|
}
|
|
530
508
|
/**
|
|
@@ -694,14 +672,13 @@ export class InteractiveShell {
|
|
|
694
672
|
});
|
|
695
673
|
}
|
|
696
674
|
setProcessingStatus(detail) {
|
|
697
|
-
this.latestTokenUsage = { used: null, limit: this.latestTokenUsage.limit };
|
|
698
675
|
this.statusTracker.setBase('Working on your request', {
|
|
699
676
|
detail: this.describeStatusDetail(detail),
|
|
700
677
|
tone: 'info',
|
|
701
678
|
});
|
|
702
679
|
}
|
|
703
680
|
describeStatusDetail(detail) {
|
|
704
|
-
const parts = detail?.trim()
|
|
681
|
+
const parts = [detail?.trim() || this.describeModelDetail()];
|
|
705
682
|
const queued = this.followUpQueue.length;
|
|
706
683
|
if (queued > 0) {
|
|
707
684
|
parts.push(`${queued} follow-up${queued === 1 ? '' : 's'} queued`);
|
|
@@ -714,18 +691,12 @@ export class InteractiveShell {
|
|
|
714
691
|
}
|
|
715
692
|
refreshContextGauge() {
|
|
716
693
|
const tokens = getContextWindowTokens(this.sessionState.model);
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
if (normalizedTokens !== null) {
|
|
720
|
-
this.latestTokenUsage = {
|
|
721
|
-
used: this.latestTokenUsage.used,
|
|
722
|
-
limit: normalizedTokens,
|
|
723
|
-
};
|
|
724
|
-
}
|
|
694
|
+
this.activeContextWindowTokens =
|
|
695
|
+
typeof tokens === 'number' && Number.isFinite(tokens) ? tokens : null;
|
|
725
696
|
}
|
|
726
697
|
updateContextUsage(percentage) {
|
|
727
698
|
this.uiAdapter.updateContextUsage(percentage);
|
|
728
|
-
this.terminalInput.setContextUsage(percentage
|
|
699
|
+
this.terminalInput.setContextUsage(percentage);
|
|
729
700
|
}
|
|
730
701
|
refreshControlBar() {
|
|
731
702
|
this.terminalInput.setModeToggles({
|
|
@@ -733,9 +704,9 @@ export class InteractiveShell {
|
|
|
733
704
|
autoContinueEnabled: this.autoContinueEnabled,
|
|
734
705
|
verificationHotkey: 'alt+v',
|
|
735
706
|
autoContinueHotkey: 'alt+c',
|
|
736
|
-
thinkingModeLabel: this.thinkingMode,
|
|
737
|
-
thinkingHotkey: '/thinking',
|
|
738
707
|
});
|
|
708
|
+
// Update persistent model info display
|
|
709
|
+
this.terminalInput.setModelInfo(this.describeModelDetail());
|
|
739
710
|
this.refreshStatusLine();
|
|
740
711
|
this.terminalInput.render();
|
|
741
712
|
}
|
|
@@ -766,25 +737,6 @@ export class InteractiveShell {
|
|
|
766
737
|
// Set main status (tool execution, etc.) - shown when not overridden
|
|
767
738
|
const statusText = this.formatStatusLine(this.statusLineState);
|
|
768
739
|
this.terminalInput.setStatusMessage(statusText);
|
|
769
|
-
// Surface meta header (elapsed + context usage) above the divider
|
|
770
|
-
const elapsedSeconds = this.statusLineState
|
|
771
|
-
? Math.max(0, Math.floor((Date.now() - this.statusLineState.startedAt) / 1000))
|
|
772
|
-
: null;
|
|
773
|
-
const thinkingMs = display.isSpinnerActive() ? display.getThinkingElapsedMs() : null;
|
|
774
|
-
const tokensUsed = this.latestTokenUsage.used;
|
|
775
|
-
const tokenLimit = this.latestTokenUsage.limit ?? this.activeContextWindowTokens;
|
|
776
|
-
this.terminalInput.setMetaStatus({
|
|
777
|
-
elapsedSeconds,
|
|
778
|
-
tokensUsed,
|
|
779
|
-
tokenLimit,
|
|
780
|
-
thinkingMs,
|
|
781
|
-
thinkingHasContent: display.isSpinnerActive(),
|
|
782
|
-
});
|
|
783
|
-
// Keep model/provider visible in the controls bar
|
|
784
|
-
this.terminalInput.setModelContext({
|
|
785
|
-
model: this.sessionState.model,
|
|
786
|
-
provider: this.providerLabel(this.sessionState.provider),
|
|
787
|
-
});
|
|
788
740
|
if (forceRender) {
|
|
789
741
|
this.terminalInput.render();
|
|
790
742
|
}
|
|
@@ -844,14 +796,15 @@ export class InteractiveShell {
|
|
|
844
796
|
this.terminalInput.render();
|
|
845
797
|
}
|
|
846
798
|
/**
|
|
847
|
-
* Log user prompt
|
|
799
|
+
* Log the user's prompt as a visible message in the conversation.
|
|
800
|
+
* This creates a persistent log entry that remains visible during and after streaming.
|
|
848
801
|
*/
|
|
849
802
|
logUserPrompt(text) {
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
this.terminalInput.
|
|
803
|
+
// Display the user's prompt with the standard prefix
|
|
804
|
+
const prefix = formatUserPrompt();
|
|
805
|
+
display.stream(`\n${prefix}${text}\n\n`);
|
|
806
|
+
// Update content end row so chat box renders below the user prompt
|
|
807
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
855
808
|
}
|
|
856
809
|
requestPromptRefresh(force = false) {
|
|
857
810
|
if (force) {
|
|
@@ -876,40 +829,16 @@ export class InteractiveShell {
|
|
|
876
829
|
this.stopStreamingHeartbeat();
|
|
877
830
|
// Enter global streaming mode - blocks all non-streaming UI output
|
|
878
831
|
enterStreamingMode();
|
|
879
|
-
// Set up scroll region for streaming content
|
|
880
|
-
this.terminalInput.enterStreamingScrollRegion();
|
|
881
832
|
this.uiUpdates.setMode('streaming');
|
|
882
833
|
this.streamingHeartbeatStart = Date.now();
|
|
883
834
|
this.streamingHeartbeatFrame = 0;
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
this.refreshStatusLine(true);
|
|
888
|
-
// Periodically refresh the pinned input/status region while streaming so
|
|
889
|
-
// elapsed time remains visible without interrupting the scroll region.
|
|
890
|
-
this.uiUpdates.startHeartbeat('streaming', {
|
|
891
|
-
intervalMs: 1000,
|
|
892
|
-
lane: 'heartbeat',
|
|
893
|
-
mode: ['streaming', 'processing'],
|
|
894
|
-
coalesceKey: 'streaming:heartbeat',
|
|
895
|
-
run: () => {
|
|
896
|
-
const elapsedSeconds = this.streamingHeartbeatStart
|
|
897
|
-
? Math.max(0, Math.floor((Date.now() - this.streamingHeartbeatStart) / 1000))
|
|
898
|
-
: 0;
|
|
899
|
-
this.streamingHeartbeatFrame =
|
|
900
|
-
(this.streamingHeartbeatFrame + 1) % STREAMING_SPINNER_FRAMES.length;
|
|
901
|
-
const frame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
|
|
902
|
-
this.streamingStatusLabel = this.buildStreamingStatus(`${frame} ${label}`, elapsedSeconds);
|
|
903
|
-
display.updateStreamingStatus(this.streamingStatusLabel);
|
|
904
|
-
this.refreshStatusLine(true);
|
|
905
|
-
},
|
|
906
|
-
});
|
|
835
|
+
// Note: We don't start a heartbeat during streaming anymore
|
|
836
|
+
// because the UI shouldn't be rendering during streaming.
|
|
837
|
+
// The streaming status is shown in the streaming header instead.
|
|
907
838
|
}
|
|
908
839
|
stopStreamingHeartbeat() {
|
|
909
840
|
// Exit global streaming mode - allows UI to render again
|
|
910
841
|
exitStreamingMode();
|
|
911
|
-
// Exit scroll region mode
|
|
912
|
-
this.terminalInput.exitStreamingScrollRegion();
|
|
913
842
|
this.uiUpdates.stopHeartbeat('streaming');
|
|
914
843
|
this.streamingHeartbeatStart = null;
|
|
915
844
|
this.streamingHeartbeatFrame = 0;
|
|
@@ -921,28 +850,10 @@ export class InteractiveShell {
|
|
|
921
850
|
// Force refresh to update the input area now that streaming has ended
|
|
922
851
|
this.refreshStatusLine(true);
|
|
923
852
|
}
|
|
924
|
-
buildStreamingStatus(label
|
|
853
|
+
buildStreamingStatus(label) {
|
|
925
854
|
const detail = this.describeModelDetail();
|
|
926
|
-
const
|
|
927
|
-
|
|
928
|
-
: null;
|
|
929
|
-
const prefix = theme.info('⏺');
|
|
930
|
-
const parts = [label];
|
|
931
|
-
if (detail) {
|
|
932
|
-
parts.push(theme.ui.muted('·'), detail);
|
|
933
|
-
}
|
|
934
|
-
if (elapsedLabel) {
|
|
935
|
-
parts.push(theme.ui.muted('·'), elapsedLabel);
|
|
936
|
-
}
|
|
937
|
-
return `${prefix} ${parts.join(' ')}`.trim();
|
|
938
|
-
}
|
|
939
|
-
formatElapsedShort(seconds) {
|
|
940
|
-
if (seconds < 60) {
|
|
941
|
-
return `${seconds}s`;
|
|
942
|
-
}
|
|
943
|
-
const minutes = Math.floor(seconds / 60);
|
|
944
|
-
const remaining = seconds % 60;
|
|
945
|
-
return remaining > 0 ? `${minutes}m ${remaining}s` : `${minutes}m`;
|
|
855
|
+
const prefix = theme.info('●');
|
|
856
|
+
return detail ? `${prefix} ${label} ${theme.ui.muted('·')} ${detail}` : `${prefix} ${label}`;
|
|
946
857
|
}
|
|
947
858
|
refreshQueueIndicators() {
|
|
948
859
|
if (this.isProcessing) {
|
|
@@ -1190,6 +1101,17 @@ export class InteractiveShell {
|
|
|
1190
1101
|
case '/discover':
|
|
1191
1102
|
await this.discoverModelsCommand();
|
|
1192
1103
|
break;
|
|
1104
|
+
case '/memory':
|
|
1105
|
+
this.handleMemoryCommand(input);
|
|
1106
|
+
break;
|
|
1107
|
+
case '/clear':
|
|
1108
|
+
display.clear();
|
|
1109
|
+
this.cachedHistory = [];
|
|
1110
|
+
display.showInfo('Conversation cleared.');
|
|
1111
|
+
break;
|
|
1112
|
+
case '/help':
|
|
1113
|
+
this.showHelp();
|
|
1114
|
+
break;
|
|
1193
1115
|
default:
|
|
1194
1116
|
if (!(await this.tryCustomSlashCommand(command, input))) {
|
|
1195
1117
|
display.showWarning(`Unknown command "${command}".`);
|
|
@@ -1498,6 +1420,99 @@ export class InteractiveShell {
|
|
|
1498
1420
|
// Display keyboard shortcuts help (Claude Code style)
|
|
1499
1421
|
display.showSystemMessage(formatShortcutsHelp());
|
|
1500
1422
|
}
|
|
1423
|
+
handleMemoryCommand(input) {
|
|
1424
|
+
const tokens = input.trim().split(/\s+/).slice(1);
|
|
1425
|
+
const action = (tokens.shift() ?? 'show').toLowerCase();
|
|
1426
|
+
switch (action) {
|
|
1427
|
+
case '':
|
|
1428
|
+
case 'show':
|
|
1429
|
+
case 'list': {
|
|
1430
|
+
this.showMemoryStatus();
|
|
1431
|
+
break;
|
|
1432
|
+
}
|
|
1433
|
+
case 'paths': {
|
|
1434
|
+
this.showMemoryPaths();
|
|
1435
|
+
break;
|
|
1436
|
+
}
|
|
1437
|
+
case 'edit': {
|
|
1438
|
+
const level = (tokens[0] ?? 'project').toLowerCase();
|
|
1439
|
+
this.openMemoryForEdit(level);
|
|
1440
|
+
break;
|
|
1441
|
+
}
|
|
1442
|
+
default:
|
|
1443
|
+
display.showWarning('Usage: /memory [show|paths|edit <user|project>]');
|
|
1444
|
+
break;
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
showMemoryStatus() {
|
|
1448
|
+
const memory = loadMemory(this.workingDir);
|
|
1449
|
+
const lines = [];
|
|
1450
|
+
lines.push(theme.bold('Persistent Memory'));
|
|
1451
|
+
lines.push('');
|
|
1452
|
+
if (memory.sources.length === 0) {
|
|
1453
|
+
lines.push(theme.secondary('No memory files found.'));
|
|
1454
|
+
lines.push('');
|
|
1455
|
+
lines.push(`Create ${theme.info('EROSOLAR.md')} in your project to add persistent context.`);
|
|
1456
|
+
lines.push(`Use ${theme.info('/memory edit project')} to create one.`);
|
|
1457
|
+
}
|
|
1458
|
+
else {
|
|
1459
|
+
for (const source of memory.sources) {
|
|
1460
|
+
const levelLabel = source.level === 'enterprise' ? 'Enterprise' :
|
|
1461
|
+
source.level === 'user' ? 'User' : 'Project';
|
|
1462
|
+
const preview = source.content.slice(0, 200).replace(/\n/g, ' ').trim();
|
|
1463
|
+
const truncated = source.content.length > 200 ? '...' : '';
|
|
1464
|
+
lines.push(`${theme.success('●')} ${theme.bold(levelLabel)}: ${source.path}`);
|
|
1465
|
+
lines.push(` ${theme.dim(preview + truncated)}`);
|
|
1466
|
+
lines.push('');
|
|
1467
|
+
}
|
|
1468
|
+
if (memory.importedPaths.length > memory.sources.length) {
|
|
1469
|
+
lines.push(theme.secondary(`Imported ${memory.importedPaths.length - memory.sources.length} additional files via @imports.`));
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
display.showSystemMessage(lines.join('\n'));
|
|
1473
|
+
}
|
|
1474
|
+
showMemoryPaths() {
|
|
1475
|
+
const paths = listMemoryPaths(this.workingDir);
|
|
1476
|
+
const lines = [];
|
|
1477
|
+
lines.push(theme.bold('Memory File Locations'));
|
|
1478
|
+
lines.push('');
|
|
1479
|
+
for (const { level, path, exists } of paths) {
|
|
1480
|
+
const icon = exists ? theme.success('✓') : theme.dim('○');
|
|
1481
|
+
const levelLabel = level.charAt(0).toUpperCase() + level.slice(1);
|
|
1482
|
+
lines.push(`${icon} ${levelLabel}: ${path}`);
|
|
1483
|
+
}
|
|
1484
|
+
lines.push('');
|
|
1485
|
+
lines.push(theme.secondary('Create any of these files to add persistent memory.'));
|
|
1486
|
+
lines.push(theme.secondary('Use @path/to/file.md syntax to import other files.'));
|
|
1487
|
+
display.showSystemMessage(lines.join('\n'));
|
|
1488
|
+
}
|
|
1489
|
+
openMemoryForEdit(level) {
|
|
1490
|
+
let targetPath;
|
|
1491
|
+
if (level === 'user') {
|
|
1492
|
+
targetPath = getUserMemoryEditPath();
|
|
1493
|
+
}
|
|
1494
|
+
else if (level === 'project') {
|
|
1495
|
+
targetPath = getDefaultProjectMemoryPath(this.workingDir);
|
|
1496
|
+
}
|
|
1497
|
+
else {
|
|
1498
|
+
display.showWarning('Specify "user" or "project" to edit. Enterprise memory is read-only.');
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
display.showInfo(`Memory file: ${targetPath}`);
|
|
1502
|
+
display.showInfo('Create or edit this file to add persistent context for the AI.');
|
|
1503
|
+
display.showInfo('');
|
|
1504
|
+
display.showInfo('Example EROSOLAR.md content:');
|
|
1505
|
+
display.showInfo('');
|
|
1506
|
+
display.showInfo(theme.dim(`# Project Guidelines
|
|
1507
|
+
|
|
1508
|
+
When working in this codebase:
|
|
1509
|
+
- Follow TypeScript strict mode conventions
|
|
1510
|
+
- Use functional patterns where appropriate
|
|
1511
|
+
- Run tests before committing
|
|
1512
|
+
|
|
1513
|
+
@./docs/coding-standards.md
|
|
1514
|
+
`));
|
|
1515
|
+
}
|
|
1501
1516
|
showFileChangeSummary() {
|
|
1502
1517
|
const summary = this._fileChangeTracker.getSummary();
|
|
1503
1518
|
const changes = this._fileChangeTracker.getAllChanges();
|
|
@@ -1540,11 +1555,11 @@ export class InteractiveShell {
|
|
|
1540
1555
|
display.showSystemMessage(lines.join('\n'));
|
|
1541
1556
|
}
|
|
1542
1557
|
showAlphaZeroMetrics() {
|
|
1543
|
-
const summary = this.
|
|
1558
|
+
const summary = this.sessionMetrics.getPerformanceSummary();
|
|
1544
1559
|
display.showSystemMessage(summary);
|
|
1545
1560
|
}
|
|
1546
1561
|
showImprovementSuggestions() {
|
|
1547
|
-
const suggestions = this.
|
|
1562
|
+
const suggestions = this.sessionMetrics.getImprovementSuggestions();
|
|
1548
1563
|
if (suggestions.length === 0) {
|
|
1549
1564
|
display.showInfo('No improvement suggestions at this time. Keep using the shell to generate metrics!');
|
|
1550
1565
|
return;
|
|
@@ -1590,9 +1605,7 @@ export class InteractiveShell {
|
|
|
1590
1605
|
}
|
|
1591
1606
|
}
|
|
1592
1607
|
lines.push(theme.secondary('CLI Flags:'));
|
|
1593
|
-
lines.push(' --alpha-zero Enable Alpha Zero 2 RL framework');
|
|
1594
1608
|
lines.push(' --coding Enable enhanced coding tools');
|
|
1595
|
-
lines.push(' --security Enable security research tools');
|
|
1596
1609
|
lines.push(' --all-plugins Enable all optional plugins');
|
|
1597
1610
|
display.showSystemMessage(lines.join('\n'));
|
|
1598
1611
|
}
|
|
@@ -1836,75 +1849,6 @@ export class InteractiveShell {
|
|
|
1836
1849
|
}
|
|
1837
1850
|
return `${warning.label}: ${warning.reason}.`;
|
|
1838
1851
|
}
|
|
1839
|
-
buildLaunchCommandPalette() {
|
|
1840
|
-
const entries = [];
|
|
1841
|
-
const secretsSummary = this.summarizeSecretsForPalette();
|
|
1842
|
-
const toolSummary = this.getToolSelectionSummary();
|
|
1843
|
-
const autosaveLabel = this.autosaveEnabled ? 'on' : 'off';
|
|
1844
|
-
for (const command of this.slashCommands) {
|
|
1845
|
-
const entry = {
|
|
1846
|
-
command: command.command,
|
|
1847
|
-
description: command.description,
|
|
1848
|
-
category: command.category ?? 'other',
|
|
1849
|
-
};
|
|
1850
|
-
switch (command.command) {
|
|
1851
|
-
case '/secrets':
|
|
1852
|
-
if (secretsSummary.text) {
|
|
1853
|
-
entry.description = `${command.description} (${secretsSummary.text})`;
|
|
1854
|
-
entry.tone = secretsSummary.tone;
|
|
1855
|
-
}
|
|
1856
|
-
break;
|
|
1857
|
-
case '/tools':
|
|
1858
|
-
if (toolSummary) {
|
|
1859
|
-
entry.description = `${command.description} (${toolSummary})`;
|
|
1860
|
-
}
|
|
1861
|
-
break;
|
|
1862
|
-
case '/sessions':
|
|
1863
|
-
entry.description = `${command.description} (autosave ${autosaveLabel})`;
|
|
1864
|
-
break;
|
|
1865
|
-
case '/model':
|
|
1866
|
-
entry.description = `${command.description} (current: ${this.sessionState.model})`;
|
|
1867
|
-
break;
|
|
1868
|
-
case '/provider':
|
|
1869
|
-
entry.description = `${command.description} (current: ${this.providerLabel(this.sessionState.provider)})`;
|
|
1870
|
-
break;
|
|
1871
|
-
default:
|
|
1872
|
-
break;
|
|
1873
|
-
}
|
|
1874
|
-
entries.push(entry);
|
|
1875
|
-
}
|
|
1876
|
-
return entries;
|
|
1877
|
-
}
|
|
1878
|
-
summarizeSecretsForPalette() {
|
|
1879
|
-
const definitions = listSecretDefinitions();
|
|
1880
|
-
if (!definitions.length) {
|
|
1881
|
-
return { text: null };
|
|
1882
|
-
}
|
|
1883
|
-
const missing = definitions.filter((definition) => !getSecretValue(definition.id));
|
|
1884
|
-
if (missing.length === 0) {
|
|
1885
|
-
return { text: 'all configured', tone: 'success' };
|
|
1886
|
-
}
|
|
1887
|
-
const labels = missing.map((definition) => definition.label ?? definition.id);
|
|
1888
|
-
return { text: `missing ${this.formatList(labels)}`, tone: 'warn' };
|
|
1889
|
-
}
|
|
1890
|
-
getToolSelectionSummary() {
|
|
1891
|
-
const toolSettings = loadToolSettings();
|
|
1892
|
-
const selection = buildEnabledToolSet(toolSettings);
|
|
1893
|
-
const options = getToolToggleOptions();
|
|
1894
|
-
if (!options.length) {
|
|
1895
|
-
return null;
|
|
1896
|
-
}
|
|
1897
|
-
const enabledCount = options.filter((option) => selection.has(option.id)).length;
|
|
1898
|
-
return `${enabledCount}/${options.length} enabled`;
|
|
1899
|
-
}
|
|
1900
|
-
formatList(values, maxItems = 3) {
|
|
1901
|
-
if (!values.length) {
|
|
1902
|
-
return '';
|
|
1903
|
-
}
|
|
1904
|
-
const shown = values.slice(0, maxItems);
|
|
1905
|
-
const suffix = values.length > maxItems ? ', …' : '';
|
|
1906
|
-
return `${shown.join(', ')}${suffix}`;
|
|
1907
|
-
}
|
|
1908
1852
|
buildSlashCommandList(header) {
|
|
1909
1853
|
const lines = [theme.gradient.primary(header), ''];
|
|
1910
1854
|
for (const command of this.slashCommands) {
|
|
@@ -2373,7 +2317,7 @@ export class InteractiveShell {
|
|
|
2373
2317
|
this.autosaveIfEnabled();
|
|
2374
2318
|
// Track metrics with Alpha Zero 2
|
|
2375
2319
|
const elapsedMs = Date.now() - requestStartTime;
|
|
2376
|
-
this.
|
|
2320
|
+
this.sessionMetrics.recordMessage(elapsedMs);
|
|
2377
2321
|
if (!responseText?.trim()) {
|
|
2378
2322
|
display.showWarning('The provider returned an empty response. Check your API key/provider selection or retry the prompt.');
|
|
2379
2323
|
}
|
|
@@ -2391,10 +2335,14 @@ export class InteractiveShell {
|
|
|
2391
2335
|
this.stopStreamingHeartbeat();
|
|
2392
2336
|
this.isProcessing = false;
|
|
2393
2337
|
this.terminalInput.setStreaming(false);
|
|
2338
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2394
2339
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2395
2340
|
this.setIdleStatus();
|
|
2396
2341
|
display.newLine();
|
|
2397
2342
|
this.updateStatusMessage(null);
|
|
2343
|
+
// Claude Code style: Show unified status bar before prompt
|
|
2344
|
+
// This creates consistent UI between startup and post-streaming
|
|
2345
|
+
this.showUnifiedStatusBar();
|
|
2398
2346
|
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
2399
2347
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
2400
2348
|
// Claude Code style: New prompt naturally appears at bottom
|
|
@@ -2471,14 +2419,13 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
|
|
|
2471
2419
|
try {
|
|
2472
2420
|
// Send the request and capture the response (streaming disabled)
|
|
2473
2421
|
display.showThinking('Responding...');
|
|
2474
|
-
this.refreshStatusLine(true);
|
|
2475
2422
|
const response = await agent.send(currentPrompt, true);
|
|
2476
2423
|
await this.awaitPendingCleanup();
|
|
2477
2424
|
this.captureHistorySnapshot();
|
|
2478
2425
|
this.autosaveIfEnabled();
|
|
2479
2426
|
// Track metrics
|
|
2480
2427
|
const elapsedMs = Date.now() - overallStartTime;
|
|
2481
|
-
this.
|
|
2428
|
+
this.sessionMetrics.recordMessage(elapsedMs);
|
|
2482
2429
|
if (!response?.trim()) {
|
|
2483
2430
|
display.showWarning('Model returned an empty response. Retrying this iteration...');
|
|
2484
2431
|
consecutiveNoProgress++;
|
|
@@ -2615,6 +2562,7 @@ What's the next action?`;
|
|
|
2615
2562
|
this.stopStreamingHeartbeat();
|
|
2616
2563
|
this.isProcessing = false;
|
|
2617
2564
|
this.terminalInput.setStreaming(false);
|
|
2565
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2618
2566
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2619
2567
|
this.setIdleStatus();
|
|
2620
2568
|
this.updateStatusMessage(null);
|
|
@@ -2971,10 +2919,8 @@ What's the next action?`;
|
|
|
2971
2919
|
try {
|
|
2972
2920
|
// Send the error to the agent for fixing
|
|
2973
2921
|
display.showThinking('Analyzing build errors');
|
|
2974
|
-
this.refreshStatusLine(true);
|
|
2975
2922
|
const response = await this.agent.send(prompt, true);
|
|
2976
2923
|
display.stopThinking();
|
|
2977
|
-
this.refreshStatusLine(true);
|
|
2978
2924
|
if (response) {
|
|
2979
2925
|
display.showAssistantMessage(response, { isFinal: true });
|
|
2980
2926
|
}
|
|
@@ -3001,8 +2947,8 @@ What's the next action?`;
|
|
|
3001
2947
|
};
|
|
3002
2948
|
this.agent = this.runtimeSession.createAgent(selection, {
|
|
3003
2949
|
onStreamChunk: (chunk) => {
|
|
3004
|
-
// Stream output
|
|
3005
|
-
|
|
2950
|
+
// Stream output directly - no spinner during streaming to avoid race conditions
|
|
2951
|
+
display.stream(chunk);
|
|
3006
2952
|
},
|
|
3007
2953
|
onStreamFallback: (info) => this.handleStreamingFallback(info),
|
|
3008
2954
|
onAssistantMessage: (content, metadata) => {
|
|
@@ -3024,16 +2970,18 @@ What's the next action?`;
|
|
|
3024
2970
|
display.showAssistantMessage(finalContent, enriched);
|
|
3025
2971
|
}
|
|
3026
2972
|
}
|
|
3027
|
-
//
|
|
2973
|
+
// Show status line at end (Claude Code style: "• Context X% used • Ready for prompts (2s)")
|
|
3028
2974
|
display.stopThinking();
|
|
3029
|
-
//
|
|
2975
|
+
// Calculate context usage
|
|
2976
|
+
let contextInfo;
|
|
3030
2977
|
if (enriched.contextWindowTokens && metadata.usage) {
|
|
3031
2978
|
const total = this.totalTokens(metadata.usage);
|
|
3032
2979
|
if (total && total > 0) {
|
|
3033
2980
|
const percentage = Math.round((total / enriched.contextWindowTokens) * 100);
|
|
3034
|
-
|
|
2981
|
+
contextInfo = { percentage, tokens: total };
|
|
3035
2982
|
}
|
|
3036
2983
|
}
|
|
2984
|
+
display.showStatusLine('Ready for prompts', enriched.elapsedMs, contextInfo);
|
|
3037
2985
|
// Auto-verify changes: build first (catches type errors), then tests
|
|
3038
2986
|
void this.enforceAutoBuild('final-response');
|
|
3039
2987
|
void this.enforceAutoTests('final-response');
|
|
@@ -3103,6 +3051,7 @@ What's the next action?`;
|
|
|
3103
3051
|
this.stopStreamingHeartbeat();
|
|
3104
3052
|
this.updateStatusMessage(null);
|
|
3105
3053
|
this.terminalInput.setStreaming(false);
|
|
3054
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3106
3055
|
this.terminalInput.render();
|
|
3107
3056
|
},
|
|
3108
3057
|
onVerificationNeeded: () => {
|
|
@@ -3139,6 +3088,7 @@ What's the next action?`;
|
|
|
3139
3088
|
resetChatBoxAfterModelSwap() {
|
|
3140
3089
|
this.updateStatusMessage(null);
|
|
3141
3090
|
this.terminalInput.setStreaming(false);
|
|
3091
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3142
3092
|
this.terminalInput.render();
|
|
3143
3093
|
this.ensureReadlineReady();
|
|
3144
3094
|
}
|
|
@@ -3203,14 +3153,9 @@ What's the next action?`;
|
|
|
3203
3153
|
return null;
|
|
3204
3154
|
}
|
|
3205
3155
|
const usageRatio = total / windowTokens;
|
|
3206
|
-
this.latestTokenUsage = {
|
|
3207
|
-
used: total,
|
|
3208
|
-
limit: windowTokens,
|
|
3209
|
-
};
|
|
3210
3156
|
// Always update context usage in the UI
|
|
3211
3157
|
const percentUsed = Math.round(usageRatio * 100);
|
|
3212
3158
|
this.updateContextUsage(percentUsed);
|
|
3213
|
-
this.refreshStatusLine(true);
|
|
3214
3159
|
if (usageRatio < CONTEXT_USAGE_THRESHOLD) {
|
|
3215
3160
|
return null;
|
|
3216
3161
|
}
|
|
@@ -3477,22 +3422,6 @@ What's the next action?`;
|
|
|
3477
3422
|
this.sessionState.reasoningEffort = preset.reasoningEffort;
|
|
3478
3423
|
}
|
|
3479
3424
|
}
|
|
3480
|
-
/**
|
|
3481
|
-
* Build the session banner.
|
|
3482
|
-
*/
|
|
3483
|
-
buildBanner() {
|
|
3484
|
-
const terminalWidth = output.columns ?? 100;
|
|
3485
|
-
const width = Math.min(terminalWidth - 4, 110);
|
|
3486
|
-
return renderSessionFrame({
|
|
3487
|
-
profileLabel: this.profileLabel,
|
|
3488
|
-
profileName: this.profile,
|
|
3489
|
-
model: this.sessionState.model,
|
|
3490
|
-
provider: this.sessionState.provider,
|
|
3491
|
-
workspace: this.workingDir,
|
|
3492
|
-
version: this.version,
|
|
3493
|
-
width,
|
|
3494
|
-
});
|
|
3495
|
-
}
|
|
3496
3425
|
refreshBannerSessionInfo() {
|
|
3497
3426
|
const nextState = {
|
|
3498
3427
|
model: this.sessionState.model,
|
|
@@ -3503,11 +3432,13 @@ What's the next action?`;
|
|
|
3503
3432
|
return;
|
|
3504
3433
|
}
|
|
3505
3434
|
this.refreshContextGauge();
|
|
3506
|
-
|
|
3507
|
-
//
|
|
3435
|
+
display.updateSessionInfo(nextState.model, nextState.provider);
|
|
3436
|
+
// Update the persistent model info display in terminal input
|
|
3437
|
+
this.terminalInput.setModelInfo(this.describeModelDetail());
|
|
3508
3438
|
if (!this.isProcessing) {
|
|
3509
3439
|
this.setIdleStatus();
|
|
3510
3440
|
}
|
|
3441
|
+
// Pinned header rows are disabled; scroll region handles all output.
|
|
3511
3442
|
this.bannerSessionState = nextState;
|
|
3512
3443
|
}
|
|
3513
3444
|
providerLabel(id) {
|