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
@@ -0,0 +1,463 @@
1
+ """
2
+ Agent Listing Service for CLI commands
3
+ =======================================
4
+
5
+ WHY: The agent listing logic was previously embedded in the agents CLI command,
6
+ making it difficult to test and reuse. This service extracts that functionality
7
+ into a reusable, testable component that can be used by multiple CLI commands.
8
+
9
+ DESIGN DECISIONS:
10
+ - Interface-based design for dependency injection and testing
11
+ - Caching for performance optimization
12
+ - Integration with AgentRegistryAdapter for unified agent discovery
13
+ - Support for multiple listing modes (system, deployed, by-tier)
14
+ - Comprehensive error handling and logging
15
+ """
16
+
17
+ import time
18
+ from abc import ABC, abstractmethod
19
+ from dataclasses import dataclass
20
+ from pathlib import Path
21
+ from typing import Any, Dict, List, Optional, Tuple
22
+
23
+ from ...core.agent_registry import AgentRegistryAdapter
24
+ from ...core.logger import get_logger
25
+ from ...services.agents.deployment import AgentDeploymentService
26
+ from ...services.agents.deployment.deployment_wrapper import DeploymentServiceWrapper
27
+
28
+
29
+ @dataclass
30
+ class AgentInfo:
31
+ """Information about an agent."""
32
+
33
+ name: str
34
+ type: str
35
+ tier: str
36
+ path: str
37
+ description: Optional[str] = None
38
+ specializations: Optional[List[str]] = None
39
+ version: Optional[str] = None
40
+ deployed: bool = False
41
+ active: bool = True
42
+ overridden_by: Optional[List[str]] = None
43
+
44
+
45
+ @dataclass
46
+ class AgentTierInfo:
47
+ """Information about agents grouped by tier."""
48
+
49
+ project: List[AgentInfo]
50
+ user: List[AgentInfo]
51
+ system: List[AgentInfo]
52
+
53
+ @property
54
+ def total_count(self) -> int:
55
+ """Get total number of agents across all tiers."""
56
+ return len(self.project) + len(self.user) + len(self.system)
57
+
58
+ @property
59
+ def active_count(self) -> int:
60
+ """Get count of active agents (not overridden)."""
61
+ count = 0
62
+ for agents in [self.project, self.user, self.system]:
63
+ count += sum(1 for a in agents if a.active)
64
+ return count
65
+
66
+
67
+ class IAgentListingService(ABC):
68
+ """Interface for agent listing service."""
69
+
70
+ @abstractmethod
71
+ def list_system_agents(self, verbose: bool = False) -> List[AgentInfo]:
72
+ """
73
+ List available system agent templates.
74
+
75
+ Args:
76
+ verbose: Include detailed metadata
77
+
78
+ Returns:
79
+ List of system agent information
80
+ """
81
+
82
+ @abstractmethod
83
+ def list_deployed_agents(
84
+ self, verbose: bool = False
85
+ ) -> Tuple[List[AgentInfo], List[str]]:
86
+ """
87
+ List currently deployed agents.
88
+
89
+ Args:
90
+ verbose: Include detailed metadata
91
+
92
+ Returns:
93
+ Tuple of (agent list, warnings)
94
+ """
95
+
96
+ @abstractmethod
97
+ def list_agents_by_tier(self) -> AgentTierInfo:
98
+ """
99
+ List agents grouped by tier/precedence.
100
+
101
+ Returns:
102
+ Agent information grouped by tier
103
+ """
104
+
105
+ @abstractmethod
106
+ def get_agent_details(self, agent_name: str) -> Optional[Dict[str, Any]]:
107
+ """
108
+ Get detailed information for a specific agent.
109
+
110
+ Args:
111
+ agent_name: Name of the agent
112
+
113
+ Returns:
114
+ Agent details or None if not found
115
+ """
116
+
117
+ @abstractmethod
118
+ def compare_versions(self, agent_name: str) -> Dict[str, Any]:
119
+ """
120
+ Compare versions of an agent across tiers.
121
+
122
+ Args:
123
+ agent_name: Name of the agent
124
+
125
+ Returns:
126
+ Version comparison data
127
+ """
128
+
129
+ @abstractmethod
130
+ def find_agent(self, agent_name: str) -> Optional[AgentInfo]:
131
+ """
132
+ Find an agent by name across all sources.
133
+
134
+ Args:
135
+ agent_name: Name of the agent
136
+
137
+ Returns:
138
+ Agent info or None if not found
139
+ """
140
+
141
+ @abstractmethod
142
+ def clear_cache(self) -> None:
143
+ """Clear the service cache."""
144
+
145
+
146
+ class AgentListingService(IAgentListingService):
147
+ """Implementation of agent listing service."""
148
+
149
+ def __init__(self, deployment_service: Optional[AgentDeploymentService] = None):
150
+ """
151
+ Initialize agent listing service.
152
+
153
+ Args:
154
+ deployment_service: Optional deployment service instance
155
+ """
156
+ self.logger = get_logger(self.__class__.__name__)
157
+ self._deployment_service = deployment_service
158
+ self._registry_adapter = None
159
+ self._cache = {}
160
+ self._cache_ttl = 60 # Cache for 60 seconds
161
+ self._cache_times = {}
162
+
163
+ @property
164
+ def deployment_service(self) -> AgentDeploymentService:
165
+ """Get deployment service instance (lazy loaded)."""
166
+ if self._deployment_service is None:
167
+ try:
168
+ from ...services import AgentDeploymentService
169
+
170
+ base_service = AgentDeploymentService()
171
+ self._deployment_service = DeploymentServiceWrapper(base_service)
172
+ except ImportError:
173
+ raise ImportError("Agent deployment service not available")
174
+ return self._deployment_service
175
+
176
+ @property
177
+ def registry_adapter(self) -> AgentRegistryAdapter:
178
+ """Get registry adapter instance (lazy loaded)."""
179
+ if self._registry_adapter is None:
180
+ self._registry_adapter = AgentRegistryAdapter()
181
+ return self._registry_adapter
182
+
183
+ def _is_cache_valid(self, key: str) -> bool:
184
+ """Check if cache entry is still valid."""
185
+ if key not in self._cache_times:
186
+ return False
187
+ return (time.time() - self._cache_times[key]) < self._cache_ttl
188
+
189
+ def _get_from_cache(self, key: str) -> Optional[Any]:
190
+ """Get value from cache if valid."""
191
+ if self._is_cache_valid(key):
192
+ return self._cache.get(key)
193
+ return None
194
+
195
+ def _set_cache(self, key: str, value: Any) -> None:
196
+ """Set cache value."""
197
+ self._cache[key] = value
198
+ self._cache_times[key] = time.time()
199
+
200
+ def list_system_agents(self, verbose: bool = False) -> List[AgentInfo]:
201
+ """List available system agent templates."""
202
+ cache_key = f"system_agents_{verbose}"
203
+ cached = self._get_from_cache(cache_key)
204
+ if cached is not None:
205
+ return cached
206
+
207
+ try:
208
+ agents_data = self.deployment_service.list_available_agents()
209
+ agents = []
210
+
211
+ for agent_data in agents_data:
212
+ agent = AgentInfo(
213
+ name=agent_data.get("name", ""),
214
+ type=agent_data.get("type", "agent"),
215
+ tier="system",
216
+ path=agent_data.get("path", ""),
217
+ description=agent_data.get("description") if verbose else None,
218
+ specializations=(
219
+ agent_data.get("specializations") if verbose else None
220
+ ),
221
+ version=agent_data.get("version") if verbose else None,
222
+ )
223
+ agents.append(agent)
224
+
225
+ self._set_cache(cache_key, agents)
226
+ return agents
227
+
228
+ except Exception as e:
229
+ self.logger.error(f"Error listing system agents: {e}", exc_info=True)
230
+ return []
231
+
232
+ def list_deployed_agents(
233
+ self, verbose: bool = False
234
+ ) -> Tuple[List[AgentInfo], List[str]]:
235
+ """List currently deployed agents."""
236
+ cache_key = f"deployed_agents_{verbose}"
237
+ cached = self._get_from_cache(cache_key)
238
+ if cached is not None:
239
+ return cached
240
+
241
+ try:
242
+ verification = self.deployment_service.verify_deployment()
243
+ agents_data = verification.get("agents_found", [])
244
+ warnings = verification.get("warnings", [])
245
+
246
+ agents = []
247
+ for agent_data in agents_data:
248
+ agent = AgentInfo(
249
+ name=agent_data.get("name", ""),
250
+ type=agent_data.get("type", "agent"),
251
+ tier=agent_data.get("tier", "system"),
252
+ path=agent_data.get("path", ""),
253
+ description=agent_data.get("description") if verbose else None,
254
+ specializations=(
255
+ agent_data.get("specializations") if verbose else None
256
+ ),
257
+ version=agent_data.get("version") if verbose else None,
258
+ deployed=True,
259
+ )
260
+ agents.append(agent)
261
+
262
+ result = (agents, warnings)
263
+ self._set_cache(cache_key, result)
264
+ return result
265
+
266
+ except Exception as e:
267
+ self.logger.error(f"Error listing deployed agents: {e}", exc_info=True)
268
+ return ([], [f"Error listing deployed agents: {e}"])
269
+
270
+ def list_agents_by_tier(self) -> AgentTierInfo:
271
+ """List agents grouped by tier/precedence."""
272
+ cache_key = "agents_by_tier"
273
+ cached = self._get_from_cache(cache_key)
274
+ if cached is not None:
275
+ return cached
276
+
277
+ try:
278
+ if not self.registry_adapter.registry:
279
+ self.logger.error("Could not initialize agent registry")
280
+ return AgentTierInfo(project=[], user=[], system=[])
281
+
282
+ # Get all agents and group by tier
283
+ all_agents = self.registry_adapter.registry.list_agents()
284
+
285
+ # Group agents by tier
286
+ tiers = {"project": [], "user": [], "system": []}
287
+ agent_names = set()
288
+
289
+ for agent_id, metadata in all_agents.items():
290
+ tier = metadata.get("tier", "system")
291
+ if tier not in tiers:
292
+ continue
293
+
294
+ agent_info = AgentInfo(
295
+ name=agent_id,
296
+ type=metadata.get("type", "agent"),
297
+ tier=tier,
298
+ path=metadata.get("path", ""),
299
+ description=metadata.get("description"),
300
+ specializations=metadata.get("specializations", []),
301
+ deployed=metadata.get("deployed", False),
302
+ )
303
+
304
+ tiers[tier].append(agent_info)
305
+ agent_names.add(agent_id)
306
+
307
+ # Check for overrides
308
+ for tier_name in ["project", "user", "system"]:
309
+ for agent in tiers[tier_name]:
310
+ overridden_by = []
311
+
312
+ # Check if overridden by higher tiers
313
+ if tier_name == "system":
314
+ # Check if overridden by user or project
315
+ if any(a.name == agent.name for a in tiers["user"]):
316
+ overridden_by.append("USER")
317
+ if any(a.name == agent.name for a in tiers["project"]):
318
+ overridden_by.append("PROJECT")
319
+ elif tier_name == "user":
320
+ # Check if overridden by project
321
+ if any(a.name == agent.name for a in tiers["project"]):
322
+ overridden_by.append("PROJECT")
323
+
324
+ if overridden_by:
325
+ agent.active = False
326
+ agent.overridden_by = overridden_by
327
+
328
+ result = AgentTierInfo(
329
+ project=tiers["project"], user=tiers["user"], system=tiers["system"]
330
+ )
331
+
332
+ self._set_cache(cache_key, result)
333
+ return result
334
+
335
+ except Exception as e:
336
+ self.logger.error(f"Error listing agents by tier: {e}", exc_info=True)
337
+ return AgentTierInfo(project=[], user=[], system=[])
338
+
339
+ def get_agent_details(self, agent_name: str) -> Optional[Dict[str, Any]]:
340
+ """Get detailed information for a specific agent."""
341
+ cache_key = f"agent_details_{agent_name}"
342
+ cached = self._get_from_cache(cache_key)
343
+ if cached is not None:
344
+ return cached
345
+
346
+ try:
347
+ # Try to get from deployment service first
348
+ details = self.deployment_service.get_agent_details(agent_name)
349
+
350
+ if details:
351
+ self._set_cache(cache_key, details)
352
+ return details
353
+
354
+ # Fall back to registry
355
+ if not self.registry_adapter.registry:
356
+ return None
357
+
358
+ agent = self.registry_adapter.registry.get_agent(agent_name)
359
+ if not agent:
360
+ return None
361
+
362
+ # Read agent file for full content
363
+ agent_path = Path(agent.path)
364
+ if not agent_path.exists():
365
+ return None
366
+
367
+ with open(agent_path) as f:
368
+ content = f.read()
369
+
370
+ details = {
371
+ "name": getattr(agent, "name", agent_name),
372
+ "type": getattr(agent, "type", "agent"),
373
+ "tier": getattr(agent, "tier", "system"),
374
+ "path": str(getattr(agent, "path", agent_path)),
375
+ "description": getattr(agent, "description", None),
376
+ "specializations": getattr(agent, "specializations", []),
377
+ "content": content,
378
+ "size": agent_path.stat().st_size,
379
+ "modified": agent_path.stat().st_mtime,
380
+ }
381
+
382
+ self._set_cache(cache_key, details)
383
+ return details
384
+
385
+ except Exception as e:
386
+ self.logger.error(f"Error getting agent details: {e}", exc_info=True)
387
+ return None
388
+
389
+ def compare_versions(self, agent_name: str) -> Dict[str, Any]:
390
+ """Compare versions of an agent across tiers."""
391
+ cache_key = f"version_compare_{agent_name}"
392
+ cached = self._get_from_cache(cache_key)
393
+ if cached is not None:
394
+ return cached
395
+
396
+ try:
397
+ tier_info = self.list_agents_by_tier()
398
+ versions = {}
399
+
400
+ # Check each tier for the agent
401
+ for tier_name, agents in [
402
+ ("project", tier_info.project),
403
+ ("user", tier_info.user),
404
+ ("system", tier_info.system),
405
+ ]:
406
+ for agent in agents:
407
+ if agent.name == agent_name:
408
+ versions[tier_name] = {
409
+ "path": agent.path,
410
+ "version": agent.version,
411
+ "active": agent.active,
412
+ "overridden_by": agent.overridden_by,
413
+ }
414
+
415
+ result = {
416
+ "agent_name": agent_name,
417
+ "versions": versions,
418
+ "active_tier": next(
419
+ (tier for tier, v in versions.items() if v.get("active")), None
420
+ ),
421
+ }
422
+
423
+ self._set_cache(cache_key, result)
424
+ return result
425
+
426
+ except Exception as e:
427
+ self.logger.error(f"Error comparing versions: {e}", exc_info=True)
428
+ return {"agent_name": agent_name, "versions": {}, "error": str(e)}
429
+
430
+ def find_agent(self, agent_name: str) -> Optional[AgentInfo]:
431
+ """Find an agent by name across all sources."""
432
+ cache_key = f"find_agent_{agent_name}"
433
+ cached = self._get_from_cache(cache_key)
434
+ if cached is not None:
435
+ return cached
436
+
437
+ try:
438
+ # First check deployed agents
439
+ deployed, _ = self.list_deployed_agents()
440
+ for agent in deployed:
441
+ if agent.name == agent_name:
442
+ self._set_cache(cache_key, agent)
443
+ return agent
444
+
445
+ # Check all tiers
446
+ tier_info = self.list_agents_by_tier()
447
+ for agents in [tier_info.project, tier_info.user, tier_info.system]:
448
+ for agent in agents:
449
+ if agent.name == agent_name:
450
+ self._set_cache(cache_key, agent)
451
+ return agent
452
+
453
+ return None
454
+
455
+ except Exception as e:
456
+ self.logger.error(f"Error finding agent: {e}", exc_info=True)
457
+ return None
458
+
459
+ def clear_cache(self) -> None:
460
+ """Clear the service cache."""
461
+ self._cache.clear()
462
+ self._cache_times.clear()
463
+ self.logger.debug("Agent listing service cache cleared")