claude-mpm 4.1.1__py3-none-any.whl → 4.1.3__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 (389) 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/engineer.json +33 -11
  18. claude_mpm/agents/templates/imagemagick.json +256 -0
  19. claude_mpm/agents/templates/qa.json +41 -2
  20. claude_mpm/agents/templates/ticketing.json +5 -5
  21. claude_mpm/agents/templates/web_qa.json +50 -2
  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 +648 -1098
  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 +339 -967
  39. claude_mpm/cli/commands/monitor.py +117 -88
  40. claude_mpm/cli/commands/run.py +233 -542
  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 +280 -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 +22 -29
  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 +500 -680
  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 -17
  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 +99 -154
  114. claude_mpm/hooks/claude_hooks/hook_handler.py +110 -720
  115. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
  116. claude_mpm/hooks/claude_hooks/hook_handler_original.py +1040 -0
  117. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +347 -0
  118. claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
  119. claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
  120. claude_mpm/hooks/claude_hooks/services/__init__.py +13 -0
  121. claude_mpm/hooks/claude_hooks/services/connection_manager.py +190 -0
  122. claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
  123. claude_mpm/hooks/claude_hooks/services/state_manager.py +282 -0
  124. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
  125. claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
  126. claude_mpm/hooks/memory_integration_hook.py +5 -5
  127. claude_mpm/hooks/tool_call_interceptor.py +1 -1
  128. claude_mpm/hooks/validation_hooks.py +4 -4
  129. claude_mpm/init.py +4 -9
  130. claude_mpm/models/__init__.py +2 -2
  131. claude_mpm/models/agent_session.py +11 -14
  132. claude_mpm/scripts/mcp_server.py +20 -11
  133. claude_mpm/scripts/mcp_wrapper.py +5 -5
  134. claude_mpm/scripts/mpm_doctor.py +321 -0
  135. claude_mpm/scripts/socketio_daemon.py +28 -25
  136. claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
  137. claude_mpm/scripts/socketio_server_manager.py +116 -95
  138. claude_mpm/services/__init__.py +49 -49
  139. claude_mpm/services/agent_capabilities_service.py +12 -18
  140. claude_mpm/services/agents/__init__.py +22 -22
  141. claude_mpm/services/agents/agent_builder.py +140 -119
  142. claude_mpm/services/agents/deployment/__init__.py +3 -3
  143. claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
  144. claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
  145. claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
  146. claude_mpm/services/agents/deployment/agent_deployment.py +129 -511
  147. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
  148. claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
  149. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
  150. claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
  151. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
  152. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
  153. claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
  154. claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
  155. claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
  156. claude_mpm/services/agents/deployment/agent_validator.py +0 -1
  157. claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
  158. claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
  159. claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
  160. claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
  161. claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
  162. claude_mpm/services/agents/deployment/config/__init__.py +1 -1
  163. claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
  164. claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
  165. claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
  166. claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
  167. claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
  168. claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
  169. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
  170. claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
  171. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
  172. claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
  173. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
  174. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
  175. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
  176. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
  177. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
  178. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
  179. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
  180. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
  181. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
  182. claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
  183. claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
  184. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
  185. claude_mpm/services/agents/deployment/results/__init__.py +1 -1
  186. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
  187. claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
  188. claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
  189. claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
  190. claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
  191. claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
  192. claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
  193. claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
  194. claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
  195. claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
  196. claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
  197. claude_mpm/services/agents/loading/__init__.py +1 -1
  198. claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
  199. claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
  200. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
  201. claude_mpm/services/agents/management/__init__.py +1 -1
  202. claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
  203. claude_mpm/services/agents/management/agent_management_service.py +5 -9
  204. claude_mpm/services/agents/memory/__init__.py +4 -4
  205. claude_mpm/services/agents/memory/agent_memory_manager.py +157 -503
  206. claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
  207. claude_mpm/services/agents/memory/content_manager.py +44 -38
  208. claude_mpm/services/agents/memory/memory_categorization_service.py +165 -0
  209. claude_mpm/services/agents/memory/memory_file_service.py +103 -0
  210. claude_mpm/services/agents/memory/memory_format_service.py +201 -0
  211. claude_mpm/services/agents/memory/memory_limits_service.py +99 -0
  212. claude_mpm/services/agents/memory/template_generator.py +4 -6
  213. claude_mpm/services/agents/registry/__init__.py +11 -7
  214. claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
  215. claude_mpm/services/agents/registry/modification_tracker.py +3 -6
  216. claude_mpm/services/async_session_logger.py +1 -2
  217. claude_mpm/services/claude_session_logger.py +1 -2
  218. claude_mpm/services/cli/__init__.py +18 -0
  219. claude_mpm/services/cli/agent_cleanup_service.py +407 -0
  220. claude_mpm/services/cli/agent_dependency_service.py +395 -0
  221. claude_mpm/services/cli/agent_listing_service.py +463 -0
  222. claude_mpm/services/cli/agent_output_formatter.py +605 -0
  223. claude_mpm/services/cli/agent_validation_service.py +589 -0
  224. claude_mpm/services/cli/dashboard_launcher.py +424 -0
  225. claude_mpm/services/cli/memory_crud_service.py +617 -0
  226. claude_mpm/services/cli/memory_output_formatter.py +604 -0
  227. claude_mpm/services/cli/session_manager.py +513 -0
  228. claude_mpm/services/cli/socketio_manager.py +498 -0
  229. claude_mpm/services/cli/startup_checker.py +370 -0
  230. claude_mpm/services/command_deployment_service.py +173 -0
  231. claude_mpm/services/command_handler_service.py +20 -22
  232. claude_mpm/services/core/__init__.py +25 -25
  233. claude_mpm/services/core/base.py +0 -5
  234. claude_mpm/services/core/cache_manager.py +311 -0
  235. claude_mpm/services/core/interfaces/__init__.py +32 -32
  236. claude_mpm/services/core/interfaces/agent.py +0 -21
  237. claude_mpm/services/core/interfaces/communication.py +0 -27
  238. claude_mpm/services/core/interfaces/infrastructure.py +0 -56
  239. claude_mpm/services/core/interfaces/service.py +0 -29
  240. claude_mpm/services/core/memory_manager.py +637 -0
  241. claude_mpm/services/core/path_resolver.py +498 -0
  242. claude_mpm/services/core/service_container.py +520 -0
  243. claude_mpm/services/core/service_interfaces.py +436 -0
  244. claude_mpm/services/diagnostics/__init__.py +1 -1
  245. claude_mpm/services/diagnostics/checks/__init__.py +6 -6
  246. claude_mpm/services/diagnostics/checks/agent_check.py +152 -97
  247. claude_mpm/services/diagnostics/checks/base_check.py +12 -16
  248. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
  249. claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
  250. claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
  251. claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
  252. claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
  253. claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
  254. claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
  255. claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
  256. claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
  257. claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
  258. claude_mpm/services/diagnostics/models.py +21 -19
  259. claude_mpm/services/event_aggregator.py +10 -17
  260. claude_mpm/services/event_bus/__init__.py +1 -1
  261. claude_mpm/services/event_bus/config.py +54 -35
  262. claude_mpm/services/event_bus/event_bus.py +76 -71
  263. claude_mpm/services/event_bus/relay.py +74 -64
  264. claude_mpm/services/events/__init__.py +11 -11
  265. claude_mpm/services/events/consumers/__init__.py +3 -3
  266. claude_mpm/services/events/consumers/dead_letter.py +71 -63
  267. claude_mpm/services/events/consumers/logging.py +39 -37
  268. claude_mpm/services/events/consumers/metrics.py +56 -57
  269. claude_mpm/services/events/consumers/socketio.py +82 -81
  270. claude_mpm/services/events/core.py +110 -99
  271. claude_mpm/services/events/interfaces.py +56 -72
  272. claude_mpm/services/events/producers/__init__.py +1 -1
  273. claude_mpm/services/events/producers/hook.py +38 -38
  274. claude_mpm/services/events/producers/system.py +46 -44
  275. claude_mpm/services/exceptions.py +81 -80
  276. claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
  277. claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
  278. claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
  279. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
  280. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
  281. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
  282. claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
  283. claude_mpm/services/hook_service.py +6 -9
  284. claude_mpm/services/infrastructure/__init__.py +1 -1
  285. claude_mpm/services/infrastructure/context_preservation.py +8 -12
  286. claude_mpm/services/infrastructure/monitoring.py +21 -23
  287. claude_mpm/services/mcp_gateway/__init__.py +37 -37
  288. claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
  289. claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
  290. claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
  291. claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
  292. claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
  293. claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
  294. claude_mpm/services/mcp_gateway/core/base.py +0 -3
  295. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
  296. claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
  297. claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
  298. claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
  299. claude_mpm/services/mcp_gateway/main.py +2 -1
  300. claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
  301. claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
  302. claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
  303. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
  304. claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
  305. claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
  306. claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
  307. claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
  308. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
  309. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
  310. claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
  311. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
  312. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
  313. claude_mpm/services/memory/__init__.py +3 -3
  314. claude_mpm/services/memory/builder.py +3 -6
  315. claude_mpm/services/memory/cache/__init__.py +1 -1
  316. claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
  317. claude_mpm/services/memory/cache/simple_cache.py +1 -1
  318. claude_mpm/services/memory/indexed_memory.py +5 -7
  319. claude_mpm/services/memory/optimizer.py +7 -10
  320. claude_mpm/services/memory/router.py +8 -9
  321. claude_mpm/services/memory_hook_service.py +48 -34
  322. claude_mpm/services/monitor_build_service.py +77 -73
  323. claude_mpm/services/port_manager.py +130 -108
  324. claude_mpm/services/project/analyzer.py +12 -10
  325. claude_mpm/services/project/registry.py +11 -11
  326. claude_mpm/services/recovery_manager.py +10 -19
  327. claude_mpm/services/response_tracker.py +0 -1
  328. claude_mpm/services/runner_configuration_service.py +19 -20
  329. claude_mpm/services/session_management_service.py +7 -11
  330. claude_mpm/services/shared/__init__.py +1 -1
  331. claude_mpm/services/shared/async_service_base.py +58 -50
  332. claude_mpm/services/shared/config_service_base.py +73 -67
  333. claude_mpm/services/shared/lifecycle_service_base.py +82 -78
  334. claude_mpm/services/shared/manager_base.py +94 -82
  335. claude_mpm/services/shared/service_factory.py +96 -98
  336. claude_mpm/services/socketio/__init__.py +3 -3
  337. claude_mpm/services/socketio/client_proxy.py +5 -5
  338. claude_mpm/services/socketio/event_normalizer.py +199 -181
  339. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  340. claude_mpm/services/socketio/handlers/base.py +5 -4
  341. claude_mpm/services/socketio/handlers/connection.py +163 -136
  342. claude_mpm/services/socketio/handlers/file.py +13 -14
  343. claude_mpm/services/socketio/handlers/git.py +12 -7
  344. claude_mpm/services/socketio/handlers/hook.py +49 -44
  345. claude_mpm/services/socketio/handlers/memory.py +0 -1
  346. claude_mpm/services/socketio/handlers/project.py +0 -1
  347. claude_mpm/services/socketio/handlers/registry.py +37 -19
  348. claude_mpm/services/socketio/migration_utils.py +98 -84
  349. claude_mpm/services/socketio/server/__init__.py +1 -1
  350. claude_mpm/services/socketio/server/broadcaster.py +81 -87
  351. claude_mpm/services/socketio/server/core.py +65 -54
  352. claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
  353. claude_mpm/services/socketio/server/main.py +64 -38
  354. claude_mpm/services/socketio_client_manager.py +10 -12
  355. claude_mpm/services/subprocess_launcher_service.py +4 -7
  356. claude_mpm/services/system_instructions_service.py +13 -14
  357. claude_mpm/services/ticket_manager.py +2 -2
  358. claude_mpm/services/utility_service.py +5 -13
  359. claude_mpm/services/version_control/__init__.py +16 -16
  360. claude_mpm/services/version_control/branch_strategy.py +5 -8
  361. claude_mpm/services/version_control/conflict_resolution.py +9 -23
  362. claude_mpm/services/version_control/git_operations.py +5 -7
  363. claude_mpm/services/version_control/semantic_versioning.py +16 -17
  364. claude_mpm/services/version_control/version_parser.py +13 -18
  365. claude_mpm/services/version_service.py +10 -11
  366. claude_mpm/storage/__init__.py +1 -1
  367. claude_mpm/storage/state_storage.py +22 -28
  368. claude_mpm/utils/__init__.py +6 -6
  369. claude_mpm/utils/agent_dependency_loader.py +47 -33
  370. claude_mpm/utils/config_manager.py +11 -14
  371. claude_mpm/utils/dependency_cache.py +1 -1
  372. claude_mpm/utils/dependency_manager.py +13 -17
  373. claude_mpm/utils/dependency_strategies.py +8 -10
  374. claude_mpm/utils/environment_context.py +3 -9
  375. claude_mpm/utils/error_handler.py +3 -13
  376. claude_mpm/utils/file_utils.py +1 -1
  377. claude_mpm/utils/path_operations.py +8 -12
  378. claude_mpm/utils/robust_installer.py +110 -33
  379. claude_mpm/utils/subprocess_utils.py +5 -6
  380. claude_mpm/validation/agent_validator.py +3 -6
  381. claude_mpm/validation/frontmatter_validator.py +1 -1
  382. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/METADATA +1 -1
  383. claude_mpm-4.1.3.dist-info/RECORD +528 -0
  384. claude_mpm/cli/commands/run_config_checker.py +0 -160
  385. claude_mpm-4.1.1.dist-info/RECORD +0 -494
  386. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/WHEEL +0 -0
  387. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/entry_points.txt +0 -0
  388. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/licenses/LICENSE +0 -0
  389. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.3.dist-info}/top_level.txt +0 -0
