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
@@ -29,7 +29,6 @@ from typing import Any, Dict, List, Optional, Tuple
29
29
  import aiofiles
30
30
 
31
31
  from claude_mpm.config.paths import paths
32
- from claude_mpm.constants import EnvironmentVars, Paths
33
32
  from claude_mpm.core.config import Config
34
33
  from claude_mpm.core.logger import get_logger
35
34
 
@@ -95,12 +94,12 @@ class AsyncAgentDeploymentService:
95
94
  "parallel_files_processed": 0,
96
95
  "time_saved_ms": 0.0,
97
96
  }
98
-
97
+
99
98
  self.logger.info(f"Base agent path: {self.base_agent_path}")
100
-
99
+
101
100
  def _find_base_agent_file(self) -> Path:
102
101
  """Find base agent file with priority-based search.
103
-
102
+
104
103
  Priority order:
105
104
  1. Environment variable override (CLAUDE_MPM_BASE_AGENT_PATH)
106
105
  2. Current working directory (for local development)
@@ -113,49 +112,68 @@ class AsyncAgentDeploymentService:
113
112
  if env_path:
114
113
  env_base_agent = Path(env_path)
115
114
  if env_base_agent.exists():
116
- self.logger.info(f"Using environment variable base_agent: {env_base_agent}")
115
+ self.logger.info(
116
+ f"Using environment variable base_agent: {env_base_agent}"
117
+ )
117
118
  return env_base_agent
118
- else:
119
- self.logger.warning(f"CLAUDE_MPM_BASE_AGENT_PATH set but file doesn't exist: {env_base_agent}")
120
-
119
+ self.logger.warning(
120
+ f"CLAUDE_MPM_BASE_AGENT_PATH set but file doesn't exist: {env_base_agent}"
121
+ )
122
+
121
123
  # Priority 1: Check current working directory for local development
122
124
  cwd = Path.cwd()
123
125
  cwd_base_agent = cwd / "src" / "claude_mpm" / "agents" / "base_agent.json"
124
126
  if cwd_base_agent.exists():
125
- self.logger.info(f"Using local development base_agent from cwd: {cwd_base_agent}")
127
+ self.logger.info(
128
+ f"Using local development base_agent from cwd: {cwd_base_agent}"
129
+ )
126
130
  return cwd_base_agent
127
-
131
+
128
132
  # Priority 2: Check known development locations
129
133
  known_dev_paths = [
130
- Path("/Users/masa/Projects/claude-mpm/src/claude_mpm/agents/base_agent.json"),
131
- Path.home() / "Projects" / "claude-mpm" / "src" / "claude_mpm" / "agents" / "base_agent.json",
132
- Path.home() / "projects" / "claude-mpm" / "src" / "claude_mpm" / "agents" / "base_agent.json",
134
+ Path(
135
+ "/Users/masa/Projects/claude-mpm/src/claude_mpm/agents/base_agent.json"
136
+ ),
137
+ Path.home()
138
+ / "Projects"
139
+ / "claude-mpm"
140
+ / "src"
141
+ / "claude_mpm"
142
+ / "agents"
143
+ / "base_agent.json",
144
+ Path.home()
145
+ / "projects"
146
+ / "claude-mpm"
147
+ / "src"
148
+ / "claude_mpm"
149
+ / "agents"
150
+ / "base_agent.json",
133
151
  ]
134
-
152
+
135
153
  for dev_path in known_dev_paths:
136
154
  if dev_path.exists():
137
155
  self.logger.info(f"Using development base_agent: {dev_path}")
138
156
  return dev_path
139
-
157
+
140
158
  # Priority 3: Check user override location
141
159
  user_base_agent = Path.home() / ".claude" / "agents" / "base_agent.json"
142
160
  if user_base_agent.exists():
143
161
  self.logger.info(f"Using user override base_agent: {user_base_agent}")
144
162
  return user_base_agent
145
-
163
+
146
164
  # Priority 4: Use framework agents directory (fallback)
147
165
  framework_base_agent = paths.agents_dir / "base_agent.json"
148
166
  if framework_base_agent.exists():
149
167
  self.logger.info(f"Using framework base_agent: {framework_base_agent}")
150
168
  return framework_base_agent
151
-
169
+
152
170
  # If still not found, log all searched locations
153
171
  self.logger.warning("Base agent file not found in any location:")
154
172
  self.logger.warning(f" 1. CWD: {cwd_base_agent}")
155
173
  self.logger.warning(f" 2. Dev paths: {known_dev_paths}")
156
174
  self.logger.warning(f" 3. User: {user_base_agent}")
157
175
  self.logger.warning(f" 4. Framework: {framework_base_agent}")
158
-
176
+
159
177
  # Final fallback to framework path even if it doesn't exist
160
178
  return framework_base_agent
161
179
 
@@ -233,7 +251,7 @@ class AsyncAgentDeploymentService:
233
251
  """Load and parse a single agent file asynchronously."""
234
252
  try:
235
253
  # Non-blocking file read
236
- async with aiofiles.open(file_path, "r") as f:
254
+ async with aiofiles.open(file_path) as f:
237
255
  content = await f.read()
238
256
 
239
257
  # Parse JSON in thread pool (CPU-bound)
@@ -291,13 +309,12 @@ class AsyncAgentDeploymentService:
291
309
  required_fields = ["agent_id", "instructions"]
292
310
  if all(field in agent for field in required_fields):
293
311
  return agent
294
- else:
295
- missing = [f for f in required_fields if f not in agent]
296
- self.logger.warning(
297
- f"Agent {agent.get('_agent_name', 'unknown')} "
298
- f"missing required fields: {missing}"
299
- )
300
- return None
312
+ missing = [f for f in required_fields if f not in agent]
313
+ self.logger.warning(
314
+ f"Agent {agent.get('_agent_name', 'unknown')} "
315
+ f"missing required fields: {missing}"
316
+ )
317
+ return None
301
318
  except Exception as e:
302
319
  self.logger.error(f"Validation error: {e}")
303
320
  return None
@@ -415,10 +432,9 @@ class AsyncAgentDeploymentService:
415
432
 
416
433
  if target_dir.name == "agents":
417
434
  return target_dir
418
- elif target_dir.name in [".claude-mpm", ".claude"]:
435
+ if target_dir.name in [".claude-mpm", ".claude"]:
419
436
  return target_dir / "agents"
420
- else:
421
- return target_dir / ".claude" / "agents"
437
+ return target_dir / ".claude" / "agents"
422
438
 
423
439
  def _filter_excluded_agents(
424
440
  self,
@@ -494,7 +510,6 @@ class AsyncAgentDeploymentService:
494
510
 
495
511
  def _build_agent_markdown_sync(self, agent_data: Dict[str, Any]) -> str:
496
512
  """Build agent markdown content matching the synchronous deployment format."""
497
- from datetime import datetime
498
513
 
499
514
  # Extract agent info from the loaded JSON data
500
515
  agent_name = agent_data.get("_agent_name", "unknown")
@@ -521,7 +536,7 @@ class AsyncAgentDeploymentService:
521
536
  )
522
537
 
523
538
  # Get tags from new format (metadata.tags) or old format
524
- tags = (
539
+ (
525
540
  agent_data.get("metadata", {}).get("tags")
526
541
  or agent_data.get("configuration_fields", {}).get("tags")
527
542
  or agent_data.get("tags")
@@ -583,7 +598,7 @@ class AsyncAgentDeploymentService:
583
598
  f"description: {description}",
584
599
  f"version: {version_string}",
585
600
  f"base_version: {self._format_version_display(base_version)}",
586
- f"author: claude-mpm", # Identify as system agent for deployment
601
+ "author: claude-mpm", # Identify as system agent for deployment
587
602
  f"tools: {tools_str}",
588
603
  f"model: {model}",
589
604
  ]
@@ -667,9 +682,8 @@ class AsyncAgentDeploymentService:
667
682
  if isinstance(version_tuple, tuple) and len(version_tuple) == 3:
668
683
  major, minor, patch = version_tuple
669
684
  return f"{major}.{minor}.{patch}"
670
- else:
671
- # Fallback for legacy format
672
- return str(version_tuple)
685
+ # Fallback for legacy format
686
+ return str(version_tuple)
673
687
 
674
688
  async def cleanup(self):
675
689
  """Clean up resources."""
@@ -706,10 +720,9 @@ def deploy_agents_async_wrapper(
706
720
  )
707
721
 
708
722
  try:
709
- results = await service.deploy_agents_async(
723
+ return await service.deploy_agents_async(
710
724
  target_dir=target_dir, force_rebuild=force_rebuild, config=config
711
725
  )
712
- return results
713
726
  finally:
714
727
  await service.cleanup()
715
728
 
@@ -717,7 +730,7 @@ def deploy_agents_async_wrapper(
717
730
  try:
718
731
  # Check if we're already in an async context
719
732
  try:
720
- loop = asyncio.get_running_loop()
733
+ asyncio.get_running_loop()
721
734
  # We're in an async context, run in thread pool to avoid blocking
722
735
  import concurrent.futures
723
736
 
@@ -0,0 +1,132 @@
1
+ """Base agent locator service for finding base agent configuration files."""
2
+
3
+ import logging
4
+ import os
5
+ from pathlib import Path
6
+ from typing import Optional
7
+
8
+
9
+ class BaseAgentLocator:
10
+ """Service for locating base agent configuration files.
11
+
12
+ This service handles the priority-based search for base_agent.json
13
+ files across multiple possible locations including environment
14
+ variables, development paths, and user overrides.
15
+ """
16
+
17
+ def __init__(self, logger: Optional[logging.Logger] = None):
18
+ """Initialize the base agent locator.
19
+
20
+ Args:
21
+ logger: Optional logger instance
22
+ """
23
+ self.logger = logger or logging.getLogger(__name__)
24
+
25
+ def find_base_agent_file(self, paths_agents_dir: Path) -> Path:
26
+ """Find base agent file with priority-based search.
27
+
28
+ Priority order:
29
+ 1. Environment variable override (CLAUDE_MPM_BASE_AGENT_PATH)
30
+ 2. Current working directory (for local development)
31
+ 3. Known development locations
32
+ 4. User override location (~/.claude/agents/)
33
+ 5. Framework agents directory (from paths)
34
+
35
+ Args:
36
+ paths_agents_dir: Framework agents directory from paths
37
+
38
+ Returns:
39
+ Path to base agent file
40
+ """
41
+ # Priority 0: Check environment variable override
42
+ env_path = os.environ.get("CLAUDE_MPM_BASE_AGENT_PATH")
43
+ if env_path:
44
+ env_base_agent = Path(env_path)
45
+ if env_base_agent.exists():
46
+ self.logger.info(
47
+ f"Using environment variable base_agent: {env_base_agent}"
48
+ )
49
+ return env_base_agent
50
+ self.logger.warning(
51
+ f"CLAUDE_MPM_BASE_AGENT_PATH set but file doesn't exist: {env_base_agent}"
52
+ )
53
+
54
+ # Priority 1: Check current working directory for local development
55
+ cwd = Path.cwd()
56
+ cwd_base_agent = cwd / "src" / "claude_mpm" / "agents" / "base_agent.json"
57
+ if cwd_base_agent.exists():
58
+ self.logger.info(
59
+ f"Using local development base_agent from cwd: {cwd_base_agent}"
60
+ )
61
+ return cwd_base_agent
62
+
63
+ # Priority 2: Check known development locations
64
+ known_dev_paths = [
65
+ Path(
66
+ "/Users/masa/Projects/claude-mpm/src/claude_mpm/agents/base_agent.json"
67
+ ),
68
+ Path.home()
69
+ / "Projects"
70
+ / "claude-mpm"
71
+ / "src"
72
+ / "claude_mpm"
73
+ / "agents"
74
+ / "base_agent.json",
75
+ Path.home()
76
+ / "projects"
77
+ / "claude-mpm"
78
+ / "src"
79
+ / "claude_mpm"
80
+ / "agents"
81
+ / "base_agent.json",
82
+ ]
83
+
84
+ for dev_path in known_dev_paths:
85
+ if dev_path.exists():
86
+ self.logger.info(f"Using development base_agent: {dev_path}")
87
+ return dev_path
88
+
89
+ # Priority 3: Check user override location
90
+ user_base_agent = Path.home() / ".claude" / "agents" / "base_agent.json"
91
+ if user_base_agent.exists():
92
+ self.logger.info(f"Using user override base_agent: {user_base_agent}")
93
+ return user_base_agent
94
+
95
+ # Priority 4: Use framework agents directory (fallback)
96
+ framework_base_agent = paths_agents_dir / "base_agent.json"
97
+ if framework_base_agent.exists():
98
+ self.logger.info(f"Using framework base_agent: {framework_base_agent}")
99
+ return framework_base_agent
100
+
101
+ # If still not found, log all searched locations and raise error
102
+ self.logger.error("Base agent file not found in any location:")
103
+ self.logger.error(f" 1. CWD: {cwd_base_agent}")
104
+ self.logger.error(f" 2. Dev paths: {known_dev_paths}")
105
+ self.logger.error(f" 3. User: {user_base_agent}")
106
+ self.logger.error(f" 4. Framework: {framework_base_agent}")
107
+
108
+ # Final fallback to framework path even if it doesn't exist
109
+ # (will fail later with better error message)
110
+ return framework_base_agent
111
+
112
+ def determine_source_tier(self, templates_dir: Path) -> str:
113
+ """Determine the source tier for logging.
114
+
115
+ Args:
116
+ templates_dir: Templates directory path
117
+
118
+ Returns:
119
+ Source tier string (framework/user/project)
120
+ """
121
+ templates_str = str(templates_dir.resolve())
122
+
123
+ # Check if this is a user-level installation
124
+ if str(Path.home()) in templates_str and ".claude-mpm" in templates_str:
125
+ return "user"
126
+
127
+ # Check if this is a project-level installation
128
+ if ".claude-mpm" in templates_str:
129
+ return "project"
130
+
131
+ # Default to framework
132
+ return "framework"
@@ -8,6 +8,6 @@ from .deployment_config import DeploymentConfig
8
8
  from .deployment_config_manager import DeploymentConfigManager
9
9
 
10
10
  __all__ = [
11
- "DeploymentConfigManager",
12
11
  "DeploymentConfig",
12
+ "DeploymentConfigManager",
13
13
  ]
@@ -87,8 +87,7 @@ class DeploymentConfig:
87
87
  """
