claude-mpm 4.1.0__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 (358) 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 +133 -58
  21. claude_mpm/agents/templates/web_ui.json +3 -3
  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 +271 -268
  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 +192 -141
  39. claude_mpm/cli/commands/monitor.py +117 -88
  40. claude_mpm/cli/commands/run.py +120 -84
  41. claude_mpm/cli/commands/run_config_checker.py +4 -5
  42. claude_mpm/cli/commands/socketio_monitor.py +17 -19
  43. claude_mpm/cli/commands/tickets.py +92 -92
  44. claude_mpm/cli/parser.py +1 -5
  45. claude_mpm/cli/parsers/__init__.py +1 -1
  46. claude_mpm/cli/parsers/agent_manager_parser.py +50 -98
  47. claude_mpm/cli/parsers/agents_parser.py +2 -3
  48. claude_mpm/cli/parsers/base_parser.py +7 -5
  49. claude_mpm/cli/parsers/mcp_parser.py +4 -2
  50. claude_mpm/cli/parsers/monitor_parser.py +26 -18
  51. claude_mpm/cli/shared/__init__.py +10 -10
  52. claude_mpm/cli/shared/argument_patterns.py +57 -71
  53. claude_mpm/cli/shared/base_command.py +61 -53
  54. claude_mpm/cli/shared/error_handling.py +62 -58
  55. claude_mpm/cli/shared/output_formatters.py +78 -77
  56. claude_mpm/cli/startup_logging.py +204 -172
  57. claude_mpm/cli/utils.py +10 -11
  58. claude_mpm/cli_module/__init__.py +1 -1
  59. claude_mpm/cli_module/args.py +1 -1
  60. claude_mpm/cli_module/migration_example.py +5 -5
  61. claude_mpm/config/__init__.py +9 -9
  62. claude_mpm/config/agent_config.py +15 -14
  63. claude_mpm/config/experimental_features.py +4 -4
  64. claude_mpm/config/paths.py +0 -1
  65. claude_mpm/config/socketio_config.py +5 -6
  66. claude_mpm/constants.py +1 -2
  67. claude_mpm/core/__init__.py +8 -8
  68. claude_mpm/core/agent_name_normalizer.py +1 -1
  69. claude_mpm/core/agent_registry.py +20 -23
  70. claude_mpm/core/agent_session_manager.py +3 -3
  71. claude_mpm/core/base_service.py +7 -15
  72. claude_mpm/core/cache.py +4 -6
  73. claude_mpm/core/claude_runner.py +85 -113
  74. claude_mpm/core/config.py +43 -28
  75. claude_mpm/core/config_aliases.py +0 -9
  76. claude_mpm/core/config_constants.py +52 -30
  77. claude_mpm/core/constants.py +0 -1
  78. claude_mpm/core/container.py +18 -27
  79. claude_mpm/core/exceptions.py +2 -2
  80. claude_mpm/core/factories.py +10 -12
  81. claude_mpm/core/framework_loader.py +581 -280
  82. claude_mpm/core/hook_manager.py +26 -22
  83. claude_mpm/core/hook_performance_config.py +58 -47
  84. claude_mpm/core/injectable_service.py +1 -1
  85. claude_mpm/core/interactive_session.py +61 -152
  86. claude_mpm/core/interfaces.py +1 -100
  87. claude_mpm/core/lazy.py +5 -5
  88. claude_mpm/core/log_manager.py +587 -0
  89. claude_mpm/core/logger.py +125 -8
  90. claude_mpm/core/logging_config.py +15 -15
  91. claude_mpm/core/minimal_framework_loader.py +5 -8
  92. claude_mpm/core/oneshot_session.py +15 -33
  93. claude_mpm/core/optimized_agent_loader.py +4 -6
  94. claude_mpm/core/optimized_startup.py +2 -1
  95. claude_mpm/core/output_style_manager.py +147 -106
  96. claude_mpm/core/pm_hook_interceptor.py +0 -1
  97. claude_mpm/core/service_registry.py +11 -8
  98. claude_mpm/core/session_manager.py +1 -2
  99. claude_mpm/core/shared/__init__.py +1 -1
  100. claude_mpm/core/shared/config_loader.py +101 -97
  101. claude_mpm/core/shared/path_resolver.py +72 -68
  102. claude_mpm/core/shared/singleton_manager.py +56 -50
  103. claude_mpm/core/socketio_pool.py +26 -6
  104. claude_mpm/core/tool_access_control.py +4 -5
  105. claude_mpm/core/typing_utils.py +50 -59
  106. claude_mpm/core/unified_agent_registry.py +14 -19
  107. claude_mpm/core/unified_config.py +4 -6
  108. claude_mpm/core/unified_paths.py +197 -109
  109. claude_mpm/dashboard/open_dashboard.py +2 -4
  110. claude_mpm/experimental/cli_enhancements.py +51 -36
  111. claude_mpm/generators/agent_profile_generator.py +2 -4
  112. claude_mpm/hooks/base_hook.py +1 -2
  113. claude_mpm/hooks/claude_hooks/connection_pool.py +72 -26
  114. claude_mpm/hooks/claude_hooks/event_handlers.py +93 -38
  115. claude_mpm/hooks/claude_hooks/hook_handler.py +130 -76
  116. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +104 -77
  117. claude_mpm/hooks/claude_hooks/memory_integration.py +2 -4
  118. claude_mpm/hooks/claude_hooks/response_tracking.py +15 -11
  119. claude_mpm/hooks/claude_hooks/tool_analysis.py +12 -18
  120. claude_mpm/hooks/memory_integration_hook.py +5 -5
  121. claude_mpm/hooks/tool_call_interceptor.py +1 -1
  122. claude_mpm/hooks/validation_hooks.py +4 -4
  123. claude_mpm/init.py +4 -9
  124. claude_mpm/models/__init__.py +2 -2
  125. claude_mpm/models/agent_session.py +11 -14
  126. claude_mpm/scripts/mcp_server.py +20 -11
  127. claude_mpm/scripts/mcp_wrapper.py +5 -5
  128. claude_mpm/scripts/mpm_doctor.py +321 -0
  129. claude_mpm/scripts/socketio_daemon.py +28 -25
  130. claude_mpm/scripts/socketio_daemon_hardened.py +298 -258
  131. claude_mpm/scripts/socketio_server_manager.py +116 -95
  132. claude_mpm/services/__init__.py +49 -49
  133. claude_mpm/services/agent_capabilities_service.py +12 -18
  134. claude_mpm/services/agents/__init__.py +22 -22
  135. claude_mpm/services/agents/agent_builder.py +140 -119
  136. claude_mpm/services/agents/deployment/__init__.py +3 -3
  137. claude_mpm/services/agents/deployment/agent_config_provider.py +9 -9
  138. claude_mpm/services/agents/deployment/agent_configuration_manager.py +19 -20
  139. claude_mpm/services/agents/deployment/agent_definition_factory.py +1 -5
  140. claude_mpm/services/agents/deployment/agent_deployment.py +136 -106
  141. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -8
  142. claude_mpm/services/agents/deployment/agent_environment_manager.py +2 -7
  143. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +6 -10
  144. claude_mpm/services/agents/deployment/agent_format_converter.py +11 -15
  145. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +2 -3
  146. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -5
  147. claude_mpm/services/agents/deployment/agent_metrics_collector.py +13 -19
  148. claude_mpm/services/agents/deployment/agent_restore_handler.py +0 -1
  149. claude_mpm/services/agents/deployment/agent_template_builder.py +26 -35
  150. claude_mpm/services/agents/deployment/agent_validator.py +0 -1
  151. claude_mpm/services/agents/deployment/agent_version_manager.py +7 -9
  152. claude_mpm/services/agents/deployment/agent_versioning.py +3 -3
  153. claude_mpm/services/agents/deployment/agents_directory_resolver.py +6 -7
  154. claude_mpm/services/agents/deployment/async_agent_deployment.py +51 -38
  155. claude_mpm/services/agents/deployment/config/__init__.py +1 -1
  156. claude_mpm/services/agents/deployment/config/deployment_config.py +7 -8
  157. claude_mpm/services/agents/deployment/deployment_type_detector.py +1 -1
  158. claude_mpm/services/agents/deployment/deployment_wrapper.py +18 -18
  159. claude_mpm/services/agents/deployment/facade/__init__.py +1 -1
  160. claude_mpm/services/agents/deployment/facade/deployment_executor.py +0 -3
  161. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -4
  162. claude_mpm/services/agents/deployment/interface_adapter.py +5 -7
  163. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +345 -276
  164. claude_mpm/services/agents/deployment/pipeline/__init__.py +2 -2
  165. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +1 -1
  166. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +6 -4
  167. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +3 -3
  168. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +2 -2
  169. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +14 -13
  170. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +0 -1
  171. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +1 -1
  172. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +8 -9
  173. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +1 -1
  174. claude_mpm/services/agents/deployment/processors/__init__.py +1 -1
  175. claude_mpm/services/agents/deployment/processors/agent_processor.py +20 -16
  176. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +5 -12
  177. claude_mpm/services/agents/deployment/results/__init__.py +1 -1
  178. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +1 -1
  179. claude_mpm/services/agents/deployment/strategies/__init__.py +2 -2
  180. claude_mpm/services/agents/deployment/strategies/base_strategy.py +1 -7
  181. claude_mpm/services/agents/deployment/strategies/project_strategy.py +1 -4
  182. claude_mpm/services/agents/deployment/strategies/system_strategy.py +2 -3
  183. claude_mpm/services/agents/deployment/strategies/user_strategy.py +3 -7
  184. claude_mpm/services/agents/deployment/validation/__init__.py +1 -1
  185. claude_mpm/services/agents/deployment/validation/agent_validator.py +1 -1
  186. claude_mpm/services/agents/deployment/validation/template_validator.py +2 -2
  187. claude_mpm/services/agents/deployment/validation/validation_result.py +2 -6
  188. claude_mpm/services/agents/loading/__init__.py +1 -1
  189. claude_mpm/services/agents/loading/agent_profile_loader.py +6 -12
  190. claude_mpm/services/agents/loading/base_agent_manager.py +5 -5
  191. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -4
  192. claude_mpm/services/agents/management/__init__.py +1 -1
  193. claude_mpm/services/agents/management/agent_capabilities_generator.py +1 -3
  194. claude_mpm/services/agents/management/agent_management_service.py +5 -9
  195. claude_mpm/services/agents/memory/__init__.py +4 -4
  196. claude_mpm/services/agents/memory/agent_memory_manager.py +280 -160
  197. claude_mpm/services/agents/memory/agent_persistence_service.py +0 -2
  198. claude_mpm/services/agents/memory/content_manager.py +44 -38
  199. claude_mpm/services/agents/memory/template_generator.py +4 -6
  200. claude_mpm/services/agents/registry/__init__.py +10 -6
  201. claude_mpm/services/agents/registry/deployed_agent_discovery.py +30 -27
  202. claude_mpm/services/agents/registry/modification_tracker.py +3 -6
  203. claude_mpm/services/async_session_logger.py +1 -2
  204. claude_mpm/services/claude_session_logger.py +1 -2
  205. claude_mpm/services/command_deployment_service.py +173 -0
  206. claude_mpm/services/command_handler_service.py +20 -22
  207. claude_mpm/services/core/__init__.py +25 -25
  208. claude_mpm/services/core/base.py +0 -5
  209. claude_mpm/services/core/interfaces/__init__.py +32 -32
  210. claude_mpm/services/core/interfaces/agent.py +0 -21
  211. claude_mpm/services/core/interfaces/communication.py +0 -27
  212. claude_mpm/services/core/interfaces/infrastructure.py +0 -56
  213. claude_mpm/services/core/interfaces/service.py +0 -29
  214. claude_mpm/services/diagnostics/__init__.py +1 -1
  215. claude_mpm/services/diagnostics/checks/__init__.py +6 -6
  216. claude_mpm/services/diagnostics/checks/agent_check.py +89 -80
  217. claude_mpm/services/diagnostics/checks/base_check.py +12 -16
  218. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +84 -81
  219. claude_mpm/services/diagnostics/checks/common_issues_check.py +99 -91
  220. claude_mpm/services/diagnostics/checks/configuration_check.py +82 -77
  221. claude_mpm/services/diagnostics/checks/filesystem_check.py +67 -68
  222. claude_mpm/services/diagnostics/checks/installation_check.py +254 -94
  223. claude_mpm/services/diagnostics/checks/mcp_check.py +90 -88
  224. claude_mpm/services/diagnostics/checks/monitor_check.py +75 -76
  225. claude_mpm/services/diagnostics/checks/startup_log_check.py +67 -73
  226. claude_mpm/services/diagnostics/diagnostic_runner.py +67 -59
  227. claude_mpm/services/diagnostics/doctor_reporter.py +107 -70
  228. claude_mpm/services/diagnostics/models.py +21 -19
  229. claude_mpm/services/event_aggregator.py +10 -17
  230. claude_mpm/services/event_bus/__init__.py +1 -1
  231. claude_mpm/services/event_bus/config.py +54 -35
  232. claude_mpm/services/event_bus/event_bus.py +76 -71
  233. claude_mpm/services/event_bus/relay.py +74 -64
  234. claude_mpm/services/events/__init__.py +11 -11
  235. claude_mpm/services/events/consumers/__init__.py +3 -3
  236. claude_mpm/services/events/consumers/dead_letter.py +71 -63
  237. claude_mpm/services/events/consumers/logging.py +39 -37
  238. claude_mpm/services/events/consumers/metrics.py +56 -57
  239. claude_mpm/services/events/consumers/socketio.py +82 -81
  240. claude_mpm/services/events/core.py +110 -99
  241. claude_mpm/services/events/interfaces.py +56 -72
  242. claude_mpm/services/events/producers/__init__.py +1 -1
  243. claude_mpm/services/events/producers/hook.py +38 -38
  244. claude_mpm/services/events/producers/system.py +46 -44
  245. claude_mpm/services/exceptions.py +81 -80
  246. claude_mpm/services/framework_claude_md_generator/__init__.py +2 -4
  247. claude_mpm/services/framework_claude_md_generator/content_assembler.py +3 -5
  248. claude_mpm/services/framework_claude_md_generator/content_validator.py +1 -1
  249. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +4 -4
  250. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +0 -1
  251. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +0 -2
  252. claude_mpm/services/framework_claude_md_generator/version_manager.py +4 -5
  253. claude_mpm/services/hook_service.py +6 -9
  254. claude_mpm/services/infrastructure/__init__.py +1 -1
  255. claude_mpm/services/infrastructure/context_preservation.py +8 -12
  256. claude_mpm/services/infrastructure/monitoring.py +21 -23
  257. claude_mpm/services/mcp_gateway/__init__.py +37 -37
  258. claude_mpm/services/mcp_gateway/auto_configure.py +95 -103
  259. claude_mpm/services/mcp_gateway/config/__init__.py +1 -1
  260. claude_mpm/services/mcp_gateway/config/config_loader.py +23 -25
  261. claude_mpm/services/mcp_gateway/config/config_schema.py +5 -5
  262. claude_mpm/services/mcp_gateway/config/configuration.py +9 -6
  263. claude_mpm/services/mcp_gateway/core/__init__.py +10 -10
  264. claude_mpm/services/mcp_gateway/core/base.py +0 -3
  265. claude_mpm/services/mcp_gateway/core/interfaces.py +1 -38
  266. claude_mpm/services/mcp_gateway/core/process_pool.py +99 -93
  267. claude_mpm/services/mcp_gateway/core/singleton_manager.py +65 -62
  268. claude_mpm/services/mcp_gateway/core/startup_verification.py +75 -74
  269. claude_mpm/services/mcp_gateway/main.py +2 -1
  270. claude_mpm/services/mcp_gateway/registry/service_registry.py +5 -8
  271. claude_mpm/services/mcp_gateway/registry/tool_registry.py +1 -1
  272. claude_mpm/services/mcp_gateway/server/__init__.py +1 -1
  273. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +12 -19
  274. claude_mpm/services/mcp_gateway/server/stdio_handler.py +4 -3
  275. claude_mpm/services/mcp_gateway/server/stdio_server.py +79 -71
  276. claude_mpm/services/mcp_gateway/tools/__init__.py +2 -2
  277. claude_mpm/services/mcp_gateway/tools/base_adapter.py +5 -6
  278. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +13 -22
  279. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +79 -78
  280. claude_mpm/services/mcp_gateway/tools/hello_world.py +12 -14
  281. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +42 -49
  282. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +51 -55
  283. claude_mpm/services/memory/__init__.py +3 -3
  284. claude_mpm/services/memory/builder.py +3 -6
  285. claude_mpm/services/memory/cache/__init__.py +1 -1
  286. claude_mpm/services/memory/cache/shared_prompt_cache.py +3 -5
  287. claude_mpm/services/memory/cache/simple_cache.py +1 -1
  288. claude_mpm/services/memory/indexed_memory.py +5 -7
  289. claude_mpm/services/memory/optimizer.py +7 -10
  290. claude_mpm/services/memory/router.py +8 -9
  291. claude_mpm/services/memory_hook_service.py +48 -34
  292. claude_mpm/services/monitor_build_service.py +77 -73
  293. claude_mpm/services/port_manager.py +130 -108
  294. claude_mpm/services/project/analyzer.py +12 -10
  295. claude_mpm/services/project/registry.py +11 -11
  296. claude_mpm/services/recovery_manager.py +10 -19
  297. claude_mpm/services/response_tracker.py +0 -1
  298. claude_mpm/services/runner_configuration_service.py +19 -20
  299. claude_mpm/services/session_management_service.py +7 -11
  300. claude_mpm/services/shared/__init__.py +1 -1
  301. claude_mpm/services/shared/async_service_base.py +58 -50
  302. claude_mpm/services/shared/config_service_base.py +73 -67
  303. claude_mpm/services/shared/lifecycle_service_base.py +82 -78
  304. claude_mpm/services/shared/manager_base.py +94 -82
  305. claude_mpm/services/shared/service_factory.py +96 -98
  306. claude_mpm/services/socketio/__init__.py +3 -3
  307. claude_mpm/services/socketio/client_proxy.py +5 -5
  308. claude_mpm/services/socketio/event_normalizer.py +199 -181
  309. claude_mpm/services/socketio/handlers/__init__.py +3 -3
  310. claude_mpm/services/socketio/handlers/base.py +5 -4
  311. claude_mpm/services/socketio/handlers/connection.py +163 -136
  312. claude_mpm/services/socketio/handlers/file.py +13 -14
  313. claude_mpm/services/socketio/handlers/git.py +12 -7
  314. claude_mpm/services/socketio/handlers/hook.py +49 -44
  315. claude_mpm/services/socketio/handlers/memory.py +0 -1
  316. claude_mpm/services/socketio/handlers/project.py +0 -1
  317. claude_mpm/services/socketio/handlers/registry.py +37 -19
  318. claude_mpm/services/socketio/migration_utils.py +98 -84
  319. claude_mpm/services/socketio/server/__init__.py +1 -1
  320. claude_mpm/services/socketio/server/broadcaster.py +81 -87
  321. claude_mpm/services/socketio/server/core.py +65 -54
  322. claude_mpm/services/socketio/server/eventbus_integration.py +95 -56
  323. claude_mpm/services/socketio/server/main.py +64 -38
  324. claude_mpm/services/socketio_client_manager.py +10 -12
  325. claude_mpm/services/subprocess_launcher_service.py +4 -7
  326. claude_mpm/services/system_instructions_service.py +13 -14
  327. claude_mpm/services/ticket_manager.py +2 -2
  328. claude_mpm/services/utility_service.py +5 -13
  329. claude_mpm/services/version_control/__init__.py +16 -16
  330. claude_mpm/services/version_control/branch_strategy.py +5 -8
  331. claude_mpm/services/version_control/conflict_resolution.py +9 -23
  332. claude_mpm/services/version_control/git_operations.py +5 -7
  333. claude_mpm/services/version_control/semantic_versioning.py +16 -17
  334. claude_mpm/services/version_control/version_parser.py +13 -18
  335. claude_mpm/services/version_service.py +10 -11
  336. claude_mpm/storage/__init__.py +1 -1
  337. claude_mpm/storage/state_storage.py +22 -28
  338. claude_mpm/utils/__init__.py +6 -6
  339. claude_mpm/utils/agent_dependency_loader.py +47 -33
  340. claude_mpm/utils/config_manager.py +11 -14
  341. claude_mpm/utils/dependency_cache.py +1 -1
  342. claude_mpm/utils/dependency_manager.py +13 -17
  343. claude_mpm/utils/dependency_strategies.py +8 -10
  344. claude_mpm/utils/environment_context.py +3 -9
  345. claude_mpm/utils/error_handler.py +3 -13
  346. claude_mpm/utils/file_utils.py +1 -1
  347. claude_mpm/utils/path_operations.py +8 -12
  348. claude_mpm/utils/robust_installer.py +110 -33
  349. claude_mpm/utils/subprocess_utils.py +5 -6
  350. claude_mpm/validation/agent_validator.py +3 -6
  351. claude_mpm/validation/frontmatter_validator.py +1 -1
  352. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/METADATA +1 -1
  353. claude_mpm-4.1.2.dist-info/RECORD +498 -0
  354. claude_mpm-4.1.0.dist-info/RECORD +0 -494
  355. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/WHEEL +0 -0
  356. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/entry_points.txt +0 -0
  357. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/licenses/LICENSE +0 -0
  358. {claude_mpm-4.1.0.dist-info → claude_mpm-4.1.2.dist-info}/top_level.txt +0 -0
