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