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

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

Potentially problematic release.


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

Files changed (467) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
  3. claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
  4. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
  5. claude_mpm/agents/PM_INSTRUCTIONS.md +119 -689
  6. claude_mpm/agents/WORKFLOW.md +2 -0
  7. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  8. claude_mpm/cli/__init__.py +5 -1
  9. claude_mpm/cli/commands/agents.py +2 -4
  10. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  11. claude_mpm/cli/commands/autotodos.py +566 -0
  12. claude_mpm/cli/commands/commander.py +216 -0
  13. claude_mpm/cli/commands/configure.py +620 -21
  14. claude_mpm/cli/commands/configure_agent_display.py +3 -1
  15. claude_mpm/cli/commands/hook_errors.py +60 -60
  16. claude_mpm/cli/commands/monitor.py +2 -2
  17. claude_mpm/cli/commands/mpm_init/core.py +15 -8
  18. claude_mpm/cli/commands/profile.py +9 -10
  19. claude_mpm/cli/commands/run.py +35 -3
  20. claude_mpm/cli/commands/skill_source.py +51 -2
  21. claude_mpm/cli/commands/skills.py +171 -17
  22. claude_mpm/cli/executor.py +120 -16
  23. claude_mpm/cli/interactive/__init__.py +10 -0
  24. claude_mpm/cli/interactive/agent_wizard.py +30 -50
  25. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  26. claude_mpm/cli/interactive/skill_selector.py +481 -0
  27. claude_mpm/cli/parsers/base_parser.py +76 -1
  28. claude_mpm/cli/parsers/commander_parser.py +116 -0
  29. claude_mpm/cli/parsers/profile_parser.py +0 -1
  30. claude_mpm/cli/parsers/run_parser.py +10 -0
  31. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  32. claude_mpm/cli/parsers/skills_parser.py +5 -0
  33. claude_mpm/cli/startup.py +544 -511
  34. claude_mpm/cli/startup_display.py +74 -6
  35. claude_mpm/cli/startup_logging.py +2 -2
  36. claude_mpm/cli/utils.py +7 -3
  37. claude_mpm/commander/__init__.py +78 -0
  38. claude_mpm/commander/adapters/__init__.py +60 -0
  39. claude_mpm/commander/adapters/auggie.py +260 -0
  40. claude_mpm/commander/adapters/base.py +288 -0
  41. claude_mpm/commander/adapters/claude_code.py +392 -0
  42. claude_mpm/commander/adapters/codex.py +237 -0
  43. claude_mpm/commander/adapters/communication.py +366 -0
  44. claude_mpm/commander/adapters/example_usage.py +310 -0
  45. claude_mpm/commander/adapters/mpm.py +389 -0
  46. claude_mpm/commander/adapters/registry.py +204 -0
  47. claude_mpm/commander/api/__init__.py +16 -0
  48. claude_mpm/commander/api/app.py +121 -0
  49. claude_mpm/commander/api/errors.py +133 -0
  50. claude_mpm/commander/api/routes/__init__.py +8 -0
  51. claude_mpm/commander/api/routes/events.py +184 -0
  52. claude_mpm/commander/api/routes/inbox.py +171 -0
  53. claude_mpm/commander/api/routes/messages.py +148 -0
  54. claude_mpm/commander/api/routes/projects.py +271 -0
  55. claude_mpm/commander/api/routes/sessions.py +226 -0
  56. claude_mpm/commander/api/routes/work.py +296 -0
  57. claude_mpm/commander/api/schemas.py +186 -0
  58. claude_mpm/commander/chat/__init__.py +7 -0
  59. claude_mpm/commander/chat/cli.py +146 -0
  60. claude_mpm/commander/chat/commands.py +96 -0
  61. claude_mpm/commander/chat/repl.py +310 -0
  62. claude_mpm/commander/config.py +51 -0
  63. claude_mpm/commander/config_loader.py +115 -0
  64. claude_mpm/commander/core/__init__.py +10 -0
  65. claude_mpm/commander/core/block_manager.py +325 -0
  66. claude_mpm/commander/core/response_manager.py +323 -0
  67. claude_mpm/commander/daemon.py +603 -0
  68. claude_mpm/commander/env_loader.py +59 -0
  69. claude_mpm/commander/events/__init__.py +26 -0
  70. claude_mpm/commander/events/manager.py +332 -0
  71. claude_mpm/commander/frameworks/__init__.py +12 -0
  72. claude_mpm/commander/frameworks/base.py +146 -0
  73. claude_mpm/commander/frameworks/claude_code.py +58 -0
  74. claude_mpm/commander/frameworks/mpm.py +62 -0
  75. claude_mpm/commander/inbox/__init__.py +16 -0
  76. claude_mpm/commander/inbox/dedup.py +128 -0
  77. claude_mpm/commander/inbox/inbox.py +224 -0
  78. claude_mpm/commander/inbox/models.py +70 -0
  79. claude_mpm/commander/instance_manager.py +450 -0
  80. claude_mpm/commander/llm/__init__.py +6 -0
  81. claude_mpm/commander/llm/openrouter_client.py +167 -0
  82. claude_mpm/commander/llm/summarizer.py +70 -0
  83. claude_mpm/commander/memory/__init__.py +45 -0
  84. claude_mpm/commander/memory/compression.py +347 -0
  85. claude_mpm/commander/memory/embeddings.py +230 -0
  86. claude_mpm/commander/memory/entities.py +310 -0
  87. claude_mpm/commander/memory/example_usage.py +290 -0
  88. claude_mpm/commander/memory/integration.py +325 -0
  89. claude_mpm/commander/memory/search.py +381 -0
  90. claude_mpm/commander/memory/store.py +657 -0
  91. claude_mpm/commander/models/__init__.py +18 -0
  92. claude_mpm/commander/models/events.py +121 -0
  93. claude_mpm/commander/models/project.py +162 -0
  94. claude_mpm/commander/models/work.py +214 -0
  95. claude_mpm/commander/parsing/__init__.py +20 -0
  96. claude_mpm/commander/parsing/extractor.py +132 -0
  97. claude_mpm/commander/parsing/output_parser.py +270 -0
  98. claude_mpm/commander/parsing/patterns.py +100 -0
  99. claude_mpm/commander/persistence/__init__.py +11 -0
  100. claude_mpm/commander/persistence/event_store.py +274 -0
  101. claude_mpm/commander/persistence/state_store.py +309 -0
  102. claude_mpm/commander/persistence/work_store.py +164 -0
  103. claude_mpm/commander/polling/__init__.py +13 -0
  104. claude_mpm/commander/polling/event_detector.py +104 -0
  105. claude_mpm/commander/polling/output_buffer.py +49 -0
  106. claude_mpm/commander/polling/output_poller.py +153 -0
  107. claude_mpm/commander/project_session.py +268 -0
  108. claude_mpm/commander/proxy/__init__.py +12 -0
  109. claude_mpm/commander/proxy/formatter.py +89 -0
  110. claude_mpm/commander/proxy/output_handler.py +191 -0
  111. claude_mpm/commander/proxy/relay.py +155 -0
  112. claude_mpm/commander/registry.py +410 -0
  113. claude_mpm/commander/runtime/__init__.py +10 -0
  114. claude_mpm/commander/runtime/executor.py +191 -0
  115. claude_mpm/commander/runtime/monitor.py +346 -0
  116. claude_mpm/commander/session/__init__.py +6 -0
  117. claude_mpm/commander/session/context.py +81 -0
  118. claude_mpm/commander/session/manager.py +59 -0
  119. claude_mpm/commander/tmux_orchestrator.py +361 -0
  120. claude_mpm/commander/web/__init__.py +1 -0
  121. claude_mpm/commander/work/__init__.py +30 -0
  122. claude_mpm/commander/work/executor.py +207 -0
  123. claude_mpm/commander/work/queue.py +405 -0
  124. claude_mpm/commander/workflow/__init__.py +27 -0
  125. claude_mpm/commander/workflow/event_handler.py +241 -0
  126. claude_mpm/commander/workflow/notifier.py +146 -0
  127. claude_mpm/commands/mpm-config.md +8 -0
  128. claude_mpm/commands/mpm-doctor.md +8 -0
  129. claude_mpm/commands/mpm-help.md +8 -0
  130. claude_mpm/commands/mpm-init.md +8 -0
  131. claude_mpm/commands/mpm-monitor.md +8 -0
  132. claude_mpm/commands/mpm-organize.md +8 -0
  133. claude_mpm/commands/mpm-postmortem.md +8 -0
  134. claude_mpm/commands/mpm-session-resume.md +9 -1
  135. claude_mpm/commands/mpm-status.md +8 -0
  136. claude_mpm/commands/mpm-ticket-view.md +8 -0
  137. claude_mpm/commands/mpm-version.md +8 -0
  138. claude_mpm/commands/mpm.md +8 -0
  139. claude_mpm/config/agent_presets.py +8 -7
  140. claude_mpm/config/skill_sources.py +16 -0
  141. claude_mpm/constants.py +1 -0
  142. claude_mpm/core/claude_runner.py +154 -2
  143. claude_mpm/core/config.py +35 -22
  144. claude_mpm/core/config_constants.py +74 -9
  145. claude_mpm/core/constants.py +56 -12
  146. claude_mpm/core/hook_manager.py +51 -3
  147. claude_mpm/core/interactive_session.py +12 -11
  148. claude_mpm/core/logger.py +26 -9
  149. claude_mpm/core/logging_utils.py +39 -13
  150. claude_mpm/core/network_config.py +148 -0
  151. claude_mpm/core/oneshot_session.py +7 -6
  152. claude_mpm/core/optimized_startup.py +3 -1
  153. claude_mpm/core/output_style_manager.py +66 -18
  154. claude_mpm/core/shared/config_loader.py +3 -1
  155. claude_mpm/core/socketio_pool.py +47 -15
  156. claude_mpm/core/unified_config.py +54 -8
  157. claude_mpm/core/unified_paths.py +95 -90
  158. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
  159. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
  160. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
  161. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
  162. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
  163. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
  164. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
  165. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
  166. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
  167. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
  168. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  169. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
  170. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
  171. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
  172. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
  173. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
  174. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
  175. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
  176. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
  177. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
  178. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
  179. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
  180. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
  181. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
  182. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
  183. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
  184. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
  185. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
  186. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
  187. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
  188. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
  189. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  190. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
  191. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  192. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
  193. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
  194. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
  195. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
  196. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
  197. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{N4qtv3Hx.js → DR8nis88.js} +2 -2
  198. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
  199. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  200. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
  201. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
  202. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
  203. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
  204. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
  205. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
  206. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  207. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
  208. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
  209. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
  210. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DjhvlsAc.js → NqQ1dWOy.js} +1 -1
  211. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
  212. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
  213. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
  214. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
  215. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
  216. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
  217. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
  218. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
  219. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.CAGBuiOw.js → 0.RgBboRvH.js} +1 -1
  220. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
  221. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
  222. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
  223. claude_mpm/dashboard/static/svelte-build/index.html +11 -11
  224. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  225. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  226. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  227. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  228. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  229. claude_mpm/experimental/cli_enhancements.py +2 -1
  230. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  231. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  232. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  233. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  234. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  235. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  236. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  237. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
  238. claude_mpm/hooks/claude_hooks/event_handlers.py +527 -136
  239. claude_mpm/hooks/claude_hooks/hook_handler.py +170 -104
  240. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  241. claude_mpm/hooks/claude_hooks/installer.py +206 -36
  242. claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
  243. claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
  244. claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
  245. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  246. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  247. claude_mpm/hooks/claude_hooks/services/__pycache__/container.cpython-311.pyc +0 -0
  248. claude_mpm/hooks/claude_hooks/services/__pycache__/protocols.cpython-311.pyc +0 -0
  249. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  250. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  251. claude_mpm/hooks/claude_hooks/services/connection_manager.py +41 -26
  252. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
  253. claude_mpm/hooks/claude_hooks/services/container.py +310 -0
  254. claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
  255. claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
  256. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
  257. claude_mpm/hooks/session_resume_hook.py +89 -1
  258. claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
  259. claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
  260. claude_mpm/init.py +215 -2
  261. claude_mpm/scripts/claude-hook-handler.sh +46 -19
  262. claude_mpm/scripts/start_activity_logging.py +0 -0
  263. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  264. claude_mpm/services/agents/agent_selection_service.py +2 -2
  265. claude_mpm/services/agents/cache_git_manager.py +1 -1
  266. claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -1
  267. claude_mpm/services/agents/deployment/agent_format_converter.py +8 -6
  268. claude_mpm/services/agents/deployment/agent_template_builder.py +14 -4
  269. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  270. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +4 -4
  271. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +4 -1
  272. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  273. claude_mpm/services/agents/git_source_manager.py +6 -2
  274. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  275. claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
  276. claude_mpm/services/agents/sources/git_source_sync_service.py +10 -5
  277. claude_mpm/services/agents/startup_sync.py +5 -2
  278. claude_mpm/services/cli/__init__.py +3 -0
  279. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  280. claude_mpm/services/cli/session_resume_helper.py +10 -2
  281. claude_mpm/services/command_deployment_service.py +44 -26
  282. claude_mpm/services/delegation_detector.py +175 -0
  283. claude_mpm/services/diagnostics/checks/agent_sources_check.py +30 -0
  284. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  285. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  286. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  287. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  288. claude_mpm/services/diagnostics/models.py +14 -1
  289. claude_mpm/services/event_log.py +325 -0
  290. claude_mpm/services/hook_installer_service.py +77 -8
  291. claude_mpm/services/infrastructure/__init__.py +4 -0
  292. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  293. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  294. claude_mpm/services/monitor/daemon_manager.py +15 -4
  295. claude_mpm/services/monitor/management/lifecycle.py +8 -3
  296. claude_mpm/services/monitor/server.py +106 -16
  297. claude_mpm/services/pm_skills_deployer.py +267 -94
  298. claude_mpm/services/profile_manager.py +10 -4
  299. claude_mpm/services/skills/git_skill_source_manager.py +192 -29
  300. claude_mpm/services/skills/selective_skill_deployer.py +211 -46
  301. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  302. claude_mpm/services/skills_deployer.py +188 -67
  303. claude_mpm/services/socketio/handlers/hook.py +14 -7
  304. claude_mpm/services/socketio/server/main.py +12 -4
  305. claude_mpm/skills/__init__.py +2 -1
  306. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  307. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  308. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  309. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  310. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  311. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  312. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  313. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  314. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  315. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  316. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  317. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  318. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  319. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  320. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  321. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  322. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  323. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  324. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  325. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  326. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  327. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  328. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  329. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  330. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  331. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  332. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  333. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  334. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  335. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  336. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  337. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  338. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  339. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  340. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  341. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  342. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  343. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  344. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  345. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  346. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  347. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  348. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  349. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  350. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  351. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  352. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  353. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  354. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  355. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  356. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  357. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  358. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  359. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  360. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  361. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  362. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  363. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  364. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  365. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  366. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  367. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  368. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  369. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  370. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  371. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  372. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  373. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  374. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  375. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  376. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  377. claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
  378. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  379. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  380. claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
  381. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  382. claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
  383. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  384. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  385. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  386. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  387. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  388. claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
  389. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  390. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  391. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  392. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  393. claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
  394. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  395. claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
  396. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  397. claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
  398. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  399. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  400. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  401. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  402. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  403. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  404. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  405. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  406. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  407. claude_mpm/skills/bundled/security-scanning.md +112 -0
  408. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  409. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  410. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  411. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  412. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  413. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  414. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  415. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  416. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  417. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  418. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  419. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  420. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  421. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  422. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  423. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  424. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  425. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  426. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  427. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  428. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  429. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  430. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  431. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  432. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  433. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  434. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  435. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  436. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  437. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  438. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  439. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  440. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  441. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  442. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  443. claude_mpm/skills/registry.py +295 -90
  444. claude_mpm/skills/skill_manager.py +29 -23
  445. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  446. claude_mpm/utils/agent_dependency_loader.py +103 -4
  447. claude_mpm/utils/robust_installer.py +45 -24
  448. claude_mpm-5.6.34.dist-info/METADATA +393 -0
  449. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/RECORD +453 -151
  450. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
  451. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
  452. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
  453. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
  454. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +0 -1
  455. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
  456. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
  457. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
  458. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
  459. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
  460. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  461. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  462. claude_mpm-5.4.48.dist-info/METADATA +0 -999
  463. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/WHEEL +0 -0
  464. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/entry_points.txt +0 -0
  465. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE +0 -0
  466. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  467. {claude_mpm-5.4.48.dist-info → claude_mpm-5.6.34.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,310 @@
1
+ """Dependency Injection container for hook handler services.
2
+
3
+ This module provides a DI container that manages service instantiation,
4
+ lazy initialization, and service overriding for testing.
5
+
6
+ WHY DI Container:
7
+ - Centralized service management
8
+ - Lazy initialization reduces startup overhead
9
+ - Easy testing through service overriding
10
+ - Clear dependency graph
11
+ - Thread-safe singleton pattern
12
+ """
13
+
14
+ import threading
15
+ from typing import Any, Optional, TypeVar
16
+
17
+ # Import service protocols for type hints
18
+ from .protocols import (
19
+ IAutoPauseHandler,
20
+ IConnectionManager,
21
+ IDuplicateDetector,
22
+ IEventHandlers,
23
+ IMemoryHookManager,
24
+ IResponseTrackingManager,
25
+ IStateManager,
26
+ ISubagentProcessor,
27
+ )
28
+
29
+ T = TypeVar("T")
30
+
31
+
32
+ class HookServiceContainer:
33
+ """Dependency injection container for hook handler services.
34
+
35
+ Features:
36
+ - Lazy initialization of services
37
+ - Thread-safe singleton pattern
38
+ - Service overriding for testing
39
+ - Automatic dependency resolution
40
+
41
+ Usage:
42
+ # Normal usage (services created lazily)
43
+ container = HookServiceContainer()
44
+ state_manager = container.get_state_manager()
45
+
46
+ # Testing usage (override services)
47
+ container = HookServiceContainer()
48
+ container.override_state_manager(mock_state_manager)
49
+ state_manager = container.get_state_manager() # Returns mock
50
+
51
+ # Reset overrides
52
+ container.reset_overrides()
53
+ """
54
+
55
+ # Thread-safe singleton
56
+ _instance: Optional["HookServiceContainer"] = None
57
+ _lock = threading.Lock()
58
+
59
+ def __new__(cls) -> "HookServiceContainer":
60
+ """Thread-safe singleton pattern."""
61
+ if cls._instance is None:
62
+ with cls._lock:
63
+ # Double-check locking pattern
64
+ if cls._instance is None:
65
+ cls._instance = super().__new__(cls)
66
+ cls._instance._initialized = False
67
+ return cls._instance
68
+
69
+ def __init__(self) -> None:
70
+ """Initialize container if not already initialized."""
71
+ if getattr(self, "_initialized", False):
72
+ return
73
+
74
+ # Service instances (lazily initialized)
75
+ self._state_manager: Optional[IStateManager] = None
76
+ self._connection_manager: Optional[IConnectionManager] = None
77
+ self._duplicate_detector: Optional[IDuplicateDetector] = None
78
+ self._response_tracking_manager: Optional[IResponseTrackingManager] = None
79
+ self._memory_hook_manager: Optional[IMemoryHookManager] = None
80
+ self._subagent_processor: Optional[ISubagentProcessor] = None
81
+ self._auto_pause_handler: Optional[IAutoPauseHandler] = None
82
+ self._event_handlers: Optional[IEventHandlers] = None
83
+
84
+ # Override factories for testing
85
+ self._overrides: dict[str, Any] = {}
86
+
87
+ # Lock for lazy initialization
88
+ self._init_lock = threading.Lock()
89
+
90
+ self._initialized = True
91
+
92
+ # =========================================================================
93
+ # Lazy Service Getters
94
+ # =========================================================================
95
+
96
+ def get_state_manager(self) -> IStateManager:
97
+ """Get or create StateManagerService instance."""
98
+ if "state_manager" in self._overrides:
99
+ return self._overrides["state_manager"]
100
+
101
+ if self._state_manager is None:
102
+ with self._init_lock:
103
+ if self._state_manager is None:
104
+ from .state_manager import StateManagerService
105
+
106
+ self._state_manager = StateManagerService()
107
+ return self._state_manager
108
+
109
+ def get_connection_manager(self) -> IConnectionManager:
110
+ """Get or create ConnectionManagerService instance."""
111
+ if "connection_manager" in self._overrides:
112
+ return self._overrides["connection_manager"]
113
+
114
+ if self._connection_manager is None:
115
+ with self._init_lock:
116
+ if self._connection_manager is None:
117
+ from .connection_manager_http import ConnectionManagerService
118
+
119
+ self._connection_manager = ConnectionManagerService()
120
+ return self._connection_manager
121
+
122
+ def get_duplicate_detector(self) -> IDuplicateDetector:
123
+ """Get or create DuplicateEventDetector instance."""
124
+ if "duplicate_detector" in self._overrides:
125
+ return self._overrides["duplicate_detector"]
126
+
127
+ if self._duplicate_detector is None:
128
+ with self._init_lock:
129
+ if self._duplicate_detector is None:
130
+ from .duplicate_detector import DuplicateEventDetector
131
+
132
+ self._duplicate_detector = DuplicateEventDetector()
133
+ return self._duplicate_detector
134
+
135
+ def get_response_tracking_manager(self) -> IResponseTrackingManager:
136
+ """Get or create ResponseTrackingManager instance."""
137
+ if "response_tracking_manager" in self._overrides:
138
+ return self._overrides["response_tracking_manager"]
139
+
140
+ if self._response_tracking_manager is None:
141
+ with self._init_lock:
142
+ if self._response_tracking_manager is None:
143
+ from ..response_tracking import ResponseTrackingManager
144
+
145
+ self._response_tracking_manager = ResponseTrackingManager()
146
+ return self._response_tracking_manager
147
+
148
+ def get_memory_hook_manager(self) -> IMemoryHookManager:
149
+ """Get or create MemoryHookManager instance."""
150
+ if "memory_hook_manager" in self._overrides:
151
+ return self._overrides["memory_hook_manager"]
152
+
153
+ if self._memory_hook_manager is None:
154
+ with self._init_lock:
155
+ if self._memory_hook_manager is None:
156
+ from ..memory_integration import MemoryHookManager
157
+
158
+ self._memory_hook_manager = MemoryHookManager()
159
+ return self._memory_hook_manager
160
+
161
+ def get_auto_pause_handler(self) -> Optional[IAutoPauseHandler]:
162
+ """Get or create AutoPauseHandler instance.
163
+
164
+ Returns None if initialization fails (auto-pause is optional).
165
+ """
166
+ if "auto_pause_handler" in self._overrides:
167
+ return self._overrides["auto_pause_handler"]
168
+
169
+ if self._auto_pause_handler is None:
170
+ with self._init_lock:
171
+ if self._auto_pause_handler is None:
172
+ try:
173
+ from ..auto_pause_handler import AutoPauseHandler
174
+
175
+ self._auto_pause_handler = AutoPauseHandler()
176
+ except Exception:
177
+ # Auto-pause is optional
178
+ self._auto_pause_handler = None
179
+ return self._auto_pause_handler
180
+
181
+ def get_subagent_processor(
182
+ self,
183
+ state_manager: Optional[IStateManager] = None,
184
+ response_tracking_manager: Optional[IResponseTrackingManager] = None,
185
+ connection_manager: Optional[IConnectionManager] = None,
186
+ ) -> ISubagentProcessor:
187
+ """Get or create SubagentResponseProcessor instance.
188
+
189
+ Args:
190
+ state_manager: Optional override for state manager
191
+ response_tracking_manager: Optional override for response tracking
192
+ connection_manager: Optional override for connection manager
193
+ """
194
+ if "subagent_processor" in self._overrides:
195
+ return self._overrides["subagent_processor"]
196
+
197
+ if self._subagent_processor is None:
198
+ with self._init_lock:
199
+ if self._subagent_processor is None:
200
+ from .subagent_processor import SubagentResponseProcessor
201
+
202
+ # Use provided dependencies or get from container
203
+ sm = state_manager or self.get_state_manager()
204
+ rtm = (
205
+ response_tracking_manager
206
+ or self.get_response_tracking_manager()
207
+ )
208
+ cm = connection_manager or self.get_connection_manager()
209
+
210
+ self._subagent_processor = SubagentResponseProcessor(sm, rtm, cm)
211
+ return self._subagent_processor
212
+
213
+ def get_event_handlers(self, hook_handler: Any = None) -> IEventHandlers:
214
+ """Get or create EventHandlers instance.
215
+
216
+ Args:
217
+ hook_handler: The ClaudeHookHandler instance for backward compatibility.
218
+ In the future, this will be replaced with proper DI.
219
+ """
220
+ if "event_handlers" in self._overrides:
221
+ return self._overrides["event_handlers"]
222
+
223
+ if self._event_handlers is None:
224
+ with self._init_lock:
225
+ if self._event_handlers is None:
226
+ from ..event_handlers import EventHandlers
227
+
228
+ if hook_handler is None:
229
+ raise ValueError(
230
+ "hook_handler is required to create EventHandlers"
231
+ )
232
+ self._event_handlers = EventHandlers(hook_handler)
233
+ return self._event_handlers
234
+
235
+ # =========================================================================
236
+ # Service Override Methods (for testing)
237
+ # =========================================================================
238
+
239
+ def override_state_manager(self, service: IStateManager) -> None:
240
+ """Override state manager with a mock or custom implementation."""
241
+ self._overrides["state_manager"] = service
242
+
243
+ def override_connection_manager(self, service: IConnectionManager) -> None:
244
+ """Override connection manager with a mock or custom implementation."""
245
+ self._overrides["connection_manager"] = service
246
+
247
+ def override_duplicate_detector(self, service: IDuplicateDetector) -> None:
248
+ """Override duplicate detector with a mock or custom implementation."""
249
+ self._overrides["duplicate_detector"] = service
250
+
251
+ def override_response_tracking_manager(
252
+ self, service: IResponseTrackingManager
253
+ ) -> None:
254
+ """Override response tracking manager with a mock or custom implementation."""
255
+ self._overrides["response_tracking_manager"] = service
256
+
257
+ def override_memory_hook_manager(self, service: IMemoryHookManager) -> None:
258
+ """Override memory hook manager with a mock or custom implementation."""
259
+ self._overrides["memory_hook_manager"] = service
260
+
261
+ def override_subagent_processor(self, service: ISubagentProcessor) -> None:
262
+ """Override subagent processor with a mock or custom implementation."""
263
+ self._overrides["subagent_processor"] = service
264
+
265
+ def override_auto_pause_handler(self, service: Optional[IAutoPauseHandler]) -> None:
266
+ """Override auto-pause handler with a mock or custom implementation."""
267
+ self._overrides["auto_pause_handler"] = service
268
+
269
+ def override_event_handlers(self, service: IEventHandlers) -> None:
270
+ """Override event handlers with a mock or custom implementation."""
271
+ self._overrides["event_handlers"] = service
272
+
273
+ def reset_overrides(self) -> None:
274
+ """Reset all service overrides."""
275
+ self._overrides.clear()
276
+
277
+ def reset_all(self) -> None:
278
+ """Reset all services and overrides.
279
+
280
+ Useful for testing to ensure clean state between tests.
281
+ """
282
+ self._state_manager = None
283
+ self._connection_manager = None
284
+ self._duplicate_detector = None
285
+ self._response_tracking_manager = None
286
+ self._memory_hook_manager = None
287
+ self._subagent_processor = None
288
+ self._auto_pause_handler = None
289
+ self._event_handlers = None
290
+ self._overrides.clear()
291
+
292
+ @classmethod
293
+ def reset_singleton(cls) -> None:
294
+ """Reset the singleton instance.
295
+
296
+ USE WITH CAUTION: This is primarily for testing.
297
+ """
298
+ with cls._lock:
299
+ if cls._instance is not None:
300
+ cls._instance.reset_all()
301
+ cls._instance = None
302
+
303
+
304
+ def get_container() -> HookServiceContainer:
305
+ """Get the global HookServiceContainer singleton.
306
+
307
+ Returns:
308
+ The singleton HookServiceContainer instance.
309
+ """
310
+ return HookServiceContainer()
@@ -0,0 +1,328 @@
1
+ """Protocol definitions for hook handler services.
2
+
3
+ This module defines Protocol classes for all hook handler services,
4
+ enabling type-safe dependency injection and easy testing through
5
+ protocol-based duck typing.
6
+
7
+ WHY Protocol-based DI:
8
+ - Enables loose coupling between components
9
+ - Allows easy mocking in tests without monkey-patching
10
+ - Provides clear interface contracts
11
+ - Supports static type checking with mypy
12
+ """
13
+
14
+ from typing import Any, Callable, Optional, Protocol, runtime_checkable
15
+
16
+
17
+ @runtime_checkable
18
+ class IStateManager(Protocol):
19
+ """Protocol for state management service.
20
+
21
+ Manages:
22
+ - Agent delegation tracking
23
+ - Git branch caching
24
+ - Session state management
25
+ - Cleanup of old entries
26
+ """
27
+
28
+ active_delegations: dict
29
+ delegation_history: Any # deque
30
+ delegation_requests: dict
31
+ pending_prompts: dict
32
+ events_processed: int
33
+
34
+ def track_delegation(
35
+ self, session_id: str, agent_type: str, request_data: Optional[dict] = None
36
+ ) -> None:
37
+ """Track a new agent delegation with optional request data."""
38
+ ...
39
+
40
+ def get_delegation_agent_type(self, session_id: str) -> str:
41
+ """Get the agent type for a session's active delegation."""
42
+ ...
43
+
44
+ def cleanup_old_entries(self) -> None:
45
+ """Clean up old entries to prevent memory growth."""
46
+ ...
47
+
48
+ def get_git_branch(self, working_dir: Optional[str] = None) -> str:
49
+ """Get git branch for the given directory with caching."""
50
+ ...
51
+
52
+ def find_matching_request(self, session_id: str) -> Optional[dict]:
53
+ """Find matching request data for a session, with fuzzy matching fallback."""
54
+ ...
55
+
56
+ def remove_request(self, session_id: str) -> None:
57
+ """Remove request data for a session."""
58
+ ...
59
+
60
+ def increment_events_processed(self) -> bool:
61
+ """Increment events processed counter and return True if cleanup is needed."""
62
+ ...
63
+
64
+
65
+ @runtime_checkable
66
+ class IConnectionManager(Protocol):
67
+ """Protocol for connection management service.
68
+
69
+ Handles:
70
+ - HTTP-based event emission to dashboard
71
+ - Event queuing and batching
72
+ - Connection state management
73
+ """
74
+
75
+ def emit_event(self, namespace: str, event: str, data: dict) -> None:
76
+ """Emit an event through HTTP to the dashboard."""
77
+ ...
78
+
79
+ def cleanup(self) -> None:
80
+ """Clean up any resources."""
81
+ ...
82
+
83
+
84
+ @runtime_checkable
85
+ class IDuplicateDetector(Protocol):
86
+ """Protocol for duplicate event detection service.
87
+
88
+ Detects:
89
+ - Duplicate events within a time window
90
+ - Rapid-fire events that should be deduplicated
91
+ """
92
+
93
+ def is_duplicate(self, event: dict) -> bool:
94
+ """Check if an event is a duplicate of a recent event."""
95
+ ...
96
+
97
+ def generate_event_key(self, event: dict) -> str:
98
+ """Generate a unique key for an event for deduplication."""
99
+ ...
100
+
101
+
102
+ @runtime_checkable
103
+ class IResponseTrackingManager(Protocol):
104
+ """Protocol for response tracking management.
105
+
106
+ Manages:
107
+ - Response tracking enablement
108
+ - Comprehensive response logging
109
+ - Agent response correlation
110
+ """
111
+
112
+ response_tracking_enabled: bool
113
+ response_tracker: Optional[Any]
114
+ track_all_interactions: bool
115
+ auto_pause_handler: Optional[Any]
116
+
117
+ def track_agent_response(
118
+ self,
119
+ session_id: str,
120
+ agent_type: str,
121
+ event: dict,
122
+ delegation_requests: dict,
123
+ ) -> None:
124
+ """Track an agent response for logging."""
125
+ ...
126
+
127
+ def track_stop_response(
128
+ self,
129
+ event: dict,
130
+ session_id: str,
131
+ metadata: dict,
132
+ pending_prompts: dict,
133
+ ) -> None:
134
+ """Track a stop event response."""
135
+ ...
136
+
137
+ def track_assistant_response(
138
+ self,
139
+ event: dict,
140
+ pending_prompts: dict,
141
+ ) -> None:
142
+ """Track an assistant response."""
143
+ ...
144
+
145
+
146
+ @runtime_checkable
147
+ class IMemoryHookManager(Protocol):
148
+ """Protocol for memory hook management.
149
+
150
+ Manages:
151
+ - Pre/post delegation memory hooks
152
+ - Memory field processing
153
+ """
154
+
155
+ def trigger_pre_delegation_hook(
156
+ self, agent_type: str, tool_input: dict, session_id: str
157
+ ) -> None:
158
+ """Trigger memory hooks before delegation."""
159
+ ...
160
+
161
+ def trigger_post_delegation_hook(
162
+ self, agent_type: str, event: dict, session_id: str
163
+ ) -> None:
164
+ """Trigger memory hooks after delegation."""
165
+ ...
166
+
167
+
168
+ @runtime_checkable
169
+ class ISubagentProcessor(Protocol):
170
+ """Protocol for subagent response processing.
171
+
172
+ Handles:
173
+ - SubagentStop event processing
174
+ - Structured response extraction
175
+ - Response tracking and correlation
176
+ """
177
+
178
+ def process_subagent_stop(self, event: dict) -> None:
179
+ """Handle subagent stop events."""
180
+ ...
181
+
182
+
183
+ @runtime_checkable
184
+ class IAutoPauseHandler(Protocol):
185
+ """Protocol for auto-pause functionality.
186
+
187
+ Manages:
188
+ - Session pause tracking
189
+ - Usage threshold monitoring
190
+ - Session state capture
191
+ """
192
+
193
+ def is_pause_active(self) -> bool:
194
+ """Check if auto-pause is currently active."""
195
+ ...
196
+
197
+ def on_user_message(self, message: str) -> None:
198
+ """Record a user message for auto-pause tracking."""
199
+ ...
200
+
201
+ def on_tool_call(self, tool_name: str, tool_input: dict) -> None:
202
+ """Record a tool call for auto-pause tracking."""
203
+ ...
204
+
205
+ def on_assistant_response(self, response: str) -> None:
206
+ """Record an assistant response for auto-pause tracking."""
207
+ ...
208
+
209
+ def on_usage_update(self, usage: dict) -> Optional[str]:
210
+ """Update usage metrics and return threshold crossed if any."""
211
+ ...
212
+
213
+ def emit_threshold_warning(self, threshold: str) -> str:
214
+ """Emit a warning for a crossed threshold."""
215
+ ...
216
+
217
+ def on_session_end(self) -> Optional[Any]:
218
+ """Finalize the current auto-pause session."""
219
+ ...
220
+
221
+
222
+ @runtime_checkable
223
+ class IEventHandlers(Protocol):
224
+ """Protocol for event handler collection.
225
+
226
+ Provides handlers for:
227
+ - UserPromptSubmit
228
+ - PreToolUse
229
+ - PostToolUse
230
+ - Notification
231
+ - Stop
232
+ - SubagentStop
233
+ - SubagentStart
234
+ - SessionStart
235
+ - AssistantResponse
236
+ """
237
+
238
+ def handle_user_prompt_fast(self, event: dict) -> None:
239
+ """Handle user prompt with comprehensive data capture."""
240
+ ...
241
+
242
+ def handle_pre_tool_fast(self, event: dict) -> Optional[dict]:
243
+ """Handle pre-tool use with comprehensive data capture."""
244
+ ...
245
+
246
+ def handle_post_tool_fast(self, event: dict) -> None:
247
+ """Handle post-tool use with comprehensive data capture."""
248
+ ...
249
+
250
+ def handle_notification_fast(self, event: dict) -> None:
251
+ """Handle notification events from Claude."""
252
+ ...
253
+
254
+ def handle_stop_fast(self, event: dict) -> None:
255
+ """Handle stop events when Claude processing stops."""
256
+ ...
257
+
258
+ def handle_subagent_stop_fast(self, event: dict) -> None:
259
+ """Handle subagent stop events."""
260
+ ...
261
+
262
+ def handle_subagent_start_fast(self, event: dict) -> None:
263
+ """Handle SubagentStart events."""
264
+ ...
265
+
266
+ def handle_session_start_fast(self, event: dict) -> None:
267
+ """Handle session start events."""
268
+ ...
269
+
270
+ def handle_assistant_response(self, event: dict) -> None:
271
+ """Handle assistant response events."""
272
+ ...
273
+
274
+
275
+ # Type alias for log function
276
+ LogFunction = Callable[[str], None]
277
+
278
+
279
+ @runtime_checkable
280
+ class ILogManager(Protocol):
281
+ """Protocol for log manager service (optional dependency).
282
+
283
+ Used for logging agent prompts and responses.
284
+ """
285
+
286
+ async def log_prompt(
287
+ self, source: str, content: str, metadata: dict
288
+ ) -> Optional[Any]:
289
+ """Log a prompt to the log manager."""
290
+ ...
291
+
292
+
293
+ @runtime_checkable
294
+ class IDelegationDetector(Protocol):
295
+ """Protocol for delegation pattern detector (optional dependency).
296
+
297
+ Used for detecting delegation anti-patterns in responses.
298
+ """
299
+
300
+ def detect_user_delegation(self, text: str) -> list[dict]:
301
+ """Detect delegation patterns in text."""
302
+ ...
303
+
304
+
305
+ @runtime_checkable
306
+ class IEventLog(Protocol):
307
+ """Protocol for event log service (optional dependency).
308
+
309
+ Used for logging PM violations and other events.
310
+ """
311
+
312
+ def append_event(
313
+ self,
314
+ event_type: str,
315
+ payload: dict,
316
+ status: str = "pending",
317
+ ) -> None:
318
+ """Append an event to the log."""
319
+ ...
320
+
321
+
322
+ @runtime_checkable
323
+ class IConfig(Protocol):
324
+ """Protocol for configuration service (optional dependency)."""
325
+
326
+ def get(self, key: str, default: Any = None) -> Any:
327
+ """Get a configuration value."""
328
+ ...