claude-mpm 4.1.1__py3-none-any.whl → 4.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (357) hide show
  1. claude_mpm/BUILD_NUMBER +1 -1
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/__main__.py +1 -1
  4. claude_mpm/agents/BASE_PM.md +74 -46
  5. claude_mpm/agents/INSTRUCTIONS.md +11 -153
  6. claude_mpm/agents/WORKFLOW.md +61 -321
  7. claude_mpm/agents/__init__.py +11 -11
  8. claude_mpm/agents/agent_loader.py +23 -20
  9. claude_mpm/agents/agent_loader_integration.py +1 -1
  10. claude_mpm/agents/agents_metadata.py +27 -0
  11. claude_mpm/agents/async_agent_loader.py +5 -8
  12. claude_mpm/agents/base_agent_loader.py +36 -25
  13. claude_mpm/agents/frontmatter_validator.py +6 -6
  14. claude_mpm/agents/schema/agent_schema.json +1 -1
  15. claude_mpm/agents/system_agent_config.py +9 -9
  16. claude_mpm/agents/templates/api_qa.json +47 -2
  17. claude_mpm/agents/templates/imagemagick.json +256 -0
  18. claude_mpm/agents/templates/qa.json +41 -2
  19. claude_mpm/agents/templates/ticketing.json +5 -5
  20. claude_mpm/agents/templates/web_qa.json +50 -2
  21. claude_mpm/cli/__init__.py +51 -46
  22. claude_mpm/cli/__main__.py +1 -1
  23. claude_mpm/cli/commands/__init__.py +10 -12
  24. claude_mpm/cli/commands/agent_manager.py +186 -181
  25. claude_mpm/cli/commands/agents.py +271 -268
  26. claude_mpm/cli/commands/aggregate.py +30 -29
  27. claude_mpm/cli/commands/cleanup.py +50 -44
  28. claude_mpm/cli/commands/cleanup_orphaned_agents.py +25 -25
  29. claude_mpm/cli/commands/config.py +162 -127
  30. claude_mpm/cli/commands/doctor.py +52 -62
  31. claude_mpm/cli/commands/info.py +37 -25
  32. claude_mpm/cli/commands/mcp.py +3 -7
  33. claude_mpm/cli/commands/mcp_command_router.py +14 -18
  34. claude_mpm/cli/commands/mcp_install_commands.py +28 -23
  35. claude_mpm/cli/commands/mcp_pipx_config.py +58 -49
  36. claude_mpm/cli/commands/mcp_server_commands.py +23 -17
  37. claude_mpm/cli/commands/memory.py +192 -141
  38. claude_mpm/cli/commands/monitor.py +117 -88
  39. claude_mpm/cli/commands/run.py +120 -84
  40. claude_mpm/cli/commands/run_config_checker.py +4 -5
  41. claude_mpm/cli/commands/socketio_monitor.py +17 -19
  42. claude_mpm/cli/commands/tickets.py +92 -92
  43. claude_mpm/cli/parser.py +1 -5
  44. claude_mpm/cli/parsers/__init__.py +1 -1
  45. claude_mpm/cli/parsers/agent_manager_parser.py +50 -98
  46. claude_mpm/cli/parsers/agents_parser.py +2 -3
  47. claude_mpm/cli/parsers/base_parser.py +7 -5
  48. claude_mpm/cli/parsers/mcp_parser.py +4 -2
  49. claude_mpm/cli/parsers/monitor_parser.py +26 -18
  50. claude_mpm/cli/shared/__init__.py +10 -10
  51. claude_mpm/cli/shared/argument_patterns.py +57 -71
  52. claude_mpm/cli/shared/base_command.py +61 -53
  53. claude_mpm/cli/shared/error_handling.py +62 -58
  54. claude_mpm/cli/shared/output_formatters.py +78 -77
  55. claude_mpm/cli/startup_logging.py +204 -172
  56. claude_mpm/cli/utils.py +10 -11
  57. claude_mpm/cli_module/__init__.py +1 -1
  58. claude_mpm/cli_module/args.py +1 -1
  59. claude_mpm/cli_module/migration_example.py +5 -5
  60. claude_mpm/config/__init__.py +9 -9
  61. claude_mpm/config/agent_config.py +15 -14
  62. claude_mpm/config/experimental_features.py +4 -4
  63. claude_mpm/config/paths.py +0 -1
  64. claude_mpm/config/socketio_config.py +5 -6
  65. claude_mpm/constants.py +1 -2
  66. claude_mpm/core/__init__.py +8 -8
  67. claude_mpm/core/agent_name_normalizer.py +1 -1
  68. claude_mpm/core/agent_registry.py +20 -23
  69. claude_mpm/core/agent_session_manager.py +3 -3
  70. claude_mpm/core/base_service.py +7 -15
  71. claude_mpm/core/cache.py +4 -6
  72. claude_mpm/core/claude_runner.py +85 -113
  73. claude_mpm/core/config.py +43 -28
  74. claude_mpm/core/config_aliases.py +0 -9
  75. claude_mpm/core/config_constants.py +52 -30
  76. claude_mpm/core/constants.py +0 -1
  77. claude_mpm/core/container.py +18 -27
  78. claude_mpm/core/exceptions.py +2 -2
  79. claude_mpm/core/factories.py +10 -12
  80. claude_mpm/core/framework_loader.py +581 -280
  81. claude_mpm/core/hook_manager.py +26 -22
  82. claude_mpm/core/hook_performance_config.py +58 -47
  83. claude_mpm/core/injectable_service.py +1 -1
  84. claude_mpm/core/interactive_session.py +61 -152
  85. claude_mpm/core/interfaces.py +1 -100
  86. claude_mpm/core/lazy.py +5 -5
  87. claude_mpm/core/log_manager.py +587 -0
  88. claude_mpm/core/logger.py +125 -8
  89. claude_mpm/core/logging_config.py +15 -15
  90. claude_mpm/core/minimal_framework_loader.py +5 -8
  91. claude_mpm/core/oneshot_session.py +15 -33
  92. claude_mpm/core/optimized_agent_loader.py +4 -6
  93. claude_mpm/core/optimized_startup.py +2 -1
  94. claude_mpm/core/output_style_manager.py +147 -106
  95. claude_mpm/core/pm_hook_interceptor.py +0 -1
  96. claude_mpm/core/service_registry.py +11 -8
  97. claude_mpm/core/session_manager.py +1 -2
  98. claude_mpm/core/shared/__init__.py +1 -1
  99. claude_mpm/core/shared/config_loader.py +101 -97
  100. claude_mpm/core/shared/path_resolver.py +72 -68
  101. claude_mpm/core/shared/singleton_manager.py +56 -50
  102. claude_mpm/core/socketio_pool.py +26 -6
  103. claude_mpm/core/tool_access_control.py +4 -5
  104. claude_mpm/core/typing_utils.py +50 -59
  105. claude_mpm/core/unified_agent_registry.py +14 -19
  106. claude_mpm/core/unified_config.py +4 -6
  107. claude_mpm/core/unified_paths.py +197 -109
  108. claude_mpm/dashboard/open_dashboard.py +2 -4
  109. claude_mpm/experimental/cli_enhancements.py +51 -36
  110. claude_mpm/generators/agent_profile_generator.py +2 -4
  111. claude_mpm/hooks/base_hook.py +1 -2
  112. claude_mpm/hooks/claude_hooks/connection_pool.py +72 -26
  113. claude_mpm/hooks/claude_hooks/event_handlers.py +93 -38
  114. claude_mpm/hooks/claude_hooks/hook_handler.py +130 -76
  115. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
  116. claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
  117. claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
  118. claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
  119. claude_mpm/hooks/memory_integration_hook.py +5 -5
  120. claude_mpm/hooks/tool_call_interceptor.py +1 -1
  121. claude_mpm/hooks/validation_hooks.py +4 -4
  122. claude_mpm/init.py +4 -9
  123. claude_mpm/models/__init__.py +2 -2
  124. claude_mpm/models/agent_session.py +11 -14
  125. claude_mpm/scripts/mcp_server.py +20 -11
  126. claude_mpm/scripts/mcp_wrapper.py +5 -5
  127. claude_mpm/scripts/mpm_doctor.py +321 -0
  128. claude_mpm/scripts/socketio_daemon.py +28 -25
  129. claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
  130. claude_mpm/scripts/socketio_server_manager.py +116 -95
  131. claude_mpm/services/__init__.py +49 -49
  132. claude_mpm/services/agent_capabilities_service.py +12 -18
  133. claude_mpm/services/agents/__init__.py +22 -22
  134. claude_mpm/services/agents/agent_builder.py +140 -119
  135. claude_mpm/services/agents/deployment/__init__.py +3 -3
  136. claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
  137. claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
  138. claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
  139. claude_mpm/services/agents/deployment/agent_deployment.py +136 -106
  140. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
  141. claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
  142. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
  143. claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
  144. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
  145. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
  146. claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
  147. claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
  148. claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
  149. claude_mpm/services/agents/deployment/agent_validator.py +0 -1
  150. claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
  151. claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
  152. claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
  153. claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
  154. claude_mpm/services/agents/deployment/config/__init__.py +1 -1
  155. claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
  156. claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
  157. claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
  158. claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
  159. claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
  160. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
  161. claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
  162. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
  163. claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
  164. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
  165. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
  166. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
  167. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
  168. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
  169. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
  170. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
  171. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
  172. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
  173. claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
  174. claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
  175. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
  176. claude_mpm/services/agents/deployment/results/__init__.py +1 -1
  177. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
  178. claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
  179. claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
  180. claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
  181. claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
  182. claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
  183. claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
  184. claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
  185. claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
  186. claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
  187. claude_mpm/services/agents/loading/__init__.py +1 -1
  188. claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
  189. claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
  190. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
  191. claude_mpm/services/agents/management/__init__.py +1 -1
  192. claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
  193. claude_mpm/services/agents/management/agent_management_service.py +5 -9
  194. claude_mpm/services/agents/memory/__init__.py +4 -4
  195. claude_mpm/services/agents/memory/agent_memory_manager.py +280 -160
  196. claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
  197. claude_mpm/services/agents/memory/content_manager.py +44 -38
  198. claude_mpm/services/agents/memory/template_generator.py +4 -6
  199. claude_mpm/services/agents/registry/__init__.py +10 -6
  200. claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
  201. claude_mpm/services/agents/registry/modification_tracker.py +3 -6
  202. claude_mpm/services/async_session_logger.py +1 -2
  203. claude_mpm/services/claude_session_logger.py +1 -2
  204. claude_mpm/services/command_deployment_service.py +173 -0
  205. claude_mpm/services/command_handler_service.py +20 -22
  206. claude_mpm/services/core/__init__.py +25 -25
  207. claude_mpm/services/core/base.py +0 -5
  208. claude_mpm/services/core/interfaces/__init__.py +32 -32
  209. claude_mpm/services/core/interfaces/agent.py +0 -21
  210. claude_mpm/services/core/interfaces/communication.py +0 -27
  211. claude_mpm/services/core/interfaces/infrastructure.py +0 -56
  212. claude_mpm/services/core/interfaces/service.py +0 -29
  213. claude_mpm/services/diagnostics/__init__.py +1 -1
  214. claude_mpm/services/diagnostics/checks/__init__.py +6 -6
  215. claude_mpm/services/diagnostics/checks/agent_check.py +89 -80
  216. claude_mpm/services/diagnostics/checks/base_check.py +12 -16
  217. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
  218. claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
  219. claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
  220. claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
  221. claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
  222. claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
  223. claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
  224. claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
  225. claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
  226. claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
  227. claude_mpm/services/diagnostics/models.py +21 -19
  228. claude_mpm/services/event_aggregator.py +10 -17
  229. claude_mpm/services/event_bus/__init__.py +1 -1
  230. claude_mpm/services/event_bus/config.py +54 -35
  231. claude_mpm/services/event_bus/event_bus.py +76 -71
  232. claude_mpm/services/event_bus/relay.py +74 -64
  233. claude_mpm/services/events/__init__.py +11 -11
  234. claude_mpm/services/events/consumers/__init__.py +3 -3
  235. claude_mpm/services/events/consumers/dead_letter.py +71 -63
  236. claude_mpm/services/events/consumers/logging.py +39 -37
  237. claude_mpm/services/events/consumers/metrics.py +56 -57
  238. claude_mpm/services/events/consumers/socketio.py +82 -81
  239. claude_mpm/services/events/core.py +110 -99
  240. claude_mpm/services/events/interfaces.py +56 -72
  241. claude_mpm/services/events/producers/__init__.py +1 -1
  242. claude_mpm/services/events/producers/hook.py +38 -38
  243. claude_mpm/services/events/producers/system.py +46 -44
  244. claude_mpm/services/exceptions.py +81 -80
  245. claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
  246. claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
  247. claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
  248. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
  249. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
  250. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
  251. claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
  252. claude_mpm/services/hook_service.py +6 -9
  253. claude_mpm/services/infrastructure/__init__.py +1 -1
  254. claude_mpm/services/infrastructure/context_preservation.py +8 -12
  255. claude_mpm/services/infrastructure/monitoring.py +21 -23
  256. claude_mpm/services/mcp_gateway/__init__.py +37 -37
  257. claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
  258. claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
  259. claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
  260. claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
  261. claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
  262. claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
  263. claude_mpm/services/mcp_gateway/core/base.py +0 -3
  264. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
  265. claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
  266. claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
  267. claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
  268. claude_mpm/services/mcp_gateway/main.py +2 -1
  269. claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
  270. claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
  271. claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
  272. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
  273. claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
  274. claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
  275. claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
  276. claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
  277. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
  278. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
  279. claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
  280. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
  281. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
  282. claude_mpm/services/memory/__init__.py +3 -3
  283. claude_mpm/services/memory/builder.py +3 -6
  284. claude_mpm/services/memory/cache/__init__.py +1 -1
  285. claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
  286. claude_mpm/services/memory/cache/simple_cache.py +1 -1
  287. claude_mpm/services/memory/indexed_memory.py +5 -7
  288. claude_mpm/services/memory/optimizer.py +7 -10
  289. claude_mpm/services/memory/router.py +8 -9
  290. claude_mpm/services/memory_hook_service.py +48 -34
  291. claude_mpm/services/monitor_build_service.py +77 -73
  292. claude_mpm/services/port_manager.py +130 -108
  293. claude_mpm/services/project/analyzer.py +12 -10
  294. claude_mpm/services/project/registry.py +11 -11
  295. claude_mpm/services/recovery_manager.py +10 -19
  296. claude_mpm/services/response_tracker.py +0 -1
  297. claude_mpm/services/runner_configuration_service.py +19 -20
  298. claude_mpm/services/session_management_service.py +7 -11
  299. claude_mpm/services/shared/__init__.py +1 -1
  300. claude_mpm/services/shared/async_service_base.py +58 -50
  301. claude_mpm/services/shared/config_service_base.py +73 -67
  302. claude_mpm/services/shared/lifecycle_service_base.py +82 -78
  303. claude_mpm/services/shared/manager_base.py +94 -82
  304. claude_mpm/services/shared/service_factory.py +96 -98
  305. claude_mpm/services/socketio/__init__.py +3 -3
  306. claude_mpm/services/socketio/client_proxy.py +5 -5
  307. claude_mpm/services/socketio/event_normalizer.py +199 -181
  308. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  309. claude_mpm/services/socketio/handlers/base.py +5 -4
  310. claude_mpm/services/socketio/handlers/connection.py +163 -136
  311. claude_mpm/services/socketio/handlers/file.py +13 -14
  312. claude_mpm/services/socketio/handlers/git.py +12 -7
  313. claude_mpm/services/socketio/handlers/hook.py +49 -44
  314. claude_mpm/services/socketio/handlers/memory.py +0 -1
  315. claude_mpm/services/socketio/handlers/project.py +0 -1
  316. claude_mpm/services/socketio/handlers/registry.py +37 -19
  317. claude_mpm/services/socketio/migration_utils.py +98 -84
  318. claude_mpm/services/socketio/server/__init__.py +1 -1
  319. claude_mpm/services/socketio/server/broadcaster.py +81 -87
  320. claude_mpm/services/socketio/server/core.py +65 -54
  321. claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
  322. claude_mpm/services/socketio/server/main.py +64 -38
  323. claude_mpm/services/socketio_client_manager.py +10 -12
  324. claude_mpm/services/subprocess_launcher_service.py +4 -7
  325. claude_mpm/services/system_instructions_service.py +13 -14
  326. claude_mpm/services/ticket_manager.py +2 -2
  327. claude_mpm/services/utility_service.py +5 -13
  328. claude_mpm/services/version_control/__init__.py +16 -16
  329. claude_mpm/services/version_control/branch_strategy.py +5 -8
  330. claude_mpm/services/version_control/conflict_resolution.py +9 -23
  331. claude_mpm/services/version_control/git_operations.py +5 -7
  332. claude_mpm/services/version_control/semantic_versioning.py +16 -17
  333. claude_mpm/services/version_control/version_parser.py +13 -18
  334. claude_mpm/services/version_service.py +10 -11
  335. claude_mpm/storage/__init__.py +1 -1
  336. claude_mpm/storage/state_storage.py +22 -28
  337. claude_mpm/utils/__init__.py +6 -6
  338. claude_mpm/utils/agent_dependency_loader.py +47 -33
  339. claude_mpm/utils/config_manager.py +11 -14
  340. claude_mpm/utils/dependency_cache.py +1 -1
  341. claude_mpm/utils/dependency_manager.py +13 -17
  342. claude_mpm/utils/dependency_strategies.py +8 -10
  343. claude_mpm/utils/environment_context.py +3 -9
  344. claude_mpm/utils/error_handler.py +3 -13
  345. claude_mpm/utils/file_utils.py +1 -1
  346. claude_mpm/utils/path_operations.py +8 -12
  347. claude_mpm/utils/robust_installer.py +110 -33
  348. claude_mpm/utils/subprocess_utils.py +5 -6
  349. claude_mpm/validation/agent_validator.py +3 -6
  350. claude_mpm/validation/frontmatter_validator.py +1 -1
  351. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/METADATA +1 -1
  352. claude_mpm-4.1.2.dist-info/RECORD +498 -0
  353. claude_mpm-4.1.1.dist-info/RECORD +0 -494
  354. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/WHEEL +0 -0
  355. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/entry_points.txt +0 -0
  356. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/licenses/LICENSE +0 -0
  357. {claude_mpm-4.1.1.dist-info → claude_mpm-4.1.2.dist-info}/top_level.txt +0 -0
