erosolar-cli 1.7.373 → 1.7.379

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.
Files changed (99) hide show
  1. package/dist/capabilities/agentSpawningCapability.d.ts.map +1 -1
  2. package/dist/capabilities/agentSpawningCapability.js +29 -1
  3. package/dist/capabilities/agentSpawningCapability.js.map +1 -1
  4. package/dist/contracts/agent-schemas.json +105 -0
  5. package/dist/core/alphaZeroModular.d.ts +186 -0
  6. package/dist/core/alphaZeroModular.d.ts.map +1 -0
  7. package/dist/core/alphaZeroModular.js +755 -0
  8. package/dist/core/alphaZeroModular.js.map +1 -0
  9. package/dist/core/alphaZeroOrchestrator.d.ts +140 -0
  10. package/dist/core/alphaZeroOrchestrator.d.ts.map +1 -0
  11. package/dist/core/alphaZeroOrchestrator.js +418 -0
  12. package/dist/core/alphaZeroOrchestrator.js.map +1 -0
  13. package/dist/core/checkpoint.d.ts +76 -0
  14. package/dist/core/checkpoint.d.ts.map +1 -0
  15. package/dist/core/checkpoint.js +278 -0
  16. package/dist/core/checkpoint.js.map +1 -0
  17. package/dist/core/claudeCodeFeatures.d.ts +64 -0
  18. package/dist/core/claudeCodeFeatures.d.ts.map +1 -0
  19. package/dist/core/claudeCodeFeatures.js +163 -0
  20. package/dist/core/claudeCodeFeatures.js.map +1 -0
  21. package/dist/core/costTracker.d.ts +87 -0
  22. package/dist/core/costTracker.d.ts.map +1 -0
  23. package/dist/core/costTracker.js +285 -0
  24. package/dist/core/costTracker.js.map +1 -0
  25. package/dist/core/failureRecovery.d.ts +122 -0
  26. package/dist/core/failureRecovery.d.ts.map +1 -0
  27. package/dist/core/failureRecovery.js +477 -0
  28. package/dist/core/failureRecovery.js.map +1 -0
  29. package/dist/core/intelligentTestFlows.d.ts +126 -0
  30. package/dist/core/intelligentTestFlows.d.ts.map +1 -0
  31. package/dist/core/intelligentTestFlows.js +678 -0
  32. package/dist/core/intelligentTestFlows.js.map +1 -0
  33. package/dist/core/learningPersistence.d.ts +145 -0
  34. package/dist/core/learningPersistence.d.ts.map +1 -0
  35. package/dist/core/learningPersistence.js +477 -0
  36. package/dist/core/learningPersistence.js.map +1 -0
  37. package/dist/core/memorySystem.d.ts +67 -0
  38. package/dist/core/memorySystem.d.ts.map +1 -0
  39. package/dist/core/memorySystem.js +334 -0
  40. package/dist/core/memorySystem.js.map +1 -0
  41. package/dist/core/outputStyles.d.ts +48 -0
  42. package/dist/core/outputStyles.d.ts.map +1 -0
  43. package/dist/core/outputStyles.js +270 -0
  44. package/dist/core/outputStyles.js.map +1 -0
  45. package/dist/core/selfEvolution.d.ts +155 -0
  46. package/dist/core/selfEvolution.d.ts.map +1 -0
  47. package/dist/core/selfEvolution.js +1000 -0
  48. package/dist/core/selfEvolution.js.map +1 -0
  49. package/dist/core/selfImprovement.d.ts +141 -0
  50. package/dist/core/selfImprovement.d.ts.map +1 -0
  51. package/dist/core/selfImprovement.js +700 -0
  52. package/dist/core/selfImprovement.js.map +1 -0
  53. package/dist/core/updateManager.d.ts +62 -0
  54. package/dist/core/updateManager.d.ts.map +1 -0
  55. package/dist/core/updateManager.js +266 -0
  56. package/dist/core/updateManager.js.map +1 -0
  57. package/dist/shell/interactiveShell.d.ts +67 -0
  58. package/dist/shell/interactiveShell.d.ts.map +1 -1
  59. package/dist/shell/interactiveShell.js +1546 -3
  60. package/dist/shell/interactiveShell.js.map +1 -1
  61. package/dist/shell/keyboardShortcuts.d.ts +53 -0
  62. package/dist/shell/keyboardShortcuts.d.ts.map +1 -0
  63. package/dist/shell/keyboardShortcuts.js +163 -0
  64. package/dist/shell/keyboardShortcuts.js.map +1 -0
  65. package/dist/shell/terminalInput.d.ts +51 -1
  66. package/dist/shell/terminalInput.d.ts.map +1 -1
  67. package/dist/shell/terminalInput.js +223 -12
  68. package/dist/shell/terminalInput.js.map +1 -1
  69. package/dist/shell/terminalInputAdapter.d.ts +7 -1
  70. package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
  71. package/dist/shell/terminalInputAdapter.js +7 -0
  72. package/dist/shell/terminalInputAdapter.js.map +1 -1
  73. package/dist/shell/vimMode.d.ts +66 -0
  74. package/dist/shell/vimMode.d.ts.map +1 -0
  75. package/dist/shell/vimMode.js +434 -0
  76. package/dist/shell/vimMode.js.map +1 -0
  77. package/dist/subagents/parallelAgentManager.d.ts +99 -0
  78. package/dist/subagents/parallelAgentManager.d.ts.map +1 -0
  79. package/dist/subagents/parallelAgentManager.js +249 -0
  80. package/dist/subagents/parallelAgentManager.js.map +1 -0
  81. package/dist/subagents/taskRunner.d.ts +6 -1
  82. package/dist/subagents/taskRunner.d.ts.map +1 -1
  83. package/dist/subagents/taskRunner.js +57 -2
  84. package/dist/subagents/taskRunner.js.map +1 -1
  85. package/dist/tools/planningTools.d.ts +9 -0
  86. package/dist/tools/planningTools.d.ts.map +1 -1
  87. package/dist/tools/planningTools.js +90 -0
  88. package/dist/tools/planningTools.js.map +1 -1
  89. package/dist/ui/display.d.ts +5 -0
  90. package/dist/ui/display.d.ts.map +1 -1
  91. package/dist/ui/display.js +14 -0
  92. package/dist/ui/display.js.map +1 -1
  93. package/dist/ui/shortcutsHelp.d.ts.map +1 -1
  94. package/dist/ui/shortcutsHelp.js +43 -12
  95. package/dist/ui/shortcutsHelp.js.map +1 -1
  96. package/dist/ui/unified/layout.d.ts.map +1 -1
  97. package/dist/ui/unified/layout.js +9 -9
  98. package/dist/ui/unified/layout.js.map +1 -1
  99. 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,16 @@ 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';
32
+ import { analyzeTokenUsage, discoverModularTargets, getModularStatusDisplay, generateContextOptimizations, getGuidelines, deleteGuideline, getPendingActions, executeModularAction, } from '../core/alphaZeroModular.js';
33
+ import { generateTestFlows, detectBugs, detectUIUpdates, saveTestFlows, saveBugReports, saveUIUpdates, getTestFlowStatus, } from '../core/intelligentTestFlows.js';
25
34
  import { TerminalInputAdapter } from './terminalInputAdapter.js';
26
35
  import { renderSessionFrame } from '../ui/unified/layout.js';
27
36
  import { isUpdateInProgress, maybeOfferCliUpdate } from './updateManager.js';
@@ -29,6 +38,7 @@ import { writeLock } from '../ui/writeLock.js';
29
38
  import { enterStreamingMode, exitStreamingMode } from '../ui/globalWriteLock.js';
30
39
  import { setGlobalAIEnhancer } from '../tools/localExplore.js';
31
40
  import { createProvider } from '../providers/providerFactory.js';
41
+ import { getParallelAgentManager } from '../subagents/parallelAgentManager.js';
32
42
  const execAsync = promisify(exec);
