erosolar-cli 1.7.373 → 1.7.377
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/dist/capabilities/agentSpawningCapability.d.ts.map +1 -1
- package/dist/capabilities/agentSpawningCapability.js +29 -1
- package/dist/capabilities/agentSpawningCapability.js.map +1 -1
- package/dist/contracts/agent-schemas.json +100 -0
- package/dist/core/alphaZeroOrchestrator.d.ts +140 -0
- package/dist/core/alphaZeroOrchestrator.d.ts.map +1 -0
- package/dist/core/alphaZeroOrchestrator.js +418 -0
- package/dist/core/alphaZeroOrchestrator.js.map +1 -0
- package/dist/core/checkpoint.d.ts +76 -0
- package/dist/core/checkpoint.d.ts.map +1 -0
- package/dist/core/checkpoint.js +278 -0
- package/dist/core/checkpoint.js.map +1 -0
- package/dist/core/claudeCodeFeatures.d.ts +64 -0
- package/dist/core/claudeCodeFeatures.d.ts.map +1 -0
- package/dist/core/claudeCodeFeatures.js +163 -0
- package/dist/core/claudeCodeFeatures.js.map +1 -0
- package/dist/core/costTracker.d.ts +87 -0
- package/dist/core/costTracker.d.ts.map +1 -0
- package/dist/core/costTracker.js +285 -0
- package/dist/core/costTracker.js.map +1 -0
- package/dist/core/failureRecovery.d.ts +122 -0
- package/dist/core/failureRecovery.d.ts.map +1 -0
- package/dist/core/failureRecovery.js +477 -0
- package/dist/core/failureRecovery.js.map +1 -0
- package/dist/core/learningPersistence.d.ts +145 -0
- package/dist/core/learningPersistence.d.ts.map +1 -0
- package/dist/core/learningPersistence.js +477 -0
- package/dist/core/learningPersistence.js.map +1 -0
- package/dist/core/memorySystem.d.ts +67 -0
- package/dist/core/memorySystem.d.ts.map +1 -0
- package/dist/core/memorySystem.js +334 -0
- package/dist/core/memorySystem.js.map +1 -0
- package/dist/core/outputStyles.d.ts +48 -0
- package/dist/core/outputStyles.d.ts.map +1 -0
- package/dist/core/outputStyles.js +270 -0
- package/dist/core/outputStyles.js.map +1 -0
- package/dist/core/selfEvolution.d.ts +155 -0
- package/dist/core/selfEvolution.d.ts.map +1 -0
- package/dist/core/selfEvolution.js +1000 -0
- package/dist/core/selfEvolution.js.map +1 -0
- package/dist/core/selfImprovement.d.ts +141 -0
- package/dist/core/selfImprovement.d.ts.map +1 -0
- package/dist/core/selfImprovement.js +700 -0
- package/dist/core/selfImprovement.js.map +1 -0
- package/dist/core/updateManager.d.ts +62 -0
- package/dist/core/updateManager.d.ts.map +1 -0
- package/dist/core/updateManager.js +266 -0
- package/dist/core/updateManager.js.map +1 -0
- package/dist/shell/interactiveShell.d.ts +45 -0
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +1156 -3
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/keyboardShortcuts.d.ts +53 -0
- package/dist/shell/keyboardShortcuts.d.ts.map +1 -0
- package/dist/shell/keyboardShortcuts.js +163 -0
- package/dist/shell/keyboardShortcuts.js.map +1 -0
- package/dist/shell/terminalInput.d.ts +1 -1
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +8 -4
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/vimMode.d.ts +66 -0
- package/dist/shell/vimMode.d.ts.map +1 -0
- package/dist/shell/vimMode.js +434 -0
- package/dist/shell/vimMode.js.map +1 -0
- package/dist/subagents/parallelAgentManager.d.ts +99 -0
- package/dist/subagents/parallelAgentManager.d.ts.map +1 -0
- package/dist/subagents/parallelAgentManager.js +249 -0
- package/dist/subagents/parallelAgentManager.js.map +1 -0
- package/dist/subagents/taskRunner.d.ts +6 -1
- package/dist/subagents/taskRunner.d.ts.map +1 -1
- package/dist/subagents/taskRunner.js +57 -2
- package/dist/subagents/taskRunner.js.map +1 -1
- package/dist/tools/planningTools.d.ts +9 -0
- package/dist/tools/planningTools.d.ts.map +1 -1
- package/dist/tools/planningTools.js +90 -0
- package/dist/tools/planningTools.js.map +1 -1
- package/dist/ui/display.d.ts +5 -0
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +14 -0
- package/dist/ui/display.js.map +1 -1
- package/dist/ui/shortcutsHelp.d.ts.map +1 -1
- package/dist/ui/shortcutsHelp.js +34 -3
- package/dist/ui/shortcutsHelp.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,6 +6,7 @@ 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, loadFeatureFlags, saveFeatureFlags, toggleFeatureFlag, FEATURE_FLAG_INFO, } from '../core/preferences.js';
|
|
9
|
+
import { getLearningSummary, getRecentLearning, commitLearning, exportAllLearning, getLearningDir, } from '../core/learningPersistence.js';
|
|
9
10
|
import { buildEnabledToolSet, evaluateToolPermissions, getToolToggleOptions, } from '../capabilities/toolRegistry.js';
|
|
10
11
|
import { detectApiKeyError } from '../core/errors/apiKeyErrors.js';
|
|
11
12
|
import { buildWorkspaceContext } from '../workspace.js';
|
|
@@ -20,8 +21,14 @@ import { SkillRepository } from '../skills/skillRepository.js';
|
|
|
20
21
|
import { createSkillTools } from '../tools/skillTools.js';
|
|
21
22
|
import { FileChangeTracker } from './fileChangeTracker.js';
|
|
22
23
|
import { formatShortcutsHelp } from '../ui/shortcutsHelp.js';
|
|
24
|
+
import { setPlanApprovalCallback } from '../tools/planningTools.js';
|
|
23
25
|
import { MetricsTracker } from '../core/metricsTracker.js';
|
|
26
|
+
import { detectFailure, clearActionHistory, findRecoveryStrategy, } from '../core/failureRecovery.js';
|
|
27
|
+
import { addToolPattern } from '../core/learningPersistence.js';
|
|
28
|
+
import { classifyTaskType } from '../core/alphaZeroEngine.js';
|
|
29
|
+
import { analyzeImprovementOpportunities, runSelfImprovementCycle, getImprovementSummary, runAutonomousImprovement, requestAutoImprovementStop, getAutoImprovementState, emergencyRollback, } from '../core/selfImprovement.js';
|
|
24
30
|
import { listAvailablePlugins } from '../plugins/index.js';
|
|
31
|
+
import { isErosolarRepo, isValidSourceRepo, getRepoName, analyzeSource, runSelfEvolution, stopEvolution, getEvolutionStatus, emergencyEvolutionRollback, learnSourcePatterns, generateFix, } from '../core/selfEvolution.js';
|
|
25
32
|
import { TerminalInputAdapter } from './terminalInputAdapter.js';
|
|
26
33
|
import { renderSessionFrame } from '../ui/unified/layout.js';
|
|
27
34
|
import { isUpdateInProgress, maybeOfferCliUpdate } from './updateManager.js';
|
|
@@ -29,6 +36,7 @@ import { writeLock } from '../ui/writeLock.js';
|
|
|
29
36
|
import { enterStreamingMode, exitStreamingMode } from '../ui/globalWriteLock.js';
|
|
30
37
|
import { setGlobalAIEnhancer } from '../tools/localExplore.js';
|
|
31
38
|
import { createProvider } from '../providers/providerFactory.js';
|
|
39
|
+
import { getParallelAgentManager } from '../subagents/parallelAgentManager.js';
|
|
32
40
|
const execAsync = promisify(exec);
|
|
33
41
|
const DROPDOWN_COLORS = [
|
|
34
42
|
theme.primary,
|
|
@@ -125,6 +133,11 @@ export class InteractiveShell {
|
|
|
125
133
|
cachedProviderStatus = [];
|
|
126
134
|
// Auto-test tracking
|
|
127
135
|
autoTestInFlight = false;
|
|
136
|
+
// AlphaZero learning tracking
|
|
137
|
+
currentTaskType = 'general';
|
|
138
|
+
currentToolCalls = [];
|
|
139
|
+
lastUserQuery = '';
|
|
140
|
+
lastFailure = null;
|
|
128
141
|
lastAutoTestRun = null;
|
|
129
142
|
// Auto-build tracking
|
|
130
143
|
autoBuildInFlight = false;
|
|
@@ -256,6 +269,37 @@ export class InteractiveShell {
|
|
|
256
269
|
this.rebuildAgent();
|
|
257
270
|
this.setupHandlers();
|
|
258
271
|
this.refreshBannerSessionInfo();
|
|
272
|
+
// Subscribe to parallel agent manager events
|
|
273
|
+
this.setupParallelAgentTracking();
|
|
274
|
+
}
|
|
275
|
+
parallelAgentDisplayLines = [];
|
|
276
|
+
setupParallelAgentTracking() {
|
|
277
|
+
const manager = getParallelAgentManager();
|
|
278
|
+
// Update display when agent status changes
|
|
279
|
+
const updateDisplay = () => {
|
|
280
|
+
this.parallelAgentDisplayLines = manager.formatDisplay();
|
|
281
|
+
// Trigger UI refresh if streaming
|
|
282
|
+
if (this.streamingHeartbeatStart) {
|
|
283
|
+
this.displayParallelAgents();
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
manager.on('agent:started', updateDisplay);
|
|
287
|
+
manager.on('agent:progress', updateDisplay);
|
|
288
|
+
manager.on('agent:completed', updateDisplay);
|
|
289
|
+
manager.on('agent:error', updateDisplay);
|
|
290
|
+
manager.on('batch:completed', () => {
|
|
291
|
+
// Clear after batch completes to show final summary
|
|
292
|
+
setTimeout(() => {
|
|
293
|
+
this.parallelAgentDisplayLines = [];
|
|
294
|
+
}, 2000);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
displayParallelAgents() {
|
|
298
|
+
if (this.parallelAgentDisplayLines.length === 0)
|
|
299
|
+
return;
|
|
300
|
+
// Display parallel agent tree above the current output
|
|
301
|
+
const agentDisplay = this.parallelAgentDisplayLines.join('\n');
|
|
302
|
+
display.parallelAgentStatus(agentDisplay);
|
|
259
303
|
}
|
|
260
304
|
initializeSessionHistory() {
|
|
261
305
|
this.cachedHistory = [];
|
|
@@ -386,11 +430,22 @@ export class InteractiveShell {
|
|
|
386
430
|
handleEditModeChange(mode) {
|
|
387
431
|
this.editGuardMode = mode;
|
|
388
432
|
this.pendingPermissionInput = null;
|
|
389
|
-
if (mode === '
|
|
390
|
-
|
|
433
|
+
if (mode === 'plan') {
|
|
434
|
+
// Register plan approval callback for interactive UI
|
|
435
|
+
setPlanApprovalCallback((steps, explanation) => {
|
|
436
|
+
this.showPlanApproval(steps, explanation);
|
|
437
|
+
});
|
|
438
|
+
display.showSystemMessage('📋 Plan mode enabled. AI will create a plan and ask for approval before implementing.');
|
|
391
439
|
}
|
|
392
440
|
else {
|
|
393
|
-
|
|
441
|
+
// Unregister callback when not in plan mode
|
|
442
|
+
setPlanApprovalCallback(null);
|
|
443
|
+
if (mode === 'ask-permission') {
|
|
444
|
+
display.showSystemMessage('🛡️ Ask-to-edit mode enabled. Confirm each request before sending.');
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
display.showSystemMessage('✏️ Display edits mode enabled.');
|
|
448
|
+
}
|
|
394
449
|
}
|
|
395
450
|
this.terminalInput.render();
|
|
396
451
|
}
|
|
@@ -757,6 +812,130 @@ export class InteractiveShell {
|
|
|
757
812
|
this.agentMenu.persistedProfile = profileName;
|
|
758
813
|
display.showInfo(`${this.agentMenuLabel(profileName)} will load the next time you start the CLI. Restart to switch now.`);
|
|
759
814
|
}
|
|
815
|
+
/**
|
|
816
|
+
* Show plan approval UI with interactive step selection
|
|
817
|
+
*/
|
|
818
|
+
showPlanApproval(steps, explanation) {
|
|
819
|
+
const planSteps = steps.map((step, idx) => ({
|
|
820
|
+
id: idx + 1,
|
|
821
|
+
description: step.description,
|
|
822
|
+
status: 'pending',
|
|
823
|
+
}));
|
|
824
|
+
this.pendingInteraction = {
|
|
825
|
+
type: 'plan-approval',
|
|
826
|
+
steps: planSteps,
|
|
827
|
+
selectedSteps: new Set(planSteps.map(s => s.id)), // All selected by default
|
|
828
|
+
explanation,
|
|
829
|
+
};
|
|
830
|
+
this.displayPlanApprovalUI();
|
|
831
|
+
}
|
|
832
|
+
displayPlanApprovalUI() {
|
|
833
|
+
const pending = this.pendingInteraction;
|
|
834
|
+
if (!pending || pending.type !== 'plan-approval')
|
|
835
|
+
return;
|
|
836
|
+
const lines = [];
|
|
837
|
+
lines.push('');
|
|
838
|
+
lines.push(theme.gradient.primary('═'.repeat(60)));
|
|
839
|
+
lines.push(theme.gradient.primary('📋 PLAN FOR APPROVAL'));
|
|
840
|
+
lines.push(theme.gradient.primary('═'.repeat(60)));
|
|
841
|
+
lines.push('');
|
|
842
|
+
if (pending.explanation) {
|
|
843
|
+
lines.push(theme.ui.muted(pending.explanation));
|
|
844
|
+
lines.push('');
|
|
845
|
+
}
|
|
846
|
+
lines.push(theme.info('Steps (toggle with number, or enter your own):'));
|
|
847
|
+
lines.push('');
|
|
848
|
+
for (const step of pending.steps) {
|
|
849
|
+
const isSelected = pending.selectedSteps.has(step.id);
|
|
850
|
+
const checkbox = isSelected ? theme.success('☑') : theme.ui.muted('☐');
|
|
851
|
+
const stepNum = theme.info(`${step.id}.`);
|
|
852
|
+
const desc = isSelected ? step.description : theme.ui.muted(step.description);
|
|
853
|
+
lines.push(` ${checkbox} ${stepNum} ${desc}`);
|
|
854
|
+
}
|
|
855
|
+
lines.push('');
|
|
856
|
+
lines.push(theme.ui.muted('─'.repeat(60)));
|
|
857
|
+
lines.push('');
|
|
858
|
+
lines.push(theme.info('Commands:'));
|
|
859
|
+
lines.push(` ${theme.primary('1-N')} Toggle step selection`);
|
|
860
|
+
lines.push(` ${theme.primary('all')} Select all steps`);
|
|
861
|
+
lines.push(` ${theme.primary('none')} Deselect all steps`);
|
|
862
|
+
lines.push(` ${theme.primary('go')} Execute selected steps`);
|
|
863
|
+
lines.push(` ${theme.primary('cancel')} Cancel planning`);
|
|
864
|
+
lines.push(` ${theme.primary('[text]')} Submit your own solution instead`);
|
|
865
|
+
lines.push('');
|
|
866
|
+
display.showSystemMessage(lines.join('\n'));
|
|
867
|
+
this.terminalInput.render();
|
|
868
|
+
}
|
|
869
|
+
async handlePlanApprovalInput(input) {
|
|
870
|
+
const pending = this.pendingInteraction;
|
|
871
|
+
if (!pending || pending.type !== 'plan-approval')
|
|
872
|
+
return;
|
|
873
|
+
const trimmed = input.trim();
|
|
874
|
+
if (!trimmed) {
|
|
875
|
+
display.showWarning('Enter a command or your own solution.');
|
|
876
|
+
this.terminalInput.render();
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
const lower = trimmed.toLowerCase();
|
|
880
|
+
// Cancel
|
|
881
|
+
if (lower === 'cancel' || lower === 'c') {
|
|
882
|
+
this.pendingInteraction = null;
|
|
883
|
+
display.showInfo('Plan cancelled. You can continue with a different approach.');
|
|
884
|
+
this.terminalInput.render();
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
// Select all
|
|
888
|
+
if (lower === 'all' || lower === 'a') {
|
|
889
|
+
pending.selectedSteps = new Set(pending.steps.map(s => s.id));
|
|
890
|
+
this.displayPlanApprovalUI();
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
// Deselect all
|
|
894
|
+
if (lower === 'none' || lower === 'n') {
|
|
895
|
+
pending.selectedSteps.clear();
|
|
896
|
+
this.displayPlanApprovalUI();
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
899
|
+
// Execute selected steps
|
|
900
|
+
if (lower === 'go' || lower === 'g' || lower === 'yes' || lower === 'y') {
|
|
901
|
+
const selectedSteps = pending.steps.filter(s => pending.selectedSteps.has(s.id));
|
|
902
|
+
if (selectedSteps.length === 0) {
|
|
903
|
+
display.showWarning('No steps selected. Select steps or enter your own solution.');
|
|
904
|
+
this.terminalInput.render();
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
this.pendingInteraction = null;
|
|
908
|
+
// Build the implementation prompt with selected steps
|
|
909
|
+
const stepList = selectedSteps.map(s => `${s.id}. ${s.description}`).join('\n');
|
|
910
|
+
const implementPrompt = `Proceed with implementing the following steps:\n\n${stepList}\n\nStart implementing now. Use the appropriate tools.`;
|
|
911
|
+
// Queue the implementation request
|
|
912
|
+
await this.processInputBlock(implementPrompt);
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
// Toggle step by number
|
|
916
|
+
const num = Number.parseInt(trimmed, 10);
|
|
917
|
+
if (Number.isFinite(num) && num >= 1 && num <= pending.steps.length) {
|
|
918
|
+
if (pending.selectedSteps.has(num)) {
|
|
919
|
+
pending.selectedSteps.delete(num);
|
|
920
|
+
}
|
|
921
|
+
else {
|
|
922
|
+
pending.selectedSteps.add(num);
|
|
923
|
+
}
|
|
924
|
+
this.displayPlanApprovalUI();
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
// User submitted their own solution - treat as custom input
|
|
928
|
+
if (trimmed.length > 10) {
|
|
929
|
+
this.pendingInteraction = null;
|
|
930
|
+
display.showInfo('Using your custom solution...');
|
|
931
|
+
// Send the custom solution as the implementation request
|
|
932
|
+
const customPrompt = `The user has provided their own solution instead of the plan. Please implement this:\n\n${trimmed}`;
|
|
933
|
+
await this.processInputBlock(customPrompt);
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
display.showWarning('Invalid input. Enter a step number, command (go/cancel/all/none), or your own solution.');
|
|
937
|
+
this.terminalInput.render();
|
|
938
|
+
}
|
|
760
939
|
setupHandlers() {
|
|
761
940
|
// Handle terminal resize
|
|
762
941
|
output.on('resize', () => {
|
|
@@ -1008,6 +1187,12 @@ export class InteractiveShell {
|
|
|
1008
1187
|
const frame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
|
|
1009
1188
|
this.streamingStatusLabel = this.buildStreamingStatus(`${frame} ${label}`, elapsedSeconds);
|
|
1010
1189
|
display.updateStreamingStatus(this.streamingStatusLabel);
|
|
1190
|
+
// Update parallel agent display during streaming
|
|
1191
|
+
const manager = getParallelAgentManager();
|
|
1192
|
+
if (manager.isRunning()) {
|
|
1193
|
+
this.parallelAgentDisplayLines = manager.formatDisplay();
|
|
1194
|
+
this.displayParallelAgents();
|
|
1195
|
+
}
|
|
1011
1196
|
this.refreshStatusLine(true);
|
|
1012
1197
|
},
|
|
1013
1198
|
});
|
|
@@ -1219,6 +1404,9 @@ export class InteractiveShell {
|
|
|
1219
1404
|
case 'agent-selection':
|
|
1220
1405
|
await this.handleAgentSelectionInput(input);
|
|
1221
1406
|
return true;
|
|
1407
|
+
case 'plan-approval':
|
|
1408
|
+
await this.handlePlanApprovalInput(input);
|
|
1409
|
+
return true;
|
|
1222
1410
|
default:
|
|
1223
1411
|
return false;
|
|
1224
1412
|
}
|
|
@@ -1238,6 +1426,12 @@ export class InteractiveShell {
|
|
|
1238
1426
|
case '/features':
|
|
1239
1427
|
this.showFeaturesMenu(input);
|
|
1240
1428
|
break;
|
|
1429
|
+
case '/learn':
|
|
1430
|
+
this.showLearningStatus(input);
|
|
1431
|
+
break;
|
|
1432
|
+
case '/improve':
|
|
1433
|
+
void this.handleImprovementCommand(input);
|
|
1434
|
+
break;
|
|
1241
1435
|
case '/model':
|
|
1242
1436
|
this.showModelMenu();
|
|
1243
1437
|
break;
|
|
@@ -1299,6 +1493,9 @@ export class InteractiveShell {
|
|
|
1299
1493
|
case '/plugins':
|
|
1300
1494
|
this.showPluginStatus();
|
|
1301
1495
|
break;
|
|
1496
|
+
case '/evolve':
|
|
1497
|
+
void this.handleEvolveCommand(input);
|
|
1498
|
+
break;
|
|
1302
1499
|
case '/provider':
|
|
1303
1500
|
await this.handleProviderCommand(input);
|
|
1304
1501
|
break;
|
|
@@ -1311,6 +1508,58 @@ export class InteractiveShell {
|
|
|
1311
1508
|
case '/discover':
|
|
1312
1509
|
await this.discoverModelsCommand();
|
|
1313
1510
|
break;
|
|
1511
|
+
// Claude Code style commands
|
|
1512
|
+
case '/rewind':
|
|
1513
|
+
await this.handleRewindCommand(input);
|
|
1514
|
+
break;
|
|
1515
|
+
case '/memory':
|
|
1516
|
+
this.handleMemoryCommand(input);
|
|
1517
|
+
break;
|
|
1518
|
+
case '/vim':
|
|
1519
|
+
this.handleVimCommand();
|
|
1520
|
+
break;
|
|
1521
|
+
case '/output-style':
|
|
1522
|
+
this.handleOutputStyleCommand(input);
|
|
1523
|
+
break;
|
|
1524
|
+
case '/cost':
|
|
1525
|
+
this.handleCostCommand();
|
|
1526
|
+
break;
|
|
1527
|
+
case '/usage':
|
|
1528
|
+
this.handleUsageCommand();
|
|
1529
|
+
break;
|
|
1530
|
+
case '/update':
|
|
1531
|
+
await this.handleUpdateCommand();
|
|
1532
|
+
break;
|
|
1533
|
+
case '/clear':
|
|
1534
|
+
this.handleClearCommand();
|
|
1535
|
+
break;
|
|
1536
|
+
case '/resume':
|
|
1537
|
+
await this.handleResumeCommand(input);
|
|
1538
|
+
break;
|
|
1539
|
+
case '/export':
|
|
1540
|
+
this.handleExportCommand(input);
|
|
1541
|
+
break;
|
|
1542
|
+
case '/review':
|
|
1543
|
+
await this.handleReviewCommand();
|
|
1544
|
+
break;
|
|
1545
|
+
case '/security-review':
|
|
1546
|
+
await this.handleSecurityReviewCommand();
|
|
1547
|
+
break;
|
|
1548
|
+
case '/bug':
|
|
1549
|
+
this.handleBugCommand();
|
|
1550
|
+
break;
|
|
1551
|
+
case '/terminal-setup':
|
|
1552
|
+
this.handleTerminalSetupCommand();
|
|
1553
|
+
break;
|
|
1554
|
+
case '/permissions':
|
|
1555
|
+
this.handlePermissionsCommand();
|
|
1556
|
+
break;
|
|
1557
|
+
case '/init':
|
|
1558
|
+
this.handleInitCommand();
|
|
1559
|
+
break;
|
|
1560
|
+
case '/compact':
|
|
1561
|
+
await this.handleCompactCommand();
|
|
1562
|
+
break;
|
|
1314
1563
|
default:
|
|
1315
1564
|
if (!(await this.tryCustomSlashCommand(command, input))) {
|
|
1316
1565
|
display.showWarning(`Unknown command "${command}".`);
|
|
@@ -1772,6 +2021,590 @@ export class InteractiveShell {
|
|
|
1772
2021
|
lines.push(theme.ui.muted('Feature changes take effect on next launch.'));
|
|
1773
2022
|
display.showSystemMessage(lines.join('\n'));
|
|
1774
2023
|
}
|
|
2024
|
+
showLearningStatus(input) {
|
|
2025
|
+
const args = input.split(/\s+/).slice(1);
|
|
2026
|
+
const subcommand = args[0]?.toLowerCase();
|
|
2027
|
+
// Handle subcommands
|
|
2028
|
+
if (subcommand === 'commit') {
|
|
2029
|
+
const result = commitLearning(args.slice(1).join(' ') || 'Manual learning checkpoint', this.workingDir);
|
|
2030
|
+
if (result.success) {
|
|
2031
|
+
display.showInfo(`Learning committed: ${result.commitHash}`);
|
|
2032
|
+
}
|
|
2033
|
+
else {
|
|
2034
|
+
display.showWarning(`Could not commit: ${result.error}`);
|
|
2035
|
+
}
|
|
2036
|
+
return;
|
|
2037
|
+
}
|
|
2038
|
+
if (subcommand === 'export') {
|
|
2039
|
+
const data = exportAllLearning();
|
|
2040
|
+
const json = JSON.stringify(data, null, 2);
|
|
2041
|
+
display.showSystemMessage(`Exported learning data:\n\n${json.slice(0, 2000)}${json.length > 2000 ? '\n...(truncated)' : ''}`);
|
|
2042
|
+
return;
|
|
2043
|
+
}
|
|
2044
|
+
if (subcommand === 'history') {
|
|
2045
|
+
const history = getRecentLearning(20);
|
|
2046
|
+
const lines = [];
|
|
2047
|
+
lines.push(theme.gradient.primary('Recent Learning History'));
|
|
2048
|
+
lines.push('');
|
|
2049
|
+
if (history.length === 0) {
|
|
2050
|
+
lines.push(theme.ui.muted('No learning history yet.'));
|
|
2051
|
+
}
|
|
2052
|
+
else {
|
|
2053
|
+
for (const entry of history) {
|
|
2054
|
+
const date = new Date(entry.timestamp).toLocaleString();
|
|
2055
|
+
const icon = entry.type === 'tool-pattern' ? '🔧' :
|
|
2056
|
+
entry.type === 'quality-threshold' ? '📊' :
|
|
2057
|
+
entry.type === 'failure-pattern' ? '⚠️' : '💡';
|
|
2058
|
+
lines.push(` ${icon} ${theme.ui.muted(date)}`);
|
|
2059
|
+
lines.push(` ${entry.description}`);
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2063
|
+
return;
|
|
2064
|
+
}
|
|
2065
|
+
// Default: show summary
|
|
2066
|
+
const summary = getLearningSummary();
|
|
2067
|
+
const lines = [];
|
|
2068
|
+
lines.push(theme.gradient.primary('🧠 AlphaZero Learning Status'));
|
|
2069
|
+
lines.push('');
|
|
2070
|
+
// Tool patterns
|
|
2071
|
+
lines.push(theme.bold('Tool Patterns Learned:'));
|
|
2072
|
+
if (summary.toolPatterns.totalPatterns === 0) {
|
|
2073
|
+
lines.push(` ${theme.ui.muted('No patterns learned yet. Use the CLI to build up patterns.')}`);
|
|
2074
|
+
}
|
|
2075
|
+
else {
|
|
2076
|
+
lines.push(` Total: ${theme.info(String(summary.toolPatterns.totalPatterns))} patterns across ${summary.toolPatterns.taskTypes.length} task types`);
|
|
2077
|
+
if (summary.toolPatterns.bestPatterns.length > 0) {
|
|
2078
|
+
lines.push(' Best patterns:');
|
|
2079
|
+
for (const p of summary.toolPatterns.bestPatterns) {
|
|
2080
|
+
const rate = Math.round(p.successRate * 100);
|
|
2081
|
+
lines.push(` ${theme.success('•')} ${p.taskType}: ${theme.ui.muted(p.pattern)} (${rate}% success)`);
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
lines.push('');
|
|
2086
|
+
// Quality thresholds
|
|
2087
|
+
lines.push(theme.bold('Quality Thresholds:'));
|
|
2088
|
+
lines.push(` Min acceptable: ${theme.warning(String(Math.round(summary.qualityThresholds.avgMinAcceptable)))}/100`);
|
|
2089
|
+
lines.push(` Target quality: ${theme.success(String(Math.round(summary.qualityThresholds.avgTargetQuality)))}/100`);
|
|
2090
|
+
lines.push(` Task types: ${summary.qualityThresholds.taskTypes.join(', ')}`);
|
|
2091
|
+
lines.push('');
|
|
2092
|
+
// Failure patterns
|
|
2093
|
+
lines.push(theme.bold('Failure Patterns:'));
|
|
2094
|
+
if (summary.failurePatterns.totalPatterns === 0) {
|
|
2095
|
+
lines.push(` ${theme.ui.muted('No failure patterns recorded.')}`);
|
|
2096
|
+
}
|
|
2097
|
+
else {
|
|
2098
|
+
lines.push(` Total: ${theme.warning(String(summary.failurePatterns.totalPatterns))} patterns to avoid`);
|
|
2099
|
+
if (summary.failurePatterns.mostFrequent.length > 0) {
|
|
2100
|
+
for (const f of summary.failurePatterns.mostFrequent) {
|
|
2101
|
+
lines.push(` ${theme.error('✗')} ${f.description} (${f.occurrences}x)`);
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
lines.push('');
|
|
2106
|
+
// Prompt improvements
|
|
2107
|
+
lines.push(theme.bold('Prompt Improvements:'));
|
|
2108
|
+
if (summary.promptImprovements.totalImprovements === 0) {
|
|
2109
|
+
lines.push(` ${theme.ui.muted('No prompt improvements discovered yet.')}`);
|
|
2110
|
+
}
|
|
2111
|
+
else {
|
|
2112
|
+
lines.push(` Total: ${theme.info(String(summary.promptImprovements.totalImprovements))} improvements`);
|
|
2113
|
+
lines.push(` Categories: ${summary.promptImprovements.categories.join(', ')}`);
|
|
2114
|
+
lines.push(` Avg quality gain: ${theme.success(`+${Math.round(summary.promptImprovements.avgQualityGain)}%`)}`);
|
|
2115
|
+
}
|
|
2116
|
+
lines.push('');
|
|
2117
|
+
// Recent activity
|
|
2118
|
+
lines.push(theme.bold('Activity:'));
|
|
2119
|
+
lines.push(` Learning events (24h): ${summary.recentActivity}`);
|
|
2120
|
+
lines.push(` Storage: ${theme.ui.muted(getLearningDir())}`);
|
|
2121
|
+
lines.push('');
|
|
2122
|
+
// Commands
|
|
2123
|
+
lines.push(theme.bold('Commands:'));
|
|
2124
|
+
lines.push(` ${theme.primary('/learn')} - Show this summary`);
|
|
2125
|
+
lines.push(` ${theme.primary('/learn history')} - View recent learning events`);
|
|
2126
|
+
lines.push(` ${theme.primary('/learn commit')} - Commit learning to git`);
|
|
2127
|
+
lines.push(` ${theme.primary('/learn export')} - Export learning data as JSON`);
|
|
2128
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2129
|
+
}
|
|
2130
|
+
/**
|
|
2131
|
+
* Handle /improve command for self-improvement
|
|
2132
|
+
*/
|
|
2133
|
+
async handleImprovementCommand(input) {
|
|
2134
|
+
const args = input.split(/\s+/).slice(1);
|
|
2135
|
+
const subcommand = args[0]?.toLowerCase();
|
|
2136
|
+
if (subcommand === 'analyze') {
|
|
2137
|
+
const opportunities = analyzeImprovementOpportunities(this.workingDir);
|
|
2138
|
+
const lines = [];
|
|
2139
|
+
lines.push(theme.gradient.primary('🔍 Improvement Analysis'));
|
|
2140
|
+
lines.push('');
|
|
2141
|
+
if (opportunities.length === 0) {
|
|
2142
|
+
lines.push(theme.ui.muted('No improvement opportunities found. Keep using the CLI to build learning data.'));
|
|
2143
|
+
}
|
|
2144
|
+
else {
|
|
2145
|
+
lines.push(`Found ${theme.info(String(opportunities.length))} improvement opportunities:`);
|
|
2146
|
+
lines.push('');
|
|
2147
|
+
for (const opp of opportunities.slice(0, 10)) {
|
|
2148
|
+
const icon = opp.type === 'bug-fix' ? '🐛' : opp.type === 'refactor' ? '🔧' : '⚡';
|
|
2149
|
+
const priorityColor = opp.priority === 'critical' ? theme.error :
|
|
2150
|
+
opp.priority === 'high' ? theme.warning : theme.info;
|
|
2151
|
+
lines.push(` ${icon} ${priorityColor(`[${opp.priority}]`)} ${opp.description.slice(0, 60)}`);
|
|
2152
|
+
lines.push(` ${theme.ui.muted(`Confidence: ${Math.round(opp.confidence * 100)}%`)} | ${theme.ui.muted(`File: ${opp.sourceFile}`)}`);
|
|
2153
|
+
for (const ev of opp.evidence.slice(0, 2)) {
|
|
2154
|
+
lines.push(` ${theme.dim(`• ${ev}`)}`);
|
|
2155
|
+
}
|
|
2156
|
+
lines.push('');
|
|
2157
|
+
}
|
|
2158
|
+
if (opportunities.length > 10) {
|
|
2159
|
+
lines.push(theme.ui.muted(`... and ${opportunities.length - 10} more`));
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2163
|
+
return;
|
|
2164
|
+
}
|
|
2165
|
+
if (subcommand === 'apply') {
|
|
2166
|
+
display.showSystemMessage(theme.gradient.primary('🚀 Running Self-Improvement Cycle...'));
|
|
2167
|
+
display.showSystemMessage('');
|
|
2168
|
+
try {
|
|
2169
|
+
const result = await runSelfImprovementCycle(this.workingDir, {
|
|
2170
|
+
maxChanges: 3,
|
|
2171
|
+
minConfidence: 0.7,
|
|
2172
|
+
runTests: true,
|
|
2173
|
+
autoCommit: true,
|
|
2174
|
+
});
|
|
2175
|
+
const lines = [];
|
|
2176
|
+
lines.push(theme.bold('Results:'));
|
|
2177
|
+
lines.push(result.summary);
|
|
2178
|
+
lines.push('');
|
|
2179
|
+
if (result.applied > 0) {
|
|
2180
|
+
lines.push(theme.success(`✅ Applied ${result.applied} improvements!`));
|
|
2181
|
+
for (const r of result.results.filter(r => r.success)) {
|
|
2182
|
+
lines.push(` - Files: ${r.filesChanged.join(', ')}`);
|
|
2183
|
+
if (r.commitHash) {
|
|
2184
|
+
lines.push(` Commit: ${theme.ui.muted(r.commitHash)}`);
|
|
2185
|
+
lines.push(` Rollback: ${theme.dim(r.rollbackCommand ?? '')}`);
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
else {
|
|
2190
|
+
lines.push(theme.warning('No improvements were applied.'));
|
|
2191
|
+
for (const r of result.results.filter(r => !r.success)) {
|
|
2192
|
+
lines.push(` ${theme.error('✗')} ${r.error}`);
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2196
|
+
}
|
|
2197
|
+
catch (error) {
|
|
2198
|
+
display.showError(`Self-improvement failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
2199
|
+
}
|
|
2200
|
+
return;
|
|
2201
|
+
}
|
|
2202
|
+
if (subcommand === 'dry-run') {
|
|
2203
|
+
const opportunities = analyzeImprovementOpportunities(this.workingDir);
|
|
2204
|
+
const filtered = opportunities.filter(o => o.confidence >= 0.7);
|
|
2205
|
+
const toApply = filtered.slice(0, 3);
|
|
2206
|
+
const lines = [];
|
|
2207
|
+
lines.push(theme.gradient.primary('🔮 Dry Run - Preview Changes'));
|
|
2208
|
+
lines.push('');
|
|
2209
|
+
if (toApply.length === 0) {
|
|
2210
|
+
lines.push(theme.ui.muted('No high-confidence improvements to apply.'));
|
|
2211
|
+
}
|
|
2212
|
+
else {
|
|
2213
|
+
lines.push(`Would apply ${theme.info(String(toApply.length))} improvements:`);
|
|
2214
|
+
lines.push('');
|
|
2215
|
+
for (const opp of toApply) {
|
|
2216
|
+
const icon = opp.type === 'bug-fix' ? '🐛' : opp.type === 'refactor' ? '🔧' : '⚡';
|
|
2217
|
+
lines.push(` ${icon} ${opp.description.slice(0, 60)}`);
|
|
2218
|
+
lines.push(` ${theme.ui.muted(`File: ${opp.sourceFile}`)}`);
|
|
2219
|
+
lines.push(` ${theme.dim(`Suggested: ${opp.suggestedChange.slice(0, 100)}...`)}`);
|
|
2220
|
+
lines.push('');
|
|
2221
|
+
}
|
|
2222
|
+
lines.push(theme.bold('Run `/improve apply` to execute these changes.'));
|
|
2223
|
+
}
|
|
2224
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2225
|
+
return;
|
|
2226
|
+
}
|
|
2227
|
+
if (subcommand === 'auto') {
|
|
2228
|
+
void this.runAutonomousImprovementMode();
|
|
2229
|
+
return;
|
|
2230
|
+
}
|
|
2231
|
+
if (subcommand === 'stop') {
|
|
2232
|
+
requestAutoImprovementStop();
|
|
2233
|
+
display.showInfo('Requested stop of autonomous improvement...');
|
|
2234
|
+
return;
|
|
2235
|
+
}
|
|
2236
|
+
if (subcommand === 'rollback') {
|
|
2237
|
+
const result = emergencyRollback(this.workingDir);
|
|
2238
|
+
if (result.success) {
|
|
2239
|
+
display.showSuccess(result.message);
|
|
2240
|
+
}
|
|
2241
|
+
else {
|
|
2242
|
+
display.showError(result.message);
|
|
2243
|
+
}
|
|
2244
|
+
return;
|
|
2245
|
+
}
|
|
2246
|
+
if (subcommand === 'status') {
|
|
2247
|
+
const state = getAutoImprovementState();
|
|
2248
|
+
const lines = [];
|
|
2249
|
+
lines.push(theme.gradient.primary('🤖 Auto-Improvement Status'));
|
|
2250
|
+
lines.push('');
|
|
2251
|
+
lines.push(`Running: ${state.isRunning ? theme.success('Yes') : theme.ui.muted('No')}`);
|
|
2252
|
+
if (state.startTime) {
|
|
2253
|
+
lines.push(`Started: ${theme.ui.muted(state.startTime)}`);
|
|
2254
|
+
}
|
|
2255
|
+
lines.push(`Iteration: ${state.iteration}`);
|
|
2256
|
+
lines.push(`Applied: ${theme.success(String(state.applied))}`);
|
|
2257
|
+
lines.push(`Failed: ${theme.warning(String(state.failed))}`);
|
|
2258
|
+
lines.push(`Rollbacks: ${theme.error(String(state.rollbacks))}`);
|
|
2259
|
+
if (state.lastError) {
|
|
2260
|
+
lines.push(`Last Error: ${theme.error(state.lastError)}`);
|
|
2261
|
+
}
|
|
2262
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2263
|
+
return;
|
|
2264
|
+
}
|
|
2265
|
+
// Default: show summary
|
|
2266
|
+
const summary = getImprovementSummary(this.workingDir);
|
|
2267
|
+
display.showSystemMessage(summary);
|
|
2268
|
+
}
|
|
2269
|
+
/**
|
|
2270
|
+
* Run autonomous improvement mode with self-relaunch capability
|
|
2271
|
+
*/
|
|
2272
|
+
async runAutonomousImprovementMode() {
|
|
2273
|
+
const isSelfImproving = this.workingDir.includes('erosolar');
|
|
2274
|
+
display.showSystemMessage(theme.gradient.primary('🤖 Starting Autonomous Improvement Mode'));
|
|
2275
|
+
display.showSystemMessage('');
|
|
2276
|
+
display.showSystemMessage(`${theme.bold('Safety Features:')}`);
|
|
2277
|
+
display.showSystemMessage(' • Git checkpoint created before starting');
|
|
2278
|
+
display.showSystemMessage(' • Each change validated with build + tests');
|
|
2279
|
+
display.showSystemMessage(' • Auto-rollback on failures');
|
|
2280
|
+
display.showSystemMessage(' • Press Ctrl+C to stop gracefully');
|
|
2281
|
+
if (isSelfImproving) {
|
|
2282
|
+
display.showSystemMessage(' • CLI will relaunch after improvements to run new code');
|
|
2283
|
+
}
|
|
2284
|
+
display.showSystemMessage('');
|
|
2285
|
+
display.showSystemMessage(`${theme.bold('Commands while running:')}`);
|
|
2286
|
+
display.showSystemMessage(' /improve stop - Request graceful stop');
|
|
2287
|
+
display.showSystemMessage(' /improve status - Check current status');
|
|
2288
|
+
display.showSystemMessage(' /improve rollback - Emergency rollback to checkpoint');
|
|
2289
|
+
display.showSystemMessage('');
|
|
2290
|
+
let stopRequested = false;
|
|
2291
|
+
// Set up Ctrl+C handler
|
|
2292
|
+
const originalSigintHandler = process.listeners('SIGINT');
|
|
2293
|
+
process.removeAllListeners('SIGINT');
|
|
2294
|
+
process.once('SIGINT', () => {
|
|
2295
|
+
display.showWarning('Ctrl+C pressed - stopping after current iteration...');
|
|
2296
|
+
stopRequested = true;
|
|
2297
|
+
requestAutoImprovementStop();
|
|
2298
|
+
});
|
|
2299
|
+
try {
|
|
2300
|
+
const result = await runAutonomousImprovement({
|
|
2301
|
+
workingDir: this.workingDir,
|
|
2302
|
+
minConfidence: 0.75,
|
|
2303
|
+
maxIterations: 100,
|
|
2304
|
+
delayBetweenMs: 3000,
|
|
2305
|
+
runTests: true,
|
|
2306
|
+
shouldStop: () => stopRequested,
|
|
2307
|
+
onProgress: (event) => {
|
|
2308
|
+
switch (event.type) {
|
|
2309
|
+
case 'start':
|
|
2310
|
+
display.showInfo(event.message);
|
|
2311
|
+
break;
|
|
2312
|
+
case 'iteration':
|
|
2313
|
+
display.showSystemMessage(`\n${theme.bold(`[Iteration ${event.iteration}]`)} ${event.message}`);
|
|
2314
|
+
break;
|
|
2315
|
+
case 'applied':
|
|
2316
|
+
display.showSuccess(event.message);
|
|
2317
|
+
display.showSystemMessage(` Total applied: ${event.totalApplied}`);
|
|
2318
|
+
break;
|
|
2319
|
+
case 'failed':
|
|
2320
|
+
display.showWarning(event.message);
|
|
2321
|
+
break;
|
|
2322
|
+
case 'rollback':
|
|
2323
|
+
display.showError(event.message);
|
|
2324
|
+
break;
|
|
2325
|
+
case 'no-opportunities':
|
|
2326
|
+
display.showInfo(event.message);
|
|
2327
|
+
break;
|
|
2328
|
+
case 'complete':
|
|
2329
|
+
display.showSystemMessage('');
|
|
2330
|
+
display.showSystemMessage(theme.gradient.primary('═══ Autonomous Improvement Complete ═══'));
|
|
2331
|
+
display.showSystemMessage(event.message);
|
|
2332
|
+
if (event.totalApplied !== undefined) {
|
|
2333
|
+
display.showSystemMessage(`Applied: ${theme.success(String(event.totalApplied))}`);
|
|
2334
|
+
}
|
|
2335
|
+
if (event.totalFailed !== undefined) {
|
|
2336
|
+
display.showSystemMessage(`Failed: ${theme.warning(String(event.totalFailed))}`);
|
|
2337
|
+
}
|
|
2338
|
+
break;
|
|
2339
|
+
}
|
|
2340
|
+
},
|
|
2341
|
+
});
|
|
2342
|
+
// Restore SIGINT handlers
|
|
2343
|
+
process.removeAllListeners('SIGINT');
|
|
2344
|
+
for (const handler of originalSigintHandler) {
|
|
2345
|
+
process.on('SIGINT', handler);
|
|
2346
|
+
}
|
|
2347
|
+
// Summary
|
|
2348
|
+
display.showSystemMessage('');
|
|
2349
|
+
display.showSystemMessage(theme.bold('Final Summary:'));
|
|
2350
|
+
display.showSystemMessage(` Iterations: ${result.iterations}`);
|
|
2351
|
+
display.showSystemMessage(` Applied: ${theme.success(String(result.totalApplied))}`);
|
|
2352
|
+
display.showSystemMessage(` Failed: ${theme.warning(String(result.totalFailed))}`);
|
|
2353
|
+
display.showSystemMessage(` Rollbacks: ${theme.error(String(result.totalRollbacks))}`);
|
|
2354
|
+
display.showSystemMessage(` Stopped: ${result.stoppedReason}`);
|
|
2355
|
+
// If we improved erosolar-cli itself and applied changes, offer to relaunch
|
|
2356
|
+
if (isSelfImproving && result.totalApplied > 0) {
|
|
2357
|
+
display.showSystemMessage('');
|
|
2358
|
+
display.showSystemMessage(theme.gradient.primary('🔄 CLI source code was updated!'));
|
|
2359
|
+
display.showSystemMessage('To run the improved version:');
|
|
2360
|
+
display.showSystemMessage(` ${theme.bold('npm run build && erosolar')}`);
|
|
2361
|
+
display.showSystemMessage('');
|
|
2362
|
+
display.showSystemMessage('Or to continue auto-improvement with new code:');
|
|
2363
|
+
display.showSystemMessage(` ${theme.bold('npm run build && erosolar -c "/improve auto"')}`);
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
catch (error) {
|
|
2367
|
+
// Restore SIGINT handlers
|
|
2368
|
+
process.removeAllListeners('SIGINT');
|
|
2369
|
+
for (const handler of originalSigintHandler) {
|
|
2370
|
+
process.on('SIGINT', handler);
|
|
2371
|
+
}
|
|
2372
|
+
display.showError(`Autonomous improvement failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
2373
|
+
display.showSystemMessage('');
|
|
2374
|
+
display.showSystemMessage('Run `/improve rollback` to restore to the checkpoint if needed.');
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
/**
|
|
2378
|
+
* Handle /evolve command for self-evolution (erosolar-cli source only)
|
|
2379
|
+
*/
|
|
2380
|
+
async handleEvolveCommand(input) {
|
|
2381
|
+
const args = input.split(/\s+/).slice(1);
|
|
2382
|
+
const subcommand = args[0]?.toLowerCase();
|
|
2383
|
+
// Check if we're in a valid source repository
|
|
2384
|
+
if (!isValidSourceRepo(this.workingDir)) {
|
|
2385
|
+
display.showWarning('Self-evolution requires a git repository with source code.');
|
|
2386
|
+
display.showSystemMessage('');
|
|
2387
|
+
display.showSystemMessage('Current directory: ' + this.workingDir);
|
|
2388
|
+
display.showSystemMessage('');
|
|
2389
|
+
display.showSystemMessage('Requirements:');
|
|
2390
|
+
display.showSystemMessage(' • Must be a git repository (.git folder)');
|
|
2391
|
+
display.showSystemMessage(' • Must have package.json or src/ directory');
|
|
2392
|
+
display.showSystemMessage('');
|
|
2393
|
+
display.showSystemMessage('Navigate to your project directory and try again.');
|
|
2394
|
+
return;
|
|
2395
|
+
}
|
|
2396
|
+
const repoName = getRepoName(this.workingDir);
|
|
2397
|
+
const isErosolar = isErosolarRepo(this.workingDir);
|
|
2398
|
+
if (subcommand === 'analyze') {
|
|
2399
|
+
display.showSystemMessage(theme.gradient.primary(`🔍 Analyzing ${repoName} Source Code...`));
|
|
2400
|
+
display.showSystemMessage('');
|
|
2401
|
+
const issues = analyzeSource(this.workingDir);
|
|
2402
|
+
const lines = [];
|
|
2403
|
+
if (issues.length === 0) {
|
|
2404
|
+
lines.push(theme.success('✅ No issues found! Source code looks clean.'));
|
|
2405
|
+
}
|
|
2406
|
+
else {
|
|
2407
|
+
const bySeverity = {
|
|
2408
|
+
critical: issues.filter(i => i.severity === 'critical'),
|
|
2409
|
+
high: issues.filter(i => i.severity === 'high'),
|
|
2410
|
+
medium: issues.filter(i => i.severity === 'medium'),
|
|
2411
|
+
low: issues.filter(i => i.severity === 'low'),
|
|
2412
|
+
};
|
|
2413
|
+
lines.push(`Found ${theme.bold(String(issues.length))} issues:`);
|
|
2414
|
+
lines.push('');
|
|
2415
|
+
if (bySeverity.critical.length > 0) {
|
|
2416
|
+
lines.push(theme.error(` 🔴 Critical: ${bySeverity.critical.length}`));
|
|
2417
|
+
}
|
|
2418
|
+
if (bySeverity.high.length > 0) {
|
|
2419
|
+
lines.push(theme.warning(` 🟠 High: ${bySeverity.high.length}`));
|
|
2420
|
+
}
|
|
2421
|
+
if (bySeverity.medium.length > 0) {
|
|
2422
|
+
lines.push(theme.info(` 🟡 Medium: ${bySeverity.medium.length}`));
|
|
2423
|
+
}
|
|
2424
|
+
if (bySeverity.low.length > 0) {
|
|
2425
|
+
lines.push(theme.dim(` ⚪ Low: ${bySeverity.low.length}`));
|
|
2426
|
+
}
|
|
2427
|
+
lines.push('');
|
|
2428
|
+
// Show top 10 issues
|
|
2429
|
+
lines.push(theme.bold('Top Issues:'));
|
|
2430
|
+
for (const issue of issues.slice(0, 10)) {
|
|
2431
|
+
const icon = issue.severity === 'critical' ? '🔴' :
|
|
2432
|
+
issue.severity === 'high' ? '🟠' :
|
|
2433
|
+
issue.severity === 'medium' ? '🟡' : '⚪';
|
|
2434
|
+
lines.push(` ${icon} ${issue.file}:${issue.line ?? '?'}`);
|
|
2435
|
+
lines.push(` ${theme.dim(issue.description.slice(0, 70))}`);
|
|
2436
|
+
lines.push(` ${theme.ui.muted(`Confidence: ${Math.round(issue.confidence * 100)}%`)}`);
|
|
2437
|
+
}
|
|
2438
|
+
if (issues.length > 10) {
|
|
2439
|
+
lines.push('');
|
|
2440
|
+
lines.push(theme.ui.muted(`... and ${issues.length - 10} more issues`));
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2444
|
+
return;
|
|
2445
|
+
}
|
|
2446
|
+
if (subcommand === 'start') {
|
|
2447
|
+
display.showSystemMessage(theme.gradient.primary('🧬 Starting Self-Evolution Mode'));
|
|
2448
|
+
display.showSystemMessage('');
|
|
2449
|
+
display.showSystemMessage(theme.bold('Safety Features:'));
|
|
2450
|
+
display.showSystemMessage(' • Git checkpoint created before starting');
|
|
2451
|
+
display.showSystemMessage(' • Each change validated with build + tests');
|
|
2452
|
+
display.showSystemMessage(' • Auto-rollback on failures');
|
|
2453
|
+
display.showSystemMessage(' • Auto-relaunch with improved code');
|
|
2454
|
+
display.showSystemMessage(' • Press Ctrl+C to stop gracefully');
|
|
2455
|
+
display.showSystemMessage('');
|
|
2456
|
+
try {
|
|
2457
|
+
const result = await runSelfEvolution(this.workingDir, {
|
|
2458
|
+
maxIterations: 50,
|
|
2459
|
+
minConfidence: 0.8,
|
|
2460
|
+
runTests: true,
|
|
2461
|
+
autoRelaunch: true,
|
|
2462
|
+
}, {
|
|
2463
|
+
onStart: () => {
|
|
2464
|
+
display.showInfo('Evolution started. Creating checkpoint...');
|
|
2465
|
+
},
|
|
2466
|
+
onIteration: (iteration, issues) => {
|
|
2467
|
+
display.showSystemMessage(`\n[Iteration ${iteration}] Found ${issues.length} high-confidence issues`);
|
|
2468
|
+
},
|
|
2469
|
+
onFix: (issue, success) => {
|
|
2470
|
+
if (success) {
|
|
2471
|
+
display.showSuccess(`Fixed: ${issue.description.slice(0, 50)}`);
|
|
2472
|
+
}
|
|
2473
|
+
else {
|
|
2474
|
+
display.showWarning(`Failed: ${issue.description.slice(0, 50)}`);
|
|
2475
|
+
}
|
|
2476
|
+
},
|
|
2477
|
+
onRelaunch: () => {
|
|
2478
|
+
display.showSystemMessage('');
|
|
2479
|
+
display.showSystemMessage(theme.gradient.primary('🔄 Relaunching with improved code...'));
|
|
2480
|
+
},
|
|
2481
|
+
onComplete: (result) => {
|
|
2482
|
+
display.showSystemMessage('');
|
|
2483
|
+
display.showSuccess(`Evolution complete! Fixed ${result.issuesFixed} issues.`);
|
|
2484
|
+
},
|
|
2485
|
+
onError: (error) => {
|
|
2486
|
+
display.showError(`Evolution error: ${error}`);
|
|
2487
|
+
},
|
|
2488
|
+
});
|
|
2489
|
+
const lines = [];
|
|
2490
|
+
lines.push('');
|
|
2491
|
+
lines.push(theme.bold('Evolution Result:'));
|
|
2492
|
+
lines.push(` Success: ${result.success ? theme.success('Yes') : theme.error('No')}`);
|
|
2493
|
+
lines.push(` Iterations: ${result.iteration}`);
|
|
2494
|
+
lines.push(` Issues Found: ${result.issuesFound}`);
|
|
2495
|
+
lines.push(` Issues Fixed: ${result.issuesFixed}`);
|
|
2496
|
+
if (result.error) {
|
|
2497
|
+
lines.push(` Error: ${theme.error(result.error)}`);
|
|
2498
|
+
}
|
|
2499
|
+
lines.push(` Next Action: ${result.nextAction}`);
|
|
2500
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2501
|
+
}
|
|
2502
|
+
catch (error) {
|
|
2503
|
+
display.showError(`Evolution failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
2504
|
+
}
|
|
2505
|
+
return;
|
|
2506
|
+
}
|
|
2507
|
+
if (subcommand === 'stop') {
|
|
2508
|
+
stopEvolution();
|
|
2509
|
+
display.showInfo('Requested stop of evolution...');
|
|
2510
|
+
return;
|
|
2511
|
+
}
|
|
2512
|
+
if (subcommand === 'rollback') {
|
|
2513
|
+
const result = emergencyEvolutionRollback(this.workingDir);
|
|
2514
|
+
if (result.success) {
|
|
2515
|
+
display.showSuccess(result.message);
|
|
2516
|
+
}
|
|
2517
|
+
else {
|
|
2518
|
+
display.showError(result.message);
|
|
2519
|
+
}
|
|
2520
|
+
return;
|
|
2521
|
+
}
|
|
2522
|
+
if (subcommand === 'status') {
|
|
2523
|
+
const status = getEvolutionStatus(this.workingDir);
|
|
2524
|
+
display.showSystemMessage(status);
|
|
2525
|
+
return;
|
|
2526
|
+
}
|
|
2527
|
+
if (subcommand === 'learn') {
|
|
2528
|
+
display.showSystemMessage(theme.gradient.primary(`📚 Learning from ${repoName} Source Code...`));
|
|
2529
|
+
display.showSystemMessage('');
|
|
2530
|
+
const patterns = learnSourcePatterns(this.workingDir);
|
|
2531
|
+
const lines = [];
|
|
2532
|
+
if (patterns.length === 0) {
|
|
2533
|
+
lines.push(theme.warning('No patterns could be extracted.'));
|
|
2534
|
+
}
|
|
2535
|
+
else {
|
|
2536
|
+
lines.push(`Learned ${theme.bold(String(patterns.length))} patterns from source code:`);
|
|
2537
|
+
lines.push('');
|
|
2538
|
+
const byCategory = {
|
|
2539
|
+
'tool-implementation': patterns.filter(p => p.category === 'tool-implementation'),
|
|
2540
|
+
'error-handling': patterns.filter(p => p.category === 'error-handling'),
|
|
2541
|
+
'type-pattern': patterns.filter(p => p.category === 'type-pattern'),
|
|
2542
|
+
'api-design': patterns.filter(p => p.category === 'api-design'),
|
|
2543
|
+
};
|
|
2544
|
+
for (const [category, catPatterns] of Object.entries(byCategory)) {
|
|
2545
|
+
if (catPatterns.length > 0) {
|
|
2546
|
+
const icon = category === 'tool-implementation' ? '🔧' :
|
|
2547
|
+
category === 'error-handling' ? '⚠️' :
|
|
2548
|
+
category === 'type-pattern' ? '📝' : '🏗️';
|
|
2549
|
+
lines.push(`${icon} ${theme.bold(category)}: ${catPatterns.length} patterns`);
|
|
2550
|
+
for (const pattern of catPatterns.slice(0, 3)) {
|
|
2551
|
+
lines.push(` • ${pattern.description}`);
|
|
2552
|
+
lines.push(` ${theme.dim(`Source: ${pattern.sourceFile}`)}`);
|
|
2553
|
+
}
|
|
2554
|
+
if (catPatterns.length > 3) {
|
|
2555
|
+
lines.push(` ${theme.ui.muted(`... and ${catPatterns.length - 3} more`)}`);
|
|
2556
|
+
}
|
|
2557
|
+
lines.push('');
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
lines.push(theme.success('✅ Patterns saved to ~/.erosolar/source-patterns.json'));
|
|
2561
|
+
lines.push('');
|
|
2562
|
+
lines.push('These patterns help the system understand optimal code structures');
|
|
2563
|
+
lines.push('and can be used to guide future code generation.');
|
|
2564
|
+
}
|
|
2565
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2566
|
+
return;
|
|
2567
|
+
}
|
|
2568
|
+
if (subcommand === 'fix') {
|
|
2569
|
+
display.showSystemMessage(theme.gradient.primary('🔧 Generating Fixes for Source Issues...'));
|
|
2570
|
+
display.showSystemMessage('');
|
|
2571
|
+
const issues = analyzeSource(this.workingDir);
|
|
2572
|
+
const highConfidence = issues.filter(i => i.confidence >= 0.7);
|
|
2573
|
+
if (highConfidence.length === 0) {
|
|
2574
|
+
display.showInfo('No high-confidence issues found that need fixing.');
|
|
2575
|
+
return;
|
|
2576
|
+
}
|
|
2577
|
+
const lines = [];
|
|
2578
|
+
lines.push(`Found ${highConfidence.length} issues. Generating fixes...`);
|
|
2579
|
+
lines.push('');
|
|
2580
|
+
let fixCount = 0;
|
|
2581
|
+
for (const issue of highConfidence.slice(0, 5)) {
|
|
2582
|
+
const fix = generateFix(issue, this.workingDir);
|
|
2583
|
+
if (fix) {
|
|
2584
|
+
fixCount++;
|
|
2585
|
+
lines.push(`${theme.bold(`Fix ${fixCount}:`)} ${issue.file}:${issue.line}`);
|
|
2586
|
+
lines.push(` Issue: ${issue.description.slice(0, 60)}`);
|
|
2587
|
+
lines.push(` Fix: ${fix.explanation}`);
|
|
2588
|
+
lines.push(` Confidence: ${Math.round(fix.confidence * 100)}%`);
|
|
2589
|
+
lines.push(` ${fix.requiresManualReview ? theme.warning('⚠️ Requires review') : theme.success('✅ Auto-applicable')}`);
|
|
2590
|
+
lines.push('');
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
if (fixCount === 0) {
|
|
2594
|
+
lines.push(theme.warning('No automatic fixes could be generated for these issues.'));
|
|
2595
|
+
}
|
|
2596
|
+
else {
|
|
2597
|
+
lines.push(`Generated ${fixCount} fix suggestions.`);
|
|
2598
|
+
lines.push('');
|
|
2599
|
+
lines.push(`Run ${theme.bold('/evolve start')} to apply fixes automatically with safety checks.`);
|
|
2600
|
+
}
|
|
2601
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2602
|
+
return;
|
|
2603
|
+
}
|
|
2604
|
+
// Default: show status
|
|
2605
|
+
const status = getEvolutionStatus(this.workingDir);
|
|
2606
|
+
display.showSystemMessage(status);
|
|
2607
|
+
}
|
|
1775
2608
|
showPluginStatus() {
|
|
1776
2609
|
const available = listAvailablePlugins();
|
|
1777
2610
|
const lines = [];
|
|
@@ -1956,6 +2789,277 @@ export class InteractiveShell {
|
|
|
1956
2789
|
}
|
|
1957
2790
|
this.setAutoContinueMode(value === 'on', 'command');
|
|
1958
2791
|
}
|
|
2792
|
+
// ==================== Claude Code Style Commands ====================
|
|
2793
|
+
async handleRewindCommand(input) {
|
|
2794
|
+
const lines = [];
|
|
2795
|
+
lines.push(theme.bold('Rewind / Checkpoint System'));
|
|
2796
|
+
lines.push('');
|
|
2797
|
+
lines.push('Use checkpoints to restore previous states of your code and conversation.');
|
|
2798
|
+
lines.push('');
|
|
2799
|
+
lines.push(theme.secondary('Usage:'));
|
|
2800
|
+
lines.push(' /rewind Show available checkpoints');
|
|
2801
|
+
lines.push(' /rewind list List all checkpoints');
|
|
2802
|
+
lines.push(' /rewind <id> Rewind to specific checkpoint');
|
|
2803
|
+
lines.push(' /rewind code Rewind code only (keep conversation)');
|
|
2804
|
+
lines.push(' /rewind conv Rewind conversation only (keep code)');
|
|
2805
|
+
lines.push('');
|
|
2806
|
+
lines.push(theme.ui.muted('Tip: Press Esc+Esc for quick access to rewind menu'));
|
|
2807
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2808
|
+
}
|
|
2809
|
+
handleMemoryCommand(input) {
|
|
2810
|
+
const lines = [];
|
|
2811
|
+
lines.push(theme.bold('Memory System (EROSOLAR.md)'));
|
|
2812
|
+
lines.push('');
|
|
2813
|
+
lines.push('Create EROSOLAR.md files to store persistent context and preferences.');
|
|
2814
|
+
lines.push('');
|
|
2815
|
+
lines.push(theme.secondary('Memory Locations:'));
|
|
2816
|
+
lines.push(` ~/.erosolar/EROSOLAR.md ${theme.ui.muted('User preferences (global)')}`);
|
|
2817
|
+
lines.push(` ./EROSOLAR.md ${theme.ui.muted('Project memory')}`);
|
|
2818
|
+
lines.push(` ./.erosolar/EROSOLAR.md ${theme.ui.muted('Project memory (alternative)')}`);
|
|
2819
|
+
lines.push('');
|
|
2820
|
+
lines.push(theme.secondary('Features:'));
|
|
2821
|
+
lines.push(' - Use @path/to/file in prompts to reference files');
|
|
2822
|
+
lines.push(' - Use # prefix to quickly add notes to project memory');
|
|
2823
|
+
lines.push(' - Import other files with @./relative/path syntax');
|
|
2824
|
+
lines.push('');
|
|
2825
|
+
lines.push(theme.ui.muted('Tip: Create EROSOLAR.md with project coding standards for better results'));
|
|
2826
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2827
|
+
}
|
|
2828
|
+
handleVimCommand() {
|
|
2829
|
+
const lines = [];
|
|
2830
|
+
lines.push(theme.bold('Vim Mode'));
|
|
2831
|
+
lines.push('');
|
|
2832
|
+
lines.push('Enable vim-style editing in the input area.');
|
|
2833
|
+
lines.push('');
|
|
2834
|
+
lines.push(theme.secondary('Basic Commands:'));
|
|
2835
|
+
lines.push(' h/j/k/l Move left/down/up/right');
|
|
2836
|
+
lines.push(' w/b Word forward/backward');
|
|
2837
|
+
lines.push(' 0/$ Line start/end');
|
|
2838
|
+
lines.push(' i/a Insert before/after cursor');
|
|
2839
|
+
lines.push(' I/A Insert at line start/end');
|
|
2840
|
+
lines.push(' o/O Open line below/above');
|
|
2841
|
+
lines.push(' x Delete character');
|
|
2842
|
+
lines.push(' dd Delete line');
|
|
2843
|
+
lines.push(' yy Yank (copy) line');
|
|
2844
|
+
lines.push(' p Paste');
|
|
2845
|
+
lines.push(' Escape Return to normal mode');
|
|
2846
|
+
lines.push('');
|
|
2847
|
+
lines.push(theme.ui.muted('Vim mode is experimental. Toggle with /vim'));
|
|
2848
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2849
|
+
}
|
|
2850
|
+
handleOutputStyleCommand(input) {
|
|
2851
|
+
const lines = [];
|
|
2852
|
+
lines.push(theme.bold('Output Styles'));
|
|
2853
|
+
lines.push('');
|
|
2854
|
+
lines.push('Change how the AI responds to your requests.');
|
|
2855
|
+
lines.push('');
|
|
2856
|
+
lines.push(theme.secondary('Built-in Styles:'));
|
|
2857
|
+
lines.push(` default ${theme.ui.muted('Standard efficient coding mode')}`);
|
|
2858
|
+
lines.push(` explanatory ${theme.ui.muted('Educational with detailed explanations')}`);
|
|
2859
|
+
lines.push(` learning ${theme.ui.muted('Collaborative with TODO(human) markers')}`);
|
|
2860
|
+
lines.push(` concise ${theme.ui.muted('Minimal output, code-focused only')}`);
|
|
2861
|
+
lines.push('');
|
|
2862
|
+
lines.push(theme.secondary('Custom Styles:'));
|
|
2863
|
+
lines.push(' Create custom styles in ~/.erosolar/output-styles/');
|
|
2864
|
+
lines.push(' or .erosolar/output-styles/ for project-specific styles.');
|
|
2865
|
+
lines.push('');
|
|
2866
|
+
lines.push(theme.secondary('Usage:'));
|
|
2867
|
+
lines.push(' /output-style <name> Switch to a style');
|
|
2868
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2869
|
+
}
|
|
2870
|
+
handleCostCommand() {
|
|
2871
|
+
const lines = [];
|
|
2872
|
+
lines.push(theme.bold('Cost & Token Usage'));
|
|
2873
|
+
lines.push('');
|
|
2874
|
+
// This will be populated with actual data from costTracker
|
|
2875
|
+
lines.push(theme.secondary('Session Statistics:'));
|
|
2876
|
+
lines.push(' Input tokens: (tracking enabled)');
|
|
2877
|
+
lines.push(' Output tokens: (tracking enabled)');
|
|
2878
|
+
lines.push(' Estimated cost: $0.00');
|
|
2879
|
+
lines.push('');
|
|
2880
|
+
lines.push(theme.ui.muted('Token usage is tracked automatically during the session.'));
|
|
2881
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2882
|
+
}
|
|
2883
|
+
handleUsageCommand() {
|
|
2884
|
+
const percentage = this.latestTokenUsage.limit && this.latestTokenUsage.used
|
|
2885
|
+
? Math.round((this.latestTokenUsage.used / this.latestTokenUsage.limit) * 100)
|
|
2886
|
+
: 0;
|
|
2887
|
+
const lines = [];
|
|
2888
|
+
lines.push(theme.bold('Context Usage'));
|
|
2889
|
+
lines.push('');
|
|
2890
|
+
lines.push(theme.secondary('Current Context:'));
|
|
2891
|
+
lines.push(` Used: ${this.latestTokenUsage.used?.toLocaleString() ?? '?'} tokens`);
|
|
2892
|
+
lines.push(` Limit: ${this.latestTokenUsage.limit?.toLocaleString() ?? '?'} tokens`);
|
|
2893
|
+
lines.push(` Usage: ${percentage}%`);
|
|
2894
|
+
lines.push('');
|
|
2895
|
+
if (percentage > 80) {
|
|
2896
|
+
lines.push(theme.warning('Context is getting full. Consider using /compact.'));
|
|
2897
|
+
}
|
|
2898
|
+
else if (percentage > 60) {
|
|
2899
|
+
lines.push(theme.secondary('Context usage is moderate.'));
|
|
2900
|
+
}
|
|
2901
|
+
else {
|
|
2902
|
+
lines.push(theme.success('Plenty of context available.'));
|
|
2903
|
+
}
|
|
2904
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2905
|
+
}
|
|
2906
|
+
async handleUpdateCommand() {
|
|
2907
|
+
display.showInfo('Checking for updates...');
|
|
2908
|
+
const lines = [];
|
|
2909
|
+
lines.push(theme.bold('Update Check'));
|
|
2910
|
+
lines.push('');
|
|
2911
|
+
lines.push(`Current version: ${this.version ?? 'unknown'}`);
|
|
2912
|
+
lines.push('');
|
|
2913
|
+
lines.push(theme.secondary('To update:'));
|
|
2914
|
+
lines.push(' npm install -g erosolar-cli@latest');
|
|
2915
|
+
lines.push(' or: npm update erosolar-cli');
|
|
2916
|
+
lines.push('');
|
|
2917
|
+
lines.push(theme.ui.muted('Auto-updates will be checked periodically.'));
|
|
2918
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2919
|
+
}
|
|
2920
|
+
handleClearCommand() {
|
|
2921
|
+
if (this.agent) {
|
|
2922
|
+
this.agent.clearHistory();
|
|
2923
|
+
this.cachedHistory = this.agent.getHistory();
|
|
2924
|
+
}
|
|
2925
|
+
display.clear();
|
|
2926
|
+
clearAutosaveSnapshot(this.profile);
|
|
2927
|
+
display.showInfo('Conversation cleared. Starting fresh.');
|
|
2928
|
+
this.terminalInput.render();
|
|
2929
|
+
}
|
|
2930
|
+
async handleResumeCommand(input) {
|
|
2931
|
+
const tokens = input.split(/\s+/).slice(1);
|
|
2932
|
+
const sessionId = tokens[0];
|
|
2933
|
+
if (sessionId) {
|
|
2934
|
+
await this.loadSessionCommand(sessionId);
|
|
2935
|
+
}
|
|
2936
|
+
else {
|
|
2937
|
+
// Show session list and auto-select the most recent
|
|
2938
|
+
const sessions = listSessions(this.profile);
|
|
2939
|
+
if (sessions.length > 0) {
|
|
2940
|
+
display.showInfo('Resuming most recent session...');
|
|
2941
|
+
await this.loadSessionCommand('1');
|
|
2942
|
+
}
|
|
2943
|
+
else {
|
|
2944
|
+
display.showWarning('No previous sessions found. Use /sessions to manage sessions.');
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
}
|
|
2948
|
+
handleExportCommand(input) {
|
|
2949
|
+
const lines = [];
|
|
2950
|
+
lines.push(theme.bold('Export Conversation'));
|
|
2951
|
+
lines.push('');
|
|
2952
|
+
lines.push('Export your conversation history for sharing or documentation.');
|
|
2953
|
+
lines.push('');
|
|
2954
|
+
lines.push(theme.secondary('Usage:'));
|
|
2955
|
+
lines.push(' /export Export to default file');
|
|
2956
|
+
lines.push(' /export <filename> Export to specific file');
|
|
2957
|
+
lines.push('');
|
|
2958
|
+
lines.push(theme.ui.muted('Exports include conversation history and tool results.'));
|
|
2959
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2960
|
+
}
|
|
2961
|
+
async handleReviewCommand() {
|
|
2962
|
+
if (this.isProcessing) {
|
|
2963
|
+
display.showWarning('Wait for the current operation to finish.');
|
|
2964
|
+
return;
|
|
2965
|
+
}
|
|
2966
|
+
display.showInfo('Triggering code review of pending changes...');
|
|
2967
|
+
await this.processRequest('Please review all the code changes we made in this session. Look for bugs, security issues, and improvements.');
|
|
2968
|
+
}
|
|
2969
|
+
async handleSecurityReviewCommand() {
|
|
2970
|
+
if (this.isProcessing) {
|
|
2971
|
+
display.showWarning('Wait for the current operation to finish.');
|
|
2972
|
+
return;
|
|
2973
|
+
}
|
|
2974
|
+
display.showInfo('Running comprehensive security review...');
|
|
2975
|
+
await this.processRequest('Please perform a comprehensive security review of the codebase. Check for OWASP top 10 vulnerabilities, insecure patterns, and potential attack vectors.');
|
|
2976
|
+
}
|
|
2977
|
+
handleBugCommand() {
|
|
2978
|
+
const lines = [];
|
|
2979
|
+
lines.push(theme.bold('Report an Issue'));
|
|
2980
|
+
lines.push('');
|
|
2981
|
+
lines.push('Found a bug or have a suggestion?');
|
|
2982
|
+
lines.push('');
|
|
2983
|
+
lines.push(theme.secondary('Report issues at:'));
|
|
2984
|
+
lines.push(' https://github.com/erosolar/erosolar-cli/issues');
|
|
2985
|
+
lines.push('');
|
|
2986
|
+
lines.push(theme.secondary('Include:'));
|
|
2987
|
+
lines.push(' - Steps to reproduce');
|
|
2988
|
+
lines.push(' - Expected vs actual behavior');
|
|
2989
|
+
lines.push(' - Version info (erosolar --version)');
|
|
2990
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2991
|
+
}
|
|
2992
|
+
handleTerminalSetupCommand() {
|
|
2993
|
+
const lines = [];
|
|
2994
|
+
lines.push(theme.bold('Terminal Setup'));
|
|
2995
|
+
lines.push('');
|
|
2996
|
+
lines.push('Configure terminal keybindings for better experience.');
|
|
2997
|
+
lines.push('');
|
|
2998
|
+
lines.push(theme.secondary('Recommended Settings:'));
|
|
2999
|
+
lines.push('');
|
|
3000
|
+
lines.push(theme.bold(' iTerm2:'));
|
|
3001
|
+
lines.push(' Preferences > Keys > Key Bindings');
|
|
3002
|
+
lines.push(' Add: Shift+Enter → Send Escape Sequence: [13;2u');
|
|
3003
|
+
lines.push('');
|
|
3004
|
+
lines.push(theme.bold(' VS Code Terminal:'));
|
|
3005
|
+
lines.push(' Already supports Shift+Enter natively');
|
|
3006
|
+
lines.push('');
|
|
3007
|
+
lines.push(theme.bold(' Kitty/Wezterm:'));
|
|
3008
|
+
lines.push(' Modern terminals support extended keys automatically');
|
|
3009
|
+
lines.push('');
|
|
3010
|
+
lines.push(theme.ui.muted('Shift+Enter enables multi-line input.'));
|
|
3011
|
+
display.showSystemMessage(lines.join('\n'));
|
|
3012
|
+
}
|
|
3013
|
+
handlePermissionsCommand() {
|
|
3014
|
+
const lines = [];
|
|
3015
|
+
lines.push(theme.bold('Tool Permissions'));
|
|
3016
|
+
lines.push('');
|
|
3017
|
+
lines.push('Configure which tools require confirmation before execution.');
|
|
3018
|
+
lines.push('');
|
|
3019
|
+
lines.push(theme.secondary('Current Mode:'));
|
|
3020
|
+
const editMode = this.editGuardMode;
|
|
3021
|
+
lines.push(` Edit Guard: ${editMode === 'ask-permission' ? 'Ask before edits' : editMode === 'plan' ? 'Plan mode' : 'Auto-accept'}`);
|
|
3022
|
+
lines.push('');
|
|
3023
|
+
lines.push(theme.secondary('Toggle with:'));
|
|
3024
|
+
lines.push(' Shift+Tab Cycle through modes');
|
|
3025
|
+
lines.push(' Option+E Toggle edit permission');
|
|
3026
|
+
lines.push('');
|
|
3027
|
+
lines.push(theme.ui.muted('Use /tools to manage which tool suites are enabled.'));
|
|
3028
|
+
display.showSystemMessage(lines.join('\n'));
|
|
3029
|
+
}
|
|
3030
|
+
handleInitCommand() {
|
|
3031
|
+
const lines = [];
|
|
3032
|
+
lines.push(theme.bold('Initialize Project'));
|
|
3033
|
+
lines.push('');
|
|
3034
|
+
lines.push('Create EROSOLAR.md to configure project-specific settings.');
|
|
3035
|
+
lines.push('');
|
|
3036
|
+
lines.push(theme.secondary('This will create:'));
|
|
3037
|
+
lines.push(` ${this.workingDir}/EROSOLAR.md`);
|
|
3038
|
+
lines.push('');
|
|
3039
|
+
lines.push(theme.secondary('Template includes:'));
|
|
3040
|
+
lines.push(' - Project description');
|
|
3041
|
+
lines.push(' - Coding standards');
|
|
3042
|
+
lines.push(' - File conventions');
|
|
3043
|
+
lines.push(' - Testing requirements');
|
|
3044
|
+
lines.push('');
|
|
3045
|
+
lines.push(theme.ui.muted('Use /init confirm to create the file.'));
|
|
3046
|
+
display.showSystemMessage(lines.join('\n'));
|
|
3047
|
+
}
|
|
3048
|
+
async handleCompactCommand() {
|
|
3049
|
+
if (this.isProcessing) {
|
|
3050
|
+
display.showWarning('Wait for the current operation to finish.');
|
|
3051
|
+
return;
|
|
3052
|
+
}
|
|
3053
|
+
display.showInfo('Compacting conversation context...');
|
|
3054
|
+
// Check if compaction is needed based on tracked usage
|
|
3055
|
+
const { used, limit } = this.latestTokenUsage;
|
|
3056
|
+
if (used && limit && used / limit < 0.5) {
|
|
3057
|
+
display.showInfo('Context usage is low. No compaction needed.');
|
|
3058
|
+
return;
|
|
3059
|
+
}
|
|
3060
|
+
await this.processRequest('Please summarize our conversation so far in a concise way, preserving key decisions, code changes, and next steps. This will help compact the context.');
|
|
3061
|
+
}
|
|
3062
|
+
// ==================== End Claude Code Style Commands ====================
|
|
1959
3063
|
updateActiveSession(summary, remember = false) {
|
|
1960
3064
|
this.activeSessionId = summary?.id ?? null;
|
|
1961
3065
|
this.activeSessionTitle = summary?.title ?? null;
|
|
@@ -2631,6 +3735,14 @@ export class InteractiveShell {
|
|
|
2631
3735
|
// Keep the persistent input/control bar active as we transition into streaming.
|
|
2632
3736
|
this.terminalInput.forceRender();
|
|
2633
3737
|
const requestStartTime = Date.now(); // Alpha Zero 2 timing
|
|
3738
|
+
// Clear previous parallel agents and start fresh for new request
|
|
3739
|
+
const parallelManager = getParallelAgentManager();
|
|
3740
|
+
parallelManager.clear();
|
|
3741
|
+
parallelManager.startBatch();
|
|
3742
|
+
// AlphaZero: Track task for learning
|
|
3743
|
+
this.lastUserQuery = request;
|
|
3744
|
+
this.currentTaskType = classifyTaskType(request);
|
|
3745
|
+
this.currentToolCalls = [];
|
|
2634
3746
|
this.uiAdapter.startProcessing('Working on your request');
|
|
2635
3747
|
this.setProcessingStatus();
|
|
2636
3748
|
let responseText = '';
|
|
@@ -2647,6 +3759,43 @@ export class InteractiveShell {
|
|
|
2647
3759
|
if (!responseText?.trim()) {
|
|
2648
3760
|
display.showWarning('The provider returned an empty response. Check your API key/provider selection or retry the prompt.');
|
|
2649
3761
|
}
|
|
3762
|
+
// AlphaZero: Extract and track tool calls from response
|
|
3763
|
+
const toolsUsed = this.extractToolsFromResponse(responseText);
|
|
3764
|
+
this.currentToolCalls = toolsUsed.map(name => ({
|
|
3765
|
+
name,
|
|
3766
|
+
arguments: {},
|
|
3767
|
+
success: true, // Assume success if we got here
|
|
3768
|
+
duration: 0,
|
|
3769
|
+
}));
|
|
3770
|
+
// AlphaZero: Check for failure in response
|
|
3771
|
+
const failure = detectFailure(responseText, {
|
|
3772
|
+
toolCalls: this.currentToolCalls,
|
|
3773
|
+
userMessage: request,
|
|
3774
|
+
});
|
|
3775
|
+
if (failure) {
|
|
3776
|
+
this.lastFailure = failure;
|
|
3777
|
+
// Check if we have a recovery strategy
|
|
3778
|
+
const strategy = findRecoveryStrategy(failure);
|
|
3779
|
+
if (strategy) {
|
|
3780
|
+
display.showSystemMessage(`🔄 Found recovery strategy for this type of issue (success rate: ${Math.round(strategy.successRate * 100)}%)`);
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3783
|
+
else {
|
|
3784
|
+
// Success - record the tool pattern for this task type
|
|
3785
|
+
if (this.currentToolCalls.length > 0) {
|
|
3786
|
+
const toolPattern = {
|
|
3787
|
+
taskType: this.currentTaskType,
|
|
3788
|
+
toolSequence: this.currentToolCalls.map(t => t.name),
|
|
3789
|
+
successRate: 1.0,
|
|
3790
|
+
avgDuration: elapsedMs,
|
|
3791
|
+
occurrences: 1,
|
|
3792
|
+
};
|
|
3793
|
+
addToolPattern(this.currentTaskType, toolPattern);
|
|
3794
|
+
}
|
|
3795
|
+
// Clear action history on success
|
|
3796
|
+
clearActionHistory();
|
|
3797
|
+
this.lastFailure = null;
|
|
3798
|
+
}
|
|
2650
3799
|
}
|
|
2651
3800
|
catch (error) {
|
|
2652
3801
|
const handled = this.handleProviderError(error, () => this.processRequest(request));
|
|
@@ -2704,6 +3853,10 @@ export class InteractiveShell {
|
|
|
2704
3853
|
this.uiUpdates.setMode('processing');
|
|
2705
3854
|
this.terminalInput.setStreaming(true);
|
|
2706
3855
|
const overallStartTime = Date.now();
|
|
3856
|
+
// Clear previous parallel agents and start fresh for continuous mode
|
|
3857
|
+
const parallelManager = getParallelAgentManager();
|
|
3858
|
+
parallelManager.clear();
|
|
3859
|
+
parallelManager.startBatch();
|
|
2707
3860
|
// Initialize the task completion detector
|
|
2708
3861
|
const completionDetector = getTaskCompletionDetector();
|
|
2709
3862
|
completionDetector.reset();
|