claude-mpm 5.4.41__py3-none-any.whl → 5.6.23__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 (460) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
  3. claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
  4. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
  5. claude_mpm/agents/PM_INSTRUCTIONS.md +161 -298
  6. claude_mpm/agents/WORKFLOW.md +2 -0
  7. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  8. claude_mpm/cli/__init__.py +5 -1
  9. claude_mpm/cli/commands/agents.py +2 -4
  10. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  11. claude_mpm/cli/commands/autotodos.py +566 -0
  12. claude_mpm/cli/commands/commander.py +216 -0
  13. claude_mpm/cli/commands/configure.py +620 -21
  14. claude_mpm/cli/commands/configure_agent_display.py +3 -1
  15. claude_mpm/cli/commands/hook_errors.py +60 -60
  16. claude_mpm/cli/commands/monitor.py +2 -2
  17. claude_mpm/cli/commands/mpm_init/core.py +15 -8
  18. claude_mpm/cli/commands/profile.py +9 -10
  19. claude_mpm/cli/commands/run.py +35 -3
  20. claude_mpm/cli/commands/skill_source.py +51 -2
  21. claude_mpm/cli/commands/skills.py +182 -32
  22. claude_mpm/cli/executor.py +120 -16
  23. claude_mpm/cli/interactive/__init__.py +10 -0
  24. claude_mpm/cli/interactive/agent_wizard.py +30 -50
  25. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  26. claude_mpm/cli/interactive/skill_selector.py +481 -0
  27. claude_mpm/cli/parsers/base_parser.py +76 -1
  28. claude_mpm/cli/parsers/commander_parser.py +116 -0
  29. claude_mpm/cli/parsers/profile_parser.py +0 -1
  30. claude_mpm/cli/parsers/run_parser.py +10 -0
  31. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  32. claude_mpm/cli/parsers/skills_parser.py +2 -3
  33. claude_mpm/cli/startup.py +527 -506
  34. claude_mpm/cli/startup_display.py +74 -6
  35. claude_mpm/cli/startup_logging.py +2 -2
  36. claude_mpm/cli/utils.py +7 -3
  37. claude_mpm/commander/__init__.py +78 -0
  38. claude_mpm/commander/adapters/__init__.py +60 -0
  39. claude_mpm/commander/adapters/auggie.py +260 -0
  40. claude_mpm/commander/adapters/base.py +288 -0
  41. claude_mpm/commander/adapters/claude_code.py +392 -0
  42. claude_mpm/commander/adapters/codex.py +237 -0
  43. claude_mpm/commander/adapters/communication.py +366 -0
  44. claude_mpm/commander/adapters/example_usage.py +310 -0
  45. claude_mpm/commander/adapters/mpm.py +389 -0
  46. claude_mpm/commander/adapters/registry.py +204 -0
  47. claude_mpm/commander/api/__init__.py +16 -0
  48. claude_mpm/commander/api/app.py +121 -0
  49. claude_mpm/commander/api/errors.py +133 -0
  50. claude_mpm/commander/api/routes/__init__.py +8 -0
  51. claude_mpm/commander/api/routes/events.py +184 -0
  52. claude_mpm/commander/api/routes/inbox.py +171 -0
  53. claude_mpm/commander/api/routes/messages.py +148 -0
  54. claude_mpm/commander/api/routes/projects.py +271 -0
  55. claude_mpm/commander/api/routes/sessions.py +226 -0
  56. claude_mpm/commander/api/routes/work.py +296 -0
  57. claude_mpm/commander/api/schemas.py +186 -0
  58. claude_mpm/commander/chat/__init__.py +7 -0
  59. claude_mpm/commander/chat/cli.py +146 -0
  60. claude_mpm/commander/chat/commands.py +96 -0
  61. claude_mpm/commander/chat/repl.py +310 -0
  62. claude_mpm/commander/config.py +51 -0
  63. claude_mpm/commander/config_loader.py +115 -0
  64. claude_mpm/commander/core/__init__.py +10 -0
  65. claude_mpm/commander/core/block_manager.py +325 -0
  66. claude_mpm/commander/core/response_manager.py +323 -0
  67. claude_mpm/commander/daemon.py +603 -0
  68. claude_mpm/commander/env_loader.py +59 -0
  69. claude_mpm/commander/events/__init__.py +26 -0
  70. claude_mpm/commander/events/manager.py +332 -0
  71. claude_mpm/commander/frameworks/__init__.py +12 -0
  72. claude_mpm/commander/frameworks/base.py +146 -0
  73. claude_mpm/commander/frameworks/claude_code.py +58 -0
  74. claude_mpm/commander/frameworks/mpm.py +62 -0
  75. claude_mpm/commander/inbox/__init__.py +16 -0
  76. claude_mpm/commander/inbox/dedup.py +128 -0
  77. claude_mpm/commander/inbox/inbox.py +224 -0
  78. claude_mpm/commander/inbox/models.py +70 -0
  79. claude_mpm/commander/instance_manager.py +450 -0
  80. claude_mpm/commander/llm/__init__.py +6 -0
  81. claude_mpm/commander/llm/openrouter_client.py +167 -0
  82. claude_mpm/commander/llm/summarizer.py +70 -0
  83. claude_mpm/commander/memory/__init__.py +45 -0
  84. claude_mpm/commander/memory/compression.py +347 -0
  85. claude_mpm/commander/memory/embeddings.py +230 -0
  86. claude_mpm/commander/memory/entities.py +310 -0
  87. claude_mpm/commander/memory/example_usage.py +290 -0
  88. claude_mpm/commander/memory/integration.py +325 -0
  89. claude_mpm/commander/memory/search.py +381 -0
  90. claude_mpm/commander/memory/store.py +657 -0
  91. claude_mpm/commander/models/__init__.py +18 -0
  92. claude_mpm/commander/models/events.py +121 -0
  93. claude_mpm/commander/models/project.py +162 -0
  94. claude_mpm/commander/models/work.py +214 -0
  95. claude_mpm/commander/parsing/__init__.py +20 -0
  96. claude_mpm/commander/parsing/extractor.py +132 -0
  97. claude_mpm/commander/parsing/output_parser.py +270 -0
  98. claude_mpm/commander/parsing/patterns.py +100 -0
  99. claude_mpm/commander/persistence/__init__.py +11 -0
  100. claude_mpm/commander/persistence/event_store.py +274 -0
  101. claude_mpm/commander/persistence/state_store.py +309 -0
  102. claude_mpm/commander/persistence/work_store.py +164 -0
  103. claude_mpm/commander/polling/__init__.py +13 -0
  104. claude_mpm/commander/polling/event_detector.py +104 -0
  105. claude_mpm/commander/polling/output_buffer.py +49 -0
  106. claude_mpm/commander/polling/output_poller.py +153 -0
  107. claude_mpm/commander/project_session.py +268 -0
  108. claude_mpm/commander/proxy/__init__.py +12 -0
  109. claude_mpm/commander/proxy/formatter.py +89 -0
  110. claude_mpm/commander/proxy/output_handler.py +191 -0
  111. claude_mpm/commander/proxy/relay.py +155 -0
  112. claude_mpm/commander/registry.py +410 -0
  113. claude_mpm/commander/runtime/__init__.py +10 -0
  114. claude_mpm/commander/runtime/executor.py +191 -0
  115. claude_mpm/commander/runtime/monitor.py +346 -0
  116. claude_mpm/commander/session/__init__.py +6 -0
  117. claude_mpm/commander/session/context.py +81 -0
  118. claude_mpm/commander/session/manager.py +59 -0
  119. claude_mpm/commander/tmux_orchestrator.py +361 -0
  120. claude_mpm/commander/web/__init__.py +1 -0
  121. claude_mpm/commander/work/__init__.py +30 -0
  122. claude_mpm/commander/work/executor.py +207 -0
  123. claude_mpm/commander/work/queue.py +405 -0
  124. claude_mpm/commander/workflow/__init__.py +27 -0
  125. claude_mpm/commander/workflow/event_handler.py +241 -0
  126. claude_mpm/commander/workflow/notifier.py +146 -0
  127. claude_mpm/commands/mpm-config.md +8 -0
  128. claude_mpm/commands/mpm-doctor.md +8 -0
  129. claude_mpm/commands/mpm-help.md +8 -0
  130. claude_mpm/commands/mpm-init.md +8 -0
  131. claude_mpm/commands/mpm-monitor.md +8 -0
  132. claude_mpm/commands/mpm-organize.md +8 -0
  133. claude_mpm/commands/mpm-postmortem.md +8 -0
  134. claude_mpm/commands/mpm-session-resume.md +9 -1
  135. claude_mpm/commands/mpm-status.md +8 -0
  136. claude_mpm/commands/mpm-ticket-view.md +8 -0
  137. claude_mpm/commands/mpm-version.md +8 -0
  138. claude_mpm/commands/mpm.md +8 -0
  139. claude_mpm/config/agent_presets.py +8 -7
  140. claude_mpm/config/skill_sources.py +16 -0
  141. claude_mpm/constants.py +1 -0
  142. claude_mpm/core/claude_runner.py +154 -2
  143. claude_mpm/core/config.py +35 -22
  144. claude_mpm/core/config_constants.py +74 -9
  145. claude_mpm/core/constants.py +56 -12
  146. claude_mpm/core/hook_manager.py +51 -3
  147. claude_mpm/core/interactive_session.py +12 -11
  148. claude_mpm/core/logger.py +26 -9
  149. claude_mpm/core/logging_utils.py +35 -11
  150. claude_mpm/core/network_config.py +148 -0
  151. claude_mpm/core/oneshot_session.py +7 -6
  152. claude_mpm/core/optimized_startup.py +3 -1
  153. claude_mpm/core/output_style_manager.py +63 -18
  154. claude_mpm/core/shared/config_loader.py +3 -1
  155. claude_mpm/core/socketio_pool.py +13 -5
  156. claude_mpm/core/unified_config.py +54 -8
  157. claude_mpm/core/unified_paths.py +95 -90
  158. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
  159. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
  160. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
  161. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
  162. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
  163. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
  164. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
  165. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
  166. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
  167. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
  168. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  169. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
  170. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
  171. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
  172. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
  173. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
  174. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
  175. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
  176. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
  177. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
  178. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
  179. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
  180. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
  181. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
  182. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
  183. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
  184. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
  185. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
  186. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
  187. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
  188. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
  189. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  190. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
  191. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  192. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
  193. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
  194. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
  195. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
  196. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
  197. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{N4qtv3Hx.js → DR8nis88.js} +2 -2
  198. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
  199. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  200. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
  201. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
  202. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
  203. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
  204. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
  205. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
  206. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  207. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
  208. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
  209. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
  210. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DjhvlsAc.js → NqQ1dWOy.js} +1 -1
  211. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
  212. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
  213. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
  214. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
  215. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
  216. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
  217. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
  218. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
  219. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.CAGBuiOw.js → 0.RgBboRvH.js} +1 -1
  220. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
  221. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
  222. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
  223. claude_mpm/dashboard/static/svelte-build/index.html +11 -11
  224. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  225. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  226. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  227. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  228. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  229. claude_mpm/experimental/cli_enhancements.py +2 -1
  230. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  231. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  232. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  233. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  234. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  235. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  236. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  237. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
  238. claude_mpm/hooks/claude_hooks/event_handlers.py +305 -87
  239. claude_mpm/hooks/claude_hooks/hook_handler.py +106 -89
  240. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  241. claude_mpm/hooks/claude_hooks/installer.py +116 -8
  242. claude_mpm/hooks/claude_hooks/memory_integration.py +51 -31
  243. claude_mpm/hooks/claude_hooks/response_tracking.py +42 -59
  244. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  245. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  246. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  247. claude_mpm/hooks/claude_hooks/services/connection_manager.py +39 -24
  248. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +36 -103
  249. claude_mpm/hooks/claude_hooks/services/state_manager.py +23 -36
  250. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +73 -75
  251. claude_mpm/hooks/kuzu_memory_hook.py +5 -5
  252. claude_mpm/hooks/session_resume_hook.py +89 -1
  253. claude_mpm/hooks/templates/pre_tool_use_template.py +10 -2
  254. claude_mpm/init.py +215 -2
  255. claude_mpm/scripts/claude-hook-handler.sh +43 -16
  256. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  257. claude_mpm/services/agents/agent_selection_service.py +2 -2
  258. claude_mpm/services/agents/cache_git_manager.py +1 -1
  259. claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -1
  260. claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
  261. claude_mpm/services/agents/deployment/agent_template_builder.py +37 -17
  262. claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
  263. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  264. claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
  265. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +36 -8
  266. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +50 -26
  267. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  268. claude_mpm/services/agents/git_source_manager.py +21 -2
  269. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  270. claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
  271. claude_mpm/services/agents/sources/git_source_sync_service.py +116 -5
  272. claude_mpm/services/agents/startup_sync.py +5 -2
  273. claude_mpm/services/cli/__init__.py +3 -0
  274. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  275. claude_mpm/services/cli/session_resume_helper.py +10 -2
  276. claude_mpm/services/delegation_detector.py +175 -0
  277. claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
  278. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  279. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  280. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  281. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  282. claude_mpm/services/diagnostics/models.py +14 -1
  283. claude_mpm/services/event_log.py +325 -0
  284. claude_mpm/services/infrastructure/__init__.py +4 -0
  285. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  286. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  287. claude_mpm/services/monitor/daemon_manager.py +15 -4
  288. claude_mpm/services/monitor/management/lifecycle.py +8 -3
  289. claude_mpm/services/monitor/server.py +106 -16
  290. claude_mpm/services/pm_skills_deployer.py +302 -94
  291. claude_mpm/services/profile_manager.py +10 -4
  292. claude_mpm/services/skills/git_skill_source_manager.py +192 -29
  293. claude_mpm/services/skills/selective_skill_deployer.py +211 -46
  294. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  295. claude_mpm/services/skills_deployer.py +192 -70
  296. claude_mpm/services/socketio/handlers/hook.py +14 -7
  297. claude_mpm/services/socketio/server/main.py +12 -4
  298. claude_mpm/skills/__init__.py +2 -1
  299. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  300. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  301. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  302. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  303. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  304. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  305. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  306. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  307. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  308. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  309. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  310. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  311. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  312. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  313. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  314. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  315. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  316. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  317. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  318. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  319. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  320. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  321. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  322. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  323. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  324. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  325. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  326. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  327. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  328. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  329. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  330. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  331. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  332. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  333. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  334. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  335. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  336. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  337. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  338. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  339. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  340. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  341. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  342. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  343. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  344. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  345. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  346. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  347. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  348. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  349. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  350. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  351. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  352. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  353. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  354. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  355. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  356. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  357. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  358. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  359. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  360. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  361. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  362. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  363. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  364. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  365. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  366. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  367. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  368. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  369. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  370. claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
  371. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  372. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  373. claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
  374. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  375. claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
  376. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  377. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  378. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  379. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  380. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  381. claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
  382. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  383. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  384. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  385. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  386. claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
  387. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  388. claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
  389. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  390. claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
  391. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  392. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  393. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  394. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  395. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  396. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  397. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  398. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  399. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  400. claude_mpm/skills/bundled/security-scanning.md +112 -0
  401. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  402. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  403. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  404. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  405. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  406. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  407. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  408. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  409. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  410. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  411. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  412. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  413. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  414. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  415. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  416. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  417. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  418. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  419. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  420. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  421. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  422. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  423. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  424. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  425. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  426. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  427. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  428. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  429. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  430. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  431. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  432. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  433. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  434. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  435. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  436. claude_mpm/skills/registry.py +295 -90
  437. claude_mpm/skills/skill_manager.py +29 -23
  438. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  439. claude_mpm/utils/agent_dependency_loader.py +103 -4
  440. claude_mpm/utils/robust_installer.py +45 -24
  441. claude_mpm-5.6.23.dist-info/METADATA +393 -0
  442. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/RECORD +447 -149
  443. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
  444. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
  445. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
  446. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
  447. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +0 -1
  448. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
  449. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
  450. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
  451. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
  452. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
  453. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  454. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  455. claude_mpm-5.4.41.dist-info/METADATA +0 -998
  456. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/WHEEL +0 -0
  457. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/entry_points.txt +0 -0
  458. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/licenses/LICENSE +0 -0
  459. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  460. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/top_level.txt +0 -0
