claude-mpm 5.4.22__py3-none-any.whl → 5.6.34__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 (487) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_AGENT.md +164 -0
  3. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  4. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
  5. claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
  6. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
  7. claude_mpm/agents/MEMORY.md +1 -1
  8. claude_mpm/agents/PM_INSTRUCTIONS.md +374 -1257
  9. claude_mpm/agents/WORKFLOW.md +6 -253
  10. claude_mpm/agents/agent_loader.py +1 -1
  11. claude_mpm/agents/base_agent.json +31 -0
  12. claude_mpm/agents/frontmatter_validator.py +2 -2
  13. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  14. claude_mpm/cli/__init__.py +5 -1
  15. claude_mpm/cli/commands/agent_state_manager.py +10 -10
  16. claude_mpm/cli/commands/agents.py +11 -13
  17. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  18. claude_mpm/cli/commands/auto_configure.py +4 -4
  19. claude_mpm/cli/commands/autotodos.py +566 -0
  20. claude_mpm/cli/commands/commander.py +216 -0
  21. claude_mpm/cli/commands/configure.py +621 -22
  22. claude_mpm/cli/commands/configure_agent_display.py +12 -0
  23. claude_mpm/cli/commands/hook_errors.py +60 -60
  24. claude_mpm/cli/commands/monitor.py +2 -2
  25. claude_mpm/cli/commands/mpm_init/core.py +72 -0
  26. claude_mpm/cli/commands/postmortem.py +1 -1
  27. claude_mpm/cli/commands/profile.py +276 -0
  28. claude_mpm/cli/commands/run.py +35 -3
  29. claude_mpm/cli/commands/skill_source.py +51 -2
  30. claude_mpm/cli/commands/skills.py +182 -32
  31. claude_mpm/cli/executor.py +130 -16
  32. claude_mpm/cli/interactive/__init__.py +10 -0
  33. claude_mpm/cli/interactive/agent_wizard.py +32 -52
  34. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  35. claude_mpm/cli/interactive/skill_selector.py +481 -0
  36. claude_mpm/cli/parsers/base_parser.py +83 -1
  37. claude_mpm/cli/parsers/commander_parser.py +116 -0
  38. claude_mpm/cli/parsers/profile_parser.py +147 -0
  39. claude_mpm/cli/parsers/run_parser.py +10 -0
  40. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  41. claude_mpm/cli/parsers/skills_parser.py +2 -3
  42. claude_mpm/cli/startup.py +690 -386
  43. claude_mpm/cli/startup_display.py +74 -6
  44. claude_mpm/cli/startup_logging.py +2 -2
  45. claude_mpm/cli/utils.py +7 -3
  46. claude_mpm/commander/__init__.py +78 -0
  47. claude_mpm/commander/adapters/__init__.py +60 -0
  48. claude_mpm/commander/adapters/auggie.py +260 -0
  49. claude_mpm/commander/adapters/base.py +288 -0
  50. claude_mpm/commander/adapters/claude_code.py +392 -0
  51. claude_mpm/commander/adapters/codex.py +237 -0
  52. claude_mpm/commander/adapters/communication.py +366 -0
  53. claude_mpm/commander/adapters/example_usage.py +310 -0
  54. claude_mpm/commander/adapters/mpm.py +389 -0
  55. claude_mpm/commander/adapters/registry.py +204 -0
  56. claude_mpm/commander/api/__init__.py +16 -0
  57. claude_mpm/commander/api/app.py +121 -0
  58. claude_mpm/commander/api/errors.py +133 -0
  59. claude_mpm/commander/api/routes/__init__.py +8 -0
  60. claude_mpm/commander/api/routes/events.py +184 -0
  61. claude_mpm/commander/api/routes/inbox.py +171 -0
  62. claude_mpm/commander/api/routes/messages.py +148 -0
  63. claude_mpm/commander/api/routes/projects.py +271 -0
  64. claude_mpm/commander/api/routes/sessions.py +226 -0
  65. claude_mpm/commander/api/routes/work.py +296 -0
  66. claude_mpm/commander/api/schemas.py +186 -0
  67. claude_mpm/commander/chat/__init__.py +7 -0
  68. claude_mpm/commander/chat/cli.py +146 -0
  69. claude_mpm/commander/chat/commands.py +96 -0
  70. claude_mpm/commander/chat/repl.py +310 -0
  71. claude_mpm/commander/config.py +51 -0
  72. claude_mpm/commander/config_loader.py +115 -0
  73. claude_mpm/commander/core/__init__.py +10 -0
  74. claude_mpm/commander/core/block_manager.py +325 -0
  75. claude_mpm/commander/core/response_manager.py +323 -0
  76. claude_mpm/commander/daemon.py +603 -0
  77. claude_mpm/commander/env_loader.py +59 -0
  78. claude_mpm/commander/events/__init__.py +26 -0
  79. claude_mpm/commander/events/manager.py +332 -0
  80. claude_mpm/commander/frameworks/__init__.py +12 -0
  81. claude_mpm/commander/frameworks/base.py +146 -0
  82. claude_mpm/commander/frameworks/claude_code.py +58 -0
  83. claude_mpm/commander/frameworks/mpm.py +62 -0
  84. claude_mpm/commander/inbox/__init__.py +16 -0
  85. claude_mpm/commander/inbox/dedup.py +128 -0
  86. claude_mpm/commander/inbox/inbox.py +224 -0
  87. claude_mpm/commander/inbox/models.py +70 -0
  88. claude_mpm/commander/instance_manager.py +450 -0
  89. claude_mpm/commander/llm/__init__.py +6 -0
  90. claude_mpm/commander/llm/openrouter_client.py +167 -0
  91. claude_mpm/commander/llm/summarizer.py +70 -0
  92. claude_mpm/commander/memory/__init__.py +45 -0
  93. claude_mpm/commander/memory/compression.py +347 -0
  94. claude_mpm/commander/memory/embeddings.py +230 -0
  95. claude_mpm/commander/memory/entities.py +310 -0
  96. claude_mpm/commander/memory/example_usage.py +290 -0
  97. claude_mpm/commander/memory/integration.py +325 -0
  98. claude_mpm/commander/memory/search.py +381 -0
  99. claude_mpm/commander/memory/store.py +657 -0
  100. claude_mpm/commander/models/__init__.py +18 -0
  101. claude_mpm/commander/models/events.py +121 -0
  102. claude_mpm/commander/models/project.py +162 -0
  103. claude_mpm/commander/models/work.py +214 -0
  104. claude_mpm/commander/parsing/__init__.py +20 -0
  105. claude_mpm/commander/parsing/extractor.py +132 -0
  106. claude_mpm/commander/parsing/output_parser.py +270 -0
  107. claude_mpm/commander/parsing/patterns.py +100 -0
  108. claude_mpm/commander/persistence/__init__.py +11 -0
  109. claude_mpm/commander/persistence/event_store.py +274 -0
  110. claude_mpm/commander/persistence/state_store.py +309 -0
  111. claude_mpm/commander/persistence/work_store.py +164 -0
  112. claude_mpm/commander/polling/__init__.py +13 -0
  113. claude_mpm/commander/polling/event_detector.py +104 -0
  114. claude_mpm/commander/polling/output_buffer.py +49 -0
  115. claude_mpm/commander/polling/output_poller.py +153 -0
  116. claude_mpm/commander/project_session.py +268 -0
  117. claude_mpm/commander/proxy/__init__.py +12 -0
  118. claude_mpm/commander/proxy/formatter.py +89 -0
  119. claude_mpm/commander/proxy/output_handler.py +191 -0
  120. claude_mpm/commander/proxy/relay.py +155 -0
  121. claude_mpm/commander/registry.py +410 -0
  122. claude_mpm/commander/runtime/__init__.py +10 -0
  123. claude_mpm/commander/runtime/executor.py +191 -0
  124. claude_mpm/commander/runtime/monitor.py +346 -0
  125. claude_mpm/commander/session/__init__.py +6 -0
  126. claude_mpm/commander/session/context.py +81 -0
  127. claude_mpm/commander/session/manager.py +59 -0
  128. claude_mpm/commander/tmux_orchestrator.py +361 -0
  129. claude_mpm/commander/web/__init__.py +1 -0
  130. claude_mpm/commander/work/__init__.py +30 -0
  131. claude_mpm/commander/work/executor.py +207 -0
  132. claude_mpm/commander/work/queue.py +405 -0
  133. claude_mpm/commander/workflow/__init__.py +27 -0
  134. claude_mpm/commander/workflow/event_handler.py +241 -0
  135. claude_mpm/commander/workflow/notifier.py +146 -0
  136. claude_mpm/commands/mpm-config.md +20 -249
  137. claude_mpm/commands/mpm-doctor.md +16 -21
  138. claude_mpm/commands/mpm-help.md +12 -205
  139. claude_mpm/commands/mpm-init.md +88 -506
  140. claude_mpm/commands/mpm-monitor.md +22 -401
  141. claude_mpm/commands/mpm-organize.md +70 -442
  142. claude_mpm/commands/mpm-postmortem.md +13 -107
  143. claude_mpm/commands/mpm-session-resume.md +20 -363
  144. claude_mpm/commands/mpm-status.md +13 -69
  145. claude_mpm/commands/mpm-ticket-view.md +60 -495
  146. claude_mpm/commands/mpm-version.md +13 -107
  147. claude_mpm/commands/mpm.md +8 -0
  148. claude_mpm/config/agent_presets.py +8 -7
  149. claude_mpm/config/skill_sources.py +16 -0
  150. claude_mpm/constants.py +1 -0
  151. claude_mpm/core/claude_runner.py +154 -2
  152. claude_mpm/core/config.py +37 -26
  153. claude_mpm/core/config_constants.py +74 -9
  154. claude_mpm/core/constants.py +56 -12
  155. claude_mpm/core/framework/loaders/agent_loader.py +1 -1
  156. claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
  157. claude_mpm/core/hook_manager.py +51 -3
  158. claude_mpm/core/interactive_session.py +12 -11
  159. claude_mpm/core/logger.py +26 -9
  160. claude_mpm/core/logging_utils.py +39 -13
  161. claude_mpm/core/network_config.py +148 -0
  162. claude_mpm/core/oneshot_session.py +7 -6
  163. claude_mpm/core/optimized_startup.py +61 -0
  164. claude_mpm/core/output_style_manager.py +66 -18
  165. claude_mpm/core/shared/config_loader.py +3 -1
  166. claude_mpm/core/socketio_pool.py +47 -15
  167. claude_mpm/core/unified_agent_registry.py +1 -1
  168. claude_mpm/core/unified_config.py +54 -8
  169. claude_mpm/core/unified_paths.py +95 -90
  170. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  171. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
  172. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
  173. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
  174. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
  175. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
  176. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
  177. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
  178. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
  179. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
  180. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
  181. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  182. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
  183. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
  184. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
  185. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
  186. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
  187. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
  188. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
  189. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
  190. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
  191. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
  192. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
  193. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
  194. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
  195. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
  196. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
  197. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
  198. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
  199. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
  200. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
  201. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
  202. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  203. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
  204. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  205. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
  206. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
  207. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
  208. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
  209. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
  210. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DR8nis88.js +2 -0
  211. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
  212. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  213. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
  214. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
  215. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
  216. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
  217. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
  218. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
  219. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  220. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
  221. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
  222. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
  223. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
  224. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
  225. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
  226. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
  227. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
  228. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
  229. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
  230. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
  231. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
  232. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.RgBboRvH.js +1 -0
  233. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
  234. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
  235. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  236. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  237. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  238. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  239. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  240. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  241. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  242. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  243. claude_mpm/experimental/cli_enhancements.py +2 -1
  244. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  245. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  246. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  247. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  248. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  249. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  250. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  251. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  252. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  253. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  254. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
  255. claude_mpm/hooks/claude_hooks/event_handlers.py +527 -136
  256. claude_mpm/hooks/claude_hooks/hook_handler.py +313 -99
  257. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  258. claude_mpm/hooks/claude_hooks/installer.py +206 -36
  259. claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
  260. claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
  261. claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
  262. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  263. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  264. claude_mpm/hooks/claude_hooks/services/__pycache__/container.cpython-311.pyc +0 -0
  265. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  266. claude_mpm/hooks/claude_hooks/services/__pycache__/protocols.cpython-311.pyc +0 -0
  267. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  268. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  269. claude_mpm/hooks/claude_hooks/services/connection_manager.py +67 -32
  270. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
  271. claude_mpm/hooks/claude_hooks/services/container.py +310 -0
  272. claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
  273. claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
  274. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
  275. claude_mpm/hooks/kuzu_memory_hook.py +5 -5
  276. claude_mpm/hooks/session_resume_hook.py +89 -1
  277. claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
  278. claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
  279. claude_mpm/init.py +276 -0
  280. claude_mpm/models/git_repository.py +3 -3
  281. claude_mpm/scripts/claude-hook-handler.sh +46 -19
  282. claude_mpm/services/agents/agent_builder.py +3 -3
  283. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  284. claude_mpm/services/agents/agent_selection_service.py +2 -2
  285. claude_mpm/services/agents/cache_git_manager.py +7 -7
  286. claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
  287. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -2
  288. claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
  289. claude_mpm/services/agents/deployment/agent_template_builder.py +39 -19
  290. claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
  291. claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
  292. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  293. claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
  294. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +169 -26
  295. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +101 -75
  296. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  297. claude_mpm/services/agents/git_source_manager.py +23 -4
  298. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  299. claude_mpm/services/agents/recommender.py +5 -3
  300. claude_mpm/services/agents/single_tier_deployment_service.py +6 -6
  301. claude_mpm/services/agents/sources/git_source_sync_service.py +121 -10
  302. claude_mpm/services/agents/startup_sync.py +27 -4
  303. claude_mpm/services/cli/__init__.py +3 -0
  304. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  305. claude_mpm/services/cli/session_resume_helper.py +10 -2
  306. claude_mpm/services/command_deployment_service.py +44 -26
  307. claude_mpm/services/delegation_detector.py +175 -0
  308. claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
  309. claude_mpm/services/diagnostics/checks/agent_sources_check.py +31 -1
  310. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  311. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  312. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  313. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  314. claude_mpm/services/diagnostics/models.py +14 -1
  315. claude_mpm/services/event_log.py +325 -0
  316. claude_mpm/services/git/git_operations_service.py +8 -8
  317. claude_mpm/services/hook_installer_service.py +77 -8
  318. claude_mpm/services/infrastructure/__init__.py +4 -0
  319. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  320. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  321. claude_mpm/services/monitor/daemon_manager.py +15 -4
  322. claude_mpm/services/monitor/management/lifecycle.py +15 -3
  323. claude_mpm/services/monitor/server.py +571 -11
  324. claude_mpm/services/pm_skills_deployer.py +884 -0
  325. claude_mpm/services/profile_manager.py +337 -0
  326. claude_mpm/services/skills/git_skill_source_manager.py +281 -20
  327. claude_mpm/services/skills/selective_skill_deployer.py +211 -46
  328. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  329. claude_mpm/services/skills_deployer.py +192 -70
  330. claude_mpm/services/socketio/dashboard_server.py +1 -0
  331. claude_mpm/services/socketio/event_normalizer.py +37 -6
  332. claude_mpm/services/socketio/handlers/hook.py +14 -7
  333. claude_mpm/services/socketio/server/core.py +262 -123
  334. claude_mpm/services/socketio/server/main.py +12 -4
  335. claude_mpm/skills/__init__.py +2 -1
  336. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  337. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  338. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  339. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  340. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  341. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  342. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  343. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  344. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  345. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  346. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  347. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  348. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  349. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  350. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  351. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  352. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  353. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  354. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  355. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  356. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  357. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  358. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  359. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  360. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  361. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  362. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  363. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  364. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  365. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  366. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  367. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  368. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  369. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  370. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  371. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  372. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  373. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  374. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  375. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  376. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  377. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  378. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  379. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  380. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  381. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  382. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  383. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  384. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  385. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  386. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  387. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  388. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  389. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  390. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  391. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  392. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  393. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  394. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  395. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  396. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  397. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  398. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  399. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  400. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  401. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  402. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  403. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  404. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  405. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  406. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  407. claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
  408. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  409. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  410. claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
  411. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  412. claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
  413. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  414. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  415. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  416. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  417. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  418. claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
  419. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  420. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  421. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  422. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  423. claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
  424. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  425. claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
  426. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  427. claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
  428. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  429. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  430. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  431. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  432. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  433. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  434. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  435. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  436. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  437. claude_mpm/skills/bundled/security-scanning.md +112 -0
  438. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  439. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  440. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  441. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  442. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  443. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  444. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  445. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  446. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  447. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  448. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  449. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  450. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  451. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  452. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  453. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  454. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  455. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  456. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  457. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  458. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  459. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  460. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  461. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  462. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  463. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  464. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  465. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  466. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  467. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  468. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  469. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  470. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  471. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  472. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  473. claude_mpm/skills/registry.py +295 -90
  474. claude_mpm/skills/skill_manager.py +98 -3
  475. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  476. claude_mpm/utils/agent_dependency_loader.py +115 -4
  477. claude_mpm/utils/agent_filters.py +1 -1
  478. claude_mpm/utils/migration.py +4 -4
  479. claude_mpm/utils/robust_installer.py +86 -21
  480. claude_mpm-5.6.34.dist-info/METADATA +393 -0
  481. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/RECORD +486 -145
  482. claude_mpm-5.4.22.dist-info/METADATA +0 -996
  483. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/WHEEL +0 -0
  484. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/entry_points.txt +0 -0
  485. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE +0 -0
  486. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  487. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,577 @@