@@ -9,146 +9,160 @@ DESIGN DECISION: Provide both transformation and validation utilities
9
9
  to help identify and fix inconsistent event formats across the codebase.
10
10
  """
11
11
 
12
- from datetime import datetime
13
- from typing import Any, Dict, List, Optional, Tuple
14
- import json
12
+ from typing import Any, Dict, List, Tuple
15
13
 
16
14
  from ...core.logging_config import get_logger
17
15
 
18
16
 
19
17
  class EventMigrationHelper:
20
18
  """Helper class for migrating events to the new schema.
21
-
19
+
22
20
  WHY: Provides utilities to identify old format events and
23
21
  transform them to the new normalized schema.
24
22
  """
25
-
23
+
26
24
  def __init__(self):
27
25
  self.logger = get_logger(self.__class__.__name__)
28
26
  self.migration_stats = {
29
27
  "old_format_detected": 0,
30
28
  "transformed": 0,
31
29
  "validation_failed": 0,
32
- "already_normalized": 0
30
+ "already_normalized": 0,
33
31
  }
34
-
32
+
35
33
  def is_old_format(self, event_data: Any) -> bool:
36
34
  """Check if an event is in the old format.
37
-
35
+
38
36
  WHY: Need to identify which events need migration.
39
37
  """
40
38
  if not isinstance(event_data, dict):
41
39
  return True # Non-dict events are definitely old format
42
-
40
+
43
41
  # Check for new format fields
44
42
  required_new_fields = {"event", "type", "subtype", "timestamp", "data"}
45
43
  has_all_new_fields = all(field in event_data for field in required_new_fields)
46
-
44
+
47
45
  if has_all_new_fields:
48
46
  self.migration_stats["already_normalized"] += 1
49
47
  return False
50
-
48
+
51
49
  # Old format indicators
52
50
  old_format_indicators = [
53
51
  # Hook format with "hook." prefix in type
54
- "type" in event_data and isinstance(event_data.get("type"), str) and event_data["type"].startswith("hook."),
52
+ "type" in event_data
53
+ and isinstance(event_data.get("type"), str)
54
+ and event_data["type"].startswith("hook."),
55
55
  # Missing subtype field
56
56
  "type" in event_data and "subtype" not in event_data,
57
57
  # Event field used differently
58
58
  "event" in event_data and event_data.get("event") != "claude_event",
59
59
  ]
60
-
60
+
61
61
  if any(old_format_indicators):
62
62
  self.migration_stats["old_format_detected"] += 1
63
63
  return True
64
-
64
+
65
65
  return False
66
-
66
+
67
67
  def transform_to_new_format(self, event_data: Any) -> Dict[str, Any]:
68
68
  """Transform an old format event to the new schema.