@@ -14,16 +14,18 @@ DESIGN DECISIONS:
14
14
  import json
15
15
  import os
16
16
  from pathlib import Path
17
- from typing import Any, Dict, Optional
18
17
 
19
18
  import yaml
20
19
 
21
20
  from ...agents.frontmatter_validator import FrontmatterValidator
22
21
  from ...constants import AgentCommands
23
22
  from ...core.agent_registry import AgentRegistryAdapter
24
- from ...core.config import Config
23
+ from ...core.logger import get_logger
25
24
  from ...core.shared.config_loader import ConfigLoader
26
- from ..shared import AgentCommand, CommandResult, add_agent_arguments, add_output_arguments
25
+ from ..shared import (
26
+ AgentCommand,
27
+ CommandResult,
28
+ )
27
29
  from ..utils import get_agent_versions_display
28
30
 
29
31
 
@@ -40,7 +42,10 @@ class AgentsCommand(AgentCommand):
40
42
  if self._deployment_service is None:
41
43
  try:
42
44
  from ...services import AgentDeploymentService
43
- from ...services.agents.deployment.deployment_wrapper import DeploymentServiceWrapper
45
+ from ...services.agents.deployment.deployment_wrapper import (
46
+ DeploymentServiceWrapper,
47
+ )
48
+
44
49
  base_service = AgentDeploymentService()
