erosolar-cli 1.7.326 → 1.7.327
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 +24 -148
- package/dist/bin/erosolar.js +5 -21
- package/dist/bin/erosolar.js.map +1 -1
- package/dist/capabilities/agentSpawningCapability.d.ts.map +1 -1
- package/dist/capabilities/agentSpawningCapability.js +56 -31
- package/dist/capabilities/agentSpawningCapability.js.map +1 -1
- package/dist/contracts/agent-schemas.json +0 -15
- package/dist/contracts/tools.schema.json +0 -9
- 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/customCommands.d.ts +1 -0
- package/dist/core/customCommands.d.ts.map +1 -1
- package/dist/core/customCommands.js +3 -0
- package/dist/core/customCommands.js.map +1 -1
- package/dist/core/hooks.d.ts +113 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +267 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/metricsTracker.d.ts +122 -0
- package/dist/core/metricsTracker.d.ts.map +1 -0
- package/dist/{alpha-zero → core}/metricsTracker.js +2 -5
- package/dist/core/metricsTracker.js.map +1 -0
- package/dist/core/securityAssessment.d.ts +91 -0
- package/dist/core/securityAssessment.d.ts.map +1 -0
- package/dist/core/securityAssessment.js +580 -0
- package/dist/core/securityAssessment.js.map +1 -0
- package/dist/core/toolPreconditions.d.ts.map +1 -1
- package/dist/core/toolPreconditions.js +0 -14
- package/dist/core/toolPreconditions.js.map +1 -1
- package/dist/core/toolRuntime.d.ts +22 -1
- package/dist/core/toolRuntime.d.ts.map +1 -1
- package/dist/core/toolRuntime.js +0 -5
- package/dist/core/toolRuntime.js.map +1 -1
- package/dist/core/toolValidation.d.ts.map +1 -1
- package/dist/core/toolValidation.js +14 -3
- package/dist/core/toolValidation.js.map +1 -1
- package/dist/core/validationRunner.d.ts +1 -3
- package/dist/core/validationRunner.d.ts.map +1 -1
- package/dist/core/validationRunner.js.map +1 -1
- package/dist/core/verification.d.ts +137 -0
- package/dist/core/verification.d.ts.map +1 -0
- package/dist/core/verification.js +323 -0
- package/dist/core/verification.js.map +1 -0
- package/dist/headless/headlessApp.d.ts.map +1 -1
- package/dist/headless/headlessApp.js +21 -0
- package/dist/headless/headlessApp.js.map +1 -1
- package/dist/mcp/sseClient.d.ts.map +1 -1
- package/dist/mcp/sseClient.js +9 -18
- package/dist/mcp/sseClient.js.map +1 -1
- package/dist/plugins/tools/build/buildPlugin.d.ts +0 -6
- package/dist/plugins/tools/build/buildPlugin.d.ts.map +1 -1
- package/dist/plugins/tools/build/buildPlugin.js +4 -10
- package/dist/plugins/tools/build/buildPlugin.js.map +1 -1
- package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -1
- package/dist/plugins/tools/nodeDefaults.js +0 -2
- package/dist/plugins/tools/nodeDefaults.js.map +1 -1
- 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/shell/interactiveShell.d.ts +16 -7
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +235 -164
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/shellApp.d.ts +2 -0
- package/dist/shell/shellApp.d.ts.map +1 -1
- package/dist/shell/shellApp.js +40 -9
- package/dist/shell/shellApp.js.map +1 -1
- package/dist/shell/systemPrompt.d.ts.map +1 -1
- package/dist/shell/systemPrompt.js +1 -4
- package/dist/shell/systemPrompt.js.map +1 -1
- package/dist/shell/terminalInput.d.ts +149 -116
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +639 -521
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/terminalInputAdapter.d.ts +79 -20
- package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
- package/dist/shell/terminalInputAdapter.js +99 -30
- package/dist/shell/terminalInputAdapter.js.map +1 -1
- package/dist/subagents/agentConfig.d.ts +27 -0
- package/dist/subagents/agentConfig.d.ts.map +1 -0
- package/dist/subagents/agentConfig.js +89 -0
- package/dist/subagents/agentConfig.js.map +1 -0
- package/dist/subagents/agentRegistry.d.ts +33 -0
- package/dist/subagents/agentRegistry.d.ts.map +1 -0
- package/dist/subagents/agentRegistry.js +162 -0
- package/dist/subagents/agentRegistry.js.map +1 -0
- package/dist/subagents/taskRunner.d.ts +7 -1
- package/dist/subagents/taskRunner.d.ts.map +1 -1
- package/dist/subagents/taskRunner.js +180 -47
- package/dist/subagents/taskRunner.js.map +1 -1
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +13 -12
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/display.d.ts +24 -45
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +140 -259
- package/dist/ui/display.js.map +1 -1
- package/dist/ui/theme.d.ts.map +1 -1
- package/dist/ui/theme.js +6 -8
- package/dist/ui/theme.js.map +1 -1
- package/dist/ui/toolDisplay.d.ts +0 -158
- package/dist/ui/toolDisplay.d.ts.map +1 -1
- package/dist/ui/toolDisplay.js +0 -348
- package/dist/ui/toolDisplay.js.map +1 -1
- package/dist/ui/unified/layout.d.ts +1 -0
- package/dist/ui/unified/layout.d.ts.map +1 -1
- package/dist/ui/unified/layout.js +15 -25
- package/dist/ui/unified/layout.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +10 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +78 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/package.json +4 -4
- package/dist/alpha-zero/agentWrapper.d.ts +0 -84
- package/dist/alpha-zero/agentWrapper.d.ts.map +0 -1
- package/dist/alpha-zero/agentWrapper.js +0 -171
- package/dist/alpha-zero/agentWrapper.js.map +0 -1
- package/dist/alpha-zero/codeEvaluator.d.ts +0 -25
- package/dist/alpha-zero/codeEvaluator.d.ts.map +0 -1
- package/dist/alpha-zero/codeEvaluator.js +0 -273
- package/dist/alpha-zero/codeEvaluator.js.map +0 -1
- package/dist/alpha-zero/competitiveRunner.d.ts +0 -66
- package/dist/alpha-zero/competitiveRunner.d.ts.map +0 -1
- package/dist/alpha-zero/competitiveRunner.js +0 -224
- package/dist/alpha-zero/competitiveRunner.js.map +0 -1
- package/dist/alpha-zero/index.d.ts +0 -67
- package/dist/alpha-zero/index.d.ts.map +0 -1
- package/dist/alpha-zero/index.js +0 -99
- package/dist/alpha-zero/index.js.map +0 -1
- package/dist/alpha-zero/introspection.d.ts +0 -128
- package/dist/alpha-zero/introspection.d.ts.map +0 -1
- package/dist/alpha-zero/introspection.js +0 -300
- package/dist/alpha-zero/introspection.js.map +0 -1
- package/dist/alpha-zero/metricsTracker.d.ts +0 -71
- package/dist/alpha-zero/metricsTracker.d.ts.map +0 -1
- package/dist/alpha-zero/metricsTracker.js.map +0 -1
- package/dist/alpha-zero/security/core.d.ts +0 -125
- package/dist/alpha-zero/security/core.d.ts.map +0 -1
- package/dist/alpha-zero/security/core.js +0 -271
- package/dist/alpha-zero/security/core.js.map +0 -1
- package/dist/alpha-zero/security/google.d.ts +0 -125
- package/dist/alpha-zero/security/google.d.ts.map +0 -1
- package/dist/alpha-zero/security/google.js +0 -311
- package/dist/alpha-zero/security/google.js.map +0 -1
- package/dist/alpha-zero/security/googleLoader.d.ts +0 -17
- package/dist/alpha-zero/security/googleLoader.d.ts.map +0 -1
- package/dist/alpha-zero/security/googleLoader.js +0 -41
- package/dist/alpha-zero/security/googleLoader.js.map +0 -1
- package/dist/alpha-zero/security/index.d.ts +0 -29
- package/dist/alpha-zero/security/index.d.ts.map +0 -1
- package/dist/alpha-zero/security/index.js +0 -32
- package/dist/alpha-zero/security/index.js.map +0 -1
- package/dist/alpha-zero/security/simulation.d.ts +0 -124
- package/dist/alpha-zero/security/simulation.d.ts.map +0 -1
- package/dist/alpha-zero/security/simulation.js +0 -277
- package/dist/alpha-zero/security/simulation.js.map +0 -1
- package/dist/alpha-zero/selfModification.d.ts +0 -109
- package/dist/alpha-zero/selfModification.d.ts.map +0 -1
- package/dist/alpha-zero/selfModification.js +0 -233
- package/dist/alpha-zero/selfModification.js.map +0 -1
- package/dist/alpha-zero/types.d.ts +0 -170
- package/dist/alpha-zero/types.d.ts.map +0 -1
- package/dist/alpha-zero/types.js +0 -31
- package/dist/alpha-zero/types.js.map +0 -1
- package/dist/capabilities/securityTestingCapability.d.ts +0 -13
- package/dist/capabilities/securityTestingCapability.d.ts.map +0 -1
- package/dist/capabilities/securityTestingCapability.js +0 -25
- package/dist/capabilities/securityTestingCapability.js.map +0 -1
- package/dist/core/aiFlowOptimizer.d.ts +0 -26
- package/dist/core/aiFlowOptimizer.d.ts.map +0 -1
- package/dist/core/aiFlowOptimizer.js +0 -31
- package/dist/core/aiFlowOptimizer.js.map +0 -1
- package/dist/core/aiOptimizationEngine.d.ts +0 -158
- package/dist/core/aiOptimizationEngine.d.ts.map +0 -1
- package/dist/core/aiOptimizationEngine.js +0 -428
- package/dist/core/aiOptimizationEngine.js.map +0 -1
- package/dist/core/aiOptimizationIntegration.d.ts +0 -93
- package/dist/core/aiOptimizationIntegration.d.ts.map +0 -1
- package/dist/core/aiOptimizationIntegration.js +0 -250
- package/dist/core/aiOptimizationIntegration.js.map +0 -1
- package/dist/core/enhancedErrorRecovery.d.ts +0 -100
- package/dist/core/enhancedErrorRecovery.d.ts.map +0 -1
- package/dist/core/enhancedErrorRecovery.js +0 -345
- package/dist/core/enhancedErrorRecovery.js.map +0 -1
- package/dist/core/hooksSystem.d.ts +0 -65
- package/dist/core/hooksSystem.d.ts.map +0 -1
- package/dist/core/hooksSystem.js +0 -273
- package/dist/core/hooksSystem.js.map +0 -1
- package/dist/core/memorySystem.d.ts +0 -48
- package/dist/core/memorySystem.d.ts.map +0 -1
- package/dist/core/memorySystem.js +0 -271
- package/dist/core/memorySystem.js.map +0 -1
- package/dist/core/unified/errors.d.ts +0 -189
- package/dist/core/unified/errors.d.ts.map +0 -1
- package/dist/core/unified/errors.js +0 -497
- package/dist/core/unified/errors.js.map +0 -1
- package/dist/core/unified/index.d.ts +0 -19
- package/dist/core/unified/index.d.ts.map +0 -1
- package/dist/core/unified/index.js +0 -68
- package/dist/core/unified/index.js.map +0 -1
- package/dist/core/unified/schema.d.ts +0 -101
- package/dist/core/unified/schema.d.ts.map +0 -1
- package/dist/core/unified/schema.js +0 -350
- package/dist/core/unified/schema.js.map +0 -1
- package/dist/core/unified/toolRuntime.d.ts +0 -179
- package/dist/core/unified/toolRuntime.d.ts.map +0 -1
- package/dist/core/unified/toolRuntime.js +0 -517
- package/dist/core/unified/toolRuntime.js.map +0 -1
- package/dist/core/unified/tools.d.ts +0 -127
- package/dist/core/unified/tools.d.ts.map +0 -1
- package/dist/core/unified/tools.js +0 -1333
- package/dist/core/unified/tools.js.map +0 -1
- package/dist/core/unified/types.d.ts +0 -352
- package/dist/core/unified/types.d.ts.map +0 -1
- package/dist/core/unified/types.js +0 -12
- package/dist/core/unified/types.js.map +0 -1
- package/dist/core/unified/version.d.ts +0 -209
- package/dist/core/unified/version.d.ts.map +0 -1
- package/dist/core/unified/version.js +0 -454
- package/dist/core/unified/version.js.map +0 -1
- package/dist/plugins/tools/security/securityPlugin.d.ts +0 -3
- package/dist/plugins/tools/security/securityPlugin.d.ts.map +0 -1
- package/dist/plugins/tools/security/securityPlugin.js +0 -12
- package/dist/plugins/tools/security/securityPlugin.js.map +0 -1
- package/dist/security/active-stack-security.d.ts +0 -112
- package/dist/security/active-stack-security.d.ts.map +0 -1
- package/dist/security/active-stack-security.js +0 -296
- package/dist/security/active-stack-security.js.map +0 -1
- package/dist/security/advanced-persistence-research.d.ts +0 -92
- package/dist/security/advanced-persistence-research.d.ts.map +0 -1
- package/dist/security/advanced-persistence-research.js +0 -195
- package/dist/security/advanced-persistence-research.js.map +0 -1
- package/dist/security/advanced-targeting.d.ts +0 -119
- package/dist/security/advanced-targeting.d.ts.map +0 -1
- package/dist/security/advanced-targeting.js +0 -233
- package/dist/security/advanced-targeting.js.map +0 -1
- package/dist/security/assessment/vulnerabilityAssessment.d.ts +0 -104
- package/dist/security/assessment/vulnerabilityAssessment.d.ts.map +0 -1
- package/dist/security/assessment/vulnerabilityAssessment.js +0 -315
- package/dist/security/assessment/vulnerabilityAssessment.js.map +0 -1
- package/dist/security/authorization/securityAuthorization.d.ts +0 -88
- package/dist/security/authorization/securityAuthorization.d.ts.map +0 -1
- package/dist/security/authorization/securityAuthorization.js +0 -172
- package/dist/security/authorization/securityAuthorization.js.map +0 -1
- package/dist/security/comprehensive-targeting.d.ts +0 -85
- package/dist/security/comprehensive-targeting.d.ts.map +0 -1
- package/dist/security/comprehensive-targeting.js +0 -438
- package/dist/security/comprehensive-targeting.js.map +0 -1
- package/dist/security/global-security-integration.d.ts +0 -91
- package/dist/security/global-security-integration.d.ts.map +0 -1
- package/dist/security/global-security-integration.js +0 -218
- package/dist/security/global-security-integration.js.map +0 -1
- package/dist/security/index.d.ts +0 -38
- package/dist/security/index.d.ts.map +0 -1
- package/dist/security/index.js +0 -47
- package/dist/security/index.js.map +0 -1
- package/dist/security/persistence-analyzer.d.ts +0 -56
- package/dist/security/persistence-analyzer.d.ts.map +0 -1
- package/dist/security/persistence-analyzer.js +0 -187
- package/dist/security/persistence-analyzer.js.map +0 -1
- package/dist/security/persistence-cli.d.ts +0 -36
- package/dist/security/persistence-cli.d.ts.map +0 -1
- package/dist/security/persistence-cli.js +0 -160
- package/dist/security/persistence-cli.js.map +0 -1
- package/dist/security/persistence-research.d.ts +0 -92
- package/dist/security/persistence-research.d.ts.map +0 -1
- package/dist/security/persistence-research.js +0 -364
- package/dist/security/persistence-research.js.map +0 -1
- package/dist/security/research/persistenceResearch.d.ts +0 -97
- package/dist/security/research/persistenceResearch.d.ts.map +0 -1
- package/dist/security/research/persistenceResearch.js +0 -282
- package/dist/security/research/persistenceResearch.js.map +0 -1
- package/dist/security/security-integration.d.ts +0 -74
- package/dist/security/security-integration.d.ts.map +0 -1
- package/dist/security/security-integration.js +0 -137
- package/dist/security/security-integration.js.map +0 -1
- package/dist/security/security-testing-framework.d.ts +0 -112
- package/dist/security/security-testing-framework.d.ts.map +0 -1
- package/dist/security/security-testing-framework.js +0 -364
- package/dist/security/security-testing-framework.js.map +0 -1
- package/dist/security/simulation/attackSimulation.d.ts +0 -93
- package/dist/security/simulation/attackSimulation.d.ts.map +0 -1
- package/dist/security/simulation/attackSimulation.js +0 -341
- package/dist/security/simulation/attackSimulation.js.map +0 -1
- package/dist/security/strategic-operations.d.ts +0 -100
- package/dist/security/strategic-operations.d.ts.map +0 -1
- package/dist/security/strategic-operations.js +0 -276
- package/dist/security/strategic-operations.js.map +0 -1
- package/dist/security/tool-security-wrapper.d.ts +0 -58
- package/dist/security/tool-security-wrapper.d.ts.map +0 -1
- package/dist/security/tool-security-wrapper.js +0 -156
- package/dist/security/tool-security-wrapper.js.map +0 -1
- package/dist/shell/claudeCodeStreamHandler.d.ts +0 -145
- package/dist/shell/claudeCodeStreamHandler.d.ts.map +0 -1
- package/dist/shell/claudeCodeStreamHandler.js +0 -322
- package/dist/shell/claudeCodeStreamHandler.js.map +0 -1
- package/dist/shell/inputQueueManager.d.ts +0 -144
- package/dist/shell/inputQueueManager.d.ts.map +0 -1
- package/dist/shell/inputQueueManager.js +0 -290
- package/dist/shell/inputQueueManager.js.map +0 -1
- package/dist/shell/metricsTracker.d.ts +0 -60
- package/dist/shell/metricsTracker.d.ts.map +0 -1
- package/dist/shell/metricsTracker.js +0 -119
- package/dist/shell/metricsTracker.js.map +0 -1
- package/dist/shell/streamingOutputManager.d.ts +0 -115
- package/dist/shell/streamingOutputManager.d.ts.map +0 -1
- package/dist/shell/streamingOutputManager.js +0 -225
- package/dist/shell/streamingOutputManager.js.map +0 -1
- package/dist/tools/securityTools.d.ts +0 -22
- package/dist/tools/securityTools.d.ts.map +0 -1
- package/dist/tools/securityTools.js +0 -448
- package/dist/tools/securityTools.js.map +0 -1
- package/dist/ui/persistentPrompt.d.ts +0 -50
- package/dist/ui/persistentPrompt.d.ts.map +0 -1
- package/dist/ui/persistentPrompt.js +0 -92
- package/dist/ui/persistentPrompt.js.map +0 -1
- package/dist/ui/terminalUISchema.d.ts +0 -195
- package/dist/ui/terminalUISchema.d.ts.map +0 -1
- package/dist/ui/terminalUISchema.js +0 -113
- package/dist/ui/terminalUISchema.js.map +0 -1
- package/scripts/deploy-security-capabilities.js +0 -178
|
@@ -2,7 +2,7 @@ import { stdin as input, stdout as output, exit } from 'node:process';
|
|
|
2
2
|
import { exec } from 'node:child_process';
|
|
3
3
|
import { promisify } from 'node:util';
|
|
4
4
|
import { display } from '../ui/display.js';
|
|
5
|
-
import { theme
|
|
5
|
+
import { theme } from '../ui/theme.js';
|
|
6
6
|
import { getContextWindowTokens } from '../core/contextWindow.js';
|
|
7
7
|
import { ensureSecretForProvider, getSecretDefinitionForProvider, getSecretValue, listSecretDefinitions, maskSecret, setSecretValue, } from '../core/secretStore.js';
|
|
8
8
|
import { saveActiveProfilePreference, saveModelPreference, loadToolSettings, saveToolSettings, clearToolSettings, clearActiveProfilePreference, loadSessionPreferences, saveSessionPreferences, } from '../core/preferences.js';
|
|
@@ -19,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 '../core/metricsTracker.js';
|
|
23
23
|
import { listAvailablePlugins } from '../plugins/index.js';
|
|
24
|
-
import { loadMemory, listMemoryPaths, getDefaultProjectMemoryPath, getUserMemoryEditPath, } from '../core/memorySystem.js';
|
|
25
24
|
import { TerminalInputAdapter } from './terminalInputAdapter.js';
|
|
26
|
-
import {
|
|
25
|
+
import { renderSessionFrame } from '../ui/unified/layout.js';
|
|
26
|
+
import { isUpdateInProgress, maybeOfferCliUpdate } 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,6 +35,7 @@ const DROPDOWN_COLORS = [
|
|
|
35
35
|
theme.success,
|
|
36
36
|
theme.warning,
|
|
37
37
|
];
|
|
38
|
+
const STREAMING_SPINNER_FRAMES = ['◐', '◓', '◑', '◒'];
|
|
38
39
|
// Load MODEL_PRESETS from centralized schema
|
|
39
40
|
const MODEL_PRESETS = getModels().map((model) => ({
|
|
40
41
|
id: model.id,
|
|
@@ -49,11 +50,13 @@ const MODEL_PRESETS = getModels().map((model) => ({
|
|
|
49
50
|
const BASE_SLASH_COMMANDS = getSlashCommands().map((cmd) => ({
|
|
50
51
|
command: cmd.command,
|
|
51
52
|
description: cmd.description,
|
|
53
|
+
category: cmd.category,
|
|
52
54
|
}));
|
|
53
55
|
// Load PROVIDER_LABELS from centralized schema
|
|
54
56
|
const PROVIDER_LABELS = Object.fromEntries(getProviders().map((provider) => [provider.id, provider.label]));
|
|
55
57
|
// Allow enough time for paste detection to kick in before flushing buffered lines
|
|
56
58
|
const CONTEXT_USAGE_THRESHOLD = 0.9;
|
|
59
|
+
const CONTEXT_AUTOCOMPACT_PERCENT = Math.round(CONTEXT_USAGE_THRESHOLD * 100);
|
|
57
60
|
const CONTEXT_RECENT_MESSAGE_COUNT = 12;
|
|
58
61
|
const CONTEXT_CLEANUP_CHARS_PER_CHUNK = 6000;
|
|
59
62
|
const CONTEXT_CLEANUP_MAX_OUTPUT_TOKENS = 800;
|
|
@@ -94,11 +97,12 @@ export class InteractiveShell {
|
|
|
94
97
|
uiAdapter;
|
|
95
98
|
uiUpdates;
|
|
96
99
|
_fileChangeTracker = new FileChangeTracker(); // Reserved for future file tracking features
|
|
97
|
-
|
|
100
|
+
alphaZeroMetrics; // Alpha Zero 2 performance tracking
|
|
98
101
|
statusSubscription = null;
|
|
99
102
|
followUpQueue = [];
|
|
100
103
|
isDrainingQueue = false;
|
|
101
104
|
activeContextWindowTokens = null;
|
|
105
|
+
latestTokenUsage = { used: null, limit: null };
|
|
102
106
|
sessionPreferences;
|
|
103
107
|
autosaveEnabled;
|
|
104
108
|
autoContinueEnabled;
|
|
@@ -129,6 +133,8 @@ export class InteractiveShell {
|
|
|
129
133
|
statusLineState = null;
|
|
130
134
|
statusMessageOverride = null;
|
|
131
135
|
promptRefreshTimer = null;
|
|
136
|
+
launchPaletteShown = false;
|
|
137
|
+
version;
|
|
132
138
|
constructor(config) {
|
|
133
139
|
this.profile = config.profile;
|
|
134
140
|
this.profileLabel = config.profileLabel;
|
|
@@ -142,6 +148,7 @@ export class InteractiveShell {
|
|
|
142
148
|
this.autoContinueEnabled = this.sessionPreferences.autoContinue;
|
|
143
149
|
this.sessionRestoreConfig = config.sessionRestore ?? { mode: 'none' };
|
|
144
150
|
this._enabledPlugins = config.enabledPlugins ?? [];
|
|
151
|
+
this.version = config.version ?? '0.0.0';
|
|
145
152
|
this.initializeSessionHistory();
|
|
146
153
|
this.sessionState = {
|
|
147
154
|
provider: config.initialModel.provider,
|
|
@@ -162,6 +169,7 @@ export class InteractiveShell {
|
|
|
162
169
|
this.slashCommands.push({
|
|
163
170
|
command: '/agents',
|
|
164
171
|
description: 'Select the default agent profile (applies on next launch)',
|
|
172
|
+
category: 'configuration',
|
|
165
173
|
});
|
|
166
174
|
}
|
|
167
175
|
this.customCommands = loadCustomSlashCommands();
|
|
@@ -170,18 +178,21 @@ export class InteractiveShell {
|
|
|
170
178
|
this.slashCommands.push({
|
|
171
179
|
command: custom.command,
|
|
172
180
|
description: `${custom.description} (custom)`,
|
|
181
|
+
category: custom.category ?? 'other',
|
|
173
182
|
});
|
|
174
183
|
}
|
|
175
184
|
if (!this.slashCommands.some((cmd) => cmd.command === '/exit')) {
|
|
176
185
|
this.slashCommands.push({
|
|
177
186
|
command: '/exit',
|
|
178
187
|
description: 'Quit the CLI immediately',
|
|
188
|
+
category: 'other',
|
|
179
189
|
});
|
|
180
190
|
}
|
|
181
191
|
// Add /plugins command
|
|
182
192
|
this.slashCommands.push({
|
|
183
193
|
command: '/plugins',
|
|
184
194
|
description: 'Show available and loaded plugins',
|
|
195
|
+
category: 'configuration',
|
|
185
196
|
});
|
|
186
197
|
this.statusTracker = config.statusTracker;
|
|
187
198
|
this.ui = config.ui;
|
|
@@ -214,19 +225,21 @@ export class InteractiveShell {
|
|
|
214
225
|
onToggleVerify: () => this.toggleVerificationMode(),
|
|
215
226
|
onToggleAutoContinue: () => this.toggleAutoContinueMode(),
|
|
216
227
|
});
|
|
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();
|
|
224
228
|
// Initialize Alpha Zero 2 metrics tracking
|
|
225
|
-
this.
|
|
229
|
+
this.alphaZeroMetrics = new MetricsTracker(`${this.profile}-${Date.now()}`);
|
|
226
230
|
this.setupStatusTracking();
|
|
227
231
|
this.refreshContextGauge();
|
|
232
|
+
// Start terminal input (sets up handlers)
|
|
228
233
|
this.terminalInput.start();
|
|
234
|
+
// Enter alternate screen buffer for clean UI control
|
|
235
|
+
// This preserves user's terminal history when they exit
|
|
236
|
+
this.terminalInput.enterAlternateScreen();
|
|
237
|
+
// Stream banner first - this sets up scroll region dynamically
|
|
238
|
+
const banner = this.buildBanner();
|
|
239
|
+
this.terminalInput.streamContent(banner + '\n\n');
|
|
240
|
+
// Render chat box after banner is streamed
|
|
229
241
|
this.refreshControlBar();
|
|
242
|
+
this.terminalInput.forceRender();
|
|
230
243
|
this.rebuildAgent();
|
|
231
244
|
this.setupHandlers();
|
|
232
245
|
this.refreshBannerSessionInfo();
|
|
@@ -273,14 +286,24 @@ export class InteractiveShell {
|
|
|
273
286
|
this.sessionResumeNotice = null;
|
|
274
287
|
}
|
|
275
288
|
async start(initialPrompt) {
|
|
289
|
+
// Check for updates in background (non-blocking)
|
|
290
|
+
if (this.version) {
|
|
291
|
+
void maybeOfferCliUpdate(this.version);
|
|
292
|
+
}
|
|
276
293
|
if (initialPrompt) {
|
|
277
294
|
this.logUserPrompt(initialPrompt);
|
|
278
295
|
await this.processInputBlock(initialPrompt);
|
|
279
296
|
return;
|
|
280
297
|
}
|
|
298
|
+
this.showLaunchCommandPalette();
|
|
281
299
|
// Ensure the terminal input is visible
|
|
282
300
|
this.terminalInput.render();
|
|
283
301
|
}
|
|
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
|
+
}
|
|
284
307
|
/**
|
|
285
308
|
* TerminalInputAdapter submit handler
|
|
286
309
|
*/
|
|
@@ -294,9 +317,8 @@ export class InteractiveShell {
|
|
|
294
317
|
this.handleInputChange('');
|
|
295
318
|
return;
|
|
296
319
|
}
|
|
297
|
-
//
|
|
298
|
-
//
|
|
299
|
-
this.terminalInput.setStreaming(true);
|
|
320
|
+
// DON'T clear the input here - keep it visible while streaming.
|
|
321
|
+
// The input will be cleared after streaming completes in the finally block.
|
|
300
322
|
this.logUserPrompt(approved);
|
|
301
323
|
void this.processInputBlock(approved).catch((err) => {
|
|
302
324
|
display.showError(err instanceof Error ? err.message : String(err), err);
|
|
@@ -497,12 +519,12 @@ export class InteractiveShell {
|
|
|
497
519
|
this.terminalInput.dispose();
|
|
498
520
|
// Dispose unified UI adapter
|
|
499
521
|
this.uiAdapter.dispose();
|
|
522
|
+
// Exit alternate screen buffer before printing goodbye
|
|
523
|
+
this.terminalInput.exitAlternateScreen();
|
|
500
524
|
display.newLine();
|
|
501
|
-
|
|
502
|
-
console.log(theme.
|
|
503
|
-
console.log(
|
|
504
|
-
console.log(` ${theme.ui.muted('Support:')} ${theme.info('support@ero.solar')}`);
|
|
505
|
-
console.log(theme.gradient.warm('━'.repeat(50)));
|
|
525
|
+
console.log(theme.ui.muted('━'.repeat(44)));
|
|
526
|
+
console.log(theme.ui.muted(' Goodbye! · support@ero.solar'));
|
|
527
|
+
console.log(theme.ui.muted('━'.repeat(44)));
|
|
506
528
|
exit(0);
|
|
507
529
|
}
|
|
508
530
|
/**
|
|
@@ -672,13 +694,14 @@ export class InteractiveShell {
|
|
|
672
694
|
});
|
|
673
695
|
}
|
|
674
696
|
setProcessingStatus(detail) {
|
|
697
|
+
this.latestTokenUsage = { used: null, limit: this.latestTokenUsage.limit };
|
|
675
698
|
this.statusTracker.setBase('Working on your request', {
|
|
676
699
|
detail: this.describeStatusDetail(detail),
|
|
677
700
|
tone: 'info',
|
|
678
701
|
});
|
|
679
702
|
}
|
|
680
703
|
describeStatusDetail(detail) {
|
|
681
|
-
const parts =
|
|
704
|
+
const parts = detail?.trim() ? [detail.trim()] : [];
|
|
682
705
|
const queued = this.followUpQueue.length;
|
|
683
706
|
if (queued > 0) {
|
|
684
707
|
parts.push(`${queued} follow-up${queued === 1 ? '' : 's'} queued`);
|
|
@@ -691,12 +714,18 @@ export class InteractiveShell {
|
|
|
691
714
|
}
|
|
692
715
|
refreshContextGauge() {
|
|
693
716
|
const tokens = getContextWindowTokens(this.sessionState.model);
|
|
694
|
-
|
|
695
|
-
|
|
717
|
+
const normalizedTokens = typeof tokens === 'number' && Number.isFinite(tokens) ? tokens : null;
|
|
718
|
+
this.activeContextWindowTokens = normalizedTokens;
|
|
719
|
+
if (normalizedTokens !== null) {
|
|
720
|
+
this.latestTokenUsage = {
|
|
721
|
+
used: this.latestTokenUsage.used,
|
|
722
|
+
limit: normalizedTokens,
|
|
723
|
+
};
|
|
724
|
+
}
|
|
696
725
|
}
|
|
697
726
|
updateContextUsage(percentage) {
|
|
698
727
|
this.uiAdapter.updateContextUsage(percentage);
|
|
699
|
-
this.terminalInput.setContextUsage(percentage);
|
|
728
|
+
this.terminalInput.setContextUsage(percentage, CONTEXT_AUTOCOMPACT_PERCENT);
|
|
700
729
|
}
|
|
701
730
|
refreshControlBar() {
|
|
702
731
|
this.terminalInput.setModeToggles({
|
|
@@ -704,9 +733,9 @@ export class InteractiveShell {
|
|
|
704
733
|
autoContinueEnabled: this.autoContinueEnabled,
|
|
705
734
|
verificationHotkey: 'alt+v',
|
|
706
735
|
autoContinueHotkey: 'alt+c',
|
|
736
|
+
thinkingModeLabel: this.thinkingMode,
|
|
737
|
+
thinkingHotkey: '/thinking',
|
|
707
738
|
});
|
|
708
|
-
// Update persistent model info display
|
|
709
|
-
this.terminalInput.setModelInfo(this.describeModelDetail());
|
|
710
739
|
this.refreshStatusLine();
|
|
711
740
|
this.terminalInput.render();
|
|
712
741
|
}
|
|
@@ -737,6 +766,25 @@ export class InteractiveShell {
|
|
|
737
766
|
// Set main status (tool execution, etc.) - shown when not overridden
|
|
738
767
|
const statusText = this.formatStatusLine(this.statusLineState);
|
|
739
768
|
this.terminalInput.setStatusMessage(statusText);
|
|
769
|
+
// Surface meta header (elapsed + context usage) above the divider
|
|
770
|
+
const elapsedSeconds = this.statusLineState
|
|
771
|
+
? Math.max(0, Math.floor((Date.now() - this.statusLineState.startedAt) / 1000))
|
|
772
|
+
: null;
|
|
773
|
+
const thinkingMs = display.isSpinnerActive() ? display.getThinkingElapsedMs() : null;
|
|
774
|
+
const tokensUsed = this.latestTokenUsage.used;
|
|
775
|
+
const tokenLimit = this.latestTokenUsage.limit ?? this.activeContextWindowTokens;
|
|
776
|
+
this.terminalInput.setMetaStatus({
|
|
777
|
+
elapsedSeconds,
|
|
778
|
+
tokensUsed,
|
|
779
|
+
tokenLimit,
|
|
780
|
+
thinkingMs,
|
|
781
|
+
thinkingHasContent: display.isSpinnerActive(),
|
|
782
|
+
});
|
|
783
|
+
// Keep model/provider visible in the controls bar
|
|
784
|
+
this.terminalInput.setModelContext({
|
|
785
|
+
model: this.sessionState.model,
|
|
786
|
+
provider: this.providerLabel(this.sessionState.provider),
|
|
787
|
+
});
|
|
740
788
|
if (forceRender) {
|
|
741
789
|
this.terminalInput.render();
|
|
742
790
|
}
|
|
@@ -796,13 +844,14 @@ export class InteractiveShell {
|
|
|
796
844
|
this.terminalInput.render();
|
|
797
845
|
}
|
|
798
846
|
/**
|
|
799
|
-
* Log
|
|
800
|
-
* This creates a persistent log entry that remains visible during and after streaming.
|
|
847
|
+
* Log user prompt to the scroll region so it's part of the conversation flow.
|
|
801
848
|
*/
|
|
802
849
|
logUserPrompt(text) {
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
850
|
+
if (!text.trim())
|
|
851
|
+
return;
|
|
852
|
+
// Format with user prompt prefix and write to scroll region
|
|
853
|
+
const formatted = `${theme.user('>')} ${text}\n`;
|
|
854
|
+
this.terminalInput.writeToScrollRegion(formatted);
|
|
806
855
|
}
|
|
807
856
|
requestPromptRefresh(force = false) {
|
|
808
857
|
if (force) {
|
|
@@ -827,16 +876,40 @@ export class InteractiveShell {
|
|
|
827
876
|
this.stopStreamingHeartbeat();
|
|
828
877
|
// Enter global streaming mode - blocks all non-streaming UI output
|
|
829
878
|
enterStreamingMode();
|
|
879
|
+
// Set up scroll region for streaming content
|
|
880
|
+
this.terminalInput.enterStreamingScrollRegion();
|
|
830
881
|
this.uiUpdates.setMode('streaming');
|
|
831
882
|
this.streamingHeartbeatStart = Date.now();
|
|
832
883
|
this.streamingHeartbeatFrame = 0;
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
884
|
+
const initialFrame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
|
|
885
|
+
this.streamingStatusLabel = this.buildStreamingStatus(`${initialFrame} ${label}`, 0);
|
|
886
|
+
display.updateStreamingStatus(this.streamingStatusLabel);
|
|
887
|
+
this.refreshStatusLine(true);
|
|
888
|
+
// Periodically refresh the pinned input/status region while streaming so
|
|
889
|
+
// elapsed time remains visible without interrupting the scroll region.
|
|
890
|
+
this.uiUpdates.startHeartbeat('streaming', {
|
|
891
|
+
intervalMs: 1000,
|
|
892
|
+
lane: 'heartbeat',
|
|
893
|
+
mode: ['streaming', 'processing'],
|
|
894
|
+
coalesceKey: 'streaming:heartbeat',
|
|
895
|
+
run: () => {
|
|
896
|
+
const elapsedSeconds = this.streamingHeartbeatStart
|
|
897
|
+
? Math.max(0, Math.floor((Date.now() - this.streamingHeartbeatStart) / 1000))
|
|
898
|
+
: 0;
|
|
899
|
+
this.streamingHeartbeatFrame =
|
|
900
|
+
(this.streamingHeartbeatFrame + 1) % STREAMING_SPINNER_FRAMES.length;
|
|
901
|
+
const frame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
|
|
902
|
+
this.streamingStatusLabel = this.buildStreamingStatus(`${frame} ${label}`, elapsedSeconds);
|
|
903
|
+
display.updateStreamingStatus(this.streamingStatusLabel);
|
|
904
|
+
this.refreshStatusLine(true);
|
|
905
|
+
},
|
|
906
|
+
});
|
|
836
907
|
}
|
|
837
908
|
stopStreamingHeartbeat() {
|
|
838
909
|
// Exit global streaming mode - allows UI to render again
|
|
839
910
|
exitStreamingMode();
|
|
911
|
+
// Exit scroll region mode
|
|
912
|
+
this.terminalInput.exitStreamingScrollRegion();
|
|
840
913
|
this.uiUpdates.stopHeartbeat('streaming');
|
|
841
914
|
this.streamingHeartbeatStart = null;
|
|
842
915
|
this.streamingHeartbeatFrame = 0;
|
|
@@ -848,10 +921,28 @@ export class InteractiveShell {
|
|
|
848
921
|
// Force refresh to update the input area now that streaming has ended
|
|
849
922
|
this.refreshStatusLine(true);
|
|
850
923
|
}
|
|
851
|
-
buildStreamingStatus(label) {
|
|
924
|
+
buildStreamingStatus(label, elapsedSeconds) {
|
|
852
925
|
const detail = this.describeModelDetail();
|
|
853
|
-
const
|
|
854
|
-
|
|
926
|
+
const elapsedLabel = typeof elapsedSeconds === 'number' && elapsedSeconds >= 0
|
|
927
|
+
? theme.ui.muted(this.formatElapsedShort(elapsedSeconds))
|
|
928
|
+
: null;
|
|
929
|
+
const prefix = theme.info('⏺');
|
|
930
|
+
const parts = [label];
|
|
931
|
+
if (detail) {
|
|
932
|
+
parts.push(theme.ui.muted('·'), detail);
|
|
933
|
+
}
|
|
934
|
+
if (elapsedLabel) {
|
|
935
|
+
parts.push(theme.ui.muted('·'), elapsedLabel);
|
|
936
|
+
}
|
|
937
|
+
return `${prefix} ${parts.join(' ')}`.trim();
|
|
938
|
+
}
|
|
939
|
+
formatElapsedShort(seconds) {
|
|
940
|
+
if (seconds < 60) {
|
|
941
|
+
return `${seconds}s`;
|
|
942
|
+
}
|
|
943
|
+
const minutes = Math.floor(seconds / 60);
|
|
944
|
+
const remaining = seconds % 60;
|
|
945
|
+
return remaining > 0 ? `${minutes}m ${remaining}s` : `${minutes}m`;
|
|
855
946
|
}
|
|
856
947
|
refreshQueueIndicators() {
|
|
857
948
|
if (this.isProcessing) {
|
|
@@ -1099,17 +1190,6 @@ export class InteractiveShell {
|
|
|
1099
1190
|
case '/discover':
|
|
1100
1191
|
await this.discoverModelsCommand();
|
|
1101
1192
|
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;
|
|
1113
1193
|
default:
|
|
1114
1194
|
if (!(await this.tryCustomSlashCommand(command, input))) {
|
|
1115
1195
|
display.showWarning(`Unknown command "${command}".`);
|
|
@@ -1418,99 +1498,6 @@ export class InteractiveShell {
|
|
|
1418
1498
|
// Display keyboard shortcuts help (Claude Code style)
|
|
1419
1499
|
display.showSystemMessage(formatShortcutsHelp());
|
|
1420
1500
|
}
|
|
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
|
-
}
|
|
1514
1501
|
showFileChangeSummary() {
|
|
1515
1502
|
const summary = this._fileChangeTracker.getSummary();
|
|
1516
1503
|
const changes = this._fileChangeTracker.getAllChanges();
|
|
@@ -1553,11 +1540,11 @@ When working in this codebase:
|
|
|
1553
1540
|
display.showSystemMessage(lines.join('\n'));
|
|
1554
1541
|
}
|
|
1555
1542
|
showAlphaZeroMetrics() {
|
|
1556
|
-
const summary = this.
|
|
1543
|
+
const summary = this.alphaZeroMetrics.getPerformanceSummary();
|
|
1557
1544
|
display.showSystemMessage(summary);
|
|
1558
1545
|
}
|
|
1559
1546
|
showImprovementSuggestions() {
|
|
1560
|
-
const suggestions = this.
|
|
1547
|
+
const suggestions = this.alphaZeroMetrics.getImprovementSuggestions();
|
|
1561
1548
|
if (suggestions.length === 0) {
|
|
1562
1549
|
display.showInfo('No improvement suggestions at this time. Keep using the shell to generate metrics!');
|
|
1563
1550
|
return;
|
|
@@ -1603,7 +1590,9 @@ When working in this codebase:
|
|
|
1603
1590
|
}
|
|
1604
1591
|
}
|
|
1605
1592
|
lines.push(theme.secondary('CLI Flags:'));
|
|
1593
|
+
lines.push(' --alpha-zero Enable Alpha Zero 2 RL framework');
|
|
1606
1594
|
lines.push(' --coding Enable enhanced coding tools');
|
|
1595
|
+
lines.push(' --security Enable security research tools');
|
|
1607
1596
|
lines.push(' --all-plugins Enable all optional plugins');
|
|
1608
1597
|
display.showSystemMessage(lines.join('\n'));
|
|
1609
1598
|
}
|
|
@@ -1847,6 +1836,75 @@ When working in this codebase:
|
|
|
1847
1836
|
}
|
|
1848
1837
|
return `${warning.label}: ${warning.reason}.`;
|
|
1849
1838
|
}
|
|
1839
|
+
buildLaunchCommandPalette() {
|
|
1840
|
+
const entries = [];
|
|
1841
|
+
const secretsSummary = this.summarizeSecretsForPalette();
|
|
1842
|
+
const toolSummary = this.getToolSelectionSummary();
|
|
1843
|
+
const autosaveLabel = this.autosaveEnabled ? 'on' : 'off';
|
|
1844
|
+
for (const command of this.slashCommands) {
|
|
1845
|
+
const entry = {
|
|
1846
|
+
command: command.command,
|
|
1847
|
+
description: command.description,
|
|
1848
|
+
category: command.category ?? 'other',
|
|
1849
|
+
};
|
|
1850
|
+
switch (command.command) {
|
|
1851
|
+
case '/secrets':
|
|
1852
|
+
if (secretsSummary.text) {
|
|
1853
|
+
entry.description = `${command.description} (${secretsSummary.text})`;
|
|
1854
|
+
entry.tone = secretsSummary.tone;
|
|
1855
|
+
}
|
|
1856
|
+
break;
|
|
1857
|
+
case '/tools':
|
|
1858
|
+
if (toolSummary) {
|
|
1859
|
+
entry.description = `${command.description} (${toolSummary})`;
|
|
1860
|
+
}
|
|
1861
|
+
break;
|
|
1862
|
+
case '/sessions':
|
|
1863
|
+
entry.description = `${command.description} (autosave ${autosaveLabel})`;
|
|
1864
|
+
break;
|
|
1865
|
+
case '/model':
|
|
1866
|
+
entry.description = `${command.description} (current: ${this.sessionState.model})`;
|
|
1867
|
+
break;
|
|
1868
|
+
case '/provider':
|
|
1869
|
+
entry.description = `${command.description} (current: ${this.providerLabel(this.sessionState.provider)})`;
|
|
1870
|
+
break;
|
|
1871
|
+
default:
|
|
1872
|
+
break;
|
|
1873
|
+
}
|
|
1874
|
+
entries.push(entry);
|
|
1875
|
+
}
|
|
1876
|
+
return entries;
|
|
1877
|
+
}
|
|
1878
|
+
summarizeSecretsForPalette() {
|
|
1879
|
+
const definitions = listSecretDefinitions();
|
|
1880
|
+
if (!definitions.length) {
|
|
1881
|
+
return { text: null };
|
|
1882
|
+
}
|
|
1883
|
+
const missing = definitions.filter((definition) => !getSecretValue(definition.id));
|
|
1884
|
+
if (missing.length === 0) {
|
|
1885
|
+
return { text: 'all configured', tone: 'success' };
|
|
1886
|
+
}
|
|
1887
|
+
const labels = missing.map((definition) => definition.label ?? definition.id);
|
|
1888
|
+
return { text: `missing ${this.formatList(labels)}`, tone: 'warn' };
|
|
1889
|
+
}
|
|
1890
|
+
getToolSelectionSummary() {
|
|
1891
|
+
const toolSettings = loadToolSettings();
|
|
1892
|
+
const selection = buildEnabledToolSet(toolSettings);
|
|
1893
|
+
const options = getToolToggleOptions();
|
|
1894
|
+
if (!options.length) {
|
|
1895
|
+
return null;
|
|
1896
|
+
}
|
|
1897
|
+
const enabledCount = options.filter((option) => selection.has(option.id)).length;
|
|
1898
|
+
return `${enabledCount}/${options.length} enabled`;
|
|
1899
|
+
}
|
|
1900
|
+
formatList(values, maxItems = 3) {
|
|
1901
|
+
if (!values.length) {
|
|
1902
|
+
return '';
|
|
1903
|
+
}
|
|
1904
|
+
const shown = values.slice(0, maxItems);
|
|
1905
|
+
const suffix = values.length > maxItems ? ', …' : '';
|
|
1906
|
+
return `${shown.join(', ')}${suffix}`;
|
|
1907
|
+
}
|
|
1850
1908
|
buildSlashCommandList(header) {
|
|
1851
1909
|
const lines = [theme.gradient.primary(header), ''];
|
|
1852
1910
|
for (const command of this.slashCommands) {
|
|
@@ -2315,7 +2373,7 @@ When working in this codebase:
|
|
|
2315
2373
|
this.autosaveIfEnabled();
|
|
2316
2374
|
// Track metrics with Alpha Zero 2
|
|
2317
2375
|
const elapsedMs = Date.now() - requestStartTime;
|
|
2318
|
-
this.
|
|
2376
|
+
this.alphaZeroMetrics.recordMessage(elapsedMs);
|
|
2319
2377
|
if (!responseText?.trim()) {
|
|
2320
2378
|
display.showWarning('The provider returned an empty response. Check your API key/provider selection or retry the prompt.');
|
|
2321
2379
|
}
|
|
@@ -2333,14 +2391,10 @@ When working in this codebase:
|
|
|
2333
2391
|
this.stopStreamingHeartbeat();
|
|
2334
2392
|
this.isProcessing = false;
|
|
2335
2393
|
this.terminalInput.setStreaming(false);
|
|
2336
|
-
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2337
2394
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2338
2395
|
this.setIdleStatus();
|
|
2339
2396
|
display.newLine();
|
|
2340
2397
|
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();
|
|
2344
2398
|
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
2345
2399
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
2346
2400
|
// Claude Code style: New prompt naturally appears at bottom
|
|
@@ -2417,13 +2471,14 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
|
|
|
2417
2471
|
try {
|
|
2418
2472
|
// Send the request and capture the response (streaming disabled)
|
|
2419
2473
|
display.showThinking('Responding...');
|
|
2474
|
+
this.refreshStatusLine(true);
|
|
2420
2475
|
const response = await agent.send(currentPrompt, true);
|
|
2421
2476
|
await this.awaitPendingCleanup();
|
|
2422
2477
|
this.captureHistorySnapshot();
|
|
2423
2478
|
this.autosaveIfEnabled();
|
|
2424
2479
|
// Track metrics
|
|
2425
2480
|
const elapsedMs = Date.now() - overallStartTime;
|
|
2426
|
-
this.
|
|
2481
|
+
this.alphaZeroMetrics.recordMessage(elapsedMs);
|
|
2427
2482
|
if (!response?.trim()) {
|
|
2428
2483
|
display.showWarning('Model returned an empty response. Retrying this iteration...');
|
|
2429
2484
|
consecutiveNoProgress++;
|
|
@@ -2560,7 +2615,6 @@ What's the next action?`;
|
|
|
2560
2615
|
this.stopStreamingHeartbeat();
|
|
2561
2616
|
this.isProcessing = false;
|
|
2562
2617
|
this.terminalInput.setStreaming(false);
|
|
2563
|
-
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2564
2618
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2565
2619
|
this.setIdleStatus();
|
|
2566
2620
|
this.updateStatusMessage(null);
|
|
@@ -2917,8 +2971,10 @@ What's the next action?`;
|
|
|
2917
2971
|
try {
|
|
2918
2972
|
// Send the error to the agent for fixing
|
|
2919
2973
|
display.showThinking('Analyzing build errors');
|
|
2974
|
+
this.refreshStatusLine(true);
|
|
2920
2975
|
const response = await this.agent.send(prompt, true);
|
|
2921
2976
|
display.stopThinking();
|
|
2977
|
+
this.refreshStatusLine(true);
|
|
2922
2978
|
if (response) {
|
|
2923
2979
|
display.showAssistantMessage(response, { isFinal: true });
|
|
2924
2980
|
}
|
|
@@ -2945,8 +3001,8 @@ What's the next action?`;
|
|
|
2945
3001
|
};
|
|
2946
3002
|
this.agent = this.runtimeSession.createAgent(selection, {
|
|
2947
3003
|
onStreamChunk: (chunk) => {
|
|
2948
|
-
// Stream output
|
|
2949
|
-
|
|
3004
|
+
// Stream output using clean streamContent() - chat box floats below
|
|
3005
|
+
this.terminalInput.streamContent(chunk);
|
|
2950
3006
|
},
|
|
2951
3007
|
onStreamFallback: (info) => this.handleStreamingFallback(info),
|
|
2952
3008
|
onAssistantMessage: (content, metadata) => {
|
|
@@ -2968,18 +3024,16 @@ What's the next action?`;
|
|
|
2968
3024
|
display.showAssistantMessage(finalContent, enriched);
|
|
2969
3025
|
}
|
|
2970
3026
|
}
|
|
2971
|
-
//
|
|
3027
|
+
// Status shown in mode controls bar - no separate status line needed
|
|
2972
3028
|
display.stopThinking();
|
|
2973
|
-
//
|
|
2974
|
-
let contextInfo;
|
|
3029
|
+
// Update context usage for mode controls display
|
|
2975
3030
|
if (enriched.contextWindowTokens && metadata.usage) {
|
|
2976
3031
|
const total = this.totalTokens(metadata.usage);
|
|
2977
3032
|
if (total && total > 0) {
|
|
2978
3033
|
const percentage = Math.round((total / enriched.contextWindowTokens) * 100);
|
|
2979
|
-
|
|
3034
|
+
this.updateContextUsage(percentage);
|
|
2980
3035
|
}
|
|
2981
3036
|
}
|
|
2982
|
-
display.showStatusLine('Ready for prompts', enriched.elapsedMs, contextInfo);
|
|
2983
3037
|
// Auto-verify changes: build first (catches type errors), then tests
|
|
2984
3038
|
void this.enforceAutoBuild('final-response');
|
|
2985
3039
|
void this.enforceAutoTests('final-response');
|
|
@@ -3049,7 +3103,6 @@ What's the next action?`;
|
|
|
3049
3103
|
this.stopStreamingHeartbeat();
|
|
3050
3104
|
this.updateStatusMessage(null);
|
|
3051
3105
|
this.terminalInput.setStreaming(false);
|
|
3052
|
-
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3053
3106
|
this.terminalInput.render();
|
|
3054
3107
|
},
|
|
3055
3108
|
onVerificationNeeded: () => {
|
|
@@ -3086,7 +3139,6 @@ What's the next action?`;
|
|
|
3086
3139
|
resetChatBoxAfterModelSwap() {
|
|
3087
3140
|
this.updateStatusMessage(null);
|
|
3088
3141
|
this.terminalInput.setStreaming(false);
|
|
3089
|
-
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3090
3142
|
this.terminalInput.render();
|
|
3091
3143
|
this.ensureReadlineReady();
|
|
3092
3144
|
}
|
|
@@ -3151,9 +3203,14 @@ What's the next action?`;
|
|
|
3151
3203
|
return null;
|
|
3152
3204
|
}
|
|
3153
3205
|
const usageRatio = total / windowTokens;
|
|
3206
|
+
this.latestTokenUsage = {
|
|
3207
|
+
used: total,
|
|
3208
|
+
limit: windowTokens,
|
|
3209
|
+
};
|
|
3154
3210
|
// Always update context usage in the UI
|
|
3155
3211
|
const percentUsed = Math.round(usageRatio * 100);
|
|
3156
3212
|
this.updateContextUsage(percentUsed);
|
|
3213
|
+
this.refreshStatusLine(true);
|
|
3157
3214
|
if (usageRatio < CONTEXT_USAGE_THRESHOLD) {
|
|
3158
3215
|
return null;
|
|
3159
3216
|
}
|
|
@@ -3420,6 +3477,22 @@ What's the next action?`;
|
|
|
3420
3477
|
this.sessionState.reasoningEffort = preset.reasoningEffort;
|
|
3421
3478
|
}
|
|
3422
3479
|
}
|
|
3480
|
+
/**
|
|
3481
|
+
* Build the session banner.
|
|
3482
|
+
*/
|
|
3483
|
+
buildBanner() {
|
|
3484
|
+
const terminalWidth = output.columns ?? 100;
|
|
3485
|
+
const width = Math.min(terminalWidth - 4, 110);
|
|
3486
|
+
return renderSessionFrame({
|
|
3487
|
+
profileLabel: this.profileLabel,
|
|
3488
|
+
profileName: this.profile,
|
|
3489
|
+
model: this.sessionState.model,
|
|
3490
|
+
provider: this.sessionState.provider,
|
|
3491
|
+
workspace: this.workingDir,
|
|
3492
|
+
version: this.version,
|
|
3493
|
+
width,
|
|
3494
|
+
});
|
|
3495
|
+
}
|
|
3423
3496
|
refreshBannerSessionInfo() {
|
|
3424
3497
|
const nextState = {
|
|
3425
3498
|
model: this.sessionState.model,
|
|
@@ -3430,13 +3503,11 @@ What's the next action?`;
|
|
|
3430
3503
|
return;
|
|
3431
3504
|
}
|
|
3432
3505
|
this.refreshContextGauge();
|
|
3433
|
-
display
|
|
3434
|
-
//
|
|
3435
|
-
this.terminalInput.setModelInfo(this.describeModelDetail());
|
|
3506
|
+
// Banner is no longer stored in display - it was streamed as content
|
|
3507
|
+
// Model/provider changes are visible in the control bar
|
|
3436
3508
|
if (!this.isProcessing) {
|
|
3437
3509
|
this.setIdleStatus();
|
|
3438
3510
|
}
|
|
3439
|
-
// Pinned header rows are disabled; scroll region handles all output.
|
|
3440
3511
|
this.bannerSessionState = nextState;
|
|
3441
3512
|
}
|
|
3442
3513
|
providerLabel(id) {
|