claude-mpm 4.1.1__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 (357) 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 +50 -2
  21. claude_mpm/cli/__init__.py +51 -46
  22. claude_mpm/cli/__main__.py +1 -1
  23. claude_mpm/cli/commands/__init__.py +10 -12
  24. claude_mpm/cli/commands/agent_manager.py +186 -181
  25. claude_mpm/cli/commands/agents.py +271 -268
  26. claude_mpm/cli/commands/aggregate.py +30 -29
  27. claude_mpm/cli/commands/cleanup.py +50 -44
  28. claude_mpm/cli/commands/cleanup_orphaned_agents.py +25 -25
  29. claude_mpm/cli/commands/config.py +162 -127
  30. claude_mpm/cli/commands/doctor.py +52 -62
  31. claude_mpm/cli/commands/info.py +37 -25
  32. claude_mpm/cli/commands/mcp.py +3 -7
  33. claude_mpm/cli/commands/mcp_command_router.py +14 -18
  34. claude_mpm/cli/commands/mcp_install_commands.py +28 -23
  35. claude_mpm/cli/commands/mcp_pipx_config.py +58 -49
  36. claude_mpm/cli/commands/mcp_server_commands.py +23 -17
  37. claude_mpm/cli/commands/memory.py +192 -141
  38. claude_mpm/cli/commands/monitor.py +117 -88
  39. claude_mpm/cli/commands/run.py +120 -84
  40. claude_mpm/cli/commands/run_config_checker.py +4 -5
  41. claude_mpm/cli/commands/socketio_monitor.py +17 -19
  42. claude_mpm/cli/commands/tickets.py +92 -92
  43. claude_mpm/cli/parser.py +1 -5
  44. claude_mpm/cli/parsers/__init__.py +1 -1
  45. claude_mpm/cli/parsers/agent_manager_parser.py +50 -98
  46. claude_mpm/cli/parsers/agents_parser.py +2 -3
  47. claude_mpm/cli/parsers/base_parser.py +7 -5
  48. claude_mpm/cli/parsers/mcp_parser.py +4 -2
  49. claude_mpm/cli/parsers/monitor_parser.py +26 -18
  50. claude_mpm/cli/shared/__init__.py +10 -10
  51. claude_mpm/cli/shared/argument_patterns.py +57 -71
  52. claude_mpm/cli/shared/base_command.py +61 -53
  53. claude_mpm/cli/shared/error_handling.py +62 -58
  54. claude_mpm/cli/shared/output_formatters.py +78 -77
  55. claude_mpm/cli/startup_logging.py +204 -172
  56. claude_mpm/cli/utils.py +10 -11
  57. claude_mpm/cli_module/__init__.py +1 -1
  58. claude_mpm/cli_module/args.py +1 -1
  59. claude_mpm/cli_module/migration_example.py +5 -5
  60. claude_mpm/config/__init__.py +9 -9
  61. claude_mpm/config/agent_config.py +15 -14
  62. claude_mpm/config/experimental_features.py +4 -4
  63. claude_mpm/config/paths.py +0 -1
  64. claude_mpm/config/socketio_config.py +5 -6
  65. claude_mpm/constants.py +1 -2
  66. claude_mpm/core/__init__.py +8 -8
  67. claude_mpm/core/agent_name_normalizer.py +1 -1
  68. claude_mpm/core/agent_registry.py +20 -23
  69. claude_mpm/core/agent_session_manager.py +3 -3
  70. claude_mpm/core/base_service.py +7 -15
  71. claude_mpm/core/cache.py +4 -6
  72. claude_mpm/core/claude_runner.py +85 -113
  73. claude_mpm/core/config.py +43 -28
  74. claude_mpm/core/config_aliases.py +0 -9
  75. claude_mpm/core/config_constants.py +52 -30
  76. claude_mpm/core/constants.py +0 -1
  77. claude_mpm/core/container.py +18 -27
  78. claude_mpm/core/exceptions.py +2 -2
  79. claude_mpm/core/factories.py +10 -12
  80. claude_mpm/core/framework_loader.py +581 -280
  81. claude_mpm/core/hook_manager.py +26 -22
  82. claude_mpm/core/hook_performance_config.py +58 -47
  83. claude_mpm/core/injectable_service.py +1 -1
  84. claude_mpm/core/interactive_session.py +61 -152
  85. claude_mpm/core/interfaces.py +1 -100
  86. claude_mpm/core/lazy.py +5 -5
  87. claude_mpm/core/log_manager.py +587 -0
  88. claude_mpm/core/logger.py +125 -8
  89. claude_mpm/core/logging_config.py +15 -15
  90. claude_mpm/core/minimal_framework_loader.py +5 -8
  91. claude_mpm/core/oneshot_session.py +15 -33
  92. claude_mpm/core/optimized_agent_loader.py +4 -6
  93. claude_mpm/core/optimized_startup.py +2 -1
  94. claude_mpm/core/output_style_manager.py +147 -106
  95. claude_mpm/core/pm_hook_interceptor.py +0 -1
  96. claude_mpm/core/service_registry.py +11 -8
  97. claude_mpm/core/session_manager.py +1 -2
  98. claude_mpm/core/shared/__init__.py +1 -1
  99. claude_mpm/core/shared/config_loader.py +101 -97
  100. claude_mpm/core/shared/path_resolver.py +72 -68
  101. claude_mpm/core/shared/singleton_manager.py +56 -50
  102. claude_mpm/core/socketio_pool.py +26 -6
  103. claude_mpm/core/tool_access_control.py +4 -5
  104. claude_mpm/core/typing_utils.py +50 -59
  105. claude_mpm/core/unified_agent_registry.py +14 -19
  106. claude_mpm/core/unified_config.py +4 -6
  107. claude_mpm/core/unified_paths.py +197 -109
  108. claude_mpm/dashboard/open_dashboard.py +2 -4
  109. claude_mpm/experimental/cli_enhancements.py +51 -36
  110. claude_mpm/generators/agent_profile_generator.py +2 -4
  111. claude_mpm/hooks/base_hook.py +1 -2
  112. claude_mpm/hooks/claude_hooks/connection_pool.py +72 -26
  113. claude_mpm/hooks/claude_hooks/event_handlers.py +93 -38
  114. claude_mpm/hooks/claude_hooks/hook_handler.py +130 -76
  115. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
  116. claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
  117. claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
  118. claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
  119. claude_mpm/hooks/memory_integration_hook.py +5 -5
  120. claude_mpm/hooks/tool_call_interceptor.py +1 -1
  121. claude_mpm/hooks/validation_hooks.py +4 -4
  122. claude_mpm/init.py +4 -9
  123. claude_mpm/models/__init__.py +2 -2
  124. claude_mpm/models/agent_session.py +11 -14
  125. claude_mpm/scripts/mcp_server.py +20 -11
  126. claude_mpm/scripts/mcp_wrapper.py +5 -5
  127. claude_mpm/scripts/mpm_doctor.py +321 -0
  128. claude_mpm/scripts/socketio_daemon.py +28 -25
  129. claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
  130. claude_mpm/scripts/socketio_server_manager.py +116 -95
  131. claude_mpm/services/__init__.py +49 -49
  132. claude_mpm/services/agent_capabilities_service.py +12 -18
  133. claude_mpm/services/agents/__init__.py +22 -22
  134. claude_mpm/services/agents/agent_builder.py +140 -119
  135. claude_mpm/services/agents/deployment/__init__.py +3 -3
  136. claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
  137. claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
  138. claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
  139. claude_mpm/services/agents/deployment/agent_deployment.py +136 -106
  140. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
  141. claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
  142. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
  143. claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
  144. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
  145. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
  146. claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
  147. claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
  148. claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
  149. claude_mpm/services/agents/deployment/agent_validator.py +0 -1
  150. claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
  151. claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
  152. claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
  153. claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
  154. claude_mpm/services/agents/deployment/config/__init__.py +1 -1
  155. claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
  156. claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
  157. claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
  158. claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
  159. claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
  160. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
  161. claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
  162. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
  163. claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
  164. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
  165. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
  166. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
  167. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
  168. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
  169. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
  170. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
  171. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
  172. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
  173. claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
  174. claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
  175. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
  176. claude_mpm/services/agents/deployment/results/__init__.py +1 -1
  177. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
  178. claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
  179. claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
  180. claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
  181. claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
  182. claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
  183. claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
  184. claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
  185. claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
  186. claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
  187. claude_mpm/services/agents/loading/__init__.py +1 -1
  188. claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
  189. claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
  190. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
  191. claude_mpm/services/agents/management/__init__.py +1 -1
  192. claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
  193. claude_mpm/services/agents/management/agent_management_service.py +5 -9
  194. claude_mpm/services/agents/memory/__init__.py +4 -4
  195. claude_mpm/services/agents/memory/agent_memory_manager.py +280 -160
  196. claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
  197. claude_mpm/services/agents/memory/content_manager.py +44 -38
  198. claude_mpm/services/agents/memory/template_generator.py +4 -6
  199. claude_mpm/services/agents/registry/__init__.py +10 -6
  200. claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
  201. claude_mpm/services/agents/registry/modification_tracker.py +3 -6
  202. claude_mpm/services/async_session_logger.py +1 -2
  203. claude_mpm/services/claude_session_logger.py +1 -2
  204. claude_mpm/services/command_deployment_service.py +173 -0
  205. claude_mpm/services/command_handler_service.py +20 -22
  206. claude_mpm/services/core/__init__.py +25 -25
  207. claude_mpm/services/core/base.py +0 -5
  208. claude_mpm/services/core/interfaces/__init__.py +32 -32
  209. claude_mpm/services/core/interfaces/agent.py +0 -21
  210. claude_mpm/services/core/interfaces/communication.py +0 -27
  211. claude_mpm/services/core/interfaces/infrastructure.py +0 -56
  212. claude_mpm/services/core/interfaces/service.py +0 -29
  213. claude_mpm/services/diagnostics/__init__.py +1 -1
  214. claude_mpm/services/diagnostics/checks/__init__.py +6 -6
  215. claude_mpm/services/diagnostics/checks/agent_check.py +89 -80
  216. claude_mpm/services/diagnostics/checks/base_check.py +12 -16
  217. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
  218. claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
  219. claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
  220. claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
  221. claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
  222. claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
  223. claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
  224. claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
  225. claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
  226. claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
  227. claude_mpm/services/diagnostics/models.py +21 -19
  228. claude_mpm/services/event_aggregator.py +10 -17
  229. claude_mpm/services/event_bus/__init__.py +1 -1
  230. claude_mpm/services/event_bus/config.py +54 -35
  231. claude_mpm/services/event_bus/event_bus.py +76 -71
  232. claude_mpm/services/event_bus/relay.py +74 -64
  233. claude_mpm/services/events/__init__.py +11 -11
  234. claude_mpm/services/events/consumers/__init__.py +3 -3
  235. claude_mpm/services/events/consumers/dead_letter.py +71 -63
  236. claude_mpm/services/events/consumers/logging.py +39 -37
  237. claude_mpm/services/events/consumers/metrics.py +56 -57
  238. claude_mpm/services/events/consumers/socketio.py +82 -81
  239. claude_mpm/services/events/core.py +110 -99
  240. claude_mpm/services/events/interfaces.py +56 -72
  241. claude_mpm/services/events/producers/__init__.py +1 -1
  242. claude_mpm/services/events/producers/hook.py +38 -38
  243. claude_mpm/services/events/producers/system.py +46 -44
  244. claude_mpm/services/exceptions.py +81 -80
  245. claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
  246. claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
  247. claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
  248. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
  249. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
  250. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
  251. claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
  252. claude_mpm/services/hook_service.py +6 -9
  253. claude_mpm/services/infrastructure/__init__.py +1 -1
  254. claude_mpm/services/infrastructure/context_preservation.py +8 -12
  255. claude_mpm/services/infrastructure/monitoring.py +21 -23
  256. claude_mpm/services/mcp_gateway/__init__.py +37 -37
  257. claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
  258. claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
  259. claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
  260. claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
  261. claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
  262. claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
  263. claude_mpm/services/mcp_gateway/core/base.py +0 -3
  264. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
  265. claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
  266. claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
  267. claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
  268. claude_mpm/services/mcp_gateway/main.py +2 -1
  269. claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
  270. claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
  271. claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
  272. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
  273. claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
  274. claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
  275. claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
  276. claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
  277. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
  278. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
  279. claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
  280. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
  281. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
  282. claude_mpm/services/memory/__init__.py +3 -3
  283. claude_mpm/services/memory/builder.py +3 -6
  284. claude_mpm/services/memory/cache/__init__.py +1 -1
  285. claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
  286. claude_mpm/services/memory/cache/simple_cache.py +1 -1
  287. claude_mpm/services/memory/indexed_memory.py +5 -7
  288. claude_mpm/services/memory/optimizer.py +7 -10
  289. claude_mpm/services/memory/router.py +8 -9
  290. claude_mpm/services/memory_hook_service.py +48 -34
  291. claude_mpm/services/monitor_build_service.py +77 -73
  292. claude_mpm/services/port_manager.py +130 -108
  293. claude_mpm/services/project/analyzer.py +12 -10
  294. claude_mpm/services/project/registry.py +11 -11
  295. claude_mpm/services/recovery_manager.py +10 -19
  296. claude_mpm/services/response_tracker.py +0 -1
  297. claude_mpm/services/runner_configuration_service.py +19 -20
  298. claude_mpm/services/session_management_service.py +7 -11
  299. claude_mpm/services/shared/__init__.py +1 -1
  300. claude_mpm/services/shared/async_service_base.py +58 -50
  301. claude_mpm/services/shared/config_service_base.py +73 -67
  302. claude_mpm/services/shared/lifecycle_service_base.py +82 -78
  303. claude_mpm/services/shared/manager_base.py +94 -82
  304. claude_mpm/services/shared/service_factory.py +96 -98
  305. claude_mpm/services/socketio/__init__.py +3 -3
  306. claude_mpm/services/socketio/client_proxy.py +5 -5
  307. claude_mpm/services/socketio/event_normalizer.py +199 -181
  308. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  309. claude_mpm/services/socketio/handlers/base.py +5 -4
  310. claude_mpm/services/socketio/handlers/connection.py +163 -136
  311. claude_mpm/services/socketio/handlers/file.py +13 -14
  312. claude_mpm/services/socketio/handlers/git.py +12 -7
  313. claude_mpm/services/socketio/handlers/hook.py +49 -44
  314. claude_mpm/services/socketio/handlers/memory.py +0 -1
  315. claude_mpm/services/socketio/handlers/project.py +0 -1
  316. claude_mpm/services/socketio/handlers/registry.py +37 -19
  317. claude_mpm/services/socketio/migration_utils.py +98 -84
  318. claude_mpm/services/socketio/server/__init__.py +1 -1
  319. claude_mpm/services/socketio/server/broadcaster.py +81 -87
  320. claude_mpm/services/socketio/server/core.py +65 -54
  321. claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
  322. claude_mpm/services/socketio/server/main.py +64 -38
  323. claude_mpm/services/socketio_client_manager.py +10 -12
  324. claude_mpm/services/subprocess_launcher_service.py +4 -7
  325. claude_mpm/services/system_instructions_service.py +13 -14
  326. claude_mpm/services/ticket_manager.py +2 -2
  327. claude_mpm/services/utility_service.py +5 -13
  328. claude_mpm/services/version_control/__init__.py +16 -16
  329. claude_mpm/services/version_control/branch_strategy.py +5 -8
  330. claude_mpm/services/version_control/conflict_resolution.py +9 -23
  331. claude_mpm/services/version_control/git_operations.py +5 -7
  332. claude_mpm/services/version_control/semantic_versioning.py +16 -17
  333. claude_mpm/services/version_control/version_parser.py +13 -18
  334. claude_mpm/services/version_service.py +10 -11
  335. claude_mpm/storage/__init__.py +1 -1
  336. claude_mpm/storage/state_storage.py +22 -28
  337. claude_mpm/utils/__init__.py +6 -6
  338. claude_mpm/utils/agent_dependency_loader.py +47 -33
  339. claude_mpm/utils/config_manager.py +11 -14
  340. claude_mpm/utils/dependency_cache.py +1 -1
  341. claude_mpm/utils/dependency_manager.py +13 -17
  342. claude_mpm/utils/dependency_strategies.py +8 -10
  343. claude_mpm/utils/environment_context.py +3 -9
  344. claude_mpm/utils/error_handler.py +3 -13
  345. claude_mpm/utils/file_utils.py +1 -1
  346. claude_mpm/utils/path_operations.py +8 -12
  347. claude_mpm/utils/robust_installer.py +110 -33
  348. claude_mpm/utils/subprocess_utils.py +5 -6
  349. claude_mpm/validation/agent_validator.py +3 -6
  350. claude_mpm/validation/frontmatter_validator.py +1 -1
  351. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/METADATA +1 -1
  352. claude_mpm-4.1.2.dist-info/RECORD +498 -0
  353. claude_mpm-4.1.1.dist-info/RECORD +0 -494
  354. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/WHEEL +0 -0
  355. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/entry_points.txt +0 -0
  356. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/licenses/LICENSE +0 -0
  357. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/top_level.txt +0 -0