@@ -8,78 +8,97 @@ WHY configuration module:
8
8
  """
9
9
 
10
10
  import os
11
- from typing import List, Optional
12
11
  from dataclasses import dataclass, field
12
+ from typing import List, Optional
13
13
 
14
14
 
15
15
  @dataclass
16
16
  class EventBusConfig:
17
17
  """Configuration for EventBus service.
18
-
18
+
19
19
  All settings can be overridden via environment variables.
20
20
  """
21
-
21
+
22
22
  # Enable/disable the EventBus
23
23
  enabled: bool = field(
24
- default_factory=lambda: os.environ.get("CLAUDE_MPM_EVENTBUS_ENABLED", "true").lower() == "true"
24
+ default_factory=lambda: os.environ.get(
25
+ "CLAUDE_MPM_EVENTBUS_ENABLED", "true"
26
+ ).lower()
27
+ == "true"
25
28
  )
26
-
29
+
27
30
  # Debug logging
28
31
  debug: bool = field(
29
- default_factory=lambda: os.environ.get("CLAUDE_MPM_EVENTBUS_DEBUG", "false").lower() == "true"
32
+ default_factory=lambda: os.environ.get(
33
+ "CLAUDE_MPM_EVENTBUS_DEBUG", "false"
34
+ ).lower()
35
+ == "true"
30
36
  )
31
-
37
+
32
38
  # Event history settings
33
39
  max_history_size: int = field(
34
- default_factory=lambda: int(os.environ.get("CLAUDE_MPM_EVENTBUS_HISTORY_SIZE", "100"))
40
+ default_factory=lambda: int(
41
+ os.environ.get("CLAUDE_MPM_EVENTBUS_HISTORY_SIZE", "100")
42
+ )
35
43
  )
36
-
44
+
37
45
  # Event filters (comma-separated list)
38
46
  event_filters: List[str] = field(
39
47
  default_factory=lambda: [
40
- f.strip() for f in os.environ.get("CLAUDE_MPM_EVENTBUS_FILTERS", "").split(",")
48
+ f.strip()
49
+ for f in os.environ.get("CLAUDE_MPM_EVENTBUS_FILTERS", "").split(",")
41
50
  if f.strip()
42
51
  ]
43
52
  )
44
-
53
+
45
54
  # Relay configuration
46
55
  relay_enabled: bool = field(
47
- default_factory=lambda: os.environ.get("CLAUDE_MPM_RELAY_ENABLED", "true").lower() == "true"
56
+ default_factory=lambda: os.environ.get(
57
+ "CLAUDE_MPM_RELAY_ENABLED", "true"
58
+ ).lower()
59
+ == "true"
48
60
  )
49
-
61
+
50
62
  relay_port: int = field(
51
63
  default_factory=lambda: int(os.environ.get("CLAUDE_MPM_SOCKETIO_PORT", "8765"))
52
64
  )
53
-
65
+
54
66
  relay_debug: bool = field(
55
- default_factory=lambda: os.environ.get("CLAUDE_MPM_RELAY_DEBUG", "false").lower() == "true"
67
+ default_factory=lambda: os.environ.get(
68
+ "CLAUDE_MPM_RELAY_DEBUG", "false"
69
+ ).lower()
70
+ == "true"
56
71
  )
57
-
72
+
58
73
  # Connection settings
59
74
  relay_max_retries: int = field(
60
75
  default_factory=lambda: int(os.environ.get("CLAUDE_MPM_RELAY_MAX_RETRIES", "3"))
61
76
  )
62
-
77
+
63
78
  relay_retry_delay: float = field(
64
- default_factory=lambda: float(os.environ.get("CLAUDE_MPM_RELAY_RETRY_DELAY", "0.5"))
79
+ default_factory=lambda: float(
80
+ os.environ.get("CLAUDE_MPM_RELAY_RETRY_DELAY", "0.5")
81
+ )
65
82
  )
66
-
83
+
67
84
  relay_connection_cooldown: float = field(
68
- default_factory=lambda: float(os.environ.get("CLAUDE_MPM_RELAY_CONNECTION_COOLDOWN", "5.0"))
85
+ default_factory=lambda: float(
86
+ os.environ.get("CLAUDE_MPM_RELAY_CONNECTION_COOLDOWN", "5.0")
87
+ )
69
88
  )
70
-
89
+
71
90
  @classmethod
72
91
  def from_env(cls) -> "EventBusConfig":
73
92
  """Create configuration from environment variables.
