claude-mpm 5.4.22__py3-none-any.whl → 5.6.34__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (487) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_AGENT.md +164 -0
  3. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  4. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
  5. claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
  6. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
  7. claude_mpm/agents/MEMORY.md +1 -1
  8. claude_mpm/agents/PM_INSTRUCTIONS.md +374 -1257
  9. claude_mpm/agents/WORKFLOW.md +6 -253
  10. claude_mpm/agents/agent_loader.py +1 -1
  11. claude_mpm/agents/base_agent.json +31 -0
  12. claude_mpm/agents/frontmatter_validator.py +2 -2
  13. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  14. claude_mpm/cli/__init__.py +5 -1
  15. claude_mpm/cli/commands/agent_state_manager.py +10 -10
  16. claude_mpm/cli/commands/agents.py +11 -13
  17. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  18. claude_mpm/cli/commands/auto_configure.py +4 -4
  19. claude_mpm/cli/commands/autotodos.py +566 -0
  20. claude_mpm/cli/commands/commander.py +216 -0
  21. claude_mpm/cli/commands/configure.py +621 -22
  22. claude_mpm/cli/commands/configure_agent_display.py +12 -0
  23. claude_mpm/cli/commands/hook_errors.py +60 -60
  24. claude_mpm/cli/commands/monitor.py +2 -2
  25. claude_mpm/cli/commands/mpm_init/core.py +72 -0
  26. claude_mpm/cli/commands/postmortem.py +1 -1
  27. claude_mpm/cli/commands/profile.py +276 -0
  28. claude_mpm/cli/commands/run.py +35 -3
  29. claude_mpm/cli/commands/skill_source.py +51 -2
  30. claude_mpm/cli/commands/skills.py +182 -32
  31. claude_mpm/cli/executor.py +130 -16
  32. claude_mpm/cli/interactive/__init__.py +10 -0
  33. claude_mpm/cli/interactive/agent_wizard.py +32 -52
  34. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  35. claude_mpm/cli/interactive/skill_selector.py +481 -0
  36. claude_mpm/cli/parsers/base_parser.py +83 -1
  37. claude_mpm/cli/parsers/commander_parser.py +116 -0
  38. claude_mpm/cli/parsers/profile_parser.py +147 -0
  39. claude_mpm/cli/parsers/run_parser.py +10 -0
  40. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  41. claude_mpm/cli/parsers/skills_parser.py +2 -3
  42. claude_mpm/cli/startup.py +690 -386
  43. claude_mpm/cli/startup_display.py +74 -6
  44. claude_mpm/cli/startup_logging.py +2 -2
  45. claude_mpm/cli/utils.py +7 -3
  46. claude_mpm/commander/__init__.py +78 -0
  47. claude_mpm/commander/adapters/__init__.py +60 -0
  48. claude_mpm/commander/adapters/auggie.py +260 -0
  49. claude_mpm/commander/adapters/base.py +288 -0
  50. claude_mpm/commander/adapters/claude_code.py +392 -0
  51. claude_mpm/commander/adapters/codex.py +237 -0
  52. claude_mpm/commander/adapters/communication.py +366 -0
  53. claude_mpm/commander/adapters/example_usage.py +310 -0
  54. claude_mpm/commander/adapters/mpm.py +389 -0
  55. claude_mpm/commander/adapters/registry.py +204 -0
  56. claude_mpm/commander/api/__init__.py +16 -0
  57. claude_mpm/commander/api/app.py +121 -0
  58. claude_mpm/commander/api/errors.py +133 -0
  59. claude_mpm/commander/api/routes/__init__.py +8 -0
  60. claude_mpm/commander/api/routes/events.py +184 -0
  61. claude_mpm/commander/api/routes/inbox.py +171 -0
  62. claude_mpm/commander/api/routes/messages.py +148 -0
  63. claude_mpm/commander/api/routes/projects.py +271 -0
  64. claude_mpm/commander/api/routes/sessions.py +226 -0
  65. claude_mpm/commander/api/routes/work.py +296 -0
  66. claude_mpm/commander/api/schemas.py +186 -0
  67. claude_mpm/commander/chat/__init__.py +7 -0
  68. claude_mpm/commander/chat/cli.py +146 -0
  69. claude_mpm/commander/chat/commands.py +96 -0
  70. claude_mpm/commander/chat/repl.py +310 -0
  71. claude_mpm/commander/config.py +51 -0
  72. claude_mpm/commander/config_loader.py +115 -0
  73. claude_mpm/commander/core/__init__.py +10 -0
  74. claude_mpm/commander/core/block_manager.py +325 -0
  75. claude_mpm/commander/core/response_manager.py +323 -0
  76. claude_mpm/commander/daemon.py +603 -0
  77. claude_mpm/commander/env_loader.py +59 -0
  78. claude_mpm/commander/events/__init__.py +26 -0
  79. claude_mpm/commander/events/manager.py +332 -0
  80. claude_mpm/commander/frameworks/__init__.py +12 -0
  81. claude_mpm/commander/frameworks/base.py +146 -0
  82. claude_mpm/commander/frameworks/claude_code.py +58 -0
  83. claude_mpm/commander/frameworks/mpm.py +62 -0
  84. claude_mpm/commander/inbox/__init__.py +16 -0
  85. claude_mpm/commander/inbox/dedup.py +128 -0
  86. claude_mpm/commander/inbox/inbox.py +224 -0
  87. claude_mpm/commander/inbox/models.py +70 -0
  88. claude_mpm/commander/instance_manager.py +450 -0
  89. claude_mpm/commander/llm/__init__.py +6 -0
  90. claude_mpm/commander/llm/openrouter_client.py +167 -0
  91. claude_mpm/commander/llm/summarizer.py +70 -0
  92. claude_mpm/commander/memory/__init__.py +45 -0
  93. claude_mpm/commander/memory/compression.py +347 -0
  94. claude_mpm/commander/memory/embeddings.py +230 -0
  95. claude_mpm/commander/memory/entities.py +310 -0
  96. claude_mpm/commander/memory/example_usage.py +290 -0
  97. claude_mpm/commander/memory/integration.py +325 -0
  98. claude_mpm/commander/memory/search.py +381 -0
  99. claude_mpm/commander/memory/store.py +657 -0
  100. claude_mpm/commander/models/__init__.py +18 -0
  101. claude_mpm/commander/models/events.py +121 -0
  102. claude_mpm/commander/models/project.py +162 -0
  103. claude_mpm/commander/models/work.py +214 -0
  104. claude_mpm/commander/parsing/__init__.py +20 -0
  105. claude_mpm/commander/parsing/extractor.py +132 -0
  106. claude_mpm/commander/parsing/output_parser.py +270 -0
  107. claude_mpm/commander/parsing/patterns.py +100 -0
  108. claude_mpm/commander/persistence/__init__.py +11 -0
  109. claude_mpm/commander/persistence/event_store.py +274 -0
  110. claude_mpm/commander/persistence/state_store.py +309 -0
  111. claude_mpm/commander/persistence/work_store.py +164 -0
  112. claude_mpm/commander/polling/__init__.py +13 -0
  113. claude_mpm/commander/polling/event_detector.py +104 -0
  114. claude_mpm/commander/polling/output_buffer.py +49 -0
  115. claude_mpm/commander/polling/output_poller.py +153 -0
  116. claude_mpm/commander/project_session.py +268 -0
  117. claude_mpm/commander/proxy/__init__.py +12 -0
  118. claude_mpm/commander/proxy/formatter.py +89 -0
  119. claude_mpm/commander/proxy/output_handler.py +191 -0
  120. claude_mpm/commander/proxy/relay.py +155 -0
  121. claude_mpm/commander/registry.py +410 -0
  122. claude_mpm/commander/runtime/__init__.py +10 -0
  123. claude_mpm/commander/runtime/executor.py +191 -0
  124. claude_mpm/commander/runtime/monitor.py +346 -0
  125. claude_mpm/commander/session/__init__.py +6 -0
  126. claude_mpm/commander/session/context.py +81 -0
  127. claude_mpm/commander/session/manager.py +59 -0
  128. claude_mpm/commander/tmux_orchestrator.py +361 -0
  129. claude_mpm/commander/web/__init__.py +1 -0
  130. claude_mpm/commander/work/__init__.py +30 -0
  131. claude_mpm/commander/work/executor.py +207 -0
  132. claude_mpm/commander/work/queue.py +405 -0
  133. claude_mpm/commander/workflow/__init__.py +27 -0
  134. claude_mpm/commander/workflow/event_handler.py +241 -0
  135. claude_mpm/commander/workflow/notifier.py +146 -0
  136. claude_mpm/commands/mpm-config.md +20 -249
  137. claude_mpm/commands/mpm-doctor.md +16 -21
  138. claude_mpm/commands/mpm-help.md +12 -205
  139. claude_mpm/commands/mpm-init.md +88 -506
  140. claude_mpm/commands/mpm-monitor.md +22 -401
  141. claude_mpm/commands/mpm-organize.md +70 -442
  142. claude_mpm/commands/mpm-postmortem.md +13 -107
  143. claude_mpm/commands/mpm-session-resume.md +20 -363
  144. claude_mpm/commands/mpm-status.md +13 -69
  145. claude_mpm/commands/mpm-ticket-view.md +60 -495
  146. claude_mpm/commands/mpm-version.md +13 -107
  147. claude_mpm/commands/mpm.md +8 -0
  148. claude_mpm/config/agent_presets.py +8 -7
  149. claude_mpm/config/skill_sources.py +16 -0
  150. claude_mpm/constants.py +1 -0
  151. claude_mpm/core/claude_runner.py +154 -2
  152. claude_mpm/core/config.py +37 -26
  153. claude_mpm/core/config_constants.py +74 -9
  154. claude_mpm/core/constants.py +56 -12
  155. claude_mpm/core/framework/loaders/agent_loader.py +1 -1
  156. claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
  157. claude_mpm/core/hook_manager.py +51 -3
  158. claude_mpm/core/interactive_session.py +12 -11
  159. claude_mpm/core/logger.py +26 -9
  160. claude_mpm/core/logging_utils.py +39 -13
  161. claude_mpm/core/network_config.py +148 -0
  162. claude_mpm/core/oneshot_session.py +7 -6
  163. claude_mpm/core/optimized_startup.py +61 -0
  164. claude_mpm/core/output_style_manager.py +66 -18
  165. claude_mpm/core/shared/config_loader.py +3 -1
  166. claude_mpm/core/socketio_pool.py +47 -15
  167. claude_mpm/core/unified_agent_registry.py +1 -1
  168. claude_mpm/core/unified_config.py +54 -8
  169. claude_mpm/core/unified_paths.py +95 -90
  170. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  171. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
  172. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
  173. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
  174. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
  175. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
  176. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
  177. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
  178. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
  179. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
  180. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
  181. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  182. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
  183. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
  184. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
  185. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
  186. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
  187. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
  188. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
  189. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
  190. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
  191. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
  192. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
  193. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
  194. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
  195. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
  196. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
  197. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
  198. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
  199. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
  200. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
  201. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
  202. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  203. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
  204. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  205. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
  206. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
  207. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
  208. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
  209. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
  210. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DR8nis88.js +2 -0
  211. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
  212. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  213. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
  214. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
  215. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
  216. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
  217. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
  218. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
  219. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  220. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
  221. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
  222. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
  223. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
  224. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
  225. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
  226. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
  227. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
  228. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
  229. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
  230. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
  231. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
  232. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.RgBboRvH.js +1 -0
  233. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
  234. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
  235. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  236. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  237. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  238. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  239. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  240. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  241. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  242. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  243. claude_mpm/experimental/cli_enhancements.py +2 -1
  244. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  245. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  246. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  247. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  248. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  249. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  250. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  251. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  252. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  253. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  254. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
  255. claude_mpm/hooks/claude_hooks/event_handlers.py +527 -136
  256. claude_mpm/hooks/claude_hooks/hook_handler.py +313 -99
  257. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  258. claude_mpm/hooks/claude_hooks/installer.py +206 -36
  259. claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
  260. claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
  261. claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
  262. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  263. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  264. claude_mpm/hooks/claude_hooks/services/__pycache__/container.cpython-311.pyc +0 -0
  265. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  266. claude_mpm/hooks/claude_hooks/services/__pycache__/protocols.cpython-311.pyc +0 -0
  267. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  268. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  269. claude_mpm/hooks/claude_hooks/services/connection_manager.py +67 -32
  270. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
  271. claude_mpm/hooks/claude_hooks/services/container.py +310 -0
  272. claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
  273. claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
  274. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
  275. claude_mpm/hooks/kuzu_memory_hook.py +5 -5
  276. claude_mpm/hooks/session_resume_hook.py +89 -1
  277. claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
  278. claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
  279. claude_mpm/init.py +276 -0
  280. claude_mpm/models/git_repository.py +3 -3
  281. claude_mpm/scripts/claude-hook-handler.sh +46 -19
  282. claude_mpm/services/agents/agent_builder.py +3 -3
  283. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  284. claude_mpm/services/agents/agent_selection_service.py +2 -2
  285. claude_mpm/services/agents/cache_git_manager.py +7 -7
  286. claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
  287. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -2
  288. claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
  289. claude_mpm/services/agents/deployment/agent_template_builder.py +39 -19
  290. claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
  291. claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
  292. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  293. claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
  294. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +169 -26
  295. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +101 -75
  296. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  297. claude_mpm/services/agents/git_source_manager.py +23 -4
  298. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  299. claude_mpm/services/agents/recommender.py +5 -3
  300. claude_mpm/services/agents/single_tier_deployment_service.py +6 -6
  301. claude_mpm/services/agents/sources/git_source_sync_service.py +121 -10
  302. claude_mpm/services/agents/startup_sync.py +27 -4
  303. claude_mpm/services/cli/__init__.py +3 -0
  304. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  305. claude_mpm/services/cli/session_resume_helper.py +10 -2
  306. claude_mpm/services/command_deployment_service.py +44 -26
  307. claude_mpm/services/delegation_detector.py +175 -0
  308. claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
  309. claude_mpm/services/diagnostics/checks/agent_sources_check.py +31 -1
  310. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  311. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  312. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  313. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  314. claude_mpm/services/diagnostics/models.py +14 -1
  315. claude_mpm/services/event_log.py +325 -0
  316. claude_mpm/services/git/git_operations_service.py +8 -8
  317. claude_mpm/services/hook_installer_service.py +77 -8
  318. claude_mpm/services/infrastructure/__init__.py +4 -0
  319. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  320. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  321. claude_mpm/services/monitor/daemon_manager.py +15 -4
  322. claude_mpm/services/monitor/management/lifecycle.py +15 -3
  323. claude_mpm/services/monitor/server.py +571 -11
  324. claude_mpm/services/pm_skills_deployer.py +884 -0
  325. claude_mpm/services/profile_manager.py +337 -0
  326. claude_mpm/services/skills/git_skill_source_manager.py +281 -20
  327. claude_mpm/services/skills/selective_skill_deployer.py +211 -46
  328. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  329. claude_mpm/services/skills_deployer.py +192 -70
  330. claude_mpm/services/socketio/dashboard_server.py +1 -0
  331. claude_mpm/services/socketio/event_normalizer.py +37 -6
  332. claude_mpm/services/socketio/handlers/hook.py +14 -7
  333. claude_mpm/services/socketio/server/core.py +262 -123
  334. claude_mpm/services/socketio/server/main.py +12 -4
  335. claude_mpm/skills/__init__.py +2 -1
  336. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  337. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  338. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  339. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  340. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  341. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  342. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  343. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  344. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  345. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  346. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  347. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  348. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  349. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  350. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  351. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  352. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  353. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  354. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  355. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  356. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  357. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  358. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  359. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  360. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  361. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  362. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  363. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  364. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  365. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  366. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  367. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  368. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  369. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  370. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  371. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  372. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  373. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  374. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  375. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  376. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  377. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  378. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  379. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  380. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  381. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  382. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  383. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  384. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  385. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  386. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  387. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  388. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  389. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  390. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  391. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  392. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  393. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  394. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  395. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  396. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  397. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  398. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  399. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  400. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  401. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  402. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  403. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  404. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  405. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  406. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  407. claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
  408. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  409. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  410. claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
  411. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  412. claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
  413. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  414. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  415. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  416. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  417. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  418. claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
  419. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  420. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  421. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  422. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  423. claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
  424. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  425. claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
  426. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  427. claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
  428. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  429. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  430. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  431. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  432. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  433. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  434. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  435. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  436. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  437. claude_mpm/skills/bundled/security-scanning.md +112 -0
  438. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  439. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  440. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  441. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  442. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  443. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  444. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  445. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  446. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  447. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  448. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  449. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  450. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  451. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  452. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  453. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  454. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  455. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  456. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  457. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  458. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  459. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  460. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  461. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  462. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  463. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  464. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  465. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  466. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  467. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  468. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  469. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  470. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  471. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  472. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  473. claude_mpm/skills/registry.py +295 -90
  474. claude_mpm/skills/skill_manager.py +98 -3
  475. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  476. claude_mpm/utils/agent_dependency_loader.py +115 -4
  477. claude_mpm/utils/agent_filters.py +1 -1
  478. claude_mpm/utils/migration.py +4 -4
  479. claude_mpm/utils/robust_installer.py +86 -21
  480. claude_mpm-5.6.34.dist-info/METADATA +393 -0
  481. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/RECORD +486 -145
  482. claude_mpm-5.4.22.dist-info/METADATA +0 -996
  483. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/WHEEL +0 -0
  484. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/entry_points.txt +0 -0
  485. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE +0 -0
  486. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  487. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/top_level.txt +0 -0
