claude-mpm 5.4.41__py3-none-any.whl → 5.6.23__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 (460) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
  3. claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
  4. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
  5. claude_mpm/agents/PM_INSTRUCTIONS.md +161 -298
  6. claude_mpm/agents/WORKFLOW.md +2 -0
  7. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  8. claude_mpm/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 +182 -32
  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 +2 -3
  33. claude_mpm/cli/startup.py +527 -506
  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 +35 -11
  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 +63 -18
  154. claude_mpm/core/shared/config_loader.py +3 -1
  155. claude_mpm/core/socketio_pool.py +13 -5
  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 +305 -87
  239. claude_mpm/hooks/claude_hooks/hook_handler.py +106 -89
  240. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  241. claude_mpm/hooks/claude_hooks/installer.py +116 -8
  242. claude_mpm/hooks/claude_hooks/memory_integration.py +51 -31
  243. claude_mpm/hooks/claude_hooks/response_tracking.py +42 -59
  244. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  245. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  246. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  247. claude_mpm/hooks/claude_hooks/services/connection_manager.py +39 -24
  248. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +36 -103
  249. claude_mpm/hooks/claude_hooks/services/state_manager.py +23 -36
  250. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +73 -75
  251. claude_mpm/hooks/kuzu_memory_hook.py +5 -5
  252. claude_mpm/hooks/session_resume_hook.py +89 -1
  253. claude_mpm/hooks/templates/pre_tool_use_template.py +10 -2
  254. claude_mpm/init.py +215 -2
  255. claude_mpm/scripts/claude-hook-handler.sh +43 -16
  256. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  257. claude_mpm/services/agents/agent_selection_service.py +2 -2
  258. claude_mpm/services/agents/cache_git_manager.py +1 -1
  259. claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -1
  260. claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
  261. claude_mpm/services/agents/deployment/agent_template_builder.py +37 -17
  262. claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
  263. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  264. claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
  265. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +36 -8
  266. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +50 -26
  267. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  268. claude_mpm/services/agents/git_source_manager.py +21 -2
  269. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  270. claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
  271. claude_mpm/services/agents/sources/git_source_sync_service.py +116 -5
  272. claude_mpm/services/agents/startup_sync.py +5 -2
  273. claude_mpm/services/cli/__init__.py +3 -0
  274. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  275. claude_mpm/services/cli/session_resume_helper.py +10 -2
  276. claude_mpm/services/delegation_detector.py +175 -0
  277. claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
  278. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  279. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  280. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  281. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  282. claude_mpm/services/diagnostics/models.py +14 -1
  283. claude_mpm/services/event_log.py +325 -0
  284. claude_mpm/services/infrastructure/__init__.py +4 -0
  285. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  286. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  287. claude_mpm/services/monitor/daemon_manager.py +15 -4
  288. claude_mpm/services/monitor/management/lifecycle.py +8 -3
  289. claude_mpm/services/monitor/server.py +106 -16
  290. claude_mpm/services/pm_skills_deployer.py +302 -94
  291. claude_mpm/services/profile_manager.py +10 -4
  292. claude_mpm/services/skills/git_skill_source_manager.py +192 -29
  293. claude_mpm/services/skills/selective_skill_deployer.py +211 -46
  294. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  295. claude_mpm/services/skills_deployer.py +192 -70
  296. claude_mpm/services/socketio/handlers/hook.py +14 -7
  297. claude_mpm/services/socketio/server/main.py +12 -4
  298. claude_mpm/skills/__init__.py +2 -1
  299. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  300. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  301. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  302. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  303. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  304. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  305. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  306. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  307. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  308. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  309. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  310. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  311. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  312. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  313. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  314. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  315. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  316. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  317. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  318. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  319. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  320. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  321. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  322. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  323. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  324. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  325. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  326. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  327. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  328. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  329. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  330. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  331. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  332. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  333. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  334. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  335. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  336. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  337. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  338. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  339. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  340. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  341. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  342. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  343. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  344. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  345. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  346. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  347. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  348. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  349. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  350. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  351. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  352. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  353. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  354. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  355. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  356. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  357. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  358. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  359. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  360. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  361. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  362. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  363. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  364. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  365. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  366. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  367. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  368. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  369. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  370. claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
  371. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  372. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  373. claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
  374. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  375. claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
  376. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  377. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  378. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  379. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  380. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  381. claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
  382. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  383. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  384. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  385. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  386. claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
  387. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  388. claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
  389. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  390. claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
  391. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  392. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  393. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  394. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  395. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  396. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  397. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  398. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  399. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  400. claude_mpm/skills/bundled/security-scanning.md +112 -0
  401. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  402. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  403. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  404. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  405. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  406. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  407. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  408. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  409. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  410. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  411. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  412. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  413. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  414. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  415. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  416. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  417. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  418. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  419. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  420. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  421. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  422. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  423. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  424. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  425. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  426. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  427. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  428. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  429. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  430. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  431. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  432. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  433. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  434. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  435. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  436. claude_mpm/skills/registry.py +295 -90
  437. claude_mpm/skills/skill_manager.py +29 -23
  438. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  439. claude_mpm/utils/agent_dependency_loader.py +103 -4
  440. claude_mpm/utils/robust_installer.py +45 -24
  441. claude_mpm-5.6.23.dist-info/METADATA +393 -0
  442. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/RECORD +447 -149
  443. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
  444. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
  445. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
  446. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
  447. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +0 -1
  448. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
  449. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
  450. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
  451. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
  452. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
  453. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  454. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  455. claude_mpm-5.4.41.dist-info/METADATA +0 -998
  456. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/WHEEL +0 -0
  457. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/entry_points.txt +0 -0
  458. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/licenses/LICENSE +0 -0
  459. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  460. {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.23.dist-info}/top_level.txt +0 -0
