claude-mpm 5.4.85__py3-none-any.whl → 5.6.76__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +8 -5
  3. claude_mpm/agents/{CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md → CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md} +14 -6
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +109 -706
  5. claude_mpm/agents/WORKFLOW.md +2 -0
  6. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  7. claude_mpm/auth/__init__.py +35 -0
  8. claude_mpm/auth/callback_server.py +328 -0
  9. claude_mpm/auth/models.py +104 -0
  10. claude_mpm/auth/oauth_manager.py +266 -0
  11. claude_mpm/auth/providers/__init__.py +12 -0
  12. claude_mpm/auth/providers/base.py +165 -0
  13. claude_mpm/auth/providers/google.py +261 -0
  14. claude_mpm/auth/token_storage.py +252 -0
  15. claude_mpm/cli/commands/autotodos.py +566 -0
  16. claude_mpm/cli/commands/commander.py +216 -0
  17. claude_mpm/cli/commands/hook_errors.py +60 -60
  18. claude_mpm/cli/commands/mcp.py +29 -17
  19. claude_mpm/cli/commands/mcp_command_router.py +39 -0
  20. claude_mpm/cli/commands/mcp_service_commands.py +304 -0
  21. claude_mpm/cli/commands/monitor.py +2 -2
  22. claude_mpm/cli/commands/mpm_init/core.py +2 -2
  23. claude_mpm/cli/commands/oauth.py +481 -0
  24. claude_mpm/cli/commands/run.py +35 -3
  25. claude_mpm/cli/commands/skill_source.py +51 -2
  26. claude_mpm/cli/commands/skills.py +5 -3
  27. claude_mpm/cli/executor.py +128 -16
  28. claude_mpm/cli/helpers.py +1 -1
  29. claude_mpm/cli/parsers/base_parser.py +84 -1
  30. claude_mpm/cli/parsers/commander_parser.py +116 -0
  31. claude_mpm/cli/parsers/mcp_parser.py +79 -0
  32. claude_mpm/cli/parsers/oauth_parser.py +165 -0
  33. claude_mpm/cli/parsers/run_parser.py +10 -0
  34. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  35. claude_mpm/cli/parsers/skills_parser.py +5 -0
  36. claude_mpm/cli/startup.py +345 -40
  37. claude_mpm/cli/startup_display.py +76 -7
  38. claude_mpm/cli/startup_logging.py +2 -2
  39. claude_mpm/cli/startup_migrations.py +236 -0
  40. claude_mpm/cli/utils.py +7 -3
  41. claude_mpm/commander/__init__.py +78 -0
  42. claude_mpm/commander/adapters/__init__.py +60 -0
  43. claude_mpm/commander/adapters/auggie.py +260 -0
  44. claude_mpm/commander/adapters/base.py +288 -0
  45. claude_mpm/commander/adapters/claude_code.py +392 -0
  46. claude_mpm/commander/adapters/codex.py +237 -0
  47. claude_mpm/commander/adapters/communication.py +366 -0
  48. claude_mpm/commander/adapters/example_usage.py +310 -0
  49. claude_mpm/commander/adapters/mpm.py +389 -0
  50. claude_mpm/commander/adapters/registry.py +204 -0
  51. claude_mpm/commander/api/__init__.py +16 -0
  52. claude_mpm/commander/api/app.py +121 -0
  53. claude_mpm/commander/api/errors.py +133 -0
  54. claude_mpm/commander/api/routes/__init__.py +8 -0
  55. claude_mpm/commander/api/routes/events.py +184 -0
  56. claude_mpm/commander/api/routes/inbox.py +171 -0
  57. claude_mpm/commander/api/routes/messages.py +148 -0
  58. claude_mpm/commander/api/routes/projects.py +271 -0
  59. claude_mpm/commander/api/routes/sessions.py +226 -0
  60. claude_mpm/commander/api/routes/work.py +296 -0
  61. claude_mpm/commander/api/schemas.py +186 -0
  62. claude_mpm/commander/chat/__init__.py +7 -0
  63. claude_mpm/commander/chat/cli.py +149 -0
  64. claude_mpm/commander/chat/commands.py +124 -0
  65. claude_mpm/commander/chat/repl.py +1957 -0
  66. claude_mpm/commander/config.py +51 -0
  67. claude_mpm/commander/config_loader.py +115 -0
  68. claude_mpm/commander/core/__init__.py +10 -0
  69. claude_mpm/commander/core/block_manager.py +325 -0
  70. claude_mpm/commander/core/response_manager.py +323 -0
  71. claude_mpm/commander/daemon.py +603 -0
  72. claude_mpm/commander/env_loader.py +59 -0
  73. claude_mpm/commander/events/__init__.py +26 -0
  74. claude_mpm/commander/events/manager.py +392 -0
  75. claude_mpm/commander/frameworks/__init__.py +12 -0
  76. claude_mpm/commander/frameworks/base.py +233 -0
  77. claude_mpm/commander/frameworks/claude_code.py +58 -0
  78. claude_mpm/commander/frameworks/mpm.py +57 -0
  79. claude_mpm/commander/git/__init__.py +5 -0
  80. claude_mpm/commander/git/worktree_manager.py +212 -0
  81. claude_mpm/commander/inbox/__init__.py +16 -0
  82. claude_mpm/commander/inbox/dedup.py +128 -0
  83. claude_mpm/commander/inbox/inbox.py +224 -0
  84. claude_mpm/commander/inbox/models.py +70 -0
  85. claude_mpm/commander/instance_manager.py +868 -0
  86. claude_mpm/commander/llm/__init__.py +6 -0
  87. claude_mpm/commander/llm/openrouter_client.py +167 -0
  88. claude_mpm/commander/llm/summarizer.py +70 -0
  89. claude_mpm/commander/memory/__init__.py +45 -0
  90. claude_mpm/commander/memory/compression.py +347 -0
  91. claude_mpm/commander/memory/embeddings.py +230 -0
  92. claude_mpm/commander/memory/entities.py +310 -0
  93. claude_mpm/commander/memory/example_usage.py +290 -0
  94. claude_mpm/commander/memory/integration.py +325 -0
  95. claude_mpm/commander/memory/search.py +381 -0
  96. claude_mpm/commander/memory/store.py +657 -0
  97. claude_mpm/commander/models/__init__.py +18 -0
  98. claude_mpm/commander/models/events.py +127 -0
  99. claude_mpm/commander/models/project.py +162 -0
  100. claude_mpm/commander/models/work.py +214 -0
  101. claude_mpm/commander/parsing/__init__.py +20 -0
  102. claude_mpm/commander/parsing/extractor.py +132 -0
  103. claude_mpm/commander/parsing/output_parser.py +270 -0
  104. claude_mpm/commander/parsing/patterns.py +100 -0
  105. claude_mpm/commander/persistence/__init__.py +11 -0
  106. claude_mpm/commander/persistence/event_store.py +274 -0
  107. claude_mpm/commander/persistence/state_store.py +403 -0
  108. claude_mpm/commander/persistence/work_store.py +164 -0
  109. claude_mpm/commander/polling/__init__.py +13 -0
  110. claude_mpm/commander/polling/event_detector.py +104 -0
  111. claude_mpm/commander/polling/output_buffer.py +49 -0
  112. claude_mpm/commander/polling/output_poller.py +153 -0
  113. claude_mpm/commander/project_session.py +268 -0
  114. claude_mpm/commander/proxy/__init__.py +12 -0
  115. claude_mpm/commander/proxy/formatter.py +89 -0
  116. claude_mpm/commander/proxy/output_handler.py +191 -0
  117. claude_mpm/commander/proxy/relay.py +155 -0
  118. claude_mpm/commander/registry.py +410 -0
  119. claude_mpm/commander/runtime/__init__.py +10 -0
  120. claude_mpm/commander/runtime/executor.py +191 -0
  121. claude_mpm/commander/runtime/monitor.py +346 -0
  122. claude_mpm/commander/session/__init__.py +6 -0
  123. claude_mpm/commander/session/context.py +81 -0
  124. claude_mpm/commander/session/manager.py +59 -0
  125. claude_mpm/commander/tmux_orchestrator.py +362 -0
  126. claude_mpm/commander/web/__init__.py +1 -0
  127. claude_mpm/commander/work/__init__.py +30 -0
  128. claude_mpm/commander/work/executor.py +207 -0
  129. claude_mpm/commander/work/queue.py +405 -0
  130. claude_mpm/commander/workflow/__init__.py +27 -0
  131. claude_mpm/commander/workflow/event_handler.py +241 -0
  132. claude_mpm/commander/workflow/notifier.py +146 -0
  133. claude_mpm/commands/mpm-config.md +8 -0
  134. claude_mpm/commands/mpm-doctor.md +8 -0
  135. claude_mpm/commands/mpm-help.md +8 -0
  136. claude_mpm/commands/mpm-init.md +8 -0
  137. claude_mpm/commands/mpm-monitor.md +8 -0
  138. claude_mpm/commands/mpm-organize.md +8 -0
  139. claude_mpm/commands/mpm-postmortem.md +8 -0
  140. claude_mpm/commands/mpm-session-resume.md +9 -1
  141. claude_mpm/commands/mpm-status.md +8 -0
  142. claude_mpm/commands/mpm-ticket-view.md +8 -0
  143. claude_mpm/commands/mpm-version.md +8 -0
  144. claude_mpm/commands/mpm.md +8 -0
  145. claude_mpm/config/agent_presets.py +8 -7
  146. claude_mpm/config/skill_sources.py +16 -0
  147. claude_mpm/constants.py +5 -0
  148. claude_mpm/core/claude_runner.py +152 -0
  149. claude_mpm/core/config.py +35 -22
  150. claude_mpm/core/config_constants.py +74 -9
  151. claude_mpm/core/constants.py +56 -12
  152. claude_mpm/core/hook_manager.py +53 -4
  153. claude_mpm/core/interactive_session.py +5 -4
  154. claude_mpm/core/logger.py +26 -9
  155. claude_mpm/core/logging_utils.py +39 -13
  156. claude_mpm/core/network_config.py +148 -0
  157. claude_mpm/core/oneshot_session.py +7 -6
  158. claude_mpm/core/output_style_manager.py +52 -12
  159. claude_mpm/core/socketio_pool.py +47 -15
  160. claude_mpm/core/unified_config.py +10 -6
  161. claude_mpm/core/unified_paths.py +68 -80
  162. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
  163. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
  164. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Cs_tUR18.js → 1WZnGYqX.js} +1 -1
  165. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CDuw-vjf.js → 67pF3qNn.js} +1 -1
  166. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bTOqqlTd.js → 6RxdMKe4.js} +1 -1
  167. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DwBR2MJi.js → 8cZrfX0h.js} +1 -1
  168. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{ZGh7QtNv.js → 9a6T2nm-.js} +1 -1
  169. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D9lljYKQ.js → B443AUzu.js} +1 -1
  170. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{RJiighC3.js → B8AwtY2H.js} +1 -1
  171. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uuIeMWc-.js → BF15LAsF.js} +1 -1
  172. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D3k0OPJN.js → BRcwIQNr.js} +1 -1
  173. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CyWMqx4W.js → BV6nKitt.js} +1 -1
  174. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CiIAseT4.js → BViJ8lZt.js} +5 -5
  175. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CBBdVcY8.js → BcQ-Q0FE.js} +1 -1
  176. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BovzEFCE.js → Bpyvgze_.js} +1 -1
  177. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
  178. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
  179. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{eNVUfhuA.js → C3rbW_a-.js} +1 -1
  180. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{GYwsonyD.js → C8WYN38h.js} +1 -1
  181. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BIF9m_hv.js → C9I8FlXH.js} +1 -1
  182. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B0uc0UOD.js → CIQcWgO2.js} +3 -3
  183. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Be7GpZd6.js → CIctN7YN.js} +1 -1
  184. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Bh0LDWpI.js → CKrS_JZW.js} +2 -2
  185. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DUrLdbGD.js → CR6P9C4A.js} +1 -1
  186. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7xVLGWV.js → CRRR9MD_.js} +1 -1
  187. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
  188. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dhb8PKl3.js → CSXtMOf0.js} +1 -1
  189. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BPYeabCQ.js → CT-sbxSk.js} +1 -1
  190. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{sQeU3Y1z.js → CWm6DJsp.js} +1 -1
  191. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CnA0NrzZ.js → CpqQ1Kzn.js} +1 -1
  192. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4B-KCzX.js → D2nGpDRe.js} +1 -1
  193. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DGkLK5U1.js → D9iCMida.js} +1 -1
  194. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BofRWZRR.js → D9ykgMoY.js} +1 -1
  195. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DmxopI1J.js → DL2Ldur1.js} +1 -1
  196. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C30mlcqg.js → DPfltzjH.js} +1 -1
  197. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Vzk33B_K.js → DR8nis88.js} +2 -2
  198. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DI7hHRFL.js → DUliQN2b.js} +1 -1
  199. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4JcI4KD.js → DXlhR01x.js} +1 -1
  200. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bT1r9zLR.js → D_lyTybS.js} +1 -1
  201. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DZX00Y4g.js → DngoTTgh.js} +1 -1
  202. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzZX-COe.js → DqkmHtDC.js} +1 -1
  203. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7RN905-.js → DsDh8EYs.js} +1 -1
  204. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DLVjFsZ3.js → DypDmXgd.js} +1 -1
  205. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{iEWssX7S.js → IPYC-LnN.js} +1 -1
  206. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
  207. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DaimHw_p.js → JpevfAFt.js} +1 -1
  208. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DY1XQ8fi.js → R8CEIRAd.js} +1 -1
  209. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dle-35c7.js → Zxy7qc-l.js} +2 -2
  210. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
  211. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C_Usid8X.js → qtd3IeO4.js} +2 -2
  212. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzeYkLYB.js → ulBFON_C.js} +2 -2
  213. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Cfqx1Qun.js → wQVh1CoA.js} +1 -1
  214. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/{app.D6-I5TpK.js → app.Dr7t0z2J.js} +2 -2
  215. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
  216. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.m1gL8KXf.js → 0.RgBboRvH.js} +1 -1
  217. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{1.CgNOuw-d.js → 1.DG-KkbDf.js} +1 -1
  218. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
  219. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
  220. claude_mpm/dashboard/static/svelte-build/index.html +9 -9
  221. claude_mpm/experimental/cli_enhancements.py +2 -1
  222. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  223. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  224. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
  225. claude_mpm/hooks/claude_hooks/event_handlers.py +466 -136
  226. claude_mpm/hooks/claude_hooks/hook_handler.py +204 -104
  227. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  228. claude_mpm/hooks/claude_hooks/installer.py +291 -59
  229. claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
  230. claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
  231. claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
  232. claude_mpm/hooks/claude_hooks/services/connection_manager.py +41 -26
  233. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
  234. claude_mpm/hooks/claude_hooks/services/container.py +326 -0
  235. claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
  236. claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
  237. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
  238. claude_mpm/hooks/session_resume_hook.py +89 -1
  239. claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
  240. claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
  241. claude_mpm/init.py +22 -15
  242. claude_mpm/mcp/__init__.py +9 -0
  243. claude_mpm/mcp/google_workspace_server.py +610 -0
  244. claude_mpm/scripts/claude-hook-handler.sh +46 -19
  245. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  246. claude_mpm/services/agents/agent_selection_service.py +2 -2
  247. claude_mpm/services/agents/cache_git_manager.py +1 -1
  248. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +3 -0
  249. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  250. claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
  251. claude_mpm/services/cli/__init__.py +3 -0
  252. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  253. claude_mpm/services/cli/session_resume_helper.py +10 -2
  254. claude_mpm/services/command_deployment_service.py +44 -26
  255. claude_mpm/services/delegation_detector.py +175 -0
  256. claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
  257. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  258. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  259. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  260. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  261. claude_mpm/services/diagnostics/models.py +14 -1
  262. claude_mpm/services/event_log.py +325 -0
  263. claude_mpm/services/hook_installer_service.py +77 -8
  264. claude_mpm/services/infrastructure/__init__.py +4 -0
  265. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  266. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  267. claude_mpm/services/mcp_config_manager.py +99 -19
  268. claude_mpm/services/mcp_service_registry.py +294 -0
  269. claude_mpm/services/monitor/daemon_manager.py +15 -4
  270. claude_mpm/services/monitor/management/lifecycle.py +8 -2
  271. claude_mpm/services/monitor/server.py +111 -16
  272. claude_mpm/services/pm_skills_deployer.py +261 -87
  273. claude_mpm/services/skills/git_skill_source_manager.py +130 -10
  274. claude_mpm/services/skills/selective_skill_deployer.py +142 -16
  275. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  276. claude_mpm/services/skills_deployer.py +31 -5
  277. claude_mpm/services/socketio/handlers/hook.py +14 -7
  278. claude_mpm/services/socketio/server/main.py +12 -4
  279. claude_mpm/skills/__init__.py +2 -1
  280. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  281. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  282. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  283. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  284. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  285. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  286. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  287. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  288. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  289. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  290. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  291. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  292. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  293. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  294. claude_mpm/skills/bundled/pm/{pm-teaching-mode → mpm-teaching-mode}/SKILL.md +2 -2
  295. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  296. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  297. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  298. claude_mpm/skills/registry.py +295 -90
  299. claude_mpm/skills/skill_manager.py +4 -4
  300. claude_mpm-5.6.76.dist-info/METADATA +416 -0
  301. {claude_mpm-5.4.85.dist-info → claude_mpm-5.6.76.dist-info}/RECORD +312 -175
  302. {claude_mpm-5.4.85.dist-info → claude_mpm-5.6.76.dist-info}/WHEEL +1 -1
  303. {claude_mpm-5.4.85.dist-info → claude_mpm-5.6.76.dist-info}/entry_points.txt +2 -0
  304. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +0 -1
  305. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +0 -1
  306. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +0 -1
  307. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +0 -24
  308. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +0 -1
  309. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +0 -1
  310. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +0 -323
  311. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +0 -1
  312. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +0 -1
  313. claude_mpm-5.4.85.dist-info/METADATA +0 -1023
  314. /claude_mpm/skills/bundled/pm/{pm-bug-reporting/pm-bug-reporting.md → mpm-bug-reporting/SKILL.md} +0 -0
  315. /claude_mpm/skills/bundled/pm/{pm-delegation-patterns → mpm-delegation-patterns}/SKILL.md +0 -0
  316. /claude_mpm/skills/bundled/pm/{pm-git-file-tracking → mpm-git-file-tracking}/SKILL.md +0 -0
  317. /claude_mpm/skills/bundled/pm/{pm-pr-workflow → mpm-pr-workflow}/SKILL.md +0 -0
  318. /claude_mpm/skills/bundled/pm/{pm-ticketing-integration → mpm-ticketing-integration}/SKILL.md +0 -0
  319. /claude_mpm/skills/bundled/pm/{pm-verification-protocols → mpm-verification-protocols}/SKILL.md +0 -0
  320. {claude_mpm-5.4.85.dist-info → claude_mpm-5.6.76.dist-info}/licenses/LICENSE +0 -0
  321. {claude_mpm-5.4.85.dist-info → claude_mpm-5.6.76.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  322. {claude_mpm-5.4.85.dist-info → claude_mpm-5.6.76.dist-info}/top_level.txt +0 -0
@@ -76,6 +76,10 @@ def add_skill_source_subparser(subparsers) -> argparse.ArgumentParser:
76
76
  dest="skip_test",
77
77
  help="Skip immediate testing (not recommended)",
78
78
  )