@@ -22,7 +22,7 @@ import os
22
22
  import re
23
23
  import select
24
24
  import signal
25
- import subprocess
25
+ import subprocess # nosec B404
26
26
  import sys
27
27
  import threading
28
28
  from datetime import datetime, timezone
@@ -31,12 +31,14 @@ from typing import Optional, Tuple
31
31
  # Import extracted modules with fallback for direct execution
32
32
  try:
33
33
  # Try relative imports first (when imported as module)
34
+ from .auto_pause_handler import AutoPauseHandler
34
35
  from .event_handlers import EventHandlers
35
36
  from .memory_integration import MemoryHookManager
36
37
  from .response_tracking import ResponseTrackingManager
37
38
  from .services import (
38
39
  ConnectionManagerService,
39
40
  DuplicateEventDetector,
41
+ HookServiceContainer,
40
42
  StateManagerService,
41
43
  SubagentResponseProcessor,
42
44
  )
@@ -47,27 +49,61 @@ except ImportError:
47
49
  # Add parent directory to path
48
50
  sys.path.insert(0, str(Path(__file__).parent))
49
51
 
52
+ from auto_pause_handler import AutoPauseHandler
50
53
  from event_handlers import EventHandlers
51
54
  from memory_integration import MemoryHookManager
52
55
  from response_tracking import ResponseTrackingManager
