claude-mpm 4.1.0__py3-none-any.whl → 4.1.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 (358) hide show
  1. claude_mpm/BUILD_NUMBER +1 -1
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/__main__.py +1 -1
  4. claude_mpm/agents/BASE_PM.md +74 -46
  5. claude_mpm/agents/INSTRUCTIONS.md +11 -153
  6. claude_mpm/agents/WORKFLOW.md +61 -321
  7. claude_mpm/agents/__init__.py +11 -11
  8. claude_mpm/agents/agent_loader.py +23 -20
  9. claude_mpm/agents/agent_loader_integration.py +1 -1
  10. claude_mpm/agents/agents_metadata.py +27 -0
  11. claude_mpm/agents/async_agent_loader.py +5 -8
  12. claude_mpm/agents/base_agent_loader.py +36 -25
  13. claude_mpm/agents/frontmatter_validator.py +6 -6
  14. claude_mpm/agents/schema/agent_schema.json +1 -1
  15. claude_mpm/agents/system_agent_config.py +9 -9
  16. claude_mpm/agents/templates/api_qa.json +47 -2
  17. claude_mpm/agents/templates/imagemagick.json +256 -0
  18. claude_mpm/agents/templates/qa.json +41 -2
  19. claude_mpm/agents/templates/ticketing.json +5 -5
  20. claude_mpm/agents/templates/web_qa.json +133 -58
  21. claude_mpm/agents/templates/web_ui.json +3 -3
  22. claude_mpm/cli/__init__.py +51 -46
  23. claude_mpm/cli/__main__.py +1 -1
  24. claude_mpm/cli/commands/__init__.py +10 -12
  25. claude_mpm/cli/commands/agent_manager.py +186 -181
  26. claude_mpm/cli/commands/agents.py +271 -268
  27. claude_mpm/cli/commands/aggregate.py +30 -29
  28. claude_mpm/cli/commands/cleanup.py +50 -44
  29. claude_mpm/cli/commands/cleanup_orphaned_agents.py +25 -25
  30. claude_mpm/cli/commands/config.py +162 -127
  31. claude_mpm/cli/commands/doctor.py +52 -62
  32. claude_mpm/cli/commands/info.py +37 -25
  33. claude_mpm/cli/commands/mcp.py +3 -7
  34. claude_mpm/cli/commands/mcp_command_router.py +14 -18
  35. claude_mpm/cli/commands/mcp_install_commands.py +28 -23
  36. claude_mpm/cli/commands/mcp_pipx_config.py +58 -49
  37. claude_mpm/cli/commands/mcp_server_commands.py +23 -17
  38. claude_mpm/cli/commands/memory.py +192 -141
  39. claude_mpm/cli/commands/monitor.py +117 -88
  40. claude_mpm/cli/commands/run.py +120 -84
  41. claude_mpm/cli/commands/run_config_checker.py +4 -5
  42. claude_mpm/cli/commands/socketio_monitor.py +17 -19
  43. claude_mpm/cli/commands/tickets.py +92 -92
  44. claude_mpm/cli/parser.py +1 -5
  45. claude_mpm/cli/parsers/__init__.py +1 -1
  46. claude_mpm/cli/parsers/agent_manager_parser.py +50 -98
  47. claude_mpm/cli/parsers/agents_parser.py +2 -3
  48. claude_mpm/cli/parsers/base_parser.py +7 -5
  49. claude_mpm/cli/parsers/mcp_parser.py +4 -2
  50. claude_mpm/cli/parsers/monitor_parser.py +26 -18
  51. claude_mpm/cli/shared/__init__.py +10 -10
  52. claude_mpm/cli/shared/argument_patterns.py +57 -71
  53. claude_mpm/cli/shared/base_command.py +61 -53
  54. claude_mpm/cli/shared/error_handling.py +62 -58
  55. claude_mpm/cli/shared/output_formatters.py +78 -77
  56. claude_mpm/cli/startup_logging.py +204 -172
  57. claude_mpm/cli/utils.py +10 -11
  58. claude_mpm/cli_module/__init__.py +1 -1
  59. claude_mpm/cli_module/args.py +1 -1
  60. claude_mpm/cli_module/migration_example.py +5 -5
  61. claude_mpm/config/__init__.py +9 -9
  62. claude_mpm/config/agent_config.py +15 -14
  63. claude_mpm/config/experimental_features.py +4 -4
  64. claude_mpm/config/paths.py +0 -1
  65. claude_mpm/config/socketio_config.py +5 -6
  66. claude_mpm/constants.py +1 -2
  67. claude_mpm/core/__init__.py +8 -8
  68. claude_mpm/core/agent_name_normalizer.py +1 -1
  69. claude_mpm/core/agent_registry.py +20 -23
  70. claude_mpm/core/agent_session_manager.py +3 -3
  71. claude_mpm/core/base_service.py +7 -15
  72. claude_mpm/core/cache.py +4 -6
  73. claude_mpm/core/claude_runner.py +85 -113
  74. claude_mpm/core/config.py +43 -28
  75. claude_mpm/core/config_aliases.py +0 -9
  76. claude_mpm/core/config_constants.py +52 -30
  77. claude_mpm/core/constants.py +0 -1
  78. claude_mpm/core/container.py +18 -27
  79. claude_mpm/core/exceptions.py +2 -2
  80. claude_mpm/core/factories.py +10 -12
  81. claude_mpm/core/framework_loader.py +581 -280
  82. claude_mpm/core/hook_manager.py +26 -22
  83. claude_mpm/core/hook_performance_config.py +58 -47
  84. claude_mpm/core/injectable_service.py +1 -1
  85. claude_mpm/core/interactive_session.py +61 -152
  86. claude_mpm/core/interfaces.py +1 -100
  87. claude_mpm/core/lazy.py +5 -5
  88. claude_mpm/core/log_manager.py +587 -0
  89. claude_mpm/core/logger.py +125 -8
  90. claude_mpm/core/logging_config.py +15 -15
  91. claude_mpm/core/minimal_framework_loader.py +5 -8
  92. claude_mpm/core/oneshot_session.py +15 -33
  93. claude_mpm/core/optimized_agent_loader.py +4 -6
  94. claude_mpm/core/optimized_startup.py +2 -1
  95. claude_mpm/core/output_style_manager.py +147 -106
  96. claude_mpm/core/pm_hook_interceptor.py +0 -1
  97. claude_mpm/core/service_registry.py +11 -8
  98. claude_mpm/core/session_manager.py +1 -2
  99. claude_mpm/core/shared/__init__.py +1 -1
  100. claude_mpm/core/shared/config_loader.py +101 -97
  101. claude_mpm/core/shared/path_resolver.py +72 -68
  102. claude_mpm/core/shared/singleton_manager.py +56 -50
  103. claude_mpm/core/socketio_pool.py +26 -6
  104. claude_mpm/core/tool_access_control.py +4 -5
  105. claude_mpm/core/typing_utils.py +50 -59
  106. claude_mpm/core/unified_agent_registry.py +14 -19
  107. claude_mpm/core/unified_config.py +4 -6
  108. claude_mpm/core/unified_paths.py +197 -109
  109. claude_mpm/dashboard/open_dashboard.py +2 -4
  110. claude_mpm/experimental/cli_enhancements.py +51 -36
  111. claude_mpm/generators/agent_profile_generator.py +2 -4
  112. claude_mpm/hooks/base_hook.py +1 -2
  113. claude_mpm/hooks/claude_hooks/connection_pool.py +72 -26
  114. claude_mpm/hooks/claude_hooks/event_handlers.py +93 -38
  115. claude_mpm/hooks/claude_hooks/hook_handler.py +130 -76
  116. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
  117. claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
  118. claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
  119. claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
  120. claude_mpm/hooks/memory_integration_hook.py +5 -5
  121. claude_mpm/hooks/tool_call_interceptor.py +1 -1
  122. claude_mpm/hooks/validation_hooks.py +4 -4
  123. claude_mpm/init.py +4 -9
  124. claude_mpm/models/__init__.py +2 -2
  125. claude_mpm/models/agent_session.py +11 -14
  126. claude_mpm/scripts/mcp_server.py +20 -11
  127. claude_mpm/scripts/mcp_wrapper.py +5 -5
  128. claude_mpm/scripts/mpm_doctor.py +321 -0
  129. claude_mpm/scripts/socketio_daemon.py +28 -25
  130. claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
  131. claude_mpm/scripts/socketio_server_manager.py +116 -95
  132. claude_mpm/services/__init__.py +49 -49
  133. claude_mpm/services/agent_capabilities_service.py +12 -18
  134. claude_mpm/services/agents/__init__.py +22 -22
  135. claude_mpm/services/agents/agent_builder.py +140 -119
  136. claude_mpm/services/agents/deployment/__init__.py +3 -3
  137. claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
  138. claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
  139. claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
  140. claude_mpm/services/agents/deployment/agent_deployment.py +136 -106
  141. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
  142. claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
  143. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
  144. claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
  145. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
  146. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
  147. claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
  148. claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
  149. claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
  150. claude_mpm/services/agents/deployment/agent_validator.py +0 -1
  151. claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
  152. claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
  153. claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
  154. claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
  155. claude_mpm/services/agents/deployment/config/__init__.py +1 -1
  156. claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
  157. claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
  158. claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
  159. claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
  160. claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
  161. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
  162. claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
  163. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
  164. claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
  165. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
  166. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
  167. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
  168. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
  169. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
  170. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
  171. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
  172. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
  173. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
  174. claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
  175. claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
  176. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
  177. claude_mpm/services/agents/deployment/results/__init__.py +1 -1
  178. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
  179. claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
  180. claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
  181. claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
  182. claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
  183. claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
  184. claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
  185. claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
  186. claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
  187. claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
  188. claude_mpm/services/agents/loading/__init__.py +1 -1
  189. claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
  190. claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
  191. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
  192. claude_mpm/services/agents/management/__init__.py +1 -1
  193. claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
  194. claude_mpm/services/agents/management/agent_management_service.py +5 -9
  195. claude_mpm/services/agents/memory/__init__.py +4 -4
  196. claude_mpm/services/agents/memory/agent_memory_manager.py +280 -160
  197. claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
  198. claude_mpm/services/agents/memory/content_manager.py +44 -38
  199. claude_mpm/services/agents/memory/template_generator.py +4 -6
  200. claude_mpm/services/agents/registry/__init__.py +10 -6
  201. claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
  202. claude_mpm/services/agents/registry/modification_tracker.py +3 -6
  203. claude_mpm/services/async_session_logger.py +1 -2
  204. claude_mpm/services/claude_session_logger.py +1 -2
  205. claude_mpm/services/command_deployment_service.py +173 -0
  206. claude_mpm/services/command_handler_service.py +20 -22
  207. claude_mpm/services/core/__init__.py +25 -25
  208. claude_mpm/services/core/base.py +0 -5
  209. claude_mpm/services/core/interfaces/__init__.py +32 -32
  210. claude_mpm/services/core/interfaces/agent.py +0 -21
  211. claude_mpm/services/core/interfaces/communication.py +0 -27
  212. claude_mpm/services/core/interfaces/infrastructure.py +0 -56
  213. claude_mpm/services/core/interfaces/service.py +0 -29
  214. claude_mpm/services/diagnostics/__init__.py +1 -1
  215. claude_mpm/services/diagnostics/checks/__init__.py +6 -6
  216. claude_mpm/services/diagnostics/checks/agent_check.py +89 -80
  217. claude_mpm/services/diagnostics/checks/base_check.py +12 -16
  218. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
  219. claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
  220. claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
  221. claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
  222. claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
  223. claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
  224. claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
  225. claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
  226. claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
  227. claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
  228. claude_mpm/services/diagnostics/models.py +21 -19
  229. claude_mpm/services/event_aggregator.py +10 -17
  230. claude_mpm/services/event_bus/__init__.py +1 -1
  231. claude_mpm/services/event_bus/config.py +54 -35
  232. claude_mpm/services/event_bus/event_bus.py +76 -71
  233. claude_mpm/services/event_bus/relay.py +74 -64
  234. claude_mpm/services/events/__init__.py +11 -11
  235. claude_mpm/services/events/consumers/__init__.py +3 -3
  236. claude_mpm/services/events/consumers/dead_letter.py +71 -63
  237. claude_mpm/services/events/consumers/logging.py +39 -37
  238. claude_mpm/services/events/consumers/metrics.py +56 -57
  239. claude_mpm/services/events/consumers/socketio.py +82 -81
  240. claude_mpm/services/events/core.py +110 -99
  241. claude_mpm/services/events/interfaces.py +56 -72
  242. claude_mpm/services/events/producers/__init__.py +1 -1
  243. claude_mpm/services/events/producers/hook.py +38 -38
  244. claude_mpm/services/events/producers/system.py +46 -44
  245. claude_mpm/services/exceptions.py +81 -80
  246. claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
  247. claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
  248. claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
  249. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
  250. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
  251. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
  252. claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
  253. claude_mpm/services/hook_service.py +6 -9
  254. claude_mpm/services/infrastructure/__init__.py +1 -1
  255. claude_mpm/services/infrastructure/context_preservation.py +8 -12
  256. claude_mpm/services/infrastructure/monitoring.py +21 -23
  257. claude_mpm/services/mcp_gateway/__init__.py +37 -37
  258. claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
  259. claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
  260. claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
  261. claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
  262. claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
  263. claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
  264. claude_mpm/services/mcp_gateway/core/base.py +0 -3
  265. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
  266. claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
  267. claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
  268. claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
  269. claude_mpm/services/mcp_gateway/main.py +2 -1
  270. claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
  271. claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
  272. claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
  273. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
  274. claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
  275. claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
  276. claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
  277. claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
  278. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
  279. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
  280. claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
  281. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
  282. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
  283. claude_mpm/services/memory/__init__.py +3 -3
  284. claude_mpm/services/memory/builder.py +3 -6
  285. claude_mpm/services/memory/cache/__init__.py +1 -1
  286. claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
  287. claude_mpm/services/memory/cache/simple_cache.py +1 -1
  288. claude_mpm/services/memory/indexed_memory.py +5 -7
  289. claude_mpm/services/memory/optimizer.py +7 -10
  290. claude_mpm/services/memory/router.py +8 -9
  291. claude_mpm/services/memory_hook_service.py +48 -34
  292. claude_mpm/services/monitor_build_service.py +77 -73
  293. claude_mpm/services/port_manager.py +130 -108
  294. claude_mpm/services/project/analyzer.py +12 -10
  295. claude_mpm/services/project/registry.py +11 -11
  296. claude_mpm/services/recovery_manager.py +10 -19
  297. claude_mpm/services/response_tracker.py +0 -1
  298. claude_mpm/services/runner_configuration_service.py +19 -20
  299. claude_mpm/services/session_management_service.py +7 -11
  300. claude_mpm/services/shared/__init__.py +1 -1
  301. claude_mpm/services/shared/async_service_base.py +58 -50
  302. claude_mpm/services/shared/config_service_base.py +73 -67
  303. claude_mpm/services/shared/lifecycle_service_base.py +82 -78
  304. claude_mpm/services/shared/manager_base.py +94 -82
  305. claude_mpm/services/shared/service_factory.py +96 -98
  306. claude_mpm/services/socketio/__init__.py +3 -3
  307. claude_mpm/services/socketio/client_proxy.py +5 -5
  308. claude_mpm/services/socketio/event_normalizer.py +199 -181
  309. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  310. claude_mpm/services/socketio/handlers/base.py +5 -4
  311. claude_mpm/services/socketio/handlers/connection.py +163 -136
  312. claude_mpm/services/socketio/handlers/file.py +13 -14
  313. claude_mpm/services/socketio/handlers/git.py +12 -7
  314. claude_mpm/services/socketio/handlers/hook.py +49 -44
  315. claude_mpm/services/socketio/handlers/memory.py +0 -1
  316. claude_mpm/services/socketio/handlers/project.py +0 -1
  317. claude_mpm/services/socketio/handlers/registry.py +37 -19
  318. claude_mpm/services/socketio/migration_utils.py +98 -84
  319. claude_mpm/services/socketio/server/__init__.py +1 -1
  320. claude_mpm/services/socketio/server/broadcaster.py +81 -87
  321. claude_mpm/services/socketio/server/core.py +65 -54
  322. claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
  323. claude_mpm/services/socketio/server/main.py +64 -38
  324. claude_mpm/services/socketio_client_manager.py +10 -12
  325. claude_mpm/services/subprocess_launcher_service.py +4 -7
  326. claude_mpm/services/system_instructions_service.py +13 -14
  327. claude_mpm/services/ticket_manager.py +2 -2
  328. claude_mpm/services/utility_service.py +5 -13
  329. claude_mpm/services/version_control/__init__.py +16 -16
  330. claude_mpm/services/version_control/branch_strategy.py +5 -8
  331. claude_mpm/services/version_control/conflict_resolution.py +9 -23
  332. claude_mpm/services/version_control/git_operations.py +5 -7
  333. claude_mpm/services/version_control/semantic_versioning.py +16 -17
  334. claude_mpm/services/version_control/version_parser.py +13 -18
  335. claude_mpm/services/version_service.py +10 -11
  336. claude_mpm/storage/__init__.py +1 -1
  337. claude_mpm/storage/state_storage.py +22 -28
  338. claude_mpm/utils/__init__.py +6 -6
  339. claude_mpm/utils/agent_dependency_loader.py +47 -33
  340. claude_mpm/utils/config_manager.py +11 -14
  341. claude_mpm/utils/dependency_cache.py +1 -1
  342. claude_mpm/utils/dependency_manager.py +13 -17
  343. claude_mpm/utils/dependency_strategies.py +8 -10
  344. claude_mpm/utils/environment_context.py +3 -9
  345. claude_mpm/utils/error_handler.py +3 -13
  346. claude_mpm/utils/file_utils.py +1 -1
  347. claude_mpm/utils/path_operations.py +8 -12
  348. claude_mpm/utils/robust_installer.py +110 -33
  349. claude_mpm/utils/subprocess_utils.py +5 -6
  350. claude_mpm/validation/agent_validator.py +3 -6
  351. claude_mpm/validation/frontmatter_validator.py +1 -1
  352. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/METADATA +1 -1
  353. claude_mpm-4.1.2.dist-info/RECORD +498 -0
  354. claude_mpm-4.1.0.dist-info/RECORD +0 -494
  355. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/WHEEL +0 -0
  356. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/entry_points.txt +0 -0
  357. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/licenses/LICENSE +0 -0
  358. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/top_level.txt +0 -0
