@wundr.io/cli 1.0.10 → 1.0.12

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 (269) hide show
  1. package/bin/wundr.js +8 -4
  2. package/package.json +23 -23
  3. package/src/ai/ai-service.ts +16 -17
  4. package/src/ai/claude-client.ts +16 -16
  5. package/src/ai/conversation-manager.ts +29 -29
  6. package/src/cli.ts +4 -4
  7. package/src/commands/ai.ts +246 -78
  8. package/src/commands/alignment.ts +74 -74
  9. package/src/commands/analyze-optimized.ts +111 -78
  10. package/src/commands/analyze.ts +14 -14
  11. package/src/commands/batch.ts +179 -42
  12. package/src/commands/chat.ts +37 -30
  13. package/src/commands/claude-init.ts +41 -45
  14. package/src/commands/claude-setup.ts +204 -119
  15. package/src/commands/computer-setup.ts +85 -43
  16. package/src/commands/create-command.ts +4 -4
  17. package/src/commands/create.ts +27 -27
  18. package/src/commands/dashboard.ts +24 -24
  19. package/src/commands/govern.ts +25 -25
  20. package/src/commands/governance.ts +34 -34
  21. package/src/commands/guardian.ts +56 -56
  22. package/src/commands/init.ts +25 -22
  23. package/src/commands/orchestrator.ts +68 -41
  24. package/src/commands/performance-optimizer.ts +34 -35
  25. package/src/commands/plugins.ts +27 -27
  26. package/src/commands/project-update.ts +175 -72
  27. package/src/commands/rag.ts +185 -78
  28. package/src/commands/session.ts +35 -35
  29. package/src/commands/setup.ts +40 -344
  30. package/src/commands/test-init.ts +3 -3
  31. package/src/commands/test.ts +4 -4
  32. package/src/commands/watch.ts +28 -29
  33. package/src/commands/worktree.ts +49 -49
  34. package/src/context/context-manager.ts +10 -10
  35. package/src/context/session-manager.ts +41 -41
  36. package/src/framework/command-interface.ts +520 -0
  37. package/src/framework/command-registry.ts +942 -0
  38. package/src/framework/completion-exporter.ts +383 -0
  39. package/src/framework/debug-logger.ts +519 -0
  40. package/src/framework/error-handler.ts +867 -0
  41. package/src/framework/help-generator.ts +540 -0
  42. package/src/framework/index.ts +169 -0
  43. package/src/framework/interactive-repl.ts +703 -0
  44. package/src/framework/output-formatter.ts +834 -0
  45. package/src/framework/progress-manager.ts +539 -0
  46. package/src/index.ts +4 -4
  47. package/src/interactive/interactive-mode.ts +16 -16
  48. package/src/lib/conflict-resolution.ts +799 -9
  49. package/src/lib/merge-strategy.ts +529 -7
  50. package/src/lib/safety-mechanisms.ts +422 -18
  51. package/src/lib/state-detection.ts +1015 -13
  52. package/src/nlp/command-mapper.ts +29 -29
  53. package/src/nlp/command-parser.ts +17 -17
  54. package/src/nlp/intent-classifier.ts +7 -7
  55. package/src/nlp/intent-parser.ts +54 -52
  56. package/src/plugins/plugin-manager.ts +61 -39
  57. package/src/tests/computer-setup-integration.test.ts +46 -15
  58. package/src/types/modules.d.ts +424 -1
  59. package/src/utils/backup-rollback-manager.ts +11 -8
  60. package/src/utils/config-manager.ts +3 -3
  61. package/src/utils/error-handler.ts +2 -2
  62. package/src/utils/logger.ts +22 -22
  63. package/templates/batch/ci-cd.yaml +7 -7
  64. package/test-suites/api/health.spec.ts +20 -23
  65. package/test-suites/helpers/test-config.ts +14 -13
  66. package/test-suites/ui/accessibility.spec.ts +27 -22
  67. package/test-suites/ui/smoke.spec.ts +26 -21
  68. package/LICENSE +0 -21
  69. package/dist/ai/ai-service.d.ts +0 -152
  70. package/dist/ai/ai-service.d.ts.map +0 -1
  71. package/dist/ai/ai-service.js +0 -430
  72. package/dist/ai/ai-service.js.map +0 -1
  73. package/dist/ai/claude-client.d.ts +0 -130
  74. package/dist/ai/claude-client.d.ts.map +0 -1
  75. package/dist/ai/claude-client.js +0 -340
  76. package/dist/ai/claude-client.js.map +0 -1
  77. package/dist/ai/conversation-manager.d.ts +0 -164
  78. package/dist/ai/conversation-manager.d.ts.map +0 -1
  79. package/dist/ai/conversation-manager.js +0 -614
  80. package/dist/ai/conversation-manager.js.map +0 -1
  81. package/dist/ai/index.d.ts +0 -5
  82. package/dist/ai/index.d.ts.map +0 -1
  83. package/dist/ai/index.js +0 -8
  84. package/dist/ai/index.js.map +0 -1
  85. package/dist/cli.d.ts +0 -36
  86. package/dist/cli.d.ts.map +0 -1
  87. package/dist/cli.js +0 -192
  88. package/dist/cli.js.map +0 -1
  89. package/dist/commands/ai.d.ts +0 -89
  90. package/dist/commands/ai.d.ts.map +0 -1
  91. package/dist/commands/ai.js +0 -799
  92. package/dist/commands/ai.js.map +0 -1
  93. package/dist/commands/alignment.d.ts +0 -78
  94. package/dist/commands/alignment.d.ts.map +0 -1
  95. package/dist/commands/alignment.js +0 -817
  96. package/dist/commands/alignment.js.map +0 -1
  97. package/dist/commands/analyze-optimized.d.ts +0 -14
  98. package/dist/commands/analyze-optimized.d.ts.map +0 -1
  99. package/dist/commands/analyze-optimized.js +0 -600
  100. package/dist/commands/analyze-optimized.js.map +0 -1
  101. package/dist/commands/analyze.d.ts +0 -65
  102. package/dist/commands/analyze.d.ts.map +0 -1
  103. package/dist/commands/analyze.js +0 -435
  104. package/dist/commands/analyze.js.map +0 -1
  105. package/dist/commands/batch.d.ts +0 -71
  106. package/dist/commands/batch.d.ts.map +0 -1
  107. package/dist/commands/batch.js +0 -738
  108. package/dist/commands/batch.js.map +0 -1
  109. package/dist/commands/chat.d.ts +0 -71
  110. package/dist/commands/chat.d.ts.map +0 -1
  111. package/dist/commands/chat.js +0 -674
  112. package/dist/commands/chat.js.map +0 -1
  113. package/dist/commands/claude-init.d.ts +0 -28
  114. package/dist/commands/claude-init.d.ts.map +0 -1
  115. package/dist/commands/claude-init.js +0 -591
  116. package/dist/commands/claude-init.js.map +0 -1
  117. package/dist/commands/claude-setup.d.ts +0 -119
  118. package/dist/commands/claude-setup.d.ts.map +0 -1
  119. package/dist/commands/claude-setup.js +0 -1073
  120. package/dist/commands/claude-setup.js.map +0 -1
  121. package/dist/commands/computer-setup-commands.d.ts +0 -53
  122. package/dist/commands/computer-setup-commands.d.ts.map +0 -1
  123. package/dist/commands/computer-setup-commands.js +0 -705
  124. package/dist/commands/computer-setup-commands.js.map +0 -1
  125. package/dist/commands/computer-setup.d.ts +0 -7
  126. package/dist/commands/computer-setup.d.ts.map +0 -1
  127. package/dist/commands/computer-setup.js +0 -849
  128. package/dist/commands/computer-setup.js.map +0 -1
  129. package/dist/commands/create-command.d.ts +0 -7
  130. package/dist/commands/create-command.d.ts.map +0 -1
  131. package/dist/commands/create-command.js +0 -158
  132. package/dist/commands/create-command.js.map +0 -1
  133. package/dist/commands/create.d.ts +0 -74
  134. package/dist/commands/create.d.ts.map +0 -1
  135. package/dist/commands/create.js +0 -556
  136. package/dist/commands/create.js.map +0 -1
  137. package/dist/commands/dashboard.d.ts +0 -91
  138. package/dist/commands/dashboard.d.ts.map +0 -1
  139. package/dist/commands/dashboard.js +0 -538
  140. package/dist/commands/dashboard.js.map +0 -1
  141. package/dist/commands/govern.d.ts +0 -70
  142. package/dist/commands/govern.d.ts.map +0 -1
  143. package/dist/commands/govern.js +0 -481
  144. package/dist/commands/govern.js.map +0 -1
  145. package/dist/commands/governance.d.ts +0 -17
  146. package/dist/commands/governance.d.ts.map +0 -1
  147. package/dist/commands/governance.js +0 -703
  148. package/dist/commands/governance.js.map +0 -1
  149. package/dist/commands/guardian.d.ts +0 -20
  150. package/dist/commands/guardian.d.ts.map +0 -1
  151. package/dist/commands/guardian.js +0 -597
  152. package/dist/commands/guardian.js.map +0 -1
  153. package/dist/commands/init.d.ts +0 -59
  154. package/dist/commands/init.d.ts.map +0 -1
  155. package/dist/commands/init.js +0 -650
  156. package/dist/commands/init.js.map +0 -1
  157. package/dist/commands/orchestrator.d.ts +0 -7
  158. package/dist/commands/orchestrator.d.ts.map +0 -1
  159. package/dist/commands/orchestrator.js +0 -571
  160. package/dist/commands/orchestrator.js.map +0 -1
  161. package/dist/commands/performance-optimizer.d.ts +0 -30
  162. package/dist/commands/performance-optimizer.d.ts.map +0 -1
  163. package/dist/commands/performance-optimizer.js +0 -650
  164. package/dist/commands/performance-optimizer.js.map +0 -1
  165. package/dist/commands/plugins.d.ts +0 -87
  166. package/dist/commands/plugins.d.ts.map +0 -1
  167. package/dist/commands/plugins.js +0 -685
  168. package/dist/commands/plugins.js.map +0 -1
  169. package/dist/commands/rag.d.ts +0 -7
  170. package/dist/commands/rag.d.ts.map +0 -1
  171. package/dist/commands/rag.js +0 -748
  172. package/dist/commands/rag.js.map +0 -1
  173. package/dist/commands/session.d.ts +0 -41
  174. package/dist/commands/session.d.ts.map +0 -1
  175. package/dist/commands/session.js +0 -441
  176. package/dist/commands/session.js.map +0 -1
  177. package/dist/commands/setup.d.ts +0 -29
  178. package/dist/commands/setup.d.ts.map +0 -1
  179. package/dist/commands/setup.js +0 -397
  180. package/dist/commands/setup.js.map +0 -1
  181. package/dist/commands/test-init.d.ts +0 -9
  182. package/dist/commands/test-init.d.ts.map +0 -1
  183. package/dist/commands/test-init.js +0 -222
  184. package/dist/commands/test-init.js.map +0 -1
  185. package/dist/commands/test.d.ts +0 -25
  186. package/dist/commands/test.d.ts.map +0 -1
  187. package/dist/commands/test.js +0 -217
  188. package/dist/commands/test.js.map +0 -1
  189. package/dist/commands/vp.d.ts +0 -7
  190. package/dist/commands/vp.d.ts.map +0 -1
  191. package/dist/commands/vp.js +0 -571
  192. package/dist/commands/vp.js.map +0 -1
  193. package/dist/commands/watch.d.ts +0 -76
  194. package/dist/commands/watch.d.ts.map +0 -1
  195. package/dist/commands/watch.js +0 -613
  196. package/dist/commands/watch.js.map +0 -1
  197. package/dist/commands/worktree.d.ts +0 -63
  198. package/dist/commands/worktree.d.ts.map +0 -1
  199. package/dist/commands/worktree.js +0 -774
  200. package/dist/commands/worktree.js.map +0 -1
  201. package/dist/context/context-manager.d.ts +0 -155
  202. package/dist/context/context-manager.d.ts.map +0 -1
  203. package/dist/context/context-manager.js +0 -383
  204. package/dist/context/context-manager.js.map +0 -1
  205. package/dist/context/index.d.ts +0 -3
  206. package/dist/context/index.d.ts.map +0 -1
  207. package/dist/context/index.js +0 -6
  208. package/dist/context/index.js.map +0 -1
  209. package/dist/context/session-manager.d.ts +0 -207
  210. package/dist/context/session-manager.d.ts.map +0 -1
  211. package/dist/context/session-manager.js +0 -686
  212. package/dist/context/session-manager.js.map +0 -1
  213. package/dist/index.d.ts +0 -8
  214. package/dist/index.d.ts.map +0 -1
  215. package/dist/index.js +0 -51
  216. package/dist/index.js.map +0 -1
  217. package/dist/interactive/interactive-mode.d.ts +0 -76
  218. package/dist/interactive/interactive-mode.d.ts.map +0 -1
  219. package/dist/interactive/interactive-mode.js +0 -732
  220. package/dist/interactive/interactive-mode.js.map +0 -1
  221. package/dist/nlp/command-mapper.d.ts +0 -174
  222. package/dist/nlp/command-mapper.d.ts.map +0 -1
  223. package/dist/nlp/command-mapper.js +0 -624
  224. package/dist/nlp/command-mapper.js.map +0 -1
  225. package/dist/nlp/command-parser.d.ts +0 -106
  226. package/dist/nlp/command-parser.d.ts.map +0 -1
  227. package/dist/nlp/command-parser.js +0 -417
  228. package/dist/nlp/command-parser.js.map +0 -1
  229. package/dist/nlp/index.d.ts +0 -5
  230. package/dist/nlp/index.d.ts.map +0 -1
  231. package/dist/nlp/index.js +0 -8
  232. package/dist/nlp/index.js.map +0 -1
  233. package/dist/nlp/intent-classifier.d.ts +0 -59
  234. package/dist/nlp/intent-classifier.d.ts.map +0 -1
  235. package/dist/nlp/intent-classifier.js +0 -384
  236. package/dist/nlp/intent-classifier.js.map +0 -1
  237. package/dist/nlp/intent-parser.d.ts +0 -152
  238. package/dist/nlp/intent-parser.d.ts.map +0 -1
  239. package/dist/nlp/intent-parser.js +0 -744
  240. package/dist/nlp/intent-parser.js.map +0 -1
  241. package/dist/plugins/plugin-manager.d.ts +0 -120
  242. package/dist/plugins/plugin-manager.d.ts.map +0 -1
  243. package/dist/plugins/plugin-manager.js +0 -595
  244. package/dist/plugins/plugin-manager.js.map +0 -1
  245. package/dist/types/index.d.ts +0 -224
  246. package/dist/types/index.d.ts.map +0 -1
  247. package/dist/types/index.js +0 -3
  248. package/dist/types/index.js.map +0 -1
  249. package/dist/utils/backup-rollback-manager.d.ts +0 -72
  250. package/dist/utils/backup-rollback-manager.d.ts.map +0 -1
  251. package/dist/utils/backup-rollback-manager.js +0 -289
  252. package/dist/utils/backup-rollback-manager.js.map +0 -1
  253. package/dist/utils/claude-config-installer.d.ts +0 -98
  254. package/dist/utils/claude-config-installer.d.ts.map +0 -1
  255. package/dist/utils/claude-config-installer.js +0 -678
  256. package/dist/utils/claude-config-installer.js.map +0 -1
  257. package/dist/utils/config-manager.d.ts +0 -73
  258. package/dist/utils/config-manager.d.ts.map +0 -1
  259. package/dist/utils/config-manager.js +0 -339
  260. package/dist/utils/config-manager.js.map +0 -1
  261. package/dist/utils/error-handler.d.ts +0 -46
  262. package/dist/utils/error-handler.d.ts.map +0 -1
  263. package/dist/utils/error-handler.js +0 -169
  264. package/dist/utils/error-handler.js.map +0 -1
  265. package/dist/utils/logger.d.ts +0 -25
  266. package/dist/utils/logger.d.ts.map +0 -1
  267. package/dist/utils/logger.js +0 -105
  268. package/dist/utils/logger.js.map +0 -1
  269. package/src/commands/computer-setup-commands.ts +0 -872
