@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,565 @@
1
+ /**
2
+ * Computer setup command for provisioning new developer machines
3
+ * Integrates new-starter functionality into the unified wundr CLI
4
+ */
5
+
6
+ import { Command } from 'commander';
7
+ import chalk from 'chalk';
8
+ import ora from 'ora';
9
+ import inquirer from 'inquirer';
10
+ import { ComputerSetupManager } from '@wundr.io/computer-setup';
11
+ // import { getLogger } from '@wundr/core';
12
+ const logger = { info: console.log, error: console.error, warn: console.warn };
13
+
14
+ // const logger = getLogger('cli:computer-setup');
15
+
16
+ export function createComputerSetupCommand(): Command {
17
+ const command = new Command('computer-setup')
18
+ .alias('setup-machine')
19
+ .alias('provision')
20
+ .description(
21
+ 'Set up a new developer machine with all required tools and configurations'
22
+ )
23
+ .option(
24
+ '-p, --profile <profile>',
25
+ 'Use a specific profile (frontend, backend, fullstack, devops, ml)'
26
+ )
27
+ .option('-t, --team <team>', 'Apply team-specific configurations')
28
+ .option(
29
+ '-m, --mode <mode>',
30
+ 'Setup mode (interactive, automated, minimal)',
31
+ 'interactive'
32
+ )
33
+ .option('--dry-run', 'Show what would be installed without making changes')
34
+ .option('--skip-existing', 'Skip tools that are already installed')
35
+ .option('--parallel', 'Install tools in parallel where possible')
36
+ .option('--verbose', 'Show detailed output')
37
+ .option('--report', 'Generate a detailed setup report')
38
+ .action(async options => {
39
+ await runComputerSetup(options);
40
+ });
41
+
42
+ // Subcommands
43
+ command
44
+ .command('profile')
45
+ .description('Manage developer profiles')
46
+ .action(async () => {
47
+ await manageProfiles();
48
+ });
49
+
50
+ command
51
+ .command('validate')
52
+ .description('Validate current machine setup')
53
+ .action(async () => {
54
+ await validateSetup();
55
+ });
56
+
57
+ command
58
+ .command('doctor')
59
+ .description('Diagnose and fix common setup issues')
60
+ .action(async () => {
61
+ await runDoctor();
62
+ });
63
+
64
+ command
65
+ .command('team-config')
66
+ .description('Download and apply team configuration')
67
+ .argument('<team>', 'Team identifier')
68
+ .action(async team => {
69
+ await applyTeamConfig(team);
70
+ });
71
+
72
+ return command;
73
+ }
74
+
75
+ async function runComputerSetup(options: any): Promise<void> {
76
+ const spinner = ora('Initializing computer setup...').start();
77
+
78
+ try {
79
+ const manager = new ComputerSetupManager();
80
+ await manager.initialize();
81
+
82
+ spinner.stop();
83
+
84
+ // Get or create profile
85
+ let profile;
86
+ if (options.profile) {
87
+ // Get profile by name - ProfileManager will handle normalization
88
+ profile = await manager.getProfile(options.profile);
89
+ if (!profile) {
90
+ console.log(
91
+ chalk.yellow(`Profile '${options.profile}' not found. Using default.`)
92
+ );
93
+ profile = await manager.getDefaultProfile();
94
+ }
95
+ } else if (options.mode === 'interactive' || options.interactive) {
96
+ profile = await createInteractiveProfile();
97
+ } else {
98
+ profile = await manager.getDefaultProfile();
99
+ }
100
+
101
+ // Detect platform
102
+ const platform = {
103
+ os: process.platform as 'darwin' | 'linux' | 'win32',
104
+ arch: process.arch as 'x64' | 'arm64',
105
+ version: process.version,
106
+ };
107
+
108
+ console.log(chalk.cyan('\nšŸ–„ļø Computer Setup for Engineering Teams\n'));
109
+ console.log(chalk.gray('━'.repeat(50)));
110
+ console.log(chalk.white('Profile:'), chalk.green(profile.name));
111
+ console.log(chalk.white('Role:'), chalk.green(profile.role));
112
+ console.log(
113
+ chalk.white('Platform:'),
114
+ chalk.green(`${platform.os} ${platform.arch}`)
115
+ );
116
+ console.log(chalk.white('Mode:'), chalk.green(options.mode));
117
+ console.log(chalk.gray('━'.repeat(50)));
118
+
119
+ if (options.dryRun) {
120
+ console.log(
121
+ chalk.yellow('\nāš ļø DRY RUN MODE - No changes will be made\n')
122
+ );
123
+ }
124
+
125
+ // Confirm before proceeding
126
+ if (options.mode === 'interactive' && !options.dryRun) {
127
+ const { proceed } = await inquirer.prompt([
128
+ {
129
+ type: 'confirm',
130
+ name: 'proceed',
131
+ message: 'Ready to set up your machine?',
132
+ default: true,
133
+ },
134
+ ]);
135
+
136
+ if (!proceed) {
137
+ console.log(chalk.yellow('Setup cancelled'));
138
+ return;
139
+ }
140
+ }
141
+
142
+ // Set up progress monitoring
143
+ manager.on('progress', progress => {
144
+ const bar = generateProgressBar(progress.percentage);
145
+ console.log(chalk.cyan(`\n[${bar}] ${progress.percentage}%`));
146
+ console.log(chalk.gray(`Current: ${progress.currentStep}`));
147
+ console.log(
148
+ chalk.gray(`Steps: ${progress.completedSteps}/${progress.totalSteps}`)
149
+ );
150
+ });
151
+
152
+ // Run setup
153
+ spinner.text = 'Setting up your machine...';
154
+ spinner.start();
155
+
156
+ const result = await manager.setup({
157
+ profile,
158
+ platform,
159
+ mode: options.mode,
160
+ skipExisting: options.skipExisting || false,
161
+ dryRun: options.dryRun || false,
162
+ verbose: options.verbose || false,
163
+ parallel: options.parallel || false,
164
+ generateReport: options.report || false,
165
+ });
166
+
167
+ spinner.stop();
168
+
169
+ // Display results
170
+ if (result.success) {
171
+ console.log(chalk.green('\nāœ… Computer setup completed successfully!\n'));
172
+ } else {
173
+ console.log(chalk.red('\nāŒ Computer setup completed with errors\n'));
174
+ }
175
+
176
+ console.log(chalk.white('Summary:'));
177
+ console.log(
178
+ chalk.green(` āœ“ Completed: ${result.completedSteps?.length || 0} steps`)
179
+ );
180
+ if (result.skippedSteps && result.skippedSteps.length > 0) {
181
+ console.log(
182
+ chalk.yellow(` ⊘ Skipped: ${result.skippedSteps.length} steps`)
183
+ );
184
+ }
185
+ if (result.failedSteps && result.failedSteps.length > 0) {
186
+ console.log(chalk.red(` āœ— Failed: ${result.failedSteps.length} steps`));
187
+ }
188
+
189
+ if (result.warnings && result.warnings.length > 0) {
190
+ console.log(chalk.yellow('\nāš ļø Warnings:'));
191
+ result.warnings.forEach(w => console.log(chalk.yellow(` - ${w}`)));
192
+ }
193
+
194
+ if (result.errors && result.errors.length > 0) {
195
+ console.log(chalk.red('\nāŒ Errors:'));
196
+ result.errors.forEach(e =>
197
+ console.log(chalk.red(` - ${(e as any)?.message || e}`))
198
+ );
199
+ }
200
+
201
+ if (result.report) {
202
+ console.log(chalk.cyan(`\nšŸ“„ Setup report generated successfully`));
203
+ }
204
+
205
+ // Display next steps
206
+ console.log(chalk.cyan('\nšŸ“ Next Steps:'));
207
+ const nextSteps = [
208
+ 'Restart your terminal to apply configurations',
209
+ 'Run "wundr computer-setup validate" to verify',
210
+ 'Sign in to your team communication tools',
211
+ 'Clone your team repositories',
212
+ 'Review team onboarding documentation',
213
+ ];
214
+ nextSteps.forEach((step, i) => {
215
+ console.log(chalk.white(` ${i + 1}. ${step}`));
216
+ });
217
+
218
+ console.log(chalk.gray('\n━'.repeat(50)));
219
+ console.log(chalk.cyan('Welcome to the team! šŸŽ‰'));
220
+ console.log(chalk.gray('━'.repeat(50)));
221
+ } catch (error) {
222
+ spinner.stop();
223
+ logger.error('Computer setup failed', error);
224
+ console.error(chalk.red('Setup failed:'), error);
225
+ process.exit(1);
226
+ }
227
+ }
228
+
229
+ async function createInteractiveProfile(): Promise<any> {
230
+ console.log(chalk.cyan("\nšŸ‘¤ Let's create your developer profile\n"));
231
+
232
+ const answers = await inquirer.prompt([
233
+ {
234
+ type: 'input',
235
+ name: 'name',
236
+ message: 'What is your name?',
237
+ validate: input => input.length > 0,
238
+ },
239
+ {
240
+ type: 'input',
241
+ name: 'email',
242
+ message: 'What is your email?',
243
+ validate: input => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input),
244
+ },
245
+ {
246
+ type: 'list',
247
+ name: 'role',
248
+ message: 'What is your role?',
249
+ choices: [
250
+ { name: 'Frontend Developer', value: 'frontend' },
251
+ { name: 'Backend Developer', value: 'backend' },
252
+ { name: 'Full Stack Developer', value: 'fullstack' },
253
+ { name: 'DevOps Engineer', value: 'devops' },
254
+ { name: 'Machine Learning Engineer', value: 'ml' },
255
+ { name: 'Mobile Developer', value: 'mobile' },
256
+ ],
257
+ },
258
+ {
259
+ type: 'input',
260
+ name: 'team',
261
+ message: 'What team are you joining? (optional)',
262
+ default: '',
263
+ },
264
+ {
265
+ type: 'list',
266
+ name: 'shell',
267
+ message: 'Which shell do you prefer?',
268
+ choices: ['zsh', 'bash', 'fish'],
269
+ },
270
+ {
271
+ type: 'list',
272
+ name: 'editor',
273
+ message: 'Which editor do you use?',
274
+ choices: [
275
+ { name: 'Visual Studio Code', value: 'vscode' },
276
+ { name: 'Vim', value: 'vim' },
277
+ { name: 'Neovim', value: 'neovim' },
278
+ { name: 'Sublime Text', value: 'sublime' },
279
+ { name: 'IntelliJ IDEA', value: 'intellij' },
280
+ ],
281
+ },
282
+ {
283
+ type: 'checkbox',
284
+ name: 'languages',
285
+ message: 'Which programming languages do you need?',
286
+ choices: [
287
+ { name: 'Node.js', value: 'node', checked: true },
288
+ { name: 'Python', value: 'python' },
289
+ { name: 'Go', value: 'go' },
290
+ { name: 'Rust', value: 'rust' },
291
+ { name: 'Java', value: 'java' },
292
+ ],
293
+ },
294
+ {
295
+ type: 'checkbox',
296
+ name: 'tools',
297
+ message: 'Which tools do you need?',
298
+ choices: [
299
+ { name: 'Docker', value: 'docker', checked: true },
300
+ { name: 'Kubernetes', value: 'kubernetes' },
301
+ { name: 'AWS CLI', value: 'aws' },
302
+ { name: 'Google Cloud SDK', value: 'gcloud' },
303
+ { name: 'PostgreSQL', value: 'postgresql' },
304
+ { name: 'Redis', value: 'redis' },
305
+ ],
306
+ },
307
+ {
308
+ type: 'confirm',
309
+ name: 'aiTools',
310
+ message:
311
+ 'Do you want to set up AI development tools (Claude Code, Claude Flow)?',
312
+ default: true,
313
+ },
314
+ {
315
+ type: 'confirm',
316
+ name: 'slack',
317
+ message: 'Do you need Slack configuration?',
318
+ default: true,
319
+ },
320
+ ]);
321
+
322
+ // Build profile from answers
323
+ return {
324
+ name: answers.name,
325
+ email: answers.email,
326
+ role: answers.role,
327
+ team: answers.team,
328
+ preferences: {
329
+ shell: answers.shell,
330
+ editor: answers.editor,
331
+ theme: 'auto',
332
+ gitConfig: {
333
+ userName: answers.name,
334
+ userEmail: answers.email,
335
+ signCommits: true,
336
+ defaultBranch: 'main',
337
+ aliases: {},
338
+ },
339
+ aiTools: {
340
+ claudeCode: answers.aiTools,
341
+ claudeFlow: answers.aiTools,
342
+ mcpTools: answers.aiTools ? ['all'] : [],
343
+ swarmAgents: answers.aiTools ? ['default'] : [],
344
+ memoryAllocation: '2GB',
345
+ },
346
+ },
347
+ tools: {
348
+ languages: buildLanguageConfig(answers.languages),
349
+ packageManagers: {
350
+ npm: true,
351
+ pnpm: true,
352
+ yarn: false,
353
+ brew: process.platform === 'darwin',
354
+ },
355
+ containers: {
356
+ docker: answers.tools.includes('docker'),
357
+ dockerCompose: answers.tools.includes('docker'),
358
+ kubernetes: answers.tools.includes('kubernetes'),
359
+ },
360
+ cloudCLIs: {
361
+ aws: answers.tools.includes('aws'),
362
+ gcloud: answers.tools.includes('gcloud'),
363
+ },
364
+ databases: {
365
+ postgresql: answers.tools.includes('postgresql'),
366
+ redis: answers.tools.includes('redis'),
367
+ },
368
+ monitoring: {},
369
+ communication: {
370
+ slack: answers.slack
371
+ ? {
372
+ workspaces: [],
373
+ profile: {
374
+ displayName: answers.name,
375
+ statusText: 'New team member',
376
+ statusEmoji: ':wave:',
377
+ },
378
+ }
379
+ : undefined,
380
+ },
381
+ },
382
+ };
383
+ }
384
+
385
+ function buildLanguageConfig(languages: string[]): any {
386
+ const config: any = {};
387
+
388
+ if (languages.includes('node')) {
389
+ config.node = {
390
+ versions: ['20', '18'],
391
+ defaultVersion: '20',
392
+ globalPackages: ['pnpm', 'typescript', 'tsx'],
393
+ };
394
+ }
395
+
396
+ if (languages.includes('python')) {
397
+ config.python = {
398
+ versions: ['3.11', '3.10'],
399
+ defaultVersion: '3.11',
400
+ virtualEnv: 'venv',
401
+ };
402
+ }
403
+
404
+ if (languages.includes('go')) {
405
+ config.go = {
406
+ version: 'latest',
407
+ goPath: '$HOME/go',
408
+ };
409
+ }
410
+
411
+ if (languages.includes('rust')) {
412
+ config.rust = {
413
+ version: 'stable',
414
+ components: ['rustfmt', 'clippy'],
415
+ };
416
+ }
417
+
418
+ if (languages.includes('java')) {
419
+ config.java = {
420
+ version: '17',
421
+ jdk: 'adoptium',
422
+ };
423
+ }
424
+
425
+ return config;
426
+ }
427
+
428
+ async function manageProfiles(): Promise<void> {
429
+ const manager = new ComputerSetupManager();
430
+ await manager.initialize();
431
+
432
+ const profiles = await manager.getAvailableProfiles();
433
+
434
+ console.log(chalk.cyan('\nšŸ“‹ Developer Profiles\n'));
435
+
436
+ if (profiles.length === 0) {
437
+ console.log(
438
+ chalk.yellow('No profiles found. Create one with "wundr computer-setup"')
439
+ );
440
+ return;
441
+ }
442
+
443
+ profiles.forEach((profile, i) => {
444
+ console.log(chalk.white(`${i + 1}. ${profile.name}`));
445
+ console.log(chalk.gray(` Role: ${profile.role}`));
446
+ console.log(chalk.gray(` Email: ${profile.email}`));
447
+ if (profile.team) {
448
+ console.log(chalk.gray(` Team: ${profile.team}`));
449
+ }
450
+ });
451
+ }
452
+
453
+ async function validateSetup(): Promise<void> {
454
+ const spinner = ora('Validating machine setup...').start();
455
+
456
+ try {
457
+ const manager = new ComputerSetupManager();
458
+ await manager.initialize();
459
+
460
+ // Get current profile
461
+ const profiles = await manager.getAvailableProfiles();
462
+ if (profiles.length === 0) {
463
+ spinner.stop();
464
+ console.log(
465
+ chalk.yellow('No profile found. Run "wundr computer-setup" first.')
466
+ );
467
+ return;
468
+ }
469
+
470
+ const profile = profiles[0]; // Use most recent
471
+ if (!profile) {
472
+ console.log(
473
+ chalk.yellow('No profile found. Run "wundr computer-setup" first.')
474
+ );
475
+ return;
476
+ }
477
+ const isValid = await manager.validateSetup(profile);
478
+
479
+ spinner.stop();
480
+
481
+ if (isValid) {
482
+ console.log(chalk.green('āœ… Machine setup is valid!'));
483
+ } else {
484
+ console.log(chalk.red('āŒ Machine setup has issues'));
485
+ console.log(
486
+ chalk.yellow(
487
+ '\nRun "wundr computer-setup doctor" to diagnose and fix issues'
488
+ )
489
+ );
490
+ }
491
+ } catch (error) {
492
+ spinner.stop();
493
+ console.error(chalk.red('Validation failed:'), error);
494
+ }
495
+ }
496
+
497
+ async function runDoctor(): Promise<void> {
498
+ console.log(chalk.cyan('\nšŸ„ Computer Setup Doctor\n'));
499
+ console.log(chalk.gray('Diagnosing your machine setup...\n'));
500
+
501
+ const checks = [
502
+ { name: 'Node.js', command: 'node --version', required: true },
503
+ { name: 'npm', command: 'npm --version', required: true },
504
+ { name: 'pnpm', command: 'pnpm --version', required: false },
505
+ { name: 'Git', command: 'git --version', required: true },
506
+ { name: 'Docker', command: 'docker --version', required: false },
507
+ { name: 'Claude Code', command: 'claude --version', required: false },
508
+ { name: 'GitHub CLI', command: 'gh --version', required: false },
509
+ ];
510
+
511
+ for (const check of checks) {
512
+ const spinner = ora(`Checking ${check.name}...`).start();
513
+
514
+ try {
515
+ const { execa } = (await import('execa')) as any;
516
+ const { stdout } = await execa(
517
+ check.command.split(' ')[0],
518
+ check.command.split(' ').slice(1)
519
+ );
520
+ spinner.succeed(`${check.name}: ${stdout.trim()}`);
521
+ } catch (error) {
522
+ if (check.required) {
523
+ spinner.fail(`${check.name}: Not found (REQUIRED)`);
524
+ } else {
525
+ spinner.warn(`${check.name}: Not found (optional)`);
526
+ }
527
+ }
528
+ }
529
+
530
+ console.log(chalk.cyan('\nšŸ’Š Recommendations:\n'));
531
+ console.log('1. Install missing required tools');
532
+ console.log('2. Run "wundr computer-setup" to complete setup');
533
+ console.log('3. Check PATH environment variable');
534
+ }
535
+
536
+ async function applyTeamConfig(team: string): Promise<void> {
537
+ console.log(chalk.cyan(`\nšŸ‘„ Applying team configuration: ${team}\n`));
538
+
539
+ const spinner = ora('Downloading team configuration...').start();
540
+
541
+ try {
542
+ // This would fetch team config from a central repository
543
+ // For now, we'll simulate it
544
+ await new Promise(resolve => setTimeout(resolve, 2000));
545
+
546
+ spinner.succeed('Team configuration downloaded');
547
+ console.log(chalk.green('āœ… Team configuration applied successfully!'));
548
+
549
+ console.log(chalk.cyan('\nTeam tools installed:'));
550
+ console.log(' - Internal CLI tools');
551
+ console.log(' - Team-specific VS Code extensions');
552
+ console.log(' - Pre-commit hooks');
553
+ console.log(' - Team aliases and scripts');
554
+ } catch (error) {
555
+ spinner.fail('Failed to apply team configuration');
556
+ console.error(chalk.red('Error:'), error);
557
+ }
558
+ }
559
+
560
+ function generateProgressBar(percentage: number): string {
561
+ const width = 30;
562
+ const filled = Math.round((width * percentage) / 100);
563
+ const empty = width - filled;
564
+ return 'ā–ˆ'.repeat(filled) + 'ā–‘'.repeat(empty);
565
+ }