@@ -8,7 +8,6 @@ dependencies, and installation method.
8
8
  import subprocess
9
9
  import sys
10
10
  from pathlib import Path
11
- from typing import Dict, Any
12
11
 
13
12
  from ..models import DiagnosticResult, DiagnosticStatus
14
13
  from .base_check import BaseDiagnosticCheck
@@ -16,42 +15,42 @@ from .base_check import BaseDiagnosticCheck
16
15
 
17
16
  class InstallationCheck(BaseDiagnosticCheck):
18
17
  """Check claude-mpm installation and dependencies."""
19
-
18
+
20
19
  @property
21
20
  def name(self) -> str:
22
21
  return "installation_check"
23
-
22
+
24
23
  @property
25
24
  def category(self) -> str:
26
25
  return "Installation"
27
-
26
+
28
27
  def run(self) -> DiagnosticResult:
29
28
  """Run installation diagnostics."""
30
29
  try:
31
30
  details = {}
32
31
  sub_results = []
33
-
32
+
34
33
  # Check Python version
35
34
  python_result = self._check_python_version()
36
35
  sub_results.append(python_result)
37
36
  details["python_version"] = python_result.details.get("version")
38
-
37
+
39
38
  # Check claude-mpm version
40
39
  version_result = self._check_claude_mpm_version()