74
-
93
+
75
94
  Returns:
76
95
  EventBusConfig: Configuration instance
77
96
  """
78
97
  return cls()
79
-
98
+
80
99
  def to_dict(self) -> dict:
81
100
  """Convert configuration to dictionary.
82
-
101
+
83
102
  Returns:
84
103
  dict: Configuration as dictionary
85
104
  """
@@ -93,12 +112,12 @@ class EventBusConfig:
93
112
  "relay_debug": self.relay_debug,
94
113
  "relay_max_retries": self.relay_max_retries,
95
114
  "relay_retry_delay": self.relay_retry_delay,
96
- "relay_connection_cooldown": self.relay_connection_cooldown
115
+ "relay_connection_cooldown": self.relay_connection_cooldown,
97
116
  }
98
-
117
+
99
118
  def apply_to_eventbus(self, event_bus) -> None:
100
119
  """Apply configuration to an EventBus instance.
101
-
120
+
102
121
  Args:
103
122
  event_bus: EventBus instance to configure
104
123
  """
@@ -106,18 +125,18 @@ class EventBusConfig:
106
125
  event_bus.disable()
107
126
  else:
108
127
  event_bus.enable()
109
-
128
+
110
129
  event_bus.set_debug(self.debug)
111
130
  event_bus._max_history_size = self.max_history_size
112
-
131
+
113
132
  # Apply filters
114
133
  event_bus.clear_filters()
115
134
  for filter_pattern in self.event_filters:
116
135
  event_bus.add_filter(filter_pattern)
117
-
136
+
118
137
  def apply_to_relay(self, relay) -> None:
119
138
  """Apply configuration to a SocketIORelay instance.
