claude-mpm 5.4.65__py3-none-any.whl → 5.6.10__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 (313) 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 +107 -1928
  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 +46 -0
  13. claude_mpm/cli/commands/configure.py +620 -21
  14. claude_mpm/cli/commands/hook_errors.py +60 -60
  15. claude_mpm/cli/commands/monitor.py +2 -2
  16. claude_mpm/cli/commands/mpm_init/core.py +2 -2
  17. claude_mpm/cli/commands/run.py +35 -3
  18. claude_mpm/cli/commands/skill_source.py +51 -2
  19. claude_mpm/cli/commands/skills.py +171 -17
  20. claude_mpm/cli/executor.py +120 -16
  21. claude_mpm/cli/interactive/__init__.py +10 -0
  22. claude_mpm/cli/interactive/agent_wizard.py +30 -50
  23. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  24. claude_mpm/cli/interactive/skill_selector.py +481 -0
  25. claude_mpm/cli/parsers/base_parser.py +76 -1
  26. claude_mpm/cli/parsers/commander_parser.py +83 -0
  27. claude_mpm/cli/parsers/run_parser.py +10 -0
  28. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  29. claude_mpm/cli/parsers/skills_parser.py +5 -0
  30. claude_mpm/cli/startup.py +203 -359
  31. claude_mpm/cli/startup_display.py +72 -5
  32. claude_mpm/cli/startup_logging.py +2 -2
  33. claude_mpm/cli/utils.py +7 -3
  34. claude_mpm/commander/__init__.py +72 -0
  35. claude_mpm/commander/adapters/__init__.py +31 -0
  36. claude_mpm/commander/adapters/base.py +191 -0
  37. claude_mpm/commander/adapters/claude_code.py +361 -0
  38. claude_mpm/commander/adapters/communication.py +366 -0
  39. claude_mpm/commander/api/__init__.py +16 -0
  40. claude_mpm/commander/api/app.py +105 -0
  41. claude_mpm/commander/api/errors.py +133 -0
  42. claude_mpm/commander/api/routes/__init__.py +8 -0
  43. claude_mpm/commander/api/routes/events.py +184 -0
  44. claude_mpm/commander/api/routes/inbox.py +171 -0
  45. claude_mpm/commander/api/routes/messages.py +148 -0
  46. claude_mpm/commander/api/routes/projects.py +271 -0
  47. claude_mpm/commander/api/routes/sessions.py +228 -0
  48. claude_mpm/commander/api/routes/work.py +260 -0
  49. claude_mpm/commander/api/schemas.py +182 -0
  50. claude_mpm/commander/chat/__init__.py +7 -0
  51. claude_mpm/commander/chat/cli.py +107 -0
  52. claude_mpm/commander/chat/commands.py +96 -0
  53. claude_mpm/commander/chat/repl.py +310 -0
  54. claude_mpm/commander/config.py +49 -0
  55. claude_mpm/commander/config_loader.py +115 -0
  56. claude_mpm/commander/daemon.py +398 -0
  57. claude_mpm/commander/events/__init__.py +26 -0
  58. claude_mpm/commander/events/manager.py +332 -0
  59. claude_mpm/commander/frameworks/__init__.py +12 -0
  60. claude_mpm/commander/frameworks/base.py +143 -0
  61. claude_mpm/commander/frameworks/claude_code.py +58 -0
  62. claude_mpm/commander/frameworks/mpm.py +62 -0
  63. claude_mpm/commander/inbox/__init__.py +16 -0
  64. claude_mpm/commander/inbox/dedup.py +128 -0
  65. claude_mpm/commander/inbox/inbox.py +224 -0
  66. claude_mpm/commander/inbox/models.py +70 -0
  67. claude_mpm/commander/instance_manager.py +337 -0
  68. claude_mpm/commander/llm/__init__.py +6 -0
  69. claude_mpm/commander/llm/openrouter_client.py +167 -0
  70. claude_mpm/commander/llm/summarizer.py +70 -0
  71. claude_mpm/commander/models/__init__.py +18 -0
  72. claude_mpm/commander/models/events.py +121 -0
  73. claude_mpm/commander/models/project.py +162 -0
  74. claude_mpm/commander/models/work.py +214 -0
  75. claude_mpm/commander/parsing/__init__.py +20 -0
  76. claude_mpm/commander/parsing/extractor.py +132 -0
  77. claude_mpm/commander/parsing/output_parser.py +270 -0
  78. claude_mpm/commander/parsing/patterns.py +100 -0
  79. claude_mpm/commander/persistence/__init__.py +11 -0
  80. claude_mpm/commander/persistence/event_store.py +274 -0
  81. claude_mpm/commander/persistence/state_store.py +309 -0
  82. claude_mpm/commander/persistence/work_store.py +164 -0
  83. claude_mpm/commander/polling/__init__.py +13 -0
  84. claude_mpm/commander/polling/event_detector.py +104 -0
  85. claude_mpm/commander/polling/output_buffer.py +49 -0
  86. claude_mpm/commander/polling/output_poller.py +153 -0
  87. claude_mpm/commander/project_session.py +268 -0
  88. claude_mpm/commander/proxy/__init__.py +12 -0
  89. claude_mpm/commander/proxy/formatter.py +89 -0
  90. claude_mpm/commander/proxy/output_handler.py +191 -0
  91. claude_mpm/commander/proxy/relay.py +155 -0
  92. claude_mpm/commander/registry.py +404 -0
  93. claude_mpm/commander/runtime/__init__.py +10 -0
  94. claude_mpm/commander/runtime/executor.py +191 -0
  95. claude_mpm/commander/runtime/monitor.py +316 -0
  96. claude_mpm/commander/session/__init__.py +6 -0
  97. claude_mpm/commander/session/context.py +81 -0
  98. claude_mpm/commander/session/manager.py +59 -0
  99. claude_mpm/commander/tmux_orchestrator.py +361 -0
  100. claude_mpm/commander/web/__init__.py +1 -0
  101. claude_mpm/commander/work/__init__.py +30 -0
  102. claude_mpm/commander/work/executor.py +189 -0
  103. claude_mpm/commander/work/queue.py +405 -0
  104. claude_mpm/commander/workflow/__init__.py +27 -0
  105. claude_mpm/commander/workflow/event_handler.py +219 -0
  106. claude_mpm/commander/workflow/notifier.py +146 -0
  107. claude_mpm/commands/mpm-config.md +8 -0
  108. claude_mpm/commands/mpm-doctor.md +8 -0
  109. claude_mpm/commands/mpm-help.md +8 -0
  110. claude_mpm/commands/mpm-init.md +8 -0
  111. claude_mpm/commands/mpm-monitor.md +8 -0
  112. claude_mpm/commands/mpm-organize.md +8 -0
  113. claude_mpm/commands/mpm-postmortem.md +8 -0
  114. claude_mpm/commands/mpm-session-resume.md +9 -1
  115. claude_mpm/commands/mpm-status.md +8 -0
  116. claude_mpm/commands/mpm-ticket-view.md +8 -0
  117. claude_mpm/commands/mpm-version.md +8 -0
  118. claude_mpm/commands/mpm.md +8 -0
  119. claude_mpm/config/agent_presets.py +8 -7
  120. claude_mpm/config/skill_sources.py +16 -0
  121. claude_mpm/constants.py +1 -0
  122. claude_mpm/core/claude_runner.py +2 -2
  123. claude_mpm/core/config.py +32 -19
  124. claude_mpm/core/hook_manager.py +51 -3
  125. claude_mpm/core/interactive_session.py +7 -7
  126. claude_mpm/core/logger.py +26 -9
  127. claude_mpm/core/logging_utils.py +35 -11
  128. claude_mpm/core/output_style_manager.py +31 -13
  129. claude_mpm/core/unified_config.py +54 -8
  130. claude_mpm/core/unified_paths.py +95 -90
  131. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
  132. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
  133. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Cs_tUR18.js → 1WZnGYqX.js} +1 -1
  134. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CDuw-vjf.js → 67pF3qNn.js} +1 -1
  135. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bTOqqlTd.js → 6RxdMKe4.js} +1 -1
  136. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DwBR2MJi.js → 8cZrfX0h.js} +1 -1
  137. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{ZGh7QtNv.js → 9a6T2nm-.js} +1 -1
  138. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D9lljYKQ.js → B443AUzu.js} +1 -1
  139. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{RJiighC3.js → B8AwtY2H.js} +1 -1
  140. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uuIeMWc-.js → BF15LAsF.js} +1 -1
  141. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D3k0OPJN.js → BRcwIQNr.js} +1 -1
  142. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CyWMqx4W.js → BV6nKitt.js} +1 -1
  143. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CiIAseT4.js → BViJ8lZt.js} +5 -5
  144. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CBBdVcY8.js → BcQ-Q0FE.js} +1 -1
  145. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BovzEFCE.js → Bpyvgze_.js} +1 -1
  146. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
  147. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
  148. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{eNVUfhuA.js → C3rbW_a-.js} +1 -1
  149. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{GYwsonyD.js → C8WYN38h.js} +1 -1
  150. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BIF9m_hv.js → C9I8FlXH.js} +1 -1
  151. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B0uc0UOD.js → CIQcWgO2.js} +3 -3
  152. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Be7GpZd6.js → CIctN7YN.js} +1 -1
  153. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Bh0LDWpI.js → CKrS_JZW.js} +2 -2
  154. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DUrLdbGD.js → CR6P9C4A.js} +1 -1
  155. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7xVLGWV.js → CRRR9MD_.js} +1 -1
  156. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
  157. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dhb8PKl3.js → CSXtMOf0.js} +1 -1
  158. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BPYeabCQ.js → CT-sbxSk.js} +1 -1
  159. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{sQeU3Y1z.js → CWm6DJsp.js} +1 -1
  160. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CnA0NrzZ.js → CpqQ1Kzn.js} +1 -1
  161. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4B-KCzX.js → D2nGpDRe.js} +1 -1
  162. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DGkLK5U1.js → D9iCMida.js} +1 -1
  163. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BofRWZRR.js → D9ykgMoY.js} +1 -1
  164. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DmxopI1J.js → DL2Ldur1.js} +1 -1
  165. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C30mlcqg.js → DPfltzjH.js} +1 -1
  166. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Vzk33B_K.js → DR8nis88.js} +2 -2
  167. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DI7hHRFL.js → DUliQN2b.js} +1 -1
  168. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4JcI4KD.js → DXlhR01x.js} +1 -1
  169. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bT1r9zLR.js → D_lyTybS.js} +1 -1
  170. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DZX00Y4g.js → DngoTTgh.js} +1 -1
  171. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzZX-COe.js → DqkmHtDC.js} +1 -1
  172. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7RN905-.js → DsDh8EYs.js} +1 -1
  173. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DLVjFsZ3.js → DypDmXgd.js} +1 -1
  174. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{iEWssX7S.js → IPYC-LnN.js} +1 -1
  175. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
  176. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DaimHw_p.js → JpevfAFt.js} +1 -1
  177. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DY1XQ8fi.js → R8CEIRAd.js} +1 -1
  178. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dle-35c7.js → Zxy7qc-l.js} +2 -2
  179. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
  180. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C_Usid8X.js → qtd3IeO4.js} +2 -2
  181. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzeYkLYB.js → ulBFON_C.js} +2 -2
  182. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Cfqx1Qun.js → wQVh1CoA.js} +1 -1
  183. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/{app.D6-I5TpK.js → app.Dr7t0z2J.js} +2 -2
  184. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
  185. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.m1gL8KXf.js → 0.RgBboRvH.js} +1 -1
  186. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{1.CgNOuw-d.js → 1.DG-KkbDf.js} +1 -1
  187. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
  188. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
  189. claude_mpm/dashboard/static/svelte-build/index.html +9 -9
  190. claude_mpm/experimental/cli_enhancements.py +2 -1
  191. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  192. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  193. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-314.pyc +0 -0
  194. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  195. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-312.pyc +0 -0
  196. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-314.pyc +0 -0
  197. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  198. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-312.pyc +0 -0
  199. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-314.pyc +0 -0
  200. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  201. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-312.pyc +0 -0
  202. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-314.pyc +0 -0
  203. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  204. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-314.pyc +0 -0
  205. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  206. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-312.pyc +0 -0
  207. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-314.pyc +0 -0
  208. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  209. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-312.pyc +0 -0
  210. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-314.pyc +0 -0
  211. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-314.pyc +0 -0
  212. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
  213. claude_mpm/hooks/claude_hooks/event_handlers.py +283 -87
  214. claude_mpm/hooks/claude_hooks/hook_handler.py +106 -89
  215. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  216. claude_mpm/hooks/claude_hooks/installer.py +116 -8
  217. claude_mpm/hooks/claude_hooks/memory_integration.py +51 -31
  218. claude_mpm/hooks/claude_hooks/response_tracking.py +42 -59
  219. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-314.pyc +0 -0
  220. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  221. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-312.pyc +0 -0
  222. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-314.pyc +0 -0
  223. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-314.pyc +0 -0
  224. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  225. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-312.pyc +0 -0
  226. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-314.pyc +0 -0
  227. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  228. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-312.pyc +0 -0
  229. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-314.pyc +0 -0
  230. claude_mpm/hooks/claude_hooks/services/connection_manager.py +39 -24
  231. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +36 -103
  232. claude_mpm/hooks/claude_hooks/services/state_manager.py +23 -36
  233. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +73 -75
  234. claude_mpm/hooks/session_resume_hook.py +89 -1
  235. claude_mpm/hooks/templates/pre_tool_use_template.py +10 -2
  236. claude_mpm/init.py +1 -1
  237. claude_mpm/scripts/claude-hook-handler.sh +43 -16
  238. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  239. claude_mpm/services/agents/agent_selection_service.py +2 -2
  240. claude_mpm/services/agents/cache_git_manager.py +1 -1
  241. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  242. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +3 -0
  243. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  244. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  245. claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
  246. claude_mpm/services/agents/startup_sync.py +5 -2
  247. claude_mpm/services/cli/__init__.py +3 -0
  248. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  249. claude_mpm/services/cli/session_resume_helper.py +10 -2
  250. claude_mpm/services/delegation_detector.py +175 -0
  251. claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
  252. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  253. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  254. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  255. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  256. claude_mpm/services/diagnostics/models.py +14 -1
  257. claude_mpm/services/event_log.py +325 -0
  258. claude_mpm/services/infrastructure/__init__.py +4 -0
  259. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  260. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  261. claude_mpm/services/monitor/daemon_manager.py +15 -4
  262. claude_mpm/services/monitor/management/lifecycle.py +8 -2
  263. claude_mpm/services/monitor/server.py +106 -16
  264. claude_mpm/services/pm_skills_deployer.py +259 -87
  265. claude_mpm/services/skills/git_skill_source_manager.py +135 -11
  266. claude_mpm/services/skills/selective_skill_deployer.py +142 -26
  267. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  268. claude_mpm/services/skills_deployer.py +31 -5
  269. claude_mpm/services/socketio/handlers/hook.py +14 -7
  270. claude_mpm/services/socketio/server/main.py +12 -4
  271. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  272. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  273. claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
  274. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  275. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  276. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  277. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  278. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  279. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  280. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  281. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  282. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  283. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  284. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  285. claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
  286. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  287. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  288. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  289. claude_mpm/skills/skill_manager.py +4 -4
  290. claude_mpm/utils/agent_dependency_loader.py +4 -2
  291. claude_mpm/utils/robust_installer.py +10 -6
  292. claude_mpm-5.6.10.dist-info/METADATA +391 -0
  293. {claude_mpm-5.4.65.dist-info → claude_mpm-5.6.10.dist-info}/RECORD +303 -181
  294. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +0 -1
  295. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +0 -1
  296. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +0 -1
  297. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +0 -24
  298. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +0 -1
  299. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +0 -1
  300. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +0 -323
  301. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +0 -1
  302. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +0 -1
  303. claude_mpm-5.4.65.dist-info/METADATA +0 -999
  304. /claude_mpm/skills/bundled/pm/{pm-delegation-patterns → mpm-delegation-patterns}/SKILL.md +0 -0
  305. /claude_mpm/skills/bundled/pm/{pm-git-file-tracking → mpm-git-file-tracking}/SKILL.md +0 -0
  306. /claude_mpm/skills/bundled/pm/{pm-pr-workflow → mpm-pr-workflow}/SKILL.md +0 -0
  307. /claude_mpm/skills/bundled/pm/{pm-ticketing-integration → mpm-ticketing-integration}/SKILL.md +0 -0
  308. /claude_mpm/skills/bundled/pm/{pm-verification-protocols → mpm-verification-protocols}/SKILL.md +0 -0
  309. {claude_mpm-5.4.65.dist-info → claude_mpm-5.6.10.dist-info}/WHEEL +0 -0
  310. {claude_mpm-5.4.65.dist-info → claude_mpm-5.6.10.dist-info}/entry_points.txt +0 -0
  311. {claude_mpm-5.4.65.dist-info → claude_mpm-5.6.10.dist-info}/licenses/LICENSE +0 -0
  312. {claude_mpm-5.4.65.dist-info → claude_mpm-5.6.10.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  313. {claude_mpm-5.4.65.dist-info → claude_mpm-5.6.10.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,146 @@
1
+ """Basic notification delivery for events.
2
+
3
+ This module provides Notifier which sends notifications for events.
4
+ Currently supports logging, with extensibility for future channels
5
+ (Slack, email, webhooks).
6
+ """
7
+
8
+ import logging
9
+ from dataclasses import dataclass
10
+
11
+ from ..models.events import Event
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ @dataclass
17
+ class NotifierConfig:
18
+ """Configuration for notifier.
19
+
20
+ Attributes:
21
+ log_level: Logging level for notifications (default: INFO)
22
+
23
+ Future attributes:
24
+ slack_webhook: URL for Slack webhook notifications
25
+ email_config: SMTP configuration for email notifications
26
+ webhook_urls: List of webhook URLs for custom integrations
27
+ """
28
+
29
+ log_level: str = "INFO"
30
+ # Future: slack_webhook, email_config, webhook_urls
31
+
32
+
33
+ class Notifier:
34
+ """Sends notifications for events.
35
+
36
+ Currently implements logging-based notifications with configurable
37
+ log levels. Designed for extensibility to support future notification
38
+ channels like Slack, email, and webhooks.
39
+
40
+ Attributes:
41
+ config: Notifier configuration
42
+
43
+ Example:
44
+ >>> config = NotifierConfig(log_level="INFO")
45
+ >>> notifier = Notifier(config)
46
+ >>> await notifier.notify(event)
47
+ >>> await notifier.notify_resolution(event, "User responded")
48
+ """
49
+
50
+ def __init__(self, config: NotifierConfig | None = None) -> None:
51
+ """Initialize notifier.
52
+
53
+ Args:
54
+ config: Optional NotifierConfig (uses defaults if not provided)
55
+ """
56
+ self.config = config or NotifierConfig()
57
+
58
+ # Map log level string to logging level
59
+ level_map = {
60
+ "DEBUG": logging.DEBUG,
61
+ "INFO": logging.INFO,
62
+ "WARNING": logging.WARNING,
63
+ "ERROR": logging.ERROR,
64
+ "CRITICAL": logging.CRITICAL,
65
+ }
66
+ self._log_level = level_map.get(self.config.log_level.upper(), logging.INFO)
67
+
68
+ logger.debug("Notifier initialized with log level: %s", self.config.log_level)
69
+
70
+ async def notify(self, event: Event) -> None:
71
+ """Send notification for an event.
72
+
73
+ Currently logs the event at the configured log level. Future versions
74
+ will support additional notification channels.
75
+
76
+ Args:
77
+ event: Event to notify about
78
+
79
+ Example:
80
+ >>> await notifier.notify(event)
81
+ # Logs: [HIGH] Event evt_123: Choose deployment target
82
+ """
83
+ # Format notification message
84
+ message = self._format_event(event)
85
+
86
+ # Log notification
87
+ logger.log(
88
+ self._log_level,
89
+ "Event notification: %s",
90
+ message,
91
+ )
92
+
93
+ # Future: Send to Slack, email, webhooks
94
+ # if self.config.slack_webhook:
95
+ # await self._send_slack(event)
96
+ # if self.config.email_config:
97
+ # await self._send_email(event)
98
+
99
+ async def notify_resolution(self, event: Event, response: str) -> None:
100
+ """Notify that an event was resolved.
101
+
102
+ Logs the resolution with the user's response. Future versions will
103
+ send resolution notifications to configured channels.
104
+
105
+ Args:
106
+ event: Event that was resolved
107
+ response: User's response to the event
108
+
109
+ Example:
110
+ >>> await notifier.notify_resolution(event, "Deploy to staging")
111
+ # Logs: Event evt_123 resolved: Deploy to staging
112
+ """
113
+ message = f"Event {event.id} resolved: {response[:100]}"
114
+
115
+ logger.log(
116
+ self._log_level,
117
+ "Event resolution: %s",
118
+ message,
119
+ )
120
+
121
+ # Future: Send resolution notifications to channels
122
+
123
+ def _format_event(self, event: Event) -> str:
124
+ """Format event for notification display.
125
+
126
+ Args:
127
+ event: Event to format
128
+
129
+ Returns:
130
+ Formatted notification string
131
+
132
+ Example:
133
+ >>> msg = notifier._format_event(event)
134
+ '[HIGH] evt_123 (proj_456): Choose deployment target'
135
+ """
136
+ parts = [
137
+ f"[{event.priority.value.upper()}]",
138
+ f"{event.id}",
139
+ f"({event.project_id})",
140
+ f"{event.title}",
141
+ ]
142
+
143
+ if event.options:
144
+ parts.append(f"Options: {', '.join(event.options)}")
145
+
146
+ return " ".join(parts)
@@ -5,7 +5,15 @@ aliases: [mpm-config]
5
5
  migration_target: /mpm/config
6
6
  category: config
7
7
  description: Manage Claude MPM configuration
8
+ deprecated: true
9
+ deprecated_in: "5.5.0"
10
+ replacement: "skill:mpm-config"
8
11
  ---
12
+
13
+ > **Deprecated:** This command file is deprecated in favor of the `mpm-config` skill.
14
+ > For Claude Code 2.1.3+, use the skill-based `/mpm-config` command instead.
15
+ > This file is kept for backward compatibility with Claude Code < 2.1.3.
16
+
9
17
  # /mpm-config
10
18
 
11
19
  Unified configuration management with auto-detection.
@@ -5,7 +5,15 @@ aliases: [mpm-doctor]
5
5
  migration_target: /mpm/system:doctor
6
6
  category: system
7
7
  description: Run diagnostic checks on Claude MPM installation
8
+ deprecated: true
9
+ deprecated_in: "5.5.0"
10
+ replacement: "skill:mpm-doctor"
8
11
  ---
12
+
13
+ > **Deprecated:** This command file is deprecated in favor of the `mpm-doctor` skill.
14
+ > For Claude Code 2.1.3+, use the skill-based `/mpm-doctor` command instead.
15
+ > This file is kept for backward compatibility with Claude Code < 2.1.3.
16
+
9
17
  # /mpm-doctor
10
18
 
11
19
  Run comprehensive diagnostics on Claude MPM installation.
@@ -5,7 +5,15 @@ aliases: [mpm-help]
5
5
  migration_target: /mpm/system:help
6
6
  category: system
7
7
  description: Display help for Claude MPM commands
8
+ deprecated: true
9
+ deprecated_in: "5.5.0"
10
+ replacement: "skill:mpm-help"
8
11
  ---
12
+
13
+ > **Deprecated:** This command file is deprecated in favor of the `mpm-help` skill.
14
+ > For Claude Code 2.1.3+, use the skill-based `/mpm-help` command instead.
15
+ > This file is kept for backward compatibility with Claude Code < 2.1.3.
16
+
9
17
  # /mpm-help
10
18
 
11
19
  Show help for MPM commands. Delegates to PM agent.
@@ -5,7 +5,15 @@ aliases: [mpm-init]
5
5
  migration_target: /mpm/system:init
6
6
  category: system
7
7
  description: Initialize or update project for Claude Code and MPM
8
+ deprecated: true
9
+ deprecated_in: "5.5.0"
10
+ replacement: "skill:mpm-init"
8
11
  ---
12
+
13
+ > **Deprecated:** This command file is deprecated in favor of the `mpm-init` skill.
14
+ > For Claude Code 2.1.3+, use the skill-based `/mpm-init` command instead.
15
+ > This file is kept for backward compatibility with Claude Code < 2.1.3.
16
+
9
17
  # /mpm-init
10
18
 
11
19
  Initialize or intelligently update project for Claude Code and Claude MPM.
@@ -5,7 +5,15 @@ aliases: [mpm-monitor]
5
5
  migration_target: /mpm/system:monitor
6
6
  category: system
7
7
  description: Control monitoring server and dashboard
8
+ deprecated: true
9
+ deprecated_in: "5.5.0"
10
+ replacement: "skill:mpm-monitor"
8
11
  ---
12
+
13
+ > **Deprecated:** This command file is deprecated in favor of the `mpm-monitor` skill.
14
+ > For Claude Code 2.1.3+, use the skill-based `/mpm-monitor` command instead.
15
+ > This file is kept for backward compatibility with Claude Code < 2.1.3.
16
+
9
17
  # /mpm-monitor
10
18
 
11
19
  Manage Socket.IO monitoring server for real-time dashboard.
@@ -5,7 +5,15 @@ aliases: [mpm-organize]
5
5
  migration_target: /mpm/system:organize
6
6
  category: system
7
7
  description: Organize project files with intelligent consolidation
8
+ deprecated: true
9
+ deprecated_in: "5.5.0"
10
+ replacement: "skill:mpm-organize"
8
11
  ---
12
+
13
+ > **Deprecated:** This command file is deprecated in favor of the `mpm-organize` skill.
14
+ > For Claude Code 2.1.3+, use the skill-based `/mpm-organize` command instead.
15
+ > This file is kept for backward compatibility with Claude Code < 2.1.3.
16
+
9
17
  # /mpm-organize
10
18
 
11
19
  Organize ALL project files with intelligent detection, consolidation, and pruning.
@@ -5,7 +5,15 @@ aliases: [mpm-postmortem]
5
5
  migration_target: /mpm/analysis:postmortem
6
6
  category: analysis
7
7
  description: Analyze session errors and suggest improvements
8
+ deprecated: true
9
+ deprecated_in: "5.5.0"
10
+ replacement: "skill:mpm-postmortem"
8
11
  ---
12
+
13
+ > **Deprecated:** This command file is deprecated in favor of the `mpm-postmortem` skill.
14
+ > For Claude Code 2.1.3+, use the skill-based `/mpm-postmortem` command instead.
15
+ > This file is kept for backward compatibility with Claude Code < 2.1.3.
16
+
9
17
  # /mpm-postmortem
10
18
 
11
19
  Analyze session errors and generate improvement suggestions.
@@ -5,7 +5,15 @@ aliases: [mpm-session-resume]
5
5
  migration_target: /mpm/session:resume
6
6
  category: session
7
7
  description: Load context from paused session
8
+ deprecated: true
9
+ deprecated_in: "5.5.0"
10
+ replacement: "skill:mpm-session-resume"
8
11
  ---
12
+
13
+ > **Deprecated:** This command file is deprecated in favor of the `mpm-session-resume` skill.
14
+ > For Claude Code 2.1.3+, use the skill-based `/mpm-session-resume` command instead.
15
+ > This file is kept for backward compatibility with Claude Code < 2.1.3.
16
+
9
17
  # /mpm-session-resume
10
18
 
11
19
  Load and display context from most recent paused session.
@@ -21,7 +29,7 @@ Load and display context from most recent paused session.
21
29
  - Git context and recent commits
22
30
  - Next recommended actions
23
31
 
24
- **Session location:** `.claude-mpm/sessions/session-*.json`
32
+ **Session location:** `.claude-mpm/sessions/session-*.md`
25
33
 
26
34
  **Token usage:** ~20-40k tokens (10-20% of context budget)
27
35
 
@@ -5,7 +5,15 @@ aliases: [mpm-status]
5
5
  migration_target: /mpm/system:status
6
6
  category: system
7
7
  description: Display Claude MPM system status
8
+ deprecated: true
9
+ deprecated_in: "5.5.0"
10
+ replacement: "skill:mpm-status"
8
11
  ---
12
+
13
+ > **Deprecated:** This command file is deprecated in favor of the `mpm-status` skill.
14
+ > For Claude Code 2.1.3+, use the skill-based `/mpm-status` command instead.
15
+ > This file is kept for backward compatibility with Claude Code < 2.1.3.
16
+
9
17
  # /mpm-status
10
18
 
11
19
  Show MPM system status. Delegates to PM agent.
@@ -5,7 +5,15 @@ aliases: [mpm-ticket-view]
5
5
  migration_target: /mpm/ticket:view
6
6
  category: tickets
7
7
  description: Orchestrate ticketing agent for project management workflows
8
+ deprecated: true
9
+ deprecated_in: "5.5.0"
10
+ replacement: "skill:mpm-ticket-view"
8
11
  ---
12
+
13
+ > **Deprecated:** This command file is deprecated in favor of the `mpm-ticket-view` skill.
14
+ > For Claude Code 2.1.3+, use the skill-based `/mpm-ticket-view` command instead.
15
+ > This file is kept for backward compatibility with Claude Code < 2.1.3.
16
+
9
17
  # /mpm-ticket
10
18
 
11
19
  High-level ticketing workflows delegating to ticketing agent.
@@ -5,7 +5,15 @@ aliases: [mpm-version]
5
5
  migration_target: /mpm/system:version
6
6
  category: system
7
7
  description: Show version information
8
+ deprecated: true
9
+ deprecated_in: "5.5.0"
10
+ replacement: "skill:mpm-version"
8
11
  ---
12
+
13
+ > **Deprecated:** This command file is deprecated in favor of the `mpm-version` skill.
14
+ > For Claude Code 2.1.3+, use the skill-based `/mpm-version` command instead.
15
+ > This file is kept for backward compatibility with Claude Code < 2.1.3.
16
+
9
17
  # /mpm-version
10
18
 
11
19
  Display version information for MPM, agents, and skills.
@@ -6,7 +6,15 @@ migration_target: /mpm
6
6
  category: system
7
7
  deprecated_aliases: []
8
8
  description: Access Claude MPM functionality and manage multi-agent orchestration
9
+ deprecated: true
10
+ deprecated_in: "5.5.0"
11
+ replacement: "skill:mpm"
9
12
  ---
13
+
14
+ > **Deprecated:** This command file is deprecated in favor of the `mpm` skill.
15
+ > For Claude Code 2.1.3+, use the skill-based `/mpm` command instead.
16
+ > This file is kept for backward compatibility with Claude Code < 2.1.3.
17
+
10
18
  # Claude MPM - Multi-Agent Project Manager
11
19
 
12
20
  Access Claude MPM functionality and manage your multi-agent orchestration.
@@ -25,12 +25,17 @@ from typing import Any, Callable, Dict, List, Union
25
25
  PresetResolver = Union[List[str], Callable[[], List[str]]]
26
26
 
27
27
  # Core agents included in ALL presets (MIN and MAX)
28
+ # Standard 9 core agents for essential PM workflow functionality
28
29
  CORE_AGENTS = [
29
30
  "claude-mpm/mpm-agent-manager", # Agent lifecycle management
30
31
  "claude-mpm/mpm-skills-manager", # Skills management
31
- "universal/research", # Codebase investigation
32
+ "engineer/core/engineer", # General-purpose implementation
33
+ "universal/research", # Codebase exploration and analysis
34
+ "qa/qa", # Testing and quality assurance
35
+ "qa/web-qa", # Browser-based testing specialist
32
36
  "documentation/documentation", # Documentation generation
33
- "engineer/core/engineer", # General-purpose engineering
37
+ "ops/core/ops", # Basic deployment operations
38
+ "documentation/ticketing", # Ticket tracking (essential for PM workflow)
34
39
  ]
35
40
 
36
41
  PRESETS: Dict[str, Dict[str, Any]] = {
@@ -39,11 +44,7 @@ PRESETS: Dict[str, Dict[str, Any]] = {
39
44
  # ========================================
40
45
  "minimal": {
41
46
  "description": "Core agents only - universal starter kit",
42
- "agents": CORE_AGENTS
43
- + [
44
- "qa/qa",
45
- "ops/core/ops",
46
- ],
47
+ "agents": CORE_AGENTS, # All 8 core agents (no additional needed)
47
48
  "use_cases": ["Any project type", "Quick start", "Learning"],
48
49
  },
49
50
  # ========================================
@@ -54,6 +54,7 @@ class SkillSource:
54
54
  branch: Git branch to use (default: "main")
55
55
  priority: Priority for skill resolution (lower = higher precedence)
56
56
  enabled: Whether this source should be synced
57
+ token: Optional GitHub token or env var reference (e.g., "$MY_TOKEN")
57
58
 
58
59
  Priority System:
59
60
  - 0: Reserved for system repository (highest precedence)
@@ -61,6 +62,12 @@ class SkillSource:
61
62
  - 100-999: Normal priority custom sources
62
63
  - 1000+: Low priority custom sources
63
64
 
65
+ Token Authentication:
66
+ - Direct token: "ghp_xxxxx" (stored in config, not recommended)
67
+ - Env var reference: "$PRIVATE_REPO_TOKEN" (resolved at runtime)
68
+ - If None, falls back to GITHUB_TOKEN or GH_TOKEN env vars
69
+ - Priority: source.token > GITHUB_TOKEN > GH_TOKEN
70
+
64
71
  Example:
65
72
  >>> source = SkillSource(
66
73
  ... id="system",
@@ -70,6 +77,12 @@ class SkillSource:
70
77
  ... )
71
78
  >>> source.validate()
72
79
  []
80
+ >>> private_source = SkillSource(
81
+ ... id="private",
82
+ ... type="git",
83
+ ... url="https://github.com/myorg/private-skills",
84
+ ... token="$PRIVATE_REPO_TOKEN"
85
+ ... )
73
86
  """
74
87
 
75
88
  id: str
@@ -78,6 +91,7 @@ class SkillSource:
78
91
  branch: str = "main"
79
92
  priority: int = 100
80
93
  enabled: bool = True
94
+ token: Optional[str] = None
81
95
 
82
96
  def __post_init__(self):
83
97
  """Validate skill source configuration after initialization.
@@ -262,6 +276,7 @@ class SkillSourceConfiguration:
262
276
  branch=source_data.get("branch", "main"),
263
277
  priority=source_data.get("priority", 100),
264
278
  enabled=source_data.get("enabled", True),
279
+ token=source_data.get("token"),
265
280
  )
266
281
  sources.append(source)
267
282
  except (KeyError, ValueError) as e:
@@ -326,6 +341,7 @@ class SkillSourceConfiguration:
326
341
  "branch": source.branch,
327
342
  "priority": source.priority,
328
343
  "enabled": source.enabled,
344
+ **({"token": source.token} if source.token else {}),
329
345
  }
330
346
  for source in sources
331
347
  ]
claude_mpm/constants.py CHANGED
@@ -169,6 +169,7 @@ class SkillsCommands(str, Enum):
169
169
  INFO = "info"
170
170
  CONFIG = "config"
171
171
  CONFIGURE = "configure" # Interactive skills selection (like agents configure)
172
+ SELECT = "select" # Interactive topic-grouped skill selector
172
173
  # GitHub deployment commands
173
174
  DEPLOY_FROM_GITHUB = "deploy-github"
174
175
  LIST_AVAILABLE = "list-available"
@@ -730,7 +730,7 @@ Use these agents to delegate specialized work via the Task tool.
730
730
  import json
731
731
 
732
732
  settings = json.loads(settings_file.read_text())
733
- if settings.get("activeOutputStyle") == "claude-mpm":
733
+ if settings.get("activeOutputStyle") == "Claude MPM":
734
734
  # Already active, check if file exists
735
735
  output_style_file = (
736
736
  Path.home() / ".claude" / "output-styles" / "claude-mpm.md"
@@ -740,7 +740,7 @@ Use these agents to delegate specialized work via the Task tool.
740
740
  "Output style 'Claude MPM' already deployed and active"
741
741
  )
742
742
  return
743
- except Exception:
743
+ except Exception: # nosec B110
744
744
  pass # Continue with deployment if we can't read settings
745
745
 
746
746
  # Read the OUTPUT_STYLE.md content if it exists
claude_mpm/core/config.py CHANGED
@@ -12,11 +12,10 @@ import threading
12
12
  from pathlib import Path
13
13
  from typing import Any, Dict, List, Optional, Tuple, Union
14
14
 
15
- import yaml
16
-
17
15
  from claude_mpm.core.logging_utils import get_logger
18
16
 
19
- from ..utils.config_manager import ConfigurationManager
17
+ # Lazy import ConfigurationManager to avoid importing yaml at module level
18
+ # This prevents hook errors when yaml isn't available in the execution environment
20
19
  from .exceptions import ConfigurationError, FileOperationError
21
20
  from .unified_paths import get_path_manager
22
21
 
@@ -104,6 +103,9 @@ class Config:
104
103
  Config._initialized = True
105
104
  logger.debug("Initializing Config singleton for the first time")
106
105
 
106
+ # Lazy import ConfigurationManager at runtime to avoid yaml import at module level
107
+ from ..utils.config_manager import ConfigurationManager
108
+
107
109
  # Initialize instance variables inside the lock to ensure thread safety
108
110
  self._config: Dict[str, Any] = {}
109
111
  self._env_prefix = env_prefix
@@ -224,21 +226,6 @@ class Config:
224
226
  f"Response logging format: {response_logging.get('format', 'json')}"
225
227
  )