41
40
  sub_results.append(version_result)
42
41
  details["claude_mpm_version"] = version_result.details.get("version")
43
42
  details["build_number"] = version_result.details.get("build_number")
44
-
43
+
45
44
  # Check installation method
46
45
  method_result = self._check_installation_method()
47
46
  sub_results.append(method_result)
48
47
  details["installation_method"] = method_result.details.get("method")
49
-
48
+
50
49
  # Check critical dependencies
51
50
  deps_result = self._check_dependencies()
52
51
  sub_results.append(deps_result)
53
52
  details["dependencies"] = deps_result.details.get("status")
54
-
53
+
55
54
  # Determine overall status
56
55
  if any(r.status == DiagnosticStatus.ERROR for r in sub_results):
57
56
  status = DiagnosticStatus.ERROR
@@ -62,64 +61,63 @@ class InstallationCheck(BaseDiagnosticCheck):
62
61
  else:
63
62
  status = DiagnosticStatus.OK
64
63
  message = "Installation is healthy"
65
-
64
+
66
65
  return DiagnosticResult(
67
66
  category=self.category,
68
67
  status=status,
69
68
  message=message,
70
69
  details=details,
71
- sub_results=sub_results if self.verbose else []
70
+ sub_results=sub_results if self.verbose else [],
72
71
  )
