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
@@ -24,6 +24,7 @@ import time
24
24
  from collections import deque
25
25
  from datetime import datetime
26
26
  from pathlib import Path
27
+ from typing import Optional
27
28
 
28
29
  # Add parent path for imports
29
30
  sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
@@ -31,6 +32,7 @@ sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
31
32
  # Import EventBus
32
33
  try:
33
34
  from claude_mpm.services.event_bus import EventBus
35
+
34
36
  EVENTBUS_AVAILABLE = True
35
37
  except ImportError:
36
38
  EVENTBUS_AVAILABLE = False
@@ -44,16 +46,23 @@ except ImportError:
44
46
  class EventNormalizer:
45
47
  def normalize(self, event_data, source="hook"):
46
48
  """Simple fallback normalizer that returns event as-is."""
47
- return type('NormalizedEvent', (), {
48
- 'to_dict': lambda: {
49
- 'event': 'claude_event',
50
- 'type': event_data.get('type', 'unknown'),
51
- 'subtype': event_data.get('subtype', 'generic'),
52
- 'timestamp': event_data.get('timestamp', datetime.now().isoformat()),
53
- 'data': event_data.get('data', event_data),
54
- 'source': source
55
- }
56
- })
49
+ return type(
50
+ "NormalizedEvent",
51
+ (),
52
+ {
53
+ "to_dict": lambda: {
54
+ "event": "claude_event",
55
+ "type": event_data.get("type", "unknown"),
56
+ "subtype": event_data.get("subtype", "generic"),
57
+ "timestamp": event_data.get(
58
+ "timestamp", datetime.now().isoformat()
59
+ ),
60
+ "data": event_data.get("data", event_data),
61
+ "source": source,
62
+ }
63
+ },
64
+ )
65
+
57
66
 
58
67
  # Import constants for configuration
59
68
  try:
@@ -63,16 +72,17 @@ except ImportError:
63
72
  class TimeoutConfig:
64
73
  QUICK_TIMEOUT = 2.0
65
74
 
75
+
66
76
  # Import other handler modules
67
77
  try:
78
+ from .event_handlers import EventHandlers
68
79
  from .memory_integration import MemoryHookManager
69
80
  from .response_tracking import ResponseTrackingManager
70
- from .event_handlers import EventHandlers
71
81
  except ImportError:
72
82
  # Fallback for direct execution
83
+ from event_handlers import EventHandlers
73
84
  from memory_integration import MemoryHookManager
74
85
  from response_tracking import ResponseTrackingManager
75
- from event_handlers import EventHandlers
76
86
 
77
87
  # Debug mode is enabled by default for better visibility into hook processing
78
88
  DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "true").lower() != "false"
@@ -88,74 +98,77 @@ _events_lock = threading.Lock()
88
98
 
89
99
  class HookHandler:
90
100
  """Main hook handler class using EventBus for event emission.
91
-
101
+
92
102
  WHY EventBus integration:
93
103
  - Replaces direct Socket.IO connections with EventBus publishing
94
104
  - Events are published once and consumed by multiple listeners
95
105
  - Failures in one consumer don't affect others
96
106
  - Simplified testing without Socket.IO dependencies
97
107
  """
98
-
108
+
99
109
  # Tracking dictionaries with size limits
100
110
  MAX_DELEGATION_TRACKING = 100
101
111
  MAX_PROMPT_TRACKING = 50
102
112
  MAX_CACHE_AGE_SECONDS = 1800 # 30 minutes
103
-
113
+
104
114
  def __init__(self):
105
115
  """Initialize the hook handler with EventBus."""
106
116
  # Initialize EventBus if available
107
117
  self.event_bus = EventBus.get_instance() if EVENTBUS_AVAILABLE else None
108
118
  self.event_normalizer = EventNormalizer()
109
-
119
+
110
120
  # Initialize tracking managers
111
121
  self.memory_manager = MemoryHookManager()
112
122
  self.response_tracker = ResponseTrackingManager()
113
123
  self.event_handlers = EventHandlers(self)
114
-
124
+
115
125
  # Delegation tracking
