@wundr.io/cli 1.0.12 → 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 (234) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ai/ai-service.d.ts +152 -0
  3. package/dist/ai/ai-service.d.ts.map +1 -0
  4. package/dist/ai/ai-service.js +430 -0
  5. package/dist/ai/ai-service.js.map +1 -0
  6. package/dist/ai/claude-client.d.ts +130 -0
  7. package/dist/ai/claude-client.d.ts.map +1 -0
  8. package/dist/ai/claude-client.js +340 -0
  9. package/dist/ai/claude-client.js.map +1 -0
  10. package/dist/ai/conversation-manager.d.ts +164 -0
  11. package/dist/ai/conversation-manager.d.ts.map +1 -0
  12. package/dist/ai/conversation-manager.js +614 -0
  13. package/dist/ai/conversation-manager.js.map +1 -0
  14. package/dist/ai/index.d.ts +5 -0
  15. package/dist/ai/index.d.ts.map +1 -0
  16. package/dist/ai/index.js +8 -0
  17. package/dist/ai/index.js.map +1 -0
  18. package/dist/cli.d.ts +36 -0
  19. package/dist/cli.d.ts.map +1 -0
  20. package/dist/cli.js +192 -0
  21. package/dist/cli.js.map +1 -0
  22. package/dist/commands/ai.d.ts +89 -0
  23. package/dist/commands/ai.d.ts.map +1 -0
  24. package/dist/commands/ai.js +954 -0
  25. package/dist/commands/ai.js.map +1 -0
  26. package/dist/commands/alignment.d.ts +78 -0
  27. package/dist/commands/alignment.d.ts.map +1 -0
  28. package/dist/commands/alignment.js +817 -0
  29. package/dist/commands/alignment.js.map +1 -0
  30. package/dist/commands/analyze-optimized.d.ts +14 -0
  31. package/dist/commands/analyze-optimized.d.ts.map +1 -0
  32. package/dist/commands/analyze-optimized.js +609 -0
  33. package/dist/commands/analyze-optimized.js.map +1 -0
  34. package/dist/commands/analyze.d.ts +65 -0
  35. package/dist/commands/analyze.d.ts.map +1 -0
  36. package/dist/commands/analyze.js +435 -0
  37. package/dist/commands/analyze.js.map +1 -0
  38. package/dist/commands/batch.d.ts +93 -0
  39. package/dist/commands/batch.d.ts.map +1 -0
  40. package/dist/commands/batch.js +854 -0
  41. package/dist/commands/batch.js.map +1 -0
  42. package/dist/commands/chat.d.ts +72 -0
  43. package/dist/commands/chat.d.ts.map +1 -0
  44. package/dist/commands/chat.js +678 -0
  45. package/dist/commands/chat.js.map +1 -0
  46. package/dist/commands/claude-init.d.ts +28 -0
  47. package/dist/commands/claude-init.d.ts.map +1 -0
  48. package/dist/commands/claude-init.js +591 -0
  49. package/dist/commands/claude-init.js.map +1 -0
  50. package/dist/commands/claude-setup.d.ts +119 -0
  51. package/dist/commands/claude-setup.d.ts.map +1 -0
  52. package/dist/commands/claude-setup.js +1079 -0
  53. package/dist/commands/claude-setup.js.map +1 -0
  54. package/dist/commands/computer-setup.d.ts +8 -0
  55. package/dist/commands/computer-setup.d.ts.map +1 -0
  56. package/dist/commands/computer-setup.js +877 -0
  57. package/dist/commands/computer-setup.js.map +1 -0
  58. package/dist/commands/create-command.d.ts +7 -0
  59. package/dist/commands/create-command.d.ts.map +1 -0
  60. package/dist/commands/create-command.js +158 -0
  61. package/dist/commands/create-command.js.map +1 -0
  62. package/dist/commands/create.d.ts +74 -0
  63. package/dist/commands/create.d.ts.map +1 -0
  64. package/dist/commands/create.js +556 -0
  65. package/dist/commands/create.js.map +1 -0
  66. package/dist/commands/dashboard.d.ts +91 -0
  67. package/dist/commands/dashboard.d.ts.map +1 -0
  68. package/dist/commands/dashboard.js +538 -0
  69. package/dist/commands/dashboard.js.map +1 -0
  70. package/dist/commands/govern.d.ts +70 -0
  71. package/dist/commands/govern.d.ts.map +1 -0
  72. package/dist/commands/govern.js +481 -0
  73. package/dist/commands/govern.js.map +1 -0
  74. package/dist/commands/governance.d.ts +17 -0
  75. package/dist/commands/governance.d.ts.map +1 -0
  76. package/dist/commands/governance.js +703 -0
  77. package/dist/commands/governance.js.map +1 -0
  78. package/dist/commands/guardian.d.ts +20 -0
  79. package/dist/commands/guardian.d.ts.map +1 -0
  80. package/dist/commands/guardian.js +597 -0
  81. package/dist/commands/guardian.js.map +1 -0
  82. package/dist/commands/init.d.ts +59 -0
  83. package/dist/commands/init.d.ts.map +1 -0
  84. package/dist/commands/init.js +650 -0
  85. package/dist/commands/init.js.map +1 -0
  86. package/dist/commands/orchestrator.d.ts +7 -0
  87. package/dist/commands/orchestrator.d.ts.map +1 -0
  88. package/dist/commands/orchestrator.js +578 -0
  89. package/dist/commands/orchestrator.js.map +1 -0
  90. package/dist/commands/performance-optimizer.d.ts +30 -0
  91. package/dist/commands/performance-optimizer.d.ts.map +1 -0
  92. package/dist/commands/performance-optimizer.js +650 -0
  93. package/dist/commands/performance-optimizer.js.map +1 -0
  94. package/dist/commands/plugins.d.ts +87 -0
  95. package/dist/commands/plugins.d.ts.map +1 -0
  96. package/dist/commands/plugins.js +685 -0
  97. package/dist/commands/plugins.js.map +1 -0
  98. package/dist/commands/rag.d.ts +7 -0
  99. package/dist/commands/rag.d.ts.map +1 -0
  100. package/dist/commands/rag.js +751 -0
  101. package/dist/commands/rag.js.map +1 -0
  102. package/dist/commands/session.d.ts +41 -0
  103. package/dist/commands/session.d.ts.map +1 -0
  104. package/dist/commands/session.js +441 -0
  105. package/dist/commands/session.js.map +1 -0
  106. package/dist/commands/setup.d.ts +24 -0
  107. package/dist/commands/setup.d.ts.map +1 -0
  108. package/dist/commands/setup.js +172 -0
  109. package/dist/commands/setup.js.map +1 -0
  110. package/dist/commands/test-init.d.ts +9 -0
  111. package/dist/commands/test-init.d.ts.map +1 -0
  112. package/dist/commands/test-init.js +222 -0
  113. package/dist/commands/test-init.js.map +1 -0
  114. package/dist/commands/test.d.ts +25 -0
  115. package/dist/commands/test.d.ts.map +1 -0
  116. package/dist/commands/test.js +217 -0
  117. package/dist/commands/test.js.map +1 -0
  118. package/dist/commands/watch.d.ts +76 -0
  119. package/dist/commands/watch.d.ts.map +1 -0
  120. package/dist/commands/watch.js +613 -0
  121. package/dist/commands/watch.js.map +1 -0
  122. package/dist/commands/worktree.d.ts +63 -0
  123. package/dist/commands/worktree.d.ts.map +1 -0
  124. package/dist/commands/worktree.js +774 -0
  125. package/dist/commands/worktree.js.map +1 -0
  126. package/dist/context/context-manager.d.ts +155 -0
  127. package/dist/context/context-manager.d.ts.map +1 -0
  128. package/dist/context/context-manager.js +383 -0
  129. package/dist/context/context-manager.js.map +1 -0
  130. package/dist/context/index.d.ts +3 -0
  131. package/dist/context/index.d.ts.map +1 -0
  132. package/dist/context/index.js +6 -0
  133. package/dist/context/index.js.map +1 -0
  134. package/dist/context/session-manager.d.ts +207 -0
  135. package/dist/context/session-manager.d.ts.map +1 -0
  136. package/dist/context/session-manager.js +686 -0
  137. package/dist/context/session-manager.js.map +1 -0
  138. package/dist/framework/command-interface.d.ts +349 -0
  139. package/dist/framework/command-interface.d.ts.map +1 -0
  140. package/dist/framework/command-interface.js +101 -0
  141. package/dist/framework/command-interface.js.map +1 -0
  142. package/dist/framework/command-registry.d.ts +173 -0
  143. package/dist/framework/command-registry.d.ts.map +1 -0
  144. package/dist/framework/command-registry.js +734 -0
  145. package/dist/framework/command-registry.js.map +1 -0
  146. package/dist/framework/completion-exporter.d.ts +79 -0
  147. package/dist/framework/completion-exporter.d.ts.map +1 -0
  148. package/dist/framework/completion-exporter.js +259 -0
  149. package/dist/framework/completion-exporter.js.map +1 -0
  150. package/dist/framework/debug-logger.d.ts +163 -0
  151. package/dist/framework/debug-logger.d.ts.map +1 -0
  152. package/dist/framework/debug-logger.js +373 -0
  153. package/dist/framework/debug-logger.js.map +1 -0
  154. package/dist/framework/error-handler.d.ts +196 -0
  155. package/dist/framework/error-handler.d.ts.map +1 -0
  156. package/dist/framework/error-handler.js +613 -0
  157. package/dist/framework/error-handler.js.map +1 -0
  158. package/dist/framework/help-generator.d.ts +78 -0
  159. package/dist/framework/help-generator.d.ts.map +1 -0
  160. package/dist/framework/help-generator.js +414 -0
  161. package/dist/framework/help-generator.js.map +1 -0
  162. package/dist/framework/index.d.ts +62 -0
  163. package/dist/framework/index.d.ts.map +1 -0
  164. package/dist/framework/index.js +95 -0
  165. package/dist/framework/index.js.map +1 -0
  166. package/dist/framework/interactive-repl.d.ts +138 -0
  167. package/dist/framework/interactive-repl.d.ts.map +1 -0
  168. package/dist/framework/interactive-repl.js +567 -0
  169. package/dist/framework/interactive-repl.js.map +1 -0
  170. package/dist/framework/output-formatter.d.ts +274 -0
  171. package/dist/framework/output-formatter.d.ts.map +1 -0
  172. package/dist/framework/output-formatter.js +545 -0
  173. package/dist/framework/output-formatter.js.map +1 -0
  174. package/dist/framework/progress-manager.d.ts +192 -0
  175. package/dist/framework/progress-manager.d.ts.map +1 -0
  176. package/dist/framework/progress-manager.js +408 -0
  177. package/dist/framework/progress-manager.js.map +1 -0
  178. package/dist/index.d.ts +8 -0
  179. package/dist/index.d.ts.map +1 -0
  180. package/dist/index.js +51 -0
  181. package/dist/index.js.map +1 -0
  182. package/dist/interactive/interactive-mode.d.ts +76 -0
  183. package/dist/interactive/interactive-mode.d.ts.map +1 -0
  184. package/dist/interactive/interactive-mode.js +732 -0
  185. package/dist/interactive/interactive-mode.js.map +1 -0
  186. package/dist/nlp/command-mapper.d.ts +174 -0
  187. package/dist/nlp/command-mapper.d.ts.map +1 -0
  188. package/dist/nlp/command-mapper.js +624 -0
  189. package/dist/nlp/command-mapper.js.map +1 -0
  190. package/dist/nlp/command-parser.d.ts +106 -0
  191. package/dist/nlp/command-parser.d.ts.map +1 -0
  192. package/dist/nlp/command-parser.js +417 -0
  193. package/dist/nlp/command-parser.js.map +1 -0
  194. package/dist/nlp/index.d.ts +5 -0
  195. package/dist/nlp/index.d.ts.map +1 -0
  196. package/dist/nlp/index.js +8 -0
  197. package/dist/nlp/index.js.map +1 -0
  198. package/dist/nlp/intent-classifier.d.ts +59 -0
  199. package/dist/nlp/intent-classifier.d.ts.map +1 -0
  200. package/dist/nlp/intent-classifier.js +384 -0
  201. package/dist/nlp/intent-classifier.js.map +1 -0
  202. package/dist/nlp/intent-parser.d.ts +152 -0
  203. package/dist/nlp/intent-parser.d.ts.map +1 -0
  204. package/dist/nlp/intent-parser.js +746 -0
  205. package/dist/nlp/intent-parser.js.map +1 -0
  206. package/dist/plugins/plugin-manager.d.ts +121 -0
  207. package/dist/plugins/plugin-manager.d.ts.map +1 -0
  208. package/dist/plugins/plugin-manager.js +606 -0
  209. package/dist/plugins/plugin-manager.js.map +1 -0
  210. package/dist/types/index.d.ts +224 -0
  211. package/dist/types/index.d.ts.map +1 -0
  212. package/dist/types/index.js +3 -0
  213. package/dist/types/index.js.map +1 -0
  214. package/dist/utils/backup-rollback-manager.d.ts +72 -0
  215. package/dist/utils/backup-rollback-manager.d.ts.map +1 -0
  216. package/dist/utils/backup-rollback-manager.js +288 -0
  217. package/dist/utils/backup-rollback-manager.js.map +1 -0
  218. package/dist/utils/claude-config-installer.d.ts +98 -0
  219. package/dist/utils/claude-config-installer.d.ts.map +1 -0
  220. package/dist/utils/claude-config-installer.js +678 -0
  221. package/dist/utils/claude-config-installer.js.map +1 -0
  222. package/dist/utils/config-manager.d.ts +73 -0
  223. package/dist/utils/config-manager.d.ts.map +1 -0
  224. package/dist/utils/config-manager.js +339 -0
  225. package/dist/utils/config-manager.js.map +1 -0
  226. package/dist/utils/error-handler.d.ts +46 -0
  227. package/dist/utils/error-handler.d.ts.map +1 -0
  228. package/dist/utils/error-handler.js +169 -0
  229. package/dist/utils/error-handler.js.map +1 -0
  230. package/dist/utils/logger.d.ts +25 -0
  231. package/dist/utils/logger.d.ts.map +1 -0
  232. package/dist/utils/logger.js +105 -0
  233. package/dist/utils/logger.js.map +1 -0
  234. package/package.json +23 -23