69
-
69
+
70
70
  WHY: Provides a migration path from old to new format.
71
71
  """
72
72
  # Import here to avoid circular dependency
73
73
  from .event_normalizer import EventNormalizer
74
-
74
+
75
75
  normalizer = EventNormalizer()
76
76
  normalized = normalizer.normalize(event_data)
77
-
77
+
78
78
  self.migration_stats["transformed"] += 1
79
79
  return normalized.to_dict()
80
-
81
- def validate_event_schema(self, event_data: Dict[str, Any]) -> Tuple[bool, List[str]]:
80
+
81
+ def validate_event_schema(
82
+ self, event_data: Dict[str, Any]
83
+ ) -> Tuple[bool, List[str]]:
82
84
  """Validate an event against the new schema.
83
-
85
+
84
86
  WHY: Ensures events conform to the expected structure
85
87
  before being sent to clients.
86
-
88
+
87
89
  Returns:
88
90
  Tuple of (is_valid, list_of_errors)
89
91
  """
90
92
  errors = []
91
-
93
+
92
94
  # Check required fields
93
95
  required_fields = {"event", "type", "subtype", "timestamp", "data"}
94
96
  missing_fields = required_fields - set(event_data.keys())
95
97
  if missing_fields:
96
98
  errors.append(f"Missing required fields: {missing_fields}")
97
-
99
+
98
100
  # Validate field types
99
101
  if "event" in event_data and event_data["event"] != "claude_event":
100
- errors.append(f"Invalid event name: {event_data['event']} (should be 'claude_event')")
101
-
102
+ errors.append(
103
+ f"Invalid event name: {event_data['event']} (should be 'claude_event')"
104
+ )
105
+
102
106
  if "type" in event_data and not isinstance(event_data["type"], str):
103
- errors.append(f"Invalid type field: should be string, got {type(event_data['type'])}")
104
-
107
+ errors.append(
108
+ f"Invalid type field: should be string, got {type(event_data['type'])}"
109
+ )
110
+
105
111
  if "subtype" in event_data and not isinstance(event_data["subtype"], str):
106
- errors.append(f"Invalid subtype field: should be string, got {type(event_data['subtype'])}")
107
-
112
+ errors.append(
113
+ f"Invalid subtype field: should be string, got {type(event_data['subtype'])}"
114
+ )
115
+
108
116
  if "timestamp" in event_data:
109
117
  timestamp = event_data["timestamp"]
110
118
  if not isinstance(timestamp, str) or "T" not in timestamp:
111
- errors.append(f"Invalid timestamp format: {timestamp} (should be ISO format)")
112
-
119
+ errors.append(
120
+ f"Invalid timestamp format: {timestamp} (should be ISO format)"
121
+ )
122
+
113
123
  if "data" in event_data and not isinstance(event_data["data"], dict):
114
- errors.append(f"Invalid data field: should be dict, got {type(event_data['data'])}")
115
-
124
+ errors.append(
125
+ f"Invalid data field: should be dict, got {type(event_data['data'])}"
126
+ )
127
+
116
128
  if errors:
117
129
  self.migration_stats["validation_failed"] += 1
118
130
  return False, errors
119
-
131
+
120
132
  return True, []
121
-
133
+
122
134
  def get_migration_report(self) -> str:
123
135
  """Generate a report of migration statistics.