@@ -7,13 +7,21 @@ Claude Code hook events.
7
7
 
8
8
  import os
9
9
  import re
10
- import subprocess
11
- import sys
10
+ import subprocess # nosec B404 - subprocess used for safe claude CLI version checking only
12
11
  import uuid
13
12
  from datetime import datetime, timezone
14
13
  from pathlib import Path
15
14
  from typing import Optional
16
15
 
16
+ # Import _log helper to avoid stderr writes (which cause hook errors)
17
+ try:
18
+ from .hook_handler import _log
19
+ except ImportError:
20
+ # Fallback for direct execution
21
+ def _log(message: str) -> None:
22
+ """Fallback logger when hook_handler not available."""
23
+
24
+
17
25
  # Import tool analysis with fallback for direct execution
18
26
  try:
19
27
  # Try relative import first (when imported as module)
@@ -34,8 +42,8 @@ except ImportError:
34
42
  extract_tool_results,
35
43
  )
36
44
 
37
- # Debug mode
38
- DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "true").lower() != "false"
45
+ # Debug mode - MUST match hook_handler.py default (false) to prevent stderr writes
46
+ DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "false").lower() == "true"
39
47
 
40
48
  # Import constants for configuration
41
49
  try:
@@ -111,14 +119,22 @@ class EventHandlers:
111
119
  "working_directory": working_dir,
112
120
  }
113
121
  if DEBUG:
114
- print(
115
- f"Stored prompt for comprehensive tracking: session {session_id[:8]}...",
116
- file=sys.stderr,
122
+ _log(
123
+ f"Stored prompt for comprehensive tracking: session {session_id[:8]}..."
117
124
  )
118
- except Exception:
125
+ except Exception: # nosec B110
119
126
  # Response tracking is optional - silently continue if it fails
120
127
  pass
121
128
 
129
+ # Record user message for auto-pause if active
130
+ auto_pause = getattr(self.hook_handler, "auto_pause_handler", None)
131
+ if auto_pause and auto_pause.is_pause_active():
132
+ try:
133
+ auto_pause.on_user_message(prompt)
134
+ except Exception as e:
135
+ if DEBUG:
136
+ _log(f"Auto-pause user message recording error: {e}")
137
+
122
138
  # Emit normalized event (namespace no longer needed with normalized events)
123
139
  self.hook_handler._emit_socketio_event("", "user_prompt", prompt_data)
124
140
 
@@ -133,11 +149,8 @@ class EventHandlers:
133
149
  # Enhanced debug logging for session correlation
134
150
  session_id = event.get("session_id", "")
135
151
  if DEBUG:
136
- print(
137
- f" - session_id: {session_id[:16] if session_id else 'None'}...",
138
- file=sys.stderr,
139
- )
140
- print(f" - event keys: {list(event.keys())}", file=sys.stderr)
152
+ _log(f" - session_id: {session_id[:16] if session_id else 'None'}...")
153
+ _log(f" - event keys: {list(event.keys())}")
141
154
 
142
155
  tool_name = event.get("tool_name", "")
143
156
  tool_input = event.get("tool_input", {})
@@ -180,17 +193,41 @@ class EventHandlers:
180
193
 
181
194
  CorrelationManager.store(session_id, tool_call_id, tool_name)
182
195
  if DEBUG:
183
- print(
184
- f" - Generated tool_call_id: {tool_call_id[:8]}... for session {session_id[:8]}...",
185
- file=sys.stderr,
196
+ _log(
197
+ f" - Generated tool_call_id: {tool_call_id[:8]}... for session {session_id[:8]}..."
186
198
  )
187
199
 
188
200
  # Add delegation-specific data if this is a Task tool
189
201
  if tool_name == "Task" and isinstance(tool_input, dict):
190
202
  self._handle_task_delegation(tool_input, pre_tool_data, session_id)
191
203
 
204
+ # Record tool call for auto-pause if active
205
+ auto_pause = getattr(self.hook_handler, "auto_pause_handler", None)
206
+ if auto_pause and auto_pause.is_pause_active():
207
+ try:
208
+ auto_pause.on_tool_call(tool_name, tool_input)
209
+ except Exception as e:
210
+ if DEBUG:
211
+ _log(f"Auto-pause tool recording error: {e}")
212
+
192
213
  self.hook_handler._emit_socketio_event("", "pre_tool", pre_tool_data)
193
214
 
215
+ # Handle TodoWrite specially - emit dedicated todo_updated event
216
+ # WHY: Frontend expects todo_updated events for dashboard display
217
+ # The broadcaster.todo_updated() method exists but was never called
218
+ if tool_name == "TodoWrite" and tool_params.get("todos"):
219
+ todo_data = {
220
+ "todos": tool_params["todos"],
221
+ "total_count": len(tool_params["todos"]),
222
+ "session_id": session_id,
223
+ "timestamp": timestamp,
224
+ }
225
+ self.hook_handler._emit_socketio_event("", "todo_updated", todo_data)
226
+ if DEBUG:
227
+ _log(
228
+ f" - Emitted todo_updated event with {len(tool_params['todos'])} todos for session {session_id[:8]}..."
229
+ )
230
+
194
231
  def _handle_task_delegation(
195
232
  self, tool_input: dict, pre_tool_data: dict, session_id: str
196
233
  ):
@@ -229,12 +266,9 @@ class EventHandlers:
229
266
 
230
267
  # Track this delegation for SubagentStop correlation and response tracking
231
268
  if DEBUG:
232
- print(
233
- f" - session_id: {session_id[:16] if session_id else 'None'}...",
234
- file=sys.stderr,
235
- )
236
- print(f" - agent_type: {agent_type}", file=sys.stderr)
237
- print(f" - raw_agent_type: {raw_agent_type}", file=sys.stderr)
269
+ _log(f" - session_id: {session_id[:16] if session_id else 'None'}...")
270
+ _log(f" - agent_type: {agent_type}")
271
+ _log(f" - raw_agent_type: {raw_agent_type}")
238
272
 
239
273
  if session_id and agent_type != "unknown":
240
274
  # Prepare request data for response tracking correlation
@@ -246,24 +280,17 @@ class EventHandlers:
246
280
  self.hook_handler._track_delegation(session_id, agent_type, request_data)
247
281
 
248
282
  if DEBUG:
249
- print(" - Delegation tracked successfully", file=sys.stderr)
250
- print(
251
- f" - Request data keys: {list(request_data.keys())}",
252
- file=sys.stderr,
253
- )
283
+ _log(" - Delegation tracked successfully")
284
+ _log(f" - Request data keys: {list(request_data.keys())}")
254
285
  delegation_requests = getattr(
255
286
  self.hook_handler, "delegation_requests", {}
256
287
  )
257
- print(
258
- f" - delegation_requests size: {len(delegation_requests)}",
259
- file=sys.stderr,
260
- )
288
+ _log(f" - delegation_requests size: {len(delegation_requests)}")
261
289
 
262
290
  # Log important delegations for debugging
263
291
  if DEBUG or agent_type in ["research", "engineer", "qa", "documentation"]:
264
- print(
265
- f"Hook handler: Task delegation started - agent: '{agent_type}', session: '{session_id}'",
266
- file=sys.stderr,
292
+ _log(
293
+ f"Hook handler: Task delegation started - agent: '{agent_type}', session: '{session_id}'"
267
294
  )
268
295
 
269
296
  # Trigger memory pre-delegation hook
@@ -271,7 +298,7 @@ class EventHandlers:
271
298
  mhm = getattr(self.hook_handler, "memory_hook_manager", None)
272
299
  if mhm and hasattr(mhm, "trigger_pre_delegation_hook"):
273
300
  mhm.trigger_pre_delegation_hook(agent_type, tool_input, session_id)
274
- except Exception:
301
+ except Exception: # nosec B110
275
302
  # Memory hooks are optional
276
303
  pass
277
304
 
@@ -333,10 +360,10 @@ class EventHandlers:
333
360
  )
334
361
 
335
362
  if DEBUG:
336
- print(f" - Agent prompt logged for {agent_type}", file=sys.stderr)
363
+ _log(f" - Agent prompt logged for {agent_type}")
337
364
  except Exception as e:
338
365
  if DEBUG:
339
- print(f" - Could not log agent prompt: {e}", file=sys.stderr)
366
+ _log(f" - Could not log agent prompt: {e}")
340
367
 
341
368
  def _get_git_branch(self, working_dir: Optional[str] = None) -> str:
342
369
  """Get git branch for the given directory with caching."""
@@ -364,7 +391,7 @@ class EventHandlers:
364
391
  os.chdir(working_dir)
365
392
 
366
393
  # Run git command to get current branch
367
- result = subprocess.run(
394
+ result = subprocess.run( # nosec B603 B607
368
395
  ["git", "branch", "--show-current"],
369
396
  capture_output=True,
370
397
  text=True,
@@ -424,9 +451,8 @@ class EventHandlers:
424
451
 
425
452
  tool_call_id = CorrelationManager.retrieve(session_id) if session_id else None
426
453
  if DEBUG and tool_call_id:
427
- print(
428
- f" - Retrieved tool_call_id: {tool_call_id[:8]}... for session {session_id[:8]}...",
429
- file=sys.stderr,
454
+ _log(
455
+ f" - Retrieved tool_call_id: {tool_call_id[:8]}... for session {session_id[:8]}..."
430
456
  )
431
457
 
432
458
  post_tool_data = {
@@ -474,7 +500,7 @@ class EventHandlers:
474
500
  mhm = getattr(self.hook_handler, "memory_hook_manager", None)
475
501
  if mhm and hasattr(mhm, "trigger_post_delegation_hook"):
476
502
  mhm.trigger_post_delegation_hook(agent_type, event, session_id)
477
- except Exception:
503
+ except Exception: # nosec B110
478
504
  # Memory hooks are optional
479
505
  pass
480
506
 
@@ -488,7 +514,7 @@ class EventHandlers:
488
514
  rtm.track_agent_response(
489
515
  session_id, agent_type, event, delegation_requests
490
516
  )
491
- except Exception:
517
+ except Exception: # nosec B110
492
518
  # Response tracking is optional
493
519
  pass
494
520
 
@@ -550,13 +576,62 @@ class EventHandlers:
550
576
  if DEBUG:
551
577
  self._log_stop_event_debug(event, session_id, metadata)
552
578
 
579
+ # Auto-pause integration (independent of response tracking)
580
+ # WHY HERE: Auto-pause must work even when response_tracking is disabled
581
+ # Extract usage data directly from event and trigger auto-pause if thresholds crossed
582
+ if "usage" in event:
583
+ auto_pause = getattr(self.hook_handler, "auto_pause_handler", None)
584
+ if auto_pause:
585
+ try:
586
+ usage_data = event["usage"]
587
+ metadata["usage"] = {
588
+ "input_tokens": usage_data.get("input_tokens", 0),
589
+ "output_tokens": usage_data.get("output_tokens", 0),
590
+ "cache_creation_input_tokens": usage_data.get(
591
+ "cache_creation_input_tokens", 0
592
+ ),
593
+ "cache_read_input_tokens": usage_data.get(
594
+ "cache_read_input_tokens", 0
595
+ ),
596
+ }
597
+
598
+ threshold_crossed = auto_pause.on_usage_update(metadata["usage"])
599
+ if threshold_crossed:
600
+ warning = auto_pause.emit_threshold_warning(threshold_crossed)
601
+ # CRITICAL: Never write to stderr unconditionally - causes hook errors
602
+ # Use _log() instead which only writes to file if DEBUG=true
603
+ from . import _log
604
+
605
+ _log(f"⚠️ Auto-pause threshold crossed: {warning}")
606
+
607
+ if DEBUG:
608
+ _log(
609
+ f" - Auto-pause threshold crossed: {threshold_crossed}"
610
+ )
611
+ except Exception as e:
612
+ if DEBUG:
613
+ _log(f"Auto-pause error in handle_stop_fast: {e}")
614
+
615
+ # Finalize pause session if active
616
+ try:
617
+ if auto_pause.is_pause_active():
618
+ session_file = auto_pause.on_session_end()
619
+ if session_file:
620
+ if DEBUG:
621
+ _log(
622
+ f"✅ Auto-pause session finalized: {session_file.name}"
623
+ )
624
+ except Exception as e:
625
+ if DEBUG:
626
+ _log(f"❌ Failed to finalize auto-pause session: {e}")
627
+
553
628
  # Track response if enabled
554
629
  try:
555
630
  rtm = getattr(self.hook_handler, "response_tracking_manager", None)
556
631
  if rtm and hasattr(rtm, "track_stop_response"):
557
632
  pending_prompts = getattr(self.hook_handler, "pending_prompts", {})
558
633
  rtm.track_stop_response(event, session_id, metadata, pending_prompts)
559
- except Exception:
634
+ except Exception: # nosec B110
560
635
  # Response tracking is optional
561
636
  pass
562
637
 
@@ -590,24 +665,15 @@ class EventHandlers:
590
665
  getattr(rtm, "response_tracker", None) is not None if rtm else False
591
666
  )
592
667
 
593
- print(
594
- f" - response_tracking_enabled: {tracking_enabled}",
595
- file=sys.stderr,
596
- )
597
- print(
598
- f" - response_tracker exists: {tracker_exists}",
599
- file=sys.stderr,
600
- )
601
- except Exception:
668
+ _log(f" - response_tracking_enabled: {tracking_enabled}")
669
+ _log(f" - response_tracker exists: {tracker_exists}")
670
+ except Exception: # nosec B110
602
671
  # If debug logging fails, just skip it
603
672
  pass
604
673
 
605
- print(
606
- f" - session_id: {session_id[:8] if session_id else 'None'}...",
607
- file=sys.stderr,
608
- )
609
- print(f" - reason: {metadata['reason']}", file=sys.stderr)
610
- print(f" - stop_type: {metadata['stop_type']}", file=sys.stderr)
674
+ _log(f" - session_id: {session_id[:8] if session_id else 'None'}...")
675
+ _log(f" - reason: {metadata['reason']}")
676
+ _log(f" - stop_type: {metadata['stop_type']}")
611
677
 
612
678
  def _emit_stop_event(self, event: dict, session_id: str, metadata: dict) -> None:
613
679
  """Emit stop event data to Socket.IO."""
@@ -664,15 +730,12 @@ class EventHandlers:
664
730
  try:
665
731
  # Get the original request data (with fuzzy matching fallback)
666
732
  delegation_requests = getattr(self.hook_handler, "delegation_requests", {})
667
- request_info = delegation_requests.get(session_id)
733
+ request_info = delegation_requests.get(session_id) # nosec B113
668
734
 
669
735
  # If exact match fails, try partial matching
670
736
  if not request_info and session_id:
671
737
  if DEBUG:
672
- print(
673
- f" - Trying fuzzy match for session {session_id[:16]}...",
674
- file=sys.stderr,
675
- )
738
+ _log(f" - Trying fuzzy match for session {session_id[:16]}...")
676
739
  # Try to find a session that matches the first 8-16 characters
677
740
  for stored_sid in list(delegation_requests.keys()):
678
741
  if (
@@ -685,11 +748,8 @@ class EventHandlers:
685
748
  )
686
749
  ):
687
750
  if DEBUG:
688
- print(
689
- f" - Fuzzy match found: {stored_sid[:16]}...",
690
- file=sys.stderr,
691
- )
692
- request_info = delegation_requests.get(stored_sid)
751
+ _log(f" - ✅ Fuzzy match found: {stored_sid[:16]}...")
752
+ request_info = delegation_requests.get(stored_sid) # nosec B113
693
753
  # Update the key to use the current session_id for consistency
694
754
  if request_info:
695
755
  delegation_requests[session_id] = request_info
@@ -757,9 +817,8 @@ class EventHandlers:
757
817
  )
758
818
 
759
819
  if file_path and DEBUG:
760
- print(
761
- f"✅ Tracked {agent_type} agent response on SubagentStop: {file_path.name}",
762
- file=sys.stderr,
820
+ _log(
821
+ f"✅ Tracked {agent_type} agent response on SubagentStop: {file_path.name}"
763
822
  )
764
823
 
765
824
  # Clean up the request data
@@ -770,16 +829,13 @@ class EventHandlers:
770
829
  del delegation_requests[session_id]
771
830
 
772
831
  elif DEBUG:
773
- print(
774
- f"No request data for SubagentStop session {session_id[:8]}..., agent: {agent_type}",
775
- file=sys.stderr,
832
+ _log(
833
+ f"No request data for SubagentStop session {session_id[:8]}..., agent: {agent_type}"
776
834
  )
777
835
 
778
836
  except Exception as e:
779
837
  if DEBUG:
780
- print(
781
- f"❌ Failed to track response on SubagentStop: {e}", file=sys.stderr
782
- )
838
+ _log(f"❌ Failed to track response on SubagentStop: {e}")
783
839
 
784
840
  def handle_assistant_response(self, event):
785
841
  """Handle assistant response events for comprehensive response tracking.
@@ -789,6 +845,7 @@ class EventHandlers:
789
845
  - Captures response content and metadata for analysis
790
846
  - Enables tracking of conversation flow and response patterns
791
847
  - Essential for comprehensive monitoring of Claude interactions
848
+ - Scans for delegation anti-patterns and creates autotodos
792
849
  """
793
850
  # Track the response for logging
794
851
  try:
@@ -796,10 +853,17 @@ class EventHandlers:
796
853
  if rtm and hasattr(rtm, "track_assistant_response"):
797
854
  pending_prompts = getattr(self.hook_handler, "pending_prompts", {})
798
855
  rtm.track_assistant_response(event, pending_prompts)
799
- except Exception:
856
+ except Exception: # nosec B110
800
857
  # Response tracking is optional
801
858
  pass
802
859
 
860
+ # Scan response for delegation anti-patterns and create autotodos
861
+ try:
862
+ self._scan_for_delegation_patterns(event)
863
+ except Exception as e: # nosec B110
864
+ if DEBUG:
865
+ _log(f"Delegation scanning error: {e}")
866
+
803
867
  # Get working directory and git branch
804
868
  working_dir = event.get("cwd", "")
805
869
  git_branch = self._get_git_branch(working_dir) if working_dir else "Unknown"
@@ -847,11 +911,25 @@ class EventHandlers:
847
911
 
848
912
  # Debug logging
849
913
  if DEBUG:
850
- print(
851
- f"Hook handler: Processing AssistantResponse - session: '{session_id}', response_length: {len(response_text)}",
852
- file=sys.stderr,
914
+ _log(
915
+ f"Hook handler: Processing AssistantResponse - session: '{session_id}', response_length: {len(response_text)}"
853
916
  )
854
917
 
918
+ # Record assistant response for auto-pause if active
919
+ auto_pause = getattr(self.hook_handler, "auto_pause_handler", None)
920
+ if auto_pause and auto_pause.is_pause_active():
921
+ try:
922
+ # Summarize response to first 200 chars
923
+ summary = (
924
+ response_text[:200] + "..."
925
+ if len(response_text) > 200
926
+ else response_text
927
+ )
928
+ auto_pause.on_assistant_response(summary)
929
+ except Exception as e:
930
+ if DEBUG:
931
+ _log(f"Auto-pause response recording error: {e}")
932
+
855
933
  # Emit normalized event
856
934
  self.hook_handler._emit_socketio_event(
857
935
  "", "assistant_response", assistant_response_data
@@ -864,6 +942,7 @@ class EventHandlers:
864
942
  - Provides visibility into new conversation sessions
865
943
  - Enables tracking of session lifecycle and duration
866
944
  - Useful for monitoring concurrent sessions and resource usage
945
+ - Auto-inject pending autotodos if enabled in config
867
946
  """
868
947
  session_id = event.get("session_id", "")
869
948
  working_dir = event.get("cwd", "")
@@ -877,12 +956,151 @@ class EventHandlers:
877
956
  "hook_event_name": "SessionStart",
878
957
  }
879
958
 
959
+ # Auto-inject pending autotodos if enabled
960
+ try:
961
+ from pathlib import Path
962
+
963
+ from claude_mpm.cli.commands.autotodos import get_pending_todos
964
+ from claude_mpm.core.config import Config
965
+
966
+ config = Config()
967
+ auto_inject_enabled = config.get("autotodos.auto_inject_on_startup", True)
968
+ max_todos = config.get("autotodos.max_todos_per_session", 10)
969
+
970
+ if auto_inject_enabled:
971
+ # Pass working directory from event to avoid Path.cwd() issues
972
+ working_dir_param = None
973
+ if working_dir:
974
+ working_dir_param = Path(working_dir)
975
+
976
+ pending_todos = get_pending_todos(
977
+ max_todos=max_todos, working_dir=working_dir_param
978
+ )
979
+ if pending_todos:
980
+ session_start_data["pending_autotodos"] = pending_todos
981
+ session_start_data["autotodos_count"] = len(pending_todos)
982
+ _log(f" - Auto-injected {len(pending_todos)} pending autotodos")
983
+ except Exception as e: # nosec B110
984
+ # Auto-injection is optional - continue if it fails
985
+ _log(f" - Failed to auto-inject autotodos: {e}")
986
+
987
+ # Debug logging
988
+ _log(f"Hook handler: Processing SessionStart - session: '{session_id}'")
989
+
990
+ # Emit normalized event
991
+ self.hook_handler._emit_socketio_event("", "session_start", session_start_data)
992
+
993
+ def handle_subagent_start_fast(self, event):
994
+ """Handle SubagentStart events with proper agent type extraction.
995
+
996
+ WHY separate from SessionStart:
997
+ - SubagentStart contains agent-specific information
998
+ - Frontend needs agent_type to create distinct agent nodes
999
+ - Multiple engineers should show as separate nodes in hierarchy
1000
+ - Research agents must appear in the agent hierarchy
1001
+
1002
+ Unlike SessionStart, SubagentStart events contain agent-specific
1003
+ information that must be preserved and emitted to the dashboard.
1004
+ """
1005
+ session_id = event.get("session_id", "")
1006
+
1007
+ # Extract agent type from event - Claude provides this in SubagentStart
1008
+ # Try multiple possible field names for compatibility
1009
+ agent_type = event.get("agent_type") or event.get("subagent_type") or "unknown"
1010
+
1011
+ # Generate unique agent ID combining type and session
1012
+ agent_id = event.get("agent_id", f"{agent_type}_{session_id[:8]}")
1013
+
1014
+ # Get working directory and git branch
1015
+ working_dir = event.get("cwd", "")
1016
+ git_branch = self._get_git_branch(working_dir) if working_dir else "Unknown"
1017
+
1018
+ # Build subagent start data with all required fields
1019
+ subagent_start_data = {
1020
+ "session_id": session_id,
1021
+ "agent_type": agent_type,
1022
+ "agent_id": agent_id,
1023
+ "timestamp": datetime.now(timezone.utc).isoformat(),
1024
+ "hook_event_name": "SubagentStart", # Preserve correct hook name
1025
+ "working_directory": working_dir,
1026
+ "git_branch": git_branch,
1027
+ }
1028
+
880
1029
  # Debug logging
881
1030
  if DEBUG:
882
- print(
883
- f"Hook handler: Processing SessionStart - session: '{session_id}'",
884
- file=sys.stderr,
1031
+ _log(
1032
+ f"Hook handler: SubagentStart - agent_type='{agent_type}', agent_id='{agent_id}', session_id='{session_id[:16]}...'"
885
1033
  )
886
1034
 
887
- # Emit normalized event
888
- self.hook_handler._emit_socketio_event("", "session_start", session_start_data)
1035
+ # Emit to /hook namespace as subagent_start (NOT session_start!)
1036
+ self.hook_handler._emit_socketio_event(
1037
+ "", "subagent_start", subagent_start_data
1038
+ )
1039
+
1040
+ def _scan_for_delegation_patterns(self, event):
1041
+ """Scan assistant response for delegation anti-patterns.
1042
+
1043
+ WHY this is needed:
1044
+ - Detect when PM asks user to do something manually instead of delegating
1045
+ - Flag PM behavior violations for immediate correction
1046
+ - Enforce delegation principle in PM workflow
1047
+ - Help PM recognize delegation opportunities
1048
+
1049
+ This method scans the assistant's response text for patterns like:
1050
+ - "Make sure .env.local is in your .gitignore"
1051
+ - "You'll need to run npm install"
1052
+ - "Please run the tests manually"
1053
+
1054
+ When patterns are detected, PM violations are logged as errors/warnings
1055
+ that should be corrected immediately, NOT as todos to delegate.
1056
+
1057
+ DESIGN DECISION: pm.violation vs autotodo.delegation
1058
+ - Delegation patterns = PM doing something WRONG → pm.violation (error)
1059
+ - Script failures = Something BROKEN → autotodo.error (todo)
1060
+ """
1061
+ # Only scan if delegation detector is available
1062
+ try:
1063
+ from claude_mpm.services.delegation_detector import get_delegation_detector
1064
+ from claude_mpm.services.event_log import get_event_log
1065
+ except ImportError:
1066
+ if DEBUG:
1067
+ _log("Delegation detector or event log not available")
1068
+ return
1069
+
1070
+ response_text = event.get("response", "")
1071
+ if not response_text:
1072
+ return
1073
+
1074
+ # Get the delegation detector
1075
+ detector = get_delegation_detector()
1076
+
1077
+ # Detect delegation patterns
1078
+ detections = detector.detect_user_delegation(response_text)
1079
+
1080
+ if not detections:
1081
+ return # No patterns detected
1082
+
1083
+ # Get event log for violation recording
1084
+ event_log = get_event_log()
1085
+
1086
+ # Create PM violation events (NOT autotodos)
1087
+ for detection in detections:
1088
+ # Create event log entry as pm.violation
1089
+ event_log.append_event(
1090
+ event_type="pm.violation",
1091
+ payload={
1092
+ "violation_type": "delegation_anti_pattern",
1093
+ "pattern_type": detection["pattern_type"],
1094
+ "original_text": detection["original_text"],
1095
+ "suggested_action": detection["suggested_todo"],
1096
+ "action": detection["action"],
1097
+ "session_id": event.get("session_id", ""),
1098
+ "timestamp": datetime.now(timezone.utc).isoformat(),
1099
+ "severity": "warning", # Not critical, but should be fixed
1100
+ "message": f"PM asked user to do something manually: {detection['original_text'][:80]}...",
1101
+ },
1102
+ status="pending",
1103
+ )
1104
+
1105
+ if DEBUG:
1106
+ _log(f"⚠️ PM violation detected: {detection['original_text'][:60]}...")