claude-mpm 5.4.48__py3-none-any.whl → 5.6.34__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 (467) 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 +119 -689
  6. claude_mpm/agents/WORKFLOW.md +2 -0
  7. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  8. claude_mpm/cli/__init__.py +5 -1
  9. claude_mpm/cli/commands/agents.py +2 -4
  10. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  11. claude_mpm/cli/commands/autotodos.py +566 -0
  12. claude_mpm/cli/commands/commander.py +216 -0
  13. claude_mpm/cli/commands/configure.py +620 -21
  14. claude_mpm/cli/commands/configure_agent_display.py +3 -1
  15. claude_mpm/cli/commands/hook_errors.py +60 -60
  16. claude_mpm/cli/commands/monitor.py +2 -2
  17. claude_mpm/cli/commands/mpm_init/core.py +15 -8
  18. claude_mpm/cli/commands/profile.py +9 -10
  19. claude_mpm/cli/commands/run.py +35 -3
  20. claude_mpm/cli/commands/skill_source.py +51 -2
  21. claude_mpm/cli/commands/skills.py +171 -17
  22. claude_mpm/cli/executor.py +120 -16
  23. claude_mpm/cli/interactive/__init__.py +10 -0
  24. claude_mpm/cli/interactive/agent_wizard.py +30 -50
  25. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  26. claude_mpm/cli/interactive/skill_selector.py +481 -0
  27. claude_mpm/cli/parsers/base_parser.py +76 -1
  28. claude_mpm/cli/parsers/commander_parser.py +116 -0
  29. claude_mpm/cli/parsers/profile_parser.py +0 -1
  30. claude_mpm/cli/parsers/run_parser.py +10 -0
  31. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  32. claude_mpm/cli/parsers/skills_parser.py +5 -0
  33. claude_mpm/cli/startup.py +544 -511
  34. claude_mpm/cli/startup_display.py +74 -6
  35. claude_mpm/cli/startup_logging.py +2 -2
  36. claude_mpm/cli/utils.py +7 -3
  37. claude_mpm/commander/__init__.py +78 -0
  38. claude_mpm/commander/adapters/__init__.py +60 -0
  39. claude_mpm/commander/adapters/auggie.py +260 -0
  40. claude_mpm/commander/adapters/base.py +288 -0
  41. claude_mpm/commander/adapters/claude_code.py +392 -0
  42. claude_mpm/commander/adapters/codex.py +237 -0
  43. claude_mpm/commander/adapters/communication.py +366 -0
  44. claude_mpm/commander/adapters/example_usage.py +310 -0
  45. claude_mpm/commander/adapters/mpm.py +389 -0
  46. claude_mpm/commander/adapters/registry.py +204 -0
  47. claude_mpm/commander/api/__init__.py +16 -0
  48. claude_mpm/commander/api/app.py +121 -0
  49. claude_mpm/commander/api/errors.py +133 -0
  50. claude_mpm/commander/api/routes/__init__.py +8 -0
  51. claude_mpm/commander/api/routes/events.py +184 -0
  52. claude_mpm/commander/api/routes/inbox.py +171 -0
  53. claude_mpm/commander/api/routes/messages.py +148 -0
  54. claude_mpm/commander/api/routes/projects.py +271 -0
  55. claude_mpm/commander/api/routes/sessions.py +226 -0
  56. claude_mpm/commander/api/routes/work.py +296 -0
  57. claude_mpm/commander/api/schemas.py +186 -0
  58. claude_mpm/commander/chat/__init__.py +7 -0
  59. claude_mpm/commander/chat/cli.py +146 -0
  60. claude_mpm/commander/chat/commands.py +96 -0
  61. claude_mpm/commander/chat/repl.py +310 -0
  62. claude_mpm/commander/config.py +51 -0
  63. claude_mpm/commander/config_loader.py +115 -0
  64. claude_mpm/commander/core/__init__.py +10 -0
  65. claude_mpm/commander/core/block_manager.py +325 -0
  66. claude_mpm/commander/core/response_manager.py +323 -0
  67. claude_mpm/commander/daemon.py +603 -0
  68. claude_mpm/commander/env_loader.py +59 -0
  69. claude_mpm/commander/events/__init__.py +26 -0
  70. claude_mpm/commander/events/manager.py +332 -0
  71. claude_mpm/commander/frameworks/__init__.py +12 -0
  72. claude_mpm/commander/frameworks/base.py +146 -0
  73. claude_mpm/commander/frameworks/claude_code.py +58 -0
  74. claude_mpm/commander/frameworks/mpm.py +62 -0
  75. claude_mpm/commander/inbox/__init__.py +16 -0
  76. claude_mpm/commander/inbox/dedup.py +128 -0
  77. claude_mpm/commander/inbox/inbox.py +224 -0
  78. claude_mpm/commander/inbox/models.py +70 -0
  79. claude_mpm/commander/instance_manager.py +450 -0
  80. claude_mpm/commander/llm/__init__.py +6 -0
  81. claude_mpm/commander/llm/openrouter_client.py +167 -0
  82. claude_mpm/commander/llm/summarizer.py +70 -0
  83. claude_mpm/commander/memory/__init__.py +45 -0
  84. claude_mpm/commander/memory/compression.py +347 -0
  85. claude_mpm/commander/memory/embeddings.py +230 -0
  86. claude_mpm/commander/memory/entities.py +310 -0
  87. claude_mpm/commander/memory/example_usage.py +290 -0
  88. claude_mpm/commander/memory/integration.py +325 -0
  89. claude_mpm/commander/memory/search.py +381 -0
  90. claude_mpm/commander/memory/store.py +657 -0
  91. claude_mpm/commander/models/__init__.py +18 -0
  92. claude_mpm/commander/models/events.py +121 -0
  93. claude_mpm/commander/models/project.py +162 -0
  94. claude_mpm/commander/models/work.py +214 -0
  95. claude_mpm/commander/parsing/__init__.py +20 -0
  96. claude_mpm/commander/parsing/extractor.py +132 -0
  97. claude_mpm/commander/parsing/output_parser.py +270 -0
  98. claude_mpm/commander/parsing/patterns.py +100 -0
  99. claude_mpm/commander/persistence/__init__.py +11 -0
  100. claude_mpm/commander/persistence/event_store.py +274 -0
  101. claude_mpm/commander/persistence/state_store.py +309 -0
  102. claude_mpm/commander/persistence/work_store.py +164 -0
  103. claude_mpm/commander/polling/__init__.py +13 -0
  104. claude_mpm/commander/polling/event_detector.py +104 -0
  105. claude_mpm/commander/polling/output_buffer.py +49 -0
  106. claude_mpm/commander/polling/output_poller.py +153 -0
  107. claude_mpm/commander/project_session.py +268 -0
  108. claude_mpm/commander/proxy/__init__.py +12 -0
  109. claude_mpm/commander/proxy/formatter.py +89 -0
  110. claude_mpm/commander/proxy/output_handler.py +191 -0
  111. claude_mpm/commander/proxy/relay.py +155 -0
  112. claude_mpm/commander/registry.py +410 -0
  113. claude_mpm/commander/runtime/__init__.py +10 -0
  114. claude_mpm/commander/runtime/executor.py +191 -0
  115. claude_mpm/commander/runtime/monitor.py +346 -0
  116. claude_mpm/commander/session/__init__.py +6 -0
  117. claude_mpm/commander/session/context.py +81 -0
  118. claude_mpm/commander/session/manager.py +59 -0
  119. claude_mpm/commander/tmux_orchestrator.py +361 -0
  120. claude_mpm/commander/web/__init__.py +1 -0
  121. claude_mpm/commander/work/__init__.py +30 -0
  122. claude_mpm/commander/work/executor.py +207 -0
  123. claude_mpm/commander/work/queue.py +405 -0
  124. claude_mpm/commander/workflow/__init__.py +27 -0
  125. claude_mpm/commander/workflow/event_handler.py +241 -0
  126. claude_mpm/commander/workflow/notifier.py +146 -0
  127. claude_mpm/commands/mpm-config.md +8 -0
  128. claude_mpm/commands/mpm-doctor.md +8 -0
  129. claude_mpm/commands/mpm-help.md +8 -0
  130. claude_mpm/commands/mpm-init.md +8 -0
  131. claude_mpm/commands/mpm-monitor.md +8 -0
  132. claude_mpm/commands/mpm-organize.md +8 -0
  133. claude_mpm/commands/mpm-postmortem.md +8 -0
  134. claude_mpm/commands/mpm-session-resume.md +9 -1
  135. claude_mpm/commands/mpm-status.md +8 -0
  136. claude_mpm/commands/mpm-ticket-view.md +8 -0
  137. claude_mpm/commands/mpm-version.md +8 -0
  138. claude_mpm/commands/mpm.md +8 -0
  139. claude_mpm/config/agent_presets.py +8 -7
  140. claude_mpm/config/skill_sources.py +16 -0
  141. claude_mpm/constants.py +1 -0
  142. claude_mpm/core/claude_runner.py +154 -2
  143. claude_mpm/core/config.py +35 -22
  144. claude_mpm/core/config_constants.py +74 -9
  145. claude_mpm/core/constants.py +56 -12
  146. claude_mpm/core/hook_manager.py +51 -3
  147. claude_mpm/core/interactive_session.py +12 -11
  148. claude_mpm/core/logger.py +26 -9
  149. claude_mpm/core/logging_utils.py +39 -13
  150. claude_mpm/core/network_config.py +148 -0
  151. claude_mpm/core/oneshot_session.py +7 -6
  152. claude_mpm/core/optimized_startup.py +3 -1
  153. claude_mpm/core/output_style_manager.py +66 -18
  154. claude_mpm/core/shared/config_loader.py +3 -1
  155. claude_mpm/core/socketio_pool.py +47 -15
  156. claude_mpm/core/unified_config.py +54 -8
  157. claude_mpm/core/unified_paths.py +95 -90
  158. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
  159. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
  160. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
  161. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
  162. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
  163. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
  164. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
  165. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
  166. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
  167. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
  168. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  169. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
  170. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
  171. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
  172. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
  173. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
  174. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
  175. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
  176. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
  177. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
  178. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
  179. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
  180. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
  181. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
  182. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
  183. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
  184. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
  185. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
  186. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
  187. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
  188. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
  189. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  190. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
  191. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  192. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
  193. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
  194. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
  195. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
  196. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
  197. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{N4qtv3Hx.js → DR8nis88.js} +2 -2
  198. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
  199. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  200. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
  201. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
  202. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
  203. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
  204. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
  205. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
  206. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  207. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
  208. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
  209. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
  210. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DjhvlsAc.js → NqQ1dWOy.js} +1 -1
  211. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
  212. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
  213. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
  214. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
  215. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
  216. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
  217. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
  218. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
  219. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.CAGBuiOw.js → 0.RgBboRvH.js} +1 -1
  220. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
  221. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
  222. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
  223. claude_mpm/dashboard/static/svelte-build/index.html +11 -11
  224. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  225. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  226. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  227. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  228. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  229. claude_mpm/experimental/cli_enhancements.py +2 -1
  230. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  231. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  232. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  233. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  234. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  235. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  236. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  237. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
  238. claude_mpm/hooks/claude_hooks/event_handlers.py +527 -136
  239. claude_mpm/hooks/claude_hooks/hook_handler.py +170 -104
  240. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  241. claude_mpm/hooks/claude_hooks/installer.py +206 -36
  242. claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
  243. claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
  244. claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
  245. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  246. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  247. claude_mpm/hooks/claude_hooks/services/__pycache__/container.cpython-311.pyc +0 -0
  248. claude_mpm/hooks/claude_hooks/services/__pycache__/protocols.cpython-311.pyc +0 -0
  249. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  250. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  251. claude_mpm/hooks/claude_hooks/services/connection_manager.py +41 -26
  252. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
  253. claude_mpm/hooks/claude_hooks/services/container.py +310 -0
  254. claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
  255. claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
  256. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
  257. claude_mpm/hooks/session_resume_hook.py +89 -1
  258. claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
  259. claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
  260. claude_mpm/init.py +215 -2
  261. claude_mpm/scripts/claude-hook-handler.sh +46 -19
  262. claude_mpm/scripts/start_activity_logging.py +0 -0
  263. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  264. claude_mpm/services/agents/agent_selection_service.py +2 -2
  265. claude_mpm/services/agents/cache_git_manager.py +1 -1
  266. claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -1
  267. claude_mpm/services/agents/deployment/agent_format_converter.py +8 -6
  268. claude_mpm/services/agents/deployment/agent_template_builder.py +14 -4
  269. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  270. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +4 -4
  271. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +4 -1
  272. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  273. claude_mpm/services/agents/git_source_manager.py +6 -2
  274. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  275. claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
  276. claude_mpm/services/agents/sources/git_source_sync_service.py +10 -5
  277. claude_mpm/services/agents/startup_sync.py +5 -2
  278. claude_mpm/services/cli/__init__.py +3 -0
  279. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  280. claude_mpm/services/cli/session_resume_helper.py +10 -2
  281. claude_mpm/services/command_deployment_service.py +44 -26
  282. claude_mpm/services/delegation_detector.py +175 -0
  283. claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
  284. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  285. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  286. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  287. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  288. claude_mpm/services/diagnostics/models.py +14 -1
  289. claude_mpm/services/event_log.py +325 -0
  290. claude_mpm/services/hook_installer_service.py +77 -8
  291. claude_mpm/services/infrastructure/__init__.py +4 -0
  292. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  293. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  294. claude_mpm/services/monitor/daemon_manager.py +15 -4
  295. claude_mpm/services/monitor/management/lifecycle.py +8 -3
  296. claude_mpm/services/monitor/server.py +106 -16
  297. claude_mpm/services/pm_skills_deployer.py +267 -94
  298. claude_mpm/services/profile_manager.py +10 -4
  299. claude_mpm/services/skills/git_skill_source_manager.py +192 -29
  300. claude_mpm/services/skills/selective_skill_deployer.py +211 -46
  301. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  302. claude_mpm/services/skills_deployer.py +188 -67
  303. claude_mpm/services/socketio/handlers/hook.py +14 -7
  304. claude_mpm/services/socketio/server/main.py +12 -4
  305. claude_mpm/skills/__init__.py +2 -1
  306. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  307. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  308. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  309. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  310. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  311. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  312. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  313. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  314. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  315. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  316. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  317. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  318. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  319. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  320. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  321. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  322. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  323. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  324. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  325. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  326. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  327. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  328. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  329. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  330. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  331. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  332. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  333. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  334. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  335. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  336. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  337. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  338. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  339. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  340. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  341. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  342. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  343. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  344. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  345. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  346. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  347. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  348. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  349. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  350. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  351. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  352. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  353. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  354. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  355. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  356. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  357. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  358. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  359. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  360. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  361. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  362. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  363. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  364. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  365. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  366. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  367. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  368. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  369. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  370. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  371. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  372. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  373. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  374. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  375. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  376. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  377. claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
  378. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  379. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  380. claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
  381. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  382. claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
  383. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  384. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  385. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  386. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  387. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  388. claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
  389. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  390. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  391. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  392. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  393. claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
  394. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  395. claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
  396. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  397. claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
  398. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  399. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  400. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  401. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  402. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  403. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  404. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  405. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  406. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  407. claude_mpm/skills/bundled/security-scanning.md +112 -0
  408. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  409. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  410. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  411. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  412. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  413. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  414. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  415. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  416. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  417. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  418. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  419. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  420. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  421. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  422. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  423. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  424. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  425. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  426. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  427. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  428. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  429. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  430. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  431. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  432. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  433. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  434. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  435. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  436. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  437. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  438. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  439. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  440. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  441. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  442. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  443. claude_mpm/skills/registry.py +295 -90
  444. claude_mpm/skills/skill_manager.py +29 -23
  445. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  446. claude_mpm/utils/agent_dependency_loader.py +103 -4
  447. claude_mpm/utils/robust_installer.py +45 -24
  448. claude_mpm-5.6.34.dist-info/METADATA +393 -0
  449. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/RECORD +453 -151
  450. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
  451. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
  452. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
  453. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
  454. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +0 -1
  455. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
  456. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
  457. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
  458. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
  459. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
  460. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  461. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  462. claude_mpm-5.4.48.dist-info/METADATA +0 -999
  463. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/WHEEL +0 -0
  464. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/entry_points.txt +0 -0
  465. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE +0 -0
  466. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  467. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,332 @@