120
-
139
+
121
140
  Args:
122
141
  relay: SocketIORelay instance to configure
123
142
  """
@@ -125,7 +144,7 @@ class EventBusConfig:
125
144
  relay.disable()
126
145
  else:
127
146
  relay.enable()
128
-
147
+
129
148
  relay.port = self.relay_port
130
149
  relay.debug = self.relay_debug
131
150
  relay.max_retries = self.relay_max_retries
@@ -139,7 +158,7 @@ _config: Optional[EventBusConfig] = None
139
158
 
140
159
  def get_config() -> EventBusConfig:
141
160
  """Get the global EventBus configuration.
142
-
161
+
143
162
  Returns:
144
163
  EventBusConfig: Configuration instance
145
164
  """
@@ -151,7 +170,7 @@ def get_config() -> EventBusConfig:
151
170
 
152
171
  def set_config(config: EventBusConfig) -> None:
153
172
  """Set the global EventBus configuration.
154
-
173
+
155
174
  Args:
156
175
  config: Configuration to set
157
176
  """
@@ -162,4 +181,4 @@ def set_config(config: EventBusConfig) -> None:
162
181
  def reset_config() -> None:
163
182
  """Reset configuration to defaults from environment."""
164
183
  global _config
165
- _config = EventBusConfig.from_env()
184
+ _config = EventBusConfig.from_env()
@@ -13,6 +13,7 @@ import logging
13
13
  import threading
14
14
  from datetime import datetime
15
15
  from typing import Any, Callable, Dict, List, Optional, Set
16
+
16
17
  from pyee.asyncio import AsyncIOEventEmitter
17
18
 
18
19
  # Configure logger
@@ -21,17 +22,17 @@ logger = logging.getLogger(__name__)
21
22
 
22
23
  class EventBus:
23
24
  """Singleton Event Bus for decoupled event handling.
