claude-mpm 4.21.3__py3-none-any.whl → 5.1.9__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.

Potentially problematic release.


This version of claude-mpm might be problematic. Click here for more details.

Files changed (517) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +12 -0
  3. claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +3 -48
  4. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
  5. claude_mpm/agents/PM_INSTRUCTIONS.md +1239 -674
  6. claude_mpm/agents/WORKFLOW.md +75 -2
  7. claude_mpm/agents/__init__.py +6 -0
  8. claude_mpm/agents/agent_loader.py +1 -4
  9. claude_mpm/agents/base_agent.json +6 -3
  10. claude_mpm/agents/base_agent_loader.py +10 -35
  11. claude_mpm/agents/frontmatter_validator.py +69 -1
  12. claude_mpm/agents/templates/circuit-breakers.md +1254 -0
  13. claude_mpm/agents/templates/context-management-examples.md +544 -0
  14. claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
  15. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  16. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  17. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  18. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  19. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  20. claude_mpm/cli/__init__.py +37 -2
  21. claude_mpm/cli/commands/__init__.py +2 -0
  22. claude_mpm/cli/commands/agent_source.py +774 -0
  23. claude_mpm/cli/commands/agent_state_manager.py +188 -30
  24. claude_mpm/cli/commands/agents.py +1128 -36
  25. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  26. claude_mpm/cli/commands/agents_discover.py +338 -0
  27. claude_mpm/cli/commands/aggregate.py +1 -1
  28. claude_mpm/cli/commands/analyze.py +3 -3
  29. claude_mpm/cli/commands/auto_configure.py +537 -239
  30. claude_mpm/cli/commands/cleanup.py +1 -1
  31. claude_mpm/cli/commands/config.py +7 -4
  32. claude_mpm/cli/commands/configure.py +935 -45
  33. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  34. claude_mpm/cli/commands/configure_navigation.py +63 -46
  35. claude_mpm/cli/commands/debug.py +12 -12
  36. claude_mpm/cli/commands/doctor.py +10 -2
  37. claude_mpm/cli/commands/hook_errors.py +277 -0
  38. claude_mpm/cli/commands/local_deploy.py +1 -4
  39. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  40. claude_mpm/cli/commands/mpm_init/core.py +50 -2
  41. claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
  42. claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
  43. claude_mpm/cli/commands/postmortem.py +401 -0
  44. claude_mpm/cli/commands/run.py +125 -167
  45. claude_mpm/cli/commands/skill_source.py +694 -0
  46. claude_mpm/cli/commands/skills.py +757 -20
  47. claude_mpm/cli/executor.py +78 -3
  48. claude_mpm/cli/interactive/agent_wizard.py +1032 -47
  49. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  50. claude_mpm/cli/parsers/agents_parser.py +310 -4
  51. claude_mpm/cli/parsers/auto_configure_parser.py +13 -0
  52. claude_mpm/cli/parsers/base_parser.py +53 -0
  53. claude_mpm/cli/parsers/config_parser.py +96 -43
  54. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  55. claude_mpm/cli/parsers/skills_parser.py +145 -0
  56. claude_mpm/cli/parsers/source_parser.py +138 -0
  57. claude_mpm/cli/startup.py +564 -108
  58. claude_mpm/cli/startup_display.py +480 -0
  59. claude_mpm/cli/utils.py +1 -1
  60. claude_mpm/cli_module/commands.py +1 -1
  61. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  62. claude_mpm/commands/mpm-agents-detect.md +9 -0
  63. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  64. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  65. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  66. claude_mpm/commands/mpm-doctor.md +9 -0
  67. claude_mpm/commands/mpm-help.md +14 -2
  68. claude_mpm/commands/mpm-init.md +27 -2
  69. claude_mpm/commands/mpm-monitor.md +9 -0
  70. claude_mpm/commands/mpm-postmortem.md +123 -0
  71. claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
  72. claude_mpm/commands/mpm-status.md +9 -0
  73. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  74. claude_mpm/commands/mpm-ticket-view.md +552 -0
  75. claude_mpm/commands/mpm-version.md +9 -0
  76. claude_mpm/commands/mpm.md +10 -0
  77. claude_mpm/config/agent_presets.py +488 -0
  78. claude_mpm/config/agent_sources.py +325 -0
  79. claude_mpm/config/skill_presets.py +392 -0
  80. claude_mpm/config/skill_sources.py +590 -0
  81. claude_mpm/constants.py +13 -0
  82. claude_mpm/core/api_validator.py +1 -1
  83. claude_mpm/core/claude_runner.py +19 -35
  84. claude_mpm/core/config.py +24 -0
  85. claude_mpm/core/constants.py +1 -1
  86. claude_mpm/core/framework/__init__.py +3 -16
  87. claude_mpm/core/framework/loaders/file_loader.py +54 -101
  88. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  89. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  90. claude_mpm/core/hook_error_memory.py +381 -0
  91. claude_mpm/core/hook_manager.py +41 -2
  92. claude_mpm/core/interactive_session.py +131 -10
  93. claude_mpm/core/logger.py +3 -1
  94. claude_mpm/core/oneshot_session.py +110 -8
  95. claude_mpm/core/output_style_manager.py +173 -43
  96. claude_mpm/core/protocols/__init__.py +23 -0
  97. claude_mpm/core/protocols/runner_protocol.py +103 -0
  98. claude_mpm/core/protocols/session_protocol.py +131 -0
  99. claude_mpm/core/shared/singleton_manager.py +11 -4
  100. claude_mpm/core/system_context.py +38 -0
  101. claude_mpm/core/unified_agent_registry.py +129 -1
  102. claude_mpm/core/unified_config.py +22 -0
  103. claude_mpm/dashboard/static/css/activity.css +69 -69
  104. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  105. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  106. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  107. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  108. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  109. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  110. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  111. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  112. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  113. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  114. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  115. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  116. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  117. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  118. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  119. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  120. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  121. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  122. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  123. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  124. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  125. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  126. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  127. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  128. claude_mpm/dashboard/templates/code_simple.html +23 -23
  129. claude_mpm/dashboard/templates/index.html +18 -18
  130. claude_mpm/experimental/cli_enhancements.py +1 -5
  131. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  132. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  133. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  134. claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
  135. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  136. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  137. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  138. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  139. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  140. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  141. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  142. claude_mpm/models/agent_definition.py +7 -0
  143. claude_mpm/models/git_repository.py +198 -0
  144. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  145. claude_mpm/scripts/start_activity_logging.py +3 -1
  146. claude_mpm/services/agents/agent_builder.py +45 -9
  147. claude_mpm/services/agents/agent_preset_service.py +238 -0
  148. claude_mpm/services/agents/agent_selection_service.py +484 -0
  149. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  150. claude_mpm/services/agents/cache_git_manager.py +621 -0
  151. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  152. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  153. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  154. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  155. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  156. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  157. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  158. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  159. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  160. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  161. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +225 -18
  162. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  163. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  164. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +557 -0
  165. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  166. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  167. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  168. claude_mpm/services/agents/git_source_manager.py +629 -0
  169. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  170. claude_mpm/services/agents/local_template_manager.py +50 -10
  171. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  172. claude_mpm/services/agents/sources/__init__.py +13 -0
  173. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  174. claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
  175. claude_mpm/services/agents/startup_sync.py +239 -0
  176. claude_mpm/services/agents/toolchain_detector.py +474 -0
  177. claude_mpm/services/analysis/__init__.py +25 -0
  178. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  179. claude_mpm/services/analysis/postmortem_service.py +765 -0
  180. claude_mpm/services/cli/session_pause_manager.py +1 -1
  181. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  182. claude_mpm/services/command_deployment_service.py +200 -6
  183. claude_mpm/services/core/base.py +7 -2
  184. claude_mpm/services/core/interfaces/__init__.py +1 -3
  185. claude_mpm/services/core/interfaces/health.py +1 -4
  186. claude_mpm/services/core/models/__init__.py +2 -11
  187. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  188. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  189. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  190. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  191. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  192. claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
  193. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  194. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  195. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  196. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  197. claude_mpm/services/event_bus/direct_relay.py +3 -3
  198. claude_mpm/services/event_bus/event_bus.py +36 -3
  199. claude_mpm/services/events/consumers/logging.py +1 -2
  200. claude_mpm/services/git/__init__.py +21 -0
  201. claude_mpm/services/git/git_operations_service.py +494 -0
  202. claude_mpm/services/github/__init__.py +21 -0
  203. claude_mpm/services/github/github_cli_service.py +397 -0
  204. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  205. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  206. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  207. claude_mpm/services/instructions/__init__.py +9 -0
  208. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  209. claude_mpm/services/local_ops/__init__.py +3 -13
  210. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  211. claude_mpm/services/local_ops/health_manager.py +1 -4
  212. claude_mpm/services/local_ops/process_manager.py +1 -1
  213. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  214. claude_mpm/services/mcp_config_manager.py +75 -145
  215. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  216. claude_mpm/services/mcp_gateway/core/process_pool.py +22 -16
  217. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  218. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  219. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  220. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  221. claude_mpm/services/mcp_service_verifier.py +6 -3
  222. claude_mpm/services/memory/optimizer.py +1 -1
  223. claude_mpm/services/model/model_router.py +8 -9
  224. claude_mpm/services/monitor/daemon.py +29 -9
  225. claude_mpm/services/monitor/daemon_manager.py +96 -19
  226. claude_mpm/services/monitor/server.py +2 -2
  227. claude_mpm/services/native_agent_converter.py +356 -0
  228. claude_mpm/services/port_manager.py +1 -1
  229. claude_mpm/services/pr/__init__.py +14 -0
  230. claude_mpm/services/pr/pr_template_service.py +329 -0
  231. claude_mpm/services/project/documentation_manager.py +2 -1
  232. claude_mpm/services/project/project_organizer.py +4 -0
  233. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  234. claude_mpm/services/runner_configuration_service.py +17 -3
  235. claude_mpm/services/self_upgrade_service.py +165 -7
  236. claude_mpm/services/session_management_service.py +16 -4
  237. claude_mpm/services/skills/__init__.py +18 -0
  238. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  239. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  240. claude_mpm/services/skills_config.py +547 -0
  241. claude_mpm/services/skills_deployer.py +955 -0
  242. claude_mpm/services/socketio/handlers/connection.py +1 -1
  243. claude_mpm/services/socketio/handlers/git.py +2 -2
  244. claude_mpm/services/socketio/server/core.py +1 -4
  245. claude_mpm/services/socketio/server/main.py +1 -3
  246. claude_mpm/services/system_instructions_service.py +1 -3
  247. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  248. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  249. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  250. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  251. claude_mpm/services/unified/unified_deployment.py +1 -5
  252. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  253. claude_mpm/services/visualization/__init__.py +1 -5
  254. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  255. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  256. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  257. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
  258. claude_mpm/skills/skills_registry.py +0 -1
  259. claude_mpm/templates/questions/__init__.py +38 -0
  260. claude_mpm/templates/questions/base.py +193 -0
  261. claude_mpm/templates/questions/pr_strategy.py +311 -0
  262. claude_mpm/templates/questions/project_init.py +385 -0
  263. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  264. claude_mpm/tools/__main__.py +8 -8
  265. claude_mpm/tools/code_tree_analyzer/analysis.py +1 -1
  266. claude_mpm/utils/agent_dependency_loader.py +80 -13
  267. claude_mpm/utils/agent_filters.py +288 -0
  268. claude_mpm/utils/dependency_cache.py +3 -1
  269. claude_mpm/utils/gitignore.py +244 -0
  270. claude_mpm/utils/log_cleanup.py +3 -3
  271. claude_mpm/utils/migration.py +372 -0
  272. claude_mpm/utils/progress.py +387 -0
  273. claude_mpm/utils/robust_installer.py +3 -5
  274. claude_mpm/utils/structured_questions.py +619 -0
  275. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/METADATA +496 -65
  276. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/RECORD +284 -443
  277. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  278. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  279. claude_mpm/agents/templates/agent-manager.json +0 -273
  280. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  281. claude_mpm/agents/templates/api_qa.json +0 -180
  282. claude_mpm/agents/templates/circuit_breakers.md +0 -638
  283. claude_mpm/agents/templates/clerk-ops.json +0 -235
  284. claude_mpm/agents/templates/code_analyzer.json +0 -101
  285. claude_mpm/agents/templates/content-agent.json +0 -358
  286. claude_mpm/agents/templates/dart_engineer.json +0 -307
  287. claude_mpm/agents/templates/data_engineer.json +0 -225
  288. claude_mpm/agents/templates/documentation.json +0 -211
  289. claude_mpm/agents/templates/engineer.json +0 -210
  290. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  291. claude_mpm/agents/templates/golang_engineer.json +0 -270
  292. claude_mpm/agents/templates/imagemagick.json +0 -264
  293. claude_mpm/agents/templates/java_engineer.json +0 -346
  294. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  295. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  296. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  297. claude_mpm/agents/templates/memory_manager.json +0 -158
  298. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  299. claude_mpm/agents/templates/ops.json +0 -185
  300. claude_mpm/agents/templates/php-engineer.json +0 -287
  301. claude_mpm/agents/templates/product_owner.json +0 -338
  302. claude_mpm/agents/templates/project_organizer.json +0 -140
  303. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  304. claude_mpm/agents/templates/python_engineer.json +0 -387
  305. claude_mpm/agents/templates/qa.json +0 -242
  306. claude_mpm/agents/templates/react_engineer.json +0 -238
  307. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  308. claude_mpm/agents/templates/research.json +0 -188
  309. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  310. claude_mpm/agents/templates/rust_engineer.json +0 -275
  311. claude_mpm/agents/templates/security.json +0 -202
  312. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  313. claude_mpm/agents/templates/ticketing.json +0 -177
  314. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  315. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  316. claude_mpm/agents/templates/version_control.json +0 -157
  317. claude_mpm/agents/templates/web_qa.json +0 -399
  318. claude_mpm/agents/templates/web_ui.json +0 -189
  319. claude_mpm/commands/mpm-tickets.md +0 -102
  320. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  321. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  322. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  323. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  324. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  325. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  326. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  327. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  328. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  329. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  330. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  331. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  332. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  333. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  334. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  335. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  336. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  337. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  338. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  339. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  340. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  341. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  342. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  343. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  344. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  345. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  346. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  347. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  348. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  349. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  350. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  351. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  352. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  353. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  354. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  355. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  356. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  357. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  358. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  359. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  360. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  361. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  362. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  363. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  364. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  365. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  366. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  367. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  368. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  369. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  370. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  371. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  372. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  373. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  374. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  375. claude_mpm/dashboard/static/built/react/events.js +0 -30
  376. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  377. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  378. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  379. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  380. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  381. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  382. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  383. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  384. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  385. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  386. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  387. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  388. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  389. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  390. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  391. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  392. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  393. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  394. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  395. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  396. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  397. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  398. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  399. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  400. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  401. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  402. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  403. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  404. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  405. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  406. claude_mpm/dashboard/static/events.html +0 -607
  407. claude_mpm/dashboard/static/index.html +0 -635
  408. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  409. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  410. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  411. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  412. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  413. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  414. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  415. claude_mpm/dashboard/static/legacy/files.html +0 -747
  416. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  417. claude_mpm/dashboard/static/monitors.html +0 -431
  418. claude_mpm/dashboard/static/production/events.html +0 -659
  419. claude_mpm/dashboard/static/production/main.html +0 -698
  420. claude_mpm/dashboard/static/production/monitors.html +0 -483
  421. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  422. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  423. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  424. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  425. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  426. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  427. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  428. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  429. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  430. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  431. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  432. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  433. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  434. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  435. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  436. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  437. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  438. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  439. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  440. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  441. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  442. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  443. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  444. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  445. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  446. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  447. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  448. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  449. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  450. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  451. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  452. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  453. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  454. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  455. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  456. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  457. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  458. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  459. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  460. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  461. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  462. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  463. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  464. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  465. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  466. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  467. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  468. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  469. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  470. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  471. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  472. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  473. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  474. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  475. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  476. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  477. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  478. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  479. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  480. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  481. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  482. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  483. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  484. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  485. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  486. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  487. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  488. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  489. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  490. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  491. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  492. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  493. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  494. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  495. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  496. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  497. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  498. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  499. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
  500. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
  501. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
  502. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
  503. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
  504. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
  505. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  506. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  507. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  508. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  509. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  510. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  511. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  512. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  513. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  514. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/WHEEL +0 -0
  515. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/entry_points.txt +0 -0
  516. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/licenses/LICENSE +0 -0
  517. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/top_level.txt +0 -0