@@ -0,0 +1,954 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AICommands = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
+ const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
7
+ const ai_service_1 = require("../ai/ai-service");
8
+ const error_handler_1 = require("../utils/error-handler");
9
+ const logger_1 = require("../utils/logger");
10
+ /**
11
+ * AI commands for AI-powered development features
12
+ */
13
+ class AICommands {
14
+ program;
15
+ configManager;
16
+ aiService;
17
+ pluginManager;
18
+ constructor(program, configManager, pluginManager) {
19
+ this.program = program;
20
+ this.configManager = configManager;
21
+ this.pluginManager = pluginManager;
22
+ this.aiService = new ai_service_1.AIService(configManager);
23
+ this.registerCommands();
24
+ }
25
+ registerCommands() {
26
+ const aiCmd = this.program
27
+ .command('ai')
28
+ .description('AI-powered development features');
29
+ // Code generation
30
+ aiCmd
31
+ .command('generate <type>')
32
+ .alias('gen')
33
+ .description('generate code using AI')
34
+ .option('--prompt <prompt>', 'generation prompt')
35
+ .option('--template <template>', 'use specific template')
36
+ .option('--context <path>', 'include context from path')
37
+ .option('--output <path>', 'output file path')
38
+ .action(async (type, options) => {
39
+ await this.generateCode(type, options);
40
+ });
41
+ // Code review
42
+ aiCmd
43
+ .command('review [files...]')
44
+ .description('AI-powered code review')
45
+ .option('--focus <aspect>', 'review focus (security, performance, style)', 'all')
46
+ .option('--severity <level>', 'minimum issue severity', 'info')
47
+ .option('--suggest-fixes', 'suggest fixes for issues')
48
+ .action(async (files, options) => {
49
+ await this.reviewCode(files, options);
50
+ });
51
+ // Code refactoring
52
+ aiCmd
53
+ .command('refactor <target>')
54
+ .description('AI-assisted code refactoring')
55
+ .option('--type <type>', 'refactoring type (extract, rename, optimize)', 'optimize')
56
+ .option('--scope <scope>', 'refactoring scope (function, class, file)', 'function')
57
+ .option('--dry-run', 'show refactoring plan without applying')
58
+ .action(async (target, options) => {
59
+ await this.refactorCode(target, options);
60
+ });
61
+ // Documentation generation
62
+ aiCmd
63
+ .command('docs <target>')
64
+ .description('generate documentation using AI')
65
+ .option('--type <type>', 'documentation type (api, readme, comments)', 'api')
66
+ .option('--format <format>', 'output format (markdown, html, json)', 'markdown')
67
+ .option('--include-examples', 'include code examples')
68
+ .action(async (target, options) => {
69
+ await this.generateDocs(target, options);
70
+ });
71
+ // Test generation
72
+ aiCmd
73
+ .command('test <target>')
74
+ .description('generate tests using AI')
75
+ .option('--framework <framework>', 'testing framework (jest, mocha, vitest)', 'jest')
76
+ .option('--coverage <level>', 'coverage level (unit, integration, e2e)', 'unit')
77
+ .option('--mocks', 'generate mock objects')
78
+ .action(async (target, options) => {
79
+ await this.generateTests(target, options);
80
+ });
81
+ // Chat interface
82
+ aiCmd
83
+ .command('chat')
84
+ .alias('c')
85
+ .description('start AI chat session')
86
+ .option('--model <model>', 'AI model to use')
87
+ .option('--context <path>', 'include project context')
88
+ .option('--session <id>', 'resume existing session')
89
+ .action(async (options) => {
90
+ await this.startChatSession(options);
91
+ });
92
+ // Code analysis
93
+ aiCmd
94
+ .command('analyze <target>')
95
+ .description('AI-powered code analysis')
96
+ .option('--aspect <aspect>', 'analysis aspect (complexity, maintainability, security)', 'all')
97
+ .option('--suggestions', 'include improvement suggestions')
98
+ .action(async (target, options) => {
99
+ await this.analyzeCode(target, options);
100
+ });
101
+ // Performance optimization
102
+ aiCmd
103
+ .command('optimize <target>')
104
+ .description('AI-powered performance optimization')
105
+ .option('--focus <focus>', 'optimization focus (speed, memory, bundle)', 'speed')
106
+ .option('--benchmarks', 'run before/after benchmarks')
107
+ .action(async (target, options) => {
108
+ await this.optimizeCode(target, options);
109
+ });
110
+ // AI Setup Command
111
+ aiCmd
112
+ .command('setup')
113
+ .description('setup AI configuration and API keys')
114
+ .option('--provider <provider>', 'AI provider (claude, openai)', 'claude')
115
+ .option('--api-key <key>', 'API key for the provider')
116
+ .option('--validate', 'validate the API key after setup')
117
+ .action(async (options) => {
118
+ await this.setupAI(options);
119
+ });
120
+ // Status Command
121
+ aiCmd
122
+ .command('status')
123
+ .description('check AI configuration status')
124
+ .action(async () => {
125
+ await this.showAIStatus();
126
+ });
127
+ // Validate Command
128
+ aiCmd
129
+ .command('validate')
130
+ .description('validate AI connection and API key')
131
+ .action(async () => {
132
+ await this.validateAI();
133
+ });
134
+ // Configuration
135
+ aiCmd.command('config').description('configure AI settings');
136
+ aiCmd
137
+ .command('config set <key> <value>')
138
+ .description('set AI configuration')
139
+ .action(async (key, value) => {
140
+ await this.setAIConfig(key, value);
141
+ });
142
+ aiCmd
143
+ .command('config get [key]')
144
+ .description('get AI configuration')
145
+ .action(async (key) => {
146
+ await this.getAIConfig(key);
147
+ });
148
+ }
149
+ /**
150
+ * Generate code using AI
151
+ */
152
+ async generateCode(type, options) {
153
+ try {
154
+ // Check if AI is ready
155
+ if (!this.aiService.isReady()) {
156
+ console.log(chalk_1.default.red('\n❌ AI service not configured'));
157
+ console.log(chalk_1.default.yellow('Run `wundr ai setup` to configure your API key first'));
158
+ return;
159
+ }
160
+ logger_1.logger.info(`Generating ${chalk_1.default.cyan(type)} code...`);
161
+ const prompt = options.prompt || (await this.promptForGeneration(type));
162
+ const context = options.context
163
+ ? await this.loadContext(options.context)
164
+ : '';
165
+ const generatedCode = await this.callAI('generate', {
166
+ type,
167
+ prompt,
168
+ context,
169
+ template: options.template,
170
+ });
171
+ if (options.output) {
172
+ await this.saveGeneratedCode(generatedCode, options.output);
173
+ logger_1.logger.success(`Code generated and saved to ${options.output}`);
174
+ }
175
+ else {
176
+ console.log(chalk_1.default.green('\nGenerated Code:'));
177
+ console.log(generatedCode);
178
+ }
179
+ }
180
+ catch (error) {
181
+ throw error_handler_1.errorHandler.createError('WUNDR_AI_GENERATE_FAILED', 'Failed to generate code', { type, options }, true);
182
+ }
183
+ }
184
+ /**
185
+ * AI-powered code review
186
+ */
187
+ async reviewCode(files, options) {
188
+ try {
189
+ // Check if AI is ready
190
+ if (!this.aiService.isReady()) {
191
+ console.log(chalk_1.default.red('\n❌ AI service not configured'));
192
+ console.log(chalk_1.default.yellow('Run `wundr ai setup` to configure your API key first'));
193
+ return;
194
+ }
195
+ logger_1.logger.info('Starting AI code review...');
196
+ const filesToReview = files.length > 0 ? files : await this.getChangedFiles();
197
+ const reviewResults = [];
198
+ for (const file of filesToReview) {
199
+ logger_1.logger.debug(`Reviewing ${file}...`);
200
+ const code = await this.readFile(file);
201
+ const review = await this.callAI('review', {
202
+ code,
203
+ file,
204
+ focus: options.focus,
205
+ severity: options.severity,
206
+ });
207
+ reviewResults.push({
208
+ file,
209
+ issues: review.issues,
210
+ suggestions: review.suggestions,
211
+ score: review.score,
212
+ });
213
+ }
214
+ this.displayReviewResults(reviewResults);
215
+ if (options.suggestFixes) {
216
+ await this.suggestFixes(reviewResults);
217
+ }
218
+ }
219
+ catch (error) {
220
+ throw error_handler_1.errorHandler.createError('WUNDR_AI_REVIEW_FAILED', 'Failed to review code', { files, options }, true);
221
+ }
222
+ }
223
+ /**
224
+ * AI-assisted code refactoring
225
+ */
226
+ async refactorCode(target, options) {
227
+ try {
228
+ // Check if AI is ready
229
+ if (!this.aiService.isReady()) {
230
+ console.log(chalk_1.default.red('\n❌ AI service not configured'));
231
+ console.log(chalk_1.default.yellow('Run `wundr ai setup` to configure your API key first'));
232
+ return;
233
+ }
234
+ logger_1.logger.info(`Refactoring ${chalk_1.default.cyan(target)}...`);
235
+ const code = await this.readFile(target);
236
+ const refactoringPlan = await this.callAI('refactor', {
237
+ code,
238
+ target,
239
+ type: options.type,
240
+ scope: options.scope,
241
+ });
242
+ if (options.dryRun) {
243
+ logger_1.logger.info('Refactoring Plan:');
244
+ console.log(refactoringPlan.description);
245
+ console.log('\nProposed Changes:');
246
+ refactoringPlan.changes.forEach((change, i) => {
247
+ console.log(`${i + 1}. ${change.description}`);
248
+ });
249
+ return;
250
+ }
251
+ const { proceed } = await inquirer_1.default.prompt([
252
+ {
253
+ type: 'confirm',
254
+ name: 'proceed',
255
+ message: 'Apply refactoring changes?',
256
+ default: false,
257
+ },
258
+ ]);
259
+ if (proceed) {
260
+ await this.applyRefactoring(target, refactoringPlan);
261
+ logger_1.logger.success(`Refactoring applied to ${target}`);
262
+ }
263
+ }
264
+ catch (error) {
265
+ throw error_handler_1.errorHandler.createError('WUNDR_AI_REFACTOR_FAILED', 'Failed to refactor code', { target, options }, true);
266
+ }
267
+ }
268
+ /**
269
+ * Generate documentation using AI
270
+ */
271
+ async generateDocs(target, options) {
272
+ try {
273
+ // Check if AI is ready
274
+ if (!this.aiService.isReady()) {
275
+ console.log(chalk_1.default.red('\n❌ AI service not configured'));
276
+ console.log(chalk_1.default.yellow('Run `wundr ai setup` to configure your API key first'));
277
+ return;
278
+ }
279
+ logger_1.logger.info(`Generating ${options.type} documentation for ${chalk_1.default.cyan(target)}...`);
280
+ const code = await this.readFile(target);
281
+ const docs = await this.callAI('docs', {
282
+ code,
283
+ target,
284
+ type: options.type,
285
+ format: options.format,
286
+ includeExamples: options.includeExamples,
287
+ });
288
+ const outputPath = this.getDocsOutputPath(target, options.type, options.format);
289
+ await this.saveGeneratedDocs(docs, outputPath);
290
+ logger_1.logger.success(`Documentation generated: ${outputPath}`);
291
+ }
292
+ catch (error) {
293
+ throw error_handler_1.errorHandler.createError('WUNDR_AI_DOCS_FAILED', 'Failed to generate documentation', { target, options }, true);
294
+ }
295
+ }
296
+ /**
297
+ * Generate tests using AI
298
+ */
299
+ async generateTests(target, options) {
300
+ try {
301
+ // Check if AI is ready
302
+ if (!this.aiService.isReady()) {
303
+ console.log(chalk_1.default.red('\n❌ AI service not configured'));
304
+ console.log(chalk_1.default.yellow('Run `wundr ai setup` to configure your API key first'));
305
+ return;
306
+ }
307
+ logger_1.logger.info(`Generating tests for ${chalk_1.default.cyan(target)}...`);
308
+ const code = await this.readFile(target);
309
+ const tests = await this.callAI('test', {
310
+ code,
311
+ target,
312
+ framework: options.framework,
313
+ coverage: options.coverage,
314
+ mocks: options.mocks,
315
+ });
316
+ const testPath = this.getTestOutputPath(target, options.framework);
317
+ await this.saveGeneratedCode(tests, testPath);
318
+ logger_1.logger.success(`Tests generated: ${testPath}`);
319
+ }
320
+ catch (error) {
321
+ throw error_handler_1.errorHandler.createError('WUNDR_AI_TEST_FAILED', 'Failed to generate tests', { target, options }, true);
322
+ }
323
+ }
324
+ /**
325
+ * Start AI chat session
326
+ */
327
+ async startChatSession(options) {
328
+ try {
329
+ // Check if AI is ready
330
+ if (!this.aiService.isReady()) {
331
+ console.log(chalk_1.default.red('\n❌ AI service not configured'));
332
+ console.log(chalk_1.default.yellow('Run `wundr ai setup` to configure your API key first'));
333
+ return;
334
+ }
335
+ logger_1.logger.info('Starting AI chat session...');
336
+ const session = options.session
337
+ ? await this.loadChatSession(options.session)
338
+ : await this.createChatSession(options);
339
+ await this.runChatLoop(session);
340
+ }
341
+ catch (error) {
342
+ throw error_handler_1.errorHandler.createError('WUNDR_AI_CHAT_FAILED', 'Failed to start chat session', { options }, true);
343
+ }
344
+ }
345
+ /**
346
+ * AI-powered code analysis
347
+ */
348
+ async analyzeCode(target, options) {
349
+ try {
350
+ // Check if AI is ready
351
+ if (!this.aiService.isReady()) {
352
+ console.log(chalk_1.default.red('\n❌ AI service not configured'));
353
+ console.log(chalk_1.default.yellow('Run `wundr ai setup` to configure your API key first'));
354
+ return;
355
+ }
356
+ logger_1.logger.info(`Analyzing ${chalk_1.default.cyan(target)}...`);
357
+ const code = await this.readFile(target);
358
+ const analysis = await this.callAI('analyze', {
359
+ code,
360
+ target,
361
+ aspect: options.aspect,
362
+ suggestions: options.suggestions,
363
+ });
364
+ this.displayAnalysisResults(analysis);
365
+ }
366
+ catch (error) {
367
+ throw error_handler_1.errorHandler.createError('WUNDR_AI_ANALYZE_FAILED', 'Failed to analyze code', { target, options }, true);
368
+ }
369
+ }
370
+ /**
371
+ * AI-powered performance optimization
372
+ */
373
+ async optimizeCode(target, options) {
374
+ try {
375
+ // Check if AI is ready
376
+ if (!this.aiService.isReady()) {
377
+ console.log(chalk_1.default.red('\n❌ AI service not configured'));
378
+ console.log(chalk_1.default.yellow('Run `wundr ai setup` to configure your API key first'));
379
+ return;
380
+ }
381
+ logger_1.logger.info(`Optimizing ${chalk_1.default.cyan(target)}...`);
382
+ const code = await this.readFile(target);
383
+ let beforeBenchmark;
384
+ if (options.benchmarks) {
385
+ beforeBenchmark = await this.runBenchmark(target);
386
+ }
387
+ const optimization = await this.callAI('optimize', {
388
+ code,
389
+ target,
390
+ focus: options.focus,
391
+ });
392
+ const { apply } = await inquirer_1.default.prompt([
393
+ {
394
+ type: 'confirm',
395
+ name: 'apply',
396
+ message: 'Apply optimization changes?',
397
+ default: false,
398
+ },
399
+ ]);
400
+ if (apply) {
401
+ await this.applyOptimization(target, optimization);
402
+ if (options.benchmarks && beforeBenchmark) {
403
+ const afterBenchmark = await this.runBenchmark(target);
404
+ this.displayBenchmarkComparison(beforeBenchmark, afterBenchmark);
405
+ }
406
+ logger_1.logger.success(`Code optimized: ${target}`);
407
+ }
408
+ }
409
+ catch (error) {
410
+ throw error_handler_1.errorHandler.createError('WUNDR_AI_OPTIMIZE_FAILED', 'Failed to optimize code', { target, options }, true);
411
+ }
412
+ }
413
+ /**
414
+ * Set AI configuration
415
+ */
416
+ async setAIConfig(key, value) {
417
+ try {
418
+ this.configManager.set(`ai.${key}`, value);
419
+ await this.configManager.saveConfig();
420
+ logger_1.logger.success(`AI configuration updated: ${key} = ${value}`);
421
+ }
422
+ catch (error) {
423
+ throw error_handler_1.errorHandler.createError('WUNDR_AI_CONFIG_SET_FAILED', 'Failed to set AI configuration', { key, value }, true);
424
+ }
425
+ }
426
+ /**
427
+ * Get AI configuration
428
+ */
429
+ async getAIConfig(key) {
430
+ try {
431
+ if (key) {
432
+ const value = this.configManager.get(`ai.${key}`);
433
+ console.log(`${key}: ${value}`);
434
+ }
435
+ else {
436
+ const aiConfig = this.configManager.get('ai');
437
+ console.log(JSON.stringify(aiConfig, null, 2));
438
+ }
439
+ }
440
+ catch (error) {
441
+ throw error_handler_1.errorHandler.createError('WUNDR_AI_CONFIG_GET_FAILED', 'Failed to get AI configuration', { key }, true);
442
+ }
443
+ }
444
+ /**
445
+ * Setup AI configuration
446
+ */
447
+ async setupAI(options) {
448
+ try {
449
+ console.log(chalk_1.default.blue('\n🤖 Wundr AI Setup'));
450
+ console.log(chalk_1.default.gray('Configure your AI assistant for enhanced CLI features\n'));
451
+ let { provider, apiKey } = options;
452
+ // Ask for provider if not specified
453
+ if (!provider) {
454
+ const providerAnswer = await inquirer_1.default.prompt([
455
+ {
456
+ type: 'list',
457
+ name: 'provider',
458
+ message: 'Select AI provider:',
459
+ choices: [
460
+ { name: 'Claude (Anthropic)', value: 'claude' },
461
+ { name: 'OpenAI GPT', value: 'openai' },
462
+ ],
463
+ default: 'claude',
464
+ },
465
+ ]);
466
+ provider = providerAnswer.provider;
467
+ }
468
+ // Ask for API key if not provided
469
+ if (!apiKey) {
470
+ const keyPrompt = provider === 'claude'
471
+ ? 'Enter your Claude API key (from https://console.anthropic.com):'
472
+ : 'Enter your OpenAI API key (from https://platform.openai.com):';
473
+ const keyAnswer = await inquirer_1.default.prompt([
474
+ {
475
+ type: 'password',
476
+ name: 'apiKey',
477
+ message: keyPrompt,
478
+ validate: input => {
479
+ if (!input || input.length < 10) {
480
+ return 'Please enter a valid API key';
481
+ }
482
+ return true;
483
+ },
484
+ },
485
+ ]);
486
+ apiKey = keyAnswer.apiKey;
487
+ }
488
+ // Set up the AI service
489
+ await this.aiService.setupAI(apiKey, provider);
490
+ // Validate if requested
491
+ if (options.validate) {
492
+ console.log(chalk_1.default.blue('\nValidating API key...'));
493
+ const validation = await this.aiService.validateConnection();
494
+ if (validation.connected) {
495
+ console.log(chalk_1.default.green('✅ API key is valid and working!'));
496
+ }
497
+ else {
498
+ console.log(chalk_1.default.red(`❌ API key validation failed: ${validation.error}`));
499
+ return;
500
+ }
501
+ }
502
+ console.log(chalk_1.default.green('\n✅ AI setup completed successfully!'));
503
+ console.log(chalk_1.default.gray('\nYou can now use AI features like:'));
504
+ console.log(chalk_1.default.gray(' • wundr ai chat - Interactive AI assistant'));
505
+ console.log(chalk_1.default.gray(' • wundr ai generate - Code generation'));
506
+ console.log(chalk_1.default.gray(' • wundr ai review - Code review'));
507
+ console.log(chalk_1.default.gray('\nRun `wundr ai status` to check configuration'));
508
+ }
509
+ catch (error) {
510
+ throw error_handler_1.errorHandler.createError('WUNDR_AI_SETUP_FAILED', 'Failed to setup AI configuration', { options }, true);
511
+ }
512
+ }
513
+ /**
514
+ * Show AI status
515
+ */
516
+ async showAIStatus() {
517
+ try {
518
+ const status = this.aiService.getStatus();
519
+ console.log(chalk_1.default.blue('\n🤖 AI Configuration Status\n'));
520
+ console.log(`Provider: ${chalk_1.default.cyan(status.provider)}`);
521
+ console.log(`Model: ${chalk_1.default.cyan(status.model)}`);
522
+ console.log(`API Key: ${status.hasApiKey ? chalk_1.default.green('✅ Configured') : chalk_1.default.red('❌ Missing')}`);
523
+ console.log(`Status: ${status.ready ? chalk_1.default.green('✅ Ready') : chalk_1.default.yellow('⚠️ Not Ready')}`);
524
+ if (!status.hasApiKey) {
525
+ console.log(chalk_1.default.yellow('\n⚠️ API key not configured'));
526
+ console.log(chalk_1.default.gray('Run `wundr ai setup` to configure your API key'));
527
+ console.log(chalk_1.default.gray('Or set the CLAUDE_API_KEY environment variable'));
528
+ }
529
+ else if (!status.ready) {
530
+ console.log(chalk_1.default.yellow('\n⚠️ AI service not ready'));
531
+ console.log(chalk_1.default.gray('Try running `wundr ai validate` to check connection'));
532
+ }
533
+ }
534
+ catch (error) {
535
+ throw error_handler_1.errorHandler.createError('WUNDR_AI_STATUS_FAILED', 'Failed to get AI status', {}, true);
536
+ }
537
+ }
538
+ /**
539
+ * Validate AI connection
540
+ */
541
+ async validateAI() {
542
+ try {
543
+ console.log(chalk_1.default.blue('\n🔍 Validating AI connection...'));
544
+ const validation = await this.aiService.validateConnection();
545
+ console.log(`\nProvider: ${chalk_1.default.cyan(validation.provider)}`);
546
+ console.log(`Model: ${chalk_1.default.cyan(validation.model)}`);
547
+ if (validation.connected) {
548
+ console.log(chalk_1.default.green('\n✅ Connection successful!'));
549
+ console.log(chalk_1.default.gray('AI features are ready to use.'));
550
+ }
551
+ else {
552
+ console.log(chalk_1.default.red('\n❌ Connection failed'));
553
+ console.log(chalk_1.default.red(`Error: ${validation.error}`));
554
+ if (validation.error?.includes('API key')) {
555
+ console.log(chalk_1.default.yellow('\n💡 Try:'));
556
+ console.log(chalk_1.default.gray('1. Run `wundr ai setup` to configure your API key'));
557
+ console.log(chalk_1.default.gray('2. Check your API key is valid and has sufficient credits'));
558
+ console.log(chalk_1.default.gray('3. Verify your internet connection'));
559
+ }
560
+ }
561
+ }
562
+ catch (error) {
563
+ throw error_handler_1.errorHandler.createError('WUNDR_AI_VALIDATE_FAILED', 'Failed to validate AI connection', {}, true);
564
+ }
565
+ }
566
+ /**
567
+ * Helper methods
568
+ */
569
+ async callAI(operation, params) {
570
+ // Check if AI service is ready
571
+ if (!this.aiService.isReady()) {
572
+ throw new Error('AI service not configured. Set ANTHROPIC_API_KEY or OPENAI_API_KEY, or run `wundr ai setup`.');
573
+ }
574
+ logger_1.logger.debug(`Calling AI for operation: ${operation}`);
575
+ const sessionId = `ai-cmd-${operation}-${Date.now()}`;
576
+ switch (operation) {
577
+ case 'generate': {
578
+ const prompt = [
579
+ `Generate ${params.type} code.`,
580
+ params.prompt ? `Requirements: ${params.prompt}` : '',
581
+ params.template ? `Use template style: ${params.template}` : '',
582
+ params.context ? `Context:\n${params.context}` : '',
583
+ 'Return only the code, no explanation.',
584
+ ]
585
+ .filter(Boolean)
586
+ .join('\n');
587
+ return this.aiService.sendMessage(sessionId, prompt);
588
+ }
589
+ case 'review': {
590
+ const prompt = [
591
+ `Review the following ${params.file} code for issues.`,
592
+ `Focus: ${params.focus || 'all'}. Minimum severity: ${params.severity || 'info'}.`,
593
+ 'Return a JSON object with this exact shape: {"issues":[{"severity":"string","description":"string"}],"suggestions":["string"],"score":number}',
594
+ `Code:\n${params.code}`,
595
+ ].join('\n');
596
+ const raw = await this.aiService.sendMessage(sessionId, prompt);
597
+ try {
598
+ const jsonMatch = raw.match(/\{[\s\S]*\}/);
599
+ return jsonMatch
600
+ ? JSON.parse(jsonMatch[0])
601
+ : { issues: [], suggestions: [], score: 0 };
602
+ }
603
+ catch {
604
+ return { issues: [], suggestions: [], score: 0 };
605
+ }
606
+ }
607
+ case 'refactor': {
608
+ const prompt = [
609
+ `Create a refactoring plan for the following code in ${params.target}.`,
610
+ `Refactoring type: ${params.type || 'optimize'}. Scope: ${params.scope || 'function'}.`,
611
+ 'Return a JSON object with this exact shape: {"description":"string","changes":[{"description":"string","code":"string"}]}',
612
+ `Code:\n${params.code}`,
613
+ ].join('\n');
614
+ const raw = await this.aiService.sendMessage(sessionId, prompt);
615
+ try {
616
+ const jsonMatch = raw.match(/\{[\s\S]*\}/);
617
+ return jsonMatch
618
+ ? JSON.parse(jsonMatch[0])
619
+ : { description: '', changes: [] };
620
+ }
621
+ catch {
622
+ return { description: '', changes: [] };
623
+ }
624
+ }
625
+ case 'docs': {
626
+ const prompt = [
627
+ `Generate ${params.type || 'api'} documentation in ${params.format || 'markdown'} format for ${params.target}.`,
628
+ params.includeExamples ? 'Include code examples.' : '',
629
+ `Code:\n${params.code}`,
630
+ ]
631
+ .filter(Boolean)
632
+ .join('\n');
633
+ return this.aiService.sendMessage(sessionId, prompt);
634
+ }
635
+ case 'test': {
636
+ const prompt = [
637
+ `Generate ${params.coverage || 'unit'} tests using ${params.framework || 'jest'} for ${params.target}.`,
638
+ params.mocks ? 'Include mock objects where appropriate.' : '',
639
+ 'Return only the test code, no explanation.',
640
+ `Code:\n${params.code}`,
641
+ ]
642
+ .filter(Boolean)
643
+ .join('\n');
644
+ return this.aiService.sendMessage(sessionId, prompt);
645
+ }
646
+ case 'analyze': {
647
+ const prompt = [
648
+ `Analyze the following code from ${params.target}.`,
649
+ `Aspect: ${params.aspect || 'all'}.`,
650
+ params.suggestions ? 'Include improvement suggestions.' : '',
651
+ 'Return a JSON object with this exact shape: {"complexity":"string","maintainability":"string","suggestions":["string"]}',
652
+ `Code:\n${params.code}`,
653
+ ]
654
+ .filter(Boolean)
655
+ .join('\n');
656
+ const raw = await this.aiService.sendMessage(sessionId, prompt);
657
+ try {
658
+ const jsonMatch = raw.match(/\{[\s\S]*\}/);
659
+ return jsonMatch
660
+ ? JSON.parse(jsonMatch[0])
661
+ : {
662
+ complexity: 'unknown',
663
+ maintainability: 'unknown',
664
+ suggestions: [],
665
+ };
666
+ }
667
+ catch {
668
+ return {
669
+ complexity: 'unknown',
670
+ maintainability: 'unknown',
671
+ suggestions: [],
672
+ };
673
+ }
674
+ }
675
+ case 'optimize': {
676
+ const prompt = [
677
+ `Create a performance optimization plan for the following code in ${params.target}.`,
678
+ `Optimization focus: ${params.focus || 'speed'}.`,
679
+ 'Return a JSON object with this exact shape: {"description":"string","changes":[{"description":"string"}],"optimizedCode":"string"}',
680
+ `Code:\n${params.code}`,
681
+ ].join('\n');
682
+ const raw = await this.aiService.sendMessage(sessionId, prompt);
683
+ try {
684
+ const jsonMatch = raw.match(/\{[\s\S]*\}/);
685
+ return jsonMatch
686
+ ? JSON.parse(jsonMatch[0])
687
+ : { description: '', changes: [], optimizedCode: params.code };
688
+ }
689
+ catch {
690
+ return { description: '', changes: [], optimizedCode: params.code };
691
+ }
692
+ }
693
+ case 'chat':
694
+ return this.aiService.sendMessage(sessionId, params.message || '');
695
+ case 'suggest-fix': {
696
+ const prompt = [
697
+ `Suggest a fix for the following issue in ${params.file}:`,
698
+ `Issue (${params.severity}): ${params.issue}`,
699
+ 'Return a JSON object with this shape: {"suggestion":"string"}',
700
+ ].join('\n');
701
+ const raw = await this.aiService.sendMessage(sessionId, prompt);
702
+ try {
703
+ const jsonMatch = raw.match(/\{[\s\S]*\}/);
704
+ return jsonMatch ? JSON.parse(jsonMatch[0]) : { suggestion: raw };
705
+ }
706
+ catch {
707
+ return { suggestion: raw };
708
+ }
709
+ }
710
+ default:
711
+ throw new Error(`Unknown AI operation: ${operation}`);
712
+ }
713
+ }
714
+ async promptForGeneration(type) {
715
+ const { prompt } = await inquirer_1.default.prompt([
716
+ {
717
+ type: 'input',
718
+ name: 'prompt',
719
+ message: `Describe the ${type} you want to generate:`,
720
+ validate: input => input.length > 0 || 'Prompt is required',
721
+ },
722
+ ]);
723
+ return prompt;
724
+ }
725
+ async loadContext(contextPath) {
726
+ const fs = await Promise.resolve().then(() => tslib_1.__importStar(require('fs/promises')));
727
+ const path = await Promise.resolve().then(() => tslib_1.__importStar(require('path')));
728
+ const stat = await fs.stat(contextPath);
729
+ if (stat.isDirectory()) {
730
+ // Read all TypeScript/JavaScript files in the directory (non-recursive, shallow)
731
+ const entries = await fs.readdir(contextPath);
732
+ const parts = [];
733
+ for (const entry of entries) {
734
+ if (/\.(ts|tsx|js|jsx)$/.test(entry)) {
735
+ const filePath = path.join(contextPath, entry);
736
+ const content = await fs.readFile(filePath, 'utf-8');
737
+ parts.push(`// ${filePath}\n${content}`);
738
+ }
739
+ }
740
+ return parts.join('\n\n');
741
+ }
742
+ return fs.readFile(contextPath, 'utf-8');
743
+ }
744
+ async saveGeneratedCode(code, outputPath) {
745
+ const fs = await Promise.resolve().then(() => tslib_1.__importStar(require('fs/promises')));
746
+ const path = await Promise.resolve().then(() => tslib_1.__importStar(require('path')));
747
+ // Ensure directory exists
748
+ const dir = path.dirname(outputPath);
749
+ await fs.mkdir(dir, { recursive: true });
750
+ // Write the generated code to file
751
+ await fs.writeFile(outputPath, code, 'utf-8');
752
+ logger_1.logger.debug(`Saved generated code to ${outputPath}`);
753
+ }
754
+ async readFile(filePath) {
755
+ const fs = await Promise.resolve().then(() => tslib_1.__importStar(require('fs/promises')));
756
+ return fs.readFile(filePath, 'utf-8');
757
+ }
758
+ async getChangedFiles() {
759
+ const { execSync } = await Promise.resolve().then(() => tslib_1.__importStar(require('child_process')));
760
+ try {
761
+ const output = execSync('git diff --name-only HEAD', {
762
+ encoding: 'utf-8',
763
+ stdio: ['pipe', 'pipe', 'pipe'],
764
+ }).trim();
765
+ if (!output) {
766
+ return [];
767
+ }
768
+ return output.split('\n').filter(Boolean);
769
+ }
770
+ catch {
771
+ // Fall back to staged changes if HEAD diff fails (e.g. no commits yet)
772
+ try {
773
+ const { execSync: exec } = await Promise.resolve().then(() => tslib_1.__importStar(require('child_process')));
774
+ const output = exec('git diff --name-only --cached', {
775
+ encoding: 'utf-8',
776
+ stdio: ['pipe', 'pipe', 'pipe'],
777
+ }).trim();
778
+ return output ? output.split('\n').filter(Boolean) : [];
779
+ }
780
+ catch {
781
+ return [];
782
+ }
783
+ }
784
+ }
785
+ displayReviewResults(results) {
786
+ console.log(chalk_1.default.blue('\nCode Review Results:'));
787
+ results.forEach(result => {
788
+ console.log(`\n${chalk_1.default.cyan(result.file)} (Score: ${result.score}/100)`);
789
+ if (result.issues.length > 0) {
790
+ result.issues.forEach(issue => {
791
+ console.log(` ${issue.severity}: ${issue.description}`);
792
+ });
793
+ }
794
+ });
795
+ }
796
+ async suggestFixes(results) {
797
+ logger_1.logger.info('Generating fix suggestions...');
798
+ for (const result of results) {
799
+ if (result.issues.length > 0) {
800
+ console.log(chalk_1.default.yellow(`\nSuggested fixes for ${result.file}:`));
801
+ for (const issue of result.issues) {
802
+ const fix = await this.callAI('suggest-fix', {
803
+ file: result.file,
804
+ issue: issue.description,
805
+ severity: issue.severity,
806
+ });
807
+ console.log(` - ${issue.description}: ${fix.suggestion || 'No automatic fix available'}`);
808
+ }
809
+ }
810
+ }
811
+ }
812
+ async applyRefactoring(target, plan) {
813
+ const fs = await Promise.resolve().then(() => tslib_1.__importStar(require('fs/promises')));
814
+ logger_1.logger.debug(`Applying refactoring to ${target}`);
815
+ logger_1.logger.info(`Refactoring: ${plan.description}`);
816
+ // Apply each change from the refactoring plan
817
+ for (const change of plan.changes) {
818
+ logger_1.logger.debug(` Applying: ${change.description}`);
819
+ if (change.code) {
820
+ await fs.writeFile(target, change.code, 'utf-8');
821
+ }
822
+ }
823
+ }
824
+ getDocsOutputPath(target, type, format) {
825
+ const ext = format === 'markdown' ? 'md' : format;
826
+ return `docs/${target}.${type}.${ext}`;
827
+ }
828
+ async saveGeneratedDocs(docs, outputPath) {
829
+ const fs = await Promise.resolve().then(() => tslib_1.__importStar(require('fs/promises')));
830
+ const path = await Promise.resolve().then(() => tslib_1.__importStar(require('path')));
831
+ // Ensure docs directory exists
832
+ const dir = path.dirname(outputPath);
833
+ await fs.mkdir(dir, { recursive: true });
834
+ // Write the generated documentation to file
835
+ await fs.writeFile(outputPath, docs, 'utf-8');
836
+ logger_1.logger.debug(`Saved documentation to ${outputPath}`);
837
+ }
838
+ getTestOutputPath(target, framework) {
839
+ const path = require('path');
840
+ const baseName = path.basename(target, path.extname(target));
841
+ const dirName = path.dirname(target);
842
+ // Use framework-specific test file extensions
843
+ const extension = framework === 'vitest' ? '.test.ts' : '.test.js';
844
+ return path.join(dirName, '__tests__', `${baseName}${extension}`);
845
+ }
846
+ async loadChatSession(sessionId) {
847
+ // Load existing chat session
848
+ return {
849
+ id: sessionId,
850
+ model: 'claude-3',
851
+ history: [],
852
+ created: new Date(),
853
+ updated: new Date(),
854
+ };
855
+ }
856
+ async createChatSession(options) {
857
+ return {
858
+ id: `session-${Date.now()}`,
859
+ model: options.model || 'claude-3',
860
+ context: options.context,
861
+ history: [],
862
+ created: new Date(),
863
+ updated: new Date(),
864
+ };
865
+ }
866
+ async runChatLoop(session) {
867
+ console.log(chalk_1.default.green(`\nAI Chat Session (${session.model})`));
868
+ console.log(chalk_1.default.gray('Type "exit" to end the session\n'));
869
+ // Load existing session into AI service
870
+ this.aiService.loadChatSession(session);
871
+ while (true) {
872
+ const { message } = await inquirer_1.default.prompt([
873
+ {
874
+ type: 'input',
875
+ name: 'message',
876
+ message: 'You:',
877
+ validate: input => input.length > 0 || 'Message cannot be empty',
878
+ },
879
+ ]);
880
+ if (message.toLowerCase() === 'exit') {
881
+ break;
882
+ }
883
+ try {
884
+ // Use real AI service for chat
885
+ const response = await this.aiService.sendMessage(session.id, message, {
886
+ projectPath: process.cwd(),
887
+ currentGoal: 'Interactive chat session',
888
+ });
889
+ console.log(chalk_1.default.cyan(`AI: ${response}`));
890
+ // Update session history from AI service
891
+ session.history = this.aiService.exportChatSession(session.id);
892
+ session.updated = new Date();
893
+ }
894
+ catch (error) {
895
+ console.log(chalk_1.default.red(`Error: ${error.message}`));
896
+ console.log(chalk_1.default.yellow('\nTip: Try `wundr ai validate` to check your connection'));
897
+ }
898
+ }
899
+ logger_1.logger.success('Chat session ended');
900
+ }
901
+ displayAnalysisResults(analysis) {
902
+ console.log(chalk_1.default.blue('\nCode Analysis Results:'));
903
+ console.log(`Complexity: ${analysis.complexity}`);
904
+ console.log(`Maintainability: ${analysis.maintainability}`);
905
+ if (analysis.suggestions.length > 0) {
906
+ console.log('\nSuggestions:');
907
+ analysis.suggestions.forEach((suggestion, i) => {
908
+ console.log(`${i + 1}. ${suggestion}`);
909
+ });
910
+ }
911
+ }
912
+ async runBenchmark(target) {
913
+ const { performance } = await Promise.resolve().then(() => tslib_1.__importStar(require('perf_hooks')));
914
+ logger_1.logger.debug(`Running benchmark for ${target}`);
915
+ const startTime = performance.now();
916
+ const startMemory = process.memoryUsage().heapUsed / 1024 / 1024;
917
+ // Simulate loading and analyzing the file for benchmarking
918
+ const code = await this.readFile(target);
919
+ // Simple analysis to measure time
920
+ const lines = code.split('\n').length;
921
+ logger_1.logger.debug(`Analyzed ${lines} lines`);
922
+ const endTime = performance.now();
923
+ const endMemory = process.memoryUsage().heapUsed / 1024 / 1024;
924
+ return {
925
+ time: Math.round(endTime - startTime),
926
+ memory: Math.round(endMemory - startMemory),
927
+ };
928
+ }
929
+ async applyOptimization(target, optimization) {
930
+ const fs = await Promise.resolve().then(() => tslib_1.__importStar(require('fs/promises')));
931
+ logger_1.logger.debug(`Applying optimization to ${target}`);
932
+ logger_1.logger.info(`Optimization: ${optimization.description}`);
933
+ // Log each change being applied
934
+ for (const change of optimization.changes) {
935
+ logger_1.logger.debug(` Applying: ${change.description}`);
936
+ }
937
+ // Write the optimized code to the file
938
+ if (optimization.optimizedCode) {
939
+ await fs.writeFile(target, optimization.optimizedCode, 'utf-8');
940
+ logger_1.logger.success(`Optimization applied to ${target}`);
941
+ }
942
+ }
943
+ displayBenchmarkComparison(before, after) {
944
+ console.log(chalk_1.default.blue('\nBenchmark Comparison:'));
945
+ const timeDiff = after.time - before.time;
946
+ const memDiff = after.memory - before.memory;
947
+ const timeColor = timeDiff < 0 ? chalk_1.default.green : chalk_1.default.yellow;
948
+ const memColor = memDiff < 0 ? chalk_1.default.green : chalk_1.default.yellow;
949
+ console.log(`Time: ${before.time}ms → ${after.time}ms (${timeColor(timeDiff > 0 ? '+' : '')}${timeColor(timeDiff + 'ms')})`);
950
+ console.log(`Memory: ${before.memory}MB → ${after.memory}MB (${memColor(memDiff > 0 ? '+' : '')}${memColor(memDiff + 'MB')})`);
951
+ }
952
+ }
953
+ exports.AICommands = AICommands;
954
+ //# sourceMappingURL=ai.js.map