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
@@ -17,7 +17,6 @@ import sys
17
17
  from typing import Optional
18
18
 
19
19
  from ...core.logger import get_logger
20
- from ...models.agent_session import AgentSession
21
20
  from ...services.event_aggregator import (
22
21
  aggregator_status,
23
22
  get_aggregator,
@@ -37,7 +36,7 @@ class AggregateCommand(BaseCommand):
37
36
 
38
37
  def validate_args(self, args) -> Optional[str]:
39
38
  """Validate command arguments."""
40
- if not hasattr(args, 'aggregate_subcommand') or not args.aggregate_subcommand:
39
+ if not hasattr(args, "aggregate_subcommand") or not args.aggregate_subcommand:
41
40
  return "No aggregate subcommand specified"
42
41
 
43
42
  valid_commands = ["start", "stop", "status", "sessions", "view", "export"]
@@ -62,11 +61,15 @@ class AggregateCommand(BaseCommand):
62
61
  if args.aggregate_subcommand in command_map:
63
62
  exit_code = command_map[args.aggregate_subcommand](args)
64
63
  if exit_code == 0:
65
- return CommandResult.success_result(f"Aggregate {args.aggregate_subcommand} completed successfully")
66
- else:
67
- return CommandResult.error_result(f"Aggregate {args.aggregate_subcommand} failed", exit_code=exit_code)
68
- else:
69
- return CommandResult.error_result(f"Unknown aggregate command: {args.aggregate_subcommand}")
64
+ return CommandResult.success_result(
65
+ f"Aggregate {args.aggregate_subcommand} completed successfully"
66
+ )
67
+ return CommandResult.error_result(
68
+ f"Aggregate {args.aggregate_subcommand} failed", exit_code=exit_code
69
+ )
70
+ return CommandResult.error_result(
71
+ f"Unknown aggregate command: {args.aggregate_subcommand}"
72
+ )
70
73
 
71
74
  except Exception as e:
72
75
  self.logger.error(f"Error executing aggregate command: {e}", exc_info=True)
@@ -107,7 +110,7 @@ def aggregate_command(args):
107
110
  result = command.execute(args)
108
111
 
109
112
  # Print result if structured output format is requested
110
- if hasattr(args, 'format') and args.format in ['json', 'yaml']:
113
+ if hasattr(args, "format") and args.format in ["json", "yaml"]:
111
114
  command.print_result(result, args)
112
115
 
113
116
  return result.exit_code
@@ -123,19 +126,18 @@ def aggregate_command_legacy(args):
123
126
 
124
127
  if subcommand == "start":
125
128
  return start_command_legacy(args)
126
- elif subcommand == "stop":
129
+ if subcommand == "stop":
127
130
  return stop_command_legacy(args)
128
- elif subcommand == "status":
131
+ if subcommand == "status":
129
132
  return status_command_legacy(args)
130
- elif subcommand == "sessions":
133
+ if subcommand == "sessions":
131
134
  return sessions_command_legacy(args)
132
- elif subcommand == "view":
135
+ if subcommand == "view":
133
136
  return view_command_legacy(args)
134
- elif subcommand == "export":
137
+ if subcommand == "export":
135
138
  return export_command_legacy(args)
136
- else:
137
- print(f"Unknown subcommand: {subcommand}", file=sys.stderr)
138
- return 1
139
+ print(f"Unknown subcommand: {subcommand}", file=sys.stderr)
140
+ return 1
139
141
 
140
142
 
141
143
  def start_command_legacy(args):
@@ -165,12 +167,12 @@ def start_command_legacy(args):
165
167
  # Start the aggregator
166
168
  if start_aggregator():
167
169
  print("✅ Event Aggregator started successfully")
168
- print(f"Capturing events from localhost:8765")
169
- print(f"Sessions will be saved to: .claude-mpm/sessions/")
170
+ print("Capturing events from localhost:8765")
171
+ print("Sessions will be saved to: .claude-mpm/sessions/")
170
172
 
171
173
  # Show initial status
172
174
  status = aggregator_status()
173
- print(f"\nStatus:")
175
+ print("\nStatus:")
174
176
  print(f" Connected: {status['connected']}")
175
177
  print(f" Active sessions: {status['active_sessions']}")
176
178
 
@@ -191,10 +193,9 @@ def start_command_legacy(args):
191
193
  stop_aggregator()
192
194
 
193
195
  return 0
194
- else:
195
- print(" Failed to start Event Aggregator")
196
- print("Check that python-socketio is installed: pip install python-socketio")
197
- return 1
196
+ print("❌ Failed to start Event Aggregator")
197
+ print("Check that python-socketio is installed: pip install python-socketio")
198
+ return 1
198
199
 
199
200
 
200
201
  def stop_command_legacy(args):
@@ -216,10 +217,10 @@ def stop_command_legacy(args):
216
217
 
217
218
  # Show final statistics
218
219
  if status["total_events"] > 0:
219
- print(f"\nStatistics:")
220
+ print("\nStatistics:")
220
221
  print(f" Total events captured: {status['total_events']}")
221
222
  print(f" Sessions completed: {status['sessions_completed']}")
222
- print(f" Events by type:")
223
+ print(" Events by type:")
223
224
  for event_type, count in sorted(
224
225
  status["events_by_type"].items(), key=lambda x: x[1], reverse=True
225
226
  )[:5]:
@@ -285,7 +286,7 @@ def sessions_command_legacy(args):
285
286
  print(f" Delegations: {session['delegations']}")
286
287
  print(f" Prompt: {session['initial_prompt']}")
287
288
 
288
- print(f"\nUse 'claude-mpm aggregate view <session_id>' to view details")
289
+ print("\nUse 'claude-mpm aggregate view <session_id>' to view details")
289
290
 
290
291
  return 0
291
292
 
@@ -315,7 +316,7 @@ def view_command_legacy(args):
315
316
  if session.git_branch:
316
317
  print(f"Git branch: {session.git_branch}")
317
318
 
318
- print(f"\nInitial prompt:")
319
+ print("\nInitial prompt:")
319
320
  print("-" * 40)
320
321
  if session.initial_prompt:
321
322
  print(session.initial_prompt[:500])
@@ -324,7 +325,7 @@ def view_command_legacy(args):
324
325
  else:
325
326
  print("(No prompt captured)")
326
327
 
327
- print(f"\nMetrics:")
328
+ print("\nMetrics:")
328
329
  print("-" * 40)
329
330
  metrics = session.metrics
330
331
  print(f"Total events: {metrics.total_events}")
@@ -376,7 +377,7 @@ def view_command_legacy(args):
376
377
  print(f" Correlation: {event.correlation_id}")
377
378
 
378
379
  if session.final_response and not args.no_response:
379
- print(f"\nFinal response:")
380
+ print("\nFinal response:")
380
381
  print("-" * 40)
381
382
  print(session.final_response[:1000])
382
383
  if len(session.final_response) > 1000:
@@ -154,12 +154,12 @@ def analyze_claude_json(file_path: Path) -> Tuple[Dict[str, Any], List[str]]:
154
154
  stats["file_size"] = file_stat.st_size
155
155
 
156
156
  # Count lines
157
- with open(file_path, "r") as f:
157
+ with open(file_path) as f:
158
158
  stats["line_count"] = sum(1 for _ in f)
159
159
 
160
160
  # Try to parse JSON structure
161
161
  try:
162
- with open(file_path, "r") as f:
162
+ with open(file_path) as f:
163
163
  data = json.load(f)
164
164
 
165
165
  # Analyze conversation structure
@@ -279,14 +279,14 @@ class CleanupCommand(BaseCommand):
279
279
  def validate_args(self, args) -> str:
280
280
  """Validate command arguments."""
281
281
  # Validate max_size format
282
- max_size = getattr(args, 'max_size', '500KB')
282
+ max_size = getattr(args, "max_size", "500KB")
283
283
  try:
284
284
  parse_size(max_size)
285
285
  except ValueError as e:
286
286
  return str(e)
287
287
 
288
288
  # Validate days
289
- days = getattr(args, 'days', 30)
289
+ days = getattr(args, "days", 30)
290
290
  if days < 0:
291
291
  return "Days must be a positive number"
292
292
 
@@ -298,20 +298,22 @@ class CleanupCommand(BaseCommand):
298
298
  # Gather cleanup information
299
299
  cleanup_data = self._analyze_cleanup_needs(args)
300
300
 
301
- output_format = getattr(args, 'format', 'text')
301
+ output_format = getattr(args, "format", "text")
302
302
 
303
- if output_format in ['json', 'yaml']:
303
+ if output_format in ["json", "yaml"]:
304
304
  # Structured output
305
- if getattr(args, 'dry_run', False):
306
- return CommandResult.success_result("Cleanup analysis completed (dry run)", data=cleanup_data)
307
- else:
308
- # Perform actual cleanup
309
- result_data = self._perform_cleanup(args, cleanup_data)
310
- return CommandResult.success_result("Cleanup completed", data=result_data)
311
- else:
312
- # Text output using existing function
313
- cleanup_memory(args)
314
- return CommandResult.success_result("Cleanup completed")
305
+ if getattr(args, "dry_run", False):
306
+ return CommandResult.success_result(
307
+ "Cleanup analysis completed (dry run)", data=cleanup_data
308
+ )
309
+ # Perform actual cleanup
310
+ result_data = self._perform_cleanup(args, cleanup_data)
311
+ return CommandResult.success_result(
312
+ "Cleanup completed", data=result_data
313
+ )
314
+ # Text output using existing function
315
+ cleanup_memory(args)
316
+ return CommandResult.success_result("Cleanup completed")
315
317
 
316
318
  except Exception as e:
317
319
  self.logger.error(f"Error during cleanup: {e}", exc_info=True)
@@ -327,14 +329,14 @@ class CleanupCommand(BaseCommand):
327
329
  "file_exists": False,
328
330
  "file_path": str(claude_json),
329
331
  "needs_cleanup": False,
330
- "message": "No .claude.json file found - nothing to clean up"
332
+ "message": "No .claude.json file found - nothing to clean up",
331
333
  }