226
228
 
227
- except yaml.YAMLError as e:
228
- logger.error(f"YAML syntax error in {file_path}: {e}")
229
- if hasattr(e, "problem_mark"):
230
- mark = e.problem_mark
231
- logger.error(f"Error at line {mark.line + 1}, column {mark.column + 1}")
232
- logger.info(
233
- "TIP: Validate your YAML at https://www.yamllint.com/ or run: python scripts/validate_configuration.py"
234
- )
235
- logger.info(
236
- "TIP: Common issue - YAML requires spaces, not tabs. Fix with: sed -i '' 's/\t/ /g' "
237
- + str(file_path)
238
- )
239
- # Store error for later retrieval
240
- self._config["_load_error"] = str(e)
241
-
242
229
  except json.JSONDecodeError as e:
243
230
  logger.error(f"JSON syntax error in {file_path}: {e}")
244
231
  logger.error(f"Error at line {e.lineno}, column {e.colno}")
@@ -255,7 +242,28 @@ class Config:
255
242
  },
256
243
  ) from e
257
244
  except Exception as e:
258
- # Catch any remaining unexpected errors and wrap them as configuration errors
245
+ # Handle YAML errors without importing yaml at module level
246
+ # ConfigurationManager.load_yaml raises yaml.YAMLError, but we don't want to import yaml
247
+ # Check if it's a YAML error by class name to avoid import
248
+ if e.__class__.__name__ == "YAMLError":
249
+ logger.error(f"YAML syntax error in {file_path}: {e}")
250
+ if hasattr(e, "problem_mark"):
251
+ mark = e.problem_mark
252
+ logger.error(
253
+ f"Error at line {mark.line + 1}, column {mark.column + 1}"
254
+ )
255
+ logger.info(
256
+ "TIP: Validate your YAML at https://www.yamllint.com/ or run: python scripts/validate_configuration.py"
257
+ )
258
+ logger.info(
259
+ "TIP: Common issue - YAML requires spaces, not tabs. Fix with: sed -i '' 's/\t/ /g' "
260
+ + str(file_path)
261
+ )
262
+ # Store error for later retrieval
263
+ self._config["_load_error"] = str(e)
264
+ return # Don't re-raise, we handled it
265
+
266
+ # Not a YAML error, wrap as configuration error
259
267
  raise ConfigurationError(
260
268
  f"Unexpected error loading configuration from {file_path}: {e}",
261
269
  context={
@@ -605,6 +613,11 @@ class Config:
605
613
  "sync_interval": "startup", # Options: "startup", "hourly", "daily", "manual"
606
614
  "cache_dir": str(Path.home() / ".claude-mpm" / "cache" / "agents"),
607
615
  },
616
+ # Autotodos configuration
617
+ "autotodos": {
618
+ "auto_inject_on_startup": True, # Auto-inject pending todos on PM session start
619
+ "max_todos_per_session": 10, # Max todos to inject per session
620
+ },
608
621
  }