53
56
  from services import (
54
57
  ConnectionManagerService,
55
58
  DuplicateEventDetector,
59
+ HookServiceContainer,
56
60
  StateManagerService,
57
61
  SubagentResponseProcessor,
58
62
  )
59
63
 
64
+ # Import CorrelationManager with fallback (used in _route_event cleanup)
65
+ # WHY at top level: Runtime relative imports fail with "no known parent package" error
66
+ try:
67
+ from .correlation_manager import CorrelationManager
68
+ except ImportError:
69
+ try:
70
+ from correlation_manager import CorrelationManager
71
+ except ImportError:
72
+ # Fallback: create a no-op class if module unavailable
73
+ class CorrelationManager:
74
+ @staticmethod
75
+ def cleanup_old():
76
+ pass
77
+
78
+
60
79
  """
61
80
  Debug mode configuration for hook processing.
62
81
 
63
- WHY enabled by default: Hook processing can be complex and hard to debug.
64
- Having debug output available by default helps diagnose issues during development.
65
- Production deployments can disable via environment variable.
82
+ WHY disabled by default: Production users should see clean output without debug noise.
83
+ Hook errors appear less confusing when debug output is minimal.
84
+ Development and debugging can enable via CLAUDE_MPM_HOOK_DEBUG=true.
66
85
 
67
86
  Performance Impact: Debug logging adds ~5-10% overhead but provides crucial
68
- visibility into event flow, timing, and error conditions.
87
+ visibility into event flow, timing, and error conditions when enabled.
69
88
  """
