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,127 @@
1
+ """Event models for MPM Commander (Phase 2).
2
+
3
+ This module defines the complete event model supporting all event types,
4
+ priorities, and statuses for the inbox system.
5
+ """
6
+
7
+ from dataclasses import dataclass, field
8
+ from datetime import datetime, timezone
9
+ from enum import Enum
10
+ from typing import Any, Dict, List, Optional
11
+
12
+
13
+ def _utc_now() -> datetime:
14
+ """Return current UTC time with timezone info."""
15
+ return datetime.now(timezone.utc)
16
+
17
+
18
+ class EventType(Enum):
19
+ """Types of events that can be raised by projects."""
20
+
21
+ DECISION_NEEDED = "decision_needed" # Tool asking which option
22
+ CLARIFICATION = "clarification" # Tool needs more info
23
+ ERROR = "error" # Something failed
24
+ APPROVAL = "approval" # Destructive action pending
25
+ TASK_COMPLETE = "task_complete" # Work item finished
26
+ MILESTONE = "milestone" # Significant progress
27
+ STATUS = "status" # General update
28
+ PROJECT_IDLE = "project_idle" # Project has no work
29
+ INSTANCE_STARTING = "instance_starting" # Instance is starting up
30
+ INSTANCE_READY = "instance_ready" # Instance is ready for work
31
+ INSTANCE_ERROR = "instance_error" # Instance encountered an error
32
+
33
+
34
+ class EventPriority(Enum):
35
+ """Priority levels for events, ordered from highest to lowest."""
36
+
37
+ CRITICAL = "critical" # Blocking all progress
38
+ HIGH = "high" # Blocking this project
39
+ NORMAL = "normal" # Needs response, not blocking
40
+ LOW = "low" # Informational, can batch
41
+ INFO = "info" # No response needed
42
+
43
+ def __lt__(self, other: "EventPriority") -> bool:
44
+ """Enable priority comparison for sorting."""
45
+ order = [self.CRITICAL, self.HIGH, self.NORMAL, self.LOW, self.INFO]
46
+ return order.index(self) < order.index(other)
47
+
48
+
49
+ class EventStatus(Enum):
50
+ """Lifecycle status of an event."""
51
+
52
+ PENDING = "pending" # Awaiting response
53
+ ACKNOWLEDGED = "acknowledged" # Seen but not resolved
54
+ RESOLVED = "resolved" # Response provided
55
+ DISMISSED = "dismissed" # Intentionally ignored
56
+
57
+
58
+ # Default priority by event type
59
+ DEFAULT_PRIORITIES: Dict[EventType, EventPriority] = {
60
+ EventType.ERROR: EventPriority.CRITICAL,
61
+ EventType.DECISION_NEEDED: EventPriority.HIGH,
62
+ EventType.APPROVAL: EventPriority.HIGH,
63
+ EventType.CLARIFICATION: EventPriority.NORMAL,
64
+ EventType.TASK_COMPLETE: EventPriority.LOW,
65
+ EventType.MILESTONE: EventPriority.LOW,
66
+ EventType.STATUS: EventPriority.INFO,
67
+ EventType.PROJECT_IDLE: EventPriority.INFO,
68
+ EventType.INSTANCE_STARTING: EventPriority.INFO,
69
+ EventType.INSTANCE_READY: EventPriority.INFO,
70
+ EventType.INSTANCE_ERROR: EventPriority.HIGH,
71
+ }
72
+
73
+
74
+ # Which event types block progress and their scope
75
+ BLOCKING_EVENTS: Dict[EventType, str] = {
76
+ EventType.ERROR: "all", # Blocks all projects
77
+ EventType.DECISION_NEEDED: "project", # Blocks this project
78
+ EventType.APPROVAL: "project", # Blocks this project
79
+ }
80
+
81
+
82
+ @dataclass
83
+ class Event:
84
+ """Represents an event in the MPM Commander system.
85
+
86
+ Events are raised by projects to communicate with the user or
87
+ system about state changes, decisions needed, or progress updates.
88
+
89
+ Attributes:
90
+ id: Unique event identifier
91
+ project_id: ID of project that raised this event
92
+ type: Type of event (decision, error, status, etc.)
93
+ priority: Urgency level
94
+ title: Short summary of the event
95
+ session_id: Optional session ID if event is session-specific
96
+ status: Current lifecycle status
97
+ content: Detailed event message or description
98
+ context: Additional structured data about the event
99
+ options: For DECISION_NEEDED events, list of choices
100
+ response: User's response to the event
101
+ responded_at: When the response was recorded
102
+ created_at: When the event was created
103
+ """
104
+
105
+ id: str
106
+ project_id: str
107
+ type: EventType
108
+ priority: EventPriority
109
+ title: str
110
+ session_id: Optional[str] = None
111
+ status: EventStatus = EventStatus.PENDING
112
+ content: str = ""
113
+ context: Dict[str, Any] = field(default_factory=dict)
114
+ options: Optional[List[str]] = None
115
+ response: Optional[str] = None
116
+ responded_at: Optional[datetime] = None
117
+ created_at: datetime = field(default_factory=_utc_now)
118
+
119
+ @property
120
+ def is_blocking(self) -> bool:
121
+ """Check if this event blocks progress."""
122
+ return self.type in BLOCKING_EVENTS and self.status == EventStatus.PENDING
123
+
124
+ @property
125
+ def blocking_scope(self) -> Optional[str]:
126
+ """Get the scope this event blocks ('all' or 'project')."""
127
+ return BLOCKING_EVENTS.get(self.type)
@@ -0,0 +1,162 @@
1
+ """Project data models for MPM Commander.
2
+
3
+ This module defines the core data structures for managing projects,
4
+ tool sessions, and conversation threads.
5
+ """
6
+
7
+ from dataclasses import dataclass, field
8
+ from datetime import datetime, timezone
9
+ from enum import Enum
10
+ from typing import Any, Dict, List, Optional
11
+
12
+
13
+ def _utc_now() -> datetime:
14
+ """Return current UTC time with timezone awareness."""
15
+ return datetime.now(timezone.utc)
16
+
17
+
18
+ class ProjectState(Enum):
19
+ """Project execution state.
20
+
21
+ Attributes:
22
+ IDLE: No pending work in queue
23
+ WORKING: Currently executing a work item
24
+ BLOCKED: Waiting on human input or approval
25
+ PAUSED: Manually paused by user
26
+ ERROR: Encountered unrecoverable error
27
+ """
28
+
29
+ IDLE = "idle"
30
+ WORKING = "working"
31
+ BLOCKED = "blocked"
32
+ PAUSED = "paused"
33
+ ERROR = "error"
34
+
35
+
36
+ @dataclass
37
+ class ToolSession:
38
+ """Tool runtime session (Claude Code, Codex, Aider, etc.).
39
+
40
+ Each session runs in an isolated tmux pane for output capture.
41
+
42
+ Attributes:
43
+ id: Unique session identifier
44
+ project_id: Parent project ID
45
+ runtime: Tool runtime name (e.g., "claude-code", "aider")
46
+ tmux_target: Tmux window:pane identifier (e.g., "commander:proj-a-cc")
47
+ status: Current session status
48
+ output_buffer: Captured output from tool
49
+ created_at: Session creation timestamp
50
+ last_output_at: Last output received timestamp
51
+
52
+ Example:
53
+ >>> session = ToolSession(
54
+ ... id="sess-123",
55
+ ... project_id="proj-abc",
56
+ ... runtime="claude-code",
57
+ ... tmux_target="commander:proj-abc-cc"
58
+ ... )
59
+ >>> session.status
60
+ 'initializing'
61
+ """
62
+
63
+ id: str
64
+ project_id: str
65
+ runtime: str
66
+ tmux_target: str
67
+ status: str = "initializing"
68
+ output_buffer: str = ""
69
+ created_at: datetime = field(default_factory=_utc_now)
70
+ last_output_at: Optional[datetime] = None
71
+
72
+
73
+ @dataclass
74
+ class ThreadMessage:
75
+ """Conversation thread message.
76
+
77
+ Represents a single message in the project's conversation history,
78
+ which can come from user, assistant, system, or tool outputs.
79
+
80
+ Attributes:
81
+ id: Unique message identifier
82
+ role: Message sender role
83
+ content: Message content
84
+ session_id: Associated tool session (if from tool)
85
+ event_id: Associated event (Phase 2)
86
+ timestamp: Message creation timestamp
87
+
88
+ Example:
89
+ >>> msg = ThreadMessage(
90
+ ... id="msg-1",
91
+ ... role="user",
92
+ ... content="Fix the login bug"
93
+ ... )
94
+ >>> msg.role
95
+ 'user'
96
+ """
97
+
98
+ id: str
99
+ role: str # user, assistant, system, tool
100
+ content: str
101
+ session_id: Optional[str] = None
102
+ event_id: Optional[str] = None
103
+ timestamp: datetime = field(default_factory=_utc_now)
104
+
105
+
106
+ @dataclass
107
+ class Project:
108
+ """Project context and state management.
109
+
110
+ Maintains isolated state for a single project including:
111
+ - Execution state and work queue
112
+ - Tool sessions (Claude Code, Aider, etc.)
113
+ - Conversation thread
114
+ - Events and history (Phase 2)
115
+
116
+ Attributes:
117
+ id: Unique project identifier (UUID)
118
+ path: Absolute filesystem path to project
119
+ name: Human-readable project name
120
+ state: Current execution state
121
+ state_reason: Optional reason for state (e.g., error message)
122
+ config_loaded: Whether .claude-mpm/ config loaded
123
+ config: Loaded configuration dict
124
+ sessions: Active tool sessions by session_id
125
+ work_queue: Pending work items (Phase 3)
126
+ active_work: Currently executing work item
127
+ completed_work: History of completed work items
128
+ pending_events: Events pending processing (Phase 2)
129
+ event_history: Processed events (Phase 2)
130
+ thread: Conversation message history
131
+ created_at: Project registration timestamp
132
+ last_activity: Last activity timestamp (updated on any change)
133
+
134
+ Example:
135
+ >>> from pathlib import Path
136
+ >>> project = Project(
137
+ ... id="proj-abc123",
138
+ ... path="/Users/masa/Projects/my-app",
139
+ ... name="my-app"
140
+ ... )
141
+ >>> project.state
142
+ <ProjectState.IDLE: 'idle'>
143
+ >>> project.state = ProjectState.WORKING
144
+ >>> project.state_reason = "Processing ticket #123"
145
+ """
146
+
147
+ id: str
148
+ path: str
149
+ name: str
150
+ state: ProjectState = ProjectState.IDLE
151
+ state_reason: Optional[str] = None
152
+ config_loaded: bool = False
153
+ config: Optional[Dict[str, Any]] = None
154
+ sessions: Dict[str, ToolSession] = field(default_factory=dict)
155
+ work_queue: List[Any] = field(default_factory=list)
156
+ active_work: Optional[Any] = None
157
+ completed_work: List[Any] = field(default_factory=list)
158
+ pending_events: List[Any] = field(default_factory=list)
159
+ event_history: List[Any] = field(default_factory=list)
160
+ thread: List[ThreadMessage] = field(default_factory=list)
161
+ created_at: datetime = field(default_factory=_utc_now)
162
+ last_activity: datetime = field(default_factory=_utc_now)
@@ -0,0 +1,214 @@
1
+ """Work item models for MPM Commander work queue.
2
+
3
+ This module defines work items that represent tasks to be executed
4
+ by the Commander daemon across multiple projects.
5
+ """
6
+
7
+ from dataclasses import dataclass, field
8
+ from datetime import datetime, timezone
9
+ from enum import Enum
10
+ from typing import Any, Dict, List, Optional
11
+
12
+
13
+ def _utc_now() -> datetime:
14
+ """Return current UTC time with timezone info."""
15
+ return datetime.now(timezone.utc)
16
+
17
+
18
+ class WorkState(Enum):
19
+ """Lifecycle states of a work item."""
20
+
21
+ PENDING = "pending" # Created but not yet queued
22
+ QUEUED = "queued" # In queue, waiting for execution
23
+ IN_PROGRESS = "in_progress" # Currently being executed
24
+ BLOCKED = "blocked" # Paused due to blocking event
25
+ COMPLETED = "completed" # Successfully finished
26
+ FAILED = "failed" # Failed with error
27
+ CANCELLED = "cancelled" # Manually cancelled
28
+
29
+
30
+ class WorkPriority(Enum):
31
+ """Priority levels for work items, ordered from highest to lowest."""
32
+
33
+ CRITICAL = 4 # Execute immediately
34
+ HIGH = 3 # Execute as soon as possible
35
+ MEDIUM = 2 # Normal priority
36
+ LOW = 1 # Execute when idle
37
+
38
+ def __lt__(self, other: "WorkPriority") -> bool:
39
+ """Enable priority comparison for sorting (higher value = higher priority)."""
40
+ if not isinstance(other, WorkPriority):
41
+ return NotImplemented
42
+ return self.value < other.value
43
+
44
+ def __le__(self, other: "WorkPriority") -> bool:
45
+ """Less than or equal comparison."""
46
+ if not isinstance(other, WorkPriority):
47
+ return NotImplemented
48
+ return self.value <= other.value
49
+
50
+ def __gt__(self, other: "WorkPriority") -> bool:
51
+ """Greater than comparison."""
52
+ if not isinstance(other, WorkPriority):
53
+ return NotImplemented
54
+ return self.value > other.value
55
+
56
+ def __ge__(self, other: "WorkPriority") -> bool:
57
+ """Greater than or equal comparison."""
58
+ if not isinstance(other, WorkPriority):
59
+ return NotImplemented
60
+ return self.value >= other.value
61
+
62
+
63
+ @dataclass
64
+ class WorkItem:
65
+ """Represents a work item to be executed by the Commander.
66
+
67
+ Work items are queued tasks that will be executed by RuntimeExecutor.
68
+ They support priority-based execution and dependency chains.
69
+
70
+ Attributes:
71
+ id: Unique work item identifier
72
+ project_id: ID of project this work belongs to
73
+ content: The message/task to send to Claude
74
+ state: Current lifecycle state
75
+ priority: Execution priority
76
+ created_at: When the work item was created
77
+ started_at: When execution started (if IN_PROGRESS or later)
78
+ completed_at: When execution completed (if COMPLETED/FAILED)
79
+ result: Result output on completion
80
+ error: Error message if FAILED
81
+ depends_on: List of work item IDs that must complete first
82
+ metadata: Additional structured data about the work
83
+
84
+ Example:
85
+ >>> work = WorkItem(
86
+ ... id="work-123",
87
+ ... project_id="proj-abc",
88
+ ... content="Implement OAuth2 authentication",
89
+ ... priority=WorkPriority.HIGH
90
+ ... )
91
+ >>> work.can_start({"work-122"}) # Check if dependencies satisfied
92
+ True
93
+ """
94
+
95
+ id: str
96
+ project_id: str
97
+ content: str
98
+ state: WorkState = WorkState.PENDING
99
+ priority: WorkPriority = WorkPriority.MEDIUM
100
+ created_at: datetime = field(default_factory=_utc_now)
101
+ started_at: Optional[datetime] = None
102
+ completed_at: Optional[datetime] = None
103
+ result: Optional[str] = None
104
+ error: Optional[str] = None
105
+ depends_on: List[str] = field(default_factory=list)
106
+ metadata: Dict[str, Any] = field(default_factory=dict)
107
+
108
+ def can_start(self, completed_ids: set[str]) -> bool:
109
+ """Check if dependencies are satisfied.
110
+
111
+ Args:
112
+ completed_ids: Set of work item IDs that have completed
113
+
114
+ Returns:
115
+ True if all dependencies in completed_ids, False otherwise
116
+
117
+ Example:
118
+ >>> work = WorkItem(id="w1", project_id="p1", content="Task",
119
+ ... depends_on=["w0"])
120
+ >>> work.can_start({"w0"})
121
+ True
122
+ >>> work.can_start(set())
123
+ False
124
+ """
125
+ if not self.depends_on:
126
+ return True
127
+ return all(dep_id in completed_ids for dep_id in self.depends_on)
128
+
129
+ def to_dict(self) -> Dict[str, Any]:
130
+ """Serialize for persistence.
131
+
132
+ Returns:
133
+ Dictionary representation suitable for JSON serialization
134
+
135
+ Example:
136
+ >>> work = WorkItem(id="w1", project_id="p1", content="Task")
137
+ >>> data = work.to_dict()
138
+ >>> data["id"]
139
+ 'w1'
140
+ """
141
+ return {
142
+ "id": self.id,
143
+ "project_id": self.project_id,
144
+ "content": self.content,
145
+ "state": self.state.value,
146
+ "priority": self.priority.value,
147
+ "created_at": self.created_at.isoformat(),
148
+ "started_at": self.started_at.isoformat() if self.started_at else None,
149
+ "completed_at": (
150
+ self.completed_at.isoformat() if self.completed_at else None
151
+ ),
152
+ "result": self.result,
153
+ "error": self.error,
154
+ "depends_on": self.depends_on,
155
+ "metadata": self.metadata,
156
+ }
157
+
158
+ @classmethod
159
+ def from_dict(cls, data: Dict[str, Any]) -> "WorkItem":
160
+ """Deserialize from persistence.
161
+
162
+ Args:
163
+ data: Dictionary from to_dict()
164
+
165
+ Returns:
166
+ Reconstructed WorkItem instance
167
+
168
+ Raises:
169
+ ValueError: If required fields missing or invalid
170
+
171
+ Example:
172
+ >>> data = {"id": "w1", "project_id": "p1", "content": "Task",
173
+ ... "state": "pending", "priority": 2}
174
+ >>> work = WorkItem.from_dict(data)
175
+ >>> work.id
176
+ 'w1'
177
+ """
178
+ # Parse enums
179
+ try:
180
+ state = WorkState(data["state"])
181
+ except (KeyError, ValueError) as e:
182
+ raise ValueError(f"Invalid or missing state: {e}") from e
183
+
184
+ # Priority can be int or string
185
+ priority_val = data.get("priority", 2)
186
+ if isinstance(priority_val, str):
187
+ priority = WorkPriority[priority_val.upper()]
188
+ else:
189
+ priority = WorkPriority(priority_val)
190
+
191
+ # Parse datetimes
192
+ def parse_datetime(dt_str: Optional[str]) -> Optional[datetime]:
193
+ if not dt_str:
194
+ return None
195
+ return datetime.fromisoformat(dt_str)
196
+
197
+ created_at = parse_datetime(data.get("created_at"))
198
+ if not created_at:
199
+ created_at = _utc_now()
200
+
201
+ return cls(
202
+ id=data["id"],
203
+ project_id=data["project_id"],
204
+ content=data["content"],
205
+ state=state,
206
+ priority=priority,
207
+ created_at=created_at,
208
+ started_at=parse_datetime(data.get("started_at")),
209
+ completed_at=parse_datetime(data.get("completed_at")),
210
+ result=data.get("result"),
211
+ error=data.get("error"),
212
+ depends_on=data.get("depends_on", []),
213
+ metadata=data.get("metadata", {}),
214
+ )
@@ -0,0 +1,20 @@
1
+ """Output parsing module for detecting events in tool output."""
2
+
3
+ from .extractor import (
4
+ extract_action_details,
5
+ extract_error_context,
6
+ extract_options,
7
+ strip_code_blocks,
8
+ )
9
+ from .output_parser import OutputParser, ParseResult
10
+ from .patterns import ALL_PATTERNS
11
+
12
+ __all__ = [
13
+ "ALL_PATTERNS",
14
+ "OutputParser",
15
+ "ParseResult",
16
+ "extract_action_details",
17
+ "extract_error_context",
18
+ "extract_options",
19
+ "strip_code_blocks",
20
+ ]
@@ -0,0 +1,132 @@
1
+ """Extract options and context from matched patterns."""
2
+
3
+ import re
4
+ from typing import Any, Dict, List, Optional
5
+
6
+
7
+ def extract_options(content: str) -> Optional[List[str]]:
8
+ """Extract options from decision content.
9
+
10
+ Supports multiple formats:
11
+ - Numbered lists: "1. Option A\n2. Option B"
12
+ - Bullet lists: "• Option A\n- Option B"
13
+ - Inline options: "(option1/option2/option3)"
14
+ - Y/n style: "[Y/n]", "[yes/no]"
15
+
16
+ Args:
17
+ content: Content to extract options from
18
+
19
+ Returns:
20
+ List of option strings if found, None otherwise
21
+ """
22
+ # Numbered list: "1. Option A\n2. Option B"
23
+ numbered = re.findall(r"^\s*\d+[\.\)]\s*(.+)$", content, re.MULTILINE)
24
+ if numbered:
25
+ return [opt.strip() for opt in numbered]
26
+
27
+ # Bullet list: "• Option A\n- Option B"
28
+ bullets = re.findall(r"^\s*[-•*]\s*(.+)$", content, re.MULTILINE)
29
+ if bullets:
30
+ return [opt.strip() for opt in bullets]
31
+
32
+ # Inline options: "(option1/option2/option3)"
33
+ inline = re.search(r"\(([^)]+/[^)]+)\)", content)
34
+ if inline:
35
+ return [o.strip() for o in inline.group(1).split("/")]
36
+
37
+ # Y/n style
38
+ yn = re.search(r"\[(Y/n|y/N|yes/no|Yes/No)\]", content, re.I)
39
+ if yn:
40
+ parts = yn.group(1).split("/")
41
+ return [p.strip() for p in parts]
42
+
43
+ return None
44
+
45
+
46
+ def extract_error_context(
47
+ content: str, match_start: int, match_end: int, context_lines: int = 5
48
+ ) -> Dict[str, Any]:
49
+ """Extract surrounding context for error.
50
+
51
+ Args:
52
+ content: Full content text
53
+ match_start: Character position where match starts
54
+ match_end: Character position where match ends
55
+ context_lines: Number of lines to include before/after error
56
+
57
+ Returns:
58
+ Dict with surrounding lines and error position info
59
+ """
60
+ lines = content.split("\n")
61
+
62
+ # Find which line the match is on
63
+ char_count = 0
64
+ match_line = 0
65
+ for i, line in enumerate(lines):
66
+ char_count += len(line) + 1 # +1 for newline
67
+ if char_count > match_start:
68
+ match_line = i
69
+ break
70
+
71
+ # Get context lines
72
+ start = max(0, match_line - context_lines)
73
+ end = min(len(lines), match_line + context_lines + 1)
74
+
75
+ return {
76
+ "surrounding_lines": lines[start:end],
77
+ "error_line_index": match_line - start,
78
+ "total_lines": len(lines),
79
+ "match_line": match_line,
80
+ }
81
+
82
+
83
+ def extract_action_details(content: str, match: re.Match) -> Dict[str, Any]:
84
+ """Extract details about an action from approval match.
85
+
86
+ Args:
87
+ content: Full content text
88
+ match: Regex match object for the approval pattern
89
+
90
+ Returns:
91
+ Dict with action type, target, and reversibility info
92
+ """
93
+ groups = match.groups()
94
+ # Use the first captured group if available, otherwise the full match
95
+ action_text = groups[0] if groups else match.group(0)
96
+
97
+ # Try to identify the action type from the full matched text
98
+ full_match = match.group(0)
99
+ action_type = "unknown"
100
+ if re.search(r"delete|remove", full_match, re.I):
101
+ action_type = "delete"
102
+ elif re.search(r"overwrite|modify|change", full_match, re.I):
103
+ action_type = "modify"
104
+ elif re.search(r"create|add", full_match, re.I):
105
+ action_type = "create"
106
+
107
+ # Check if reversible
108
+ reversible = "cannot be undone" not in content.lower()
109
+
110
+ return {
111
+ "action": action_type,
112
+ "target": action_text.strip(),
113
+ "reversible": reversible,
114
+ }
115
+
116
+
117
+ def strip_code_blocks(content: str) -> str:
118
+ """Remove code blocks to avoid false positives.
119
+
120
+ Replaces fenced code blocks and inline code with placeholders
121
+ to prevent pattern matching inside code.
122
+
123
+ Args:
124
+ content: Content to strip code blocks from
125
+
126
+ Returns:
127
+ Content with code blocks replaced by placeholders
128
+ """
129
+ # Remove fenced code blocks
130
+ content = re.sub(r"```[\s\S]*?```", "[CODE_BLOCK]", content)
131
+ # Remove inline code and return
132
+ return re.sub(r"`[^`]+`", "[INLINE_CODE]", content)