claude-mpm 5.4.41__py3-none-any.whl → 5.6.72__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of claude-mpm might be problematic. Click here for more details.

Files changed (490) 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 +161 -298
  6. claude_mpm/agents/WORKFLOW.md +2 -0
  7. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  8. claude_mpm/auth/__init__.py +35 -0
  9. claude_mpm/auth/callback_server.py +328 -0
  10. claude_mpm/auth/models.py +104 -0
  11. claude_mpm/auth/oauth_manager.py +266 -0
  12. claude_mpm/auth/providers/__init__.py +12 -0
  13. claude_mpm/auth/providers/base.py +165 -0
  14. claude_mpm/auth/providers/google.py +261 -0
  15. claude_mpm/auth/token_storage.py +252 -0
  16. claude_mpm/cli/__init__.py +5 -1
  17. claude_mpm/cli/commands/agents.py +2 -4
  18. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  19. claude_mpm/cli/commands/autotodos.py +566 -0
  20. claude_mpm/cli/commands/commander.py +216 -0
  21. claude_mpm/cli/commands/configure.py +620 -21
  22. claude_mpm/cli/commands/configure_agent_display.py +3 -1
  23. claude_mpm/cli/commands/hook_errors.py +60 -60
  24. claude_mpm/cli/commands/mcp.py +29 -17
  25. claude_mpm/cli/commands/mcp_command_router.py +39 -0
  26. claude_mpm/cli/commands/mcp_service_commands.py +304 -0
  27. claude_mpm/cli/commands/monitor.py +2 -2
  28. claude_mpm/cli/commands/mpm_init/core.py +15 -8
  29. claude_mpm/cli/commands/oauth.py +481 -0
  30. claude_mpm/cli/commands/profile.py +9 -10
  31. claude_mpm/cli/commands/run.py +35 -3
  32. claude_mpm/cli/commands/skill_source.py +51 -2
  33. claude_mpm/cli/commands/skills.py +182 -32
  34. claude_mpm/cli/executor.py +129 -16
  35. claude_mpm/cli/helpers.py +1 -1
  36. claude_mpm/cli/interactive/__init__.py +10 -0
  37. claude_mpm/cli/interactive/agent_wizard.py +30 -50
  38. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  39. claude_mpm/cli/interactive/skill_selector.py +481 -0
  40. claude_mpm/cli/parsers/base_parser.py +89 -1
  41. claude_mpm/cli/parsers/commander_parser.py +116 -0
  42. claude_mpm/cli/parsers/mcp_parser.py +79 -0
  43. claude_mpm/cli/parsers/oauth_parser.py +165 -0
  44. claude_mpm/cli/parsers/profile_parser.py +0 -1
  45. claude_mpm/cli/parsers/run_parser.py +10 -0
  46. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  47. claude_mpm/cli/parsers/skills_parser.py +2 -3
  48. claude_mpm/cli/startup.py +662 -524
  49. claude_mpm/cli/startup_display.py +76 -7
  50. claude_mpm/cli/startup_logging.py +2 -2
  51. claude_mpm/cli/utils.py +7 -3
  52. claude_mpm/commander/__init__.py +78 -0
  53. claude_mpm/commander/adapters/__init__.py +60 -0
  54. claude_mpm/commander/adapters/auggie.py +260 -0
  55. claude_mpm/commander/adapters/base.py +288 -0
  56. claude_mpm/commander/adapters/claude_code.py +392 -0
  57. claude_mpm/commander/adapters/codex.py +237 -0
  58. claude_mpm/commander/adapters/communication.py +366 -0
  59. claude_mpm/commander/adapters/example_usage.py +310 -0
  60. claude_mpm/commander/adapters/mpm.py +389 -0
  61. claude_mpm/commander/adapters/registry.py +204 -0
  62. claude_mpm/commander/api/__init__.py +16 -0
  63. claude_mpm/commander/api/app.py +121 -0
  64. claude_mpm/commander/api/errors.py +133 -0
  65. claude_mpm/commander/api/routes/__init__.py +8 -0
  66. claude_mpm/commander/api/routes/events.py +184 -0
  67. claude_mpm/commander/api/routes/inbox.py +171 -0
  68. claude_mpm/commander/api/routes/messages.py +148 -0
  69. claude_mpm/commander/api/routes/projects.py +271 -0
  70. claude_mpm/commander/api/routes/sessions.py +226 -0
  71. claude_mpm/commander/api/routes/work.py +296 -0
  72. claude_mpm/commander/api/schemas.py +186 -0
  73. claude_mpm/commander/chat/__init__.py +7 -0
  74. claude_mpm/commander/chat/cli.py +149 -0
  75. claude_mpm/commander/chat/commands.py +122 -0
  76. claude_mpm/commander/chat/repl.py +1821 -0
  77. claude_mpm/commander/config.py +51 -0
  78. claude_mpm/commander/config_loader.py +115 -0
  79. claude_mpm/commander/core/__init__.py +10 -0
  80. claude_mpm/commander/core/block_manager.py +325 -0
  81. claude_mpm/commander/core/response_manager.py +323 -0
  82. claude_mpm/commander/daemon.py +603 -0
  83. claude_mpm/commander/env_loader.py +59 -0
  84. claude_mpm/commander/events/__init__.py +26 -0
  85. claude_mpm/commander/events/manager.py +392 -0
  86. claude_mpm/commander/frameworks/__init__.py +12 -0
  87. claude_mpm/commander/frameworks/base.py +233 -0
  88. claude_mpm/commander/frameworks/claude_code.py +58 -0
  89. claude_mpm/commander/frameworks/mpm.py +57 -0
  90. claude_mpm/commander/git/__init__.py +5 -0
  91. claude_mpm/commander/git/worktree_manager.py +212 -0
  92. claude_mpm/commander/inbox/__init__.py +16 -0
  93. claude_mpm/commander/inbox/dedup.py +128 -0
  94. claude_mpm/commander/inbox/inbox.py +224 -0
  95. claude_mpm/commander/inbox/models.py +70 -0
  96. claude_mpm/commander/instance_manager.py +865 -0
  97. claude_mpm/commander/llm/__init__.py +6 -0
  98. claude_mpm/commander/llm/openrouter_client.py +167 -0
  99. claude_mpm/commander/llm/summarizer.py +70 -0
  100. claude_mpm/commander/memory/__init__.py +45 -0
  101. claude_mpm/commander/memory/compression.py +347 -0
  102. claude_mpm/commander/memory/embeddings.py +230 -0
  103. claude_mpm/commander/memory/entities.py +310 -0
  104. claude_mpm/commander/memory/example_usage.py +290 -0
  105. claude_mpm/commander/memory/integration.py +325 -0
  106. claude_mpm/commander/memory/search.py +381 -0
  107. claude_mpm/commander/memory/store.py +657 -0
  108. claude_mpm/commander/models/__init__.py +18 -0
  109. claude_mpm/commander/models/events.py +127 -0
  110. claude_mpm/commander/models/project.py +162 -0
  111. claude_mpm/commander/models/work.py +214 -0
  112. claude_mpm/commander/parsing/__init__.py +20 -0
  113. claude_mpm/commander/parsing/extractor.py +132 -0
  114. claude_mpm/commander/parsing/output_parser.py +270 -0
  115. claude_mpm/commander/parsing/patterns.py +100 -0
  116. claude_mpm/commander/persistence/__init__.py +11 -0
  117. claude_mpm/commander/persistence/event_store.py +274 -0
  118. claude_mpm/commander/persistence/state_store.py +403 -0
  119. claude_mpm/commander/persistence/work_store.py +164 -0
  120. claude_mpm/commander/polling/__init__.py +13 -0
  121. claude_mpm/commander/polling/event_detector.py +104 -0
  122. claude_mpm/commander/polling/output_buffer.py +49 -0
  123. claude_mpm/commander/polling/output_poller.py +153 -0
  124. claude_mpm/commander/project_session.py +268 -0
  125. claude_mpm/commander/proxy/__init__.py +12 -0
  126. claude_mpm/commander/proxy/formatter.py +89 -0
  127. claude_mpm/commander/proxy/output_handler.py +191 -0
  128. claude_mpm/commander/proxy/relay.py +155 -0
  129. claude_mpm/commander/registry.py +410 -0
  130. claude_mpm/commander/runtime/__init__.py +10 -0
  131. claude_mpm/commander/runtime/executor.py +191 -0
  132. claude_mpm/commander/runtime/monitor.py +346 -0
  133. claude_mpm/commander/session/__init__.py +6 -0
  134. claude_mpm/commander/session/context.py +81 -0
  135. claude_mpm/commander/session/manager.py +59 -0
  136. claude_mpm/commander/tmux_orchestrator.py +362 -0
  137. claude_mpm/commander/web/__init__.py +1 -0
  138. claude_mpm/commander/work/__init__.py +30 -0
  139. claude_mpm/commander/work/executor.py +207 -0
  140. claude_mpm/commander/work/queue.py +405 -0
  141. claude_mpm/commander/workflow/__init__.py +27 -0
  142. claude_mpm/commander/workflow/event_handler.py +241 -0
  143. claude_mpm/commander/workflow/notifier.py +146 -0
  144. claude_mpm/commands/mpm-config.md +8 -0
  145. claude_mpm/commands/mpm-doctor.md +8 -0
  146. claude_mpm/commands/mpm-help.md +8 -0
  147. claude_mpm/commands/mpm-init.md +8 -0
  148. claude_mpm/commands/mpm-monitor.md +8 -0
  149. claude_mpm/commands/mpm-organize.md +8 -0
  150. claude_mpm/commands/mpm-postmortem.md +8 -0
  151. claude_mpm/commands/mpm-session-resume.md +9 -1
  152. claude_mpm/commands/mpm-status.md +8 -0
  153. claude_mpm/commands/mpm-ticket-view.md +8 -0
  154. claude_mpm/commands/mpm-version.md +8 -0
  155. claude_mpm/commands/mpm.md +8 -0
  156. claude_mpm/config/agent_presets.py +8 -7
  157. claude_mpm/config/skill_sources.py +16 -0
  158. claude_mpm/constants.py +6 -0
  159. claude_mpm/core/claude_runner.py +154 -2
  160. claude_mpm/core/config.py +35 -22
  161. claude_mpm/core/config_constants.py +74 -9
  162. claude_mpm/core/constants.py +56 -12
  163. claude_mpm/core/hook_manager.py +53 -4
  164. claude_mpm/core/interactive_session.py +12 -11
  165. claude_mpm/core/logger.py +26 -9
  166. claude_mpm/core/logging_utils.py +39 -13
  167. claude_mpm/core/network_config.py +148 -0
  168. claude_mpm/core/oneshot_session.py +7 -6
  169. claude_mpm/core/optimized_startup.py +3 -1
  170. claude_mpm/core/output_style_manager.py +66 -18
  171. claude_mpm/core/shared/config_loader.py +3 -1
  172. claude_mpm/core/socketio_pool.py +47 -15
  173. claude_mpm/core/unified_config.py +54 -8
  174. claude_mpm/core/unified_paths.py +95 -90
  175. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
  176. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
  177. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
  178. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
  179. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
  180. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
  181. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
  182. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
  183. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
  184. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
  185. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  186. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
  187. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
  188. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
  189. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
  190. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
  191. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
  192. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
  193. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
  194. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
  195. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
  196. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
  197. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
  198. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
  199. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
  200. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
  201. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
  202. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
  203. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
  204. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
  205. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
  206. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  207. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
  208. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  209. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
  210. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
  211. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
  212. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
  213. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
  214. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{N4qtv3Hx.js → DR8nis88.js} +2 -2
  215. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
  216. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  217. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
  218. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
  219. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
  220. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
  221. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
  222. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
  223. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  224. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
  225. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
  226. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
  227. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DjhvlsAc.js → NqQ1dWOy.js} +1 -1
  228. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
  229. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
  230. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
  231. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
  232. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
  233. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
  234. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
  235. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
  236. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.CAGBuiOw.js → 0.RgBboRvH.js} +1 -1
  237. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
  238. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
  239. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
  240. claude_mpm/dashboard/static/svelte-build/index.html +11 -11
  241. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  242. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  243. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  244. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  245. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  246. claude_mpm/experimental/cli_enhancements.py +2 -1
  247. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  248. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  249. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  250. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  251. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  252. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  253. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  254. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
  255. claude_mpm/hooks/claude_hooks/event_handlers.py +466 -136
  256. claude_mpm/hooks/claude_hooks/hook_handler.py +204 -104
  257. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  258. claude_mpm/hooks/claude_hooks/installer.py +291 -59
  259. claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
  260. claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
  261. claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
  262. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  263. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  264. claude_mpm/hooks/claude_hooks/services/__pycache__/container.cpython-311.pyc +0 -0
  265. claude_mpm/hooks/claude_hooks/services/__pycache__/protocols.cpython-311.pyc +0 -0
  266. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  267. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  268. claude_mpm/hooks/claude_hooks/services/connection_manager.py +41 -26
  269. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
  270. claude_mpm/hooks/claude_hooks/services/container.py +326 -0
  271. claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
  272. claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
  273. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
  274. claude_mpm/hooks/kuzu_memory_hook.py +5 -5
  275. claude_mpm/hooks/session_resume_hook.py +89 -1
  276. claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
  277. claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
  278. claude_mpm/init.py +224 -4
  279. claude_mpm/mcp/__init__.py +9 -0
  280. claude_mpm/mcp/google_workspace_server.py +610 -0
  281. claude_mpm/scripts/claude-hook-handler.sh +46 -19
  282. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  283. claude_mpm/services/agents/agent_selection_service.py +2 -2
  284. claude_mpm/services/agents/cache_git_manager.py +1 -1
  285. claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -1
  286. claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
  287. claude_mpm/services/agents/deployment/agent_template_builder.py +37 -17
  288. claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
  289. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  290. claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
  291. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +36 -8
  292. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +50 -26
  293. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  294. claude_mpm/services/agents/git_source_manager.py +21 -2
  295. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  296. claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
  297. claude_mpm/services/agents/sources/git_source_sync_service.py +116 -5
  298. claude_mpm/services/agents/startup_sync.py +5 -2
  299. claude_mpm/services/cli/__init__.py +3 -0
  300. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  301. claude_mpm/services/cli/session_resume_helper.py +10 -2
  302. claude_mpm/services/command_deployment_service.py +44 -26
  303. claude_mpm/services/delegation_detector.py +175 -0
  304. claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
  305. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  306. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  307. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  308. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  309. claude_mpm/services/diagnostics/models.py +14 -1
  310. claude_mpm/services/event_log.py +325 -0
  311. claude_mpm/services/hook_installer_service.py +77 -8
  312. claude_mpm/services/infrastructure/__init__.py +4 -0
  313. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  314. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  315. claude_mpm/services/mcp_config_manager.py +99 -19
  316. claude_mpm/services/mcp_service_registry.py +294 -0
  317. claude_mpm/services/monitor/daemon_manager.py +15 -4
  318. claude_mpm/services/monitor/management/lifecycle.py +8 -3
  319. claude_mpm/services/monitor/server.py +111 -16
  320. claude_mpm/services/pm_skills_deployer.py +302 -94
  321. claude_mpm/services/profile_manager.py +10 -4
  322. claude_mpm/services/skills/git_skill_source_manager.py +192 -29
  323. claude_mpm/services/skills/selective_skill_deployer.py +211 -46
  324. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  325. claude_mpm/services/skills_deployer.py +192 -70
  326. claude_mpm/services/socketio/handlers/hook.py +14 -7
  327. claude_mpm/services/socketio/server/main.py +12 -4
  328. claude_mpm/skills/__init__.py +2 -1
  329. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  330. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  331. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  332. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  333. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  334. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  335. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  336. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  337. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  338. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  339. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  340. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  341. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  342. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  343. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  344. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  345. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  346. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  347. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  348. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  349. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  350. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  351. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  352. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  353. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  354. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  355. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  356. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  357. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  358. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  359. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  360. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  361. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  362. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  363. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  364. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  365. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  366. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  367. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  368. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  369. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  370. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  371. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  372. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  373. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  374. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  375. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  376. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  377. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  378. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  379. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  380. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  381. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  382. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  383. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  384. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  385. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  386. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  387. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  388. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  389. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  390. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  391. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  392. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  393. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  394. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  395. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  396. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  397. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  398. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  399. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  400. claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
  401. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  402. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  403. claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
  404. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  405. claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
  406. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  407. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  408. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  409. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  410. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  411. claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
  412. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  413. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  414. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  415. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  416. claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
  417. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  418. claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
  419. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  420. claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
  421. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  422. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  423. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  424. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  425. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  426. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  427. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  428. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  429. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  430. claude_mpm/skills/bundled/security-scanning.md +112 -0
  431. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  432. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  433. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  434. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  435. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  436. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  437. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  438. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  439. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  440. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  441. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  442. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  443. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  444. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  445. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  446. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  447. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  448. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  449. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  450. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  451. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  452. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  453. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  454. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  455. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  456. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  457. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  458. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  459. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  460. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  461. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  462. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  463. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  464. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  465. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  466. claude_mpm/skills/registry.py +295 -90
  467. claude_mpm/skills/skill_manager.py +29 -23
  468. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  469. claude_mpm/utils/agent_dependency_loader.py +103 -4
  470. claude_mpm/utils/robust_installer.py +45 -24
  471. claude_mpm-5.6.72.dist-info/METADATA +416 -0
  472. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/RECORD +477 -159
  473. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/WHEEL +1 -1
  474. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/entry_points.txt +2 -0
  475. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
  476. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
  477. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
  478. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
  479. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +0 -1
  480. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
  481. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
  482. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
  483. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
  484. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
  485. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  486. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  487. claude_mpm-5.4.41.dist-info/METADATA +0 -998
  488. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/licenses/LICENSE +0 -0
  489. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  490. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,204 @@
