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
@@ -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,6 +31,7 @@ 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
@@ -47,6 +48,7 @@ except ImportError:
47
48
  # Add parent directory to path
48
49
  sys.path.insert(0, str(Path(__file__).parent))
49
50
 
51
+ from auto_pause_handler import AutoPauseHandler
50
52
  from event_handlers import EventHandlers
51
53
  from memory_integration import MemoryHookManager
52
54
  from response_tracking import ResponseTrackingManager
@@ -60,14 +62,31 @@ except ImportError:
60
62
  """
61
63
  Debug mode configuration for hook processing.
62
64
 
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.
65
+ WHY disabled by default: Production users should see clean output without debug noise.
66
+ Hook errors appear less confusing when debug output is minimal.
67
+ Development and debugging can enable via CLAUDE_MPM_HOOK_DEBUG=true.
66
68
 
67
69
  Performance Impact: Debug logging adds ~5-10% overhead but provides crucial
68
- visibility into event flow, timing, and error conditions.
70
+ visibility into event flow, timing, and error conditions when enabled.
69
71
  """
70
- DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "true").lower() != "false"
72
+ DEBUG = os.environ.get("CLAUDE_MPM_HOOK_DEBUG", "false").lower() == "true"
73
+
74
+
75
+ def _log(message: str) -> None:
76
+ """Log message to file if DEBUG enabled. Never write to stderr.
77
+
78
+ WHY: Claude Code interprets ANY stderr output as a hook error.
79
+ Writing to stderr causes confusing "hook error" messages even for debug logs.
80
+
81
+ This helper ensures all debug output goes to a log file instead.
82
+ """
83
+ if DEBUG:
84
+ try:
85
+ with open("/tmp/claude-mpm-hook.log", "a") as f: # nosec B108
86
+ f.write(f"[{datetime.now(timezone.utc).isoformat()}] {message}\n")
87
+ except Exception: # nosec B110 - intentional silent failure
88
+ pass # Never disrupt hook execution
89
+
71
90
 
72
91
  """
73
92
  Conditional imports with graceful fallbacks for testing and modularity.
@@ -109,6 +128,8 @@ WHY version checking:
109
128
  Security: Version checking prevents execution on incompatible environments.
110
129
  """
111
130
  MIN_CLAUDE_VERSION = "1.0.92"
131
+ # Minimum version for user-invocable skills support
132
+ MIN_SKILLS_VERSION = "2.1.3"
112
133
 
113
134
 
114
135
  def check_claude_version() -> Tuple[bool, Optional[str]]:
@@ -153,7 +174,7 @@ def check_claude_version() -> Tuple[bool, Optional[str]]:
153
174
  """
154
175
  try:
155
176
  # Try to detect Claude Code version
156
- result = subprocess.run(
177
+ result = subprocess.run( # nosec B603 B607 - Safe: hardcoded claude CLI with --version flag, no user input
157
178
  ["claude", "--version"],
158
179
  capture_output=True,
159
180
  text=True,
@@ -184,22 +205,17 @@ def check_claude_version() -> Tuple[bool, Optional[str]]:
184
205
  req_part = required[i] if i < len(required) else 0
185
206
 
186
207
  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
- )
208
+ _log(
209
+ f"⚠️ Claude Code {version} does not support matcher-based hooks "
210
+ f"(requires {MIN_CLAUDE_VERSION}+). Hook monitoring disabled."
211
+ )
193
212
  return False, version
194
213
  if curr_part > req_part:
195
214
  return True, version
196
215
 
197
216
  return True, version
198
217
  except Exception as e:
199
- if DEBUG:
200
- print(
201
- f"Warning: Could not detect Claude Code version: {e}", file=sys.stderr
202
- )
218
+ _log(f"Warning: Could not detect Claude Code version: {e}")
203
219
 
204
220
  return False, None
205
221
 
@@ -230,8 +246,21 @@ class ClaudeHookHandler:
230
246
  self.state_manager, self.response_tracking_manager, self.connection_manager
231
247
  )
232
248
 
249
+ # Initialize auto-pause handler
250
+ try:
251
+ self.auto_pause_handler = AutoPauseHandler()
252
+ # Pass reference to ResponseTrackingManager so it can call auto_pause
253
+ if hasattr(self, "response_tracking_manager"):
254
+ self.response_tracking_manager.auto_pause_handler = (
255
+ self.auto_pause_handler
256
+ )
257
+ except Exception as e:
258
+ self.auto_pause_handler = None
259
+ _log(f"Auto-pause initialization failed: {e}")
260
+
233
261
  # Backward compatibility properties for tests
234
- self.connection_pool = self.connection_manager.connection_pool
262
+ # Note: HTTP-based connection manager doesn't use connection_pool
263
+ self.connection_pool = None # Deprecated: No longer needed with HTTP emission
235
264
 
236
265
  # Expose state manager properties for backward compatibility
237
266
  self.active_delegations = self.state_manager.active_delegations
@@ -260,8 +289,7 @@ class ClaudeHookHandler:
260
289
  def timeout_handler(signum, frame):
261
290
  """Handle timeout by forcing exit."""
262
291
  nonlocal _continue_sent
263
- if DEBUG:
264
- print(f"Hook handler timeout (pid: {os.getpid()})", file=sys.stderr)
292
+ _log(f"Hook handler timeout (pid: {os.getpid()})")
265
293
  if not _continue_sent:
266
294
  self._continue_execution()
267
295
  _continue_sent = True
@@ -282,11 +310,9 @@ class ClaudeHookHandler:
282
310
 
283
311
  # Check for duplicate events (same event within 100ms)
284
312
  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
- )
313
+ _log(
314
+ f"[{datetime.now(timezone.utc).isoformat()}] Skipping duplicate event: {event.get('hook_event_name', 'unknown')} (PID: {os.getpid()})"
315
+ )
290
316
  # Still need to output continue for this invocation
291
317
  if not _continue_sent:
292
318
  self._continue_execution()
@@ -294,12 +320,10 @@ class ClaudeHookHandler:
294
320
  return
295
321
 
296
322
  # 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
- )
323
+ hook_type = event.get("hook_event_name", "unknown")
324
+ _log(
325
+ f"\n[{datetime.now(timezone.utc).isoformat()}] Processing hook event: {hook_type} (PID: {os.getpid()})"
326
+ )
303
327
 
304
328
  # Perform periodic cleanup if needed
305
329
  if self.state_manager.increment_events_processed():
@@ -308,11 +332,9 @@ class ClaudeHookHandler:
308
332
  from .correlation_manager import CorrelationManager
309
333
 
310
334
  CorrelationManager.cleanup_old()
311
- if DEBUG:
312
- print(
313
- f"🧹 Performed cleanup after {self.state_manager.events_processed} events",
314
- file=sys.stderr,
315
- )
335
+ _log(
336
+ f"🧹 Performed cleanup after {self.state_manager.events_processed} events"
337
+ )
316
338
 
317
339
  # Route event to appropriate handler
318
340
  # Handlers can optionally return modified input for PreToolUse events
@@ -352,8 +374,7 @@ class ClaudeHookHandler:
352
374
  ready, _, _ = select.select([sys.stdin], [], [], 1.0)
353
375
  if not ready:
354
376
  # No data available within timeout
355
- if DEBUG:
356
- print("No hook event data received within timeout", file=sys.stderr)
377
+ _log("No hook event data received within timeout")
357
378
  return None
358
379
 
359
380
  # Data is available, read it
@@ -364,21 +385,16 @@ class ClaudeHookHandler:
364
385
 
365
386
  parsed = json.loads(event_data)
366
387
  # 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)
388
+ _log(f"Received event with keys: {list(parsed.keys())}")
389
+ for key in ["hook_event_name", "event", "type", "event_type"]:
390
+ if key in parsed:
391
+ _log(f" {key} = '{parsed[key]}'")
374
392
  return parsed
375
393
  except (json.JSONDecodeError, ValueError) as e:
376
- if DEBUG:
377
- print(f"Failed to parse hook event: {e}", file=sys.stderr)
394
+ _log(f"Failed to parse hook event: {e}")
378
395
  return None
379
396
  except Exception as e:
380
- if DEBUG:
381
- print(f"Error reading hook event: {e}", file=sys.stderr)
397
+ _log(f"Error reading hook event: {e}")
382
398
  return None
383
399
 
384
400
  def _route_event(self, event: dict) -> Optional[dict]:
@@ -407,9 +423,9 @@ class ClaudeHookHandler:
407
423
  )
408
424
 
409
425
  # Log the actual event structure for debugging
410
- if DEBUG and hook_type == "unknown":
411
- print(f"Unknown event format, keys: {list(event.keys())}", file=sys.stderr)
412
- print(f"Event sample: {str(event)[:200]}", file=sys.stderr)
426
+ if hook_type == "unknown":
427
+ _log(f"Unknown event format, keys: {list(event.keys())}")
428
+ _log(f"Event sample: {str(event)[:200]}")
413
429
 
414
430
  # Map event types to handlers
415
431
  event_handlers = {
@@ -419,7 +435,7 @@ class ClaudeHookHandler:
419
435
  "Notification": self.event_handlers.handle_notification_fast,
420
436
  "Stop": self.event_handlers.handle_stop_fast,
421
437
  "SubagentStop": self.event_handlers.handle_subagent_stop_fast,
422
- "SubagentStart": self.event_handlers.handle_session_start_fast,
438
+ "SubagentStart": self.event_handlers.handle_subagent_start_fast,
423
439
  "SessionStart": self.event_handlers.handle_session_start_fast,
424
440
  "AssistantResponse": self.event_handlers.handle_assistant_response,
425
441
  }
@@ -445,8 +461,7 @@ class ClaudeHookHandler:
445
461
  except Exception as e:
446
462
  error_message = str(e)
447
463
  return_value = None
448
- if DEBUG:
449
- print(f"Error handling {hook_type}: {e}", file=sys.stderr)
464
+ _log(f"Error handling {hook_type}: {e}")
450
465
  finally:
451
466
  # Calculate duration
452
467
  duration_ms = int((time.time() - start_time) * 1000)
@@ -480,9 +495,12 @@ class ClaudeHookHandler:
480
495
  """
