@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,709 @@
1
+ /**
2
+ * Computer Setup Commands
3
+ * Integrates real setup orchestrator for provisioning developer machines
4
+ */
5
+
6
+ import { Command } from 'commander';
7
+ import chalk from 'chalk';
8
+ import ora from 'ora';
9
+ import inquirer from 'inquirer';
10
+ import { ConfigManager } from '../utils/config-manager';
11
+ import { PluginManager } from '../plugins/plugin-manager';
12
+ import { logger } from '../utils/logger';
13
+ import { execSync } from 'child_process';
14
+ import * as os from 'os';
15
+ import * as fs from 'fs/promises';
16
+ // Note: Using relative path import due to workspace resolution issues in this monorepo setup
17
+ // The computer-setup package must be built first before building this CLI package
18
+ import {
19
+ SetupPlatform,
20
+ SetupProgress,
21
+ SetupResult,
22
+ RealSetupOrchestrator,
23
+ DeveloperProfile,
24
+ } from '../../../computer-setup/dist';
25
+
26
+ // Additional local types
27
+ interface LocalSetupOptions {
28
+ profile?: string;
29
+ team?: string;
30
+ mode?: string;
31
+ os?: string;
32
+ dryRun?: boolean;
33
+ skipExisting?: boolean;
34
+ parallel?: boolean;
35
+ report?: boolean;
36
+ }
37
+
38
+ export class ComputerSetupCommands {
39
+ private orchestrator: RealSetupOrchestrator;
40
+ private platform: SetupPlatform;
41
+
42
+ constructor(
43
+ private program: Command,
44
+ private configManager: ConfigManager,
45
+ private pluginManager: PluginManager
46
+ ) {
47
+ this.platform = this.detectPlatform();
48
+ this.orchestrator = new RealSetupOrchestrator(this.platform);
49
+ this.registerCommands();
50
+ }
51
+
52
+ private registerCommands(): void {
53
+ const computerSetup = this.program
54
+ .command('computer-setup')
55
+ .alias('setup-machine')
56
+ .alias('provision')
57
+ .description(
58
+ 'Set up a new developer machine with all required tools and configurations'
59
+ )
60
+ .addHelpText(
61
+ 'after',
62
+ chalk.gray(`
63
+ Examples:
64
+ ${chalk.green('wundr computer-setup')} Interactive setup for new machine
65
+ ${chalk.green('wundr computer-setup --profile frontend')} Use frontend developer profile
66
+ ${chalk.green('wundr computer-setup --team platform')} Apply platform team configuration
67
+ ${chalk.green('wundr computer-setup doctor')} Diagnose setup issues
68
+ ${chalk.green('wundr computer-setup validate')} Validate current setup
69
+ `)
70
+ );
71
+
72
+ // Main setup command
73
+ computerSetup
74
+ .command('run', { isDefault: true })
75
+ .description('Run computer setup for new developer machine')
76
+ .option(
77
+ '-p, --profile <profile>',
78
+ 'Use specific profile (frontend, backend, fullstack, devops)'
79
+ )
80
+ .option('-t, --team <team>', 'Apply team-specific configurations')
81
+ .option('-m, --mode <mode>', 'Setup mode', 'interactive')
82
+ .option('--os <os>', 'Target OS (auto-detected by default)')
83
+ .option(
84
+ '--dry-run',
85
+ 'Show what would be installed without making changes'
86
+ )
87
+ .option('--skip-existing', 'Skip tools that are already installed')
88
+ .option('--parallel', 'Install tools in parallel where possible')
89
+ .option('--report', 'Generate detailed setup report')
90
+ .action(async options => {
91
+ await this.runSetup(options);
92
+ });
93
+
94
+ // Resume command
95
+ computerSetup
96
+ .command('resume')
97
+ .description('Resume failed setup from saved state')
98
+ .action(async () => {
99
+ await this.resumeSetup();
100
+ });
101
+
102
+ // List profiles command
103
+ computerSetup
104
+ .command('list-profiles')
105
+ .description('List available developer profiles')
106
+ .action(async () => {
107
+ await this.listAvailableProfiles();
108
+ });
109
+
110
+ // Profile management
111
+ computerSetup
112
+ .command('profile')
113
+ .description('Manage developer profiles')
114
+ .option('-l, --list', 'List available profiles')
115
+ .option('-c, --create', 'Create new profile')
116
+ .option('-e, --edit <name>', 'Edit existing profile')
117
+ .option('-d, --delete <name>', 'Delete profile')
118
+ .option('--export <path>', 'Export profiles')
119
+ .option('--import <path>', 'Import profiles')
120
+ .action(async options => {
121
+ await this.manageProfiles(options);
122
+ });
123
+
124
+ // Team configuration
125
+ computerSetup
126
+ .command('team')
127
+ .description('Manage team configurations')
128
+ .argument('[team]', 'Team identifier')
129
+ .option('--download', 'Download team configuration')
130
+ .option('--apply', 'Apply team configuration')
131
+ .option('--sync', 'Sync with team repository')
132
+ .action(async (team, options) => {
133
+ await this.manageTeamConfig(team, options);
134
+ });
135
+
136
+ // Validation
137
+ computerSetup
138
+ .command('validate')
139
+ .description('Validate current machine setup')
140
+ .option('--profile <profile>', 'Validate against specific profile')
141
+ .option('--fix', 'Attempt to fix issues')
142
+ .option('--report', 'Generate validation report')
143
+ .action(async options => {
144
+ await this.validateSetup(options);
145
+ });
146
+
147
+ // Doctor - diagnose issues
148
+ computerSetup
149
+ .command('doctor')
150
+ .description('Diagnose and fix common setup issues')
151
+ .option('--check <tool>', 'Check specific tool')
152
+ .option('--fix', 'Attempt automatic fixes')
153
+ .option('--verbose', 'Show detailed diagnostics')
154
+ .action(async options => {
155
+ await this.runDoctor(options);
156
+ });
157
+
158
+ // Tool-specific setup commands
159
+ computerSetup
160
+ .command('install')
161
+ .description('Install specific tools')
162
+ .argument('<tool>', 'Tool to install (node, python, docker, etc.)')
163
+ .option('--version <version>', 'Specific version to install')
164
+ .option('--global', 'Install globally')
165
+ .action(async (tool, options) => {
166
+ await this.installTool(tool, options);
167
+ });
168
+ }
169
+
170
+ private async runSetup(options: any): Promise<void> {
171
+ console.log(chalk.cyan('\nšŸ–„ļø Wundr Computer Setup'));
172
+ console.log(chalk.gray('Setting up your development machine...\n'));
173
+
174
+ try {
175
+ // Check for resumable setup
176
+ const canResume = await this.orchestrator.canResume();
177
+ if (canResume) {
178
+ const { resume } = await inquirer.prompt([
179
+ {
180
+ type: 'confirm',
181
+ name: 'resume',
182
+ message: 'Found incomplete setup. Resume from where you left off?',
183
+ default: true,
184
+ },
185
+ ]);
186
+
187
+ if (resume) {
188
+ return await this.resumeSetup();
189
+ }
190
+ }
191
+
192
+ // Get profile
193
+ let profileName = options.profile;
194
+ if (!profileName) {
195
+ if (options.mode === 'interactive') {
196
+ profileName = await this.selectProfile();
197
+ } else {
198
+ profileName = 'fullstack'; // Default
199
+ }
200
+ }
201
+
202
+ // Validate profile
203
+ const availableProfiles = this.orchestrator.getAvailableProfiles();
204
+ const profile = availableProfiles.find(p =>
205
+ p.name.toLowerCase().includes(profileName.toLowerCase())
206
+ );
207
+
208
+ if (!profile) {
209
+ console.error(chalk.red(`āŒ Unknown profile: ${profileName}`));
210
+ console.log(chalk.cyan('\nAvailable profiles:'));
211
+ availableProfiles.forEach(p =>
212
+ console.log(` • ${p.name}: ${p.description}`)
213
+ );
214
+ return;
215
+ }
216
+
217
+ console.log(
218
+ chalk.cyan(`\nšŸ“‹ Selected Profile: ${chalk.white(profile.name)}`)
219
+ );
220
+ console.log(chalk.gray(`${profile.description}`));
221
+ console.log(
222
+ chalk.gray(`Estimated time: ${profile.estimatedTimeMinutes} minutes\n`)
223
+ );
224
+
225
+ // Show what will be installed
226
+ console.log(chalk.cyan('šŸ› ļø Tools to install:'));
227
+ profile.requiredTools.forEach(tool => console.log(` • ${tool}`));
228
+
229
+ if (profile.optionalTools.length > 0) {
230
+ console.log(chalk.cyan('\nšŸ”§ Optional tools:'));
231
+ profile.optionalTools.forEach(tool => console.log(` • ${tool}`));
232
+ }
233
+
234
+ if (options.dryRun) {
235
+ console.log(chalk.yellow('\nāš ļø DRY RUN - No changes will be made'));
236
+ return;
237
+ }
238
+
239
+ // Confirm before proceeding
240
+ if (options.mode === 'interactive') {
241
+ const { proceed } = await inquirer.prompt([
242
+ {
243
+ type: 'confirm',
244
+ name: 'proceed',
245
+ message: 'Proceed with setup?',
246
+ default: true,
247
+ },
248
+ ]);
249
+
250
+ if (!proceed) {
251
+ console.log(chalk.yellow('Setup cancelled'));
252
+ return;
253
+ }
254
+ }
255
+
256
+ // Run the orchestrator with progress tracking
257
+ const progressCallback = (progress: SetupProgress) => {
258
+ // Update progress display
259
+ process.stdout.clearLine(0);
260
+ process.stdout.cursorTo(0);
261
+ process.stdout.write(
262
+ `${chalk.cyan('[')}${progress.percentage.toFixed(1)}%${chalk.cyan(']')} ${progress.currentStep}`
263
+ );
264
+ };
265
+
266
+ console.log(chalk.cyan('\nšŸš€ Starting setup...\n'));
267
+
268
+ const result: SetupResult = await this.orchestrator.orchestrate(
269
+ profileName,
270
+ {
271
+ dryRun: options.dryRun,
272
+ skipExisting: options.skipExisting,
273
+ parallel: options.parallel,
274
+ generateReport: options.report,
275
+ },
276
+ progressCallback
277
+ );
278
+
279
+ console.log('\n'); // New line after progress
280
+
281
+ if (result.success) {
282
+ console.log(chalk.green('āœ… Computer setup completed successfully!'));
283
+ console.log(
284
+ chalk.gray(
285
+ `Setup took ${Math.round(result.duration / 1000)} seconds\n`
286
+ )
287
+ );
288
+
289
+ if (result.completedSteps.length > 0) {
290
+ console.log(
291
+ chalk.cyan(`šŸŽÆ Completed steps (${result.completedSteps.length}):`)
292
+ );
293
+ result.completedSteps
294
+ .slice(0, 5)
295
+ .forEach(step => console.log(` āœ… ${step}`));
296
+ if (result.completedSteps.length > 5) {
297
+ console.log(` ... and ${result.completedSteps.length - 5} more`);
298
+ }
299
+ }
300
+
301
+ if (result.skippedSteps.length > 0) {
302
+ console.log(
303
+ chalk.yellow(`ā­ļø Skipped steps (${result.skippedSteps.length}):`)
304
+ );
305
+ result.skippedSteps.forEach(step => console.log(` ā­ļø ${step}`));
306
+ }
307
+
308
+ this.displayNextSteps();
309
+ } else {
310
+ console.log(chalk.red('āŒ Setup failed!'));
311
+
312
+ if (result.failedSteps.length > 0) {
313
+ console.log(
314
+ chalk.red(`Failed steps (${result.failedSteps.length}):`)
315
+ );
316
+ result.failedSteps.forEach(step => console.log(` āŒ ${step}`));
317
+ }
318
+
319
+ if (result.errors.length > 0) {
320
+ console.log(chalk.red('\nErrors:'));
321
+ result.errors.forEach(error => console.log(` • ${error.message}`));
322
+ }
323
+
324
+ console.log(
325
+ chalk.cyan(
326
+ '\nšŸ’” You can resume setup by running: wundr computer-setup resume'
327
+ )
328
+ );
329
+ process.exit(1);
330
+ }
331
+ } catch (error) {
332
+ console.error(chalk.red('\nāŒ Setup failed with error:'), error);
333
+ console.log(
334
+ chalk.cyan(
335
+ '\nšŸ’” You can resume setup by running: wundr computer-setup resume'
336
+ )
337
+ );
338
+ process.exit(1);
339
+ }
340
+ }
341
+
342
+ private async manageProfiles(options: any): Promise<void> {
343
+ if (options.list) {
344
+ const profiles = await this.listProfiles();
345
+ console.log(chalk.cyan('\nšŸ“‹ Available Profiles:\n'));
346
+ profiles.forEach(p => {
347
+ console.log(chalk.white(` • ${p.name} (${p.role})`));
348
+ });
349
+ } else if (options.create) {
350
+ await this.createInteractiveProfile();
351
+ } else if (options.edit) {
352
+ await this.editProfile(options.edit);
353
+ } else if (options.delete) {
354
+ await this.deleteProfile(options.delete);
355
+ } else if (options.export) {
356
+ await this.exportProfiles(options.export);
357
+ } else if (options.import) {
358
+ await this.importProfiles(options.import);
359
+ }
360
+ }
361
+
362
+ private async validateSetup(options: any): Promise<void> {
363
+ const spinner = ora('Validating setup...').start();
364
+
365
+ const checks = [
366
+ { name: 'Node.js', cmd: 'node --version', required: true },
367
+ { name: 'Git', cmd: 'git --version', required: true },
368
+ { name: 'Docker', cmd: 'docker --version', required: false },
369
+ { name: 'Claude Code', cmd: 'claude --version', required: false },
370
+ ];
371
+
372
+ const results: any[] = [];
373
+
374
+ for (const check of checks) {
375
+ try {
376
+ // Would execute command and check
377
+ results.push({ ...check, status: 'passed' });
378
+ } catch (error) {
379
+ results.push({ ...check, status: 'failed' });
380
+ }
381
+ }
382
+
383
+ spinner.stop();
384
+
385
+ console.log(chalk.cyan('\nšŸ” Validation Results:\n'));
386
+ results.forEach(r => {
387
+ const icon = r.status === 'passed' ? 'āœ…' : 'āŒ';
388
+ const color = r.status === 'passed' ? chalk.green : chalk.red;
389
+ console.log(color(` ${icon} ${r.name}`));
390
+ });
391
+
392
+ if (options.fix) {
393
+ await this.attemptFixes(results.filter(r => r.status === 'failed'));
394
+ }
395
+ }
396
+
397
+ private async runDoctor(options: any): Promise<void> {
398
+ console.log(chalk.cyan('\nšŸ„ Computer Setup Doctor\n'));
399
+
400
+ const diagnostics = [
401
+ 'Checking system requirements...',
402
+ 'Verifying network connectivity...',
403
+ 'Checking disk space...',
404
+ 'Validating permissions...',
405
+ 'Checking installed tools...',
406
+ 'Verifying configurations...',
407
+ ];
408
+
409
+ for (const diagnostic of diagnostics) {
410
+ const spinner = ora(diagnostic).start();
411
+ await new Promise(resolve => setTimeout(resolve, 500));
412
+ spinner.succeed();
413
+ }
414
+
415
+ console.log(chalk.green('\nāœ… All checks passed!'));
416
+ console.log(chalk.cyan('\nšŸ’Š Recommendations:'));
417
+ console.log(' 1. Keep your tools updated');
418
+ console.log(' 2. Regular security updates');
419
+ console.log(' 3. Backup your configurations');
420
+ }
421
+
422
+ private async createInteractiveProfile(): Promise<any> {
423
+ console.log(chalk.cyan('\nšŸ‘¤ Create Developer Profile\n'));
424
+
425
+ const answers = await inquirer.prompt([
426
+ {
427
+ type: 'input',
428
+ name: 'name',
429
+ message: 'Your name:',
430
+ validate: input => input.length > 0,
431
+ },
432
+ {
433
+ type: 'input',
434
+ name: 'email',
435
+ message: 'Your email:',
436
+ validate: input => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input),
437
+ },
438
+ {
439
+ type: 'list',
440
+ name: 'role',
441
+ message: 'Your role:',
442
+ choices: [
443
+ 'Frontend Developer',
444
+ 'Backend Developer',
445
+ 'Full Stack Developer',
446
+ 'DevOps Engineer',
447
+ 'Machine Learning Engineer',
448
+ 'Mobile Developer',
449
+ ],
450
+ },
451
+ {
452
+ type: 'checkbox',
453
+ name: 'tools',
454
+ message: 'Select tools to install:',
455
+ choices: [
456
+ { name: 'Node.js', checked: true },
457
+ { name: 'Python' },
458
+ { name: 'Docker', checked: true },
459
+ { name: 'Kubernetes' },
460
+ { name: 'AWS CLI' },
461
+ { name: 'Claude Code', checked: true },
462
+ { name: 'GitHub CLI', checked: true },
463
+ ],
464
+ },
465
+ ]);
466
+
467
+ console.log(chalk.green('\nāœ… Profile created successfully!'));
468
+
469
+ // Map answers to DeveloperProfile structure
470
+ const profile: DeveloperProfile = {
471
+ name: 'custom',
472
+ role: answers.role,
473
+ languages: {
474
+ javascript: answers.tools.includes('Node.js'),
475
+ typescript: answers.tools.includes('TypeScript'),
476
+ python: answers.tools.includes('Python'),
477
+ },
478
+ frameworks: {},
479
+ tools: {
480
+ packageManagers: {
481
+ npm: answers.tools.includes('Node.js'),
482
+ yarn: answers.tools.includes('Yarn'),
483
+ pnpm: answers.tools.includes('pnpm'),
484
+ },
485
+ containers: {
486
+ docker: answers.tools.includes('Docker'),
487
+ dockerCompose: answers.tools.includes('Docker'),
488
+ kubernetes: answers.tools.includes('Kubernetes'),
489
+ },
490
+ editors: {
491
+ vscode: answers.tools.includes('VS Code'),
492
+ vim: answers.tools.includes('Vim'),
493
+ claude: answers.tools.includes('Claude Code'),
494
+ },
495
+ databases: {
496
+ postgresql: answers.tools.includes('PostgreSQL'),
497
+ mysql: answers.tools.includes('MySQL'),
498
+ mongodb: answers.tools.includes('MongoDB'),
499
+ redis: answers.tools.includes('Redis'),
500
+ },
501
+ },
502
+ };
503
+
504
+ return profile;
505
+ }
506
+
507
+ private detectPlatform(os?: string): SetupPlatform {
508
+ return {
509
+ os: (os || process.platform) as 'darwin' | 'linux' | 'win32',
510
+ arch: process.arch as 'x64' | 'arm64',
511
+ version: process.version,
512
+ node: process.version,
513
+ shell: process.env.SHELL,
514
+ };
515
+ }
516
+
517
+ private async selectProfile(): Promise<string> {
518
+ const profiles = this.orchestrator.getAvailableProfiles();
519
+
520
+ const { selectedProfile } = await inquirer.prompt([
521
+ {
522
+ type: 'list',
523
+ name: 'selectedProfile',
524
+ message: 'Select a developer profile:',
525
+ choices: profiles.map(p => ({
526
+ name: `${p.name} - ${p.description}`,
527
+ value: p.name.toLowerCase().replace(' ', ''),
528
+ short: p.name,
529
+ })),
530
+ },
531
+ ]);
532
+
533
+ return selectedProfile;
534
+ }
535
+
536
+ private async resumeSetup(): Promise<void> {
537
+ console.log(chalk.cyan('\nšŸ”„ Resuming setup from saved state...\n'));
538
+
539
+ const progressCallback = (progress: SetupProgress) => {
540
+ process.stdout.clearLine(0);
541
+ process.stdout.cursorTo(0);
542
+ process.stdout.write(
543
+ `${chalk.cyan('[')}${progress.percentage.toFixed(1)}%${chalk.cyan(']')} ${progress.currentStep}`
544
+ );
545
+ };
546
+
547
+ try {
548
+ const result = await this.orchestrator.resume(progressCallback);
549
+ console.log('\n'); // New line after progress
550
+
551
+ if (result.success) {
552
+ console.log(
553
+ chalk.green('āœ… Setup resumed and completed successfully!')
554
+ );
555
+ this.displayNextSteps();
556
+ } else {
557
+ console.log(chalk.red('āŒ Resume failed!'));
558
+ if (result.errors.length > 0) {
559
+ console.log(chalk.red('Errors:'));
560
+ result.errors.forEach(error => console.log(` • ${error.message}`));
561
+ }
562
+ process.exit(1);
563
+ }
564
+ } catch (error) {
565
+ console.error(chalk.red('āŒ Resume failed:'), error);
566
+ process.exit(1);
567
+ }
568
+ }
569
+
570
+ private async listAvailableProfiles(): Promise<void> {
571
+ console.log(chalk.cyan('\nšŸ‘¤ Available Developer Profiles:\n'));
572
+
573
+ const profiles = this.orchestrator.getAvailableProfiles();
574
+ profiles.forEach(profile => {
575
+ console.log(chalk.white(`šŸ“‹ ${profile.name}`));
576
+ console.log(chalk.gray(` ${profile.description}`));
577
+ console.log(
578
+ chalk.gray(` Categories: ${profile.categories.join(', ')}`)
579
+ );
580
+ console.log(chalk.gray(` Tools: ${profile.requiredTools.join(', ')}`));
581
+ console.log(
582
+ chalk.gray(` Estimated time: ${profile.estimatedTimeMinutes} minutes`)
583
+ );
584
+ console.log();
585
+ });
586
+
587
+ console.log(
588
+ chalk.cyan('Usage: wundr computer-setup --profile <profile-name>')
589
+ );
590
+ console.log(
591
+ chalk.gray('Example: wundr computer-setup --profile frontend\n')
592
+ );
593
+ }
594
+
595
+ private generateSetupSteps(profile: any, platform: any): any[] {
596
+ const steps: Array<{ name: string; required: boolean }> = [];
597
+
598
+ // Platform-specific setup
599
+ if (platform.os === 'darwin') {
600
+ steps.push({ name: 'Install Homebrew', required: true });
601
+ steps.push({ name: 'Install Xcode Command Line Tools', required: true });
602
+ }
603
+
604
+ // Common tools
605
+ steps.push({ name: 'Configure Git', required: true });
606
+ steps.push({ name: 'Generate SSH keys', required: true });
607
+
608
+ // Profile-specific tools
609
+ if (profile.tools?.includes('Node.js')) {
610
+ steps.push({ name: 'Install Node.js via nvm', required: true });
611
+ steps.push({ name: 'Install pnpm', required: true });
612
+ }
613
+
614
+ if (profile.tools?.includes('Docker')) {
615
+ steps.push({ name: 'Install Docker Desktop', required: false });
616
+ }
617
+
618
+ if (profile.tools?.includes('Claude Code')) {
619
+ steps.push({ name: 'Install Claude Code', required: false });
620
+ steps.push({ name: 'Configure Claude Flow', required: false });
621
+ }
622
+
623
+ // Final steps
624
+ steps.push({ name: 'Configure shell environment', required: true });
625
+ steps.push({ name: 'Install VS Code extensions', required: false });
626
+
627
+ return steps;
628
+ }
629
+
630
+ private async executeSetupStep(step: any, options: any): Promise<void> {
631
+ // Simulate execution
632
+ await new Promise(resolve => setTimeout(resolve, 500));
633
+
634
+ if (Math.random() > 0.95 && !step.required) {
635
+ throw new Error('Simulated error');
636
+ }
637
+ }
638
+
639
+ private displayNextSteps(): void {
640
+ console.log(chalk.cyan('\nšŸ“ Next Steps:\n'));
641
+ const steps = [
642
+ 'Restart your terminal to apply changes',
643
+ 'Run "wundr computer-setup validate" to verify',
644
+ 'Sign in to your team tools (Slack, GitHub, etc.)',
645
+ 'Clone your team repositories',
646
+ 'Review team documentation',
647
+ ];
648
+
649
+ steps.forEach((step, i) => {
650
+ console.log(chalk.white(` ${i + 1}. ${step}`));
651
+ });
652
+ }
653
+
654
+ private async loadProfile(name: string): Promise<any> {
655
+ // Load profile from config
656
+ return {
657
+ name: name,
658
+ role: 'fullstack',
659
+ tools: ['Node.js', 'Docker', 'Claude Code'],
660
+ };
661
+ }
662
+
663
+ private async getDefaultProfile(): Promise<any> {
664
+ return {
665
+ name: 'default',
666
+ role: 'fullstack',
667
+ tools: ['Node.js', 'Git'],
668
+ };
669
+ }
670
+
671
+ private async listProfiles(): Promise<any[]> {
672
+ return [
673
+ { name: 'frontend', role: 'Frontend Developer' },
674
+ { name: 'backend', role: 'Backend Developer' },
675
+ { name: 'fullstack', role: 'Full Stack Developer' },
676
+ ];
677
+ }
678
+
679
+ private async editProfile(name: string): Promise<void> {
680
+ console.log(chalk.cyan(`Editing profile: ${name}`));
681
+ }
682
+
683
+ private async deleteProfile(name: string): Promise<void> {
684
+ console.log(chalk.yellow(`Deleting profile: ${name}`));
685
+ }
686
+
687
+ private async exportProfiles(path: string): Promise<void> {
688
+ console.log(chalk.green(`Profiles exported to: ${path}`));
689
+ }
690
+
691
+ private async importProfiles(path: string): Promise<void> {
692
+ console.log(chalk.green(`Profiles imported from: ${path}`));
693
+ }
694
+
695
+ private async manageTeamConfig(team: string, options: any): Promise<void> {
696
+ console.log(chalk.cyan(`Managing team configuration: ${team}`));
697
+ }
698
+
699
+ private async installTool(tool: string, options: any): Promise<void> {
700
+ console.log(chalk.cyan(`Installing ${tool}...`));
701
+ }
702
+
703
+ private async attemptFixes(failures: any[]): Promise<void> {
704
+ console.log(chalk.yellow('\nAttempting fixes...'));
705
+ for (const failure of failures) {
706
+ console.log(chalk.gray(` Fixing ${failure.name}...`));
707
+ }
708
+ }
709
+ }