332
334
 
333
335
  # Analyze current state
334
336
  stats, issues = analyze_claude_json(claude_json)
335
337
 
336
338
  # Check if cleanup is needed
337
- max_size = parse_size(getattr(args, 'max_size', '500KB'))
339
+ max_size = parse_size(getattr(args, "max_size", "500KB"))
338
340
  needs_cleanup = stats["file_size"] > max_size
339
341
 
340
342
  return {
@@ -348,11 +350,11 @@ class CleanupCommand(BaseCommand):
348
350
  "max_size_formatted": format_size(max_size),
349
351
  "current_size_formatted": format_size(stats["file_size"]),
350
352
  "settings": {
351
- "days": getattr(args, 'days', 30),
352
- "archive": getattr(args, 'archive', True),
353
- "force": getattr(args, 'force', False),
354
- "dry_run": getattr(args, 'dry_run', False)
355
- }
353
+ "days": getattr(args, "days", 30),
354
+ "archive": getattr(args, "archive", True),
355
+ "force": getattr(args, "force", False),
356
+ "dry_run": getattr(args, "dry_run", False),
357
+ },
356
358
  }
357
359
 
358
360
  def _perform_cleanup(self, args, cleanup_data: Dict[str, Any]) -> Dict[str, Any]:
@@ -366,11 +368,14 @@ class CleanupCommand(BaseCommand):
366
368
  "original_size": cleanup_data["stats"]["file_size"],