481
496
  if modified_input is not None:
482
497
  # Claude Code v2.0.30+ supports modifying PreToolUse tool inputs
483
- print(json.dumps({"action": "continue", "tool_input": modified_input}))
498
+ print(
499
+ json.dumps({"action": "continue", "tool_input": modified_input}),
500
+ flush=True,
501
+ )
484
502
  else:
485
- print(json.dumps({"action": "continue"}))
503
+ print(json.dumps({"action": "continue"}), flush=True)
486
504
 
487
505
  # Delegation methods for compatibility with event_handlers
488
506
  def _track_delegation(self, session_id: str, agent_type: str, request_data=None):
@@ -535,13 +553,15 @@ class ClaudeHookHandler:
535
553
  # Build hook execution data
536
554
  hook_data = {
537
555
  "hook_name": hook_type,
538
- "hook_type": hook_type,
556
+ "hook_type": hook_type, # Actual hook type (PreToolUse, UserPromptSubmit, etc.)
557
+ "hook_event_type": hook_type, # Additional field for clarity
539
558
  "session_id": session_id,
540
559
  "working_directory": working_dir,
541
560
  "success": success,
542
561
  "duration_ms": duration_ms,
543
562
  "result_summary": summary,
544
563
  "timestamp": datetime.now(timezone.utc).isoformat(),
564
+ "source": "claude_hook_handler", # Explicit source identification
545
565
  }
546
566
 
547
567
  # Add error information if present
@@ -566,11 +586,9 @@ class ClaudeHookHandler:
566
586
  # This uses the existing event infrastructure
567
587
  self._emit_socketio_event("", "hook_execution", hook_data)
568
588
 
569
- if DEBUG:
570
- print(
571
- f"📊 Hook execution event: {hook_type} - {duration_ms}ms - {'✅' if success else '❌'}",
572
- file=sys.stderr,
573
- )
589
+ _log(
590
+ f"📊 Hook execution event: {hook_type} - {duration_ms}ms - {'✅' if success else '❌'}"
591
+ )
574
592
 
