@wundr.io/cli 1.0.0

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 (213) hide show
  1. package/README.md +551 -0
  2. package/bin/wundr.js +39 -0
  3. package/dist/ai/ai-service.d.ts +152 -0
  4. package/dist/ai/ai-service.d.ts.map +1 -0
  5. package/dist/ai/ai-service.js +430 -0
  6. package/dist/ai/ai-service.js.map +1 -0
  7. package/dist/ai/claude-client.d.ts +130 -0
  8. package/dist/ai/claude-client.d.ts.map +1 -0
  9. package/dist/ai/claude-client.js +339 -0
  10. package/dist/ai/claude-client.js.map +1 -0
  11. package/dist/ai/conversation-manager.d.ts +164 -0
  12. package/dist/ai/conversation-manager.d.ts.map +1 -0
  13. package/dist/ai/conversation-manager.js +612 -0
  14. package/dist/ai/conversation-manager.js.map +1 -0
  15. package/dist/ai/index.d.ts +5 -0
  16. package/dist/ai/index.d.ts.map +1 -0
  17. package/dist/ai/index.js +8 -0
  18. package/dist/ai/index.js.map +1 -0
  19. package/dist/cli.d.ts +36 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +173 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/commands/ai.d.ts +89 -0
  24. package/dist/commands/ai.d.ts.map +1 -0
  25. package/dist/commands/ai.js +735 -0
  26. package/dist/commands/ai.js.map +1 -0
  27. package/dist/commands/analyze-optimized.d.ts +14 -0
  28. package/dist/commands/analyze-optimized.d.ts.map +1 -0
  29. package/dist/commands/analyze-optimized.js +437 -0
  30. package/dist/commands/analyze-optimized.js.map +1 -0
  31. package/dist/commands/analyze.d.ts +65 -0
  32. package/dist/commands/analyze.d.ts.map +1 -0
  33. package/dist/commands/analyze.js +435 -0
  34. package/dist/commands/analyze.js.map +1 -0
  35. package/dist/commands/batch.d.ts +71 -0
  36. package/dist/commands/batch.d.ts.map +1 -0
  37. package/dist/commands/batch.js +738 -0
  38. package/dist/commands/batch.js.map +1 -0
  39. package/dist/commands/chat.d.ts +71 -0
  40. package/dist/commands/chat.d.ts.map +1 -0
  41. package/dist/commands/chat.js +674 -0
  42. package/dist/commands/chat.js.map +1 -0
  43. package/dist/commands/claude-init.d.ts +28 -0
  44. package/dist/commands/claude-init.d.ts.map +1 -0
  45. package/dist/commands/claude-init.js +587 -0
  46. package/dist/commands/claude-init.js.map +1 -0
  47. package/dist/commands/claude-setup.d.ts +32 -0
  48. package/dist/commands/claude-setup.d.ts.map +1 -0
  49. package/dist/commands/claude-setup.js +570 -0
  50. package/dist/commands/claude-setup.js.map +1 -0
  51. package/dist/commands/computer-setup-commands.d.ts +39 -0
  52. package/dist/commands/computer-setup-commands.d.ts.map +1 -0
  53. package/dist/commands/computer-setup-commands.js +563 -0
  54. package/dist/commands/computer-setup-commands.js.map +1 -0
  55. package/dist/commands/computer-setup.d.ts +7 -0
  56. package/dist/commands/computer-setup.d.ts.map +1 -0
  57. package/dist/commands/computer-setup.js +481 -0
  58. package/dist/commands/computer-setup.js.map +1 -0
  59. package/dist/commands/create-command.d.ts +7 -0
  60. package/dist/commands/create-command.d.ts.map +1 -0
  61. package/dist/commands/create-command.js +158 -0
  62. package/dist/commands/create-command.js.map +1 -0
  63. package/dist/commands/create.d.ts +74 -0
  64. package/dist/commands/create.d.ts.map +1 -0
  65. package/dist/commands/create.js +556 -0
  66. package/dist/commands/create.js.map +1 -0
  67. package/dist/commands/dashboard.d.ts +91 -0
  68. package/dist/commands/dashboard.d.ts.map +1 -0
  69. package/dist/commands/dashboard.js +537 -0
  70. package/dist/commands/dashboard.js.map +1 -0
  71. package/dist/commands/govern.d.ts +70 -0
  72. package/dist/commands/govern.d.ts.map +1 -0
  73. package/dist/commands/govern.js +480 -0
  74. package/dist/commands/govern.js.map +1 -0
  75. package/dist/commands/init.d.ts +55 -0
  76. package/dist/commands/init.d.ts.map +1 -0
  77. package/dist/commands/init.js +584 -0
  78. package/dist/commands/init.js.map +1 -0
  79. package/dist/commands/performance-optimizer.d.ts +30 -0
  80. package/dist/commands/performance-optimizer.d.ts.map +1 -0
  81. package/dist/commands/performance-optimizer.js +649 -0
  82. package/dist/commands/performance-optimizer.js.map +1 -0
  83. package/dist/commands/plugins.d.ts +87 -0
  84. package/dist/commands/plugins.d.ts.map +1 -0
  85. package/dist/commands/plugins.js +685 -0
  86. package/dist/commands/plugins.js.map +1 -0
  87. package/dist/commands/setup.d.ts +29 -0
  88. package/dist/commands/setup.d.ts.map +1 -0
  89. package/dist/commands/setup.js +399 -0
  90. package/dist/commands/setup.js.map +1 -0
  91. package/dist/commands/test-init.d.ts +9 -0
  92. package/dist/commands/test-init.d.ts.map +1 -0
  93. package/dist/commands/test-init.js +222 -0
  94. package/dist/commands/test-init.js.map +1 -0
  95. package/dist/commands/test.d.ts +25 -0
  96. package/dist/commands/test.d.ts.map +1 -0
  97. package/dist/commands/test.js +217 -0
  98. package/dist/commands/test.js.map +1 -0
  99. package/dist/commands/watch.d.ts +76 -0
  100. package/dist/commands/watch.d.ts.map +1 -0
  101. package/dist/commands/watch.js +610 -0
  102. package/dist/commands/watch.js.map +1 -0
  103. package/dist/context/context-manager.d.ts +155 -0
  104. package/dist/context/context-manager.d.ts.map +1 -0
  105. package/dist/context/context-manager.js +383 -0
  106. package/dist/context/context-manager.js.map +1 -0
  107. package/dist/context/index.d.ts +3 -0
  108. package/dist/context/index.d.ts.map +1 -0
  109. package/dist/context/index.js +6 -0
  110. package/dist/context/index.js.map +1 -0
  111. package/dist/context/session-manager.d.ts +207 -0
  112. package/dist/context/session-manager.d.ts.map +1 -0
  113. package/dist/context/session-manager.js +682 -0
  114. package/dist/context/session-manager.js.map +1 -0
  115. package/dist/index.d.ts +8 -0
  116. package/dist/index.d.ts.map +1 -0
  117. package/dist/index.js +51 -0
  118. package/dist/index.js.map +1 -0
  119. package/dist/interactive/interactive-mode.d.ts +76 -0
  120. package/dist/interactive/interactive-mode.d.ts.map +1 -0
  121. package/dist/interactive/interactive-mode.js +730 -0
  122. package/dist/interactive/interactive-mode.js.map +1 -0
  123. package/dist/nlp/command-mapper.d.ts +174 -0
  124. package/dist/nlp/command-mapper.d.ts.map +1 -0
  125. package/dist/nlp/command-mapper.js +623 -0
  126. package/dist/nlp/command-mapper.js.map +1 -0
  127. package/dist/nlp/command-parser.d.ts +106 -0
  128. package/dist/nlp/command-parser.d.ts.map +1 -0
  129. package/dist/nlp/command-parser.js +416 -0
  130. package/dist/nlp/command-parser.js.map +1 -0
  131. package/dist/nlp/index.d.ts +5 -0
  132. package/dist/nlp/index.d.ts.map +1 -0
  133. package/dist/nlp/index.js +8 -0
  134. package/dist/nlp/index.js.map +1 -0
  135. package/dist/nlp/intent-classifier.d.ts +59 -0
  136. package/dist/nlp/intent-classifier.d.ts.map +1 -0
  137. package/dist/nlp/intent-classifier.js +384 -0
  138. package/dist/nlp/intent-classifier.js.map +1 -0
  139. package/dist/nlp/intent-parser.d.ts +152 -0
  140. package/dist/nlp/intent-parser.d.ts.map +1 -0
  141. package/dist/nlp/intent-parser.js +739 -0
  142. package/dist/nlp/intent-parser.js.map +1 -0
  143. package/dist/plugins/plugin-manager.d.ts +120 -0
  144. package/dist/plugins/plugin-manager.d.ts.map +1 -0
  145. package/dist/plugins/plugin-manager.js +595 -0
  146. package/dist/plugins/plugin-manager.js.map +1 -0
  147. package/dist/types/index.d.ts +224 -0
  148. package/dist/types/index.d.ts.map +1 -0
  149. package/dist/types/index.js +3 -0
  150. package/dist/types/index.js.map +1 -0
  151. package/dist/utils/config-manager.d.ts +73 -0
  152. package/dist/utils/config-manager.d.ts.map +1 -0
  153. package/dist/utils/config-manager.js +339 -0
  154. package/dist/utils/config-manager.js.map +1 -0
  155. package/dist/utils/error-handler.d.ts +46 -0
  156. package/dist/utils/error-handler.d.ts.map +1 -0
  157. package/dist/utils/error-handler.js +169 -0
  158. package/dist/utils/error-handler.js.map +1 -0
  159. package/dist/utils/logger.d.ts +25 -0
  160. package/dist/utils/logger.d.ts.map +1 -0
  161. package/dist/utils/logger.js +94 -0
  162. package/dist/utils/logger.js.map +1 -0
  163. package/package.json +119 -0
  164. package/src/ai/ai-service.ts +595 -0
  165. package/src/ai/claude-client.ts +490 -0
  166. package/src/ai/conversation-manager.ts +907 -0
  167. package/src/ai/index.ts +8 -0
  168. package/src/cli.ts +202 -0
  169. package/src/commands/ai.ts +995 -0
  170. package/src/commands/analyze-optimized.ts +641 -0
  171. package/src/commands/analyze.ts +576 -0
  172. package/src/commands/batch.ts +935 -0
  173. package/src/commands/chat.ts +876 -0
  174. package/src/commands/claude-init.ts +715 -0
  175. package/src/commands/claude-setup.ts +697 -0
  176. package/src/commands/computer-setup-commands.ts +709 -0
  177. package/src/commands/computer-setup.ts +565 -0
  178. package/src/commands/create-command.ts +175 -0
  179. package/src/commands/create.ts +727 -0
  180. package/src/commands/dashboard.ts +691 -0
  181. package/src/commands/govern.ts +635 -0
  182. package/src/commands/init.ts +677 -0
  183. package/src/commands/performance-optimizer.ts +864 -0
  184. package/src/commands/plugins.ts +848 -0
  185. package/src/commands/setup.ts +508 -0
  186. package/src/commands/test-init.ts +242 -0
  187. package/src/commands/test.ts +264 -0
  188. package/src/commands/watch.ts +755 -0
  189. package/src/context/context-manager.ts +546 -0
  190. package/src/context/index.ts +9 -0
  191. package/src/context/session-manager.ts +1019 -0
  192. package/src/index.ts +64 -0
  193. package/src/interactive/interactive-mode.ts +830 -0
  194. package/src/nlp/command-mapper.ts +885 -0
  195. package/src/nlp/command-parser.ts +564 -0
  196. package/src/nlp/index.ts +4 -0
  197. package/src/nlp/intent-classifier.ts +458 -0
  198. package/src/nlp/intent-parser.ts +1101 -0
  199. package/src/plugins/plugin-manager.ts +744 -0
  200. package/src/types/index.ts +252 -0
  201. package/src/types/modules.d.ts +56 -0
  202. package/src/utils/config-manager.ts +391 -0
  203. package/src/utils/error-handler.ts +192 -0
  204. package/src/utils/logger.ts +104 -0
  205. package/templates/batch/ci-cd.yaml +62 -0
  206. package/templates/component/{{fileName}}.test.tsx +17 -0
  207. package/templates/component/{{fileName}}.tsx +21 -0
  208. package/templates/service/{{fileName}}.ts +98 -0
  209. package/templates/wundr-test.config.js +0 -0
  210. package/test-suites/api/health.spec.ts +134 -0
  211. package/test-suites/helpers/test-config.ts +84 -0
  212. package/test-suites/ui/accessibility.spec.ts +102 -0
  213. package/test-suites/ui/smoke.spec.ts +92 -0