367
369
  "new_size": cleanup_data["stats"]["file_size"],
368
370
  "savings": 0,
369
- "old_archives_removed": 0
371
+ "old_archives_removed": 0,
370
372
  }
371
373
 
372
374
  # Create archive if requested
373
- if cleanup_data["settings"]["archive"] and not cleanup_data["settings"]["dry_run"]:
375
+ if (
376
+ cleanup_data["settings"]["archive"]
377
+ and not cleanup_data["settings"]["dry_run"]
378
+ ):
374
379
  try:
375
380
  archive_path = create_archive(claude_json, archive_dir)
376
381
  result["archive_created"] = True
@@ -382,7 +387,7 @@ class CleanupCommand(BaseCommand):
382
387
  original_size, new_size = clean_claude_json(
383
388
  claude_json,
384
389
  keep_days=cleanup_data["settings"]["days"],
385
- dry_run=cleanup_data["settings"]["dry_run"]
390
+ dry_run=cleanup_data["settings"]["dry_run"],
386
391
  )
387
392
 
388
393
  result["original_size"] = original_size
@@ -390,7 +395,10 @@ class CleanupCommand(BaseCommand):
390
395
  result["savings"] = original_size - new_size
391
396
 
392
397
  # Clean up old archives
393
- if cleanup_data["settings"]["archive"] and not cleanup_data["settings"]["dry_run"]:
398
+ if (
399
+ cleanup_data["settings"]["archive"]
400
+ and not cleanup_data["settings"]["dry_run"]
401
+ ):
394
402
  old_archives = clean_old_archives(archive_dir, keep_days=90)
395
403
  result["old_archives_removed"] = len(old_archives)
396
404
 
@@ -411,6 +419,7 @@ def cleanup_memory(args):
411
419
  def _cleanup_memory_original(args):
412
420
  """Original cleanup implementation for backward compatibility."""
413
421
  from ...core.logger import get_logger
422
+
414
423
  logger = get_logger("cleanup")