33
43
  const DROPDOWN_COLORS = [
34
44
  theme.primary,
@@ -125,6 +135,11 @@ export class InteractiveShell {
125
135
  cachedProviderStatus = [];
126
136
  // Auto-test tracking
127
137
  autoTestInFlight = false;
138
+ // AlphaZero learning tracking
139
+ currentTaskType = 'general';
140
+ currentToolCalls = [];
141
+ lastUserQuery = '';
142
+ lastFailure = null;
128
143
  lastAutoTestRun = null;
129
144
  // Auto-build tracking
130
145
  autoBuildInFlight = false;
@@ -240,6 +255,8 @@ export class InteractiveShell {
240
255
  this.refreshContextGauge();
241
256
  // Start terminal input (sets up handlers)
242
257
  this.terminalInput.start();
258
+ // Set up command autocomplete with all slash commands
259
+ this.setupCommandAutocomplete();
243
260
  // Enter alternate screen buffer when enabled, otherwise clear the main screen for layout
244
261
  if (this.alternateScreenEnabled) {
245
262
  this.terminalInput.enterAlternateScreen();
@@ -256,6 +273,37 @@ export class InteractiveShell {
256
273
  this.rebuildAgent();
257
274
  this.setupHandlers();
258
275
  this.refreshBannerSessionInfo();
276
+ // Subscribe to parallel agent manager events
277
+ this.setupParallelAgentTracking();
278
+ }
279
+ parallelAgentDisplayLines = [];
280
+ setupParallelAgentTracking() {
281
+ const manager = getParallelAgentManager();
282
+ // Update display when agent status changes
283
+ const updateDisplay = () => {
284
+ this.parallelAgentDisplayLines = manager.formatDisplay();
285
+ // Trigger UI refresh if streaming
286
+ if (this.streamingHeartbeatStart) {
287
+ this.displayParallelAgents();
288
+ }
289
+ };
290
+ manager.on('agent:started', updateDisplay);
291
+ manager.on('agent:progress', updateDisplay);
292
+ manager.on('agent:completed', updateDisplay);
293
+ manager.on('agent:error', updateDisplay);
294
+ manager.on('batch:completed', () => {
295
+ // Clear after batch completes to show final summary
296
+ setTimeout(() => {
297
+ this.parallelAgentDisplayLines = [];
298
+ }, 2000);
299
+ });
300
+ }
301
+ displayParallelAgents() {
302
+ if (this.parallelAgentDisplayLines.length === 0)
303
+ return;
304
+ // Display parallel agent tree above the current output
305
+ const agentDisplay = this.parallelAgentDisplayLines.join('\n');
306
+ display.parallelAgentStatus(agentDisplay);
259
307
  }
260
308
  initializeSessionHistory() {
261
309
  this.cachedHistory = [];
@@ -362,6 +410,18 @@ export class InteractiveShell {
362
410
  this.shutdown();
363
411
  return;
364
412
  }
413
+ // Handle pending interactions (from /model, /secrets, etc.) immediately
414
+ if (this.pendingInteraction) {
415
+ this.terminalInput.dequeue();
416
+ void this.handlePendingInteraction(text);
417
+ return;
418
+ }
419
+ // Allow certain commands to run immediately during streaming
420
+ if (this.isImmediateCommand(text)) {
421
+ this.terminalInput.dequeue();
422
+ void this.executeImmediateCommand(text);
423
+ return;
424
+ }
365
425
  // Keep adapter queue trimmed so hints stay accurate
366
426
  this.terminalInput.dequeue();
367
427
  this.followUpQueue.push({ type: 'request', text });
@@ -370,6 +430,51 @@ export class InteractiveShell {
370
430
  this.scheduleQueueProcessing();
371
431
  this.handleInputChange('');
372
432
  }
433
+ /**
434
+ * Check if a command can execute immediately during streaming.
435
+ * These are configuration and info commands that don't interact with the AI.
436
+ */
437
+ isImmediateCommand(text) {
438
+ const trimmed = text.trim().toLowerCase();
439
+ if (!trimmed.startsWith('/'))
440
+ return false;
441
+ // Commands that can run during streaming
442
+ const immediateCommands = [
443
+ '/help', '/?',
444
+ '/model', '/models',
445
+ '/secrets',
446
+ '/tools',
447
+ '/mcp',
448
+ '/provider', '/providers',
449
+ '/thinking',
450
+ '/autocontinue',
451
+ '/shortcuts', '/keys',
452
+ '/cost', '/usage',
453
+ '/context',
454
+ '/sessions',
455
+ '/features',
456
+ '/local', '/discover',
457
+ '/evolve', '/modular', '/a0',
458
+ '/learn',
459
+ '/test', '/tests',
460
+ '/plugins',
461
+ '/metrics', '/stats', '/perf',
462
+ '/terminal-setup',
463
+ '/permissions',
464
+ '/vim',
465
+ '/output-style',
466
+ ];
467
+ const cmd = trimmed.split(/\s+/)[0];
468
+ return immediateCommands.includes(cmd);
469
+ }
470
+ /**
471
+ * Execute a command immediately during streaming.
472
+ */
473
+ async executeImmediateCommand(text) {
474
+ // Pause streaming display briefly to show command output
475
+ display.showInfo(`Running command during stream: ${text}`);
476
+ await this.processSlashCommand(text);
477
+ }
373
478
  /**
374
479
  * TerminalInputAdapter change handler
375
480
  */
@@ -386,11 +491,22 @@ export class InteractiveShell {
386
491
  handleEditModeChange(mode) {
387
492
  this.editGuardMode = mode;
388
493
  this.pendingPermissionInput = null;
389
- if (mode === 'ask-permission') {
390
- display.showSystemMessage('🛡️ Ask-to-edit mode enabled. Confirm each request before sending.');
494
+ if (mode === 'plan') {
495
+ // Register plan approval callback for interactive UI
496
+ setPlanApprovalCallback((steps, explanation) => {
497
+ this.showPlanApproval(steps, explanation);
498
+ });
499
+ display.showSystemMessage('📋 Plan mode enabled. AI will create a plan and ask for approval before implementing.');
391
500
  }
392
501
  else {
393
- display.showSystemMessage('✏️ Display edits mode enabled.');
502
+ // Unregister callback when not in plan mode
503
+ setPlanApprovalCallback(null);
504
+ if (mode === 'ask-permission') {
505
+ display.showSystemMessage('🛡️ Ask-to-edit mode enabled. Confirm each request before sending.');
506
+ }
507
+ else {
508
+ display.showSystemMessage('✏️ Display edits mode enabled.');
509
+ }
394
510
  }
395
511
  this.terminalInput.render();
396
512
  }
@@ -757,6 +873,130 @@ export class InteractiveShell {
757
873
  this.agentMenu.persistedProfile = profileName;
758
874
  display.showInfo(`${this.agentMenuLabel(profileName)} will load the next time you start the CLI. Restart to switch now.`);
759
875
  }
876
+ /**
877
+ * Show plan approval UI with interactive step selection
878
+ */
879
+ showPlanApproval(steps, explanation) {
880
+ const planSteps = steps.map((step, idx) => ({
881
+ id: idx + 1,
882
+ description: step.description,
883
+ status: 'pending',
884
+ }));
885
+ this.pendingInteraction = {
886
+ type: 'plan-approval',
887
+ steps: planSteps,
888
+ selectedSteps: new Set(planSteps.map(s => s.id)), // All selected by default
889
+ explanation,
890
+ };
891
+ this.displayPlanApprovalUI();
892
+ }
893
+ displayPlanApprovalUI() {
894
+ const pending = this.pendingInteraction;
895
+ if (!pending || pending.type !== 'plan-approval')
896
+ return;
897
+ const lines = [];
898
+ lines.push('');
899
+ lines.push(theme.gradient.primary('═'.repeat(60)));
900
+ lines.push(theme.gradient.primary('📋 PLAN FOR APPROVAL'));
901
+ lines.push(theme.gradient.primary('═'.repeat(60)));
902
+ lines.push('');
903
+ if (pending.explanation) {
904
+ lines.push(theme.ui.muted(pending.explanation));
905
+ lines.push('');
906
+ }
907
+ lines.push(theme.info('Steps (toggle with number, or enter your own):'));
908
+ lines.push('');
909
+ for (const step of pending.steps) {
910
+ const isSelected = pending.selectedSteps.has(step.id);
911
+ const checkbox = isSelected ? theme.success('☑') : theme.ui.muted('☐');
912
+ const stepNum = theme.info(`${step.id}.`);
913
+ const desc = isSelected ? step.description : theme.ui.muted(step.description);
914
+ lines.push(` ${checkbox} ${stepNum} ${desc}`);
915
+ }
916
+ lines.push('');
917
+ lines.push(theme.ui.muted('─'.repeat(60)));
918
+ lines.push('');
919
+ lines.push(theme.info('Commands:'));
920
+ lines.push(` ${theme.primary('1-N')} Toggle step selection`);
921
+ lines.push(` ${theme.primary('all')} Select all steps`);
922
+ lines.push(` ${theme.primary('none')} Deselect all steps`);
923
+ lines.push(` ${theme.primary('go')} Execute selected steps`);
924
+ lines.push(` ${theme.primary('cancel')} Cancel planning`);
925
+ lines.push(` ${theme.primary('[text]')} Submit your own solution instead`);
926
+ lines.push('');
927
+ display.showSystemMessage(lines.join('\n'));
928
+ this.terminalInput.render();
929
+ }
930
+ async handlePlanApprovalInput(input) {
931
+ const pending = this.pendingInteraction;
932
+ if (!pending || pending.type !== 'plan-approval')
933
+ return;
934
+ const trimmed = input.trim();
935
+ if (!trimmed) {
936
+ display.showWarning('Enter a command or your own solution.');
937
+ this.terminalInput.render();
938
+ return;
939
+ }
940
+ const lower = trimmed.toLowerCase();
941
+ // Cancel
942
+ if (lower === 'cancel' || lower === 'c') {
943
+ this.pendingInteraction = null;
944
+ display.showInfo('Plan cancelled. You can continue with a different approach.');
945
+ this.terminalInput.render();
946
+ return;
947
+ }
948
+ // Select all
949
+ if (lower === 'all' || lower === 'a') {
950
+ pending.selectedSteps = new Set(pending.steps.map(s => s.id));
951
+ this.displayPlanApprovalUI();
952
+ return;
953
+ }
954
+ // Deselect all
955
+ if (lower === 'none' || lower === 'n') {
956
+ pending.selectedSteps.clear();
957
+ this.displayPlanApprovalUI();
958
+ return;
959
+ }
960
+ // Execute selected steps
961
+ if (lower === 'go' || lower === 'g' || lower === 'yes' || lower === 'y') {
962
+ const selectedSteps = pending.steps.filter(s => pending.selectedSteps.has(s.id));
963
+ if (selectedSteps.length === 0) {
964
+ display.showWarning('No steps selected. Select steps or enter your own solution.');
965
+ this.terminalInput.render();
966
+ return;
967
+ }
968
+ this.pendingInteraction = null;
969
+ // Build the implementation prompt with selected steps
970
+ const stepList = selectedSteps.map(s => `${s.id}. ${s.description}`).join('\n');
971
+ const implementPrompt = `Proceed with implementing the following steps:\n\n${stepList}\n\nStart implementing now. Use the appropriate tools.`;
972
+ // Queue the implementation request
973
+ await this.processInputBlock(implementPrompt);
974
+ return;
975
+ }
976
+ // Toggle step by number
977
+ const num = Number.parseInt(trimmed, 10);
978
+ if (Number.isFinite(num) && num >= 1 && num <= pending.steps.length) {
979
+ if (pending.selectedSteps.has(num)) {
980
+ pending.selectedSteps.delete(num);
981
+ }
982
+ else {
983
+ pending.selectedSteps.add(num);
984
+ }
985
+ this.displayPlanApprovalUI();
986
+ return;
987
+ }
988
+ // User submitted their own solution - treat as custom input
989
+ if (trimmed.length > 10) {
990
+ this.pendingInteraction = null;
991
+ display.showInfo('Using your custom solution...');
992
+ // Send the custom solution as the implementation request
993
+ const customPrompt = `The user has provided their own solution instead of the plan. Please implement this:\n\n${trimmed}`;
994
+ await this.processInputBlock(customPrompt);
995
+ return;
996
+ }
997
+ display.showWarning('Invalid input. Enter a step number, command (go/cancel/all/none), or your own solution.');
998
+ this.terminalInput.render();
999
+ }
760
1000
  setupHandlers() {
761
1001
  // Handle terminal resize
762
1002
  output.on('resize', () => {
@@ -765,6 +1005,39 @@ export class InteractiveShell {
765
1005
  // Show initial input UI
766
1006
  this.terminalInput.render();
767
1007
  }
1008
+ /**
1009
+ * Set up command autocomplete with all available slash commands.
1010
+ * Commands are loaded from agent-schemas.json and custom commands.
1011
+ */
1012
+ setupCommandAutocomplete() {
1013
+ const commands = [];
1014
+ // Load built-in slash commands from schema
1015
+ const schemaCommands = getSlashCommands();
1016
+ for (const cmd of schemaCommands) {
1017
+ commands.push({
1018
+ command: cmd.command,
1019
+ description: cmd.description,
1020
+ category: cmd.category,
1021
+ });
1022
+ }
1023
+ // Load custom commands (if any)
1024
+ try {
1025
+ const customCommands = loadCustomSlashCommands(this.workingDir);
1026
+ for (const custom of customCommands) {
1027
+ commands.push({
1028
+ command: custom.command,
1029
+ description: custom.description || 'Custom command',
1030
+ category: custom.category || 'custom',
1031
+ });
1032
+ }
1033
+ }
1034
+ catch {
1035
+ // Custom commands are optional
1036
+ }
1037
+ // Sort commands alphabetically
1038
+ commands.sort((a, b) => a.command.localeCompare(b.command));
1039
+ this.terminalInput.setAvailableCommands(commands);
1040
+ }
768
1041
  setupStatusTracking() {
769
1042
  this.statusSubscription = this.statusTracker.subscribe((state) => {
770
1043
  this.statusLineState = state;
@@ -1008,6 +1281,12 @@ export class InteractiveShell {
1008
1281
  const frame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
1009
1282
  this.streamingStatusLabel = this.buildStreamingStatus(`${frame} ${label}`, elapsedSeconds);
1010
1283
  display.updateStreamingStatus(this.streamingStatusLabel);
1284
+ // Update parallel agent display during streaming
1285
+ const manager = getParallelAgentManager();
1286
+ if (manager.isRunning()) {
1287
+ this.parallelAgentDisplayLines = manager.formatDisplay();
1288
+ this.displayParallelAgents();
1289
+ }
1011
1290
  this.refreshStatusLine(true);
1012
1291
  },
1013
1292
  });
@@ -1219,6 +1498,9 @@ export class InteractiveShell {
1219
1498
  case 'agent-selection':
1220
1499
  await this.handleAgentSelectionInput(input);
1221
1500
  return true;
1501
+ case 'plan-approval':
1502
+ await this.handlePlanApprovalInput(input);
1503
+ return true;
1222
1504
  default:
1223
1505
  return false;
1224
1506
  }
@@ -1238,6 +1520,12 @@ export class InteractiveShell {
1238
1520
  case '/features':
1239
1521
  this.showFeaturesMenu(input);
1240
1522
  break;
1523
+ case '/learn':
1524
+ this.showLearningStatus(input);
1525
+ break;
1526
+ case '/improve':
1527
+ void this.handleImprovementCommand(input);
1528
+ break;
1241
1529
  case '/model':
1242
1530
  this.showModelMenu();
1243
1531
  break;
@@ -1299,6 +1587,17 @@ export class InteractiveShell {
1299
1587
  case '/plugins':
1300
1588
  this.showPluginStatus();
1301
1589
  break;
1590
+ case '/evolve':
1591
+ void this.handleEvolveCommand(input);
1592
+ break;
1593
+ case '/modular':
1594
+ case '/a0':
1595
+ void this.handleModularCommand(input);
1596
+ break;
1597
+ case '/test':
1598
+ case '/tests':
1599
+ void this.handleTestCommand(input);
1600
+ break;
1302
1601
  case '/provider':
1303
1602
  await this.handleProviderCommand(input);
1304
1603
  break;
@@ -1311,6 +1610,58 @@ export class InteractiveShell {
1311
1610
  case '/discover':
1312
1611
  await this.discoverModelsCommand();
1313
1612
  break;
1613
+ // Claude Code style commands
1614
+ case '/rewind':
1615
+ await this.handleRewindCommand(input);
1616
+ break;
1617
+ case '/memory':
1618
+ this.handleMemoryCommand(input);
1619
+ break;
1620
+ case '/vim':
1621
+ this.handleVimCommand();
1622
+ break;
1623
+ case '/output-style':
1624
+ this.handleOutputStyleCommand(input);
1625
+ break;
1626
+ case '/cost':
1627
+ this.handleCostCommand();
1628
+ break;
1629
+ case '/usage':
1630
+ this.handleUsageCommand();
1631
+ break;
1632
+ case '/update':
1633
+ await this.handleUpdateCommand();
1634
+ break;
1635
+ case '/clear':
1636
+ this.handleClearCommand();
1637
+ break;
1638
+ case '/resume':
1639
+ await this.handleResumeCommand(input);
1640
+ break;
1641
+ case '/export':
1642
+ this.handleExportCommand(input);
1643
+ break;
1644
+ case '/review':
1645
+ await this.handleReviewCommand();
1646
+ break;
1647
+ case '/security-review':
1648
+ await this.handleSecurityReviewCommand();
1649
+ break;
1650
+ case '/bug':
1651
+ this.handleBugCommand();
1652
+ break;
1653
+ case '/terminal-setup':
1654
+ this.handleTerminalSetupCommand();
1655
+ break;
1656
+ case '/permissions':
1657
+ this.handlePermissionsCommand();
1658
+ break;
1659
+ case '/init':
1660
+ this.handleInitCommand();
1661
+ break;
1662
+ case '/compact':
1663
+ await this.handleCompactCommand();
1664
+ break;
1314
1665
  default:
1315
1666
  if (!(await this.tryCustomSlashCommand(command, input))) {
1316
1667
  display.showWarning(`Unknown command "${command}".`);
@@ -1772,6 +2123,878 @@ export class InteractiveShell {
1772
2123
  lines.push(theme.ui.muted('Feature changes take effect on next launch.'));
1773
2124
  display.showSystemMessage(lines.join('\n'));
1774
2125
  }
2126
+ showLearningStatus(input) {
2127
+ const args = input.split(/\s+/).slice(1);
2128
+ const subcommand = args[0]?.toLowerCase();
2129
+ // Handle subcommands
2130
+ if (subcommand === 'commit') {
2131
+ const result = commitLearning(args.slice(1).join(' ') || 'Manual learning checkpoint', this.workingDir);
2132
+ if (result.success) {
2133
+ display.showInfo(`Learning committed: ${result.commitHash}`);
2134
+ }
2135
+ else {
2136
+ display.showWarning(`Could not commit: ${result.error}`);
2137
+ }
2138
+ return;
2139
+ }
2140
+ if (subcommand === 'export') {
2141
+ const data = exportAllLearning();
2142
+ const json = JSON.stringify(data, null, 2);
2143
+ display.showSystemMessage(`Exported learning data:\n\n${json.slice(0, 2000)}${json.length > 2000 ? '\n...(truncated)' : ''}`);
2144
+ return;
2145
+ }
2146
+ if (subcommand === 'history') {
2147
+ const history = getRecentLearning(20);
2148
+ const lines = [];
2149
+ lines.push(theme.gradient.primary('Recent Learning History'));
2150
+ lines.push('');
2151
+ if (history.length === 0) {
2152
+ lines.push(theme.ui.muted('No learning history yet.'));
2153
+ }
2154
+ else {
2155
+ for (const entry of history) {
2156
+ const date = new Date(entry.timestamp).toLocaleString();
2157
+ const icon = entry.type === 'tool-pattern' ? '🔧' :
2158
+ entry.type === 'quality-threshold' ? '📊' :
2159
+ entry.type === 'failure-pattern' ? '⚠️' : '💡';
2160
+ lines.push(` ${icon} ${theme.ui.muted(date)}`);
2161
+ lines.push(` ${entry.description}`);
2162
+ }
2163
+ }
2164
+ display.showSystemMessage(lines.join('\n'));
2165
+ return;
2166
+ }
2167
+ // Default: show summary
2168
+ const summary = getLearningSummary();
2169
+ const lines = [];
2170
+ lines.push(theme.gradient.primary('🧠 AlphaZero Learning Status'));
2171
+ lines.push('');
2172
+ // Tool patterns
2173
+ lines.push(theme.bold('Tool Patterns Learned:'));
2174
+ if (summary.toolPatterns.totalPatterns === 0) {
2175
+ lines.push(` ${theme.ui.muted('No patterns learned yet. Use the CLI to build up patterns.')}`);
2176
+ }
2177
+ else {
2178
+ lines.push(` Total: ${theme.info(String(summary.toolPatterns.totalPatterns))} patterns across ${summary.toolPatterns.taskTypes.length} task types`);
2179
+ if (summary.toolPatterns.bestPatterns.length > 0) {
2180
+ lines.push(' Best patterns:');
2181
+ for (const p of summary.toolPatterns.bestPatterns) {
2182
+ const rate = Math.round(p.successRate * 100);
2183
+ lines.push(` ${theme.success('•')} ${p.taskType}: ${theme.ui.muted(p.pattern)} (${rate}% success)`);
2184
+ }
2185
+ }
2186
+ }
2187
+ lines.push('');
2188
+ // Quality thresholds
2189
+ lines.push(theme.bold('Quality Thresholds:'));
2190
+ lines.push(` Min acceptable: ${theme.warning(String(Math.round(summary.qualityThresholds.avgMinAcceptable)))}/100`);
2191
+ lines.push(` Target quality: ${theme.success(String(Math.round(summary.qualityThresholds.avgTargetQuality)))}/100`);
2192
+ lines.push(` Task types: ${summary.qualityThresholds.taskTypes.join(', ')}`);
2193
+ lines.push('');
2194
+ // Failure patterns
2195
+ lines.push(theme.bold('Failure Patterns:'));
2196
+ if (summary.failurePatterns.totalPatterns === 0) {
2197
+ lines.push(` ${theme.ui.muted('No failure patterns recorded.')}`);
2198
+ }
2199
+ else {
2200
+ lines.push(` Total: ${theme.warning(String(summary.failurePatterns.totalPatterns))} patterns to avoid`);
2201
+ if (summary.failurePatterns.mostFrequent.length > 0) {
2202
+ for (const f of summary.failurePatterns.mostFrequent) {
2203
+ lines.push(` ${theme.error('✗')} ${f.description} (${f.occurrences}x)`);
2204
+ }
2205
+ }
2206
+ }
2207
+ lines.push('');
2208
+ // Prompt improvements
2209
+ lines.push(theme.bold('Prompt Improvements:'));
2210
+ if (summary.promptImprovements.totalImprovements === 0) {
2211
+ lines.push(` ${theme.ui.muted('No prompt improvements discovered yet.')}`);
2212
+ }
2213
+ else {
2214
+ lines.push(` Total: ${theme.info(String(summary.promptImprovements.totalImprovements))} improvements`);
2215
+ lines.push(` Categories: ${summary.promptImprovements.categories.join(', ')}`);
2216
+ lines.push(` Avg quality gain: ${theme.success(`+${Math.round(summary.promptImprovements.avgQualityGain)}%`)}`);
2217
+ }
2218
+ lines.push('');
2219
+ // Recent activity
2220
+ lines.push(theme.bold('Activity:'));
2221
+ lines.push(` Learning events (24h): ${summary.recentActivity}`);
2222
+ lines.push(` Storage: ${theme.ui.muted(getLearningDir())}`);
2223
+ lines.push('');
2224
+ // Commands
2225
+ lines.push(theme.bold('Commands:'));
2226
+ lines.push(` ${theme.primary('/learn')} - Show this summary`);
2227
+ lines.push(` ${theme.primary('/learn history')} - View recent learning events`);
2228
+ lines.push(` ${theme.primary('/learn commit')} - Commit learning to git`);
2229
+ lines.push(` ${theme.primary('/learn export')} - Export learning data as JSON`);
2230
+ display.showSystemMessage(lines.join('\n'));
2231
+ }
2232
+ /**
2233
+ * Handle /improve command for self-improvement
2234
+ */
2235
+ async handleImprovementCommand(input) {
2236
+ const args = input.split(/\s+/).slice(1);
2237
+ const subcommand = args[0]?.toLowerCase();
2238
+ if (subcommand === 'analyze') {
2239
+ const opportunities = analyzeImprovementOpportunities(this.workingDir);
2240
+ const lines = [];
2241
+ lines.push(theme.gradient.primary('🔍 Improvement Analysis'));
2242
+ lines.push('');
2243
+ if (opportunities.length === 0) {
2244
+ lines.push(theme.ui.muted('No improvement opportunities found. Keep using the CLI to build learning data.'));
2245
+ }
2246
+ else {
2247
+ lines.push(`Found ${theme.info(String(opportunities.length))} improvement opportunities:`);
2248
+ lines.push('');
2249
+ for (const opp of opportunities.slice(0, 10)) {
2250
+ const icon = opp.type === 'bug-fix' ? '🐛' : opp.type === 'refactor' ? '🔧' : '⚡';
2251
+ const priorityColor = opp.priority === 'critical' ? theme.error :
2252
+ opp.priority === 'high' ? theme.warning : theme.info;
2253
+ lines.push(` ${icon} ${priorityColor(`[${opp.priority}]`)} ${opp.description.slice(0, 60)}`);
2254
+ lines.push(` ${theme.ui.muted(`Confidence: ${Math.round(opp.confidence * 100)}%`)} | ${theme.ui.muted(`File: ${opp.sourceFile}`)}`);
2255
+ for (const ev of opp.evidence.slice(0, 2)) {
2256
+ lines.push(` ${theme.dim(`• ${ev}`)}`);
2257
+ }
2258
+ lines.push('');
2259
+ }
2260
+ if (opportunities.length > 10) {
2261
+ lines.push(theme.ui.muted(`... and ${opportunities.length - 10} more`));
2262
+ }
2263
+ }
2264
+ display.showSystemMessage(lines.join('\n'));
2265
+ return;
2266
+ }
2267
+ if (subcommand === 'apply') {
2268
+ display.showSystemMessage(theme.gradient.primary('🚀 Running Self-Improvement Cycle...'));
2269
+ display.showSystemMessage('');
2270
+ try {
2271
+ const result = await runSelfImprovementCycle(this.workingDir, {
2272
+ maxChanges: 3,
2273
+ minConfidence: 0.7,
2274
+ runTests: true,
2275
+ autoCommit: true,
2276
+ });
2277
+ const lines = [];
2278
+ lines.push(theme.bold('Results:'));
2279
+ lines.push(result.summary);
2280
+ lines.push('');
2281
+ if (result.applied > 0) {
2282
+ lines.push(theme.success(`✅ Applied ${result.applied} improvements!`));
2283
+ for (const r of result.results.filter(r => r.success)) {
2284
+ lines.push(` - Files: ${r.filesChanged.join(', ')}`);
2285
+ if (r.commitHash) {
2286
+ lines.push(` Commit: ${theme.ui.muted(r.commitHash)}`);
2287
+ lines.push(` Rollback: ${theme.dim(r.rollbackCommand ?? '')}`);
2288
+ }
2289
+ }
2290
+ }
2291
+ else {
2292
+ lines.push(theme.warning('No improvements were applied.'));
2293
+ for (const r of result.results.filter(r => !r.success)) {
2294
+ lines.push(` ${theme.error('✗')} ${r.error}`);
2295
+ }
2296
+ }
2297
+ display.showSystemMessage(lines.join('\n'));
2298
+ }
2299
+ catch (error) {
2300
+ display.showError(`Self-improvement failed: ${error instanceof Error ? error.message : String(error)}`);
2301
+ }
2302
+ return;
2303
+ }
2304
+ if (subcommand === 'dry-run') {
2305
+ const opportunities = analyzeImprovementOpportunities(this.workingDir);
2306
+ const filtered = opportunities.filter(o => o.confidence >= 0.7);
2307
+ const toApply = filtered.slice(0, 3);
2308
+ const lines = [];
2309
+ lines.push(theme.gradient.primary('🔮 Dry Run - Preview Changes'));
2310
+ lines.push('');
2311
+ if (toApply.length === 0) {
2312
+ lines.push(theme.ui.muted('No high-confidence improvements to apply.'));
2313
+ }
2314
+ else {
2315
+ lines.push(`Would apply ${theme.info(String(toApply.length))} improvements:`);
2316
+ lines.push('');
2317
+ for (const opp of toApply) {
2318
+ const icon = opp.type === 'bug-fix' ? '🐛' : opp.type === 'refactor' ? '🔧' : '⚡';
2319
+ lines.push(` ${icon} ${opp.description.slice(0, 60)}`);
2320
+ lines.push(` ${theme.ui.muted(`File: ${opp.sourceFile}`)}`);
2321
+ lines.push(` ${theme.dim(`Suggested: ${opp.suggestedChange.slice(0, 100)}...`)}`);
2322
+ lines.push('');
2323
+ }
2324
+ lines.push(theme.bold('Run `/improve apply` to execute these changes.'));
2325
+ }
2326
+ display.showSystemMessage(lines.join('\n'));
2327
+ return;
2328
+ }
2329
+ if (subcommand === 'auto') {
2330
+ void this.runAutonomousImprovementMode();
2331
+ return;
2332
+ }
2333
+ if (subcommand === 'stop') {
2334
+ requestAutoImprovementStop();
2335
+ display.showInfo('Requested stop of autonomous improvement...');
2336
+ return;
2337
+ }
2338
+ if (subcommand === 'rollback') {
2339
+ const result = emergencyRollback(this.workingDir);
2340
+ if (result.success) {
2341
+ display.showSuccess(result.message);
2342
+ }
2343
+ else {
2344
+ display.showError(result.message);
2345
+ }
2346
+ return;
2347
+ }
2348
+ if (subcommand === 'status') {
2349
+ const state = getAutoImprovementState();
2350
+ const lines = [];
2351
+ lines.push(theme.gradient.primary('🤖 Auto-Improvement Status'));
2352
+ lines.push('');
2353
+ lines.push(`Running: ${state.isRunning ? theme.success('Yes') : theme.ui.muted('No')}`);
2354
+ if (state.startTime) {
2355
+ lines.push(`Started: ${theme.ui.muted(state.startTime)}`);
2356
+ }
2357
+ lines.push(`Iteration: ${state.iteration}`);
2358
+ lines.push(`Applied: ${theme.success(String(state.applied))}`);
2359
+ lines.push(`Failed: ${theme.warning(String(state.failed))}`);
2360
+ lines.push(`Rollbacks: ${theme.error(String(state.rollbacks))}`);
2361
+ if (state.lastError) {
2362
+ lines.push(`Last Error: ${theme.error(state.lastError)}`);
2363
+ }
2364
+ display.showSystemMessage(lines.join('\n'));
2365
+ return;
2366
+ }
2367
+ // Default: show summary
2368
+ const summary = getImprovementSummary(this.workingDir);
2369
+ display.showSystemMessage(summary);
2370
+ }
2371
+ /**
2372
+ * Run autonomous improvement mode with self-relaunch capability
2373
+ */
2374
+ async runAutonomousImprovementMode() {
2375
+ const isSelfImproving = this.workingDir.includes('erosolar');
2376
+ display.showSystemMessage(theme.gradient.primary('🤖 Starting Autonomous Improvement Mode'));
2377
+ display.showSystemMessage('');
2378
+ display.showSystemMessage(`${theme.bold('Safety Features:')}`);
2379
+ display.showSystemMessage(' • Git checkpoint created before starting');
2380
+ display.showSystemMessage(' • Each change validated with build + tests');
2381
+ display.showSystemMessage(' • Auto-rollback on failures');
2382
+ display.showSystemMessage(' • Press Ctrl+C to stop gracefully');
2383
+ if (isSelfImproving) {
2384
+ display.showSystemMessage(' • CLI will relaunch after improvements to run new code');
2385
+ }
2386
+ display.showSystemMessage('');
2387
+ display.showSystemMessage(`${theme.bold('Commands while running:')}`);
2388
+ display.showSystemMessage(' /improve stop - Request graceful stop');
2389
+ display.showSystemMessage(' /improve status - Check current status');
2390
+ display.showSystemMessage(' /improve rollback - Emergency rollback to checkpoint');
2391
+ display.showSystemMessage('');
2392
+ let stopRequested = false;
2393
+ // Set up Ctrl+C handler
2394
+ const originalSigintHandler = process.listeners('SIGINT');
2395
+ process.removeAllListeners('SIGINT');
2396
+ process.once('SIGINT', () => {
2397
+ display.showWarning('Ctrl+C pressed - stopping after current iteration...');
2398
+ stopRequested = true;
2399
+ requestAutoImprovementStop();
2400
+ });
2401
+ try {
2402
+ const result = await runAutonomousImprovement({
2403
+ workingDir: this.workingDir,
2404
+ minConfidence: 0.75,
2405
+ maxIterations: 100,
2406
+ delayBetweenMs: 3000,
2407
+ runTests: true,
2408
+ shouldStop: () => stopRequested,
2409
+ onProgress: (event) => {
2410
+ switch (event.type) {
2411
+ case 'start':
2412
+ display.showInfo(event.message);
2413
+ break;
2414
+ case 'iteration':
2415
+ display.showSystemMessage(`\n${theme.bold(`[Iteration ${event.iteration}]`)} ${event.message}`);
2416
+ break;
2417
+ case 'applied':
2418
+ display.showSuccess(event.message);
2419
+ display.showSystemMessage(` Total applied: ${event.totalApplied}`);
2420
+ break;
2421
+ case 'failed':
2422
+ display.showWarning(event.message);
2423
+ break;
2424
+ case 'rollback':
2425
+ display.showError(event.message);
2426
+ break;
2427
+ case 'no-opportunities':
2428
+ display.showInfo(event.message);
2429
+ break;
2430
+ case 'complete':
2431
+ display.showSystemMessage('');
2432
+ display.showSystemMessage(theme.gradient.primary('═══ Autonomous Improvement Complete ═══'));
2433
+ display.showSystemMessage(event.message);
2434
+ if (event.totalApplied !== undefined) {
2435
+ display.showSystemMessage(`Applied: ${theme.success(String(event.totalApplied))}`);
2436
+ }
2437
+ if (event.totalFailed !== undefined) {
2438
+ display.showSystemMessage(`Failed: ${theme.warning(String(event.totalFailed))}`);
2439
+ }
2440
+ break;
2441
+ }
2442
+ },
2443
+ });
2444
+ // Restore SIGINT handlers
2445
+ process.removeAllListeners('SIGINT');
2446
+ for (const handler of originalSigintHandler) {
2447
+ process.on('SIGINT', handler);
2448
+ }
2449
+ // Summary
2450
+ display.showSystemMessage('');
2451
+ display.showSystemMessage(theme.bold('Final Summary:'));
2452
+ display.showSystemMessage(` Iterations: ${result.iterations}`);
2453
+ display.showSystemMessage(` Applied: ${theme.success(String(result.totalApplied))}`);
2454
+ display.showSystemMessage(` Failed: ${theme.warning(String(result.totalFailed))}`);
2455
+ display.showSystemMessage(` Rollbacks: ${theme.error(String(result.totalRollbacks))}`);
2456
+ display.showSystemMessage(` Stopped: ${result.stoppedReason}`);
2457
+ // If we improved erosolar-cli itself and applied changes, offer to relaunch
2458
+ if (isSelfImproving && result.totalApplied > 0) {
2459
+ display.showSystemMessage('');
2460
+ display.showSystemMessage(theme.gradient.primary('🔄 CLI source code was updated!'));
2461
+ display.showSystemMessage('To run the improved version:');
2462
+ display.showSystemMessage(` ${theme.bold('npm run build && erosolar')}`);
2463
+ display.showSystemMessage('');
2464
+ display.showSystemMessage('Or to continue auto-improvement with new code:');
2465
+ display.showSystemMessage(` ${theme.bold('npm run build && erosolar -c "/improve auto"')}`);
2466
+ }
2467
+ }
2468
+ catch (error) {
2469
+ // Restore SIGINT handlers
2470
+ process.removeAllListeners('SIGINT');
2471
+ for (const handler of originalSigintHandler) {
2472
+ process.on('SIGINT', handler);
2473
+ }
2474
+ display.showError(`Autonomous improvement failed: ${error instanceof Error ? error.message : String(error)}`);
2475
+ display.showSystemMessage('');
2476
+ display.showSystemMessage('Run `/improve rollback` to restore to the checkpoint if needed.');
2477
+ }
2478
+ }
2479
+ /**
2480
+ * Handle /evolve command for self-evolution (erosolar-cli source only)
2481
+ */
2482
+ async handleEvolveCommand(input) {
2483
+ const args = input.split(/\s+/).slice(1);
2484
+ const subcommand = args[0]?.toLowerCase();
2485
+ // Check if we're in a valid source repository
2486
+ if (!isValidSourceRepo(this.workingDir)) {
2487
+ display.showWarning('Self-evolution requires a git repository with source code.');
2488
+ display.showSystemMessage('');
2489
+ display.showSystemMessage('Current directory: ' + this.workingDir);
2490
+ display.showSystemMessage('');
2491
+ display.showSystemMessage('Requirements:');
2492
+ display.showSystemMessage(' • Must be a git repository (.git folder)');
2493
+ display.showSystemMessage(' • Must have package.json or src/ directory');
2494
+ display.showSystemMessage('');
2495
+ display.showSystemMessage('Navigate to your project directory and try again.');
2496
+ return;
2497
+ }
2498
+ const repoName = getRepoName(this.workingDir);
2499
+ const isErosolar = isErosolarRepo(this.workingDir);
2500
+ if (subcommand === 'analyze') {
2501
+ display.showSystemMessage(theme.gradient.primary(`🔍 Analyzing ${repoName} Source Code...`));
2502
+ display.showSystemMessage('');
2503
+ const issues = analyzeSource(this.workingDir);
2504
+ const lines = [];
2505
+ if (issues.length === 0) {
2506
+ lines.push(theme.success('✅ No issues found! Source code looks clean.'));
2507
+ }
2508
+ else {
2509
+ const bySeverity = {
2510
+ critical: issues.filter(i => i.severity === 'critical'),
2511
+ high: issues.filter(i => i.severity === 'high'),
2512
+ medium: issues.filter(i => i.severity === 'medium'),
2513
+ low: issues.filter(i => i.severity === 'low'),
2514
+ };
2515
+ lines.push(`Found ${theme.bold(String(issues.length))} issues:`);
2516
+ lines.push('');
2517
+ if (bySeverity.critical.length > 0) {
2518
+ lines.push(theme.error(` 🔴 Critical: ${bySeverity.critical.length}`));
2519
+ }
2520
+ if (bySeverity.high.length > 0) {
2521
+ lines.push(theme.warning(` 🟠 High: ${bySeverity.high.length}`));
2522
+ }
2523
+ if (bySeverity.medium.length > 0) {
2524
+ lines.push(theme.info(` 🟡 Medium: ${bySeverity.medium.length}`));
2525
+ }
2526
+ if (bySeverity.low.length > 0) {
2527
+ lines.push(theme.dim(` ⚪ Low: ${bySeverity.low.length}`));
2528
+ }
2529
+ lines.push('');
2530
+ // Show top 10 issues
2531
+ lines.push(theme.bold('Top Issues:'));
2532
+ for (const issue of issues.slice(0, 10)) {
2533
+ const icon = issue.severity === 'critical' ? '🔴' :
2534
+ issue.severity === 'high' ? '🟠' :
2535
+ issue.severity === 'medium' ? '🟡' : '⚪';
2536
+ lines.push(` ${icon} ${issue.file}:${issue.line ?? '?'}`);
2537
+ lines.push(` ${theme.dim(issue.description.slice(0, 70))}`);
2538
+ lines.push(` ${theme.ui.muted(`Confidence: ${Math.round(issue.confidence * 100)}%`)}`);
2539
+ }
2540
+ if (issues.length > 10) {
2541
+ lines.push('');
2542
+ lines.push(theme.ui.muted(`... and ${issues.length - 10} more issues`));
2543
+ }
2544
+ }
2545
+ display.showSystemMessage(lines.join('\n'));
2546
+ return;
2547
+ }
2548
+ if (subcommand === 'start') {
2549
+ display.showSystemMessage(theme.gradient.primary('🧬 Starting Self-Evolution Mode'));
2550
+ display.showSystemMessage('');
2551
+ display.showSystemMessage(theme.bold('Safety Features:'));
2552
+ display.showSystemMessage(' • Git checkpoint created before starting');
2553
+ display.showSystemMessage(' • Each change validated with build + tests');
2554
+ display.showSystemMessage(' • Auto-rollback on failures');
2555
+ display.showSystemMessage(' • Auto-relaunch with improved code');
2556
+ display.showSystemMessage(' • Press Ctrl+C to stop gracefully');
2557
+ display.showSystemMessage('');
2558
+ try {
2559
+ const result = await runSelfEvolution(this.workingDir, {
2560
+ maxIterations: 50,
2561
+ minConfidence: 0.8,
2562
+ runTests: true,
2563
+ autoRelaunch: true,
2564
+ }, {
2565
+ onStart: () => {
2566
+ display.showInfo('Evolution started. Creating checkpoint...');
2567
+ },
2568
+ onIteration: (iteration, issues) => {
2569
+ display.showSystemMessage(`\n[Iteration ${iteration}] Found ${issues.length} high-confidence issues`);
2570
+ },
2571
+ onFix: (issue, success) => {
2572
+ if (success) {
2573
+ display.showSuccess(`Fixed: ${issue.description.slice(0, 50)}`);
2574
+ }
2575
+ else {
2576
+ display.showWarning(`Failed: ${issue.description.slice(0, 50)}`);
2577
+ }
2578
+ },
2579
+ onRelaunch: () => {
2580
+ display.showSystemMessage('');
2581
+ display.showSystemMessage(theme.gradient.primary('🔄 Relaunching with improved code...'));
2582
+ },
2583
+ onComplete: (result) => {
2584
+ display.showSystemMessage('');
2585
+ display.showSuccess(`Evolution complete! Fixed ${result.issuesFixed} issues.`);
2586
+ },
2587
+ onError: (error) => {
2588
+ display.showError(`Evolution error: ${error}`);
2589
+ },
2590
+ });
2591
+ const lines = [];
2592
+ lines.push('');
2593
+ lines.push(theme.bold('Evolution Result:'));
2594
+ lines.push(` Success: ${result.success ? theme.success('Yes') : theme.error('No')}`);
2595
+ lines.push(` Iterations: ${result.iteration}`);
2596
+ lines.push(` Issues Found: ${result.issuesFound}`);
2597
+ lines.push(` Issues Fixed: ${result.issuesFixed}`);
2598
+ if (result.error) {
2599
+ lines.push(` Error: ${theme.error(result.error)}`);
2600
+ }
2601
+ lines.push(` Next Action: ${result.nextAction}`);
2602
+ display.showSystemMessage(lines.join('\n'));
2603
+ }
2604
+ catch (error) {
2605
+ display.showError(`Evolution failed: ${error instanceof Error ? error.message : String(error)}`);
2606
+ }
2607
+ return;
2608
+ }
2609
+ if (subcommand === 'stop') {
2610
+ stopEvolution();
2611
+ display.showInfo('Requested stop of evolution...');
2612
+ return;
2613
+ }
2614
+ if (subcommand === 'rollback') {
2615
+ const result = emergencyEvolutionRollback(this.workingDir);
2616
+ if (result.success) {
2617
+ display.showSuccess(result.message);
2618
+ }
2619
+ else {
2620
+ display.showError(result.message);
2621
+ }
2622
+ return;
2623
+ }
2624
+ if (subcommand === 'status') {
2625
+ const status = getEvolutionStatus(this.workingDir);
2626
+ display.showSystemMessage(status);
2627
+ return;
2628
+ }
2629
+ if (subcommand === 'learn') {
2630
+ display.showSystemMessage(theme.gradient.primary(`📚 Learning from ${repoName} Source Code...`));
2631
+ display.showSystemMessage('');
2632
+ const patterns = learnSourcePatterns(this.workingDir);
2633
+ const lines = [];
2634
+ if (patterns.length === 0) {
2635
+ lines.push(theme.warning('No patterns could be extracted.'));
2636
+ }
2637
+ else {
2638
+ lines.push(`Learned ${theme.bold(String(patterns.length))} patterns from source code:`);
2639
+ lines.push('');
2640
+ const byCategory = {
2641
+ 'tool-implementation': patterns.filter(p => p.category === 'tool-implementation'),
2642
+ 'error-handling': patterns.filter(p => p.category === 'error-handling'),
2643
+ 'type-pattern': patterns.filter(p => p.category === 'type-pattern'),
2644
+ 'api-design': patterns.filter(p => p.category === 'api-design'),
2645
+ };
2646
+ for (const [category, catPatterns] of Object.entries(byCategory)) {
2647
+ if (catPatterns.length > 0) {
2648
+ const icon = category === 'tool-implementation' ? '🔧' :
2649
+ category === 'error-handling' ? '⚠️' :
2650
+ category === 'type-pattern' ? '📝' : '🏗️';
2651
+ lines.push(`${icon} ${theme.bold(category)}: ${catPatterns.length} patterns`);
2652
+ for (const pattern of catPatterns.slice(0, 3)) {
2653
+ lines.push(` • ${pattern.description}`);
2654
+ lines.push(` ${theme.dim(`Source: ${pattern.sourceFile}`)}`);
2655
+ }
2656
+ if (catPatterns.length > 3) {
2657
+ lines.push(` ${theme.ui.muted(`... and ${catPatterns.length - 3} more`)}`);
2658
+ }
2659
+ lines.push('');
2660
+ }
2661
+ }
2662
+ lines.push(theme.success('✅ Patterns saved to ~/.erosolar/source-patterns.json'));
2663
+ lines.push('');
2664
+ lines.push('These patterns help the system understand optimal code structures');
2665
+ lines.push('and can be used to guide future code generation.');
2666
+ }
2667
+ display.showSystemMessage(lines.join('\n'));
2668
+ return;
2669
+ }
2670
+ if (subcommand === 'fix') {
2671
+ display.showSystemMessage(theme.gradient.primary('🔧 Generating Fixes for Source Issues...'));
2672
+ display.showSystemMessage('');
2673
+ const issues = analyzeSource(this.workingDir);
2674
+ const highConfidence = issues.filter(i => i.confidence >= 0.7);
2675
+ if (highConfidence.length === 0) {
2676
+ display.showInfo('No high-confidence issues found that need fixing.');
2677
+ return;
2678
+ }
2679
+ const lines = [];
2680
+ lines.push(`Found ${highConfidence.length} issues. Generating fixes...`);
2681
+ lines.push('');
2682
+ let fixCount = 0;
2683
+ for (const issue of highConfidence.slice(0, 5)) {
2684
+ const fix = generateFix(issue, this.workingDir);
2685
+ if (fix) {
2686
+ fixCount++;
2687
+ lines.push(`${theme.bold(`Fix ${fixCount}:`)} ${issue.file}:${issue.line}`);
2688
+ lines.push(` Issue: ${issue.description.slice(0, 60)}`);
2689
+ lines.push(` Fix: ${fix.explanation}`);
2690
+ lines.push(` Confidence: ${Math.round(fix.confidence * 100)}%`);
2691
+ lines.push(` ${fix.requiresManualReview ? theme.warning('⚠️ Requires review') : theme.success('✅ Auto-applicable')}`);
2692
+ lines.push('');
2693
+ }
2694
+ }
2695
+ if (fixCount === 0) {
2696
+ lines.push(theme.warning('No automatic fixes could be generated for these issues.'));
2697
+ }
2698
+ else {
2699
+ lines.push(`Generated ${fixCount} fix suggestions.`);
2700
+ lines.push('');
2701
+ lines.push(`Run ${theme.bold('/evolve start')} to apply fixes automatically with safety checks.`);
2702
+ }
2703
+ display.showSystemMessage(lines.join('\n'));
2704
+ return;
2705
+ }
2706
+ // ========== MODULAR / TOKEN OPTIMIZATION COMMANDS ==========
2707
+ if (subcommand === 'tokens') {
2708
+ display.showSystemMessage(theme.gradient.primary('🔍 Analyzing Token Usage...'));
2709
+ display.showSystemMessage('');
2710
+ const analysis = analyzeTokenUsage(this.workingDir);
2711
+ const lines = [];
2712
+ lines.push(`Total Tokens: ${theme.bold(analysis.totalTokens.toLocaleString())}`);
2713
+ lines.push('');
2714
+ lines.push(theme.bold('By Category:'));
2715
+ for (const [category, tokens] of Object.entries(analysis.byCategory)) {
2716
+ const pct = ((tokens / analysis.totalTokens) * 100).toFixed(1);
2717
+ const bar = '█'.repeat(Math.floor(Number(pct) / 5)) + '░'.repeat(20 - Math.floor(Number(pct) / 5));
2718
+ lines.push(` ${category.padEnd(15)} ${bar} ${tokens.toLocaleString().padStart(8)} (${pct}%)`);
2719
+ }
2720
+ lines.push('');
2721
+ lines.push(theme.bold('Optimization Opportunities:'));
2722
+ for (const opp of analysis.optimizationOpportunities.slice(0, 10)) {
2723
+ lines.push(` ${opp.autoFixable ? '✅' : '⚠️'} ${opp.target}`);
2724
+ lines.push(` Save: ${opp.savings} tokens (${opp.savingsPercent}%)`);
2725
+ lines.push(` ${theme.dim(opp.strategy)}`);
2726
+ }
2727
+ display.showSystemMessage(lines.join('\n'));
2728
+ return;
2729
+ }
2730
+ if (subcommand === 'targets') {
2731
+ const targets = discoverModularTargets(this.workingDir);
2732
+ const lines = [];
2733
+ lines.push(theme.gradient.primary('🎯 Modular Targets'));
2734
+ lines.push('');
2735
+ lines.push(`Found ${theme.bold(String(targets.length))} targets`);
2736
+ lines.push('');
2737
+ const byType = {};
2738
+ for (const target of targets) {
2739
+ if (!byType[target.type])
2740
+ byType[target.type] = [];
2741
+ byType[target.type].push(target);
2742
+ }
2743
+ for (const [type, typeTargets] of Object.entries(byType)) {
2744
+ lines.push(theme.bold(`${type} (${typeTargets.length}):`));
2745
+ for (const target of typeTargets.slice(0, 5)) {
2746
+ const issueCount = target.issues.length;
2747
+ const icon = issueCount === 0 ? '✅' : issueCount < 3 ? '⚠️' : '🔴';
2748
+ lines.push(` ${icon} ${target.name} (${target.tokenCount} tokens)`);
2749
+ if (target.issues.length > 0) {
2750
+ lines.push(` ${theme.dim(target.issues[0]?.description ?? '')}`);
2751
+ }
2752
+ }
2753
+ if (typeTargets.length > 5) {
2754
+ lines.push(` ${theme.dim(`... and ${typeTargets.length - 5} more`)}`);
2755
+ }
2756
+ lines.push('');
2757
+ }
2758
+ display.showSystemMessage(lines.join('\n'));
2759
+ return;
2760
+ }
2761
+ if (subcommand === 'optimize') {
2762
+ const optimizations = generateContextOptimizations(this.workingDir);
2763
+ const lines = [];
2764
+ lines.push(theme.gradient.primary('⚡ Context Optimization Strategies'));
2765
+ lines.push('');
2766
+ const totalSavings = optimizations.reduce((sum, o) => sum + o.tokensSaved, 0);
2767
+ lines.push(`Total potential savings: ${theme.success(totalSavings.toLocaleString())} tokens`);
2768
+ lines.push('');
2769
+ for (const opt of optimizations) {
2770
+ const icon = opt.impact === 'high' ? '🔴' : opt.impact === 'medium' ? '🟡' : '⚪';
2771
+ lines.push(`${icon} ${theme.bold(opt.strategy)}`);
2772
+ lines.push(` ${opt.description}`);
2773
+ lines.push(` Savings: ${theme.success(opt.tokensSaved.toLocaleString())} tokens`);
2774
+ lines.push(` ${theme.dim(opt.implementation)}`);
2775
+ lines.push('');
2776
+ }
2777
+ display.showSystemMessage(lines.join('\n'));
2778
+ return;
2779
+ }
2780
+ if (subcommand === 'guidelines') {
2781
+ const action = args[1]?.toLowerCase();
2782
+ if (action === 'add') {
2783
+ display.showInfo('Use: /evolve guidelines add <id> <category> <rule>');
2784
+ return;
2785
+ }
2786
+ if (action === 'delete' && args[2]) {
2787
+ const result = deleteGuideline(args[2]);
2788
+ if (result.success) {
2789
+ display.showSuccess(`Deleted guideline: ${args[2]}`);
2790
+ }
2791
+ else {
2792
+ display.showError(result.error ?? 'Failed to delete');
2793
+ }
2794
+ return;
2795
+ }
2796
+ const guidelines = getGuidelines();
2797
+ const lines = [];
2798
+ lines.push(theme.gradient.primary('📋 Active Guidelines'));
2799
+ lines.push('');
2800
+ for (const g of guidelines) {
2801
+ const icon = g.severity === 'must' ? '🔴' : g.severity === 'should' ? '🟡' : '⚪';
2802
+ lines.push(`${icon} [${g.category}] ${theme.bold(g.id)}`);
2803
+ lines.push(` ${g.rule}`);
2804
+ lines.push(` ${theme.dim(g.rationale)}`);
2805
+ lines.push('');
2806
+ }
2807
+ display.showSystemMessage(lines.join('\n'));
2808
+ return;
2809
+ }
2810
+ if (subcommand === 'actions') {
2811
+ const actions = getPendingActions();
2812
+ const lines = [];
2813
+ lines.push(theme.gradient.primary('📝 Pending Actions'));
2814
+ lines.push('');
2815
+ if (actions.length === 0) {
2816
+ lines.push(theme.dim('No pending actions'));
2817
+ }
2818
+ else {
2819
+ for (let i = 0; i < actions.length; i++) {
2820
+ const action = actions[i];
2821
+ lines.push(`${i + 1}. [${action.type}] ${action.target.name}`);
2822
+ lines.push(` Impact: ${action.tokenImpact > 0 ? '+' : ''}${action.tokenImpact} tokens`);
2823
+ lines.push(` ${theme.dim(action.changes.slice(0, 60))}`);
2824
+ lines.push('');
2825
+ }
2826
+ lines.push('Run /evolve execute <number> to apply an action');
2827
+ }
2828
+ display.showSystemMessage(lines.join('\n'));
2829
+ return;
2830
+ }
2831
+ if (subcommand === 'execute') {
2832
+ const actionIndex = parseInt(args[1] ?? '', 10) - 1;
2833
+ const result = executeModularAction(actionIndex, this.workingDir);
2834
+ if (result.success) {
2835
+ display.showSuccess('Action executed successfully');
2836
+ }
2837
+ else {
2838
+ display.showError(result.error ?? 'Failed to execute');
2839
+ }
2840
+ return;
2841
+ }
2842
+ // Default: show combined status
2843
+ const evolveStatus = getEvolutionStatus(this.workingDir);
2844
+ const modularStatus = getModularStatusDisplay(this.workingDir);
2845
+ display.showSystemMessage(evolveStatus);
2846
+ display.showSystemMessage('');
2847
+ display.showSystemMessage(modularStatus);
2848
+ }
2849
+ /**
2850
+ * Handle /modular command - redirects to /evolve (merged functionality)
2851
+ */
2852
+ async handleModularCommand(input) {
2853
+ // Redirect /modular to /evolve with the same arguments
2854
+ const evolveInput = input.replace(/^\/(?:modular|a0)\s*/i, '/evolve ');
2855
+ display.showInfo('Note: /modular is now part of /evolve. Use /evolve tokens, /evolve targets, etc.');
2856
+ await this.handleEvolveCommand(evolveInput);
2857
+ }
2858
+ /**
2859
+ * Handle /test command for intelligent test flows
2860
+ */
2861
+ async handleTestCommand(input) {
2862
+ const args = input.split(/\s+/).slice(1);
2863
+ const subcommand = args[0]?.toLowerCase();
2864
+ if (subcommand === 'status' || !subcommand) {
2865
+ const status = getTestFlowStatus(this.workingDir);
2866
+ display.showSystemMessage(status);
2867
+ return;
2868
+ }
2869
+ if (subcommand === 'generate') {
2870
+ const targetPath = args[1];
2871
+ if (!targetPath) {
2872
+ display.showWarning('Usage: /test generate <file-path>');
2873
+ return;
2874
+ }
2875
+ display.showSystemMessage(theme.gradient.primary(`🧪 Generating Test Flows for ${targetPath}...`));
2876
+ display.showSystemMessage('');
2877
+ const flows = generateTestFlows(this.workingDir, targetPath);
2878
+ saveTestFlows(flows);
2879
+ const lines = [];
2880
+ lines.push(`Generated ${theme.bold(String(flows.length))} test flows`);
2881
+ lines.push('');
2882
+ const byCategory = {};
2883
+ for (const flow of flows) {
2884
+ byCategory[flow.category] = (byCategory[flow.category] || 0) + 1;
2885
+ }
2886
+ for (const [category, count] of Object.entries(byCategory)) {
2887
+ lines.push(` ${category}: ${count}`);
2888
+ }
2889
+ lines.push('');
2890
+ lines.push(theme.bold('Generated flows:'));
2891
+ for (const flow of flows.slice(0, 10)) {
2892
+ const icon = flow.complexity === 'extreme' ? '🔴' :
2893
+ flow.complexity === 'complex' ? '🟠' :
2894
+ flow.complexity === 'moderate' ? '🟡' : '⚪';
2895
+ lines.push(` ${icon} ${flow.name}`);
2896
+ lines.push(` ${theme.dim(flow.description.slice(0, 60))}`);
2897
+ }
2898
+ if (flows.length > 10) {
2899
+ lines.push(` ${theme.dim(`... and ${flows.length - 10} more`)}`);
2900
+ }
2901
+ lines.push('');
2902
+ lines.push(`Saved to ~/.erosolar/test-flows/`);
2903
+ display.showSystemMessage(lines.join('\n'));
2904
+ return;
2905
+ }
2906
+ if (subcommand === 'bugs') {
2907
+ display.showSystemMessage(theme.gradient.primary('🐛 Detecting Potential Bugs...'));
2908
+ display.showSystemMessage('');
2909
+ const bugs = detectBugs(this.workingDir);
2910
+ saveBugReports(bugs);
2911
+ const lines = [];
2912
+ lines.push(`Found ${theme.bold(String(bugs.length))} potential issues`);
2913
+ lines.push('');
2914
+ const bySeverity = {};
2915
+ for (const bug of bugs) {
2916
+ bySeverity[bug.severity] = (bySeverity[bug.severity] || 0) + 1;
2917
+ }
2918
+ if (bySeverity['critical'])
2919
+ lines.push(` 🔴 Critical: ${bySeverity['critical']}`);
2920
+ if (bySeverity['high'])
2921
+ lines.push(` 🟠 High: ${bySeverity['high']}`);
2922
+ if (bySeverity['medium'])
2923
+ lines.push(` 🟡 Medium: ${bySeverity['medium']}`);
2924
+ if (bySeverity['low'])
2925
+ lines.push(` ⚪ Low: ${bySeverity['low']}`);
2926
+ lines.push('');
2927
+ lines.push(theme.bold('Top Issues:'));
2928
+ for (const bug of bugs.slice(0, 10)) {
2929
+ const icon = bug.severity === 'critical' ? '🔴' :
2930
+ bug.severity === 'high' ? '🟠' :
2931
+ bug.severity === 'medium' ? '🟡' : '⚪';
2932
+ lines.push(` ${icon} ${bug.title}`);
2933
+ lines.push(` ${bug.file}:${bug.line ?? '?'}`);
2934
+ lines.push(` ${theme.dim(bug.description.slice(0, 50))}`);
2935
+ if (bug.suggestedFix) {
2936
+ lines.push(` ${theme.success('Fix:')} ${bug.suggestedFix.slice(0, 50)}`);
2937
+ }
2938
+ lines.push('');
2939
+ }
2940
+ display.showSystemMessage(lines.join('\n'));
2941
+ return;
2942
+ }
2943
+ if (subcommand === 'ui') {
2944
+ display.showSystemMessage(theme.gradient.primary('🎨 Detecting UI Updates...'));
2945
+ display.showSystemMessage('');
2946
+ const updates = detectUIUpdates(this.workingDir);
2947
+ saveUIUpdates(updates);
2948
+ const lines = [];
2949
+ lines.push(`Found ${theme.bold(String(updates.length))} UI improvements`);
2950
+ lines.push('');
2951
+ const byType = {};
2952
+ for (const update of updates) {
2953
+ byType[update.type] = (byType[update.type] || 0) + 1;
2954
+ }
2955
+ for (const [type, count] of Object.entries(byType)) {
2956
+ const icon = type === 'accessibility' ? '♿' :
2957
+ type === 'performance' ? '⚡' :
2958
+ type === 'style' ? '🎨' : '🔧';
2959
+ lines.push(` ${icon} ${type}: ${count}`);
2960
+ }
2961
+ lines.push('');
2962
+ lines.push(theme.bold('Updates:'));
2963
+ for (const update of updates.slice(0, 10)) {
2964
+ lines.push(` 📦 ${update.component} [${update.type}]`);
2965
+ lines.push(` ${theme.dim(update.description)}`);
2966
+ lines.push(` Before: ${theme.error(update.before.slice(0, 40))}`);
2967
+ lines.push(` After: ${theme.success(update.after.slice(0, 40))}`);
2968
+ lines.push('');
2969
+ }
2970
+ display.showSystemMessage(lines.join('\n'));
2971
+ return;
2972
+ }
2973
+ if (subcommand === 'edge') {
2974
+ display.showSystemMessage(theme.gradient.primary('🔬 Edge Case Analysis'));
2975
+ display.showSystemMessage('');
2976
+ const bugs = detectBugs(this.workingDir);
2977
+ const edgeCases = bugs.filter(b => b.type === 'edge-case');
2978
+ const lines = [];
2979
+ lines.push(`Found ${theme.bold(String(edgeCases.length))} edge case issues`);
2980
+ lines.push('');
2981
+ for (const bug of edgeCases.slice(0, 15)) {
2982
+ const icon = bug.severity === 'critical' ? '🔴' :
2983
+ bug.severity === 'high' ? '🟠' : '🟡';
2984
+ lines.push(` ${icon} ${bug.title}`);
2985
+ lines.push(` ${bug.file}:${bug.line ?? '?'}`);
2986
+ if (bug.suggestedFix) {
2987
+ lines.push(` ${theme.success('Fix:')} ${bug.suggestedFix}`);
2988
+ }
2989
+ lines.push('');
2990
+ }
2991
+ display.showSystemMessage(lines.join('\n'));
2992
+ return;
2993
+ }
2994
+ // Default: show status
2995
+ const status = getTestFlowStatus(this.workingDir);
2996
+ display.showSystemMessage(status);
2997
+ }
1775
2998
  showPluginStatus() {
1776
2999
  const available = listAvailablePlugins();
1777
3000
  const lines = [];
@@ -1956,6 +3179,277 @@ export class InteractiveShell {
1956
3179
  }
1957
3180
  this.setAutoContinueMode(value === 'on', 'command');
1958
3181
  }
3182
+ // ==================== Claude Code Style Commands ====================
3183
+ async handleRewindCommand(input) {
3184
+ const lines = [];
3185
+ lines.push(theme.bold('Rewind / Checkpoint System'));
3186
+ lines.push('');
3187
+ lines.push('Use checkpoints to restore previous states of your code and conversation.');
3188
+ lines.push('');
3189
+ lines.push(theme.secondary('Usage:'));
3190
+ lines.push(' /rewind Show available checkpoints');
3191
+ lines.push(' /rewind list List all checkpoints');
3192
+ lines.push(' /rewind <id> Rewind to specific checkpoint');
3193
+ lines.push(' /rewind code Rewind code only (keep conversation)');
3194
+ lines.push(' /rewind conv Rewind conversation only (keep code)');
3195
+ lines.push('');
3196
+ lines.push(theme.ui.muted('Tip: Press Esc+Esc for quick access to rewind menu'));
3197
+ display.showSystemMessage(lines.join('\n'));
3198
+ }
3199
+ handleMemoryCommand(input) {
3200
+ const lines = [];
3201
+ lines.push(theme.bold('Memory System (EROSOLAR.md)'));
3202
+ lines.push('');
3203
+ lines.push('Create EROSOLAR.md files to store persistent context and preferences.');
3204
+ lines.push('');
3205
+ lines.push(theme.secondary('Memory Locations:'));
3206
+ lines.push(` ~/.erosolar/EROSOLAR.md ${theme.ui.muted('User preferences (global)')}`);
3207
+ lines.push(` ./EROSOLAR.md ${theme.ui.muted('Project memory')}`);
3208
+ lines.push(` ./.erosolar/EROSOLAR.md ${theme.ui.muted('Project memory (alternative)')}`);
3209
+ lines.push('');
3210
+ lines.push(theme.secondary('Features:'));
3211
+ lines.push(' - Use @path/to/file in prompts to reference files');
3212
+ lines.push(' - Use # prefix to quickly add notes to project memory');
3213
+ lines.push(' - Import other files with @./relative/path syntax');
3214
+ lines.push('');
3215
+ lines.push(theme.ui.muted('Tip: Create EROSOLAR.md with project coding standards for better results'));
3216
+ display.showSystemMessage(lines.join('\n'));
3217
+ }
3218
+ handleVimCommand() {
3219
+ const lines = [];
3220
+ lines.push(theme.bold('Vim Mode'));
3221
+ lines.push('');
3222
+ lines.push('Enable vim-style editing in the input area.');
3223
+ lines.push('');
3224
+ lines.push(theme.secondary('Basic Commands:'));
3225
+ lines.push(' h/j/k/l Move left/down/up/right');
3226
+ lines.push(' w/b Word forward/backward');
3227
+ lines.push(' 0/$ Line start/end');
3228
+ lines.push(' i/a Insert before/after cursor');
3229
+ lines.push(' I/A Insert at line start/end');
3230
+ lines.push(' o/O Open line below/above');
3231
+ lines.push(' x Delete character');
3232
+ lines.push(' dd Delete line');
3233
+ lines.push(' yy Yank (copy) line');
3234
+ lines.push(' p Paste');
3235
+ lines.push(' Escape Return to normal mode');
3236
+ lines.push('');
3237
+ lines.push(theme.ui.muted('Vim mode is experimental. Toggle with /vim'));
3238
+ display.showSystemMessage(lines.join('\n'));
3239
+ }
3240
+ handleOutputStyleCommand(input) {
3241
+ const lines = [];
3242
+ lines.push(theme.bold('Output Styles'));
3243
+ lines.push('');
3244
+ lines.push('Change how the AI responds to your requests.');
3245
+ lines.push('');
3246
+ lines.push(theme.secondary('Built-in Styles:'));
3247
+ lines.push(` default ${theme.ui.muted('Standard efficient coding mode')}`);
3248
+ lines.push(` explanatory ${theme.ui.muted('Educational with detailed explanations')}`);
3249
+ lines.push(` learning ${theme.ui.muted('Collaborative with TODO(human) markers')}`);
3250
+ lines.push(` concise ${theme.ui.muted('Minimal output, code-focused only')}`);
3251
+ lines.push('');
3252
+ lines.push(theme.secondary('Custom Styles:'));
3253
+ lines.push(' Create custom styles in ~/.erosolar/output-styles/');
3254
+ lines.push(' or .erosolar/output-styles/ for project-specific styles.');
3255
+ lines.push('');
3256
+ lines.push(theme.secondary('Usage:'));
3257
+ lines.push(' /output-style <name> Switch to a style');
3258
+ display.showSystemMessage(lines.join('\n'));
3259
+ }
3260
+ handleCostCommand() {
3261
+ const lines = [];
3262
+ lines.push(theme.bold('Cost & Token Usage'));
3263
+ lines.push('');
3264
+ // This will be populated with actual data from costTracker
3265
+ lines.push(theme.secondary('Session Statistics:'));
3266
+ lines.push(' Input tokens: (tracking enabled)');
3267
+ lines.push(' Output tokens: (tracking enabled)');
3268
+ lines.push(' Estimated cost: $0.00');
3269
+ lines.push('');
3270
+ lines.push(theme.ui.muted('Token usage is tracked automatically during the session.'));
3271
+ display.showSystemMessage(lines.join('\n'));
3272
+ }
3273
+ handleUsageCommand() {
3274
+ const percentage = this.latestTokenUsage.limit && this.latestTokenUsage.used
3275
+ ? Math.round((this.latestTokenUsage.used / this.latestTokenUsage.limit) * 100)
3276
+ : 0;
3277
+ const lines = [];
3278
+ lines.push(theme.bold('Context Usage'));
3279
+ lines.push('');
3280
+ lines.push(theme.secondary('Current Context:'));
3281
+ lines.push(` Used: ${this.latestTokenUsage.used?.toLocaleString() ?? '?'} tokens`);
3282
+ lines.push(` Limit: ${this.latestTokenUsage.limit?.toLocaleString() ?? '?'} tokens`);
3283
+ lines.push(` Usage: ${percentage}%`);
3284
+ lines.push('');
3285
+ if (percentage > 80) {
3286
+ lines.push(theme.warning('Context is getting full. Consider using /compact.'));
3287
+ }
3288
+ else if (percentage > 60) {
3289
+ lines.push(theme.secondary('Context usage is moderate.'));
3290
+ }
3291
+ else {
3292
+ lines.push(theme.success('Plenty of context available.'));
3293
+ }
3294
+ display.showSystemMessage(lines.join('\n'));
3295
+ }
3296
+ async handleUpdateCommand() {
3297
+ display.showInfo('Checking for updates...');
3298
+ const lines = [];
3299
+ lines.push(theme.bold('Update Check'));
3300
+ lines.push('');
3301
+ lines.push(`Current version: ${this.version ?? 'unknown'}`);
3302
+ lines.push('');
3303
+ lines.push(theme.secondary('To update:'));
3304
+ lines.push(' npm install -g erosolar-cli@latest');
3305
+ lines.push(' or: npm update erosolar-cli');
3306
+ lines.push('');
3307
+ lines.push(theme.ui.muted('Auto-updates will be checked periodically.'));
3308
+ display.showSystemMessage(lines.join('\n'));
3309
+ }
3310
+ handleClearCommand() {
3311
+ if (this.agent) {
3312
+ this.agent.clearHistory();
3313
+ this.cachedHistory = this.agent.getHistory();
3314
+ }
3315
+ display.clear();
3316
+ clearAutosaveSnapshot(this.profile);
3317
+ display.showInfo('Conversation cleared. Starting fresh.');
3318
+ this.terminalInput.render();
3319
+ }
3320
+ async handleResumeCommand(input) {
3321
+ const tokens = input.split(/\s+/).slice(1);
3322
+ const sessionId = tokens[0];
3323
+ if (sessionId) {
3324
+ await this.loadSessionCommand(sessionId);
3325
+ }
3326
+ else {
3327
+ // Show session list and auto-select the most recent
3328
+ const sessions = listSessions(this.profile);
3329
+ if (sessions.length > 0) {
3330
+ display.showInfo('Resuming most recent session...');
3331
+ await this.loadSessionCommand('1');
3332
+ }
3333
+ else {
3334
+ display.showWarning('No previous sessions found. Use /sessions to manage sessions.');
3335
+ }
3336
+ }
3337
+ }
3338
+ handleExportCommand(input) {
3339
+ const lines = [];
3340
+ lines.push(theme.bold('Export Conversation'));
3341
+ lines.push('');
3342
+ lines.push('Export your conversation history for sharing or documentation.');
3343
+ lines.push('');
3344
+ lines.push(theme.secondary('Usage:'));
3345
+ lines.push(' /export Export to default file');
3346
+ lines.push(' /export <filename> Export to specific file');
3347
+ lines.push('');
3348
+ lines.push(theme.ui.muted('Exports include conversation history and tool results.'));
3349
+ display.showSystemMessage(lines.join('\n'));
3350
+ }
3351
+ async handleReviewCommand() {
3352
+ if (this.isProcessing) {
3353
+ display.showWarning('Wait for the current operation to finish.');
3354
+ return;
3355
+ }
3356
+ display.showInfo('Triggering code review of pending changes...');
3357
+ await this.processRequest('Please review all the code changes we made in this session. Look for bugs, security issues, and improvements.');
3358
+ }
3359
+ async handleSecurityReviewCommand() {
3360
+ if (this.isProcessing) {
3361
+ display.showWarning('Wait for the current operation to finish.');
3362
+ return;
3363
+ }
3364
+ display.showInfo('Running comprehensive security review...');
3365
+ await this.processRequest('Please perform a comprehensive security review of the codebase. Check for OWASP top 10 vulnerabilities, insecure patterns, and potential attack vectors.');
3366
+ }
3367
+ handleBugCommand() {
3368
+ const lines = [];
3369
+ lines.push(theme.bold('Report an Issue'));
3370
+ lines.push('');
3371
+ lines.push('Found a bug or have a suggestion?');
3372
+ lines.push('');
3373
+ lines.push(theme.secondary('Report issues at:'));
3374
+ lines.push(' https://github.com/erosolar/erosolar-cli/issues');
3375
+ lines.push('');
3376
+ lines.push(theme.secondary('Include:'));
3377
+ lines.push(' - Steps to reproduce');
3378
+ lines.push(' - Expected vs actual behavior');
3379
+ lines.push(' - Version info (erosolar --version)');
3380
+ display.showSystemMessage(lines.join('\n'));
3381
+ }
3382
+ handleTerminalSetupCommand() {
3383
+ const lines = [];
3384
+ lines.push(theme.bold('Terminal Setup'));
3385
+ lines.push('');
3386
+ lines.push('Configure terminal keybindings for better experience.');
3387
+ lines.push('');
3388
+ lines.push(theme.secondary('Recommended Settings:'));
3389
+ lines.push('');
3390
+ lines.push(theme.bold(' iTerm2:'));
3391
+ lines.push(' Preferences > Keys > Key Bindings');
3392
+ lines.push(' Add: Shift+Enter → Send Escape Sequence: [13;2u');
3393
+ lines.push('');
3394
+ lines.push(theme.bold(' VS Code Terminal:'));
3395
+ lines.push(' Already supports Shift+Enter natively');
3396
+ lines.push('');
3397
+ lines.push(theme.bold(' Kitty/Wezterm:'));
3398
+ lines.push(' Modern terminals support extended keys automatically');
3399
+ lines.push('');
3400
+ lines.push(theme.ui.muted('Shift+Enter enables multi-line input.'));
3401
+ display.showSystemMessage(lines.join('\n'));
3402
+ }
3403
+ handlePermissionsCommand() {
3404
+ const lines = [];
3405
+ lines.push(theme.bold('Tool Permissions'));
3406
+ lines.push('');
3407
+ lines.push('Configure which tools require confirmation before execution.');
3408
+ lines.push('');
3409
+ lines.push(theme.secondary('Current Mode:'));
3410
+ const editMode = this.editGuardMode;
3411
+ lines.push(` Edit Guard: ${editMode === 'ask-permission' ? 'Ask before edits' : editMode === 'plan' ? 'Plan mode' : 'Auto-accept'}`);
3412
+ lines.push('');
3413
+ lines.push(theme.secondary('Toggle with:'));
3414
+ lines.push(' Shift+Tab Cycle through modes');
3415
+ lines.push(' Option+E Toggle edit permission');
3416
+ lines.push('');
3417
+ lines.push(theme.ui.muted('Use /tools to manage which tool suites are enabled.'));
3418
+ display.showSystemMessage(lines.join('\n'));
3419
+ }
3420
+ handleInitCommand() {
3421
+ const lines = [];
3422
+ lines.push(theme.bold('Initialize Project'));
3423
+ lines.push('');
3424
+ lines.push('Create EROSOLAR.md to configure project-specific settings.');
3425
+ lines.push('');
3426
+ lines.push(theme.secondary('This will create:'));
3427
+ lines.push(` ${this.workingDir}/EROSOLAR.md`);
3428
+ lines.push('');
3429
+ lines.push(theme.secondary('Template includes:'));
3430
+ lines.push(' - Project description');
3431
+ lines.push(' - Coding standards');
3432
+ lines.push(' - File conventions');
3433
+ lines.push(' - Testing requirements');
3434
+ lines.push('');
3435
+ lines.push(theme.ui.muted('Use /init confirm to create the file.'));
3436
+ display.showSystemMessage(lines.join('\n'));
3437
+ }
3438
+ async handleCompactCommand() {
3439
+ if (this.isProcessing) {
3440
+ display.showWarning('Wait for the current operation to finish.');
3441
+ return;
3442
+ }
3443
+ display.showInfo('Compacting conversation context...');
3444
+ // Check if compaction is needed based on tracked usage
3445
+ const { used, limit } = this.latestTokenUsage;
3446
+ if (used && limit && used / limit < 0.5) {
3447
+ display.showInfo('Context usage is low. No compaction needed.');
3448
+ return;
3449
+ }
3450
+ 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.');
3451
+ }
3452
+ // ==================== End Claude Code Style Commands ====================
1959
3453
  updateActiveSession(summary, remember = false) {
1960
3454
  this.activeSessionId = summary?.id ?? null;
1961
3455
  this.activeSessionTitle = summary?.title ?? null;
@@ -2631,6 +4125,14 @@ export class InteractiveShell {
2631
4125
  // Keep the persistent input/control bar active as we transition into streaming.
2632
4126
  this.terminalInput.forceRender();
2633
4127
  const requestStartTime = Date.now(); // Alpha Zero 2 timing
4128
+ // Clear previous parallel agents and start fresh for new request
4129
+ const parallelManager = getParallelAgentManager();
4130
+ parallelManager.clear();
4131
+ parallelManager.startBatch();
4132
+ // AlphaZero: Track task for learning
4133
+ this.lastUserQuery = request;
4134
+ this.currentTaskType = classifyTaskType(request);
4135
+ this.currentToolCalls = [];
2634
4136
  this.uiAdapter.startProcessing('Working on your request');
2635
4137
  this.setProcessingStatus();
2636
4138
  let responseText = '';
@@ -2647,6 +4149,43 @@ export class InteractiveShell {
2647
4149
  if (!responseText?.trim()) {
2648
4150
  display.showWarning('The provider returned an empty response. Check your API key/provider selection or retry the prompt.');
2649
4151
  }
4152
+ // AlphaZero: Extract and track tool calls from response
4153
+ const toolsUsed = this.extractToolsFromResponse(responseText);
4154
+ this.currentToolCalls = toolsUsed.map(name => ({
4155
+ name,
4156
+ arguments: {},
4157
+ success: true, // Assume success if we got here
4158
+ duration: 0,
4159
+ }));
4160
+ // AlphaZero: Check for failure in response
4161
+ const failure = detectFailure(responseText, {
4162
+ toolCalls: this.currentToolCalls,
4163
+ userMessage: request,
4164
+ });
4165
+ if (failure) {
4166
+ this.lastFailure = failure;
4167
+ // Check if we have a recovery strategy
4168
+ const strategy = findRecoveryStrategy(failure);
4169
+ if (strategy) {
4170
+ display.showSystemMessage(`🔄 Found recovery strategy for this type of issue (success rate: ${Math.round(strategy.successRate * 100)}%)`);
4171
+ }
4172
+ }
4173
+ else {
4174
+ // Success - record the tool pattern for this task type
4175
+ if (this.currentToolCalls.length > 0) {
4176
+ const toolPattern = {
4177
+ taskType: this.currentTaskType,
4178
+ toolSequence: this.currentToolCalls.map(t => t.name),
4179
+ successRate: 1.0,
4180
+ avgDuration: elapsedMs,
4181
+ occurrences: 1,
4182
+ };
4183
+ addToolPattern(this.currentTaskType, toolPattern);
4184
+ }
4185
+ // Clear action history on success
4186
+ clearActionHistory();
4187
+ this.lastFailure = null;
4188
+ }
2650
4189
  }
2651
4190
  catch (error) {
2652
4191
  const handled = this.handleProviderError(error, () => this.processRequest(request));
@@ -2704,6 +4243,10 @@ export class InteractiveShell {
2704
4243
  this.uiUpdates.setMode('processing');
2705
4244
  this.terminalInput.setStreaming(true);
2706
4245
  const overallStartTime = Date.now();
4246
+ // Clear previous parallel agents and start fresh for continuous mode
4247
+ const parallelManager = getParallelAgentManager();
4248
+ parallelManager.clear();
4249
+ parallelManager.startBatch();
2707
4250
  // Initialize the task completion detector
2708
4251
  const completionDetector = getTaskCompletionDetector();
2709
4252
  completionDetector.reset();