claude-mpm 5.4.36__py3-none-any.whl → 5.4.62__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 (254) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +5 -0
  3. claude_mpm/agents/PM_INSTRUCTIONS.md +489 -177
  4. claude_mpm/agents/base_agent.json +1 -1
  5. claude_mpm/agents/frontmatter_validator.py +2 -2
  6. claude_mpm/cli/commands/configure_agent_display.py +12 -0
  7. claude_mpm/cli/commands/mpm_init/core.py +72 -0
  8. claude_mpm/cli/commands/profile.py +276 -0
  9. claude_mpm/cli/commands/skills.py +14 -18
  10. claude_mpm/cli/executor.py +10 -0
  11. claude_mpm/cli/parsers/base_parser.py +7 -0
  12. claude_mpm/cli/parsers/profile_parser.py +147 -0
  13. claude_mpm/cli/parsers/skills_parser.py +0 -6
  14. claude_mpm/cli/startup.py +433 -147
  15. claude_mpm/commands/mpm-config.md +13 -250
  16. claude_mpm/commands/mpm-doctor.md +9 -22
  17. claude_mpm/commands/mpm-help.md +5 -206
  18. claude_mpm/commands/mpm-init.md +81 -507
  19. claude_mpm/commands/mpm-monitor.md +15 -402
  20. claude_mpm/commands/mpm-organize.md +61 -441
  21. claude_mpm/commands/mpm-postmortem.md +6 -108
  22. claude_mpm/commands/mpm-session-resume.md +12 -363
  23. claude_mpm/commands/mpm-status.md +5 -69
  24. claude_mpm/commands/mpm-ticket-view.md +52 -495
  25. claude_mpm/commands/mpm-version.md +5 -107
  26. claude_mpm/core/optimized_startup.py +61 -0
  27. claude_mpm/core/shared/config_loader.py +3 -1
  28. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
  29. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
  30. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CWc5urbQ.js → 4TdZjIqw.js} +1 -1
  31. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
  32. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
  33. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
  34. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
  35. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
  36. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
  37. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
  38. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  39. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
  40. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
  41. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
  42. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
  43. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
  44. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
  45. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
  46. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
  47. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
  48. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
  49. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
  50. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
  51. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
  52. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  53. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
  54. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
  55. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  56. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
  57. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
  58. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
  59. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
  60. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
  61. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
  62. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
  63. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
  64. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
  65. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  66. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
  67. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
  68. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
  69. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
  70. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
  71. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
  72. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
  73. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
  74. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
  75. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
  76. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  77. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DjhvlsAc.js → NqQ1dWOy.js} +1 -1
  78. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
  79. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{N4qtv3Hx.js → Vzk33B_K.js} +1 -1
  80. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
  81. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
  82. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
  83. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
  84. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
  85. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
  86. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
  87. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
  88. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
  89. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.CAGBuiOw.js → 0.m1gL8KXf.js} +1 -1
  90. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
  91. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
  92. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
  93. claude_mpm/dashboard/static/svelte-build/index.html +10 -10
  94. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  95. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  96. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  97. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  98. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  99. claude_mpm/hooks/kuzu_memory_hook.py +5 -5
  100. claude_mpm/init.py +276 -0
  101. claude_mpm/services/agents/agent_builder.py +3 -3
  102. claude_mpm/services/agents/deployment/agent_deployment.py +22 -0
  103. claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -1
  104. claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
  105. claude_mpm/services/agents/deployment/agent_template_builder.py +37 -17
  106. claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
  107. claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
  108. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +149 -4
  109. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +47 -26
  110. claude_mpm/services/agents/git_source_manager.py +21 -2
  111. claude_mpm/services/agents/sources/git_source_sync_service.py +116 -5
  112. claude_mpm/services/monitor/management/lifecycle.py +7 -1
  113. claude_mpm/services/pm_skills_deployer.py +711 -0
  114. claude_mpm/services/profile_manager.py +337 -0
  115. claude_mpm/services/skills/git_skill_source_manager.py +148 -11
  116. claude_mpm/services/skills/selective_skill_deployer.py +97 -48
  117. claude_mpm/services/skills_deployer.py +161 -65
  118. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  119. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  120. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  121. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  122. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  123. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  124. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  125. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  126. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  127. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  128. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  129. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  130. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  131. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  132. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  133. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  134. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  135. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  136. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  137. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  138. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  139. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  140. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  141. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  142. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  143. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  144. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  145. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  146. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  147. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  148. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  149. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  150. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  151. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  152. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  153. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  154. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  155. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  156. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  157. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  158. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  159. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  160. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  161. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  162. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  163. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  164. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  165. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  166. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  167. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  168. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  169. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  170. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  171. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  172. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  173. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  174. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  175. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  176. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  177. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  178. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  179. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  180. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  181. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  182. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  183. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  184. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  185. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  186. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  187. claude_mpm/skills/bundled/pm/pm-delegation-patterns/SKILL.md +167 -0
  188. claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md +113 -0
  189. claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md +124 -0
  190. claude_mpm/skills/bundled/pm/pm-ticketing-integration/SKILL.md +154 -0
  191. claude_mpm/skills/bundled/pm/pm-verification-protocols/SKILL.md +198 -0
  192. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  193. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  194. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  195. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  196. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  197. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  198. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  199. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  200. claude_mpm/skills/bundled/security-scanning.md +112 -0
  201. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  202. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  203. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  204. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  205. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  206. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  207. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  208. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  209. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  210. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  211. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  212. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  213. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  214. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  215. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  216. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  217. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  218. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  219. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  220. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  221. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  222. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  223. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  224. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  225. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  226. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  227. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  228. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  229. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  230. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  231. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  232. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  233. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  234. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  235. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  236. claude_mpm/skills/skill_manager.py +98 -3
  237. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  238. {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/METADATA +3 -2
  239. {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/RECORD +244 -68
  240. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
  241. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
  242. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
  243. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
  244. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
  245. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
  246. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
  247. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
  248. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
  249. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  250. {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/WHEEL +0 -0
  251. {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/entry_points.txt +0 -0
  252. {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/licenses/LICENSE +0 -0
  253. {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  254. {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/top_level.txt +0 -0
claude_mpm/cli/startup.py CHANGED
@@ -59,6 +59,73 @@ def sync_hooks_on_startup(quiet: bool = False) -> bool:
59
59
  return False
60
60
 
61
61
 
62
+ def cleanup_legacy_agent_cache() -> None:
63
+ """Remove legacy hierarchical agent cache directories.
64
+
65
+ WHY: Old agent cache used category-based directory structure directly in cache.
66
+ New structure uses remote source paths. This cleanup prevents confusion from
67
+ stale cache directories.
68
+
69
+ Old structure (removed):
70
+ ~/.claude-mpm/cache/agents/engineer/
71
+ ~/.claude-mpm/cache/agents/ops/
72
+ ~/.claude-mpm/cache/agents/qa/
73
+ ...
74
+
75
+ New structure (kept):
76
+ ~/.claude-mpm/cache/agents/bobmatnyc/claude-mpm-agents/agents/...
77
+
78
+ DESIGN DECISION: Runs early in startup before agent deployment to ensure
79
+ clean cache state. Removes only known legacy directories to avoid deleting
80
+ user data.
81
+ """
82
+ import shutil
83
+ from pathlib import Path
84
+
85
+ from ..core.logger import get_logger
86
+
87
+ logger = get_logger("startup")
88
+
89
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
90
+ if not cache_dir.exists():
91
+ return
92
+
93
+ # Known legacy category directories (from old hierarchical structure)
94
+ legacy_dirs = [
95
+ "claude-mpm",
96
+ "documentation",
97
+ "engineer",
98
+ "ops",
99
+ "qa",
100
+ "security",
101
+ "universal",
102
+ ]
103
+
104
+ removed = []
105
+
106
+ # Remove legacy category directories
107
+ for dir_name in legacy_dirs:
108
+ legacy_path = cache_dir / dir_name
109
+ if legacy_path.exists() and legacy_path.is_dir():
110
+ try:
111
+ shutil.rmtree(legacy_path)
112
+ removed.append(dir_name)
113
+ except Exception as e:
114
+ logger.debug(f"Failed to remove legacy directory {dir_name}: {e}")
115
+
116
+ # Also remove stray BASE-AGENT.md in cache root
117
+ base_agent = cache_dir / "BASE-AGENT.md"
118
+ if base_agent.exists():
119
+ try:
120
+ base_agent.unlink()
121
+ removed.append("BASE-AGENT.md")
122
+ except Exception as e:
123
+ logger.debug(f"Failed to remove BASE-AGENT.md: {e}")
124
+
125
+ if removed:
126
+ logger.info(f"Cleaned up legacy agent cache: {', '.join(removed)}")
127
+
128
+
62
129
  def check_legacy_cache() -> None:
63
130
  """Deprecated: Legacy cache checking is no longer needed.
64
131
 
@@ -399,19 +466,48 @@ def sync_remote_agents_on_startup():
399
466
  block startup to ensure claude-mpm remains functional.
400
467
 
401
468
  Workflow:
402
- 1. Sync all enabled Git sources (download/cache files) - Phase 1 progress bar
403
- 2. Deploy agents to ~/.claude/agents/ - Phase 2 progress bar
404
- 3. Cleanup orphaned agents (ours but no longer deployed) - Phase 3
405
- 4. Log deployment results
469
+ 1. Cleanup legacy agent cache directories (if any)
470
+ 2. Sync all enabled Git sources (download/cache files) - Phase 1 progress bar
471
+ 3. Deploy agents to ~/.claude/agents/ - Phase 2 progress bar
472
+ 4. Cleanup orphaned agents (ours but no longer deployed) - Phase 3
473
+ 5. Log deployment results
406
474
  """
407
- # Check for legacy cache and warn user if found
475
+ # Cleanup legacy cache directories first (before syncing)
476
+ cleanup_legacy_agent_cache()
477
+
478
+ # DEPRECATED: Legacy warning - replaced by automatic cleanup above
408
479
  check_legacy_cache()
409
480
 
410
481
  try:
482
+ # Load active profile if configured
483
+ # Get project root (where .claude-mpm exists)
484
+ from pathlib import Path
485
+
486
+ from ..core.shared.config_loader import ConfigLoader
411
487
  from ..services.agents.deployment.agent_deployment import AgentDeploymentService
412
488
  from ..services.agents.startup_sync import sync_agents_on_startup
489
+ from ..services.profile_manager import ProfileManager
413
490
  from ..utils.progress import ProgressBar
414
491
 
492
+ project_root = Path.cwd()
493
+
494
+ profile_manager = ProfileManager(project_dir=project_root)
495
+ config_loader = ConfigLoader()
496
+ main_config = config_loader.load_main_config()
497
+ active_profile = main_config.get("active_profile")
498
+
499
+ if active_profile:
500
+ success = profile_manager.load_profile(active_profile)
501
+ if success:
502
+ summary = profile_manager.get_filtering_summary()
503
+ from ..core.logger import get_logger
504
+
505
+ logger = get_logger("cli")
506
+ logger.info(
507
+ f"Profile '{active_profile}' active: "
508
+ f"{summary['enabled_agents_count']} agents enabled"
509
+ )
510
+
415
511
  # Phase 1: Sync files from Git sources
416
512
  result = sync_agents_on_startup()
417
513
 
@@ -438,8 +534,55 @@ def sync_remote_agents_on_startup():
438
534
  # Phase 2: Deploy agents from cache to ~/.claude/agents/
439
535
  # This mirrors the skills deployment pattern (lines 371-407)
440
536
  try:
441
- # Initialize deployment service
442
- deployment_service = AgentDeploymentService()
537
+ # Initialize deployment service with profile-filtered configuration
538
+ from ..core.config import Config
539
+
540
+ deploy_config = None
541
+ if active_profile and profile_manager.active_profile:
542
+ # Create config with excluded agents based on profile
543
+ # Get all agents that should be excluded (not in enabled list)
544
+ from pathlib import Path
545
+
546
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
547
+ if cache_dir.exists():
548
+ # Find all agent files
549
+ # Supports both flat cache and {owner}/{repo}/agents/ structure
550
+ all_agent_files = [
551
+ f
552
+ for f in cache_dir.rglob("*.md")
553
+ if "/agents/" in str(f)
554
+ and f.stem.lower() != "base-agent"
555
+ and f.name.lower()
556
+ not in {"readme.md", "changelog.md", "contributing.md"}
557
+ ]
558
+
559
+ # Build exclusion list for agents not in profile
560
+ excluded_agents = []
561
+ for agent_file in all_agent_files:
562
+ agent_name = agent_file.stem
563
+ if not profile_manager.is_agent_enabled(agent_name):
564
+ excluded_agents.append(agent_name)
565
+
566
+ if excluded_agents:
567
+ # Get singleton config and update with profile settings
568
+ # BUGFIX: Config is a singleton that ignores dict parameter if already initialized.
569
+ # Creating Config({...}) doesn't store excluded_agents - use set() instead.
570
+ deploy_config = Config()
571
+ deploy_config.set(
572
+ "agent_deployment.excluded_agents", excluded_agents
573
+ )
574
+ deploy_config.set(
575
+ "agent_deployment.filter_non_mpm_agents", False
576
+ )
577
+ deploy_config.set("agent_deployment.case_sensitive", False)
578
+ deploy_config.set(
579
+ "agent_deployment.exclude_dependencies", False
580
+ )
581
+ logger.info(
582
+ f"Profile '{active_profile}': Excluding {len(excluded_agents)} agents from deployment"
583
+ )
584
+
585
+ deployment_service = AgentDeploymentService(config=deploy_config)
443
586
 
444
587
  # Count agents in cache to show accurate progress
445
588
  from pathlib import Path
@@ -461,12 +604,15 @@ def sync_remote_agents_on_startup():
461
604
  stale_dirs = set()
462
605
 
463
606
  for md_file in cache_dir.rglob("*.md"):
464
- # Stale cache files have multiple /agents/ in their path
465
- # Current: ~/.claude-mpm/cache/agents/engineer/...
466
- # (1 occurrence)
467
- # Old: ~/.claude-mpm/cache/agents/bobmatnyc/.../agents/...
468
- # (2+ occurrences)
469
- if str(md_file).count("/agents/") > 1:
607
+ # Stale cache files have multiple /agents/ in their path RELATIVE to cache_dir
608
+ # Current: cache/agents/bobmatnyc/claude-mpm-agents/agents/engineer/...
609
+ # (1 occurrence in relative path: /agents/)
610
+ # Old flat: cache/agents/engineer/...
611
+ # (0 occurrences in relative path - no repo structure)
612
+ # The issue: str(md_file).count("/agents/") counts BOTH cache/agents/ AND repo/agents/
613
+ # Fix: Count /agents/ in path RELATIVE to cache_dir (after cache/agents/)
614
+ relative_path = str(md_file.relative_to(cache_dir))
615
+ if relative_path.count("/agents/") > 1:
470
616
  # Track parent directory for cleanup
471
617
  # Extract subdirectory under cache/agents/
472
618
  # (e.g., "bobmatnyc")
@@ -540,8 +686,8 @@ def sync_remote_agents_on_startup():
540
686
  all_md_files = list(cache_dir.rglob("*.md"))
541
687
 
542
688
  # Filter to only agent files:
543
- # 1. Must have "/agents/" in path exactly ONCE
544
- # (current structure)
689
+ # 1. Must have "/agents/" in path (current structure supports
690
+ # both flat and {owner}/{repo}/agents/ patterns)
545
691
  # 2. Must not be in PM templates or doc files
546
692
  # 3. Exclude BASE-AGENT.md which is not a deployable agent
547
693
  # 4. Exclude build artifacts (dist/, build/, .cache/)
@@ -550,14 +696,10 @@ def sync_remote_agents_on_startup():
550
696
  f
551
697
  for f in all_md_files
552
698
  if (
553
- # Must be in an agent directory (from current
554
- # cache structure)
699
+ # Must be in an agent directory
700
+ # Supports: cache/agents/{category}/... (flat)
701
+ # Supports: cache/agents/{owner}/{repo}/agents/{category}/... (GitHub sync)
555
702
  "/agents/" in str(f)
556
- # NEW: Only ONE /agents/ in path (excludes old
557
- # nested repos)
558
- # This prevents counting old caches like
559
- # bobmatnyc/claude-mpm-agents/agents/...
560
- and str(f).count("/agents/") == 1
561
703
  # Exclude PM templates, doc files, and BASE-AGENT
562
704
  and f.name.lower() not in pm_templates
563
705
  and f.name.lower() not in doc_files
@@ -579,6 +721,7 @@ def sync_remote_agents_on_startup():
579
721
  target_dir=deploy_target,
580
722
  force_rebuild=False, # Only deploy if versions differ
581
723
  deployment_mode="update", # Version-aware updates
724
+ config=deploy_config, # Pass config to respect profile filtering
582
725
  )
583
726
 
584
727
  # Get actual counts from deployment result (reflects configured agents)
@@ -719,13 +862,16 @@ def sync_remote_skills_on_startup():
719
862
  1. Sync all enabled Git sources (download/cache files) - Phase 1 progress bar
720
863
  2. Scan deployed agents for skill requirements → save to configuration.yaml
721
864
  3. Resolve which skills to deploy (user_defined vs agent_referenced)
722
- 4. Deploy resolved skills to ~/.claude/skills/ - Phase 2 progress bar
723
- 5. Log deployment results with source indication
865
+ 4. Apply profile filtering if active
866
+ 5. Deploy resolved skills to ~/.claude/skills/ - Phase 2 progress bar
867
+ 6. Log deployment results with source indication
724
868
  """
725
869
  try:
726
870
  from pathlib import Path
727
871
 
728
872
  from ..config.skill_sources import SkillSourceConfiguration
873
+ from ..core.shared.config_loader import ConfigLoader
874
+ from ..services.profile_manager import ProfileManager
729
875
  from ..services.skills.git_skill_source_manager import GitSkillSourceManager
730
876
  from ..services.skills.selective_skill_deployer import (
731
877
  get_required_skills_from_agents,
@@ -734,6 +880,28 @@ def sync_remote_skills_on_startup():
734
880
  )
735
881
  from ..utils.progress import ProgressBar
736
882
 
883
+ # Load active profile if configured
884
+ # Get project root (where .claude-mpm exists)
885
+ project_root = Path.cwd()
886
+
887
+ profile_manager = ProfileManager(project_dir=project_root)
888
+ config_loader = ConfigLoader()
889
+ main_config = config_loader.load_main_config()
890
+ active_profile = main_config.get("active_profile")
891
+
892
+ if active_profile:
893
+ success = profile_manager.load_profile(active_profile)
894
+ if success:
895
+ from ..core.logger import get_logger
896
+
897
+ logger = get_logger("cli")
898
+ summary = profile_manager.get_filtering_summary()
899
+ logger.info(
900
+ f"Profile '{active_profile}' active: "
901
+ f"{summary['enabled_skills_count']} skills enabled, "
902
+ f"{summary['disabled_patterns_count']} patterns disabled"
903
+ )
904
+
737
905
  config = SkillSourceConfiguration()
738
906
  manager = GitSkillSourceManager(config)
739
907
 
@@ -822,108 +990,191 @@ def sync_remote_skills_on_startup():
822
990
 
823
991
  # Phase 2: Scan agents and save to configuration.yaml
824
992
  # This step populates configuration.yaml with agent-referenced skills
825
- if results["synced_count"] > 0:
826
- agents_dir = Path.cwd() / ".claude" / "agents"
827
-
828
- # Scan agents for skill requirements
829
- agent_skills = get_required_skills_from_agents(agents_dir)
830
-
831
- # Save to project-level configuration.yaml
832
- project_config_path = Path.cwd() / ".claude-mpm" / "configuration.yaml"
833
- save_agent_skills_to_config(list(agent_skills), project_config_path)
993
+ # CRITICAL: Always scan agents to populate agent_referenced, even when using cached skills.
994
+ # Without this, skill_filter=None causes ALL skills to deploy and NO cleanup to run.
995
+ agents_dir = Path.cwd() / ".claude" / "agents"
996
+
997
+ # Scan agents for skill requirements (ALWAYS run to ensure cleanup works)
998
+ agent_skills = get_required_skills_from_agents(agents_dir)
999
+ logger.info(
1000
+ f"Agent scan found {len(agent_skills)} unique skills across deployed agents"
1001
+ )
834
1002
 
835
- # Phase 3: Resolve which skills to deploy (user_defined or agent_referenced)
836
- skills_to_deploy, skill_source = get_skills_to_deploy(project_config_path)
1003
+ # Save to project-level configuration.yaml
1004
+ project_config_path = Path.cwd() / ".claude-mpm" / "configuration.yaml"
1005
+ save_agent_skills_to_config(list(agent_skills), project_config_path)
1006
+ logger.debug(
1007
+ f"Saved {len(agent_skills)} agent-referenced skills to {project_config_path}"
1008
+ )
837
1009
 
838
- # Get all skills to determine counts
839
- all_skills = manager.get_all_skills()
840
- total_skill_count = len(all_skills)
1010
+ # Phase 3: Resolve which skills to deploy (user_defined or agent_referenced)
1011
+ skills_to_deploy, skill_source = get_skills_to_deploy(project_config_path)
841
1012
 
842
- # Determine skill count based on resolution
843
- skill_count = (
844
- len(skills_to_deploy) if skills_to_deploy else total_skill_count
1013
+ # CRITICAL DEBUG: Log deployment resolution to diagnose cleanup issues
1014
+ if skills_to_deploy:
1015
+ logger.info(
1016
+ f"Resolved {len(skills_to_deploy)} skills from {skill_source} (cleanup will run)"
1017
+ )
1018
+ else:
1019
+ logger.warning(
1020
+ f"No skills resolved from {skill_source} - will deploy ALL skills WITHOUT cleanup! "
1021
+ f"This may indicate agent_referenced is empty in configuration.yaml."
845
1022
  )
846
1023
 
847
- if skill_count > 0:
848
- # Deploy skills with resolved filter
849
- # Deploy to project directory (like agents), not user directory
850
- deployment_result = manager.deploy_skills(
851
- target_dir=Path.cwd() / ".claude" / "skills",
852
- force=False,
853
- skill_filter=set(skills_to_deploy) if skills_to_deploy else None,
1024
+ # Phase 4: Apply profile filtering if active
1025
+ if active_profile and profile_manager.active_profile:
1026
+ # Filter skills based on profile
1027
+ if skills_to_deploy:
1028
+ # Filter the resolved skill list
1029
+ original_count = len(skills_to_deploy)
1030
+ filtered_skills = [
1031
+ skill
1032
+ for skill in skills_to_deploy
1033
+ if profile_manager.is_skill_enabled(skill)
1034
+ ]
1035
+ filtered_count = original_count - len(filtered_skills)
1036
+
1037
+ # SAFEGUARD: Warn if all skills were filtered out (misconfiguration)
1038
+ if not filtered_skills and original_count > 0:
1039
+ logger.warning(
1040
+ f"Profile '{active_profile}' filtered ALL {original_count} skills. "
1041
+ f"This may indicate a naming mismatch in the profile."
1042
+ )
1043
+ elif filtered_count > 0:
1044
+ logger.info(
1045
+ f"Profile '{active_profile}' filtered {filtered_count} skills "
1046
+ f"({len(filtered_skills)} remaining)"
1047
+ )
1048
+
1049
+ skills_to_deploy = filtered_skills
1050
+ skill_source = f"{skill_source} + profile filtered"
1051
+ else:
1052
+ # No explicit skill list - filter from all available
1053
+ all_skills = manager.get_all_skills()
1054
+ filtered_skills = [
1055
+ skill["name"]
1056
+ for skill in all_skills
1057
+ if profile_manager.is_skill_enabled(skill["name"])
1058
+ ]
1059
+ skills_to_deploy = filtered_skills
1060
+ skill_source = "profile filtered"
1061
+ logger.info(
1062
+ f"Profile '{active_profile}': "
1063
+ f"{len(filtered_skills)} skills enabled from {len(all_skills)} available"
854
1064
  )
855
1065
 
856
- # Get actual counts from deployment result
857
- deployed = deployment_result.get("deployed_count", 0)
858
- skipped = deployment_result.get("skipped_count", 0)
859
- filtered = deployment_result.get("filtered_count", 0)
860
- total_available = deployed + skipped
1066
+ # Get all skills to determine counts
1067
+ all_skills = manager.get_all_skills()
1068
+ total_skill_count = len(all_skills)
861
1069
 
862
- # Only show progress bar if there are skills to deploy
863
- if total_available > 0:
864
- deploy_progress = ProgressBar(
865
- total=total_available,
866
- prefix="Deploying skill directories",
867
- show_percentage=True,
868
- show_counter=True,
869
- )
870
- # Update progress bar to completion
871
- deploy_progress.update(total_available)
872
- else:
873
- # No skills to deploy - create dummy progress for message only
874
- deploy_progress = ProgressBar(
875
- total=1,
876
- prefix="Deploying skill directories",
877
- show_percentage=False,
878
- show_counter=False,
879
- )
880
- deploy_progress.update(1)
1070
+ # Determine skill count based on resolution
1071
+ skill_count = (
1072
+ len(skills_to_deploy) if skills_to_deploy else total_skill_count
1073
+ )
1074
+
1075
+ if skill_count > 0:
1076
+ # Deploy skills with resolved filter
1077
+ # Deploy ONLY to project directory (not user-level)
1078
+ # DESIGN DECISION: Project-level deployment keeps skills isolated per project,
1079
+ # avoiding pollution of user's global ~/.claude/skills/ directory.
1080
+
1081
+ # Deploy to project-local directory with cleanup
1082
+ deployment_result = manager.deploy_skills(
1083
+ target_dir=Path.cwd() / ".claude" / "skills",
1084
+ force=False,
1085
+ # CRITICAL FIX: Empty list should mean "deploy no skills", not "deploy all"
1086
+ # When skills_to_deploy is [], we want skill_filter=set() NOT skill_filter=None
1087
+ # None means "no filtering" (deploy all), empty set means "filter to nothing"
1088
+ skill_filter=set(skills_to_deploy) if skills_to_deploy is not None else None,
1089
+ )
881
1090
 
882
- # Show total available skills (deployed + already existing)
883
- # Include source indication (user_defined vs agent_referenced)
884
- # Note: total_skill_count is from cache, total_available is what's deployed/needed
885
- source_label = (
886
- "user override" if skill_source == "user_defined" else "from agents"
1091
+ # REMOVED: User-level deployment (lines 1068-1074)
1092
+ # Reason: Skills should be project-specific, not user-global.
1093
+ # Claude Code can read from project-level .claude/skills/ directory.
1094
+
1095
+ # Get actual counts from deployment result (use project-local for display)
1096
+ deployed = deployment_result.get("deployed_count", 0)
1097
+ skipped = deployment_result.get("skipped_count", 0)
1098
+ filtered = deployment_result.get("filtered_count", 0)
1099
+ removed = deployment_result.get("removed_count", 0)
1100
+ total_available = deployed + skipped
1101
+
1102
+ # Only show progress bar if there are skills to deploy
1103
+ if total_available > 0:
1104
+ deploy_progress = ProgressBar(
1105
+ total=total_available,
1106
+ prefix="Deploying skill directories",
1107
+ show_percentage=True,
1108
+ show_counter=True,
1109
+ )
1110
+ # Update progress bar to completion
1111
+ deploy_progress.update(total_available)
1112
+ else:
1113
+ # No skills to deploy - create dummy progress for message only
1114
+ deploy_progress = ProgressBar(
1115
+ total=1,
1116
+ prefix="Deploying skill directories",
1117
+ show_percentage=False,
1118
+ show_counter=False,
887
1119
  )
1120
+ deploy_progress.update(1)
1121
+
1122
+ # Show total available skills (deployed + already existing)
1123
+ # Include source indication (user_defined vs agent_referenced)
1124
+ # Note: total_skill_count is from cache, total_available is what's deployed/needed
1125
+ source_label = (
1126
+ "user override" if skill_source == "user_defined" else "from agents"
1127
+ )
888
1128
 
1129
+ # Build finish message with cleanup info
1130
+ if deployed > 0 or removed > 0:
1131
+ parts = []
889
1132
  if deployed > 0:
890
- if filtered > 0:
891
- deploy_progress.finish(
892
- f"Complete: {deployed} new, {skipped} unchanged "
893
- f"({total_available} {source_label}, {filtered} files in cache)"
894
- )
895
- else:
896
- deploy_progress.finish(
897
- f"Complete: {deployed} new, {skipped} unchanged "
898
- f"({total_available} skills {source_label} from {total_skill_count} files in cache)"
899
- )
900
- elif filtered > 0:
901
- # Skills filtered means agents require fewer skills than available
1133
+ parts.append(f"{deployed} new")
1134
+ if skipped > 0:
1135
+ parts.append(f"{skipped} unchanged")
1136
+ if removed > 0:
1137
+ parts.append(f"{removed} removed")
1138
+
1139
+ status = ", ".join(parts)
1140
+
1141
+ if filtered > 0:
902
1142
  deploy_progress.finish(
903
- f"No skills needed ({source_label}, {total_skill_count} files in cache)"
1143
+ f"Complete: {status} ({total_available} {source_label}, {filtered} files in cache)"
904
1144
  )
905
1145
  else:
906
1146
  deploy_progress.finish(
907
- f"Complete: {total_available} skills {source_label} "
908
- f"({total_skill_count} files in cache)"
1147
+ f"Complete: {status} ({total_available} skills {source_label} from {total_skill_count} files in cache)"
909
1148
  )
1149
+ elif filtered > 0:
1150
+ # Skills filtered means agents require fewer skills than available
1151
+ deploy_progress.finish(
1152
+ f"No skills needed ({source_label}, {total_skill_count} files in cache)"
1153
+ )
1154
+ else:
1155
+ # No changes - all skills already deployed
1156
+ msg = f"Complete: {total_available} skills {source_label}"
1157
+ if removed > 0:
1158
+ msg += f", {removed} removed"
1159
+ msg += f" ({total_skill_count} files in cache)"
1160
+ deploy_progress.finish(msg)
1161
+
1162
+ # Log deployment errors if any
1163
+ from ..core.logger import get_logger
910
1164
 
911
- # Log deployment errors if any
912
- from ..core.logger import get_logger
913
-
914
- logger = get_logger("cli")
1165
+ logger = get_logger("cli")
915
1166
 
916
- errors = deployment_result.get("errors", [])
917
- if errors:
918
- logger.warning(
919
- f"Skill deployment completed with {len(errors)} errors: {errors}"
920
- )
1167
+ errors = deployment_result.get("errors", [])
1168
+ if errors:
1169
+ logger.warning(
1170
+ f"Skill deployment completed with {len(errors)} errors: {errors}"
1171
+ )
921
1172
 
922
- # Log sync errors if any
923
- if results["failed_count"] > 0:
924
- logger.warning(
925
- f"Skill sync completed with {results['failed_count']} failures"
926
- )
1173
+ # Log sync errors if any
1174
+ if results["failed_count"] > 0:
1175
+ logger.warning(
1176
+ f"Skill sync completed with {results['failed_count']} failures"
1177
+ )
927
1178
 
928
1179
  except Exception as e:
929
1180
  # Non-critical - log but don't fail startup
@@ -1006,7 +1257,7 @@ def show_agent_summary():
1006
1257
  # Display summary if we have agents
1007
1258
  if installed_count > 0 or available_count > 0:
1008
1259
  print(
1009
- f"✓ Agents: {installed_count} deployed / {available_count} cached",
1260
+ f"✓ Agents: {installed_count} deployed / {max(0, available_count - installed_count)} cached",
1010
1261
  flush=True,
1011
1262
  )
1012
1263
 
@@ -1023,61 +1274,64 @@ def show_skill_summary():
1023
1274
  Display skill availability summary on startup.
1024
1275
 
1025
1276
  WHY: Users should see at a glance how many skills are deployed and available
1026
- from collections, similar to the agent summary.
1277
+ from cache, similar to the agent summary showing "X deployed / Y cached".
1278
+
1279
+ DESIGN DECISION: Fast, non-blocking check that counts skills from:
1280
+ - Deployed skills: PROJECT-level .claude/skills/ directory
1281
+ - Cached skills: ~/.claude-mpm/cache/skills/ directory (from remote sources)
1027
1282
 
1028
- DESIGN DECISION: Fast, non-blocking check that counts skills from deployment
1029
- directory and collection repos. Shows "X installed (Y available)" format.
1283
+ Shows format: "✓ Skills: X deployed / Y cached"
1030
1284
  Failures are silent to avoid blocking startup.
1031
1285
  """
1032
1286
  try:
1033
1287
  from pathlib import Path
1034
1288
 
1035
- # Count deployed skills (installed)
1036
- skills_dir = Path.home() / ".claude" / "skills"
1037
- installed_count = 0
1038
- if skills_dir.exists():
1289
+ # Count deployed skills (PROJECT-level, not user-level)
1290
+ project_skills_dir = Path.cwd() / ".claude" / "skills"
1291
+ deployed_count = 0
1292
+ if project_skills_dir.exists():
1039
1293
  # Count directories with SKILL.md (excludes collection repos)
1040
1294
  # Exclude collection directories (obra-superpowers, etc.)
1041
1295
  skill_dirs = [
1042
1296
  d
1043
- for d in skills_dir.iterdir()
1297
+ for d in project_skills_dir.iterdir()
1044
1298
  if d.is_dir()
1045
1299
  and (d / "SKILL.md").exists()
1046
1300
  and not (d / ".git").exists() # Exclude collection repos
1047
1301
  ]
1048
- installed_count = len(skill_dirs)
1302
+ deployed_count = len(skill_dirs)
1049
1303
 
1050
- # Count available skills in collections
1051
- available_count = 0
1052
- if skills_dir.exists():
1053
- # Scan all collection directories (those with .git)
1054
- for collection_dir in skills_dir.iterdir():
1055
- if (
1056
- not collection_dir.is_dir()
1057
- or not (collection_dir / ".git").exists()
1058
- ):
1304
+ # Count cached skills (from remote sources, not deployed yet)
1305
+ # This matches the agent summary pattern: deployed vs cached
1306
+ cache_dir = Path.home() / ".claude-mpm" / "cache" / "skills"
1307
+ cached_count = 0
1308
+ if cache_dir.exists():
1309
+ # Scan all repository directories in cache
1310
+ # Cache structure: ~/.claude-mpm/cache/skills/{owner}/{repo}/...
1311
+ for repo_dir in cache_dir.rglob("*"):
1312
+ if not repo_dir.is_dir():
1059
1313
  continue
1060
1314
 
1061
- # Count skill directories in this collection
1315
+ # Count skill directories (those with SKILL.md)
1062
1316
  # Skills can be nested in: skills/category/skill-name/SKILL.md
1063
1317
  # or in flat structure: skill-name/SKILL.md
1064
- for root, dirs, files in os.walk(collection_dir):
1318
+ for root, dirs, files in os.walk(repo_dir):
1065
1319
  if "SKILL.md" in files:
1066
- # Exclude build artifacts and hidden directories (within the collection)
1067
- # Get relative path from collection_dir to avoid excluding based on .claude parent
1320
+ # Exclude build artifacts and hidden directories
1068
1321
  root_path = Path(root)
1069
- relative_parts = root_path.relative_to(collection_dir).parts
1070
1322
  if not any(
1071
1323
  part.startswith(".")
1072
1324
  or part in ["dist", "build", "__pycache__"]
1073
- for part in relative_parts
1325
+ for part in root_path.parts
1074
1326
  ):
1075
- available_count += 1
1327
+ cached_count += 1
1076
1328
 
1077
- # Display summary if we have skills
1078
- if installed_count > 0 or available_count > 0:
1329
+ # Display summary using agent summary format: "X deployed / Y cached"
1330
+ # Only show non-deployed cached skills (subtract deployed from cached)
1331
+ non_deployed_cached = max(0, cached_count - deployed_count)
1332
+ if deployed_count > 0 or non_deployed_cached > 0:
1079
1333
  print(
1080
- f"✓ Skills: {installed_count} installed ({available_count} available)",
1334
+ f"✓ Skills: {deployed_count} deployed / {non_deployed_cached} cached",
1081
1335
  flush=True,
1082
1336
  )
1083
1337
 
@@ -1089,6 +1343,45 @@ def show_skill_summary():
1089
1343
  logger.debug(f"Failed to generate skill summary: {e}")
1090
1344
 
1091
1345
 
1346
+ def verify_and_show_pm_skills():
1347
+ """Verify PM skills and display status.
1348
+
1349
+ WHY: PM skills are essential for PM agent operation.
1350
+ Shows deployment status and auto-deploys if missing.
1351
+ """
1352
+ try:
1353
+ from pathlib import Path
1354
+
1355
+ from ..services.pm_skills_deployer import PMSkillsDeployerService
1356
+
1357
+ deployer = PMSkillsDeployerService()
1358
+ project_dir = Path.cwd()
1359
+
1360
+ result = deployer.verify_pm_skills(project_dir)
1361
+
1362
+ if result.verified:
1363
+ # Show verified status
1364
+ print(f"✓ PM skills: {result.skill_count} verified", flush=True)
1365
+ else:
1366
+ # Auto-deploy if missing
1367
+ print("Deploying PM skills...", end="", flush=True)
1368
+ deploy_result = deployer.deploy_pm_skills(project_dir)
1369
+ if deploy_result.success:
1370
+ total = len(deploy_result.deployed) + len(deploy_result.skipped)
1371
+ print(f"\r✓ PM skills: {total} deployed" + " " * 20, flush=True)
1372
+ else:
1373
+ print("\r⚠ PM skills: deployment failed" + " " * 20, flush=True)
1374
+
1375
+ except ImportError:
1376
+ # PM skills deployer not available - skip silently
1377
+ pass
1378
+ except Exception as e:
1379
+ from ..core.logger import get_logger
1380
+
1381
+ logger = get_logger("cli")
1382
+ logger.debug(f"PM skills verification failed: {e}")
1383
+
1384
+
1092
1385
  def auto_install_chrome_devtools_on_startup():
1093
1386
  """
1094
1387
  Automatically install chrome-devtools-mcp on startup if enabled.
@@ -1163,6 +1456,7 @@ def run_background_services():
1163
1456
  sync_remote_skills_on_startup() # Override layer: Git-based skills (takes precedence)
1164
1457
  discover_and_link_runtime_skills() # Discovery: user-added skills
1165
1458
  show_skill_summary() # Display skill counts after deployment
1459
+ verify_and_show_pm_skills() # PM skills verification and status
1166
1460
 
1167
1461
  deploy_output_style_on_startup()
1168
1462
 
@@ -1296,18 +1590,10 @@ def verify_mcp_gateway_startup():
1296
1590
  DESIGN DECISION: This is non-blocking - failures are logged but don't prevent
1297
1591
  startup to ensure claude-mpm remains functional even if MCP gateway has issues.
1298
1592
  """
1299
- # Quick verification of MCP services installation
1300
- try:
1301
- from ..core.logger import get_logger
1302
- from ..services.mcp_service_verifier import verify_mcp_services_on_startup
1303
-
1304
- logger = get_logger("mcp_verify")
1305
- all_ok, message = verify_mcp_services_on_startup()
1306
- if not all_ok:
1307
- logger.warning(message)
1308
- except Exception:
1309
- # Non-critical - continue with startup
1310
- pass
1593
+ # DISABLED: MCP service verification removed - Claude Code handles MCP natively
1594
+ # The previous check warned about missing MCP services, but users should configure
1595
+ # MCP servers through Claude Code's native MCP management, not through claude-mpm.
1596
+ # See: https://docs.anthropic.com/en/docs/claude-code/mcp
1311
1597
 
1312
1598
  try:
1313
1599
  import asyncio