415
424
 
416
425
  # File paths
@@ -444,7 +453,7 @@ def _cleanup_memory_original(args):
444
453
  return
445
454
  else:
446
455
  print(f"⚠️ File size exceeds recommended limit of {format_size(max_size)}")
447
- print(f" This can cause memory issues when using --resume")
456
+ print(" This can cause memory issues when using --resume")
448
457
 
449
458
  # Show large conversations if any
450
459
  if stats["large_conversations"]:
@@ -455,12 +464,12 @@ def _cleanup_memory_original(args):
455
464
  )
456
465
 
457
466
  # Show cleanup plan
458
- print(f"\n📋 Cleanup Plan:")
467
+ print("\n📋 Cleanup Plan:")
459
468
  print(f" • Keep conversations from last {args.days} days")
460
469
  if args.archive:
461
470
  print(f" • Archive old conversations to: {archive_dir}")
462
471
  else:
463
- print(f" • Delete old conversations (no archive)")
472
+ print(" • Delete old conversations (no archive)")
464
473
 
465
474
  if args.dry_run:
466
475
  print("\n🔍 DRY RUN MODE - No changes will be made")
@@ -496,7 +505,7 @@ def _cleanup_memory_original(args):
496
505
 
497
506
  # Create backup/archive
498
507
  if args.archive and not args.dry_run:
499
- print(f"\n📦 Creating archive...")
508
+ print("\n📦 Creating archive...")
500
509
  try:
501
510
  archive_path = create_archive(claude_json, archive_dir)
502
511
  archive_size = archive_path.stat().st_size
@@ -510,7 +519,7 @@ def _cleanup_memory_original(args):
510
519
  return
511
520
 
512
521
  # Perform cleanup
513
- print(f"\n🧹 Cleaning up conversation history...")
522
+ print("\n🧹 Cleaning up conversation history...")
514
523
 
515
524
  try:
516
525
  original_size, new_size = clean_claude_json(
@@ -522,18 +531,15 @@ def _cleanup_memory_original(args):
522
531
  f"📊 Would reduce size from {format_size(original_size)} to ~{format_size(new_size)}"
523
532
  )
524
533
  print(f"💾 Estimated savings: {format_size(original_size - new_size)}")
534
+ elif new_size < original_size:
535
+ print("✅ Cleanup complete!")
536
+ print(
537
+ f"📊 Reduced size from {format_size(original_size)} to {format_size(new_size)}"
538
+ )
539
+ print(f"💾 Saved: {format_size(original_size - new_size)}")
525
540
  else:
526
- if new_size < original_size:
527
- print(f" Cleanup complete!")
528
- print(
529
- f"📊 Reduced size from {format_size(original_size)} to {format_size(new_size)}"
530
- )
531
- print(f"💾 Saved: {format_size(original_size - new_size)}")
532
- else:
533
- print(f"ℹ️ No conversations were old enough to clean up")
534
- print(
535
- f"💡 Try using --days with a smaller value to clean more aggressively"
536
- )
541
+ print("ℹ️ No conversations were old enough to clean up")
542
+ print("💡 Try using --days with a smaller value to clean more aggressively")
537
543
 
538
544
  except Exception as e:
539
545
  logger.error(f"Cleanup failed: {e}")
@@ -542,7 +548,7 @@ def _cleanup_memory_original(args):
542
548
 
543
549
  # Clean up old archive files
544
550
  if args.archive and not args.dry_run:
545
- print(f"\n🗑️ Cleaning up old archives...")
551
+ print("\n🗑️ Cleaning up old archives...")
546
552
  old_archives = clean_old_archives(archive_dir, keep_days=90)
547
553
  if old_archives:
548
554
  print(f"✅ Removed {len(old_archives)} old archive files")
@@ -11,13 +11,13 @@ from typing import Optional
11
11
 
12
12
  from claude_mpm.core.logging_config import get_logger
13
13
  from claude_mpm.services.agents.deployment.multi_source_deployment_service import (
14
- MultiSourceAgentDeploymentService
14
+ MultiSourceAgentDeploymentService,
15
15
  )
16
16
 
17
17
 
18
18
  def add_parser(subparsers: argparse._SubParsersAction) -> None:
19
19
  """Add the cleanup-orphaned-agents command parser.
20
-
20
+
21
21
  Args:
22
22
  subparsers: The subparsers object from argparse
23
23
  """
@@ -30,46 +30,46 @@ def add_parser(subparsers: argparse._SubParsersAction) -> None:
30
30
  "from the system or when switching between agent sources."