70
- DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "true").lower() != "false"
89
+ DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "false").lower() == "true"
90
+
91
+
92
+ def _log(message: str) -> None:
93
+ """Log message to file if DEBUG enabled. Never write to stderr.
94
+
95
+ WHY: Claude Code interprets ANY stderr output as a hook error.
96
+ Writing to stderr causes confusing "hook error" messages even for debug logs.
97
+
98
+ This helper ensures all debug output goes to a log file instead.
99
+ """
100
+ if DEBUG:
101
+ try:
102
+ with open("/tmp/claude-mpm-hook.log", "a") as f: # nosec B108
103
+ f.write(f"[{datetime.now(timezone.utc).isoformat()}] {message}\n")
104
+ except Exception: # nosec B110 - intentional silent failure
105
+ pass # Never disrupt hook execution
106
+
71
107
 
72
108
  """
73
109
  Conditional imports with graceful fallbacks for testing and modularity.
@@ -109,6 +145,8 @@ WHY version checking:
109
145
  Security: Version checking prevents execution on incompatible environments.
110
146
  """
111
147
  MIN_CLAUDE_VERSION = "1.0.92"
148
+ # Minimum version for user-invocable skills support
149
+ MIN_SKILLS_VERSION = "2.1.3"
112
150
 
113
151
 
114
152
  def check_claude_version() -> Tuple[bool, Optional[str]]:
@@ -153,7 +191,7 @@ def check_claude_version() -> Tuple[bool, Optional[str]]:
153
191
  """
154
192
  try:
155
193
  # Try to detect Claude Code version
156
- result = subprocess.run(
194
+ result = subprocess.run( # nosec B603 B607 - Safe: hardcoded claude CLI with --version flag, no user input
157
195
  ["claude", "--version"],
158
196
  capture_output=True,
159
197
  text=True,
@@ -184,22 +222,17 @@ def check_claude_version() -> Tuple[bool, Optional[str]]:
184
222
  req_part = required[i] if i < len(required) else 0
185
223
 
186
224
  if curr_part < req_part:
187
- if DEBUG:
188
- print(
189
- f"⚠️ Claude Code {version} does not support matcher-based hooks "
190
- f"(requires {MIN_CLAUDE_VERSION}+). Hook monitoring disabled.",
191
- file=sys.stderr,
192
- )
225
+ _log(
226
+ f"⚠️ Claude Code {version} does not support matcher-based hooks "
227
+ f"(requires {MIN_CLAUDE_VERSION}+). Hook monitoring disabled."
228
+ )
193
229
  return False, version
194
230
  if curr_part > req_part:
195
231
  return True, version
196
232
 
197
233
  return True, version
198
234
  except Exception as e:
199
- if DEBUG:
200
- print(
201
- f"Warning: Could not detect Claude Code version: {e}", file=sys.stderr
202
- )
235
+ _log(f"Warning: Could not detect Claude Code version: {e}")
203
236
 
204
237
  return False, None
205
238
 
@@ -212,26 +245,73 @@ class ClaudeHookHandler:
212
245
  - Each service handles a specific responsibility
213
246
  - Easier to test, maintain, and extend
214
247
  - Reduced complexity in main handler class
248
+
249
+ Supports Dependency Injection:
250
+ - Pass a HookServiceContainer to override default services
251
+ - Useful for testing with mock services
252
+ - Maintains backward compatibility when no container is provided
215
253
  """
