claude-mpm 4.20.3__py3-none-any.whl → 5.1.8__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 (520) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +35 -6
  3. claude_mpm/agents/OUTPUT_STYLE.md +3 -48
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +1241 -667
  5. claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +1322 -0
  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 +1 -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 +959 -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 +924 -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/__init__.py +73 -0
  41. claude_mpm/cli/commands/mpm_init/core.py +573 -0
  42. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  43. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  44. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  45. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  46. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  47. claude_mpm/cli/commands/mpm_init_handler.py +67 -1
  48. claude_mpm/cli/commands/postmortem.py +401 -0
  49. claude_mpm/cli/commands/run.py +125 -167
  50. claude_mpm/cli/commands/skill_source.py +694 -0
  51. claude_mpm/cli/commands/skills.py +835 -44
  52. claude_mpm/cli/executor.py +78 -3
  53. claude_mpm/cli/interactive/agent_wizard.py +1032 -47
  54. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  55. claude_mpm/cli/parsers/agents_parser.py +256 -4
  56. claude_mpm/cli/parsers/auto_configure_parser.py +13 -0
  57. claude_mpm/cli/parsers/base_parser.py +53 -0
  58. claude_mpm/cli/parsers/config_parser.py +96 -43
  59. claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
  60. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  61. claude_mpm/cli/parsers/skills_parser.py +145 -0
  62. claude_mpm/cli/parsers/source_parser.py +138 -0
  63. claude_mpm/cli/startup.py +564 -108
  64. claude_mpm/cli/startup_display.py +480 -0
  65. claude_mpm/cli/utils.py +1 -1
  66. claude_mpm/cli_module/commands.py +1 -1
  67. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  68. claude_mpm/commands/mpm-agents-detect.md +9 -0
  69. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  70. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  71. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  72. claude_mpm/commands/mpm-doctor.md +9 -0
  73. claude_mpm/commands/mpm-help.md +17 -2
  74. claude_mpm/commands/mpm-init.md +28 -3
  75. claude_mpm/commands/mpm-monitor.md +9 -0
  76. claude_mpm/commands/mpm-postmortem.md +123 -0
  77. claude_mpm/commands/mpm-session-resume.md +381 -0
  78. claude_mpm/commands/mpm-status.md +9 -0
  79. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  80. claude_mpm/commands/mpm-ticket-view.md +552 -0
  81. claude_mpm/commands/mpm-version.md +9 -0
  82. claude_mpm/commands/mpm.md +11 -0
  83. claude_mpm/config/agent_presets.py +488 -0
  84. claude_mpm/config/agent_sources.py +325 -0
  85. claude_mpm/config/skill_presets.py +392 -0
  86. claude_mpm/config/skill_sources.py +590 -0
  87. claude_mpm/constants.py +13 -0
  88. claude_mpm/core/api_validator.py +1 -1
  89. claude_mpm/core/claude_runner.py +19 -35
  90. claude_mpm/core/config.py +24 -0
  91. claude_mpm/core/constants.py +1 -1
  92. claude_mpm/core/framework/__init__.py +3 -16
  93. claude_mpm/core/framework/loaders/file_loader.py +54 -101
  94. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  95. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  96. claude_mpm/core/hook_error_memory.py +381 -0
  97. claude_mpm/core/hook_manager.py +41 -2
  98. claude_mpm/core/interactive_session.py +131 -10
  99. claude_mpm/core/interfaces.py +56 -1
  100. claude_mpm/core/logger.py +3 -1
  101. claude_mpm/core/oneshot_session.py +110 -8
  102. claude_mpm/core/protocols/__init__.py +23 -0
  103. claude_mpm/core/protocols/runner_protocol.py +103 -0
  104. claude_mpm/core/protocols/session_protocol.py +131 -0
  105. claude_mpm/core/shared/singleton_manager.py +11 -4
  106. claude_mpm/core/system_context.py +38 -0
  107. claude_mpm/core/unified_config.py +22 -0
  108. claude_mpm/dashboard/static/css/activity.css +69 -69
  109. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  110. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  111. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  112. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  113. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  114. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  115. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  116. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  117. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  118. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  119. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  120. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  121. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  122. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  123. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  124. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  125. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  126. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  127. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  128. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  129. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  130. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  131. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  132. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  133. claude_mpm/dashboard/templates/code_simple.html +23 -23
  134. claude_mpm/dashboard/templates/index.html +18 -18
  135. claude_mpm/experimental/cli_enhancements.py +1 -5
  136. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  137. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  138. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  139. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  140. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  141. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  142. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  143. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  144. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  145. claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
  146. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  147. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  148. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  149. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  150. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  151. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  152. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  153. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  154. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  155. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  156. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  157. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  158. claude_mpm/models/git_repository.py +198 -0
  159. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  160. claude_mpm/scripts/start_activity_logging.py +3 -1
  161. claude_mpm/services/agents/agent_builder.py +45 -9
  162. claude_mpm/services/agents/agent_preset_service.py +238 -0
  163. claude_mpm/services/agents/agent_selection_service.py +484 -0
  164. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  165. claude_mpm/services/agents/cache_git_manager.py +621 -0
  166. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  167. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  168. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  169. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  170. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  171. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  172. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  173. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  174. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  175. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  176. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
  177. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  178. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  179. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  180. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  181. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  182. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  183. claude_mpm/services/agents/git_source_manager.py +629 -0
  184. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  185. claude_mpm/services/agents/local_template_manager.py +50 -10
  186. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  187. claude_mpm/services/agents/sources/__init__.py +13 -0
  188. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  189. claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
  190. claude_mpm/services/agents/startup_sync.py +239 -0
  191. claude_mpm/services/agents/toolchain_detector.py +474 -0
  192. claude_mpm/services/analysis/__init__.py +25 -0
  193. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  194. claude_mpm/services/analysis/postmortem_service.py +765 -0
  195. claude_mpm/services/cli/session_pause_manager.py +504 -0
  196. claude_mpm/services/cli/session_resume_helper.py +36 -16
  197. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  198. claude_mpm/services/command_deployment_service.py +200 -6
  199. claude_mpm/services/core/base.py +31 -11
  200. claude_mpm/services/core/interfaces/__init__.py +1 -3
  201. claude_mpm/services/core/interfaces/health.py +1 -4
  202. claude_mpm/services/core/interfaces.py +56 -1
  203. claude_mpm/services/core/models/__init__.py +2 -11
  204. claude_mpm/services/core/models/agent_config.py +3 -0
  205. claude_mpm/services/core/models/process.py +4 -0
  206. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  207. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  208. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  209. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  210. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  211. claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
  212. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  213. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  214. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  215. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  216. claude_mpm/services/diagnostics/models.py +21 -0
  217. claude_mpm/services/event_bus/direct_relay.py +3 -3
  218. claude_mpm/services/event_bus/event_bus.py +36 -3
  219. claude_mpm/services/event_bus/relay.py +23 -7
  220. claude_mpm/services/events/consumers/logging.py +1 -2
  221. claude_mpm/services/git/__init__.py +21 -0
  222. claude_mpm/services/git/git_operations_service.py +494 -0
  223. claude_mpm/services/github/__init__.py +21 -0
  224. claude_mpm/services/github/github_cli_service.py +397 -0
  225. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  226. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  227. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  228. claude_mpm/services/instructions/__init__.py +9 -0
  229. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  230. claude_mpm/services/local_ops/__init__.py +5 -13
  231. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  232. claude_mpm/services/local_ops/health_manager.py +1 -4
  233. claude_mpm/services/local_ops/process_manager.py +1 -1
  234. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  235. claude_mpm/services/mcp_config_manager.py +75 -145
  236. claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
  237. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  238. claude_mpm/services/mcp_gateway/core/process_pool.py +41 -26
  239. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  240. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  241. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  242. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
  243. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  244. claude_mpm/services/mcp_service_verifier.py +6 -3
  245. claude_mpm/services/memory/failure_tracker.py +19 -4
  246. claude_mpm/services/memory/optimizer.py +1 -1
  247. claude_mpm/services/model/model_router.py +8 -9
  248. claude_mpm/services/monitor/daemon.py +29 -9
  249. claude_mpm/services/monitor/daemon_manager.py +96 -19
  250. claude_mpm/services/monitor/server.py +2 -2
  251. claude_mpm/services/native_agent_converter.py +356 -0
  252. claude_mpm/services/port_manager.py +1 -1
  253. claude_mpm/services/pr/__init__.py +14 -0
  254. claude_mpm/services/pr/pr_template_service.py +329 -0
  255. claude_mpm/services/project/documentation_manager.py +2 -1
  256. claude_mpm/services/project/project_organizer.py +4 -0
  257. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  258. claude_mpm/services/runner_configuration_service.py +17 -3
  259. claude_mpm/services/self_upgrade_service.py +165 -7
  260. claude_mpm/services/session_management_service.py +16 -4
  261. claude_mpm/services/skills/__init__.py +18 -0
  262. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  263. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  264. claude_mpm/services/skills_config.py +547 -0
  265. claude_mpm/services/skills_deployer.py +955 -0
  266. claude_mpm/services/socketio/handlers/connection.py +1 -1
  267. claude_mpm/services/socketio/handlers/git.py +2 -2
  268. claude_mpm/services/socketio/server/core.py +1 -4
  269. claude_mpm/services/socketio/server/main.py +1 -3
  270. claude_mpm/services/system_instructions_service.py +1 -3
  271. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  272. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  273. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  274. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  275. claude_mpm/services/unified/unified_deployment.py +1 -5
  276. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  277. claude_mpm/services/visualization/__init__.py +1 -5
  278. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  279. claude_mpm/skills/__init__.py +3 -3
  280. claude_mpm/skills/agent_skills_injector.py +42 -49
  281. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  282. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +17 -10
  283. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +92 -39
  284. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +13 -12
  285. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +5 -3
  286. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +19 -12
  287. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  288. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +6 -6
  289. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +13 -9
  290. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +8 -8
  291. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +37 -15
  292. claude_mpm/skills/skills_registry.py +44 -48
  293. claude_mpm/skills/skills_service.py +117 -108
  294. claude_mpm/templates/questions/__init__.py +38 -0
  295. claude_mpm/templates/questions/base.py +193 -0
  296. claude_mpm/templates/questions/pr_strategy.py +311 -0
  297. claude_mpm/templates/questions/project_init.py +385 -0
  298. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  299. claude_mpm/tools/__main__.py +8 -8
  300. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  301. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  302. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  303. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  304. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  305. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  306. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  307. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  308. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  309. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  310. claude_mpm/utils/agent_dependency_loader.py +80 -13
  311. claude_mpm/utils/agent_filters.py +288 -0
  312. claude_mpm/utils/dependency_cache.py +3 -1
  313. claude_mpm/utils/gitignore.py +244 -0
  314. claude_mpm/utils/log_cleanup.py +3 -3
  315. claude_mpm/utils/migration.py +372 -0
  316. claude_mpm/utils/progress.py +387 -0
  317. claude_mpm/utils/robust_installer.py +3 -5
  318. claude_mpm/utils/structured_questions.py +619 -0
  319. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/METADATA +496 -65
  320. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/RECORD +328 -416
  321. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  322. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  323. claude_mpm/agents/templates/agent-manager.json +0 -273
  324. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  325. claude_mpm/agents/templates/api_qa.json +0 -180
  326. claude_mpm/agents/templates/circuit_breakers.md +0 -638
  327. claude_mpm/agents/templates/clerk-ops.json +0 -235
  328. claude_mpm/agents/templates/code_analyzer.json +0 -101
  329. claude_mpm/agents/templates/content-agent.json +0 -358
  330. claude_mpm/agents/templates/dart_engineer.json +0 -307
  331. claude_mpm/agents/templates/data_engineer.json +0 -225
  332. claude_mpm/agents/templates/documentation.json +0 -211
  333. claude_mpm/agents/templates/engineer.json +0 -210
  334. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  335. claude_mpm/agents/templates/golang_engineer.json +0 -270
  336. claude_mpm/agents/templates/imagemagick.json +0 -264
  337. claude_mpm/agents/templates/java_engineer.json +0 -346
  338. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  339. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  340. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  341. claude_mpm/agents/templates/memory_manager.json +0 -158
  342. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  343. claude_mpm/agents/templates/ops.json +0 -185
  344. claude_mpm/agents/templates/php-engineer.json +0 -281
  345. claude_mpm/agents/templates/product_owner.json +0 -338
  346. claude_mpm/agents/templates/project_organizer.json +0 -140
  347. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  348. claude_mpm/agents/templates/python_engineer.json +0 -387
  349. claude_mpm/agents/templates/qa.json +0 -242
  350. claude_mpm/agents/templates/react_engineer.json +0 -238
  351. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  352. claude_mpm/agents/templates/research.json +0 -188
  353. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  354. claude_mpm/agents/templates/rust_engineer.json +0 -275
  355. claude_mpm/agents/templates/security.json +0 -202
  356. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  357. claude_mpm/agents/templates/ticketing.json +0 -177
  358. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  359. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  360. claude_mpm/agents/templates/version_control.json +0 -157
  361. claude_mpm/agents/templates/web_qa.json +0 -399
  362. claude_mpm/agents/templates/web_ui.json +0 -189
  363. claude_mpm/cli/commands/mpm_init.py +0 -2093
  364. claude_mpm/commands/mpm-tickets.md +0 -102
  365. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  366. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  367. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  368. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  369. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  370. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  371. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  372. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  373. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  374. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  375. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  376. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  377. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  378. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  379. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  380. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  381. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  382. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  383. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  384. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  385. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  386. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  387. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  388. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  389. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  390. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  391. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  392. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  393. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  394. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  395. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  396. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  397. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  398. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  399. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  400. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  401. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  402. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  403. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  404. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  405. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  406. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  407. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  408. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  409. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  410. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  411. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  412. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  413. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  414. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  415. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  416. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  417. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  418. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  419. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  420. claude_mpm/dashboard/static/built/react/events.js +0 -30
  421. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  422. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  423. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  424. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  425. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  426. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  427. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  428. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  429. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  430. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  431. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  432. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  433. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  434. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  435. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  436. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  437. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  438. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  439. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  440. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  441. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  442. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  443. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  444. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  445. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  446. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  447. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  448. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  449. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  450. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  451. claude_mpm/dashboard/static/events.html +0 -607
  452. claude_mpm/dashboard/static/index.html +0 -635
  453. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  454. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  455. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  456. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  457. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  458. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  459. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  460. claude_mpm/dashboard/static/legacy/files.html +0 -747
  461. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  462. claude_mpm/dashboard/static/monitors.html +0 -431
  463. claude_mpm/dashboard/static/production/events.html +0 -659
  464. claude_mpm/dashboard/static/production/main.html +0 -698
  465. claude_mpm/dashboard/static/production/monitors.html +0 -483
  466. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  467. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  468. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  469. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  470. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  471. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -75
  472. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -184
  473. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -107
  474. claude_mpm/skills/bundled/collaboration/requesting-code-review/code-reviewer.md +0 -146
  475. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -118
  476. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -177
  477. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  478. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  479. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  480. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  481. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  482. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  483. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  484. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  485. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  486. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  487. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -175
  488. claude_mpm/skills/bundled/debugging/verification-before-completion/references/common-failures.md +0 -213
  489. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -314
  490. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -227
  491. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -74
  492. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -32
  493. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  494. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  495. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  496. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  497. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -328
  498. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  499. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  500. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  501. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  502. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -209
  503. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -123
  504. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  505. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  506. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  507. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  508. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  509. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  510. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -304
  511. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -96
  512. claude_mpm/tools/code_tree_analyzer.py +0 -1825
  513. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  514. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  515. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  516. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  517. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/WHEEL +0 -0
  518. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/entry_points.txt +0 -0
  519. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/licenses/LICENSE +0 -0
  520. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.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