@@ -27,21 +27,20 @@ Implements error handling and user guidance patterns from awesome-claude-code.
27
27
 
28
28
  import logging
29
29
  import sys
30
- from typing import Any, Dict, List, Optional
31
30
 
32
31
  import click
33
32
 
34
- from claude_mpm.hooks.validation_hooks import ValidationError, ValidationHooks
33
+ from claude_mpm.hooks.validation_hooks import ValidationHooks
35
34
  from claude_mpm.utils.error_handler import (
36
35
  ErrorContext,
37
36
  MPMError,
38
37
  handle_errors,
39
- suggest_setup_fix,
40
38
  )
41
39
  from claude_mpm.validation import AgentValidator, ValidationResult
42
40
 
43
41
  logger = logging.getLogger(__name__)
44
42
 
43
+
45
44
  class CLIContext:
46
45
  """Enhanced CLI context with validation and error handling."""
47
46
 
@@ -55,12 +54,14 @@ class CLIContext:
55
54
  def setup_logging(self, debug: bool = False) -> None:
56
55
  """Setup logging based on debug flag."""
57
56
  level = logging.DEBUG if debug else logging.INFO
58
- format_str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" if debug else "%(message)s"
57
+ format_str = (
58
+ "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
59
+ if debug
60
+ else "%(message)s"
61
+ )
59
62
 