1
+ """
2
+ Deployment Reconciliation Service - Simplified Deployment Model
3
+
4
+ This service implements the simplified deployment model where:
5
+ 1. Configuration has explicit lists: agents.enabled and skills.enabled
6
+ 2. On startup/sync, reconcile deployed state with configured state
7
+ 3. Deploy agents from cache to project .claude/ directories
8
+ 4. Remove agents/skills NOT in enabled lists
9
+
10
+ Key Principles:
11
+ - Explicit configuration over auto-discovery
12
+ - Clear reconciliation view (configured vs deployed)
13
+ - Simple cleanup of unneeded agents/skills
14
+ - Backward compatibility with empty enabled lists
15
+ """
16
+
17
+ import shutil
18
+ from dataclasses import dataclass
19
+ from pathlib import Path
20
+ from typing import Dict, List, Optional, Set
21
+
22
+ from claude_mpm.core.logging_utils import get_logger
23
+ from claude_mpm.core.unified_config import UnifiedConfig
24
+ from claude_mpm.core.unified_paths import get_path_manager
25
+
26
+ logger = get_logger(__name__)
27
+
28
+
29
+ @dataclass
30
+ class DeploymentResult:
31
+ """Result of deployment reconciliation."""
32
+
33
+ deployed: List[str] # Newly deployed
34
+ removed: List[str] # Removed (not in config)
35
+ unchanged: List[str] # Already deployed and still needed
36
+ errors: List[str] # Errors during reconciliation
37
+
38
+ @property
39
+ def success(self) -> bool:
40
+ """Whether reconciliation succeeded (no errors)."""
41
+ return len(self.errors) == 0
42
+
43
+
44
+ @dataclass
45
+ class ReconciliationState:
46
+ """Current state of agent/skill deployment."""
47
+
48
+ configured: Set[str] # IDs in config enabled list
49
+ deployed: Set[str] # IDs currently deployed
50
+ cached: Set[str] # IDs available in cache
51
+
52
+ @property
53
+ def to_deploy(self) -> Set[str]:
54
+ """Agents/skills that need deployment (in config but not deployed)."""
55
+ return self.configured - self.deployed
56
+
57
+ @property
58
+ def to_remove(self) -> Set[str]:
59
+ """Agents/skills that should be removed (deployed but not in config)."""
60
+ return self.deployed - self.configured
61
+
62
+ @property
63
+ def unchanged(self) -> Set[str]:
64
+ """Agents/skills already deployed and still needed."""
65
+ return self.configured & self.deployed
66
+
67
+
68
+ class DeploymentReconciler:
69
+ """
70
+ Reconciles configured agents/skills with deployed state.
71
+
72
+ This service implements the simplified deployment model:
73
+ 1. Read agents.enabled and skills.enabled from config
74
+ 2. Discover what's currently deployed in .claude/agents and .claude/skills
75
+ 3. Deploy missing agents/skills from cache
76
+ 4. Remove agents/skills not in enabled lists
77
+ """
78
+
79
+ def __init__(self, config: Optional[UnifiedConfig] = None):
80
+ """
81
+ Initialize reconciler.
82
+
83
+ Args:
84
+ config: UnifiedConfig instance (auto-loads if None)
85
+ """
86
+ self.config = config or self._load_config()
87
+ self.path_manager = get_path_manager()
88
+
89
+ def _load_config(self) -> UnifiedConfig:
90
+ """Load configuration from standard location."""
91
+ # For now, return default config
92
+ # TODO: Load from .claude-mpm/configuration.yaml
93
+ return UnifiedConfig()
94
+
95
+ def reconcile_agents(self, project_path: Optional[Path] = None) -> DeploymentResult:
96
+ """
97
+ Reconcile agent deployment with configuration.
98
+
99
+ Args:
100
+ project_path: Project directory (default: current directory)
101
+
102
+ Returns:
103
+ DeploymentResult with reconciliation summary
104
+ """
105
+ project_path = project_path or Path.cwd()
106
+ cache_dir = self.path_manager.get_cache_dir() / "agents"
107
+ deploy_dir = project_path / ".claude" / "agents"
108
+
109
+ # Get current state
110
+ state = self._get_agent_state(cache_dir, deploy_dir)
111
+
112
+ # Check backward compatibility
113
+ if not self.config.agents.enabled and self.config.agents.auto_discover:
114
+ logger.warning(
115
+ "agents.enabled is empty and auto_discover is True. "
116
+ "Consider migrating to explicit agent list. "
117
+ "Falling back to auto-discovery mode."
118
+ )
119
+ # In auto-discovery mode, don't remove anything
120
+ return DeploymentResult(
121
+ deployed=[], removed=[], unchanged=list(state.deployed), errors=[]
122
+ )
123
+
124
+ result = DeploymentResult(deployed=[], removed=[], unchanged=[], errors=[])
125
+
126
+ # Deploy missing agents
127
+ for agent_id in state.to_deploy:
128
+ if agent_id not in state.cached:
129
+ error_msg = f"Agent '{agent_id}' not found in cache. Run 'claude-mpm agents sync' first."
130
+ logger.warning(error_msg)
131
+ result.errors.append(error_msg)
132
+ continue
133
+
134
+ try:
135
+ self._deploy_agent(agent_id, cache_dir, deploy_dir)
136
+ result.deployed.append(agent_id)
137
+ logger.info(f"Deployed agent: {agent_id}")
138
+ except Exception as e:
139
+ error_msg = f"Failed to deploy agent '{agent_id}': {e}"
140
+ logger.error(error_msg)
141
+ result.errors.append(error_msg)
142
+
143
+ # Remove unneeded agents (only MPM agents, not user-created)
144
+ for agent_id in state.to_remove:
145
+ try:
146
+ if self._is_mpm_agent(deploy_dir, agent_id):
147
+ self._remove_agent(agent_id, deploy_dir)
148
+ result.removed.append(agent_id)
149
+ logger.info(f"Removed agent: {agent_id}")
150
+ else:
151
+ logger.debug(f"Skipping removal of user agent: {agent_id}")
152
+ result.unchanged.append(agent_id)
153
+ except Exception as e:
154
+ error_msg = f"Failed to remove agent '{agent_id}': {e}"
155
+ logger.error(error_msg)
156
+ result.errors.append(error_msg)
157
+
158
+ # Track unchanged agents
159
+ result.unchanged.extend(list(state.unchanged))
160
+
161
+ return result
162
+
163
+ def reconcile_skills(self, project_path: Optional[Path] = None) -> DeploymentResult:
164
+ """
165
+ Reconcile skill deployment with configuration.
166
+
167
+ This includes:
168
+ 1. Skills in skills.enabled list
169
+ 2. Skills required by enabled agents (if auto_detect_dependencies=True)
170
+
171
+ Args:
172
+ project_path: Project directory (default: current directory)
173
+
174
+ Returns:
175
+ DeploymentResult with reconciliation summary
176
+ """
177
+ project_path = project_path or Path.cwd()
178
+ cache_dir = self.path_manager.get_cache_dir() / "skills"
179
+ deploy_dir = project_path / ".claude" / "skills"
180
+
181
+ # Get configured skills (explicit + agent dependencies)
182
+ configured_skills = set(self.config.skills.enabled)
183
+
184
+ if self.config.skills.auto_detect_dependencies:
185
+ # Add skills required by enabled agents
186
+ agent_skill_deps = self._get_agent_skill_dependencies(
187
+ self.config.agents.enabled
188
+ )
189
+ configured_skills.update(agent_skill_deps)
190
+
191
+ # Get current state
192
+ state = ReconciliationState(
193
+ configured=configured_skills,
194
+ deployed=self._list_deployed_skills(deploy_dir),
195
+ cached=self._list_cached_skills(cache_dir),
196
+ )
197
+
198
+ result = DeploymentResult(deployed=[], removed=[], unchanged=[], errors=[])
199
+
200
+ # Deploy missing skills
201
+ for skill_id in state.to_deploy:
202
+ if skill_id not in state.cached:
203
+ error_msg = (
204
+ f"Skill '{skill_id}' not found in cache. Check skill sources."
205
+ )
206
+ logger.warning(error_msg)
207
+ result.errors.append(error_msg)
208
+ continue
209
+
210
+ try:
211
+ self._deploy_skill(skill_id, cache_dir, deploy_dir)
212
+ result.deployed.append(skill_id)
213
+ logger.info(f"Deployed skill: {skill_id}")
214
+ except Exception as e:
215
+ error_msg = f"Failed to deploy skill '{skill_id}': {e}"
216
+ logger.error(error_msg)
217
+ result.errors.append(error_msg)
218
+
219
+ # Remove unneeded skills (only MPM skills)
220
+ for skill_id in state.to_remove:
221
+ try:
222
+ if self._is_mpm_skill(deploy_dir, skill_id):
223
+ self._remove_skill(skill_id, deploy_dir)
224
+ result.removed.append(skill_id)
225
+ logger.info(f"Removed skill: {skill_id}")
226
+ else:
227
+ logger.debug(f"Skipping removal of user skill: {skill_id}")
228
+ result.unchanged.append(skill_id)
229
+ except Exception as e:
230
+ error_msg = f"Failed to remove skill '{skill_id}': {e}"
231
+ logger.error(error_msg)
232
+ result.errors.append(error_msg)
233
+
234
+ # Track unchanged skills
235
+ result.unchanged.extend(list(state.unchanged))
236
+
237
+ return result
238
+
239
+ def _get_agent_state(
240
+ self, cache_dir: Path, deploy_dir: Path
241
+ ) -> ReconciliationState:
242
+ """Get current agent deployment state."""
243
+ # Start with enabled agents
244
+ configured_agents = set(self.config.agents.enabled)
245
+
246
+ # Add required agents (cannot be disabled)
247
+ configured_agents.update(self.config.agents.required)
248
+
249
+ # Add universal agents if enabled
250
+ if self.config.agents.include_universal:
251
+ universal_agents = self._get_universal_agents(cache_dir)
252
+ configured_agents.update(universal_agents)
253
+
254
+ return ReconciliationState(
255
+ configured=configured_agents,
256
+ deployed=self._list_deployed_agents(deploy_dir),
257
+ cached=self._list_cached_agents(cache_dir),
258
+ )
259
+
260
+ def _get_universal_agents(self, cache_dir: Path) -> Set[str]:
261
+ """Get all agents with 'universal' toolchain/category."""
262
+ universal_agents = set()
263
+ if not cache_dir.exists():
264
+ return universal_agents
265
+
266
+ for agent_file in cache_dir.glob("**/*.md"):
267
+ try:
268
+ # Read frontmatter to check toolchain/category
269
+ content = agent_file.read_text(encoding="utf-8")
270
+
271
+ # Check for universal markers in frontmatter (within first 1000 chars)
272
+ frontmatter_section = content[:1000].lower()
273
+ if (
274
+ "toolchain: universal" in frontmatter_section
275
+ or "category: universal" in frontmatter_section
276
+ or "toolchain:\n - universal" in frontmatter_section
277
+ ):
278
+ universal_agents.add(agent_file.stem)
279
+ except Exception as e:
280
+ logger.debug(
281
+ f"Failed to check universal marker for {agent_file.name}: {e}"
282
+ )
283
+ continue
284
+
285
+ return universal_agents
286
+
287
+ def _list_deployed_agents(self, deploy_dir: Path) -> Set[str]:
288
+ """List agent IDs currently deployed."""
289
+ if not deploy_dir.exists():
290
+ return set()
291
+
292
+ agent_ids = set()
293
+ for agent_file in deploy_dir.glob("*.md"):
294
+ # Extract agent ID from filename (remove .md extension)
295
+ agent_id = agent_file.stem
296
+ agent_ids.add(agent_id)
297
+
298
+ return agent_ids
299
+
300
+ def _list_cached_agents(self, cache_dir: Path) -> Set[str]:
301
+ """List agent IDs available in cache."""
302
+ if not cache_dir.exists():
303
+ return set()
304
+
305
+ agent_ids = set()
306
+ for agent_file in cache_dir.glob("**/*.md"):
307
+ # Extract agent ID from filename
308
+ agent_id = agent_file.stem
309
+ agent_ids.add(agent_id)
310
+
311
+ return agent_ids
312
+
313
+ def _list_deployed_skills(self, deploy_dir: Path) -> Set[str]:
314
+ """List skill IDs currently deployed."""
315
+ if not deploy_dir.exists():
316
+ return set()
317
+
318
+ skill_ids = set()
319
+ for skill_file in deploy_dir.glob("*.md"):
320
+ skill_id = skill_file.stem
321
+ skill_ids.add(skill_id)
322
+
323
+ return skill_ids
324
+
325
+ def _list_cached_skills(self, cache_dir: Path) -> Set[str]:
326
+ """List skill IDs available in cache."""
327
+ if not cache_dir.exists():
328
+ return set()
329
+
330
+ skill_ids = set()
331
+ for skill_file in cache_dir.glob("**/*.md"):
332
+ skill_id = skill_file.stem
333
+ skill_ids.add(skill_id)
334
+
335
+ return skill_ids
336
+
337
+ def _deploy_agent(self, agent_id: str, cache_dir: Path, deploy_dir: Path) -> None:
338
+ """Deploy agent from cache to project directory."""
339
+ # Find agent file in cache
340
+ agent_file = self._find_file_in_cache(agent_id, cache_dir, "*.md")
341
+ if not agent_file:
342
+ raise FileNotFoundError(f"Agent file for '{agent_id}' not found in cache")
343
+
344
+ # Ensure deploy directory exists
345
+ deploy_dir.mkdir(parents=True, exist_ok=True)
346
+
347
+ # Copy agent file to deployment directory
348
+ dest_file = deploy_dir / agent_file.name
349
+ shutil.copy2(agent_file, dest_file)
350
+
351
+ def _deploy_skill(self, skill_id: str, cache_dir: Path, deploy_dir: Path) -> None:
352
+ """Deploy skill from cache to project directory."""
353
+ # Find skill file in cache
354
+ skill_file = self._find_file_in_cache(skill_id, cache_dir, "*.md")
355
+ if not skill_file:
356
+ raise FileNotFoundError(f"Skill file for '{skill_id}' not found in cache")
357
+
358
+ # Ensure deploy directory exists
359
+ deploy_dir.mkdir(parents=True, exist_ok=True)
360
+
361
+ # Copy skill file to deployment directory
362
+ dest_file = deploy_dir / skill_file.name
363
+ shutil.copy2(skill_file, dest_file)
364
+
365
+ def _remove_agent(self, agent_id: str, deploy_dir: Path) -> None:
366
+ """Remove deployed agent."""
367
+ agent_file = deploy_dir / f"{agent_id}.md"
368
+ if agent_file.exists():
369
+ agent_file.unlink()
370
+
371
+ def _remove_skill(self, skill_id: str, deploy_dir: Path) -> None:
372
+ """Remove deployed skill."""
373
+ skill_file = deploy_dir / f"{skill_id}.md"
374
+ if skill_file.exists():
375
+ skill_file.unlink()
376
+
377
+ def _is_mpm_agent(self, deploy_dir: Path, agent_id: str) -> bool:
378
+ """Check if agent is managed by MPM (not user-created)."""
379
+ agent_file = deploy_dir / f"{agent_id}.md"
380
+ if not agent_file.exists():
381
+ return False
382
+
383
+ try:
384
+ content = agent_file.read_text(encoding="utf-8")
385
+ # Check for MPM author markers
386
+ mpm_markers = [
387
+ "author: claude-mpm",
388
+ "author: 'claude-mpm'",
389
+ "author: anthropic",
390
+ ]
391
+ return any(marker in content.lower() for marker in mpm_markers)
392
+ except Exception as e:
393
+ logger.warning(f"Failed to check MPM marker for {agent_id}: {e}")
394
+ return False
395
+
396
+ def _is_mpm_skill(self, deploy_dir: Path, skill_id: str) -> bool:
397
+ """Check if skill is managed by MPM (not user-created)."""
398
+ skill_file = deploy_dir / f"{skill_id}.md"
399
+ if not skill_file.exists():
400
+ return False
401
+
402
+ try:
403
+ content = skill_file.read_text(encoding="utf-8")
404
+ # Check for MPM author markers
405
+ mpm_markers = [
406
+ "author: claude-mpm",
407
+ "author: 'claude-mpm'",
408
+ "author: anthropic",
409
+ ]
410
+ return any(marker in content.lower() for marker in mpm_markers)
411
+ except Exception as e:
412
+ logger.warning(f"Failed to check MPM marker for {skill_id}: {e}")
413
+ return False
414
+
415
+ def _find_file_in_cache(
416
+ self, item_id: str, cache_dir: Path, pattern: str
417
+ ) -> Optional[Path]:
418
+ """Find file in cache directory by ID pattern."""
419
+ # Try exact match first
420
+ exact_match = cache_dir / f"{item_id}.md"
421
+ if exact_match.exists():
422
+ return exact_match
423
+
424
+ # Search recursively
425
+ for file_path in cache_dir.glob(f"**/{item_id}.md"):
426
+ return file_path
427
+
428
+ return None
429
+
430
+ def _get_agent_skill_dependencies(self, agent_ids: List[str]) -> Set[str]:
431
+ """
432
+ Get skill dependencies for enabled agents.
433
+
434
+ This reads agent frontmatter to find required skills.
435
+
436
+ Args:
437
+ agent_ids: List of enabled agent IDs
438
+
439
+ Returns:
440
+ Set of skill IDs required by these agents
441
+ """
442
+ skill_deps = set()
443
+
444
+ # Get deployed agents directory
445
+ project_path = Path.cwd()
446
+ agents_dir = project_path / ".claude" / "agents"
447
+
448
+ if not agents_dir.exists():
449
+ logger.debug("No agents directory found, cannot extract skill dependencies")
450
+ return skill_deps
451
+
452
+ for agent_id in agent_ids:
453
+ agent_file = agents_dir / f"{agent_id}.md"
454
+ if not agent_file.exists():
455
+ logger.debug(
456
+ f"Agent file not found for {agent_id}, skipping skill dependency extraction"
457
+ )
458
+ continue
459
+
460
+ try:
461
+ # Parse frontmatter to get skills list
462
+ skills = self._parse_agent_skills_from_frontmatter(agent_file)
463
+ if skills:
464
+ logger.debug(f"Agent {agent_id} requires skills: {skills}")
465
+ skill_deps.update(skills)
466
+ except Exception as e:
467
+ logger.warning(f"Failed to parse skills from {agent_id}: {e}")
468
+
469
+ return skill_deps
470
+
471
+ def _parse_agent_skills_from_frontmatter(self, agent_file: Path) -> List[str]:
472
+ """
473
+ Parse skills list from agent frontmatter.
474
+
475
+ Expected frontmatter format:
476
+ ---
477
+ name: Python Engineer
478
+ skills:
479
+ - pytest
480
+ - git-workflow
481
+ ---
482
+
483
+ Args:
484
+ agent_file: Path to agent .md file
485
+
486
+ Returns:
487
+ List of skill IDs from frontmatter (empty if none found)
488
+ """
489
+ try:
490
+ import yaml
491
+ except ImportError:
492
+ logger.warning("PyYAML not installed, cannot parse agent frontmatter")
493
+ return []
494
+
495
+ try:
496
+ content = agent_file.read_text(encoding="utf-8")
497
+
498
+ # Check for frontmatter delimiters
499
+ if not content.startswith("---"):
500
+ return []
501
+
502
+ # Find end of frontmatter
503
+ end_marker = content.find("\n---\n", 4)
504
+ if end_marker == -1:
505
+ end_marker = content.find("\n---\r\n", 4)
506
+
507
+ if end_marker == -1:
508
+ logger.debug(
509
+ f"No valid frontmatter end marker found in {agent_file.name}"
510
+ )
511
+ return []
512
+
513
+ # Extract frontmatter YAML
514
+ frontmatter_yaml = content[4:end_marker]
515
+
516
+ # Parse YAML
517
+ frontmatter = yaml.safe_load(frontmatter_yaml)
518
+
519
+ if not frontmatter or not isinstance(frontmatter, dict):
520
+ return []
521
+
522
+ # Get skills list
523
+ skills = frontmatter.get("skills", [])
524
+ if isinstance(skills, list):
525
+ return [str(skill) for skill in skills]
526
+ logger.debug(
527
+ f"Skills field in {agent_file.name} is not a list: {type(skills)}"
528
+ )
529
+ return []
530
+
531
+ except yaml.YAMLError as e:
532
+ logger.warning(
533
+ f"Failed to parse YAML frontmatter in {agent_file.name}: {e}"
534
+ )
535
+ return []
536
+ except Exception as e:
537
+ logger.warning(
538
+ f"Unexpected error parsing frontmatter in {agent_file.name}: {e}"
539
+ )
540
+ return []
541
+
542
+ def get_reconciliation_view(
543
+ self, project_path: Optional[Path] = None
544
+ ) -> Dict[str, ReconciliationState]:
545
+ """
546
+ Get reconciliation view for agents and skills.
547
+
548
+ Args:
549
+ project_path: Project directory
550
+
551
+ Returns:
552
+ Dictionary with 'agents' and 'skills' reconciliation states
553
+ """
554
+ project_path = project_path or Path.cwd()
555
+
556
+ # Get agent state
557
+ agent_cache = self.path_manager.get_cache_dir() / "agents"
558
+ agent_deploy = project_path / ".claude" / "agents"
559
+ agent_state = self._get_agent_state(agent_cache, agent_deploy)
560
+
561
+ # Get skill state
562
+ skill_cache = self.path_manager.get_cache_dir() / "skills"
563
+ skill_deploy = project_path / ".claude" / "skills"
564
+
565
+ configured_skills = set(self.config.skills.enabled)
566
+ if self.config.skills.auto_detect_dependencies:
567
+ configured_skills.update(
568
+ self._get_agent_skill_dependencies(self.config.agents.enabled)
569
+ )
570
+
571
+ skill_state = ReconciliationState(
572
+ configured=configured_skills,
573
+ deployed=self._list_deployed_skills(skill_deploy),
574
+ cached=self._list_cached_skills(skill_cache),
575
+ )
576
+
577
+ return {"agents": agent_state, "skills": skill_state}
@@ -157,7 +157,9 @@ class LocalTemplateDeploymentService:
157
157
 
158
158
  # Add capabilities
159
159
  if template.capabilities:
160
- frontmatter["model"] = template.capabilities.get("model", "sonnet")
160
+ # Only include model if explicitly set (no default)
161
+ if "model" in template.capabilities:
162
+ frontmatter["model"] = template.capabilities["model"]
161
163
  tools = template.capabilities.get("tools", "*")
162
164
  if tools == "*":
163
165
  frontmatter["tools"] = "all"