45
50
  self._deployment_service = DeploymentServiceWrapper(base_service)
46
51
  except ImportError:
@@ -56,14 +61,18 @@ class AgentsCommand(AgentCommand):
56
61
  """Execute the agent command."""
57
62
  try:
58
63
  # Handle default case (no subcommand)
59
- if not hasattr(args, 'agents_command') or not args.agents_command:
64
+ if not hasattr(args, "agents_command") or not args.agents_command:
60
65
  return self._show_agent_versions(args)
61
66
 
62
67
  # Route to appropriate subcommand
63
68
  command_map = {
64
69
  AgentCommands.LIST.value: self._list_agents,
65
- AgentCommands.DEPLOY.value: lambda a: self._deploy_agents(a, force=False),
66
- AgentCommands.FORCE_DEPLOY.value: lambda a: self._deploy_agents(a, force=True),
70
+ AgentCommands.DEPLOY.value: lambda a: self._deploy_agents(
71
+ a, force=False
72
+ ),
73
+ AgentCommands.FORCE_DEPLOY.value: lambda a: self._deploy_agents(
74
+ a, force=True
75
+ ),
67
76
  AgentCommands.CLEAN.value: self._clean_agents,
68
77
  AgentCommands.VIEW.value: self._view_agent,
69
78
  AgentCommands.FIX.value: self._fix_agents,
@@ -76,10 +85,11 @@ class AgentsCommand(AgentCommand):
76
85
 
77
86
  if args.agents_command in command_map:
78
87
  return command_map[args.agents_command](args)
79
- else:
80
- return CommandResult.error_result(f"Unknown agent command: {args.agents_command}")
88
+ return CommandResult.error_result(
89
+ f"Unknown agent command: {args.agents_command}"
90
+ )
81
91
 
82
- except ImportError as e:
92
+ except ImportError:
83
93
  self.logger.error("Agent deployment service not available")
84
94
  return CommandResult.error_result("Agent deployment service not available")
85
95
  except Exception as e:
@@ -91,53 +101,58 @@ class AgentsCommand(AgentCommand):
91
101
  try:
92
102
  agent_versions = get_agent_versions_display()
93
103
 
94
- output_format = getattr(args, 'format', 'text')
95
- if output_format in ['json', 'yaml']:
104
+ output_format = getattr(args, "format", "text")
105
+ if output_format in ["json", "yaml"]:
96
106
  # Parse the agent versions display into structured data
97
107
  if agent_versions:
98
108
  data = {"agent_versions": agent_versions, "has_agents": True}
99
- return CommandResult.success_result("Agent versions retrieved", data=data)
100
- else:
101
- data = {"agent_versions": None, "has_agents": False, "suggestion": "To deploy agents, run: claude-mpm --mpm:agents deploy"}
102
- return CommandResult.success_result("No deployed agents found", data=data)
103
- else:
104
- # Text output
105
- if agent_versions:
106
- print(agent_versions)
107
- return CommandResult.success_result("Agent versions displayed")
108
- else:
109
- print("No deployed agents found")
110
- print("\nTo deploy agents, run: claude-mpm --mpm:agents deploy")
111
- return CommandResult.success_result("No deployed agents found")
109
+ return CommandResult.success_result(
110
+ "Agent versions retrieved", data=data
111
+ )
112
+ data = {
113
+ "agent_versions": None,
114
+ "has_agents": False,
115
+ "suggestion": "To deploy agents, run: claude-mpm --mpm:agents deploy",
116
+ }
117
+ return CommandResult.success_result(
118
+ "No deployed agents found", data=data
119
+ )
120
+ # Text output
121
+ if agent_versions:
122
+ print(agent_versions)
123
+ return CommandResult.success_result("Agent versions displayed")
124
+ print("No deployed agents found")
125
+ print("\nTo deploy agents, run: claude-mpm --mpm:agents deploy")
126
+ return CommandResult.success_result("No deployed agents found")
112
127
 
113
128
  except Exception as e:
114
129
  self.logger.error(f"Error getting agent versions: {e}", exc_info=True)
115
130
  return CommandResult.error_result(f"Error getting agent versions: {e}")
116
131
 
117
-
118
132
  def _list_agents(self, args) -> CommandResult:
119
133
  """List available or deployed agents."""
120
134
  try:
121
- output_format = getattr(args, 'format', 'text')
135
+ output_format = getattr(args, "format", "text")
122
136
 
123
137
  if hasattr(args, "by_tier") and args.by_tier:
124
138
  return self._list_agents_by_tier(args)
125
- elif getattr(args, 'system', False):
139
+ if getattr(args, "system", False):
126
140
  return self._list_system_agents(args)
127
- elif getattr(args, 'deployed', False):
141
+ if getattr(args, "deployed", False):
128
142
  return self._list_deployed_agents(args)
129
- else:
130
- # Default: show usage
131
- usage_msg = "Use --system to list system agents, --deployed to list deployed agents, or --by-tier to group by precedence"
143
+ # Default: show usage
144
+ usage_msg = "Use --system to list system agents, --deployed to list deployed agents, or --by-tier to group by precedence"
132
145
 
133
- if output_format in ['json', 'yaml']:
134
- return CommandResult.error_result(
135
- "No list option specified",
136
- data={"usage": usage_msg, "available_options": ["--system", "--deployed", "--by-tier"]}
137
- )
138
- else:
139
- print(usage_msg)
140
- return CommandResult.error_result("No list option specified")
146
+ if output_format in ["json", "yaml"]:
147
+ return CommandResult.error_result(
148
+ "No list option specified",
149
+ data={
150
+ "usage": usage_msg,
151
+ "available_options": ["--system", "--deployed", "--by-tier"],
152
+ },
153
+ )
154
+ print(usage_msg)
155
+ return CommandResult.error_result("No list option specified")
141
156
 
142
157
  except Exception as e:
143
158
  self.logger.error(f"Error listing agents: {e}", exc_info=True)
@@ -147,31 +162,30 @@ class AgentsCommand(AgentCommand):
147
162
  """List available agent templates."""
148
163
  try:
149
164
  agents = self.deployment_service.list_available_agents()
150
- output_format = getattr(args, 'format', 'text')
165
+ output_format = getattr(args, "format", "text")
151
166
 
152
- if output_format in ['json', 'yaml']:
167
+ if output_format in ["json", "yaml"]:
153
168
  return CommandResult.success_result(
154
169
  f"Found {len(agents)} agent templates",
155
- data={"agents": agents, "count": len(agents)}
170
+ data={"agents": agents, "count": len(agents)},
156
171
  )
172
+ # Text output
173
+ print("Available Agent Templates:")
174
+ print("-" * 80)
175
+ if not agents:
176
+ print("No agent templates found")
157
177
  else:
158
- # Text output
159
- print("Available Agent Templates:")
160
- print("-" * 80)
161
- if not agents:
162
- print("No agent templates found")
163
- else:
164
- for agent in agents:
165
- print(f"📄 {agent['file']}")
166
- if "name" in agent:
167
- print(f" Name: {agent['name']}")
168
- if "description" in agent:
169
- print(f" Description: {agent['description']}")
170
- if "version" in agent:
171
- print(f" Version: {agent['version']}")
172
- print()
178
+ for agent in agents:
179
+ print(f"📄 {agent['file']}")
180
+ if "name" in agent:
181
+ print(f" Name: {agent['name']}")
182
+ if "description" in agent:
183
+ print(f" Description: {agent['description']}")
184
+ if "version" in agent:
185
+ print(f" Version: {agent['version']}")
186
+ print()
173
187
 
174
- return CommandResult.success_result(f"Listed {len(agents)} agent templates")
188
+ return CommandResult.success_result(f"Listed {len(agents)} agent templates")
175
189
 
176
190
  except Exception as e:
177
191
  self.logger.error(f"Error listing system agents: {e}", exc_info=True)
@@ -181,38 +195,39 @@ class AgentsCommand(AgentCommand):
181
195
  """List deployed agents."""
182
196
  try:
183
197
  verification = self.deployment_service.verify_deployment()
184
- output_format = getattr(args, 'format', 'text')
198
+ output_format = getattr(args, "format", "text")
185
199
 
186
- if output_format in ['json', 'yaml']:
200
+ if output_format in ["json", "yaml"]:
187
201
  return CommandResult.success_result(
188
202
  f"Found {len(verification['agents_found'])} deployed agents",
189
203
  data={
190
204
  "agents": verification["agents_found"],
191
205
  "warnings": verification.get("warnings", []),
192
- "count": len(verification["agents_found"])
193
- }
206
+ "count": len(verification["agents_found"]),
207
+ },
194
208
  )
