@wundr.io/cli 1.0.1 → 1.0.2-dev.20260530174250.ef0ec927

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 (69) hide show
  1. package/bin/wundr.js +13 -5
  2. package/package.json +30 -9
  3. package/src/ai/ai-service.ts +6 -4
  4. package/src/ai/claude-client.ts +6 -2
  5. package/src/ai/conversation-manager.ts +12 -5
  6. package/src/cli.ts +42 -13
  7. package/src/commands/ai.ts +340 -64
  8. package/src/commands/alignment.ts +1212 -0
  9. package/src/commands/analyze-optimized.ts +371 -33
  10. package/src/commands/analyze.ts +8 -6
  11. package/src/commands/batch.ts +166 -26
  12. package/src/commands/chat.ts +20 -10
  13. package/src/commands/claude-init.ts +31 -27
  14. package/src/commands/claude-setup.ts +761 -81
  15. package/src/commands/computer-setup.ts +524 -12
  16. package/src/commands/create-command.ts +3 -3
  17. package/src/commands/create.ts +9 -6
  18. package/src/commands/dashboard.ts +11 -6
  19. package/src/commands/govern.ts +11 -6
  20. package/src/commands/governance.ts +1005 -0
  21. package/src/commands/guardian.ts +887 -0
  22. package/src/commands/init.ts +104 -11
  23. package/src/commands/orchestrator.ts +789 -0
  24. package/src/commands/performance-optimizer.ts +15 -10
  25. package/src/commands/plugins.ts +8 -5
  26. package/src/commands/project-update.ts +1156 -0
  27. package/src/commands/rag.ts +1011 -0
  28. package/src/commands/session.ts +631 -0
  29. package/src/commands/setup.ts +42 -344
  30. package/src/commands/test-init.ts +3 -2
  31. package/src/commands/test.ts +3 -2
  32. package/src/commands/watch.ts +21 -11
  33. package/src/commands/worktree.ts +1057 -0
  34. package/src/context/context-manager.ts +5 -2
  35. package/src/context/session-manager.ts +18 -7
  36. package/src/framework/command-interface.ts +520 -0
  37. package/src/framework/command-registry.ts +942 -0
  38. package/src/framework/completion-exporter.ts +383 -0
  39. package/src/framework/debug-logger.ts +519 -0
  40. package/src/framework/error-handler.ts +867 -0
  41. package/src/framework/help-generator.ts +540 -0
  42. package/src/framework/index.ts +169 -0
  43. package/src/framework/interactive-repl.ts +703 -0
  44. package/src/framework/output-formatter.ts +834 -0
  45. package/src/framework/progress-manager.ts +539 -0
  46. package/src/index.ts +3 -2
  47. package/src/interactive/interactive-mode.ts +14 -7
  48. package/src/lib/conflict-resolution.ts +818 -0
  49. package/src/lib/merge-strategy.ts +550 -0
  50. package/src/lib/safety-mechanisms.ts +451 -0
  51. package/src/lib/state-detection.ts +1030 -0
  52. package/src/nlp/command-mapper.ts +8 -3
  53. package/src/nlp/command-parser.ts +5 -2
  54. package/src/nlp/intent-parser.ts +23 -9
  55. package/src/plugins/plugin-manager.ts +50 -24
  56. package/src/tests/computer-setup-integration.test.ts +46 -15
  57. package/src/types/index.ts +1 -1
  58. package/src/types/modules.d.ts +425 -1
  59. package/src/utils/backup-rollback-manager.ts +19 -14
  60. package/src/utils/claude-config-installer.ts +119 -28
  61. package/src/utils/config-manager.ts +9 -6
  62. package/src/utils/error-handler.ts +3 -1
  63. package/src/utils/logger.ts +35 -12
  64. package/templates/batch/ci-cd.yaml +7 -7
  65. package/test-suites/api/health.spec.ts +20 -23
  66. package/test-suites/helpers/test-config.ts +14 -13
  67. package/test-suites/ui/accessibility.spec.ts +27 -22
  68. package/test-suites/ui/smoke.spec.ts +26 -21
  69. package/src/commands/computer-setup-commands.ts +0 -869