@@ -21,11 +21,9 @@ from ...services.cli.agent_dependency_service import AgentDependencyService
21
21
  from ...services.cli.agent_listing_service import AgentListingService
22
22
  from ...services.cli.agent_output_formatter import AgentOutputFormatter
23
23
  from ...services.cli.agent_validation_service import AgentValidationService
24
- from ..shared import (
25
- AgentCommand,
26
- CommandResult,
27
- )
24
+ from ..shared import AgentCommand, CommandResult
28
25
  from ..utils import get_agent_versions_display
26
+ from .agents_cleanup import handle_agents_cleanup
29
27
 
30
28
 
31
29
  def _is_structured_output(args) -> bool:
@@ -149,6 +147,7 @@ class AgentsCommand(AgentCommand):
149
147
  "deps-install": self._install_agent_dependencies,
150
148
  "deps-list": self._list_agent_dependencies,
151
149
  "deps-fix": self._fix_agent_dependencies,
150
+ "cleanup": lambda a: self._handle_cleanup_command(a),
152
151
  "cleanup-orphaned": self._cleanup_orphaned_agents,
153
152
  # Local agent management commands
154
153
  "create": self._create_local_agent,
@@ -156,9 +155,28 @@ class AgentsCommand(AgentCommand):
156
155
  "delete": self._delete_local_agent,