@@ -0,0 +1,564 @@
1
+ import { logger } from '../utils/logger';
2
+ import { AIService, ConversationContext } from '../ai/ai-service';
3
+
4
+ /**
5
+ * Natural language command parsing result
6
+ */
7
+ export interface ParsedCommand {
8
+ originalInput: string;
9
+ intent: string;
10
+ command: string;
11
+ args: string[];
12
+ options: Record<string, any>;
13
+ confidence: number;
14
+ needsConfirmation: boolean;
15
+ suggestions?: string[];
16
+ clarificationQuestion?: string;
17
+ executionPlan?: ExecutionStep[];
18
+ }
19
+
20
+ /**
21
+ * Execution step for complex commands
22
+ */
23
+ export interface ExecutionStep {
24
+ step: number;
25
+ description: string;
26
+ command: string;
27
+ args: string[];
28
+ options: Record<string, any>;
29
+ dependencies?: number[];
30
+ optional?: boolean;
31
+ }
32
+
33
+ /**
34
+ * Command template for pattern matching
35
+ */
36
+ export interface CommandTemplate {
37
+ pattern: RegExp;
38
+ command: string;
39
+ extractParams: (match: RegExpMatchArray) => Record<string, any>;
40
+ confidence: number;
41
+ }
42
+
43
+ /**
44
+ * Natural language command parser
45
+ */
46
+ export class CommandParser {
47
+ private aiService: AIService;
48
+ private commandTemplates: CommandTemplate[];
49
+
50
+ constructor(aiService: AIService) {
51
+ this.aiService = aiService;
52
+ this.commandTemplates = this.initializeTemplates();
53
+ }
54
+
55
+ /**
56
+ * Parse natural language input into CLI command
57
+ */
58
+ async parseCommand(
59
+ input: string,
60
+ context?: ConversationContext
61
+ ): Promise<ParsedCommand> {
62
+ try {
63
+ // First, try template-based parsing for common patterns
64
+ const templateResult = this.tryTemplateMatching(input);
65
+
66
+ if (templateResult && templateResult.confidence > 0.8) {
67
+ return {
68
+ originalInput: input,
69
+ intent: templateResult.intent,
70
+ command: templateResult.command,
71
+ args: templateResult.args,
72
+ options: templateResult.options,
73
+ confidence: templateResult.confidence,
74
+ needsConfirmation: false,
75
+ executionPlan: [this.createExecutionStep(templateResult)],
76
+ };
77
+ }
78
+
79
+ // Fall back to AI-powered parsing
80
+ const aiResult = await this.aiService.parseNaturalLanguageCommand(
81
+ input,
82
+ context
83
+ );
84
+
85
+ // Parse the command string into components
86
+ const parsedComponents = this.parseCommandString(aiResult.command);
87
+
88
+ return {
89
+ originalInput: input,
90
+ intent: aiResult.intent,
91
+ command: parsedComponents.command,
92
+ args: parsedComponents.args,
93
+ options: parsedComponents.options,
94
+ confidence: aiResult.confidence,
95
+ needsConfirmation: aiResult.needsConfirmation,
96
+ clarificationQuestion: aiResult.clarificationQuestion,
97
+ executionPlan: [this.createExecutionStepFromParsed(parsedComponents)],
98
+ };
99
+ } catch (error) {
100
+ logger.error('Failed to parse command:', error);
101
+
102
+ return {
103
+ originalInput: input,
104
+ intent: 'unknown',
105
+ command: '',
106
+ args: [],
107
+ options: {},
108
+ confidence: 0,
109
+ needsConfirmation: true,
110
+ clarificationQuestion: `I couldn't understand "${input}". Could you please rephrase or provide more specific details?`,
111
+ suggestions: await this.generateSuggestions(input, context),
112
+ };
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Parse complex multi-step commands
118
+ */
119
+ async parseComplexCommand(
120
+ input: string,
121
+ context?: ConversationContext
122
+ ): Promise<ParsedCommand> {
123
+ try {
124
+ // Check if this is a complex command (contains "and", "then", "after")
125
+ const complexPatterns = [
126
+ /\s+and\s+/i,
127
+ /\s+then\s+/i,
128
+ /\s+after\s+/i,
129
+ /[;,]\s*/,
130
+ ];
131
+
132
+ const isComplex = complexPatterns.some(pattern => pattern.test(input));
133
+
134
+ if (!isComplex) {
135
+ return await this.parseCommand(input, context);
136
+ }
137
+
138
+ // Split the input into steps
139
+ const steps = this.splitIntoSteps(input);
140
+ const executionPlan: ExecutionStep[] = [];
141
+
142
+ for (let i = 0; i < steps.length; i++) {
143
+ const step = steps[i];
144
+ if (!step) continue;
145
+
146
+ const stepResult = await this.parseCommand(step, context);
147
+
148
+ executionPlan.push({
149
+ step: i + 1,
150
+ description: step,
151
+ command: stepResult.command,
152
+ args: stepResult.args,
153
+ options: stepResult.options,
154
+ dependencies: i > 0 ? [i] : undefined,
155
+ });
156
+ }
157
+
158
+ return {
159
+ originalInput: input,
160
+ intent: 'complex_workflow',
161
+ command: 'batch',
162
+ args: ['--interactive'],
163
+ options: { steps: executionPlan.length },
164
+ confidence: 0.9,
165
+ needsConfirmation: true,
166
+ executionPlan,
167
+ };
168
+ } catch (error) {
169
+ logger.error('Failed to parse complex command:', error);
170
+ return await this.parseCommand(input, context);
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Validate parsed command before execution
176
+ */
177
+ async validateCommand(parsedCommand: ParsedCommand): Promise<{
178
+ valid: boolean;
179
+ issues: string[];
180
+ recommendations?: string[];
181
+ }> {
182
+ const issues: string[] = [];
183
+ const recommendations: string[] = [];
184
+
185
+ // Check if command exists
186
+ if (!parsedCommand.command || parsedCommand.command.trim() === '') {
187
+ issues.push('No valid command identified');
188
+ recommendations.push(
189
+ 'Try rephrasing with a specific action like "analyze", "create", or "init"'
190
+ );
191
+ }
192
+
193
+ // Validate command format
194
+ if (parsedCommand.command && !parsedCommand.command.startsWith('wundr ')) {
195
+ if (this.isValidWundrCommand(parsedCommand.command)) {
196
+ parsedCommand.command = `wundr ${parsedCommand.command}`;
197
+ } else {
198
+ issues.push(`Unknown command: ${parsedCommand.command}`);
199
+ recommendations.push('Use "wundr help" to see available commands');
200
+ }
201
+ }
202
+
203
+ // Check confidence level
204
+ if (parsedCommand.confidence < 0.6) {
205
+ issues.push('Low confidence in command interpretation');
206
+ recommendations.push(
207
+ 'Consider providing more specific details about what you want to accomplish'
208
+ );
209
+ }
210
+
211
+ // Validate required parameters for specific commands
212
+ await this.validateCommandSpecifics(parsedCommand, issues, recommendations);
213
+
214
+ return {
215
+ valid: issues.length === 0,
216
+ issues,
217
+ recommendations: recommendations.length > 0 ? recommendations : undefined,
218
+ };
219
+ }
220
+
221
+ /**
222
+ * Generate command suggestions based on input
223
+ */
224
+ async generateSuggestions(
225
+ input: string,
226
+ context?: ConversationContext
227
+ ): Promise<string[]> {
228
+ try {
229
+ const suggestions = await this.aiService.suggestCommands(input, context);
230
+ return suggestions.map(s => s.command);
231
+ } catch (error) {
232
+ logger.error('Failed to generate suggestions:', error);
233
+
234
+ // Fallback to template-based suggestions
235
+ return this.getFallbackSuggestions(input);
236
+ }
237
+ }
238
+
239
+ /**
240
+ * Initialize command templates for pattern matching
241
+ */
242
+ private initializeTemplates(): CommandTemplate[] {
243
+ return [
244
+ // Analysis commands
245
+ {
246
+ pattern: /analyze|check|scan|examine/i,
247
+ command: 'wundr analyze',
248
+ extractParams: match => ({}),
249
+ confidence: 0.9,
250
+ },
251
+ {
252
+ pattern: /analyze.*dependencies|dependency analysis|check deps/i,
253
+ command: 'wundr analyze --focus dependencies',
254
+ extractParams: match => ({ focus: 'dependencies' }),
255
+ confidence: 0.95,
256
+ },
257
+ {
258
+ pattern: /analyze.*duplicates|find duplicates|duplicate analysis/i,
259
+ command: 'wundr analyze --focus duplicates',
260
+ extractParams: match => ({ focus: 'duplicates' }),
261
+ confidence: 0.95,
262
+ },
263
+
264
+ // Initialization commands
265
+ {
266
+ pattern: /init|initialize|setup|start new/i,
267
+ command: 'wundr init',
268
+ extractParams: match => ({}),
269
+ confidence: 0.9,
270
+ },
271
+ {
272
+ pattern: /init.*project|initialize project|setup project/i,
273
+ command: 'wundr init --type project',
274
+ extractParams: match => ({ type: 'project' }),
275
+ confidence: 0.95,
276
+ },
277
+
278
+ // Creation commands
279
+ {
280
+ pattern: /create.*service|new service|generate service/i,
281
+ command: 'wundr create service',
282
+ extractParams: match => ({}),
283
+ confidence: 0.9,
284
+ },
285
+ {
286
+ pattern: /create.*component|new component|generate component/i,
287
+ command: 'wundr create component',
288
+ extractParams: match => ({}),
289
+ confidence: 0.9,
290
+ },
291
+
292
+ // Dashboard commands
293
+ {
294
+ pattern: /show dashboard|open dashboard|start dashboard/i,
295
+ command: 'wundr dashboard --start',
296
+ extractParams: match => ({ start: true }),
297
+ confidence: 0.9,
298
+ },
299
+
300
+ // Governance commands
301
+ {
302
+ pattern: /apply governance|governance check|compliance check/i,
303
+ command: 'wundr govern --check',
304
+ extractParams: match => ({ check: true }),
305
+ confidence: 0.9,
306
+ },
307
+
308
+ // Watch commands
309
+ {
310
+ pattern: /watch.*files|monitor files|auto.*run/i,
311
+ command: 'wundr watch',
312
+ extractParams: match => ({}),
313
+ confidence: 0.9,
314
+ },
315
+ ];
316
+ }
317
+
318
+ /**
319
+ * Try to match input against command templates
320
+ */
321
+ private tryTemplateMatching(input: string): {
322
+ intent: string;
323
+ command: string;
324
+ args: string[];
325
+ options: Record<string, any>;
326
+ confidence: number;
327
+ } | null {
328
+ for (const template of this.commandTemplates) {
329
+ const match = input.match(template.pattern);
330
+
331
+ if (match) {
332
+ const params = template.extractParams(match);
333
+ const parsedCommand = this.parseCommandString(template.command);
334
+
335
+ return {
336
+ intent: this.extractIntent(template.command),
337
+ command: parsedCommand.command,
338
+ args: parsedCommand.args,
339
+ options: { ...parsedCommand.options, ...params },
340
+ confidence: template.confidence,
341
+ };
342
+ }
343
+ }
344
+
345
+ return null;
346
+ }
347
+
348
+ /**
349
+ * Parse command string into components
350
+ */
351
+ private parseCommandString(commandStr: string): {
352
+ command: string;
353
+ args: string[];
354
+ options: Record<string, any>;
355
+ } {
356
+ const parts = commandStr.trim().split(/\s+/);
357
+ const command = parts.slice(0, 2).join(' '); // "wundr analyze"
358
+ const remaining = parts.slice(2);
359
+
360
+ const args: string[] = [];
361
+ const options: Record<string, any> = {};
362
+
363
+ for (let i = 0; i < remaining.length; i++) {
364
+ const part = remaining[i];
365
+
366
+ if (part?.startsWith('--')) {
367
+ const optionName = part.slice(2);
368
+ const nextPart = remaining[i + 1];
369
+
370
+ if (nextPart && !nextPart.startsWith('-')) {
371
+ options[optionName] = nextPart;
372
+ i++; // Skip next part
373
+ } else {
374
+ options[optionName] = true;
375
+ }
376
+ } else if (part?.startsWith('-')) {
377
+ const optionName = part.slice(1);
378
+ options[optionName] = true;
379
+ } else if (part) {
380
+ args.push(part);
381
+ }
382
+ }
383
+
384
+ return { command, args, options };
385
+ }
386
+
387
+ /**
388
+ * Extract intent from command
389
+ */
390
+ private extractIntent(command: string): string {
391
+ const parts = command.split(' ');
392
+ if (parts.length >= 2 && parts[1]) {
393
+ return parts[1]; // "analyze", "create", etc.
394
+ }
395
+ return 'unknown';
396
+ }
397
+
398
+ /**
399
+ * Create execution step from template result
400
+ */
401
+ private createExecutionStep(templateResult: {
402
+ command: string;
403
+ args: string[];
404
+ options: Record<string, any>;
405
+ }): ExecutionStep {
406
+ return {
407
+ step: 1,
408
+ description: `Execute ${templateResult.command}`,
409
+ command: templateResult.command,
410
+ args: templateResult.args,
411
+ options: templateResult.options,
412
+ };
413
+ }
414
+
415
+ /**
416
+ * Create execution step from parsed command
417
+ */
418
+ private createExecutionStepFromParsed(parsedComponents: {
419
+ command: string;
420
+ args: string[];
421
+ options: Record<string, any>;
422
+ }): ExecutionStep {
423
+ return {
424
+ step: 1,
425
+ description: `Execute ${parsedComponents.command}`,
426
+ command: parsedComponents.command,
427
+ args: parsedComponents.args,
428
+ options: parsedComponents.options,
429
+ };
430
+ }
431
+
432
+ /**
433
+ * Split complex input into execution steps
434
+ */
435
+ private splitIntoSteps(input: string): string[] {
436
+ // Split on coordinating conjunctions and punctuation
437
+ const separators = /\s+(and|then|after|next|followed by)[,\s]+|[;,]\s+/i;
438
+ return input
439
+ .split(separators)
440
+ .map(step => step.trim())
441
+ .filter(
442
+ step =>
443
+ step.length > 0 &&
444
+ !['and', 'then', 'after', 'next', 'followed by'].includes(
445
+ step.toLowerCase()
446
+ )
447
+ );
448
+ }
449
+
450
+ /**
451
+ * Check if command is a valid Wundr command
452
+ */
453
+ private isValidWundrCommand(command: string): boolean {
454
+ const validCommands = [
455
+ 'init',
456
+ 'create',
457
+ 'analyze',
458
+ 'govern',
459
+ 'dashboard',
460
+ 'watch',
461
+ 'batch',
462
+ 'plugins',
463
+ 'chat',
464
+ 'help',
465
+ ];
466
+
467
+ const baseCommand = command.split(' ')[0];
468
+ return baseCommand ? validCommands.includes(baseCommand) : false;
469
+ }
470
+
471
+ /**
472
+ * Validate command-specific requirements
473
+ */
474
+ private async validateCommandSpecifics(
475
+ parsedCommand: ParsedCommand,
476
+ issues: string[],
477
+ recommendations: string[]
478
+ ): Promise<void> {
479
+ const commandParts = parsedCommand.command.split(' ');
480
+ const baseCommand = commandParts[1]; // Skip "wundr"
481
+
482
+ switch (baseCommand) {
483
+ case 'create':
484
+ if (parsedCommand.args.length === 0) {
485
+ issues.push(
486
+ 'Create command requires a type (service, component, etc.)'
487
+ );
488
+ recommendations.push(
489
+ 'Specify what you want to create: "wundr create service MyService"'
490
+ );
491
+ }
492
+ break;
493
+
494
+ case 'analyze':
495
+ // Analyze command is flexible, but we can suggest focus areas
496
+ if (!parsedCommand.options['focus']) {
497
+ recommendations.push(
498
+ 'Consider using --focus to target specific areas (dependencies, duplicates, quality)'
499
+ );
500
+ }
501
+ break;
502
+
503
+ case 'watch':
504
+ if (
505
+ !parsedCommand.options['pattern'] &&
506
+ parsedCommand.args.length === 0
507
+ ) {
508
+ recommendations.push(
509
+ 'Specify file patterns to watch: "wundr watch --pattern "**/*.ts""'
510
+ );
511
+ }
512
+ break;
513
+
514
+ case 'batch':
515
+ if (
516
+ !parsedCommand.options['file'] &&
517
+ !parsedCommand.options['interactive']
518
+ ) {
519
+ issues.push(
520
+ 'Batch command requires either a batch file or interactive mode'
521
+ );
522
+ recommendations.push(
523
+ 'Use --file <batch-file> or --interactive for step-by-step execution'
524
+ );
525
+ }
526
+ break;
527
+ }
528
+ }
529
+
530
+ /**
531
+ * Get fallback suggestions when AI fails
532
+ */
533
+ private getFallbackSuggestions(input: string): string[] {
534
+ const suggestions: string[] = [];
535
+ const lowerInput = input.toLowerCase();
536
+
537
+ if (lowerInput.includes('analyze') || lowerInput.includes('check')) {
538
+ suggestions.push('wundr analyze --path ./src');
539
+ suggestions.push('wundr analyze --focus dependencies');
540
+ }
541
+
542
+ if (lowerInput.includes('create') || lowerInput.includes('new')) {
543
+ suggestions.push('wundr create service MyService');
544
+ suggestions.push('wundr create component MyComponent');
545
+ }
546
+
547
+ if (lowerInput.includes('init') || lowerInput.includes('setup')) {
548
+ suggestions.push('wundr init --type project');
549
+ suggestions.push('wundr init --template basic');
550
+ }
551
+
552
+ if (lowerInput.includes('dashboard') || lowerInput.includes('show')) {
553
+ suggestions.push('wundr dashboard --start');
554
+ }
555
+
556
+ if (suggestions.length === 0) {
557
+ suggestions.push('wundr help');
558
+ suggestions.push('wundr analyze --path .');
559
+ suggestions.push('wundr init');
560
+ }
561
+
562
+ return suggestions.slice(0, 3); // Limit to 3 suggestions
563
+ }
564
+ }
@@ -0,0 +1,4 @@
1
+ export { CommandParser } from './command-parser';
2
+ export type { ParsedCommand, ExecutionStep } from './command-parser';
3
+ export { IntentClassifier } from './intent-classifier';
4
+ export type { Intent, IntentPattern } from './intent-classifier';