116
126
  self.active_delegations = {}
117
127
  self.delegation_requests = {}
118
128
  self.delegation_history = deque(maxlen=20)
119
-
129
+
120
130
  # Prompt tracking
121
131
  self.pending_prompts = {}
122
-
132
+
123
133
  # Git branch caching
124
134
  self._git_branch_cache = {}
125
135
  self._git_branch_cache_time = {}
126
-
136
+
127
137
  # Session tracking
128
138
  self.current_session_id = None
129
-
139
+
130
140
  # Cleanup old entries periodically
131
141
  self._last_cleanup = time.time()
132
-
142
+
133
143
  if self.event_bus:
134
144
  logger_msg = "HookHandler initialized with EventBus"
135
145
  else:
136
146
  logger_msg = "HookHandler initialized (EventBus not available)"
137
-
147
+
138
148
  if DEBUG:
139
149
  print(f"šŸš€ {logger_msg}", file=sys.stderr)
140
-
150
+
141
151
  def _emit_event(self, event_type: str, data: dict):
142
152
  """Emit an event through the EventBus.
143
-
153
+
144
154
  WHY this approach:
145
155
  - Single point of event emission
146
156
  - Consistent event normalization
147
157
  - Graceful fallback if EventBus unavailable
148
158
  - Easy to add metrics and monitoring
149
-
159
+
150
160
  Args:
151
161
  event_type: The event type (e.g., 'pre_tool', 'subagent_stop')
152
162
  data: The event data
153
163
  """
154
164
  if not self.event_bus:
155
165
  if DEBUG:
156
- print(f"EventBus not available, cannot emit: hook.{event_type}", file=sys.stderr)
166
+ print(
167
+ f"EventBus not available, cannot emit: hook.{event_type}",
168
+ file=sys.stderr,
169
+ )
157
170
  return
158
-
171
+
159
172
  try:
160
173
  # Create event data for normalization
161
174
  raw_event = {
@@ -164,86 +177,99 @@ class HookHandler:
164
177
  "timestamp": datetime.now().isoformat(),
165
178
  "data": data,
166
179
  "source": "claude_hooks",
167
- "session_id": data.get("sessionId", self.current_session_id)
180
+ "session_id": data.get("sessionId", self.current_session_id),
168
181
  }
169
-
182
+
170
183
  # Normalize the event
171
184
  normalized_event = self.event_normalizer.normalize(raw_event, source="hook")
172
185
  event_data = normalized_event.to_dict()
173
-
186
+
174
187
  # Publish to EventBus
175
188
  success = self.event_bus.publish(f"hook.{event_type}", event_data)
176
-
189
+
177
190
  if DEBUG:
178
191
  if success:
179
- print(f"āœ… Published to EventBus: hook.{event_type}", file=sys.stderr)
192
+ print(
193
+ f"āœ… Published to EventBus: hook.{event_type}", file=sys.stderr
194
+ )
180
195
  else:
181
- print(f"āš ļø EventBus rejected event: hook.{event_type}", file=sys.stderr)
182
-
196
+ print(
197
+ f"āš ļø EventBus rejected event: hook.{event_type}", file=sys.stderr
198
+ )
199
+
183
200
  # Log important events
184
201
  if DEBUG and event_type in ["subagent_stop", "pre_tool"]:
185
202
  if event_type == "subagent_stop":
186
203
  agent_type = data.get("agent_type", "unknown")
187
- print(f"šŸ“¤ Published SubagentStop for agent '{agent_type}'", file=sys.stderr)
204
+ print(
205
+ f"šŸ“¤ Published SubagentStop for agent '{agent_type}'",
206
+ file=sys.stderr,
207
+ )
188
208
  elif event_type == "pre_tool" and data.get("tool_name") == "Task":
189
209
  delegation = data.get("delegation_details", {})
190
210
  agent_type = delegation.get("agent_type", "unknown")
191
- print(f"šŸ“¤ Published Task delegation to agent '{agent_type}'", file=sys.stderr)
192
-
211
+ print(
212
+ f"šŸ“¤ Published Task delegation to agent '{agent_type}'",
213
+ file=sys.stderr,
214
+ )
215
+
193
216
  except Exception as e:
194
217
  if DEBUG:
195
- print(f"āŒ Failed to publish event hook.{event_type}: {e}", file=sys.stderr)
196
-
197
- def _get_git_branch(self, working_dir: str = None) -> str:
218
+ print(
219
+ f"āŒ Failed to publish event hook.{event_type}: {e}",
220
+ file=sys.stderr,
221
+ )
222
+
223
+ def _get_git_branch(self, working_dir: Optional[str] = None) -> str:
198
224
  """Get git branch for the given directory with caching."""
199
225
  # Use current working directory if not specified
200
226
  if not working_dir:
201
227
  working_dir = os.getcwd()
202
-
228
+
203
229
  # Check cache first (cache for 30 seconds)
204
230
  current_time = time.time()
205
231
  cache_key = working_dir
206
-
232
+
207
233
  if (
208
234
  cache_key in self._git_branch_cache
209
235
  and cache_key in self._git_branch_cache_time
210
236
  and current_time - self._git_branch_cache_time[cache_key] < 30
211
237
  ):
212
238
  return self._git_branch_cache[cache_key]
213
-
239
+
214
240
  # Try to get git branch
215
241
  try:
216
242
  # Change to the working directory temporarily
217
243
  original_cwd = os.getcwd()
218
244
  os.chdir(working_dir)
219
-
245
+
220
246
  # Run git command to get current branch
221
247
  result = subprocess.run(
222
248
  ["git", "branch", "--show-current"],
223
249
  capture_output=True,
224
250
  text=True,
225
- timeout=TimeoutConfig.QUICK_TIMEOUT
251
+ timeout=TimeoutConfig.QUICK_TIMEOUT,
252
+ check=False,
226
253
  )
227
-
254
+
228
255
  # Restore original directory
229
256
  os.chdir(original_cwd)
230
-
257
+
231
258
  if result.returncode == 0 and result.stdout.strip():
232
259
  branch = result.stdout.strip()
233
260
  # Cache the result
234
261
  self._git_branch_cache[cache_key] = branch
235
262
  self._git_branch_cache_time[cache_key] = current_time
236
263
  return branch
237
- else:
238
- return "unknown"
239
-
264
+ return "unknown"
265
+
240
266
  except Exception:
241
267
  return "unknown"
242
-
268
+
243
269
  def _cleanup_old_entries(self):
244
270
  """Clean up old entries to prevent memory growth."""
245
- cutoff_time = time.time() - self.MAX_CACHE_AGE_SECONDS
246
-
271
+ time.time() - self.MAX_CACHE_AGE_SECONDS
272
+
247
273
  # Clean up delegation tracking dictionaries
248
274
  for storage in [self.active_delegations, self.delegation_requests]:
249
275
  if len(storage) > self.MAX_DELEGATION_TRACKING:
@@ -252,14 +278,14 @@ class HookHandler:
252
278
  excess = len(storage) - self.MAX_DELEGATION_TRACKING
253
279
  for key in sorted_keys[:excess]:
254
280
  del storage[key]
255
-
281
+
256
282
  # Clean up pending prompts
257
283
  if len(self.pending_prompts) > self.MAX_PROMPT_TRACKING:
258
284
  sorted_keys = sorted(self.pending_prompts.keys())
259
285
  excess = len(self.pending_prompts) - self.MAX_PROMPT_TRACKING
260
286
  for key in sorted_keys[:excess]:
261
287
  del self.pending_prompts[key]
262
-
288
+
263
289
  # Clean up git branch cache