609
622
 
610
623
  # Apply defaults for missing keys
@@ -16,13 +16,15 @@ import contextlib
16
16
  import json
17
17
  import os
18
18
  import queue
19
- import subprocess
19
+ import subprocess # nosec B404
20
20
  import threading
21
21
  import uuid
22
22
  from datetime import datetime, timezone
23
23
  from typing import Any, Dict, Optional
24
24
 
25
25
  from ..core.logger import get_logger
26
+ from ..services.event_bus.event_bus import EventBus
27
+ from ..services.event_log import get_event_log
26
28
  from .hook_error_memory import get_hook_error_memory
27
29
  from .hook_performance_config import get_hook_performance_config
28
30
  from .unified_paths import get_package_root
@@ -46,6 +48,10 @@ class HookManager:
46
48
  # Initialize error memory for tracking and preventing repeated errors
47
49
  self.error_memory = get_hook_error_memory()
48
50
 
51
+ # Initialize event log and event bus for event-driven architecture
52
+ self.event_log = get_event_log()
53
+ self.event_bus = EventBus.get_instance()
54
+
49
55
  # Initialize background hook processing for async execution
50
56
  self.performance_config = get_hook_performance_config()
51
57
  queue_config = self.performance_config.get_queue_config()
@@ -100,6 +106,45 @@ class HookManager:
100
106
  self.background_thread.start()