60
63
  logging.basicConfig(
61
- level=level,
62
- format=format_str,
63
- handlers=[logging.StreamHandler(sys.stdout)]
64
+ level=level, format=format_str, handlers=[logging.StreamHandler(sys.stdout)]
64
65
  )
65
66
  self.debug = debug
66
67
 
@@ -78,9 +79,9 @@ class CLIContext:
78
79
 
79
80
  # Check required directories
80
81
  required_dirs = [
81
- Path.home() / '.claude-mpm',
82
- Path.home() / '.claude-mpm' / 'profiles',
83
- Path.home() / '.claude-mpm' / 'logs',
82
+ Path.home() / ".claude-mpm",
83
+ Path.home() / ".claude-mpm" / "profiles",
84
+ Path.home() / ".claude-mpm" / "logs",
84
85
  ]
85
86
 
86
87
  for dir_path in required_dirs:
@@ -94,8 +95,9 @@ class CLIContext:
94
95
 
95
96
  return all_passed
96
97
 
97
- def handle_validation_result(self, result: ValidationResult,
98
- operation: str = "operation") -> None:
98
+ def handle_validation_result(
99
+ self, result: ValidationResult, operation: str = "operation"
100
+ ) -> None:
99
101
  """Handle validation results with user-friendly output."""