24
-
25
+
25
26
  WHY singleton pattern:
26
27
  - Ensures single point of event coordination
27
28
  - Prevents duplicate event processing
28
29
  - Simplifies configuration and management
29
30
  - Thread-safe initialization with proper locking
30
31
  """
31
-
32
+
32
33
  _instance: Optional["EventBus"] = None
33
34
  _lock = threading.Lock()
34
-
35
+
35
36
  def __new__(cls) -> "EventBus":
36
37
  """Ensure singleton instance creation."""
37
38
  if cls._instance is None:
@@ -39,13 +40,13 @@ class EventBus:
39
40
  if cls._instance is None:
40
41
  cls._instance = super().__new__(cls)
41
42
  return cls._instance
42
-
43
+
43
44
  def __init__(self):
44
45
  """Initialize the event bus once."""
45
46
  # Only initialize once
46
47
  if hasattr(self, "_initialized"):
47
48
  return
48
-
49
+
49
50
  self._initialized = True
50
51
  self._emitter = AsyncIOEventEmitter()
51
52
  self._enabled = True
@@ -54,38 +55,38 @@ class EventBus:
54
55
  "events_published": 0,
55
56
  "events_filtered": 0,
56
57
  "events_failed": 0,
57
- "last_event_time": None
58
+ "last_event_time": None,
58
59
  }
59
60
  self._debug = False
60
-
61
+
61
62
  # Event history for debugging (limited size)
62
63
  self._event_history: List[Dict[str, Any]] = []
63
64
  self._max_history_size = 100
64
-
65
+
65
66
  logger.info("EventBus initialized")
66
-
67
+
67
68
  @classmethod
68
69
  def get_instance(cls) -> "EventBus":
69
70
  """Get the singleton EventBus instance.
