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