claude-mpm 4.21.0__py3-none-any.whl → 5.0.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 (497) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +12 -0
  3. claude_mpm/agents/OUTPUT_STYLE.md +3 -48
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +632 -334
  5. claude_mpm/agents/WORKFLOW.md +75 -2
  6. claude_mpm/agents/__init__.py +6 -0
  7. claude_mpm/agents/agent_loader.py +1 -4
  8. claude_mpm/agents/base_agent.json +6 -3
  9. claude_mpm/agents/frontmatter_validator.py +1 -1
  10. claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +370 -3
  11. claude_mpm/agents/templates/context-management-examples.md +544 -0
  12. claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
  13. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  14. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  15. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  16. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  17. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  18. claude_mpm/cli/__init__.py +38 -2
  19. claude_mpm/cli/commands/agent_source.py +774 -0
  20. claude_mpm/cli/commands/agent_state_manager.py +125 -20
  21. claude_mpm/cli/commands/agents.py +684 -13
  22. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  23. claude_mpm/cli/commands/agents_discover.py +338 -0
  24. claude_mpm/cli/commands/aggregate.py +1 -1
  25. claude_mpm/cli/commands/analyze.py +3 -3
  26. claude_mpm/cli/commands/auto_configure.py +2 -6
  27. claude_mpm/cli/commands/cleanup.py +1 -1
  28. claude_mpm/cli/commands/config.py +7 -4
  29. claude_mpm/cli/commands/configure.py +478 -44
  30. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  31. claude_mpm/cli/commands/configure_navigation.py +63 -46
  32. claude_mpm/cli/commands/debug.py +12 -12
  33. claude_mpm/cli/commands/doctor.py +10 -2
  34. claude_mpm/cli/commands/hook_errors.py +277 -0
  35. claude_mpm/cli/commands/local_deploy.py +1 -4
  36. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  37. claude_mpm/cli/commands/mpm_init/core.py +50 -2
  38. claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
  39. claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
  40. claude_mpm/cli/commands/run.py +124 -128
  41. claude_mpm/cli/commands/skill_source.py +694 -0
  42. claude_mpm/cli/commands/skills.py +435 -1
  43. claude_mpm/cli/executor.py +78 -3
  44. claude_mpm/cli/interactive/agent_wizard.py +919 -41
  45. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  46. claude_mpm/cli/parsers/agents_parser.py +173 -4
  47. claude_mpm/cli/parsers/base_parser.py +49 -0
  48. claude_mpm/cli/parsers/config_parser.py +96 -43
  49. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  50. claude_mpm/cli/parsers/skills_parser.py +138 -0
  51. claude_mpm/cli/parsers/source_parser.py +138 -0
  52. claude_mpm/cli/startup.py +499 -84
  53. claude_mpm/cli/startup_display.py +480 -0
  54. claude_mpm/cli/utils.py +1 -1
  55. claude_mpm/cli_module/commands.py +1 -1
  56. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  57. claude_mpm/commands/mpm-agents-detect.md +9 -0
  58. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  59. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  60. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  61. claude_mpm/commands/mpm-doctor.md +9 -0
  62. claude_mpm/commands/mpm-help.md +14 -2
  63. claude_mpm/commands/mpm-init.md +27 -2
  64. claude_mpm/commands/mpm-monitor.md +9 -0
  65. claude_mpm/commands/mpm-session-resume.md +381 -0
  66. claude_mpm/commands/mpm-status.md +9 -0
  67. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  68. claude_mpm/commands/mpm-ticket-view.md +552 -0
  69. claude_mpm/commands/mpm-version.md +9 -0
  70. claude_mpm/commands/mpm.md +11 -0
  71. claude_mpm/config/agent_presets.py +258 -0
  72. claude_mpm/config/agent_sources.py +325 -0
  73. claude_mpm/config/skill_sources.py +590 -0
  74. claude_mpm/constants.py +12 -0
  75. claude_mpm/core/api_validator.py +1 -1
  76. claude_mpm/core/claude_runner.py +17 -10
  77. claude_mpm/core/config.py +24 -0
  78. claude_mpm/core/constants.py +1 -1
  79. claude_mpm/core/framework/__init__.py +3 -16
  80. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  81. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  82. claude_mpm/core/hook_error_memory.py +381 -0
  83. claude_mpm/core/hook_manager.py +41 -2
  84. claude_mpm/core/interactive_session.py +112 -5
  85. claude_mpm/core/logger.py +3 -1
  86. claude_mpm/core/oneshot_session.py +94 -4
  87. claude_mpm/dashboard/static/css/activity.css +69 -69
  88. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  89. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  90. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  91. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  92. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  93. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  94. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  95. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  96. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  97. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  98. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  99. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  100. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  101. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  102. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  103. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  104. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  105. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  106. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  107. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  108. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  109. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  110. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  111. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  112. claude_mpm/dashboard/templates/code_simple.html +23 -23
  113. claude_mpm/dashboard/templates/index.html +18 -18
  114. claude_mpm/experimental/cli_enhancements.py +1 -5
  115. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  116. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  117. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  118. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  119. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  120. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  121. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  122. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  123. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  124. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  125. claude_mpm/models/git_repository.py +198 -0
  126. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  127. claude_mpm/scripts/start_activity_logging.py +3 -1
  128. claude_mpm/services/agents/agent_builder.py +45 -9
  129. claude_mpm/services/agents/agent_preset_service.py +238 -0
  130. claude_mpm/services/agents/agent_selection_service.py +484 -0
  131. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  132. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  133. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  134. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  135. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  136. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  137. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  138. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  139. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  140. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  141. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  142. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
  143. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  144. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  145. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  146. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  147. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  148. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  149. claude_mpm/services/agents/git_source_manager.py +629 -0
  150. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  151. claude_mpm/services/agents/local_template_manager.py +50 -10
  152. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  153. claude_mpm/services/agents/sources/__init__.py +13 -0
  154. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  155. claude_mpm/services/agents/sources/git_source_sync_service.py +1055 -0
  156. claude_mpm/services/agents/startup_sync.py +239 -0
  157. claude_mpm/services/agents/toolchain_detector.py +474 -0
  158. claude_mpm/services/cli/session_pause_manager.py +1 -1
  159. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  160. claude_mpm/services/command_deployment_service.py +92 -1
  161. claude_mpm/services/core/base.py +26 -11
  162. claude_mpm/services/core/interfaces/__init__.py +1 -3
  163. claude_mpm/services/core/interfaces/health.py +1 -4
  164. claude_mpm/services/core/models/__init__.py +2 -11
  165. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  166. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  167. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  168. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  169. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  170. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  171. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  172. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  173. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  174. claude_mpm/services/event_bus/direct_relay.py +3 -3
  175. claude_mpm/services/event_bus/event_bus.py +36 -3
  176. claude_mpm/services/event_bus/relay.py +23 -7
  177. claude_mpm/services/events/consumers/logging.py +1 -2
  178. claude_mpm/services/git/__init__.py +21 -0
  179. claude_mpm/services/git/git_operations_service.py +494 -0
  180. claude_mpm/services/github/__init__.py +21 -0
  181. claude_mpm/services/github/github_cli_service.py +397 -0
  182. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  183. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  184. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  185. claude_mpm/services/instructions/__init__.py +9 -0
  186. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  187. claude_mpm/services/local_ops/__init__.py +3 -13
  188. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  189. claude_mpm/services/local_ops/health_manager.py +1 -4
  190. claude_mpm/services/local_ops/process_manager.py +1 -1
  191. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  192. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  193. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  194. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  195. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  196. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  197. claude_mpm/services/memory/failure_tracker.py +19 -4
  198. claude_mpm/services/memory/optimizer.py +1 -1
  199. claude_mpm/services/model/model_router.py +8 -9
  200. claude_mpm/services/monitor/daemon.py +1 -1
  201. claude_mpm/services/monitor/server.py +2 -2
  202. claude_mpm/services/native_agent_converter.py +356 -0
  203. claude_mpm/services/port_manager.py +1 -1
  204. claude_mpm/services/pr/__init__.py +14 -0
  205. claude_mpm/services/pr/pr_template_service.py +329 -0
  206. claude_mpm/services/project/documentation_manager.py +2 -1
  207. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  208. claude_mpm/services/runner_configuration_service.py +1 -0
  209. claude_mpm/services/self_upgrade_service.py +165 -7
  210. claude_mpm/services/skills/__init__.py +18 -0
  211. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  212. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  213. claude_mpm/services/skills_config.py +547 -0
  214. claude_mpm/services/skills_deployer.py +955 -0
  215. claude_mpm/services/socketio/handlers/connection.py +1 -1
  216. claude_mpm/services/socketio/handlers/git.py +2 -2
  217. claude_mpm/services/socketio/server/core.py +1 -4
  218. claude_mpm/services/socketio/server/main.py +1 -3
  219. claude_mpm/services/system_instructions_service.py +1 -3
  220. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  221. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  222. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  223. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  224. claude_mpm/services/unified/unified_deployment.py +1 -5
  225. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  226. claude_mpm/services/visualization/__init__.py +1 -5
  227. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  228. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  229. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  230. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
  231. claude_mpm/skills/skills_registry.py +0 -1
  232. claude_mpm/templates/questions/__init__.py +38 -0
  233. claude_mpm/templates/questions/base.py +193 -0
  234. claude_mpm/templates/questions/pr_strategy.py +311 -0
  235. claude_mpm/templates/questions/project_init.py +385 -0
  236. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  237. claude_mpm/tools/__main__.py +8 -8
  238. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  239. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  240. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  241. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  242. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  243. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  244. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  245. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  246. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  247. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  248. claude_mpm/utils/agent_dependency_loader.py +80 -13
  249. claude_mpm/utils/dependency_cache.py +3 -1
  250. claude_mpm/utils/gitignore.py +241 -0
  251. claude_mpm/utils/log_cleanup.py +3 -3
  252. claude_mpm/utils/progress.py +383 -0
  253. claude_mpm/utils/robust_installer.py +3 -5
  254. claude_mpm/utils/structured_questions.py +619 -0
  255. {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/METADATA +429 -59
  256. {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/RECORD +264 -427
  257. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  258. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  259. claude_mpm/agents/templates/agent-manager.json +0 -273
  260. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  261. claude_mpm/agents/templates/api_qa.json +0 -180
  262. claude_mpm/agents/templates/clerk-ops.json +0 -235
  263. claude_mpm/agents/templates/code_analyzer.json +0 -101
  264. claude_mpm/agents/templates/content-agent.json +0 -358
  265. claude_mpm/agents/templates/dart_engineer.json +0 -307
  266. claude_mpm/agents/templates/data_engineer.json +0 -225
  267. claude_mpm/agents/templates/documentation.json +0 -211
  268. claude_mpm/agents/templates/engineer.json +0 -210
  269. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  270. claude_mpm/agents/templates/golang_engineer.json +0 -270
  271. claude_mpm/agents/templates/imagemagick.json +0 -264
  272. claude_mpm/agents/templates/java_engineer.json +0 -346
  273. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  274. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  275. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  276. claude_mpm/agents/templates/memory_manager.json +0 -158
  277. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  278. claude_mpm/agents/templates/ops.json +0 -185
  279. claude_mpm/agents/templates/php-engineer.json +0 -287
  280. claude_mpm/agents/templates/product_owner.json +0 -338
  281. claude_mpm/agents/templates/project_organizer.json +0 -140
  282. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  283. claude_mpm/agents/templates/python_engineer.json +0 -387
  284. claude_mpm/agents/templates/qa.json +0 -242
  285. claude_mpm/agents/templates/react_engineer.json +0 -238
  286. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  287. claude_mpm/agents/templates/research.json +0 -188
  288. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  289. claude_mpm/agents/templates/rust_engineer.json +0 -275
  290. claude_mpm/agents/templates/security.json +0 -202
  291. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  292. claude_mpm/agents/templates/ticketing.json +0 -177
  293. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  294. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  295. claude_mpm/agents/templates/version_control.json +0 -157
  296. claude_mpm/agents/templates/web_qa.json +0 -399
  297. claude_mpm/agents/templates/web_ui.json +0 -189
  298. claude_mpm/commands/mpm-tickets.md +0 -102
  299. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  300. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  301. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  302. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  303. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  304. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  305. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  306. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  307. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  308. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  309. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  310. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  311. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  312. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  313. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  314. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  315. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  316. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  317. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  318. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  319. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  320. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  321. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  322. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  323. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  324. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  325. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  326. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  327. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  328. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  329. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  330. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  331. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  332. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  333. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  334. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  335. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  336. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  337. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  338. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  339. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  340. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  341. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  342. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  343. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  344. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  345. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  346. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  347. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  348. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  349. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  350. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  351. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  352. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  353. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  354. claude_mpm/dashboard/static/built/react/events.js +0 -30
  355. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  356. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  357. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  358. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  359. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  360. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  361. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  362. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  363. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  364. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  365. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  366. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  367. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  368. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  369. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  370. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  371. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  372. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  373. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  374. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  375. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  376. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  377. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  378. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  379. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  380. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  381. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  382. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  383. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  384. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  385. claude_mpm/dashboard/static/events.html +0 -607
  386. claude_mpm/dashboard/static/index.html +0 -635
  387. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  388. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  389. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  390. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  391. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  392. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  393. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  394. claude_mpm/dashboard/static/legacy/files.html +0 -747
  395. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  396. claude_mpm/dashboard/static/monitors.html +0 -431
  397. claude_mpm/dashboard/static/production/events.html +0 -659
  398. claude_mpm/dashboard/static/production/main.html +0 -698
  399. claude_mpm/dashboard/static/production/monitors.html +0 -483
  400. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  401. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  402. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  403. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  404. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  405. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  406. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  407. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  408. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  409. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  410. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  411. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  412. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  413. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  414. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  415. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  416. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  417. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  418. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  419. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  420. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  421. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  422. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  423. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  424. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  425. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  426. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  427. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  428. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  429. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  430. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  431. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  432. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  433. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  434. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  435. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  436. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  437. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  438. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  439. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  440. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  441. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  442. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  443. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  444. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  445. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  446. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  447. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  448. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  449. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  450. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  451. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  452. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  453. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  454. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  455. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  456. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  457. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  458. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  459. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  460. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  461. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  462. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  463. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  464. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  465. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  466. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  467. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  468. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  469. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  470. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  471. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  472. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  473. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  474. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  475. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  476. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  477. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  478. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
  479. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
  480. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
  481. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
  482. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
  483. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
  484. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  485. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  486. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  487. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  488. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  489. claude_mpm/tools/code_tree_analyzer.py +0 -1825
  490. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  491. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  492. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  493. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  494. {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/WHEEL +0 -0
  495. {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/entry_points.txt +0 -0
  496. {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/licenses/LICENSE +0 -0
  497. {claude_mpm-4.21.0.dist-info → claude_mpm-5.0.2.dist-info}/top_level.txt +0 -0
@@ -21,19 +21,29 @@ from claude_mpm.core.logging_config import get_logger
21
21
 
22
22
  from .agent_discovery_service import AgentDiscoveryService
23
23
  from .agent_version_manager import AgentVersionManager
24
+ from .remote_agent_discovery_service import RemoteAgentDiscoveryService
24
25
 
25
26
 
26
27
  class MultiSourceAgentDeploymentService:
27
28
  """Service for deploying agents from multiple sources with version comparison.
28
29
 
29
30
  This service ensures that the highest version of each agent is deployed,
30
- regardless of whether it comes from system templates, project agents, or
31
- user agents.
31
+ regardless of whether it comes from system templates, project agents,
32
+ user agents, or remote agents.
33
+
34
+ 4-Tier Agent Discovery:
35
+ 1. System templates (lowest priority) - Built-in agents
36
+ 2. User agents (DEPRECATED) - User-level customizations (~/.claude-mpm/agents/)
37
+ 3. Remote agents - Agents cached from GitHub
38
+ 4. Project agents (highest priority) - Project-specific customizations
32
39
 
33
40
  WHY: The current system processes agents from a single source at a time,
34
41
  which can result in lower version agents being deployed if they exist in
35
42
  a higher priority source. This service fixes that by comparing versions
36
43
  across all sources.
44
+
45
+ DEPRECATION: User-level agents (~/.claude-mpm/agents/) are deprecated and
46
+ will be removed in v5.0.0. Use project-level agents instead.
37
47
  """
38
48
 
39
49
  def __init__(self):
@@ -46,18 +56,30 @@ class MultiSourceAgentDeploymentService:
46
56
  system_templates_dir: Optional[Path] = None,
47
57
  project_agents_dir: Optional[Path] = None,
48
58
  user_agents_dir: Optional[Path] = None,
59
+ remote_agents_dir: Optional[Path] = None,
49
60
  working_directory: Optional[Path] = None,
50
61
  ) -> Dict[str, List[Dict[str, Any]]]:
51
- """Discover agents from all available sources.
62
+ """Discover agents from all 4 tiers (system, user, remote, project).
63
+
64
+ Priority hierarchy (highest to lowest):
65
+ 4. Project agents - Highest priority, project-specific customizations
66
+ 3. Remote agents - GitHub-synced agents from cache
67
+ 2. User agents - DEPRECATED, user-level customizations
68
+ 1. System templates - Lowest priority, built-in agents
52
69
 
53
70
  Args:
54
71
  system_templates_dir: Directory containing system agent templates
55
72
  project_agents_dir: Directory containing project-specific agents
56
- user_agents_dir: Directory containing user custom agents
73
+ user_agents_dir: Directory containing user custom agents (DEPRECATED)
74
+ remote_agents_dir: Directory containing cached remote agents
57
75
  working_directory: Current working directory for finding project agents
58
76
 
59
77
  Returns:
60
78
  Dictionary mapping agent names to list of agent info from different sources
79
+
80
+ Deprecation Warning:
81
+ User-level agents are deprecated and will show a warning if found.
82
+ Use 'claude-mpm agents migrate-to-project' to migrate them.
61
83
  """
62
84
  agents_by_name = {}
63
85
 
@@ -80,24 +102,53 @@ class MultiSourceAgentDeploymentService:
80
102
  if not user_agents_dir.exists():
81
103
  user_agents_dir = None
82
104
 
83
- # Discover agents from each source
105
+ if not remote_agents_dir:
106
+ # Check for remote agents in cache directory
107
+ cache_dir = Path.home() / ".claude-mpm" / "cache"
108
+ remote_agents_dir = cache_dir / "remote-agents"
109
+ if not remote_agents_dir.exists():
110
+ remote_agents_dir = None
111
+
112
+ # Discover agents from each source in priority order
113
+ # Note: We process in reverse priority order (system first) and build up the dictionary
114
+ # The select_highest_version_agents() method will handle the actual prioritization
84
115
  sources = [
85
116
  ("system", system_templates_dir),
86
- ("project", project_agents_dir),
87
117
  ("user", user_agents_dir),
118
+ ("remote", remote_agents_dir),
119
+ ("project", project_agents_dir),
88
120
  ]
89
121
 
122
+ # Track if we found user agents for deprecation warning
123
+ user_agents_found = False
124
+
90
125
  for source_name, source_dir in sources:
91
126
  if source_dir and source_dir.exists():
92
127
  self.logger.debug(
93
128
  f"Discovering agents from {source_name} source: {source_dir}"
94
129
  )
95
- discovery_service = AgentDiscoveryService(source_dir)
96
- # Pass log_discovery=False to avoid duplicate logging
97
- agents = discovery_service.list_available_agents(log_discovery=False)
130
+
131
+ # Use appropriate discovery service based on source type
132
+ if source_name == "remote":
133
+ # Remote agents are Markdown, use RemoteAgentDiscoveryService
134
+ remote_service = RemoteAgentDiscoveryService(source_dir)
135
+ agents = remote_service.discover_remote_agents()
136
+ else:
137
+ # Other sources are JSON, use AgentDiscoveryService
138
+ discovery_service = AgentDiscoveryService(source_dir)
139
+ # Pass log_discovery=False to avoid duplicate logging
140
+ agents = discovery_service.list_available_agents(
141
+ log_discovery=False
142
+ )
143
+
144
+ # Track user agents for deprecation warning
145
+ if source_name == "user" and agents:
146
+ user_agents_found = True
98
147
 
99
148
  for agent_info in agents:
100
- agent_name = agent_info.get("name")
149
+ agent_name = agent_info.get("name") or agent_info.get(
150
+ "metadata", {}
151
+ ).get("name")
101
152
  if not agent_name:
102
153
  continue
103
154
 
@@ -116,6 +167,26 @@ class MultiSourceAgentDeploymentService:
116
167
  f"Discovered {len(agents)} {source_name} agent templates from {source_dir.name}"
117
168
  )
118
169
 
170
+ # Show deprecation warning if user agents found
171
+ if user_agents_found:
172
+ self.logger.warning(
173
+ "\n"
174
+ "⚠️ DEPRECATION WARNING: User-level agents found in ~/.claude-mpm/agents/\n"
175
+ " User-level agent deployment is deprecated and will be removed in v5.0.0\n"
176
+ "\n"
177
+ " Why this change?\n"
178
+ " - Project isolation: Agents should be project-specific\n"
179
+ " - Version control: Project agents can be versioned with your code\n"
180
+ " - Team consistency: All team members use the same agents\n"
181
+ "\n"
182
+ " Migration:\n"
183
+ " 1. Run: claude-mpm agents migrate-to-project\n"
184
+ " 2. Verify agents work in .claude-mpm/agents/\n"
185
+ " 3. Remove: rm -rf ~/.claude-mpm/agents/\n"
186
+ "\n"
187
+ " Learn more: https://docs.claude-mpm.dev/agents/migration\n"
188
+ )
189
+
119
190
  return agents_by_name
120
191
 
121
192
  def select_highest_version_agents(
@@ -226,17 +297,19 @@ class MultiSourceAgentDeploymentService:
226
297
  system_templates_dir: Optional[Path] = None,
227
298
  project_agents_dir: Optional[Path] = None,
228
299
  user_agents_dir: Optional[Path] = None,
300
+ remote_agents_dir: Optional[Path] = None,
229
301
  working_directory: Optional[Path] = None,
230
302
  excluded_agents: Optional[List[str]] = None,
231
303
  config: Optional[Config] = None,
232
304
  cleanup_outdated: bool = True,
233
305
  ) -> Tuple[Dict[str, Path], Dict[str, str], Dict[str, Any]]:
234
- """Get the highest version agents from all sources for deployment.
306
+ """Get the highest version agents from all 4 tiers for deployment.
235
307
 
236
308
  Args:
237
309
  system_templates_dir: Directory containing system agent templates
238
310
  project_agents_dir: Directory containing project-specific agents
239
- user_agents_dir: Directory containing user custom agents
311
+ user_agents_dir: Directory containing user custom agents (DEPRECATED)
312
+ remote_agents_dir: Directory containing cached remote agents
240
313
  working_directory: Current working directory for finding project agents
241
314
  excluded_agents: List of agent names to exclude from deployment
242
315
  config: Configuration object for additional filtering
@@ -248,11 +321,12 @@ class MultiSourceAgentDeploymentService:
248
321
  - Dictionary mapping agent names to their source
249
322
  - Dictionary with cleanup results (removed, preserved, errors)
250
323
  """
251
- # Discover all available agents
324
+ # Discover all available agents from 4 tiers
252
325
  agents_by_name = self.discover_agents_from_all_sources(
253
326
  system_templates_dir=system_templates_dir,
254
327
  project_agents_dir=project_agents_dir,
255
328
  user_agents_dir=user_agents_dir,
329
+ remote_agents_dir=remote_agents_dir,
256
330
  working_directory=working_directory,
257
331
  )
258
332
 
@@ -300,7 +374,21 @@ class MultiSourceAgentDeploymentService:
300
374
  agent_sources = {}
301
375
 
302
376
  for agent_name, agent_info in selected_agents.items():
303
- template_path = Path(agent_info["path"])
377
+ # Defensive: Try multiple path fields for backward compatibility (ticket 1M-480)
378
+ # Priority: 'path' -> 'file_path' -> 'source_file'
379
+ path_str = (
380
+ agent_info.get("path")
381
+ or agent_info.get("file_path")
382
+ or agent_info.get("source_file")
383
+ )
384
+
385
+ if not path_str:
386
+ self.logger.warning(
387
+ f"Agent '{agent_name}' missing path information (no 'path', 'file_path', or 'source_file' field)"
388
+ )
389
+ continue
390
+
391
+ template_path = Path(path_str)
304
392
  if template_path.exists():
305
393
  # Use the file stem as the key for consistency
306
394
  file_stem = template_path.stem
@@ -371,8 +459,20 @@ class MultiSourceAgentDeploymentService:
371
459
  if agent_info["source"] != "user":
372
460
  continue
373
461
 
462
+ # Defensive: Get path from agent_info (ticket 1M-480)
463
+ path_str = (
464
+ agent_info.get("path")
465
+ or agent_info.get("file_path")
466
+ or agent_info.get("source_file")
467
+ )
468
+ if not path_str:
469
+ self.logger.warning(
470
+ f"User agent '{agent_name}' missing path information, skipping cleanup"
471
+ )
472
+ continue
473
+
374
474
  # Safety check - ensure path is within user agents directory
375
- user_agent_path = Path(agent_info["path"])
475
+ user_agent_path = Path(path_str)
376
476
  try:
377
477
  # Resolve paths to compare them safely
378
478
  resolved_user_path = user_agent_path.resolve()
@@ -51,11 +51,11 @@ class DeploymentPipelineExecutor:
51
51
  try:
52
52
  # Check if step should be executed
53
53
  if not step.should_execute(context):
54
- self.logger.info(f"Skipping step {i+1}/{len(steps)}: {step.name}")
54
+ self.logger.info(f"Skipping step {i + 1}/{len(steps)}: {step.name}")
55
55
  skipped_steps.append(step.name)
56
56
  continue
57
57
 
58
- self.logger.info(f"Executing step {i+1}/{len(steps)}: {step.name}")
58
+ self.logger.info(f"Executing step {i + 1}/{len(steps)}: {step.name}")
59
59
 
60
60
  # Execute the step
61
61
  result = step.execute(context)
@@ -9,10 +9,7 @@ from claude_mpm.core.logger import get_logger
9
9
 
10
10
  from .config import DeploymentConfigManager
11
11
  from .facade import DeploymentFacade
12
- from .pipeline import (
13
- DeploymentPipelineBuilder,
14
- DeploymentPipelineExecutor,
15
- )
12
+ from .pipeline import DeploymentPipelineBuilder, DeploymentPipelineExecutor
16
13
  from .results import DeploymentResultBuilder
17
14
 
18
15
  # Import refactored components
@@ -0,0 +1,363 @@
1
+ """Service for discovering and converting remote Markdown agents to JSON format.
2
+
3
+ This service handles the 4th tier of agent discovery: remote agents cached from GitHub.
4
+ Remote agents are stored as Markdown files with YAML frontmatter and need to be converted
5
+ to the JSON template format expected by the deployment system.
6
+
7
+ WHY: Remote agents from GitHub are cached as Markdown but the deployment system expects
8
+ JSON templates. This service bridges that gap and integrates remote agents into the
9
+ multi-tier discovery system.
10
+ """
11
+
12
+ import json
13
+ import re
14
+ from dataclasses import dataclass
15
+ from pathlib import Path
16
+ from typing import Any, Dict, List, Optional
17
+
18
+ from claude_mpm.core.logging_config import get_logger
19
+
20
+ logger = get_logger(__name__)
21
+
22
+
23
+ @dataclass
24
+ class RemoteAgentMetadata:
25
+ """Metadata extracted from remote agent Markdown file."""
26
+
27
+ name: str
28
+ description: str
29
+ model: str
30
+ routing_keywords: List[str]
31
+ routing_paths: List[str]
32
+ routing_priority: int
33
+ source_file: Path
34
+ version: str # SHA-256 hash from cache metadata
35
+
36
+
37
+ class RemoteAgentDiscoveryService:
38
+ """Discovers and converts remote Markdown agents to JSON format.
39
+
40
+ Remote agents are discovered from the cache directory (~/.claude-mpm/cache/remote-agents/)
41
+ where they are stored as Markdown files. This service:
42
+ 1. Discovers all *.md files in the remote agents cache
43
+ 2. Parses Markdown frontmatter and content to extract metadata
44
+ 3. Converts to JSON template format for deployment
45
+ 4. Retrieves version (SHA-256 hash) from cache metadata
46
+
47
+ Design Decision: Markdown Parsing Strategy
48
+ - Use regex for simple frontmatter extraction (fast, no dependencies)
49
+ - Parse key-value pairs from Configuration section
50
+ - Extract routing info from Routing section
51
+ - Fallback to sensible defaults when sections are missing
52
+
53
+ Trade-offs:
54
+ - Performance: Regex parsing is fast for our simple format
55
+ - Maintainability: Clear regex patterns are easy to understand
56
+ - Flexibility: Supports optional sections with defaults
57
+ """
58
+
59
+ def __init__(self, remote_agents_dir: Path):
60
+ """Initialize the remote agent discovery service.
61
+
62
+ Args:
63
+ remote_agents_dir: Directory containing cached remote agent Markdown files
64
+ """
65
+ self.remote_agents_dir = remote_agents_dir
66
+ self.logger = get_logger(__name__)
67
+
68
+ def _generate_hierarchical_id(self, file_path: Path) -> str:
69
+ """Generate hierarchical agent ID from file path.
70
+
71
+ Converts file path relative to agents subdirectory into hierarchical ID.
72
+
73
+ Design Decision: Path-based IDs for hierarchy preservation
74
+
75
+ Rationale: Agent IDs must reflect directory hierarchy to enable:
76
+ - Category-based filtering (engineer/backend/python-engineer)
77
+ - Preset matching against AUTO-DEPLOY-INDEX.md
78
+ - Multi-level organization without name collisions
79
+
80
+ Bug #4 Fix: Calculate relative to /agents/ subdirectory, not repository root
81
+ This ensures agent IDs are based on their position within the agents directory.
82
+
83
+ Example:
84
+ Input: /cache/bobmatnyc/claude-mpm-agents/agents/engineer/backend/python-engineer.md
85
+ Root: /cache/bobmatnyc/claude-mpm-agents/agents
86
+ Output: engineer/backend/python-engineer
87
+
88
+ Args:
89
+ file_path: Absolute path to agent Markdown file
90
+
91
+ Returns:
92
+ Hierarchical agent ID with forward slashes
93
+ """
94
+ try:
95
+ # Calculate relative to /agents/ subdirectory (Bug #4 fix)
96
+ agents_dir = self.remote_agents_dir / "agents"
97
+ relative_path = file_path.relative_to(agents_dir)
98
+
99
+ # Remove .md extension and convert to forward slashes
100
+ return str(relative_path.with_suffix("")).replace("\\", "/")
101
+ except ValueError:
102
+ # File is not under agents subdirectory, fall back to filename
103
+ self.logger.warning(
104
+ f"File {file_path} not under agents directory, using filename"
105
+ )
106
+ return file_path.stem
107
+
108
+ def _detect_category_from_path(self, file_path: Path) -> str:
109
+ """Detect category from file path hierarchy.
110
+
111
+ Extracts category from directory structure. Category is the path
112
+ from agents subdirectory to the file, excluding the filename.
113
+
114
+ Bug #4 Fix: Calculate relative to /agents/ subdirectory, not repository root
115
+ This ensures categories are based on agent organization within /agents/.
116
+
117
+ Example:
118
+ Input: /cache/bobmatnyc/claude-mpm-agents/agents/engineer/backend/python-engineer.md
119
+ Root: /cache/bobmatnyc/claude-mpm-agents/agents
120
+ Output: engineer/backend
121
+
122
+ Args:
123
+ file_path: Absolute path to agent Markdown file
124
+
125
+ Returns:
126
+ Category path with forward slashes, or "universal" if in root
127
+ """
128
+ try:
129
+ # Calculate relative to /agents/ subdirectory (Bug #4 fix)
130
+ agents_dir = self.remote_agents_dir / "agents"
131
+ relative_path = file_path.relative_to(agents_dir)
132
+ parts = relative_path.parts[:-1] # Exclude filename
133
+ return "/".join(parts) if parts else "universal"
134
+ except ValueError:
135
+ return "universal"
136
+
137
+ def discover_remote_agents(self) -> List[Dict[str, Any]]:
138
+ """Discover all remote agents from cache directory.
139
+
140
+ Scans the remote agents directory for *.md files recursively and converts each
141
+ to JSON template format. Skips files that can't be parsed.
142
+
143
+ Bug #4 Fix: Only scan /agents/ subdirectory, not entire repository
144
+ This prevents README.md, CHANGELOG.md, etc. from being treated as agents.
145
+
146
+ Returns:
147
+ List of agent dictionaries in JSON template format
148
+
149
+ Example:
150
+ >>> service = RemoteAgentDiscoveryService(Path("~/.claude-mpm/cache/remote-agents"))
151
+ >>> agents = service.discover_remote_agents()
152
+ >>> len(agents)
153
+ 5
154
+ >>> agents[0]['name']
155
+ 'Security Scanner Agent'
156
+ """
157
+ agents = []
158
+
159
+ if not self.remote_agents_dir.exists():
160
+ self.logger.debug(
161
+ f"Remote agents directory does not exist: {self.remote_agents_dir}"
162
+ )
163
+ return agents
164
+
165
+ # Bug #4 Fix: Only scan /agents/ subdirectory, not entire repository
166
+ # This prevents non-agent files (README.md, CHANGELOG.md, etc.) from polluting results
167
+ agents_dir = self.remote_agents_dir / "agents"
168
+
169
+ if not agents_dir.exists():
170
+ self.logger.warning(
171
+ f"Agents subdirectory not found: {agents_dir}. "
172
+ f"Expected agents to be in /agents/ subdirectory."
173
+ )
174
+ return agents
175
+
176
+ # Find all Markdown files recursively in /agents/ subdirectory only
177
+ md_files = list(agents_dir.rglob("*.md"))
178
+ self.logger.debug(f"Found {len(md_files)} Markdown files in {agents_dir}")
179
+
180
+ for md_file in md_files:
181
+ try:
182
+ agent_dict = self._parse_markdown_agent(md_file)
183
+ if agent_dict:
184
+ agents.append(agent_dict)
185
+ self.logger.debug(
186
+ f"Successfully parsed remote agent: {md_file.name}"
187
+ )
188
+ else:
189
+ self.logger.warning(
190
+ f"Failed to parse remote agent (no name found): {md_file.name}"
191
+ )
192
+ except Exception as e:
193
+ self.logger.warning(f"Failed to parse remote agent {md_file.name}: {e}")
194
+
195
+ self.logger.info(
196
+ f"Discovered {len(agents)} remote agents from {self.remote_agents_dir.name}"
197
+ )
198
+ return agents
199
+
200
+ def _parse_markdown_agent(self, md_file: Path) -> Optional[Dict[str, Any]]:
201
+ """Parse Markdown agent file and convert to JSON template format.
202
+
203
+ Expected Markdown format:
204
+ ```markdown
205
+ # Agent Name
206
+
207
+ Description paragraph (first paragraph after heading)
208
+
209
+ ## Configuration
210
+ - Model: sonnet
211
+ - Priority: 100
212
+
213
+ ## Routing
214
+ - Keywords: keyword1, keyword2
215
+ - Paths: /path1/, /path2/
216
+ ```
217
+
218
+ Args:
219
+ md_file: Path to Markdown agent file
220
+
221
+ Returns:
222
+ Agent dictionary in JSON template format, or None if parsing fails
223
+
224
+ Error Handling:
225
+ - Returns None if agent name (first heading) is missing
226
+ - Uses defaults for missing sections (model=sonnet, priority=50)
227
+ - Empty routing keywords/paths if Routing section missing
228
+ """
229
+ try:
230
+ content = md_file.read_text(encoding="utf-8")
231
+ except Exception as e:
232
+ self.logger.error(f"Failed to read file {md_file}: {e}")
233
+ return None
234
+
235
+ # Extract agent name from first heading
236
+ name_match = re.search(r"^#\s+(.+?)$", content, re.MULTILINE)
237
+ if not name_match:
238
+ self.logger.debug(f"No agent name heading found in {md_file.name}")
239
+ return None
240
+ name = name_match.group(1).strip()
241
+
242
+ # Extract description (first paragraph after heading, before next heading)
243
+ desc_match = re.search(
244
+ r"^#.+?\n\n(.+?)(?:\n\n##|\Z)", content, re.DOTALL | re.MULTILINE
245
+ )
246
+ description = desc_match.group(1).strip() if desc_match else ""
247
+
248
+ # Extract model from Configuration section
249
+ model_match = re.search(r"Model:\s*(\w+)", content, re.IGNORECASE)
250
+ model = model_match.group(1) if model_match else "sonnet"
251
+
252
+ # Extract priority from Configuration section
253
+ priority_match = re.search(r"Priority:\s*(\d+)", content, re.IGNORECASE)
254
+ priority = int(priority_match.group(1)) if priority_match else 50
255
+
256
+ # Extract routing keywords
257
+ keywords_match = re.search(r"Keywords:\s*(.+?)(?:\n|$)", content, re.IGNORECASE)
258
+ keywords = []
259
+ if keywords_match:
260
+ keywords = [k.strip() for k in keywords_match.group(1).split(",")]
261
+
262
+ # Extract routing paths
263
+ paths_match = re.search(r"Paths:\s*(.+?)(?:\n|$)", content, re.IGNORECASE)
264
+ paths = []
265
+ if paths_match:
266
+ paths = [p.strip() for p in paths_match.group(1).split(",")]
267
+
268
+ # Get version (SHA-256 hash) from cache metadata
269
+ version = self._get_agent_version(md_file)
270
+
271
+ # Bug #3 fix: Generate hierarchical agent_id from file path
272
+ # This preserves directory structure for category filtering and preset matching
273
+ agent_id = self._generate_hierarchical_id(md_file)
274
+
275
+ # Bug #1 fix: Detect category from directory path
276
+ category = self._detect_category_from_path(md_file)
277
+
278
+ # Convert to JSON template format and return
279
+ # IMPORTANT: Include 'path' field for compatibility with deployment validation (ticket 1M-480)
280
+ # Git-sourced agents must have 'path' field to match structure from AgentDiscoveryService
281
+ return {
282
+ "agent_id": agent_id,
283
+ "metadata": {
284
+ "name": name,
285
+ "description": description,
286
+ "version": version,
287
+ "author": "remote", # Mark as remote agent
288
+ "category": category, # Use detected category from path
289
+ },
290
+ "model": model,
291
+ "source": "remote", # Mark as remote agent
292
+ "source_file": str(md_file),
293
+ "path": str(
294
+ md_file
295
+ ), # Add 'path' field for deployment compatibility (1M-480)
296
+ "file_path": str(md_file), # Keep for backward compatibility
297
+ "version": version, # Include at root level for version comparison
298
+ "category": category, # Add category at root level for filtering
299
+ "routing": {"keywords": keywords, "paths": paths, "priority": priority},
300
+ }
301
+
302
+ def _get_agent_version(self, md_file: Path) -> str:
303
+ """Get version (SHA-256 hash) from cache metadata.
304
+
305
+ Looks for corresponding .meta.json file in cache directory that contains
306
+ the SHA-256 hash of the agent content.
307
+
308
+ Args:
309
+ md_file: Path to Markdown agent file
310
+
311
+ Returns:
312
+ SHA-256 hash from metadata, or 'unknown' if not found
313
+
314
+ Example metadata file:
315
+ {
316
+ "content_hash": "abc123...",
317
+ "etag": "W/\"abc123\"",
318
+ "last_modified": "2025-11-30T10:00:00Z"
319
+ }
320
+ """
321
+ # Look for .meta.json file
322
+ meta_file = md_file.with_suffix(".md.meta.json")
323
+
324
+ if not meta_file.exists():
325
+ self.logger.debug(f"No metadata file found for {md_file.name}")
326
+ return "unknown"
327
+
328
+ try:
329
+ meta_data = json.loads(meta_file.read_text(encoding="utf-8"))
330
+ content_hash = meta_data.get("content_hash", "unknown")
331
+ self.logger.debug(
332
+ f"Retrieved version {content_hash[:8]}... for {md_file.name}"
333
+ )
334
+ return content_hash
335
+ except Exception as e:
336
+ self.logger.warning(f"Failed to read metadata for {md_file.name}: {e}")
337
+ return "unknown"
338
+
339
+ def get_remote_agent_metadata(
340
+ self, agent_name: str
341
+ ) -> Optional[RemoteAgentMetadata]:
342
+ """Get metadata for a specific remote agent.
343
+
344
+ Args:
345
+ agent_name: Name of the agent to retrieve
346
+
347
+ Returns:
348
+ RemoteAgentMetadata if found, None otherwise
349
+ """
350
+ for md_file in self.remote_agents_dir.glob("*.md"):
351
+ agent_dict = self._parse_markdown_agent(md_file)
352
+ if agent_dict and agent_dict["metadata"]["name"] == agent_name:
353
+ return RemoteAgentMetadata(
354
+ name=agent_dict["metadata"]["name"],
355
+ description=agent_dict["metadata"]["description"],
356
+ model=agent_dict["model"],
357
+ routing_keywords=agent_dict["routing"]["keywords"],
358
+ routing_paths=agent_dict["routing"]["paths"],
359
+ routing_priority=agent_dict["routing"]["priority"],
360
+ source_file=Path(agent_dict["source_file"]),
361
+ version=agent_dict["version"],
362
+ )
363
+ return None
@@ -200,8 +200,8 @@ class SingleAgentDeployer:
200
200
  - Enables selective agent management in projects
201
201
  """
202
202
  try:
203
- # Find the template file
204
- template_file = templates_dir / f"{agent_name}.json"
203
+ # Find the template file (templates migrated to .md in v4.26.0+)
204
+ template_file = templates_dir / f"{agent_name}.md"
205
205
  if not template_file.exists():
206
206
  self.logger.error(f"Agent template not found: {agent_name}")
207
207
  return False