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
@@ -6,7 +6,6 @@ Handles events that failed processing in other consumers.
6
6
  """
7
7
 
8
8
  import json
9
- import os
10
9
  from datetime import datetime
11
10
  from pathlib import Path
12
11
  from typing import Any, Dict, List, Optional
@@ -20,24 +19,24 @@ from ..interfaces import ConsumerConfig, ConsumerPriority, IEventConsumer
20
19
  class DeadLetterConsumer(IEventConsumer):
21
20
  """
22
21
  Handles failed events by persisting them for later analysis.
23
-
22
+
24
23
  Features:
25
24
  - Persist failed events to disk
26
25
  - Configurable retention policy
27
26
  - Event replay capability
28
27
  - Failed event analysis
29
28
  """
30
-
29
+
31
30
  def __init__(
32
31
  self,
33
32
  output_dir: Optional[Path] = None,
34
33
  max_file_size: int = 10 * 1024 * 1024, # 10MB
35
34
  retention_days: int = 7,
36
- topics: List[str] = None,
35
+ topics: Optional[List[str]] = None,
37
36
  ):
38
37
  """
39
38
  Initialize dead letter consumer.
40
-
39
+
41
40
  Args:
42
41
  output_dir: Directory to store failed events
43
42
  max_file_size: Maximum size per file (bytes)
@@ -45,17 +44,17 @@ class DeadLetterConsumer(IEventConsumer):
45
44
  topics: Topics to handle (None = all failed events)
46
45
  """
47
46
  self.logger = get_logger("DeadLetterConsumer")
48
-
47
+
49
48
  # Configuration
50
49
  self.output_dir = output_dir or Path.home() / ".claude-mpm" / "dead-letter"
51
50
  self.max_file_size = max_file_size
52
51
  self.retention_days = retention_days
53
-
52
+
54
53
  # State
55
54
  self._initialized = False
56
55
  self._current_file: Optional[Path] = None
57
56
  self._current_file_size = 0
58
-
57
+
59
58
  # Metrics
60
59
  self._metrics = {
61
60
  "events_stored": 0,
@@ -63,7 +62,7 @@ class DeadLetterConsumer(IEventConsumer):
63
62
  "files_created": 0,
64
63
  "total_size_bytes": 0,
65
64
  }
66
-
65
+
67
66
  # Consumer configuration
68
67
  self._config = ConsumerConfig(
69
68
  name="DeadLetterConsumer",
@@ -71,62 +70,64 @@ class DeadLetterConsumer(IEventConsumer):
71
70
  priority=ConsumerPriority.CRITICAL, # Process failed events first
72
71
  filter_func=self._should_store,
73
72
  )
74
-
73
+
75
74
  async def initialize(self) -> bool:
76
75
  """Initialize the dead letter consumer."""
77
76
  try:
78
77
  # Create output directory
79
78
  self.output_dir.mkdir(parents=True, exist_ok=True)
80
-
79
+
81
80
  # Clean old files
82
81
  await self._cleanup_old_files()
83
-
82
+
84
83
  # Initialize current file
85
84
  self._rotate_file()
86
-
85
+
87
86
  self._initialized = True
88
- self.logger.info(f"Dead letter consumer initialized (output: {self.output_dir})")
87
+ self.logger.info(
88
+ f"Dead letter consumer initialized (output: {self.output_dir})"
89
+ )
89
90
  return True
90
-
91
+
91
92
  except Exception as e:
92
93
  self.logger.error(f"Failed to initialize dead letter consumer: {e}")
93
94
  return False
94
-
95
+
95
96
  async def consume(self, event: Event) -> bool:
96
97
  """Store a failed event."""
97
98
  if not self._initialized:
98
99
  return False
99
-
100
+
100
101
  try:
101
102
  # Serialize event
102
103
  event_data = self._serialize_event(event)
103
104
  event_json = json.dumps(event_data) + "\n"
104
105
  event_bytes = event_json.encode("utf-8")
105
-
106
+
106
107
  # Check if rotation needed
107
108
  if self._current_file_size + len(event_bytes) > self.max_file_size:
108
109
  self._rotate_file()
109
-
110
+
110
111
  # Write to file
111
112
  with open(self._current_file, "a") as f:
112
113
  f.write(event_json)
113
-
114
+
114
115
  # Update metrics
115
116
  self._current_file_size += len(event_bytes)
116
117
  self._metrics["events_stored"] += 1
117
118
  self._metrics["total_size_bytes"] += len(event_bytes)
118
-
119
+
119
120
  self.logger.debug(
120
121
  f"Stored failed event: {event.topic}/{event.type} "
121
122
  f"(reason: {event.metadata.error_messages if event.metadata else 'unknown'})"
122
123
  )
123
-
124
+
124
125
  return True
125
-
126
+
126
127
  except Exception as e:
127
128
  self.logger.error(f"Error storing failed event: {e}")
128
129
  return False
129
-
130
+
130
131
  async def consume_batch(self, events: List[Event]) -> int:
131
132
  """Store multiple failed events."""
132
133
  successful = 0
@@ -134,14 +135,14 @@ class DeadLetterConsumer(IEventConsumer):
134
135
  if await self.consume(event):
135
136
  successful += 1
136
137
  return successful
137
-
138
+
138
139
  async def shutdown(self) -> None:
139
140
  """Shutdown the consumer."""
140
141
  self.logger.info(
141
142
  f"Dead letter consumer shutdown - stored {self._metrics['events_stored']} events"
142
143
  )
143
144
  self._initialized = False
144
-
145
+
145
146
  async def replay_events(
146
147
  self,
147
148
  start_time: Optional[datetime] = None,
@@ -150,56 +151,58 @@ class DeadLetterConsumer(IEventConsumer):
150
151
  ) -> List[Event]:
151
152
  """