216
254
 
217
- def __init__(self):
218
- # Initialize services
219
- self.state_manager = StateManagerService()
220
- self.connection_manager = ConnectionManagerService()
221
- self.duplicate_detector = DuplicateEventDetector()
255
+ def __init__(self, container: Optional[HookServiceContainer] = None):
256
+ """Initialize hook handler with optional DI container.
257
+
258
+ Args:
259
+ container: Optional HookServiceContainer for dependency injection.
260
+ If None, services are created directly (backward compatible).
261
+ """
262
+ # Use container if provided, otherwise create services directly
263
+ if container is not None:
264
+ # DI mode: get services from container
265
+ self._container = container
266
+ self.state_manager = container.get_state_manager()
267
+ self.connection_manager = container.get_connection_manager()
268
+ self.duplicate_detector = container.get_duplicate_detector()
269
+ self.memory_hook_manager = container.get_memory_hook_manager()
270
+ self.response_tracking_manager = container.get_response_tracking_manager()
271
+ self.auto_pause_handler = container.get_auto_pause_handler()
272
+
273
+ # Event handlers need reference to this handler (circular, but contained)
274
+ self.event_handlers = EventHandlers(self)
275
+
276
+ # Subagent processor with injected dependencies
277
+ self.subagent_processor = container.get_subagent_processor(
278
+ self.state_manager,
279
+ self.response_tracking_manager,
280
+ self.connection_manager,
281
+ )
282
+ else:
283
+ # Backward compatible mode: create services directly
284
+ self._container = None
285
+ self.state_manager = StateManagerService()
286
+ self.connection_manager = ConnectionManagerService()
287
+ self.duplicate_detector = DuplicateEventDetector()
288
+
289
+ # Initialize extracted managers
290
+ self.memory_hook_manager = MemoryHookManager()
291
+ self.response_tracking_manager = ResponseTrackingManager()
292
+ self.event_handlers = EventHandlers(self)
293
+
294
+ # Initialize subagent processor with dependencies
295
+ self.subagent_processor = SubagentResponseProcessor(
296
+ self.state_manager,
297
+ self.response_tracking_manager,
298
+ self.connection_manager,
299
+ )
222
300
 
223
- # Initialize extracted managers
224
- self.memory_hook_manager = MemoryHookManager()
225
- self.response_tracking_manager = ResponseTrackingManager()
226
- self.event_handlers = EventHandlers(self)
301
+ # Initialize auto-pause handler
302
+ try:
303
+ self.auto_pause_handler = AutoPauseHandler()
304
+ except Exception as e:
305
+ self.auto_pause_handler = None
306
+ _log(f"Auto-pause initialization failed: {e}")
227
307
 
228
- # Initialize subagent processor with dependencies
229
- self.subagent_processor = SubagentResponseProcessor(
230
- self.state_manager, self.response_tracking_manager, self.connection_manager
231
- )
308
+ # Link auto-pause handler to response tracking manager
309
+ if self.auto_pause_handler and hasattr(self, "response_tracking_manager"):
310
+ self.response_tracking_manager.auto_pause_handler = self.auto_pause_handler
232
311
 
233
312
  # Backward compatibility properties for tests
234
- self.connection_pool = self.connection_manager.connection_pool
313
+ # Note: HTTP-based connection manager doesn't use connection_pool
314
+ self.connection_pool = None # Deprecated: No longer needed with HTTP emission
235
315
 
236
316
  # Expose state manager properties for backward compatibility
237
317
  self.active_delegations = self.state_manager.active_delegations
@@ -260,8 +340,7 @@ class ClaudeHookHandler:
260
340
  def timeout_handler(signum, frame):
261
341
  """Handle timeout by forcing exit."""
262
342
  nonlocal _continue_sent
263
- if DEBUG:
264
- print(f"Hook handler timeout (pid: {os.getpid()})", file=sys.stderr)
343
+ _log(f"Hook handler timeout (pid: {os.getpid()})")
265
344
  if not _continue_sent:
266
345
  self._continue_execution()
267
346
  _continue_sent = True
@@ -282,11 +361,9 @@ class ClaudeHookHandler:
282
361
 
283
362
  # Check for duplicate events (same event within 100ms)
284
363
  if self.duplicate_detector.is_duplicate(event):
285
- if DEBUG:
286
- print(
287
- f"[{datetime.now(timezone.utc).isoformat()}] Skipping duplicate event: {event.get('hook_event_name', 'unknown')} (PID: {os.getpid()})",
288
- file=sys.stderr,
289
- )
364
+ _log(
365
+ f"[{datetime.now(timezone.utc).isoformat()}] Skipping duplicate event: {event.get('hook_event_name', 'unknown')} (PID: {os.getpid()})"
366
+ )
290
367
  # Still need to output continue for this invocation
291
368
  if not _continue_sent:
292
369
  self._continue_execution()
@@ -294,25 +371,19 @@ class ClaudeHookHandler:
294
371
  return
295
372
 
296
373
  # Debug: Log that we're processing an event