101
107
  self.logger.debug("Started background hook processor thread")
102
108
 
109
+ def _publish_error_event(
110
+ self, hook_type: str, error_info: Dict[str, str], suggestion: str
111
+ ):
112
+ """Publish hook error event to event log and event bus.
113
+
114
+ WHY publish events:
115
+ - Decouple error detection from error handling
116
+ - Enable autotodos CLI to read from persistent event log
117
+ - Support real-time notifications via event bus
118
+ - Maintain audit trail of all hook errors
119
+
120
+ Args:
121
+ hook_type: Type of hook that failed
122
+ error_info: Error information from error detection
123
+ suggestion: Fix suggestion from error memory
124
+ """
125
+ try:
126
+ # Prepare event payload
127
+ payload = {
128
+ "error_type": error_info["type"],
129
+ "hook_type": hook_type,
130
+ "details": error_info.get("details", ""),
131
+ "full_message": error_info.get("match", ""),
132
+ "suggested_fix": suggestion,
133
+ "source": "hook_manager",
134
+ }
135
+
136
+ # Publish to event log (persistent storage)
137
+ self.event_log.append_event(
138
+ event_type="autotodo.error", payload=payload, status="pending"
139
+ )
140
+
141
+ # Publish to event bus (real-time listeners)
142
+ self.event_bus.publish("autotodo.error", payload)
143
+
144
+ except Exception as e:
145
+ # Don't let event publishing break hook processing
146
+ self.logger.debug(f"Failed to publish error event: {e}")
147
+
103
148
  def _execute_hook_sync(self, hook_data: Dict[str, Any]):