70
-
71
+
71
72
  Returns:
72
73
  EventBus: The singleton instance
73
74
  """
74
75
  return cls()
75
-
76
+
76
77
  def enable(self) -> None:
77
78
  """Enable event bus processing."""
78
79
  self._enabled = True
79
80
  logger.info("EventBus enabled")
80
-
81
+
81
82
  def disable(self) -> None:
82
83
  """Disable event bus processing (for testing or maintenance)."""
83
84
  self._enabled = False
84
85
  logger.info("EventBus disabled")
85
-
86
+
86
87
  def set_debug(self, debug: bool) -> None:
87
88
  """Enable or disable debug logging.
88
-
89
+
89
90
  Args:
90
91
  debug: Whether to enable debug logging
91
92
  """
@@ -94,46 +95,46 @@ class EventBus:
94
95
  logger.setLevel(logging.DEBUG)
95
96
  else:
96
97
  logger.setLevel(logging.INFO)
97
-
98
+
98
99
  def add_filter(self, pattern: str) -> None:
99
100
  """Add an event filter pattern.
100
-
101
+
101
102
  Only events matching filter patterns will be processed.
102
103
  Use wildcards: 'hook.*' matches all hook events.
103
-
104
+
104
105
  Args:
105
106
  pattern: Event name pattern to allow
106
107
  """
107
108
  self._event_filters.add(pattern)
108
109
  logger.debug(f"Added event filter: {pattern}")
109
-
110
+
110
111
  def remove_filter(self, pattern: str) -> None:
111
112
  """Remove an event filter pattern.
112
-
113
+
113
114
  Args:
114
115
  pattern: Event name pattern to remove
115
116
  """
116
117
  self._event_filters.discard(pattern)
117
118
  logger.debug(f"Removed event filter: {pattern}")
118
-
119
+
119
120
  def clear_filters(self) -> None:
120
121
  """Clear all event filters (allow all events)."""
121
122
  self._event_filters.clear()
122
123
  logger.debug("Cleared all event filters")
123
-
124
+
124
125
  def _should_process_event(self, event_type: str) -> bool:
125
126
  """Check if an event should be processed based on filters.
126
-
127
+
127
128
  Args:
128
129
  event_type: The event type to check
129
-
130
+
130
131
  Returns:
131
132
  bool: True if event should be processed
132
133
  """
133
134
  # If no filters, process all events
134
135
  if not self._event_filters:
135
136
  return True
136
-
137
+
137
138
  # Check if event matches any filter
138
139
  for filter_pattern in self._event_filters:
139
140
  if filter_pattern.endswith("*"):
@@ -144,19 +145,19 @@ class EventBus:
144
145
  elif event_type == filter_pattern:
145
146
  # Exact match
146
147
  return True
147
-
148
+
148
149
  return False
149
-
150
+
150
151
  def publish(self, event_type: str, data: Any) -> bool:
151
152
  """Publish an event synchronously (for use from sync contexts like hooks).
152
-
153
+
153
154
  This method is thread-safe and can be called from any thread.
154
155
  Events are dispatched asynchronously to handlers.
155
-
156
+
156
157
  Args:
157
158
  event_type: The event type (e.g., 'hook.pre_tool')
158
159
  data: The event data
159
-
160
+
160
161
  Returns:
161
162
  bool: True if event was published, False if filtered or disabled
162
163
  """
@@ -164,23 +165,23 @@ class EventBus:
164
165
  if self._debug:
165
166
  logger.debug(f"EventBus disabled, dropping event: {event_type}")
166
167
  return False
167
-
168
+
168
169
  # Check filters
169
170
  if not self._should_process_event(event_type):
170
171
  self._stats["events_filtered"] += 1
171
172
  if self._debug:
172
173
  logger.debug(f"Event filtered out: {event_type}")
173
174
  return False
174
-
175
+
175
176
  try:
176
177
  # Record event in history
177
178
  self._record_event(event_type, data)
178
-
179
+
179
180
  # Emit event to regular handlers (pyee handles thread safety)
180
181
  self._emitter.emit(event_type, data)
181
-
182
+
182
183
  # Also emit to wildcard handlers
183
- if hasattr(self, '_wildcard_handlers'):
184
+ if hasattr(self, "_wildcard_handlers"):
184
185
  for prefix, handlers in self._wildcard_handlers.items():
185
186
  if event_type.startswith(prefix):
186
187
  for handler in handlers:
@@ -191,9 +192,13 @@ class EventBus:
191
192
  try:
192
193
  loop = asyncio.get_event_loop()
193
194
  if loop.is_running():
194
- asyncio.create_task(handler(event_type, data))
195
+ asyncio.create_task(
196
+ handler(event_type, data)
197
+ )
195
198
  else:
196
- loop.run_until_complete(handler(event_type, data))
199
+ loop.run_until_complete(
200
+ handler(event_type, data)
201
+ )
197
202
  except RuntimeError:
198
203
  # No event loop, skip async handler
199
204
  pass
@@ -202,83 +207,83 @@ class EventBus:
202
207
  except Exception as e:
203
208
  if self._debug:
204
209
  logger.debug(f"Wildcard handler error: {e}")
205
-
210
+
206
211
  # Update stats
207
212
  self._stats["events_published"] += 1
208
213
  self._stats["last_event_time"] = datetime.now().isoformat()
209
-
214
+
210
215
  if self._debug:
211
216
  logger.debug(f"Published event: {event_type}")
212
-
217
+
213
218
  return True
214
-
219
+
215
220
  except Exception as e:
216
221
  self._stats["events_failed"] += 1
217
222
  logger.error(f"Failed to publish event {event_type}: {e}")
218
223
  return False
219
-
224
+
220
225
  async def publish_async(self, event_type: str, data: Any) -> bool:
221
226
  """Publish an event from an async context.
222
-
227
+
223
228
  Args:
224
229
  event_type: The event type
225
230
  data: The event data
226
-
231
+
227
232
  Returns:
228
233
  bool: True if event was published
229
234
  """
230
235
  # Just delegate to sync publish (pyee handles both)
231
236
  return self.publish(event_type, data)
232
-
237
+
233
238
  def on(self, event_type: str, handler: Callable) -> None:
234
239
  """Register an event handler.
235
-
240
+
236
241
  The handler can be sync or async. For async handlers,
237
242
  they will be scheduled on the event loop.
238
-
243
+
239
244
  Args:
240
245
  event_type: The event type to listen for (supports wildcards)
241
246
  handler: The handler function