264
290
  expired_keys = [
265
291
  key
@@ -269,10 +295,10 @@ class HookHandler:
269
295
  for key in expired_keys:
270
296
  self._git_branch_cache.pop(key, None)
271
297
  self._git_branch_cache_time.pop(key, None)
272
-
298
+
273
299
  def handle_event(self, event: dict):
274
300
  """Process an event from Claude Code.
275
-
301
+
276
302
  Args:
277
303
  event: The event dictionary from Claude
278
304
  """
@@ -281,24 +307,26 @@ class HookHandler:
281
307
  if current_time - self._last_cleanup > 300: # Every 5 minutes
282
308
  self._cleanup_old_entries()
283
309
  self._last_cleanup = current_time
284
-
310
+
285
311
  # Extract event details
286
312
  event_type = event.get("type", "")
287
313
  event_name = event.get("name", "")
288
-
314
+
289
315
  # Update session ID if present
290
316
  if "sessionId" in event:
291
317
  self.current_session_id = event["sessionId"]
292
-
318
+
293
319
  # Detect duplicate events
294
- event_signature = f"{event_type}:{event_name}:{json.dumps(event.get('data', ''))[:100]}"
320
+ event_signature = (
321
+ f"{event_type}:{event_name}:{json.dumps(event.get('data', ''))[:100]}"
322
+ )
295
323
  with _events_lock:
296
324
  if event_signature in _recent_events:
297
325
  if DEBUG:
298
326
  print(f"Skipping duplicate event: {event_type}", file=sys.stderr)
299
327
  return
300
328
  _recent_events.append(event_signature)
301
-
329
+
302
330
  # Route to appropriate handler
303
331
  if event_type == "Start":
304
332
  self.event_handlers.handle_start(event)
@@ -321,15 +349,14 @@ class HookHandler:
321
349
  elif event_type == "PromptCachingBetaStats":
322
350
  # Ignore caching stats events
323
351
  pass
324
- else:
325
- # Log unhandled events in debug mode
326
- if DEBUG:
327
- print(f"Unhandled event type: {event_type}", file=sys.stderr)
352
+ # Log unhandled events in debug mode
353
+ elif DEBUG:
354
+ print(f"Unhandled event type: {event_type}", file=sys.stderr)
328
355
 
329
356
 
330
357
  def get_handler() -> HookHandler:
331
358
  """Get or create the global hook handler instance.
332
-
359
+
333
360
  Returns:
334
361
  HookHandler: The singleton handler instance
335
362
  """
@@ -345,18 +372,18 @@ def main():
345
372
  """Main entry point for the hook handler."""
346
373
  if DEBUG:
347
374
  print("šŸŽÆ EventBus Hook Handler starting...", file=sys.stderr)
348
-
375
+
349
376
  handler = get_handler()
350
-
377
+
351
378
  # Set up signal handling for clean shutdown
352
379
  def signal_handler(signum, frame):
353
380
  if DEBUG:
354
381
  print("\nšŸ‘‹ Hook handler shutting down...", file=sys.stderr)
355
382
  sys.exit(0)
356
-
383
+
357
384
  signal.signal(signal.SIGINT, signal_handler)
358
385
  signal.signal(signal.SIGTERM, signal_handler)
359
-
386
+
360
387
  # Process events from stdin
361
388
  try:
362
389
  while True:
@@ -366,15 +393,15 @@ def main():
366
393
  line = sys.stdin.readline()
367
394
  if not line:
368
395
  break
369
-
396
+
370
397
  try:
371
398
  event = json.loads(line.strip())
372
399
  handler.handle_event(event)
373
-
400
+
374
401
  # Acknowledge event
375
402
  print(json.dumps({"status": "ok"}))
376
403
  sys.stdout.flush()
377
-
404
+
378
405
  except json.JSONDecodeError as e:
379
406
  if DEBUG:
380
407
  print(f"Invalid JSON: {e}", file=sys.stderr)
@@ -385,7 +412,7 @@ def main():
385
412
  print(f"Error processing event: {e}", file=sys.stderr)
386
413
  print(json.dumps({"status": "error", "message": str(e)}))
387
414
  sys.stdout.flush()
388
-
415
+
389
416
  except KeyboardInterrupt:
390
417
  if DEBUG:
391
418
  print("\nšŸ‘‹ Hook handler interrupted", file=sys.stderr)
@@ -395,4 +422,4 @@ def main():
395
422
 
396
423
 
397
424
  if __name__ == "__main__":
398
- main()
425
+ main()