@@ -402,10 +402,11 @@ class RemoteAgentDiscoveryService:
402
402
  )
403
403
  return agents
404
404
 
405
- # Support three cache structures (PRIORITY ORDER):
405
+ # Support four cache structures (PRIORITY ORDER):
406
406
  # 1. Built output: {path}/dist/agents/ - PREFERRED (built with BASE-AGENT composition)
407
407
  # 2. Git repo path: {path}/agents/ - source files (fallback)
408
- # 3. Flattened cache: {path}/ - directly contains category directories (legacy)
408
+ # 3. Owner/repo structure: {path}/{owner}/{repo}/agents/ - GitHub sync structure
409
+ # 4. Flattened cache: {path}/ - directly contains category directories (legacy)
409
410
 
410
411
  # Priority 1: Check for dist/agents/ (built output with BASE-AGENT composition)
411
412
  dist_agents_dir = self.agents_cache_dir / "dist" / "agents"
@@ -422,32 +423,52 @@ class RemoteAgentDiscoveryService:
422
423
  self.logger.debug(f"Using source agents (no dist/ found): {agents_dir}")
423
424
  scan_dir = agents_dir
424
425
  else:
425
- # LEGACY: Flattened cache structure - scan root directly
426
- # Check if this looks like the flattened cache (has category subdirectories)
427
- category_dirs = [
428
- "universal",
429
- "engineer",
430
- "ops",
431
- "qa",
432
- "security",
433
- "documentation",
434
- ]
435
- has_categories = any(
436
- (self.agents_cache_dir / cat).exists() for cat in category_dirs
437
- )
438
-
439
- if has_categories:
440
- self.logger.debug(
441
- f"Using flattened cache structure: {self.agents_cache_dir}"
442
- )
443
- scan_dir = self.agents_cache_dir
426
+ # Priority 3: Check for {owner}/{repo}/agents/ structure (GitHub sync)
427
+ # e.g., ~/.claude-mpm/cache/agents/bobmatnyc/claude-mpm-agents/agents/
428
+ owner_repo_agents_dir = None
429
+ for owner_dir in self.agents_cache_dir.iterdir():
430
+ if owner_dir.is_dir() and not owner_dir.name.startswith("."):
431
+ for repo_dir in owner_dir.iterdir():
432
+ if repo_dir.is_dir():
433
+ potential_agents = repo_dir / "agents"
434
+ if potential_agents.exists():
435
+ owner_repo_agents_dir = potential_agents
436
+ self.logger.debug(
437
+ f"Using GitHub sync structure: {owner_repo_agents_dir}"
438
+ )
439
+ break
440
+ if owner_repo_agents_dir:
441
+ break
442
+
443
+ if owner_repo_agents_dir:
444
+ scan_dir = owner_repo_agents_dir
444
445
  else:
445
- self.logger.warning(
446
- f"No agent directories found. Checked: {dist_agents_dir}, {agents_dir}, "
447
- f"and category directories in {self.agents_cache_dir}. "
448
- f"Expected agents in /dist/agents/, /agents/, or category directories."
446
+ # LEGACY: Flattened cache structure - scan root directly
447
+ # Check if this looks like the flattened cache (has category subdirectories)
448
+ category_dirs = [
449
+ "universal",
450
+ "engineer",
451
+ "ops",
452
+ "qa",
453
+ "security",
454
+ "documentation",
455
+ ]
456
+ has_categories = any(
457
+ (self.agents_cache_dir / cat).exists() for cat in category_dirs
449
458
  )
450
- return agents
459
+
460
+ if has_categories:
461
+ self.logger.debug(
462
+ f"Using flattened cache structure: {self.agents_cache_dir}"
463
+ )
464
+ scan_dir = self.agents_cache_dir
465
+ else:
466
+ self.logger.warning(
467
+ f"No agent directories found. Checked: {dist_agents_dir}, {agents_dir}, "
468
+ f"owner/repo/agents/ structure, and category directories in {self.agents_cache_dir}. "
469
+ "Expected agents in /dist/agents/, /agents/, owner/repo/agents/, or category directories."
470
+ )
471
+ return agents
451
472
 
452
473
  # Find all Markdown files recursively
453
474
  md_files = list(scan_dir.rglob("*.md"))
@@ -470,6 +491,9 @@ class RemoteAgentDiscoveryService:
470
491
  "SKILL.md",
471
492
  "SKILLS.md",
472
493
  "skill-template.md",
494
+ # Legacy agents superseded by newer versions
495
+ # TODO: Remove after bobmatnyc/claude-mpm-agents#XXX is merged
496
+ "memory-manager.md", # Superseded by memory-manager-agent.md (v1.2.0)
473
497
  }