209
+ # Text output
210
+ print("Deployed Agents:")
211
+ print("-" * 80)
212
+ if not verification["agents_found"]:
213
+ print("No deployed agents found")
195
214
  else:
196
- # Text output
197
- print("Deployed Agents:")
198
- print("-" * 80)
199
- if not verification["agents_found"]:
200
- print("No deployed agents found")
201
- else:
202
- for agent in verification["agents_found"]:
203
- print(f"📄 {agent['file']}")
204
- if "name" in agent:
205
- print(f" Name: {agent['name']}")
206
- if "path" in agent:
207
- print(f" Path: {agent['path']}")
208
- print()
215
+ for agent in verification["agents_found"]:
216
+ print(f"📄 {agent['file']}")
217
+ if "name" in agent:
218
+ print(f" Name: {agent['name']}")
219
+ if "path" in agent:
220
+ print(f" Path: {agent['path']}")
221
+ print()
209
222
 
210
- if verification["warnings"]:
211
- print("\nWarnings:")
212
- for warning in verification["warnings"]:
213
- print(f" ⚠️ {warning}")
223
+ if verification["warnings"]:
224
+ print("\nWarnings:")
225
+ for warning in verification["warnings"]:
226
+ print(f" ⚠️ {warning}")
214
227
 
215
- return CommandResult.success_result(f"Listed {len(verification['agents_found'])} deployed agents")
228
+ return CommandResult.success_result(
229
+ f"Listed {len(verification['agents_found'])} deployed agents"
230
+ )
216
231
 