297
- if DEBUG:
298
- hook_type = event.get("hook_event_name", "unknown")
299
- print(
300
- f"\n[{datetime.now(timezone.utc).isoformat()}] Processing hook event: {hook_type} (PID: {os.getpid()})",
301
- file=sys.stderr,
302
- )
374
+ hook_type = event.get("hook_event_name", "unknown")
375
+ _log(
376
+ f"\n[{datetime.now(timezone.utc).isoformat()}] Processing hook event: {hook_type} (PID: {os.getpid()})"
377
+ )
303
378
 
304
379
  # Perform periodic cleanup if needed
305
380
  if self.state_manager.increment_events_processed():
306
381
  self.state_manager.cleanup_old_entries()
307
382
  # Also cleanup old correlation files
308
- from .correlation_manager import CorrelationManager
309
-
310
383
  CorrelationManager.cleanup_old()
311
- if DEBUG:
312
- print(
313
- f"🧹 Performed cleanup after {self.state_manager.events_processed} events",
314
- file=sys.stderr,
315
- )
384
+ _log(
385
+ f"🧹 Performed cleanup after {self.state_manager.events_processed} events"
386
+ )
316
387
 
317
388
  # Route event to appropriate handler
318
389
  # Handlers can optionally return modified input for PreToolUse events
@@ -352,8 +423,7 @@ class ClaudeHookHandler:
352
423
  ready, _, _ = select.select([sys.stdin], [], [], 1.0)
353
424
  if not ready:
354
425
  # No data available within timeout
355
- if DEBUG:
356
- print("No hook event data received within timeout", file=sys.stderr)
426
+ _log("No hook event data received within timeout")
357
427
  return None
358
428
 
359
429
  # Data is available, read it
@@ -364,21 +434,16 @@ class ClaudeHookHandler:
364
434
 
365
435
  parsed = json.loads(event_data)
366
436
  # Debug: Log the actual event format we receive
367
- if DEBUG:
368
- print(
369
- f"Received event with keys: {list(parsed.keys())}", file=sys.stderr
370
- )
371
- for key in ["hook_event_name", "event", "type", "event_type"]:
372
- if key in parsed:
373
- print(f" {key} = '{parsed[key]}'", file=sys.stderr)
437
+ _log(f"Received event with keys: {list(parsed.keys())}")
438
+ for key in ["hook_event_name", "event", "type", "event_type"]:
439
+ if key in parsed:
440
+ _log(f" {key} = '{parsed[key]}'")
374
441
  return parsed
375
442
  except (json.JSONDecodeError, ValueError) as e:
376
- if DEBUG:
377
- print(f"Failed to parse hook event: {e}", file=sys.stderr)
443
+ _log(f"Failed to parse hook event: {e}")
378
444
  return None
379
445
  except Exception as e:
380
- if DEBUG:
381
- print(f"Error reading hook event: {e}", file=sys.stderr)
446
+ _log(f"Error reading hook event: {e}")
382
447
  return None
383
448
 
384
449
  def _route_event(self, event: dict) -> Optional[dict]:
@@ -394,6 +459,8 @@ class ClaudeHookHandler:
394
459
  Returns:
395
460
  Modified input for PreToolUse events (v2.0.30+), None otherwise
396
461
  """
462
+ import time
463
+
397
464
  # Try multiple field names for compatibility
398
465
  hook_type = (
399
466
  event.get("hook_event_name")
@@ -405,9 +472,9 @@ class ClaudeHookHandler:
405
472
  )
406
473
 
407
474
  # Log the actual event structure for debugging
408
- if DEBUG and hook_type == "unknown":
409
- print(f"Unknown event format, keys: {list(event.keys())}", file=sys.stderr)
410
- print(f"Event sample: {str(event)[:200]}", file=sys.stderr)
475
+ if hook_type == "unknown":
476
+ _log(f"Unknown event format, keys: {list(event.keys())}")
477
+ _log(f"Event sample: {str(event)[:200]}")
411
478
 
412
479
  # Map event types to handlers
413
480
  event_handlers = {
@@ -417,7 +484,7 @@ class ClaudeHookHandler:
417
484
  "Notification": self.event_handlers.handle_notification_fast,
418
485
  "Stop": self.event_handlers.handle_stop_fast,
419
486
  "SubagentStop": self.event_handlers.handle_subagent_stop_fast,
420
- "SubagentStart": self.event_handlers.handle_session_start_fast,
487
+ "SubagentStart": self.event_handlers.handle_subagent_start_fast,
421
488
  "SessionStart": self.event_handlers.handle_session_start_fast,
422
489
  "AssistantResponse": self.event_handlers.handle_assistant_response,
423
490
  }
@@ -425,15 +492,39 @@ class ClaudeHookHandler:
425
492
  # Call appropriate handler if exists
426
493
  handler = event_handlers.get(hook_type)
427
494
  if handler:
495
+ # Track execution timing for hook emission
496
+ start_time = time.time()
497
+ success = False
498
+ error_message = None
499
+ result = None
500
+
428
501
  try:
429
502
  # Handlers can optionally return modified input
430
503
  result = handler(event)
504
+ success = True
431
505
  # Only PreToolUse handlers should return modified input
432
506
  if hook_type == "PreToolUse" and result is not None:
433
- return result
507
+ return_value = result
508
+ else:
509
+ return_value = None
434
510
  except Exception as e:
435
- if DEBUG:
436
- print(f"Error handling {hook_type}: {e}", file=sys.stderr)
511
+ error_message = str(e)
512
+ return_value = None
513
+ _log(f"Error handling {hook_type}: {e}")
514
+ finally:
515
+ # Calculate duration
516
+ duration_ms = int((time.time() - start_time) * 1000)
517
+
518
+ # Emit hook execution event
519
+ self._emit_hook_execution_event(
520
+ hook_type=hook_type,
521
+ event=event,
522
+ success=success,
523
+ duration_ms=duration_ms,
524
+ error_message=error_message,
525
+ )
526
+
527
+ return return_value
437
528
 
438
529
  return None
439
530
 
@@ -453,9 +544,12 @@ class ClaudeHookHandler:
453
544
  """