@@ -1,24 +1,55 @@
1
- import { Command } from 'commander';
2
- import inquirer from 'inquirer';
3
1
  import chalk from 'chalk';
4
- import { ConfigManager } from '../utils/config-manager';
5
- import { PluginManager } from '../plugins/plugin-manager';
2
+ import inquirer from 'inquirer';
3
+
6
4
  import { AIService } from '../ai/ai-service';
7
- import { logger } from '../utils/logger';
8
5
  import { errorHandler } from '../utils/error-handler';
9
- import { ChatSession } from '../types';
6
+ import { logger } from '../utils/logger';
7
+
8
+ import type { PluginManager } from '../plugins/plugin-manager';
9
+ import type { ChatSession } from '../types';
10
+ import type { ConfigManager } from '../utils/config-manager';
11
+ import type { Command } from 'commander';
12
+
13
+ /** Review result for a single file */
14
+ interface FileReviewResult {
15
+ file: string;
16
+ issues: Array<{ severity: string; description: string }>;
17
+ suggestions: string[];
18
+ score: number;
19
+ }
20
+
21
+ /** Refactoring plan from AI analysis */
22
+ interface RefactoringPlan {
23
+ description: string;
24
+ changes: Array<{ description: string; code?: string }>;
25
+ }
26
+
27
+ /** Optimization plan from AI analysis */
28
+ interface OptimizationPlan {
29
+ description: string;
30
+ changes: Array<{ description: string; code?: string }>;
31
+ optimizedCode: string;
32
+ }
33
+
34
+ /** Benchmark result metrics */
35
+ interface BenchmarkResult {
36
+ time: number;
37
+ memory: number;
38
+ }
10
39
 
11
40
  /**
12
41
  * AI commands for AI-powered development features
13
42
  */