575
593
  def _generate_hook_summary(self, hook_type: str, event: dict, success: bool) -> str:
576
594
  """Generate a human-readable summary of what the hook did.
@@ -628,12 +646,19 @@ class ClaudeHookHandler:
628
646
 
629
647
  def __del__(self):
630
648
  """Cleanup on handler destruction."""
649
+ # Finalize any active auto-pause session
650
+ if hasattr(self, "auto_pause_handler") and self.auto_pause_handler:
651
+ try:
652
+ self.auto_pause_handler.on_session_end()
653
+ except Exception:
654
+ pass # nosec B110 - Intentionally ignore cleanup errors during handler destruction
655
+
631
656
  # Clean up connection manager if it exists
632
657
  if hasattr(self, "connection_manager") and self.connection_manager:
633
658
  try:
634
659
  self.connection_manager.cleanup()
635
660
  except Exception:
636
- pass # Ignore cleanup errors during destruction
661
+ pass # nosec B110 - Intentionally ignore cleanup errors during handler destruction
637
662
 
638
663
 
639
664
  def main():
@@ -646,25 +671,18 @@ def main():
646
671
  if not is_compatible:
647
672
  # Version incompatible - just continue without processing
648
673
  # This prevents errors on older Claude Code versions
649
- if DEBUG and version:
650
- print(
651
- f"Skipping hook processing due to version incompatibility ({version})",
652
- file=sys.stderr,
653
- )
654
- print(json.dumps({"action": "continue"}))
674
+ if version:
675
+ _log(f"Skipping hook processing due to version incompatibility ({version})")
676
+ print(json.dumps({"action": "continue"}), flush=True)
655
677
  sys.exit(0)
656
678
 
657
679
  def cleanup_handler(signum=None, frame=None):
658
680
  """Cleanup handler for signals and exit."""
659
681
  nonlocal _continue_printed
660
- if DEBUG:
661
- print(
662
- f"Hook handler cleanup (pid: {os.getpid()}, signal: {signum})",
663
- file=sys.stderr,
664
- )
682
+ _log(f"Hook handler cleanup (pid: {os.getpid()}, signal: {signum})")
665
683
  # Only output continue if we haven't already (i.e., if interrupted by signal)
666
684
  if signum is not None and not _continue_printed:
667
- print(json.dumps({"action": "continue"}))
685
+ print(json.dumps({"action": "continue"}), flush=True)
668
686
  _continue_printed = True
669
687
  sys.exit(0)
670
688
 
@@ -678,15 +696,10 @@ def main():
678
696
  with _handler_lock:
679
697
  if _global_handler is None:
680
698
  _global_handler = ClaudeHookHandler()
681
- if DEBUG:
682
- print(
683
- f"✅ Created new ClaudeHookHandler singleton (pid: {os.getpid()})",
684
- file=sys.stderr,
685
- )
686
- elif DEBUG:
687
- print(
688
- f"♻️ Reusing existing ClaudeHookHandler singleton (pid: {os.getpid()})",
689
- file=sys.stderr,
699
+ _log(f"✅ Created new ClaudeHookHandler singleton (pid: {os.getpid()})")
700
+ else:
701
+ _log(
702
+ f"♻️ Reusing existing ClaudeHookHandler singleton (pid: {os.getpid()})"
690
703
  )
691
704
 
692
705
  handler = _global_handler
@@ -702,13 +715,17 @@ def main():
702
715
  except Exception as e:
703
716
  # Only output continue if not already printed
704
717
  if not _continue_printed:
705
- print(json.dumps({"action": "continue"}))
718
+ print(json.dumps({"action": "continue"}), flush=True)
706
719
  _continue_printed = True
707
720
  # Log error for debugging
708
- if DEBUG:
709
- print(f"Hook handler error: {e}", file=sys.stderr)
721
+ _log(f"Hook handler error: {e}")
710
722
  sys.exit(0) # Exit cleanly even on error
711
723
 
712
724
 
713
725
  if __name__ == "__main__":
714
- main()
726
+ try:
727
+ main()
728
+ except Exception:
729
+ # Catastrophic failure (import error, etc.) - always output valid JSON
730
+ print(json.dumps({"action": "continue"}), flush=True)
731
+ 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 $?
@@ -10,12 +10,10 @@ import os
10
10
  import re
11
11
  import shutil
12
12
  import stat
13
- import subprocess
13
+ import subprocess # nosec B404 - Safe: only uses hardcoded 'claude' CLI command, no user input
14
14
  from pathlib import Path
15
15
  from typing import Dict, List, Optional, Tuple
16
16
 
17
- from ...core.logger import get_logger
18
-
19
17
 
20
18
  class HookInstaller:
21
19
  """Manages installation and configuration of Claude MPM hooks."""
@@ -194,10 +192,17 @@ main "$@"
194
192
  MIN_CLAUDE_VERSION = "1.0.92"
195
193
  # Minimum version for PreToolUse input modification support
196
194
  MIN_PRETOOL_MODIFY_VERSION = "2.0.30"
195
+ # Minimum version for user-invocable skills support
196
+ MIN_SKILLS_VERSION = "2.1.3"
197
197
 
198
198
  def __init__(self):
199
199
  """Initialize the hook installer."""
200
- self.logger = get_logger(__name__)
200
+ # Use __name__ directly to avoid double prefix
201
+ # __name__ is already 'claude_mpm.hooks.claude_hooks.installer'
202
+ # get_logger() adds 'claude_mpm.' prefix, causing duplicate
203
+ import logging
204
+
205
+ self.logger = logging.getLogger(__name__)
201
206
  self.claude_dir = Path.home() / ".claude"
202
207
  self.hooks_dir = self.claude_dir / "hooks" # Kept for backward compatibility
203
208
  # Use settings.json for hooks (Claude Code reads from this file)
@@ -220,7 +225,7 @@ main "$@"
220
225
 
221
226
  try:
222
227
  # Run claude --version command
223
- result = subprocess.run(
228
+ result = subprocess.run( # nosec B607 B603 - Safe: hardcoded command, no user input
224
229
  ["claude", "--version"],
225
230
  capture_output=True,
226
231
  text=True,
@@ -331,6 +336,53 @@ main "$@"
331
336
 
332
337
  return True
333
338
 
339
+ def _version_meets_minimum(self, version: str, min_version: str) -> bool:
340
+ """Check if a version meets minimum requirements.
341
+
342
+ Args:
343
+ version: Current version string (e.g., "2.1.3")
344
+ min_version: Minimum required version string (e.g., "2.1.3")
345
+
346
+ Returns:
347
+ True if version meets or exceeds minimum, False otherwise
348
+ """
349
+
350
+ def parse_version(v: str) -> List[int]:
351
+ """Parse semantic version string to list of integers."""
352
+ try:
353
+ return [int(x) for x in v.split(".")]
354
+ except (ValueError, AttributeError):
355
+ return [0]
356
+
357
+ current = parse_version(version)
358
+ required = parse_version(min_version)
359
+
360
+ # Compare versions
361
+ for i in range(max(len(current), len(required))):
362
+ curr_part = current[i] if i < len(current) else 0
363
+ req_part = required[i] if i < len(required) else 0
364
+
365
+ if curr_part < req_part:
366
+ return False
367
+ if curr_part > req_part:
368
+ return True
369
+
370
+ return True
371
+
372
+ def supports_user_invocable_skills(self) -> bool:
373
+ """Check if Claude Code version supports user-invocable skills.
374
+
375
+ User-invocable skills were added in Claude Code v2.1.3.
376
+ This feature allows users to invoke skills via slash commands.
377
+
378
+ Returns:
379
+ True if version supports user-invocable skills, False otherwise
380
+ """
381
+ version = self.get_claude_version()
382
+ if not version:
383
+ return False
384
+ return self._version_meets_minimum(version, self.MIN_SKILLS_VERSION)
385
+
334
386
  def get_hook_script_path(self) -> Path:
335
387
  """Get the path to the hook handler script based on installation method.