1
+ """EventManager for MPM Commander inbox system.
2
+
3
+ Manages event lifecycle, inbox queries, and project event tracking.
4
+ """
5
+
6
+ import logging
7
+ import threading
8
+ import uuid
9
+ from datetime import datetime, timezone
10
+ from typing import Any, Dict, List, Optional
11
+
12
+ from ..models.events import (
13
+ DEFAULT_PRIORITIES,
14
+ Event,
15
+ EventPriority,
16
+ EventStatus,
17
+ EventType,
18
+ )
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ class EventManager:
24
+ """Manages event lifecycle and inbox queries.
25
+
26
+ Thread-safe event storage with support for:
27
+ - Creating events with automatic priority assignment
28
+ - Querying pending events by project or globally
29
+ - Inbox sorting by priority then timestamp
30
+ - Responding to, acknowledging, or dismissing events
31
+ - Detecting blocking events
32
+ - Clearing project events
33
+
34
+ Example:
35
+ manager = EventManager()
36
+ event = manager.create(
37
+ project_id="proj_123",
38
+ event_type=EventType.DECISION_NEEDED,
39
+ title="Choose deployment target",
40
+ options=["staging", "production"]
41
+ )
42
+ inbox = manager.get_inbox()
43
+ manager.respond(event.id, "staging")
44
+ """
45
+
46
+ def __init__(self) -> None:
47
+ """Initialize empty event storage."""
48
+ self._events: Dict[str, Event] = {}
49
+ self._project_index: Dict[str, List[str]] = {} # project_id -> event_ids
50
+ self._lock = threading.RLock()
51
+
52
+ def create(
53
+ self,
54
+ project_id: str,
55
+ event_type: EventType,
56
+ title: str,
57
+ content: str = "",
58
+ session_id: Optional[str] = None,
59
+ priority: Optional[EventPriority] = None,
60
+ options: Optional[List[str]] = None,
61
+ context: Optional[Dict[str, Any]] = None,
62
+ ) -> Event:
63
+ """Create and queue a new event.
64
+
65
+ Args:
66
+ project_id: ID of project raising this event
67
+ event_type: Type of event
68
+ title: Short summary
69
+ content: Detailed description
70
+ session_id: Optional session ID
71
+ priority: Optional priority (uses default if not specified)
72
+ options: For DECISION_NEEDED, list of choices
73
+ context: Additional structured data
74
+
75
+ Returns:
76
+ The created Event
77
+
78
+ Example:
79
+ event = manager.create(
80
+ project_id="proj_123",
81
+ event_type=EventType.ERROR,
82
+ title="Database connection failed",
83
+ content="Could not connect to postgres://..."
84
+ )
85
+ """
86
+ with self._lock:
87
+ event_id = f"evt_{uuid.uuid4().hex[:12]}"
88
+
89
+ # Use default priority if not specified
90
+ if priority is None:
91
+ priority = DEFAULT_PRIORITIES.get(event_type, EventPriority.NORMAL)
92
+
93
+ event = Event(
94
+ id=event_id,
95
+ project_id=project_id,
96
+ session_id=session_id,
97
+ type=event_type,
98
+ priority=priority,
99
+ title=title,
100
+ content=content,
101
+ context=context or {},
102
+ options=options,
103
+ )
104
+
105
+ self._events[event_id] = event
106
+
107
+ # Index by project
108
+ if project_id not in self._project_index:
109
+ self._project_index[project_id] = []
110
+ self._project_index[project_id].append(event_id)
111
+
112
+ logger.info("Created event %s: [%s] %s", event_id, event_type.value, title)
113
+ return event
114
+
115
+ def add_event(self, event: Event) -> None:
116
+ """Add existing event to manager (for loading from persistence).
117
+
118
+ Args:
119
+ event: Event instance to add
120
+
121
+ Example:
122
+ # Load events from disk and add to manager
123
+ for event in loaded_events:
124
+ manager.add_event(event)
125
+ """
126
+ with self._lock:
127
+ self._events[event.id] = event
128
+
129
+ # Index by project
130
+ if event.project_id not in self._project_index:
131
+ self._project_index[event.project_id] = []
132
+ if event.id not in self._project_index[event.project_id]:
133
+ self._project_index[event.project_id].append(event.id)
134
+
135
+ logger.debug("Added event %s to manager", event.id)
136
+
137
+ def get(self, event_id: str) -> Optional[Event]:
138
+ """Get event by ID.
139
+
140
+ Args:
141
+ event_id: Unique event identifier
142
+
143
+ Returns:
144
+ Event if found, None otherwise
145
+ """
146
+ return self._events.get(event_id)
147
+
148
+ def get_pending(self, project_id: Optional[str] = None) -> List[Event]:
149
+ """Get all pending events, optionally filtered by project.
150
+
151
+ Args:
152
+ project_id: If provided, only return events for this project
153
+
154
+ Returns:
155
+ List of pending events (unsorted)
156
+
157
+ Example:
158
+ # Get all pending events
159
+ all_pending = manager.get_pending()
160
+
161
+ # Get pending events for one project
162
+ project_pending = manager.get_pending("proj_123")
163
+ """
164
+ with self._lock:
165
+ if project_id:
166
+ event_ids = self._project_index.get(project_id, [])
167
+ events = [self._events[eid] for eid in event_ids if eid in self._events]
168
+ else:
169
+ events = list(self._events.values())
170
+
171
+ return [e for e in events if e.status == EventStatus.PENDING]
172
+
173
+ def get_inbox(self, limit: int = 50) -> List[Event]:
174
+ """Get events for inbox, sorted by priority then time.
175
+
176
+ Sorting order:
177
+ 1. Priority: CRITICAL > HIGH > NORMAL > LOW > INFO
178
+ 2. Within same priority: oldest first (created_at ascending)
179
+
180
+ Args:
181
+ limit: Maximum number of events to return
182
+
183
+ Returns:
184
+ Sorted list of pending events, limited to `limit` items
185
+
186
+ Example:
187
+ inbox = manager.get_inbox(limit=20)
188
+ for event in inbox:
189
+ print(f"{event.priority.value}: {event.title}")
190
+ """
191
+ with self._lock:
192
+ pending = [
193
+ e for e in self._events.values() if e.status == EventStatus.PENDING
194
+ ]
195
+
196
+ # Sort by priority (CRITICAL first) then by created_at (oldest first)
197
+ priority_order = [
198
+ EventPriority.CRITICAL,
199
+ EventPriority.HIGH,
200
+ EventPriority.NORMAL,
201
+ EventPriority.LOW,
202
+ EventPriority.INFO,
203
+ ]
204
+
205
+ def sort_key(event: Event) -> tuple[int, datetime]:
206
+ pri_idx = (
207
+ priority_order.index(event.priority)
208
+ if event.priority in priority_order
209
+ else 99
210
+ )
211
+ return (pri_idx, event.created_at)
212
+
213
+ sorted_events = sorted(pending, key=sort_key)
214
+ return sorted_events[:limit]
215
+
216
+ def respond(self, event_id: str, response: str) -> Event:
217
+ """Record response to event and mark as resolved.
218
+
219
+ Args:
220
+ event_id: ID of event to respond to
221
+ response: User's response text
222
+
223
+ Returns:
224
+ The updated Event
225
+
226
+ Raises:
227
+ KeyError: If event_id not found
228
+
229
+ Example:
230
+ event = manager.respond("evt_abc123", "Deploy to staging")
231
+ """
232
+ with self._lock:
233
+ event = self._events.get(event_id)
234
+ if not event:
235
+ raise KeyError(f"Event not found: {event_id}")
236
+
237
+ event.response = response
238
+ event.responded_at = datetime.now(timezone.utc)
239
+ event.status = EventStatus.RESOLVED
240
+
241
+ logger.info("Responded to event %s: %s", event_id, response[:50])
242
+ return event
243
+
244
+ def dismiss(self, event_id: str) -> Event:
245
+ """Mark event as dismissed without providing a response.
246
+
247
+ Args:
248
+ event_id: ID of event to dismiss
249
+
250
+ Returns:
251
+ The updated Event
252
+
253
+ Raises:
254
+ KeyError: If event_id not found
255
+
256
+ Example:
257
+ manager.dismiss("evt_abc123")
258
+ """
259
+ with self._lock:
260
+ event = self._events.get(event_id)
261
+ if not event:
262
+ raise KeyError(f"Event not found: {event_id}")
263
+
264
+ event.status = EventStatus.DISMISSED
265
+
266
+ logger.info("Dismissed event %s", event_id)
267
+ return event
268
+
269
+ def acknowledge(self, event_id: str) -> Event:
270
+ """Mark event as seen but not resolved yet.
271
+
272
+ Args:
273
+ event_id: ID of event to acknowledge
274
+
275
+ Returns:
276
+ The updated Event
277
+
278
+ Raises:
279
+ KeyError: If event_id not found
280
+
281
+ Example:
282
+ manager.acknowledge("evt_abc123")
283
+ """
284
+ with self._lock:
285
+ event = self._events.get(event_id)
286
+ if not event:
287
+ raise KeyError(f"Event not found: {event_id}")
288
+
289
+ event.status = EventStatus.ACKNOWLEDGED
290
+
291
+ logger.info("Acknowledged event %s", event_id)
292
+ return event
293
+
294
+ def get_blocking_events(self, project_id: Optional[str] = None) -> List[Event]:
295
+ """Get events that are blocking progress.
296
+
297
+ Args:
298
+ project_id: If provided, include project-scoped blocking events
299
+ for this project. Always includes global blocking events.
300
+
301
+ Returns:
302
+ List of blocking events
303
+
304
+ Example:
305
+ # Get all blocking events (global scope only)
306
+ blockers = manager.get_blocking_events()
307
+
308
+ # Get blocking events for specific project (global + project scope)
309
+ blockers = manager.get_blocking_events("proj_123")
310
+ """
311
+ with self._lock:
312
+ pending = self.get_pending(project_id)
313
+ return [e for e in pending if e.is_blocking]
314
+
315
+ def clear_project_events(self, project_id: str) -> int:
316
+ """Clear all events for a project.
317
+
318
+ Args:
319
+ project_id: ID of project whose events should be cleared
320
+
321
+ Returns:
322
+ Number of events removed
323
+
324
+ Example:
325
+ removed = manager.clear_project_events("proj_123")
326
+ print(f"Cleared {removed} events")
327
+ """
328
+ with self._lock:
329
+ event_ids = self._project_index.pop(project_id, [])
330
+ for eid in event_ids:
331
+ self._events.pop(eid, None)
332
+ return len(event_ids)
@@ -0,0 +1,12 @@
1
+ """Framework abstractions for AI coding assistants."""
2
+
3
+ from .base import BaseFramework, InstanceInfo
4
+ from .claude_code import ClaudeCodeFramework
5
+ from .mpm import MPMFramework
6
+
7
+ __all__ = [
8
+ "BaseFramework",
9
+ "ClaudeCodeFramework",
10
+ "InstanceInfo",
11
+ "MPMFramework",
12
+ ]
@@ -0,0 +1,146 @@
1
+ """Base framework abstraction for different AI coding assistants."""
2
+
3
+ import subprocess # nosec B404 - Required for git operations
4
+ from abc import ABC, abstractmethod
5
+ from dataclasses import dataclass
6
+ from pathlib import Path
7
+ from typing import Optional
8
+
9
+
10
+ @dataclass
11
+ class InstanceInfo:
12
+ """Information about a running framework instance.
13
+
14
+ Attributes:
15
+ name: Instance name (e.g., "myapp")
16
+ project_path: Path to project directory
17
+ framework: Framework identifier (e.g., "cc", "mpm")
18
+ tmux_session: Tmux session name
19
+ pane_target: Tmux pane target (e.g., "%1")
20
+ git_branch: Current git branch if project is a git repo
21
+ git_status: Git status summary if project is a git repo
22
+ connected: Whether instance has an active adapter connection
23
+
24
+ Example:
25
+ >>> info = InstanceInfo(
26
+ ... name="myapp",
27
+ ... project_path=Path("/Users/user/myapp"),
28
+ ... framework="cc",
29
+ ... tmux_session="mpm-commander",
30
+ ... pane_target="%1",
31
+ ... git_branch="main",
32
+ ... git_status="clean",
33
+ ... connected=True
34
+ ... )
35
+ """
36
+
37
+ name: str
38
+ project_path: Path
39
+ framework: str
40
+ tmux_session: str
41
+ pane_target: str
42
+ git_branch: Optional[str] = None
43
+ git_status: Optional[str] = None
44
+ connected: bool = False
45
+
46
+
47
+ class BaseFramework(ABC):
48
+ """Base class for AI coding assistant frameworks.
49
+
50
+ A framework represents a specific AI coding tool (Claude Code, Claude MPM, etc.)
51
+ that can be launched in a project directory via tmux.
52
+
53
+ Attributes:
54
+ name: Short identifier (e.g., "cc", "mpm")
55
+ display_name: Human-readable name (e.g., "Claude Code", "Claude MPM")
56
+ command: The command to run (e.g., "claude")
57
+
58
+ Example:
59
+ >>> class MyFramework(BaseFramework):
60
+ ... name = "my"
61
+ ... display_name = "My Framework"
62
+ ... command = "my-command"
63
+ ...
64
+ ... def get_startup_command(self, project_path: Path) -> str:
65
+ ... return f"cd {project_path} && my-command"
66
+ ...
67
+ ... def is_available(self) -> bool:
68
+ ... return True
69
+ """
70
+
71
+ name: str # "cc", "mpm", etc.
72
+ display_name: str # "Claude Code", "Claude MPM", etc.
73
+ command: str # The command to run
74
+
75
+ @abstractmethod
76
+ def get_startup_command(self, project_path: Path) -> str:
77
+ """Get the command to start this framework in a project.
78
+
79
+ Args:
80
+ project_path: Path to the project directory
81
+
82
+ Returns:
83
+ Shell command string to start the framework
84
+
85
+ Example:
86
+ >>> framework = ClaudeCodeFramework()
87
+ >>> framework.get_startup_command(Path("/Users/user/myapp"))
88
+ "cd /Users/user/myapp && claude"
89
+ """
90
+
91
+ @abstractmethod
92
+ def is_available(self) -> bool:
93
+ """Check if this framework is installed/available.
94
+
95
+ Returns:
96
+ True if the framework command is available on the system
97
+
98
+ Example:
99
+ >>> framework = ClaudeCodeFramework()
100
+ >>> framework.is_available()
101
+ True
102
+ """
103
+
104
+ def get_git_info(self, project_path: Path) -> tuple[Optional[str], Optional[str]]:
105
+ """Get git branch and status for project.
106
+
107
+ Args:
108
+ project_path: Path to the project directory
109
+
110
+ Returns:
111
+ Tuple of (branch, status) where:
112
+ - branch: Current git branch name or None if not a git repo
113
+ - status: "clean" if no changes, "dirty" if changes, or None if not a git repo
114
+
115
+ Example:
116
+ >>> framework = ClaudeCodeFramework()
117
+ >>> branch, status = framework.get_git_info(Path("/Users/user/myapp"))
118
+ >>> print(branch, status)
119
+ main clean
120
+ """
121
+ if not (project_path / ".git").exists():
122
+ return None, None
123
+
124
+ try:
125
+ # Get current branch
126
+ result = subprocess.run( # nosec B603, B607 - Controlled git command
127
+ ["git", "-C", str(project_path), "rev-parse", "--abbrev-ref", "HEAD"],
128
+ capture_output=True,
129
+ text=True,
130
+ check=True,
131
+ )
132
+ branch = result.stdout.strip()
133
+
134
+ # Check if working directory is clean
135
+ result = subprocess.run( # nosec B603, B607 - Controlled git command
136
+ ["git", "-C", str(project_path), "status", "--porcelain"],
137
+ capture_output=True,
138
+ text=True,
139
+ check=True,
140
+ )
141
+ status = "clean" if not result.stdout.strip() else "dirty"
142
+
143
+ return branch, status
144
+
145
+ except (subprocess.CalledProcessError, FileNotFoundError):
146
+ return None, None
@@ -0,0 +1,58 @@
1
+ """Claude Code (cc) framework implementation."""
2
+
3
+ import shlex
4
+ import shutil
5
+ from pathlib import Path
6
+
7
+ from .base import BaseFramework
8
+
9
+
10
+ class ClaudeCodeFramework(BaseFramework):
11
+ """Claude Code CLI framework.
12
+
13
+ This framework launches the standard Claude Code CLI in a project directory.
14
+ It uses the 'claude' command with appropriate flags for automated operation.
15
+
16
+ Example:
17
+ >>> framework = ClaudeCodeFramework()
18
+ >>> framework.name
19
+ 'cc'
20
+ >>> framework.is_available()
21
+ True
22
+ >>> framework.get_startup_command(Path("/Users/user/myapp"))
23
+ "cd '/Users/user/myapp' && claude --dangerously-skip-permissions"
24
+ """
25
+
26
+ name = "cc"
27
+ display_name = "Claude Code"
28
+ command = "claude"
29
+
30
+ def get_startup_command(self, project_path: Path) -> str:
31
+ """Get the command to start Claude Code in a project.
32
+
33
+ Args:
34
+ project_path: Path to the project directory
35
+
36
+ Returns:
37
+ Shell command string to start Claude Code
38
+
39
+ Example:
40
+ >>> framework = ClaudeCodeFramework()
41
+ >>> framework.get_startup_command(Path("/Users/user/myapp"))
42
+ "cd '/Users/user/myapp' && claude --dangerously-skip-permissions"
43
+ """
44
+ quoted_path = shlex.quote(str(project_path))
45
+ return f"cd {quoted_path} && claude --dangerously-skip-permissions"
46
+
47
+ def is_available(self) -> bool:
48
+ """Check if 'claude' command is available.
49
+
50
+ Returns:
51
+ True if 'claude' command exists in PATH
52
+
53
+ Example:
54
+ >>> framework = ClaudeCodeFramework()
55
+ >>> framework.is_available()
56
+ True
57
+ """
58
+ return shutil.which("claude") is not None
@@ -0,0 +1,62 @@
1
+ """Claude MPM framework implementation."""
2
+
3
+ import shlex
4
+ import shutil
5
+ from pathlib import Path
6
+
7
+ from .base import BaseFramework
8
+
9
+
10
+ class MPMFramework(BaseFramework):
11
+ """Claude MPM framework.
12
+
13
+ This framework launches Claude with MPM agent loading via CLAUDE.md.
14
+ It uses the same 'claude' command as Claude Code, but relies on CLAUDE.md
15
+ in the project to load the MPM agent system.
16
+
17
+ Example:
18
+ >>> framework = MPMFramework()
19
+ >>> framework.name
20
+ 'mpm'
21
+ >>> framework.is_available()
22
+ True
23
+ >>> framework.get_startup_command(Path("/Users/user/myapp"))
24
+ "cd '/Users/user/myapp' && claude --dangerously-skip-permissions"
25
+ """
26
+
27
+ name = "mpm"
28
+ display_name = "Claude MPM"
29
+ command = "claude" # Uses claude with MPM agent loading
30
+
31
+ def get_startup_command(self, project_path: Path) -> str:
32
+ """Get the command to start Claude MPM in a project.
33
+
34
+ The MPM framework uses the standard 'claude' command, but expects
35
+ a CLAUDE.md file in the project to load the MPM agent system.
36
+
37
+ Args:
38
+ project_path: Path to the project directory
39
+
40
+ Returns:
41
+ Shell command string to start Claude with MPM
42
+
43
+ Example:
44
+ >>> framework = MPMFramework()
45
+ >>> framework.get_startup_command(Path("/Users/user/myapp"))
46
+ "cd '/Users/user/myapp' && claude --dangerously-skip-permissions"
47
+ """
48
+ quoted_path = shlex.quote(str(project_path))
49
+ return f"cd {quoted_path} && claude --dangerously-skip-permissions"
50
+
51
+ def is_available(self) -> bool:
52
+ """Check if 'claude' command is available.
53
+
54
+ Returns:
55
+ True if 'claude' command exists in PATH
56
+
57
+ Example:
58
+ >>> framework = MPMFramework()
59
+ >>> framework.is_available()
60
+ True
61
+ """
62
+ return shutil.which("claude") is not None
@@ -0,0 +1,16 @@
1
+ """Inbox system for MPM Commander.
2
+
3
+ Provides centralized event aggregation and display.
4
+ """
5
+
6
+ from .dedup import DedupEntry, EventDeduplicator
7
+ from .inbox import Inbox, InboxCounts
8
+ from .models import InboxItem
9
+
10
+ __all__ = [
11
+ "DedupEntry",
12
+ "EventDeduplicator",
13
+ "Inbox",
14
+ "InboxCounts",
15
+ "InboxItem",
16
+ ]