157
156
  "manage": self._manage_local_agents,
158
157
  "configure": self._configure_deployment,
158
+ # Migration command (DEPRECATION support)
159
+ "migrate-to-project": self._migrate_to_project,
159
160
  # Auto-configuration commands (TSK-0054 Phase 5)
160
161
  "detect": self._detect_toolchain,
161
162
  "recommend": self._recommend_agents,
163
+ # Agent selection modes (Phase 3: 1M-382)
164
+ "deploy-minimal": self._deploy_minimal_configuration,
165
+ "deploy-auto": self._deploy_auto_configure,
166
+ # Agent source management (Phase 2: 1M-442)
167
+ "available": self._list_available_from_sources,
168
+ # Agent discovery with rich filtering (Phase 1: Discovery & Browsing)
169
+ "discover": self._discover_agents,
170
+ # NEW: Collection-based agent management
171
+ "list-collections": self._list_collections,
172
+ "deploy-collection": self._deploy_collection,
173
+ "list-by-collection": self._list_by_collection,
174
+ # Cache git management commands
175
+ "cache-status": self._cache_status,
176
+ "cache-pull": self._cache_pull,
177
+ "cache-push": self._cache_push,
178
+ "cache-sync": self._cache_sync,
179
+ "cache-commit": self._cache_commit,
162
180
  }
163
181
 
164
182
  if args.agents_command in command_map:
@@ -396,31 +414,210 @@ class AgentsCommand(AgentCommand):
396
414
  self.logger.error(f"Error listing agents by tier: {e}", exc_info=True)
397
415
  return CommandResult.error_result(f"Error listing agents by tier: {e}")
398
416
 
417
+ def _list_available_from_sources(self, args) -> CommandResult:
418
+ """List available agents from all configured git sources.
419
+
420
+ This command shows agents discovered from configured agent sources
421
+ (Git repositories) after syncing their cache. Implements Phase 2 of 1M-442.
422
+
423
+ Args:
424
+ args: Command arguments with optional source filter and format
425
+
426
+ Returns:
427
+ CommandResult with agent list or error
428
+ """
429
+ try:
430
+ from ...config.agent_sources import AgentSourceConfiguration
431
+ from ...services.agents.git_source_manager import GitSourceManager
432
+
433
+ # Load agent sources configuration
434
+ config = AgentSourceConfiguration.load()
435
+ enabled_repos = [r for r in config.repositories if r.enabled]
436
+
437
+ if not enabled_repos:
438
+ message = (
439
+ "No agent sources configured.\n\n"
440
+ "Configure sources with:\n"
441
+ " claude-mpm agent-source add <url>\n\n"
442
+ "Example:\n"
443
+ " claude-mpm agent-source add https://github.com/owner/repo/agents"
444
+ )
445
+ print(message)
446
+ return CommandResult.error_result("No agent sources configured")
447
+
448
+ # Initialize git source manager
449
+ manager = GitSourceManager()
450
+
451
+ # Sync all configured sources (with timeout)
452
+ self.logger.info(f"Syncing {len(enabled_repos)} agent sources...")
453
+ sync_results = {}
454
+
455
+ for repo in enabled_repos:
456
+ try:
457
+ result = manager.sync_repository(repo, force=False)
458
+ sync_results[repo.identifier] = result
459
+ except Exception as e:
460
+ self.logger.warning(f"Failed to sync {repo.identifier}: {e}")
461
+ sync_results[repo.identifier] = {"synced": False, "error": str(e)}
462
+
463
+ # Get source filter from args
464
+ source_filter = getattr(args, "source", None)
465
+
466
+ # List all cached agents
467
+ all_agents = manager.list_cached_agents(repo_identifier=source_filter)
468
+
469
+ if not all_agents:
470
+ message = "No agents found in configured sources."
471
+ if sync_results:
472
+ failed_count = sum(
473
+ 1 for r in sync_results.values() if not r.get("synced")
474
+ )
475
+ if failed_count > 0:
476
+ message += f"\n\n{failed_count} source(s) failed to sync. Check logs for details."
477
+ print(message)
478
+ return CommandResult.success_result(message, data={"agents": []})
479
+
480
+ # Format output
481
+ output_format = getattr(args, "format", "table")
482
+
483
+ if output_format == "json":
484
+ import json
485
+
486
+ print(json.dumps(all_agents, indent=2))
487
+ elif output_format == "simple":
488
+ for agent in all_agents:
489
+ name = agent.get("metadata", {}).get(
490
+ "name", agent.get("agent_id", "unknown")
491
+ )
492
+ repo = agent.get("repository", "unknown")
493
+ print(f"{name} (from {repo})")
494
+ else: # table format
495
+ print(f"\n{'Agent Name':<30} {'Repository':<40} {'Version':<15}")
496
+ print("=" * 85)
497
+ for agent in all_agents:
498
+ name = agent.get("metadata", {}).get(
499
+ "name", agent.get("agent_id", "unknown")
500
+ )
501
+ repo = agent.get("repository", "unknown")
502
+ version = agent.get("version", "unknown")[:12]
503
+ print(f"{name:<30} {repo:<40} {version:<15}")
504
+ print(
505
+ f"\nTotal: {len(all_agents)} agents from {len(sync_results)} sources"
506
+ )
507
+
508
+ return CommandResult.success_result(
509
+ f"Listed {len(all_agents)} agents from sources",
510
+ data={"agents": all_agents, "sync_results": sync_results},
511
+ )
512
+
513
+ except Exception as e:
514
+ self.logger.error(f"Error listing available agents: {e}", exc_info=True)
515
+ return CommandResult.error_result(f"Error listing available agents: {e}")
516
+
517
+ def _discover_agents(self, args) -> CommandResult:
518
+ """Discover agents with rich filtering capabilities.
519
+
520
+ This command extends the 'available' command by adding semantic filtering
521
+ based on AUTO-DEPLOY-INDEX.md categories. Users can filter by category,
522
+ language, framework, platform, and specialization.
523
+
524
+ Design Decision: Delegate to agents_discover.py module
525
+
526
+ Rationale: Keep CLI command logic separate from routing logic for better
527
+ testability and maintainability. The discover_command function handles
528
+ all the complex filtering and formatting logic.
529
+
530
+ Args:
531
+ args: Command arguments with filter options:
532
+ - source: Source repository filter
533
+ - category: Category filter (e.g., 'engineer/backend')
534
+ - language: Language filter (e.g., 'python')
535
+ - framework: Framework filter (e.g., 'react')
536
+ - platform: Platform filter (e.g., 'vercel')
537
+ - specialization: Specialization filter (e.g., 'data')
538
+ - format: Output format (table, json, simple)
539
+ - verbose: Show descriptions and metadata
540
+
541
+ Returns:
542
+ CommandResult with filtered agent list or error
543
+
544
+ Example:
545
+ >>> # Called via: claude-mpm agents discover --category engineer/backend
546
+ >>> _discover_agents(args)
547
+ CommandResult(success=True, message="Discovered 8 agents")
548
+ """
549
+ try:
550
+ from .agents_discover import discover_command
551
+
552
+ # Call discover_command and convert exit code to CommandResult
553
+ exit_code = discover_command(args)
554
+
555
+ if exit_code == 0:
556
+ return CommandResult.success_result("Agent discovery complete")
557
+ return CommandResult.error_result("Agent discovery failed")
558
+
559
+ except Exception as e:
560
+ self.logger.error(f"Error discovering agents: {e}", exc_info=True)
561
+ return CommandResult.error_result(f"Error discovering agents: {e}")
562
+
399
563
  def _deploy_agents(self, args, force=False) -> CommandResult:
400
- """Deploy both system and project agents."""
564
+ """Deploy agents using two-phase sync: cache → deploy.
565
+
566
+ Phase 3 Integration (1M-486): Uses Git sync service for deployment.
567
+ - Phase 1: Sync agents to ~/.claude-mpm/cache/remote-agents/ (if needed)
568
+ - Phase 2: Deploy from cache to project .claude-mpm/agents/
569
+
570
+ This replaces the old single-tier deployment with a multi-project
571
+ architecture where one cache serves multiple project deployments.
572
+ """
401
573
  try:
402
- # Deploy system agents
403
- system_result = self.deployment_service.deploy_system_agents(force=force)
574
+ # Handle preset deployment (uses different path)
575
+ if hasattr(args, "preset") and args.preset:
576
+ return self._deploy_preset(args)
577
+
578
+ from ...services.agents.sources.git_source_sync_service import (
579
+ GitSourceSyncService,
580
+ )
404
581
 
405
- # Deploy project agents if they exist
406
- project_result = self.deployment_service.deploy_project_agents(force=force)
582
+ # Initialize git sync service
583
+ git_sync = GitSourceSyncService()
584
+ project_dir = Path.cwd()
407
585
 
408
- # Combine results
586
+ self.logger.info("Phase 1: Syncing agents to cache...")
587
+
588
+ # Sync to cache (downloads from GitHub if needed)
589
+ sync_result = git_sync.sync_repository(force=force)
590
+
591
+ if not sync_result.get("synced"):
592
+ error_msg = sync_result.get("error", "Unknown sync error")
593
+ self.logger.error(f"Sync failed: {error_msg}")
594
+ return CommandResult.error_result(f"Sync failed: {error_msg}")
595
+
596
+ self.logger.info(
597
+ f"Phase 1 complete: {sync_result.get('agent_count', 0)} agents in cache"
598
+ )
599
+ self.logger.info(f"Phase 2: Deploying agents to {project_dir}...")
600
+
601
+ # Deploy from cache to project directory
602
+ deploy_result = git_sync.deploy_agents_to_project(
603
+ project_dir=project_dir,
604
+ agent_list=None, # Deploy all cached agents
605
+ force=force,
606
+ )
607
+
608
+ # Format combined results for output
409
609
  combined_result = {
410
- "deployed_count": system_result.get("deployed_count", 0)
411
- + project_result.get("deployed_count", 0),
412
- "deployed": system_result.get("deployed", [])
413
- + project_result.get("deployed", []),
414
- "updated_count": system_result.get("updated_count", 0)
415
- + project_result.get("updated_count", 0),
416
- "updated": system_result.get("updated", [])
417
- + project_result.get("updated", []),
418
- "skipped": system_result.get("skipped", [])
419
- + project_result.get("skipped", []),
420
- "errors": system_result.get("errors", [])
421
- + project_result.get("errors", []),
422
- "target_dir": system_result.get("target_dir")
423
- or project_result.get("target_dir"),
610
+ "deployed_count": len(deploy_result.get("deployed", []))
611
+ + len(deploy_result.get("updated", [])),
612
+ "deployed": deploy_result.get("deployed", []),
613
+ "updated": deploy_result.get("updated", []),
614
+ "skipped": deploy_result.get("skipped", []),
615
+ "errors": deploy_result.get("failed", []),
616
+ "target_dir": deploy_result.get("deployment_dir", ""),
617
+ "sync_info": {
618
+ "cached_agents": sync_result.get("agent_count", 0),
619
+ "cache_dir": sync_result.get("cache_dir", ""),
620
+ },
424
621
  }
425
622
 
426
623
  output_format = self._get_output_format(args)
@@ -431,12 +628,15 @@ class AgentsCommand(AgentCommand):
431
628
  )
432
629
  print(formatted)
433
630
 
631
+ success_count = len(deploy_result["deployed"]) + len(
632
+ deploy_result["updated"]
633
+ )
434
634
  return CommandResult.success_result(
435
- f"Deployed {combined_result['deployed_count']} agents",
635
+ f"Deployed {success_count} agents from cache",
436
636
  data={
437
- "system_agents": system_result,
438
- "project_agents": project_result,
439
- "total_deployed": combined_result["deployed_count"],
637
+ "sync_result": sync_result,
638
+ "deploy_result": deploy_result,
639
+ "total_deployed": success_count,
440
640
  },
441
641
  )
442
642
 
@@ -444,6 +644,173 @@ class AgentsCommand(AgentCommand):
444
644
  self.logger.error(f"Error deploying agents: {e}", exc_info=True)
445
645
  return CommandResult.error_result(f"Error deploying agents: {e}")
446
646
 
647
+ def _deploy_preset(self, args) -> CommandResult:
648
+ """Deploy agents by preset name.
649
+
650
+ This method implements Phase 2 of the agents/skills CLI redesign,
651
+ enabling preset-based deployment like:
652
+ claude-mpm agents deploy --preset python-dev
653
+
654
+ Args:
655
+ args: Command arguments with preset name and optional flags
656
+
657
+ Returns:
658
+ CommandResult with deployment status
659
+ """
660
+ try:
661
+ from pathlib import Path
662
+
663
+ from ...config.agent_sources import AgentSourceConfiguration
664
+ from ...services.agents.agent_preset_service import AgentPresetService
665
+ from ...services.agents.git_source_manager import GitSourceManager
666
+ from ...services.agents.single_tier_deployment_service import (
667
+ SingleTierDeploymentService,
668
+ )
669
+
670
+ preset_name = args.preset
671
+ dry_run = getattr(args, "dry_run", False)
672
+
673
+ # Initialize services
674
+ config = AgentSourceConfiguration.load()
675
+ deployment_dir = Path.home() / ".claude" / "agents"
676
+ git_source_manager = GitSourceManager()
677
+ preset_service = AgentPresetService(git_source_manager)
678
+ deployment_service = SingleTierDeploymentService(config, deployment_dir)
679
+
680
+ # Validate preset
681
+ if not preset_service.validate_preset(preset_name):
682
+ available = preset_service.list_presets()
683
+ print(f"❌ Unknown preset: {preset_name}")
684
+ print("\n📚 Available presets:")
685
+ for preset in available:
686
+ print(
687
+ f" • {preset['name']}: {preset['description']} ({preset['agent_count']} agents)"
688
+ )
689
+ print(f" Use cases: {', '.join(preset['use_cases'])}")
690
+ return CommandResult.error_result(f"Unknown preset: {preset_name}")
691
+
692
+ # Resolve preset to agent list
693
+ print(f"\n🔍 Resolving preset: {preset_name}")
694
+ resolution = preset_service.resolve_agents(
695
+ preset_name, validate_availability=True
696
+ )
697
+
698
+ # Show preset info
699
+ preset_info = resolution["preset_info"]
700
+ print(f"\n🎯 Preset: {preset_info['description']}")
701
+ print(f" Agents: {preset_info['agent_count']}")
702
+ print(f" Use cases: {', '.join(preset_info['use_cases'])}")
703
+
704
+ # Show warnings for missing agents
705
+ if resolution["missing_agents"]:
706
+ print("\n⚠️ Missing agents (not found in configured sources):")
707
+ for agent_id in resolution["missing_agents"]:
708
+ print(f" • {agent_id}")
709
+ print("\n💡 These agents are not available in your configured sources.")
710
+ print(" Deployment will continue with available agents.")
711
+
712
+ # Show conflicts
713
+ if resolution["conflicts"]:
714
+ print("\n⚠️ Priority conflicts detected:")
715
+ for conflict in resolution["conflicts"]:
716
+ sources = ", ".join(conflict["sources"])
717
+ print(f" • {conflict['agent_id']} (found in: {sources})")
718
+ print(" Using highest priority source for each")
719
+
720
+ # Dry run mode
721
+ if dry_run:
722
+ print("\n🔍 DRY RUN: Preview agent deployment\n")
723
+ print("Agents to deploy:")
724
+ for agent in resolution["agents"]:
725
+ source = agent.get("source", "unknown")
726
+ print(f" ✓ {agent['agent_id']} (from {source})")
727
+ print(
728
+ "\n💡 This is a dry run. Run without --dry-run to actually deploy."
729
+ )
730
+ return CommandResult.success_result(
731
+ "Dry run complete",
732
+ data={
733
+ "preset": preset_name,
734
+ "agents": resolution["agents"],
735
+ "missing": resolution["missing_agents"],
736
+ },
737
+ )
738
+
739
+ # Deploy agents
740
+ print(f"\n📦 Deploying {len(resolution['agents'])} agents...")
741
+ deployed_count = 0
742
+ failed_count = 0
743
+ skipped_count = len(resolution["missing_agents"])
744
+ deployed_agents = []
745
+ failed_agents = []
746
+
747
+ for agent in resolution["agents"]:
748
+ agent_id = agent["agent_id"]
749
+ try:
750
+ # Deploy using single-tier deployment service
751
+ result = deployment_service.deploy_agent(
752
+ agent_id, source_repo=agent.get("source"), dry_run=False
753
+ )
754
+
755
+ if result.get("deployed"):
756
+ deployed_count += 1
757
+ deployed_agents.append(agent_id)
758
+ print(f" ✓ {agent_id}")
759
+ else:
760
+ failed_count += 1
761
+ failed_agents.append(
762
+ {
763
+ "agent_id": agent_id,
764
+ "error": result.get("error", "Unknown"),
765
+ }
766
+ )
767
+ print(f" ✗ {agent_id}: {result.get('error', 'Failed')}")
768
+
769
+ except Exception as e:
770
+ failed_count += 1
771
+ failed_agents.append({"agent_id": agent_id, "error": str(e)})
772
+ print(f" ✗ {agent_id}: {e}")
773
+
774
+ # Summary
775
+ print(f"\n{'=' * 60}")
776
+ print("📊 Deployment Summary")
777
+ print(f"{'=' * 60}")
778
+ print(f" ✅ Deployed: {deployed_count}")
779
+ print(f" ❌ Failed: {failed_count}")
780
+ print(f" ⏭️ Skipped: {skipped_count} (missing from sources)")
781
+ print(f"{'=' * 60}\n")
782
+
783
+ if failed_agents:
784
+ print("❌ Failed agents:")
785
+ for failure in failed_agents:
786
+ print(f" • {failure['agent_id']}: {failure['error']}")
787
+ print()
788
+
789
+ if deployed_count > 0:
790
+ print(f"✅ Successfully deployed {deployed_count} agents!")
791
+ return CommandResult.success_result(
792
+ f"Deployed {deployed_count} agents from preset '{preset_name}'",
793
+ data={
794
+ "preset": preset_name,
795
+ "deployed": deployed_agents,
796
+ "failed": failed_agents,
797
+ "skipped": resolution["missing_agents"],
798
+ },
799
+ )
800
+ return CommandResult.error_result(
801
+ f"No agents deployed from preset '{preset_name}'",
802
+ data={
803
+ "preset": preset_name,
804
+ "failed": failed_agents,
805
+ "skipped": resolution["missing_agents"],
806
+ },
807
+ )
808
+
809
+ except Exception as e:
810
+ self.logger.error(f"Error deploying preset: {e}", exc_info=True)
811
+ print(f"\n❌ Error deploying preset: {e}")
812
+ return CommandResult.error_result(f"Error deploying preset: {e}")
813
+
447
814
  def _clean_agents(self, args) -> CommandResult:
448
815
  """Clean deployed agents."""
449
816
  try:
@@ -904,6 +1271,16 @@ class AgentsCommand(AgentCommand):
904
1271
  self.logger.error(f"Error fixing dependencies: {e}", exc_info=True)
905
1272
  return CommandResult.error_result(f"Error fixing dependencies: {e}")
906
1273
 
1274
+ def _handle_cleanup_command(self, args) -> CommandResult:
1275
+ """Handle cleanup command with proper result wrapping."""
1276
+ exit_code = handle_agents_cleanup(args)
1277
+ return CommandResult(
1278
+ success=exit_code == 0,
1279
+ message=(
1280
+ "Agent cleanup complete" if exit_code == 0 else "Agent cleanup failed"
1281
+ ),
1282
+ )
1283
+
907
1284
  def _cleanup_orphaned_agents(self, args) -> CommandResult:
908
1285
  """Clean up orphaned agents that don't have templates."""
909
1286
  try:
@@ -1125,18 +1502,46 @@ class AgentsCommand(AgentCommand):
1125
1502
  return CommandResult.error_result(f"Error deleting local agents: {e}")
1126
1503
 
1127
1504
  def _manage_local_agents(self, args) -> CommandResult:
1128
- """Launch interactive management menu for local agents."""
1505
+ """Redirect to main configuration interface (DEPRECATED)."""
1129
1506
  try:
1130
- from ..interactive.agent_wizard import run_interactive_agent_manager
1507
+ from rich.console import Console
1508
+ from rich.prompt import Confirm
1131
1509
 
1132
- exit_code = run_interactive_agent_manager()
1133
- if exit_code == 0:
1134
- return CommandResult.success_result("Agent management completed")
1135
- return CommandResult.error_result("Agent management failed or cancelled")
1510
+ console = Console()
1511
+
1512
+ console.print(
1513
+ "\n[bold cyan]╭─────────────────────────────────────────╮[/bold cyan]"
1514
+ )
1515
+ console.print(
1516
+ "[bold cyan]│ Agent Management Has Moved! │[/bold cyan]"
1517
+ )
1518
+ console.print(
1519
+ "[bold cyan]╰─────────────────────────────────────────╯[/bold cyan]\n"
1520
+ )
1521
+
1522
+ console.print("For a better experience with integrated configuration:")
1523
+ console.print(" • Agent management")
1524
+ console.print(" • Skills management")
1525
+ console.print(" • Template editing")
1526
+ console.print(" • Behavior configuration")
1527
+ console.print(" • Startup settings\n")
1528
+
1529
+ console.print("Please use: [bold green]claude-mpm config[/bold green]\n")
1530
+
1531
+ if Confirm.ask("Launch configuration interface now?", default=True):
1532
+ # Import and run config command directly
1533
+ from claude_mpm.cli.commands.configure import ConfigureCommand
1534
+
1535
+ config_cmd = ConfigureCommand()
1536
+ return config_cmd.execute(args)
1537
+ console.print(
1538
+ "\n[dim]Run 'claude-mpm config' anytime to access agent management[/dim]"
1539
+ )
1540
+ return CommandResult.success_result("Redirected to config interface")
1136
1541
 
1137
1542
  except Exception as e:
1138
- self.logger.error(f"Error managing local agents: {e}", exc_info=True)
1139
- return CommandResult.error_result(f"Error managing local agents: {e}")
1543
+ self.logger.error(f"Error redirecting to config: {e}", exc_info=True)
1544
+ return CommandResult.error_result(f"Error redirecting to config: {e}")
1140
1545
 
1141
1546
  def _configure_deployment(self, args) -> CommandResult:
1142
1547
  """Configure agent deployment settings."""
@@ -1448,6 +1853,693 @@ class AgentsCommand(AgentCommand):
1448
1853
  self.logger.error(f"Error recommending agents: {e}", exc_info=True)
1449
1854
  return CommandResult.error_result(f"Error recommending agents: {e}")
1450
1855
 