79
+ add_parser.add_argument(
80
+ "--token",
81
+ help="GitHub token or env var reference (e.g., ghp_xxx or $PRIVATE_TOKEN)",
82
+ )
79
83
 
80
84
  # Remove repository
81
85
  remove_parser = skill_source_subparsers.add_parser(
@@ -167,6 +167,11 @@ def add_skills_subparser(subparsers) -> argparse.ArgumentParser:
167
167
  action="store_true",
168
168
  help="Force redeployment of already deployed skills",
169
169
  )
170
+ deploy_github_parser.add_argument(
171
+ "--all",
172
+ action="store_true",
173
+ help="Deploy all available skills, not just agent-referenced ones",
174
+ )
170
175
 
171
176
  # List available GitHub skills
172
177
  list_available_parser = skills_subparsers.add_parser(
claude_mpm/cli/startup.py CHANGED
@@ -13,6 +13,49 @@ import sys
13
13
  from pathlib import Path
14
14
 
15
15
 
16
+ def cleanup_user_level_hooks() -> bool:
17
+ """Remove stale user-level hooks directory.
18
+
19
+ WHY: claude-mpm previously deployed hooks to ~/.claude/hooks/claude-mpm/
20
+ (user-level). This is now deprecated in favor of project-level hooks
21
+ configured in .claude/settings.local.json. Stale user-level hooks can
22
+ cause conflicts and confusion.
23
+
24
+ DESIGN DECISION: Runs early in startup, before project hook sync.
25
+ Non-blocking - failures are logged at debug level but don't prevent startup.
26
+
27
+ Returns:
28
+ bool: True if hooks were cleaned up, False if none found or cleanup failed
29
+ """
30
+ import shutil
31
+
32
+ user_hooks_dir = Path.home() / ".claude" / "hooks" / "claude-mpm"
33
+
34
+ if not user_hooks_dir.exists():
35
+ return False
36
+
37
+ try:
38
+ from ..core.logger import get_logger
39
+
40
+ logger = get_logger("startup")
41
+ logger.debug(f"Removing stale user-level hooks directory: {user_hooks_dir}")
42
+
43
+ shutil.rmtree(user_hooks_dir)
44
+
45
+ logger.debug("User-level hooks cleanup complete")
46
+ return True
47
+ except Exception as e:
48
+ # Non-critical - log but don't fail startup
49
+ try:
50
+ from ..core.logger import get_logger
51
+
52
+ logger = get_logger("startup")
53
+ logger.debug(f"Failed to cleanup user-level hooks (non-fatal): {e}")
54
+ except Exception: # nosec B110
55
+ pass # Avoid any errors in error handling
56
+ return False
57
+
58
+
16
59
  def sync_hooks_on_startup(quiet: bool = False) -> bool:
17
60
  """Ensure hooks are up-to-date on startup.
18
61
 
@@ -20,7 +63,12 @@ def sync_hooks_on_startup(quiet: bool = False) -> bool:
20
63
  Reinstalling hooks ensures the hook format matches the current code.
21
64
 
22
65
  DESIGN DECISION: Shows brief status message on success for user awareness.
23
- Failures are logged but don't prevent startup to ensure claude-mpm remains functional.
66
+ Failures are logged but don't prevent startup to ensure claude-mpm
67
+ remains functional.
68
+
69
+ Workflow:
70
+ 1. Cleanup stale user-level hooks (~/.claude/hooks/claude-mpm/)
71
+ 2. Reinstall project-level hooks to .claude/settings.local.json
24
72
 
25
73
  Args:
26
74
  quiet: If True, suppress all output (used internally)
@@ -28,28 +76,45 @@ def sync_hooks_on_startup(quiet: bool = False) -> bool:
28
76
  Returns:
29
77
  bool: True if hooks were synced successfully, False otherwise
30
78
  """
79
+ is_tty = not quiet and sys.stdout.isatty()
80
+
81
+ # Step 1: Cleanup stale user-level hooks first
82
+ if is_tty:
83
+ print("Cleaning user-level hooks...", end=" ", flush=True)
84
+
85
+ cleaned = cleanup_user_level_hooks()
86
+
87
+ if is_tty:
88
+ if cleaned:
89
+ print("✓")
90
+ else:
91
+ print("(none found)")
92
+
93
+ # Step 2: Install project-level hooks
31
94
  try:
32
95
  from ..hooks.claude_hooks.installer import HookInstaller
33
96
 
34
97
  installer = HookInstaller()
35
98
 
36
99
  # Show brief status (hooks sync is fast)
37
- if not quiet:
38
- print("Syncing Claude Code hooks...", end=" ", flush=True)
100
+ if is_tty:
101
+ print("Installing project hooks...", end=" ", flush=True)
39
102
 
40
103
  # Reinstall hooks (force=True ensures update)
41
104
  success = installer.install_hooks(force=True)
42
105
 
43
- if not quiet:
106
+ if is_tty:
44
107
  if success:
45
- print("✓")
108
+ # Count hooks from settings file
109
+ hook_count = _count_installed_hooks(installer.settings_file)
110
+ print(f"{hook_count} hooks configured ✓")
46
111
  else:
47
112
  print("(skipped)")
48
113
 
49
114
  return success
50
115
 
51
116
  except Exception as e:
52
- if not quiet:
117
+ if is_tty:
53
118
  print("(error)")
54
119
  # Log but don't fail startup
55
120
  from ..core.logger import get_logger
@@ -59,6 +124,30 @@ def sync_hooks_on_startup(quiet: bool = False) -> bool:
59
124
  return False
60
125
 
61
126
 
127
+ def _count_installed_hooks(settings_file: Path) -> int:
128
+ """Count the number of hook event types configured in settings.
129
+
130
+ Args:
131
+ settings_file: Path to the settings.local.json file
132
+
133
+ Returns:
134
+ int: Number of hook event types configured (e.g., 7 for all events)
135
+ """
136
+ import json
137
+
138
+ try:
139
+ if not settings_file.exists():
140
+ return 0
141
+
142
+ with settings_file.open() as f:
143
+ settings = json.load(f)
144
+
145
+ hooks = settings.get("hooks", {})
146
+ return len(hooks)
147
+ except Exception:
148
+ return 0
149
+
150
+
62
151
  def cleanup_legacy_agent_cache() -> None:
63
152
  """Remove legacy hierarchical agent cache directories.
64
153
 
@@ -161,7 +250,25 @@ def setup_early_environment(argv):
161
250
  # CRITICAL: Suppress ALL logging by default
162
251
  # This catches all loggers (claude_mpm.*, service.*, framework_loader, etc.)
163
252
  # This will be overridden by setup_mcp_server_logging() based on user preference
164
- logging.getLogger().setLevel(logging.CRITICAL + 1) # Root logger catches everything
253
+ root_logger = logging.getLogger()
254
+ root_logger.setLevel(logging.CRITICAL + 1) # Root logger catches everything
255
+ root_logger.handlers = [] # Remove any handlers
256
+
257
+ # Also suppress common module loggers explicitly to prevent handler leakage
258
+ for logger_name in [
259
+ "claude_mpm",
260
+ "path_resolver",
261
+ "file_loader",
262
+ "framework_loader",
263
+ "service",
264
+ "instruction_loader",
265
+ "agent_loader",
266
+ "startup",
267
+ ]:
268
+ module_logger = logging.getLogger(logger_name)
269
+ module_logger.setLevel(logging.CRITICAL + 1)
270
+ module_logger.handlers = []
271
+ module_logger.propagate = False
165
272
 
166
273
  # Process argv
167
274
  if argv is None:
@@ -178,9 +285,15 @@ def should_skip_background_services(args, processed_argv):
178
285
  """
179
286
  Determine if background services should be skipped for this command.
180
287
 
181
- WHY: Some commands (help, version, configure, doctor) don't need
288
+ WHY: Some commands (help, version, configure, doctor, oauth) don't need
182
289
  background services and should start faster.
183
290
 
291
+ NOTE: Headless mode with --resume skips background services because:
292
+ - Each claude-mpm call is a NEW process (orchestrators like Vibe Kanban)
293
+ - First message (no --resume): Run full init (hooks, agents, skills)
294
+ - Follow-up messages (with --resume): Skip init to avoid latency
295
+ - Hooks/agents/skills are already deployed from the first message
296
+
184
297
  Args:
185
298
  args: Parsed arguments
186
299
  processed_argv: Processed command line arguments
@@ -188,10 +301,30 @@ def should_skip_background_services(args, processed_argv):
188
301
  Returns:
189
302
  bool: True if background services should be skipped
190
303
  """
304
+ # Headless mode with --resume: skip init for follow-up messages
305
+ # Each orchestrator call is a new process, so we need to skip init
306
+ # on follow-ups to avoid re-running hooks/agents/skills sync every time
307
+ is_headless = getattr(args, "headless", False)
308
+ has_resume = getattr(args, "resume", False) or "--resume" in (processed_argv or [])
309
+
310
+ if is_headless and has_resume:
311
+ return True
312
+
191
313
  skip_commands = ["--version", "-v", "--help", "-h"]
192
314
  return any(cmd in (processed_argv or sys.argv[1:]) for cmd in skip_commands) or (
193
315
  hasattr(args, "command")
194
- and args.command in ["info", "doctor", "config", "mcp", "configure"]
316
+ and args.command
317
+ in [
318
+ "info",
319
+ "doctor",
320
+ "config",
321
+ "mcp",
322
+ "configure",
323
+ "hook-errors",
324
+ "autotodos",
325
+ "commander",
326
+ "oauth",
327
+ ]
195
328
  )
196
329
 
197
330
 
@@ -252,11 +385,13 @@ def deploy_bundled_skills():
252
385
  if deployment_result.get("deployed"):
253
386
  # Show simple feedback for deployed skills
254
387
  deployed_count = len(deployment_result["deployed"])
255
- print(f"✓ Bundled skills ready ({deployed_count} deployed)", flush=True)
388
+ if sys.stdout.isatty():
389
+ print(f"✓ Bundled skills ready ({deployed_count} deployed)", flush=True)
256
390
  logger.info(f"Skills: Deployed {deployed_count} skill(s)")
257
391
  elif not deployment_result.get("errors"):
258
392
  # No deployment needed, skills already present
259
- print("✓ Bundled skills ready", flush=True)
393
+ if sys.stdout.isatty():
394
+ print("✓ Bundled skills ready", flush=True)
260
395
 
261
396
  if deployment_result.get("errors"):
262
397
  logger.warning(
@@ -290,7 +425,8 @@ def discover_and_link_runtime_skills():
290
425
 
291
426
  discover_skills()
292
427
  # Show simple success feedback
293
- print("✓ Runtime skills linked", flush=True)
428
+ if sys.stdout.isatty():
429
+ print("✓ Runtime skills linked", flush=True)
294
430
  except Exception as e:
295
431
  # Import logger here to avoid circular imports
296
432
  from ..core.logger import get_logger
@@ -315,7 +451,7 @@ def deploy_output_style_on_startup():
315
451
  Deploys all styles:
316
452
  - claude-mpm.md (professional mode)
317
453
  - claude-mpm-teacher.md (teaching mode)
318
- - claude-mpm-founders.md (founders mode)
454
+ - claude-mpm-research.md (research mode - for codebase analysis)
319
455
  """
320
456
  try:
321
457
  from ..core.output_style_manager import OutputStyleManager
@@ -345,7 +481,8 @@ def deploy_output_style_on_startup():
345
481
 
346
482
  if all_up_to_date:
347
483
  # Show feedback that output styles are ready
348
- print("✓ Output styles ready", flush=True)
484
+ if sys.stdout.isatty():
485
+ print("✓ Output styles ready", flush=True)
349
486
  return
350
487
 
351
488
  # Deploy all styles using the manager
@@ -355,7 +492,8 @@ def deploy_output_style_on_startup():
355
492
  deployed_count = sum(1 for success in results.values() if success)
356
493
 
357
494
  if deployed_count > 0:
358
- print(f"✓ Output styles deployed ({deployed_count} styles)", flush=True)
495
+ if sys.stdout.isatty():
496
+ print(f"✓ Output styles deployed ({deployed_count} styles)", flush=True)
359
497
  else:
360
498
  # Deployment failed - log but don't fail startup
361
499
  from ..core.logger import get_logger
@@ -450,6 +588,94 @@ def _cleanup_orphaned_agents(deploy_target: Path, deployed_agents: list[str]) ->
450
588
  return removed_count
451
589
 
452
590
 
591
+ def _save_deployment_state_after_reconciliation(
592
+ agent_result, project_path: Path
593
+ ) -> None:
594
+ """Save deployment state after reconciliation to prevent duplicate deployment.
595
+
596
+ WHY: After perform_startup_reconciliation() deploys agents to .claude/agents/,
597
+ we need to save a deployment state file so that ClaudeRunner.setup_agents()
598
+ can detect agents are already deployed and skip redundant deployment.
599
+
600
+ This prevents the "✓ Deployed 31 native agents" duplicate deployment that
601
+ occurs when setup_agents() doesn't know reconciliation already ran.
602
+
603
+ Args:
604
+ agent_result: DeploymentResult from perform_startup_reconciliation()
605
+ project_path: Project root directory
606
+
607
+ DESIGN DECISION: Use same state file format as ClaudeRunner._save_deployment_state()
608
+ Located at: .claude-mpm/cache/deployment_state.json
609
+
610
+ State file format:
611
+ {
612
+ "version": "5.6.13",
613
+ "agent_count": 15,
614
+ "deployment_hash": "sha256:...",
615
+ "deployed_at": 1234567890.123
616
+ }
617
+ """
618
+ import hashlib
619
+ import json
620
+ import time
621
+
622
+ from ..core.logger import get_logger
623
+
624
+ logger = get_logger("cli")
625
+
626
+ try:
627
+ # Get version from package
628
+ from claude_mpm import __version__
629
+
630
+ # Path to state file (matches ClaudeRunner._get_deployment_state_path())
631
+ state_file = project_path / ".claude-mpm" / "cache" / "deployment_state.json"
632
+ agents_dir = project_path / ".claude" / "agents"
633
+
634
+ # Count deployed agents
635
+ if agents_dir.exists():
636
+ agent_count = len(list(agents_dir.glob("*.md")))
637
+ else:
638
+ agent_count = 0
639
+
640
+ # Calculate deployment hash (matches ClaudeRunner._calculate_deployment_hash())
641
+ # CRITICAL: Must match exact hash algorithm used in ClaudeRunner
642
+ # Hashes filename + file content (not mtime) for consistency
643
+ deployment_hash = ""
644
+ if agents_dir.exists():
645
+ agent_files = sorted(agents_dir.glob("*.md"))
646
+ hash_obj = hashlib.sha256()
647
+ for agent_file in agent_files:
648
+ # Include filename and content in hash (matches ClaudeRunner)
649
+ hash_obj.update(agent_file.name.encode())
650
+ try:
651
+ hash_obj.update(agent_file.read_bytes())
652
+ except Exception as e:
653
+ logger.debug(f"Error reading {agent_file} for hash: {e}")
654
+
655
+ deployment_hash = hash_obj.hexdigest()
656
+
657
+ # Create state data
658
+ state_data = {
659
+ "version": __version__,
660
+ "agent_count": agent_count,
661
+ "deployment_hash": deployment_hash,
662
+ "deployed_at": time.time(),
663
+ }
664
+
665
+ # Ensure directory exists
666
+ state_file.parent.mkdir(parents=True, exist_ok=True)
667
+
668
+ # Write state file
669
+ state_file.write_text(json.dumps(state_data, indent=2))
670
+ logger.debug(
671
+ f"Saved deployment state after reconciliation: {agent_count} agents"
672
+ )
673
+
674
+ except Exception as e:
675
+ # Non-critical error - log but don't fail startup
676
+ logger.debug(f"Failed to save deployment state: {e}")
677
+
678
+
453
679
  def sync_remote_agents_on_startup(force_sync: bool = False):
454
680
  """
455
681
  Synchronize agent templates from remote sources on startup.
@@ -612,6 +838,12 @@ def sync_remote_agents_on_startup(force_sync: bool = False):
612
838
  )
613
839
  print(" Run with --verbose for detailed error information.\n")
614
840
 
841
+ # Save deployment state to prevent duplicate deployment in ClaudeRunner
842
+ # This ensures setup_agents() skips deployment since we already reconciled
843
+ _save_deployment_state_after_reconciliation(
844
+ agent_result=agent_result, project_path=project_path
845
+ )
846
+
615
847
  except Exception as e:
616
848
  # Deployment failure shouldn't block startup
617
849
  from ..core.logger import get_logger
@@ -1139,33 +1371,74 @@ def show_skill_summary():
1139
1371
 
1140
1372
 
1141
1373
  def verify_and_show_pm_skills():
1142
- """Verify PM skills and display status.
1374
+ """Verify PM skills and display status with enhanced validation.
1143
1375
 
1144
- WHY: PM skills are essential for PM agent operation.
1145
- Shows deployment status and auto-deploys if missing.
1376
+ WHY: PM skills are CRITICAL for PM agent operation. PM must KNOW if
1377
+ framework knowledge is unavailable at startup. Enhanced validation
1378
+ checks all required skills exist, are not corrupted, and auto-repairs
1379
+ if needed.
1380
+
1381
+ Shows deployment status:
1382
+ - "✓ PM skills: 8/8 verified" if all required skills are valid
1383
+ - "⚠ PM skills: 2 missing, auto-repairing..." if issues detected
1384
+ - Non-blocking but visible warning if auto-repair fails
1146
1385
  """
1147
1386
  try:
1148
1387
  from pathlib import Path
1149
1388
 
1150
- from ..services.pm_skills_deployer import PMSkillsDeployerService
1389
+ from ..services.pm_skills_deployer import (
1390
+ REQUIRED_PM_SKILLS,
1391
+ PMSkillsDeployerService,
1392
+ )
1151
1393
 
1152
1394
  deployer = PMSkillsDeployerService()
1153
1395
  project_dir = Path.cwd()
1154
1396
 
1155
- result = deployer.verify_pm_skills(project_dir)
1397
+ # Verify with auto-repair enabled
1398
+ result = deployer.verify_pm_skills(project_dir, auto_repair=True)
1156
1399
 
1157
1400
  if result.verified:
1158
- # Show verified status
1159
- print(f"✓ PM skills: {result.skill_count} verified", flush=True)
1401
+ # Show verified status with count
1402
+ total_required = len(REQUIRED_PM_SKILLS)
1403
+ if sys.stdout.isatty():
1404
+ print(
1405
+ f"✓ PM skills: {total_required}/{total_required} verified",
1406
+ flush=True,
1407
+ )
1160
1408
  else:
1161
- # Auto-deploy if missing
1162
- print("Deploying PM skills...", end="", flush=True)
1163
- deploy_result = deployer.deploy_pm_skills(project_dir)
1164
- if deploy_result.success:
1165
- total = len(deploy_result.deployed) + len(deploy_result.skipped)
1166
- print(f"\r✓ PM skills: {total} deployed" + " " * 20, flush=True)
1409
+ # Show warning with details
1410
+ missing_count = len(result.missing_skills)
1411
+ corrupted_count = len(result.corrupted_skills)
1412
+
1413
+ # Build status message
1414
+ issues = []
1415
+ if missing_count > 0:
1416
+ issues.append(f"{missing_count} missing")
1417
+ if corrupted_count > 0:
1418
+ issues.append(f"{corrupted_count} corrupted")
1419
+
1420
+ status = ", ".join(issues)
1421
+
1422
+ # Check if auto-repair was attempted
1423
+ if "Auto-repaired" in result.message:
1424
+ # Auto-repair succeeded
1425
+ total_required = len(REQUIRED_PM_SKILLS)
1426
+ if sys.stdout.isatty():
1427
+ print(
1428
+ f"✓ PM skills: {total_required}/{total_required} verified (auto-repaired)",
1429
+ flush=True,
1430
+ )
1167
1431
  else:
1168
- print("\r⚠ PM skills: deployment failed" + " " * 20, flush=True)
1432
+ # Auto-repair failed or not attempted
1433
+ if sys.stdout.isatty():
1434
+ print(f"⚠ PM skills: {status}", flush=True)
1435
+
1436
+ # Log warnings for debugging
1437
+ from ..core.logger import get_logger
1438
+
1439
+ logger = get_logger("cli")
1440
+ for warning in result.warnings:
1441
+ logger.warning(f"PM skills: {warning}")
1169
1442
 
1170
1443
  except ImportError:
1171
1444
  # PM skills deployer not available - skip silently
@@ -1218,6 +1491,28 @@ def auto_install_chrome_devtools_on_startup():
1218
1491
  # Continue execution - chrome-devtools installation failure shouldn't block startup
1219
1492
 
1220
1493
 
1494
+ def sync_deployment_on_startup(force_sync: bool = False) -> None:
1495
+ """Consolidated deployment block: hooks + agents.
1496
+
1497
+ WHY: Groups all deployment tasks into a single logical block for clarity.
1498
+ This ensures hooks and agents are deployed together before other services.
1499
+
1500
+ Order:
1501
+ 1. Hook cleanup (remove ~/.claude/hooks/claude-mpm/)
1502
+ 2. Hook reinstall (update .claude/settings.local.json)
1503
+ 3. Agent sync from remote Git sources
1504
+
1505
+ Args:
1506
+ force_sync: Force download even if cache is fresh (bypasses ETag).
1507
+ """
1508
+ # Step 1-2: Hooks (cleanup + reinstall handled by sync_hooks_on_startup)
1509
+ sync_hooks_on_startup() # Shows "Syncing Claude Code hooks... ✓"
1510
+
1511
+ # Step 3: Agents from remote sources
1512
+ sync_remote_agents_on_startup(force_sync=force_sync)
1513
+ show_agent_summary() # Display agent counts after deployment
1514
+
1515
+
1221
1516
  def run_background_services(force_sync: bool = False):
1222
1517
  """
1223
1518
  Initialize all background services on startup.
@@ -1233,19 +1528,21 @@ def run_background_services(force_sync: bool = False):
1233
1528
  Args:
1234
1529
  force_sync: Force download even if cache is fresh (bypasses ETag).
1235
1530
  """
1236
- # Sync hooks early to ensure up-to-date configuration
1237
- # RATIONALE: Hooks should be synced before other services to fix stale configs
1238
- # This is fast (<100ms) and non-blocking, so it doesn't delay startup
1239
- sync_hooks_on_startup() # Shows "Syncing Claude Code hooks... ✓"
1531
+ # Run startup migrations FIRST (before any sync operations)
1532
+ # These fix configuration issues from previous versions
1533
+ from .startup_migrations import run_migrations
1534
+
1535
+ run_migrations()
1536
+
1537
+ # Consolidated deployment block: hooks + agents
1538
+ # RATIONALE: Hooks and agents are deployed together before other services
1539
+ # This ensures the deployment phase is complete before configuration checks
1540
+ sync_deployment_on_startup(force_sync=force_sync)
1240
1541
 
1241
1542
  initialize_project_registry()
1242
1543
  check_mcp_auto_configuration()
1243
1544
  verify_mcp_gateway_startup()
1244
1545
  check_for_updates_async()
1245
- sync_remote_agents_on_startup(
1246
- force_sync=force_sync
1247
- ) # Sync agents from remote sources
1248
- show_agent_summary() # Display agent counts after deployment
1249
1546
 
1250
1547
  # Skills deployment order (precedence: remote > bundled)
1251
1548
  # 1. Deploy bundled skills first (base layer from package)
@@ -1357,7 +1654,9 @@ def check_mcp_auto_configuration():
1357
1654
  from ..services.mcp_gateway.auto_configure import check_and_configure_mcp
1358
1655
 
1359
1656
  # Show progress feedback - this operation can take 10+ seconds
1360
- print("Checking MCP configuration...", end="", flush=True)
1657
+ # Only show progress message in TTY mode to avoid interfering with Claude Code's status display
1658
+ if sys.stdout.isatty():
1659
+ print("Checking MCP configuration...", end="", flush=True)
1361
1660
 
1362
1661
  # This function handles all the logic:
1363
1662
  # - Checks if already configured
@@ -1368,11 +1667,17 @@ def check_mcp_auto_configuration():
1368
1667
  check_and_configure_mcp()
1369
1668
 
1370
1669
  # Clear the "Checking..." message by overwriting with spaces
1371
- print("\r" + " " * 30 + "\r", end="", flush=True)
1670
+ # Only use carriage return clearing if stdout is a real TTY
1671
+ if sys.stdout.isatty():
1672
+ print("\r" + " " * 30 + "\r", end="", flush=True)
1673
+ # In non-TTY mode, don't print anything - the "Checking..." message will just remain on its line
1372
1674
 
1373
1675
  except Exception as e:
1374
1676
  # Clear progress message on error
1375
- print("\r" + " " * 30 + "\r", end="", flush=True)
1677
+ # Only use carriage return clearing if stdout is a real TTY
1678
+ if sys.stdout.isatty():
1679
+ print("\r" + " " * 30 + "\r", end="", flush=True)
1680
+ # In non-TTY mode, don't print anything - the "Checking..." message will just remain on its line
1376
1681
 
1377
1682
  # Non-critical - log but don't fail
1378
1683
  from ..core.logger import get_logger