100
102
  if result.is_valid:
101
103
  if result.warnings:
@@ -116,13 +118,14 @@ class CLIContext:
116
118
 
117
119
  sys.exit(1)
118
120
 
121
+
119
122
  def create_enhanced_cli() -> click.Group:
120
123
  """Create enhanced CLI with better error handling."""
121
124
  cli_context = CLIContext()
122
125
 
123
126
  @click.group()
124
- @click.option('--debug', is_flag=True, help='Enable debug logging')
125
- @click.option('--dry-run', is_flag=True, help='Run without making changes')
127
+ @click.option("--debug", is_flag=True, help="Enable debug logging")
128
+ @click.option("--dry-run", is_flag=True, help="Run without making changes")
126
129
  @click.pass_context
127
130
  def cli(ctx, debug: bool, dry_run: bool):
128
131
  """Enhanced claude-mpm CLI with validation and error handling."""
@@ -131,6 +134,7 @@ def create_enhanced_cli() -> click.Group:
131
134
  cli_context.dry_run = dry_run
132
135
 
133
136
  if debug:
137
+ print("🐛 Debug mode enabled")
134
138
 
135
139
  if dry_run:
136
140
  print("🏃 Dry-run mode enabled")
@@ -154,7 +158,7 @@ def create_enhanced_cli() -> click.Group:
154
158
  sys.exit(1)
