@wundr.io/cli 1.0.11 → 1.0.13

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 (180) hide show
  1. package/bin/wundr.js +8 -4
  2. package/dist/ai/ai-service.d.ts.map +1 -1
  3. package/dist/ai/ai-service.js.map +1 -1
  4. package/dist/ai/claude-client.js.map +1 -1
  5. package/dist/ai/conversation-manager.js.map +1 -1
  6. package/dist/commands/ai.d.ts.map +1 -1
  7. package/dist/commands/ai.js +179 -24
  8. package/dist/commands/ai.js.map +1 -1
  9. package/dist/commands/analyze-optimized.d.ts.map +1 -1
  10. package/dist/commands/analyze-optimized.js +15 -6
  11. package/dist/commands/analyze-optimized.js.map +1 -1
  12. package/dist/commands/batch.d.ts +22 -0
  13. package/dist/commands/batch.d.ts.map +1 -1
  14. package/dist/commands/batch.js +130 -14
  15. package/dist/commands/batch.js.map +1 -1
  16. package/dist/commands/chat.d.ts +1 -0
  17. package/dist/commands/chat.d.ts.map +1 -1
  18. package/dist/commands/chat.js +7 -3
  19. package/dist/commands/chat.js.map +1 -1
  20. package/dist/commands/claude-init.d.ts +1 -1
  21. package/dist/commands/claude-init.d.ts.map +1 -1
  22. package/dist/commands/claude-init.js +16 -16
  23. package/dist/commands/claude-init.js.map +1 -1
  24. package/dist/commands/claude-setup.d.ts +5 -5
  25. package/dist/commands/claude-setup.d.ts.map +1 -1
  26. package/dist/commands/claude-setup.js +65 -59
  27. package/dist/commands/claude-setup.js.map +1 -1
  28. package/dist/commands/computer-setup.d.ts +1 -0
  29. package/dist/commands/computer-setup.d.ts.map +1 -1
  30. package/dist/commands/computer-setup.js +35 -7
  31. package/dist/commands/computer-setup.js.map +1 -1
  32. package/dist/commands/dashboard.js.map +1 -1
  33. package/dist/commands/govern.js.map +1 -1
  34. package/dist/commands/init.d.ts.map +1 -1
  35. package/dist/commands/init.js +3 -3
  36. package/dist/commands/init.js.map +1 -1
  37. package/dist/commands/orchestrator.d.ts.map +1 -1
  38. package/dist/commands/orchestrator.js +11 -4
  39. package/dist/commands/orchestrator.js.map +1 -1
  40. package/dist/commands/performance-optimizer.d.ts.map +1 -1
  41. package/dist/commands/performance-optimizer.js.map +1 -1
  42. package/dist/commands/rag.d.ts.map +1 -1
  43. package/dist/commands/rag.js +9 -6
  44. package/dist/commands/rag.js.map +1 -1
  45. package/dist/commands/setup.d.ts +5 -10
  46. package/dist/commands/setup.d.ts.map +1 -1
  47. package/dist/commands/setup.js +35 -260
  48. package/dist/commands/setup.js.map +1 -1
  49. package/dist/commands/watch.d.ts.map +1 -1
  50. package/dist/commands/watch.js.map +1 -1
  51. package/dist/context/session-manager.js.map +1 -1
  52. package/dist/framework/command-interface.d.ts +349 -0
  53. package/dist/framework/command-interface.d.ts.map +1 -0
  54. package/dist/framework/command-interface.js +101 -0
  55. package/dist/framework/command-interface.js.map +1 -0
  56. package/dist/framework/command-registry.d.ts +173 -0
  57. package/dist/framework/command-registry.d.ts.map +1 -0
  58. package/dist/framework/command-registry.js +734 -0
  59. package/dist/framework/command-registry.js.map +1 -0
  60. package/dist/framework/completion-exporter.d.ts +79 -0
  61. package/dist/framework/completion-exporter.d.ts.map +1 -0
  62. package/dist/framework/completion-exporter.js +259 -0
  63. package/dist/framework/completion-exporter.js.map +1 -0
  64. package/dist/framework/debug-logger.d.ts +163 -0
  65. package/dist/framework/debug-logger.d.ts.map +1 -0
  66. package/dist/framework/debug-logger.js +373 -0
  67. package/dist/framework/debug-logger.js.map +1 -0
  68. package/dist/framework/error-handler.d.ts +196 -0
  69. package/dist/framework/error-handler.d.ts.map +1 -0
  70. package/dist/framework/error-handler.js +613 -0
  71. package/dist/framework/error-handler.js.map +1 -0
  72. package/dist/framework/help-generator.d.ts +78 -0
  73. package/dist/framework/help-generator.d.ts.map +1 -0
  74. package/dist/framework/help-generator.js +414 -0
  75. package/dist/framework/help-generator.js.map +1 -0
  76. package/dist/framework/index.d.ts +62 -0
  77. package/dist/framework/index.d.ts.map +1 -0
  78. package/dist/framework/index.js +95 -0
  79. package/dist/framework/index.js.map +1 -0
  80. package/dist/framework/interactive-repl.d.ts +138 -0
  81. package/dist/framework/interactive-repl.d.ts.map +1 -0
  82. package/dist/framework/interactive-repl.js +567 -0
  83. package/dist/framework/interactive-repl.js.map +1 -0
  84. package/dist/framework/output-formatter.d.ts +274 -0
  85. package/dist/framework/output-formatter.d.ts.map +1 -0
  86. package/dist/framework/output-formatter.js +545 -0
  87. package/dist/framework/output-formatter.js.map +1 -0
  88. package/dist/framework/progress-manager.d.ts +192 -0
  89. package/dist/framework/progress-manager.d.ts.map +1 -0
  90. package/dist/framework/progress-manager.js +408 -0
  91. package/dist/framework/progress-manager.js.map +1 -0
  92. package/dist/interactive/interactive-mode.js.map +1 -1
  93. package/dist/nlp/command-mapper.js.map +1 -1
  94. package/dist/nlp/command-parser.js.map +1 -1
  95. package/dist/nlp/intent-parser.d.ts.map +1 -1
  96. package/dist/nlp/intent-parser.js +4 -2
  97. package/dist/nlp/intent-parser.js.map +1 -1
  98. package/dist/plugins/plugin-manager.d.ts +2 -1
  99. package/dist/plugins/plugin-manager.d.ts.map +1 -1
  100. package/dist/plugins/plugin-manager.js +30 -19
  101. package/dist/plugins/plugin-manager.js.map +1 -1
  102. package/dist/utils/backup-rollback-manager.d.ts.map +1 -1
  103. package/dist/utils/backup-rollback-manager.js +1 -2
  104. package/dist/utils/backup-rollback-manager.js.map +1 -1
  105. package/dist/utils/logger.js.map +1 -1
  106. package/package.json +6 -6
  107. package/src/ai/ai-service.ts +16 -17
  108. package/src/ai/claude-client.ts +16 -16
  109. package/src/ai/conversation-manager.ts +29 -29
  110. package/src/cli.ts +4 -4
  111. package/src/commands/ai.ts +246 -78
  112. package/src/commands/alignment.ts +74 -74
  113. package/src/commands/analyze-optimized.ts +111 -78
  114. package/src/commands/analyze.ts +14 -14
  115. package/src/commands/batch.ts +179 -42
  116. package/src/commands/chat.ts +37 -30
  117. package/src/commands/claude-init.ts +41 -45
  118. package/src/commands/claude-setup.ts +204 -119
  119. package/src/commands/computer-setup.ts +85 -43
  120. package/src/commands/create-command.ts +4 -4
  121. package/src/commands/create.ts +27 -27
  122. package/src/commands/dashboard.ts +24 -24
  123. package/src/commands/govern.ts +25 -25
  124. package/src/commands/governance.ts +34 -34
  125. package/src/commands/guardian.ts +56 -56
  126. package/src/commands/init.ts +25 -22
  127. package/src/commands/orchestrator.ts +68 -41
  128. package/src/commands/performance-optimizer.ts +34 -35
  129. package/src/commands/plugins.ts +27 -27
  130. package/src/commands/project-update.ts +175 -72
  131. package/src/commands/rag.ts +185 -78
  132. package/src/commands/session.ts +35 -35
  133. package/src/commands/setup.ts +40 -344
  134. package/src/commands/test-init.ts +3 -3
  135. package/src/commands/test.ts +4 -4
  136. package/src/commands/watch.ts +28 -29
  137. package/src/commands/worktree.ts +49 -49
  138. package/src/context/context-manager.ts +10 -10
  139. package/src/context/session-manager.ts +41 -41
  140. package/src/framework/command-interface.ts +520 -0
  141. package/src/framework/command-registry.ts +942 -0
  142. package/src/framework/completion-exporter.ts +383 -0
  143. package/src/framework/debug-logger.ts +519 -0
  144. package/src/framework/error-handler.ts +867 -0
  145. package/src/framework/help-generator.ts +540 -0
  146. package/src/framework/index.ts +169 -0
  147. package/src/framework/interactive-repl.ts +703 -0
  148. package/src/framework/output-formatter.ts +834 -0
  149. package/src/framework/progress-manager.ts +539 -0
  150. package/src/index.ts +4 -4
  151. package/src/interactive/interactive-mode.ts +16 -16
  152. package/src/lib/conflict-resolution.ts +799 -9
  153. package/src/lib/merge-strategy.ts +529 -7
  154. package/src/lib/safety-mechanisms.ts +422 -18
  155. package/src/lib/state-detection.ts +1015 -13
  156. package/src/nlp/command-mapper.ts +29 -29
  157. package/src/nlp/command-parser.ts +17 -17
  158. package/src/nlp/intent-classifier.ts +7 -7
  159. package/src/nlp/intent-parser.ts +54 -52
  160. package/src/plugins/plugin-manager.ts +61 -39
  161. package/src/tests/computer-setup-integration.test.ts +46 -15
  162. package/src/types/modules.d.ts +424 -1
  163. package/src/utils/backup-rollback-manager.ts +11 -8
  164. package/src/utils/config-manager.ts +3 -3
  165. package/src/utils/error-handler.ts +2 -2
  166. package/src/utils/logger.ts +22 -22
  167. package/templates/batch/ci-cd.yaml +7 -7
  168. package/test-suites/api/health.spec.ts +20 -23
  169. package/test-suites/helpers/test-config.ts +14 -13
  170. package/test-suites/ui/accessibility.spec.ts +27 -22
  171. package/test-suites/ui/smoke.spec.ts +26 -21
  172. package/dist/commands/computer-setup-commands.d.ts +0 -53
  173. package/dist/commands/computer-setup-commands.d.ts.map +0 -1
  174. package/dist/commands/computer-setup-commands.js +0 -705
  175. package/dist/commands/computer-setup-commands.js.map +0 -1
  176. package/dist/commands/vp.d.ts +0 -7
  177. package/dist/commands/vp.d.ts.map +0 -1
  178. package/dist/commands/vp.js +0 -571
  179. package/dist/commands/vp.js.map +0 -1
  180. package/src/commands/computer-setup-commands.ts +0 -872