73
-
72
+
74
73
  except Exception as e:
75
74
  return DiagnosticResult(
76
75
  category=self.category,
77
76
  status=DiagnosticStatus.ERROR,
78
- message=f"Installation check failed: {str(e)}",
79
- details={"error": str(e)}
77
+ message=f"Installation check failed: {e!s}",
78
+ details={"error": str(e)},
80
79
  )
81
-
80
+
82
81
  def _check_python_version(self) -> DiagnosticResult:
83
82
  """Check Python version compatibility."""
84
83
  version = sys.version
85
84
  version_info = sys.version_info
86
-
85
+
87
86
  min_version = (3, 9)
88
87
  recommended_version = (3, 11)
89
-
88
+
90
89
  if version_info < min_version:
91
90
  return DiagnosticResult(
92
91
  category="Python Version",
93
92
  status=DiagnosticStatus.ERROR,
94
93
  message=f"Python {version_info.major}.{version_info.minor} is below minimum required {min_version[0]}.{min_version[1]}",
95
94
  details={"version": version},
96
- fix_description="Upgrade Python to 3.9 or higher"
95
+ fix_description="Upgrade Python to 3.9 or higher",
97
96
  )
98
- elif version_info < recommended_version:
97
+ if version_info < recommended_version:
99
98
  return DiagnosticResult(
100
99
  category="Python Version",
101
100
  status=DiagnosticStatus.WARNING,
102
101
  message=f"Python {version_info.major}.{version_info.minor} works but {recommended_version[0]}.{recommended_version[1]}+ is recommended",
103
- details={"version": version}
104
- )
105
- else:
106
- return DiagnosticResult(
107
- category="Python Version",
108
- status=DiagnosticStatus.OK,
109
- message=f"Python {version_info.major}.{version_info.minor}.{version_info.micro}",
110
- details={"version": version}
102
+ details={"version": version},
111
103
  )