124
-
136
+
125
137
  WHY: Helps track migration progress and identify issues.
126
138
  """
127
139
  report = "Event Migration Report\n"
128
140
  report += "=" * 50 + "\n"
129
- report += f"Old format detected: {self.migration_stats['old_format_detected']}\n"
141
+ report += (
142
+ f"Old format detected: {self.migration_stats['old_format_detected']}\n"
143
+ )
130
144
  report += f"Events transformed: {self.migration_stats['transformed']}\n"
131
145
  report += f"Validation failures: {self.migration_stats['validation_failed']}\n"
132
146
  report += f"Already normalized: {self.migration_stats['already_normalized']}\n"
133
147
  return report
134
-
148
+
135
149
  def reset_stats(self):
136
150
  """Reset migration statistics."""
137
151
  self.migration_stats = {
138
152
  "old_format_detected": 0,
139
153
  "transformed": 0,
140
154
  "validation_failed": 0,
141
- "already_normalized": 0
155
+ "already_normalized": 0,
142
156
  }
143
157
 
144
158
 
145
159
  class EventTypeMapper:
146
160
  """Maps old event types to new type/subtype categories.
147
-
161
+
148
162
  WHY: Provides a consistent mapping from legacy event names
149
163
  to the new categorized structure.
150
164
  """
151
-
165
+
152
166
  # Comprehensive mapping of old event formats to new categories
153
167
  TYPE_MAPPINGS = {
154
168
  # Hook events with "hook." prefix
@@ -160,121 +174,108 @@ class EventTypeMapper:
160
174
  "hook.stop": ("hook", "stop"),
161
175
  "hook.subagent_start": ("hook", "subagent_start"),
162
176
  "hook.subagent_stop": ("hook", "subagent_stop"),
163
-
164
177
  # Hook events without prefix
165
178
  "pre_tool": ("hook", "pre_tool"),
166
179
  "post_tool": ("hook", "post_tool"),
167
180
  "pre_response": ("hook", "pre_response"),
168
181
  "post_response": ("hook", "post_response"),
169
-
170
182
  # System events
171
183
  "system_heartbeat": ("system", "heartbeat"),
172
184
  "heartbeat": ("system", "heartbeat"),
173
185
  "system_status": ("system", "status"),
174
-
175
186
  # Session events
176
187
  "session_started": ("session", "started"),
177
188
  "session_ended": ("session", "ended"),
178
-
179
189
  # File events
180
190
  "file_changed": ("file", "changed"),
181
191
  "file_created": ("file", "created"),
182
192
  "file_deleted": ("file", "deleted"),
183
-
184
193
  # Connection events
185
194
  "client_connected": ("connection", "connected"),
186
195
  "client_disconnected": ("connection", "disconnected"),
187
-
188
196
  # Memory events
189
197
  "memory_loaded": ("memory", "loaded"),
190
198
  "memory_created": ("memory", "created"),
191
199
  "memory_updated": ("memory", "updated"),
192
200
  "memory_injected": ("memory", "injected"),
193
-
194
201
  # Git events
195
202
  "git_operation": ("git", "operation"),
196
203
  "git_commit": ("git", "commit"),
197
204
  "git_push": ("git", "push"),
198
-
199
205
  # Todo events
200
206
  "todo_updated": ("todo", "updated"),
201
207
  "todo_created": ("todo", "created"),
202
-
203
208
  # Ticket events
204
209
  "ticket_created": ("ticket", "created"),
205
210
  "ticket_updated": ("ticket", "updated"),
206
-
207
211
  # Agent events
208
212
  "agent_delegated": ("agent", "delegated"),
209
213
  "agent_completed": ("agent", "completed"),
210
-
211
214
  # Claude events
212
215
  "claude_status": ("claude", "status"),
213
216
  "claude_output": ("claude", "output"),
214
-
215
217
  # Error events
216
218
  "error": ("error", "general"),
217
219
  "error_occurred": ("error", "occurred"),
218
-
219
220
  # Performance events
220
221
  "performance": ("performance", "metric"),
221
222
  "performance_metric": ("performance", "metric"),
222
223
  }
223
-
224
+
224
225
  @classmethod
225
226
  def map_event_type(cls, old_type: str) -> Tuple[str, str]:
226
227
  """Map an old event type to new type/subtype.