31
31
  ),
32
32
  )
33
-
33
+
34
34
  parser.add_argument(
35
35
  "--agents-dir",
36
36
  type=Path,
37
37
  help="Directory containing deployed agents (default: .claude/agents/)",
38
38
  )
39
-
39
+
40
40
  parser.add_argument(
41
41
  "--dry-run",
42
42
  action="store_true",
43
43
  default=True,
44
44
  help="Only show what would be removed without actually removing (default)",
45
45
  )
46
-
46
+
47
47
  parser.add_argument(
48
48
  "--force",
49
49
  action="store_true",
50
50
  help="Actually remove orphaned agents (disables dry-run)",
51
51
  )
52
-
52
+
53
53
  parser.add_argument(
54
54
  "--quiet",
55
55
  action="store_true",
56
56
  help="Only show summary, not individual agents",
57
57
  )
58
-
58
+
59
59
  parser.set_defaults(func=cleanup_orphaned_agents)
60
60
 
61
61
 
62
62
  def cleanup_orphaned_agents(args: argparse.Namespace) -> int:
63
63
  """Clean up orphaned agents.
64
-
64
+
65
65
  Args:
66
66
  args: Command line arguments
67
-
67
+
68
68
  Returns:
69
69
  Exit code (0 for success, non-zero for errors)
70
70
  """
71
71
  logger = get_logger(__name__)
72
-
72
+
73
73
  # Determine agents directory
74
74
  if args.agents_dir:
75
75
  agents_dir = args.agents_dir
@@ -81,33 +81,33 @@ def cleanup_orphaned_agents(args: argparse.Namespace) -> int:
81
81
  else:
82
82
  # Fall back to user home directory
83
83
  agents_dir = Path.home() / ".claude" / "agents"
84
-
84
+
85
85
  if not agents_dir.exists():
86
86
  logger.info(f"Agents directory not found: {agents_dir}")
87
87
  return 0
88
-
88
+
89
89
  logger.info(f"Checking for orphaned agents in: {agents_dir}")
90
-
90
+
91
91
  # Initialize service
92
92
  service = MultiSourceAgentDeploymentService()
93
-
93
+
94
94
  # Determine if we're doing a dry run
95
95
  dry_run = args.dry_run and not args.force
96
-
96
+
97
97
  try:
98
98
  # Perform cleanup
99
99
  results = service.cleanup_orphaned_agents(agents_dir, dry_run=dry_run)
100
-
100
+
101
101
  # Handle results
102
102
  if not results["orphaned"]:
103
103
  logger.info("✅ No orphaned agents found")
104
104
  return 0
105
-
105
+
106
106
  if not args.quiet:
107
107
  logger.info(f"\nFound {len(results['orphaned'])} orphaned agent(s):")
108
108
  for orphan in results["orphaned"]:
109
109
  logger.info(f" - {orphan['name']} v{orphan['version']}")
110
-
110
+
111
111
  if dry_run:
112
112
  logger.info(
113
113
  f"\n📝 This was a dry run. Use --force to actually remove "
@@ -118,15 +118,15 @@ def cleanup_orphaned_agents(args: argparse.Namespace) -> int:
118
118
  logger.info(
119
119
  f"\n✅ Successfully removed {len(results['removed'])} orphaned agent(s)"
120
120
  )
121
-
121
+
122
122
  if results["errors"]:
123
123
  logger.error(f"\n❌ Encountered {len(results['errors'])} error(s):")
124
124
  for error in results["errors"]:
125
125
  logger.error(f" - {error}")
126
126
  return 1
127
-
127
+
128
128
  return 0
129
-
129
+
130
130
  except Exception as e:
131
131
  logger.error(f"Error during cleanup: {e}")
132
132
  return 1
@@ -135,10 +135,10 @@ def cleanup_orphaned_agents(args: argparse.Namespace) -> int:
135
135
  # For backward compatibility
136
136
  def main(args: Optional[argparse.Namespace] = None) -> int:
137
137
  """Main entry point for the command.
138
-
138
+
139
139
  Args:
140
140
  args: Command line arguments
141
-
141
+
142
142
  Returns:
143
143
  Exit code
144
144
  """
@@ -146,5 +146,5 @@ def main(args: Optional[argparse.Namespace] = None) -> int:
146
146
  parser = argparse.ArgumentParser()
147
147
  add_parser(parser.add_subparsers())
148
148
  args = parser.parse_args()
149
-
150
- return cleanup_orphaned_agents(args)
149
+
150
+ return cleanup_orphaned_agents(args)