1856
+ def _migrate_to_project(self, args) -> CommandResult:
1857
+ """Migrate user-level agents to project-level.
1858
+
1859
+ DEPRECATION: User-level agents (~/.claude-mpm/agents/) are deprecated and
1860
+ will be removed in v5.0.0. This command migrates them to project-level
1861
+ (.claude-mpm/agents/) where they belong.
1862
+
1863
+ Args:
1864
+ args: Command arguments with dry_run and force flags
1865
+
1866
+ Returns:
1867
+ CommandResult with migration status
1868
+ """
1869
+ import shutil
1870
+
1871
+ try:
1872
+ user_agents_dir = Path.home() / ".claude-mpm" / "agents"
1873
+ project_agents_dir = Path.cwd() / ".claude-mpm" / "agents"
1874
+
1875
+ dry_run = getattr(args, "dry_run", False)
1876
+ force = getattr(args, "force", False)
1877
+
1878
+ # Check if user agents directory exists
1879
+ if not user_agents_dir.exists():
1880
+ print("✅ No user-level agents found. Nothing to migrate.")
1881
+ return CommandResult.success_result("No user-level agents to migrate")
1882
+
1883
+ # Find all user agent files
1884
+ user_agent_files = list(user_agents_dir.glob("*.json")) + list(
1885
+ user_agents_dir.glob("*.md")
1886
+ )
1887
+
1888
+ if not user_agent_files:
1889
+ print("✅ No user-level agents found. Nothing to migrate.")
1890
+ return CommandResult.success_result("No user-level agents to migrate")
1891
+
1892
+ # Display what we found
1893
+ print(f"\n📦 Found {len(user_agent_files)} user-level agent(s) to migrate:")
1894
+ for agent_file in user_agent_files:
1895
+ print(f" - {agent_file.name}")
1896
+
1897
+ if dry_run:
1898
+ print("\n🔍 DRY RUN: Would migrate to:")
1899
+ print(f" → {project_agents_dir}")
1900
+ print("\nRun without --dry-run to perform the migration.")
1901
+ return CommandResult.success_result(
1902
+ "Dry run completed",
1903
+ data={
1904
+ "user_agents_found": len(user_agent_files),
1905
+ "target_directory": str(project_agents_dir),
1906
+ },
1907
+ )
1908
+
1909
+ # Create project agents directory
1910
+ project_agents_dir.mkdir(parents=True, exist_ok=True)
1911
+
1912
+ # Migrate agents
1913
+ migrated = 0
1914
+ skipped = 0
1915
+ errors = []
1916
+
1917
+ for agent_file in user_agent_files:
1918
+ target_file = project_agents_dir / agent_file.name
1919
+
1920
+ # Check for conflicts
1921
+ if target_file.exists() and not force:
1922
+ print(f"⚠️ Skipping {agent_file.name} (already exists in project)")
1923
+ print(" Use --force to overwrite existing agents")
1924
+ skipped += 1
1925
+ continue
1926
+
1927
+ try:
1928
+ # Copy agent to project directory
1929
+ shutil.copy2(agent_file, target_file)
1930
+ migrated += 1
1931
+ print(f"✅ Migrated {agent_file.name}")
1932
+ except Exception as e:
1933
+ error_msg = f"Failed to migrate {agent_file.name}: {e}"
1934
+ errors.append(error_msg)
1935
+ print(f"❌ {error_msg}")
1936
+
1937
+ # Summary
1938
+ print("\n📊 Migration Summary:")
1939
+ print(f" ✅ Migrated: {migrated}/{len(user_agent_files)}")
1940
+ if skipped > 0:
1941
+ print(f" ⏭️ Skipped: {skipped} (already exist)")
1942
+ if errors:
1943
+ print(f" ❌ Errors: {len(errors)}")
1944
+
1945
+ if migrated > 0:
1946
+ print(f"\n✅ Successfully migrated {migrated} agent(s) to:")
1947
+ print(f" {project_agents_dir}")
1948
+ print(
1949
+ "\n⚠️ IMPORTANT: Verify agents work correctly, then remove user-level agents:"
1950
+ )
1951
+ print(f" rm -rf {user_agents_dir}")
1952
+ print("\n💡 Why this change?")
1953
+ print(" - Project isolation: Each project has its own agents")
1954
+ print(" - Version control: Agents can be versioned with your code")
1955
+ print(" - Team consistency: Everyone uses the same agents")
1956
+
1957
+ return CommandResult.success_result(
1958
+ f"Migrated {migrated} agents",
1959
+ data={
1960
+ "migrated": migrated,
1961
+ "skipped": skipped,
1962
+ "errors": errors,
1963
+ "total": len(user_agent_files),
1964
+ },
1965
+ )
1966
+
1967
+ except Exception as e:
1968
+ self.logger.error(f"Error migrating agents: {e}", exc_info=True)
1969
+ return CommandResult.error_result(f"Error migrating agents: {e}")
1970
+
1971
+ def _deploy_minimal_configuration(self, args) -> CommandResult:
1972
+ """Deploy minimal configuration (6 core agents).
1973
+
1974
+ Part of Phase 3 (1M-382): Agent Selection Modes.
1975
+ Deploy exactly 6 agents for basic Claude MPM workflow:
1976
+ engineer, documentation, qa, research, ops, ticketing.
1977
+ """
1978
+ try:
1979
+ from ...config.agent_sources import AgentSourceConfiguration
1980
+ from ...services.agents.agent_selection_service import AgentSelectionService
1981
+ from ...services.agents.single_tier_deployment_service import (
1982
+ SingleTierDeploymentService,
1983
+ )
1984
+
1985
+ # Initialize services
1986
+ config = AgentSourceConfiguration.load()
1987
+ deployment_dir = Path.home() / ".claude" / "agents"
1988
+ deployment_service = SingleTierDeploymentService(config, deployment_dir)
1989
+ selection_service = AgentSelectionService(deployment_service)
1990
+
1991
+ # Get dry_run flag
1992
+ dry_run = getattr(args, "dry_run", False)
1993
+
1994
+ # Deploy minimal configuration
1995
+ print("🎯 Deploying minimal configuration (6 core agents)...")
1996
+ if dry_run:
1997
+ print("🔍 DRY RUN MODE - No agents will be deployed\n")
1998
+
1999
+ result = selection_service.deploy_minimal_configuration(dry_run=dry_run)
2000
+
2001
+ # Format output
2002
+ output_format = self._get_output_format(args)
2003
+ if self._is_structured_format(output_format):
2004
+ formatted = (
2005
+ self._formatter.format_as_json(result)
2006
+ if str(output_format).lower() == OutputFormat.JSON
2007
+ else self._formatter.format_as_yaml(result)
2008
+ )
2009
+ print(formatted)
2010
+ return CommandResult.success_result(
2011
+ f"Minimal configuration {result['status']}", data=result
2012
+ )
2013
+
2014
+ # Text output
2015
+ print(f"\n{'=' * 60}")
2016
+ print(f"Status: {result['status'].upper()}")
2017
+ print(f"Mode: {result['mode']}")
2018
+ print(f"{'=' * 60}")
2019
+ print(
2020
+ f"\n📊 Summary: {result['deployed_count']} deployed, "
2021
+ f"{result['failed_count']} failed, {result['missing_count']} missing"
2022
+ )
2023
+
2024
+ if result["deployed_agents"]:
2025
+ print(f"\n✅ Deployed agents ({len(result['deployed_agents'])}):")
2026
+ for agent in result["deployed_agents"]:
2027
+ print(f" • {agent}")
2028
+
2029
+ if result["failed_agents"]:
2030
+ print(f"\n❌ Failed agents ({len(result['failed_agents'])}):")
2031
+ for agent in result["failed_agents"]:
2032
+ print(f" • {agent}")
2033
+
2034
+ if result["missing_agents"]:
2035
+ print(f"\n⚠️ Missing agents ({len(result['missing_agents'])}):")
2036
+ for agent in result["missing_agents"]:
2037
+ print(f" • {agent}")
2038
+ print("\nThese agents are not available in configured sources.")
2039
+
2040
+ if dry_run:
2041
+ print(
2042
+ "\n💡 This was a dry run. Run without --dry-run to deploy agents."
2043
+ )
2044
+
2045
+ return CommandResult.success_result(
2046
+ f"Minimal configuration {result['status']}", data=result
2047
+ )
2048
+
2049
+ except Exception as e:
2050
+ self.logger.error(
2051
+ f"Error deploying minimal configuration: {e}", exc_info=True
2052
+ )
2053
+ return CommandResult.error_result(
2054
+ f"Error deploying minimal configuration: {e}"
2055
+ )
2056
+
2057
+ def _deploy_auto_configure(self, args) -> CommandResult:
2058
+ """Auto-detect toolchain and deploy matching agents.
2059
+
2060
+ Part of Phase 3 (1M-382): Agent Selection Modes.
2061
+ Detect project toolchain (languages, frameworks, build tools) and
2062
+ deploy matching specialized agents.
2063
+ """
2064
+ try:
2065
+ from ...config.agent_sources import AgentSourceConfiguration
2066
+ from ...services.agents.agent_selection_service import AgentSelectionService
2067
+ from ...services.agents.single_tier_deployment_service import (
2068
+ SingleTierDeploymentService,
2069
+ )
2070
+
2071
+ # Initialize services
2072
+ config = AgentSourceConfiguration.load()
2073
+ deployment_dir = Path.home() / ".claude" / "agents"
2074
+ deployment_service = SingleTierDeploymentService(config, deployment_dir)
2075
+ selection_service = AgentSelectionService(deployment_service)
2076
+
2077
+ # Get arguments
2078
+ project_path = getattr(args, "path", Path.cwd())
2079
+ dry_run = getattr(args, "dry_run", False)
2080
+
2081
+ # Deploy auto-configure
2082
+ print(f"🔍 Auto-detecting toolchain in {project_path}...")
2083
+ if dry_run:
2084
+ print("🔍 DRY RUN MODE - No agents will be deployed\n")
2085
+
2086
+ result = selection_service.deploy_auto_configure(
2087
+ project_path=project_path, dry_run=dry_run
2088
+ )
2089
+
2090
+ # Format output
2091
+ output_format = self._get_output_format(args)
2092
+ if self._is_structured_format(output_format):
2093
+ formatted = (
2094
+ self._formatter.format_as_json(result)
2095
+ if str(output_format).lower() == OutputFormat.JSON
2096
+ else self._formatter.format_as_yaml(result)
2097
+ )
2098
+ print(formatted)
2099
+ return CommandResult.success_result(
2100
+ f"Auto-configure {result['status']}", data=result
2101
+ )
2102
+
2103
+ # Text output
2104
+ print(f"\n{'=' * 60}")
2105
+ print(f"Status: {result['status'].upper()}")
2106
+ print(f"Mode: {result['mode']}")
2107
+ print(f"{'=' * 60}")
2108
+
2109
+ # Show detected toolchain
2110
+ toolchain = result.get("toolchain", {})
2111
+ print("\n🔧 Detected Toolchain:")
2112
+ if toolchain.get("languages"):
2113
+ print(f" Languages: {', '.join(toolchain['languages'])}")
2114
+ if toolchain.get("frameworks"):
2115
+ print(f" Frameworks: {', '.join(toolchain['frameworks'])}")
2116
+ if toolchain.get("build_tools"):
2117
+ print(f" Build Tools: {', '.join(toolchain['build_tools'])}")
2118
+
2119
+ if not any(toolchain.values()):
2120
+ print(" (No toolchain detected)")
2121
+
2122
+ # Show recommended agents
2123
+ recommended = result.get("recommended_agents", [])
2124
+ if recommended:
2125
+ print(f"\n🎯 Recommended agents ({len(recommended)}):")
2126
+ for agent in recommended:
2127
+ print(f" • {agent}")
2128
+
2129
+ # Show deployment summary
2130
+ print(
2131
+ f"\n📊 Summary: {result['deployed_count']} deployed, "
2132
+ f"{result['failed_count']} failed, {result['missing_count']} missing"
2133
+ )
2134
+
2135
+ if result.get("deployed_agents"):
2136
+ print(f"\n✅ Deployed agents ({len(result['deployed_agents'])}):")
2137
+ for agent in result["deployed_agents"]:
2138
+ print(f" • {agent}")
2139
+
2140
+ if result.get("failed_agents"):
2141
+ print(f"\n❌ Failed agents ({len(result['failed_agents'])}):")
2142
+ for agent in result["failed_agents"]:
2143
+ print(f" • {agent}")
2144
+
2145
+ if result.get("missing_agents"):
2146
+ print(f"\n⚠️ Missing agents ({len(result['missing_agents'])}):")
2147
+ for agent in result["missing_agents"]:
2148
+ print(f" • {agent}")
2149
+ print("\nThese agents are not available in configured sources.")
2150
+
2151
+ if dry_run:
2152
+ print(
2153
+ "\n💡 This was a dry run. Run without --dry-run to deploy agents."
2154
+ )
2155
+
2156
+ return CommandResult.success_result(
2157
+ f"Auto-configure {result['status']}", data=result
2158
+ )
2159
+
2160
+ except Exception as e:
2161
+ self.logger.error(f"Error in auto-configure: {e}", exc_info=True)
2162
+ return CommandResult.error_result(f"Error in auto-configure: {e}")
2163
+
2164
+ def _list_collections(self, args) -> CommandResult:
2165
+ """List all available agent collections.
2166
+
2167
+ NEW: Shows all collections with agent counts and metadata.
2168
+ Enables discovery of available agent collections before deployment.
2169
+ """
2170
+ try:
2171
+ from pathlib import Path
2172
+
2173
+ from ...services.agents.deployment.remote_agent_discovery_service import (
2174
+ RemoteAgentDiscoveryService,
2175
+ )
2176
+
2177
+ # Get remote agents cache directory
2178
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2179
+
2180
+ if not cache_dir.exists():
2181
+ return CommandResult.error_result(
2182
+ "No remote agent collections found. Run 'claude-mpm agents deploy' first."
2183
+ )
2184
+
2185
+ # Use RemoteAgentDiscoveryService to list collections
2186
+ remote_service = RemoteAgentDiscoveryService(cache_dir)
2187
+ collections = remote_service.list_collections()
2188
+
2189
+ if not collections:
2190
+ return CommandResult.success_result(
2191
+ "No agent collections found in cache.", data={"collections": []}
2192
+ )
2193
+
2194
+ # Format output
2195
+ output_lines = ["Available Agent Collections:\n"]
2196
+ for collection in collections:
2197
+ output_lines.append(
2198
+ f" • {collection['collection_id']} ({collection['agent_count']} agents)"
2199
+ )
2200
+
2201
+ return CommandResult.success_result(
2202
+ "\n".join(output_lines), data={"collections": collections}
2203
+ )
2204
+
2205
+ except Exception as e:
2206
+ self.logger.error(f"Error listing collections: {e}", exc_info=True)
2207
+ return CommandResult.error_result(f"Error listing collections: {e}")
2208
+
2209
+ def _deploy_collection(self, args) -> CommandResult:
2210
+ """Deploy all agents from a specific collection.
2211
+
2212
+ NEW: Enables bulk deployment of all agents from a named collection.
2213
+ Useful for deploying entire agent sets at once.
2214
+ """
2215
+ try:
2216
+ from pathlib import Path
2217
+
2218
+ from ...services.agents.deployment.multi_source_deployment_service import (
2219
+ MultiSourceAgentDeploymentService,
2220
+ )
2221
+
2222
+ collection_id = args.collection_id
2223
+
2224
+ # Get agents from collection
2225
+ service = MultiSourceAgentDeploymentService()
2226
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2227
+ agents = service.get_agents_by_collection(collection_id, cache_dir)
2228
+
2229
+ if not agents:
2230
+ return CommandResult.error_result(
2231
+ f"No agents found in collection '{collection_id}'"
2232
+ )
2233
+
2234
+ # Dry run mode
2235
+ if getattr(args, "dry_run", False):
2236
+ agent_names = [
2237
+ agent.get("metadata", {}).get("name", "Unknown") for agent in agents
2238
+ ]
2239
+ output = f"Would deploy {len(agents)} agents from collection '{collection_id}':\n"
2240
+ for name in agent_names:
2241
+ output += f" • {name}\n"
2242
+ return CommandResult.success_result(
2243
+ output,
2244
+ data={"collection_id": collection_id, "agent_count": len(agents)},
2245
+ )
2246
+
2247
+ # Deploy agents
2248
+ # TODO: Implement actual deployment logic using deployment service
2249
+ # For now, show what would be deployed
2250
+ return CommandResult.success_result(
2251
+ f"Deployment of collection '{collection_id}' would deploy {len(agents)} agents.\n"
2252
+ f"(Full deployment implementation pending)",
2253
+ data={
2254
+ "collection_id": collection_id,
2255
+ "agent_count": len(agents),
2256
+ "status": "pending_implementation",
2257
+ },
2258
+ )
2259
+
2260
+ except Exception as e:
2261
+ self.logger.error(f"Error deploying collection: {e}", exc_info=True)
2262
+ return CommandResult.error_result(f"Error deploying collection: {e}")
2263
+
2264
+ def _list_by_collection(self, args) -> CommandResult:
2265
+ """List agents from a specific collection.
2266
+
2267
+ NEW: Shows detailed information about agents in a collection.
2268
+ Supports multiple output formats (table, json, yaml).
2269
+ """
2270
+ try:
2271
+ import json as json_lib
2272
+ from pathlib import Path
2273
+
2274
+ from ...services.agents.deployment.multi_source_deployment_service import (
2275
+ MultiSourceAgentDeploymentService,
2276
+ )
2277
+
2278
+ collection_id = args.collection_id
2279
+ output_format = getattr(args, "format", "table")
2280
+
2281
+ # Get agents from collection
2282
+ service = MultiSourceAgentDeploymentService()
2283
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2284
+ agents = service.get_agents_by_collection(collection_id, cache_dir)
2285
+
2286
+ if not agents:
2287
+ return CommandResult.error_result(
2288
+ f"No agents found in collection '{collection_id}'"
2289
+ )
2290
+
2291
+ # Format output based on requested format
2292
+ if output_format == "json":
2293
+ return CommandResult.success_result(
2294
+ json_lib.dumps(agents, indent=2),
2295
+ data={"collection_id": collection_id, "agents": agents},
2296
+ )
2297
+ if output_format == "yaml":
2298
+ try:
2299
+ import yaml
2300
+
2301
+ return CommandResult.success_result(
2302
+ yaml.dump(agents, default_flow_style=False),
2303
+ data={"collection_id": collection_id, "agents": agents},
2304
+ )
2305
+ except ImportError:
2306
+ return CommandResult.error_result(
2307
+ "YAML support not available (install PyYAML)"
2308
+ )
2309
+
2310
+ # Table format (default)
2311
+ output_lines = [f"Agents in collection '{collection_id}':\n"]
2312
+ for agent in agents:
2313
+ metadata = agent.get("metadata", {})
2314
+ name = metadata.get("name", "Unknown")
2315
+ description = metadata.get("description", "No description")
2316
+ version = agent.get("version", "unknown")
2317
+ output_lines.append(f" • {name} (v{version})")
2318
+ output_lines.append(f" {description}\n")
2319
+
2320
+ return CommandResult.success_result(
2321
+ "\n".join(output_lines),
2322
+ data={"collection_id": collection_id, "agent_count": len(agents)},
2323
+ )
2324
+
2325
+ except Exception as e:
2326
+ self.logger.error(f"Error listing collection agents: {e}", exc_info=True)
2327
+ return CommandResult.error_result(f"Error listing collection agents: {e}")
2328
+
2329
+ def _cache_status(self, args) -> CommandResult:
2330
+ """Show git status of agent cache.
2331
+
2332
+ Displays current branch, uncommitted changes, unpushed commits, and
2333
+ remote URL for the agent cache repository.
2334
+ """
2335
+ try:
2336
+ from ...services.agents.cache_git_manager import CacheGitManager
2337
+
2338
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2339
+ manager = CacheGitManager(cache_dir)
2340
+
2341
+ if not manager.is_git_repo():
2342
+ print("❌ Cache is not a git repository")
2343
+ print(f"\nCache location: {cache_dir}")
2344
+ print(
2345
+ "\n💡 This is expected if you haven't cloned the agents repository."
2346
+ )
2347
+ print(" The cache will be managed via HTTP sync instead.")
2348
+ return CommandResult.error_result("Cache is not a git repository")
2349
+
2350
+ status = manager.get_status()
2351
+ output_format = self._get_output_format(args)
2352
+
2353
+ if self._is_structured_format(output_format):
2354
+ formatted = (
2355
+ self._formatter.format_as_json(status)
2356
+ if str(output_format).lower() == OutputFormat.JSON
2357
+ else self._formatter.format_as_yaml(status)
2358
+ )
2359
+ print(formatted)
2360
+ return CommandResult.success_result(
2361
+ "Cache status retrieved", data=status
2362
+ )
2363
+
2364
+ # Text output
2365
+ print(f"\n📁 Cache: {manager.repo_path}")
2366
+ print(f"🌿 Branch: {status.get('branch', 'unknown')}")
2367
+
2368
+ if status.get("remote_url"):
2369
+ print(f"🔗 Remote: {status['remote_url']}")
2370
+
2371
+ # Show sync status
2372
+ ahead = status.get("ahead", 0)
2373
+ behind = status.get("behind", 0)
2374
+
2375
+ if ahead > 0:
2376
+ print(f"📤 Ahead of remote: {ahead} commit(s)")
2377
+ if behind > 0:
2378
+ print(f"📥 Behind remote: {behind} commit(s)")
2379
+
2380
+ if ahead == 0 and behind == 0:
2381
+ print("✅ In sync with remote")
2382
+
2383
+ # Show uncommitted changes
2384
+ uncommitted = status.get("uncommitted", [])
2385
+ if uncommitted:
2386
+ print(f"\n⚠️ Uncommitted changes: {len(uncommitted)}")
2387
+ for file in uncommitted[:10]: # Show max 10 files
2388
+ print(f" - {file}")
2389
+ if len(uncommitted) > 10:
2390
+ print(f" ... and {len(uncommitted) - 10} more")
2391
+ else:
2392
+ print("\n✅ No uncommitted changes")
2393
+
2394
+ # Overall status
2395
+ if status.get("is_clean"):
2396
+ print("\n✨ Cache is clean and up-to-date")
2397
+ else:
2398
+ print("\n💡 Run 'claude-mpm agents cache-sync' to sync with remote")
2399
+
2400
+ return CommandResult.success_result("Cache status displayed", data=status)
2401
+
2402
+ except Exception as e:
2403
+ self.logger.error(f"Error getting cache status: {e}", exc_info=True)
2404
+ return CommandResult.error_result(f"Error getting cache status: {e}")
2405
+
2406
+ def _cache_pull(self, args) -> CommandResult:
2407
+ """Pull latest agents from remote repository."""
2408
+ try:
2409
+ from ...services.agents.cache_git_manager import CacheGitManager
2410
+
2411
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2412
+ manager = CacheGitManager(cache_dir)
2413
+
2414
+ if not manager.is_git_repo():
2415
+ print("❌ Cache is not a git repository")
2416
+ return CommandResult.error_result("Cache is not a git repository")
2417
+
2418
+ branch = getattr(args, "branch", "main")
2419
+ print(f"🔄 Pulling latest changes from {branch}...")
2420
+
2421
+ success, msg = manager.pull_latest(branch)
2422
+
2423
+ if success:
2424
+ print(f"✅ {msg}")
2425
+ return CommandResult.success_result(msg)
2426
+ print(f"❌ {msg}")
2427
+ return CommandResult.error_result(msg)
2428
+
2429
+ except Exception as e:
2430
+ self.logger.error(f"Error pulling cache: {e}", exc_info=True)
2431
+ return CommandResult.error_result(f"Error pulling cache: {e}")
2432
+
2433
+ def _cache_commit(self, args) -> CommandResult:
2434
+ """Commit changes to cache repository."""
2435
+ try:
2436
+ from ...services.agents.cache_git_manager import CacheGitManager
2437
+
2438
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2439
+ manager = CacheGitManager(cache_dir)
2440
+
2441
+ if not manager.is_git_repo():
2442
+ print("❌ Cache is not a git repository")
2443
+ return CommandResult.error_result("Cache is not a git repository")
2444
+
2445
+ # Get commit message from args
2446
+ message = getattr(args, "message", None)
2447
+ if not message:
2448
+ # Default message
2449
+ message = "feat: update agents from local development"
2450
+
2451
+ print("💾 Committing changes...")
2452
+ success, msg = manager.commit_changes(message)
2453
+
2454
+ if success:
2455
+ print(f"✅ {msg}")
2456
+ print(f"\n💡 Commit message: {message}")
2457
+ return CommandResult.success_result(msg)
2458
+ print(f"❌ {msg}")
2459
+ return CommandResult.error_result(msg)
2460
+
2461
+ except Exception as e:
2462
+ self.logger.error(f"Error committing cache changes: {e}", exc_info=True)
2463
+ return CommandResult.error_result(f"Error committing cache changes: {e}")
2464
+
2465
+ def _cache_push(self, args) -> CommandResult:
2466
+ """Push local agent changes to remote."""
2467
+ try:
2468
+ from ...services.agents.cache_git_manager import CacheGitManager
2469
+
2470
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2471
+ manager = CacheGitManager(cache_dir)
2472
+
2473
+ if not manager.is_git_repo():
2474
+ print("❌ Cache is not a git repository")
2475
+ return CommandResult.error_result("Cache is not a git repository")
2476
+
2477
+ # Check for uncommitted changes
2478
+ if manager.has_uncommitted_changes():
2479
+ print("⚠️ You have uncommitted changes.")
2480
+ print("\n💡 Commit changes first with:")
2481
+ print(" claude-mpm agents cache-commit --message 'your message'")
2482
+
2483
+ # Ask if user wants to commit first
2484
+ auto_commit = getattr(args, "auto_commit", False)
2485
+ if auto_commit:
2486
+ print("\n📝 Auto-committing changes...")
2487
+ success, msg = manager.commit_changes("feat: update agents")
2488
+ if not success:
2489
+ print(f"❌ Commit failed: {msg}")
2490
+ return CommandResult.error_result(f"Commit failed: {msg}")
2491
+ print(f"✅ {msg}")
2492
+ else:
2493
+ return CommandResult.error_result(
2494
+ "Uncommitted changes detected. Commit first or use --auto-commit"
2495
+ )
2496
+
2497
+ # Push changes
2498
+ branch = getattr(args, "branch", "main")
2499
+ print(f"📤 Pushing changes to {branch}...")
2500
+
2501
+ success, msg = manager.push_changes(branch)
2502
+
2503
+ if success:
2504
+ print(f"✅ {msg}")
2505
+ return CommandResult.success_result(msg)
2506
+ print(f"❌ {msg}")
2507
+ return CommandResult.error_result(msg)
2508
+
2509
+ except Exception as e:
2510
+ self.logger.error(f"Error pushing cache: {e}", exc_info=True)
2511
+ return CommandResult.error_result(f"Error pushing cache: {e}")
2512
+
2513
+ def _cache_sync(self, args) -> CommandResult:
2514
+ """Full cache sync: pull, commit (if needed), push."""
2515
+ try:
2516
+ from ...services.agents.cache_git_manager import CacheGitManager
2517
+
2518
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "remote-agents"
2519
+ manager = CacheGitManager(cache_dir)
2520
+
2521
+ if not manager.is_git_repo():
2522
+ print("❌ Cache is not a git repository")
2523
+ return CommandResult.error_result("Cache is not a git repository")
2524
+
2525
+ print("🔄 Syncing cache with remote...\n")
2526
+
2527
+ success, msg = manager.sync_with_remote()
2528
+
2529
+ # Print detailed sync message
2530
+ print(msg)
2531
+
2532
+ if success:
2533
+ print("\n✨ Cache sync complete!")
2534
+ return CommandResult.success_result("Cache synced successfully")
2535
+
2536
+ print("\n❌ Cache sync failed. See details above.")
2537
+ return CommandResult.error_result("Cache sync failed")
2538
+
2539
+ except Exception as e:
2540
+ self.logger.error(f"Error syncing cache: {e}", exc_info=True)
2541
+ return CommandResult.error_result(f"Error syncing cache: {e}")
2542
+
1451
2543
 
1452
2544
  def manage_agents(args):
1453
2545
  """