242
247
  """
243
248
  if event_type.endswith("*"):
244
249
  # Store wildcard handlers separately
245
- if not hasattr(self, '_wildcard_handlers'):
250
+ if not hasattr(self, "_wildcard_handlers"):
246
251
  self._wildcard_handlers = {}
247
-
252
+
248
253
  prefix = event_type[:-1]
249
254
  if prefix not in self._wildcard_handlers:
250
255
  self._wildcard_handlers[prefix] = []
251
256
  self._wildcard_handlers[prefix].append(handler)
252
-
257
+
253
258
  logger.debug(f"Registered wildcard handler for: {event_type}")
254
259
  else:
255
260
  # Regular event registration
256
261
  self._emitter.on(event_type, handler)
257
262
  logger.debug(f"Registered handler for: {event_type}")
258
-
263
+
259
264
  def once(self, event_type: str, handler: Callable) -> None:
260
265
  """Register a one-time event handler.
261
-
266
+
262
267
  Args:
263
268
  event_type: The event type to listen for
264
269
  handler: The handler function
265
270
  """
266
271
  self._emitter.once(event_type, handler)
267
272
  logger.debug(f"Registered one-time handler for: {event_type}")
268
-
273
+
269
274
  def remove_listener(self, event_type: str, handler: Callable) -> None:
270
275
  """Remove an event handler.
271
-
276
+
272
277
  Args:
273
278
  event_type: The event type
274
279
  handler: The handler to remove
275
280
  """
276
281
  self._emitter.remove_listener(event_type, handler)
277
282
  logger.debug(f"Removed handler for: {event_type}")
278
-
283
+
279
284
  def remove_all_listeners(self, event_type: Optional[str] = None) -> None:
280
285
  """Remove all listeners for an event type, or all listeners.
281
-
286
+
282
287
  Args:
283
288
  event_type: Optional event type. If None, removes all listeners.
284
289
  """
@@ -288,10 +293,10 @@ class EventBus:
288
293
  else:
289
294
  self._emitter.remove_all_listeners()
290
295
  logger.debug("Removed all event handlers")
291
-
296
+
292
297
  def _record_event(self, event_type: str, data: Any) -> None:
293
298
  """Record event in history for debugging.
294
-
299
+
295
300
  Args:
296
301
  event_type: The event type
297
302
  data: The event data
@@ -299,18 +304,18 @@ class EventBus:
299
304
  event_record = {
300
305
  "timestamp": datetime.now().isoformat(),
301
306
  "type": event_type,
302
- "data": data
307
+ "data": data,
303
308
  }
304
-
309
+
305
310
  self._event_history.append(event_record)
306
-
311
+
307
312
  # Trim history if too large
308
313
  if len(self._event_history) > self._max_history_size:
309
- self._event_history = self._event_history[-self._max_history_size:]
310
-
314
+ self._event_history = self._event_history[-self._max_history_size :]
315
+
311
316
  def get_stats(self) -> Dict[str, Any]:
312
317
  """Get event bus statistics.
313
-
318
+
314
319
  Returns:
315
320
  dict: Statistics about event processing
316
321
  """
@@ -319,31 +324,31 @@ class EventBus:
319
324
  "enabled": self._enabled,
320
325
  "filters_active": len(self._event_filters) > 0,
321
326
  "filter_count": len(self._event_filters),
322
- "history_size": len(self._event_history)
327
+ "history_size": len(self._event_history),
323
328
  }
324
-
329
+
325
330
  def get_recent_events(self, limit: int = 10) -> List[Dict[str, Any]]:
326
331
  """Get recent events from history.
327
-
332
+
328
333
  Args:
329
334
  limit: Maximum number of events to return
330
-
335
+
331
336
  Returns:
332
337
  list: Recent events
333
338
  """
334
339
  return self._event_history[-limit:]
335
-
340
+
336
341
  def clear_history(self) -> None:
337
342
  """Clear the event history."""
338
343
  self._event_history.clear()
339
344
  logger.debug("Cleared event history")
340
-
345
+
341
346
  def reset_stats(self) -> None:
342
347
  """Reset event statistics."""
343
348
  self._stats = {
344
349
  "events_published": 0,
345
350
  "events_filtered": 0,
346
351
  "events_failed": 0,
347
- "last_event_time": None
352
+ "last_event_time": None,
348
353
  }
349
- logger.debug("Reset event statistics")
354
+ logger.debug("Reset event statistics")