claude-flow-novice 2.0.3 → 2.0.4

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 (272) hide show
  1. package/dist/src/cli/commands/guidance.js +487 -668
  2. package/dist/src/cli/commands/index-validate.js +18 -29
  3. package/dist/src/cli/commands/mcp-troubleshoot.js +230 -282
  4. package/dist/src/cli/commands/neural-goal-init.js +92 -125
  5. package/dist/src/cli/commands/swarm-exec.js +317 -393
  6. package/dist/src/cli/commands/swarm.js +1 -1
  7. package/dist/src/cli/commands/validate-framework.js +983 -1100
  8. package/dist/src/cli/commands/validate.js +144 -223
  9. package/dist/src/cli/simple-commands/__tests__/agent.test.js +265 -277
  10. package/dist/src/cli/simple-commands/__tests__/memory.test.js +6 -7
  11. package/dist/src/cli/simple-commands/__tests__/swarm.test.js +373 -356
  12. package/dist/src/cli/simple-commands/__tests__/task.test.js +6 -7
  13. package/dist/src/cli/simple-commands/agent.js +157 -193
  14. package/dist/src/cli/simple-commands/analysis.js +336 -446
  15. package/dist/src/cli/simple-commands/automation-executor.js +1095 -1339
  16. package/dist/src/cli/simple-commands/automation.js +481 -469
  17. package/dist/src/cli/simple-commands/batch-manager.js +261 -313
  18. package/dist/src/cli/simple-commands/claude-telemetry.js +241 -267
  19. package/dist/src/cli/simple-commands/claude-track.js +68 -90
  20. package/dist/src/cli/simple-commands/concurrent-display.js +266 -320
  21. package/dist/src/cli/simple-commands/config.js +245 -290
  22. package/dist/src/cli/simple-commands/coordination.js +182 -234
  23. package/dist/src/cli/simple-commands/enhanced-ui-views.js +812 -615
  24. package/dist/src/cli/simple-commands/enhanced-webui-complete.js +922 -981
  25. package/dist/src/cli/simple-commands/fix-hook-variables.js +274 -294
  26. package/dist/src/cli/simple-commands/github/gh-coordinator.js +378 -457
  27. package/dist/src/cli/simple-commands/github/github-api.js +535 -574
  28. package/dist/src/cli/simple-commands/github/init.js +276 -303
  29. package/dist/src/cli/simple-commands/github.js +222 -247
  30. package/dist/src/cli/simple-commands/goal.js +51 -63
  31. package/dist/src/cli/simple-commands/hive-mind/auto-save-middleware.js +208 -278
  32. package/dist/src/cli/simple-commands/hive-mind/communication.js +601 -696
  33. package/dist/src/cli/simple-commands/hive-mind/core.js +907 -979
  34. package/dist/src/cli/simple-commands/hive-mind/db-optimizer.js +406 -655
  35. package/dist/src/cli/simple-commands/hive-mind/mcp-wrapper.js +1125 -1245
  36. package/dist/src/cli/simple-commands/hive-mind/memory.js +854 -1090
  37. package/dist/src/cli/simple-commands/hive-mind/performance-optimizer.js +459 -574
  38. package/dist/src/cli/simple-commands/hive-mind/performance-test.js +263 -347
  39. package/dist/src/cli/simple-commands/hive-mind/queen.js +727 -768
  40. package/dist/src/cli/simple-commands/hive-mind/session-manager.js +745 -1049
  41. package/dist/src/cli/simple-commands/hive-mind-optimize.js +227 -283
  42. package/dist/src/cli/simple-commands/hive-mind-wizard.js +174 -217
  43. package/dist/src/cli/simple-commands/hive-mind.js +1842 -2283
  44. package/dist/src/cli/simple-commands/hive.js +90 -79
  45. package/dist/src/cli/simple-commands/hook-safety.js +431 -521
  46. package/dist/src/cli/simple-commands/hooks/session-start-soul.js +203 -254
  47. package/dist/src/cli/simple-commands/hooks.js +1064 -1204
  48. package/dist/src/cli/simple-commands/init/agent-copier.js +294 -319
  49. package/dist/src/cli/simple-commands/init/batch-init.js +496 -562
  50. package/dist/src/cli/simple-commands/init/claude-commands/claude-flow-commands.js +13 -19
  51. package/dist/src/cli/simple-commands/init/claude-commands/optimized-claude-flow-commands.js +13 -19
  52. package/dist/src/cli/simple-commands/init/claude-commands/optimized-slash-commands.js +61 -88
  53. package/dist/src/cli/simple-commands/init/claude-commands/optimized-sparc-commands.js +125 -150
  54. package/dist/src/cli/simple-commands/init/claude-commands/slash-commands.js +42 -49
  55. package/dist/src/cli/simple-commands/init/claude-commands/sparc-commands.js +43 -61
  56. package/dist/src/cli/simple-commands/init/copy-revised-templates.js +141 -147
  57. package/dist/src/cli/simple-commands/init/executable-wrapper.js +31 -44
  58. package/dist/src/cli/simple-commands/init/gitignore-updater.js +64 -90
  59. package/dist/src/cli/simple-commands/init/help.js +104 -107
  60. package/dist/src/cli/simple-commands/init/hive-mind-init.js +509 -528
  61. package/dist/src/cli/simple-commands/init/index.js +1510 -1759
  62. package/dist/src/cli/simple-commands/init/performance-monitor.js +234 -317
  63. package/dist/src/cli/simple-commands/init/rollback/backup-manager.js +441 -504
  64. package/dist/src/cli/simple-commands/init/rollback/index.js +289 -364
  65. package/dist/src/cli/simple-commands/init/rollback/recovery-manager.js +652 -728
  66. package/dist/src/cli/simple-commands/init/rollback/rollback-executor.js +416 -481
  67. package/dist/src/cli/simple-commands/init/rollback/state-tracker.js +369 -448
  68. package/dist/src/cli/simple-commands/init/sparc/roo-readme.js +1 -2
  69. package/dist/src/cli/simple-commands/init/sparc/roomodes-config.js +122 -99
  70. package/dist/src/cli/simple-commands/init/sparc/workflows.js +32 -37
  71. package/dist/src/cli/simple-commands/init/sparc-structure.js +55 -62
  72. package/dist/src/cli/simple-commands/init/template-copier.js +421 -533
  73. package/dist/src/cli/simple-commands/init/templates/coordination-md.js +3 -6
  74. package/dist/src/cli/simple-commands/init/templates/enhanced-templates.js +344 -318
  75. package/dist/src/cli/simple-commands/init/templates/github-safe-enhanced.js +173 -218
  76. package/dist/src/cli/simple-commands/init/templates/github-safe.js +65 -75
  77. package/dist/src/cli/simple-commands/init/templates/memory-bank-md.js +3 -6
  78. package/dist/src/cli/simple-commands/init/templates/readme-files.js +2 -4
  79. package/dist/src/cli/simple-commands/init/templates/safe-hook-patterns.js +187 -230
  80. package/dist/src/cli/simple-commands/init/templates/sparc-modes.js +53 -80
  81. package/dist/src/cli/simple-commands/init/templates/verification-claude-md.js +101 -85
  82. package/dist/src/cli/simple-commands/init/validation/config-validator.js +283 -330
  83. package/dist/src/cli/simple-commands/init/validation/health-checker.js +495 -561
  84. package/dist/src/cli/simple-commands/init/validation/index.js +302 -358
  85. package/dist/src/cli/simple-commands/init/validation/mode-validator.js +308 -359
  86. package/dist/src/cli/simple-commands/init/validation/post-init-validator.js +389 -366
  87. package/dist/src/cli/simple-commands/init/validation/pre-init-validator.js +270 -268
  88. package/dist/src/cli/simple-commands/init/validation/test-runner.js +427 -447
  89. package/dist/src/cli/simple-commands/init.js +1 -2
  90. package/dist/src/cli/simple-commands/mcp-health.js +131 -158
  91. package/dist/src/cli/simple-commands/mcp-integration-layer.js +533 -634
  92. package/dist/src/cli/simple-commands/mcp.js +345 -400
  93. package/dist/src/cli/simple-commands/memory-consolidation.js +426 -537
  94. package/dist/src/cli/simple-commands/memory.js +247 -311
  95. package/dist/src/cli/simple-commands/migrate-hooks.js +39 -46
  96. package/dist/src/cli/simple-commands/monitor.js +294 -363
  97. package/dist/src/cli/simple-commands/neural.js +51 -65
  98. package/dist/src/cli/simple-commands/pair-autofix-only.js +538 -662
  99. package/dist/src/cli/simple-commands/pair-basic.js +528 -656
  100. package/dist/src/cli/simple-commands/pair-old.js +430 -543
  101. package/dist/src/cli/simple-commands/pair-working.js +615 -751
  102. package/dist/src/cli/simple-commands/pair.js +615 -751
  103. package/dist/src/cli/simple-commands/performance-hooks.js +83 -111
  104. package/dist/src/cli/simple-commands/performance-metrics.js +348 -433
  105. package/dist/src/cli/simple-commands/process-ui-enhanced.js +708 -787
  106. package/dist/src/cli/simple-commands/process-ui.js +230 -254
  107. package/dist/src/cli/simple-commands/realtime-update-system.js +525 -611
  108. package/dist/src/cli/simple-commands/sparc/architecture.js +1704 -1530
  109. package/dist/src/cli/simple-commands/sparc/commands.js +438 -516
  110. package/dist/src/cli/simple-commands/sparc/completion.js +1224 -1481
  111. package/dist/src/cli/simple-commands/sparc/coordinator.js +913 -978
  112. package/dist/src/cli/simple-commands/sparc/index.js +241 -298
  113. package/dist/src/cli/simple-commands/sparc/phase-base.js +314 -390
  114. package/dist/src/cli/simple-commands/sparc/pseudocode.js +965 -869
  115. package/dist/src/cli/simple-commands/sparc/refinement.js +980 -1273
  116. package/dist/src/cli/simple-commands/sparc/specification.js +559 -645
  117. package/dist/src/cli/simple-commands/sparc-modes/architect.js +1 -1
  118. package/dist/src/cli/simple-commands/sparc-modes/ask.js +1 -1
  119. package/dist/src/cli/simple-commands/sparc-modes/code.js +1 -1
  120. package/dist/src/cli/simple-commands/sparc-modes/debug.js +1 -1
  121. package/dist/src/cli/simple-commands/sparc-modes/devops.js +1 -1
  122. package/dist/src/cli/simple-commands/sparc-modes/docs-writer.js +1 -1
  123. package/dist/src/cli/simple-commands/sparc-modes/generic.js +1 -1
  124. package/dist/src/cli/simple-commands/sparc-modes/index.js +47 -55
  125. package/dist/src/cli/simple-commands/sparc-modes/integration.js +1 -1
  126. package/dist/src/cli/simple-commands/sparc-modes/mcp.js +1 -1
  127. package/dist/src/cli/simple-commands/sparc-modes/monitoring.js +1 -1
  128. package/dist/src/cli/simple-commands/sparc-modes/optimization.js +1 -1
  129. package/dist/src/cli/simple-commands/sparc-modes/security-review.js +1 -1
  130. package/dist/src/cli/simple-commands/sparc-modes/sparc-orchestrator.js +1 -1
  131. package/dist/src/cli/simple-commands/sparc-modes/spec-pseudocode.js +1 -1
  132. package/dist/src/cli/simple-commands/sparc-modes/supabase-admin.js +1 -1
  133. package/dist/src/cli/simple-commands/sparc-modes/swarm.js +101 -87
  134. package/dist/src/cli/simple-commands/sparc-modes/tdd.js +1 -1
  135. package/dist/src/cli/simple-commands/sparc-modes/tutorial.js +1 -1
  136. package/dist/src/cli/simple-commands/sparc.js +465 -493
  137. package/dist/src/cli/simple-commands/start-ui.js +108 -132
  138. package/dist/src/cli/simple-commands/start-wrapper.js +240 -268
  139. package/dist/src/cli/simple-commands/start.js +1 -1
  140. package/dist/src/cli/simple-commands/status.js +254 -275
  141. package/dist/src/cli/simple-commands/stream-chain-clean.js +128 -171
  142. package/dist/src/cli/simple-commands/stream-chain-fixed.js +61 -82
  143. package/dist/src/cli/simple-commands/stream-chain-real.js +267 -331
  144. package/dist/src/cli/simple-commands/stream-chain-working.js +211 -263
  145. package/dist/src/cli/simple-commands/stream-chain.js +260 -318
  146. package/dist/src/cli/simple-commands/stream-processor.js +290 -315
  147. package/dist/src/cli/simple-commands/swarm-executor.js +189 -222
  148. package/dist/src/cli/simple-commands/swarm-metrics-integration.js +208 -300
  149. package/dist/src/cli/simple-commands/swarm-ui.js +623 -703
  150. package/dist/src/cli/simple-commands/swarm-webui-integration.js +258 -286
  151. package/dist/src/cli/simple-commands/swarm.js +887 -1082
  152. package/dist/src/cli/simple-commands/task.js +161 -206
  153. package/dist/src/cli/simple-commands/timestamp-fix.js +59 -89
  154. package/dist/src/cli/simple-commands/token-tracker.js +258 -316
  155. package/dist/src/cli/simple-commands/tool-execution-framework.js +433 -519
  156. package/dist/src/cli/simple-commands/train-and-stream.js +275 -331
  157. package/dist/src/cli/simple-commands/training-pipeline.js +619 -725
  158. package/dist/src/cli/simple-commands/training.js +170 -227
  159. package/dist/src/cli/simple-commands/verification-hooks.js +261 -284
  160. package/dist/src/cli/simple-commands/verification-integration.js +389 -417
  161. package/dist/src/cli/simple-commands/verification-training-integration.js +486 -606
  162. package/dist/src/cli/simple-commands/verification.js +493 -513
  163. package/dist/src/cli/simple-commands/web-server.js +766 -836
  164. package/dist/src/cli/simple-commands/webui-validator.js +106 -124
  165. package/dist/src/coordination/event-bus/demo-wasm-integration.js +212 -251
  166. package/dist/src/coordination/event-bus/qe-event-bus.js +608 -748
  167. package/dist/src/coordination/event-bus/qe-event-bus.test.js +379 -454
  168. package/dist/src/coordination/iteration-tracker.js +363 -454
  169. package/dist/src/enterprise/analytics-manager.js +1135 -0
  170. package/dist/src/enterprise/audit-manager.js +1115 -0
  171. package/dist/src/enterprise/cloud-manager.js +891 -0
  172. package/dist/src/enterprise/deployment-manager.js +966 -0
  173. package/dist/src/enterprise/index.js +6 -0
  174. package/dist/src/enterprise/project-manager.js +584 -0
  175. package/dist/src/enterprise/security-manager.js +991 -0
  176. package/dist/src/index.js +1 -1
  177. package/dist/src/mcp/DEPRECATED.js +46 -60
  178. package/dist/src/mcp/fixes/mcp-error-fixes.js +115 -134
  179. package/dist/src/mcp/implementations/agent-tracker.js +114 -128
  180. package/dist/src/mcp/implementations/daa-tools.js +292 -350
  181. package/dist/src/mcp/implementations/workflow-tools.js +329 -361
  182. package/dist/src/mcp/mcp-config-manager.js +1183 -1331
  183. package/dist/src/mcp/mcp-server-novice-simplified.js +11 -17
  184. package/dist/src/mcp/mcp-server-novice.js +11 -17
  185. package/dist/src/mcp/mcp-server-sdk.js +11 -17
  186. package/dist/src/mcp/mcp-server.js +1620 -1484
  187. package/dist/src/mcp/ruv-swarm-wrapper.js +209 -239
  188. package/dist/src/memory/advanced-serializer.js +609 -589
  189. package/dist/src/memory/enhanced-examples.js +220 -305
  190. package/dist/src/memory/enhanced-memory.js +295 -336
  191. package/dist/src/memory/enhanced-session-serializer.js +408 -492
  192. package/dist/src/memory/fallback-memory-system.js +900 -1021
  193. package/dist/src/memory/fallback-store.js +93 -131
  194. package/dist/src/memory/high-performance-serialization.js +592 -730
  195. package/dist/src/memory/in-memory-store.js +161 -213
  196. package/dist/src/memory/index.js +123 -157
  197. package/dist/src/memory/lock-free-structures.js +578 -764
  198. package/dist/src/memory/memory-mapped-persistence.js +585 -766
  199. package/dist/src/memory/memory-pressure-manager.js +569 -707
  200. package/dist/src/memory/migration.js +358 -445
  201. package/dist/src/memory/shared-memory.js +641 -768
  202. package/dist/src/memory/sqlite-store.js +245 -325
  203. package/dist/src/memory/sqlite-wrapper.js +122 -151
  204. package/dist/src/memory/swarm-memory.js +470 -603
  205. package/dist/src/memory/test-example.js +126 -134
  206. package/dist/src/memory/ultra-fast-memory-store.js +622 -821
  207. package/dist/src/memory/unified-memory-manager.js +356 -437
  208. package/dist/src/migration/index.js +92 -0
  209. package/dist/src/migration/logger.js +121 -0
  210. package/dist/src/migration/migration-analyzer.js +268 -0
  211. package/dist/src/migration/migration-runner.js +522 -0
  212. package/dist/src/migration/migration-validator.js +285 -0
  213. package/dist/src/migration/progress-reporter.js +150 -0
  214. package/dist/src/migration/rollback-manager.js +321 -0
  215. package/dist/src/migration/tests/migration-system.test.js +7 -0
  216. package/dist/src/migration/types.js +3 -0
  217. package/dist/src/swarm/CodeRefactoringSwarm.js +777 -952
  218. package/dist/src/swarm/__tests__/integration.test.js +227 -0
  219. package/dist/src/swarm/__tests__/prompt-copier.test.js +344 -0
  220. package/dist/src/swarm/advanced-orchestrator.js +1095 -0
  221. package/dist/src/swarm/claude-code-interface.js +961 -0
  222. package/dist/src/swarm/claude-flow-executor.js +229 -0
  223. package/dist/src/swarm/consensus-coordinator.js +475 -0
  224. package/dist/src/swarm/coordinator.js +2993 -0
  225. package/dist/src/swarm/direct-executor.js +1180 -0
  226. package/dist/src/swarm/error-recovery/advanced-error-detection.js +691 -0
  227. package/dist/src/swarm/error-recovery/automated-recovery-workflows.js +998 -0
  228. package/dist/src/swarm/error-recovery/error-recovery-coordinator.js +1197 -0
  229. package/dist/src/swarm/error-recovery/recovery-monitoring.js +772 -0
  230. package/dist/src/swarm/error-recovery/resilience-architecture.js +714 -0
  231. package/dist/src/swarm/error-recovery/self-healing-mechanisms.js +1319 -0
  232. package/dist/src/swarm/error-recovery/test-error-recovery-effectiveness.js +808 -0
  233. package/dist/src/swarm/executor-v2.js +322 -0
  234. package/dist/src/swarm/executor.js +815 -0
  235. package/dist/src/swarm/hive-mind-integration.js +703 -0
  236. package/dist/src/swarm/index.js +41 -0
  237. package/dist/src/swarm/json-output-aggregator.js +267 -0
  238. package/dist/src/swarm/large-scale-coordinator.js +542 -0
  239. package/dist/src/swarm/mcp-integration-wrapper.js +628 -0
  240. package/dist/src/swarm/memory.js +1117 -0
  241. package/dist/src/swarm/optimizations/__tests__/optimization.test.js +348 -0
  242. package/dist/src/swarm/optimizations/async-file-manager.js +285 -0
  243. package/dist/src/swarm/optimizations/circular-buffer.js +162 -0
  244. package/dist/src/swarm/optimizations/connection-pool.js +244 -0
  245. package/dist/src/swarm/optimizations/index.js +28 -0
  246. package/dist/src/swarm/optimizations/optimized-executor.js +320 -0
  247. package/dist/src/swarm/optimizations/ttl-map.js +234 -0
  248. package/dist/src/swarm/prompt-cli.js +200 -0
  249. package/dist/src/swarm/prompt-copier-enhanced.js +202 -0
  250. package/dist/src/swarm/prompt-copier.js +381 -0
  251. package/dist/src/swarm/prompt-manager.js +295 -0
  252. package/dist/src/swarm/prompt-utils.js +310 -0
  253. package/dist/src/swarm/result-aggregator.js +718 -0
  254. package/dist/src/swarm/sparc-executor.js +1568 -0
  255. package/dist/src/swarm/strategies/auto.js +758 -0
  256. package/dist/src/swarm/strategies/base.js +128 -0
  257. package/dist/src/swarm/strategies/research.js +914 -0
  258. package/dist/src/swarm/strategies/strategy-metrics-patch.js +2 -0
  259. package/dist/src/swarm/types.js +52 -0
  260. package/dist/src/swarm/workers/copy-worker.js +56 -0
  261. package/dist/src/utils/__tests__/github-cli-safety-wrapper.test.js +332 -400
  262. package/dist/src/utils/github-cli-safe.js +56 -64
  263. package/dist/src/utils/github-cli-safety-wrapper.js +451 -546
  264. package/dist/src/utils/npx-isolated-cache.js +104 -119
  265. package/dist/src/utils/preference-manager.js +622 -652
  266. package/dist/src/utils/timezone-utils.js +86 -105
  267. package/dist/src/validators/epic-config-schema.js +214 -0
  268. package/dist/src/validators/index.js +10 -0
  269. package/dist/src/validators/swarm-init-validator.js +259 -0
  270. package/dist/src/validators/todowrite-batching-validator.js +215 -0
  271. package/dist/src/validators/todowrite-integration.js +187 -0
  272. package/package.json +2 -2