152
153
  Replay stored events for reprocessing.
153
-
154
+
154
155
  Args:
155
156
  start_time: Start of time range
156
157
  end_time: End of time range
157
158
  topic_filter: Topic pattern to filter
158
-
159
+
159
160
  Returns:
160
161
  List of events matching criteria
161
162
  """
162
163
  replayed_events = []
163
-
164
+
164
165
  # Find files in time range
165
166
  for file_path in sorted(self.output_dir.glob("dead-letter-*.jsonl")):
166
167
  try:
167
- with open(file_path, "r") as f:
168
+ with open(file_path) as f:
168
169
  for line in f:
169
170
  event_data = json.loads(line)
170
-
171
+
171
172
  # Apply filters
172
173
  event_time = datetime.fromisoformat(event_data["timestamp"])
173
-
174
+
174
175
  if start_time and event_time < start_time:
175
176
  continue
176
177
  if end_time and event_time > end_time:
177
178
  continue
178
- if topic_filter and not event_data["topic"].startswith(topic_filter):
179
+ if topic_filter and not event_data["topic"].startswith(
180
+ topic_filter
181
+ ):
179
182
  continue
180
-
183
+
181
184
  # Reconstruct event
182
185
  event = self._deserialize_event(event_data)
183
186
  replayed_events.append(event)
184
-
187
+
185
188
  except Exception as e:
186
189
  self.logger.error(f"Error replaying events from {file_path}: {e}")
187
-
190
+
188
191
  self._metrics["events_replayed"] += len(replayed_events)
189
192
  self.logger.info(f"Replayed {len(replayed_events)} events")
190
-
193
+
191
194
  return replayed_events
192
-
195
+
193
196
  @property
194
197
  def config(self) -> ConsumerConfig:
195
198
  """Get consumer configuration."""
196
199
  return self._config
197
-
200
+
198
201
  @property
199
202
  def is_healthy(self) -> bool:
200
203
  """Check if consumer is healthy."""
201
204
  return self._initialized and self._current_file is not None
202
-
205
+
203
206
  def get_metrics(self) -> Dict[str, Any]:
204
207
  """Get consumer metrics."""
205
208
  return {
@@ -207,30 +210,27 @@ class DeadLetterConsumer(IEventConsumer):
207
210
  "current_file": str(self._current_file) if self._current_file else None,
208
211
  "current_file_size": self._current_file_size,
209
212
  }
210
-
213
+
211
214
  def _should_store(self, event: Event) -> bool:
212
215
  """
213
216
  Determine if an event should be stored.
214
-
217
+
215
218
  Only store events that have actually failed processing.
