@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,830 @@
1
+ import inquirer from 'inquirer';
2
+ import blessed from 'blessed';
3
+ import chalk from 'chalk';
4
+ import { ConfigManager } from '../utils/config-manager';
5
+ import { PluginManager } from '../plugins/plugin-manager';
6
+ import { logger } from '../utils/logger';
7
+ import { errorHandler } from '../utils/error-handler';
8
+ import { InteractiveSession, TUILayout, ChatSession } from '../types';
9
+
10
+ /**
11
+ * Interactive mode manager for wizard, TUI, and chat interfaces
12
+ */
13
+ export class InteractiveMode {
14
+ private activeSessions: Map<string, InteractiveSession> = new Map();
15
+
16
+ constructor(
17
+ private configManager: ConfigManager,
18
+ private pluginManager: PluginManager
19
+ ) {}
20
+
21
+ /**
22
+ * Launch interactive wizard mode
23
+ */
24
+ async launchWizard(mode: string = 'setup'): Promise<void> {
25
+ try {
26
+ logger.info('Launching interactive wizard...');
27
+
28
+ const session: InteractiveSession = {
29
+ mode: 'wizard',
30
+ config: { wizardMode: mode },
31
+ state: {},
32
+ active: true,
33
+ };
34
+
35
+ this.activeSessions.set(`wizard-${Date.now()}`, session);
36
+
37
+ switch (mode) {
38
+ case 'setup':
39
+ await this.setupWizard();
40
+ break;
41
+ case 'analyze':
42
+ await this.analyzeWizard();
43
+ break;
44
+ case 'create':
45
+ await this.createWizard();
46
+ break;
47
+ case 'govern':
48
+ await this.governWizard();
49
+ break;
50
+ default:
51
+ await this.generalWizard();
52
+ }
53
+ } catch (error) {
54
+ throw errorHandler.createError(
55
+ 'WUNDR_WIZARD_FAILED',
56
+ 'Failed to launch wizard',
57
+ { mode },
58
+ true
59
+ );
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Launch chat interface
65
+ */
66
+ async launchChat(options: any): Promise<void> {
67
+ try {
68
+ logger.info('Launching chat interface...');
69
+
70
+ // This would integrate with the chat commands
71
+ const { spawn } = await import('child_process');
72
+ const chatArgs = ['chat', 'start'];
73
+
74
+ if (options.model) chatArgs.push('--model', options.model);
75
+ if (options.context) chatArgs.push('--context', options.context);
76
+
77
+ const child = spawn('wundr', chatArgs, {
78
+ stdio: 'inherit',
79
+ shell: true,
80
+ });
81
+
82
+ child.on('exit', code => {
83
+ if (code !== 0) {
84
+ logger.error(`Chat interface exited with code ${code}`);
85
+ }
86
+ });
87
+ } catch (error) {
88
+ throw errorHandler.createError(
89
+ 'WUNDR_CHAT_LAUNCH_FAILED',
90
+ 'Failed to launch chat interface',
91
+ { options },
92
+ true
93
+ );
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Launch Terminal User Interface (TUI)
99
+ */
100
+ async launchTUI(layout: string = 'dashboard'): Promise<void> {
101
+ try {
102
+ logger.info(`Launching TUI with layout: ${layout}`);
103
+
104
+ const screen = blessed.screen({
105
+ smartCSR: true,
106
+ title: 'Wundr CLI Dashboard',
107
+ });
108
+
109
+ await this.setupTUILayout(screen, layout);
110
+
111
+ // Handle exit
112
+ screen.key(['escape', 'q', 'C-c'], () => {
113
+ return process.exit(0);
114
+ });
115
+
116
+ screen.render();
117
+ } catch (error) {
118
+ throw errorHandler.createError(
119
+ 'WUNDR_TUI_LAUNCH_FAILED',
120
+ 'Failed to launch TUI',
121
+ { layout },
122
+ true
123
+ );
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Setup wizard for initial configuration
129
+ */
130
+ private async setupWizard(): Promise<void> {
131
+ console.log(chalk.cyan('\n🚀 Welcome to Wundr CLI Setup Wizard\n'));
132
+
133
+ const answers = await inquirer.prompt([
134
+ {
135
+ type: 'confirm',
136
+ name: 'initialize',
137
+ message: 'Initialize Wundr in this directory?',
138
+ default: true,
139
+ },
140
+ {
141
+ type: 'list',
142
+ name: 'projectType',
143
+ message: 'What type of project is this?',
144
+ choices: [
145
+ { name: 'Single Package', value: 'single' },
146
+ { name: 'Monorepo', value: 'monorepo' },
147
+ { name: 'Workspace', value: 'workspace' },
148
+ ],
149
+ when: answers => answers.initialize,
150
+ },
151
+ {
152
+ type: 'checkbox',
153
+ name: 'features',
154
+ message: 'Select features to enable:',
155
+ choices: [
156
+ { name: 'Code Analysis', value: 'analysis', checked: true },
157
+ { name: 'Governance Rules', value: 'governance', checked: true },
158
+ { name: 'AI Assistance', value: 'ai', checked: false },
159
+ { name: 'Dashboard', value: 'dashboard', checked: true },
160
+ { name: 'Watch Mode', value: 'watch', checked: false },
161
+ ],
162
+ when: answers => answers.initialize,
163
+ },
164
+ {
165
+ type: 'input',
166
+ name: 'aiProvider',
167
+ message: 'AI Provider:',
168
+ default: 'claude',
169
+ when: answers => answers.features?.includes('ai'),
170
+ },
171
+ {
172
+ type: 'password',
173
+ name: 'aiApiKey',
174
+ message: 'AI API Key (optional):',
175
+ mask: '*',
176
+ when: answers => answers.features?.includes('ai'),
177
+ },
178
+ ]);
179
+
180
+ if (!answers.initialize) {
181
+ console.log(chalk.yellow('Setup cancelled'));
182
+ return;
183
+ }
184
+
185
+ // Execute setup commands based on answers
186
+ console.log(chalk.green('\n✨ Setting up your project...\n'));
187
+
188
+ const setupCommands = [
189
+ `wundr init ${answers.projectType === 'single' ? 'project' : answers.projectType}`,
190
+ 'wundr init config',
191
+ ];
192
+
193
+ if (answers.features?.includes('governance')) {
194
+ setupCommands.push('wundr govern rules add no-console');
195
+ }
196
+
197
+ if (answers.features?.includes('dashboard')) {
198
+ setupCommands.push('wundr dashboard config set theme default');
199
+ }
200
+
201
+ for (const command of setupCommands) {
202
+ console.log(chalk.blue(`Running: ${command}`));
203
+ // Execute command (simplified for demo)
204
+ await this.simulateCommand(command);
205
+ }
206
+
207
+ console.log(
208
+ chalk.green('\n🎉 Setup complete! Your Wundr project is ready.')
209
+ );
210
+ console.log(chalk.gray('\nNext steps:'));
211
+ console.log(chalk.gray(' • Run "wundr analyze" to analyze your code'));
212
+ console.log(
213
+ chalk.gray(' • Run "wundr dashboard start" to launch the dashboard')
214
+ );
215
+ console.log(
216
+ chalk.gray(' • Run "wundr --help" to see all available commands')
217
+ );
218
+ }
219
+
220
+ /**
221
+ * Analysis wizard
222
+ */
223
+ private async analyzeWizard(): Promise<void> {
224
+ console.log(chalk.cyan('\n🔍 Code Analysis Wizard\n'));
225
+
226
+ const answers = await inquirer.prompt([
227
+ {
228
+ type: 'checkbox',
229
+ name: 'analysisTypes',
230
+ message: 'What would you like to analyze?',
231
+ choices: [
232
+ { name: 'Dependencies', value: 'deps', checked: true },
233
+ { name: 'Code Quality', value: 'quality', checked: true },
234
+ { name: 'Performance', value: 'perf', checked: false },
235
+ { name: 'Architecture', value: 'arch', checked: false },
236
+ { name: 'Security', value: 'security', checked: true },
237
+ ],
238
+ },
239
+ {
240
+ type: 'list',
241
+ name: 'outputFormat',
242
+ message: 'Output format:',
243
+ choices: [
244
+ { name: 'Table (Console)', value: 'table' },
245
+ { name: 'JSON File', value: 'json' },
246
+ { name: 'HTML Report', value: 'html' },
247
+ ],
248
+ default: 'table',
249
+ },
250
+ {
251
+ type: 'confirm',
252
+ name: 'autoFix',
253
+ message: 'Automatically fix issues where possible?',
254
+ default: false,
255
+ },
256
+ ]);
257
+
258
+ console.log(chalk.green('\n🔬 Running analysis...\n'));
259
+
260
+ for (const analysisType of answers.analysisTypes) {
261
+ let command = `wundr analyze ${analysisType}`;
262
+ if (answers.outputFormat !== 'table') {
263
+ command += ` --format ${answers.outputFormat}`;
264
+ }
265
+ if (answers.autoFix) {
266
+ command += ' --fix';
267
+ }
268
+
269
+ console.log(chalk.blue(`Running: ${command}`));
270
+ await this.simulateCommand(command);
271
+ }
272
+
273
+ console.log(chalk.green('\n✅ Analysis complete!'));
274
+ }
275
+
276
+ /**
277
+ * Creation wizard
278
+ */
279
+ private async createWizard(): Promise<void> {
280
+ console.log(chalk.cyan('\n🛠️ Code Generation Wizard\n'));
281
+
282
+ const answers = await inquirer.prompt([
283
+ {
284
+ type: 'list',
285
+ name: 'createType',
286
+ message: 'What would you like to create?',
287
+ choices: [
288
+ { name: 'Component', value: 'component' },
289
+ { name: 'Service', value: 'service' },
290
+ { name: 'Package (Monorepo)', value: 'package' },
291
+ { name: 'Template', value: 'template' },
292
+ { name: 'Workflow', value: 'workflow' },
293
+ { name: 'Configuration', value: 'config' },
294
+ ],
295
+ },
296
+ {
297
+ type: 'input',
298
+ name: 'name',
299
+ message: 'Name:',
300
+ validate: input => input.length > 0 || 'Name is required',
301
+ },
302
+ ]);
303
+
304
+ // Get specific options based on type
305
+ let specificAnswers = {};
306
+
307
+ switch (answers.createType) {
308
+ case 'component':
309
+ specificAnswers = await this.getComponentOptions();
310
+ break;
311
+ case 'service':
312
+ specificAnswers = await this.getServiceOptions();
313
+ break;
314
+ case 'package':
315
+ specificAnswers = await this.getPackageOptions();
316
+ break;
317
+ default:
318
+ specificAnswers = {};
319
+ }
320
+
321
+ console.log(
322
+ chalk.green(`\n🏗️ Creating ${answers.createType}: ${answers.name}\n`)
323
+ );
324
+
325
+ let command = `wundr create ${answers.createType} ${answers.name}`;
326
+
327
+ // Add specific options to command
328
+ Object.entries(specificAnswers).forEach(([key, value]) => {
329
+ if (typeof value === 'boolean' && value) {
330
+ command += ` --${key}`;
331
+ } else if (typeof value === 'string' && value) {
332
+ command += ` --${key} ${value}`;
333
+ }
334
+ });
335
+
336
+ console.log(chalk.blue(`Running: ${command}`));
337
+ await this.simulateCommand(command);
338
+
339
+ console.log(
340
+ chalk.green(`\n🎉 ${answers.createType} created successfully!`)
341
+ );
342
+ }
343
+
344
+ /**
345
+ * Governance wizard
346
+ */
347
+ private async governWizard(): Promise<void> {
348
+ console.log(chalk.cyan('\n⚖️ Governance Setup Wizard\n'));
349
+
350
+ const answers = await inquirer.prompt([
351
+ {
352
+ type: 'checkbox',
353
+ name: 'ruleCategories',
354
+ message: 'Select rule categories to enable:',
355
+ choices: [
356
+ { name: 'Code Quality', value: 'quality', checked: true },
357
+ { name: 'Security', value: 'security', checked: true },
358
+ { name: 'Performance', value: 'performance', checked: false },
359
+ { name: 'Testing', value: 'testing', checked: true },
360
+ { name: 'Documentation', value: 'docs', checked: false },
361
+ ],
362
+ },
363
+ {
364
+ type: 'list',
365
+ name: 'severity',
366
+ message: 'Default severity level:',
367
+ choices: [
368
+ { name: 'Error (Strict)', value: 'error' },
369
+ { name: 'Warning (Balanced)', value: 'warning' },
370
+ { name: 'Info (Lenient)', value: 'info' },
371
+ ],
372
+ default: 'warning',
373
+ },
374
+ {
375
+ type: 'confirm',
376
+ name: 'createQualityGate',
377
+ message: 'Create a quality gate?',
378
+ default: true,
379
+ },
380
+ ]);
381
+
382
+ console.log(chalk.green('\n⚙️ Setting up governance rules...\n'));
383
+
384
+ // Add rules based on categories
385
+ for (const category of answers.ruleCategories) {
386
+ const rules = this.getRulesForCategory(category);
387
+ for (const rule of rules) {
388
+ const command = `wundr govern rules add ${rule}`;
389
+ console.log(chalk.blue(`Running: ${command}`));
390
+ await this.simulateCommand(command);
391
+ }
392
+ }
393
+
394
+ // Set severity
395
+ const severityCommand = `wundr govern config set severity ${answers.severity}`;
396
+ console.log(chalk.blue(`Running: ${severityCommand}`));
397
+ await this.simulateCommand(severityCommand);
398
+
399
+ // Create quality gate
400
+ if (answers.createQualityGate) {
401
+ const gateCommand =
402
+ 'wundr govern gate create default --conditions "coverage>80,complexity<10"';
403
+ console.log(chalk.blue(`Running: ${gateCommand}`));
404
+ await this.simulateCommand(gateCommand);
405
+ }
406
+
407
+ console.log(chalk.green('\n✅ Governance setup complete!'));
408
+ console.log(
409
+ chalk.gray(
410
+ '\nRun "wundr govern check" to validate your code against the rules.'
411
+ )
412
+ );
413
+ }
414
+
415
+ /**
416
+ * General purpose wizard
417
+ */
418
+ private async generalWizard(): Promise<void> {
419
+ console.log(chalk.cyan('\n🧙 Wundr CLI Wizard\n'));
420
+
421
+ const answers = await inquirer.prompt([
422
+ {
423
+ type: 'list',
424
+ name: 'action',
425
+ message: 'What would you like to do?',
426
+ choices: [
427
+ { name: 'Setup a new project', value: 'setup' },
428
+ { name: 'Analyze existing code', value: 'analyze' },
429
+ { name: 'Create new code', value: 'create' },
430
+ { name: 'Setup governance', value: 'govern' },
431
+ { name: 'Configure AI features', value: 'ai' },
432
+ { name: 'Launch dashboard', value: 'dashboard' },
433
+ ],
434
+ },
435
+ ]);
436
+
437
+ switch (answers.action) {
438
+ case 'setup':
439
+ await this.setupWizard();
440
+ break;
441
+ case 'analyze':
442
+ await this.analyzeWizard();
443
+ break;
444
+ case 'create':
445
+ await this.createWizard();
446
+ break;
447
+ case 'govern':
448
+ await this.governWizard();
449
+ break;
450
+ case 'ai':
451
+ await this.aiConfigWizard();
452
+ break;
453
+ case 'dashboard':
454
+ await this.launchDashboard();
455
+ break;
456
+ }
457
+ }
458
+
459
+ /**
460
+ * AI configuration wizard
461
+ */
462
+ private async aiConfigWizard(): Promise<void> {
463
+ console.log(chalk.cyan('\n🤖 AI Configuration Wizard\n'));
464
+
465
+ const answers = await inquirer.prompt([
466
+ {
467
+ type: 'list',
468
+ name: 'provider',
469
+ message: 'AI Provider:',
470
+ choices: [
471
+ { name: 'Claude (Anthropic)', value: 'claude' },
472
+ { name: 'ChatGPT (OpenAI)', value: 'openai' },
473
+ { name: 'Local Model', value: 'local' },
474
+ ],
475
+ },
476
+ {
477
+ type: 'list',
478
+ name: 'model',
479
+ message: 'Model:',
480
+ choices: answers => {
481
+ switch (answers.provider) {
482
+ case 'claude':
483
+ return ['claude-3', 'claude-3-haiku', 'claude-3-sonnet'];
484
+ case 'openai':
485
+ return ['gpt-4', 'gpt-4-turbo', 'gpt-3.5-turbo'];
486
+ case 'local':
487
+ return ['llama2', 'codellama', 'custom'];
488
+ default:
489
+ return ['claude-3'];
490
+ }
491
+ },
492
+ },
493
+ {
494
+ type: 'password',
495
+ name: 'apiKey',
496
+ message: 'API Key:',
497
+ mask: '*',
498
+ when: answers => answers.provider !== 'local',
499
+ },
500
+ {
501
+ type: 'checkbox',
502
+ name: 'features',
503
+ message: 'Enable AI features:',
504
+ choices: [
505
+ { name: 'Code Generation', value: 'generate', checked: true },
506
+ { name: 'Code Review', value: 'review', checked: true },
507
+ { name: 'Refactoring', value: 'refactor', checked: false },
508
+ { name: 'Documentation', value: 'docs', checked: true },
509
+ { name: 'Test Generation', value: 'test', checked: false },
510
+ ],
511
+ },
512
+ ]);
513
+
514
+ console.log(chalk.green('\n🔧 Configuring AI features...\n'));
515
+
516
+ // Set AI configuration
517
+ const commands = [
518
+ `wundr ai config set provider ${answers.provider}`,
519
+ `wundr ai config set model ${answers.model}`,
520
+ ];
521
+
522
+ if (answers.apiKey) {
523
+ commands.push(`wundr ai config set apiKey ${answers.apiKey}`);
524
+ }
525
+
526
+ for (const command of commands) {
527
+ console.log(chalk.blue(`Running: ${command}`));
528
+ await this.simulateCommand(command);
529
+ }
530
+
531
+ console.log(chalk.green('\n✅ AI configuration complete!'));
532
+ console.log(chalk.gray('\nTry "wundr ai ask" to start chatting with AI.'));
533
+ }
534
+
535
+ /**
536
+ * Launch dashboard shortcut
537
+ */
538
+ private async launchDashboard(): Promise<void> {
539
+ console.log(chalk.green('\n📊 Launching Wundr Dashboard...\n'));
540
+
541
+ const command = 'wundr dashboard start --open';
542
+ console.log(chalk.blue(`Running: ${command}`));
543
+ await this.simulateCommand(command);
544
+ }
545
+
546
+ /**
547
+ * Setup TUI layout
548
+ */
549
+ private async setupTUILayout(screen: any, layoutType: string): Promise<void> {
550
+ switch (layoutType) {
551
+ case 'dashboard':
552
+ await this.setupDashboardLayout(screen);
553
+ break;
554
+ case 'monitor':
555
+ await this.setupMonitorLayout(screen);
556
+ break;
557
+ case 'debug':
558
+ await this.setupDebugLayout(screen);
559
+ break;
560
+ default:
561
+ await this.setupDashboardLayout(screen);
562
+ }
563
+ }
564
+
565
+ /**
566
+ * Setup dashboard TUI layout
567
+ */
568
+ private async setupDashboardLayout(screen: any): Promise<void> {
569
+ // Header
570
+ const header = blessed.box({
571
+ top: 0,
572
+ left: 0,
573
+ width: '100%',
574
+ height: 3,
575
+ content: `{center}${chalk.cyan('🚀 Wundr CLI Dashboard')}{/center}`,
576
+ tags: true,
577
+ border: {
578
+ type: 'line',
579
+ },
580
+ style: {
581
+ fg: 'white',
582
+ bg: 'blue',
583
+ border: {
584
+ fg: '#f0f0f0',
585
+ },
586
+ },
587
+ });
588
+
589
+ // Sidebar
590
+ const sidebar = blessed.box({
591
+ top: 3,
592
+ left: 0,
593
+ width: '25%',
594
+ height: '100%-6',
595
+ content:
596
+ 'Navigation\n\n→ Overview\n Analysis\n Governance\n AI Tools\n Settings',
597
+ border: {
598
+ type: 'line',
599
+ },
600
+ style: {
601
+ fg: 'white',
602
+ border: {
603
+ fg: '#f0f0f0',
604
+ },
605
+ },
606
+ });
607
+
608
+ // Main content
609
+ const main = blessed.box({
610
+ top: 3,
611
+ left: '25%',
612
+ width: '75%',
613
+ height: '100%-6',
614
+ content:
615
+ 'Project Overview\n\n' +
616
+ '📁 Files: 1,234\n' +
617
+ '🔍 Issues: 5\n' +
618
+ '✅ Tests: 98% coverage\n' +
619
+ '📦 Dependencies: 45\n' +
620
+ '🚀 Performance: Good',
621
+ border: {
622
+ type: 'line',
623
+ },
624
+ style: {
625
+ fg: 'white',
626
+ border: {
627
+ fg: '#f0f0f0',
628
+ },
629
+ },
630
+ });
631
+
632
+ // Footer
633
+ const footer = blessed.box({
634
+ bottom: 0,
635
+ left: 0,
636
+ width: '100%',
637
+ height: 3,
638
+ content: '{center}Press q or Esc to exit{/center}',
639
+ tags: true,
640
+ border: {
641
+ type: 'line',
642
+ },
643
+ style: {
644
+ fg: 'white',
645
+ bg: 'black',
646
+ border: {
647
+ fg: '#f0f0f0',
648
+ },
649
+ },
650
+ });
651
+
652
+ screen.append(header);
653
+ screen.append(sidebar);
654
+ screen.append(main);
655
+ screen.append(footer);
656
+
657
+ // Focus handling
658
+ main.focus();
659
+ }
660
+
661
+ /**
662
+ * Setup monitor TUI layout
663
+ */
664
+ private async setupMonitorLayout(screen: any): Promise<void> {
665
+ // Real-time monitoring layout with logs and metrics
666
+ const log = blessed.log({
667
+ top: 0,
668
+ left: 0,
669
+ width: '100%',
670
+ height: '100%',
671
+ border: {
672
+ type: 'line',
673
+ },
674
+ style: {
675
+ fg: 'white',
676
+ border: {
677
+ fg: '#f0f0f0',
678
+ },
679
+ },
680
+ scrollable: true,
681
+ alwaysScroll: true,
682
+ });
683
+
684
+ screen.append(log);
685
+
686
+ // Simulate log entries
687
+ setInterval(() => {
688
+ log.log(`[${new Date().toLocaleTimeString()}] Monitoring active...`);
689
+ }, 2000);
690
+
691
+ log.focus();
692
+ }
693
+
694
+ /**
695
+ * Setup debug TUI layout
696
+ */
697
+ private async setupDebugLayout(screen: any): Promise<void> {
698
+ // Debug information layout
699
+ const debugInfo = blessed.box({
700
+ top: 0,
701
+ left: 0,
702
+ width: '100%',
703
+ height: '100%',
704
+ content:
705
+ 'Debug Information\n\n' +
706
+ 'CLI Version: 1.0.0\n' +
707
+ 'Node Version: ' +
708
+ process.version +
709
+ '\n' +
710
+ 'Platform: ' +
711
+ process.platform +
712
+ '\n' +
713
+ 'Working Directory: ' +
714
+ process.cwd() +
715
+ '\n' +
716
+ 'Arguments: ' +
717
+ process.argv.join(' '),
718
+ border: {
719
+ type: 'line',
720
+ },
721
+ style: {
722
+ fg: 'white',
723
+ border: {
724
+ fg: '#f0f0f0',
725
+ },
726
+ },
727
+ });
728
+
729
+ screen.append(debugInfo);
730
+ debugInfo.focus();
731
+ }
732
+
733
+ /**
734
+ * Helper methods for wizard options
735
+ */
736
+ private async getComponentOptions(): Promise<any> {
737
+ return await inquirer.prompt([
738
+ {
739
+ type: 'list',
740
+ name: 'type',
741
+ message: 'Component type:',
742
+ choices: ['react', 'vue', 'angular'],
743
+ default: 'react',
744
+ },
745
+ {
746
+ type: 'confirm',
747
+ name: 'withTests',
748
+ message: 'Generate test files?',
749
+ default: true,
750
+ },
751
+ {
752
+ type: 'confirm',
753
+ name: 'withStories',
754
+ message: 'Generate Storybook stories?',
755
+ default: false,
756
+ },
757
+ ]);
758
+ }
759
+
760
+ private async getServiceOptions(): Promise<any> {
761
+ return await inquirer.prompt([
762
+ {
763
+ type: 'list',
764
+ name: 'type',
765
+ message: 'Service type:',
766
+ choices: ['api', 'worker', 'microservice'],
767
+ default: 'api',
768
+ },
769
+ {
770
+ type: 'list',
771
+ name: 'framework',
772
+ message: 'Framework:',
773
+ choices: ['express', 'fastify', 'nest'],
774
+ default: 'express',
775
+ },
776
+ {
777
+ type: 'confirm',
778
+ name: 'withTests',
779
+ message: 'Generate test files?',
780
+ default: true,
781
+ },
782
+ {
783
+ type: 'confirm',
784
+ name: 'withDocs',
785
+ message: 'Generate API documentation?',
786
+ default: true,
787
+ },
788
+ ]);
789
+ }
790
+
791
+ private async getPackageOptions(): Promise<any> {
792
+ return await inquirer.prompt([
793
+ {
794
+ type: 'list',
795
+ name: 'type',
796
+ message: 'Package type:',
797
+ choices: ['library', 'app', 'tool'],
798
+ default: 'library',
799
+ },
800
+ {
801
+ type: 'confirm',
802
+ name: 'public',
803
+ message: 'Make package public?',
804
+ default: false,
805
+ },
806
+ ]);
807
+ }
808
+
809
+ private getRulesForCategory(category: string): string[] {
810
+ const rulesByCategory = {
811
+ quality: ['no-console', 'no-debugger', 'prefer-const'],
812
+ security: ['no-eval', 'no-unsafe-inline'],
813
+ performance: ['no-inefficient-loops', 'prefer-map-over-loop'],
814
+ testing: ['require-tests', 'no-skip-tests'],
815
+ docs: ['require-jsdoc', 'require-readme'],
816
+ };
817
+
818
+ return rulesByCategory[category as keyof typeof rulesByCategory] || [];
819
+ }
820
+
821
+ private async simulateCommand(command: string): Promise<void> {
822
+ // Simulate command execution with a delay
823
+ return new Promise(resolve => {
824
+ setTimeout(() => {
825
+ console.log(chalk.green(` ✓ ${command}`));
826
+ resolve();
827
+ }, 500);
828
+ });
829
+ }
830
+ }