@@ -1,37 +1,29 @@
1
1
  /**
2
2
  * Simple Setup Commands - Main setup entry points
3
- * Provides the primary wundr setup commands that integrate with computer-setup
3
+ *
4
+ * `wundr setup` (and its sub-commands) delegate to the SAME code path as
5
+ * `wundr computer-setup` (runComputerSetup -> ComputerSetupManager), so there is
6
+ * a single orchestrator engine across the whole CLI. The old RealSetupOrchestrator
7
+ * has been retired.
4
8
  */
5
9
 
6
10
  import chalk from 'chalk';
7
11
  import inquirer from 'inquirer';
8
12
  import ora from 'ora';
9
13
 
10
- import {
11
- RealSetupOrchestrator,
12
- } from '@wundr.io/computer-setup';
13
- import { logger } from '../utils/logger';
14
+ import { runComputerSetup } from './computer-setup';
14
15
 
15
- import type {
16
- SetupPlatform,
17
- SetupProgress,
18
- SetupResult} from '@wundr.io/computer-setup';
19
16
  import type { PluginManager } from '../plugins/plugin-manager';
20
17
  import type { ConfigManager } from '../utils/config-manager';
21
18
 
22
19
  import type { Command } from 'commander';
23
20
 
24
21
  export class SetupCommands {
25
- private orchestrator: RealSetupOrchestrator;
26
- private platform: SetupPlatform;
27
-
28
22
  constructor(
29
23
  private program: Command,
30
24
  private configManager: ConfigManager,
31
- private pluginManager: PluginManager,
25
+ private pluginManager: PluginManager
32
26
  ) {
33
- this.platform = this.detectPlatform();
34
- this.orchestrator = new RealSetupOrchestrator(this.platform);
35
27
  this.registerCommands();
36
28
  }
37
29
 
@@ -43,13 +35,14 @@ export class SetupCommands {
43
35
  .option(
44
36
  '-p, --profile <profile>',
45
37
  'Use specific profile (frontend, backend, fullstack, devops)',
46
- 'fullstack',
38
+ 'fullstack'
47
39
  )
48
40
  .option(
49
41
  '--dry-run',
50
- 'Show what would be installed without making changes',
42
+ 'Show what would be installed without making changes'
51
43
  )
52
44
  .option('--interactive', 'Run in interactive mode')
45
+ .option('--no-remote-access', 'Skip remote-access provisioning')
53
46
  .action(async options => {
54
47
  await this.runSetup(options);
55
48
  });
@@ -59,33 +52,14 @@ export class SetupCommands {
59
52
  .command('setup:profile')
60
53
  .description('Set up using a specific developer profile');
61
54
 
62
- setupProfile
63
- .command('frontend')
64
- .description('Set up frontend development environment')
65
- .action(async () => {
66
- await this.runSetup({ profile: 'frontend' });
67
- });
68
-
69
- setupProfile
70
- .command('backend')
71
- .description('Set up backend development environment')
72
- .action(async () => {
73
- await this.runSetup({ profile: 'backend' });
74
- });
75
-
76
- setupProfile
77
- .command('fullstack')
78
- .description('Set up full-stack development environment')
79
- .action(async () => {
80
- await this.runSetup({ profile: 'fullstack' });
81
- });
82
-
83
- setupProfile
84
- .command('devops')
85
- .description('Set up DevOps engineering environment')
86
- .action(async () => {
87
- await this.runSetup({ profile: 'devops' });
88
- });
55
+ for (const profile of ['frontend', 'backend', 'fullstack', 'devops']) {
56
+ setupProfile
57
+ .command(profile)
58
+ .description(`Set up ${profile} development environment`)
59
+ .action(async () => {
60
+ await this.runSetup({ profile });
61
+ });
62
+ }
89
63
 
90
64
  // Validate setup (wundr setup:validate)
91
65
  this.program
@@ -97,12 +71,14 @@ export class SetupCommands {
97
71
  await this.validateSetup(options);
98
72
  });
99
73
 
100
- // Resume setup (wundr setup:resume)
74
+ // Resume setup (wundr setup:resume) — re-runs idempotently, skipping
75
+ // already-installed tools (the setup flow is now idempotent).
101
76
  this.program
102
77
  .command('setup:resume')
103
- .description('Resume interrupted setup from saved state')
104
- .action(async () => {
105
- await this.resumeSetup();
78
+ .description('Re-run setup, skipping tools that are already installed')
79
+ .option('-p, --profile <profile>', 'Profile to resume', 'fullstack')
80
+ .action(async options => {
81
+ await this.runSetup({ ...options, skipExisting: true });
106
82
  });
107
83
 
108
84
  // Personalize setup (wundr setup:personalize)
@@ -115,144 +91,15 @@ export class SetupCommands {
115
91
  }
116
92
 
117
93
  private async runSetup(options: any): Promise<void> {
118
- console.log(chalk.cyan('\nšŸš€ Wundr Development Environment Setup'));
119
- console.log(chalk.gray('Setting up your development machine...\n'));
120
-
121
- try {
122
- // Check for resumable setup
123
- const canResume = await this.orchestrator.canResume();
124
- if (canResume && !options.dryRun) {
125
- const { resume } = await inquirer.prompt([
126
- {
127
- type: 'confirm',
128
- name: 'resume',
129
- message: 'Found incomplete setup. Resume from where you left off?',
130
- default: true,
131
- },
132
- ]);
133
-
134
- if (resume) {
135
- return await this.resumeSetup();
136
- }
137
- }
138
-
139
- // Get profile
140
- let profileName = options.profile;
141
- if (options.interactive && !profileName) {
142
- profileName = await this.selectProfile();
143
- }
144
-
145
- // Validate profile
146
- const availableProfiles = this.orchestrator.getAvailableProfiles();
147
-
148
- // Try different matching strategies
149
- let profile = availableProfiles.find(
150
- p => p.name.toLowerCase() === profileName.toLowerCase(),
151
- );
152
-
153
- if (!profile) {
154
- // Try partial match
155
- profile = availableProfiles.find(
156
- p =>
157
- p.name.toLowerCase().includes(profileName.toLowerCase()) ||
158
- profileName
159
- .toLowerCase()
160
- .includes(p.name.toLowerCase().split(' ')[0]),
161
- );
162
- }
163
-
164
- // Map common aliases
165
- if (!profile) {
166
- const aliases: Record<string, string> = {
167
- fullstack: 'Full Stack Developer',
168
- 'full-stack': 'Full Stack Developer',
169
- frontend: 'Frontend Developer',
170
- backend: 'Backend Developer',
171
- devops: 'DevOps Engineer',
172
- };
173
-
174
- const mappedName = aliases[profileName.toLowerCase()];
175
- if (mappedName) {
176
- profile = availableProfiles.find(p => p.name === mappedName);
177
- }
178
- }
179
-
180
- if (!profile) {
181
- console.error(chalk.red(`āŒ Unknown profile: ${profileName}`));
182
- console.log(chalk.cyan('\nšŸ“‹ Available profiles:'));
183
- availableProfiles.forEach(p =>
184
- console.log(
185
- ` • ${chalk.white(p.name)}: ${chalk.gray(p.description)}`,
186
- ),
187
- );
188
- return;
189
- }
190
-
191
- console.log(
192
- chalk.cyan(`\nšŸ“‹ Selected Profile: ${chalk.white(profile.name)}`),
193
- );
194
- console.log(chalk.gray(`${profile.description}`));
195
- console.log(
196
- chalk.gray(`Estimated time: ${profile.estimatedTimeMinutes} minutes\n`),
197
- );
198
-
199
- if (options.dryRun) {
200
- console.log(
201
- chalk.yellow('šŸ” DRY RUN - Showing what would be installed:\n'),
202
- );
203
- console.log(chalk.cyan('Required tools:'));
204
- profile.requiredTools.forEach(tool => console.log(` āœ“ ${tool}`));
205
- if (profile.optionalTools.length > 0) {
206
- console.log(chalk.cyan('\nOptional tools:'));
207
- profile.optionalTools.forEach(tool => console.log(` • ${tool}`));
208
- }
209
- return;
210
- }
211
-
212
- // Progress tracking
213
- const progressCallback = (progress: SetupProgress) => {
214
- process.stdout.clearLine(0);
215
- process.stdout.cursorTo(0);
216
- const progressBar = this.createProgressBar(progress.percentage);
217
- process.stdout.write(
218
- `${progressBar} ${progress.percentage.toFixed(1)}% - ${progress.currentStep}`,
219
- );
220
- };
221
-
222
- console.log(chalk.cyan('šŸš€ Starting setup...\n'));
223
-
224
- const result: SetupResult = await this.orchestrator.orchestrate(
225
- profileName,
226
- {
227
- dryRun: options.dryRun,
228
- skipExisting: true,
229
- parallel: false,
230
- generateReport: true,
231
- },
232
- progressCallback,
233
- );
234
-
235
- console.log('\n'); // New line after progress
236
-
237
- if (result.success) {
238
- console.log(chalk.green('\nāœ… Setup completed successfully!'));
239
- console.log(
240
- chalk.gray(`Duration: ${Math.round(result.duration / 1000)}s\n`),
241
- );
242
-
243
- this.showSetupSummary(result);
244
- this.showNextSteps();
245
- } else {
246
- console.log(chalk.red('\nāŒ Setup failed!'));
247
- this.showErrors(result);
248
- console.log(chalk.cyan('\nšŸ’” Resume with: wundr setup:resume'));
249
- process.exit(1);
250
- }
251
- } catch (error) {
252
- console.error(chalk.red('\nāŒ Setup failed:'), (error as Error).message);
253
- console.log(chalk.cyan('\nšŸ’” Resume with: wundr setup:resume'));
254
- process.exit(1);
255
- }
94
+ // Single source of truth: the same handler that backs `wundr computer-setup`.
95
+ await runComputerSetup({
96
+ profile: options.profile,
97
+ mode: options.interactive ? 'interactive' : 'automated',
98
+ dryRun: Boolean(options.dryRun),
99
+ interactive: Boolean(options.interactive),
100
+ skipExisting: Boolean(options.skipExisting),
101
+ remoteAccess: options.remoteAccess,
102
+ });
256
103
  }
257
104
 
258
105
  private async validateSetup(options: any): Promise<void> {
@@ -260,7 +107,6 @@ export class SetupCommands {
260
107
 
261
108
  const spinner = ora('Running validation checks...').start();
262
109
 
263
- // Basic validation checks
264
110
  const checks = [
265
111
  { name: 'Node.js', test: () => this.checkCommand('node --version') },
266
112
  { name: 'Git', test: () => this.checkCommand('git --version') },
@@ -272,23 +118,17 @@ export class SetupCommands {
272
118
  name: string;
273
119
  status: 'pass' | 'fail';
274
120
  version?: string;
275
- error?: string;
276
121
  }> = [];
277
122
 
278
123
  for (const check of checks) {
279
124
  try {
280
- const result = await check.test();
281
125
  results.push({
282
126
  name: check.name,
283
127
  status: 'pass',
284
- version: result,
285
- });
286
- } catch (error) {
287
- results.push({
288
- name: check.name,
289
- status: 'fail',
290
- error: (error as Error).message,
128
+ version: await check.test(),
291
129
  });
130
+ } catch {
131
+ results.push({ name: check.name, status: 'fail' });
292
132
  }
293
133
  }
294
134
 
@@ -299,7 +139,7 @@ export class SetupCommands {
299
139
  const icon = result.status === 'pass' ? 'āœ…' : 'āŒ';
300
140
  const status =
301
141
  result.status === 'pass'
302
- ? chalk.green(`${result.version || 'installed'}`)
142
+ ? chalk.green(result.version || 'installed')
303
143
  : chalk.red('not found');
304
144
  console.log(`${icon} ${result.name}: ${status}`);
305
145
  });
@@ -307,13 +147,12 @@ export class SetupCommands {
307
147
  const failed = results.filter(r => r.status === 'fail');
308
148
  if (failed.length > 0) {
309
149
  console.log(chalk.yellow(`\nāš ļø ${failed.length} issues found`));
310
-
311
150
  if (options.fix) {
312
151
  console.log(chalk.cyan('\nšŸ”§ Attempting to fix issues...'));
313
152
  await this.runSetup({ profile: options.profile || 'fullstack' });
314
153
  } else {
315
154
  console.log(
316
- chalk.cyan('\nšŸ’” Fix issues with: wundr setup:validate --fix'),
155
+ chalk.cyan('\nšŸ’” Fix issues with: wundr setup:validate --fix')
317
156
  );
318
157
  }
319
158
  } else {
@@ -321,37 +160,6 @@ export class SetupCommands {
321
160
  }
322
161
  }
323
162
 
324
- private async resumeSetup(): Promise<void> {
325
- console.log(chalk.cyan('\nšŸ”„ Resuming setup...\n'));
326
-
327
- const progressCallback = (progress: SetupProgress) => {
328
- process.stdout.clearLine(0);
329
- process.stdout.cursorTo(0);
330
- const progressBar = this.createProgressBar(progress.percentage);
331
- process.stdout.write(
332
- `${progressBar} ${progress.percentage.toFixed(1)}% - ${progress.currentStep}`,
333
- );
334
- };
335
-
336
- try {
337
- const result = await this.orchestrator.resume(progressCallback);
338
- console.log('\n');
339
-
340
- if (result.success) {
341
- console.log(chalk.green('āœ… Setup completed successfully!'));
342
- this.showSetupSummary(result);
343
- this.showNextSteps();
344
- } else {
345
- console.log(chalk.red('āŒ Resume failed!'));
346
- this.showErrors(result);
347
- process.exit(1);
348
- }
349
- } catch (error) {
350
- console.error(chalk.red('āŒ Resume failed:'), (error as Error).message);
351
- process.exit(1);
352
- }
353
- }
354
-
355
163
  private async personalizeSetup(): Promise<void> {
356
164
  console.log(chalk.cyan('\nšŸ‘¤ Personal Configuration Setup\n'));
357
165
 
@@ -369,134 +177,22 @@ export class SetupCommands {
369
177
  validate: (input: string) =>
370
178
  /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input) || 'Valid email required',
371
179
  },
372
- {
373
- type: 'list',
374
- name: 'shell',
375
- message: 'Preferred shell:',
376
- choices: ['zsh', 'bash', 'fish'],
377
- default: 'zsh',
378
- },
379
- {
380
- type: 'confirm',
381
- name: 'aliases',
382
- message: 'Install helpful shell aliases?',
383
- default: true,
384
- },
385
180
  ]);
386
181
 
387
182
  console.log(chalk.cyan('\nāš™ļø Configuring personal settings...'));
388
-
389
- // Configure Git
390
183
  try {
391
184
  await this.runCommand(`git config --global user.name "${answers.name}"`);
392
185
  await this.runCommand(
393
- `git config --global user.email "${answers.email}"`,
186
+ `git config --global user.email "${answers.email}"`
394
187
  );
395
188
  console.log(chalk.green('āœ… Git configured'));
396
- } catch (error) {
189
+ } catch {
397
190
  console.log(chalk.yellow('āš ļø Could not configure Git'));
398
191
  }
399
192
 
400
193
  console.log(chalk.green('\nāœ… Personalization complete!'));
401
194
  }
402
195
 
403
- private async selectProfile(): Promise<string> {
404
- const profiles = this.orchestrator.getAvailableProfiles();
405
-
406
- const { selectedProfile } = await inquirer.prompt([
407
- {
408
- type: 'list',
409
- name: 'selectedProfile',
410
- message: 'Select your development profile:',
411
- choices: profiles.map(p => ({
412
- name: `${p.name} - ${p.description}`,
413
- value: p.name.toLowerCase().replace(/\s+/g, ''),
414
- short: p.name,
415
- })),
416
- },
417
- ]);
418
-
419
- return selectedProfile;
420
- }
421
-
422
- private createProgressBar(percentage: number): string {
423
- const width = 20;
424
- const filled = Math.round((percentage / 100) * width);
425
- const empty = width - filled;
426
- return (
427
- chalk.cyan('[') +
428
- chalk.green('='.repeat(filled)) +
429
- chalk.gray('-'.repeat(empty)) +
430
- chalk.cyan(']')
431
- );
432
- }
433
-
434
- private showSetupSummary(result: SetupResult): void {
435
- if (result.completedSteps.length > 0) {
436
- console.log(
437
- chalk.cyan(`šŸŽÆ Completed (${result.completedSteps.length}):`),
438
- );
439
- result.completedSteps
440
- .slice(0, 5)
441
- .forEach(step => console.log(` āœ… ${step.replace('install-', '')}`));
442
- if (result.completedSteps.length > 5) {
443
- console.log(` ... and ${result.completedSteps.length - 5} more`);
444
- }
445
- }
446
-
447
- if (result.skippedSteps.length > 0) {
448
- console.log(
449
- chalk.yellow(`\nā­ļø Skipped (${result.skippedSteps.length}):`),
450
- );
451
- result.skippedSteps
452
- .slice(0, 3)
453
- .forEach(step =>
454
- console.log(
455
- ` ā­ļø ${step.replace('install-', '')} (already installed)`,
456
- ),
457
- );
458
- }
459
- }
460
-
461
- private showErrors(result: SetupResult): void {
462
- if (result.failedSteps.length > 0) {
463
- console.log(chalk.red(`āŒ Failed (${result.failedSteps.length}):`));
464
- result.failedSteps.forEach(step =>
465
- console.log(` āŒ ${step.replace('install-', '')}`),
466
- );
467
- }
468
-
469
- if (result.errors.length > 0) {
470
- console.log(chalk.red('\nšŸ” Errors:'));
471
- result.errors
472
- .slice(0, 3)
473
- .forEach(error => console.log(` • ${error.message}`));
474
- }
475
- }
476
-
477
- private showNextSteps(): void {
478
- console.log(chalk.cyan('\nšŸ“ Next Steps:'));
479
- const steps = [
480
- 'Restart your terminal to apply changes',
481
- 'Validate setup: wundr setup:validate',
482
- 'Personalize: wundr setup:personalize',
483
- 'Start coding! šŸš€',
484
- ];
485
-
486
- steps.forEach((step, i) => {
487
- console.log(` ${i + 1}. ${step}`);
488
- });
489
- console.log();
490
- }
491
-
492
- private detectPlatform(): SetupPlatform {
493
- return {
494
- os: process.platform as 'darwin' | 'linux' | 'win32',
495
- arch: process.arch as 'x64' | 'arm64',
496
- version: process.version || 'unknown',
497
- };
498
- }
499
-
500
196
  private async checkCommand(command: string): Promise<string> {
501
197
  const { execa } = await import('execa');
502
198
  const { stdout } = await execa('sh', ['-c', command]);
@@ -71,7 +71,7 @@ export class TestInitCommand {
71
71
  await fs.writeFile(configPath, config);
72
72
 
73
73
  console.log(
74
- chalk.green('\nāœ… Test configuration created: wundr-test.config.js'),
74
+ chalk.green('\nāœ… Test configuration created: wundr-test.config.js')
75
75
  );
76
76
 
77
77
  // Add package.json scripts
@@ -225,8 +225,8 @@ jobs:
225
225
 
226
226
  console.log(
227
227
  chalk.green(
228
- 'āœ… Created GitHub Actions workflow: .github/workflows/wundr-tests.yml',
229
- ),
228
+ 'āœ… Created GitHub Actions workflow: .github/workflows/wundr-tests.yml'
229
+ )
230
230
  );
231
231
  }
232
232
  }
@@ -134,7 +134,7 @@ export default defineConfig({
134
134
 
135
135
  await fs.writeFile(
136
136
  path.join(config.outputDir, 'playwright.config.ts'),
137
- playwrightConfig,
137
+ playwrightConfig
138
138
  );
139
139
  }
140
140
 
@@ -191,7 +191,7 @@ export default defineConfig({
191
191
 
192
192
  // Check for Jest or Vitest
193
193
  const packageJson = await fs.readJson(
194
- path.join(process.cwd(), 'package.json'),
194
+ path.join(process.cwd(), 'package.json')
195
195
  );
196
196
 
197
197
  if (packageJson.scripts?.test) {
@@ -235,11 +235,11 @@ export function createTestCommand(): Command {
235
235
  .option(
236
236
  '-t, --type <type>',
237
237
  'Type of tests to run (ui, api, unit, all)',
238
- 'all',
238
+ 'all'
239
239
  )
240
240
  .option(
241
241
  '-b, --browser <browser>',
242
- 'Browser to use (chromium, firefox, webkit)',
242
+ 'Browser to use (chromium, firefox, webkit)'
243
243
  )
244
244
  .option('--headed', 'Run tests in headed mode')
245
245
  .option('--base-url <url>', 'Base URL for the application')