216
219
  """
217
220
  if not event.metadata:
218
221
  return False
219
-
222
+
220
223
  # Store if any consumers failed
221
224
  if event.metadata.consumers_failed:
222
225
  return True
223
-
226
+
224
227
  # Store if max retries exceeded
225
228
  if event.metadata.retry_count >= event.metadata.max_retries:
226
229
  return True
227
-
230
+
228
231
  # Store if event has error messages
229
- if event.metadata.error_messages:
230
- return True
231
-
232
- return False
233
-
232
+ return bool(event.metadata.error_messages)
233
+
234
234
  def _serialize_event(self, event: Event) -> Dict[str, Any]:
235
235
  """Serialize an event for storage."""
236
236
  return {
@@ -242,17 +242,25 @@ class DeadLetterConsumer(IEventConsumer):
242
242
  "data": event.data,
243
243
  "correlation_id": event.correlation_id,
244
244
  "priority": event.priority.name,
245
- "metadata": {
246
- "retry_count": event.metadata.retry_count if event.metadata else 0,
247
- "consumers_failed": list(event.metadata.consumers_failed) if event.metadata else [],
248
- "error_messages": event.metadata.error_messages if event.metadata else [],
249
- } if event.metadata else None,
245
+ "metadata": (
246
+ {
247
+ "retry_count": event.metadata.retry_count if event.metadata else 0,
248
+ "consumers_failed": (
249
+ list(event.metadata.consumers_failed) if event.metadata else []
250
+ ),
251
+ "error_messages": (
252
+ event.metadata.error_messages if event.metadata else []
253
+ ),
254
+ }
255
+ if event.metadata
256
+ else None
257
+ ),
250
258
  }
251
-
259
+
252
260
  def _deserialize_event(self, data: Dict[str, Any]) -> Event:
253
261
  """Deserialize an event from storage."""
254
262
  from ..core import EventMetadata, EventPriority
255
-
263
+
256
264
  # Reconstruct metadata
257
265
  metadata = None
258
266
  if data.get("metadata"):
@@ -261,7 +269,7 @@ class DeadLetterConsumer(IEventConsumer):
261
269
  consumers_failed=set(data["metadata"].get("consumers_failed", [])),
262
270
  error_messages=data["metadata"].get("error_messages", []),
263
271
  )
264
-
272
+
265
273
  return Event(
266
274
  id=data["id"],
267
275
  topic=data["topic"],
@@ -273,24 +281,24 @@ class DeadLetterConsumer(IEventConsumer):
273
281
  correlation_id=data.get("correlation_id"),
274
282
  priority=EventPriority[data.get("priority", "NORMAL")],
275
283
  )
276
-
284
+
277
285
  def _rotate_file(self) -> None:
278
286
  """Rotate to a new output file."""
279
287
  timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
280
288
  self._current_file = self.output_dir / f"dead-letter-{timestamp}.jsonl"
281
289
  self._current_file_size = 0
282
290
  self._metrics["files_created"] += 1
283
-
291
+
284
292
  self.logger.debug(f"Rotated to new file: {self._current_file}")
285
-
293
+
286
294
  async def _cleanup_old_files(self) -> None:
287
295
  """Remove files older than retention period."""
288
296
  cutoff_time = datetime.now().timestamp() - (self.retention_days * 86400)
289
-
297
+
290
298
  for file_path in self.output_dir.glob("dead-letter-*.jsonl"):
291
299
  try:
292
300
  if file_path.stat().st_mtime < cutoff_time:
293
301
  file_path.unlink()
294
302
  self.logger.info(f"Removed old dead letter file: {file_path}")
295
303
  except Exception as e:
296
- self.logger.error(f"Error removing old file {file_path}: {e}")
304
+ self.logger.error(f"Error removing old file {file_path}: {e}")
@@ -6,7 +6,7 @@ Logs events for debugging and monitoring purposes.
6
6
  """
7
7
 
8
8
  import json
9
- from typing import Any, Dict, List
9
+ from typing import Any, Dict, List, Optional
10
10
 
11
11
  from claude_mpm.core.logging_config import get_logger
12
12
 
@@ -17,25 +17,25 @@ from ..interfaces import ConsumerConfig, ConsumerPriority, IEventConsumer
17
17
  class LoggingConsumer(IEventConsumer):
18
18
  """
19
19
  Logs events for debugging and monitoring.
20
-
20
+
21
21
  Features:
22
22
  - Configurable log levels per topic
23
23
  - Structured logging with JSON support
24
24
  - Event filtering
25
25
  - Performance metrics
26
26
  """
27
-
27
+
28
28
  def __init__(
29
29
  self,
30
30
  log_level: str = "INFO",
31
- topics: List[str] = None,
31
+ topics: Optional[List[str]] = None,
32
32
  format_json: bool = True,
33
33
  include_data: bool = True,
34
34
  max_data_length: int = 1000,
35
35
  ):
36
36
  """
37
37
  Initialize logging consumer.
38
-
38
+
39
39
  Args:
40
40
  log_level: Default log level (DEBUG, INFO, WARNING, ERROR)
41
41
  topics: Topics to log (None = all)
@@ -44,30 +44,30 @@ class LoggingConsumer(IEventConsumer):
44
44
  max_data_length: Maximum data length to log
45
45
  """
46
46
  self.logger = get_logger("EventLogger")
47
-
47
+
48
48
  # Configuration
49
49
  self.log_level = log_level
50
50
  self.format_json = format_json
51
51
  self.include_data = include_data
52
52
  self.max_data_length = max_data_length
53
-
53
+
54
54
  # State
55
55
  self._initialized = False
56
-
56
+
57
57
  # Metrics
58
58
  self._metrics = {
59
59
  "events_logged": 0,
60
60
  "events_filtered": 0,
61
61
  "errors": 0,
62
62
  }
63
-
63
+
64
64
  # Consumer configuration
65
65
  self._config = ConsumerConfig(
66
66
  name="LoggingConsumer",
67
67
  topics=topics or ["**"],
68
68
  priority=ConsumerPriority.LOW, # Log after other processing
69
69
  )