217
232
  except Exception as e:
218
233
  self.logger.error(f"Error listing deployed agents: {e}", exc_info=True)
@@ -222,28 +237,26 @@ class AgentsCommand(AgentCommand):
222
237
  """List agents grouped by tier/precedence."""
223
238
  try:
224
239
  agents_by_tier = self.deployment_service.list_agents_by_tier()
225
- output_format = getattr(args, 'format', 'text')
240
+ output_format = getattr(args, "format", "text")
226
241
 
227
- if output_format in ['json', 'yaml']:
242
+ if output_format in ["json", "yaml"]:
228
243
  return CommandResult.success_result(
229
- "Agents listed by tier",
230
- data=agents_by_tier
244
+ "Agents listed by tier", data=agents_by_tier
231
245
  )
232
- else:
233
- # Text output
234
- print("Agents by Tier/Precedence:")
235
- print("=" * 50)
236
-
237
- for tier, agents in agents_by_tier.items():
238
- print(f"\n{tier.upper()}:")
239
- print("-" * 20)
240
- if agents:
241
- for agent in agents:
242
- print(f" • {agent}")
243
- else:
244
- print(" (none)")
246
+ # Text output
247
+ print("Agents by Tier/Precedence:")
248
+ print("=" * 50)
249
+
250
+ for tier, agents in agents_by_tier.items():
251
+ print(f"\n{tier.upper()}:")
252
+ print("-" * 20)
253
+ if agents:
254
+ for agent in agents:
255
+ print(f" • {agent}")
256
+ else:
257
+ print(" (none)")
245
258
 
246
- return CommandResult.success_result("Agents listed by tier")
259
+ return CommandResult.success_result("Agents listed by tier")
247
260
 
248
261
  except Exception as e:
249
262
  self.logger.error(f"Error listing agents by tier: {e}", exc_info=True)
@@ -259,29 +272,30 @@ class AgentsCommand(AgentCommand):
259
272
  project_result = self.deployment_service.deploy_project_agents(force=force)
260
273
 
261
274
  # Combine results
262
- total_deployed = system_result.get('deployed_count', 0) + project_result.get('deployed_count', 0)
275
+ total_deployed = system_result.get(
276
+ "deployed_count", 0
277
+ ) + project_result.get("deployed_count", 0)
263
278
 
264
- output_format = getattr(args, 'format', 'text')
265
- if output_format in ['json', 'yaml']:
279
+ output_format = getattr(args, "format", "text")
280
+ if output_format in ["json", "yaml"]:
266
281
  return CommandResult.success_result(
267
282
  f"Deployed {total_deployed} agents",
268
283
  data={
269
284
  "system_agents": system_result,
270
285
  "project_agents": project_result,
271
- "total_deployed": total_deployed
272
- }
286
+ "total_deployed": total_deployed,
287
+ },
273
288
  )
274
- else:
275
- # Text output
276
- if system_result.get('deployed_count', 0) > 0:
277
- print(f" Deployed {system_result['deployed_count']} system agents")
278
- if project_result.get('deployed_count', 0) > 0:
279
- print(f"✓ Deployed {project_result['deployed_count']} project agents")
289
+ # Text output
290
+ if system_result.get("deployed_count", 0) > 0:
291
+ print(f"✓ Deployed {system_result['deployed_count']} system agents")
292
+ if project_result.get("deployed_count", 0) > 0:
293
+ print(f"✓ Deployed {project_result['deployed_count']} project agents")
280
294
 
281
- if total_deployed == 0:
282
- print("No agents were deployed (all up to date)")
295
+ if total_deployed == 0:
296
+ print("No agents were deployed (all up to date)")
283
297
 
284
- return CommandResult.success_result(f"Deployed {total_deployed} agents")
298
+ return CommandResult.success_result(f"Deployed {total_deployed} agents")
285
299
 
286
300
  except Exception as e:
287
301
  self.logger.error(f"Error deploying agents: {e}", exc_info=True)
@@ -292,21 +306,19 @@ class AgentsCommand(AgentCommand):
292
306
  try:
293
307
  result = self.deployment_service.clean_deployment()
294
308
 
295
- output_format = getattr(args, 'format', 'text')
296
- if output_format in ['json', 'yaml']:
309
+ output_format = getattr(args, "format", "text")
310
+ if output_format in ["json", "yaml"]:
297
311
  return CommandResult.success_result(
298
- f"Cleaned {result.get('cleaned_count', 0)} agents",
299
- data=result
312
+ f"Cleaned {result.get('cleaned_count', 0)} agents", data=result
300
313
  )
314
+ # Text output
315
+ cleaned_count = result.get("cleaned_count", 0)
316
+ if cleaned_count > 0:
317
+ print(f"✓ Cleaned {cleaned_count} deployed agents")
301
318
  else:
302
- # Text output
303
- cleaned_count = result.get('cleaned_count', 0)
304
- if cleaned_count > 0:
305
- print(f"✓ Cleaned {cleaned_count} deployed agents")
306
- else:
307
- print("No deployed agents to clean")
319
+ print("No deployed agents to clean")
308
320
 
309
- return CommandResult.success_result(f"Cleaned {cleaned_count} agents")
321
+ return CommandResult.success_result(f"Cleaned {cleaned_count} agents")
310
322
 
311
323
  except Exception as e:
312
324
  self.logger.error(f"Error cleaning agents: {e}", exc_info=True)
@@ -315,27 +327,27 @@ class AgentsCommand(AgentCommand):
315
327
  def _view_agent(self, args) -> CommandResult:
316
328
  """View details of a specific agent."""
317
329
  try:
318
- agent_name = getattr(args, 'agent_name', None)
330
+ agent_name = getattr(args, "agent_name", None)
319
331
  if not agent_name:
320
- return CommandResult.error_result("Agent name is required for view command")
332
+ return CommandResult.error_result(
333
+ "Agent name is required for view command"
334
+ )
321
335
 
322
336
  # Get agent details from deployment service
323
337
  agent_details = self.deployment_service.get_agent_details(agent_name)
324
338
 
325
- output_format = getattr(args, 'format', 'text')
326
- if output_format in ['json', 'yaml']:
339
+ output_format = getattr(args, "format", "text")
340
+ if output_format in ["json", "yaml"]:
327
341
  return CommandResult.success_result(
328
- f"Agent details for {agent_name}",
329
- data=agent_details
342
+ f"Agent details for {agent_name}", data=agent_details
330
343
  )
331
- else:
332
- # Text output
333
- print(f"Agent: {agent_name}")
334
- print("-" * 40)
335
- for key, value in agent_details.items():
336
- print(f"{key}: {value}")
344
+ # Text output
345
+ print(f"Agent: {agent_name}")
346
+ print("-" * 40)
347
+ for key, value in agent_details.items():
348
+ print(f"{key}: {value}")
337
349
 
338
- return CommandResult.success_result(f"Displayed details for {agent_name}")
350
+ return CommandResult.success_result(f"Displayed details for {agent_name}")
339
351
 
340
352
  except Exception as e:
341
353
  self.logger.error(f"Error viewing agent: {e}", exc_info=True)
@@ -346,20 +358,18 @@ class AgentsCommand(AgentCommand):
346
358
  try:
347
359
  result = self.deployment_service.fix_deployment()
348
360
 
349
- output_format = getattr(args, 'format', 'text')
350
- if output_format in ['json', 'yaml']:
361
+ output_format = getattr(args, "format", "text")
362
+ if output_format in ["json", "yaml"]:
351
363
  return CommandResult.success_result(
352
- "Agent deployment fixed",
353
- data=result
364
+ "Agent deployment fixed", data=result
354
365
  )
355
- else:
356
- # Text output
357
- print("✓ Agent deployment issues fixed")
358
- if result.get('fixes_applied'):
359
- for fix in result['fixes_applied']:
360
- print(f" - {fix}")
366
+ # Text output
367
+ print("✓ Agent deployment issues fixed")
368
+ if result.get("fixes_applied"):
369
+ for fix in result["fixes_applied"]:
370
+ print(f" - {fix}")
361
371
 
362
- return CommandResult.success_result("Agent deployment fixed")
372
+ return CommandResult.success_result("Agent deployment fixed")
363
373
 
364
374
  except Exception as e:
365
375
  self.logger.error(f"Error fixing agents: {e}", exc_info=True)
@@ -370,24 +380,22 @@ class AgentsCommand(AgentCommand):
370
380
  try:
371
381
  result = self.deployment_service.check_dependencies()
372
382
 
373
- output_format = getattr(args, 'format', 'text')
374
- if output_format in ['json', 'yaml']:
383
+ output_format = getattr(args, "format", "text")
384
+ if output_format in ["json", "yaml"]:
375
385
  return CommandResult.success_result(
376
- "Dependency check completed",
377
- data=result
386
+ "Dependency check completed", data=result
378
387
  )
388
+ # Text output
389
+ print("Agent Dependencies Check:")
390
+ print("-" * 40)
391
+ if result.get("missing_dependencies"):
392
+ print("Missing dependencies:")
393
+ for dep in result["missing_dependencies"]:
394
+ print(f" - {dep}")
379
395
  else:
380
- # Text output
381
- print("Agent Dependencies Check:")
382
- print("-" * 40)
383
- if result.get('missing_dependencies'):
384
- print("Missing dependencies:")
385
- for dep in result['missing_dependencies']:
386
- print(f" - {dep}")
387
- else:
388
- print("✓ All dependencies satisfied")
396
+ print("✓ All dependencies satisfied")
389
397
 
390
- return CommandResult.success_result("Dependency check completed")
398
+ return CommandResult.success_result("Dependency check completed")
391
399
 
392
400
  except Exception as e:
393
401
  self.logger.error(f"Error checking dependencies: {e}", exc_info=True)
@@ -398,21 +406,22 @@ class AgentsCommand(AgentCommand):
398
406
  try:
399
407
  result = self.deployment_service.install_dependencies()
400
408
 
401
- output_format = getattr(args, 'format', 'text')
402
- if output_format in ['json', 'yaml']:
409
+ output_format = getattr(args, "format", "text")
410
+ if output_format in ["json", "yaml"]:
403
411
  return CommandResult.success_result(
404
412
  f"Installed {result.get('installed_count', 0)} dependencies",
405
- data=result
413
+ data=result,
406
414
  )
415
+ # Text output
416
+ installed_count = result.get("installed_count", 0)
417
+ if installed_count > 0:
418
+ print(f"✓ Installed {installed_count} dependencies")
407
419
  else:
408
- # Text output
409
- installed_count = result.get('installed_count', 0)
410
- if installed_count > 0:
411
- print(f"✓ Installed {installed_count} dependencies")
412
- else:
413
- print("No dependencies needed installation")
420
+ print("No dependencies needed installation")
414
421
 
415
- return CommandResult.success_result(f"Installed {installed_count} dependencies")
422
+ return CommandResult.success_result(
423
+ f"Installed {installed_count} dependencies"
424
+ )
416
425
 
417
426
  except Exception as e:
418
427
  self.logger.error(f"Error installing dependencies: {e}", exc_info=True)
@@ -423,25 +432,26 @@ class AgentsCommand(AgentCommand):
423
432
  try:
424
433
  result = self.deployment_service.list_dependencies()
425
434
 
426
- output_format = getattr(args, 'format', 'text')
427
- if output_format in ['json', 'yaml']:
435
+ output_format = getattr(args, "format", "text")
436
+ if output_format in ["json", "yaml"]:
428
437
  return CommandResult.success_result(
429
438
  f"Found {len(result.get('dependencies', []))} dependencies",
430
- data=result
439
+ data=result,
431
440
  )
441
+ # Text output
442
+ dependencies = result.get("dependencies", [])
443
+ print("Agent Dependencies:")
444
+ print("-" * 40)
445
+ if dependencies:
446
+ for dep in dependencies:
447
+ status = "✓" if dep.get("installed") else "✗"
448
+ print(f"{status} {dep.get('name', 'Unknown')}")
432
449
  else:
433
- # Text output
434
- dependencies = result.get('dependencies', [])
435
- print("Agent Dependencies:")
436
- print("-" * 40)
437
- if dependencies:
438
- for dep in dependencies:
439
- status = "✓" if dep.get('installed') else "✗"
440
- print(f"{status} {dep.get('name', 'Unknown')}")
441
- else:
442
- print("No dependencies found")
450
+ print("No dependencies found")
443
451
 
444
- return CommandResult.success_result(f"Listed {len(dependencies)} dependencies")
452
+ return CommandResult.success_result(
453
+ f"Listed {len(dependencies)} dependencies"
454
+ )
445
455
 
446
456
  except Exception as e:
447
457
  self.logger.error(f"Error listing dependencies: {e}", exc_info=True)
@@ -452,34 +462,32 @@ class AgentsCommand(AgentCommand):
452
462
  try:
453
463
  result = self.deployment_service.fix_dependencies()
454
464
 
455
- output_format = getattr(args, 'format', 'text')
456
- if output_format in ['json', 'yaml']:
465
+ output_format = getattr(args, "format", "text")
466
+ if output_format in ["json", "yaml"]:
457
467
  return CommandResult.success_result(
458
- "Dependency issues fixed",
459
- data=result
468
+ "Dependency issues fixed", data=result
460
469
  )
461
- else:
462
- # Text output
463
- print("✓ Agent dependency issues fixed")
464
- if result.get('fixes_applied'):
465
- for fix in result['fixes_applied']:
466
- print(f" - {fix}")
470
+ # Text output
471
+ print("✓ Agent dependency issues fixed")
472
+ if result.get("fixes_applied"):
473
+ for fix in result["fixes_applied"]:
474
+ print(f" - {fix}")
467
475
 
468
- return CommandResult.success_result("Dependency issues fixed")
476
+ return CommandResult.success_result("Dependency issues fixed")
469
477
 
470
478
  except Exception as e:
471
479
  self.logger.error(f"Error fixing dependencies: {e}", exc_info=True)
472
480
  return CommandResult.error_result(f"Error fixing dependencies: {e}")
473
-
481
+
474
482
  def _cleanup_orphaned_agents(self, args) -> CommandResult:
475
483
  """Clean up orphaned agents that don't have templates."""
476
484
  try:
477
485
  from ...services.agents.deployment.multi_source_deployment_service import (
478
- MultiSourceAgentDeploymentService
486
+ MultiSourceAgentDeploymentService,
479
487
  )
480
-
488
+
481
489
  # Determine agents directory
482
- if hasattr(args, 'agents_dir') and args.agents_dir:
490
+ if hasattr(args, "agents_dir") and args.agents_dir:
483
491
  agents_dir = args.agents_dir
484
492
  else:
485
493
  # Check for project-level .claude/agents first
@@ -489,65 +497,65 @@ class AgentsCommand(AgentCommand):
489
497
  else:
490
498
  # Fall back to user home directory
491
499
  agents_dir = Path.home() / ".claude" / "agents"
492
-
500
+
493
501
  if not agents_dir.exists():
494
- return CommandResult.success_result(f"Agents directory not found: {agents_dir}")
495
-
502
+ return CommandResult.success_result(
503
+ f"Agents directory not found: {agents_dir}"
504
+ )
505
+
496
506
  # Initialize service
497
507
  service = MultiSourceAgentDeploymentService()
498
-
508
+
499
509
  # Determine if we're doing a dry run
500
- dry_run = getattr(args, 'dry_run', True)
501
- if hasattr(args, 'force') and args.force:
510
+ dry_run = getattr(args, "dry_run", True)
511
+ if hasattr(args, "force") and args.force:
502
512
  dry_run = False
503
-
513
+
504
514
  # Perform cleanup
505
515
  results = service.cleanup_orphaned_agents(agents_dir, dry_run=dry_run)
506
-
507
- output_format = getattr(args, 'format', 'text')
508
- quiet = getattr(args, 'quiet', False)
509
-
510
- if output_format in ['json', 'yaml']:
516
+
517
+ output_format = getattr(args, "format", "text")
518
+ quiet = getattr(args, "quiet", False)
519
+
520
+ if output_format in ["json", "yaml"]:
511
521
  return CommandResult.success_result(
512
522
  f"Found {len(results.get('orphaned', []))} orphaned agents",
513
- data=results
523
+ data=results,
524
+ )
525
+ # Text output
526
+ if not results.get("orphaned"):
527
+ print("✅ No orphaned agents found")
528
+ return CommandResult.success_result("No orphaned agents found")
529
+
530
+ if not quiet:
531
+ print(f"\nFound {len(results['orphaned'])} orphaned agent(s):")
532
+ for orphan in results["orphaned"]:
533
+ print(f" - {orphan['name']} v{orphan['version']}")
534
+
535
+ if dry_run:
536
+ print(
537
+ f"\n📝 This was a dry run. Use --force to actually remove "
538
+ f"{len(results['orphaned'])} orphaned agent(s)"
514
539
  )
515
540
  else:
516
- # Text output
517
- if not results.get("orphaned"):
518
- print("✅ No orphaned agents found")
519
- return CommandResult.success_result("No orphaned agents found")
520
-
521
- if not quiet:
522
- print(f"\nFound {len(results['orphaned'])} orphaned agent(s):")
523
- for orphan in results["orphaned"]:
524
- print(f" - {orphan['name']} v{orphan['version']}")
525
-
526
- if dry_run:
541
+ if results.get("removed"):
527
542
  print(
528
- f"\n📝 This was a dry run. Use --force to actually remove "
529
- f"{len(results['orphaned'])} orphaned agent(s)"
543
+ f"\n Successfully removed {len(results['removed'])} orphaned agent(s)"
530
544
  )
531
- else:
532
- if results.get("removed"):
533
- print(
534
- f"\n✅ Successfully removed {len(results['removed'])} orphaned agent(s)"
535
- )
536
-
537
- if results.get("errors"):
538
- print(f"\n❌ Encountered {len(results['errors'])} error(s):")
539
- for error in results["errors"]:
540
- print(f" - {error}")
541
- return CommandResult.error_result(
542
- f"Cleanup completed with {len(results['errors'])} errors",
543
- data=results
544
- )
545
-
546
- return CommandResult.success_result(
547
- f"Cleanup {'preview' if dry_run else 'completed'}",
548
- data=results
549
- )
550
-
545
+
546
+ if results.get("errors"):
547
+ print(f"\n❌ Encountered {len(results['errors'])} error(s):")
548
+ for error in results["errors"]:
549
+ print(f" - {error}")
550
+ return CommandResult.error_result(
551
+ f"Cleanup completed with {len(results['errors'])} errors",
552
+ data=results,
553
+ )
554
+
555
+ return CommandResult.success_result(
556
+ f"Cleanup {'preview' if dry_run else 'completed'}", data=results
557
+ )
558
+
551
559
  except Exception as e:
552
560
  self.logger.error(f"Error during cleanup: {e}", exc_info=True)
553
561
  return CommandResult.error_result(f"Error during cleanup: {e}")
@@ -563,7 +571,7 @@ def manage_agents(args):
563
571
  result = command.execute(args)
564
572
 
565
573
  # Print result if structured output format is requested
566
- if hasattr(args, 'format') and args.format in ['json', 'yaml']:
574
+ if hasattr(args, "format") and args.format in ["json", "yaml"]:
567
575
  command.print_result(result, args)
568
576
 
569
577
  return result.exit_code
@@ -611,7 +619,7 @@ def _deploy_agents(args, deployment_service, force=False):
611
619
 
612
620
  # Warn if commonly used agents are being excluded
613
621
  common_agents = {"engineer", "qa", "security", "documentation"}
614
- excluded_common = set(a.lower() for a in excluded_agents) & common_agents
622
+ excluded_common = {a.lower() for a in excluded_agents} & common_agents
615
623
  if excluded_common:
616
624
  print(
617
625
  f"⚠️ Warning: Common agents are being excluded: {', '.join(excluded_common)}"
@@ -629,7 +637,6 @@ def _deploy_agents(args, deployment_service, force=False):
629
637
  results = deployment_service.deploy_agents(None, force_rebuild=force, config=config)
630
638
 
631
639
  # Also deploy project agents if they exist
632
- import os
633
640
  from pathlib import Path
634
641
 
635
642
  # Use the user's working directory if available
@@ -700,7 +707,7 @@ def _deploy_agents(args, deployment_service, force=False):
700
707
  env_vars = deployment_service.set_claude_environment(
701
708
  args.target.parent if args.target else None
702
709
  )
703
- print(f"\n✓ Set Claude environment variables:")
710
+ print("\n✓ Set Claude environment variables:")
704
711
  for key, value in env_vars.items():
705
712
  print(f" - {key}={value}")
706
713
 
@@ -777,11 +784,11 @@ def _list_agents_by_tier():
777
784
  else:
778
785
  # Check paths to determine actual locations
779
786
  if tier_key == "project":
780
- print(f" Location: .claude-mpm/agents/ (in current project)")
787
+ print(" Location: .claude-mpm/agents/ (in current project)")
781
788
  elif tier_key == "user":
782
- print(f" Location: ~/.claude-mpm/agents/")
789
+ print(" Location: ~/.claude-mpm/agents/")
783
790
  else:
784
- print(f" Location: Built-in framework agents")
791
+ print(" Location: Built-in framework agents")
785
792
 
786
793
  print(f"\n Found {len(agents)} agent(s):\n")
787
794
 
@@ -863,7 +870,7 @@ def _view_agent(args):
863
870
  print(f"❌ Agent file not found: {agent_path}")
864
871
  return
865
872
 
866
- with open(agent_path, "r") as f:
873
+ with open(agent_path) as f:
867
874
  content = f.read()
868
875
 
869
876
  # Display agent information
@@ -872,7 +879,7 @@ def _view_agent(args):
872
879
  print("=" * 80)
873
880
 
874
881
  # Basic info
875
- print(f"\n📋 BASIC INFORMATION:")
882
+ print("\n📋 BASIC INFORMATION:")
876
883
  print(f" Name: {agent.name}")
877
884
  print(f" Type: {agent.type}")
878
885
  print(f" Tier: {agent.tier.upper()}")
@@ -893,7 +900,7 @@ def _view_agent(args):
893
900
  frontmatter_str = content[4:end_marker]
894
901
  frontmatter = yaml.safe_load(frontmatter_str)
895
902
 
896
- print(f"\n📝 FRONTMATTER:")
903
+ print("\n📝 FRONTMATTER:")
897
904
  for key, value in frontmatter.items():
898
905
  if isinstance(value, list):
899
906
  print(f" {key}: [{', '.join(str(v) for v in value)}]")
@@ -909,13 +916,11 @@ def _view_agent(args):
909
916
  instructions = content[instructions_start:].strip()
910
917
 
911
918
  if instructions:
912
- print(f"\n📖 INSTRUCTIONS PREVIEW (first 500 chars):")
919
+ print("\n📖 INSTRUCTIONS PREVIEW (first 500 chars):")
913
920
  print(" " + "-" * 76)
914
921
  preview = instructions[:500]
915
922
  if len(instructions) > 500:
916
- preview += "...\n\n [Truncated - {:.1f}KB total]".format(
917
- len(instructions) / 1024
918
- )
923
+ preview += f"...\n\n [Truncated - {len(instructions) / 1024:.1f}KB total]"
919
924
 
920
925
  for line in preview.split("\n"):
921
926
  print(f" {line}")
@@ -923,7 +928,7 @@ def _view_agent(args):
923
928
  except Exception as e:
924
929
  print(f"\n⚠️ Could not parse frontmatter: {e}")
925
930
  else:
926
- print(f"\n⚠️ No frontmatter found in agent file")
931
+ print("\n⚠️ No frontmatter found in agent file")
927
932
 
928
933
  # File stats
929
934
  import os
@@ -932,7 +937,7 @@ def _view_agent(args):
932
937
  from datetime import datetime
933
938
 
934
939
  modified = datetime.fromtimestamp(stat.st_mtime).strftime("%Y-%m-%d %H:%M:%S")
935
- print(f"\n📊 FILE STATS:")
940
+ print("\n📊 FILE STATS:")
936
941
  print(f" Size: {stat.st_size:,} bytes")
937
942
  print(f" Last modified: {modified}")
938
943
 
@@ -1058,7 +1063,7 @@ def _check_agent_dependencies(args):
1058
1063
  """
1059
1064
  from ...utils.agent_dependency_loader import AgentDependencyLoader
1060
1065
 
1061
- verbose = getattr(args, "verbose", False)
1066
+ getattr(args, "verbose", False)
1062
1067
  specific_agent = getattr(args, "agent", None)
1063
1068
 
1064
1069
  loader = AgentDependencyLoader(auto_install=False)
@@ -1093,7 +1098,6 @@ def _install_agent_dependencies(args):
1093
1098
  Args:
1094
1099
  args: Parsed command line arguments
1095
1100
  """
1096
- import sys
1097
1101
 
1098
1102
  from ...utils.agent_dependency_loader import AgentDependencyLoader
1099
1103
 
@@ -1160,7 +1164,6 @@ def _list_agent_dependencies(args):
1160
1164
  Args:
1161
1165
  args: Parsed command line arguments
1162
1166
  """
1163
- import json
1164
1167
 
1165
1168
  from ...utils.agent_dependency_loader import AgentDependencyLoader
1166
1169
 
@@ -1191,8 +1194,8 @@ def _list_agent_dependencies(args):
1191
1194
  elif output_format == "json":
1192
1195
  # Output JSON format
1193
1196
  output = {
1194
- "python": sorted(list(all_python_deps)),
1195
- "system": sorted(list(all_system_deps)),
1197
+ "python": sorted(all_python_deps),
1198
+ "system": sorted(all_system_deps),
1196
1199
  "agents": {},
1197
1200
  }
1198
1201
  for agent_id, deps in loader.agent_dependencies.items():