14
43
  export class AICommands {
15
44
  private aiService: AIService;
45
+ private pluginManager: PluginManager;
16
46
 
17
47
  constructor(
18
48
  private program: Command,
19
49
  private configManager: ConfigManager,
20
- private _pluginManager: PluginManager
50
+ pluginManager: PluginManager
21
51
  ) {
52
+ this.pluginManager = pluginManager;
22
53
  this.aiService = new AIService(configManager);
23
54
  this.registerCommands();
24
55
  }
@@ -261,12 +292,7 @@ export class AICommands {
261
292
 
262
293
  const filesToReview =
263
294
  files.length > 0 ? files : await this.getChangedFiles();
264
- const reviewResults: Array<{
265
- file: string;
266
- issues: any;
267
- suggestions: any;
268
- score: any;
269
- }> = [];
295
+ const reviewResults: FileReviewResult[] = [];
270
296
 
271
297
  for (const file of filesToReview) {
272
298
  logger.debug(`Reviewing ${file}...`);
@@ -378,7 +404,7 @@ export class AICommands {
378
404
  );
379
405
 
380
406
  const code = await this.readFile(target);
381
- const _docs = await this.callAI('docs', {
407
+ const docs = await this.callAI('docs', {
382
408
  code,
383
409
  target,
384
410
  type: options.type,
@@ -391,7 +417,7 @@ export class AICommands {
391
417
  options.type,
392
418
  options.format
393
419
  );
394
- await this.saveGeneratedDocs(_docs, outputPath);
420
+ await this.saveGeneratedDocs(docs, outputPath);
395
421
 
396
422
  logger.success(`Documentation generated: ${outputPath}`);
397
423
  } catch (error) {
@@ -526,13 +552,13 @@ export class AICommands {
526
552
  logger.info(`Optimizing ${chalk.cyan(target)}...`);
527
553
 
528
554
  const code = await this.readFile(target);
529
- let beforeBenchmark = null;
555
+ let beforeBenchmark: BenchmarkResult | undefined;
530
556
 
531
557
  if (options.benchmarks) {
532
558
  beforeBenchmark = await this.runBenchmark(target);
533
559
  }
534
560
 
535
- const _optimization = await this.callAI('optimize', {
561
+ const optimization: OptimizationPlan = await this.callAI('optimize', {
536
562
  code,
537
563
  target,
538
564
  focus: options.focus,
@@ -548,9 +574,9 @@ export class AICommands {
548
574
  ]);
549
575
 
550
576
  if (apply) {
551
- await this.applyOptimization(target, _optimization);
577
+ await this.applyOptimization(target, optimization);
552
578
 
553
- if (options.benchmarks) {
579
+ if (options.benchmarks && beforeBenchmark) {
554
580
  const afterBenchmark = await this.runBenchmark(target);
555
581
  this.displayBenchmarkComparison(beforeBenchmark, afterBenchmark);
556
582
  }
@@ -783,29 +809,153 @@ export class AICommands {
783
809
  private async callAI(operation: string, params: any): Promise<any> {
784
810
  // Check if AI service is ready
785
811
  if (!this.aiService.isReady()) {
786
- throw new Error('AI service not configured. Run `wundr ai setup` first.');
812
+ throw new Error(
813
+ 'AI service not configured. Set ANTHROPIC_API_KEY or OPENAI_API_KEY, or run `wundr ai setup`.'
814
+ );
787
815
  }
788
816
 
789
817
  logger.debug(`Calling AI for operation: ${operation}`);
790
818
 
791
- // For now, return mock responses - these would be replaced with actual AI calls
819
+ const sessionId = `ai-cmd-${operation}-${Date.now()}`;
820
+
792
821
  switch (operation) {
793
- case 'generate':
794
- return `// Generated ${params.type} code\nfunction ${params.type}() {\n // Implementation here\n}`;
795
- case 'review':
796
- return { issues: [], suggestions: [], score: 95 };
797
- case 'refactor':
798
- return { description: 'Refactoring plan', changes: [] };
799
- case 'docs':
800
- return `# ${params.target} Documentation\n\nGenerated documentation...`;
801
- case 'test':
802
- return `// Generated tests\ndescribe('${params.target}', () => {\n // Tests here\n});`;
803
- case 'analyze':
804
- return { complexity: 'low', maintainability: 'high', suggestions: [] };
805
- case 'optimize':
806
- return { description: 'Optimization plan', changes: [] };
822
+ case 'generate': {
823
+ const prompt = [
824
+ `Generate ${params.type} code.`,
825
+ params.prompt ? `Requirements: ${params.prompt}` : '',
826
+ params.template ? `Use template style: ${params.template}` : '',
827
+ params.context ? `Context:\n${params.context}` : '',
828
+ 'Return only the code, no explanation.',
829
+ ]
830
+ .filter(Boolean)
831
+ .join('\n');
832
+ return this.aiService.sendMessage(sessionId, prompt);
833
+ }
834
+
835
+ case 'review': {
836
+ const prompt = [
837
+ `Review the following ${params.file} code for issues.`,
838
+ `Focus: ${params.focus || 'all'}. Minimum severity: ${params.severity || 'info'}.`,
839
+ 'Return a JSON object with this exact shape: {"issues":[{"severity":"string","description":"string"}],"suggestions":["string"],"score":number}',
840
+ `Code:\n${params.code}`,
841
+ ].join('\n');
842
+ const raw = await this.aiService.sendMessage(sessionId, prompt);
843
+ try {
844
+ const jsonMatch = raw.match(/\{[\s\S]*\}/);
845
+ return jsonMatch
846
+ ? JSON.parse(jsonMatch[0])
847
+ : { issues: [], suggestions: [], score: 0 };
848
+ } catch {
849
+ return { issues: [], suggestions: [], score: 0 };
850
+ }
851
+ }
852
+
853
+ case 'refactor': {
854
+ const prompt = [
855
+ `Create a refactoring plan for the following code in ${params.target}.`,
856
+ `Refactoring type: ${params.type || 'optimize'}. Scope: ${params.scope || 'function'}.`,
857
+ 'Return a JSON object with this exact shape: {"description":"string","changes":[{"description":"string","code":"string"}]}',
858
+ `Code:\n${params.code}`,
859
+ ].join('\n');
860
+ const raw = await this.aiService.sendMessage(sessionId, prompt);
861
+ try {
862
+ const jsonMatch = raw.match(/\{[\s\S]*\}/);
863
+ return jsonMatch
864
+ ? JSON.parse(jsonMatch[0])
865
+ : { description: '', changes: [] };
866
+ } catch {
867
+ return { description: '', changes: [] };
868
+ }
869
+ }
870
+
871
+ case 'docs': {
872
+ const prompt = [
873
+ `Generate ${params.type || 'api'} documentation in ${params.format || 'markdown'} format for ${params.target}.`,
874
+ params.includeExamples ? 'Include code examples.' : '',
875
+ `Code:\n${params.code}`,
876
+ ]
877
+ .filter(Boolean)
878
+ .join('\n');
879
+ return this.aiService.sendMessage(sessionId, prompt);
880
+ }
881
+
882
+ case 'test': {
883
+ const prompt = [
884
+ `Generate ${params.coverage || 'unit'} tests using ${params.framework || 'jest'} for ${params.target}.`,
885
+ params.mocks ? 'Include mock objects where appropriate.' : '',
886
+ 'Return only the test code, no explanation.',
887
+ `Code:\n${params.code}`,
888
+ ]
889
+ .filter(Boolean)
890
+ .join('\n');
891
+ return this.aiService.sendMessage(sessionId, prompt);
892
+ }
893
+
894
+ case 'analyze': {
895
+ const prompt = [
896
+ `Analyze the following code from ${params.target}.`,
897
+ `Aspect: ${params.aspect || 'all'}.`,
898
+ params.suggestions ? 'Include improvement suggestions.' : '',
899
+ 'Return a JSON object with this exact shape: {"complexity":"string","maintainability":"string","suggestions":["string"]}',
900
+ `Code:\n${params.code}`,
901
+ ]
902
+ .filter(Boolean)
903
+ .join('\n');
904
+ const raw = await this.aiService.sendMessage(sessionId, prompt);
905
+ try {
906
+ const jsonMatch = raw.match(/\{[\s\S]*\}/);
907
+ return jsonMatch
908
+ ? JSON.parse(jsonMatch[0])
909
+ : {
910
+ complexity: 'unknown',
911
+ maintainability: 'unknown',
912
+ suggestions: [],
913
+ };
914
+ } catch {
915
+ return {
916
+ complexity: 'unknown',
917
+ maintainability: 'unknown',
918
+ suggestions: [],
919
+ };
920
+ }
921
+ }
922
+
923
+ case 'optimize': {
924
+ const prompt = [
925
+ `Create a performance optimization plan for the following code in ${params.target}.`,
926
+ `Optimization focus: ${params.focus || 'speed'}.`,
927
+ 'Return a JSON object with this exact shape: {"description":"string","changes":[{"description":"string"}],"optimizedCode":"string"}',
928
+ `Code:\n${params.code}`,
929
+ ].join('\n');
930
+ const raw = await this.aiService.sendMessage(sessionId, prompt);
931
+ try {
932
+ const jsonMatch = raw.match(/\{[\s\S]*\}/);
933
+ return jsonMatch
934
+ ? JSON.parse(jsonMatch[0])
935
+ : { description: '', changes: [], optimizedCode: params.code };
936
+ } catch {
937
+ return { description: '', changes: [], optimizedCode: params.code };
938
+ }
939
+ }
940
+
807
941
  case 'chat':
808
- return 'This is a mock response. In a real implementation, this would use the AI service.';
942
+ return this.aiService.sendMessage(sessionId, params.message || '');
943
+
944
+ case 'suggest-fix': {
945
+ const prompt = [
946
+ `Suggest a fix for the following issue in ${params.file}:`,
947
+ `Issue (${params.severity}): ${params.issue}`,
948
+ 'Return a JSON object with this shape: {"suggestion":"string"}',
949
+ ].join('\n');
950
+ const raw = await this.aiService.sendMessage(sessionId, prompt);
951
+ try {
952
+ const jsonMatch = raw.match(/\{[\s\S]*\}/);
953
+ return jsonMatch ? JSON.parse(jsonMatch[0]) : { suggestion: raw };
954
+ } catch {
955
+ return { suggestion: raw };
956
+ }
957
+ }
958
+
809
959
  default:
810
960
  throw new Error(`Unknown AI operation: ${operation}`);
811
961
  }
@@ -824,48 +974,120 @@ export class AICommands {
824
974
  }
825
975
 
826
976
  private async loadContext(contextPath: string): Promise<string> {
827
- // Load project context from specified path
828
- return `// Context from ${contextPath}`;
977
+ const fs = await import('fs/promises');
978
+ const path = await import('path');
979
+ const stat = await fs.stat(contextPath);
980
+ if (stat.isDirectory()) {
981
+ // Read all TypeScript/JavaScript files in the directory (non-recursive, shallow)
982
+ const entries = await fs.readdir(contextPath);
983
+ const parts: string[] = [];
984
+ for (const entry of entries) {
985
+ if (/\.(ts|tsx|js|jsx)$/.test(entry)) {
986
+ const filePath = path.join(contextPath, entry);
987
+ const content = await fs.readFile(filePath, 'utf-8');
988
+ parts.push(`// ${filePath}\n${content}`);
989
+ }
990
+ }
991
+ return parts.join('\n\n');
992
+ }
993
+ return fs.readFile(contextPath, 'utf-8');
829
994
  }
830
995
 
831
996
  private async saveGeneratedCode(
832
- _code: string,
997
+ code: string,
833
998
  outputPath: string
834
999
  ): Promise<void> {
835
- // Save generated code to file
836
- logger.debug(`Saving generated code to ${outputPath}`);
1000
+ const fs = await import('fs/promises');
1001
+ const path = await import('path');
1002
+
1003
+ // Ensure directory exists
1004
+ const dir = path.dirname(outputPath);
1005
+ await fs.mkdir(dir, { recursive: true });
1006
+
1007
+ // Write the generated code to file
1008
+ await fs.writeFile(outputPath, code, 'utf-8');
1009
+ logger.debug(`Saved generated code to ${outputPath}`);
837
1010
  }
838
1011
 
839
1012
  private async readFile(filePath: string): Promise<string> {
840
- // Read file content
841
- return `// Content of ${filePath}`;
1013
+ const fs = await import('fs/promises');
1014
+ return fs.readFile(filePath, 'utf-8');
842
1015
  }
843
1016
 
844
1017
  private async getChangedFiles(): Promise<string[]> {
845
- // Get list of changed files from git
846
- return ['src/example.ts'];
1018
+ const { execSync } = await import('child_process');
1019
+ try {
1020
+ const output = execSync('git diff --name-only HEAD', {
1021
+ encoding: 'utf-8',
1022
+ stdio: ['pipe', 'pipe', 'pipe'],
1023
+ }).trim();
1024
+ if (!output) {
1025
+ return [];
1026
+ }
1027
+ return output.split('\n').filter(Boolean);
1028
+ } catch {
1029
+ // Fall back to staged changes if HEAD diff fails (e.g. no commits yet)
1030
+ try {
1031
+ const { execSync: exec } = await import('child_process');
1032
+ const output = exec('git diff --name-only --cached', {
1033
+ encoding: 'utf-8',
1034
+ stdio: ['pipe', 'pipe', 'pipe'],
1035
+ }).trim();
1036
+ return output ? output.split('\n').filter(Boolean) : [];
1037
+ } catch {
1038
+ return [];
1039
+ }
1040
+ }
847
1041
  }
848
1042
 
849
- private displayReviewResults(results: any[]): void {
1043
+ private displayReviewResults(results: FileReviewResult[]): void {
850
1044
  console.log(chalk.blue('\nCode Review Results:'));
851
1045
  results.forEach(result => {
852
1046
  console.log(`\n${chalk.cyan(result.file)} (Score: ${result.score}/100)`);
853
1047
  if (result.issues.length > 0) {
854
- result.issues.forEach((issue: any) => {
1048
+ result.issues.forEach(issue => {
855
1049
  console.log(` ${issue.severity}: ${issue.description}`);
856
1050
  });
857
1051
  }
858
1052
  });
859
1053
  }
860
1054
 
861
- private async suggestFixes(_results: any[]): Promise<void> {
862
- // Implementation for suggesting fixes
1055
+ private async suggestFixes(results: FileReviewResult[]): Promise<void> {
863
1056
  logger.info('Generating fix suggestions...');
1057
+
1058
+ for (const result of results) {
1059
+ if (result.issues.length > 0) {
1060
+ console.log(chalk.yellow(`\nSuggested fixes for ${result.file}:`));
1061
+ for (const issue of result.issues) {
1062
+ const fix = await this.callAI('suggest-fix', {
1063
+ file: result.file,
1064
+ issue: issue.description,
1065
+ severity: issue.severity,
1066
+ });
1067
+ console.log(
1068
+ ` - ${issue.description}: ${fix.suggestion || 'No automatic fix available'}`
1069
+ );
1070
+ }
1071
+ }
1072
+ }
864
1073
  }
865
1074
 
866
- private async applyRefactoring(target: string, _plan: any): Promise<void> {
867
- // Apply refactoring changes
1075
+ private async applyRefactoring(
1076
+ target: string,
1077
+ plan: RefactoringPlan
1078
+ ): Promise<void> {
1079
+ const fs = await import('fs/promises');
1080
+
868
1081
  logger.debug(`Applying refactoring to ${target}`);
1082
+ logger.info(`Refactoring: ${plan.description}`);
1083
+
1084
+ // Apply each change from the refactoring plan
1085
+ for (const change of plan.changes) {
1086
+ logger.debug(` Applying: ${change.description}`);
1087
+ if (change.code) {
1088
+ await fs.writeFile(target, change.code, 'utf-8');
1089
+ }
1090
+ }
869
1091
  }
870
1092
 
871
1093
  private getDocsOutputPath(
@@ -878,15 +1100,29 @@ export class AICommands {
878
1100
  }
879
1101
 
880
1102
  private async saveGeneratedDocs(
881
- _docs: string,
1103
+ docs: string,
882
1104
  outputPath: string
883
1105
  ): Promise<void> {
884
- // Save generated documentation
885
- logger.debug(`Saving documentation to ${outputPath}`);
1106
+ const fs = await import('fs/promises');
1107
+ const path = await import('path');
1108
+
1109
+ // Ensure docs directory exists
1110
+ const dir = path.dirname(outputPath);
1111
+ await fs.mkdir(dir, { recursive: true });
1112
+
1113
+ // Write the generated documentation to file
1114
+ await fs.writeFile(outputPath, docs, 'utf-8');
1115
+ logger.debug(`Saved documentation to ${outputPath}`);
886
1116
  }
887
1117
 
888
- private getTestOutputPath(target: string, _framework: string): string {
889
- return `${target}.test.js`;
1118
+ private getTestOutputPath(target: string, framework: string): string {
1119
+ const path = require('path');
1120
+ const baseName = path.basename(target, path.extname(target));
1121
+ const dirName = path.dirname(target);
1122
+
1123
+ // Use framework-specific test file extensions
1124
+ const extension = framework === 'vitest' ? '.test.ts' : '.test.js';
1125
+ return path.join(dirName, '__tests__', `${baseName}${extension}`);
890
1126
  }
891
1127
 
892
1128
  private async loadChatSession(sessionId: string): Promise<ChatSession> {
@@ -970,26 +1206,66 @@ export class AICommands {
970
1206
  }
971
1207
  }
972
1208
 
973
- private async runBenchmark(_target: string): Promise<any> {
974
- // Run performance benchmark
975
- return { time: 100, memory: 50 };
1209
+ private async runBenchmark(target: string): Promise<BenchmarkResult> {
1210
+ const { performance } = await import('perf_hooks');
1211
+
1212
+ logger.debug(`Running benchmark for ${target}`);
1213
+
1214
+ const startTime = performance.now();
1215
+ const startMemory = process.memoryUsage().heapUsed / 1024 / 1024;
1216
+
1217
+ // Simulate loading and analyzing the file for benchmarking
1218
+ const code = await this.readFile(target);
1219
+ // Simple analysis to measure time
1220
+ const lines = code.split('\n').length;
1221
+ logger.debug(`Analyzed ${lines} lines`);
1222
+
1223
+ const endTime = performance.now();
1224
+ const endMemory = process.memoryUsage().heapUsed / 1024 / 1024;
1225
+
1226
+ return {
1227
+ time: Math.round(endTime - startTime),
1228
+ memory: Math.round(endMemory - startMemory),
1229
+ };
976
1230
  }
977
1231
 
978
1232
  private async applyOptimization(
979
1233
  target: string,
980
- _optimization: any
1234
+ optimization: OptimizationPlan
981
1235
  ): Promise<void> {
982
- // Apply optimization changes
1236
+ const fs = await import('fs/promises');
1237
+
983
1238
  logger.debug(`Applying optimization to ${target}`);
1239
+ logger.info(`Optimization: ${optimization.description}`);
1240
+
1241
+ // Log each change being applied
1242
+ for (const change of optimization.changes) {
1243
+ logger.debug(` Applying: ${change.description}`);
1244
+ }
1245
+
1246
+ // Write the optimized code to the file
1247
+ if (optimization.optimizedCode) {
1248
+ await fs.writeFile(target, optimization.optimizedCode, 'utf-8');
1249
+ logger.success(`Optimization applied to ${target}`);
1250
+ }
984
1251
  }
985
1252
 
986
- private displayBenchmarkComparison(before: any, after: any): void {
1253
+ private displayBenchmarkComparison(
1254
+ before: BenchmarkResult,
1255
+ after: BenchmarkResult
1256
+ ): void {
987
1257
  console.log(chalk.blue('\nBenchmark Comparison:'));
1258
+ const timeDiff = after.time - before.time;
1259
+ const memDiff = after.memory - before.memory;
1260
+
1261
+ const timeColor = timeDiff < 0 ? chalk.green : chalk.yellow;
1262
+ const memColor = memDiff < 0 ? chalk.green : chalk.yellow;
1263
+
988
1264
  console.log(
989
- `Time: ${before.time}ms → ${after.time}ms (${after.time - before.time}ms)`
1265
+ `Time: ${before.time}ms → ${after.time}ms (${timeColor(timeDiff > 0 ? '+' : '')}${timeColor(timeDiff + 'ms')})`
990
1266
  );
991
1267
  console.log(
992
- `Memory: ${before.memory}MB → ${after.memory}MB (${after.memory - before.memory}MB)`
1268
+ `Memory: ${before.memory}MB → ${after.memory}MB (${memColor(memDiff > 0 ? '+' : '')}${memColor(memDiff + 'MB')})`
993
1269
  );
994
1270
  }
995
1271
  }