88
88
  if self.case_sensitive_exclusion:
89
89
  return agent_name in self.excluded_agents
90
- else:
91
- return agent_name.lower() in [name.lower() for name in self.excluded_agents]
90
+ return agent_name.lower() in [name.lower() for name in self.excluded_agents]
92
91
 
93
92
  def get_effective_excluded_agents(self) -> List[str]:
94
93
  """Get the effective list of excluded agents.
@@ -159,12 +158,12 @@ class DeploymentConfig:
159
158
  "use_async": self.use_async,
160
159
  "target_dir": str(self.target_dir) if self.target_dir else None,
161
160
  "templates_dir": str(self.templates_dir) if self.templates_dir else None,
162
- "base_agent_path": str(self.base_agent_path)
163
- if self.base_agent_path
164
- else None,
165
- "working_directory": str(self.working_directory)
166
- if self.working_directory
167
- else None,
161
+ "base_agent_path": (
162
+ str(self.base_agent_path) if self.base_agent_path else None
163
+ ),
164
+ "working_directory": (
165
+ str(self.working_directory) if self.working_directory else None
166
+ ),
168
167
  "deploy_system_instructions": self.deploy_system_instructions,
169
168
  "deploy_user_instructions": self.deploy_user_instructions,
170
169
  "repair_existing_agents": self.repair_existing_agents,
@@ -0,0 +1,185 @@
1
+ """Deployment results manager for tracking deployment outcomes."""
2
+
3
+ import logging
4
+ import time
5
+ from pathlib import Path
6
+ from typing import Any, Dict, Optional
7
+
8
+
9
+ class DeploymentResultsManager:
10
+ """Service for managing deployment results and metrics.
11
+
12
+ This service handles initialization and updates of deployment
13
+ results dictionaries, ensuring consistent structure across
14
+ all deployment operations.
15
+ """
16
+
17
+ def __init__(self, logger: Optional[logging.Logger] = None):
18
+ """Initialize the deployment results manager.
19
+
20
+ Args:
21
+ logger: Optional logger instance
22
+ """
23
+ self.logger = logger or logging.getLogger(__name__)
24
+
25
+ # Initialize deployment metrics tracking
26
+ self._deployment_metrics = {
27
+ "total_deployments": 0,
28
+ "successful_deployments": 0,
29
+ "failed_deployments": 0,
30
+ "migrations_performed": 0,
31
+ "version_migration_count": 0,
32
+ "agent_type_counts": {},
33
+ "deployment_errors": {},
34
+ }
35
+
36
+ def initialize_deployment_results(
37
+ self, agents_dir: Path, deployment_start_time: float
38
+ ) -> Dict[str, Any]:
39
+ """Initialize the deployment results dictionary.
40
+
41
+ WHY: Consistent result structure ensures all deployment
42
+ operations return the same format for easier processing.
43
+
44
+ Args:
45
+ agents_dir: Target agents directory
46
+ deployment_start_time: Start time for metrics
47
+
48
+ Returns:
49
+ Initialized results dictionary
50
+ """
51
+ return {
52
+ "target_dir": str(agents_dir),
53
+ "deployed": [],
54
+ "errors": [],
55
+ "skipped": [],
56
+ "updated": [],
57
+ "migrated": [], # Track agents migrated from old format
58
+ "converted": [], # Track YAML to MD conversions
59
+ "repaired": [], # Track agents with repaired frontmatter
60
+ "total": 0,
61
+ # METRICS: Add detailed timing and performance data to results
62
+ "metrics": {
63
+ "start_time": deployment_start_time,
64
+ "end_time": None,
65
+ "duration_ms": None,
66
+ "agent_timings": {}, # Track individual agent deployment times
67
+ "validation_times": {}, # Track template validation times
68
+ "resource_usage": {}, # Could track memory/CPU if needed
69
+ },
70
+ }
71
+
72
+ def record_agent_deployment(
73
+ self,
74
+ agent_name: str,
75
+ template_file: Path,
76
+ target_file: Path,
77
+ is_update: bool,
78
+ is_migration: bool,
79
+ reason: str,
80
+ agent_start_time: float,
81
+ results: Dict[str, Any],
82
+ logger: Optional[logging.Logger] = None,
83
+ ) -> None:
84
+ """Record deployment metrics and update results.
85
+
86
+ WHY: Centralized metrics recording ensures consistent tracking
87
+ of deployment performance and statistics.
88
+
89
+ Args:
90
+ agent_name: Name of the agent
91
+ template_file: Template file
92
+ target_file: Target file
93
+ is_update: Whether this is an update
94
+ is_migration: Whether this is a migration
95
+ reason: Update/migration reason
96
+ agent_start_time: Start time for this agent
97
+ results: Results dictionary to update
98
+ logger: Optional logger for output
99
+ """
100
+ logger = logger or self.logger
101
+
102
+ # METRICS: Record deployment time for this agent
103
+ agent_deployment_time = (time.time() - agent_start_time) * 1000 # Convert to ms
104
+ results["metrics"]["agent_timings"][agent_name] = agent_deployment_time
105
+
106
+ # METRICS: Update agent type deployment counts
107
+ self._deployment_metrics["agent_type_counts"][agent_name] = (
108
+ self._deployment_metrics["agent_type_counts"].get(agent_name, 0) + 1
109
+ )
110
+
111
+ deployment_info = {
112
+ "name": agent_name,
113
+ "template": str(template_file),
114
+ "target": str(target_file),
115
+ "deployment_time_ms": agent_deployment_time,
116
+ }
117
+
118
+ if is_migration:
119
+ deployment_info["reason"] = reason
120
+ results["migrated"].append(deployment_info)
121
+ logger.info(
122
+ f"Successfully migrated agent: {agent_name} to semantic versioning"
123
+ )
124
+
125
+ # METRICS: Track migration statistics
126
+ self._deployment_metrics["migrations_performed"] += 1
127
+ self._deployment_metrics["version_migration_count"] += 1
128
+
129
+ elif is_update:
130
+ results["updated"].append(deployment_info)
131
+ logger.debug(f"Updated agent: {agent_name}")
132
+ else:
133
+ results["deployed"].append(deployment_info)
134
+ logger.debug(f"Built and deployed agent: {agent_name}")
135
+
136
+ def finalize_results(
137
+ self, results: Dict[str, Any], deployment_start_time: float
138
+ ) -> None:
139
+ """Finalize deployment results with end metrics.
140
+
141
+ Args:
142
+ results: Results dictionary to finalize
143
+ deployment_start_time: Original start time
144
+ """
145
+ deployment_end_time = time.time()
146
+ deployment_duration = (deployment_end_time - deployment_start_time) * 1000 # ms
147
+
148
+ results["metrics"]["end_time"] = deployment_end_time
149
+ results["metrics"]["duration_ms"] = deployment_duration
150
+
151
+ def update_deployment_metrics(
152
+ self, success: bool, error_type: Optional[str] = None
153
+ ) -> None:
154
+ """Update internal deployment metrics.
155
+
156
+ Args:
157
+ success: Whether deployment succeeded
158
+ error_type: Type of error if failed
159
+ """
160
+ self._deployment_metrics["total_deployments"] += 1
161
+
162
+ if success:
163
+ self._deployment_metrics["successful_deployments"] += 1
164
+ else:
165
+ self._deployment_metrics["failed_deployments"] += 1
166
+ if error_type:
167
+ self._deployment_metrics["deployment_errors"][error_type] = (
168
+ self._deployment_metrics["deployment_errors"].get(error_type, 0) + 1
169
+ )
170
+
171
+ def get_deployment_metrics(self) -> Dict[str, Any]:
172
+ """Get current deployment metrics."""
173
+ return self._deployment_metrics.copy()
174
+
175
+ def reset_metrics(self) -> None:
176
+ """Reset deployment metrics."""
177
+ self._deployment_metrics = {
178
+ "total_deployments": 0,
179
+ "successful_deployments": 0,
180
+ "failed_deployments": 0,
181
+ "migrations_performed": 0,
182
+ "version_migration_count": 0,
183
+ "agent_type_counts": {},
184
+ "deployment_errors": {},
185
+ }
@@ -116,7 +116,7 @@ class DeploymentTypeDetector:
116
116
  and "/templates" not in templates_str
117
117
  ):
118
118
  return "PROJECT"
119
- elif (
119
+ if (
120
120
  "/.claude-mpm/agents" in templates_str
121
121
  and "/templates" not in templates_str
122
122
  ):
@@ -1,52 +1,52 @@
1
1
  """Temporary wrapper to provide backward compatibility for CLI commands."""
2
2
 
3
3
  from pathlib import Path
4
- from typing import Dict, Any
4
+ from typing import Any, Dict
5
5
 
6
6
  from claude_mpm.services.agents.deployment import AgentDeploymentService
7
7
 
8
8
 
9
9
  class DeploymentServiceWrapper:
10
10
  """Wrapper to provide backward-compatible methods for the CLI."""
11
-
11
+
12
12
  def __init__(self, deployment_service: AgentDeploymentService):
13
13
  """Initialize wrapper with actual deployment service."""
14
14
  self.service = deployment_service
15
15
  # Pass through all attributes
16
16
  for attr in dir(deployment_service):
17
- if not attr.startswith('_') and not hasattr(self, attr):
17
+ if not attr.startswith("_") and not hasattr(self, attr):
18
18
  setattr(self, attr, getattr(deployment_service, attr))
19
-
19
+
20
20
  def deploy_system_agents(self, force: bool = False) -> Dict[str, Any]:
21
21
  """Deploy system agents only.