155
159
 
156
160
  @cli.command()
157
- @click.argument('profile_path', type=click.Path(exists=True))
161
+ @click.argument("profile_path", type=click.Path(exists=True))
158
162
  @click.pass_context
159
163
  @handle_errors(MPMError)
160
164
  async def validate_profile(ctx, profile_path: str):
@@ -167,14 +171,16 @@ def create_enhanced_cli() -> click.Group:
167
171
  # Run pre-load validation
168
172
  result = await cli_ctx.validation_hooks.run_pre_load_validation(profile)
169
173
 
170
- cli_ctx.handle_validation_result(result, f"Profile validation for {profile.name}")
174
+ cli_ctx.handle_validation_result(
175
+ result, f"Profile validation for {profile.name}"
176
+ )
171
177
 
172
178
  if result.is_valid and result.locked_fields:
173
179
  print(f"\n🔒 Locked fields: {', '.join(result.locked_fields)}")
174
180
 
175
181
  @cli.command()
176
- @click.option('--profile', '-p', help='Agent profile to load')
177
- @click.option('--task', '-t', help='Task to execute')
182
+ @click.option("--profile", "-p", help="Agent profile to load")
183
+ @click.option("--task", "-t", help="Task to execute")
178
184
  @click.pass_context
179
185
  @handle_errors(MPMError)