1
+ """Adapter registry for runtime detection and selection.
2
+
3
+ This module provides a registry for managing runtime adapters, with
4
+ automatic detection of available runtimes on the system.
5
+ """
6
+
7
+ import logging
8
+ import shutil
9
+ from typing import Dict, List, Optional, Type
10
+
11
+ from .base import RuntimeAdapter
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class AdapterRegistry:
17
+ """Registry for managing runtime adapters.
18
+
19
+ Provides centralized registration, retrieval, and auto-detection
20
+ of available runtime adapters.
21
+
22
+ Example:
23
+ >>> # Register adapter
24
+ >>> AdapterRegistry.register('claude-code', ClaudeCodeAdapter)
25
+ >>> # Get adapter instance
26
+ >>> adapter = AdapterRegistry.get('claude-code')
27
+ >>> # Detect available runtimes
28
+ >>> available = AdapterRegistry.detect_available()
29
+ >>> print(available)
30
+ ['claude-code', 'mpm']
31
+ """
32
+
33
+ _adapters: Dict[str, Type[RuntimeAdapter]] = {}
34
+ _runtime_commands: Dict[str, str] = {
35
+ "claude-code": "claude",
36
+ "auggie": "auggie",
37
+ "codex": "codex",
38
+ "mpm": "claude", # MPM uses claude with extra config
39
+ }
40
+
41
+ @classmethod
42
+ def register(cls, name: str, adapter_class: Type[RuntimeAdapter]) -> None:
43
+ """Register a runtime adapter.
44
+
45
+ Args:
46
+ name: Unique identifier for the adapter
47
+ adapter_class: RuntimeAdapter subclass to register
48
+
49
+ Example:
50
+ >>> AdapterRegistry.register('my-runtime', MyAdapter)
51
+ """
52
+ cls._adapters[name] = adapter_class
53
+ logger.debug(f"Registered adapter: {name}")
54
+
55
+ @classmethod
56
+ def unregister(cls, name: str) -> None:
57
+ """Unregister a runtime adapter.
58
+
59
+ Args:
60
+ name: Identifier of adapter to unregister
61
+
62
+ Example:
63
+ >>> AdapterRegistry.unregister('my-runtime')
64
+ """
65
+ if name in cls._adapters:
66
+ del cls._adapters[name]
67
+ logger.debug(f"Unregistered adapter: {name}")
68
+
69
+ @classmethod
70
+ def get(cls, name: str) -> Optional[RuntimeAdapter]:
71
+ """Get adapter instance by name.
72
+
73
+ Args:
74
+ name: Identifier of adapter to retrieve
75
+
76
+ Returns:
77
+ RuntimeAdapter instance if found, None otherwise
78
+
79
+ Example:
80
+ >>> adapter = AdapterRegistry.get('claude-code')
81
+ >>> if adapter:
82
+ ... print(adapter.name)
83
+ 'claude-code'
84
+ """
85
+ if name in cls._adapters:
86
+ adapter = cls._adapters[name]()
87
+ logger.debug(f"Retrieved adapter: {name}")
88
+ return adapter
89
+ logger.warning(f"Adapter not found: {name}")
90
+ return None
91
+
92
+ @classmethod
93
+ def list_registered(cls) -> List[str]:
94
+ """List all registered adapter names.
95
+
96
+ Returns:
97
+ List of registered adapter identifiers
98
+
99
+ Example:
100
+ >>> registered = AdapterRegistry.list_registered()
101
+ >>> print(registered)
102
+ ['claude-code', 'auggie', 'codex', 'mpm']
103
+ """
104
+ return list(cls._adapters.keys())
105
+
106
+ @classmethod
107
+ def detect_available(cls) -> List[str]:
108
+ """Detect which runtimes are available on this system.
109
+
110
+ Checks for CLI commands in PATH to determine which runtimes
111
+ are installed and accessible.
112
+
113
+ Returns:
114
+ List of available runtime identifiers
115
+
116
+ Example:
117
+ >>> available = AdapterRegistry.detect_available()
118
+ >>> if 'claude-code' in available:
119
+ ... print("Claude Code is available")
120
+ """
121
+ available = []
122
+
123
+ for name, command in cls._runtime_commands.items():
124
+ if name in cls._adapters and shutil.which(command):
125
+ available.append(name)
126
+ logger.debug(f"Detected available runtime: {name} (command: {command})")
127
+
128
+ logger.info(f"Available runtimes: {available}")
129
+ return available
130
+
131
+ @classmethod
132
+ def get_default(cls) -> Optional[RuntimeAdapter]:
133
+ """Get the best available adapter.
134
+
135
+ Selection priority: mpm > claude-code > auggie > codex
136
+
137
+ Returns:
138
+ RuntimeAdapter instance for best available runtime, or None
139
+
140
+ Example:
141
+ >>> adapter = AdapterRegistry.get_default()
142
+ >>> if adapter:
143
+ ... print(f"Using {adapter.name}")
144
+ """
145
+ # Priority order: MPM has most features, then Claude Code, etc.
146
+ priority = ["mpm", "claude-code", "auggie", "codex"]
147
+
148
+ available = cls.detect_available()
149
+
150
+ for name in priority:
151
+ if name in available:
152
+ adapter = cls.get(name)
153
+ logger.info(f"Selected default adapter: {name}")
154
+ return adapter
155
+
156
+ logger.warning("No adapters available")
157
+ return None
158
+
159
+ @classmethod
160
+ def is_available(cls, name: str) -> bool:
161
+ """Check if a specific runtime is available.
162
+
163
+ Args:
164
+ name: Runtime identifier to check
165
+
166
+ Returns:
167
+ True if runtime is registered and command is in PATH
168
+
169
+ Example:
170
+ >>> if AdapterRegistry.is_available('claude-code'):
171
+ ... adapter = AdapterRegistry.get('claude-code')
172
+ """
173
+ return name in cls.detect_available()
174
+
175
+ @classmethod
176
+ def get_command(cls, name: str) -> Optional[str]:
177
+ """Get CLI command for a runtime.
178
+
179
+ Args:
180
+ name: Runtime identifier
181
+
182
+ Returns:
183
+ CLI command string if found, None otherwise
184
+
185
+ Example:
186
+ >>> cmd = AdapterRegistry.get_command('claude-code')
187
+ >>> print(cmd)
188
+ 'claude'
189
+ """
190
+ return cls._runtime_commands.get(name)
191
+
192
+ @classmethod
193
+ def register_command(cls, name: str, command: str) -> None:
194
+ """Register CLI command for a runtime.
195
+
196
+ Args:
197
+ name: Runtime identifier
198
+ command: CLI command to invoke runtime
199
+
200
+ Example:
201
+ >>> AdapterRegistry.register_command('my-runtime', 'my-cli')
202
+ """
203
+ cls._runtime_commands[name] = command
204
+ logger.debug(f"Registered command for {name}: {command}")
@@ -0,0 +1,16 @@
1
+ """MPM Commander REST API.
2
+
3
+ This package provides a FastAPI-based REST API for managing projects,
4
+ sessions, and messages in the MPM Commander.
5
+
6
+ Example:
7
+ Run the API server with uvicorn:
8
+
9
+ $ uvicorn claude_mpm.commander.api.app:app --host 127.0.0.1 --port 8000
10
+
11
+ Access the API documentation at http://127.0.0.1:8000/docs
12
+ """
13
+
14
+ from .app import app
15
+
16
+ __all__ = ["app"]
@@ -0,0 +1,121 @@
1
+ """FastAPI application for MPM Commander REST API.
2
+
3
+ This module defines the main FastAPI application instance with CORS,
4
+ lifecycle management, and route registration.
5
+ """
6
+
7
+ from contextlib import asynccontextmanager
8
+ from pathlib import Path
9
+ from typing import AsyncGenerator
10
+
11
+ from fastapi import FastAPI
12
+ from fastapi.middleware.cors import CORSMiddleware
13
+ from fastapi.responses import FileResponse
14
+ from fastapi.staticfiles import StaticFiles
15
+
16
+ from ..events.manager import EventManager
17
+ from ..inbox import Inbox
18
+ from ..registry import ProjectRegistry
19
+ from ..tmux_orchestrator import TmuxOrchestrator
20
+ from ..workflow import EventHandler
21
+ from .routes import events, inbox as inbox_routes, messages, projects, sessions, work
22
+
23
+
24
+ @asynccontextmanager
25
+ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
26
+ """Manage application lifecycle.
27
+
28
+ Initializes shared resources on startup and cleans up on shutdown.
29
+
30
+ Args:
31
+ app: FastAPI application instance
32
+
33
+ Yields:
34
+ None during application runtime
35
+ """
36
+ # Startup
37
+ import logging
38
+
39
+ logger = logging.getLogger(__name__)
40
+ logger.info("Lifespan starting. Initializing app.state resources...")
41
+
42
+ # Initialize app.state resources (daemon will inject its instances later)
43
+ if not hasattr(app.state, "registry"):
44
+ app.state.registry = ProjectRegistry()
45
+ if not hasattr(app.state, "tmux"):
46
+ app.state.tmux = TmuxOrchestrator()
47
+ if not hasattr(app.state, "event_manager"):
48
+ app.state.event_manager = EventManager()
49
+ if not hasattr(app.state, "inbox"):
50
+ app.state.inbox = Inbox(app.state.event_manager, app.state.registry)
51
+ if not hasattr(app.state, "session_manager"):
52
+ app.state.session_manager = {}
53
+ if not hasattr(app.state, "work_queues"):
54
+ logger.info("work_queues not set, creating new dict")
55
+ app.state.work_queues = {}
56
+ else:
57
+ logger.info(
58
+ f"work_queues already set, preserving id: {id(app.state.work_queues)}"
59
+ )
60
+ if not hasattr(app.state, "daemon_instance"):
61
+ app.state.daemon_instance = None
62
+ if not hasattr(app.state, "event_handler"):
63
+ app.state.event_handler = EventHandler(
64
+ app.state.inbox, app.state.session_manager
65
+ )
66
+
67
+ logger.info(f"Lifespan complete. work_queues id: {id(app.state.work_queues)}")
68
+
69
+ yield
70
+
71
+ # Shutdown
72
+ # No cleanup needed for Phase 1
73
+
74
+
75
+ app = FastAPI(
76
+ title="MPM Commander API",
77
+ description="REST API for MPM Commander - Autonomous AI Orchestration",
78
+ version="1.0.0",
79
+ lifespan=lifespan,
80
+ )
81
+
82
+ # CORS for local development
83
+ app.add_middleware(
84
+ CORSMiddleware,
85
+ allow_origins=["http://localhost:*"],
86
+ allow_credentials=True,
87
+ allow_methods=["*"],
88
+ allow_headers=["*"],
89
+ )
90
+
91
+ # Include routers
92
+ app.include_router(projects.router, prefix="/api", tags=["projects"])
93
+ app.include_router(sessions.router, prefix="/api", tags=["sessions"])
94
+ app.include_router(messages.router, prefix="/api", tags=["messages"])
95
+ app.include_router(inbox_routes.router, prefix="/api", tags=["inbox"])
96
+ app.include_router(events.router, prefix="/api", tags=["events"])
97
+ app.include_router(work.router, prefix="/api", tags=["work"])
98
+
99
+ # Mount static files
100
+ static_path = Path(__file__).parent.parent / "web" / "static"
101
+ app.mount("/static", StaticFiles(directory=str(static_path)), name="static")
102
+
103
+
104
+ @app.get("/api/health")
105
+ async def health_check() -> dict:
106
+ """Health check endpoint.
107
+
108
+ Returns:
109
+ Status and version information
110
+ """
111
+ return {"status": "ok", "version": "1.0.0"}
112
+
113
+
114
+ @app.get("/")
115
+ async def root() -> FileResponse:
116
+ """Serve the web UI index page.
117
+
118
+ Returns:
119
+ HTML page for the web UI
120
+ """
121
+ return FileResponse(static_path / "index.html")
@@ -0,0 +1,133 @@
1
+ """Error handling for MPM Commander API.
2
+
3
+ This module defines custom exception classes that map to HTTP error responses
4
+ with structured error codes and messages.
5
+ """
6
+
7
+ from fastapi import HTTPException
8
+
9
+
10
+ class CommanderAPIError(HTTPException):
11
+ """Base exception for all Commander API errors.
12
+
13
+ Provides consistent error response format with code and message.
14
+
15
+ Attributes:
16
+ code: Machine-readable error code
17
+ message: Human-readable error message
18
+ status_code: HTTP status code
19
+ """
20
+
21
+ def __init__(self, code: str, message: str, status_code: int = 400):
22
+ """Initialize API error.
23
+
24
+ Args:
25
+ code: Error code (e.g., "PROJECT_NOT_FOUND")
26
+ message: Descriptive error message
27
+ status_code: HTTP status code (default: 400)
28
+ """
29
+ super().__init__(
30
+ status_code=status_code,
31
+ detail={"error": {"code": code, "message": message}},
32
+ )
33
+
34
+
35
+ class ProjectNotFoundError(CommanderAPIError):
36
+ """Project with given ID does not exist."""
37
+
38
+ def __init__(self, project_id: str):
39
+ """Initialize project not found error.
40
+
41
+ Args:
42
+ project_id: The project ID that was not found
43
+ """
44
+ super().__init__(
45
+ "PROJECT_NOT_FOUND",
46
+ f"Project not found: {project_id}",
47
+ 404,
48
+ )
49
+
50
+
51
+ class ProjectAlreadyExistsError(CommanderAPIError):
52
+ """Project already registered at given path."""
53
+
54
+ def __init__(self, path: str):
55
+ """Initialize project already exists error.
56
+
57
+ Args:
58
+ path: The path that is already registered
59
+ """
60
+ super().__init__(
61
+ "PROJECT_ALREADY_EXISTS",
62
+ f"Project already registered: {path}",
63
+ 409,
64
+ )
65
+
66
+
67
+ class InvalidPathError(CommanderAPIError):
68
+ """Path does not exist or is not a directory."""
69
+
70
+ def __init__(self, path: str):
71
+ """Initialize invalid path error.
72
+
73
+ Args:
74
+ path: The invalid path
75
+ """
76
+ super().__init__(
77
+ "INVALID_PATH",
78
+ f"Path does not exist or is not a directory: {path}",
79
+ 400,
80
+ )
81
+
82
+
83
+ class SessionNotFoundError(CommanderAPIError):
84
+ """Session with given ID does not exist."""
85
+
86
+ def __init__(self, session_id: str):
87
+ """Initialize session not found error.
88
+
89
+ Args:
90
+ session_id: The session ID that was not found
91
+ """
92
+ super().__init__(
93
+ "SESSION_NOT_FOUND",
94
+ f"Session not found: {session_id}",
95
+ 404,
96
+ )
97
+
98
+
99
+ class InvalidRuntimeError(CommanderAPIError):
100
+ """Invalid runtime adapter specified."""
101
+
102
+ def __init__(self, runtime: str):
103
+ """Initialize invalid runtime error.
104
+
105
+ Args:
106
+ runtime: The invalid runtime name
107
+ """
108
+ super().__init__(
109
+ "INVALID_RUNTIME",
110
+ f"Invalid runtime: {runtime}",
111
+ 400,
112
+ )
113
+
114
+
115
+ class TmuxNoSpaceError(CommanderAPIError):
116
+ """Raised when tmux has no space for a new pane."""
117
+
118
+ def __init__(self, message: str | None = None):
119
+ """Initialize tmux no space error.
120
+
121
+ Args:
122
+ message: Custom error message (optional)
123
+ """
124
+ default_msg = (
125
+ "Unable to create session: tmux has no space for new pane. "
126
+ "Try closing some sessions or resize your terminal window. "
127
+ "You can also create a new tmux window with `tmux new-window`."
128
+ )
129
+ super().__init__(
130
+ "TMUX_NO_SPACE",
131
+ message or default_msg,
132
+ 409,
133
+ )
@@ -0,0 +1,8 @@
1
+ """API route modules for MPM Commander.
2
+
3
+ This package exports all route modules for registration with the FastAPI app.
4
+ """
5
+
6
+ from . import messages, projects, sessions, work
7
+
8
+ __all__ = ["messages", "projects", "sessions", "work"]
@@ -0,0 +1,184 @@
1
+ """REST API routes for event resolution.
2
+
3
+ Provides HTTP endpoints for resolving events and managing event responses.
4
+ """
5
+
6
+ from typing import List, Optional
7
+
8
+ from fastapi import APIRouter, Depends, HTTPException, Query
9
+ from pydantic import BaseModel
10
+
11
+ from ...events.manager import EventManager
12
+
13
+ router = APIRouter()
14
+
15
+
16
+ def get_event_manager() -> EventManager:
17
+ """Dependency to get the global event manager instance.
18
+
19
+ Returns:
20
+ The global event manager instance
21
+
22
+ Raises:
23
+ RuntimeError: If event manager is not initialized
24
+ """
25
+ from ..app import event_manager
26
+
27
+ if event_manager is None:
28
+ raise RuntimeError("Event manager not initialized")
29
+ return event_manager
30
+
31
+
32
+ def get_event_handler():
33
+ """Dependency to get the global event handler instance.
34
+
35
+ Returns:
36
+ The global event handler instance
37
+
38
+ Raises:
39
+ RuntimeError: If event handler is not initialized
40
+ """
41
+ from ..app import event_handler
42
+
43
+ if event_handler is None:
44
+ raise RuntimeError("Event handler not initialized")
45
+ return event_handler
46
+
47
+
48
+ class EventResponse(BaseModel):
49
+ """Request model for event resolution.
50
+
51
+ Attributes:
52
+ response: User's response to the event
53
+ """
54
+
55
+ response: str
56
+
57
+
58
+ class EventResolutionResponse(BaseModel):
59
+ """Response model for event resolution.
60
+
61
+ Attributes:
62
+ event_id: ID of resolved event
63
+ status: Resolution status
64
+ session_resumed: Whether project session was resumed
65
+ """
66
+
67
+ event_id: str
68
+ status: str
69
+ session_resumed: bool
70
+
71
+
72
+ class PendingEventResponse(BaseModel):
73
+ """Response model for pending event.
74
+
75
+ Attributes:
76
+ event_id: Unique event identifier
77
+ project_id: Project that raised this event
78
+ event_type: Type of event
79
+ priority: Urgency level
80
+ status: Current lifecycle status
81
+ title: Short event summary
82
+ content: Detailed event message
83
+ options: For DECISION_NEEDED events, list of choices
84
+ is_blocking: Whether event blocks progress
85
+ """
86
+
87
+ event_id: str
88
+ project_id: str
89
+ event_type: str
90
+ priority: str
91
+ status: str
92
+ title: str
93
+ content: str
94
+ options: Optional[List[str]]
95
+ is_blocking: bool
96
+
97
+
98
+ @router.post("/events/{event_id}/resolve", response_model=EventResolutionResponse)
99
+ async def resolve_event(
100
+ event_id: str,
101
+ response: EventResponse,
102
+ event_handler=Depends(get_event_handler),
103
+ ) -> EventResolutionResponse:
104
+ """Resolve an event with user response.
105
+
106
+ Marks the event as resolved and resumes the project session if it was
107
+ paused for this event.
108
+
109
+ Args:
110
+ event_id: ID of event to resolve
111
+ response: User's response to the event
112
+
113
+ Returns:
114
+ Resolution status and whether session was resumed
115
+
116
+ Raises:
117
+ HTTPException: If event not found (404) or resolution fails (500)
118
+
119
+ Example:
120
+ POST /api/events/evt_123/resolve
121
+ {
122
+ "response": "Use authlib for OAuth2"
123
+ }
124
+
125
+ Response:
126
+ {
127
+ "event_id": "evt_123",
128
+ "status": "resolved",
129
+ "session_resumed": true
130
+ }
131
+ """
132
+ try:
133
+ session_resumed = await event_handler.resolve_event(event_id, response.response)
134
+ return EventResolutionResponse(
135
+ event_id=event_id,
136
+ status="resolved",
137
+ session_resumed=session_resumed,
138
+ )
139
+ except KeyError as e:
140
+ raise HTTPException(
141
+ status_code=404, detail=f"Event not found: {event_id}"
142
+ ) from e
143
+ except Exception as e:
144
+ raise HTTPException(
145
+ status_code=500, detail=f"Failed to resolve event: {e!s}"
146
+ ) from e
147
+
148
+
149
+ @router.get("/events/pending", response_model=List[PendingEventResponse])
150
+ async def get_pending_events(
151
+ project_id: Optional[str] = Query(None, description="Filter by project ID"),
152
+ event_handler=Depends(get_event_handler),
153
+ ) -> List[PendingEventResponse]:
154
+ """Get pending events requiring resolution.
155
+
156
+ Returns all unresolved events, optionally filtered by project.
157
+ Events are sorted by priority (high to low) then created time (old to new).
158
+
159
+ Args:
160
+ project_id: If provided, only return events for this project
161
+
162
+ Returns:
163
+ List of pending events
164
+
165
+ Example:
166
+ GET /api/events/pending
167
+ GET /api/events/pending?project_id=proj_123
168
+ """
169
+ events = await event_handler.get_pending_events(project_id)
170
+
171
+ return [
172
+ PendingEventResponse(
173
+ event_id=event.id,
174
+ project_id=event.project_id,
175
+ event_type=event.type.value,
176
+ priority=event.priority.value,
177
+ status=event.status.value,
178
+ title=event.title,
179
+ content=event.content,
180
+ options=event.options,
181
+ is_blocking=event_handler.is_blocking(event),
182
+ )
183
+ for event in events
184
+ ]