22
-
22
+
23
23
  Args:
24
24
  force: Force rebuild even if agents are up to date
25
-
25
+
26
26
  Returns:
27
27
  Deployment results
28
28
  """
29
29
  # Deploy agents with default target (system agents location)
30
30
  result = self.service.deploy_agents(
31
- force_rebuild=force,
32
- deployment_mode="update"
31
+ force_rebuild=force, deployment_mode="update"
33
32
  )
34
-
33
+
35
34
  # Transform result to expected format
36
35
  return {
37
- "deployed_count": len(result.get("deployed", [])) + len(result.get("updated", [])),
36
+ "deployed_count": len(result.get("deployed", []))
37
+ + len(result.get("updated", [])),
38
38
  "deployed": result.get("deployed", []),
39
39
  "updated": result.get("updated", []),
40
40
  "errors": result.get("errors", []),
41
- "target_dir": result.get("target_dir", "")
41
+ "target_dir": result.get("target_dir", ""),
42
42
  }
43
-
43
+
44
44
  def deploy_project_agents(self, force: bool = False) -> Dict[str, Any]:
45
45
  """Deploy project agents only.
46
-
46
+
47
47
  Args:
48
48
  force: Force rebuild even if agents are up to date
49
-
49
+
50
50
  Returns:
51
51
  Deployment results
52
52
  """
@@ -58,14 +58,14 @@ class DeploymentServiceWrapper:
58
58
  "deployed": [],
59
59
  "updated": [],
60
60
  "errors": [],
61
- "target_dir": ""
61
+ "target_dir": "",
62
62
  }
63
-
63
+
64
64
  # For now, return empty result as project agents are handled differently
65
65
  return {
66
66
  "deployed_count": 0,
67
67
  "deployed": [],
68
68
  "updated": [],
69
69
  "errors": [],
70
- "target_dir": str(project_dir)
71
- }
70
+ "target_dir": str(project_dir),
71
+ }
@@ -11,8 +11,8 @@ from .deployment_facade import DeploymentFacade
11
11
  from .sync_deployment_executor import SyncDeploymentExecutor
12
12
 
13
13
  __all__ = [
14
+ "AsyncDeploymentExecutor",
14
15
  "DeploymentExecutor",
15
16
  "DeploymentFacade",
16
- "AsyncDeploymentExecutor",
17
17
  "SyncDeploymentExecutor",
18
18
  ]