180
186
  async def run_agent(ctx, profile: str, task: str):
@@ -189,8 +195,8 @@ def create_enhanced_cli() -> click.Group:
189
195
  if not profile_path.exists():
190
196
  # Try default locations
191
197
  default_locations = [
192
- Path.home() / '.claude-mpm' / 'profiles' / f"{profile}.yaml",
193
- Path.cwd() / 'agents' / f"{profile}.yaml",
198
+ Path.home() / ".claude-mpm" / "profiles" / f"{profile}.yaml",
199
+ Path.cwd() / "agents" / f"{profile}.yaml",
194
200
  ]
195
201
 
196
202
  for location in default_locations:
@@ -200,24 +206,26 @@ def create_enhanced_cli() -> click.Group:
200
206
  else:
201
207
  raise MPMError(
202
208
  f"Profile '{profile}' not found",
203
- details={'searched_locations': [str(p) for p in default_locations]},
209
+ details={"searched_locations": [str(p) for p in default_locations]},
204
210
  suggestions=[
205
211
  "Check the profile name",
206
212
  "Use 'mpm list-profiles' to see available profiles",
207
- "Create a new profile with 'mpm create-profile'"
208
- ]
213
+ "Create a new profile with 'mpm create-profile'",
214
+ ],
209
215
  )
210
216
 
211
217
  # Run validation
212
218
  print(f"🔍 Validating profile: {profile_path.name}")
213
- validation_result = await cli_ctx.validation_hooks.run_pre_load_validation(profile_path)
219
+ validation_result = await cli_ctx.validation_hooks.run_pre_load_validation(
220
+ profile_path
221
+ )
214
222
 
215
223
  if not validation_result.is_valid:
216
224
  cli_ctx.handle_validation_result(validation_result, "Profile validation")
217
225
  return
218
226
 
219
227
  # Validate task
220
- print(f"🔍 Validating task...")
228
+ print("🔍 Validating task...")
221
229
  task_result = await cli_ctx.validation_hooks.run_pre_execute_validation(
222
230
  profile_path.stem, task
223
231
  )
@@ -242,14 +250,14 @@ def create_enhanced_cli() -> click.Group:
242
250
  cli_ctx = ctx.obj
243
251
 
244
252
  profile_locations = [
245
- Path.home() / '.claude-mpm' / 'profiles',
246
- Path.cwd() / 'agents',
253
+ Path.home() / ".claude-mpm" / "profiles",
254
+ Path.cwd() / "agents",
247
255
  ]
248
256
 
249
257
  all_profiles = []
250
258
  for location in profile_locations:
251
259
  if location.exists():
252
- profiles = list(location.glob('*.yaml')) + list(location.glob('*.yml'))
260
+ profiles = list(location.glob("*.yaml")) + list(location.glob("*.yml"))
253
261
  all_profiles.extend(profiles)
254
262
 
255
263
  if not all_profiles:
@@ -265,9 +273,9 @@ def create_enhanced_cli() -> click.Group:
265
273
  print(f" {status} {profile.stem} ({profile})")
266
274
 
267
275
  @cli.command()
268
- @click.argument('name')
269
- @click.option('--role', '-r', required=True, help='Agent role')
270
- @click.option('--category', '-c', default='analysis', help='Agent category')
276
+ @click.argument("name")
277
+ @click.option("--role", "-r", required=True, help="Agent role")
278
+ @click.option("--category", "-c", default="analysis", help="Agent category")
271
279
  @click.pass_context
272
280
  def create_profile(ctx, name: str, role: str, category: str):
273
281
  """Create a new agent profile from template."""
@@ -285,34 +293,41 @@ def create_enhanced_cli() -> click.Group:
285
293
  profile_content = generator.generate_profile(config)
286
294
 
287
295
  # Save profile