454
545
  if modified_input is not None:
455
546
  # Claude Code v2.0.30+ supports modifying PreToolUse tool inputs
456
- print(json.dumps({"action": "continue", "tool_input": modified_input}))
547
+ print(
548
+ json.dumps({"continue": True, "tool_input": modified_input}),
549
+ flush=True,
550
+ )
457
551
  else:
458
- print(json.dumps({"action": "continue"}))
552
+ print(json.dumps({"continue": True}), flush=True)
459
553
 
460
554
  # Delegation methods for compatibility with event_handlers
461
555
  def _track_delegation(self, session_id: str, agent_type: str, request_data=None):
@@ -478,14 +572,142 @@ class ClaudeHookHandler:
478
572
  """Generate event key through duplicate detector (backward compatibility)."""
479
573
  return self.duplicate_detector.generate_event_key(event)
480
574
 
575
+ def _emit_hook_execution_event(
576
+ self,
577
+ hook_type: str,
578
+ event: dict,
579
+ success: bool,
580
+ duration_ms: int,
581
+ error_message: Optional[str] = None,
582
+ ):
583
+ """Emit a structured JSON event for hook execution.
584
+
585
+ This emits a normalized event following the claude_event schema to provide
586
+ visibility into hook processing, timing, and success/failure status.
587
+
588
+ Args:
589
+ hook_type: The type of hook that executed (e.g., "UserPromptSubmit", "PreToolUse")
590
+ event: The original hook event data
591
+ success: Whether the hook executed successfully
592
+ duration_ms: How long the hook took to execute in milliseconds
593
+ error_message: Optional error message if the hook failed
594
+ """
595
+ # Generate a human-readable summary based on hook type
596
+ summary = self._generate_hook_summary(hook_type, event, success)
597
+
598
+ # Extract common fields
599
+ session_id = event.get("session_id", "")
600
+ working_dir = event.get("cwd", "")
601
+
602
+ # Build hook execution data
603
+ hook_data = {
604
+ "hook_name": hook_type,
605
+ "hook_type": hook_type, # Actual hook type (PreToolUse, UserPromptSubmit, etc.)
606
+ "hook_event_type": hook_type, # Additional field for clarity
607
+ "session_id": session_id,
608
+ "working_directory": working_dir,
609
+ "success": success,
610
+ "duration_ms": duration_ms,
611
+ "result_summary": summary,
612
+ "timestamp": datetime.now(timezone.utc).isoformat(),
613
+ "source": "claude_hook_handler", # Explicit source identification
614
+ }
615
+
616
+ # Add error information if present
617
+ if error_message:
618
+ hook_data["error_message"] = error_message
619
+
620
+ # Add hook-specific context
621
+ if hook_type == "PreToolUse":
622
+ hook_data["tool_name"] = event.get("tool_name", "")
623
+ elif hook_type == "PostToolUse":
624
+ hook_data["tool_name"] = event.get("tool_name", "")
625
+ hook_data["exit_code"] = event.get("exit_code", 0)
626
+ elif hook_type == "UserPromptSubmit":
627
+ prompt = event.get("prompt", "")
628
+ hook_data["prompt_preview"] = prompt[:100] if len(prompt) > 100 else prompt
629
+ hook_data["prompt_length"] = len(prompt)
630
+ elif hook_type == "SubagentStop":
631
+ hook_data["agent_type"] = event.get("agent_type", "unknown")
632
+ hook_data["reason"] = event.get("reason", "unknown")
633
+
634
+ # Emit through connection manager with proper structure
635
+ # This uses the existing event infrastructure
636
+ self._emit_socketio_event("", "hook_execution", hook_data)
637
+
638
+ _log(
639
+ f"📊 Hook execution event: {hook_type} - {duration_ms}ms - {'✅' if success else '❌'}"
640
+ )
641
+
642
+ def _generate_hook_summary(self, hook_type: str, event: dict, success: bool) -> str:
643
+ """Generate a human-readable summary of what the hook did.
644
+
645
+ Args:
646
+ hook_type: The type of hook
647
+ event: The hook event data
648
+ success: Whether the hook executed successfully
649
+
650
+ Returns:
651
+ A brief description of what happened
652
+ """
653
+ if not success:
654
+ return f"Hook {hook_type} failed during processing"
655
+
656
+ # Generate hook-specific summaries
657
+ if hook_type == "UserPromptSubmit":
658
+ prompt = event.get("prompt", "")
659
+ if prompt.startswith("/"):
660
+ return f"Processed command: {prompt.split()[0]}"
661
+ return f"Processed user prompt ({len(prompt)} chars)"
662
+
663
+ if hook_type == "PreToolUse":
664
+ tool_name = event.get("tool_name", "unknown")
665
+ return f"Pre-processing tool call: {tool_name}"
666
+
667
+ if hook_type == "PostToolUse":
668
+ tool_name = event.get("tool_name", "unknown")
669
+ exit_code = event.get("exit_code", 0)
670
+ status = "success" if exit_code == 0 else "failed"
671
+ return f"Completed tool call: {tool_name} ({status})"
672
+
673
+ if hook_type == "SubagentStop":
674
+ agent_type = event.get("agent_type", "unknown")
675
+ reason = event.get("reason", "unknown")
676
+ return f"Subagent {agent_type} stopped: {reason}"
677
+
678
+ if hook_type == "SessionStart":
679
+ return "New session started"
680
+
681
+ if hook_type == "Stop":
682
+ reason = event.get("reason", "unknown")
683
+ return f"Session stopped: {reason}"
684
+
685
+ if hook_type == "Notification":
686
+ notification_type = event.get("notification_type", "unknown")
687
+ return f"Notification received: {notification_type}"
688
+
689
+ if hook_type == "AssistantResponse":
690
+ response_len = len(event.get("response", ""))
691
+ return f"Assistant response generated ({response_len} chars)"
692
+
693
+ # Default summary
694
+ return f"Hook {hook_type} processed successfully"
695
+
481
696
  def __del__(self):
