erosolar-cli 1.7.284 → 1.7.285
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 +0 -1
- 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 -22
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +159 -226
- 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 +186 -78
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +927 -496
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/terminalInputAdapter.d.ts +35 -28
- package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
- package/dist/shell/terminalInputAdapter.js +50 -26
- 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 +44 -23
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +286 -139
- 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
- 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,10 +19,10 @@ 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 { renderSessionFrame } from '../ui/unified/layout.js';
|
|
26
26
|
import { isUpdateInProgress } from './updateManager.js';
|
|
27
27
|
import { writeLock } from '../ui/writeLock.js';
|
|
28
28
|
import { enterStreamingMode, exitStreamingMode } from '../ui/globalWriteLock.js';
|
|
@@ -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;
|
|
@@ -227,14 +216,17 @@ export class InteractiveShell {
|
|
|
227
216
|
});
|
|
228
217
|
// Register output interceptor for cursor positioning during streaming
|
|
229
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();
|
|
230
224
|
// Initialize Alpha Zero 2 metrics tracking
|
|
231
|
-
this.
|
|
225
|
+
this.sessionMetrics = new MetricsTracker(`${this.profile}-${Date.now()}`);
|
|
232
226
|
this.setupStatusTracking();
|
|
233
227
|
this.refreshContextGauge();
|
|
234
228
|
this.terminalInput.start();
|
|
235
229
|
this.refreshControlBar();
|
|
236
|
-
// Stream banner into the unified scroll region at the top
|
|
237
|
-
this.streamBannerToScrollRegion();
|
|
238
230
|
this.rebuildAgent();
|
|
239
231
|
this.setupHandlers();
|
|
240
232
|
this.refreshBannerSessionInfo();
|
|
@@ -286,15 +278,9 @@ export class InteractiveShell {
|
|
|
286
278
|
await this.processInputBlock(initialPrompt);
|
|
287
279
|
return;
|
|
288
280
|
}
|
|
289
|
-
this.showLaunchCommandPalette();
|
|
290
281
|
// Ensure the terminal input is visible
|
|
291
282
|
this.terminalInput.render();
|
|
292
283
|
}
|
|
293
|
-
showLaunchCommandPalette() {
|
|
294
|
-
// Disabled: Quick commands palette takes up too much space
|
|
295
|
-
// Users can type /help to see available commands
|
|
296
|
-
this.launchPaletteShown = true;
|
|
297
|
-
}
|
|
298
284
|
/**
|
|
299
285
|
* TerminalInputAdapter submit handler
|
|
300
286
|
*/
|
|
@@ -308,8 +294,9 @@ export class InteractiveShell {
|
|
|
308
294
|
this.handleInputChange('');
|
|
309
295
|
return;
|
|
310
296
|
}
|
|
311
|
-
//
|
|
312
|
-
//
|
|
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);
|
|
313
300
|
this.logUserPrompt(approved);
|
|
314
301
|
void this.processInputBlock(approved).catch((err) => {
|
|
315
302
|
display.showError(err instanceof Error ? err.message : String(err), err);
|
|
@@ -511,9 +498,11 @@ export class InteractiveShell {
|
|
|
511
498
|
// Dispose unified UI adapter
|
|
512
499
|
this.uiAdapter.dispose();
|
|
513
500
|
display.newLine();
|
|
514
|
-
|
|
515
|
-
console.log(theme.
|
|
516
|
-
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)));
|
|
517
506
|
exit(0);
|
|
518
507
|
}
|
|
519
508
|
/**
|
|
@@ -683,14 +672,13 @@ export class InteractiveShell {
|
|
|
683
672
|
});
|
|
684
673
|
}
|
|
685
674
|
setProcessingStatus(detail) {
|
|
686
|
-
this.latestTokenUsage = { used: null, limit: this.latestTokenUsage.limit };
|
|
687
675
|
this.statusTracker.setBase('Working on your request', {
|
|
688
676
|
detail: this.describeStatusDetail(detail),
|
|
689
677
|
tone: 'info',
|
|
690
678
|
});
|
|
691
679
|
}
|
|
692
680
|
describeStatusDetail(detail) {
|
|
693
|
-
const parts = detail?.trim()
|
|
681
|
+
const parts = [detail?.trim() || this.describeModelDetail()];
|
|
694
682
|
const queued = this.followUpQueue.length;
|
|
695
683
|
if (queued > 0) {
|
|
696
684
|
parts.push(`${queued} follow-up${queued === 1 ? '' : 's'} queued`);
|
|
@@ -703,18 +691,12 @@ export class InteractiveShell {
|
|
|
703
691
|
}
|
|
704
692
|
refreshContextGauge() {
|
|
705
693
|
const tokens = getContextWindowTokens(this.sessionState.model);
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
if (normalizedTokens !== null) {
|
|
709
|
-
this.latestTokenUsage = {
|
|
710
|
-
used: this.latestTokenUsage.used,
|
|
711
|
-
limit: normalizedTokens,
|
|
712
|
-
};
|
|
713
|
-
}
|
|
694
|
+
this.activeContextWindowTokens =
|
|
695
|
+
typeof tokens === 'number' && Number.isFinite(tokens) ? tokens : null;
|
|
714
696
|
}
|
|
715
697
|
updateContextUsage(percentage) {
|
|
716
698
|
this.uiAdapter.updateContextUsage(percentage);
|
|
717
|
-
this.terminalInput.setContextUsage(percentage
|
|
699
|
+
this.terminalInput.setContextUsage(percentage);
|
|
718
700
|
}
|
|
719
701
|
refreshControlBar() {
|
|
720
702
|
this.terminalInput.setModeToggles({
|
|
@@ -722,9 +704,9 @@ export class InteractiveShell {
|
|
|
722
704
|
autoContinueEnabled: this.autoContinueEnabled,
|
|
723
705
|
verificationHotkey: 'alt+v',
|
|
724
706
|
autoContinueHotkey: 'alt+c',
|
|
725
|
-
thinkingModeLabel: this.thinkingMode,
|
|
726
|
-
thinkingHotkey: '/thinking',
|
|
727
707
|
});
|
|
708
|
+
// Update persistent model info display
|
|
709
|
+
this.terminalInput.setModelInfo(this.describeModelDetail());
|
|
728
710
|
this.refreshStatusLine();
|
|
729
711
|
this.terminalInput.render();
|
|
730
712
|
}
|
|
@@ -755,25 +737,6 @@ export class InteractiveShell {
|
|
|
755
737
|
// Set main status (tool execution, etc.) - shown when not overridden
|
|
756
738
|
const statusText = this.formatStatusLine(this.statusLineState);
|
|
757
739
|
this.terminalInput.setStatusMessage(statusText);
|
|
758
|
-
// Surface meta header (elapsed + context usage) above the divider
|
|
759
|
-
const elapsedSeconds = this.statusLineState
|
|
760
|
-
? Math.max(0, Math.floor((Date.now() - this.statusLineState.startedAt) / 1000))
|
|
761
|
-
: null;
|
|
762
|
-
const thinkingMs = display.isSpinnerActive() ? display.getThinkingElapsedMs() : null;
|
|
763
|
-
const tokensUsed = this.latestTokenUsage.used;
|
|
764
|
-
const tokenLimit = this.latestTokenUsage.limit ?? this.activeContextWindowTokens;
|
|
765
|
-
this.terminalInput.setMetaStatus({
|
|
766
|
-
elapsedSeconds,
|
|
767
|
-
tokensUsed,
|
|
768
|
-
tokenLimit,
|
|
769
|
-
thinkingMs,
|
|
770
|
-
thinkingHasContent: display.isSpinnerActive(),
|
|
771
|
-
});
|
|
772
|
-
// Keep model/provider visible in the controls bar
|
|
773
|
-
this.terminalInput.setModelContext({
|
|
774
|
-
model: this.sessionState.model,
|
|
775
|
-
provider: this.providerLabel(this.sessionState.provider),
|
|
776
|
-
});
|
|
777
740
|
if (forceRender) {
|
|
778
741
|
this.terminalInput.render();
|
|
779
742
|
}
|
|
@@ -833,14 +796,13 @@ export class InteractiveShell {
|
|
|
833
796
|
this.terminalInput.render();
|
|
834
797
|
}
|
|
835
798
|
/**
|
|
836
|
-
* 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.
|
|
837
801
|
*/
|
|
838
802
|
logUserPrompt(text) {
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
const formatted = `${theme.user('>')} ${text}\n`;
|
|
843
|
-
this.terminalInput.writeToScrollRegion(formatted);
|
|
803
|
+
// Display the user's prompt with the standard prefix
|
|
804
|
+
const prefix = formatUserPrompt();
|
|
805
|
+
display.stream(`\n${prefix}${text}\n\n`);
|
|
844
806
|
}
|
|
845
807
|
requestPromptRefresh(force = false) {
|
|
846
808
|
if (force) {
|
|
@@ -868,29 +830,9 @@ export class InteractiveShell {
|
|
|
868
830
|
this.uiUpdates.setMode('streaming');
|
|
869
831
|
this.streamingHeartbeatStart = Date.now();
|
|
870
832
|
this.streamingHeartbeatFrame = 0;
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
this.refreshStatusLine(true);
|
|
875
|
-
// Periodically refresh the pinned input/status region while streaming so
|
|
876
|
-
// elapsed time remains visible without interrupting the scroll region.
|
|
877
|
-
this.uiUpdates.startHeartbeat('streaming', {
|
|
878
|
-
intervalMs: 1000,
|
|
879
|
-
lane: 'heartbeat',
|
|
880
|
-
mode: ['streaming', 'processing'],
|
|
881
|
-
coalesceKey: 'streaming:heartbeat',
|
|
882
|
-
run: () => {
|
|
883
|
-
const elapsedSeconds = this.streamingHeartbeatStart
|
|
884
|
-
? Math.max(0, Math.floor((Date.now() - this.streamingHeartbeatStart) / 1000))
|
|
885
|
-
: 0;
|
|
886
|
-
this.streamingHeartbeatFrame =
|
|
887
|
-
(this.streamingHeartbeatFrame + 1) % STREAMING_SPINNER_FRAMES.length;
|
|
888
|
-
const frame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
|
|
889
|
-
this.streamingStatusLabel = this.buildStreamingStatus(`${frame} ${label}`, elapsedSeconds);
|
|
890
|
-
display.updateStreamingStatus(this.streamingStatusLabel);
|
|
891
|
-
this.refreshStatusLine(true);
|
|
892
|
-
},
|
|
893
|
-
});
|
|
833
|
+
// Note: We don't start a heartbeat during streaming anymore
|
|
834
|
+
// because the UI shouldn't be rendering during streaming.
|
|
835
|
+
// The streaming status is shown in the streaming header instead.
|
|
894
836
|
}
|
|
895
837
|
stopStreamingHeartbeat() {
|
|
896
838
|
// Exit global streaming mode - allows UI to render again
|
|
@@ -906,28 +848,10 @@ export class InteractiveShell {
|
|
|
906
848
|
// Force refresh to update the input area now that streaming has ended
|
|
907
849
|
this.refreshStatusLine(true);
|
|
908
850
|
}
|
|
909
|
-
buildStreamingStatus(label
|
|
851
|
+
buildStreamingStatus(label) {
|
|
910
852
|
const detail = this.describeModelDetail();
|
|
911
|
-
const
|
|
912
|
-
|
|
913
|
-
: null;
|
|
914
|
-
const prefix = theme.info('⏺');
|
|
915
|
-
const parts = [label];
|
|
916
|
-
if (detail) {
|
|
917
|
-
parts.push(theme.ui.muted('·'), detail);
|
|
918
|
-
}
|
|
919
|
-
if (elapsedLabel) {
|
|
920
|
-
parts.push(theme.ui.muted('·'), elapsedLabel);
|
|
921
|
-
}
|
|
922
|
-
return `${prefix} ${parts.join(' ')}`.trim();
|
|
923
|
-
}
|
|
924
|
-
formatElapsedShort(seconds) {
|
|
925
|
-
if (seconds < 60) {
|
|
926
|
-
return `${seconds}s`;
|
|
927
|
-
}
|
|
928
|
-
const minutes = Math.floor(seconds / 60);
|
|
929
|
-
const remaining = seconds % 60;
|
|
930
|
-
return remaining > 0 ? `${minutes}m ${remaining}s` : `${minutes}m`;
|
|
853
|
+
const prefix = theme.info('●');
|
|
854
|
+
return detail ? `${prefix} ${label} ${theme.ui.muted('·')} ${detail}` : `${prefix} ${label}`;
|
|
931
855
|
}
|
|
932
856
|
refreshQueueIndicators() {
|
|
933
857
|
if (this.isProcessing) {
|
|
@@ -1175,6 +1099,17 @@ export class InteractiveShell {
|
|
|
1175
1099
|
case '/discover':
|
|
1176
1100
|
await this.discoverModelsCommand();
|
|
1177
1101
|
break;
|
|
1102
|
+
case '/memory':
|
|
1103
|
+
this.handleMemoryCommand(input);
|
|
1104
|
+
break;
|
|
1105
|
+
case '/clear':
|
|
1106
|
+
display.clear();
|
|
1107
|
+
this.cachedHistory = [];
|
|
1108
|
+
display.showInfo('Conversation cleared.');
|
|
1109
|
+
break;
|
|
1110
|
+
case '/help':
|
|
1111
|
+
this.showHelp();
|
|
1112
|
+
break;
|
|
1178
1113
|
default:
|
|
1179
1114
|
if (!(await this.tryCustomSlashCommand(command, input))) {
|
|
1180
1115
|
display.showWarning(`Unknown command "${command}".`);
|
|
@@ -1483,6 +1418,99 @@ export class InteractiveShell {
|
|
|
1483
1418
|
// Display keyboard shortcuts help (Claude Code style)
|
|
1484
1419
|
display.showSystemMessage(formatShortcutsHelp());
|
|
1485
1420
|
}
|
|
1421
|
+
handleMemoryCommand(input) {
|
|
1422
|
+
const tokens = input.trim().split(/\s+/).slice(1);
|
|
1423
|
+
const action = (tokens.shift() ?? 'show').toLowerCase();
|
|
1424
|
+
switch (action) {
|
|
1425
|
+
case '':
|
|
1426
|
+
case 'show':
|
|
1427
|
+
case 'list': {
|
|
1428
|
+
this.showMemoryStatus();
|
|
1429
|
+
break;
|
|
1430
|
+
}
|
|
1431
|
+
case 'paths': {
|
|
1432
|
+
this.showMemoryPaths();
|
|
1433
|
+
break;
|
|
1434
|
+
}
|
|
1435
|
+
case 'edit': {
|
|
1436
|
+
const level = (tokens[0] ?? 'project').toLowerCase();
|
|
1437
|
+
this.openMemoryForEdit(level);
|
|
1438
|
+
break;
|
|
1439
|
+
}
|
|
1440
|
+
default:
|
|
1441
|
+
display.showWarning('Usage: /memory [show|paths|edit <user|project>]');
|
|
1442
|
+
break;
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
showMemoryStatus() {
|
|
1446
|
+
const memory = loadMemory(this.workingDir);
|
|
1447
|
+
const lines = [];
|
|
1448
|
+
lines.push(theme.bold('Persistent Memory'));
|
|
1449
|
+
lines.push('');
|
|
1450
|
+
if (memory.sources.length === 0) {
|
|
1451
|
+
lines.push(theme.secondary('No memory files found.'));
|
|
1452
|
+
lines.push('');
|
|
1453
|
+
lines.push(`Create ${theme.info('EROSOLAR.md')} in your project to add persistent context.`);
|
|
1454
|
+
lines.push(`Use ${theme.info('/memory edit project')} to create one.`);
|
|
1455
|
+
}
|
|
1456
|
+
else {
|
|
1457
|
+
for (const source of memory.sources) {
|
|
1458
|
+
const levelLabel = source.level === 'enterprise' ? 'Enterprise' :
|
|
1459
|
+
source.level === 'user' ? 'User' : 'Project';
|
|
1460
|
+
const preview = source.content.slice(0, 200).replace(/\n/g, ' ').trim();
|
|
1461
|
+
const truncated = source.content.length > 200 ? '...' : '';
|
|
1462
|
+
lines.push(`${theme.success('●')} ${theme.bold(levelLabel)}: ${source.path}`);
|
|
1463
|
+
lines.push(` ${theme.dim(preview + truncated)}`);
|
|
1464
|
+
lines.push('');
|
|
1465
|
+
}
|
|
1466
|
+
if (memory.importedPaths.length > memory.sources.length) {
|
|
1467
|
+
lines.push(theme.secondary(`Imported ${memory.importedPaths.length - memory.sources.length} additional files via @imports.`));
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
display.showSystemMessage(lines.join('\n'));
|
|
1471
|
+
}
|
|
1472
|
+
showMemoryPaths() {
|
|
1473
|
+
const paths = listMemoryPaths(this.workingDir);
|
|
1474
|
+
const lines = [];
|
|
1475
|
+
lines.push(theme.bold('Memory File Locations'));
|
|
1476
|
+
lines.push('');
|
|
1477
|
+
for (const { level, path, exists } of paths) {
|
|
1478
|
+
const icon = exists ? theme.success('✓') : theme.dim('○');
|
|
1479
|
+
const levelLabel = level.charAt(0).toUpperCase() + level.slice(1);
|
|
1480
|
+
lines.push(`${icon} ${levelLabel}: ${path}`);
|
|
1481
|
+
}
|
|
1482
|
+
lines.push('');
|
|
1483
|
+
lines.push(theme.secondary('Create any of these files to add persistent memory.'));
|
|
1484
|
+
lines.push(theme.secondary('Use @path/to/file.md syntax to import other files.'));
|
|
1485
|
+
display.showSystemMessage(lines.join('\n'));
|
|
1486
|
+
}
|
|
1487
|
+
openMemoryForEdit(level) {
|
|
1488
|
+
let targetPath;
|
|
1489
|
+
if (level === 'user') {
|
|
1490
|
+
targetPath = getUserMemoryEditPath();
|
|
1491
|
+
}
|
|
1492
|
+
else if (level === 'project') {
|
|
1493
|
+
targetPath = getDefaultProjectMemoryPath(this.workingDir);
|
|
1494
|
+
}
|
|
1495
|
+
else {
|
|
1496
|
+
display.showWarning('Specify "user" or "project" to edit. Enterprise memory is read-only.');
|
|
1497
|
+
return;
|
|
1498
|
+
}
|
|
1499
|
+
display.showInfo(`Memory file: ${targetPath}`);
|
|
1500
|
+
display.showInfo('Create or edit this file to add persistent context for the AI.');
|
|
1501
|
+
display.showInfo('');
|
|
1502
|
+
display.showInfo('Example EROSOLAR.md content:');
|
|
1503
|
+
display.showInfo('');
|
|
1504
|
+
display.showInfo(theme.dim(`# Project Guidelines
|
|
1505
|
+
|
|
1506
|
+
When working in this codebase:
|
|
1507
|
+
- Follow TypeScript strict mode conventions
|
|
1508
|
+
- Use functional patterns where appropriate
|
|
1509
|
+
- Run tests before committing
|
|
1510
|
+
|
|
1511
|
+
@./docs/coding-standards.md
|
|
1512
|
+
`));
|
|
1513
|
+
}
|
|
1486
1514
|
showFileChangeSummary() {
|
|
1487
1515
|
const summary = this._fileChangeTracker.getSummary();
|
|
1488
1516
|
const changes = this._fileChangeTracker.getAllChanges();
|
|
@@ -1525,11 +1553,11 @@ export class InteractiveShell {
|
|
|
1525
1553
|
display.showSystemMessage(lines.join('\n'));
|
|
1526
1554
|
}
|
|
1527
1555
|
showAlphaZeroMetrics() {
|
|
1528
|
-
const summary = this.
|
|
1556
|
+
const summary = this.sessionMetrics.getPerformanceSummary();
|
|
1529
1557
|
display.showSystemMessage(summary);
|
|
1530
1558
|
}
|
|
1531
1559
|
showImprovementSuggestions() {
|
|
1532
|
-
const suggestions = this.
|
|
1560
|
+
const suggestions = this.sessionMetrics.getImprovementSuggestions();
|
|
1533
1561
|
if (suggestions.length === 0) {
|
|
1534
1562
|
display.showInfo('No improvement suggestions at this time. Keep using the shell to generate metrics!');
|
|
1535
1563
|
return;
|
|
@@ -1575,9 +1603,7 @@ export class InteractiveShell {
|
|
|
1575
1603
|
}
|
|
1576
1604
|
}
|
|
1577
1605
|
lines.push(theme.secondary('CLI Flags:'));
|
|
1578
|
-
lines.push(' --alpha-zero Enable Alpha Zero 2 RL framework');
|
|
1579
1606
|
lines.push(' --coding Enable enhanced coding tools');
|
|
1580
|
-
lines.push(' --security Enable security research tools');
|
|
1581
1607
|
lines.push(' --all-plugins Enable all optional plugins');
|
|
1582
1608
|
display.showSystemMessage(lines.join('\n'));
|
|
1583
1609
|
}
|
|
@@ -1821,75 +1847,6 @@ export class InteractiveShell {
|
|
|
1821
1847
|
}
|
|
1822
1848
|
return `${warning.label}: ${warning.reason}.`;
|
|
1823
1849
|
}
|
|
1824
|
-
buildLaunchCommandPalette() {
|
|
1825
|
-
const entries = [];
|
|
1826
|
-
const secretsSummary = this.summarizeSecretsForPalette();
|
|
1827
|
-
const toolSummary = this.getToolSelectionSummary();
|
|
1828
|
-
const autosaveLabel = this.autosaveEnabled ? 'on' : 'off';
|
|
1829
|
-
for (const command of this.slashCommands) {
|
|
1830
|
-
const entry = {
|
|
1831
|
-
command: command.command,
|
|
1832
|
-
description: command.description,
|
|
1833
|
-
category: command.category ?? 'other',
|
|
1834
|
-
};
|
|
1835
|
-
switch (command.command) {
|
|
1836
|
-
case '/secrets':
|
|
1837
|
-
if (secretsSummary.text) {
|
|
1838
|
-
entry.description = `${command.description} (${secretsSummary.text})`;
|
|
1839
|
-
entry.tone = secretsSummary.tone;
|
|
1840
|
-
}
|
|
1841
|
-
break;
|
|
1842
|
-
case '/tools':
|
|
1843
|
-
if (toolSummary) {
|
|
1844
|
-
entry.description = `${command.description} (${toolSummary})`;
|
|
1845
|
-
}
|
|
1846
|
-
break;
|
|
1847
|
-
case '/sessions':
|
|
1848
|
-
entry.description = `${command.description} (autosave ${autosaveLabel})`;
|
|
1849
|
-
break;
|
|
1850
|
-
case '/model':
|
|
1851
|
-
entry.description = `${command.description} (current: ${this.sessionState.model})`;
|
|
1852
|
-
break;
|
|
1853
|
-
case '/provider':
|
|
1854
|
-
entry.description = `${command.description} (current: ${this.providerLabel(this.sessionState.provider)})`;
|
|
1855
|
-
break;
|
|
1856
|
-
default:
|
|
1857
|
-
break;
|
|
1858
|
-
}
|
|
1859
|
-
entries.push(entry);
|
|
1860
|
-
}
|
|
1861
|
-
return entries;
|
|
1862
|
-
}
|
|
1863
|
-
summarizeSecretsForPalette() {
|
|
1864
|
-
const definitions = listSecretDefinitions();
|
|
1865
|
-
if (!definitions.length) {
|
|
1866
|
-
return { text: null };
|
|
1867
|
-
}
|
|
1868
|
-
const missing = definitions.filter((definition) => !getSecretValue(definition.id));
|
|
1869
|
-
if (missing.length === 0) {
|
|
1870
|
-
return { text: 'all configured', tone: 'success' };
|
|
1871
|
-
}
|
|
1872
|
-
const labels = missing.map((definition) => definition.label ?? definition.id);
|
|
1873
|
-
return { text: `missing ${this.formatList(labels)}`, tone: 'warn' };
|
|
1874
|
-
}
|
|
1875
|
-
getToolSelectionSummary() {
|
|
1876
|
-
const toolSettings = loadToolSettings();
|
|
1877
|
-
const selection = buildEnabledToolSet(toolSettings);
|
|
1878
|
-
const options = getToolToggleOptions();
|
|
1879
|
-
if (!options.length) {
|
|
1880
|
-
return null;
|
|
1881
|
-
}
|
|
1882
|
-
const enabledCount = options.filter((option) => selection.has(option.id)).length;
|
|
1883
|
-
return `${enabledCount}/${options.length} enabled`;
|
|
1884
|
-
}
|
|
1885
|
-
formatList(values, maxItems = 3) {
|
|
1886
|
-
if (!values.length) {
|
|
1887
|
-
return '';
|
|
1888
|
-
}
|
|
1889
|
-
const shown = values.slice(0, maxItems);
|
|
1890
|
-
const suffix = values.length > maxItems ? ', …' : '';
|
|
1891
|
-
return `${shown.join(', ')}${suffix}`;
|
|
1892
|
-
}
|
|
1893
1850
|
buildSlashCommandList(header) {
|
|
1894
1851
|
const lines = [theme.gradient.primary(header), ''];
|
|
1895
1852
|
for (const command of this.slashCommands) {
|
|
@@ -2358,7 +2315,7 @@ export class InteractiveShell {
|
|
|
2358
2315
|
this.autosaveIfEnabled();
|
|
2359
2316
|
// Track metrics with Alpha Zero 2
|
|
2360
2317
|
const elapsedMs = Date.now() - requestStartTime;
|
|
2361
|
-
this.
|
|
2318
|
+
this.sessionMetrics.recordMessage(elapsedMs);
|
|
2362
2319
|
if (!responseText?.trim()) {
|
|
2363
2320
|
display.showWarning('The provider returned an empty response. Check your API key/provider selection or retry the prompt.');
|
|
2364
2321
|
}
|
|
@@ -2376,10 +2333,14 @@ export class InteractiveShell {
|
|
|
2376
2333
|
this.stopStreamingHeartbeat();
|
|
2377
2334
|
this.isProcessing = false;
|
|
2378
2335
|
this.terminalInput.setStreaming(false);
|
|
2336
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2379
2337
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2380
2338
|
this.setIdleStatus();
|
|
2381
2339
|
display.newLine();
|
|
2382
2340
|
this.updateStatusMessage(null);
|
|
2341
|
+
// Claude Code style: Show unified status bar before prompt
|
|
2342
|
+
// This creates consistent UI between startup and post-streaming
|
|
2343
|
+
this.showUnifiedStatusBar();
|
|
2383
2344
|
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
2384
2345
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
2385
2346
|
// Claude Code style: New prompt naturally appears at bottom
|
|
@@ -2456,14 +2417,13 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
|
|
|
2456
2417
|
try {
|
|
2457
2418
|
// Send the request and capture the response (streaming disabled)
|
|
2458
2419
|
display.showThinking('Responding...');
|
|
2459
|
-
this.refreshStatusLine(true);
|
|
2460
2420
|
const response = await agent.send(currentPrompt, true);
|
|
2461
2421
|
await this.awaitPendingCleanup();
|
|
2462
2422
|
this.captureHistorySnapshot();
|
|
2463
2423
|
this.autosaveIfEnabled();
|
|
2464
2424
|
// Track metrics
|
|
2465
2425
|
const elapsedMs = Date.now() - overallStartTime;
|
|
2466
|
-
this.
|
|
2426
|
+
this.sessionMetrics.recordMessage(elapsedMs);
|
|
2467
2427
|
if (!response?.trim()) {
|
|
2468
2428
|
display.showWarning('Model returned an empty response. Retrying this iteration...');
|
|
2469
2429
|
consecutiveNoProgress++;
|
|
@@ -2600,6 +2560,7 @@ What's the next action?`;
|
|
|
2600
2560
|
this.stopStreamingHeartbeat();
|
|
2601
2561
|
this.isProcessing = false;
|
|
2602
2562
|
this.terminalInput.setStreaming(false);
|
|
2563
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2603
2564
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2604
2565
|
this.setIdleStatus();
|
|
2605
2566
|
this.updateStatusMessage(null);
|
|
@@ -2956,10 +2917,8 @@ What's the next action?`;
|
|
|
2956
2917
|
try {
|
|
2957
2918
|
// Send the error to the agent for fixing
|
|
2958
2919
|
display.showThinking('Analyzing build errors');
|
|
2959
|
-
this.refreshStatusLine(true);
|
|
2960
2920
|
const response = await this.agent.send(prompt, true);
|
|
2961
2921
|
display.stopThinking();
|
|
2962
|
-
this.refreshStatusLine(true);
|
|
2963
2922
|
if (response) {
|
|
2964
2923
|
display.showAssistantMessage(response, { isFinal: true });
|
|
2965
2924
|
}
|
|
@@ -3009,16 +2968,18 @@ What's the next action?`;
|
|
|
3009
2968
|
display.showAssistantMessage(finalContent, enriched);
|
|
3010
2969
|
}
|
|
3011
2970
|
}
|
|
3012
|
-
//
|
|
2971
|
+
// Show status line at end (Claude Code style: "• Context X% used • Ready for prompts (2s)")
|
|
3013
2972
|
display.stopThinking();
|
|
3014
|
-
//
|
|
2973
|
+
// Calculate context usage
|
|
2974
|
+
let contextInfo;
|
|
3015
2975
|
if (enriched.contextWindowTokens && metadata.usage) {
|
|
3016
2976
|
const total = this.totalTokens(metadata.usage);
|
|
3017
2977
|
if (total && total > 0) {
|
|
3018
2978
|
const percentage = Math.round((total / enriched.contextWindowTokens) * 100);
|
|
3019
|
-
|
|
2979
|
+
contextInfo = { percentage, tokens: total };
|
|
3020
2980
|
}
|
|
3021
2981
|
}
|
|
2982
|
+
display.showStatusLine('Ready for prompts', enriched.elapsedMs, contextInfo);
|
|
3022
2983
|
// Auto-verify changes: build first (catches type errors), then tests
|
|
3023
2984
|
void this.enforceAutoBuild('final-response');
|
|
3024
2985
|
void this.enforceAutoTests('final-response');
|
|
@@ -3088,6 +3049,7 @@ What's the next action?`;
|
|
|
3088
3049
|
this.stopStreamingHeartbeat();
|
|
3089
3050
|
this.updateStatusMessage(null);
|
|
3090
3051
|
this.terminalInput.setStreaming(false);
|
|
3052
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3091
3053
|
this.terminalInput.render();
|
|
3092
3054
|
},
|
|
3093
3055
|
onVerificationNeeded: () => {
|
|
@@ -3124,6 +3086,7 @@ What's the next action?`;
|
|
|
3124
3086
|
resetChatBoxAfterModelSwap() {
|
|
3125
3087
|
this.updateStatusMessage(null);
|
|
3126
3088
|
this.terminalInput.setStreaming(false);
|
|
3089
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3127
3090
|
this.terminalInput.render();
|
|
3128
3091
|
this.ensureReadlineReady();
|
|
3129
3092
|
}
|
|
@@ -3188,14 +3151,9 @@ What's the next action?`;
|
|
|
3188
3151
|
return null;
|
|
3189
3152
|
}
|
|
3190
3153
|
const usageRatio = total / windowTokens;
|
|
3191
|
-
this.latestTokenUsage = {
|
|
3192
|
-
used: total,
|
|
3193
|
-
limit: windowTokens,
|
|
3194
|
-
};
|
|
3195
3154
|
// Always update context usage in the UI
|
|
3196
3155
|
const percentUsed = Math.round(usageRatio * 100);
|
|
3197
3156
|
this.updateContextUsage(percentUsed);
|
|
3198
|
-
this.refreshStatusLine(true);
|
|
3199
3157
|
if (usageRatio < CONTEXT_USAGE_THRESHOLD) {
|
|
3200
3158
|
return null;
|
|
3201
3159
|
}
|
|
@@ -3462,33 +3420,6 @@ What's the next action?`;
|
|
|
3462
3420
|
this.sessionState.reasoningEffort = preset.reasoningEffort;
|
|
3463
3421
|
}
|
|
3464
3422
|
}
|
|
3465
|
-
/**
|
|
3466
|
-
* Build the session banner using the unified layout renderer.
|
|
3467
|
-
* This is streamed as content, not stored in display.
|
|
3468
|
-
*/
|
|
3469
|
-
buildBanner() {
|
|
3470
|
-
const terminalWidth = output.columns ?? 100;
|
|
3471
|
-
const width = Math.min(terminalWidth - 4, 110);
|
|
3472
|
-
return renderSessionFrame({
|
|
3473
|
-
profileLabel: this.profileLabel,
|
|
3474
|
-
profileName: this.profile,
|
|
3475
|
-
model: this.sessionState.model,
|
|
3476
|
-
provider: this.sessionState.provider,
|
|
3477
|
-
workspace: this.workingDir,
|
|
3478
|
-
version: this.version,
|
|
3479
|
-
width,
|
|
3480
|
-
});
|
|
3481
|
-
}
|
|
3482
|
-
/**
|
|
3483
|
-
* Stream banner into the unified scroll region.
|
|
3484
|
-
* Uses the same path as AI responses so content flows consistently.
|
|
3485
|
-
*/
|
|
3486
|
-
streamBannerToScrollRegion() {
|
|
3487
|
-
const banner = this.buildBanner();
|
|
3488
|
-
// Stream through display to use the output interceptor
|
|
3489
|
-
// This positions cursor correctly within scroll region
|
|
3490
|
-
display.stream(banner + '\n\n');
|
|
3491
|
-
}
|
|
3492
3423
|
refreshBannerSessionInfo() {
|
|
3493
3424
|
const nextState = {
|
|
3494
3425
|
model: this.sessionState.model,
|
|
@@ -3499,11 +3430,13 @@ What's the next action?`;
|
|
|
3499
3430
|
return;
|
|
3500
3431
|
}
|
|
3501
3432
|
this.refreshContextGauge();
|
|
3502
|
-
|
|
3503
|
-
//
|
|
3433
|
+
display.updateSessionInfo(nextState.model, nextState.provider);
|
|
3434
|
+
// Update the persistent model info display in terminal input
|
|
3435
|
+
this.terminalInput.setModelInfo(this.describeModelDetail());
|
|
3504
3436
|
if (!this.isProcessing) {
|
|
3505
3437
|
this.setIdleStatus();
|
|
3506
3438
|
}
|
|
3439
|
+
// Pinned header rows are disabled; scroll region handles all output.
|
|
3507
3440
|
this.bannerSessionState = nextState;
|
|
3508
3441
|
}
|
|
3509
3442
|
providerLabel(id) {
|