288
- profile_dir = Path.home() / '.claude-mpm' / 'profiles'
296
+ profile_dir = Path.home() / ".claude-mpm" / "profiles"
289
297
  profile_dir.mkdir(parents=True, exist_ok=True)
290
298
 
291
299
  profile_path = profile_dir / f"{name.lower().replace(' ', '_')}.yaml"
292
300
 
293
- if profile_path.exists() and not click.confirm(f"Profile {profile_path} exists. Overwrite?"):
301
+ if profile_path.exists() and not click.confirm(
302
+ f"Profile {profile_path} exists. Overwrite?"
303
+ ):
294
304
  print("Aborted")
295
305
  return
296
306
 
297
307
  if cli_ctx.dry_run:
298
308
  print(f"\n🏃 Dry-run mode - would create {profile_path}:")
299
309
  print("---")
300
- print(profile_content[:500] + "..." if len(profile_content) > 500 else profile_content)
310
+ print(
311
+ profile_content[:500] + "..."
312
+ if len(profile_content) > 500
313
+ else profile_content
314
+ )
301
315
  print("---")
302
316
  else:
303
317
  profile_path.write_text(profile_content)
304
318
  print(f"✅ Created profile: {profile_path}")
305
319
 
306
320
  # Generate documentation
307
- doc_path = profile_path.with_suffix('.md')
321
+ doc_path = profile_path.with_suffix(".md")
308
322
  doc_content = generator.generate_agent_documentation(config)
309
323
  doc_path.write_text(doc_content)
310
324
  print(f"📝 Created documentation: {doc_path}")
311
325
 
312
326
  return cli
313
327
 
328
+
314
329
  # Export the enhanced CLI
315
330
  enhanced_cli = create_enhanced_cli()
316
331
 
317
- if __name__ == '__main__':
332
+ if __name__ == "__main__":
318
333
  enhanced_cli()
@@ -29,7 +29,7 @@ class AgentProfileGenerator:
29
29
  if not self.template_path.exists():
30
30
  raise FileNotFoundError(f"Template not found: {self.template_path}")
31
31
 
32
- with open(self.template_path, "r") as f:
32
+ with open(self.template_path) as f:
33
33
  return yaml.safe_load(f)
34
34
 
35
35
  def generate_profile(self, config: Dict[str, Any]) -> str:
@@ -46,9 +46,7 @@ class AgentProfileGenerator:
46
46
  result = self._replace_placeholders(template_str, config)
47
47
 
48
48
  # Clean up any remaining placeholders
49
- result = re.sub(r"\{\{[^}]+\}\}", "", result)
50
-
51
- return result
49
+ return re.sub(r"\{\{[^}]+\}\}", "", result)
52
50
 
53
51
  def _replace_placeholders(self, template: str, values: Dict[str, Any]) -> str:
54
52
  """Replace template placeholders with actual values."""
@@ -6,7 +6,7 @@ from abc import ABC, abstractmethod
6
6
  from dataclasses import dataclass
7
7
  from datetime import datetime
8
8
  from enum import Enum
9
- from typing import Any, Dict, List, Optional, Union
9
+ from typing import Any, Dict, Optional
10
10
 
11
11
  logger = logging.getLogger(__name__)
12
12
 
@@ -75,7 +75,6 @@ class BaseHook(ABC):
75
75
  Returns:
76
76
  HookResult with execution results
77
77
  """
78
- pass
79
78
 
80
79
  async def async_execute(self, context: HookContext) -> HookResult:
81
80
  """Async version of execute. Override for async hooks."""
@@ -59,8 +59,7 @@ class SocketIOConnectionPool:
59
59
  client = conn["client"]
60
60
  if self._is_connection_alive(client):
61
61
  return client
62
- else:
63
- self.connections.remove(conn)
62
+ self.connections.remove(conn)
64
63
 
65
64
  if len(self.connections) < self.max_connections:
66
65
  client = self._create_connection(port)
@@ -82,7 +81,7 @@ class SocketIOConnectionPool:
82
81
 
83
82
  def _create_connection(self, port: int) -> Optional[Any]:
84
83
  """Create a new Socket.IO connection with persistent keep-alive.
85
-
84
+
86
85
  WHY persistent connections:
87
86
  - Maintains connection throughout handler lifecycle
88
87
  - Automatic reconnection on disconnect
@@ -100,32 +99,38 @@ class SocketIOConnectionPool:
100
99
  logger=False,
101
100
  engineio_logger=False,
102
101
  )
103
-
102
+
104
103
  # Set up event handlers for connection lifecycle