@@ -1,1362 +1,1214 @@
1
- // Bulletproof MCP Configuration Manager
2
- // Handles Claude Code MCP configuration with comprehensive error handling
3
- // Automatically detects and fixes broken configurations with rollback capability
4
- // Provides enhanced user experience and backwards compatibility
5
-
6
- import { promises as fs } from 'fs';
7
- import path from 'path';
8
- import os from 'os';
9
- import { execSync, spawn } from 'child_process';
10
- import { existsSync } from 'fs';
11
- import { printSuccess, printWarning, printError } from '../cli/utils.js';
12
-
13
- export class McpConfigurationManager {
14
- constructor(options = {}) {
15
- this.localConfigPath = this.findClaudeConfigPath();
16
- this.projectConfigPath = path.join(process.cwd(), '.mcp.json');
17
- this.verbose = options.verbose || false;
18
- this.autoFix = options.autoFix !== false; // Default to true for bulletproof operation
19
- this.dryRun = options.dryRun || false;
20
- this.backupPaths = new Map();
21
- this.operationLog = [];
22
- this.errorRecovery = [];
23
- this.rollbackStack = [];
24
- }
25
-
26
- /**
1
+ // Bulletproof MCP Configuration Manager
2
+ // Handles Claude Code MCP configuration with comprehensive error handling
3
+ // Automatically detects and fixes broken configurations with rollback capability
4
+ // Provides enhanced user experience and backwards compatibility
5
+ import { promises as fs } from "fs";
6
+ import path from "path";
7
+ import os from "os";
8
+ import { execSync, spawn } from "child_process";
9
+ import { existsSync } from "fs";
10
+ export class McpConfigurationManager {
11
+ /**
27
12
  * Find Claude Code configuration path with comprehensive search
28
- */
29
- findClaudeConfigPath() {
30
- const homeDir = os.homedir();
31
- const primaryPath = path.join(homeDir, '.claude.json');
32
-
33
- if (existsSync(primaryPath)) {
34
- return primaryPath;
35
- }
36
-
37
- // Search alternative locations
38
- const alternativePaths = [
39
- path.join(homeDir, '.config', 'claude.json'),
40
- path.join(homeDir, '.claude', 'config.json'),
41
- path.join(homeDir, 'AppData', 'Local', 'Claude', 'config.json'), // Windows
42
- path.join(homeDir, 'Library', 'Application Support', 'Claude', 'config.json'), // macOS
43
- ];
44
-
45
- for (const altPath of alternativePaths) {
46
- if (existsSync(altPath)) {
47
- this.log(`šŸ“ Found Claude config at alternative location: ${altPath}`);
48
- return altPath;
49
- }
50
- }
51
-
52
- // Return primary path even if it doesn't exist (for creation)
53
- return primaryPath;
54
- }
55
-
56
- /**
13
+ */ findClaudeConfigPath() {
14
+ const homeDir = os.homedir();
15
+ const primaryPath = path.join(homeDir, '.claude.json');
16
+ if (existsSync(primaryPath)) {
17
+ return primaryPath;
18
+ }
19
+ // Search alternative locations
20
+ const alternativePaths = [
21
+ path.join(homeDir, '.config', 'claude.json'),
22
+ path.join(homeDir, '.claude', 'config.json'),
23
+ path.join(homeDir, 'AppData', 'Local', 'Claude', 'config.json'),
24
+ path.join(homeDir, 'Library', 'Application Support', 'Claude', 'config.json')
25
+ ];
26
+ for (const altPath of alternativePaths){
27
+ if (existsSync(altPath)) {
28
+ this.log(`šŸ“ Found Claude config at alternative location: ${altPath}`);
29
+ return altPath;
30
+ }
31
+ }
32
+ // Return primary path even if it doesn't exist (for creation)
33
+ return primaryPath;
34
+ }
35
+ /**
57
36
  * Enhanced logging with operation tracking
58
- */
59
- log(message, level = 'info') {
60
- const timestamp = new Date().toISOString();
61
- const logEntry = { timestamp, level, message };
62
- this.operationLog.push(logEntry);
63
-
64
- if (this.verbose || level === 'error' || level === 'warn') {
65
- const prefix = {
66
- info: ' ā„¹ļø',
67
- warn: ' āš ļø',
68
- error: ' āŒ',
69
- success: ' āœ…',
70
- debug: ' šŸ”'
71
- }[level] || ' Ā·';
72
-
73
- console.log(`${prefix} ${message}`);
74
- }
75
- }
76
-
77
- /**
37
+ */ log(message, level = 'info') {
38
+ const timestamp = new Date().toISOString();
39
+ const logEntry = {
40
+ timestamp,
41
+ level,
42
+ message
43
+ };
44
+ this.operationLog.push(logEntry);
45
+ if (this.verbose || level === 'error' || level === 'warn') {
46
+ const prefix = {
47
+ info: ' ā„¹ļø',
48
+ warn: ' āš ļø',
49
+ error: ' āŒ',
50
+ success: ' āœ…',
51
+ debug: ' šŸ”'
52
+ }[level] || ' Ā·';
53
+ console.log(`${prefix} ${message}`);
54
+ }
55
+ }
56
+ /**
78
57
  * Add operation to rollback stack
79
- */
80
- addRollbackOperation(operation) {
81
- this.rollbackStack.push({
82
- ...operation,
83
- timestamp: new Date().toISOString()
84
- });
85
- }
86
-
87
- /**
58
+ */ addRollbackOperation(operation) {
59
+ this.rollbackStack.push({
60
+ ...operation,
61
+ timestamp: new Date().toISOString()
62
+ });
63
+ }
64
+ /**
88
65
  * Check if Claude Code CLI is available
89
- */
90
- isClaudeCodeInstalled() {
91
- try {
92
- execSync('which claude', { stdio: 'ignore' });
93
- return true;
94
- } catch {
95
- try {
96
- execSync('claude --version', { stdio: 'ignore' });
97
- return true;
98
- } catch {
99
- return false;
100
- }
101
- }
102
- }
103
-
104
- /**
66
+ */ isClaudeCodeInstalled() {
67
+ try {
68
+ execSync('which claude', {
69
+ stdio: 'ignore'
70
+ });
71
+ return true;
72
+ } catch {
73
+ try {
74
+ execSync('claude --version', {
75
+ stdio: 'ignore'
76
+ });
77
+ return true;
78
+ } catch {
79
+ return false;
80
+ }
81
+ }
82
+ }
83
+ /**
105
84
  * Create backup with enhanced error handling
106
- */
107
- async createConfigBackup(configPath, label = 'auto') {
108
- if (!existsSync(configPath)) {
109
- this.log(`No config file to backup at: ${configPath}`, 'debug');
110
- return null;
111
- }
112
-
113
- try {
114
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
115
- const backupPath = `${configPath}.backup-${label}-${timestamp}`;
116
-
117
- if (!this.dryRun) {
118
- await fs.copyFile(configPath, backupPath);
119
- }
120
-
121
- this.backupPaths.set(configPath, backupPath);
122
- this.addRollbackOperation({
123
- type: 'restore-backup',
124
- source: backupPath,
125
- target: configPath,
126
- action: async () => {
127
- if (existsSync(backupPath)) {
128
- await fs.copyFile(backupPath, configPath);
129
- this.log(`šŸ”„ Restored ${configPath} from backup`, 'success');
130
- }
131
- }
132
- });
133
-
134
- this.log(`šŸ’¾ Created backup: ${backupPath}`, 'success');
135
- return backupPath;
136
- } catch (error) {
137
- this.log(`āš ļø Could not create backup: ${error.message}`, 'warn');
138
- return null;
139
- }
140
- }
141
-
142
- /**
85
+ */ async createConfigBackup(configPath, label = 'auto') {
86
+ if (!existsSync(configPath)) {
87
+ this.log(`No config file to backup at: ${configPath}`, 'debug');
88
+ return null;
89
+ }
90
+ try {
91
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
92
+ const backupPath = `${configPath}.backup-${label}-${timestamp}`;
93
+ if (!this.dryRun) {
94
+ await fs.copyFile(configPath, backupPath);
95
+ }
96
+ this.backupPaths.set(configPath, backupPath);
97
+ this.addRollbackOperation({
98
+ type: 'restore-backup',
99
+ source: backupPath,
100
+ target: configPath,
101
+ action: async ()=>{
102
+ if (existsSync(backupPath)) {
103
+ await fs.copyFile(backupPath, configPath);
104
+ this.log(`šŸ”„ Restored ${configPath} from backup`, 'success');
105
+ }
106
+ }
107
+ });
108
+ this.log(`šŸ’¾ Created backup: ${backupPath}`, 'success');
109
+ return backupPath;
110
+ } catch (error) {
111
+ this.log(`āš ļø Could not create backup: ${error.message}`, 'warn');
112
+ return null;
113
+ }
114
+ }
115
+ /**
143
116
  * Enhanced configuration state detection with comprehensive analysis
144
- */
145
- async detectConfigurationState() {
146
- const state = {
147
- hasLocalConfig: false,
148
- hasProjectConfig: false,
149
- localServers: [],
150
- projectServers: [],
151
- conflictingServers: [],
152
- brokenPaths: [],
153
- recommendations: [],
154
- claudeCodeInstalled: this.isClaudeCodeInstalled(),
155
- configPaths: {
156
- local: this.localConfigPath,
157
- project: this.projectConfigPath
158
- },
159
- healthScore: 100,
160
- criticalIssues: [],
161
- warnings: []
162
- };
163
-
164
- try {
165
- this.log('šŸ” Analyzing MCP configuration state...', 'info');
166
-
167
- // Check local configuration with enhanced validation
168
- if (await this.fileExists(this.localConfigPath)) {
169
- state.hasLocalConfig = true;
170
- const localConfig = await this.readLocalConfig();
171
- if (localConfig) {
172
- state.localServers = this.extractMcpServers(localConfig);
173
- this.log(`šŸ“‹ Found ${state.localServers.length} local MCP servers`, 'info');
174
- } else {
175
- state.warnings.push('Local config file exists but is invalid/corrupted');
176
- state.healthScore -= 20;
177
- }
178
- }
179
-
180
- // Check project configuration
181
- if (await this.fileExists(this.projectConfigPath)) {
182
- state.hasProjectConfig = true;
183
- const projectConfig = await this.readProjectConfig();
184
- if (projectConfig) {
185
- state.projectServers = this.extractMcpServers(projectConfig);
186
- this.log(`šŸ“‹ Found ${state.projectServers.length} project MCP servers`, 'info');
187
- } else {
188
- state.warnings.push('Project config file exists but is invalid/corrupted');
189
- state.healthScore -= 10;
190
- }
191
- }
192
-
193
- // Enhanced analysis
194
- state.conflictingServers = this.findConflictingServers(state.localServers, state.projectServers);
195
- state.brokenPaths = await this.findBrokenServerPaths([...state.localServers, ...state.projectServers]);
196
- state.recommendations = this.generateRecommendations(state);
197
-
198
- // Calculate health score
199
- if (state.conflictingServers.length > 0) {
200
- state.healthScore -= (state.conflictingServers.length * 15);
201
- state.warnings.push(`${state.conflictingServers.length} conflicting server configurations`);
202
- }
203
-
204
- if (state.brokenPaths.length > 0) {
205
- state.healthScore -= (state.brokenPaths.length * 25);
206
- state.criticalIssues.push(`${state.brokenPaths.length} broken server paths detected`);
207
- }
208
-
209
- if (!state.claudeCodeInstalled) {
210
- state.healthScore -= 30;
211
- state.warnings.push('Claude Code CLI not installed');
212
- }
213
-
214
- this.log(`šŸ“Š Configuration health score: ${state.healthScore}/100`,
215
- state.healthScore >= 80 ? 'success' : state.healthScore >= 60 ? 'warn' : 'error');
216
-
217
- return state;
218
- } catch (error) {
219
- this.log(`āŒ Failed to detect configuration state: ${error.message}`, 'error');
220
- throw new Error(`Failed to detect configuration state: ${error.message}`);
221
- }
222
- }
223
-
224
- /**
117
+ */ async detectConfigurationState() {
118
+ const state = {
119
+ hasLocalConfig: false,
120
+ hasProjectConfig: false,
121
+ localServers: [],
122
+ projectServers: [],
123
+ conflictingServers: [],
124
+ brokenPaths: [],
125
+ recommendations: [],
126
+ claudeCodeInstalled: this.isClaudeCodeInstalled(),
127
+ configPaths: {
128
+ local: this.localConfigPath,
129
+ project: this.projectConfigPath
130
+ },
131
+ healthScore: 100,
132
+ criticalIssues: [],
133
+ warnings: []
134
+ };
135
+ try {
136
+ this.log('šŸ” Analyzing MCP configuration state...', 'info');
137
+ // Check local configuration with enhanced validation
138
+ if (await this.fileExists(this.localConfigPath)) {
139
+ state.hasLocalConfig = true;
140
+ const localConfig = await this.readLocalConfig();
141
+ if (localConfig) {
142
+ state.localServers = this.extractMcpServers(localConfig);
143
+ this.log(`šŸ“‹ Found ${state.localServers.length} local MCP servers`, 'info');
144
+ } else {
145
+ state.warnings.push('Local config file exists but is invalid/corrupted');
146
+ state.healthScore -= 20;
147
+ }
148
+ }
149
+ // Check project configuration
150
+ if (await this.fileExists(this.projectConfigPath)) {
151
+ state.hasProjectConfig = true;
152
+ const projectConfig = await this.readProjectConfig();
153
+ if (projectConfig) {
154
+ state.projectServers = this.extractMcpServers(projectConfig);
155
+ this.log(`šŸ“‹ Found ${state.projectServers.length} project MCP servers`, 'info');
156
+ } else {
157
+ state.warnings.push('Project config file exists but is invalid/corrupted');
158
+ state.healthScore -= 10;
159
+ }
160
+ }
161
+ // Enhanced analysis
162
+ state.conflictingServers = this.findConflictingServers(state.localServers, state.projectServers);
163
+ state.brokenPaths = await this.findBrokenServerPaths([
164
+ ...state.localServers,
165
+ ...state.projectServers
166
+ ]);
167
+ state.recommendations = this.generateRecommendations(state);
168
+ // Calculate health score
169
+ if (state.conflictingServers.length > 0) {
170
+ state.healthScore -= state.conflictingServers.length * 15;
171
+ state.warnings.push(`${state.conflictingServers.length} conflicting server configurations`);
172
+ }
173
+ if (state.brokenPaths.length > 0) {
174
+ state.healthScore -= state.brokenPaths.length * 25;
175
+ state.criticalIssues.push(`${state.brokenPaths.length} broken server paths detected`);
176
+ }
177
+ if (!state.claudeCodeInstalled) {
178
+ state.healthScore -= 30;
179
+ state.warnings.push('Claude Code CLI not installed');
180
+ }
181
+ this.log(`šŸ“Š Configuration health score: ${state.healthScore}/100`, state.healthScore >= 80 ? 'success' : state.healthScore >= 60 ? 'warn' : 'error');
182
+ return state;
183
+ } catch (error) {
184
+ this.log(`āŒ Failed to detect configuration state: ${error.message}`, 'error');
185
+ throw new Error(`Failed to detect configuration state: ${error.message}`);
186
+ }
187
+ }
188
+ /**
225
189
  * Perform pre-initialization audit
226
- */
227
- async performPreInitAudit() {
228
- const state = await this.detectConfigurationState();
229
- const audit = {
230
- hasIssues: false,
231
- autoFixable: [],
232
- requiresConfirmation: [],
233
- blocking: [],
234
- warnings: []
235
- };
236
-
237
- // Check for broken local servers
238
- for (const brokenServer of state.brokenPaths) {
239
- if (brokenServer.serverName === 'claude-flow-novice') {
240
- audit.hasIssues = true;
241
- audit.autoFixable.push({
242
- type: 'remove-broken-local-server',
243
- description: `Remove broken local MCP server: ${brokenServer.serverName}`,
244
- serverName: brokenServer.serverName,
245
- reason: brokenServer.reason,
246
- action: () => this.removeLocalServer(brokenServer.serverName)
247
- });
248
- }
249
- }
250
-
251
- // Check for conflicting servers
252
- for (const conflict of state.conflictingServers) {
253
- if (conflict.serverName === 'claude-flow-novice') {
254
- audit.hasIssues = true;
255
- audit.requiresConfirmation.push({
256
- type: 'conflicting-server',
257
- description: `Server '${conflict.serverName}' exists in both local and project configs`,
258
- recommendation: 'Remove from local config to use project configuration',
259
- action: () => this.removeLocalServer(conflict.serverName)
260
- });
261
- }
262
- }
263
-
264
- // Check if local config takes precedence over project config
265
- if (state.hasLocalConfig && state.hasProjectConfig) {
266
- const claudeFlowInLocal = state.localServers.some(s => s.name === 'claude-flow-novice');
267
- const claudeFlowInProject = state.projectServers.some(s => s.name === 'claude-flow-novice');
268
-
269
- if (claudeFlowInLocal && claudeFlowInProject) {
270
- audit.warnings.push({
271
- type: 'precedence-warning',
272
- description: 'Local MCP config will override project config',
273
- recommendation: 'Consider removing from local config for project-specific setup'
274
- });
275
- }
276
- }
277
-
278
- return audit;
279
- }
280
-
281
- /**
190
+ */ async performPreInitAudit() {
191
+ const state = await this.detectConfigurationState();
192
+ const audit = {
193
+ hasIssues: false,
194
+ autoFixable: [],
195
+ requiresConfirmation: [],
196
+ blocking: [],
197
+ warnings: []
198
+ };
199
+ // Check for broken local servers
200
+ for (const brokenServer of state.brokenPaths){
201
+ if (brokenServer.serverName === 'claude-flow-novice') {
202
+ audit.hasIssues = true;
203
+ audit.autoFixable.push({
204
+ type: 'remove-broken-local-server',
205
+ description: `Remove broken local MCP server: ${brokenServer.serverName}`,
206
+ serverName: brokenServer.serverName,
207
+ reason: brokenServer.reason,
208
+ action: ()=>this.removeLocalServer(brokenServer.serverName)
209
+ });
210
+ }
211
+ }
212
+ // Check for conflicting servers
213
+ for (const conflict of state.conflictingServers){
214
+ if (conflict.serverName === 'claude-flow-novice') {
215
+ audit.hasIssues = true;
216
+ audit.requiresConfirmation.push({
217
+ type: 'conflicting-server',
218
+ description: `Server '${conflict.serverName}' exists in both local and project configs`,
219
+ recommendation: 'Remove from local config to use project configuration',
220
+ action: ()=>this.removeLocalServer(conflict.serverName)
221
+ });
222
+ }
223
+ }
224
+ // Check if local config takes precedence over project config
225
+ if (state.hasLocalConfig && state.hasProjectConfig) {
226
+ const claudeFlowInLocal = state.localServers.some((s)=>s.name === 'claude-flow-novice');
227
+ const claudeFlowInProject = state.projectServers.some((s)=>s.name === 'claude-flow-novice');
228
+ if (claudeFlowInLocal && claudeFlowInProject) {
229
+ audit.warnings.push({
230
+ type: 'precedence-warning',
231
+ description: 'Local MCP config will override project config',
232
+ recommendation: 'Consider removing from local config for project-specific setup'
233
+ });
234
+ }
235
+ }
236
+ return audit;
237
+ }
238
+ /**
282
239
  * Bulletproof MCP setup with comprehensive error handling and rollback
283
- */
284
- async executeBulletproofSetup(serverConfig, ux = null) {
285
- this.log('šŸ”§ Executing bulletproof MCP setup...', 'info');
286
- const startTime = Date.now();
287
-
288
- try {
289
- // Phase 1: System validation and pre-audit
290
- this.log('šŸ” Phase 1: System validation and pre-audit...', 'info');
291
- if (ux) ux.displaySetupProgress('pre-audit');
292
-
293
- if (!this.isClaudeCodeInstalled()) {
294
- const error = new Error('Claude Code CLI not installed');
295
- error.recovery = [
296
- 'Install Claude Code: npm install -g @anthropic-ai/claude-code',
297
- 'Verify installation: claude --version',
298
- 'Re-run setup after installation'
299
- ];
300
- throw error;
301
- }
302
-
303
- const audit = await this.performPreInitAudit();
304
- const state = await this.detectConfigurationState();
305
-
306
- // Display comprehensive analysis
307
- if (ux && this.verbose) {
308
- ux.displayConfigurationAnalysis({ ...state, hasIssues: audit.hasIssues });
309
- }
310
-
311
- // Phase 2: Create safety backups
312
- this.log('šŸ’¾ Phase 2: Creating safety backups...', 'info');
313
- if (ux) ux.displaySetupProgress('backup');
314
-
315
- if (state.hasLocalConfig) {
316
- await this.createConfigBackup(this.localConfigPath, 'pre-bulletproof');
317
- }
318
- if (state.hasProjectConfig) {
319
- await this.createConfigBackup(this.projectConfigPath, 'pre-bulletproof');
320
- }
321
-
322
- // Phase 3: Issue remediation
323
- if (audit.hasIssues || state.brokenPaths.length > 0) {
324
- this.log('šŸ”§ Phase 3: Remediating configuration issues...', 'info');
325
- if (ux) ux.displaySetupProgress('cleanup');
326
-
327
- const remediationResult = await this.performAutomatedRemediation(audit, state, ux);
328
- if (!remediationResult.success) {
329
- throw new Error(`Remediation failed: ${remediationResult.error}`);
330
- }
331
- } else {
332
- this.log('āœ… No configuration issues detected', 'success');
333
- }
334
-
335
- // Phase 4: Ensure optimal project configuration
336
- this.log('āš™ļø Phase 4: Ensuring optimal project configuration...', 'info');
337
- if (ux) ux.displaySetupProgress('project-config');
338
- await this.ensureProjectConfiguration(serverConfig);
339
-
340
- // Phase 5: Comprehensive verification
341
- this.log('āœ… Phase 5: Comprehensive verification...', 'info');
342
- if (ux) ux.displaySetupProgress('verification');
343
- const verificationResult = await this.performComprehensiveVerification();
344
-
345
- if (!verificationResult.success) {
346
- this.log('āš ļø Verification failed, attempting rollback...', 'warn');
347
- await this.performRollback();
348
- throw new Error(`Setup verification failed: ${verificationResult.error}`);
349
- }
350
-
351
- // Phase 6: Success and cleanup
352
- const duration = Date.now() - startTime;
353
- this.log(`šŸŽ‰ Bulletproof MCP setup completed successfully in ${duration}ms`, 'success');
354
- if (ux) ux.displaySetupProgress('complete');
355
-
356
- return {
357
- success: true,
358
- duration,
359
- details: {
360
- issuesFixed: audit.autoFixable.length + audit.requiresConfirmation.length,
361
- backupsCreated: this.backupPaths.size,
362
- healthScore: state.healthScore,
363
- verificationPassed: verificationResult.success,
364
- operationsPerformed: this.operationLog.length
365
- },
366
- summary: this.generateSetupSummary()
367
- };
368
-
369
- } catch (error) {
370
- this.log(`āŒ Bulletproof setup failed: ${error.message}`, 'error');
371
-
372
- // Enhanced error recovery
373
- const recoveryResult = await this.handleSetupFailure(error, ux);
374
-
375
- return {
376
- success: false,
377
- error: error.message,
378
- recovery: recoveryResult,
379
- logs: this.operationLog,
380
- rollbackAvailable: this.rollbackStack.length > 0
381
- };
382
- }
383
- }
384
-
385
- /**
240
+ */ async executeBulletproofSetup(serverConfig, ux = null) {
241
+ this.log('šŸ”§ Executing bulletproof MCP setup...', 'info');
242
+ const startTime = Date.now();
243
+ try {
244
+ // Phase 1: System validation and pre-audit
245
+ this.log('šŸ” Phase 1: System validation and pre-audit...', 'info');
246
+ if (ux) ux.displaySetupProgress('pre-audit');
247
+ if (!this.isClaudeCodeInstalled()) {
248
+ const error = new Error('Claude Code CLI not installed');
249
+ error.recovery = [
250
+ 'Install Claude Code: npm install -g @anthropic-ai/claude-code',
251
+ 'Verify installation: claude --version',
252
+ 'Re-run setup after installation'
253
+ ];
254
+ throw error;
255
+ }
256
+ const audit = await this.performPreInitAudit();
257
+ const state = await this.detectConfigurationState();
258
+ // Display comprehensive analysis
259
+ if (ux && this.verbose) {
260
+ ux.displayConfigurationAnalysis({
261
+ ...state,
262
+ hasIssues: audit.hasIssues
263
+ });
264
+ }
265
+ // Phase 2: Create safety backups
266
+ this.log('šŸ’¾ Phase 2: Creating safety backups...', 'info');
267
+ if (ux) ux.displaySetupProgress('backup');
268
+ if (state.hasLocalConfig) {
269
+ await this.createConfigBackup(this.localConfigPath, 'pre-bulletproof');
270
+ }
271
+ if (state.hasProjectConfig) {
272
+ await this.createConfigBackup(this.projectConfigPath, 'pre-bulletproof');
273
+ }
274
+ // Phase 3: Issue remediation
275
+ if (audit.hasIssues || state.brokenPaths.length > 0) {
276
+ this.log('šŸ”§ Phase 3: Remediating configuration issues...', 'info');
277
+ if (ux) ux.displaySetupProgress('cleanup');
278
+ const remediationResult = await this.performAutomatedRemediation(audit, state, ux);
279
+ if (!remediationResult.success) {
280
+ throw new Error(`Remediation failed: ${remediationResult.error}`);
281
+ }
282
+ } else {
283
+ this.log('āœ… No configuration issues detected', 'success');
284
+ }
285
+ // Phase 4: Ensure optimal project configuration
286
+ this.log('āš™ļø Phase 4: Ensuring optimal project configuration...', 'info');
287
+ if (ux) ux.displaySetupProgress('project-config');
288
+ await this.ensureProjectConfiguration(serverConfig);
289
+ // Phase 5: Comprehensive verification
290
+ this.log('āœ… Phase 5: Comprehensive verification...', 'info');
291
+ if (ux) ux.displaySetupProgress('verification');
292
+ const verificationResult = await this.performComprehensiveVerification();
293
+ if (!verificationResult.success) {
294
+ this.log('āš ļø Verification failed, attempting rollback...', 'warn');
295
+ await this.performRollback();
296
+ throw new Error(`Setup verification failed: ${verificationResult.error}`);
297
+ }
298
+ // Phase 6: Success and cleanup
299
+ const duration = Date.now() - startTime;
300
+ this.log(`šŸŽ‰ Bulletproof MCP setup completed successfully in ${duration}ms`, 'success');
301
+ if (ux) ux.displaySetupProgress('complete');
302
+ return {
303
+ success: true,
304
+ duration,
305
+ details: {
306
+ issuesFixed: audit.autoFixable.length + audit.requiresConfirmation.length,
307
+ backupsCreated: this.backupPaths.size,
308
+ healthScore: state.healthScore,
309
+ verificationPassed: verificationResult.success,
310
+ operationsPerformed: this.operationLog.length
311
+ },
312
+ summary: this.generateSetupSummary()
313
+ };
314
+ } catch (error) {
315
+ this.log(`āŒ Bulletproof setup failed: ${error.message}`, 'error');
316
+ // Enhanced error recovery
317
+ const recoveryResult = await this.handleSetupFailure(error, ux);
318
+ return {
319
+ success: false,
320
+ error: error.message,
321
+ recovery: recoveryResult,
322
+ logs: this.operationLog,
323
+ rollbackAvailable: this.rollbackStack.length > 0
324
+ };
325
+ }
326
+ }
327
+ /**
386
328
  * Ensure project configuration is correct
387
- */
388
- async ensureProjectConfiguration(serverConfig) {
389
- const defaultConfig = {
390
- mcpServers: {
391
- 'claude-flow-novice': {
392
- command: 'npx',
393
- args: ['claude-flow-novice', 'mcp', 'start'],
394
- env: {
395
- NODE_ENV: 'production',
396
- CLAUDE_FLOW_NOVICE_MODE: 'novice'
397
- }
398
- }
399
- }
400
- };
401
-
402
- const configToUse = serverConfig || defaultConfig;
403
-
404
- if (!this.dryRun) {
405
- await fs.writeFile(
406
- this.projectConfigPath,
407
- JSON.stringify(configToUse, null, 2)
408
- );
409
- this.log('āœ… Created/updated .mcp.json configuration');
410
- } else {
411
- this.log('[DRY RUN] Would create/update .mcp.json configuration');
412
- }
413
- }
414
-
415
- /**
329
+ */ async ensureProjectConfiguration(serverConfig) {
330
+ const defaultConfig = {
331
+ mcpServers: {
332
+ 'claude-flow-novice': {
333
+ command: 'npx',
334
+ args: [
335
+ 'claude-flow-novice',
336
+ 'mcp',
337
+ 'start'
338
+ ],
339
+ env: {
340
+ NODE_ENV: 'production',
341
+ CLAUDE_FLOW_NOVICE_MODE: 'novice'
342
+ }
343
+ }
344
+ }
345
+ };
346
+ const configToUse = serverConfig || defaultConfig;
347
+ if (!this.dryRun) {
348
+ await fs.writeFile(this.projectConfigPath, JSON.stringify(configToUse, null, 2));
349
+ this.log('āœ… Created/updated .mcp.json configuration');
350
+ } else {
351
+ this.log('[DRY RUN] Would create/update .mcp.json configuration');
352
+ }
353
+ }
354
+ /**
416
355
  * Remove a server from local configuration
417
- */
418
- async removeLocalServer(serverName) {
419
- try {
420
- // Use Claude CLI to remove server cleanly
421
- execSync(`claude mcp remove ${serverName} -s local`, {
422
- stdio: this.verbose ? 'inherit' : 'pipe'
423
- });
424
- this.log(`āœ… Removed ${serverName} from local configuration`);
425
- } catch (error) {
426
- // Fallback: manual removal
427
- await this.manuallyRemoveFromLocalConfig(serverName);
428
- }
429
- }
430
-
431
- /**
356
+ */ async removeLocalServer(serverName) {
357
+ try {
358
+ // Use Claude CLI to remove server cleanly
359
+ execSync(`claude mcp remove ${serverName} -s local`, {
360
+ stdio: this.verbose ? 'inherit' : 'pipe'
361
+ });
362
+ this.log(`āœ… Removed ${serverName} from local configuration`);
363
+ } catch (error) {
364
+ // Fallback: manual removal
365
+ await this.manuallyRemoveFromLocalConfig(serverName);
366
+ }
367
+ }
368
+ /**
432
369
  * Manually remove server from local config (fallback)
433
- */
434
- async manuallyRemoveFromLocalConfig(serverName) {
435
- try {
436
- const localConfig = await this.readLocalConfig();
437
- if (localConfig?.mcpServers?.[serverName]) {
438
- delete localConfig.mcpServers[serverName];
439
-
440
- // Create backup
441
- await this.createConfigBackup(this.localConfigPath);
442
-
443
- // Write updated config
444
- await fs.writeFile(
445
- this.localConfigPath,
446
- JSON.stringify(localConfig, null, 2)
447
- );
448
-
449
- this.log(`āœ… Manually removed ${serverName} from local configuration`);
450
- }
451
- } catch (error) {
452
- throw new Error(`Failed to manually remove server: ${error.message}`);
453
- }
454
- }
455
-
456
- /**
370
+ */ async manuallyRemoveFromLocalConfig(serverName) {
371
+ try {
372
+ const localConfig = await this.readLocalConfig();
373
+ if (localConfig?.mcpServers?.[serverName]) {
374
+ delete localConfig.mcpServers[serverName];
375
+ // Create backup
376
+ await this.createConfigBackup(this.localConfigPath);
377
+ // Write updated config
378
+ await fs.writeFile(this.localConfigPath, JSON.stringify(localConfig, null, 2));
379
+ this.log(`āœ… Manually removed ${serverName} from local configuration`);
380
+ }
381
+ } catch (error) {
382
+ throw new Error(`Failed to manually remove server: ${error.message}`);
383
+ }
384
+ }
385
+ /**
457
386
  * Verify the setup is working
458
- */
459
- async verifySetup() {
460
- try {
461
- // Check if Claude CLI can list servers
462
- const output = execSync('claude mcp list', {
463
- encoding: 'utf8',
464
- stdio: 'pipe'
465
- });
466
-
467
- // Check if our server is properly configured
468
- if (output.includes('claude-flow-novice')) {
469
- this.log('āœ… MCP server verification successful');
470
- } else {
471
- this.log('āš ļø MCP server not visible in claude mcp list');
472
- }
473
- } catch (error) {
474
- this.log('āš ļø Could not verify MCP setup (Claude CLI may not be installed)');
475
- }
476
- }
477
-
478
- /**
387
+ */ async verifySetup() {
388
+ try {
389
+ // Check if Claude CLI can list servers
390
+ const output = execSync('claude mcp list', {
391
+ encoding: 'utf8',
392
+ stdio: 'pipe'
393
+ });
394
+ // Check if our server is properly configured
395
+ if (output.includes('claude-flow-novice')) {
396
+ this.log('āœ… MCP server verification successful');
397
+ } else {
398
+ this.log('āš ļø MCP server not visible in claude mcp list');
399
+ }
400
+ } catch (error) {
401
+ this.log('āš ļø Could not verify MCP setup (Claude CLI may not be installed)');
402
+ }
403
+ }
404
+ /**
479
405
  * Create configuration backup
480
- */
481
- async createConfigBackup(configPath) {
482
- const backupPath = `${configPath}.backup-${Date.now()}`;
483
- try {
484
- await fs.copyFile(configPath, backupPath);
485
- this.log(`šŸ’¾ Created backup: ${backupPath}`);
486
- } catch (error) {
487
- this.log(`āš ļø Could not create backup: ${error.message}`);
488
- }
489
- }
490
-
491
- /**
406
+ */ async createConfigBackup(configPath) {
407
+ const backupPath = `${configPath}.backup-${Date.now()}`;
408
+ try {
409
+ await fs.copyFile(configPath, backupPath);
410
+ this.log(`šŸ’¾ Created backup: ${backupPath}`);
411
+ } catch (error) {
412
+ this.log(`āš ļø Could not create backup: ${error.message}`);
413
+ }
414
+ }
415
+ /**
492
416
  * Helper methods
493
- */
494
- async fileExists(filePath) {
495
- try {
496
- await fs.access(filePath);
497
- return true;
498
- } catch {
499
- return false;
500
- }
501
- }
502
-
503
- async readLocalConfig() {
504
- try {
505
- const content = await fs.readFile(this.localConfigPath, 'utf8');
506
- return JSON.parse(content);
507
- } catch {
508
- return null;
509
- }
510
- }
511
-
512
- async readProjectConfig() {
513
- try {
514
- const content = await fs.readFile(this.projectConfigPath, 'utf8');
515
- return JSON.parse(content);
516
- } catch {
517
- return null;
518
- }
519
- }
520
-
521
- extractMcpServers(config) {
522
- if (!config?.mcpServers) return [];
523
-
524
- return Object.entries(config.mcpServers).map(([name, serverConfig]) => ({
525
- name,
526
- ...serverConfig
527
- }));
528
- }
529
-
530
- findConflictingServers(localServers, projectServers) {
531
- const conflicts = [];
532
- const localNames = new Set(localServers.map(s => s.name));
533
-
534
- for (const projectServer of projectServers) {
535
- if (localNames.has(projectServer.name)) {
536
- conflicts.push({
537
- serverName: projectServer.name,
538
- localConfig: localServers.find(s => s.name === projectServer.name),
539
- projectConfig: projectServer
540
- });
541
- }
542
- }
543
-
544
- return conflicts;
545
- }
546
-
547
- /**
417
+ */ async fileExists(filePath) {
418
+ try {
419
+ await fs.access(filePath);
420
+ return true;
421
+ } catch {
422
+ return false;
423
+ }
424
+ }
425
+ async readLocalConfig() {
426
+ try {
427
+ const content = await fs.readFile(this.localConfigPath, 'utf8');
428
+ return JSON.parse(content);
429
+ } catch {
430
+ return null;
431
+ }
432
+ }
433
+ async readProjectConfig() {
434
+ try {
435
+ const content = await fs.readFile(this.projectConfigPath, 'utf8');
436
+ return JSON.parse(content);
437
+ } catch {
438
+ return null;
439
+ }
440
+ }
441
+ extractMcpServers(config) {
442
+ if (!config?.mcpServers) return [];
443
+ return Object.entries(config.mcpServers).map(([name, serverConfig])=>({
444
+ name,
445
+ ...serverConfig
446
+ }));
447
+ }
448
+ findConflictingServers(localServers, projectServers) {
449
+ const conflicts = [];
450
+ const localNames = new Set(localServers.map((s)=>s.name));
451
+ for (const projectServer of projectServers){
452
+ if (localNames.has(projectServer.name)) {
453
+ conflicts.push({
454
+ serverName: projectServer.name,
455
+ localConfig: localServers.find((s)=>s.name === projectServer.name),
456
+ projectConfig: projectServer
457
+ });
458
+ }
459
+ }
460
+ return conflicts;
461
+ }
462
+ /**
548
463
  * Enhanced broken path detection with comprehensive validation
549
- */
550
- async findBrokenServerPaths(servers) {
551
- const broken = [];
552
- this.log(`šŸ” Checking ${servers.length} servers for broken paths...`, 'debug');
553
-
554
- for (const server of servers) {
555
- const issues = await this.checkServerPath(server);
556
- if (issues.length > 0) {
557
- broken.push({
558
- serverName: server.name,
559
- command: server.command,
560
- args: server.args,
561
- issues,
562
- severity: this.calculateIssueSeverity(issues)
563
- });
564
- this.log(`šŸ” Found issues with '${server.name}': ${issues.join(', ')}`, 'warn');
565
- }
566
- }
567
-
568
- return broken;
569
- }
570
-
571
- /**
464
+ */ async findBrokenServerPaths(servers) {
465
+ const broken = [];
466
+ this.log(`šŸ” Checking ${servers.length} servers for broken paths...`, 'debug');
467
+ for (const server of servers){
468
+ const issues = await this.checkServerPath(server);
469
+ if (issues.length > 0) {
470
+ broken.push({
471
+ serverName: server.name,
472
+ command: server.command,
473
+ args: server.args,
474
+ issues,
475
+ severity: this.calculateIssueSeverity(issues)
476
+ });
477
+ this.log(`šŸ” Found issues with '${server.name}': ${issues.join(', ')}`, 'warn');
478
+ }
479
+ }
480
+ return broken;
481
+ }
482
+ /**
572
483
  * Comprehensive server path validation
573
- */
574
- async checkServerPath(server) {
575
- const issues = [];
576
-
577
- // Check for .claude-flow-novice directory references (common broken pattern)
578
- if (server.command && server.command.includes('.claude-flow-novice')) {
579
- issues.push('Command points to non-existent .claude-flow-novice directory');
580
- }
581
-
582
- if (server.args && server.args.some(arg => arg.includes('.claude-flow-novice'))) {
583
- issues.push('Arguments reference non-existent .claude-flow-novice directory');
584
- }
585
-
586
- // Check if command executable exists (when not using npx)
587
- if (server.command && server.command !== 'npx' && server.command !== 'node') {
588
- try {
589
- execSync(`which ${server.command}`, { stdio: 'ignore' });
590
- } catch {
591
- issues.push(`Command '${server.command}' not found in PATH`);
592
- }
593
- }
594
-
595
- // Check if node script files exist
596
- if (server.command === 'node' && server.args && server.args[0]) {
597
- const scriptPath = path.resolve(server.args[0]);
598
- if (!existsSync(scriptPath)) {
599
- issues.push(`Script file '${server.args[0]}' does not exist`);
600
- }
601
- }
602
-
603
- // Check for invalid configuration patterns
604
- if (!server.command) {
605
- issues.push('Missing command field');
606
- }
607
-
608
- if (server.command === 'node' && (!server.args || server.args.length === 0)) {
609
- issues.push('Node command specified but no script path provided');
610
- }
611
-
612
- // Check for outdated patterns
613
- if (server.name === 'claude-flow-novice' && server.command === 'node') {
614
- issues.push('Using outdated node-based configuration (should use npx)');
615
- }
616
-
617
- return issues;
618
- }
619
-
620
- /**
484
+ */ async checkServerPath(server) {
485
+ const issues = [];
486
+ // Check for .claude-flow-novice directory references (common broken pattern)
487
+ if (server.command && server.command.includes('.claude-flow-novice')) {
488
+ issues.push('Command points to non-existent .claude-flow-novice directory');
489
+ }
490
+ if (server.args && server.args.some((arg)=>arg.includes('.claude-flow-novice'))) {
491
+ issues.push('Arguments reference non-existent .claude-flow-novice directory');
492
+ }
493
+ // Check if command executable exists (when not using npx)
494
+ if (server.command && server.command !== 'npx' && server.command !== 'node') {
495
+ try {
496
+ execSync(`which ${server.command}`, {
497
+ stdio: 'ignore'
498
+ });
499
+ } catch {
500
+ issues.push(`Command '${server.command}' not found in PATH`);
501
+ }
502
+ }
503
+ // Check if node script files exist
504
+ if (server.command === 'node' && server.args && server.args[0]) {
505
+ const scriptPath = path.resolve(server.args[0]);
506
+ if (!existsSync(scriptPath)) {
507
+ issues.push(`Script file '${server.args[0]}' does not exist`);
508
+ }
509
+ }
510
+ // Check for invalid configuration patterns
511
+ if (!server.command) {
512
+ issues.push('Missing command field');
513
+ }
514
+ if (server.command === 'node' && (!server.args || server.args.length === 0)) {
515
+ issues.push('Node command specified but no script path provided');
516
+ }
517
+ // Check for outdated patterns
518
+ if (server.name === 'claude-flow-novice' && server.command === 'node') {
519
+ issues.push('Using outdated node-based configuration (should use npx)');
520
+ }
521
+ return issues;
522
+ }
523
+ /**
621
524
  * Calculate issue severity for prioritization
622
- */
623
- calculateIssueSeverity(issues) {
624
- let severity = 'low';
625
-
626
- for (const issue of issues) {
627
- if (issue.includes('not found') || issue.includes('does not exist')) {
628
- severity = 'critical';
629
- break;
630
- } else if (issue.includes('.claude-flow-novice') || issue.includes('outdated')) {
631
- severity = 'high';
632
- } else if (severity === 'low') {
633
- severity = 'medium';
634
- }
635
- }
636
-
637
- return severity;
638
- }
639
-
640
- generateRecommendations(state) {
641
- const recommendations = [];
642
-
643
- if (state.brokenPaths.length > 0) {
644
- recommendations.push({
645
- type: 'fix-broken-paths',
646
- priority: 'high',
647
- description: 'Remove broken MCP server configurations',
648
- action: 'Run with --auto-fix to automatically clean up'
649
- });
650
- }
651
-
652
- if (state.conflictingServers.length > 0) {
653
- recommendations.push({
654
- type: 'resolve-conflicts',
655
- priority: 'medium',
656
- description: 'Resolve configuration conflicts between local and project scopes',
657
- action: 'Remove from local config to use project-specific settings'
658
- });
659
- }
660
-
661
- return recommendations;
662
- }
663
-
664
- /**
525
+ */ calculateIssueSeverity(issues) {
526
+ let severity = 'low';
527
+ for (const issue of issues){
528
+ if (issue.includes('not found') || issue.includes('does not exist')) {
529
+ severity = 'critical';
530
+ break;
531
+ } else if (issue.includes('.claude-flow-novice') || issue.includes('outdated')) {
532
+ severity = 'high';
533
+ } else if (severity === 'low') {
534
+ severity = 'medium';
535
+ }
536
+ }
537
+ return severity;
538
+ }
539
+ generateRecommendations(state) {
540
+ const recommendations = [];
541
+ if (state.brokenPaths.length > 0) {
542
+ recommendations.push({
543
+ type: 'fix-broken-paths',
544
+ priority: 'high',
545
+ description: 'Remove broken MCP server configurations',
546
+ action: 'Run with --auto-fix to automatically clean up'
547
+ });
548
+ }
549
+ if (state.conflictingServers.length > 0) {
550
+ recommendations.push({
551
+ type: 'resolve-conflicts',
552
+ priority: 'medium',
553
+ description: 'Resolve configuration conflicts between local and project scopes',
554
+ action: 'Remove from local config to use project-specific settings'
555
+ });
556
+ }
557
+ return recommendations;
558
+ }
559
+ /**
665
560
  * Perform automated remediation of issues
666
- */
667
- async performAutomatedRemediation(audit, state, ux) {
668
- const remediationResults = [];
669
-
670
- try {
671
- // Fix critical issues first (broken paths)
672
- for (const brokenServer of state.brokenPaths) {
673
- if (brokenServer.severity === 'critical') {
674
- const result = await this.fixBrokenServer(brokenServer);
675
- remediationResults.push(result);
676
- }
677
- }
678
-
679
- // Auto-fix identified issues
680
- for (const fix of audit.autoFixable) {
681
- try {
682
- if (!this.dryRun) {
683
- await fix.action();
684
- remediationResults.push({ success: true, description: fix.description });
685
- this.log(`āœ… Fixed: ${fix.description}`, 'success');
686
- } else {
687
- this.log(`[DRY RUN] Would fix: ${fix.description}`, 'info');
688
- }
689
- } catch (error) {
690
- const failureResult = { success: false, description: fix.description, error: error.message };
691
- remediationResults.push(failureResult);
692
- this.log(`āŒ Failed to fix: ${fix.description} - ${error.message}`, 'error');
693
- }
694
- }
695
-
696
- // Handle issues requiring confirmation
697
- for (const fix of audit.requiresConfirmation) {
698
- if (this.autoFix) {
699
- try {
700
- if (!this.dryRun) {
701
- await fix.action();
702
- remediationResults.push({ success: true, description: fix.description });
703
- this.log(`āœ… Auto-fixed: ${fix.description}`, 'success');
704
- }
705
- } catch (error) {
706
- remediationResults.push({ success: false, description: fix.description, error: error.message });
707
- this.log(`āŒ Failed to auto-fix: ${fix.description} - ${error.message}`, 'error');
708
- }
709
- } else if (ux) {
710
- const confirmed = await ux.promptForConfirmation(fix.description, true);
711
- if (confirmed && !this.dryRun) {
712
- await fix.action();
713
- remediationResults.push({ success: true, description: fix.description });
714
- this.log(`āœ… User-confirmed fix: ${fix.description}`, 'success');
715
- }
716
- }
717
- }
718
-
719
- const successCount = remediationResults.filter(r => r.success).length;
720
- const failureCount = remediationResults.filter(r => !r.success).length;
721
-
722
- return {
723
- success: failureCount === 0,
724
- successCount,
725
- failureCount,
726
- results: remediationResults
727
- };
728
-
729
- } catch (error) {
730
- return {
731
- success: false,
732
- error: error.message,
733
- results: remediationResults
734
- };
735
- }
736
- }
737
-
738
- /**
561
+ */ async performAutomatedRemediation(audit, state, ux) {
562
+ const remediationResults = [];
563
+ try {
564
+ // Fix critical issues first (broken paths)
565
+ for (const brokenServer of state.brokenPaths){
566
+ if (brokenServer.severity === 'critical') {
567
+ const result = await this.fixBrokenServer(brokenServer);
568
+ remediationResults.push(result);
569
+ }
570
+ }
571
+ // Auto-fix identified issues
572
+ for (const fix of audit.autoFixable){
573
+ try {
574
+ if (!this.dryRun) {
575
+ await fix.action();
576
+ remediationResults.push({
577
+ success: true,
578
+ description: fix.description
579
+ });
580
+ this.log(`āœ… Fixed: ${fix.description}`, 'success');
581
+ } else {
582
+ this.log(`[DRY RUN] Would fix: ${fix.description}`, 'info');
583
+ }
584
+ } catch (error) {
585
+ const failureResult = {
586
+ success: false,
587
+ description: fix.description,
588
+ error: error.message
589
+ };
590
+ remediationResults.push(failureResult);
591
+ this.log(`āŒ Failed to fix: ${fix.description} - ${error.message}`, 'error');
592
+ }
593
+ }
594
+ // Handle issues requiring confirmation
595
+ for (const fix of audit.requiresConfirmation){
596
+ if (this.autoFix) {
597
+ try {
598
+ if (!this.dryRun) {
599
+ await fix.action();
600
+ remediationResults.push({
601
+ success: true,
602
+ description: fix.description
603
+ });
604
+ this.log(`āœ… Auto-fixed: ${fix.description}`, 'success');
605
+ }
606
+ } catch (error) {
607
+ remediationResults.push({
608
+ success: false,
609
+ description: fix.description,
610
+ error: error.message
611
+ });
612
+ this.log(`āŒ Failed to auto-fix: ${fix.description} - ${error.message}`, 'error');
613
+ }
614
+ } else if (ux) {
615
+ const confirmed = await ux.promptForConfirmation(fix.description, true);
616
+ if (confirmed && !this.dryRun) {
617
+ await fix.action();
618
+ remediationResults.push({
619
+ success: true,
620
+ description: fix.description
621
+ });
622
+ this.log(`āœ… User-confirmed fix: ${fix.description}`, 'success');
623
+ }
624
+ }
625
+ }
626
+ const successCount = remediationResults.filter((r)=>r.success).length;
627
+ const failureCount = remediationResults.filter((r)=>!r.success).length;
628
+ return {
629
+ success: failureCount === 0,
630
+ successCount,
631
+ failureCount,
632
+ results: remediationResults
633
+ };
634
+ } catch (error) {
635
+ return {
636
+ success: false,
637
+ error: error.message,
638
+ results: remediationResults
639
+ };
640
+ }
641
+ }
642
+ /**
739
643
  * Fix broken server configuration
740
- */
741
- async fixBrokenServer(brokenServer) {
742
- const { serverName, issues, severity } = brokenServer;
743
-
744
- try {
745
- if (serverName === 'claude-flow-novice') {
746
- // Remove broken local configuration
747
- await this.removeLocalServer(serverName);
748
- return {
749
- success: true,
750
- description: `Removed broken claude-flow-novice configuration`,
751
- action: 'removed-broken-local'
752
- };
753
- } else {
754
- // For other servers, just remove if critically broken
755
- if (severity === 'critical') {
756
- await this.removeLocalServer(serverName);
757
- return {
758
- success: true,
759
- description: `Removed critically broken server: ${serverName}`,
760
- action: 'removed-broken-server'
761
- };
762
- }
763
- }
764
-
765
- return { success: true, description: `Server ${serverName} issues noted but not critical` };
766
- } catch (error) {
767
- return {
768
- success: false,
769
- description: `Failed to fix server ${serverName}`,
770
- error: error.message
771
- };
772
- }
773
- }
774
-
775
- /**
644
+ */ async fixBrokenServer(brokenServer) {
645
+ const { serverName, issues, severity } = brokenServer;
646
+ try {
647
+ if (serverName === 'claude-flow-novice') {
648
+ // Remove broken local configuration
649
+ await this.removeLocalServer(serverName);
650
+ return {
651
+ success: true,
652
+ description: `Removed broken claude-flow-novice configuration`,
653
+ action: 'removed-broken-local'
654
+ };
655
+ } else {
656
+ // For other servers, just remove if critically broken
657
+ if (severity === 'critical') {
658
+ await this.removeLocalServer(serverName);
659
+ return {
660
+ success: true,
661
+ description: `Removed critically broken server: ${serverName}`,
662
+ action: 'removed-broken-server'
663
+ };
664
+ }
665
+ }
666
+ return {
667
+ success: true,
668
+ description: `Server ${serverName} issues noted but not critical`
669
+ };
670
+ } catch (error) {
671
+ return {
672
+ success: false,
673
+ description: `Failed to fix server ${serverName}`,
674
+ error: error.message
675
+ };
676
+ }
677
+ }
678
+ /**
776
679
  * Comprehensive verification with detailed testing
777
- */
778
- async performComprehensiveVerification() {
779
- const verificationResults = {
780
- success: true,
781
- tests: [],
782
- warnings: [],
783
- errors: []
784
- };
785
-
786
- try {
787
- this.log('🧪 Running comprehensive verification tests...', 'info');
788
-
789
- // Test 1: Claude CLI availability
790
- const cliTest = await this.testClaudeCli();
791
- verificationResults.tests.push(cliTest);
792
- if (!cliTest.passed) {
793
- verificationResults.success = false;
794
- verificationResults.errors.push('Claude CLI not available');
795
- }
796
-
797
- // Test 2: MCP server listing
798
- if (cliTest.passed) {
799
- const listTest = await this.testMcpListing();
800
- verificationResults.tests.push(listTest);
801
- if (!listTest.passed) {
802
- verificationResults.warnings.push('MCP server listing issues detected');
803
- }
804
- }
805
-
806
- // Test 3: Project configuration validation
807
- const configTest = await this.testProjectConfiguration();
808
- verificationResults.tests.push(configTest);
809
- if (!configTest.passed) {
810
- verificationResults.success = false;
811
- verificationResults.errors.push('Project configuration invalid');
812
- }
813
-
814
- // Test 4: Connection test (if possible)
815
- if (cliTest.passed && !this.dryRun) {
816
- const connectionTest = await this.testMcpConnection();
817
- verificationResults.tests.push(connectionTest);
818
- if (!connectionTest.passed) {
819
- verificationResults.warnings.push('MCP connection test failed');
820
- }
821
- }
822
-
823
- // Test 5: File permissions and accessibility
824
- const permissionTest = await this.testFilePermissions();
825
- verificationResults.tests.push(permissionTest);
826
- if (!permissionTest.passed) {
827
- verificationResults.warnings.push('File permission issues detected');
828
- }
829
-
830
- const passedTests = verificationResults.tests.filter(t => t.passed).length;
831
- const totalTests = verificationResults.tests.length;
832
-
833
- this.log(`šŸ“Š Verification complete: ${passedTests}/${totalTests} tests passed`,
834
- passedTests === totalTests ? 'success' : 'warn');
835
-
836
- return verificationResults;
837
-
838
- } catch (error) {
839
- verificationResults.success = false;
840
- verificationResults.errors.push(`Verification failed: ${error.message}`);
841
- this.log(`āŒ Verification failed: ${error.message}`, 'error');
842
- return verificationResults;
843
- }
844
- }
845
-
846
- async testClaudeCli() {
847
- try {
848
- const output = execSync('claude --version', { encoding: 'utf8', stdio: 'pipe' });
849
- return {
850
- name: 'Claude CLI Availability',
851
- passed: true,
852
- details: `Version: ${output.trim()}`
853
- };
854
- } catch (error) {
855
- return {
856
- name: 'Claude CLI Availability',
857
- passed: false,
858
- details: `Not available: ${error.message}`
859
- };
860
- }
861
- }
862
-
863
- async testMcpListing() {
864
- try {
865
- const output = execSync('claude mcp list', { encoding: 'utf8', stdio: 'pipe', timeout: 10000 });
866
- const hasClaudeFlowNovice = output.includes('claude-flow-novice');
867
- return {
868
- name: 'MCP Server Listing',
869
- passed: hasClaudeFlowNovice,
870
- details: hasClaudeFlowNovice ? 'claude-flow-novice found in listing' : 'claude-flow-novice not in listing'
871
- };
872
- } catch (error) {
873
- return {
874
- name: 'MCP Server Listing',
875
- passed: false,
876
- details: `Failed to list servers: ${error.message}`
877
- };
878
- }
879
- }
880
-
881
- async testProjectConfiguration() {
882
- try {
883
- if (!existsSync(this.projectConfigPath)) {
884
- return {
885
- name: 'Project Configuration',
886
- passed: false,
887
- details: 'Project .mcp.json file does not exist'
888
- };
889
- }
890
-
891
- const config = await this.readProjectConfig();
892
- if (!config || !config.mcpServers || !config.mcpServers['claude-flow-novice']) {
893
- return {
894
- name: 'Project Configuration',
895
- passed: false,
896
- details: 'claude-flow-novice not properly configured in project config'
897
- };
898
- }
899
-
900
- return {
901
- name: 'Project Configuration',
902
- passed: true,
903
- details: 'Project configuration valid'
904
- };
905
- } catch (error) {
906
- return {
907
- name: 'Project Configuration',
908
- passed: false,
909
- details: `Configuration test failed: ${error.message}`
910
- };
911
- }
912
- }
913
-
914
- async testMcpConnection() {
915
- try {
916
- const result = await this.runCommandWithTimeout('claude', ['mcp', 'list'], 5000);
917
- const connected = result.success && result.stdout.includes('āœ“ Connected');
918
- return {
919
- name: 'MCP Connection Test',
920
- passed: connected,
921
- details: connected ? 'Connection successful' : 'Connection test inconclusive'
922
- };
923
- } catch (error) {
924
- return {
925
- name: 'MCP Connection Test',
926
- passed: false,
927
- details: `Connection test failed: ${error.message}`
928
- };
929
- }
930
- }
931
-
932
- async testFilePermissions() {
933
- const tests = [];
934
-
935
- // Test local config permissions
936
- try {
937
- if (existsSync(this.localConfigPath)) {
938
- await fs.access(this.localConfigPath, fs.constants.R_OK | fs.constants.W_OK);
939
- tests.push({ file: 'local config', accessible: true });
940
- }
941
- } catch {
942
- tests.push({ file: 'local config', accessible: false });
943
- }
944
-
945
- // Test project config permissions
946
- try {
947
- if (existsSync(this.projectConfigPath)) {
948
- await fs.access(this.projectConfigPath, fs.constants.R_OK | fs.constants.W_OK);
949
- tests.push({ file: 'project config', accessible: true });
950
- }
951
- } catch {
952
- tests.push({ file: 'project config', accessible: false });
953
- }
954
-
955
- const allAccessible = tests.every(t => t.accessible);
956
- return {
957
- name: 'File Permissions',
958
- passed: allAccessible,
959
- details: `${tests.filter(t => t.accessible).length}/${tests.length} files accessible`
960
- };
961
- }
962
-
963
- /**
680
+ */ async performComprehensiveVerification() {
681
+ const verificationResults = {
682
+ success: true,
683
+ tests: [],
684
+ warnings: [],
685
+ errors: []
686
+ };
687
+ try {
688
+ this.log('🧪 Running comprehensive verification tests...', 'info');
689
+ // Test 1: Claude CLI availability
690
+ const cliTest = await this.testClaudeCli();
691
+ verificationResults.tests.push(cliTest);
692
+ if (!cliTest.passed) {
693
+ verificationResults.success = false;
694
+ verificationResults.errors.push('Claude CLI not available');
695
+ }
696
+ // Test 2: MCP server listing
697
+ if (cliTest.passed) {
698
+ const listTest = await this.testMcpListing();
699
+ verificationResults.tests.push(listTest);
700
+ if (!listTest.passed) {
701
+ verificationResults.warnings.push('MCP server listing issues detected');
702
+ }
703
+ }
704
+ // Test 3: Project configuration validation
705
+ const configTest = await this.testProjectConfiguration();
706
+ verificationResults.tests.push(configTest);
707
+ if (!configTest.passed) {
708
+ verificationResults.success = false;
709
+ verificationResults.errors.push('Project configuration invalid');
710
+ }
711
+ // Test 4: Connection test (if possible)
712
+ if (cliTest.passed && !this.dryRun) {
713
+ const connectionTest = await this.testMcpConnection();
714
+ verificationResults.tests.push(connectionTest);
715
+ if (!connectionTest.passed) {
716
+ verificationResults.warnings.push('MCP connection test failed');
717
+ }
718
+ }
719
+ // Test 5: File permissions and accessibility
720
+ const permissionTest = await this.testFilePermissions();
721
+ verificationResults.tests.push(permissionTest);
722
+ if (!permissionTest.passed) {
723
+ verificationResults.warnings.push('File permission issues detected');
724
+ }
725
+ const passedTests = verificationResults.tests.filter((t)=>t.passed).length;
726
+ const totalTests = verificationResults.tests.length;
727
+ this.log(`šŸ“Š Verification complete: ${passedTests}/${totalTests} tests passed`, passedTests === totalTests ? 'success' : 'warn');
728
+ return verificationResults;
729
+ } catch (error) {
730
+ verificationResults.success = false;
731
+ verificationResults.errors.push(`Verification failed: ${error.message}`);
732
+ this.log(`āŒ Verification failed: ${error.message}`, 'error');
733
+ return verificationResults;
734
+ }
735
+ }
736
+ async testClaudeCli() {
737
+ try {
738
+ const output = execSync('claude --version', {
739
+ encoding: 'utf8',
740
+ stdio: 'pipe'
741
+ });
742
+ return {
743
+ name: 'Claude CLI Availability',
744
+ passed: true,
745
+ details: `Version: ${output.trim()}`
746
+ };
747
+ } catch (error) {
748
+ return {
749
+ name: 'Claude CLI Availability',
750
+ passed: false,
751
+ details: `Not available: ${error.message}`
752
+ };
753
+ }
754
+ }
755
+ async testMcpListing() {
756
+ try {
757
+ const output = execSync('claude mcp list', {
758
+ encoding: 'utf8',
759
+ stdio: 'pipe',
760
+ timeout: 10000
761
+ });
762
+ const hasClaudeFlowNovice = output.includes('claude-flow-novice');
763
+ return {
764
+ name: 'MCP Server Listing',
765
+ passed: hasClaudeFlowNovice,
766
+ details: hasClaudeFlowNovice ? 'claude-flow-novice found in listing' : 'claude-flow-novice not in listing'
767
+ };
768
+ } catch (error) {
769
+ return {
770
+ name: 'MCP Server Listing',
771
+ passed: false,
772
+ details: `Failed to list servers: ${error.message}`
773
+ };
774
+ }
775
+ }
776
+ async testProjectConfiguration() {
777
+ try {
778
+ if (!existsSync(this.projectConfigPath)) {
779
+ return {
780
+ name: 'Project Configuration',
781
+ passed: false,
782
+ details: 'Project .mcp.json file does not exist'
783
+ };
784
+ }
785
+ const config = await this.readProjectConfig();
786
+ if (!config || !config.mcpServers || !config.mcpServers['claude-flow-novice']) {
787
+ return {
788
+ name: 'Project Configuration',
789
+ passed: false,
790
+ details: 'claude-flow-novice not properly configured in project config'
791
+ };
792
+ }
793
+ return {
794
+ name: 'Project Configuration',
795
+ passed: true,
796
+ details: 'Project configuration valid'
797
+ };
798
+ } catch (error) {
799
+ return {
800
+ name: 'Project Configuration',
801
+ passed: false,
802
+ details: `Configuration test failed: ${error.message}`
803
+ };
804
+ }
805
+ }
806
+ async testMcpConnection() {
807
+ try {
808
+ const result = await this.runCommandWithTimeout('claude', [
809
+ 'mcp',
810
+ 'list'
811
+ ], 5000);
812
+ const connected = result.success && result.stdout.includes('āœ“ Connected');
813
+ return {
814
+ name: 'MCP Connection Test',
815
+ passed: connected,
816
+ details: connected ? 'Connection successful' : 'Connection test inconclusive'
817
+ };
818
+ } catch (error) {
819
+ return {
820
+ name: 'MCP Connection Test',
821
+ passed: false,
822
+ details: `Connection test failed: ${error.message}`
823
+ };
824
+ }
825
+ }
826
+ async testFilePermissions() {
827
+ const tests = [];
828
+ // Test local config permissions
829
+ try {
830
+ if (existsSync(this.localConfigPath)) {
831
+ await fs.access(this.localConfigPath, fs.constants.R_OK | fs.constants.W_OK);
832
+ tests.push({
833
+ file: 'local config',
834
+ accessible: true
835
+ });
836
+ }
837
+ } catch {
838
+ tests.push({
839
+ file: 'local config',
840
+ accessible: false
841
+ });
842
+ }
843
+ // Test project config permissions
844
+ try {
845
+ if (existsSync(this.projectConfigPath)) {
846
+ await fs.access(this.projectConfigPath, fs.constants.R_OK | fs.constants.W_OK);
847
+ tests.push({
848
+ file: 'project config',
849
+ accessible: true
850
+ });
851
+ }
852
+ } catch {
853
+ tests.push({
854
+ file: 'project config',
855
+ accessible: false
856
+ });
857
+ }
858
+ const allAccessible = tests.every((t)=>t.accessible);
859
+ return {
860
+ name: 'File Permissions',
861
+ passed: allAccessible,
862
+ details: `${tests.filter((t)=>t.accessible).length}/${tests.length} files accessible`
863
+ };
864
+ }
865
+ /**
964
866
  * Run command with timeout
965
- */
966
- runCommandWithTimeout(command, args, timeout = 30000) {
967
- return new Promise((resolve, reject) => {
968
- const child = spawn(command, args, { stdio: 'pipe' });
969
- let stdout = '';
970
- let stderr = '';
971
-
972
- const timer = setTimeout(() => {
973
- child.kill('SIGTERM');
974
- reject(new Error(`Command timed out after ${timeout}ms`));
975
- }, timeout);
976
-
977
- child.stdout.on('data', (data) => {
978
- stdout += data.toString();
979
- });
980
-
981
- child.stderr.on('data', (data) => {
982
- stderr += data.toString();
983
- });
984
-
985
- child.on('close', (code) => {
986
- clearTimeout(timer);
987
- resolve({
988
- success: code === 0,
989
- code,
990
- stdout,
991
- stderr
992
- });
993
- });
994
-
995
- child.on('error', (error) => {
996
- clearTimeout(timer);
997
- reject(error);
998
- });
999
- });
1000
- }
1001
-
1002
- /**
867
+ */ runCommandWithTimeout(command, args, timeout = 30000) {
868
+ return new Promise((resolve, reject)=>{
869
+ const child = spawn(command, args, {
870
+ stdio: 'pipe'
871
+ });
872
+ let stdout = '';
873
+ let stderr = '';
874
+ const timer = setTimeout(()=>{
875
+ child.kill('SIGTERM');
876
+ reject(new Error(`Command timed out after ${timeout}ms`));
877
+ }, timeout);
878
+ child.stdout.on('data', (data)=>{
879
+ stdout += data.toString();
880
+ });
881
+ child.stderr.on('data', (data)=>{
882
+ stderr += data.toString();
883
+ });
884
+ child.on('close', (code)=>{
885
+ clearTimeout(timer);
886
+ resolve({
887
+ success: code === 0,
888
+ code,
889
+ stdout,
890
+ stderr
891
+ });
892
+ });
893
+ child.on('error', (error)=>{
894
+ clearTimeout(timer);
895
+ reject(error);
896
+ });
897
+ });
898
+ }
899
+ /**
1003
900
  * Perform complete rollback of all operations
1004
- */
1005
- async performRollback() {
1006
- this.log('šŸ”„ Performing rollback of all operations...', 'warn');
1007
- let rollbackCount = 0;
1008
-
1009
- // Execute rollback operations in reverse order
1010
- for (let i = this.rollbackStack.length - 1; i >= 0; i--) {
1011
- const operation = this.rollbackStack[i];
1012
- try {
1013
- if (!this.dryRun) {
1014
- await operation.action();
1015
- }
1016
- rollbackCount++;
1017
- this.log(`šŸ”„ Rolled back: ${operation.type}`, 'info');
1018
- } catch (error) {
1019
- this.log(`āŒ Rollback failed for ${operation.type}: ${error.message}`, 'error');
1020
- }
1021
- }
1022
-
1023
- this.log(`šŸ”„ Rollback completed: ${rollbackCount} operations reversed`, 'info');
1024
- return { success: rollbackCount > 0, operationsRolledBack: rollbackCount };
1025
- }
1026
-
1027
- /**
901
+ */ async performRollback() {
902
+ this.log('šŸ”„ Performing rollback of all operations...', 'warn');
903
+ let rollbackCount = 0;
904
+ // Execute rollback operations in reverse order
905
+ for(let i = this.rollbackStack.length - 1; i >= 0; i--){
906
+ const operation = this.rollbackStack[i];
907
+ try {
908
+ if (!this.dryRun) {
909
+ await operation.action();
910
+ }
911
+ rollbackCount++;
912
+ this.log(`šŸ”„ Rolled back: ${operation.type}`, 'info');
913
+ } catch (error) {
914
+ this.log(`āŒ Rollback failed for ${operation.type}: ${error.message}`, 'error');
915
+ }
916
+ }
917
+ this.log(`šŸ”„ Rollback completed: ${rollbackCount} operations reversed`, 'info');
918
+ return {
919
+ success: rollbackCount > 0,
920
+ operationsRolledBack: rollbackCount
921
+ };
922
+ }
923
+ /**
1028
924
  * Handle setup failure with comprehensive recovery
1029
- */
1030
- async handleSetupFailure(error, ux) {
1031
- this.log(`āŒ Setup failed: ${error.message}`, 'error');
1032
-
1033
- const recovery = {
1034
- rollbackPerformed: false,
1035
- backupsAvailable: this.backupPaths.size > 0,
1036
- errorAnalysis: this.analyzeError(error),
1037
- recommendedActions: []
1038
- };
1039
-
1040
- // Attempt automatic rollback if we have operations to roll back
1041
- if (this.rollbackStack.length > 0) {
1042
- try {
1043
- const rollbackResult = await this.performRollback();
1044
- recovery.rollbackPerformed = rollbackResult.success;
1045
- recovery.operationsRolledBack = rollbackResult.operationsRolledBack;
1046
- } catch (rollbackError) {
1047
- this.log(`āŒ Rollback also failed: ${rollbackError.message}`, 'error');
1048
- recovery.rollbackError = rollbackError.message;
1049
- }
1050
- }
1051
-
1052
- // Generate recovery recommendations
1053
- recovery.recommendedActions = this.generateRecoveryActions(error, recovery);
1054
-
1055
- // Display recovery information if UX is available
1056
- if (ux) {
1057
- ux.displayErrorRecovery(error, recovery);
1058
- } else {
1059
- this.displayBasicRecovery(error, recovery);
1060
- }
1061
-
1062
- return recovery;
1063
- }
1064
-
1065
- /**
925
+ */ async handleSetupFailure(error, ux) {
926
+ this.log(`āŒ Setup failed: ${error.message}`, 'error');
927
+ const recovery = {
928
+ rollbackPerformed: false,
929
+ backupsAvailable: this.backupPaths.size > 0,
930
+ errorAnalysis: this.analyzeError(error),
931
+ recommendedActions: []
932
+ };
933
+ // Attempt automatic rollback if we have operations to roll back
934
+ if (this.rollbackStack.length > 0) {
935
+ try {
936
+ const rollbackResult = await this.performRollback();
937
+ recovery.rollbackPerformed = rollbackResult.success;
938
+ recovery.operationsRolledBack = rollbackResult.operationsRolledBack;
939
+ } catch (rollbackError) {
940
+ this.log(`āŒ Rollback also failed: ${rollbackError.message}`, 'error');
941
+ recovery.rollbackError = rollbackError.message;
942
+ }
943
+ }
944
+ // Generate recovery recommendations
945
+ recovery.recommendedActions = this.generateRecoveryActions(error, recovery);
946
+ // Display recovery information if UX is available
947
+ if (ux) {
948
+ ux.displayErrorRecovery(error, recovery);
949
+ } else {
950
+ this.displayBasicRecovery(error, recovery);
951
+ }
952
+ return recovery;
953
+ }
954
+ /**
1066
955
  * Analyze error for better recovery recommendations
1067
- */
1068
- analyzeError(error) {
1069
- const analysis = {
1070
- type: 'unknown',
1071
- severity: 'medium',
1072
- recoverable: true,
1073
- category: 'general'
1074
- };
1075
-
1076
- const message = error.message.toLowerCase();
1077
-
1078
- if (message.includes('permission denied') || message.includes('eacces')) {
1079
- analysis.type = 'permission';
1080
- analysis.severity = 'high';
1081
- analysis.category = 'filesystem';
1082
- } else if (message.includes('not found') || message.includes('enoent')) {
1083
- analysis.type = 'missing-file';
1084
- analysis.severity = 'high';
1085
- analysis.category = 'filesystem';
1086
- } else if (message.includes('claude') && message.includes('not installed')) {
1087
- analysis.type = 'missing-dependency';
1088
- analysis.severity = 'critical';
1089
- analysis.category = 'environment';
1090
- analysis.recoverable = false;
1091
- } else if (message.includes('timeout') || message.includes('timed out')) {
1092
- analysis.type = 'timeout';
1093
- analysis.severity = 'medium';
1094
- analysis.category = 'network';
1095
- } else if (message.includes('json') || message.includes('parse')) {
1096
- analysis.type = 'config-corruption';
1097
- analysis.severity = 'high';
1098
- analysis.category = 'configuration';
1099
- }
1100
-
1101
- return analysis;
1102
- }
1103
-
1104
- /**
956
+ */ analyzeError(error) {
957
+ const analysis = {
958
+ type: 'unknown',
959
+ severity: 'medium',
960
+ recoverable: true,
961
+ category: 'general'
962
+ };
963
+ const message = error.message.toLowerCase();
964
+ if (message.includes('permission denied') || message.includes('eacces')) {
965
+ analysis.type = 'permission';
966
+ analysis.severity = 'high';
967
+ analysis.category = 'filesystem';
968
+ } else if (message.includes('not found') || message.includes('enoent')) {
969
+ analysis.type = 'missing-file';
970
+ analysis.severity = 'high';
971
+ analysis.category = 'filesystem';
972
+ } else if (message.includes('claude') && message.includes('not installed')) {
973
+ analysis.type = 'missing-dependency';
974
+ analysis.severity = 'critical';
975
+ analysis.category = 'environment';
976
+ analysis.recoverable = false;
977
+ } else if (message.includes('timeout') || message.includes('timed out')) {
978
+ analysis.type = 'timeout';
979
+ analysis.severity = 'medium';
980
+ analysis.category = 'network';
981
+ } else if (message.includes('json') || message.includes('parse')) {
982
+ analysis.type = 'config-corruption';
983
+ analysis.severity = 'high';
984
+ analysis.category = 'configuration';
985
+ }
986
+ return analysis;
987
+ }
988
+ /**
1105
989
  * Generate specific recovery actions based on error analysis
1106
- */
1107
- generateRecoveryActions(error, recovery) {
1108
- const actions = [];
1109
- const analysis = recovery.errorAnalysis;
1110
-
1111
- switch (analysis.type) {
1112
- case 'permission':
1113
- actions.push('Check file permissions on configuration files');
1114
- actions.push('Run with appropriate user privileges');
1115
- actions.push('Ensure home directory is accessible');
1116
- break;
1117
-
1118
- case 'missing-file':
1119
- actions.push('Verify Claude Code installation');
1120
- actions.push('Check if configuration files exist');
1121
- actions.push('Re-run initialization if needed');
1122
- break;
1123
-
1124
- case 'missing-dependency':
1125
- actions.push('Install Claude Code: npm install -g @anthropic-ai/claude-code');
1126
- actions.push('Verify installation: claude --version');
1127
- actions.push('Re-run setup after installation');
1128
- break;
1129
-
1130
- case 'timeout':
1131
- actions.push('Check network connectivity');
1132
- actions.push('Retry with increased timeout');
1133
- actions.push('Check if Claude Code service is running');
1134
- break;
1135
-
1136
- case 'config-corruption':
1137
- if (recovery.backupsAvailable) {
1138
- actions.push('Restore from automatic backup');
1139
- actions.push('Validate configuration file syntax');
1140
- }
1141
- actions.push('Remove corrupted configuration and reinitialize');
1142
- break;
1143
-
1144
- default:
1145
- actions.push('Check the error log for specific details');
1146
- actions.push('Try running with --verbose for more information');
1147
- if (recovery.backupsAvailable) {
1148
- actions.push('Restore from backup if needed');
1149
- }
1150
- actions.push('Contact support if the issue persists');
1151
- }
1152
-
1153
- return actions;
1154
- }
1155
-
1156
- /**
990
+ */ generateRecoveryActions(error, recovery) {
991
+ const actions = [];
992
+ const analysis = recovery.errorAnalysis;
993
+ switch(analysis.type){
994
+ case 'permission':
995
+ actions.push('Check file permissions on configuration files');
996
+ actions.push('Run with appropriate user privileges');
997
+ actions.push('Ensure home directory is accessible');
998
+ break;
999
+ case 'missing-file':
1000
+ actions.push('Verify Claude Code installation');
1001
+ actions.push('Check if configuration files exist');
1002
+ actions.push('Re-run initialization if needed');
1003
+ break;
1004
+ case 'missing-dependency':
1005
+ actions.push('Install Claude Code: npm install -g @anthropic-ai/claude-code');
1006
+ actions.push('Verify installation: claude --version');
1007
+ actions.push('Re-run setup after installation');
1008
+ break;
1009
+ case 'timeout':
1010
+ actions.push('Check network connectivity');
1011
+ actions.push('Retry with increased timeout');
1012
+ actions.push('Check if Claude Code service is running');
1013
+ break;
1014
+ case 'config-corruption':
1015
+ if (recovery.backupsAvailable) {
1016
+ actions.push('Restore from automatic backup');
1017
+ actions.push('Validate configuration file syntax');
1018
+ }
1019
+ actions.push('Remove corrupted configuration and reinitialize');
1020
+ break;
1021
+ default:
1022
+ actions.push('Check the error log for specific details');
1023
+ actions.push('Try running with --verbose for more information');
1024
+ if (recovery.backupsAvailable) {
1025
+ actions.push('Restore from backup if needed');
1026
+ }
1027
+ actions.push('Contact support if the issue persists');
1028
+ }
1029
+ return actions;
1030
+ }
1031
+ /**
1157
1032
  * Display basic recovery information when UX module isn't available
1158
- */
1159
- displayBasicRecovery(error, recovery) {
1160
- console.log('\nāŒ Setup Failed - Recovery Information:');
1161
- console.log(` Error: ${error.message}`);
1162
- console.log(` Type: ${recovery.errorAnalysis.type}`);
1163
- console.log(` Severity: ${recovery.errorAnalysis.severity}`);
1164
-
1165
- if (recovery.rollbackPerformed) {
1166
- console.log(`\nšŸ”„ Automatic rollback completed (${recovery.operationsRolledBack} operations)`);
1167
- }
1168
-
1169
- if (recovery.backupsAvailable) {
1170
- console.log(`\nšŸ’¾ Backups available for manual recovery`);
1171
- }
1172
-
1173
- console.log('\nšŸ› ļø Recommended actions:');
1174
- recovery.recommendedActions.forEach((action, i) => {
1175
- console.log(` ${i + 1}. ${action}`);
1176
- });
1177
- }
1178
-
1179
- /**
1033
+ */ displayBasicRecovery(error, recovery) {
1034
+ console.log('\nāŒ Setup Failed - Recovery Information:');
1035
+ console.log(` Error: ${error.message}`);
1036
+ console.log(` Type: ${recovery.errorAnalysis.type}`);
1037
+ console.log(` Severity: ${recovery.errorAnalysis.severity}`);
1038
+ if (recovery.rollbackPerformed) {
1039
+ console.log(`\nšŸ”„ Automatic rollback completed (${recovery.operationsRolledBack} operations)`);
1040
+ }
1041
+ if (recovery.backupsAvailable) {
1042
+ console.log(`\nšŸ’¾ Backups available for manual recovery`);
1043
+ }
1044
+ console.log('\nšŸ› ļø Recommended actions:');
1045
+ recovery.recommendedActions.forEach((action, i)=>{
1046
+ console.log(` ${i + 1}. ${action}`);
1047
+ });
1048
+ }
1049
+ /**
1180
1050
  * Generate comprehensive setup summary
1181
- */
1182
- generateSetupSummary() {
1183
- return {
1184
- operationsPerformed: this.operationLog.length,
1185
- backupsCreated: this.backupPaths.size,
1186
- rollbackOperationsAvailable: this.rollbackStack.length,
1187
- configurationPaths: {
1188
- local: this.localConfigPath,
1189
- project: this.projectConfigPath
1190
- },
1191
- timestamp: new Date().toISOString()
1192
- };
1193
- }
1194
- }
1195
-
1051
+ */ generateSetupSummary() {
1052
+ return {
1053
+ operationsPerformed: this.operationLog.length,
1054
+ backupsCreated: this.backupPaths.size,
1055
+ rollbackOperationsAvailable: this.rollbackStack.length,
1056
+ configurationPaths: {
1057
+ local: this.localConfigPath,
1058
+ project: this.projectConfigPath
1059
+ },
1060
+ timestamp: new Date().toISOString()
1061
+ };
1062
+ }
1063
+ constructor(options = {}){
1064
+ this.localConfigPath = this.findClaudeConfigPath();
1065
+ this.projectConfigPath = path.join(process.cwd(), '.mcp.json');
1066
+ this.verbose = options.verbose || false;
1067
+ this.autoFix = options.autoFix !== false; // Default to true for bulletproof operation
1068
+ this.dryRun = options.dryRun || false;
1069
+ this.backupPaths = new Map();
1070
+ this.operationLog = [];
1071
+ this.errorRecovery = [];
1072
+ this.rollbackStack = [];
1073
+ }
1074
+ }
1196
1075
  /**
1197
1076
  * Enhanced MCP initialization with bulletproof error handling and recovery
1198
- */
1199
- export async function enhancedMcpInit(options = {}) {
1200
- const manager = new McpConfigurationManager({
1201
- verbose: options.verbose || false,
1202
- autoFix: options.autoFix !== false, // Default to true for bulletproof operation
1203
- dryRun: options.dryRun || false
1204
- });
1205
-
1206
- console.log('šŸ” Starting enhanced MCP initialization...', options.dryRun ? ' (DRY RUN)' : '');
1207
-
1208
- try {
1209
- // Initialize UX module if available and requested
1210
- let ux = null;
1211
- if (options.enhancedUx !== false) {
1212
- try {
1213
- const { McpUserExperience } = await import('../cli/mcp-user-experience.js');
1214
- ux = new McpUserExperience({
1215
- verbose: options.verbose,
1216
- interactive: options.interactive !== false
1217
- });
1218
-
1219
- // Show educational content for first-time users
1220
- if (options.showEducation) {
1221
- ux.displayMcpEducation();
1222
- }
1223
- } catch (uxError) {
1224
- manager.log(`āš ļø UX module not available, using basic output: ${uxError.message}`, 'warn');
1225
- }
1226
- }
1227
-
1228
- // Comprehensive state detection
1229
- const state = await manager.detectConfigurationState();
1230
-
1231
- // Display state information
1232
- if (options.verbose || state.healthScore < 80) {
1233
- console.log('\nšŸ“‹ MCP Configuration Analysis:');
1234
- console.log(` Health Score: ${state.healthScore}/100 ${state.healthScore >= 80 ? 'āœ…' : state.healthScore >= 60 ? 'āš ļø' : 'āŒ'}`);
1235
- console.log(` Claude Code: ${state.claudeCodeInstalled ? 'āœ… Installed' : 'āŒ Not installed'}`);
1236
- console.log(` Local config: ${state.hasLocalConfig ? 'āœ… Found' : 'āŒ Not found'}`);
1237
- console.log(` Project config: ${state.hasProjectConfig ? 'āœ… Found' : 'āŒ Not found'}`);
1238
- console.log(` Servers: ${state.localServers.length} local, ${state.projectServers.length} project`);
1239
- console.log(` Issues: ${state.conflictingServers.length} conflicts, ${state.brokenPaths.length} broken paths`);
1240
-
1241
- if (state.criticalIssues.length > 0) {
1242
- console.log('\nāŒ Critical Issues:');
1243
- state.criticalIssues.forEach(issue => console.log(` • ${issue}`));
1244
- }
1245
-
1246
- if (state.warnings.length > 0) {
1247
- console.log('\nāš ļø Warnings:');
1248
- state.warnings.forEach(warning => console.log(` • ${warning}`));
1249
- }
1250
- }
1251
-
1252
- // Execute bulletproof setup
1253
- const result = await manager.executeBulletproofSetup(options.serverConfig, ux);
1254
-
1255
- // Enhanced success reporting
1256
- if (result.success) {
1257
- console.log('\nšŸŽ‰ Enhanced MCP initialization completed successfully!');
1258
- console.log(` Duration: ${result.duration}ms`);
1259
- console.log(` Issues Fixed: ${result.details.issuesFixed}`);
1260
- console.log(` Health Score: ${result.details.healthScore}/100`);
1261
- console.log(` Operations: ${result.details.operationsPerformed}`);
1262
-
1263
- if (result.details.backupsCreated > 0) {
1264
- console.log(` Backups Created: ${result.details.backupsCreated}`);
1265
- }
1266
-
1267
- // Show success summary if UX is available
1268
- if (ux) {
1269
- ux.displaySuccessSummary(result.details);
1270
- }
1271
- } else {
1272
- console.log('\nāŒ Enhanced MCP initialization failed');
1273
- if (result.rollbackAvailable) {
1274
- console.log(' šŸ”„ Rollback operations are available');
1275
- }
1276
- }
1277
-
1278
- return result;
1279
-
1280
- } catch (error) {
1281
- console.log(`\nāŒ Enhanced MCP init failed: ${error.message}`);
1282
-
1283
- // Provide error context
1284
- if (error.recovery) {
1285
- console.log('\nšŸ› ļø Recovery suggestions:');
1286
- error.recovery.forEach((suggestion, i) => {
1287
- console.log(` ${i + 1}. ${suggestion}`);
1288
- });
1289
- }
1290
-
1291
- return {
1292
- success: false,
1293
- error: error.message,
1294
- recovery: error.recovery || [],
1295
- logs: manager.operationLog
1296
- };
1297
- }
1298
- }
1299
-
1077
+ */ export async function enhancedMcpInit(options = {}) {
1078
+ const manager = new McpConfigurationManager({
1079
+ verbose: options.verbose || false,
1080
+ autoFix: options.autoFix !== false,
1081
+ dryRun: options.dryRun || false
1082
+ });
1083
+ console.log('šŸ” Starting enhanced MCP initialization...', options.dryRun ? ' (DRY RUN)' : '');
1084
+ try {
1085
+ // Initialize UX module if available and requested
1086
+ let ux = null;
1087
+ if (options.enhancedUx !== false) {
1088
+ try {
1089
+ const { McpUserExperience } = await import("../cli/mcp-user-experience.js");
1090
+ ux = new McpUserExperience({
1091
+ verbose: options.verbose,
1092
+ interactive: options.interactive !== false
1093
+ });
1094
+ // Show educational content for first-time users
1095
+ if (options.showEducation) {
1096
+ ux.displayMcpEducation();
1097
+ }
1098
+ } catch (uxError) {
1099
+ manager.log(`āš ļø UX module not available, using basic output: ${uxError.message}`, 'warn');
1100
+ }
1101
+ }
1102
+ // Comprehensive state detection
1103
+ const state = await manager.detectConfigurationState();
1104
+ // Display state information
1105
+ if (options.verbose || state.healthScore < 80) {
1106
+ console.log('\nšŸ“‹ MCP Configuration Analysis:');
1107
+ console.log(` Health Score: ${state.healthScore}/100 ${state.healthScore >= 80 ? 'āœ…' : state.healthScore >= 60 ? 'āš ļø' : 'āŒ'}`);
1108
+ console.log(` Claude Code: ${state.claudeCodeInstalled ? 'āœ… Installed' : 'āŒ Not installed'}`);
1109
+ console.log(` Local config: ${state.hasLocalConfig ? 'āœ… Found' : 'āŒ Not found'}`);
1110
+ console.log(` Project config: ${state.hasProjectConfig ? 'āœ… Found' : 'āŒ Not found'}`);
1111
+ console.log(` Servers: ${state.localServers.length} local, ${state.projectServers.length} project`);
1112
+ console.log(` Issues: ${state.conflictingServers.length} conflicts, ${state.brokenPaths.length} broken paths`);
1113
+ if (state.criticalIssues.length > 0) {
1114
+ console.log('\nāŒ Critical Issues:');
1115
+ state.criticalIssues.forEach((issue)=>console.log(` • ${issue}`));
1116
+ }
1117
+ if (state.warnings.length > 0) {
1118
+ console.log('\nāš ļø Warnings:');
1119
+ state.warnings.forEach((warning)=>console.log(` • ${warning}`));
1120
+ }
1121
+ }
1122
+ // Execute bulletproof setup
1123
+ const result = await manager.executeBulletproofSetup(options.serverConfig, ux);
1124
+ // Enhanced success reporting
1125
+ if (result.success) {
1126
+ console.log('\nšŸŽ‰ Enhanced MCP initialization completed successfully!');
1127
+ console.log(` Duration: ${result.duration}ms`);
1128
+ console.log(` Issues Fixed: ${result.details.issuesFixed}`);
1129
+ console.log(` Health Score: ${result.details.healthScore}/100`);
1130
+ console.log(` Operations: ${result.details.operationsPerformed}`);
1131
+ if (result.details.backupsCreated > 0) {
1132
+ console.log(` Backups Created: ${result.details.backupsCreated}`);
1133
+ }
1134
+ // Show success summary if UX is available
1135
+ if (ux) {
1136
+ ux.displaySuccessSummary(result.details);
1137
+ }
1138
+ } else {
1139
+ console.log('\nāŒ Enhanced MCP initialization failed');
1140
+ if (result.rollbackAvailable) {
1141
+ console.log(' šŸ”„ Rollback operations are available');
1142
+ }
1143
+ }
1144
+ return result;
1145
+ } catch (error) {
1146
+ console.log(`\nāŒ Enhanced MCP init failed: ${error.message}`);
1147
+ // Provide error context
1148
+ if (error.recovery) {
1149
+ console.log('\nšŸ› ļø Recovery suggestions:');
1150
+ error.recovery.forEach((suggestion, i)=>{
1151
+ console.log(` ${i + 1}. ${suggestion}`);
1152
+ });
1153
+ }
1154
+ return {
1155
+ success: false,
1156
+ error: error.message,
1157
+ recovery: error.recovery || [],
1158
+ logs: manager.operationLog
1159
+ };
1160
+ }
1161
+ }
1300
1162
  /**
1301
1163
  * Quick MCP health check for troubleshooting
1302
- */
1303
- export async function quickMcpHealthCheck(options = {}) {
1304
- const manager = new McpConfigurationManager({
1305
- verbose: options.verbose || false,
1306
- dryRun: true // Health check is always read-only
1307
- });
1308
-
1309
- console.log('šŸ„ Quick MCP health check...');
1310
-
1311
- try {
1312
- const state = await manager.detectConfigurationState();
1313
- const verification = await manager.performComprehensiveVerification();
1314
-
1315
- console.log('\nšŸ“Š Health Report:');
1316
- console.log(` Overall Health: ${state.healthScore}/100 ${state.healthScore >= 80 ? 'āœ…' : state.healthScore >= 60 ? 'āš ļø' : 'āŒ'}`);
1317
- console.log(` Claude Code: ${state.claudeCodeInstalled ? 'āœ…' : 'āŒ'}`);
1318
- console.log(` Configuration: ${state.hasLocalConfig || state.hasProjectConfig ? 'āœ…' : 'āŒ'}`);
1319
- console.log(` Verification: ${verification.tests.filter(t => t.passed).length}/${verification.tests.length} tests passed`);
1320
-
1321
- if (state.brokenPaths.length > 0) {
1322
- console.log('\nāŒ Broken Configurations:');
1323
- state.brokenPaths.forEach(broken => {
1324
- console.log(` • ${broken.serverName}: ${broken.issues.join(', ')}`);
1325
- });
1326
- }
1327
-
1328
- if (state.conflictingServers.length > 0) {
1329
- console.log('\nāš ļø Configuration Conflicts:');
1330
- state.conflictingServers.forEach(conflict => {
1331
- console.log(` • ${conflict.serverName}: Local vs Project configuration`);
1332
- });
1333
- }
1334
-
1335
- console.log('\nšŸ› ļø Recommendations:');
1336
- if (state.recommendations.length > 0) {
1337
- state.recommendations.forEach(rec => {
1338
- console.log(` • ${rec.description}`);
1339
- });
1340
- } else {
1341
- console.log(' • No immediate action required');
1342
- }
1343
-
1344
- return {
1345
- healthy: state.healthScore >= 80 && verification.success,
1346
- healthScore: state.healthScore,
1347
- state,
1348
- verification,
1349
- needsAttention: state.healthScore < 80 || state.brokenPaths.length > 0
1350
- };
1351
-
1352
- } catch (error) {
1353
- console.log(`\nāŒ Health check failed: ${error.message}`);
1354
- return {
1355
- healthy: false,
1356
- error: error.message,
1357
- needsAttention: true
1358
- };
1359
- }
1360
- }
1361
-
1362
- export default McpConfigurationManager;
1164
+ */ export async function quickMcpHealthCheck(options = {}) {
1165
+ const manager = new McpConfigurationManager({
1166
+ verbose: options.verbose || false,
1167
+ dryRun: true // Health check is always read-only
1168
+ });
1169
+ console.log('šŸ„ Quick MCP health check...');
1170
+ try {
1171
+ const state = await manager.detectConfigurationState();
1172
+ const verification = await manager.performComprehensiveVerification();
1173
+ console.log('\nšŸ“Š Health Report:');
1174
+ console.log(` Overall Health: ${state.healthScore}/100 ${state.healthScore >= 80 ? 'āœ…' : state.healthScore >= 60 ? 'āš ļø' : 'āŒ'}`);
1175
+ console.log(` Claude Code: ${state.claudeCodeInstalled ? 'āœ…' : 'āŒ'}`);
1176
+ console.log(` Configuration: ${state.hasLocalConfig || state.hasProjectConfig ? 'āœ…' : 'āŒ'}`);
1177
+ console.log(` Verification: ${verification.tests.filter((t)=>t.passed).length}/${verification.tests.length} tests passed`);
1178
+ if (state.brokenPaths.length > 0) {
1179
+ console.log('\nāŒ Broken Configurations:');
1180
+ state.brokenPaths.forEach((broken)=>{
1181
+ console.log(` • ${broken.serverName}: ${broken.issues.join(', ')}`);
1182
+ });
1183
+ }
1184
+ if (state.conflictingServers.length > 0) {
1185
+ console.log('\nāš ļø Configuration Conflicts:');
1186
+ state.conflictingServers.forEach((conflict)=>{
1187
+ console.log(` • ${conflict.serverName}: Local vs Project configuration`);
1188
+ });
1189
+ }
1190
+ console.log('\nšŸ› ļø Recommendations:');
1191
+ if (state.recommendations.length > 0) {
1192
+ state.recommendations.forEach((rec)=>{
1193
+ console.log(` • ${rec.description}`);
1194
+ });
1195
+ } else {
1196
+ console.log(' • No immediate action required');
1197
+ }
1198
+ return {
1199
+ healthy: state.healthScore >= 80 && verification.success,
1200
+ healthScore: state.healthScore,
1201
+ state,
1202
+ verification,
1203
+ needsAttention: state.healthScore < 80 || state.brokenPaths.length > 0
1204
+ };
1205
+ } catch (error) {
1206
+ console.log(`\nāŒ Health check failed: ${error.message}`);
1207
+ return {
1208
+ healthy: false,
1209
+ error: error.message,
1210
+ needsAttention: true
1211
+ };
1212
+ }
1213
+ }
1214
+ export default McpConfigurationManager;