erosolar-cli 1.7.315 → 1.7.317
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 +164 -229
- 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 +117 -131
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +533 -572
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/terminalInputAdapter.d.ts +20 -61
- package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
- package/dist/shell/terminalInputAdapter.js +30 -73
- 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
|
-
// Clear the entire terminal screen (including the launching command)
|
|
235
|
-
// and position cursor at top for a clean UI
|
|
236
|
-
this.terminalInput.clearScreen();
|
|
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);
|
|
@@ -520,9 +498,11 @@ export class InteractiveShell {
|
|
|
520
498
|
// Dispose unified UI adapter
|
|
521
499
|
this.uiAdapter.dispose();
|
|
522
500
|
display.newLine();
|
|
523
|
-
|
|
524
|
-
console.log(theme.
|
|
525
|
-
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)));
|
|
526
506
|
exit(0);
|
|
527
507
|
}
|
|
528
508
|
/**
|
|
@@ -692,14 +672,13 @@ export class InteractiveShell {
|
|
|
692
672
|
});
|
|
693
673
|
}
|
|
694
674
|
setProcessingStatus(detail) {
|
|
695
|
-
this.latestTokenUsage = { used: null, limit: this.latestTokenUsage.limit };
|
|
696
675
|
this.statusTracker.setBase('Working on your request', {
|
|
697
676
|
detail: this.describeStatusDetail(detail),
|
|
698
677
|
tone: 'info',
|
|
699
678
|
});
|
|
700
679
|
}
|
|
701
680
|
describeStatusDetail(detail) {
|
|
702
|
-
const parts = detail?.trim()
|
|
681
|
+
const parts = [detail?.trim() || this.describeModelDetail()];
|
|
703
682
|
const queued = this.followUpQueue.length;
|
|
704
683
|
if (queued > 0) {
|
|
705
684
|
parts.push(`${queued} follow-up${queued === 1 ? '' : 's'} queued`);
|
|
@@ -712,18 +691,12 @@ export class InteractiveShell {
|
|
|
712
691
|
}
|
|
713
692
|
refreshContextGauge() {
|
|
714
693
|
const tokens = getContextWindowTokens(this.sessionState.model);
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
if (normalizedTokens !== null) {
|
|
718
|
-
this.latestTokenUsage = {
|
|
719
|
-
used: this.latestTokenUsage.used,
|
|
720
|
-
limit: normalizedTokens,
|
|
721
|
-
};
|
|
722
|
-
}
|
|
694
|
+
this.activeContextWindowTokens =
|
|
695
|
+
typeof tokens === 'number' && Number.isFinite(tokens) ? tokens : null;
|
|
723
696
|
}
|
|
724
697
|
updateContextUsage(percentage) {
|
|
725
698
|
this.uiAdapter.updateContextUsage(percentage);
|
|
726
|
-
this.terminalInput.setContextUsage(percentage
|
|
699
|
+
this.terminalInput.setContextUsage(percentage);
|
|
727
700
|
}
|
|
728
701
|
refreshControlBar() {
|
|
729
702
|
this.terminalInput.setModeToggles({
|
|
@@ -731,9 +704,9 @@ export class InteractiveShell {
|
|
|
731
704
|
autoContinueEnabled: this.autoContinueEnabled,
|
|
732
705
|
verificationHotkey: 'alt+v',
|
|
733
706
|
autoContinueHotkey: 'alt+c',
|
|
734
|
-
thinkingModeLabel: this.thinkingMode,
|
|
735
|
-
thinkingHotkey: '/thinking',
|
|
736
707
|
});
|
|
708
|
+
// Update persistent model info display
|
|
709
|
+
this.terminalInput.setModelInfo(this.describeModelDetail());
|
|
737
710
|
this.refreshStatusLine();
|
|
738
711
|
this.terminalInput.render();
|
|
739
712
|
}
|
|
@@ -764,25 +737,6 @@ export class InteractiveShell {
|
|
|
764
737
|
// Set main status (tool execution, etc.) - shown when not overridden
|
|
765
738
|
const statusText = this.formatStatusLine(this.statusLineState);
|
|
766
739
|
this.terminalInput.setStatusMessage(statusText);
|
|
767
|
-
// Surface meta header (elapsed + context usage) above the divider
|
|
768
|
-
const elapsedSeconds = this.statusLineState
|
|
769
|
-
? Math.max(0, Math.floor((Date.now() - this.statusLineState.startedAt) / 1000))
|
|
770
|
-
: null;
|
|
771
|
-
const thinkingMs = display.isSpinnerActive() ? display.getThinkingElapsedMs() : null;
|
|
772
|
-
const tokensUsed = this.latestTokenUsage.used;
|
|
773
|
-
const tokenLimit = this.latestTokenUsage.limit ?? this.activeContextWindowTokens;
|
|
774
|
-
this.terminalInput.setMetaStatus({
|
|
775
|
-
elapsedSeconds,
|
|
776
|
-
tokensUsed,
|
|
777
|
-
tokenLimit,
|
|
778
|
-
thinkingMs,
|
|
779
|
-
thinkingHasContent: display.isSpinnerActive(),
|
|
780
|
-
});
|
|
781
|
-
// Keep model/provider visible in the controls bar
|
|
782
|
-
this.terminalInput.setModelContext({
|
|
783
|
-
model: this.sessionState.model,
|
|
784
|
-
provider: this.providerLabel(this.sessionState.provider),
|
|
785
|
-
});
|
|
786
740
|
if (forceRender) {
|
|
787
741
|
this.terminalInput.render();
|
|
788
742
|
}
|
|
@@ -842,14 +796,13 @@ export class InteractiveShell {
|
|
|
842
796
|
this.terminalInput.render();
|
|
843
797
|
}
|
|
844
798
|
/**
|
|
845
|
-
* 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.
|
|
846
801
|
*/
|
|
847
802
|
logUserPrompt(text) {
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
const formatted = `${theme.user('>')} ${text}\n`;
|
|
852
|
-
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`);
|
|
853
806
|
}
|
|
854
807
|
requestPromptRefresh(force = false) {
|
|
855
808
|
if (force) {
|
|
@@ -877,29 +830,9 @@ export class InteractiveShell {
|
|
|
877
830
|
this.uiUpdates.setMode('streaming');
|
|
878
831
|
this.streamingHeartbeatStart = Date.now();
|
|
879
832
|
this.streamingHeartbeatFrame = 0;
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
this.refreshStatusLine(true);
|
|
884
|
-
// Periodically refresh the pinned input/status region while streaming so
|
|
885
|
-
// elapsed time remains visible without interrupting the scroll region.
|
|
886
|
-
this.uiUpdates.startHeartbeat('streaming', {
|
|
887
|
-
intervalMs: 1000,
|
|
888
|
-
lane: 'heartbeat',
|
|
889
|
-
mode: ['streaming', 'processing'],
|
|
890
|
-
coalesceKey: 'streaming:heartbeat',
|
|
891
|
-
run: () => {
|
|
892
|
-
const elapsedSeconds = this.streamingHeartbeatStart
|
|
893
|
-
? Math.max(0, Math.floor((Date.now() - this.streamingHeartbeatStart) / 1000))
|
|
894
|
-
: 0;
|
|
895
|
-
this.streamingHeartbeatFrame =
|
|
896
|
-
(this.streamingHeartbeatFrame + 1) % STREAMING_SPINNER_FRAMES.length;
|
|
897
|
-
const frame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
|
|
898
|
-
this.streamingStatusLabel = this.buildStreamingStatus(`${frame} ${label}`, elapsedSeconds);
|
|
899
|
-
display.updateStreamingStatus(this.streamingStatusLabel);
|
|
900
|
-
this.refreshStatusLine(true);
|
|
901
|
-
},
|
|
902
|
-
});
|
|
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.
|
|
903
836
|
}
|
|
904
837
|
stopStreamingHeartbeat() {
|
|
905
838
|
// Exit global streaming mode - allows UI to render again
|
|
@@ -915,28 +848,10 @@ export class InteractiveShell {
|
|
|
915
848
|
// Force refresh to update the input area now that streaming has ended
|
|
916
849
|
this.refreshStatusLine(true);
|
|
917
850
|
}
|
|
918
|
-
buildStreamingStatus(label
|
|
851
|
+
buildStreamingStatus(label) {
|
|
919
852
|
const detail = this.describeModelDetail();
|
|
920
|
-
const
|
|
921
|
-
|
|
922
|
-
: null;
|
|
923
|
-
const prefix = theme.info('⏺');
|
|
924
|
-
const parts = [label];
|
|
925
|
-
if (detail) {
|
|
926
|
-
parts.push(theme.ui.muted('·'), detail);
|
|
927
|
-
}
|
|
928
|
-
if (elapsedLabel) {
|
|
929
|
-
parts.push(theme.ui.muted('·'), elapsedLabel);
|
|
930
|
-
}
|
|
931
|
-
return `${prefix} ${parts.join(' ')}`.trim();
|
|
932
|
-
}
|
|
933
|
-
formatElapsedShort(seconds) {
|
|
934
|
-
if (seconds < 60) {
|
|
935
|
-
return `${seconds}s`;
|
|
936
|
-
}
|
|
937
|
-
const minutes = Math.floor(seconds / 60);
|
|
938
|
-
const remaining = seconds % 60;
|
|
939
|
-
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}`;
|
|
940
855
|
}
|
|
941
856
|
refreshQueueIndicators() {
|
|
942
857
|
if (this.isProcessing) {
|
|
@@ -1184,6 +1099,17 @@ export class InteractiveShell {
|
|
|
1184
1099
|
case '/discover':
|
|
1185
1100
|
await this.discoverModelsCommand();
|
|
1186
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;
|
|
1187
1113
|
default:
|
|
1188
1114
|
if (!(await this.tryCustomSlashCommand(command, input))) {
|
|
1189
1115
|
display.showWarning(`Unknown command "${command}".`);
|
|
@@ -1492,6 +1418,99 @@ export class InteractiveShell {
|
|
|
1492
1418
|
// Display keyboard shortcuts help (Claude Code style)
|
|
1493
1419
|
display.showSystemMessage(formatShortcutsHelp());
|
|
1494
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
|
+
}
|
|
1495
1514
|
showFileChangeSummary() {
|
|
1496
1515
|
const summary = this._fileChangeTracker.getSummary();
|
|
1497
1516
|
const changes = this._fileChangeTracker.getAllChanges();
|
|
@@ -1534,11 +1553,11 @@ export class InteractiveShell {
|
|
|
1534
1553
|
display.showSystemMessage(lines.join('\n'));
|
|
1535
1554
|
}
|
|
1536
1555
|
showAlphaZeroMetrics() {
|
|
1537
|
-
const summary = this.
|
|
1556
|
+
const summary = this.sessionMetrics.getPerformanceSummary();
|
|
1538
1557
|
display.showSystemMessage(summary);
|
|
1539
1558
|
}
|
|
1540
1559
|
showImprovementSuggestions() {
|
|
1541
|
-
const suggestions = this.
|
|
1560
|
+
const suggestions = this.sessionMetrics.getImprovementSuggestions();
|
|
1542
1561
|
if (suggestions.length === 0) {
|
|
1543
1562
|
display.showInfo('No improvement suggestions at this time. Keep using the shell to generate metrics!');
|
|
1544
1563
|
return;
|
|
@@ -1584,9 +1603,7 @@ export class InteractiveShell {
|
|
|
1584
1603
|
}
|
|
1585
1604
|
}
|
|
1586
1605
|
lines.push(theme.secondary('CLI Flags:'));
|
|
1587
|
-
lines.push(' --alpha-zero Enable Alpha Zero 2 RL framework');
|
|
1588
1606
|
lines.push(' --coding Enable enhanced coding tools');
|
|
1589
|
-
lines.push(' --security Enable security research tools');
|
|
1590
1607
|
lines.push(' --all-plugins Enable all optional plugins');
|
|
1591
1608
|
display.showSystemMessage(lines.join('\n'));
|
|
1592
1609
|
}
|
|
@@ -1830,75 +1847,6 @@ export class InteractiveShell {
|
|
|
1830
1847
|
}
|
|
1831
1848
|
return `${warning.label}: ${warning.reason}.`;
|
|
1832
1849
|
}
|
|
1833
|
-
buildLaunchCommandPalette() {
|
|
1834
|
-
const entries = [];
|
|
1835
|
-
const secretsSummary = this.summarizeSecretsForPalette();
|
|
1836
|
-
const toolSummary = this.getToolSelectionSummary();
|
|
1837
|
-
const autosaveLabel = this.autosaveEnabled ? 'on' : 'off';
|
|
1838
|
-
for (const command of this.slashCommands) {
|
|
1839
|
-
const entry = {
|
|
1840
|
-
command: command.command,
|
|
1841
|
-
description: command.description,
|
|
1842
|
-
category: command.category ?? 'other',
|
|
1843
|
-
};
|
|
1844
|
-
switch (command.command) {
|
|
1845
|
-
case '/secrets':
|
|
1846
|
-
if (secretsSummary.text) {
|
|
1847
|
-
entry.description = `${command.description} (${secretsSummary.text})`;
|
|
1848
|
-
entry.tone = secretsSummary.tone;
|
|
1849
|
-
}
|
|
1850
|
-
break;
|
|
1851
|
-
case '/tools':
|
|
1852
|
-
if (toolSummary) {
|
|
1853
|
-
entry.description = `${command.description} (${toolSummary})`;
|
|
1854
|
-
}
|
|
1855
|
-
break;
|
|
1856
|
-
case '/sessions':
|
|
1857
|
-
entry.description = `${command.description} (autosave ${autosaveLabel})`;
|
|
1858
|
-
break;
|
|
1859
|
-
case '/model':
|
|
1860
|
-
entry.description = `${command.description} (current: ${this.sessionState.model})`;
|
|
1861
|
-
break;
|
|
1862
|
-
case '/provider':
|
|
1863
|
-
entry.description = `${command.description} (current: ${this.providerLabel(this.sessionState.provider)})`;
|
|
1864
|
-
break;
|
|
1865
|
-
default:
|
|
1866
|
-
break;
|
|
1867
|
-
}
|
|
1868
|
-
entries.push(entry);
|
|
1869
|
-
}
|
|
1870
|
-
return entries;
|
|
1871
|
-
}
|
|
1872
|
-
summarizeSecretsForPalette() {
|
|
1873
|
-
const definitions = listSecretDefinitions();
|
|
1874
|
-
if (!definitions.length) {
|
|
1875
|
-
return { text: null };
|
|
1876
|
-
}
|
|
1877
|
-
const missing = definitions.filter((definition) => !getSecretValue(definition.id));
|
|
1878
|
-
if (missing.length === 0) {
|
|
1879
|
-
return { text: 'all configured', tone: 'success' };
|
|
1880
|
-
}
|
|
1881
|
-
const labels = missing.map((definition) => definition.label ?? definition.id);
|
|
1882
|
-
return { text: `missing ${this.formatList(labels)}`, tone: 'warn' };
|
|
1883
|
-
}
|
|
1884
|
-
getToolSelectionSummary() {
|
|
1885
|
-
const toolSettings = loadToolSettings();
|
|
1886
|
-
const selection = buildEnabledToolSet(toolSettings);
|
|
1887
|
-
const options = getToolToggleOptions();
|
|
1888
|
-
if (!options.length) {
|
|
1889
|
-
return null;
|
|
1890
|
-
}
|
|
1891
|
-
const enabledCount = options.filter((option) => selection.has(option.id)).length;
|
|
1892
|
-
return `${enabledCount}/${options.length} enabled`;
|
|
1893
|
-
}
|
|
1894
|
-
formatList(values, maxItems = 3) {
|
|
1895
|
-
if (!values.length) {
|
|
1896
|
-
return '';
|
|
1897
|
-
}
|
|
1898
|
-
const shown = values.slice(0, maxItems);
|
|
1899
|
-
const suffix = values.length > maxItems ? ', …' : '';
|
|
1900
|
-
return `${shown.join(', ')}${suffix}`;
|
|
1901
|
-
}
|
|
1902
1850
|
buildSlashCommandList(header) {
|
|
1903
1851
|
const lines = [theme.gradient.primary(header), ''];
|
|
1904
1852
|
for (const command of this.slashCommands) {
|
|
@@ -2367,7 +2315,7 @@ export class InteractiveShell {
|
|
|
2367
2315
|
this.autosaveIfEnabled();
|
|
2368
2316
|
// Track metrics with Alpha Zero 2
|
|
2369
2317
|
const elapsedMs = Date.now() - requestStartTime;
|
|
2370
|
-
this.
|
|
2318
|
+
this.sessionMetrics.recordMessage(elapsedMs);
|
|
2371
2319
|
if (!responseText?.trim()) {
|
|
2372
2320
|
display.showWarning('The provider returned an empty response. Check your API key/provider selection or retry the prompt.');
|
|
2373
2321
|
}
|
|
@@ -2385,10 +2333,14 @@ export class InteractiveShell {
|
|
|
2385
2333
|
this.stopStreamingHeartbeat();
|
|
2386
2334
|
this.isProcessing = false;
|
|
2387
2335
|
this.terminalInput.setStreaming(false);
|
|
2336
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2388
2337
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2389
2338
|
this.setIdleStatus();
|
|
2390
2339
|
display.newLine();
|
|
2391
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();
|
|
2392
2344
|
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
2393
2345
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
2394
2346
|
// Claude Code style: New prompt naturally appears at bottom
|
|
@@ -2465,14 +2417,13 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
|
|
|
2465
2417
|
try {
|
|
2466
2418
|
// Send the request and capture the response (streaming disabled)
|
|
2467
2419
|
display.showThinking('Responding...');
|
|
2468
|
-
this.refreshStatusLine(true);
|
|
2469
2420
|
const response = await agent.send(currentPrompt, true);
|
|
2470
2421
|
await this.awaitPendingCleanup();
|
|
2471
2422
|
this.captureHistorySnapshot();
|
|
2472
2423
|
this.autosaveIfEnabled();
|
|
2473
2424
|
// Track metrics
|
|
2474
2425
|
const elapsedMs = Date.now() - overallStartTime;
|
|
2475
|
-
this.
|
|
2426
|
+
this.sessionMetrics.recordMessage(elapsedMs);
|
|
2476
2427
|
if (!response?.trim()) {
|
|
2477
2428
|
display.showWarning('Model returned an empty response. Retrying this iteration...');
|
|
2478
2429
|
consecutiveNoProgress++;
|
|
@@ -2609,6 +2560,7 @@ What's the next action?`;
|
|
|
2609
2560
|
this.stopStreamingHeartbeat();
|
|
2610
2561
|
this.isProcessing = false;
|
|
2611
2562
|
this.terminalInput.setStreaming(false);
|
|
2563
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2612
2564
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2613
2565
|
this.setIdleStatus();
|
|
2614
2566
|
this.updateStatusMessage(null);
|
|
@@ -2965,10 +2917,8 @@ What's the next action?`;
|
|
|
2965
2917
|
try {
|
|
2966
2918
|
// Send the error to the agent for fixing
|
|
2967
2919
|
display.showThinking('Analyzing build errors');
|
|
2968
|
-
this.refreshStatusLine(true);
|
|
2969
2920
|
const response = await this.agent.send(prompt, true);
|
|
2970
2921
|
display.stopThinking();
|
|
2971
|
-
this.refreshStatusLine(true);
|
|
2972
2922
|
if (response) {
|
|
2973
2923
|
display.showAssistantMessage(response, { isFinal: true });
|
|
2974
2924
|
}
|
|
@@ -2995,8 +2945,8 @@ What's the next action?`;
|
|
|
2995
2945
|
};
|
|
2996
2946
|
this.agent = this.runtimeSession.createAgent(selection, {
|
|
2997
2947
|
onStreamChunk: (chunk) => {
|
|
2998
|
-
// Stream output
|
|
2999
|
-
|
|
2948
|
+
// Stream output directly - no spinner during streaming to avoid race conditions
|
|
2949
|
+
display.stream(chunk);
|
|
3000
2950
|
},
|
|
3001
2951
|
onStreamFallback: (info) => this.handleStreamingFallback(info),
|
|
3002
2952
|
onAssistantMessage: (content, metadata) => {
|
|
@@ -3018,16 +2968,18 @@ What's the next action?`;
|
|
|
3018
2968
|
display.showAssistantMessage(finalContent, enriched);
|
|
3019
2969
|
}
|
|
3020
2970
|
}
|
|
3021
|
-
//
|
|
2971
|
+
// Show status line at end (Claude Code style: "• Context X% used • Ready for prompts (2s)")
|
|
3022
2972
|
display.stopThinking();
|
|
3023
|
-
//
|
|
2973
|
+
// Calculate context usage
|
|
2974
|
+
let contextInfo;
|
|
3024
2975
|
if (enriched.contextWindowTokens && metadata.usage) {
|
|
3025
2976
|
const total = this.totalTokens(metadata.usage);
|
|
3026
2977
|
if (total && total > 0) {
|
|
3027
2978
|
const percentage = Math.round((total / enriched.contextWindowTokens) * 100);
|
|
3028
|
-
|
|
2979
|
+
contextInfo = { percentage, tokens: total };
|
|
3029
2980
|
}
|
|
3030
2981
|
}
|
|
2982
|
+
display.showStatusLine('Ready for prompts', enriched.elapsedMs, contextInfo);
|
|
3031
2983
|
// Auto-verify changes: build first (catches type errors), then tests
|
|
3032
2984
|
void this.enforceAutoBuild('final-response');
|
|
3033
2985
|
void this.enforceAutoTests('final-response');
|
|
@@ -3097,6 +3049,7 @@ What's the next action?`;
|
|
|
3097
3049
|
this.stopStreamingHeartbeat();
|
|
3098
3050
|
this.updateStatusMessage(null);
|
|
3099
3051
|
this.terminalInput.setStreaming(false);
|
|
3052
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3100
3053
|
this.terminalInput.render();
|
|
3101
3054
|
},
|
|
3102
3055
|
onVerificationNeeded: () => {
|
|
@@ -3133,6 +3086,7 @@ What's the next action?`;
|
|
|
3133
3086
|
resetChatBoxAfterModelSwap() {
|
|
3134
3087
|
this.updateStatusMessage(null);
|
|
3135
3088
|
this.terminalInput.setStreaming(false);
|
|
3089
|
+
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3136
3090
|
this.terminalInput.render();
|
|
3137
3091
|
this.ensureReadlineReady();
|
|
3138
3092
|
}
|
|
@@ -3197,14 +3151,9 @@ What's the next action?`;
|
|
|
3197
3151
|
return null;
|
|
3198
3152
|
}
|
|
3199
3153
|
const usageRatio = total / windowTokens;
|
|
3200
|
-
this.latestTokenUsage = {
|
|
3201
|
-
used: total,
|
|
3202
|
-
limit: windowTokens,
|
|
3203
|
-
};
|
|
3204
3154
|
// Always update context usage in the UI
|
|
3205
3155
|
const percentUsed = Math.round(usageRatio * 100);
|
|
3206
3156
|
this.updateContextUsage(percentUsed);
|
|
3207
|
-
this.refreshStatusLine(true);
|
|
3208
3157
|
if (usageRatio < CONTEXT_USAGE_THRESHOLD) {
|
|
3209
3158
|
return null;
|
|
3210
3159
|
}
|
|
@@ -3471,22 +3420,6 @@ What's the next action?`;
|
|
|
3471
3420
|
this.sessionState.reasoningEffort = preset.reasoningEffort;
|
|
3472
3421
|
}
|
|
3473
3422
|
}
|
|
3474
|
-
/**
|
|
3475
|
-
* Build the session banner.
|
|
3476
|
-
*/
|
|
3477
|
-
buildBanner() {
|
|
3478
|
-
const terminalWidth = output.columns ?? 100;
|
|
3479
|
-
const width = Math.min(terminalWidth - 4, 110);
|
|
3480
|
-
return renderSessionFrame({
|
|
3481
|
-
profileLabel: this.profileLabel,
|
|
3482
|
-
profileName: this.profile,
|
|
3483
|
-
model: this.sessionState.model,
|
|
3484
|
-
provider: this.sessionState.provider,
|
|
3485
|
-
workspace: this.workingDir,
|
|
3486
|
-
version: this.version,
|
|
3487
|
-
width,
|
|
3488
|
-
});
|
|
3489
|
-
}
|
|
3490
3423
|
refreshBannerSessionInfo() {
|
|
3491
3424
|
const nextState = {
|
|
3492
3425
|
model: this.sessionState.model,
|
|
@@ -3497,11 +3430,13 @@ What's the next action?`;
|
|
|
3497
3430
|
return;
|
|
3498
3431
|
}
|
|
3499
3432
|
this.refreshContextGauge();
|
|
3500
|
-
|
|
3501
|
-
//
|
|
3433
|
+
display.updateSessionInfo(nextState.model, nextState.provider);
|
|
3434
|
+
// Update the persistent model info display in terminal input
|
|
3435
|
+
this.terminalInput.setModelInfo(this.describeModelDetail());
|
|
3502
3436
|
if (!this.isProcessing) {
|
|
3503
3437
|
this.setIdleStatus();
|
|
3504
3438
|
}
|
|
3439
|
+
// Pinned header rows are disabled; scroll region handles all output.
|
|
3505
3440
|
this.bannerSessionState = nextState;
|
|
3506
3441
|
}
|
|
3507
3442
|
providerLabel(id) {
|