105
- @client.on('connect')
104
+ @client.on("connect")
106
105
  def on_connect():
107
106
  pass # Connection established
108
-
109
- @client.on('disconnect')
107
+
108
+ @client.on("disconnect")
110
109
  def on_disconnect():
111
110
  pass # Will automatically try to reconnect
112
-
111
+
113
112
  client.connect(
114
113
  f"http://localhost:{port}",
115
114
  wait=True, # Wait for connection to establish
116
115
  wait_timeout=NetworkConfig.SOCKET_WAIT_TIMEOUT,
117
- transports=['websocket', 'polling'], # Try WebSocket first, fall back to polling
116
+ transports=[
117
+ "websocket",
118
+ "polling",
119
+ ], # Try WebSocket first, fall back to polling
118
120
  )
119
-
121
+
120
122
  if client.connected:
121
123
  # Send a keep-alive ping to establish the connection
122
124
  try:
123
- client.emit('ping', {
124
- 'type': 'system',
125
- 'subtype': 'ping',
126
- 'timestamp': time.time(),
127
- 'source': 'connection_pool'
128
- })
125
+ client.emit(
126
+ "ping",
127
+ {
128
+ "type": "system",
129
+ "subtype": "ping",
130
+ "timestamp": time.time(),
131
+ "source": "connection_pool",
132
+ },
133
+ )
129
134
  except:
130
135
  pass # Ignore ping errors
131
136
  return client
@@ -135,7 +140,7 @@ class SocketIOConnectionPool:
135
140
 
136
141
  def _is_connection_alive(self, client: Any) -> bool:
137
142
  """Check if a connection is still alive.
138
-
143
+
139
144
  WHY enhanced check:
140
145
  - Verifies actual connection state
141
146
  - Attempts to ping server for liveness check
@@ -144,21 +149,24 @@ class SocketIOConnectionPool:
144
149
  try:
145
150
  if not client:
146
151
  return False
147
-
152
+
148
153
  # Check basic connection state
149
154
  if not client.connected:
150
155
  return False
151
-
156
+
152
157
  # Try a quick ping to verify connection is truly alive
153
158
  # This helps detect zombie connections
154
159
  try:
155
160
  # Just emit a ping, don't wait for response (faster)
156
- client.emit('ping', {
157
- 'type': 'system',
158
- 'subtype': 'ping',
159
- 'timestamp': time.time(),
160
- 'source': 'connection_pool'
161
- })
161
+ client.emit(
162
+ "ping",
163
+ {
164
+ "type": "system",
165
+ "subtype": "ping",
166
+ "timestamp": time.time(),
167
+ "source": "connection_pool",
168
+ },
169
+ )
162
170
  return True
163
171
  except:
164
172
  # If ping fails, connection might be dead
@@ -176,7 +184,7 @@ class SocketIOConnectionPool:
176
184
 
177
185
  def _cleanup_dead_connections(self) -> None:
178
186
  """Remove dead connections from the pool and attempt reconnection.
179
-
187
+
180
188
  WHY proactive reconnection:
181
189
  - Maintains pool health
182
190
  - Ensures connections are ready when needed
@@ -202,3 +210,41 @@ class SocketIOConnectionPool:
202
210
  for conn in self.connections:
203
211
  self._close_connection(conn.get("client"))
204
212
  self.connections.clear()
213
+
214
+ def emit(self, event: str, data: Dict[str, Any]) -> bool:
215
+ """Emit an event through the connection pool.
216
+
217
+ This method provides backward compatibility for the deprecated
218
+ connection pool. It attempts to send events directly to the
219
+ Socket.IO server.
220
+
221
+ Args:
222
+ event: Event name (e.g., "claude_event")
223
+ data: Event data dictionary
224
+
225
+ Returns:
226
+ bool: True if event was sent successfully
227
+ """
228
+ if not SOCKETIO_AVAILABLE:
229
+ return False
230
+
231
+ # Try multiple ports in the range
232
+ for port in range(
233
+ NetworkConfig.SOCKETIO_PORT_RANGE[0],
234
+ NetworkConfig.SOCKETIO_PORT_RANGE[1] + 1,
235
+ ):
236
+ client = self.get_connection(port)
237
+ if client:
238
+ try:
239
+ # Emit the event
240
+ client.emit(event, data)
241
+ return True
242
+ except Exception:
243
+ # Try next port
244
+ continue
245
+
246
+ return False
247
+
248
+ def cleanup(self) -> None:
249
+ """Cleanup all connections (alias for close_all)."""
250
+ self.close_all()