474
498
  md_files = [f for f in md_files if f.name not in excluded_files]
475
499
 
@@ -0,0 +1,138 @@
1
+ """
2
+ Startup Reconciliation Hook
3
+
4
+ This module provides a hook for performing agent/skill reconciliation
5
+ during application startup, ensuring deployed state matches configuration.
6
+
7
+ Usage:
8
+ from claude_mpm.services.agents.deployment.startup_reconciliation import (
9
+ perform_startup_reconciliation
10
+ )
11
+
12
+ # In your startup code
13
+ perform_startup_reconciliation()
14
+ """
15
+
16
+ from pathlib import Path
17
+ from typing import Optional
18
+
19
+ from claude_mpm.core.logging_utils import get_logger
20
+ from claude_mpm.core.unified_config import UnifiedConfig
21
+
22
+ from .deployment_reconciler import DeploymentReconciler, DeploymentResult
23
+
24
+ logger = get_logger(__name__)
25
+
26
+
27
+ def perform_startup_reconciliation(
28
+ project_path: Optional[Path] = None,
29
+ config: Optional[UnifiedConfig] = None,
30
+ silent: bool = False,
31
+ ) -> tuple[DeploymentResult, DeploymentResult]:
32
+ """
33
+ Perform agent and skill reconciliation during startup.
34
+
35
+ This ensures the deployed state (.claude/agents, .claude/skills) matches
36
+ the configuration (agents.enabled, skills.enabled lists).
37
+
38
+ Args:
39
+ project_path: Project directory (default: current directory)
40
+ config: Configuration instance (auto-loads if None)
41
+ silent: Suppress info logging (only errors)
42
+
43
+ Returns:
44
+ Tuple of (agent_result, skill_result)
45
+ """
46
+ project_path = project_path or Path.cwd()
47
+
48
+ # Load config if not provided
49
+ if config is None:
50
+ config = UnifiedConfig()
51
+
52
+ # Initialize reconciler
53
+ reconciler = DeploymentReconciler(config)
54
+
55
+ if not silent:
56
+ logger.info("Performing startup reconciliation...")
57
+
58
+ # Reconcile agents
59
+ agent_result = reconciler.reconcile_agents(project_path)
60
+
61
+ if agent_result.deployed and not silent:
62
+ logger.info(f"Deployed agents: {', '.join(agent_result.deployed)}")
63
+ if agent_result.removed and not silent:
64
+ logger.info(f"Removed agents: {', '.join(agent_result.removed)}")
65
+ if agent_result.errors:
66
+ for error in agent_result.errors:
67
+ logger.error(f"Agent reconciliation error: {error}")
68
+
69
+ # Reconcile skills
70
+ skill_result = reconciler.reconcile_skills(project_path)
71
+
72
+ if skill_result.deployed and not silent:
73
+ logger.info(f"Deployed skills: {', '.join(skill_result.deployed)}")
74
+ if skill_result.removed and not silent:
75
+ logger.info(f"Removed skills: {', '.join(skill_result.removed)}")
76
+ if skill_result.errors:
77
+ for error in skill_result.errors:
78
+ logger.error(f"Skill reconciliation error: {error}")
79
+
80
+ if not silent:
81
+ total_errors = len(agent_result.errors) + len(skill_result.errors)
82
+ if total_errors == 0:
83
+ logger.info("Startup reconciliation complete")
84
+ else:
85
+ logger.warning(
86
+ f"Startup reconciliation complete with {total_errors} errors"
87
+ )
88
+
89
+ return agent_result, skill_result
90
+
91
+
92
+ def check_reconciliation_needed(
93
+ project_path: Optional[Path] = None, config: Optional[UnifiedConfig] = None
94
+ ) -> bool:
95
+ """
96
+ Check if reconciliation is needed (without performing it).
97
+
98
+ Args:
99
+ project_path: Project directory
100
+ config: Configuration instance
101
+
102
+ Returns:
103
+ True if reconciliation would make changes
104
+ """
105
+ project_path = project_path or Path.cwd()
106
+
107
+ if config is None:
108
+ config = UnifiedConfig()
109
+
110
+ reconciler = DeploymentReconciler(config)
111
+ view = reconciler.get_reconciliation_view(project_path)
112
+
113
+ agent_state = view["agents"]
114
+ skill_state = view["skills"]
115
+
116
+ # Check if any changes needed
117
+ return (
118
+ len(agent_state.to_deploy) > 0
119
+ or len(agent_state.to_remove) > 0
120
+ or len(skill_state.to_deploy) > 0
121
+ or len(skill_state.to_remove) > 0
122
+ )
123
+
124
+
125
+ # Example integration in startup code:
126
+ #
127
+ # from claude_mpm.services.agents.deployment.startup_reconciliation import (
128
+ # perform_startup_reconciliation,
129
+ # check_reconciliation_needed
130
+ # )
131
+ #
132
+ # def startup():
133
+ # # Check if reconciliation needed
134
+ # if check_reconciliation_needed():
135
+ # logger.info("Reconciliation needed, performing...")
136
+ # perform_startup_reconciliation()
137
+ # else:
138
+ # logger.debug("No reconciliation needed")
@@ -395,8 +395,27 @@ class GitSourceManager:
395
395
  )