227
-
228
+
228
229
  WHY: Provides consistent categorization for all events.
229
-
230
+
230
231
  Args:
231
232
  old_type: The old event type string
232
-
233
+
233
234
  Returns:
234
235
  Tuple of (type, subtype)
235
236
  """
236
237
  # Direct mapping
237
238
  if old_type in cls.TYPE_MAPPINGS:
238
239
  return cls.TYPE_MAPPINGS[old_type]
239
-
240
+
240
241
  # Try to infer from patterns
241
242
  old_lower = old_type.lower()
242
-
243
+
243
244
  # Hook events
244
- if "hook" in old_lower or old_lower.startswith("pre_") or old_lower.startswith("post_"):
245
+ if "hook" in old_lower or old_lower.startswith(("pre_", "post_")):
245
246
  # Remove "hook." prefix if present
246
247
  clean_type = old_type.replace("hook.", "")
247
248
  return "hook", clean_type
248
-
249
+
249
250
  # System events
250
251
  if "system" in old_lower or "heartbeat" in old_lower:
251
252
  return "system", old_type.replace("system_", "")
252
-
253
+
253
254
  # Session events
254
255
  if "session" in old_lower:
255
256
  if "start" in old_lower:
256
257
  return "session", "started"
257
- elif "end" in old_lower:
258
+ if "end" in old_lower:
258
259
  return "session", "ended"
259
260
  return "session", "generic"
260
-
261
+
261
262
  # File events
262
263
  if "file" in old_lower:
263
264
  if "create" in old_lower:
264
265
  return "file", "created"
265
- elif "delete" in old_lower:
266
+ if "delete" in old_lower:
266
267
  return "file", "deleted"
267
- elif "change" in old_lower or "modify" in old_lower:
268
+ if "change" in old_lower or "modify" in old_lower:
268
269
  return "file", "changed"
269
270
  return "file", "generic"
270
-
271
+
271
272
  # Default mapping
272
273
  return "unknown", old_type
273
-
274
+
274
275
  @classmethod
275
276
  def get_event_category(cls, event_type: str, event_subtype: str) -> str:
276
277
  """Get a human-readable category for an event.