112
-
104
+ return DiagnosticResult(
105
+ category="Python Version",
106
+ status=DiagnosticStatus.OK,
107
+ message=f"Python {version_info.major}.{version_info.minor}.{version_info.micro}",
108
+ details={"version": version},
109
+ )
110
+
113
111
  def _check_claude_mpm_version(self) -> DiagnosticResult:
114
112
  """Check claude-mpm version."""
115
113
  try:
116
114
  from ....services.version_service import VersionService
117
-
115
+
118
116
  service = VersionService()
119
117
  version = service.get_version()
120
118
  semantic_version = service.get_semantic_version()
121
119
  build_number = service.get_build_number()
122
-
120
+
123
121
  return DiagnosticResult(
124
122
  category="Claude MPM Version",
125
123
  status=DiagnosticStatus.OK,
@@ -127,129 +125,291 @@ class InstallationCheck(BaseDiagnosticCheck):
127
125
  details={
128
126
  "version": semantic_version,
129
127
  "build_number": build_number,
130
- "display_version": version
131
- }
128
+ "display_version": version,
129
+ },
132
130
  )
133
131
  except Exception as e:
134
132
  return DiagnosticResult(
135
133
  category="Claude MPM Version",
136
134
  status=DiagnosticStatus.WARNING,
137
135
  message="Could not determine version",
138
- details={"error": str(e)}
136
+ details={"error": str(e)},
139
137
  )
