claude-mpm 4.7.4__py3-none-any.whl → 4.18.2__py3-none-any.whl

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 (308) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +118 -0
  3. claude_mpm/agents/BASE_ENGINEER.md +286 -0
  4. claude_mpm/agents/BASE_PM.md +106 -1
  5. claude_mpm/agents/OUTPUT_STYLE.md +329 -11
  6. claude_mpm/agents/PM_INSTRUCTIONS.md +397 -459
  7. claude_mpm/agents/agent_loader.py +17 -5
  8. claude_mpm/agents/frontmatter_validator.py +284 -253
  9. claude_mpm/agents/templates/README.md +465 -0
  10. claude_mpm/agents/templates/agent-manager.json +4 -1
  11. claude_mpm/agents/templates/agentic-coder-optimizer.json +13 -3
  12. claude_mpm/agents/templates/api_qa.json +11 -2
  13. claude_mpm/agents/templates/circuit_breakers.md +638 -0
  14. claude_mpm/agents/templates/clerk-ops.json +12 -2
  15. claude_mpm/agents/templates/code_analyzer.json +8 -2
  16. claude_mpm/agents/templates/content-agent.json +358 -0
  17. claude_mpm/agents/templates/dart_engineer.json +15 -2
  18. claude_mpm/agents/templates/data_engineer.json +15 -2
  19. claude_mpm/agents/templates/documentation.json +10 -2
  20. claude_mpm/agents/templates/engineer.json +21 -1
  21. claude_mpm/agents/templates/gcp_ops_agent.json +12 -2
  22. claude_mpm/agents/templates/git_file_tracking.md +584 -0
  23. claude_mpm/agents/templates/golang_engineer.json +270 -0
  24. claude_mpm/agents/templates/imagemagick.json +4 -1
  25. claude_mpm/agents/templates/java_engineer.json +346 -0
  26. claude_mpm/agents/templates/local_ops_agent.json +1227 -6
  27. claude_mpm/agents/templates/memory_manager.json +4 -1
  28. claude_mpm/agents/templates/nextjs_engineer.json +141 -133
  29. claude_mpm/agents/templates/ops.json +12 -2
  30. claude_mpm/agents/templates/php-engineer.json +270 -174
  31. claude_mpm/agents/templates/pm_examples.md +474 -0
  32. claude_mpm/agents/templates/pm_red_flags.md +240 -0
  33. claude_mpm/agents/templates/product_owner.json +338 -0
  34. claude_mpm/agents/templates/project_organizer.json +14 -4
  35. claude_mpm/agents/templates/prompt-engineer.json +13 -2
  36. claude_mpm/agents/templates/python_engineer.json +174 -81
  37. claude_mpm/agents/templates/qa.json +11 -2
  38. claude_mpm/agents/templates/react_engineer.json +16 -3
  39. claude_mpm/agents/templates/refactoring_engineer.json +12 -2
  40. claude_mpm/agents/templates/research.json +34 -21
  41. claude_mpm/agents/templates/response_format.md +583 -0
  42. claude_mpm/agents/templates/ruby-engineer.json +129 -192
  43. claude_mpm/agents/templates/rust_engineer.json +270 -0
  44. claude_mpm/agents/templates/security.json +10 -2
  45. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  46. claude_mpm/agents/templates/ticketing.json +10 -2
  47. claude_mpm/agents/templates/typescript_engineer.json +116 -125
  48. claude_mpm/agents/templates/validation_templates.md +312 -0
  49. claude_mpm/agents/templates/vercel_ops_agent.json +12 -2
  50. claude_mpm/agents/templates/version_control.json +12 -2
  51. claude_mpm/agents/templates/web_qa.json +11 -2
  52. claude_mpm/agents/templates/web_ui.json +15 -2
  53. claude_mpm/cli/__init__.py +34 -614
  54. claude_mpm/cli/commands/agent_manager.py +25 -12
  55. claude_mpm/cli/commands/agent_state_manager.py +186 -0
  56. claude_mpm/cli/commands/agents.py +235 -148
  57. claude_mpm/cli/commands/agents_detect.py +380 -0
  58. claude_mpm/cli/commands/agents_recommend.py +309 -0
  59. claude_mpm/cli/commands/aggregate.py +7 -3
  60. claude_mpm/cli/commands/analyze.py +9 -4
  61. claude_mpm/cli/commands/analyze_code.py +7 -2
  62. claude_mpm/cli/commands/auto_configure.py +570 -0
  63. claude_mpm/cli/commands/config.py +47 -13
  64. claude_mpm/cli/commands/configure.py +419 -1571
  65. claude_mpm/cli/commands/configure_agent_display.py +261 -0
  66. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  67. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  68. claude_mpm/cli/commands/configure_models.py +18 -0
  69. claude_mpm/cli/commands/configure_navigation.py +167 -0
  70. claude_mpm/cli/commands/configure_paths.py +104 -0
  71. claude_mpm/cli/commands/configure_persistence.py +254 -0
  72. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  73. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  74. claude_mpm/cli/commands/configure_validators.py +73 -0
  75. claude_mpm/cli/commands/local_deploy.py +537 -0
  76. claude_mpm/cli/commands/memory.py +54 -20
  77. claude_mpm/cli/commands/mpm_init.py +585 -196
  78. claude_mpm/cli/commands/mpm_init_handler.py +37 -3
  79. claude_mpm/cli/commands/search.py +170 -4
  80. claude_mpm/cli/commands/upgrade.py +152 -0
  81. claude_mpm/cli/executor.py +202 -0
  82. claude_mpm/cli/helpers.py +105 -0
  83. claude_mpm/cli/interactive/__init__.py +3 -0
  84. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  85. claude_mpm/cli/parsers/__init__.py +7 -1
  86. claude_mpm/cli/parsers/agents_parser.py +9 -0
  87. claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
  88. claude_mpm/cli/parsers/base_parser.py +110 -3
  89. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  90. claude_mpm/cli/parsers/mpm_init_parser.py +65 -5
  91. claude_mpm/cli/shared/output_formatters.py +28 -19
  92. claude_mpm/cli/startup.py +481 -0
  93. claude_mpm/cli/utils.py +52 -1
  94. claude_mpm/commands/mpm-agents-detect.md +168 -0
  95. claude_mpm/commands/mpm-agents-recommend.md +214 -0
  96. claude_mpm/commands/mpm-agents.md +75 -1
  97. claude_mpm/commands/mpm-auto-configure.md +217 -0
  98. claude_mpm/commands/mpm-help.md +163 -0
  99. claude_mpm/commands/mpm-init.md +148 -3
  100. claude_mpm/commands/mpm-version.md +113 -0
  101. claude_mpm/commands/mpm.md +1 -0
  102. claude_mpm/config/agent_config.py +2 -2
  103. claude_mpm/config/model_config.py +428 -0
  104. claude_mpm/constants.py +1 -0
  105. claude_mpm/core/base_service.py +13 -12
  106. claude_mpm/core/enums.py +452 -0
  107. claude_mpm/core/factories.py +1 -1
  108. claude_mpm/core/instruction_reinforcement_hook.py +2 -1
  109. claude_mpm/core/interactive_session.py +9 -3
  110. claude_mpm/core/log_manager.py +2 -0
  111. claude_mpm/core/logging_config.py +6 -2
  112. claude_mpm/core/oneshot_session.py +8 -4
  113. claude_mpm/core/optimized_agent_loader.py +3 -3
  114. claude_mpm/core/output_style_manager.py +12 -192
  115. claude_mpm/core/service_registry.py +5 -1
  116. claude_mpm/core/types.py +2 -9
  117. claude_mpm/core/typing_utils.py +7 -6
  118. claude_mpm/dashboard/static/js/dashboard.js +0 -14
  119. claude_mpm/dashboard/templates/index.html +3 -41
  120. claude_mpm/hooks/__init__.py +20 -0
  121. claude_mpm/hooks/claude_hooks/event_handlers.py +4 -2
  122. claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
  123. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +23 -2
  124. claude_mpm/hooks/failure_learning/__init__.py +60 -0
  125. claude_mpm/hooks/failure_learning/failure_detection_hook.py +235 -0
  126. claude_mpm/hooks/failure_learning/fix_detection_hook.py +217 -0
  127. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +286 -0
  128. claude_mpm/hooks/instruction_reinforcement.py +7 -2
  129. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  130. claude_mpm/hooks/kuzu_memory_hook.py +37 -12
  131. claude_mpm/hooks/kuzu_response_hook.py +183 -0
  132. claude_mpm/models/resume_log.py +340 -0
  133. claude_mpm/services/agents/__init__.py +18 -5
  134. claude_mpm/services/agents/auto_config_manager.py +796 -0
  135. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  136. claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
  137. claude_mpm/services/agents/deployment/agent_validator.py +17 -1
  138. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  139. claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
  140. claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
  141. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +7 -6
  142. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
  143. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
  144. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +5 -3
  145. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
  146. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
  147. claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
  148. claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
  149. claude_mpm/services/agents/local_template_manager.py +1 -1
  150. claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
  151. claude_mpm/services/agents/observers.py +547 -0
  152. claude_mpm/services/agents/recommender.py +568 -0
  153. claude_mpm/services/agents/registry/modification_tracker.py +5 -2
  154. claude_mpm/services/command_handler_service.py +11 -5
  155. claude_mpm/services/core/__init__.py +33 -1
  156. claude_mpm/services/core/interfaces/__init__.py +90 -3
  157. claude_mpm/services/core/interfaces/agent.py +184 -0
  158. claude_mpm/services/core/interfaces/health.py +172 -0
  159. claude_mpm/services/core/interfaces/model.py +281 -0
  160. claude_mpm/services/core/interfaces/process.py +372 -0
  161. claude_mpm/services/core/interfaces/project.py +121 -0
  162. claude_mpm/services/core/interfaces/restart.py +307 -0
  163. claude_mpm/services/core/interfaces/stability.py +260 -0
  164. claude_mpm/services/core/memory_manager.py +11 -24
  165. claude_mpm/services/core/models/__init__.py +79 -0
  166. claude_mpm/services/core/models/agent_config.py +381 -0
  167. claude_mpm/services/core/models/health.py +162 -0
  168. claude_mpm/services/core/models/process.py +235 -0
  169. claude_mpm/services/core/models/restart.py +302 -0
  170. claude_mpm/services/core/models/stability.py +264 -0
  171. claude_mpm/services/core/models/toolchain.py +306 -0
  172. claude_mpm/services/core/path_resolver.py +23 -7
  173. claude_mpm/services/diagnostics/__init__.py +2 -2
  174. claude_mpm/services/diagnostics/checks/agent_check.py +25 -24
  175. claude_mpm/services/diagnostics/checks/claude_code_check.py +24 -23
  176. claude_mpm/services/diagnostics/checks/common_issues_check.py +25 -24
  177. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -23
  178. claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
  179. claude_mpm/services/diagnostics/checks/installation_check.py +30 -29
  180. claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
  181. claude_mpm/services/diagnostics/checks/mcp_check.py +50 -36
  182. claude_mpm/services/diagnostics/checks/mcp_services_check.py +38 -33
  183. claude_mpm/services/diagnostics/checks/monitor_check.py +23 -22
  184. claude_mpm/services/diagnostics/checks/startup_log_check.py +9 -8
  185. claude_mpm/services/diagnostics/diagnostic_runner.py +6 -5
  186. claude_mpm/services/diagnostics/doctor_reporter.py +28 -25
  187. claude_mpm/services/diagnostics/models.py +19 -24
  188. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
  189. claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
  190. claude_mpm/services/infrastructure/monitoring/base.py +5 -13
  191. claude_mpm/services/infrastructure/monitoring/network.py +7 -6
  192. claude_mpm/services/infrastructure/monitoring/process.py +13 -12
  193. claude_mpm/services/infrastructure/monitoring/resources.py +7 -6
  194. claude_mpm/services/infrastructure/monitoring/service.py +16 -15
  195. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  196. claude_mpm/services/local_ops/__init__.py +163 -0
  197. claude_mpm/services/local_ops/crash_detector.py +257 -0
  198. claude_mpm/services/local_ops/health_checks/__init__.py +28 -0
  199. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  200. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  201. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  202. claude_mpm/services/local_ops/health_manager.py +430 -0
  203. claude_mpm/services/local_ops/log_monitor.py +396 -0
  204. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  205. claude_mpm/services/local_ops/process_manager.py +595 -0
  206. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  207. claude_mpm/services/local_ops/restart_manager.py +401 -0
  208. claude_mpm/services/local_ops/restart_policy.py +387 -0
  209. claude_mpm/services/local_ops/state_manager.py +372 -0
  210. claude_mpm/services/local_ops/unified_manager.py +600 -0
  211. claude_mpm/services/mcp_config_manager.py +9 -4
  212. claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
  213. claude_mpm/services/mcp_gateway/core/base.py +18 -31
  214. claude_mpm/services/mcp_gateway/main.py +30 -0
  215. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +206 -32
  216. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +30 -28
  217. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +25 -5
  218. claude_mpm/services/mcp_service_verifier.py +1 -1
  219. claude_mpm/services/memory/failure_tracker.py +563 -0
  220. claude_mpm/services/memory_hook_service.py +165 -4
  221. claude_mpm/services/model/__init__.py +147 -0
  222. claude_mpm/services/model/base_provider.py +365 -0
  223. claude_mpm/services/model/claude_provider.py +412 -0
  224. claude_mpm/services/model/model_router.py +453 -0
  225. claude_mpm/services/model/ollama_provider.py +415 -0
  226. claude_mpm/services/monitor/daemon_manager.py +3 -2
  227. claude_mpm/services/monitor/handlers/dashboard.py +2 -1
  228. claude_mpm/services/monitor/handlers/hooks.py +2 -1
  229. claude_mpm/services/monitor/management/lifecycle.py +3 -2
  230. claude_mpm/services/monitor/server.py +2 -1
  231. claude_mpm/services/project/__init__.py +23 -0
  232. claude_mpm/services/project/detection_strategies.py +719 -0
  233. claude_mpm/services/project/toolchain_analyzer.py +581 -0
  234. claude_mpm/services/self_upgrade_service.py +342 -0
  235. claude_mpm/services/session_management_service.py +3 -2
  236. claude_mpm/services/session_manager.py +205 -1
  237. claude_mpm/services/shared/async_service_base.py +16 -27
  238. claude_mpm/services/shared/lifecycle_service_base.py +1 -14
  239. claude_mpm/services/socketio/handlers/__init__.py +5 -2
  240. claude_mpm/services/socketio/handlers/hook.py +13 -2
  241. claude_mpm/services/socketio/handlers/registry.py +4 -2
  242. claude_mpm/services/socketio/server/main.py +10 -8
  243. claude_mpm/services/subprocess_launcher_service.py +14 -5
  244. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +8 -7
  245. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +6 -5
  246. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +8 -7
  247. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +7 -6
  248. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +5 -4
  249. claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
  250. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
  251. claude_mpm/services/unified/deployment_strategies/local.py +6 -5
  252. claude_mpm/services/unified/deployment_strategies/utils.py +6 -5
  253. claude_mpm/services/unified/deployment_strategies/vercel.py +7 -6
  254. claude_mpm/services/unified/interfaces.py +3 -1
  255. claude_mpm/services/unified/unified_analyzer.py +14 -10
  256. claude_mpm/services/unified/unified_config.py +2 -1
  257. claude_mpm/services/unified/unified_deployment.py +9 -4
  258. claude_mpm/services/version_service.py +104 -1
  259. claude_mpm/skills/__init__.py +21 -0
  260. claude_mpm/skills/bundled/__init__.py +6 -0
  261. claude_mpm/skills/bundled/api-documentation.md +393 -0
  262. claude_mpm/skills/bundled/async-testing.md +571 -0
  263. claude_mpm/skills/bundled/code-review.md +143 -0
  264. claude_mpm/skills/bundled/database-migration.md +199 -0
  265. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  266. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  267. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  268. claude_mpm/skills/bundled/git-workflow.md +414 -0
  269. claude_mpm/skills/bundled/imagemagick.md +204 -0
  270. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  271. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  272. claude_mpm/skills/bundled/pdf.md +141 -0
  273. claude_mpm/skills/bundled/performance-profiling.md +567 -0
  274. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  275. claude_mpm/skills/bundled/security-scanning.md +327 -0
  276. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  277. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  278. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  279. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  280. claude_mpm/skills/bundled/xlsx.md +157 -0
  281. claude_mpm/skills/registry.py +286 -0
  282. claude_mpm/skills/skill_manager.py +310 -0
  283. claude_mpm/storage/state_storage.py +15 -15
  284. claude_mpm/tools/code_tree_analyzer.py +177 -141
  285. claude_mpm/tools/code_tree_events.py +4 -2
  286. claude_mpm/utils/agent_dependency_loader.py +40 -20
  287. claude_mpm/utils/display_helper.py +260 -0
  288. claude_mpm/utils/git_analyzer.py +407 -0
  289. claude_mpm/utils/robust_installer.py +73 -19
  290. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/METADATA +129 -12
  291. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/RECORD +295 -193
  292. claude_mpm/dashboard/static/css/code-tree.css +0 -1639
  293. claude_mpm/dashboard/static/index-hub-backup.html +0 -713
  294. claude_mpm/dashboard/static/js/components/code-tree/tree-breadcrumb.js +0 -353
  295. claude_mpm/dashboard/static/js/components/code-tree/tree-constants.js +0 -235
  296. claude_mpm/dashboard/static/js/components/code-tree/tree-search.js +0 -409
  297. claude_mpm/dashboard/static/js/components/code-tree/tree-utils.js +0 -435
  298. claude_mpm/dashboard/static/js/components/code-tree.js +0 -5869
  299. claude_mpm/dashboard/static/js/components/code-viewer.js +0 -1386
  300. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
  301. claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
  302. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
  303. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
  304. claude_mpm/services/project/analyzer_refactored.py +0 -450
  305. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/WHEEL +0 -0
  306. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/entry_points.txt +0 -0
  307. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/licenses/LICENSE +0 -0
  308. {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,481 @@
1
+ """
2
+ CLI Startup Functions
3
+ =====================
4
+
5
+ This module contains initialization functions that run on CLI startup,
6
+ including project registry, MCP configuration, and update checks.
7
+
8
+ Part of cli/__init__.py refactoring to reduce file size and improve modularity.
9
+ """
10
+
11
+ import os
12
+ import sys
13
+
14
+
15
+ def setup_early_environment(argv):
16
+ """
17
+ Set up early environment variables and logging suppression.
18
+
19
+ WHY: Some commands need special environment handling before any logging
20
+ or service initialization occurs.
21
+
22
+ Args:
23
+ argv: Command line arguments
24
+
25
+ Returns:
26
+ Processed argv list
27
+ """
28
+ # Disable telemetry and set cleanup flags early
29
+ os.environ.setdefault("DISABLE_TELEMETRY", "1")
30
+ os.environ.setdefault("CLAUDE_MPM_SKIP_CLEANUP", "0")
31
+
32
+ # EARLY CHECK: Suppress logging for configure command
33
+ if argv is None:
34
+ argv = sys.argv[1:]
35
+ if "configure" in argv or (len(argv) > 0 and argv[0] == "configure"):
36
+ import logging
37
+
38
+ logging.getLogger("claude_mpm").setLevel(logging.WARNING)
39
+ os.environ["CLAUDE_MPM_SKIP_CLEANUP"] = "1"
40
+
41
+ return argv
42
+
43
+
44
+ def should_skip_background_services(args, processed_argv):
45
+ """
46
+ Determine if background services should be skipped for this command.
47
+
48
+ WHY: Some commands (help, version, configure, doctor) don't need
49
+ background services and should start faster.
50
+
51
+ Args:
52
+ args: Parsed arguments
53
+ processed_argv: Processed command line arguments
54
+
55
+ Returns:
56
+ bool: True if background services should be skipped
57
+ """
58
+ skip_commands = ["--version", "-v", "--help", "-h"]
59
+ return any(cmd in (processed_argv or sys.argv[1:]) for cmd in skip_commands) or (
60
+ hasattr(args, "command")
61
+ and args.command in ["info", "doctor", "config", "mcp", "configure"]
62
+ )
63
+
64
+
65
+ def setup_configure_command_environment(args):
66
+ """
67
+ Set up special environment for configure command.
68
+
69
+ WHY: Configure command needs clean state without background services
70
+ and with suppressed logging.
71
+
72
+ Args:
73
+ args: Parsed arguments
74
+ """
75
+ if hasattr(args, "command") and args.command == "configure":
76
+ os.environ["CLAUDE_MPM_SKIP_CLEANUP"] = "1"
77
+ import logging
78
+
79
+ logging.getLogger("claude_mpm").setLevel(logging.WARNING)
80
+
81
+
82
+ def discover_and_link_runtime_skills():
83
+ """
84
+ Discover and link runtime skills from user/project directories.
85
+
86
+ WHY: Automatically discover and link skills added to .claude/skills/
87
+ without requiring manual configuration.
88
+
89
+ DESIGN DECISION: Failures are logged but don't block startup to ensure
90
+ claude-mpm remains functional even if skills discovery fails.
91
+ """
92
+ try:
93
+ from ..cli.interactive.skills_wizard import (
94
+ discover_and_link_runtime_skills as discover_skills,
95
+ )
96
+
97
+ discover_skills()
98
+ except Exception as e:
99
+ # Import logger here to avoid circular imports
100
+ from ..core.logger import get_logger
101
+
102
+ logger = get_logger("cli")
103
+ logger.debug(f"Failed to discover runtime skills: {e}")
104
+ # Continue execution - skills discovery failure shouldn't block startup
105
+
106
+
107
+ def run_background_services():
108
+ """
109
+ Initialize all background services on startup.
110
+
111
+ WHY: Centralizes all startup service initialization for cleaner main().
112
+ """
113
+ initialize_project_registry()
114
+ check_mcp_auto_configuration()
115
+ verify_mcp_gateway_startup()
116
+ check_for_updates_async()
117
+ discover_and_link_runtime_skills()
118
+
119
+
120
+ def setup_mcp_server_logging(args):
121
+ """
122
+ Configure minimal logging for MCP server mode.
123
+
124
+ WHY: MCP server needs minimal stderr-only logging to avoid interfering
125
+ with stdout protocol communication.
126
+
127
+ Args:
128
+ args: Parsed arguments
129
+
130
+ Returns:
131
+ Configured logger
132
+ """
133
+ import logging
134
+
135
+ from ..cli.utils import setup_logging
136
+ from ..constants import CLICommands
137
+
138
+ if (
139
+ args.command == CLICommands.MCP.value
140
+ and getattr(args, "mcp_command", None) == "start"
141
+ ):
142
+ if not getattr(args, "test", False) and not getattr(
143
+ args, "instructions", False
144
+ ):
145
+ # Production MCP mode - minimal logging
146
+ logging.basicConfig(
147
+ level=logging.ERROR,
148
+ format="%(message)s",
149
+ stream=sys.stderr,
150
+ force=True,
151
+ )
152
+ return logging.getLogger("claude_mpm")
153
+ # Test or instructions mode - normal logging
154
+ return setup_logging(args)
155
+ # Normal logging for all other commands
156
+ return setup_logging(args)
157
+
158
+
159
+ def initialize_project_registry():
160
+ """
161
+ Initialize or update the project registry for the current session.
162
+
163
+ WHY: The project registry tracks all claude-mpm projects and their metadata
164
+ across sessions. This function ensures the current project is properly
165
+ registered and updates session information.
166
+
167
+ DESIGN DECISION: Registry failures are logged but don't prevent startup
168
+ to ensure claude-mpm remains functional even if registry operations fail.
169
+ """
170
+ try:
171
+ from ..services.project.registry import ProjectRegistry
172
+
173
+ registry = ProjectRegistry()
174
+ registry.get_or_create_project_entry()
175
+ except Exception as e:
176
+ # Import logger here to avoid circular imports
177
+ from ..core.logger import get_logger
178
+
179
+ logger = get_logger("cli")
180
+ logger.debug(f"Failed to initialize project registry: {e}")
181
+ # Continue execution - registry failure shouldn't block startup
182
+
183
+
184
+ def check_mcp_auto_configuration():
185
+ """
186
+ Check and potentially auto-configure MCP for pipx installations.
187
+
188
+ WHY: Users installing via pipx should have MCP work out-of-the-box with
189
+ minimal friction. This function offers one-time auto-configuration with
190
+ user consent.
191
+
192
+ DESIGN DECISION: This is blocking but quick - it only runs once and has
193
+ a 10-second timeout. We want to catch users on first run for the best
194
+ experience.
195
+ """
196
+ try:
197
+ from ..services.mcp_gateway.auto_configure import check_and_configure_mcp
198
+
199
+ # This function handles all the logic:
200
+ # - Checks if already configured
201
+ # - Checks if pipx installation
202
+ # - Checks if already asked before
203
+ # - Prompts user if needed
204
+ # - Configures if user agrees
205
+ check_and_configure_mcp()
206
+
207
+ except Exception as e:
208
+ # Non-critical - log but don't fail
209
+ from ..core.logger import get_logger
210
+
211
+ logger = get_logger("cli")
212
+ logger.debug(f"MCP auto-configuration check failed: {e}")
213
+
214
+ # Skip MCP service fixes for the doctor and configure commands
215
+ # The doctor command performs its own comprehensive MCP service check
216
+ # The configure command allows users to configure which services to enable
217
+ # Running both would cause duplicate checks and log messages (9 seconds apart)
218
+ if len(sys.argv) > 1 and sys.argv[1] in ("doctor", "configure"):
219
+ return
220
+
221
+ # Also ensure MCP services are properly configured in ~/.claude.json
222
+ # This fixes incorrect paths and adds missing services
223
+ try:
224
+ from ..core.logger import get_logger
225
+ from ..services.mcp_config_manager import MCPConfigManager
226
+
227
+ logger = get_logger("cli")
228
+ mcp_manager = MCPConfigManager()
229
+
230
+ # Fix any corrupted installations first
231
+ fix_success, fix_message = mcp_manager.fix_mcp_service_issues()
232
+ if fix_message and "Fixed:" in fix_message:
233
+ logger.info(f"MCP service fixes applied: {fix_message}")
234
+
235
+ # Ensure all services are configured correctly
236
+ config_success, config_message = mcp_manager.ensure_mcp_services_configured()
237
+ if config_message and "Added MCP services" in config_message:
238
+ logger.info(f"MCP services configured: {config_message}")
239
+
240
+ except Exception as e:
241
+ # Non-critical - log but don't fail
242
+ from ..core.logger import get_logger
243
+
244
+ logger = get_logger("cli")
245
+ logger.debug(f"MCP services configuration update failed: {e}")
246
+
247
+
248
+ def verify_mcp_gateway_startup():
249
+ """
250
+ Verify MCP Gateway configuration on startup and pre-warm MCP services.
251
+
252
+ WHY: The MCP gateway should be automatically configured and verified on startup
253
+ to provide a seamless experience with diagnostic tools, file summarizer, and
254
+ ticket service. Pre-warming MCP services eliminates the 11.9s delay on first use.
255
+
256
+ DESIGN DECISION: This is non-blocking - failures are logged but don't prevent
257
+ startup to ensure claude-mpm remains functional even if MCP gateway has issues.
258
+ """
259
+ # Quick verification of MCP services installation
260
+ try:
261
+ from ..core.logger import get_logger
262
+ from ..services.mcp_service_verifier import verify_mcp_services_on_startup
263
+
264
+ logger = get_logger("mcp_verify")
265
+ all_ok, message = verify_mcp_services_on_startup()
266
+ if not all_ok:
267
+ logger.warning(message)
268
+ except Exception:
269
+ # Non-critical - continue with startup
270
+ pass
271
+
272
+ try:
273
+ import asyncio
274
+ import time
275
+
276
+ from ..core.logger import get_logger
277
+ from ..services.mcp_gateway.core.startup_verification import (
278
+ is_mcp_gateway_configured,
279
+ verify_mcp_gateway_on_startup,
280
+ )
281
+
282
+ logger = get_logger("mcp_prewarm")
283
+
284
+ # Quick check first - if already configured, skip detailed verification
285
+ gateway_configured = is_mcp_gateway_configured()
286
+
287
+ # DISABLED: Pre-warming MCP servers can interfere with Claude Code's MCP management
288
+ # This was causing issues with MCP server initialization and stderr handling
289
+ # def run_pre_warming():
290
+ # loop = None
291
+ # try:
292
+ # start_time = time.time()
293
+ # loop = asyncio.new_event_loop()
294
+ # asyncio.set_event_loop(loop)
295
+ #
296
+ # # Pre-warm MCP servers (especially vector search)
297
+ # logger.info("Pre-warming MCP servers to eliminate startup delay...")
298
+ # loop.run_until_complete(pre_warm_mcp_servers())
299
+ #
300
+ # pre_warm_time = time.time() - start_time
301
+ # if pre_warm_time > 1.0:
302
+ # logger.info(f"MCP servers pre-warmed in {pre_warm_time:.2f}s")
303
+
304
+ # Dummy function to maintain structure
305
+ def run_pre_warming():
306
+ loop = None
307
+ try:
308
+ time.time()
309
+ loop = asyncio.new_event_loop()
310
+ asyncio.set_event_loop(loop)
311
+
312
+ # Also run gateway verification if needed
313
+ if not gateway_configured:
314
+ loop.run_until_complete(verify_mcp_gateway_on_startup())
315
+
316
+ except Exception as e:
317
+ # Non-blocking - log but don't fail
318
+ logger.debug(f"MCP pre-warming error (non-critical): {e}")
319
+ finally:
320
+ # Properly clean up event loop to prevent kqueue warnings
321
+ if loop is not None:
322
+ try:
323
+ # Cancel all running tasks
324
+ pending = asyncio.all_tasks(loop)
325
+ for task in pending:
326
+ task.cancel()
327
+ # Wait for tasks to complete cancellation
328
+ if pending:
329
+ loop.run_until_complete(
330
+ asyncio.gather(*pending, return_exceptions=True)
331
+ )
332
+ except Exception:
333
+ pass # Ignore cleanup errors
334
+ finally:
335
+ loop.close()
336
+ # Clear the event loop reference to help with cleanup
337
+ asyncio.set_event_loop(None)
338
+
339
+ # Run pre-warming in background thread
340
+ import threading
341
+
342
+ pre_warm_thread = threading.Thread(target=run_pre_warming, daemon=True)
343
+ pre_warm_thread.start()
344
+
345
+ return
346
+
347
+ # Run detailed verification in background if not configured
348
+ if not gateway_configured:
349
+ # Note: We don't await this to avoid blocking startup
350
+ def run_verification():
351
+ loop = None
352
+ try:
353
+ loop = asyncio.new_event_loop()
354
+ asyncio.set_event_loop(loop)
355
+ results = loop.run_until_complete(verify_mcp_gateway_on_startup())
356
+
357
+ # Log results but don't block
358
+ from ..core.logger import get_logger
359
+
360
+ logger = get_logger("cli")
361
+
362
+ if results.get("gateway_configured"):
363
+ logger.debug("MCP Gateway verification completed successfully")
364
+ else:
365
+ logger.debug("MCP Gateway verification completed with warnings")
366
+
367
+ except Exception as e:
368
+ from ..core.logger import get_logger
369
+
370
+ logger = get_logger("cli")
371
+ logger.debug(f"MCP Gateway verification failed: {e}")
372
+ finally:
373
+ # Properly clean up event loop to prevent kqueue warnings
374
+ if loop is not None:
375
+ try:
376
+ # Cancel all running tasks
377
+ pending = asyncio.all_tasks(loop)
378
+ for task in pending:
379
+ task.cancel()
380
+ # Wait for tasks to complete cancellation
381
+ if pending:
382
+ loop.run_until_complete(
383
+ asyncio.gather(*pending, return_exceptions=True)
384
+ )
385
+ except Exception:
386
+ pass # Ignore cleanup errors
387
+ finally:
388
+ loop.close()
389
+ # Clear the event loop reference to help with cleanup
390
+ asyncio.set_event_loop(None)
391
+
392
+ # Run in background thread to avoid blocking startup
393
+ import threading
394
+
395
+ verification_thread = threading.Thread(target=run_verification, daemon=True)
396
+ verification_thread.start()
397
+
398
+ except Exception as e:
399
+ # Import logger here to avoid circular imports
400
+ from ..core.logger import get_logger
401
+
402
+ logger = get_logger("cli")
403
+ logger.debug(f"Failed to start MCP Gateway verification: {e}")
404
+ # Continue execution - MCP gateway issues shouldn't block startup
405
+
406
+
407
+ def check_for_updates_async():
408
+ """
409
+ Check for updates in background thread (non-blocking).
410
+
411
+ WHY: Users should be notified of new versions and have an easy way to upgrade
412
+ without manually checking PyPI/npm. This runs asynchronously on startup to avoid
413
+ blocking the CLI.
414
+
415
+ DESIGN DECISION: This is non-blocking and non-critical - failures are logged
416
+ but don't prevent startup. Only runs for pip/pipx/npm installations, skips
417
+ editable/development installations.
418
+ """
419
+
420
+ def run_update_check():
421
+ """Inner function to run in background thread."""
422
+ loop = None
423
+ try:
424
+ import asyncio
425
+
426
+ from ..core.logger import get_logger
427
+ from ..services.self_upgrade_service import SelfUpgradeService
428
+
429
+ logger = get_logger("upgrade_check")
430
+
431
+ # Create new event loop for this thread
432
+ loop = asyncio.new_event_loop()
433
+ asyncio.set_event_loop(loop)
434
+
435
+ # Create upgrade service and check for updates
436
+ upgrade_service = SelfUpgradeService()
437
+
438
+ # Skip for editable installs (development mode)
439
+ from ..services.self_upgrade_service import InstallationMethod
440
+
441
+ if upgrade_service.installation_method == InstallationMethod.EDITABLE:
442
+ logger.debug("Skipping version check for editable installation")
443
+ return
444
+
445
+ # Check and prompt for upgrade if available (non-blocking)
446
+ loop.run_until_complete(upgrade_service.check_and_prompt_on_startup())
447
+
448
+ except Exception as e:
449
+ # Non-critical - log but don't fail startup
450
+ try:
451
+ from ..core.logger import get_logger
452
+
453
+ logger = get_logger("upgrade_check")
454
+ logger.debug(f"Update check failed (non-critical): {e}")
455
+ except Exception:
456
+ pass # Avoid any errors in error handling
457
+ finally:
458
+ # Properly clean up event loop
459
+ if loop is not None:
460
+ try:
461
+ # Cancel all running tasks
462
+ pending = asyncio.all_tasks(loop)
463
+ for task in pending:
464
+ task.cancel()
465
+ # Wait for tasks to complete cancellation
466
+ if pending:
467
+ loop.run_until_complete(
468
+ asyncio.gather(*pending, return_exceptions=True)
469
+ )
470
+ except Exception:
471
+ pass # Ignore cleanup errors
472
+ finally:
473
+ loop.close()
474
+ # Clear the event loop reference to help with cleanup
475
+ asyncio.set_event_loop(None)
476
+
477
+ # Run update check in background thread to avoid blocking startup
478
+ import threading
479
+
480
+ update_check_thread = threading.Thread(target=run_update_check, daemon=True)
481
+ update_check_thread.start()
claude_mpm/cli/utils.py CHANGED
@@ -6,9 +6,10 @@ Centralizing these functions reduces code duplication and provides a single plac
6
6
  for common CLI operations.
7
7
  """
8
8
 
9
+ import difflib
9
10
  import sys
10
11
  from pathlib import Path
11
- from typing import Optional
12
+ from typing import List, Optional
12
13
 
13
14
  from ..core.logger import get_logger
14
15
 
@@ -207,3 +208,53 @@ def ensure_directories() -> None:
207
208
  # Continue even if initialization fails
208
209
  # The individual commands will handle missing directories as needed
209
210
  pass
211
+
212
+
213
+ def suggest_similar_commands(
214
+ invalid_command: str,
215
+ valid_commands: List[str],
216
+ cutoff: float = 0.6,
217
+ max_suggestions: int = 3,
218
+ ) -> Optional[str]:
219
+ """
220
+ Suggest similar commands for an invalid command using fuzzy matching.
221
+
222
+ WHY: Helps users quickly identify typos and discover correct command names
223
+ by suggesting the most similar valid commands. Uses stdlib difflib for
224
+ zero-dependency fuzzy matching.
225
+
226
+ DESIGN DECISION: Using difflib.get_close_matches provides good results for
227
+ typos and partial matches while being simple and lightweight (no external deps).
228
+
229
+ Args:
230
+ invalid_command: The invalid command the user typed
231
+ valid_commands: List of valid commands to match against
232
+ cutoff: Similarity threshold (0.0-1.0), default 0.6
233
+ max_suggestions: Maximum number of suggestions to return, default 3
234
+
235
+ Returns:
236
+ Formatted suggestion string or None if no good matches found
237
+
238
+ Examples:
239
+ >>> suggest_similar_commands("tickts", ["tickets", "run", "agents"])
240
+ "Did you mean 'tickets'?"
241
+
242
+ >>> suggest_similar_commands("mem", ["memory", "monitor", "mcp"])
243
+ "Did you mean one of these?\n memory\n monitor\n mcp"
244
+
245
+ >>> suggest_similar_commands("xyz", ["tickets", "run"])
246
+ None # No good matches
247
+ """
248
+ # Use difflib to find close matches
249
+ matches = difflib.get_close_matches(
250
+ invalid_command, valid_commands, n=max_suggestions, cutoff=cutoff
251
+ )
252
+
253
+ if not matches:
254
+ return None
255
+
256
+ # Format suggestion message
257
+ if len(matches) == 1:
258
+ return f"Did you mean '{matches[0]}'?"
259
+ suggestions = "\n ".join(matches)
260
+ return f"Did you mean one of these?\n {suggestions}"