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
@@ -0,0 +1,230 @@
1
+ """Embedding service for semantic search.
2
+
3
+ Generates vector embeddings using sentence-transformers (local) or
4
+ OpenAI API (cloud). Defaults to local model for zero-cost operation.
5
+ """
6
+
7
+ import asyncio
8
+ import logging
9
+ from typing import List, Literal, Optional
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ EmbeddingProvider = Literal["sentence-transformers", "openai"]
14
+
15
+
16
+ class EmbeddingService:
17
+ """Generate vector embeddings for semantic search.
18
+
19
+ Supports multiple providers:
20
+ - sentence-transformers: Local, free, good quality (default)
21
+ - openai: Cloud API, best quality, costs money
22
+
23
+ Attributes:
24
+ provider: Embedding provider to use
25
+ model: Model name for the provider
26
+ dimension: Embedding vector dimension
27
+
28
+ Example:
29
+ >>> embeddings = EmbeddingService(provider="sentence-transformers")
30
+ >>> vector = await embeddings.embed("Fix the login bug")
31
+ >>> len(vector)
32
+ 384
33
+ """
34
+
35
+ def __init__(
36
+ self,
37
+ provider: EmbeddingProvider = "sentence-transformers",
38
+ model: Optional[str] = None,
39
+ ):
40
+ """Initialize embedding service.
41
+
42
+ Args:
43
+ provider: Embedding provider ('sentence-transformers' or 'openai')
44
+ model: Model name (provider-specific default if None)
45
+ """
46
+ self.provider = provider
47
+ self._encoder = None
48
+ self._client = None
49
+
50
+ if provider == "sentence-transformers":
51
+ self.model = model or "all-MiniLM-L6-v2"
52
+ self.dimension = 384
53
+ self._init_sentence_transformers()
54
+ elif provider == "openai":
55
+ self.model = model or "text-embedding-3-small"
56
+ self.dimension = 1536
57
+ self._init_openai()
58
+ else:
59
+ raise ValueError(f"Unknown provider: {provider}")
60
+
61
+ logger.info(
62
+ "EmbeddingService initialized (provider: %s, model: %s, dim: %d)",
63
+ provider,
64
+ self.model,
65
+ self.dimension,
66
+ )
67
+
68
+ def _init_sentence_transformers(self) -> None:
69
+ """Initialize sentence-transformers encoder.
70
+
71
+ Lazy loads on first use to avoid startup delay.
72
+ """
73
+ # Lazy import to avoid dependency if not used
74
+ try:
75
+ from sentence_transformers import SentenceTransformer
76
+
77
+ self._encoder = SentenceTransformer(self.model)
78
+ logger.info("Loaded sentence-transformers model: %s", self.model)
79
+ except ImportError:
80
+ logger.error(
81
+ "sentence-transformers not installed. "
82
+ "Install with: pip install sentence-transformers"
83
+ )
84
+ raise
85
+
86
+ def _init_openai(self) -> None:
87
+ """Initialize OpenAI client.
88
+
89
+ Requires OPENAI_API_KEY environment variable.
90
+ """
91
+ try:
92
+ from openai import AsyncOpenAI
93
+
94
+ self._client = AsyncOpenAI()
95
+ logger.info("Initialized OpenAI client")
96
+ except ImportError:
97
+ logger.error("openai not installed. Install with: pip install openai")
98
+ raise
99
+
100
+ async def embed(self, text: str) -> List[float]:
101
+ """Generate embedding for text.
102
+
103
+ Args:
104
+ text: Text to embed
105
+
106
+ Returns:
107
+ Embedding vector as list of floats
108
+
109
+ Example:
110
+ >>> vector = await embeddings.embed("Fix the login bug")
111
+ >>> len(vector)
112
+ 384
113
+ """
114
+ if self.provider == "sentence-transformers":
115
+ return await self._embed_sentence_transformers(text)
116
+ if self.provider == "openai":
117
+ return await self._embed_openai(text)
118
+ raise ValueError(f"Unknown provider: {self.provider}")
119
+
120
+ async def embed_batch(self, texts: List[str]) -> List[List[float]]:
121
+ """Generate embeddings for multiple texts.
122
+
123
+ More efficient than calling embed() in a loop.
124
+
125
+ Args:
126
+ texts: List of texts to embed
127
+
128
+ Returns:
129
+ List of embedding vectors
130
+
131
+ Example:
132
+ >>> vectors = await embeddings.embed_batch([
133
+ ... "Fix the login bug",
134
+ ... "Update the README"
135
+ ... ])
136
+ >>> len(vectors)
137
+ 2
138
+ """
139
+ if self.provider == "sentence-transformers":
140
+ return await self._embed_batch_sentence_transformers(texts)
141
+ if self.provider == "openai":
142
+ return await self._embed_batch_openai(texts)
143
+ raise ValueError(f"Unknown provider: {self.provider}")
144
+
145
+ async def _embed_sentence_transformers(self, text: str) -> List[float]:
146
+ """Generate embedding using sentence-transformers.
147
+
148
+ Runs in executor to avoid blocking event loop.
149
+ """
150
+ if self._encoder is None:
151
+ raise RuntimeError("Encoder not initialized")
152
+
153
+ # Run encoding in executor (CPU-bound operation)
154
+ loop = asyncio.get_event_loop()
155
+ embedding = await loop.run_in_executor(
156
+ None, lambda: self._encoder.encode(text, convert_to_numpy=True)
157
+ )
158
+
159
+ return embedding.tolist()
160
+
161
+ async def _embed_batch_sentence_transformers(
162
+ self, texts: List[str]
163
+ ) -> List[List[float]]:
164
+ """Generate batch embeddings using sentence-transformers."""
165
+ if self._encoder is None:
166
+ raise RuntimeError("Encoder not initialized")
167
+
168
+ # Run batch encoding in executor
169
+ loop = asyncio.get_event_loop()
170
+ embeddings = await loop.run_in_executor(
171
+ None,
172
+ lambda: self._encoder.encode(
173
+ texts, convert_to_numpy=True, show_progress_bar=False
174
+ ),
175
+ )
176
+
177
+ return [emb.tolist() for emb in embeddings]
178
+
179
+ async def _embed_openai(self, text: str) -> List[float]:
180
+ """Generate embedding using OpenAI API."""
181
+ if self._client is None:
182
+ raise RuntimeError("OpenAI client not initialized")
183
+
184
+ response = await self._client.embeddings.create(
185
+ model=self.model,
186
+ input=text,
187
+ )
188
+
189
+ return response.data[0].embedding
190
+
191
+ async def _embed_batch_openai(self, texts: List[str]) -> List[List[float]]:
192
+ """Generate batch embeddings using OpenAI API."""
193
+ if self._client is None:
194
+ raise RuntimeError("OpenAI client not initialized")
195
+
196
+ response = await self._client.embeddings.create(
197
+ model=self.model,
198
+ input=texts,
199
+ )
200
+
201
+ return [item.embedding for item in response.data]
202
+
203
+ def cosine_similarity(self, vec1: List[float], vec2: List[float]) -> float:
204
+ """Calculate cosine similarity between two vectors.
205
+
206
+ Args:
207
+ vec1: First vector
208
+ vec2: Second vector
209
+
210
+ Returns:
211
+ Similarity score in range [-1, 1] (1 = identical, -1 = opposite)
212
+
213
+ Example:
214
+ >>> sim = embeddings.cosine_similarity(vec1, vec2)
215
+ >>> print(f"Similarity: {sim:.3f}")
216
+ """
217
+ import math
218
+
219
+ # Dot product
220
+ dot_product = sum(a * b for a, b in zip(vec1, vec2))
221
+
222
+ # Magnitudes
223
+ mag1 = math.sqrt(sum(a * a for a in vec1))
224
+ mag2 = math.sqrt(sum(b * b for b in vec2))
225
+
226
+ # Avoid division by zero
227
+ if mag1 == 0 or mag2 == 0:
228
+ return 0.0
229
+
230
+ return dot_product / (mag1 * mag2)
@@ -0,0 +1,310 @@
1
+ """Entity extraction from conversation messages.
2
+
3
+ Extracts structured entities like files, functions, errors, and commands
4
+ from conversation content for enhanced search and filtering.
5
+ """
6
+
7
+ import logging
8
+ import re
9
+ from dataclasses import dataclass
10
+ from enum import Enum
11
+ from typing import Any, Dict, List
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class EntityType(Enum):
17
+ """Types of entities that can be extracted.
18
+
19
+ Attributes:
20
+ FILE: File path (e.g., "src/auth.py")
21
+ FUNCTION: Function or method name (e.g., "login()")
22
+ CLASS: Class name (e.g., "UserService")
23
+ ERROR: Error type or message (e.g., "ValueError")
24
+ COMMAND: Shell command (e.g., "pytest tests/")
25
+ URL: Web URL (e.g., "https://example.com")
26
+ PACKAGE: Package or module name (e.g., "requests")
27
+ """
28
+
29
+ FILE = "file"
30
+ FUNCTION = "function"
31
+ CLASS = "class"
32
+ ERROR = "error"
33
+ COMMAND = "command"
34
+ URL = "url"
35
+ PACKAGE = "package"
36
+
37
+
38
+ @dataclass
39
+ class Entity:
40
+ """Extracted entity from conversation.
41
+
42
+ Attributes:
43
+ type: Entity type
44
+ value: Entity value (file path, function name, etc.)
45
+ context: Surrounding context (optional)
46
+ metadata: Additional metadata
47
+
48
+ Example:
49
+ >>> entity = Entity(
50
+ ... type=EntityType.FILE,
51
+ ... value="src/auth.py",
52
+ ... context="Fix the login bug in auth.py"
53
+ ... )
54
+ """
55
+
56
+ type: EntityType
57
+ value: str
58
+ context: str = ""
59
+ metadata: Dict[str, Any] = None
60
+
61
+ def __post_init__(self) -> None:
62
+ """Initialize metadata if not provided."""
63
+ if self.metadata is None:
64
+ self.metadata = {}
65
+
66
+ def to_dict(self) -> Dict[str, Any]:
67
+ """Convert to dictionary for JSON serialization."""
68
+ return {
69
+ "type": self.type.value,
70
+ "value": self.value,
71
+ "context": self.context,
72
+ "metadata": self.metadata,
73
+ }
74
+
75
+ @classmethod
76
+ def from_dict(cls, data: Dict[str, Any]) -> "Entity":
77
+ """Create Entity from dictionary."""
78
+ return cls(
79
+ type=EntityType(data["type"]),
80
+ value=data["value"],
81
+ context=data.get("context", ""),
82
+ metadata=data.get("metadata", {}),
83
+ )
84
+
85
+
86
+ class EntityExtractor:
87
+ """Extracts entities from conversation messages.
88
+
89
+ Uses regex patterns to identify files, functions, errors, commands, etc.
90
+
91
+ Example:
92
+ >>> extractor = EntityExtractor()
93
+ >>> entities = extractor.extract("Fix the login bug in src/auth.py")
94
+ >>> entities[0].type
95
+ <EntityType.FILE: 'file'>
96
+ >>> entities[0].value
97
+ 'src/auth.py'
98
+ """
99
+
100
+ # File patterns (common extensions and paths)
101
+ FILE_PATTERNS = [
102
+ r"\b[\w/\-\.]+\.(?:py|js|ts|tsx|jsx|java|cpp|c|h|go|rs|rb|php|cs|swift|kt|md|txt|json|yaml|yml|toml|xml|html|css|scss|sh|bash)\b",
103
+ r"\b(?:src|lib|tests?|scripts?|docs?|config)/[\w/\-\.]+\b",
104
+ ]
105
+
106
+ # Function patterns (with parens or common prefixes)
107
+ FUNCTION_PATTERNS = [
108
+ r"\b[a-z_][a-z0-9_]*\(\)",
109
+ r"\bdef\s+([a-z_][a-z0-9_]*)",
110
+ r"\bfunction\s+([a-z_][a-z0-9_]*)",
111
+ r"\basync\s+(?:def|function)\s+([a-z_][a-z0-9_]*)",
112
+ ]
113
+
114
+ # Class patterns (PascalCase)
115
+ CLASS_PATTERNS = [
116
+ r"\bclass\s+([A-Z][a-zA-Z0-9_]*)",
117
+ r"\b([A-Z][a-zA-Z0-9_]+(?:Service|Controller|Manager|Handler|Repository|Model|View))\b",
118
+ ]
119
+
120
+ # Error patterns
121
+ ERROR_PATTERNS = [
122
+ r"\b([A-Z][a-zA-Z]*Error)\b",
123
+ r"\b([A-Z][a-zA-Z]*Exception)\b",
124
+ r"error:\s+(.+?)(?:\n|$)",
125
+ ]
126
+
127
+ # Command patterns (common CLI tools)
128
+ COMMAND_PATTERNS = [
129
+ r"\b(?:npm|yarn|pnpm|pip|poetry|cargo|go|make|docker|kubectl|git)\s+[\w\-]+",
130
+ r"\bpytest\s+[\w/\-\.]+",
131
+ r"\bpython\s+[\w/\-\.]+",
132
+ ]
133
+
134
+ # URL patterns
135
+ URL_PATTERN = r"https?://[\w\.\-/\?=&#%]+"
136
+
137
+ # Package patterns
138
+ PACKAGE_PATTERNS = [
139
+ r"\bimport\s+([\w\.]+)",
140
+ r"\bfrom\s+([\w\.]+)\s+import",
141
+ r"\brequire\(['\"]([\w\-@/]+)['\"]",
142
+ r"\buse\s+([\w:]+)",
143
+ ]
144
+
145
+ def extract(self, text: str) -> List[Entity]:
146
+ """Extract all entities from text.
147
+
148
+ Args:
149
+ text: Text to extract entities from
150
+
151
+ Returns:
152
+ List of extracted entities
153
+
154
+ Example:
155
+ >>> entities = extractor.extract("Fix the login bug in src/auth.py")
156
+ """
157
+ entities: List[Entity] = []
158
+
159
+ # Extract files
160
+ for pattern in self.FILE_PATTERNS:
161
+ for match in re.finditer(pattern, text):
162
+ entities.append(
163
+ Entity(
164
+ type=EntityType.FILE,
165
+ value=match.group(0),
166
+ context=self._get_context(text, match.start(), match.end()),
167
+ )
168
+ )
169
+
170
+ # Extract functions
171
+ for pattern in self.FUNCTION_PATTERNS:
172
+ for match in re.finditer(pattern, text):
173
+ # Use group 1 if capturing group exists, else group 0
174
+ value = match.group(1) if match.lastindex else match.group(0)
175
+ entities.append(
176
+ Entity(
177
+ type=EntityType.FUNCTION,
178
+ value=value.rstrip("()"), # Remove parens
179
+ context=self._get_context(text, match.start(), match.end()),
180
+ )
181
+ )
182
+
183
+ # Extract classes
184
+ for pattern in self.CLASS_PATTERNS:
185
+ for match in re.finditer(pattern, text):
186
+ value = match.group(1) if match.lastindex else match.group(0)
187
+ entities.append(
188
+ Entity(
189
+ type=EntityType.CLASS,
190
+ value=value,
191
+ context=self._get_context(text, match.start(), match.end()),
192
+ )
193
+ )
194
+
195
+ # Extract errors
196
+ for pattern in self.ERROR_PATTERNS:
197
+ for match in re.finditer(pattern, text):
198
+ value = match.group(1) if match.lastindex else match.group(0)
199
+ entities.append(
200
+ Entity(
201
+ type=EntityType.ERROR,
202
+ value=value.strip(),
203
+ context=self._get_context(text, match.start(), match.end()),
204
+ )
205
+ )
206
+
207
+ # Extract commands
208
+ for pattern in self.COMMAND_PATTERNS:
209
+ for match in re.finditer(pattern, text):
210
+ entities.append(
211
+ Entity(
212
+ type=EntityType.COMMAND,
213
+ value=match.group(0),
214
+ context=self._get_context(text, match.start(), match.end()),
215
+ )
216
+ )
217
+
218
+ # Extract URLs
219
+ for match in re.finditer(self.URL_PATTERN, text):
220
+ entities.append(
221
+ Entity(
222
+ type=EntityType.URL,
223
+ value=match.group(0),
224
+ context=self._get_context(text, match.start(), match.end()),
225
+ )
226
+ )
227
+
228
+ # Extract packages
229
+ for pattern in self.PACKAGE_PATTERNS:
230
+ for match in re.finditer(pattern, text):
231
+ value = match.group(1) if match.lastindex else match.group(0)
232
+ entities.append(
233
+ Entity(
234
+ type=EntityType.PACKAGE,
235
+ value=value,
236
+ context=self._get_context(text, match.start(), match.end()),
237
+ )
238
+ )
239
+
240
+ # Deduplicate entities (same type + value)
241
+ seen = set()
242
+ unique_entities = []
243
+ for entity in entities:
244
+ key = (entity.type, entity.value)
245
+ if key not in seen:
246
+ seen.add(key)
247
+ unique_entities.append(entity)
248
+
249
+ logger.debug("Extracted %d unique entities from text", len(unique_entities))
250
+ return unique_entities
251
+
252
+ def _get_context(self, text: str, start: int, end: int, window: int = 50) -> str:
253
+ """Get surrounding context for entity.
254
+
255
+ Args:
256
+ text: Full text
257
+ start: Entity start position
258
+ end: Entity end position
259
+ window: Characters to include before/after
260
+
261
+ Returns:
262
+ Context string with entity highlighted
263
+ """
264
+ context_start = max(0, start - window)
265
+ context_end = min(len(text), end + window)
266
+
267
+ context = text[context_start:context_end]
268
+
269
+ # Truncate at sentence boundaries if possible
270
+ if context_start > 0 and ". " in context[:window]:
271
+ context = context.split(". ", 1)[1]
272
+ if context_end < len(text) and ". " in context[-window:]:
273
+ context = context.rsplit(". ", 1)[0] + "."
274
+
275
+ return context.strip()
276
+
277
+ def filter_by_type(
278
+ self, entities: List[Entity], entity_type: EntityType
279
+ ) -> List[Entity]:
280
+ """Filter entities by type.
281
+
282
+ Args:
283
+ entities: List of entities to filter
284
+ entity_type: Type to filter for
285
+
286
+ Returns:
287
+ Filtered list of entities
288
+
289
+ Example:
290
+ >>> files = extractor.filter_by_type(entities, EntityType.FILE)
291
+ """
292
+ return [e for e in entities if e.type == entity_type]
293
+
294
+ def get_unique_values(
295
+ self, entities: List[Entity], entity_type: EntityType
296
+ ) -> List[str]:
297
+ """Get unique entity values for a type.
298
+
299
+ Args:
300
+ entities: List of entities
301
+ entity_type: Type to extract values for
302
+
303
+ Returns:
304
+ List of unique values
305
+
306
+ Example:
307
+ >>> files = extractor.get_unique_values(entities, EntityType.FILE)
308
+ ['src/auth.py', 'tests/test_auth.py']
309
+ """
310
+ return list({e.value for e in entities if e.type == entity_type})