70
-
70
+
71
71
  async def initialize(self) -> bool:
72
72
  """Initialize the logging consumer."""
73
73
  self._initialized = True
@@ -76,30 +76,30 @@ class LoggingConsumer(IEventConsumer):
76
76
  f"topics={self._config.topics})"
77
77
  )
78
78
  return True
79
-
79
+
80
80
  async def consume(self, event: Event) -> bool:
81
81
  """Log a single event."""
82
82
  if not self._initialized:
83
83
  return False
84
-
84
+
85
85
  try:
86
86
  # Format log message
87
87
  message = self._format_event(event)
88
-
88
+
89
89
  # Determine log level
90
90
  level = self._get_log_level(event)
91
-
91
+
92
92
  # Log the event
93
93
  getattr(self.logger, level.lower())(message)
94
-
94
+
95
95
  self._metrics["events_logged"] += 1
96
96
  return True
97
-
97
+
98
98
  except Exception as e:
99
99
  self.logger.error(f"Error logging event: {e}")
100
100
  self._metrics["errors"] += 1
101
101
  return False
102
-
102
+
103
103
  async def consume_batch(self, events: List[Event]) -> int:
104
104
  """Log multiple events."""
105
105
  successful = 0
@@ -107,26 +107,28 @@ class LoggingConsumer(IEventConsumer):
107
107
  if await self.consume(event):
108
108
  successful += 1
109
109
  return successful
110
-
110
+
111
111
  async def shutdown(self) -> None:
112
112
  """Shutdown the consumer."""
113
- self.logger.info(f"Shutting down logging consumer (logged {self._metrics['events_logged']} events)")
113
+ self.logger.info(
114
+ f"Shutting down logging consumer (logged {self._metrics['events_logged']} events)"
115
+ )
114
116
  self._initialized = False
115
-
117
+
116
118
  @property
117
119
  def config(self) -> ConsumerConfig:
118
120
  """Get consumer configuration."""
119
121
  return self._config
120
-
122
+
121
123
  @property
122
124
  def is_healthy(self) -> bool:
123
125
  """Check if consumer is healthy."""
124
126
  return self._initialized
125
-
127
+
126
128
  def get_metrics(self) -> Dict[str, Any]:
127
129
  """Get consumer metrics."""
128
130
  return self._metrics
129
-
131
+
130
132
  def _format_event(self, event: Event) -> str:
131
133
  """Format an event for logging."""
132
134
  # Build base message
@@ -134,20 +136,20 @@ class LoggingConsumer(IEventConsumer):
134
136
  f"[{event.topic}] {event.type} "
135
137
  f"(id={event.id[:8]}, source={event.source})"
136
138
  )
137
-
139
+
138
140
  # Add data if configured
139
141
  if self.include_data and event.data:
140
142
  if self.format_json:
141
143
  data_str = json.dumps(event.data, indent=2)
142
144
  else:
143
145
  data_str = str(event.data)
144
-
146
+
145
147
  # Truncate if too long
146
148
  if len(data_str) > self.max_data_length:
147
- data_str = data_str[:self.max_data_length] + "..."
148
-
149
+ data_str = data_str[: self.max_data_length] + "..."
150
+
149
151
  message += f"\n{data_str}"
150
-
152
+
151
153
  # Add metadata if present
152
154
  if event.metadata:
153
155
  meta_info = []
@@ -155,29 +157,29 @@ class LoggingConsumer(IEventConsumer):
155
157
  meta_info.append(f"retries={event.metadata.retry_count}")
156
158
  if event.metadata.consumers_failed:
157
159
  meta_info.append(f"failed={event.metadata.consumers_failed}")
158
-
160
+
159
161
  if meta_info:
160
162
  message += f" [{', '.join(meta_info)}]"
161
-
163
+
162
164
  return message
163
-
165
+
164
166
  def _get_log_level(self, event: Event) -> str:
165
167
  """Determine log level for an event."""
166
168
  # Use ERROR for failed events
167
169
  if event.metadata and event.metadata.consumers_failed:
168
170
  return "ERROR"
169
-
171
+
170
172
  # Use WARNING for retried events
171
173
  if event.metadata and event.metadata.retry_count > 0:
172
174
  return "WARNING"
173
-
175
+
174
176
  # Use configured level for specific topics
175
177
  if event.topic.startswith("error."):
176
178
  return "ERROR"
177
- elif event.topic.startswith("warning."):
179
+ if event.topic.startswith("warning."):
178
180
  return "WARNING"
179
- elif event.topic.startswith("debug."):
181
+ if event.topic.startswith("debug."):
180
182
  return "DEBUG"
181
-
183
+
182
184
  # Default to configured level
183
- return self.log_level
185
+ return self.log_level