104
149
  """Execute a single hook synchronously in the background thread with error detection.
105
150
 
@@ -141,7 +186,7 @@ class HookManager:
141
186
  env["CLAUDE_MPM_HOOK_DEBUG"] = "true"
142
187
 
143
188
  # Execute with timeout in background thread
144
- result = subprocess.run(
189
+ result = subprocess.run( # nosec B603 B607
145
190
  ["python", str(self.hook_handler_path)],
146
191
  input=event_json,
147
192
  text=True,
@@ -157,7 +202,7 @@ class HookManager:
157
202
  )
158
203
 
159
204
  if error_info:
160
- # Record the error
205
+ # Record the error in memory (for skipping repeated failures)
161
206
  self.error_memory.record_error(error_info, hook_type)
162
207
 
163
208
  # Get fix suggestion
@@ -165,6 +210,9 @@ class HookManager:
165
210
 
166
211
  # Log error with suggestion
167
212
  self.logger.warning(f"Hook {hook_type} error detected:\n{suggestion}")
213
+
214
+ # Publish event to event log for autotodos processing
215
+ self._publish_error_event(hook_type, error_info, suggestion)
168
216
  elif result.returncode != 0:
169
217
  # Non-zero return without detected pattern
170
218
  self.logger.debug(f"Hook {hook_type} returned code {result.returncode}")