140
-
138
+
141
139
  def _check_installation_method(self) -> DiagnosticResult:
142
140
  """Detect how claude-mpm was installed."""
143
141
  methods_found = []
144
-
145
- # Check for pipx
146
- try:
147
- result = subprocess.run(
148
- ["pipx", "list"],
149
- capture_output=True,
150
- text=True,
151
- timeout=5
152
- )
153
- if "claude-mpm" in result.stdout:
154
- methods_found.append("pipx")
155
- except (subprocess.SubprocessError, FileNotFoundError):
156
- pass
157
-
158
- # Check for pip installation
142
+ details = {}
143
+
144
+ # 1. Check the actual execution context
145
+ exe_path = sys.executable
146
+ details["python_executable"] = exe_path
147
+
148
+ # 2. Check if we're in a virtual environment
149
+ in_venv = hasattr(sys, "real_prefix") or (
150
+ hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix
151
+ )
152
+
153
+ # 3. Check if running from pipx environment
154
+ # Pipx creates venvs in specific locations
155
+ is_pipx_venv = False
156
+ if in_venv and (".local/pipx/venvs" in exe_path or "pipx/venvs" in exe_path):
157
+ is_pipx_venv = True
158
+ methods_found.append("pipx")
159
+ details["pipx_venv"] = sys.prefix
160
+ elif in_venv:
161
+ # Regular virtual environment (not pipx)
162
+ methods_found.append("venv")
163
+ details["venv_path"] = sys.prefix
164
+
165
+ # 4. Check if running from source (development mode)
166
+ claude_mpm_path = Path(__file__).parent.parent.parent.parent.parent
167
+ if (claude_mpm_path / "pyproject.toml").exists():
168
+ if (claude_mpm_path / ".git").exists():
169
+ methods_found.append("development")
170
+ details["source_path"] = str(claude_mpm_path)
171
+
172
+ # 5. Check Homebrew Python
173
+ if not in_venv and "/opt/homebrew" in exe_path:
174
+ methods_found.append("homebrew")
175
+ details["homebrew_python"] = exe_path
176
+ elif not in_venv and "/usr/local" in exe_path and sys.platform == "darwin":
177
+ # Older homebrew location
178
+ methods_found.append("homebrew")
179
+ details["homebrew_python"] = exe_path
180
+
181
+ # 6. Check for system Python
182
+ if not in_venv and not methods_found:
183
+ if "/usr/bin/python" in exe_path or "/usr/local/bin/python" in exe_path:
184
+ methods_found.append("system")
185
+ details["system_python"] = exe_path
186
+
187
+ # 7. Additional check for pipx if not detected via venv
188
+ if "pipx" not in methods_found:
189
+ try:
190
+ result = subprocess.run(
191
+ ["pipx", "list"],
192
+ capture_output=True,
193
+ text=True,
194
+ timeout=5,
195
+ check=False,
196
+ )
197
+ if "claude-mpm" in result.stdout:
198
+ if not is_pipx_venv:
199
+ # Pipx is installed but we're not running from it
200
+ details["pipx_installed"] = True
201
+ details["pipx_not_active"] = (
202
+ "claude-mpm is installed via pipx but not currently running from pipx environment"
203
+ )
204
+ except (subprocess.SubprocessError, FileNotFoundError):
205
+ pass
206
+
207
+ # 8. Check pip installation status
159
208
  try:
160
209
  result = subprocess.run(
161
210
  [sys.executable, "-m", "pip", "show", "claude-mpm"],
162
211
  capture_output=True,
163
212
  text=True,
164
- timeout=5
213
+ timeout=5,
214
+ check=False,
165
215
  )
166
216
  if result.returncode == 0:
167
- methods_found.append("pip")
217
+ # Parse installation location from pip show
218
+ for line in result.stdout.split("\n"):
219
+ if line.startswith("Location:"):
220
+ location = line.split(":", 1)[1].strip()
221
+ details["pip_location"] = location
222
+
223
+ # Determine if it's editable install
224
+ if "Editable project location:" in result.stdout:
225
+ if "development" not in methods_found:
226
+ methods_found.append("development")
227
+ details["editable_install"] = True
228
+ elif not in_venv and not is_pipx_venv:
229
+ methods_found.append("pip")
168
230
  except (subprocess.SubprocessError, FileNotFoundError):
169
231
  pass
170
-
171
- # Check for development installation
172
- claude_mpm_path = Path(__file__).parent.parent.parent.parent.parent
173
- if (claude_mpm_path / "pyproject.toml").exists():
174
- if (claude_mpm_path / ".git").exists():
175
- methods_found.append("development")
176
-
232
+
233
+ # Build comprehensive details
234
+ details["methods_detected"] = methods_found
235
+
236
+ # Generate appropriate status and message based on what we found
177
237
  if not methods_found:
178
238
  return DiagnosticResult(
179
239
  category="Installation Method",
180
240
  status=DiagnosticStatus.WARNING,
181
241
  message="Installation method unknown",
182
- details={"method": "unknown"}
242
+ details=details,
243
+ )
244
+
245
+ # Pipx is the recommended method
246
+ if "pipx" in methods_found:
247
+ return DiagnosticResult(
248
+ category="Installation Method",
249
+ status=DiagnosticStatus.OK,
250
+ message="Running from pipx environment (recommended)",
251
+ details=details,
183
252
  )
184
- elif "pipx" in methods_found:
253
+
254
+ # Development in venv is also good
255
+ if "venv" in methods_found and "development" in methods_found:
256
+ venv_name = Path(sys.prefix).name
185
257
  return DiagnosticResult(
186
258
  category="Installation Method",
187
259
  status=DiagnosticStatus.OK,
188
- message="Installed via pipx (recommended)",
189
- details={"method": "pipx", "all_methods": methods_found}
260
+ message=f"Development mode in virtual environment '{venv_name}'",
261
+ details=details,
190
262
  )
191
- elif "development" in methods_found:
263
+
264
+ # Regular venv is fine
265
+ if "venv" in methods_found:
266
+ venv_name = Path(sys.prefix).name
267
+ return DiagnosticResult(
268
+ category="Installation Method",
269
+ status=DiagnosticStatus.OK,
270
+ message=f"Virtual environment '{venv_name}'",
271
+ details=details,
272
+ )
273
+
274
+ # Development with homebrew/system Python
275
+ if "development" in methods_found and "homebrew" in methods_found:
192
276
  return DiagnosticResult(
193
277
  category="Installation Method",
194
278
  status=DiagnosticStatus.OK,
195
- message="Development installation",
196
- details={"method": "development", "all_methods": methods_found}
279
+ message="Development mode with Homebrew Python",
280
+ details=details,
197
281
  )
198
- else:
282
+
283
+ if "development" in methods_found:
199
284
  return DiagnosticResult(
200
285
  category="Installation Method",
201
286
  status=DiagnosticStatus.OK,
202
- message=f"Installed via {methods_found[0]}",
203
- details={"method": methods_found[0], "all_methods": methods_found}
287
+ message="Development mode",
288
+ details=details,
204
289
  )
