@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,715 @@
1
+ import { Command } from 'commander';
2
+ import * as fs from 'fs-extra';
3
+ import * as path from 'path';
4
+ import { execSync } from 'child_process';
5
+ import chalk from 'chalk';
6
+ import ora from 'ora';
7
+ import inquirer from 'inquirer';
8
+
9
+ interface ProjectInfo {
10
+ name: string;
11
+ description: string;
12
+ type: string;
13
+ hasTypeScript: boolean;
14
+ hasReact: boolean;
15
+ hasNext: boolean;
16
+ isMonorepo: boolean;
17
+ scripts: Record<string, string>;
18
+ dependencies: string[];
19
+ }
20
+
21
+ export class ClaudeInitCommand {
22
+ private spinner = ora();
23
+
24
+ constructor(private program: Command) {
25
+ this.setupCommand();
26
+ }
27
+
28
+ private setupCommand(): void {
29
+ this.program
30
+ .command('claude-init')
31
+ .alias('ci')
32
+ .description(
33
+ 'Initialize Claude Code and Claude Flow in current repository'
34
+ )
35
+ .option('-i, --interactive', 'Interactive mode with prompts')
36
+ .option('-a, --audit', 'Run repository audit first')
37
+ .option('-f, --force', 'Force overwrite existing CLAUDE.md')
38
+ .option('--agents <agents>', 'Comma-separated list of agents to enable')
39
+ .option(
40
+ '--mcp-tools <tools>',
41
+ 'Comma-separated list of MCP tools to enable'
42
+ )
43
+ .option(
44
+ '--profile <profile>',
45
+ 'Developer profile (fullstack, frontend, backend, devops)'
46
+ )
47
+ .action(async options => {
48
+ await this.execute(options);
49
+ });
50
+ }
51
+
52
+ private async execute(options: any): Promise<void> {
53
+ console.log(chalk.blue.bold('\nšŸ¤– Wundr Claude Initialization\n'));
54
+
55
+ // Check if in a git repository
56
+ if (!this.isGitRepo()) {
57
+ console.error(
58
+ chalk.red(
59
+ 'āŒ Not in a git repository. Please run this command in a git repository.'
60
+ )
61
+ );
62
+ process.exit(1);
63
+ }
64
+
65
+ // Gather project information
66
+ const projectInfo = await this.analyzeProject();
67
+
68
+ // Run audit if requested
69
+ if (options.audit) {
70
+ await this.runAudit(projectInfo);
71
+ }
72
+
73
+ // Interactive mode
74
+ if (options.interactive) {
75
+ const answers = await this.promptUser(projectInfo);
76
+ Object.assign(options, answers);
77
+ }
78
+
79
+ // Generate CLAUDE.md
80
+ await this.generateClaudeMd(projectInfo, options);
81
+
82
+ // Setup Claude Flow
83
+ await this.setupClaudeFlow(projectInfo, options);
84
+
85
+ // Setup MCP tools
86
+ await this.setupMcpTools(options.mcpTools);
87
+
88
+ // Setup agents
89
+ await this.setupAgents(
90
+ options.agents || this.getDefaultAgents(projectInfo)
91
+ );
92
+
93
+ // Setup quality hooks
94
+ await this.setupQualityHooks(projectInfo);
95
+
96
+ console.log(chalk.green.bold('\nāœ… Claude initialization complete!\n'));
97
+ this.printNextSteps();
98
+ }
99
+
100
+ private isGitRepo(): boolean {
101
+ try {
102
+ execSync('git rev-parse --git-dir', { stdio: 'ignore' });
103
+ return true;
104
+ } catch {
105
+ return false;
106
+ }
107
+ }
108
+
109
+ private async analyzeProject(): Promise<ProjectInfo> {
110
+ this.spinner.start('Analyzing project structure...');
111
+
112
+ const projectInfo: ProjectInfo = {
113
+ name: path.basename(process.cwd()),
114
+ description: 'Project repository',
115
+ type: 'unknown',
116
+ hasTypeScript: false,
117
+ hasReact: false,
118
+ hasNext: false,
119
+ isMonorepo: false,
120
+ scripts: {},
121
+ dependencies: [],
122
+ };
123
+
124
+ // Read package.json if it exists
125
+ const packageJsonPath = path.join(process.cwd(), 'package.json');
126
+ if (await fs.pathExists(packageJsonPath)) {
127
+ const pkg = await fs.readJson(packageJsonPath);
128
+ projectInfo.name = pkg.name || projectInfo.name;
129
+ projectInfo.description = pkg.description || projectInfo.description;
130
+ projectInfo.scripts = pkg.scripts || {};
131
+ projectInfo.dependencies = [
132
+ ...Object.keys(pkg.dependencies || {}),
133
+ ...Object.keys(pkg.devDependencies || {}),
134
+ ];
135
+ }
136
+
137
+ // Detect project type
138
+ projectInfo.hasTypeScript = await fs.pathExists('tsconfig.json');
139
+ projectInfo.hasReact = projectInfo.dependencies.includes('react');
140
+ projectInfo.hasNext =
141
+ (await fs.pathExists('next.config.js')) ||
142
+ (await fs.pathExists('next.config.mjs'));
143
+ projectInfo.isMonorepo =
144
+ (await fs.pathExists('lerna.json')) ||
145
+ (await fs.pathExists('pnpm-workspace.yaml')) ||
146
+ (await fs.pathExists('rush.json'));
147
+
148
+ // Determine project type
149
+ if (projectInfo.hasNext) {
150
+ projectInfo.type = 'nextjs';
151
+ } else if (projectInfo.hasReact) {
152
+ projectInfo.type = 'react';
153
+ } else if (projectInfo.hasTypeScript) {
154
+ projectInfo.type = 'typescript';
155
+ } else if (projectInfo.dependencies.includes('express')) {
156
+ projectInfo.type = 'node-backend';
157
+ } else if (projectInfo.isMonorepo) {
158
+ projectInfo.type = 'monorepo';
159
+ } else {
160
+ projectInfo.type = 'javascript';
161
+ }
162
+
163
+ this.spinner.succeed(
164
+ `Project analyzed: ${projectInfo.name} (${projectInfo.type})`
165
+ );
166
+ return projectInfo;
167
+ }
168
+
169
+ private async runAudit(projectInfo: ProjectInfo): Promise<void> {
170
+ this.spinner.start('Running repository audit...');
171
+
172
+ const auditResults = {
173
+ score: 0,
174
+ maxScore: 100,
175
+ categories: {
176
+ structure: { score: 0, maxScore: 20 },
177
+ quality: { score: 0, maxScore: 20 },
178
+ testing: { score: 0, maxScore: 20 },
179
+ documentation: { score: 0, maxScore: 20 },
180
+ security: { score: 0, maxScore: 20 },
181
+ },
182
+ recommendations: [] as string[],
183
+ };
184
+
185
+ // Structure checks
186
+ if (await fs.pathExists('src'))
187
+ auditResults.categories.structure.score += 10;
188
+ if (await fs.pathExists('.gitignore'))
189
+ auditResults.categories.structure.score += 5;
190
+ if (projectInfo.isMonorepo && (await fs.pathExists('packages'))) {
191
+ auditResults.categories.structure.score += 5;
192
+ }
193
+
194
+ // Quality checks
195
+ if (
196
+ (await fs.pathExists('.eslintrc.json')) ||
197
+ (await fs.pathExists('.eslintrc.js'))
198
+ ) {
199
+ auditResults.categories.quality.score += 10;
200
+ } else {
201
+ auditResults.recommendations.push('Add ESLint configuration');
202
+ }
203
+
204
+ if (await fs.pathExists('.prettierrc')) {
205
+ auditResults.categories.quality.score += 5;
206
+ } else {
207
+ auditResults.recommendations.push('Add Prettier configuration');
208
+ }
209
+
210
+ if (projectInfo.hasTypeScript) {
211
+ auditResults.categories.quality.score += 5;
212
+ }
213
+
214
+ // Testing checks
215
+ if (projectInfo.scripts.test) {
216
+ auditResults.categories.testing.score += 10;
217
+ } else {
218
+ auditResults.recommendations.push('Add test script to package.json');
219
+ }
220
+
221
+ if (
222
+ (await fs.pathExists('jest.config.js')) ||
223
+ (await fs.pathExists('vitest.config.js'))
224
+ ) {
225
+ auditResults.categories.testing.score += 10;
226
+ }
227
+
228
+ // Documentation checks
229
+ if (await fs.pathExists('README.md')) {
230
+ auditResults.categories.documentation.score += 10;
231
+ } else {
232
+ auditResults.recommendations.push('Add README.md');
233
+ }
234
+
235
+ if (await fs.pathExists('docs')) {
236
+ auditResults.categories.documentation.score += 10;
237
+ }
238
+
239
+ // Security checks
240
+ if (!(await fs.pathExists('.env'))) {
241
+ auditResults.categories.security.score += 10;
242
+ }
243
+
244
+ if (await fs.pathExists('.env.example')) {
245
+ auditResults.categories.security.score += 10;
246
+ } else if (await fs.pathExists('.env')) {
247
+ auditResults.recommendations.push(
248
+ 'Add .env.example for environment variables'
249
+ );
250
+ }
251
+
252
+ // Calculate total score
253
+ for (const category of Object.values(auditResults.categories)) {
254
+ auditResults.score += category.score;
255
+ }
256
+
257
+ this.spinner.succeed('Audit complete');
258
+
259
+ // Display results
260
+ console.log(chalk.cyan('\nšŸ“Š Audit Results:'));
261
+ console.log(
262
+ chalk.white(
263
+ `Overall Score: ${auditResults.score}/${auditResults.maxScore}`
264
+ )
265
+ );
266
+
267
+ for (const [name, category] of Object.entries(auditResults.categories)) {
268
+ const percentage = (category.score / category.maxScore) * 100;
269
+ const color =
270
+ percentage >= 80
271
+ ? chalk.green
272
+ : percentage >= 50
273
+ ? chalk.yellow
274
+ : chalk.red;
275
+ console.log(
276
+ color(
277
+ ` ${name}: ${category.score}/${category.maxScore} (${percentage.toFixed(0)}%)`
278
+ )
279
+ );
280
+ }
281
+
282
+ if (auditResults.recommendations.length > 0) {
283
+ console.log(chalk.yellow('\nšŸ’” Recommendations:'));
284
+ for (const rec of auditResults.recommendations) {
285
+ console.log(chalk.white(` • ${rec}`));
286
+ }
287
+ }
288
+ }
289
+
290
+ private async promptUser(projectInfo: ProjectInfo): Promise<any> {
291
+ const answers = await inquirer.prompt([
292
+ {
293
+ type: 'confirm',
294
+ name: 'setupClaudeFlow',
295
+ message: 'Setup Claude Flow orchestration?',
296
+ default: true,
297
+ },
298
+ {
299
+ type: 'checkbox',
300
+ name: 'mcpTools',
301
+ message: 'Select MCP tools to enable:',
302
+ choices: [
303
+ { name: 'Firecrawl (Web scraping)', value: 'firecrawl' },
304
+ { name: 'Context7 (Context management)', value: 'context7' },
305
+ { name: 'Playwright (Browser automation)', value: 'playwright' },
306
+ { name: 'Browser MCP (Chrome control)', value: 'browser' },
307
+ {
308
+ name: 'Sequential Thinking (MIT reasoning)',
309
+ value: 'sequentialthinking',
310
+ },
311
+ ],
312
+ default: this.getDefaultMcpTools(projectInfo),
313
+ },
314
+ {
315
+ type: 'list',
316
+ name: 'profile',
317
+ message: 'Select developer profile:',
318
+ choices: [
319
+ { name: 'Full-stack Developer', value: 'fullstack' },
320
+ { name: 'Frontend Developer', value: 'frontend' },
321
+ { name: 'Backend Developer', value: 'backend' },
322
+ { name: 'DevOps Engineer', value: 'devops' },
323
+ { name: 'Custom', value: 'custom' },
324
+ ],
325
+ default: this.getDefaultProfile(projectInfo),
326
+ },
327
+ ]);
328
+
329
+ if (answers.profile === 'custom') {
330
+ const customAgents = await inquirer.prompt([
331
+ {
332
+ type: 'checkbox',
333
+ name: 'agents',
334
+ message: 'Select agents to enable:',
335
+ choices: this.getAllAgentChoices(),
336
+ default: this.getDefaultAgents(projectInfo),
337
+ },
338
+ ]);
339
+ answers.agents = customAgents.agents.join(',');
340
+ }
341
+
342
+ return answers;
343
+ }
344
+
345
+ private getDefaultMcpTools(projectInfo: ProjectInfo): string[] {
346
+ const tools = ['sequentialthinking'];
347
+ if (projectInfo.hasReact || projectInfo.hasNext) {
348
+ tools.push('browser', 'playwright');
349
+ }
350
+ return tools;
351
+ }
352
+
353
+ private getDefaultProfile(projectInfo: ProjectInfo): string {
354
+ if (
355
+ projectInfo.hasNext ||
356
+ (projectInfo.hasReact && projectInfo.dependencies.includes('express'))
357
+ ) {
358
+ return 'fullstack';
359
+ } else if (projectInfo.hasReact) {
360
+ return 'frontend';
361
+ } else if (
362
+ projectInfo.dependencies.includes('express') ||
363
+ projectInfo.dependencies.includes('fastify')
364
+ ) {
365
+ return 'backend';
366
+ }
367
+ return 'fullstack';
368
+ }
369
+
370
+ private getDefaultAgents(projectInfo: ProjectInfo): string[] {
371
+ const agents = ['coder', 'reviewer', 'tester', 'planner', 'researcher'];
372
+
373
+ if (projectInfo.hasTypeScript) {
374
+ agents.push('system-architect');
375
+ }
376
+ if (projectInfo.hasReact || projectInfo.hasNext) {
377
+ agents.push('mobile-dev');
378
+ }
379
+ if (projectInfo.isMonorepo) {
380
+ agents.push('repo-architect', 'sync-coordinator');
381
+ }
382
+
383
+ return agents;
384
+ }
385
+
386
+ private getAllAgentChoices(): any[] {
387
+ return [
388
+ { name: 'Coder - Implementation specialist', value: 'coder' },
389
+ { name: 'Reviewer - Code review specialist', value: 'reviewer' },
390
+ { name: 'Tester - Testing specialist', value: 'tester' },
391
+ { name: 'Planner - Strategic planning', value: 'planner' },
392
+ { name: 'Researcher - Information gathering', value: 'researcher' },
393
+ {
394
+ name: 'System Architect - Architecture design',
395
+ value: 'system-architect',
396
+ },
397
+ { name: 'Mobile Dev - React Native development', value: 'mobile-dev' },
398
+ { name: 'Backend Dev - API development', value: 'backend-dev' },
399
+ { name: 'ML Developer - Machine learning', value: 'ml-developer' },
400
+ { name: 'CICD Engineer - Pipeline automation', value: 'cicd-engineer' },
401
+ { name: 'Performance Analyzer - Optimization', value: 'perf-analyzer' },
402
+ { name: 'GitHub Modes - GitHub integration', value: 'github-modes' },
403
+ { name: 'PR Manager - Pull request management', value: 'pr-manager' },
404
+ { name: 'Issue Tracker - Issue management', value: 'issue-tracker' },
405
+ {
406
+ name: 'Release Manager - Release coordination',
407
+ value: 'release-manager',
408
+ },
409
+ ];
410
+ }
411
+
412
+ private async generateClaudeMd(
413
+ projectInfo: ProjectInfo,
414
+ options: any
415
+ ): Promise<void> {
416
+ this.spinner.start('Generating CLAUDE.md...');
417
+
418
+ const claudeMdPath = path.join(process.cwd(), 'CLAUDE.md');
419
+
420
+ if ((await fs.pathExists(claudeMdPath)) && !options.force) {
421
+ const { overwrite } = await inquirer.prompt([
422
+ {
423
+ type: 'confirm',
424
+ name: 'overwrite',
425
+ message: 'CLAUDE.md already exists. Overwrite?',
426
+ default: false,
427
+ },
428
+ ]);
429
+
430
+ if (!overwrite) {
431
+ this.spinner.warn('Skipped CLAUDE.md generation');
432
+ return;
433
+ }
434
+ }
435
+
436
+ const agents = options.agents
437
+ ? options.agents.split(',')
438
+ : this.getDefaultAgents(projectInfo);
439
+ const mcpTools = options.mcpTools || this.getDefaultMcpTools(projectInfo);
440
+
441
+ const content = `# Claude Code Configuration - ${projectInfo.name}
442
+
443
+ ## Project: ${projectInfo.name}
444
+ ${projectInfo.description}
445
+
446
+ ## 🚨 CRITICAL: VERIFICATION PROTOCOL
447
+
448
+ ### MANDATORY: ALWAYS VERIFY, NEVER ASSUME
449
+ **After EVERY code change:**
450
+ 1. **TEST IT**: Run the actual command and show real output
451
+ 2. **PROVE IT**: Show file contents, build results, test output
452
+ 3. **FAIL LOUDLY**: If something fails, say "āŒ FAILED:" immediately
453
+ 4. **VERIFY SUCCESS**: Only claim "complete" after showing it working
454
+
455
+ ## Project Type: ${projectInfo.type}
456
+ - TypeScript: ${projectInfo.hasTypeScript ? 'Yes' : 'No'}
457
+ - React: ${projectInfo.hasReact ? 'Yes' : 'No'}
458
+ - Next.js: ${projectInfo.hasNext ? 'Yes' : 'No'}
459
+ - Monorepo: ${projectInfo.isMonorepo ? 'Yes' : 'No'}
460
+
461
+ ## Available Scripts
462
+ ${Object.entries(projectInfo.scripts)
463
+ .map(([key, value]) => `- \`npm run ${key}\`: ${value}`)
464
+ .join('\n')}
465
+
466
+ ## Quality Standards
467
+ - Always run \`npm run build\` after changes
468
+ ${projectInfo.scripts.test ? '- Always run `npm run test` before committing' : ''}
469
+ ${projectInfo.scripts.lint ? '- Always run `npm run lint` before committing' : ''}
470
+ ${projectInfo.scripts.typecheck ? '- Always run `npm run typecheck` for TypeScript projects' : ''}
471
+
472
+ ## Agent Configuration
473
+ Enabled agents for this project:
474
+ ${agents.map(agent => `- **${agent}**: ${this.getAgentDescription(agent)}`).join('\n')}
475
+
476
+ ## MCP Tools
477
+ Enabled MCP tools:
478
+ ${mcpTools.map((tool: string) => `- **${tool}**: ${this.getMcpToolDescription(tool)}`).join('\n')}
479
+
480
+ ## Workflow Patterns
481
+ ${this.getWorkflowPatterns(projectInfo, agents)}
482
+
483
+ ## Code Style & Best Practices
484
+ - **Modular Design**: Keep files under 500 lines
485
+ - **Environment Safety**: Never hardcode secrets
486
+ - **Test-First**: Write tests before implementation
487
+ - **Clean Architecture**: Separate concerns
488
+ - **Documentation**: Keep updated
489
+
490
+ Generated on: ${new Date().toISOString()}
491
+ By: Wundr Claude Init
492
+ `;
493
+
494
+ await fs.writeFile(claudeMdPath, content);
495
+ this.spinner.succeed('CLAUDE.md generated successfully');
496
+ }
497
+
498
+ private getAgentDescription(agent: string): string {
499
+ const descriptions: Record<string, string> = {
500
+ coder: 'Implementation and code generation',
501
+ reviewer: 'Code review and quality assurance',
502
+ tester: 'Testing and validation',
503
+ planner: 'Task planning and orchestration',
504
+ researcher: 'Research and information gathering',
505
+ 'system-architect': 'System design and architecture',
506
+ 'mobile-dev': 'React Native mobile development',
507
+ 'backend-dev': 'Backend API development',
508
+ 'ml-developer': 'Machine learning development',
509
+ 'cicd-engineer': 'CI/CD pipeline automation',
510
+ 'perf-analyzer': 'Performance analysis and optimization',
511
+ 'github-modes': 'GitHub integration and automation',
512
+ 'pr-manager': 'Pull request management',
513
+ 'issue-tracker': 'Issue tracking and management',
514
+ 'release-manager': 'Release coordination and deployment',
515
+ };
516
+ return descriptions[agent] || 'Specialized agent';
517
+ }
518
+
519
+ private getMcpToolDescription(tool: string): string {
520
+ const descriptions: Record<string, string> = {
521
+ firecrawl: 'Web scraping and crawling',
522
+ context7: 'Context management and vector search',
523
+ playwright: 'Browser automation and testing',
524
+ browser: 'Real Chrome browser control',
525
+ sequentialthinking: 'Structured reasoning and validation',
526
+ };
527
+ return descriptions[tool] || 'MCP tool';
528
+ }
529
+
530
+ private getWorkflowPatterns(
531
+ projectInfo: ProjectInfo,
532
+ agents: string[]
533
+ ): string {
534
+ const patterns: string[] = [];
535
+
536
+ if (projectInfo.hasReact || projectInfo.hasNext) {
537
+ patterns.push(`### Frontend Development
538
+ 1. Use **researcher** to analyze requirements
539
+ 2. Use **planner** to design component structure
540
+ 3. Use **coder** to implement components
541
+ 4. Use **tester** to write tests
542
+ 5. Use **reviewer** to validate code quality`);
543
+ }
544
+
545
+ if (agents.includes('github-modes')) {
546
+ patterns.push(`### GitHub Workflow
547
+ 1. Use **issue-tracker** to manage tasks
548
+ 2. Use **pr-manager** for pull requests
549
+ 3. Use **code-review-swarm** for reviews
550
+ 4. Use **release-manager** for deployments`);
551
+ }
552
+
553
+ if (projectInfo.isMonorepo) {
554
+ patterns.push(`### Monorepo Management
555
+ 1. Use **repo-architect** for structure optimization
556
+ 2. Use **sync-coordinator** for package synchronization
557
+ 3. Use **multi-repo-swarm** for cross-package changes`);
558
+ }
559
+
560
+ return patterns.join('\n\n');
561
+ }
562
+
563
+ private async setupClaudeFlow(
564
+ projectInfo: ProjectInfo,
565
+ options: any
566
+ ): Promise<void> {
567
+ if (!options.setupClaudeFlow) return;
568
+
569
+ this.spinner.start('Setting up Claude Flow...');
570
+
571
+ try {
572
+ // Initialize Claude Flow
573
+ execSync('npx claude-flow@alpha init', { stdio: 'ignore' });
574
+
575
+ // Configure for project
576
+ const config = {
577
+ project: projectInfo.name,
578
+ topology: projectInfo.isMonorepo ? 'hierarchical' : 'mesh',
579
+ agents: options.agents
580
+ ? options.agents.split(',')
581
+ : this.getDefaultAgents(projectInfo),
582
+ memory: {
583
+ backend: 'sqlite',
584
+ path: '.claude-flow/memory.db',
585
+ },
586
+ neural: {
587
+ enabled: true,
588
+ modelPath: '.claude-flow/models',
589
+ },
590
+ };
591
+
592
+ await fs.writeJson('.claude-flow/config.json', config, { spaces: 2 });
593
+ this.spinner.succeed('Claude Flow configured');
594
+ } catch (error) {
595
+ this.spinner.fail('Failed to setup Claude Flow');
596
+ console.error(chalk.red(error));
597
+ }
598
+ }
599
+
600
+ private async setupMcpTools(mcpTools: string | string[]): Promise<void> {
601
+ if (!mcpTools) return;
602
+
603
+ const tools = Array.isArray(mcpTools) ? mcpTools : mcpTools.split(',');
604
+
605
+ for (const tool of tools) {
606
+ this.spinner.start(`Installing ${tool} MCP...`);
607
+
608
+ try {
609
+ switch (tool) {
610
+ case 'firecrawl':
611
+ execSync('npx claude mcp add firecrawl npx @firecrawl/mcp-server', {
612
+ stdio: 'ignore',
613
+ });
614
+ break;
615
+ case 'context7':
616
+ execSync('npx claude mcp add context7 npx @context7/mcp-server', {
617
+ stdio: 'ignore',
618
+ });
619
+ break;
620
+ case 'playwright':
621
+ execSync(
622
+ 'npx claude mcp add playwright npx @playwright/mcp-server',
623
+ { stdio: 'ignore' }
624
+ );
625
+ break;
626
+ case 'browser':
627
+ execSync('npx claude mcp add browser npx @browser/mcp-server', {
628
+ stdio: 'ignore',
629
+ });
630
+ break;
631
+ case 'sequentialthinking':
632
+ execSync(
633
+ 'npm install -g @modelcontextprotocol/server-sequentialthinking',
634
+ { stdio: 'ignore' }
635
+ );
636
+ break;
637
+ }
638
+ this.spinner.succeed(`${tool} MCP installed`);
639
+ } catch (error) {
640
+ this.spinner.fail(`Failed to install ${tool} MCP`);
641
+ }
642
+ }
643
+ }
644
+
645
+ private async setupAgents(agents: string[]): Promise<void> {
646
+ this.spinner.start('Setting up agents...');
647
+
648
+ const agentsDir = path.join(process.cwd(), '.claude', 'agents');
649
+ await fs.ensureDir(agentsDir);
650
+
651
+ for (const agent of agents) {
652
+ const agentConfig = {
653
+ name: agent,
654
+ description: this.getAgentDescription(agent),
655
+ enabled: true,
656
+ configuration: {
657
+ maxTokens: 8000,
658
+ temperature: 0.7,
659
+ topP: 0.9,
660
+ },
661
+ };
662
+
663
+ await fs.writeJson(path.join(agentsDir, `${agent}.json`), agentConfig, {
664
+ spaces: 2,
665
+ });
666
+ }
667
+
668
+ this.spinner.succeed(`${agents.length} agents configured`);
669
+ }
670
+
671
+ private async setupQualityHooks(projectInfo: ProjectInfo): Promise<void> {
672
+ this.spinner.start('Setting up quality enforcement hooks...');
673
+
674
+ const hooksDir = path.join(process.cwd(), '.claude', 'hooks');
675
+ await fs.ensureDir(hooksDir);
676
+
677
+ // Pre-commit hook
678
+ const preCommitHook = `#!/bin/bash
679
+ # Claude Code Quality Enforcement
680
+
681
+ echo "šŸ” Running quality checks..."
682
+
683
+ ${projectInfo.scripts.typecheck ? 'npm run typecheck || exit 1' : ''}
684
+ ${projectInfo.scripts.lint ? 'npm run lint || exit 1' : ''}
685
+ ${projectInfo.scripts.test ? 'npm test || exit 1' : ''}
686
+
687
+ echo "āœ… All quality checks passed!"
688
+ `;
689
+
690
+ await fs.writeFile(path.join(hooksDir, 'pre-commit.sh'), preCommitHook);
691
+
692
+ await fs.chmod(path.join(hooksDir, 'pre-commit.sh'), '755');
693
+
694
+ this.spinner.succeed('Quality hooks configured');
695
+ }
696
+
697
+ private printNextSteps(): void {
698
+ console.log(chalk.cyan('\nšŸ“‹ Next Steps:'));
699
+ console.log(chalk.white('1. Review and customize CLAUDE.md'));
700
+ console.log(chalk.white('2. Configure API keys for MCP tools (if needed)'));
701
+ console.log(
702
+ chalk.white('3. Restart Claude Desktop to load new configurations')
703
+ );
704
+ console.log(
705
+ chalk.white(
706
+ '4. Run: npx claude-flow@alpha sparc tdd "your first feature"'
707
+ )
708
+ );
709
+ console.log(chalk.cyan('\nšŸš€ Happy coding with Claude!\n'));
710
+ }
711
+ }
712
+
713
+ const createClaudeInitCommand = (program: Command) =>
714
+ new ClaudeInitCommand(program);
715
+ export default createClaudeInitCommand;