277
-
278
+
278
279
  WHY: Helps with filtering and display in UIs.
279
280
  """
280
281
  categories = {
@@ -291,39 +292,52 @@ class EventTypeMapper:
291
292
  "claude": "Claude Process",
292
293
  "error": "Errors",
293
294
  "performance": "Performance Metrics",
294
- "unknown": "Uncategorized"
295
+ "unknown": "Uncategorized",
295
296
  }
296
297
  return categories.get(event_type, "Other")
297
298
 
298
299
 
299
- def create_backward_compatible_event(normalized_event: Dict[str, Any]) -> Dict[str, Any]:
300
+ def create_backward_compatible_event(
301
+ normalized_event: Dict[str, Any],
302
+ ) -> Dict[str, Any]:
300
303
  """Create a backward-compatible version of a normalized event.
301
-
304
+
302
305
  WHY: During migration, some clients may still expect the old format.
303
306
  This creates an event that works with both old and new clients.
304
-
307
+
305
308
  Args:
306
309
  normalized_event: Event in the new normalized format
307
-
310
+
308
311
  Returns:
309
312
  Event that includes both old and new format fields
310
313
  """
311
314
  # Start with the normalized event
312
315
  compat_event = normalized_event.copy()
313
-
316
+
314
317
  # Add old format fields based on type/subtype
315
318
  event_type = normalized_event.get("type", "")
316
319
  event_subtype = normalized_event.get("subtype", "")
317
-
320
+
318
321
  # For hook events, add the old "hook." prefix format
319
322
  if event_type == "hook":
320
323
  compat_event["type_legacy"] = f"hook.{event_subtype}"
321
-
324
+
322
325
  # For other events, use the old naming convention
323
- elif event_type in ["session", "file", "memory", "git", "todo", "ticket", "agent", "claude"]:
326
+ elif event_type in [
327
+ "session",
328
+ "file",
329
+ "memory",
330
+ "git",
331
+ "todo",
332
+ "ticket",
333
+ "agent",
334
+ "claude",
335
+ ]:
324
336
  compat_event["type_legacy"] = f"{event_type}_{event_subtype}"
325
-
337
+
326
338
  # Add event_type field for really old clients
327
- compat_event["event_type"] = compat_event.get("type_legacy", f"{event_type}_{event_subtype}")
328
-
329
- return compat_event
339
+ compat_event["event_type"] = compat_event.get(
340
+ "type_legacy", f"{event_type}_{event_subtype}"
341
+ )
342
+
343
+ return compat_event
@@ -15,4 +15,4 @@ This improves maintainability, testability, and code organization.
15
15
  from .broadcaster import SocketIOEventBroadcaster
16
16
  from .core import SocketIOServerCore
17
17
 
18
- __all__ = ["SocketIOServerCore", "SocketIOEventBroadcaster"]
18
+ __all__ = ["SocketIOEventBroadcaster", "SocketIOServerCore"]