336
388
 
@@ -485,6 +537,44 @@ main "$@"
485
537
  except Exception as e:
486
538
  self.logger.warning(f"Could not clean up old settings file: {e}")
487
539
 
540
+ def _fix_status_line(self, settings: Dict) -> None:
541
+ """Fix statusLine command to handle both output style schema formats.
542
+
543
+ The statusLine command receives input in different formats:
544
+ - Newer format: {"activeOutputStyle": "Claude MPM", ...}
545
+ - Older format: {"output_style": {"name": "Claude MPM"}, ...}
546
+
547
+ This method ensures the jq expression checks both locations.
548
+
549
+ Args:
550
+ settings: The settings dictionary to update
551
+ """
552
+ if "statusLine" not in settings:
553
+ return
554
+
555
+ status_line = settings.get("statusLine", {})
556
+ if "command" not in status_line:
557
+ return
558
+
559
+ command = status_line["command"]
560
+
561
+ # Pattern to match: '.output_style.name // "default"'
562
+ # We need to update it to: '.output_style.name // .activeOutputStyle // "default"'
563
+ old_pattern = r'\.output_style\.name\s*//\s*"default"'
564
+ new_pattern = '.output_style.name // .activeOutputStyle // "default"'
565
+
566
+ # Check if the command needs updating
567
+ if re.search(old_pattern, command) and ".activeOutputStyle" not in command:
568
+ updated_command = re.sub(old_pattern, new_pattern, command)
569
+ settings["statusLine"]["command"] = updated_command
570
+ self.logger.info(
571
+ "Fixed statusLine command to handle both output style schemas"
572
+ )
573
+ else:
574
+ self.logger.debug(
575
+ "StatusLine command already supports both schemas or not present"
576
+ )
577
+
488
578
  def _update_claude_settings(self, hook_script_path: Path) -> None:
489
579
  """Update Claude settings to use the installed hook."""
490
580
  self.logger.info("Updating Claude settings...")
@@ -546,6 +636,9 @@ main "$@"
546
636
  }
547
637
  ]
548
638
 
639
+ # Fix statusLine command to handle both output style schemas
640
+ self._fix_status_line(settings)
641
+
549
642
  # Write settings to settings.json
550
643
  with self.settings_file.open("w") as f:
551
644
  json.dump(settings, f, indent=2)
@@ -556,7 +649,22 @@ main "$@"
556
649
  self._cleanup_old_settings()
557
650
 
558
651
  def _install_commands(self) -> None:
559
- """Install custom commands for Claude Code."""
652
+ """Install custom commands for Claude Code.
653
+
654
+ For Claude Code >= 2.1.3, commands are deployed as skills via PMSkillsDeployerService.
655
+ This method provides backward compatibility for older versions.
656
+ """
657
+ # Check if skills-based commands are supported
658
+ if self.supports_user_invocable_skills():
659
+ self.logger.info(
660
+ "Claude Code >= 2.1.3 detected. Commands deployed as skills - "
661
+ "skipping legacy command installation."
662
+ )
663
+ return
664
+
665
+ # Legacy installation for older Claude Code versions
666
+ self.logger.info("Installing legacy commands for Claude Code < 2.1.3")
667
+
560
668
  # Find commands directory using proper resource resolution
561
669
  try:
562
670
  from ...core.unified_paths import get_package_resource_path
@@ -782,7 +890,7 @@ main "$@"
782
890
  if "hooks" in settings:
783
891
  status["configured_events"] = list(settings["hooks"].keys())
784
892
  configured_in_local = True
785
- except Exception:
893
+ except Exception: # nosec B110 - Intentional: ignore errors reading settings file
786
894
  pass
787
895
 
788
896
  # Also check old settings file
@@ -796,7 +904,7 @@ main "$@"
796
904
  status["warning"] = (
797
905
  "Hooks found in settings.local.json but Claude Code reads from settings.json"
798
906
  )
799
- except Exception:
907
+ except Exception: # nosec B110 - Intentional: ignore errors reading old settings file
800
908
  pass
801
909
 
802
910
  status["settings_location"] = (