erosolar-cli 1.7.321 → 1.7.322
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 +233 -164
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/shellApp.d.ts +2 -0
- package/dist/shell/shellApp.d.ts.map +1 -1
- package/dist/shell/shellApp.js +40 -9
- package/dist/shell/shellApp.js.map +1 -1
- package/dist/shell/systemPrompt.d.ts.map +1 -1
- package/dist/shell/systemPrompt.js +1 -4
- package/dist/shell/systemPrompt.js.map +1 -1
- package/dist/shell/terminalInput.d.ts +136 -115
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +560 -511
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/terminalInputAdapter.d.ts +71 -20
- package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
- package/dist/shell/terminalInputAdapter.js +87 -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
|
+
// Clear the entire terminal screen (including the launching command)
|
|
235
|
+
// and position cursor at top for a clean UI
|
|
236
|
+
this.terminalInput.clearScreen();
|
|
237
|
+
// Stream banner first - this sets up scroll region dynamically
|
|
238
|
+
const banner = this.buildBanner();
|
|
239
|
+
this.terminalInput.streamContent(banner + '\n\n');
|
|
240
|
+
// Render chat box after banner is streamed
|
|
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);
|
|
@@ -498,11 +520,9 @@ export class InteractiveShell {
|
|
|
498
520
|
// Dispose unified UI adapter
|
|
499
521
|
this.uiAdapter.dispose();
|
|
500
522
|
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)));
|
|
523
|
+
console.log(theme.ui.muted('━'.repeat(44)));
|
|
524
|
+
console.log(theme.ui.muted(' Goodbye! · support@ero.solar'));
|
|
525
|
+
console.log(theme.ui.muted('━'.repeat(44)));
|
|
506
526
|
exit(0);
|
|
507
527
|
}
|
|
508
528
|
/**
|
|
@@ -672,13 +692,14 @@ export class InteractiveShell {
|
|
|
672
692
|
});
|
|
673
693
|
}
|
|
674
694
|
setProcessingStatus(detail) {
|
|
695
|
+
this.latestTokenUsage = { used: null, limit: this.latestTokenUsage.limit };
|
|
675
696
|
this.statusTracker.setBase('Working on your request', {
|
|
676
697
|
detail: this.describeStatusDetail(detail),
|
|
677
698
|
tone: 'info',
|
|
678
699
|
});
|
|
679
700
|
}
|
|
680
701
|
describeStatusDetail(detail) {
|
|
681
|
-
const parts =
|
|
702
|
+
const parts = detail?.trim() ? [detail.trim()] : [];
|
|
682
703
|
const queued = this.followUpQueue.length;
|
|
683
704
|
if (queued > 0) {
|
|
684
705
|
parts.push(`${queued} follow-up${queued === 1 ? '' : 's'} queued`);
|
|
@@ -691,12 +712,18 @@ export class InteractiveShell {
|
|
|
691
712
|
}
|
|
692
713
|
refreshContextGauge() {
|
|
693
714
|
const tokens = getContextWindowTokens(this.sessionState.model);
|
|
694
|
-
|
|
695
|
-
|
|
715
|
+
const normalizedTokens = typeof tokens === 'number' && Number.isFinite(tokens) ? tokens : null;
|
|
716
|
+
this.activeContextWindowTokens = normalizedTokens;
|
|
717
|
+
if (normalizedTokens !== null) {
|
|
718
|
+
this.latestTokenUsage = {
|
|
719
|
+
used: this.latestTokenUsage.used,
|
|
720
|
+
limit: normalizedTokens,
|
|
721
|
+
};
|
|
722
|
+
}
|
|
696
723
|
}
|
|
697
724
|
updateContextUsage(percentage) {
|
|
698
725
|
this.uiAdapter.updateContextUsage(percentage);
|
|
699
|
-
this.terminalInput.setContextUsage(percentage);
|
|
726
|
+
this.terminalInput.setContextUsage(percentage, CONTEXT_AUTOCOMPACT_PERCENT);
|
|
700
727
|
}
|
|
701
728
|
refreshControlBar() {
|
|
702
729
|
this.terminalInput.setModeToggles({
|
|
@@ -704,9 +731,9 @@ export class InteractiveShell {
|
|
|
704
731
|
autoContinueEnabled: this.autoContinueEnabled,
|
|
705
732
|
verificationHotkey: 'alt+v',
|
|
706
733
|
autoContinueHotkey: 'alt+c',
|
|
734
|
+
thinkingModeLabel: this.thinkingMode,
|
|
735
|
+
thinkingHotkey: '/thinking',
|
|
707
736
|
});
|
|
708
|
-
// Update persistent model info display
|
|
709
|
-
this.terminalInput.setModelInfo(this.describeModelDetail());
|
|
710
737
|
this.refreshStatusLine();
|
|
711
738
|
this.terminalInput.render();
|
|
712
739
|
}
|
|
@@ -737,6 +764,25 @@ export class InteractiveShell {
|
|
|
737
764
|
// Set main status (tool execution, etc.) - shown when not overridden
|
|
738
765
|
const statusText = this.formatStatusLine(this.statusLineState);
|
|
739
766
|
this.terminalInput.setStatusMessage(statusText);
|
|
767
|
+
// Surface meta header (elapsed + context usage) above the divider
|
|
768
|
+
const elapsedSeconds = this.statusLineState
|
|
769
|
+
? Math.max(0, Math.floor((Date.now() - this.statusLineState.startedAt) / 1000))
|
|
770
|
+
: null;
|
|
771
|
+
const thinkingMs = display.isSpinnerActive() ? display.getThinkingElapsedMs() : null;
|
|
772
|
+
const tokensUsed = this.latestTokenUsage.used;
|
|
773
|
+
const tokenLimit = this.latestTokenUsage.limit ?? this.activeContextWindowTokens;
|
|
774
|
+
this.terminalInput.setMetaStatus({
|
|
775
|
+
elapsedSeconds,
|
|
776
|
+
tokensUsed,
|
|
777
|
+
tokenLimit,
|
|
778
|
+
thinkingMs,
|
|
779
|
+
thinkingHasContent: display.isSpinnerActive(),
|
|
780
|
+
});
|
|
781
|
+
// Keep model/provider visible in the controls bar
|
|
782
|
+
this.terminalInput.setModelContext({
|
|
783
|
+
model: this.sessionState.model,
|
|
784
|
+
provider: this.providerLabel(this.sessionState.provider),
|
|
785
|
+
});
|
|
740
786
|
if (forceRender) {
|
|
741
787
|
this.terminalInput.render();
|
|
742
788
|
}
|
|
@@ -796,13 +842,14 @@ export class InteractiveShell {
|
|
|
796
842
|
this.terminalInput.render();
|
|
797
843
|
}
|
|
798
844
|
/**
|
|
799
|
-
* Log
|
|
800
|
-
* This creates a persistent log entry that remains visible during and after streaming.
|
|
845
|
+
* Log user prompt to the scroll region so it's part of the conversation flow.
|
|
801
846
|
*/
|
|
802
847
|
logUserPrompt(text) {
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
848
|
+
if (!text.trim())
|
|
849
|
+
return;
|
|
850
|
+
// Format with user prompt prefix and write to scroll region
|
|
851
|
+
const formatted = `${theme.user('>')} ${text}\n`;
|
|
852
|
+
this.terminalInput.writeToScrollRegion(formatted);
|
|
806
853
|
}
|
|
807
854
|
requestPromptRefresh(force = false) {
|
|
808
855
|
if (force) {
|
|
@@ -827,16 +874,40 @@ export class InteractiveShell {
|
|
|
827
874
|
this.stopStreamingHeartbeat();
|
|
828
875
|
// Enter global streaming mode - blocks all non-streaming UI output
|
|
829
876
|
enterStreamingMode();
|
|
877
|
+
// Set up scroll region for streaming content
|
|
878
|
+
this.terminalInput.enterStreamingScrollRegion();
|
|
830
879
|
this.uiUpdates.setMode('streaming');
|
|
831
880
|
this.streamingHeartbeatStart = Date.now();
|
|
832
881
|
this.streamingHeartbeatFrame = 0;
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
882
|
+
const initialFrame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
|
|
883
|
+
this.streamingStatusLabel = this.buildStreamingStatus(`${initialFrame} ${label}`, 0);
|
|
884
|
+
display.updateStreamingStatus(this.streamingStatusLabel);
|
|
885
|
+
this.refreshStatusLine(true);
|
|
886
|
+
// Periodically refresh the pinned input/status region while streaming so
|
|
887
|
+
// elapsed time remains visible without interrupting the scroll region.
|
|
888
|
+
this.uiUpdates.startHeartbeat('streaming', {
|
|
889
|
+
intervalMs: 1000,
|
|
890
|
+
lane: 'heartbeat',
|
|
891
|
+
mode: ['streaming', 'processing'],
|
|
892
|
+
coalesceKey: 'streaming:heartbeat',
|
|
893
|
+
run: () => {
|
|
894
|
+
const elapsedSeconds = this.streamingHeartbeatStart
|
|
895
|
+
? Math.max(0, Math.floor((Date.now() - this.streamingHeartbeatStart) / 1000))
|
|
896
|
+
: 0;
|
|
897
|
+
this.streamingHeartbeatFrame =
|
|
898
|
+
(this.streamingHeartbeatFrame + 1) % STREAMING_SPINNER_FRAMES.length;
|
|
899
|
+
const frame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
|
|
900
|
+
this.streamingStatusLabel = this.buildStreamingStatus(`${frame} ${label}`, elapsedSeconds);
|
|
901
|
+
display.updateStreamingStatus(this.streamingStatusLabel);
|
|
902
|
+
this.refreshStatusLine(true);
|
|
903
|
+
},
|
|
904
|
+
});
|
|
836
905
|
}
|
|
837
906
|
stopStreamingHeartbeat() {
|
|
838
907
|
// Exit global streaming mode - allows UI to render again
|
|
839
908
|
exitStreamingMode();
|
|
909
|
+
// Exit scroll region mode
|
|
910
|
+
this.terminalInput.exitStreamingScrollRegion();
|
|
840
911
|
this.uiUpdates.stopHeartbeat('streaming');
|
|
841
912
|
this.streamingHeartbeatStart = null;
|
|
842
913
|
this.streamingHeartbeatFrame = 0;
|
|
@@ -848,10 +919,28 @@ export class InteractiveShell {
|
|
|
848
919
|
// Force refresh to update the input area now that streaming has ended
|
|
849
920
|
this.refreshStatusLine(true);
|
|
850
921
|
}
|
|
851
|
-
buildStreamingStatus(label) {
|
|
922
|
+
buildStreamingStatus(label, elapsedSeconds) {
|
|
852
923
|
const detail = this.describeModelDetail();
|
|
853
|
-
const
|
|
854
|
-
|
|
924
|
+
const elapsedLabel = typeof elapsedSeconds === 'number' && elapsedSeconds >= 0
|
|
925
|
+
? theme.ui.muted(this.formatElapsedShort(elapsedSeconds))
|
|
926
|
+
: null;
|
|
927
|
+
const prefix = theme.info('⏺');
|
|
928
|
+
const parts = [label];
|
|
929
|
+
if (detail) {
|
|
930
|
+
parts.push(theme.ui.muted('·'), detail);
|
|
931
|
+
}
|
|
932
|
+
if (elapsedLabel) {
|
|
933
|
+
parts.push(theme.ui.muted('·'), elapsedLabel);
|
|
934
|
+
}
|
|
935
|
+
return `${prefix} ${parts.join(' ')}`.trim();
|
|
936
|
+
}
|
|
937
|
+
formatElapsedShort(seconds) {
|
|
938
|
+
if (seconds < 60) {
|
|
939
|
+
return `${seconds}s`;
|
|
940
|
+
}
|
|
941
|
+
const minutes = Math.floor(seconds / 60);
|
|
942
|
+
const remaining = seconds % 60;
|
|
943
|
+
return remaining > 0 ? `${minutes}m ${remaining}s` : `${minutes}m`;
|
|
855
944
|
}
|
|
856
945
|
refreshQueueIndicators() {
|
|
857
946
|
if (this.isProcessing) {
|
|
@@ -1099,17 +1188,6 @@ export class InteractiveShell {
|
|
|
1099
1188
|
case '/discover':
|
|
1100
1189
|
await this.discoverModelsCommand();
|
|
1101
1190
|
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
1191
|
default:
|
|
1114
1192
|
if (!(await this.tryCustomSlashCommand(command, input))) {
|
|
1115
1193
|
display.showWarning(`Unknown command "${command}".`);
|
|
@@ -1418,99 +1496,6 @@ export class InteractiveShell {
|
|
|
1418
1496
|
// Display keyboard shortcuts help (Claude Code style)
|
|
1419
1497
|
display.showSystemMessage(formatShortcutsHelp());
|
|
1420
1498
|
}
|
|
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
1499
|
showFileChangeSummary() {
|
|
1515
1500
|
const summary = this._fileChangeTracker.getSummary();
|
|
1516
1501
|
const changes = this._fileChangeTracker.getAllChanges();
|
|
@@ -1553,11 +1538,11 @@ When working in this codebase:
|
|
|
1553
1538
|
display.showSystemMessage(lines.join('\n'));
|
|
1554
1539
|
}
|
|
1555
1540
|
showAlphaZeroMetrics() {
|
|
1556
|
-
const summary = this.
|
|
1541
|
+
const summary = this.alphaZeroMetrics.getPerformanceSummary();
|
|
1557
1542
|
display.showSystemMessage(summary);
|
|
1558
1543
|
}
|
|
1559
1544
|
showImprovementSuggestions() {
|
|
1560
|
-
const suggestions = this.
|
|
1545
|
+
const suggestions = this.alphaZeroMetrics.getImprovementSuggestions();
|
|
1561
1546
|
if (suggestions.length === 0) {
|
|
1562
1547
|
display.showInfo('No improvement suggestions at this time. Keep using the shell to generate metrics!');
|
|
1563
1548
|
return;
|
|
@@ -1603,7 +1588,9 @@ When working in this codebase:
|
|
|
1603
1588
|
}
|
|
1604
1589
|
}
|
|
1605
1590
|
lines.push(theme.secondary('CLI Flags:'));
|
|
1591
|
+
lines.push(' --alpha-zero Enable Alpha Zero 2 RL framework');
|
|
1606
1592
|
lines.push(' --coding Enable enhanced coding tools');
|
|
1593
|
+
lines.push(' --security Enable security research tools');
|
|
1607
1594
|
lines.push(' --all-plugins Enable all optional plugins');
|
|
1608
1595
|
display.showSystemMessage(lines.join('\n'));
|
|
1609
1596
|
}
|
|
@@ -1847,6 +1834,75 @@ When working in this codebase:
|
|
|
1847
1834
|
}
|
|
1848
1835
|
return `${warning.label}: ${warning.reason}.`;
|
|
1849
1836
|
}
|
|
1837
|
+
buildLaunchCommandPalette() {
|
|
1838
|
+
const entries = [];
|
|
1839
|
+
const secretsSummary = this.summarizeSecretsForPalette();
|
|
1840
|
+
const toolSummary = this.getToolSelectionSummary();
|
|
1841
|
+
const autosaveLabel = this.autosaveEnabled ? 'on' : 'off';
|
|
1842
|
+
for (const command of this.slashCommands) {
|
|
1843
|
+
const entry = {
|
|
1844
|
+
command: command.command,
|
|
1845
|
+
description: command.description,
|
|
1846
|
+
category: command.category ?? 'other',
|
|
1847
|
+
};
|
|
1848
|
+
switch (command.command) {
|
|
1849
|
+
case '/secrets':
|
|
1850
|
+
if (secretsSummary.text) {
|
|
1851
|
+
entry.description = `${command.description} (${secretsSummary.text})`;
|
|
1852
|
+
entry.tone = secretsSummary.tone;
|
|
1853
|
+
}
|
|
1854
|
+
break;
|
|
1855
|
+
case '/tools':
|
|
1856
|
+
if (toolSummary) {
|
|
1857
|
+
entry.description = `${command.description} (${toolSummary})`;
|
|
1858
|
+
}
|
|
1859
|
+
break;
|
|
1860
|
+
case '/sessions':
|
|
1861
|
+
entry.description = `${command.description} (autosave ${autosaveLabel})`;
|
|
1862
|
+
break;
|
|
1863
|
+
case '/model':
|
|
1864
|
+
entry.description = `${command.description} (current: ${this.sessionState.model})`;
|
|
1865
|
+
break;
|
|
1866
|
+
case '/provider':
|
|
1867
|
+
entry.description = `${command.description} (current: ${this.providerLabel(this.sessionState.provider)})`;
|
|
1868
|
+
break;
|
|
1869
|
+
default:
|
|
1870
|
+
break;
|
|
1871
|
+
}
|
|
1872
|
+
entries.push(entry);
|
|
1873
|
+
}
|
|
1874
|
+
return entries;
|
|
1875
|
+
}
|
|
1876
|
+
summarizeSecretsForPalette() {
|
|
1877
|
+
const definitions = listSecretDefinitions();
|
|
1878
|
+
if (!definitions.length) {
|
|
1879
|
+
return { text: null };
|
|
1880
|
+
}
|
|
1881
|
+
const missing = definitions.filter((definition) => !getSecretValue(definition.id));
|
|
1882
|
+
if (missing.length === 0) {
|
|
1883
|
+
return { text: 'all configured', tone: 'success' };
|
|
1884
|
+
}
|
|
1885
|
+
const labels = missing.map((definition) => definition.label ?? definition.id);
|
|
1886
|
+
return { text: `missing ${this.formatList(labels)}`, tone: 'warn' };
|
|
1887
|
+
}
|
|
1888
|
+
getToolSelectionSummary() {
|
|
1889
|
+
const toolSettings = loadToolSettings();
|
|
1890
|
+
const selection = buildEnabledToolSet(toolSettings);
|
|
1891
|
+
const options = getToolToggleOptions();
|
|
1892
|
+
if (!options.length) {
|
|
1893
|
+
return null;
|
|
1894
|
+
}
|
|
1895
|
+
const enabledCount = options.filter((option) => selection.has(option.id)).length;
|
|
1896
|
+
return `${enabledCount}/${options.length} enabled`;
|
|
1897
|
+
}
|
|
1898
|
+
formatList(values, maxItems = 3) {
|
|
1899
|
+
if (!values.length) {
|
|
1900
|
+
return '';
|
|
1901
|
+
}
|
|
1902
|
+
const shown = values.slice(0, maxItems);
|
|
1903
|
+
const suffix = values.length > maxItems ? ', …' : '';
|
|
1904
|
+
return `${shown.join(', ')}${suffix}`;
|
|
1905
|
+
}
|
|
1850
1906
|
buildSlashCommandList(header) {
|
|
1851
1907
|
const lines = [theme.gradient.primary(header), ''];
|
|
1852
1908
|
for (const command of this.slashCommands) {
|
|
@@ -2315,7 +2371,7 @@ When working in this codebase:
|
|
|
2315
2371
|
this.autosaveIfEnabled();
|
|
2316
2372
|
// Track metrics with Alpha Zero 2
|
|
2317
2373
|
const elapsedMs = Date.now() - requestStartTime;
|
|
2318
|
-
this.
|
|
2374
|
+
this.alphaZeroMetrics.recordMessage(elapsedMs);
|
|
2319
2375
|
if (!responseText?.trim()) {
|
|
2320
2376
|
display.showWarning('The provider returned an empty response. Check your API key/provider selection or retry the prompt.');
|
|
2321
2377
|
}
|
|
@@ -2333,14 +2389,10 @@ When working in this codebase:
|
|
|
2333
2389
|
this.stopStreamingHeartbeat();
|
|
2334
2390
|
this.isProcessing = false;
|
|
2335
2391
|
this.terminalInput.setStreaming(false);
|
|
2336
|
-
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2337
2392
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2338
2393
|
this.setIdleStatus();
|
|
2339
2394
|
display.newLine();
|
|
2340
2395
|
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
2396
|
queueMicrotask(() => this.uiUpdates.setMode('idle'));
|
|
2345
2397
|
// CRITICAL: Ensure readline prompt is active for user input
|
|
2346
2398
|
// Claude Code style: New prompt naturally appears at bottom
|
|
@@ -2417,13 +2469,14 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
|
|
|
2417
2469
|
try {
|
|
2418
2470
|
// Send the request and capture the response (streaming disabled)
|
|
2419
2471
|
display.showThinking('Responding...');
|
|
2472
|
+
this.refreshStatusLine(true);
|
|
2420
2473
|
const response = await agent.send(currentPrompt, true);
|
|
2421
2474
|
await this.awaitPendingCleanup();
|
|
2422
2475
|
this.captureHistorySnapshot();
|
|
2423
2476
|
this.autosaveIfEnabled();
|
|
2424
2477
|
// Track metrics
|
|
2425
2478
|
const elapsedMs = Date.now() - overallStartTime;
|
|
2426
|
-
this.
|
|
2479
|
+
this.alphaZeroMetrics.recordMessage(elapsedMs);
|
|
2427
2480
|
if (!response?.trim()) {
|
|
2428
2481
|
display.showWarning('Model returned an empty response. Retrying this iteration...');
|
|
2429
2482
|
consecutiveNoProgress++;
|
|
@@ -2560,7 +2613,6 @@ What's the next action?`;
|
|
|
2560
2613
|
this.stopStreamingHeartbeat();
|
|
2561
2614
|
this.isProcessing = false;
|
|
2562
2615
|
this.terminalInput.setStreaming(false);
|
|
2563
|
-
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
2564
2616
|
this.uiAdapter.endProcessing('Ready for prompts');
|
|
2565
2617
|
this.setIdleStatus();
|
|
2566
2618
|
this.updateStatusMessage(null);
|
|
@@ -2917,8 +2969,10 @@ What's the next action?`;
|
|
|
2917
2969
|
try {
|
|
2918
2970
|
// Send the error to the agent for fixing
|
|
2919
2971
|
display.showThinking('Analyzing build errors');
|
|
2972
|
+
this.refreshStatusLine(true);
|
|
2920
2973
|
const response = await this.agent.send(prompt, true);
|
|
2921
2974
|
display.stopThinking();
|
|
2975
|
+
this.refreshStatusLine(true);
|
|
2922
2976
|
if (response) {
|
|
2923
2977
|
display.showAssistantMessage(response, { isFinal: true });
|
|
2924
2978
|
}
|
|
@@ -2945,8 +2999,8 @@ What's the next action?`;
|
|
|
2945
2999
|
};
|
|
2946
3000
|
this.agent = this.runtimeSession.createAgent(selection, {
|
|
2947
3001
|
onStreamChunk: (chunk) => {
|
|
2948
|
-
// Stream output
|
|
2949
|
-
|
|
3002
|
+
// Stream output using clean streamContent() - chat box floats below
|
|
3003
|
+
this.terminalInput.streamContent(chunk);
|
|
2950
3004
|
},
|
|
2951
3005
|
onStreamFallback: (info) => this.handleStreamingFallback(info),
|
|
2952
3006
|
onAssistantMessage: (content, metadata) => {
|
|
@@ -2968,18 +3022,16 @@ What's the next action?`;
|
|
|
2968
3022
|
display.showAssistantMessage(finalContent, enriched);
|
|
2969
3023
|
}
|
|
2970
3024
|
}
|
|
2971
|
-
//
|
|
3025
|
+
// Status shown in mode controls bar - no separate status line needed
|
|
2972
3026
|
display.stopThinking();
|
|
2973
|
-
//
|
|
2974
|
-
let contextInfo;
|
|
3027
|
+
// Update context usage for mode controls display
|
|
2975
3028
|
if (enriched.contextWindowTokens && metadata.usage) {
|
|
2976
3029
|
const total = this.totalTokens(metadata.usage);
|
|
2977
3030
|
if (total && total > 0) {
|
|
2978
3031
|
const percentage = Math.round((total / enriched.contextWindowTokens) * 100);
|
|
2979
|
-
|
|
3032
|
+
this.updateContextUsage(percentage);
|
|
2980
3033
|
}
|
|
2981
3034
|
}
|
|
2982
|
-
display.showStatusLine('Ready for prompts', enriched.elapsedMs, contextInfo);
|
|
2983
3035
|
// Auto-verify changes: build first (catches type errors), then tests
|
|
2984
3036
|
void this.enforceAutoBuild('final-response');
|
|
2985
3037
|
void this.enforceAutoTests('final-response');
|
|
@@ -3049,7 +3101,6 @@ What's the next action?`;
|
|
|
3049
3101
|
this.stopStreamingHeartbeat();
|
|
3050
3102
|
this.updateStatusMessage(null);
|
|
3051
3103
|
this.terminalInput.setStreaming(false);
|
|
3052
|
-
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3053
3104
|
this.terminalInput.render();
|
|
3054
3105
|
},
|
|
3055
3106
|
onVerificationNeeded: () => {
|
|
@@ -3086,7 +3137,6 @@ What's the next action?`;
|
|
|
3086
3137
|
resetChatBoxAfterModelSwap() {
|
|
3087
3138
|
this.updateStatusMessage(null);
|
|
3088
3139
|
this.terminalInput.setStreaming(false);
|
|
3089
|
-
this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
|
|
3090
3140
|
this.terminalInput.render();
|
|
3091
3141
|
this.ensureReadlineReady();
|
|
3092
3142
|
}
|
|
@@ -3151,9 +3201,14 @@ What's the next action?`;
|
|
|
3151
3201
|
return null;
|
|
3152
3202
|
}
|
|
3153
3203
|
const usageRatio = total / windowTokens;
|
|
3204
|
+
this.latestTokenUsage = {
|
|
3205
|
+
used: total,
|
|
3206
|
+
limit: windowTokens,
|
|
3207
|
+
};
|
|
3154
3208
|
// Always update context usage in the UI
|
|
3155
3209
|
const percentUsed = Math.round(usageRatio * 100);
|
|
3156
3210
|
this.updateContextUsage(percentUsed);
|
|
3211
|
+
this.refreshStatusLine(true);
|
|
3157
3212
|
if (usageRatio < CONTEXT_USAGE_THRESHOLD) {
|
|
3158
3213
|
return null;
|
|
3159
3214
|
}
|
|
@@ -3420,6 +3475,22 @@ What's the next action?`;
|
|
|
3420
3475
|
this.sessionState.reasoningEffort = preset.reasoningEffort;
|
|
3421
3476
|
}
|
|
3422
3477
|
}
|
|
3478
|
+
/**
|
|
3479
|
+
* Build the session banner.
|
|
3480
|
+
*/
|
|
3481
|
+
buildBanner() {
|
|
3482
|
+
const terminalWidth = output.columns ?? 100;
|
|
3483
|
+
const width = Math.min(terminalWidth - 4, 110);
|
|
3484
|
+
return renderSessionFrame({
|
|
3485
|
+
profileLabel: this.profileLabel,
|
|
3486
|
+
profileName: this.profile,
|
|
3487
|
+
model: this.sessionState.model,
|
|
3488
|
+
provider: this.sessionState.provider,
|
|
3489
|
+
workspace: this.workingDir,
|
|
3490
|
+
version: this.version,
|
|
3491
|
+
width,
|
|
3492
|
+
});
|
|
3493
|
+
}
|
|
3423
3494
|
refreshBannerSessionInfo() {
|
|
3424
3495
|
const nextState = {
|
|
3425
3496
|
model: this.sessionState.model,
|
|
@@ -3430,13 +3501,11 @@ What's the next action?`;
|
|
|
3430
3501
|
return;
|
|
3431
3502
|
}
|
|
3432
3503
|
this.refreshContextGauge();
|
|
3433
|
-
display
|
|
3434
|
-
//
|
|
3435
|
-
this.terminalInput.setModelInfo(this.describeModelDetail());
|
|
3504
|
+
// Banner is no longer stored in display - it was streamed as content
|
|
3505
|
+
// Model/provider changes are visible in the control bar
|
|
3436
3506
|
if (!this.isProcessing) {
|
|
3437
3507
|
this.setIdleStatus();
|
|
3438
3508
|
}
|
|
3439
|
-
// Pinned header rows are disabled; scroll region handles all output.
|
|
3440
3509
|
this.bannerSessionState = nextState;
|
|
3441
3510
|
}
|
|
3442
3511
|
providerLabel(id) {
|