claude-mpm 5.4.55__py3-none-any.whl → 5.6.1__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 (401) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
  3. claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
  4. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
  5. claude_mpm/agents/PM_INSTRUCTIONS.md +111 -686
  6. claude_mpm/agents/WORKFLOW.md +2 -0
  7. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  8. claude_mpm/cli/__init__.py +5 -1
  9. claude_mpm/cli/commands/agents.py +2 -4
  10. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  11. claude_mpm/cli/commands/autotodos.py +566 -0
  12. claude_mpm/cli/commands/commander.py +46 -0
  13. claude_mpm/cli/commands/configure.py +620 -21
  14. claude_mpm/cli/commands/hook_errors.py +60 -60
  15. claude_mpm/cli/commands/monitor.py +2 -2
  16. claude_mpm/cli/commands/mpm_init/core.py +2 -2
  17. claude_mpm/cli/commands/run.py +35 -3
  18. claude_mpm/cli/commands/skills.py +166 -14
  19. claude_mpm/cli/executor.py +120 -16
  20. claude_mpm/cli/interactive/__init__.py +10 -0
  21. claude_mpm/cli/interactive/agent_wizard.py +30 -50
  22. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  23. claude_mpm/cli/interactive/skill_selector.py +481 -0
  24. claude_mpm/cli/parsers/base_parser.py +76 -1
  25. claude_mpm/cli/parsers/commander_parser.py +83 -0
  26. claude_mpm/cli/parsers/run_parser.py +10 -0
  27. claude_mpm/cli/startup.py +276 -403
  28. claude_mpm/cli/startup_display.py +72 -5
  29. claude_mpm/cli/startup_logging.py +2 -2
  30. claude_mpm/cli/utils.py +7 -3
  31. claude_mpm/commander/__init__.py +72 -0
  32. claude_mpm/commander/adapters/__init__.py +31 -0
  33. claude_mpm/commander/adapters/base.py +191 -0
  34. claude_mpm/commander/adapters/claude_code.py +361 -0
  35. claude_mpm/commander/adapters/communication.py +366 -0
  36. claude_mpm/commander/api/__init__.py +16 -0
  37. claude_mpm/commander/api/app.py +105 -0
  38. claude_mpm/commander/api/errors.py +112 -0
  39. claude_mpm/commander/api/routes/__init__.py +8 -0
  40. claude_mpm/commander/api/routes/events.py +184 -0
  41. claude_mpm/commander/api/routes/inbox.py +171 -0
  42. claude_mpm/commander/api/routes/messages.py +148 -0
  43. claude_mpm/commander/api/routes/projects.py +271 -0
  44. claude_mpm/commander/api/routes/sessions.py +215 -0
  45. claude_mpm/commander/api/routes/work.py +260 -0
  46. claude_mpm/commander/api/schemas.py +182 -0
  47. claude_mpm/commander/chat/__init__.py +7 -0
  48. claude_mpm/commander/chat/cli.py +107 -0
  49. claude_mpm/commander/chat/commands.py +96 -0
  50. claude_mpm/commander/chat/repl.py +310 -0
  51. claude_mpm/commander/config.py +49 -0
  52. claude_mpm/commander/config_loader.py +115 -0
  53. claude_mpm/commander/daemon.py +398 -0
  54. claude_mpm/commander/events/__init__.py +26 -0
  55. claude_mpm/commander/events/manager.py +332 -0
  56. claude_mpm/commander/frameworks/__init__.py +12 -0
  57. claude_mpm/commander/frameworks/base.py +143 -0
  58. claude_mpm/commander/frameworks/claude_code.py +58 -0
  59. claude_mpm/commander/frameworks/mpm.py +62 -0
  60. claude_mpm/commander/inbox/__init__.py +16 -0
  61. claude_mpm/commander/inbox/dedup.py +128 -0
  62. claude_mpm/commander/inbox/inbox.py +224 -0
  63. claude_mpm/commander/inbox/models.py +70 -0
  64. claude_mpm/commander/instance_manager.py +337 -0
  65. claude_mpm/commander/llm/__init__.py +6 -0
  66. claude_mpm/commander/llm/openrouter_client.py +167 -0
  67. claude_mpm/commander/llm/summarizer.py +70 -0
  68. claude_mpm/commander/models/__init__.py +18 -0
  69. claude_mpm/commander/models/events.py +121 -0
  70. claude_mpm/commander/models/project.py +162 -0
  71. claude_mpm/commander/models/work.py +214 -0
  72. claude_mpm/commander/parsing/__init__.py +20 -0
  73. claude_mpm/commander/parsing/extractor.py +132 -0
  74. claude_mpm/commander/parsing/output_parser.py +270 -0
  75. claude_mpm/commander/parsing/patterns.py +100 -0
  76. claude_mpm/commander/persistence/__init__.py +11 -0
  77. claude_mpm/commander/persistence/event_store.py +274 -0
  78. claude_mpm/commander/persistence/state_store.py +309 -0
  79. claude_mpm/commander/persistence/work_store.py +164 -0
  80. claude_mpm/commander/polling/__init__.py +13 -0
  81. claude_mpm/commander/polling/event_detector.py +104 -0
  82. claude_mpm/commander/polling/output_buffer.py +49 -0
  83. claude_mpm/commander/polling/output_poller.py +153 -0
  84. claude_mpm/commander/project_session.py +268 -0
  85. claude_mpm/commander/proxy/__init__.py +12 -0
  86. claude_mpm/commander/proxy/formatter.py +89 -0
  87. claude_mpm/commander/proxy/output_handler.py +191 -0
  88. claude_mpm/commander/proxy/relay.py +155 -0
  89. claude_mpm/commander/registry.py +404 -0
  90. claude_mpm/commander/runtime/__init__.py +10 -0
  91. claude_mpm/commander/runtime/executor.py +191 -0
  92. claude_mpm/commander/runtime/monitor.py +316 -0
  93. claude_mpm/commander/session/__init__.py +6 -0
  94. claude_mpm/commander/session/context.py +81 -0
  95. claude_mpm/commander/session/manager.py +59 -0
  96. claude_mpm/commander/tmux_orchestrator.py +361 -0
  97. claude_mpm/commander/web/__init__.py +1 -0
  98. claude_mpm/commander/work/__init__.py +30 -0
  99. claude_mpm/commander/work/executor.py +189 -0
  100. claude_mpm/commander/work/queue.py +405 -0
  101. claude_mpm/commander/workflow/__init__.py +27 -0
  102. claude_mpm/commander/workflow/event_handler.py +219 -0
  103. claude_mpm/commander/workflow/notifier.py +146 -0
  104. claude_mpm/commands/mpm-config.md +8 -0
  105. claude_mpm/commands/mpm-doctor.md +8 -0
  106. claude_mpm/commands/mpm-help.md +8 -0
  107. claude_mpm/commands/mpm-init.md +8 -0
  108. claude_mpm/commands/mpm-monitor.md +8 -0
  109. claude_mpm/commands/mpm-organize.md +8 -0
  110. claude_mpm/commands/mpm-postmortem.md +8 -0
  111. claude_mpm/commands/mpm-session-resume.md +9 -1
  112. claude_mpm/commands/mpm-status.md +8 -0
  113. claude_mpm/commands/mpm-ticket-view.md +8 -0
  114. claude_mpm/commands/mpm-version.md +8 -0
  115. claude_mpm/commands/mpm.md +8 -0
  116. claude_mpm/config/agent_presets.py +8 -7
  117. claude_mpm/constants.py +1 -0
  118. claude_mpm/core/claude_runner.py +2 -2
  119. claude_mpm/core/config.py +5 -0
  120. claude_mpm/core/hook_manager.py +51 -3
  121. claude_mpm/core/interactive_session.py +7 -7
  122. claude_mpm/core/logger.py +10 -7
  123. claude_mpm/core/logging_utils.py +4 -2
  124. claude_mpm/core/output_style_manager.py +31 -13
  125. claude_mpm/core/unified_config.py +54 -8
  126. claude_mpm/core/unified_paths.py +30 -13
  127. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
  128. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
  129. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Cs_tUR18.js → 1WZnGYqX.js} +1 -1
  130. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CDuw-vjf.js → 67pF3qNn.js} +1 -1
  131. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bTOqqlTd.js → 6RxdMKe4.js} +1 -1
  132. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DwBR2MJi.js → 8cZrfX0h.js} +1 -1
  133. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{ZGh7QtNv.js → 9a6T2nm-.js} +1 -1
  134. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D9lljYKQ.js → B443AUzu.js} +1 -1
  135. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{RJiighC3.js → B8AwtY2H.js} +1 -1
  136. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uuIeMWc-.js → BF15LAsF.js} +1 -1
  137. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D3k0OPJN.js → BRcwIQNr.js} +1 -1
  138. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CyWMqx4W.js → BV6nKitt.js} +1 -1
  139. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CiIAseT4.js → BViJ8lZt.js} +5 -5
  140. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CBBdVcY8.js → BcQ-Q0FE.js} +1 -1
  141. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BovzEFCE.js → Bpyvgze_.js} +1 -1
  142. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
  143. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
  144. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{eNVUfhuA.js → C3rbW_a-.js} +1 -1
  145. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{GYwsonyD.js → C8WYN38h.js} +1 -1
  146. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BIF9m_hv.js → C9I8FlXH.js} +1 -1
  147. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B0uc0UOD.js → CIQcWgO2.js} +3 -3
  148. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Be7GpZd6.js → CIctN7YN.js} +1 -1
  149. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Bh0LDWpI.js → CKrS_JZW.js} +2 -2
  150. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DUrLdbGD.js → CR6P9C4A.js} +1 -1
  151. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7xVLGWV.js → CRRR9MD_.js} +1 -1
  152. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
  153. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dhb8PKl3.js → CSXtMOf0.js} +1 -1
  154. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BPYeabCQ.js → CT-sbxSk.js} +1 -1
  155. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{sQeU3Y1z.js → CWm6DJsp.js} +1 -1
  156. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CnA0NrzZ.js → CpqQ1Kzn.js} +1 -1
  157. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4B-KCzX.js → D2nGpDRe.js} +1 -1
  158. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DGkLK5U1.js → D9iCMida.js} +1 -1
  159. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BofRWZRR.js → D9ykgMoY.js} +1 -1
  160. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DmxopI1J.js → DL2Ldur1.js} +1 -1
  161. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C30mlcqg.js → DPfltzjH.js} +1 -1
  162. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Vzk33B_K.js → DR8nis88.js} +2 -2
  163. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DI7hHRFL.js → DUliQN2b.js} +1 -1
  164. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4JcI4KD.js → DXlhR01x.js} +1 -1
  165. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bT1r9zLR.js → D_lyTybS.js} +1 -1
  166. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DZX00Y4g.js → DngoTTgh.js} +1 -1
  167. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzZX-COe.js → DqkmHtDC.js} +1 -1
  168. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7RN905-.js → DsDh8EYs.js} +1 -1
  169. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DLVjFsZ3.js → DypDmXgd.js} +1 -1
  170. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{iEWssX7S.js → IPYC-LnN.js} +1 -1
  171. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
  172. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DaimHw_p.js → JpevfAFt.js} +1 -1
  173. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DY1XQ8fi.js → R8CEIRAd.js} +1 -1
  174. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dle-35c7.js → Zxy7qc-l.js} +2 -2
  175. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
  176. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C_Usid8X.js → qtd3IeO4.js} +2 -2
  177. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzeYkLYB.js → ulBFON_C.js} +2 -2
  178. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Cfqx1Qun.js → wQVh1CoA.js} +1 -1
  179. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/{app.D6-I5TpK.js → app.Dr7t0z2J.js} +2 -2
  180. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
  181. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.m1gL8KXf.js → 0.RgBboRvH.js} +1 -1
  182. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{1.CgNOuw-d.js → 1.DG-KkbDf.js} +1 -1
  183. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
  184. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
  185. claude_mpm/dashboard/static/svelte-build/index.html +9 -9
  186. claude_mpm/experimental/cli_enhancements.py +2 -1
  187. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  188. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  189. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +486 -0
  190. claude_mpm/hooks/claude_hooks/event_handlers.py +250 -11
  191. claude_mpm/hooks/claude_hooks/hook_handler.py +106 -89
  192. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  193. claude_mpm/hooks/claude_hooks/installer.py +69 -5
  194. claude_mpm/hooks/claude_hooks/response_tracking.py +3 -1
  195. claude_mpm/hooks/claude_hooks/services/connection_manager.py +20 -0
  196. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +14 -77
  197. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +30 -6
  198. claude_mpm/hooks/session_resume_hook.py +85 -1
  199. claude_mpm/init.py +1 -1
  200. claude_mpm/scripts/claude-hook-handler.sh +36 -10
  201. claude_mpm/scripts/start_activity_logging.py +0 -0
  202. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  203. claude_mpm/services/agents/cache_git_manager.py +1 -1
  204. claude_mpm/services/agents/deployment/agent_template_builder.py +8 -0
  205. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  206. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +3 -0
  207. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  208. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  209. claude_mpm/services/agents/sources/git_source_sync_service.py +7 -4
  210. claude_mpm/services/agents/startup_sync.py +5 -2
  211. claude_mpm/services/cli/__init__.py +3 -0
  212. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  213. claude_mpm/services/cli/session_resume_helper.py +10 -2
  214. claude_mpm/services/delegation_detector.py +175 -0
  215. claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
  216. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  217. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  218. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  219. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  220. claude_mpm/services/diagnostics/models.py +14 -1
  221. claude_mpm/services/event_log.py +325 -0
  222. claude_mpm/services/infrastructure/__init__.py +4 -0
  223. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  224. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  225. claude_mpm/services/monitor/daemon_manager.py +15 -4
  226. claude_mpm/services/monitor/management/lifecycle.py +8 -2
  227. claude_mpm/services/monitor/server.py +106 -16
  228. claude_mpm/services/pm_skills_deployer.py +261 -85
  229. claude_mpm/services/skills/git_skill_source_manager.py +75 -10
  230. claude_mpm/services/skills/selective_skill_deployer.py +177 -80
  231. claude_mpm/services/skills/skill_discovery_service.py +57 -3
  232. claude_mpm/services/socketio/handlers/hook.py +14 -7
  233. claude_mpm/services/socketio/server/main.py +12 -4
  234. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  235. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  236. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  237. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  238. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  239. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  240. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  241. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  242. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  243. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  244. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  245. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  246. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  247. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  248. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  249. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  250. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  251. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  252. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  253. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  254. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  255. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  256. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  257. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  258. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  259. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  260. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  261. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  262. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  263. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  264. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  265. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  266. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  267. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  268. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  269. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  270. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  271. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  272. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  273. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  274. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  275. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  276. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  277. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  278. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  279. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  280. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  281. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  282. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  283. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  284. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  285. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  286. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  287. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  288. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  289. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  290. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  291. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  292. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  293. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  294. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  295. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  296. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  297. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  298. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  299. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  300. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  301. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  302. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  303. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  304. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  305. claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
  306. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  307. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  308. claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
  309. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  310. claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
  311. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  312. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  313. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  314. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  315. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  316. claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
  317. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  318. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  319. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  320. claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
  321. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  322. claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
  323. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  324. claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
  325. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  326. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  327. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  328. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  329. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  330. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  331. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  332. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  333. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  334. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  335. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  336. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  337. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  338. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  339. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  340. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  341. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  342. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  343. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  344. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  345. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  346. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  347. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  348. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  349. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  350. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  351. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  352. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  353. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  354. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  355. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  356. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  357. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  358. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  359. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  360. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  361. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  362. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  363. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  364. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  365. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  366. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  367. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  368. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  369. claude_mpm/skills/skill_manager.py +4 -4
  370. claude_mpm/utils/agent_dependency_loader.py +103 -4
  371. claude_mpm/utils/robust_installer.py +45 -24
  372. claude_mpm-5.6.1.dist-info/METADATA +391 -0
  373. {claude_mpm-5.4.55.dist-info → claude_mpm-5.6.1.dist-info}/RECORD +377 -166
  374. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +0 -1
  375. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +0 -1
  376. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +0 -1
  377. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +0 -24
  378. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +0 -1
  379. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +0 -1
  380. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +0 -323
  381. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +0 -1
  382. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +0 -1
  383. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  384. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  385. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  386. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  387. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  388. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  389. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  390. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  391. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  392. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  393. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  394. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  395. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  396. claude_mpm-5.4.55.dist-info/METADATA +0 -999
  397. {claude_mpm-5.4.55.dist-info → claude_mpm-5.6.1.dist-info}/WHEEL +0 -0
  398. {claude_mpm-5.4.55.dist-info → claude_mpm-5.6.1.dist-info}/entry_points.txt +0 -0
  399. {claude_mpm-5.4.55.dist-info → claude_mpm-5.6.1.dist-info}/licenses/LICENSE +0 -0
  400. {claude_mpm-5.4.55.dist-info → claude_mpm-5.6.1.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  401. {claude_mpm-5.4.55.dist-info → claude_mpm-5.6.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,481 @@
1
+ """Interactive Skill Selector for Claude MPM.
2
+
3
+ This module provides a two-tier interactive skill selection wizard:
4
+ 1. Select topic groups (toolchains) to explore
5
+ 2. Multi-select skills within each topic group
6
+
7
+ Features:
8
+ - Groups skills by toolchain (universal, python, typescript, etc.)
9
+ - Shows skills auto-included by agent dependencies
10
+ - Displays token counts for each skill
11
+ - Uses questionary with cyan style for consistency
12
+ - Matches agent selector UI pattern with table display
13
+ """
14
+
15
+ import json
16
+ import shutil
17
+ from dataclasses import dataclass
18
+ from typing import Dict, List, Optional, Set
19
+
20
+ import questionary
21
+
22
+ from claude_mpm.cli.interactive.questionary_styles import (
23
+ BANNER_WIDTH,
24
+ MPM_STYLE,
25
+ print_banner,
26
+ )
27
+ from claude_mpm.core.logging_utils import get_logger
28
+ from claude_mpm.core.unified_config import UnifiedConfig
29
+ from claude_mpm.core.unified_paths import get_path_manager
30
+
31
+ logger = get_logger(__name__)
32
+
33
+ # Topic/toolchain icons
34
+ TOPIC_ICONS = {
35
+ "universal": "🌐",
36
+ "python": "🐍",
37
+ "typescript": "📘",
38
+ "javascript": "📒",
39
+ "rust": "⚙️",
40
+ "go": "🔷",
41
+ "java": "☕",
42
+ "ruby": "💎",
43
+ "php": "🐘",
44
+ "csharp": "🔷",
45
+ "cpp": "⚙️",
46
+ "swift": "🍎",
47
+ None: "🌐", # Default for null toolchain (universal)
48
+ }
49
+
50
+
51
+ @dataclass
52
+ class SkillInfo:
53
+ """Information about a skill from manifest."""
54
+
55
+ name: str
56
+ toolchain: Optional[str]
57
+ framework: Optional[str]
58
+ tags: List[str]
59
+ full_tokens: int
60
+ description: str = ""
61
+
62
+ @property
63
+ def display_name(self) -> str:
64
+ """Get display name with token count."""
65
+ tokens_k = self.full_tokens // 1000
66
+ return f"{self.name} ({tokens_k}K tokens)"
67
+
68
+
69
+ class SkillSelector:
70
+ """Interactive skill selector with topic grouping."""
71
+
72
+ def __init__(
73
+ self,
74
+ skills_manifest: Dict,
75
+ agent_skill_deps: Optional[List[str]] = None,
76
+ deployed_skills: Optional[Set[str]] = None,
77
+ ):
78
+ """Initialize skill selector.
79
+
80
+ Args:
81
+ skills_manifest: Full manifest dict with all skills
82
+ agent_skill_deps: Skills required by deployed agents (auto-included)
83
+ deployed_skills: Skills currently deployed in .claude/skills/
84
+ """
85
+ self.manifest = skills_manifest
86
+ self.agent_skill_deps = set(agent_skill_deps or [])
87
+ self.deployed_skills = deployed_skills or set()
88
+ self.skills_by_toolchain: Dict[str, List[SkillInfo]] = {}
89
+ self._parse_manifest()
90
+
91
+ def _parse_manifest(self) -> None:
92
+ """Parse manifest and group skills by toolchain."""
93
+ # Handle both old and new manifest formats
94
+ skills_data = self.manifest.get("skills", {})
95
+
96
+ # Flatten skills from grouped format to flat list
97
+ all_skills = []
98
+ if isinstance(skills_data, dict):
99
+ for toolchain, skills_list in skills_data.items():
100
+ all_skills.extend(skills_list)
101
+ elif isinstance(skills_data, list):
102
+ all_skills = skills_data
103
+
104
+ # Group by toolchain
105
+ for skill_data in all_skills:
106
+ try:
107
+ skill = SkillInfo(
108
+ name=skill_data.get("name", ""),
109
+ toolchain=skill_data.get("toolchain"),
110
+ framework=skill_data.get("framework"),
111
+ tags=skill_data.get("tags", []),
112
+ full_tokens=skill_data.get("full_tokens", 0),
113
+ description=skill_data.get("description", ""),
114
+ )
115
+
116
+ # Group by toolchain (null -> universal)
117
+ toolchain_key = skill.toolchain or "universal"
118
+
119
+ if toolchain_key not in self.skills_by_toolchain:
120
+ self.skills_by_toolchain[toolchain_key] = []
121
+
122
+ self.skills_by_toolchain[toolchain_key].append(skill)
123
+ except Exception as e:
124
+ logger.warning(
125
+ f"Failed to parse skill: {skill_data.get('name', 'unknown')}: {e}"
126
+ )
127
+
128
+ # Sort skills within each toolchain by name
129
+ for toolchain in self.skills_by_toolchain:
130
+ self.skills_by_toolchain[toolchain].sort(key=lambda s: s.name)
131
+
132
+ @staticmethod
133
+ def _calculate_column_widths(
134
+ terminal_width: int, columns: Dict[str, int]
135
+ ) -> Dict[str, int]:
136
+ """Calculate dynamic column widths based on terminal size.
137
+
138
+ Args:
139
+ terminal_width: Current terminal width in characters
140
+ columns: Dict mapping column names to minimum widths
141
+
142
+ Returns:
143
+ Dict mapping column names to calculated widths
144
+
145
+ Design:
146
+ - Ensures minimum widths are respected
147
+ - Distributes extra space proportionally
148
+ - Handles narrow terminals gracefully (minimum 80 chars)
149
+ """
150
+ # Ensure minimum terminal width
151
+ min_terminal_width = 80
152
+ terminal_width = max(terminal_width, min_terminal_width)
153
+
154
+ # Calculate total minimum width needed
155
+ total_min_width = sum(columns.values())
156
+
157
+ # Account for spacing between columns
158
+ overhead = len(columns) + 1
159
+ available_width = terminal_width - overhead
160
+
161
+ # If we have extra space, distribute proportionally
162
+ if available_width > total_min_width:
163
+ extra_space = available_width - total_min_width
164
+ total_weight = sum(columns.values())
165
+
166
+ result = {}
167
+ for col_name, min_width in columns.items():
168
+ # Distribute extra space based on minimum width proportion
169
+ proportion = min_width / total_weight
170
+ extra = int(extra_space * proportion)
171
+ result[col_name] = min_width + extra
172
+ return result
173
+ # Terminal too narrow, use minimum widths
174
+ return columns.copy()
175
+
176
+ def _display_skills_table(self, skills: List[SkillInfo]) -> None:
177
+ """Display skills in a table with status (matches agent selector pattern).
178
+
179
+ Args:
180
+ skills: List of skills to display
181
+ """
182
+ if not skills:
183
+ print("\n📭 No skills found.")
184
+ return
185
+
186
+ # Calculate dynamic column widths based on terminal size
187
+ terminal_width = shutil.get_terminal_size().columns
188
+ min_widths = {
189
+ "#": 4,
190
+ "Skill ID": 30,
191
+ "Description": 35,
192
+ "Toolchain": 12,
193
+ "Status": 12,
194
+ }
195
+ widths = self._calculate_column_widths(terminal_width, min_widths)
196
+
197
+ # Print header with dynamic widths
198
+ print(
199
+ f"\n{'#':<{widths['#']}} "
200
+ f"{'Skill ID':<{widths['Skill ID']}} "
201
+ f"{'Description':<{widths['Description']}} "
202
+ f"{'Toolchain':<{widths['Toolchain']}} "
203
+ f"{'Status':<{widths['Status']}}"
204
+ )
205
+ separator_width = sum(widths.values()) + len(widths) - 1
206
+ print("-" * separator_width)
207
+
208
+ for i, skill in enumerate(skills, 1):
209
+ # Truncate to fit dynamic width
210
+ skill_id = skill.name
211
+ if len(skill_id) > widths["Skill ID"]:
212
+ skill_id = skill_id[: widths["Skill ID"] - 1] + "…"
213
+
214
+ description = skill.description or skill.name
215
+ if len(description) > widths["Description"]:
216
+ description = description[: widths["Description"] - 1] + "…"
217
+
218
+ toolchain = skill.toolchain or "universal"
219
+ if len(toolchain) > widths["Toolchain"]:
220
+ toolchain = toolchain[: widths["Toolchain"] - 1] + "…"
221
+
222
+ # Determine status
223
+ if skill.name in self.agent_skill_deps:
224
+ status = "✓ Required"
225
+ elif skill.name in self.deployed_skills:
226
+ status = "✓ Installed"
227
+ else:
228
+ status = "Available"
229
+
230
+ print(
231
+ f"{i:<{widths['#']}} "
232
+ f"{skill_id:<{widths['Skill ID']}} "
233
+ f"{description:<{widths['Description']}} "
234
+ f"{toolchain:<{widths['Toolchain']}} "
235
+ f"{status:<{widths['Status']}}"
236
+ )
237
+
238
+ def select_skills(self) -> List[str]:
239
+ """Run interactive selection and return selected skill IDs.
240
+
241
+ Returns:
242
+ List of selected skill IDs (names)
243
+ """
244
+ print_banner("SKILL CONFIGURATION", width=BANNER_WIDTH)
245
+
246
+ # Show agent-required skills (auto-included)
247
+ if self.agent_skill_deps:
248
+ self._show_agent_required_skills()
249
+
250
+ # Get all skills for table display
251
+ all_skills = []
252
+ for toolchain_skills in self.skills_by_toolchain.values():
253
+ all_skills.extend(toolchain_skills)
254
+ all_skills.sort(key=lambda s: s.name)
255
+
256
+ # Display skills table
257
+ print(f"\n📋 Found {len(all_skills)} skill(s) available:")
258
+ self._display_skills_table(all_skills)
259
+
260
+ # Select topic groups to explore
261
+ selected_groups = self._select_topic_groups()
262
+
263
+ if not selected_groups:
264
+ print("\n⚠️ No topic groups selected. Using only agent-required skills.")
265
+ return list(self.agent_skill_deps)
266
+
267
+ # Multi-select skills from each group
268
+ selected_skills = set(self.agent_skill_deps) # Start with auto-included
269
+
270
+ for group in selected_groups:
271
+ group_skills = self._select_skills_from_group(group)
272
+ selected_skills.update(group_skills)
273
+
274
+ # Confirm selection
275
+ print(f"\n✅ Total skills selected: {len(selected_skills)}")
276
+ print(f" - Auto-included (from agents): {len(self.agent_skill_deps)}")
277
+ print(f" - Manually selected: {len(selected_skills - self.agent_skill_deps)}")
278
+
279
+ return list(selected_skills)
280
+
281
+ def _show_agent_required_skills(self) -> None:
282
+ """Display skills that are auto-included from agent dependencies."""
283
+ print("\n📦 Agent-Required Skills (auto-included):")
284
+ for skill_name in sorted(self.agent_skill_deps):
285
+ print(f" ✓ {skill_name}")
286
+ print()
287
+
288
+ def _select_topic_groups(self) -> List[str]:
289
+ """First tier: Select which toolchain groups to browse.
290
+
291
+ Returns:
292
+ List of selected toolchain keys
293
+ """
294
+ # Build choices with counts
295
+ choices = []
296
+ for toolchain in sorted(self.skills_by_toolchain.keys()):
297
+ skills = self.skills_by_toolchain[toolchain]
298
+ icon = TOPIC_ICONS.get(toolchain, "📦")
299
+ display_name = toolchain.capitalize() if toolchain else "Universal"
300
+ choice_text = f"{icon} {display_name} ({len(skills)} skills)"
301
+ choices.append(questionary.Choice(title=choice_text, value=toolchain))
302
+
303
+ if not choices:
304
+ print("\n⚠️ No skills available in manifest.")
305
+ return []
306
+
307
+ # Multi-select groups
308
+ selected = questionary.checkbox(
309
+ "📂 Select Topic Groups to Add Skills From:",
310
+ choices=choices,
311
+ style=MPM_STYLE,
312
+ ).ask()
313
+
314
+ if selected is None: # User cancelled
315
+ return []
316
+
317
+ return selected
318
+
319
+ def _select_skills_from_group(self, toolchain: str) -> List[str]:
320
+ """Second tier: Multi-select skills within a toolchain group.
321
+
322
+ Args:
323
+ toolchain: Toolchain key to select from
324
+
325
+ Returns:
326
+ List of selected skill names
327
+ """
328
+ skills = self.skills_by_toolchain.get(toolchain, [])
329
+ if not skills:
330
+ return []
331
+
332
+ icon = TOPIC_ICONS.get(toolchain, "📦")
333
+ display_name = toolchain.capitalize() if toolchain else "Universal"
334
+
335
+ print(f"\n{icon} {display_name} Skills:")
336
+
337
+ # Build choices with numbered format like agent selector
338
+ choices = []
339
+ for i, skill in enumerate(skills, 1):
340
+ # Mark if already selected (from agent deps)
341
+ already_selected = skill.name in self.agent_skill_deps
342
+
343
+ # Format: "1. skill-name - toolchain (XK tokens)"
344
+ tokens_k = skill.full_tokens // 1000
345
+ desc = skill.description[:50] if skill.description else skill.name
346
+ choice_text = f"{i}. {skill.name} - {desc}... ({tokens_k}K tokens)"
347
+
348
+ choice = questionary.Choice(
349
+ title=choice_text,
350
+ value=skill.name,
351
+ checked=already_selected,
352
+ )
353
+ choices.append(choice)
354
+
355
+ # Multi-select skills
356
+ selected = questionary.checkbox(
357
+ f"Select {display_name} skills to include:",
358
+ choices=choices,
359
+ style=MPM_STYLE,
360
+ ).ask()
361
+
362
+ if selected is None: # User cancelled
363
+ return []
364
+
365
+ return selected
366
+
367
+
368
+ def load_skills_manifest() -> Optional[Dict]:
369
+ """Load skills manifest from cache.
370
+
371
+ Returns:
372
+ Manifest dict or None if not found
373
+ """
374
+ try:
375
+ path_manager = get_path_manager()
376
+ manifest_path = (
377
+ path_manager.get_cache_dir() / "skills" / "system" / "manifest.json"
378
+ )
379
+
380
+ if not manifest_path.exists():
381
+ logger.error(f"Skills manifest not found at {manifest_path}")
382
+ print("\n❌ Skills manifest not found. Run 'claude-mpm skills sync' first.")
383
+ return None
384
+
385
+ with open(manifest_path, encoding="utf-8") as f:
386
+ return json.load(f)
387
+
388
+ except Exception as e:
389
+ logger.error(f"Failed to load skills manifest: {e}")
390
+ print(f"\n❌ Failed to load skills manifest: {e}")
391
+ return None
392
+
393
+
394
+ def get_agent_skill_dependencies(config: UnifiedConfig) -> List[str]:
395
+ """Get skill dependencies from deployed agents.
396
+
397
+ Args:
398
+ config: UnifiedConfig instance
399
+
400
+ Returns:
401
+ List of skill IDs required by enabled agents
402
+ """
403
+ try:
404
+ from claude_mpm.services.agents.deployment.deployment_reconciler import (
405
+ DeploymentReconciler,
406
+ )
407
+
408
+ reconciler = DeploymentReconciler(config)
409
+ enabled_agents = config.agents.enabled
410
+
411
+ if not enabled_agents:
412
+ logger.debug("No enabled agents, no skill dependencies")
413
+ return []
414
+
415
+ # Get skill dependencies
416
+ skill_deps = reconciler._get_agent_skill_dependencies(enabled_agents)
417
+ return list(skill_deps)
418
+
419
+ except Exception as e:
420
+ logger.warning(f"Failed to get agent skill dependencies: {e}")
421
+ return []
422
+
423
+
424
+ def get_deployed_skills() -> Set[str]:
425
+ """Get skills currently deployed in .claude/skills/ directory.
426
+
427
+ Returns:
428
+ Set of deployed skill IDs
429
+ """
430
+ try:
431
+ from claude_mpm.services.agents.deployment.deployment_reconciler import (
432
+ DeploymentReconciler,
433
+ )
434
+
435
+ config = UnifiedConfig()
436
+ reconciler = DeploymentReconciler(config)
437
+
438
+ # Get path to deployed skills directory
439
+ path_manager = get_path_manager()
440
+ deploy_dir = path_manager.get_deploy_dir() / "skills"
441
+
442
+ # Use reconciler's method to list deployed skills
443
+ return reconciler._list_deployed_skills(deploy_dir)
444
+
445
+ except Exception as e:
446
+ logger.warning(f"Failed to get deployed skills: {e}")
447
+ return set()
448
+
449
+
450
+ def run_skill_selector() -> Optional[List[str]]:
451
+ """Main entry point for skill selector.
452
+
453
+ Returns:
454
+ List of selected skill IDs, or None if cancelled
455
+ """
456
+ try:
457
+ # Load config
458
+ config = UnifiedConfig()
459
+
460
+ # Load manifest
461
+ manifest = load_skills_manifest()
462
+ if not manifest:
463
+ return None
464
+
465
+ # Get agent skill dependencies
466
+ agent_deps = get_agent_skill_dependencies(config)
467
+
468
+ # Get deployed skills
469
+ deployed = get_deployed_skills()
470
+
471
+ # Run selector
472
+ selector = SkillSelector(manifest, agent_deps, deployed)
473
+ return selector.select_skills()
474
+
475
+ except KeyboardInterrupt:
476
+ print("\n\n❌ Skill selection cancelled")
477
+ return None
478
+ except Exception as e:
479
+ logger.error(f"Skill selection error: {e}", exc_info=True)
480
+ print(f"\n❌ Skill selection error: {e}")
481
+ return None
@@ -125,7 +125,7 @@ def _get_enhanced_version(base_version: str) -> str:
125
125
 
126
126
  if enhanced and enhanced != base_version:
127
127
  return enhanced
128
- except Exception:
128
+ except Exception: # nosec B110
129
129
  # If anything fails, fall back to base version
130
130
  pass
131
131
 
@@ -292,6 +292,21 @@ def add_top_level_run_arguments(parser: argparse.ArgumentParser) -> None:
292
292
  action="store_true",
293
293
  help="Force rebuild of all system agents by deleting local claude-mpm agents",
294
294
  )
295
+ run_group.add_argument(
296
+ "--force-sync",
297
+ action="store_true",
298
+ help="Force refresh agents and skills from remote repos, bypassing ETag cache",
299
+ )
300
+ run_group.add_argument(
301
+ "--chrome",
302
+ action="store_true",
303
+ help="Enable Claude in Chrome integration (passed to Claude Code)",
304
+ )
305
+ run_group.add_argument(
306
+ "--no-chrome",
307
+ action="store_true",
308
+ help="Disable Claude in Chrome integration (passed to Claude Code)",
309
+ )
295
310
 
296
311
  # Dependency checking options (for backward compatibility at top level)
297
312
  dep_group_top = parser.add_argument_group(
@@ -487,6 +502,13 @@ def create_parser(
487
502
  except ImportError:
488
503
  pass
489
504
 
505
+ try:
506
+ from .commander_parser import add_commander_subparser
507
+
508
+ add_commander_subparser(subparsers)
509
+ except ImportError:
510
+ pass
511
+
490
512
  # Add uninstall command parser
491
513
  try:
492
514
  from ..commands.uninstall import add_uninstall_parser
@@ -602,6 +624,59 @@ def create_parser(
602
624
  help="Skip confirmation prompts",
603
625
  )
604
626
 
627
+ # Add autotodos command for auto-generating todos from hook errors
628
+ autotodos_parser = subparsers.add_parser(
629
+ "autotodos",
630
+ help="Auto-generate todos from hook errors and delegation patterns",
631
+ )
632
+ autotodos_parser.add_argument(
633
+ "autotodos_command",
634
+ nargs="?",
635
+ choices=["list", "inject", "clear", "status", "scan", "violations"],
636
+ help="AutoTodos subcommand",
637
+ )
638
+ autotodos_parser.add_argument(
639
+ "text",
640
+ nargs="?",
641
+ help="Text to scan for delegation patterns (scan command only)",
642
+ )
643
+ autotodos_parser.add_argument(
644
+ "--format",
645
+ choices=["table", "json"],
646
+ default="table",
647
+ help="Output format for list/scan commands",
648
+ )
649
+ autotodos_parser.add_argument(
650
+ "--output",
651
+ help="Output file path for inject command",
652
+ )
653
+ autotodos_parser.add_argument(
654
+ "--error-key",
655
+ help="Specific error key to clear",
656
+ )
657
+ autotodos_parser.add_argument(
658
+ "--event-type",
659
+ choices=["error", "violation", "all"],
660
+ default="all",
661
+ help="Type of events to clear (clear command only)",
662
+ )
663
+ autotodos_parser.add_argument(
664
+ "--file",
665
+ "-f",
666
+ help="Scan text from file (scan command only)",
667
+ )
668
+ autotodos_parser.add_argument(
669
+ "--save",
670
+ action="store_true",
671
+ help="Save detections to event log (scan command only)",
672
+ )
673
+ autotodos_parser.add_argument(
674
+ "-y",
675
+ "--yes",
676
+ action="store_true",
677
+ help="Skip confirmation prompts",
678
+ )
679
+
605
680
  # Add summarize command
606
681
  from ..commands.summarize import add_summarize_parser
607
682
 
@@ -0,0 +1,83 @@
1
+ """
2
+ Commander parser module for claude-mpm CLI.
3
+
4
+ WHY: This module provides the commander subcommand for interactive instance management
5
+ and chat interface.
6
+
7
+ DESIGN DECISION: Uses subparser pattern consistent with other commands (run, agents, etc.)
8
+ to provide a clean interface for Commander mode.
9
+ """
10
+
11
+ import argparse
12
+ from pathlib import Path
13
+
14
+
15
+ def add_commander_subparser(subparsers: argparse._SubParsersAction) -> None:
16
+ """
17
+ Add commander subcommand parser.
18
+
19
+ WHY: Provides interactive mode for managing and chatting with multiple Claude instances.
20
+
21
+ Args:
22
+ subparsers: The subparsers object to add the commander parser to
23
+ """
24
+ commander_parser = subparsers.add_parser(
25
+ "commander",
26
+ help="Interactive Commander mode for managing multiple Claude instances",
27
+ description="""
28
+ Commander Mode - Interactive Instance Management
29
+
30
+ Commander provides an interactive REPL interface for:
31
+ - Starting and stopping Claude Code/MPM instances in tmux
32
+ - Connecting to instances and sending natural language commands
33
+ - Managing multiple concurrent projects
34
+ - Viewing instance status and output
35
+
36
+ Commands:
37
+ list, ls, instances List active instances
38
+ start <path> Start new instance at path
39
+ --framework <cc|mpm> Specify framework (default: cc)
40
+ --name <name> Specify instance name (default: dir name)
41
+ stop <name> Stop an instance
42
+ connect <name> Connect to an instance
43
+ disconnect Disconnect from current instance
44
+ status Show current session status
45
+ help Show help message
46
+ exit, quit, q Exit Commander
47
+
48
+ Natural Language:
49
+ When connected to an instance, any input that is not a built-in
50
+ command will be sent to the connected instance as a message.
51
+
52
+ Examples:
53
+ claude-mpm commander
54
+ > start ~/myproject --framework cc --name myapp
55
+ > connect myapp
56
+ > Fix the authentication bug in login.py
57
+ > disconnect
58
+ > exit
59
+ """,
60
+ formatter_class=argparse.RawDescriptionHelpFormatter,
61
+ )
62
+
63
+ # Optional: Port for internal services
64
+ commander_parser.add_argument(
65
+ "--port",
66
+ type=int,
67
+ default=8765,
68
+ help="Port for internal services (default: 8765)",
69
+ )
70
+
71
+ # Optional: State directory
72
+ commander_parser.add_argument(
73
+ "--state-dir",
74
+ type=Path,
75
+ help="Directory for state persistence (optional)",
76
+ )
77
+
78
+ # Debug mode
79
+ commander_parser.add_argument(
80
+ "--debug",
81
+ action="store_true",
82
+ help="Enable debug logging",
83
+ )
@@ -85,6 +85,16 @@ def add_run_arguments(parser: argparse.ArgumentParser) -> None:
85
85
  action="store_true",
86
86
  help="Pass --resume flag to Claude Code to resume the last conversation",
87
87
  )
88
+ run_group.add_argument(
89
+ "--chrome",
90
+ action="store_true",
91
+ help="Enable Claude in Chrome integration (passed to Claude Code)",
92
+ )
93
+ run_group.add_argument(
94
+ "--no-chrome",
95
+ action="store_true",
96
+ help="Disable Claude in Chrome integration (passed to Claude Code)",
97
+ )
88
98
 
89
99
  # Dependency checking options
90
100
  dep_group = parser.add_argument_group("dependency options")