205
-
290
+
291
+ # Homebrew Python (not ideal but common)
292
+ if "homebrew" in methods_found:
293
+ msg = "Homebrew Python"
294
+ if details.get("pipx_installed"):
295
+ msg += " (pipx is installed but not active - consider using 'pipx run claude-mpm')"
296
+ status = DiagnosticStatus.WARNING
297
+ else:
298
+ status = DiagnosticStatus.OK
299
+ return DiagnosticResult(
300
+ category="Installation Method",
301
+ status=status,
302
+ message=msg,
303
+ details=details,
304
+ )
305
+
306
+ # System pip installation (not recommended)
307
+ if "pip" in methods_found:
308
+ return DiagnosticResult(
309
+ category="Installation Method",
310
+ status=DiagnosticStatus.WARNING,
311
+ message="System pip installation (consider using pipx or venv instead)",
312
+ details=details,
313
+ fix_description="Consider reinstalling with pipx for isolated environment",
314
+ )
315
+
316
+ # System Python
317
+ if "system" in methods_found:
318
+ return DiagnosticResult(
319
+ category="Installation Method",
320
+ status=DiagnosticStatus.WARNING,
321
+ message="System Python (consider using pipx or venv)",
322
+ details=details,
323
+ )
324
+
325
+ # Fallback for any other combination
326
+ return DiagnosticResult(
327
+ category="Installation Method",
328
+ status=DiagnosticStatus.OK,
329
+ message=f"Installed via {', '.join(methods_found)}",
330
+ details=details,
331
+ )
332
+
206
333
  def _check_dependencies(self) -> DiagnosticResult:
207
334
  """Check critical dependencies."""
208
335
  missing = []
209
336
  warnings = []
210
-
211
- critical_packages = [
212
- "aiohttp",
213
- "click",
214
- "pyyaml",
215
- "python-socketio",
216
- "aiofiles"
217
- ]
218
-
219
- for package in critical_packages:
337
+ installed = []
338
+
339
+ # Check if we're in a virtual environment
340
+ in_venv = hasattr(sys, "real_prefix") or (
341
+ hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix
342
+ )
343
+
344
+ # Map package names to their import names
345
+ critical_packages = {
346
+ "aiohttp": "aiohttp",
347
+ "click": "click",
348
+ "pyyaml": "yaml", # pyyaml is imported as yaml
349
+ "python-socketio": "socketio", # python-socketio is imported as socketio
350
+ "aiofiles": "aiofiles",
351
+ }
352
+
353
+ for package, import_name in critical_packages.items():
220
354
  try:
221
- __import__(package.replace("-", "_"))
355
+ __import__(import_name)
356
+ installed.append(package)
222
357
  except ImportError:
223
358
  missing.append(package)
224
-
359
+
225
360
  # Check optional but recommended packages
226
361
  optional_packages = ["rich", "tabulate"]
227
362
  for package in optional_packages:
228
363
  try:
229
364
  __import__(package)
365
+ installed.append(f"{package} (optional)")
230
366
  except ImportError:
231
367
  warnings.append(package)
232
-
368
+
369
+ # Provide context-aware fix instructions
233
370
  if missing:
371
+ if in_venv:
372
+ fix_cmd = f"{sys.executable} -m pip install -e ."
373
+ fix_desc = f"Install dependencies in virtual environment: {sys.prefix}"
374
+ else:
375
+ fix_cmd = "pip install -e ."
376
+ fix_desc = "Reinstall claude-mpm with dependencies (consider using a virtual environment)"
377
+
234
378
  return DiagnosticResult(
235
379
  category="Dependencies",
236
380
  status=DiagnosticStatus.ERROR,
237
381
  message=f"Missing critical dependencies: {', '.join(missing)}",
238
- details={"missing": missing, "optional_missing": warnings},
239
- fix_command="pip install -e .",
240
- fix_description="Reinstall claude-mpm with dependencies"
382
+ details={
383
+ "missing": missing,
384
+ "optional_missing": warnings,
385
+ "installed": installed,
386
+ "python_executable": sys.executable,
387
+ "in_venv": in_venv,
388
+ },
389
+ fix_command=fix_cmd,
390
+ fix_description=fix_desc,
241
391
  )
242
- elif warnings:
392
+ if warnings:
243
393
  return DiagnosticResult(
244
394
  category="Dependencies",
245
395
  status=DiagnosticStatus.WARNING,
246
396
  message=f"Missing optional dependencies: {', '.join(warnings)}",
247
- details={"optional_missing": warnings, "status": "partial"}
397
+ details={
398
+ "optional_missing": warnings,
399
+ "status": "partial",
400
+ "installed": installed,
401
+ "python_executable": sys.executable,
402
+ "in_venv": in_venv,
403
+ },
248
404
  )
249
- else:
250
- return DiagnosticResult(
251
- category="Dependencies",
252
- status=DiagnosticStatus.OK,
253
- message="All dependencies installed",
254
- details={"status": "complete"}
255
- )
405
+ return DiagnosticResult(
406
+ category="Dependencies",
407
+ status=DiagnosticStatus.OK,
408
+ message="All dependencies installed",
409
+ details={
410
+ "status": "complete",
411
+ "installed": installed,
412
+ "python_executable": sys.executable,
413
+ "in_venv": in_venv,
414
+ },
415
+ )