erosolar-cli 1.7.334 → 1.7.336
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 -166
- 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 -118
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +638 -532
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/terminalInputAdapter.d.ts +79 -21
- 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,15 +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
|
-
|
|
806
|
-
|
|
807
|
-
this.terminalInput.
|
|
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);
|
|
808
855
|
}
|
|
809
856
|
requestPromptRefresh(force = false) {
|
|
810
857
|
if (force) {
|
|
@@ -829,16 +876,40 @@ export class InteractiveShell {
|
|
|
829
876
|
this.stopStreamingHeartbeat();
|
|
830
877
|
// Enter global streaming mode - blocks all non-streaming UI output
|
|
831
878
|
enterStreamingMode();
|
|
879
|
+
// Set up scroll region for streaming content
|
|
880
|
+
this.terminalInput.enterStreamingScrollRegion();
|
|
832
881
|
this.uiUpdates.setMode('streaming');
|
|
833
882
|
this.streamingHeartbeatStart = Date.now();
|
|
834
883
|
this.streamingHeartbeatFrame = 0;
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
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
|
+
});
|
|
838
907
|
}
|
|
839
908
|
stopStreamingHeartbeat() {
|
|
840
909
|
// Exit global streaming mode - allows UI to render again
|
|
841
910
|
exitStreamingMode();
|
|
911
|
+
// Exit scroll region mode
|
|
912
|
+
this.terminalInput.exitStreamingScrollRegion();
|
|
842
913
|
this.uiUpdates.stopHeartbeat('streaming');
|
|
843
914
|
this.streamingHeartbeatStart = null;
|
|
844
915
|
this.streamingHeartbeatFrame = 0;
|
|
@@ -850,10 +921,28 @@ export class InteractiveShell {
|
|
|
850
921
|
// Force refresh to update the input area now that streaming has ended
|
|
851
922
|
this.refreshStatusLine(true);
|
|
852
923
|
}
|
|
853
|
-
buildStreamingStatus(label) {
|
|
924
|
+
buildStreamingStatus(label, elapsedSeconds) {
|
|
854
925
|
const detail = this.describeModelDetail();
|
|
855
|
-
const
|
|
856
|
-
|
|
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`;
|
|
857
946
|
}
|
|
858
947
|
refreshQueueIndicators() {
|
|
859
948
|
if (this.isProcessing) {
|
|
@@ -1101,17 +1190,6 @@ export class InteractiveShell {
|
|
|
1101
1190
|
case '/discover':
|
|
1102
1191
|
await this.discoverModelsCommand();
|
|
1103
1192
|
break;
|
|
1104
|
-
case '/memory':
|
|
1105
|
-
this.handleMemoryCommand(input);
|
|
1106
|
-
break;
|
|
1107
|
-
case '/clear':
|
|
1108
|
-
display.clear();
|
|
1109
|
-
this.cachedHistory = [];
|
|
1110
|
-
display.showInfo('Conversation cleared.');
|
|
1111
|
-
break;
|
|
1112
|
-
case '/help':
|
|
1113
|
-
this.showHelp();
|
|
1114
|
-
break;
|
|
1115
1193
|
default:
|
|
1116
1194
|
if (!(await this.tryCustomSlashCommand(command, input))) {
|
|
1117
1195
|
display.showWarning(`Unknown command "${command}".`);
|
|
@@ -1420,99 +1498,6 @@ export class InteractiveShell {
|
|
|
1420
1498
|
// Display keyboard shortcuts help (Claude Code style)
|
|
1421
1499
|
display.showSystemMessage(formatShortcutsHelp());
|
|
1422
1500
|
}
|
|
1423
|
-
handleMemoryCommand(input) {
|
|
1424
|
-
const tokens = input.trim().split(/\s+/).slice(1);
|
|
1425
|
-
const action = (tokens.shift() ?? 'show').toLowerCase();
|
|
1426
|
-
switch (action) {
|
|
1427
|
-
case '':
|
|
1428
|
-
case 'show':
|
|
1429
|
-
case 'list': {
|
|
1430
|
-
this.showMemoryStatus();
|
|
1431
|
-
break;
|
|
1432
|
-
}
|
|
1433
|
-
case 'paths': {
|
|
1434
|
-
this.showMemoryPaths();
|
|
1435
|
-
break;
|
|
1436
|
-
}
|
|
1437
|
-
case 'edit': {
|
|
1438
|
-
const level = (tokens[0] ?? 'project').toLowerCase();
|
|
1439
|
-
this.openMemoryForEdit(level);
|
|
1440
|
-
break;
|
|
1441
|
-
}
|
|
1442
|
-
default:
|
|
1443
|
-
display.showWarning('Usage: /memory [show|paths|edit <user|project>]');
|
|
1444
|
-
break;
|
|
1445
|
-
}
|
|
1446
|
-
}
|
|
1447
|
-
showMemoryStatus() {
|
|
1448
|
-
const memory = loadMemory(this.workingDir);
|
|
1449
|
-
const lines = [];
|
|
1450
|
-
lines.push(theme.bold('Persistent Memory'));
|
|
1451
|
-
lines.push('');
|
|
1452
|
-
if (memory.sources.length === 0) {
|
|
1453
|
-
lines.push(theme.secondary('No memory files found.'));
|
|
1454
|
-
lines.push('');
|
|
1455
|
-
lines.push(`Create ${theme.info('EROSOLAR.md')} in your project to add persistent context.`);
|
|
1456
|
-
lines.push(`Use ${theme.info('/memory edit project')} to create one.`);
|
|
1457
|
-
}
|
|
1458
|
-
else {
|
|
1459
|
-
for (const source of memory.sources) {
|
|
1460
|
-
const levelLabel = source.level === 'enterprise' ? 'Enterprise' :
|
|
1461
|
-
source.level === 'user' ? 'User' : 'Project';
|
|
1462
|
-
const preview = source.content.slice(0, 200).replace(/\n/g, ' ').trim();
|
|
1463
|
-
const truncated = source.content.length > 200 ? '...' : '';
|
|
1464
|
-
lines.push(`${theme.success('●')} ${theme.bold(levelLabel)}: ${source.path}`);
|
|
1465
|
-
lines.push(` ${theme.dim(preview + truncated)}`);
|
|
1466
|
-
lines.push('');
|
|
1467
|
-
}
|
|
1468
|
-
if (memory.importedPaths.length > memory.sources.length) {
|
|
1469
|
-
lines.push(theme.secondary(`Imported ${memory.importedPaths.length - memory.sources.length} additional files via @imports.`));
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
display.showSystemMessage(lines.join('\n'));
|
|
1473
|
-
}
|
|
1474
|
-
showMemoryPaths() {
|
|
1475
|
-
const paths = listMemoryPaths(this.workingDir);
|
|
1476
|
-
const lines = [];
|
|
1477
|
-
lines.push(theme.bold('Memory File Locations'));
|
|
1478
|
-
lines.push('');
|
|
1479
|
-
for (const { level, path, exists } of paths) {
|
|
1480
|
-
const icon = exists ? theme.success('✓') : theme.dim('○');
|
|
1481
|
-
const levelLabel = level.charAt(0).toUpperCase() + level.slice(1);
|
|
1482
|
-
lines.push(`${icon} ${levelLabel}: ${path}`);
|
|
1483
|
-
}
|
|
1484
|
-
lines.push('');
|
|
1485
|
-
lines.push(theme.secondary('Create any of these files to add persistent memory.'));
|
|
1486
|
-
lines.push(theme.secondary('Use @path/to/file.md syntax to import other files.'));
|
|
1487
|
-
display.showSystemMessage(lines.join('\n'));
|
|
1488
|
-
}
|
|
1489
|
-
openMemoryForEdit(level) {
|
|
1490
|
-
let targetPath;
|
|
1491
|
-
if (level === 'user') {
|
|
1492
|
-
targetPath = getUserMemoryEditPath();
|
|
1493
|
-
}
|
|
1494
|
-
else if (level === 'project') {
|
|
1495
|
-
targetPath = getDefaultProjectMemoryPath(this.workingDir);
|
|
1496
|
-
}
|
|
1497
|
-
else {
|
|
1498
|
-
display.showWarning('Specify "user" or "project" to edit. Enterprise memory is read-only.');
|
|
1499
|
-
return;
|
|
1500
|
-
}
|
|
1501
|
-
display.showInfo(`Memory file: ${targetPath}`);
|
|
1502
|
-
display.showInfo('Create or edit this file to add persistent context for the AI.');
|
|
1503
|
-
display.showInfo('');
|
|
1504
|
-
display.showInfo('Example EROSOLAR.md content:');
|
|
1505
|
-
display.showInfo('');
|
|
1506
|
-
display.showInfo(theme.dim(`# Project Guidelines
|
|
1507
|
-
|
|
1508
|
-
When working in this codebase:
|
|
1509
|
-
- Follow TypeScript strict mode conventions
|
|
1510
|
-
- Use functional patterns where appropriate
|
|
1511
|
-
- Run tests before committing
|
|
1512
|
-
|
|
1513
|
-
@./docs/coding-standards.md
|
|
1514
|
-
`));
|
|
1515
|
-
}
|
|
1516
1501
|
showFileChangeSummary() {
|
|
1517
1502
|
const summary = this._fileChangeTracker.getSummary();
|
|
1518
1503
|
const changes = this._fileChangeTracker.getAllChanges();
|
|
@@ -1555,11 +1540,11 @@ When working in this codebase:
|
|
|
1555
1540
|
display.showSystemMessage(lines.join('\n'));
|
|
1556
1541
|
}
|
|
1557
1542
|
showAlphaZeroMetrics() {
|
|
1558
|
-
const summary = this.
|
|
1543
|
+
const summary = this.alphaZeroMetrics.getPerformanceSummary();
|
|
1559
1544
|
display.showSystemMessage(summary);
|
|
1560
1545
|
}
|
|
1561
1546
|
showImprovementSuggestions() {
|
|
1562
|
-
const suggestions = this.
|
|
1547
|
+
const suggestions = this.alphaZeroMetrics.getImprovementSuggestions();
|
|
1563
1548
|
if (suggestions.length === 0) {
|
|
1564
1549
|
display.showInfo('No improvement suggestions at this time. Keep using the shell to generate metrics!');
|
|
1565
1550
|
return;
|
|
@@ -1605,7 +1590,9 @@ When working in this codebase:
|
|
|
1605
1590
|
}
|
|
1606
1591
|
}
|
|
1607
1592
|
lines.push(theme.secondary('CLI Flags:'));
|
|
1593
|
+
lines.push(' --alpha-zero Enable Alpha Zero 2 RL framework');
|
|
1608
1594
|
lines.push(' --coding Enable enhanced coding tools');
|
|
1595
|
+
lines.push(' --security Enable security research tools');
|
|
1609
1596
|
lines.push(' --all-plugins Enable all optional plugins');
|
|
1610
1597
|
display.showSystemMessage(lines.join('\n'));
|
|
1611
1598
|
}
|
|
@@ -1849,6 +1836,75 @@ When working in this codebase:
|
|
|
1849
1836
|
}
|
|
1850
1837
|
return `${warning.label}: ${warning.reason}.`;
|
|
1851
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
|
+
}
|
|
1852
1908
|
buildSlashCommandList(header) {
|
|
1853
1909
|
const lines = [theme.gradient.primary(header), ''];
|
|
1854
1910
|
for (const command of this.slashCommands) {
|
|
@@ -2317,7 +2373,7 @@ When working in this codebase:
|
|
|
2317
2373
|
this.autosaveIfEnabled();
|
|
2318
2374
|
// Track metrics with Alpha Zero 2
|
|
2319
2375
|
const elapsedMs = Date.now() - requestStartTime;
|
|
2320
|
-
this.
|
|
2376
|
+
this.alphaZeroMetrics.recordMessage(elapsedMs);
|
|
2321
2377
|
if (!responseText?.trim()) {
|
|
2322
2378
|
display.showWarning('The provider returned an empty response. Check your API key/provider selection or retry the prompt.');
|
|
2323
2379
|
}
|
|
@@ -2335,14 +2391,10 @@ When working in this codebase:
|
|
|
2335
2391
|
this.stopStreamingHeartbeat();
|
|
2336
2392
|
this.isProcessing = false;
|
|
2337
2393
|
this.terminalInput.setStreaming(false);
|
|
2338
|
-
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2339
2394
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2340
2395
|
this.setIdleStatus();
|
|
2341
2396
|
display.newLine();
|
|
2342
2397
|
this.updateStatusMessage(null);
|
|
2343
|
-
// Claude Code style: Show unified status bar before prompt
|
|
2344
|
-
// This creates consistent UI between startup and post-streaming
|
|
2345
|
-
this.showUnifiedStatusBar();
|
|
2346
2398
|
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
2347
2399
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
2348
2400
|
// Claude Code style: New prompt naturally appears at bottom
|
|
@@ -2419,13 +2471,14 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
|
|
|
2419
2471
|
try {
|
|
2420
2472
|
// Send the request and capture the response (streaming disabled)
|
|
2421
2473
|
display.showThinking('Responding...');
|
|
2474
|
+
this.refreshStatusLine(true);
|
|
2422
2475
|
const response = await agent.send(currentPrompt, true);
|
|
2423
2476
|
await this.awaitPendingCleanup();
|
|
2424
2477
|
this.captureHistorySnapshot();
|
|
2425
2478
|
this.autosaveIfEnabled();
|
|
2426
2479
|
// Track metrics
|
|
2427
2480
|
const elapsedMs = Date.now() - overallStartTime;
|
|
2428
|
-
this.
|
|
2481
|
+
this.alphaZeroMetrics.recordMessage(elapsedMs);
|
|
2429
2482
|
if (!response?.trim()) {
|
|
2430
2483
|
display.showWarning('Model returned an empty response. Retrying this iteration...');
|
|
2431
2484
|
consecutiveNoProgress++;
|
|
@@ -2562,7 +2615,6 @@ What's the next action?`;
|
|
|
2562
2615
|
this.stopStreamingHeartbeat();
|
|
2563
2616
|
this.isProcessing = false;
|
|
2564
2617
|
this.terminalInput.setStreaming(false);
|
|
2565
|
-
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2566
2618
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2567
2619
|
this.setIdleStatus();
|
|
2568
2620
|
this.updateStatusMessage(null);
|
|
@@ -2919,8 +2971,10 @@ What's the next action?`;
|
|
|
2919
2971
|
try {
|
|
2920
2972
|
// Send the error to the agent for fixing
|
|
2921
2973
|
display.showThinking('Analyzing build errors');
|
|
2974
|
+
this.refreshStatusLine(true);
|
|
2922
2975
|
const response = await this.agent.send(prompt, true);
|
|
2923
2976
|
display.stopThinking();
|
|
2977
|
+
this.refreshStatusLine(true);
|
|
2924
2978
|
if (response) {
|
|
2925
2979
|
display.showAssistantMessage(response, { isFinal: true });
|
|
2926
2980
|
}
|
|
@@ -2947,8 +3001,8 @@ What's the next action?`;
|
|
|
2947
3001
|
};
|
|
2948
3002
|
this.agent = this.runtimeSession.createAgent(selection, {
|
|
2949
3003
|
onStreamChunk: (chunk) => {
|
|
2950
|
-
// Stream output
|
|
2951
|
-
|
|
3004
|
+
// Stream output using clean streamContent() - chat box floats below
|
|
3005
|
+
this.terminalInput.streamContent(chunk);
|
|
2952
3006
|
},
|
|
2953
3007
|
onStreamFallback: (info) => this.handleStreamingFallback(info),
|
|
2954
3008
|
onAssistantMessage: (content, metadata) => {
|
|
@@ -2970,18 +3024,16 @@ What's the next action?`;
|
|
|
2970
3024
|
display.showAssistantMessage(finalContent, enriched);
|
|
2971
3025
|
}
|
|
2972
3026
|
}
|
|
2973
|
-
//
|
|
3027
|
+
// Status shown in mode controls bar - no separate status line needed
|
|
2974
3028
|
display.stopThinking();
|
|
2975
|
-
//
|
|
2976
|
-
let contextInfo;
|
|
3029
|
+
// Update context usage for mode controls display
|
|
2977
3030
|
if (enriched.contextWindowTokens && metadata.usage) {
|
|
2978
3031
|
const total = this.totalTokens(metadata.usage);
|
|
2979
3032
|
if (total && total > 0) {
|
|
2980
3033
|
const percentage = Math.round((total / enriched.contextWindowTokens) * 100);
|
|
2981
|
-
|
|
3034
|
+
this.updateContextUsage(percentage);
|
|
2982
3035
|
}
|
|
2983
3036
|
}
|
|
2984
|
-
display.showStatusLine('Ready for prompts', enriched.elapsedMs, contextInfo);
|
|
2985
3037
|
// Auto-verify changes: build first (catches type errors), then tests
|
|
2986
3038
|
void this.enforceAutoBuild('final-response');
|
|
2987
3039
|
void this.enforceAutoTests('final-response');
|
|
@@ -3051,7 +3103,6 @@ What's the next action?`;
|
|
|
3051
3103
|
this.stopStreamingHeartbeat();
|
|
3052
3104
|
this.updateStatusMessage(null);
|
|
3053
3105
|
this.terminalInput.setStreaming(false);
|
|
3054
|
-
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3055
3106
|
this.terminalInput.render();
|
|
3056
3107
|
},
|
|
3057
3108
|
onVerificationNeeded: () => {
|
|
@@ -3088,7 +3139,6 @@ What's the next action?`;
|
|
|
3088
3139
|
resetChatBoxAfterModelSwap() {
|
|
3089
3140
|
this.updateStatusMessage(null);
|
|
3090
3141
|
this.terminalInput.setStreaming(false);
|
|
3091
|
-
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3092
3142
|
this.terminalInput.render();
|
|
3093
3143
|
this.ensureReadlineReady();
|
|
3094
3144
|
}
|
|
@@ -3153,9 +3203,14 @@ What's the next action?`;
|
|
|
3153
3203
|
return null;
|
|
3154
3204
|
}
|
|
3155
3205
|
const usageRatio = total / windowTokens;
|
|
3206
|
+
this.latestTokenUsage = {
|
|
3207
|
+
used: total,
|
|
3208
|
+
limit: windowTokens,
|
|
3209
|
+
};
|
|
3156
3210
|
// Always update context usage in the UI
|
|
3157
3211
|
const percentUsed = Math.round(usageRatio * 100);
|
|
3158
3212
|
this.updateContextUsage(percentUsed);
|
|
3213
|
+
this.refreshStatusLine(true);
|
|
3159
3214
|
if (usageRatio < CONTEXT_USAGE_THRESHOLD) {
|
|
3160
3215
|
return null;
|
|
3161
3216
|
}
|
|
@@ -3422,6 +3477,22 @@ What's the next action?`;
|
|
|
3422
3477
|
this.sessionState.reasoningEffort = preset.reasoningEffort;
|
|
3423
3478
|
}
|
|
3424
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
|
+
}
|
|
3425
3496
|
refreshBannerSessionInfo() {
|
|
3426
3497
|
const nextState = {
|
|
3427
3498
|
model: this.sessionState.model,
|
|
@@ -3432,13 +3503,11 @@ What's the next action?`;
|
|
|
3432
3503
|
return;
|
|
3433
3504
|
}
|
|
3434
3505
|
this.refreshContextGauge();
|
|
3435
|
-
display
|
|
3436
|
-
//
|
|
3437
|
-
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
|
|
3438
3508
|
if (!this.isProcessing) {
|
|
3439
3509
|
this.setIdleStatus();
|
|
3440
3510
|
}
|
|
3441
|
-
// Pinned header rows are disabled; scroll region handles all output.
|
|
3442
3511
|
this.bannerSessionState = nextState;
|
|
3443
3512
|
}
|
|
3444
3513
|
providerLabel(id) {
|