396
396
  logger.debug(f"[DEBUG] Found {len(agents)} agents so far")
397
397
 
398
- logger.debug(f"[DEBUG] list_cached_agents COMPLETE: {len(agents)} total agents")
399
- return agents
398
+ logger.debug(
399
+ f"[DEBUG] list_cached_agents COMPLETE: {len(agents)} total agents (before deduplication)"
400
+ )
401
+
402
+ # Deduplicate agents by agent_id (Bug #2 fix)
403
+ # When same agent exists in multiple locations, keep only first occurrence
404
+ seen_ids = set()
405
+ deduplicated_agents = []
406
+
407
+ for agent in agents:
408
+ agent_id = agent.get("agent_id") or agent.get("metadata", {}).get("name")
409
+ if agent_id and agent_id not in seen_ids:
410
+ seen_ids.add(agent_id)
411
+ deduplicated_agents.append(agent)
412
+ elif agent_id:
413
+ logger.debug(f"[DEBUG] Skipping duplicate agent: {agent_id}")
414
+
415
+ logger.debug(
416
+ f"[DEBUG] After deduplication: {len(deduplicated_agents)} unique agents"
417
+ )
418
+ return deduplicated_agents
400
419
 
401
420
  def _discover_agents_in_directory(
402
421
  self,
@@ -10,10 +10,19 @@ Loading precedence: Project → User → System
10
10
 
11
11
  This service integrates with the main agent_loader.py to provide
12
12
  markdown-based agent profiles alongside JSON-based templates.
13
+
14
+ Auto-Deployment: When no agents are configured, the standard 6 core agents
15
+ are automatically deployed:
16
+ - engineer: General-purpose implementation
17
+ - research: Codebase exploration and analysis
18
+ - qa: Testing and quality assurance
19
+ - documentation: Documentation generation
20
+ - ops: Basic deployment operations
21
+ - ticketing: Ticket tracking (essential for PM workflow)
13
22
  """
14
23
 
15
24
  from pathlib import Path
16
- from typing import Any, Dict, Optional
25
+ from typing import Any, Dict, List, Optional
17
26
 
18
27
  from claude_mpm.agents.agent_loader import AgentTier, list_agents_by_tier
19
28
  from claude_mpm.core.logging_utils import get_logger
@@ -21,6 +30,17 @@ from claude_mpm.core.unified_paths import get_path_manager
21
30
 
22
31
  logger = get_logger(__name__)
23
32
 
33
+ # Standard 6 core agents that are auto-deployed when no agents are specified
34
+ # This list is the canonical source - other modules should import from here
35
+ CORE_AGENTS: List[str] = [
36
+ "engineer", # General-purpose implementation
37
+ "research", # Codebase exploration and analysis
38
+ "qa", # Testing and quality assurance
39
+ "documentation", # Documentation generation
40
+ "ops", # Basic deployment operations
41
+ "ticketing", # Ticket tracking (essential for PM workflow)
42
+ ]
43
+
24
44
 
25
45
  class FrameworkAgentLoader:
26
46
  """Loads agent profiles from project, user, and system directories with proper precedence"""
@@ -86,7 +106,7 @@ class FrameworkAgentLoader:
86
106
  data_claude = package_path / "data" / "agents" / "CLAUDE.md"
87
107
  if data_instructions.exists() or data_claude.exists():
88
108
  return package_path / "data"
89
- except Exception:
109
+ except Exception: # nosec B110 - intentional fallthrough to next location
90
110
  pass
91
111
 
92
112
  current = Path.cwd()
@@ -431,3 +451,56 @@ Please operate according to your profile specifications and maintain quality sta
431
451
  """
432
452
 
433
453
  return instruction.strip()
454
+
455
+ def get_core_agents(self) -> List[str]:
456
+ """
457
+ Get the standard 6 core agents for auto-deployment.
458
+
459
+ These agents are automatically deployed when no agents are specified
460
+ in the configuration. They provide essential PM workflow functionality.
461
+
462
+ Returns:
463
+ List of core agent IDs
464
+
465
+ Example:
466
+ >>> loader = FrameworkAgentLoader()
467
+ >>> core = loader.get_core_agents()
468
+ >>> 'engineer' in core
469
+ True
470
+ >>> len(core)
471
+ 6
472
+ """
473
+ return CORE_AGENTS.copy()
474
+
475
+ def get_agents_with_fallback(self) -> Dict[str, list]:
476
+ """
477
+ Get available agents, falling back to core agents if none found.
478
+
479
+ This method implements the auto-deployment logic: when no agents
480
+ are found in any tier (project, user, system), it returns the
481
+ standard 6 core agents as a fallback.
482
+
483
+ Returns:
484
+ Dictionary with agent lists by tier. If no agents found in any tier,
485
+ returns core agents under 'fallback' key.
486
+
487
+ Example:
488
+ >>> loader = FrameworkAgentLoader()
489
+ >>> loader.initialize()
490
+ >>> agents = loader.get_agents_with_fallback()
491
+ >>> if 'fallback' in agents:
492
+ ... print("Using core agents as fallback")
493
+ """
494
+ available = self.get_available_agents()
495
+
496
+ # Check if any agents are found
497
+ total_agents = sum(len(agents) for agents in available.values())
498
+
499
+ if total_agents == 0:
500
+ logger.info(
501
+ "No agents found in configuration. "
502
+ "Auto-deploying standard 6 core agents."
503
+ )
504
+ return {"fallback": CORE_AGENTS.copy()}
505
+
506
+ return available
@@ -30,12 +30,12 @@ from datetime import datetime, timezone
30
30
  from pathlib import Path
31
31
  from typing import Any, Dict, List, Optional
32
32
 
33
- from src.claude_mpm.config.agent_sources import AgentSourceConfiguration
34
- from src.claude_mpm.models.git_repository import GitRepository
35
- from src.claude_mpm.services.agents.deployment.remote_agent_discovery_service import (
33
+ from claude_mpm.config.agent_sources import AgentSourceConfiguration
34
+ from claude_mpm.models.git_repository import GitRepository
35
+ from claude_mpm.services.agents.deployment.remote_agent_discovery_service import (
36
36
  RemoteAgentDiscoveryService,
37
37
  )
38
- from src.claude_mpm.services.agents.git_source_manager import GitSourceManager
38
+ from claude_mpm.services.agents.git_source_manager import GitSourceManager
39
39
 
40
40
  logger = logging.getLogger(__name__)
41
41
 
@@ -13,11 +13,16 @@ import logging
13
13
  import time
14
14
  from datetime import datetime, timezone
15
15
  from pathlib import Path
16
- from typing import Any, Dict, List, Optional, Tuple
16
+ from typing import Any, Dict, List, Optional, Set, Tuple
17
17
 
18
18
  import requests
19
19
 
20
20
  from claude_mpm.core.file_utils import get_file_hash
21
+
22
+ # Import normalize function for exclusion filtering
23
+ from claude_mpm.services.agents.deployment.multi_source_deployment_service import (
24
+ _normalize_agent_name,
25
+ )
21
26
  from claude_mpm.services.agents.sources.agent_sync_state import AgentSyncState
22
27
  from claude_mpm.utils.progress import create_progress_bar
23
28
 
@@ -923,6 +928,62 @@ class GitSourceSyncService:
923
928
  """
924
929
  return self.cache_dir
925
930
 
931
+ def _cleanup_excluded_agents(
932
+ self,
933
+ deployment_dir: Path,
934
+ excluded_set: Set[str],
935
+ ) -> Dict[str, List[str]]:
936
+ """Remove excluded agents from deployment directory.
937
+
938
+ Removes any agents in the deployment directory whose normalized
939
+ names match the exclusion list. This ensures that excluded agents
940
+ are cleaned up from previous deployments.
941
+
942
+ Args:
943
+ deployment_dir: Directory containing deployed agents
944
+ excluded_set: Set of normalized agent names to exclude
945
+
946
+ Returns:
947
+ Dictionary with cleanup results:
948
+ - removed: List of agent names that were removed
949
+ """
950
+ cleanup_results: Dict[str, List[str]] = {"removed": []}
951
+
952
+ if not deployment_dir.exists():
953
+ logger.debug("Deployment directory does not exist, no cleanup needed")
954
+ return cleanup_results
955
+
956
+ for item in deployment_dir.iterdir():
957
+ # Only process .md files
958
+ if not item.is_file() or item.suffix != ".md":
959
+ continue
960
+
961
+ # Skip hidden files
962
+ if item.name.startswith("."):
963
+ continue
964
+
965
+ # Normalize agent name for comparison
966
+ agent_name = _normalize_agent_name(item.stem)
967
+
968
+ # Check if this agent is excluded
969
+ if agent_name in excluded_set:
970
+ try:
971
+ item.unlink()
972
+ cleanup_results["removed"].append(item.stem)
973
+ logger.info(f"Removed excluded agent: {item.stem}")
974
+ except PermissionError as e:
975
+ logger.error(f"Permission denied removing {item.stem}: {e}")
976
+ except Exception as e:
977
+ logger.error(f"Failed to remove {item.stem}: {e}")
978
+
979
+ # Log summary
980
+ if cleanup_results["removed"]:
981
+ logger.info(
982
+ f"Cleanup complete: removed {len(cleanup_results['removed'])} excluded agents"
983
+ )
984
+
985
+ return cleanup_results
986
+
926
987
  def deploy_agents_to_project(
927
988
  self,
928
989
  project_dir: Path,
@@ -977,6 +1038,8 @@ class GitSourceSyncService:
977
1038
  """
978
1039
  import shutil
979
1040
 
1041
+ from claude_mpm.core.config import Config
1042
+
980
1043
  # Deploy to .claude/agents/ where Claude Code expects them
981
1044
  deployment_dir = project_dir / ".claude" / "agents"
982
1045
  deployment_dir.mkdir(parents=True, exist_ok=True)
@@ -989,10 +1052,55 @@ class GitSourceSyncService:
989
1052
  "deployment_dir": str(deployment_dir),
990
1053
  }
991
1054
 
1055
+ # Load project config to get exclusion list
1056
+ config_file = project_dir / ".claude-mpm" / "configuration.yaml"
1057
+ if config_file.exists():
1058
+ config = Config(config_file=config_file)
1059
+ excluded_agents = config.get("excluded_agents", [])
1060
+ else:
1061
+ # No project config, no exclusions
1062
+ excluded_agents = []
1063
+
1064
+ # Create normalized exclusion set
1065
+ excluded_set: Set[str] = (
1066
+ {_normalize_agent_name(name) for name in excluded_agents}
1067
+ if excluded_agents
1068
+ else set()
1069
+ )
1070
+
1071
+ if excluded_set:
1072
+ logger.info(
1073
+ f"Applying exclusions: {', '.join(sorted(excluded_agents))} "
1074
+ f"(normalized: {', '.join(sorted(excluded_set))})"
1075
+ )
1076
+
992
1077
  # Get agents from cache or use provided list
993
1078
  if agent_list is None:
994
1079
  agent_list = self._discover_cached_agents()
995
1080
 
1081
+ # Filter out excluded agents
1082
+ if excluded_set:
1083
+ original_count = len(agent_list)
1084
+ agent_list = [
1085
+ agent_path
1086
+ for agent_path in agent_list
1087
+ if _normalize_agent_name(Path(agent_path).stem) not in excluded_set
1088
+ ]
1089
+ filtered_count = original_count - len(agent_list)
1090
+ if filtered_count > 0:
1091
+ logger.info(f"Filtered out {filtered_count} excluded agents")
1092
+
1093
+ # Clean up any previously deployed excluded agents
1094
+ if excluded_set:
1095
+ cleanup_results = self._cleanup_excluded_agents(
1096
+ deployment_dir, excluded_set
1097
+ )
1098
+ if cleanup_results["removed"]:
1099
+ logger.info(
1100
+ f"Cleaned up {len(cleanup_results['removed'])} excluded agents: "
1101
+ f"{', '.join(cleanup_results['removed'])}"
1102
+ )
1103
+
996
1104
  logger.info(
997
1105
  f"Deploying {len(agent_list)} agents from cache to {deployment_dir}"
998
1106
  )
@@ -1010,14 +1118,17 @@ class GitSourceSyncService:
1010
1118
  deploy_filename = Path(agent_path).name
1011
1119
  deploy_file = deployment_dir / deploy_filename
1012
1120
 
1013
- # Check if update needed (compare modification times)
1121
+ # Check if update needed (compare content, not just mtime)
1122
+ # DESIGN: Use content hash comparison for reliable change detection
1123
+ # Mtime comparison can fail when cache downloads have older timestamps
1014
1124
  should_deploy = force
1015
1125
  was_existing = deploy_file.exists()
1016
1126
 
1017
1127
  if not force and was_existing:
1018
- cache_mtime = cache_file.stat().st_mtime
1019
- deploy_mtime = deploy_file.stat().st_mtime
1020
- should_deploy = cache_mtime > deploy_mtime
1128
+ # Compare file contents using hash
1129
+ cache_content = cache_file.read_bytes()
1130
+ deploy_content = deploy_file.read_bytes()
1131
+ should_deploy = cache_content != deploy_content
1021
1132
 
1022
1133
  if not should_deploy and was_existing:
1023
1134
  results["skipped"].append(deploy_filename)
@@ -32,7 +32,9 @@ from claude_mpm.services.agents.sources.git_source_sync_service import (
32
32
  logger = logging.getLogger(__name__)
33
33
 
34
34
 
35
- def sync_agents_on_startup(config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
35
+ def sync_agents_on_startup(
36
+ config: Optional[Dict[str, Any]] = None, force_refresh: bool = False
37
+ ) -> Dict[str, Any]:
36
38
  """Synchronize agents from remote sources on Claude MPM startup.
37
39
 
38
40
  Design Decision: Single-source support for Stage 1
@@ -44,6 +46,7 @@ def sync_agents_on_startup(config: Optional[Dict[str, Any]] = None) -> Dict[str,
44
46
 
45
47
  Args:
46
48
  config: Optional configuration dictionary. If None, loads from Config singleton.
49
+ force_refresh: Force download even if cache is fresh (bypasses ETag).
47
50
 
48
51
  Returns:
49
52
  Dictionary with sync results:
@@ -156,7 +159,7 @@ def sync_agents_on_startup(config: Optional[Dict[str, Any]] = None) -> Dict[str,
156
159
  )
157
160
 
158
161
  # Perform sync
159
- sync_result = sync_service.sync_agents(force_refresh=False)
162
+ sync_result = sync_service.sync_agents(force_refresh=force_refresh)
160
163
 
161
164
  # Aggregate results
162
165
  result["sources_synced"] += 1
@@ -5,6 +5,7 @@ Services specifically for CLI command support and utilities.
5
5
 
6
6
  from .agent_dependency_service import AgentDependencyService, IAgentDependencyService
7
7
  from .agent_validation_service import AgentValidationService, IAgentValidationService
8
+ from .incremental_pause_manager import IncrementalPauseManager, PauseAction
8
9
  from .startup_checker import IStartupChecker, StartupCheckerService, StartupWarning
9
10
 
10
11
  __all__ = [
@@ -13,6 +14,8 @@ __all__ = [
13
14
  "IAgentDependencyService",
14
15
  "IAgentValidationService",
15
16
  "IStartupChecker",
17
+ "IncrementalPauseManager",
18
+ "PauseAction",
16
19
  "StartupCheckerService",
17
20
  "StartupWarning",
18
21
  ]