@@ -47,7 +47,7 @@ export class AICommands {
47
47
  constructor(
48
48
  private program: Command,
49
49
  private configManager: ConfigManager,
50
- pluginManager: PluginManager,
50
+ pluginManager: PluginManager
51
51
  ) {
52
52
  this.pluginManager = pluginManager;
53
53
  this.aiService = new AIService(configManager);
@@ -79,7 +79,7 @@ export class AICommands {
79
79
  .option(
80
80
  '--focus <aspect>',
81
81
  'review focus (security, performance, style)',
82
- 'all',
82
+ 'all'
83
83
  )
84
84
  .option('--severity <level>', 'minimum issue severity', 'info')
85
85
  .option('--suggest-fixes', 'suggest fixes for issues')
@@ -94,12 +94,12 @@ export class AICommands {
94
94
  .option(
95
95
  '--type <type>',
96
96
  'refactoring type (extract, rename, optimize)',
97
- 'optimize',
97
+ 'optimize'
98
98
  )
99
99
  .option(
100
100
  '--scope <scope>',
101
101
  'refactoring scope (function, class, file)',
102
- 'function',
102
+ 'function'
103
103
  )
104
104
  .option('--dry-run', 'show refactoring plan without applying')
105
105
  .action(async (target, options) => {
@@ -113,12 +113,12 @@ export class AICommands {
113
113
  .option(
114
114
  '--type <type>',
115
115
  'documentation type (api, readme, comments)',
116
- 'api',
116
+ 'api'
117
117
  )
118
118
  .option(
119
119
  '--format <format>',
120
120
  'output format (markdown, html, json)',
121
- 'markdown',
121
+ 'markdown'
122
122
  )
123
123
  .option('--include-examples', 'include code examples')
124
124
  .action(async (target, options) => {
@@ -132,12 +132,12 @@ export class AICommands {
132
132
  .option(
133
133
  '--framework <framework>',
134
134
  'testing framework (jest, mocha, vitest)',
135
- 'jest',
135
+ 'jest'
136
136
  )
137
137
  .option(
138
138
  '--coverage <level>',
139
139
  'coverage level (unit, integration, e2e)',
140
- 'unit',
140
+ 'unit'
141
141
  )
142
142
  .option('--mocks', 'generate mock objects')
143
143
  .action(async (target, options) => {
@@ -163,7 +163,7 @@ export class AICommands {
163
163
  .option(
164
164
  '--aspect <aspect>',
165
165
  'analysis aspect (complexity, maintainability, security)',
166
- 'all',
166
+ 'all'
167
167
  )
168
168
  .option('--suggestions', 'include improvement suggestions')
169
169
  .action(async (target, options) => {
@@ -177,7 +177,7 @@ export class AICommands {
177
177
  .option(
178
178
  '--focus <focus>',
179
179
  'optimization focus (speed, memory, bundle)',
180
- 'speed',
180
+ 'speed'
181
181
  )
182
182
  .option('--benchmarks', 'run before/after benchmarks')
183
183
  .action(async (target, options) => {
@@ -238,7 +238,7 @@ export class AICommands {
238
238
  if (!this.aiService.isReady()) {
239
239
  console.log(chalk.red('\n❌ AI service not configured'));
240
240
  console.log(
241
- chalk.yellow('Run `wundr ai setup` to configure your API key first'),
241
+ chalk.yellow('Run `wundr ai setup` to configure your API key first')
242
242
  );
243
243
  return;
244
244
  }
@@ -269,7 +269,7 @@ export class AICommands {
269
269
  'WUNDR_AI_GENERATE_FAILED',
270
270
  'Failed to generate code',
271
271
  { type, options },
272
- true,
272
+ true
273
273
  );
274
274
  }
275
275
  }
@@ -283,7 +283,7 @@ export class AICommands {
283
283
  if (!this.aiService.isReady()) {
284
284
  console.log(chalk.red('\n❌ AI service not configured'));
285
285
  console.log(
286
- chalk.yellow('Run `wundr ai setup` to configure your API key first'),
286
+ chalk.yellow('Run `wundr ai setup` to configure your API key first')
287
287
  );
288
288
  return;
289
289
  }
@@ -323,7 +323,7 @@ export class AICommands {
323
323
  'WUNDR_AI_REVIEW_FAILED',
324
324
  'Failed to review code',
325
325
  { files, options },
326
- true,
326
+ true
327
327
  );
328
328
  }
329
329
  }
@@ -337,7 +337,7 @@ export class AICommands {
337
337
  if (!this.aiService.isReady()) {
338
338
  console.log(chalk.red('\n❌ AI service not configured'));
339
339
  console.log(
340
- chalk.yellow('Run `wundr ai setup` to configure your API key first'),
340
+ chalk.yellow('Run `wundr ai setup` to configure your API key first')
341
341
  );
342
342
  return;
343
343
  }
@@ -380,7 +380,7 @@ export class AICommands {
380
380
  'WUNDR_AI_REFACTOR_FAILED',
381
381
  'Failed to refactor code',
382
382
  { target, options },
383
- true,
383
+ true
384
384
  );
385
385
  }
386
386
  }
@@ -394,13 +394,13 @@ export class AICommands {
394
394
  if (!this.aiService.isReady()) {
395
395
  console.log(chalk.red('\n❌ AI service not configured'));
396
396
  console.log(
397
- chalk.yellow('Run `wundr ai setup` to configure your API key first'),
397
+ chalk.yellow('Run `wundr ai setup` to configure your API key first')
398
398
  );
399
399
  return;
400
400
  }
401
401
 
402
402
  logger.info(
403
- `Generating ${options.type} documentation for ${chalk.cyan(target)}...`,
403
+ `Generating ${options.type} documentation for ${chalk.cyan(target)}...`
404
404
  );
405
405
 
406
406
  const code = await this.readFile(target);
@@ -415,7 +415,7 @@ export class AICommands {
415
415
  const outputPath = this.getDocsOutputPath(
416
416
  target,
417
417
  options.type,
418
- options.format,
418
+ options.format
419
419
  );
420
420
  await this.saveGeneratedDocs(docs, outputPath);
421
421
 
@@ -425,7 +425,7 @@ export class AICommands {
425
425
  'WUNDR_AI_DOCS_FAILED',
426
426
  'Failed to generate documentation',
427
427
  { target, options },
428
- true,
428
+ true
429
429
  );
430
430
  }
431
431
  }
@@ -439,7 +439,7 @@ export class AICommands {
439
439
  if (!this.aiService.isReady()) {
440
440
  console.log(chalk.red('\n❌ AI service not configured'));
441
441
  console.log(
442
- chalk.yellow('Run `wundr ai setup` to configure your API key first'),
442
+ chalk.yellow('Run `wundr ai setup` to configure your API key first')
443
443
  );
444
444
  return;
445
445
  }
@@ -464,7 +464,7 @@ export class AICommands {
464
464
  'WUNDR_AI_TEST_FAILED',
465
465
  'Failed to generate tests',
466
466
  { target, options },
467
- true,
467
+ true
468
468
  );
469
469
  }
470
470
  }
@@ -478,7 +478,7 @@ export class AICommands {
478
478
  if (!this.aiService.isReady()) {
479
479
  console.log(chalk.red('\n❌ AI service not configured'));
480
480
  console.log(
481
- chalk.yellow('Run `wundr ai setup` to configure your API key first'),
481
+ chalk.yellow('Run `wundr ai setup` to configure your API key first')
482
482
  );
483
483
  return;
484
484
  }
@@ -495,7 +495,7 @@ export class AICommands {
495
495
  'WUNDR_AI_CHAT_FAILED',
496
496
  'Failed to start chat session',
497
497
  { options },
498
- true,
498
+ true
499
499
  );
500
500
  }
501
501
  }
@@ -509,7 +509,7 @@ export class AICommands {
509
509
  if (!this.aiService.isReady()) {
510
510
  console.log(chalk.red('\n❌ AI service not configured'));
511
511
  console.log(
512
- chalk.yellow('Run `wundr ai setup` to configure your API key first'),
512
+ chalk.yellow('Run `wundr ai setup` to configure your API key first')
513
513
  );
514
514
  return;
515
515
  }
@@ -530,7 +530,7 @@ export class AICommands {
530
530
  'WUNDR_AI_ANALYZE_FAILED',
531
531
  'Failed to analyze code',
532
532
  { target, options },
533
- true,
533
+ true
534
534
  );
535
535
  }
536
536
  }
@@ -544,7 +544,7 @@ export class AICommands {
544
544
  if (!this.aiService.isReady()) {
545
545
  console.log(chalk.red('\n❌ AI service not configured'));
546
546
  console.log(
547
- chalk.yellow('Run `wundr ai setup` to configure your API key first'),
547
+ chalk.yellow('Run `wundr ai setup` to configure your API key first')
548
548
  );
549
549
  return;
550
550
  }
@@ -588,7 +588,7 @@ export class AICommands {
588
588
  'WUNDR_AI_OPTIMIZE_FAILED',
589
589
  'Failed to optimize code',
590
590
  { target, options },
591
- true,
591
+ true
592
592
  );
593
593
  }
594
594
  }
@@ -606,7 +606,7 @@ export class AICommands {
606
606
  'WUNDR_AI_CONFIG_SET_FAILED',
607
607
  'Failed to set AI configuration',
608
608
  { key, value },
609
- true,
609
+ true
610
610
  );
611
611
  }
612
612
  }
@@ -628,7 +628,7 @@ export class AICommands {
628
628
  'WUNDR_AI_CONFIG_GET_FAILED',
629
629
  'Failed to get AI configuration',
630
630
  { key },
631
- true,
631
+ true
632
632
  );
633
633
  }
634
634
  }
@@ -640,7 +640,7 @@ export class AICommands {
640
640
  try {
641
641
  console.log(chalk.blue('\n🤖 Wundr AI Setup'));
642
642
  console.log(
643
- chalk.gray('Configure your AI assistant for enhanced CLI features\n'),
643
+ chalk.gray('Configure your AI assistant for enhanced CLI features\n')
644
644
  );
645
645
 
646
646
  let { provider, apiKey } = options;
@@ -697,7 +697,7 @@ export class AICommands {
697
697
  console.log(chalk.green('✅ API key is valid and working!'));
698
698
  } else {
699
699
  console.log(
700
- chalk.red(`❌ API key validation failed: ${validation.error}`),
700
+ chalk.red(`❌ API key validation failed: ${validation.error}`)
701
701
  );
702
702
  return;
703
703
  }
@@ -714,7 +714,7 @@ export class AICommands {
714
714
  'WUNDR_AI_SETUP_FAILED',
715
715
  'Failed to setup AI configuration',
716
716
  { options },
717
- true,
717
+ true
718
718
  );
719
719
  }
720
720
  }
@@ -731,24 +731,24 @@ export class AICommands {
731
731
  console.log(`Provider: ${chalk.cyan(status.provider)}`);
732
732
  console.log(`Model: ${chalk.cyan(status.model)}`);
733
733
  console.log(
734
- `API Key: ${status.hasApiKey ? chalk.green('✅ Configured') : chalk.red('❌ Missing')}`,
734
+ `API Key: ${status.hasApiKey ? chalk.green('✅ Configured') : chalk.red('❌ Missing')}`
735
735
  );
736
736
  console.log(
737
- `Status: ${status.ready ? chalk.green('✅ Ready') : chalk.yellow('⚠️ Not Ready')}`,
737
+ `Status: ${status.ready ? chalk.green('✅ Ready') : chalk.yellow('⚠️ Not Ready')}`
738
738
  );
739
739
 
740
740
  if (!status.hasApiKey) {
741
741
  console.log(chalk.yellow('\n⚠️ API key not configured'));
742
742
  console.log(
743
- chalk.gray('Run `wundr ai setup` to configure your API key'),
743
+ chalk.gray('Run `wundr ai setup` to configure your API key')
744
744
  );
745
745
  console.log(
746
- chalk.gray('Or set the CLAUDE_API_KEY environment variable'),
746
+ chalk.gray('Or set the CLAUDE_API_KEY environment variable')
747
747
  );
748
748
  } else if (!status.ready) {
749
749
  console.log(chalk.yellow('\n⚠️ AI service not ready'));
750
750
  console.log(
751
- chalk.gray('Try running `wundr ai validate` to check connection'),
751
+ chalk.gray('Try running `wundr ai validate` to check connection')
752
752
  );
753
753
  }
754
754
  } catch (error) {
@@ -756,7 +756,7 @@ export class AICommands {
756
756
  'WUNDR_AI_STATUS_FAILED',
757
757
  'Failed to get AI status',
758
758
  {},
759
- true,
759
+ true
760
760
  );
761
761
  }
762
762
  }
@@ -783,12 +783,12 @@ export class AICommands {
783
783
  if (validation.error?.includes('API key')) {
784
784
  console.log(chalk.yellow('\n💡 Try:'));
785
785
  console.log(
786
- chalk.gray('1. Run `wundr ai setup` to configure your API key'),
786
+ chalk.gray('1. Run `wundr ai setup` to configure your API key')
787
787
  );
788
788
  console.log(
789
789
  chalk.gray(
790
- '2. Check your API key is valid and has sufficient credits',
791
- ),
790
+ '2. Check your API key is valid and has sufficient credits'
791
+ )
792
792
  );
793
793
  console.log(chalk.gray('3. Verify your internet connection'));
794
794
  }
@@ -798,7 +798,7 @@ export class AICommands {
798
798
  'WUNDR_AI_VALIDATE_FAILED',
799
799
  'Failed to validate AI connection',
800
800
  {},
801
- true,
801
+ true
802
802
  );
803
803
  }
804
804
  }
@@ -809,29 +809,153 @@ export class AICommands {
809
809
  private async callAI(operation: string, params: any): Promise<any> {
810
810
  // Check if AI service is ready
811
811
  if (!this.aiService.isReady()) {
812
- 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
+ );
813
815
  }
814
816
 
815
817
  logger.debug(`Calling AI for operation: ${operation}`);
816
818
 
817
- // For now, return mock responses - these would be replaced with actual AI calls
819
+ const sessionId = `ai-cmd-${operation}-${Date.now()}`;
820
+
818
821
  switch (operation) {
819
- case 'generate':
820
- return `// Generated ${params.type} code\nfunction ${params.type}() {\n // Implementation here\n}`;
821
- case 'review':
822
- return { issues: [], suggestions: [], score: 95 };
823
- case 'refactor':
824
- return { description: 'Refactoring plan', changes: [] };
825
- case 'docs':
826
- return `# ${params.target} Documentation\n\nGenerated documentation...`;
827
- case 'test':
828
- return `// Generated tests\ndescribe('${params.target}', () => {\n // Tests here\n});`;
829
- case 'analyze':
830
- return { complexity: 'low', maintainability: 'high', suggestions: [] };
831
- case 'optimize':
832
- 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
+
833
941
  case 'chat':
834
- 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
+
835
959
  default:
836
960
  throw new Error(`Unknown AI operation: ${operation}`);
837
961
  }
@@ -850,13 +974,28 @@ export class AICommands {
850
974
  }
851
975
 
852
976
  private async loadContext(contextPath: string): Promise<string> {
853
- // Load project context from specified path
854
- 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');
855
994
  }
856
995
 
857
996
  private async saveGeneratedCode(
858
997
  code: string,
859
- outputPath: string,
998
+ outputPath: string
860
999
  ): Promise<void> {
861
1000
  const fs = await import('fs/promises');
862
1001
  const path = await import('path');
@@ -871,13 +1010,34 @@ export class AICommands {
871
1010
  }
872
1011
 
873
1012
  private async readFile(filePath: string): Promise<string> {
874
- // Read file content
875
- return `// Content of ${filePath}`;
1013
+ const fs = await import('fs/promises');
1014
+ return fs.readFile(filePath, 'utf-8');
876
1015
  }
877
1016
 
878
1017
  private async getChangedFiles(): Promise<string[]> {
879
- // Get list of changed files from git
880
- 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
+ }
881
1041
  }
882
1042
 
883
1043
  private displayReviewResults(results: FileReviewResult[]): void {
@@ -885,7 +1045,7 @@ export class AICommands {
885
1045
  results.forEach(result => {
886
1046
  console.log(`\n${chalk.cyan(result.file)} (Score: ${result.score}/100)`);
887
1047
  if (result.issues.length > 0) {
888
- result.issues.forEach((issue) => {
1048
+ result.issues.forEach(issue => {
889
1049
  console.log(` ${issue.severity}: ${issue.description}`);
890
1050
  });
891
1051
  }
@@ -904,13 +1064,18 @@ export class AICommands {
904
1064
  issue: issue.description,
905
1065
  severity: issue.severity,
906
1066
  });
907
- console.log(` - ${issue.description}: ${fix.suggestion || 'No automatic fix available'}`);
1067
+ console.log(
1068
+ ` - ${issue.description}: ${fix.suggestion || 'No automatic fix available'}`
1069
+ );
908
1070
  }
909
1071
  }
910
1072
  }
911
1073
  }
912
1074
 
913
- private async applyRefactoring(target: string, plan: RefactoringPlan): Promise<void> {
1075
+ private async applyRefactoring(
1076
+ target: string,
1077
+ plan: RefactoringPlan
1078
+ ): Promise<void> {
914
1079
  const fs = await import('fs/promises');
915
1080
 
916
1081
  logger.debug(`Applying refactoring to ${target}`);
@@ -928,7 +1093,7 @@ export class AICommands {
928
1093
  private getDocsOutputPath(
929
1094
  target: string,
930
1095
  type: string,
931
- format: string,
1096
+ format: string
932
1097
  ): string {
933
1098
  const ext = format === 'markdown' ? 'md' : format;
934
1099
  return `docs/${target}.${type}.${ext}`;
@@ -936,7 +1101,7 @@ export class AICommands {
936
1101
 
937
1102
  private async saveGeneratedDocs(
938
1103
  docs: string,
939
- outputPath: string,
1104
+ outputPath: string
940
1105
  ): Promise<void> {
941
1106
  const fs = await import('fs/promises');
942
1107
  const path = await import('path');
@@ -1019,8 +1184,8 @@ export class AICommands {
1019
1184
  console.log(chalk.red(`Error: ${error.message}`));
1020
1185
  console.log(
1021
1186
  chalk.yellow(
1022
- '\nTip: Try `wundr ai validate` to check your connection',
1023
- ),
1187
+ '\nTip: Try `wundr ai validate` to check your connection'
1188
+ )
1024
1189
  );
1025
1190
  }
1026
1191
  }
@@ -1066,7 +1231,7 @@ export class AICommands {
1066
1231
 
1067
1232
  private async applyOptimization(
1068
1233
  target: string,
1069
- optimization: OptimizationPlan,
1234
+ optimization: OptimizationPlan
1070
1235
  ): Promise<void> {
1071
1236
  const fs = await import('fs/promises');
1072
1237
 
@@ -1085,7 +1250,10 @@ export class AICommands {
1085
1250
  }
1086
1251
  }
1087
1252
 
1088
- private displayBenchmarkComparison(before: BenchmarkResult, after: BenchmarkResult): void {
1253
+ private displayBenchmarkComparison(
1254
+ before: BenchmarkResult,
1255
+ after: BenchmarkResult
1256
+ ): void {
1089
1257
  console.log(chalk.blue('\nBenchmark Comparison:'));
1090
1258
  const timeDiff = after.time - before.time;
1091
1259
  const memDiff = after.memory - before.memory;
@@ -1094,10 +1262,10 @@ export class AICommands {
1094
1262
  const memColor = memDiff < 0 ? chalk.green : chalk.yellow;
1095
1263
 
1096
1264
  console.log(
1097
- `Time: ${before.time}ms → ${after.time}ms (${timeColor(timeDiff > 0 ? '+' : '')}${timeColor(timeDiff + 'ms')})`,
1265
+ `Time: ${before.time}ms → ${after.time}ms (${timeColor(timeDiff > 0 ? '+' : '')}${timeColor(timeDiff + 'ms')})`
1098
1266
  );
1099
1267
  console.log(
1100
- `Memory: ${before.memory}MB → ${after.memory}MB (${memColor(memDiff > 0 ? '+' : '')}${memColor(memDiff + 'MB')})`,
1268
+ `Memory: ${before.memory}MB → ${after.memory}MB (${memColor(memDiff > 0 ? '+' : '')}${memColor(memDiff + 'MB')})`
1101
1269
  );
1102
1270
  }
1103
1271
  }