482
697
  """Cleanup on handler destruction."""
698
+ # Finalize any active auto-pause session
699
+ if hasattr(self, "auto_pause_handler") and self.auto_pause_handler:
700
+ try:
701
+ self.auto_pause_handler.on_session_end()
702
+ except Exception:
703
+ pass # nosec B110 - Intentionally ignore cleanup errors during handler destruction
704
+
483
705
  # Clean up connection manager if it exists
484
706
  if hasattr(self, "connection_manager") and self.connection_manager:
485
707
  try:
486
708
  self.connection_manager.cleanup()
487
709
  except Exception:
488
- pass # Ignore cleanup errors during destruction
710
+ pass # nosec B110 - Intentionally ignore cleanup errors during handler destruction
489
711
 
490
712
 
491
713
  def main():
@@ -498,25 +720,18 @@ def main():
498
720
  if not is_compatible:
499
721
  # Version incompatible - just continue without processing
500
722
  # This prevents errors on older Claude Code versions
501
- if DEBUG and version:
502
- print(
503
- f"Skipping hook processing due to version incompatibility ({version})",
504
- file=sys.stderr,
505
- )
506
- print(json.dumps({"action": "continue"}))
723
+ if version:
724
+ _log(f"Skipping hook processing due to version incompatibility ({version})")
725
+ print(json.dumps({"continue": True}), flush=True)
507
726
  sys.exit(0)
508
727
 
509
728
  def cleanup_handler(signum=None, frame=None):
510
729
  """Cleanup handler for signals and exit."""
511
730
  nonlocal _continue_printed
512
- if DEBUG:
513
- print(
514
- f"Hook handler cleanup (pid: {os.getpid()}, signal: {signum})",
515
- file=sys.stderr,
516
- )
731
+ _log(f"Hook handler cleanup (pid: {os.getpid()}, signal: {signum})")
517
732
  # Only output continue if we haven't already (i.e., if interrupted by signal)
518
733
  if signum is not None and not _continue_printed:
519
- print(json.dumps({"action": "continue"}))
734
+ print(json.dumps({"continue": True}), flush=True)
520
735
  _continue_printed = True
521
736
  sys.exit(0)
522
737
 
@@ -530,15 +745,10 @@ def main():
530
745
  with _handler_lock:
531
746
  if _global_handler is None:
532
747
  _global_handler = ClaudeHookHandler()
533
- if DEBUG:
534
- print(
535
- f"✅ Created new ClaudeHookHandler singleton (pid: {os.getpid()})",
536
- file=sys.stderr,
537
- )
538
- elif DEBUG:
539
- print(
540
- f"♻️ Reusing existing ClaudeHookHandler singleton (pid: {os.getpid()})",
541
- file=sys.stderr,
748
+ _log(f"✅ Created new ClaudeHookHandler singleton (pid: {os.getpid()})")
749
+ else:
750
+ _log(
751
+ f"♻️ Reusing existing ClaudeHookHandler singleton (pid: {os.getpid()})"
542
752
  )
543
753
 
544
754
  handler = _global_handler
@@ -554,13 +764,17 @@ def main():
554
764
  except Exception as e:
555
765
  # Only output continue if not already printed
556
766
  if not _continue_printed:
557
- print(json.dumps({"action": "continue"}))
767
+ print(json.dumps({"continue": True}), flush=True)
558
768
  _continue_printed = True
559
769
  # Log error for debugging
560
- if DEBUG:
561
- print(f"Hook handler error: {e}", file=sys.stderr)
770
+ _log(f"Hook handler error: {e}")
562
771
  sys.exit(0) # Exit cleanly even on error
563
772
 
564
773
 
565
774
  if __name__ == "__main__":
566
- main()
775
+ try:
776
+ main()
777
+ except Exception:
778
+ # Catastrophic failure (import error, etc.) - always output valid JSON
779
+ print(json.dumps({"continue": True}), flush=True)
780
+ sys.exit(0)
@@ -48,15 +48,10 @@ echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] PYTHONPATH: $PYTHONPATH" >> /tmp/hook
48
48
  echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] Running: $PYTHON_CMD -m claude_mpm.hooks.claude_hooks.hook_handler" >> /tmp/hook-wrapper.log
49
49
  echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] SOCKETIO_PORT: $CLAUDE_MPM_SOCKETIO_PORT" >> /tmp/hook-wrapper.log
50
50
 
51
- # Run the Python hook handler as a module with error handling
52
- # Use exec to replace the shell process, but wrap in error handling
53
- if ! "$PYTHON_CMD" -m claude_mpm.hooks.claude_hooks.hook_handler "$@" 2>/tmp/hook-error.log; then
54
- # If the Python handler fails, always return continue to not block Claude
55
- echo '{"action": "continue"}'
56
- # Log the error for debugging
57
- echo "[$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)] Hook handler failed, see /tmp/hook-error.log" >> /tmp/hook-wrapper.log
58
- exit 0
59
- fi
51
+ # Run the Python hook handler as a module
52
+ # Python handler is responsible for ALL stdout output (including error fallback)
53
+ # Redirect stderr to log file for debugging
54
+ "$PYTHON_CMD" -m claude_mpm.hooks.claude_hooks.hook_handler "$@" 2>/tmp/hook-error.log
60
55
 
61
- # Success - Python handler already printed continue, just exit
62
- exit 0
56
+ # Exit with Python's exit code (should always be 0)
57
+ exit $?