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

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

Potentially problematic release.


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

Files changed (487) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_AGENT.md +164 -0
  3. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  4. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
  5. claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
  6. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
  7. claude_mpm/agents/MEMORY.md +1 -1
  8. claude_mpm/agents/PM_INSTRUCTIONS.md +374 -1257
  9. claude_mpm/agents/WORKFLOW.md +6 -253
  10. claude_mpm/agents/agent_loader.py +1 -1
  11. claude_mpm/agents/base_agent.json +31 -0
  12. claude_mpm/agents/frontmatter_validator.py +2 -2
  13. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  14. claude_mpm/cli/__init__.py +5 -1
  15. claude_mpm/cli/commands/agent_state_manager.py +10 -10
  16. claude_mpm/cli/commands/agents.py +11 -13
  17. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  18. claude_mpm/cli/commands/auto_configure.py +4 -4
  19. claude_mpm/cli/commands/autotodos.py +566 -0
  20. claude_mpm/cli/commands/commander.py +216 -0
  21. claude_mpm/cli/commands/configure.py +621 -22
  22. claude_mpm/cli/commands/configure_agent_display.py +12 -0
  23. claude_mpm/cli/commands/hook_errors.py +60 -60
  24. claude_mpm/cli/commands/monitor.py +2 -2
  25. claude_mpm/cli/commands/mpm_init/core.py +72 -0
  26. claude_mpm/cli/commands/postmortem.py +1 -1
  27. claude_mpm/cli/commands/profile.py +276 -0
  28. claude_mpm/cli/commands/run.py +35 -3
  29. claude_mpm/cli/commands/skill_source.py +51 -2
  30. claude_mpm/cli/commands/skills.py +182 -32
  31. claude_mpm/cli/executor.py +130 -16
  32. claude_mpm/cli/interactive/__init__.py +10 -0
  33. claude_mpm/cli/interactive/agent_wizard.py +32 -52
  34. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  35. claude_mpm/cli/interactive/skill_selector.py +481 -0
  36. claude_mpm/cli/parsers/base_parser.py +83 -1
  37. claude_mpm/cli/parsers/commander_parser.py +116 -0
  38. claude_mpm/cli/parsers/profile_parser.py +147 -0
  39. claude_mpm/cli/parsers/run_parser.py +10 -0
  40. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  41. claude_mpm/cli/parsers/skills_parser.py +2 -3
  42. claude_mpm/cli/startup.py +690 -386
  43. claude_mpm/cli/startup_display.py +74 -6
  44. claude_mpm/cli/startup_logging.py +2 -2
  45. claude_mpm/cli/utils.py +7 -3
  46. claude_mpm/commander/__init__.py +78 -0
  47. claude_mpm/commander/adapters/__init__.py +60 -0
  48. claude_mpm/commander/adapters/auggie.py +260 -0
  49. claude_mpm/commander/adapters/base.py +288 -0
  50. claude_mpm/commander/adapters/claude_code.py +392 -0
  51. claude_mpm/commander/adapters/codex.py +237 -0
  52. claude_mpm/commander/adapters/communication.py +366 -0
  53. claude_mpm/commander/adapters/example_usage.py +310 -0
  54. claude_mpm/commander/adapters/mpm.py +389 -0
  55. claude_mpm/commander/adapters/registry.py +204 -0
  56. claude_mpm/commander/api/__init__.py +16 -0
  57. claude_mpm/commander/api/app.py +121 -0
  58. claude_mpm/commander/api/errors.py +133 -0
  59. claude_mpm/commander/api/routes/__init__.py +8 -0
  60. claude_mpm/commander/api/routes/events.py +184 -0
  61. claude_mpm/commander/api/routes/inbox.py +171 -0
  62. claude_mpm/commander/api/routes/messages.py +148 -0
  63. claude_mpm/commander/api/routes/projects.py +271 -0
  64. claude_mpm/commander/api/routes/sessions.py +226 -0
  65. claude_mpm/commander/api/routes/work.py +296 -0
  66. claude_mpm/commander/api/schemas.py +186 -0
  67. claude_mpm/commander/chat/__init__.py +7 -0
  68. claude_mpm/commander/chat/cli.py +146 -0
  69. claude_mpm/commander/chat/commands.py +96 -0
  70. claude_mpm/commander/chat/repl.py +310 -0
  71. claude_mpm/commander/config.py +51 -0
  72. claude_mpm/commander/config_loader.py +115 -0
  73. claude_mpm/commander/core/__init__.py +10 -0
  74. claude_mpm/commander/core/block_manager.py +325 -0
  75. claude_mpm/commander/core/response_manager.py +323 -0
  76. claude_mpm/commander/daemon.py +603 -0
  77. claude_mpm/commander/env_loader.py +59 -0
  78. claude_mpm/commander/events/__init__.py +26 -0
  79. claude_mpm/commander/events/manager.py +332 -0
  80. claude_mpm/commander/frameworks/__init__.py +12 -0
  81. claude_mpm/commander/frameworks/base.py +146 -0
  82. claude_mpm/commander/frameworks/claude_code.py +58 -0
  83. claude_mpm/commander/frameworks/mpm.py +62 -0
  84. claude_mpm/commander/inbox/__init__.py +16 -0
  85. claude_mpm/commander/inbox/dedup.py +128 -0
  86. claude_mpm/commander/inbox/inbox.py +224 -0
  87. claude_mpm/commander/inbox/models.py +70 -0
  88. claude_mpm/commander/instance_manager.py +450 -0
  89. claude_mpm/commander/llm/__init__.py +6 -0
  90. claude_mpm/commander/llm/openrouter_client.py +167 -0
  91. claude_mpm/commander/llm/summarizer.py +70 -0
  92. claude_mpm/commander/memory/__init__.py +45 -0
  93. claude_mpm/commander/memory/compression.py +347 -0
  94. claude_mpm/commander/memory/embeddings.py +230 -0
  95. claude_mpm/commander/memory/entities.py +310 -0
  96. claude_mpm/commander/memory/example_usage.py +290 -0
  97. claude_mpm/commander/memory/integration.py +325 -0
  98. claude_mpm/commander/memory/search.py +381 -0
  99. claude_mpm/commander/memory/store.py +657 -0
  100. claude_mpm/commander/models/__init__.py +18 -0
  101. claude_mpm/commander/models/events.py +121 -0
  102. claude_mpm/commander/models/project.py +162 -0
  103. claude_mpm/commander/models/work.py +214 -0
  104. claude_mpm/commander/parsing/__init__.py +20 -0
  105. claude_mpm/commander/parsing/extractor.py +132 -0
  106. claude_mpm/commander/parsing/output_parser.py +270 -0
  107. claude_mpm/commander/parsing/patterns.py +100 -0
  108. claude_mpm/commander/persistence/__init__.py +11 -0
  109. claude_mpm/commander/persistence/event_store.py +274 -0
  110. claude_mpm/commander/persistence/state_store.py +309 -0
  111. claude_mpm/commander/persistence/work_store.py +164 -0
  112. claude_mpm/commander/polling/__init__.py +13 -0
  113. claude_mpm/commander/polling/event_detector.py +104 -0
  114. claude_mpm/commander/polling/output_buffer.py +49 -0
  115. claude_mpm/commander/polling/output_poller.py +153 -0
  116. claude_mpm/commander/project_session.py +268 -0
  117. claude_mpm/commander/proxy/__init__.py +12 -0
  118. claude_mpm/commander/proxy/formatter.py +89 -0
  119. claude_mpm/commander/proxy/output_handler.py +191 -0
  120. claude_mpm/commander/proxy/relay.py +155 -0
  121. claude_mpm/commander/registry.py +410 -0
  122. claude_mpm/commander/runtime/__init__.py +10 -0
  123. claude_mpm/commander/runtime/executor.py +191 -0
  124. claude_mpm/commander/runtime/monitor.py +346 -0
  125. claude_mpm/commander/session/__init__.py +6 -0
  126. claude_mpm/commander/session/context.py +81 -0
  127. claude_mpm/commander/session/manager.py +59 -0
  128. claude_mpm/commander/tmux_orchestrator.py +361 -0
  129. claude_mpm/commander/web/__init__.py +1 -0
  130. claude_mpm/commander/work/__init__.py +30 -0
  131. claude_mpm/commander/work/executor.py +207 -0
  132. claude_mpm/commander/work/queue.py +405 -0
  133. claude_mpm/commander/workflow/__init__.py +27 -0
  134. claude_mpm/commander/workflow/event_handler.py +241 -0
  135. claude_mpm/commander/workflow/notifier.py +146 -0
  136. claude_mpm/commands/mpm-config.md +20 -249
  137. claude_mpm/commands/mpm-doctor.md +16 -21
  138. claude_mpm/commands/mpm-help.md +12 -205
  139. claude_mpm/commands/mpm-init.md +88 -506
  140. claude_mpm/commands/mpm-monitor.md +22 -401
  141. claude_mpm/commands/mpm-organize.md +70 -442
  142. claude_mpm/commands/mpm-postmortem.md +13 -107
  143. claude_mpm/commands/mpm-session-resume.md +20 -363
  144. claude_mpm/commands/mpm-status.md +13 -69
  145. claude_mpm/commands/mpm-ticket-view.md +60 -495
  146. claude_mpm/commands/mpm-version.md +13 -107
  147. claude_mpm/commands/mpm.md +8 -0
  148. claude_mpm/config/agent_presets.py +8 -7
  149. claude_mpm/config/skill_sources.py +16 -0
  150. claude_mpm/constants.py +1 -0
  151. claude_mpm/core/claude_runner.py +154 -2
  152. claude_mpm/core/config.py +37 -26
  153. claude_mpm/core/config_constants.py +74 -9
  154. claude_mpm/core/constants.py +56 -12
  155. claude_mpm/core/framework/loaders/agent_loader.py +1 -1
  156. claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
  157. claude_mpm/core/hook_manager.py +51 -3
  158. claude_mpm/core/interactive_session.py +12 -11
  159. claude_mpm/core/logger.py +26 -9
  160. claude_mpm/core/logging_utils.py +39 -13
  161. claude_mpm/core/network_config.py +148 -0
  162. claude_mpm/core/oneshot_session.py +7 -6
  163. claude_mpm/core/optimized_startup.py +61 -0
  164. claude_mpm/core/output_style_manager.py +66 -18
  165. claude_mpm/core/shared/config_loader.py +3 -1
  166. claude_mpm/core/socketio_pool.py +47 -15
  167. claude_mpm/core/unified_agent_registry.py +1 -1
  168. claude_mpm/core/unified_config.py +54 -8
  169. claude_mpm/core/unified_paths.py +95 -90
  170. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  171. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
  172. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
  173. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
  174. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
  175. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
  176. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
  177. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
  178. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
  179. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
  180. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
  181. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  182. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
  183. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
  184. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
  185. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
  186. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
  187. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
  188. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
  189. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
  190. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
  191. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
  192. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
  193. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
  194. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
  195. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
  196. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
  197. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
  198. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
  199. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
  200. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
  201. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
  202. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  203. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
  204. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  205. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
  206. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
  207. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
  208. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
  209. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
  210. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DR8nis88.js +2 -0
  211. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
  212. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  213. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
  214. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
  215. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
  216. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
  217. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
  218. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
  219. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  220. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
  221. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
  222. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
  223. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
  224. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
  225. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
  226. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
  227. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
  228. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
  229. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
  230. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
  231. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
  232. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.RgBboRvH.js +1 -0
  233. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
  234. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
  235. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  236. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  237. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  238. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  239. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  240. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  241. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  242. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  243. claude_mpm/experimental/cli_enhancements.py +2 -1
  244. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  245. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  246. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  247. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  248. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  249. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  250. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  251. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  252. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  253. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  254. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
  255. claude_mpm/hooks/claude_hooks/event_handlers.py +527 -136
  256. claude_mpm/hooks/claude_hooks/hook_handler.py +313 -99
  257. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  258. claude_mpm/hooks/claude_hooks/installer.py +206 -36
  259. claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
  260. claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
  261. claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
  262. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  263. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  264. claude_mpm/hooks/claude_hooks/services/__pycache__/container.cpython-311.pyc +0 -0
  265. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  266. claude_mpm/hooks/claude_hooks/services/__pycache__/protocols.cpython-311.pyc +0 -0
  267. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  268. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  269. claude_mpm/hooks/claude_hooks/services/connection_manager.py +67 -32
  270. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
  271. claude_mpm/hooks/claude_hooks/services/container.py +310 -0
  272. claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
  273. claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
  274. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
  275. claude_mpm/hooks/kuzu_memory_hook.py +5 -5
  276. claude_mpm/hooks/session_resume_hook.py +89 -1
  277. claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
  278. claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
  279. claude_mpm/init.py +276 -0
  280. claude_mpm/models/git_repository.py +3 -3
  281. claude_mpm/scripts/claude-hook-handler.sh +46 -19
  282. claude_mpm/services/agents/agent_builder.py +3 -3
  283. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  284. claude_mpm/services/agents/agent_selection_service.py +2 -2
  285. claude_mpm/services/agents/cache_git_manager.py +7 -7
  286. claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
  287. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -2
  288. claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
  289. claude_mpm/services/agents/deployment/agent_template_builder.py +39 -19
  290. claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
  291. claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
  292. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  293. claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
  294. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +169 -26
  295. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +101 -75
  296. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  297. claude_mpm/services/agents/git_source_manager.py +23 -4
  298. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  299. claude_mpm/services/agents/recommender.py +5 -3
  300. claude_mpm/services/agents/single_tier_deployment_service.py +6 -6
  301. claude_mpm/services/agents/sources/git_source_sync_service.py +121 -10
  302. claude_mpm/services/agents/startup_sync.py +27 -4
  303. claude_mpm/services/cli/__init__.py +3 -0
  304. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  305. claude_mpm/services/cli/session_resume_helper.py +10 -2
  306. claude_mpm/services/command_deployment_service.py +44 -26
  307. claude_mpm/services/delegation_detector.py +175 -0
  308. claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
  309. claude_mpm/services/diagnostics/checks/agent_sources_check.py +31 -1
  310. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  311. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  312. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  313. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  314. claude_mpm/services/diagnostics/models.py +14 -1
  315. claude_mpm/services/event_log.py +325 -0
  316. claude_mpm/services/git/git_operations_service.py +8 -8
  317. claude_mpm/services/hook_installer_service.py +77 -8
  318. claude_mpm/services/infrastructure/__init__.py +4 -0
  319. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  320. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  321. claude_mpm/services/monitor/daemon_manager.py +15 -4
  322. claude_mpm/services/monitor/management/lifecycle.py +15 -3
  323. claude_mpm/services/monitor/server.py +571 -11
  324. claude_mpm/services/pm_skills_deployer.py +884 -0
  325. claude_mpm/services/profile_manager.py +337 -0
  326. claude_mpm/services/skills/git_skill_source_manager.py +281 -20
  327. claude_mpm/services/skills/selective_skill_deployer.py +211 -46
  328. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  329. claude_mpm/services/skills_deployer.py +192 -70
  330. claude_mpm/services/socketio/dashboard_server.py +1 -0
  331. claude_mpm/services/socketio/event_normalizer.py +37 -6
  332. claude_mpm/services/socketio/handlers/hook.py +14 -7
  333. claude_mpm/services/socketio/server/core.py +262 -123
  334. claude_mpm/services/socketio/server/main.py +12 -4
  335. claude_mpm/skills/__init__.py +2 -1
  336. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  337. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  338. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  339. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  340. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  341. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  342. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  343. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  344. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  345. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  346. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  347. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  348. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  349. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  350. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  351. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  352. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  353. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  354. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  355. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  356. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  357. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  358. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  359. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  360. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  361. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  362. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  363. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  364. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  365. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  366. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  367. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  368. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  369. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  370. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  371. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  372. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  373. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  374. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  375. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  376. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  377. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  378. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  379. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  380. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  381. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  382. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  383. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  384. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  385. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  386. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  387. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  388. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  389. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  390. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  391. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  392. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  393. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  394. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  395. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  396. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  397. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  398. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  399. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  400. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  401. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  402. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  403. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  404. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  405. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  406. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  407. claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
  408. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  409. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  410. claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
  411. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  412. claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
  413. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  414. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  415. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  416. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  417. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  418. claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
  419. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  420. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  421. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  422. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  423. claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
  424. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  425. claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
  426. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  427. claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
  428. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  429. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  430. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  431. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  432. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  433. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  434. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  435. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  436. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  437. claude_mpm/skills/bundled/security-scanning.md +112 -0
  438. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  439. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  440. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  441. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  442. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  443. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  444. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  445. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  446. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  447. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  448. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  449. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  450. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  451. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  452. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  453. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  454. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  455. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  456. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  457. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  458. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  459. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  460. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  461. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  462. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  463. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  464. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  465. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  466. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  467. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  468. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  469. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  470. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  471. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  472. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  473. claude_mpm/skills/registry.py +295 -90
  474. claude_mpm/skills/skill_manager.py +98 -3
  475. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  476. claude_mpm/utils/agent_dependency_loader.py +115 -4
  477. claude_mpm/utils/agent_filters.py +1 -1
  478. claude_mpm/utils/migration.py +4 -4
  479. claude_mpm/utils/robust_installer.py +86 -21
  480. claude_mpm-5.6.34.dist-info/METADATA +393 -0
  481. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/RECORD +486 -145
  482. claude_mpm-5.4.22.dist-info/METADATA +0 -996
  483. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/WHEEL +0 -0
  484. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/entry_points.txt +0 -0
  485. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE +0 -0
  486. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  487. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/top_level.txt +0 -0
@@ -44,11 +44,14 @@ class ConfigConstants:
44
44
  "startup": 60,
45
45
  "graceful_shutdown": 30,
46
46
  },
47
- # Ports
47
+ # Ports (updated to use network_config.NetworkPorts defaults)
48
48
  "ports": {
49
- "socketio_default": 8765,
50
- "socketio_range_start": 8765,
51
- "socketio_range_end": 8775,
49
+ "monitor_default": 8765, # NetworkPorts.MONITOR_DEFAULT
50
+ "commander_default": 8766, # NetworkPorts.COMMANDER_DEFAULT
51
+ "dashboard_default": 8767, # NetworkPorts.DASHBOARD_DEFAULT
52
+ "socketio_default": 8768, # NetworkPorts.SOCKETIO_DEFAULT
53
+ "socketio_range_start": 8765, # NetworkPorts.PORT_RANGE_START
54
+ "socketio_range_end": 8785, # NetworkPorts.PORT_RANGE_END
52
55
  },
53
56
  # Cache settings
54
57
  "cache": {
@@ -134,23 +137,70 @@ class ConfigConstants:
134
137
  Get port value by type.
135
138
 
136
139
  Args:
137
- port_type: Type of port (e.g., 'socketio_default')
140
+ port_type: Type of port (e.g., 'socketio_default', 'monitor_default')
138
141
 
139
142
  Returns:
140
143
  Port number
141
144
  """
142
145
  try:
146
+ # Try to get from unified config first
143
147
  config = cls._get_config_service().config
144
148
 
149
+ if port_type == "monitor_default":
150
+ return (
151
+ config.network.monitor_port
152
+ if hasattr(config.network, "monitor_port")
153
+ else 8765
154
+ )
155
+ if port_type == "commander_default":
156
+ return (
157
+ config.network.commander_port
158
+ if hasattr(config.network, "commander_port")
159
+ else 8766
160
+ )
161
+ if port_type == "dashboard_default":
162
+ return (
163
+ config.network.dashboard_port
164
+ if hasattr(config.network, "dashboard_port")
165
+ else 8767
166
+ )
145
167
  if port_type == "socketio_default":
146
- return config.network.socketio_port
168
+ return (
169
+ config.network.socketio_port
170
+ if hasattr(config.network, "socketio_port")
171
+ else 8768
172
+ )
147
173
  if port_type == "socketio_range_start":
148
- return config.network.socketio_port_range[0]
174
+ return (
175
+ config.network.socketio_port_range[0]
176
+ if hasattr(config.network, "socketio_port_range")
177
+ else 8765
178
+ )
149
179
  if port_type == "socketio_range_end":
150
- return config.network.socketio_port_range[1]
180
+ return (
181
+ config.network.socketio_port_range[1]
182
+ if hasattr(config.network, "socketio_port_range")
183
+ else 8785
184
+ )
151
185
  return cls.DEFAULT_VALUES["ports"].get(port_type, 8765)
152
186
  except Exception:
153
- return cls.DEFAULT_VALUES["ports"].get(port_type, 8765)
187
+ # Fallback to network_config.NetworkPorts or DEFAULT_VALUES
188
+ try:
189
+ from .network_config import NetworkPorts
190
+
191
+ port_map = {
192
+ "monitor_default": NetworkPorts.MONITOR_DEFAULT,
193
+ "commander_default": NetworkPorts.COMMANDER_DEFAULT,
194
+ "dashboard_default": NetworkPorts.DASHBOARD_DEFAULT,
195
+ "socketio_default": NetworkPorts.SOCKETIO_DEFAULT,
196
+ "socketio_range_start": NetworkPorts.PORT_RANGE_START,
197
+ "socketio_range_end": NetworkPorts.PORT_RANGE_END,
198
+ }
199
+ return port_map.get(
200
+ port_type, cls.DEFAULT_VALUES["ports"].get(port_type, 8765)
201
+ )
202
+ except Exception:
203
+ return cls.DEFAULT_VALUES["ports"].get(port_type, 8765)
154
204
 
155
205
  @classmethod
156
206
  def get_cache_setting(cls, setting_name: str) -> Any:
@@ -304,6 +354,21 @@ def get_socketio_port() -> int:
304
354
  return ConfigConstants.get_port("socketio_default")
305
355
 
306
356
 
357
+ def get_monitor_port() -> int:
358
+ """Get default monitor port."""
359
+ return ConfigConstants.get_port("monitor_default")
360
+
361
+
362
+ def get_commander_port() -> int:
363
+ """Get default commander port."""
364
+ return ConfigConstants.get_port("commander_default")
365
+
366
+
367
+ def get_dashboard_port() -> int:
368
+ """Get default dashboard port."""
369
+ return ConfigConstants.get_port("dashboard_default")
370
+
371
+
307
372
  def get_cache_size() -> float:
308
373
  """Get default cache size in MB."""
309
374
  return ConfigConstants.get_cache_setting("max_size_mb")
@@ -38,12 +38,36 @@ class SystemLimits:
38
38
 
39
39
 
40
40
  class NetworkConfig:
41
- """Network-related configuration constants."""
41
+ """Network-related configuration constants.
42
42
 
43
- # Port ranges
44
- SOCKETIO_PORT_RANGE: Tuple[int, int] = (8765, 8785)
45
- DEFAULT_SOCKETIO_PORT = 8765
46
- DEFAULT_DASHBOARD_PORT = 8765
43
+ NOTE: Port defaults are now centralized in network_config.NetworkPorts.
44
+ This class maintains backward compatibility but delegates to NetworkPorts.
45
+ """
46
+
47
+ # Import from network_config for single source of truth
48
+ # Lazy import to avoid circular dependencies
49
+ @property
50
+ def SOCKETIO_PORT_RANGE(self) -> Tuple[int, int]:
51
+ from .network_config import NetworkPorts
52
+
53
+ return (NetworkPorts.PORT_RANGE_START, NetworkPorts.PORT_RANGE_END)
54
+
55
+ @property
56
+ def DEFAULT_SOCKETIO_PORT(self) -> int:
57
+ from .network_config import NetworkPorts
58
+
59
+ return NetworkPorts.SOCKETIO_DEFAULT
60
+
61
+ @property
62
+ def DEFAULT_DASHBOARD_PORT(self) -> int:
63
+ from .network_config import NetworkPorts
64
+
65
+ return NetworkPorts.DASHBOARD_DEFAULT
66
+
67
+ # Port ranges (module-level for backward compatibility)
68
+ SOCKETIO_PORT_RANGE: Tuple[int, int] = (8765, 8785) # Will be updated at runtime
69
+ DEFAULT_SOCKETIO_PORT = 8768 # Updated to match new default
70
+ DEFAULT_DASHBOARD_PORT = 8767 # Updated to match new default
47
71
 
48
72
  # Connection timeouts (seconds)
49
73
  CONNECTION_TIMEOUT = 5.0
@@ -303,18 +327,38 @@ DEFAULT_TIMEOUT = TimeoutConfig.DEFAULT_TIMEOUT
303
327
 
304
328
 
305
329
  class NetworkPorts:
306
- """Network port configuration."""
330
+ """Network port configuration.
331
+
332
+ DEPRECATED: Use claude_mpm.core.network_config.NetworkPorts instead.
333
+ This class is maintained for backward compatibility.
334
+ """
335
+
336
+ # Import from network_config for single source of truth
337
+ @classmethod
338
+ def _get_config(cls):
339
+ from .network_config import NetworkPorts as NewNetworkPorts
340
+
341
+ return NewNetworkPorts
342
+
343
+ # Delegate to new NetworkPorts
344
+ @property
345
+ def DEFAULT_SOCKETIO(self) -> int:
346
+ return self._get_config().SOCKETIO_DEFAULT
347
+
348
+ @property
349
+ def DEFAULT_DASHBOARD(self) -> int:
350
+ return self._get_config().DASHBOARD_DEFAULT
307
351
 
308
- # Use existing values from NetworkConfig
309
- DEFAULT_SOCKETIO = NetworkConfig.DEFAULT_SOCKETIO_PORT
310
- DEFAULT_DASHBOARD = NetworkConfig.DEFAULT_DASHBOARD_PORT
311
- PORT_RANGE_START = NetworkConfig.SOCKETIO_PORT_RANGE[0]
312
- PORT_RANGE_END = NetworkConfig.SOCKETIO_PORT_RANGE[1]
352
+ # Keep class-level attributes for compatibility
353
+ DEFAULT_SOCKETIO = 8768 # Updated to match network_config
354
+ DEFAULT_DASHBOARD = 8767 # Updated to match network_config
355
+ PORT_RANGE_START = 8765
356
+ PORT_RANGE_END = 8785
313
357
 
314
358
  @classmethod
315
359
  def get_port_range(cls) -> range:
316
360
  """Get the valid port range."""
317
- return range(cls.PORT_RANGE_START, cls.PORT_RANGE_END + 1)
361
+ return cls._get_config().get_port_range()
318
362
 
319
363
 
320
364
  class ProjectPaths:
@@ -118,7 +118,7 @@ class AgentLoader:
118
118
  """Discover local JSON agent templates.
119
119
 
120
120
  NOTE: This method is kept for backward compatibility but is deprecated.
121
- The new architecture uses SOURCE (~/.claude-mpm/cache/remote-agents/)
121
+ The new architecture uses SOURCE (~/.claude-mpm/cache/agents/)
122
122
  and DEPLOYMENT (.claude/agents/) locations only.
123
123
 
124
124
  Returns:
@@ -88,39 +88,80 @@ class InstructionLoader:
88
88
  self.packaged_loader.framework_last_modified
89
89
  )
90
90
 
91
+ def _extract_version(self, file_content: str) -> int:
92
+ """Extract version number from PM_INSTRUCTIONS_VERSION comment.
93
+
94
+ Args:
95
+ file_content: Content of the file to extract version from
96
+
97
+ Returns:
98
+ Version number as integer, or 0 if not found
99
+ """
100
+ import re
101
+
102
+ match = re.search(r"PM_INSTRUCTIONS_VERSION:\s*(\d+)", file_content)
103
+ if match:
104
+ return int(match.group(1))
105
+ return 0 # No version = oldest
106
+
91
107
  def _load_filesystem_framework_instructions(self, content: Dict[str, Any]) -> None:
92
108
  """Load framework instructions from filesystem.
93
109
 
94
110
  Priority order:
95
- 1. Deployed compiled file: .claude-mpm/PM_INSTRUCTIONS_DEPLOYED.md (HIGHEST PRIORITY)
111
+ 1. Deployed compiled file: .claude-mpm/PM_INSTRUCTIONS_DEPLOYED.md (if version >= source)
96
112
  2. Source file (development): src/claude_mpm/agents/PM_INSTRUCTIONS.md
97
113
  3. Legacy file (backward compat): src/claude_mpm/agents/INSTRUCTIONS.md
98
114
 
115
+ Version validation ensures deployed file is never stale compared to source.
116
+
99
117
  Args:
100
118
  content: Dictionary to update with framework instructions
101
119
  """
120
+ # Define source path for version checking
121
+ pm_instructions_path = (
122
+ self.framework_path / "src" / "claude_mpm" / "agents" / "PM_INSTRUCTIONS.md"
123
+ )
124
+
102
125
  # PRIORITY 1: Check for compiled/deployed version in .claude-mpm/
103
126
  # This is the merged PM_INSTRUCTIONS.md + WORKFLOW.md + MEMORY.md
104
127
  deployed_path = self.current_dir / ".claude-mpm" / "PM_INSTRUCTIONS_DEPLOYED.md"
105
128
  if deployed_path.exists():
106
- loaded_content = self.file_loader.try_load_file(
107
- deployed_path, "deployed PM_INSTRUCTIONS_DEPLOYED.md"
108
- )
109
- if loaded_content:
110
- content["framework_instructions"] = loaded_content
129
+ # Validate version before using deployed file
130
+ deployed_content = deployed_path.read_text()
131
+ deployed_version = self._extract_version(deployed_content)
132
+
133
+ # Check source version for comparison
134
+ if pm_instructions_path.exists():
135
+ source_content = pm_instructions_path.read_text()
136
+ source_version = self._extract_version(source_content)
137
+
138
+ if deployed_version < source_version:
139
+ self.logger.warning(
140
+ f"Deployed PM instructions v{deployed_version:04d} is stale, "
141
+ f"source is v{source_version:04d}. Using source instead."
142
+ )
143
+ # Fall through to source loading - don't return early
144
+ else:
145
+ # Version OK, use deployed
146
+ content["framework_instructions"] = deployed_content
147
+ content["loaded"] = True
148
+ self.logger.info(
149
+ f"Loaded PM_INSTRUCTIONS_DEPLOYED.md v{deployed_version:04d} from .claude-mpm/"
150
+ )
151
+ return # Stop here - deployed version is current
152
+ else:
153
+ # Source doesn't exist, use deployed even without version check
154
+ content["framework_instructions"] = deployed_content
111
155
  content["loaded"] = True
112
156
  self.logger.info("Loaded PM_INSTRUCTIONS_DEPLOYED.md from .claude-mpm/")
113
- return # Stop here - deployed version takes precedence
157
+ return
114
158
 
115
159
  # PRIORITY 2: Development mode - load from source PM_INSTRUCTIONS.md
116
- pm_instructions_path = (
117
- self.framework_path / "src" / "claude_mpm" / "agents" / "PM_INSTRUCTIONS.md"
118
- )
119
160
  framework_instructions_path = (
120
161
  self.framework_path / "src" / "claude_mpm" / "agents" / "INSTRUCTIONS.md"
121
162
  )
122
163
 
123
- # Try loading new consolidated file
164
+ # Try loading new consolidated file (pm_instructions_path already defined above)
124
165
  if pm_instructions_path.exists():
125
166
  loaded_content = self.file_loader.try_load_file(
126
167
  pm_instructions_path, "source PM_INSTRUCTIONS.md (development mode)"
@@ -16,13 +16,15 @@ import contextlib
16
16
  import json
17
17
  import os
18
18
  import queue
19
- import subprocess
19
+ import subprocess # nosec B404
20
20
  import threading
21
21
  import uuid
22
22
  from datetime import datetime, timezone
23
23
  from typing import Any, Dict, Optional
24
24
 
25
25
  from ..core.logger import get_logger
26
+ from ..services.event_bus.event_bus import EventBus
27
+ from ..services.event_log import get_event_log
26
28
  from .hook_error_memory import get_hook_error_memory
27
29
  from .hook_performance_config import get_hook_performance_config
28
30
  from .unified_paths import get_package_root
@@ -46,6 +48,10 @@ class HookManager:
46
48
  # Initialize error memory for tracking and preventing repeated errors
47
49
  self.error_memory = get_hook_error_memory()
48
50
 
51
+ # Initialize event log and event bus for event-driven architecture
52
+ self.event_log = get_event_log()
53
+ self.event_bus = EventBus.get_instance()
54
+
49
55
  # Initialize background hook processing for async execution
50
56
  self.performance_config = get_hook_performance_config()
51
57
  queue_config = self.performance_config.get_queue_config()
@@ -100,6 +106,45 @@ class HookManager:
100
106
  self.background_thread.start()
101
107
  self.logger.debug("Started background hook processor thread")
102
108
 
109
+ def _publish_error_event(
110
+ self, hook_type: str, error_info: Dict[str, str], suggestion: str
111
+ ):
112
+ """Publish hook error event to event log and event bus.
113
+
114
+ WHY publish events:
115
+ - Decouple error detection from error handling
116
+ - Enable autotodos CLI to read from persistent event log
117
+ - Support real-time notifications via event bus
118
+ - Maintain audit trail of all hook errors
119
+
120
+ Args:
121
+ hook_type: Type of hook that failed
122
+ error_info: Error information from error detection
123
+ suggestion: Fix suggestion from error memory
124
+ """
125
+ try:
126
+ # Prepare event payload
127
+ payload = {
128
+ "error_type": error_info["type"],
129
+ "hook_type": hook_type,
130
+ "details": error_info.get("details", ""),
131
+ "full_message": error_info.get("match", ""),
132
+ "suggested_fix": suggestion,
133
+ "source": "hook_manager",
134
+ }
135
+
136
+ # Publish to event log (persistent storage)
137
+ self.event_log.append_event(
138
+ event_type="autotodo.error", payload=payload, status="pending"
139
+ )
140
+
141
+ # Publish to event bus (real-time listeners)
142
+ self.event_bus.publish("autotodo.error", payload)
143
+
144
+ except Exception as e:
145
+ # Don't let event publishing break hook processing
146
+ self.logger.debug(f"Failed to publish error event: {e}")
147
+
103
148
  def _execute_hook_sync(self, hook_data: Dict[str, Any]):
104
149
  """Execute a single hook synchronously in the background thread with error detection.
105
150
 
@@ -141,7 +186,7 @@ class HookManager:
141
186
  env["CLAUDE_MPM_HOOK_DEBUG"] = "true"
142
187
 
143
188
  # Execute with timeout in background thread
144
- result = subprocess.run(
189
+ result = subprocess.run( # nosec B603 B607
145
190
  ["python", str(self.hook_handler_path)],
146
191
  input=event_json,
147
192
  text=True,
@@ -157,7 +202,7 @@ class HookManager:
157
202
  )
158
203
 
159
204
  if error_info:
160
- # Record the error
205
+ # Record the error in memory (for skipping repeated failures)
161
206
  self.error_memory.record_error(error_info, hook_type)
162
207
 
163
208
  # Get fix suggestion
@@ -165,6 +210,9 @@ class HookManager:
165
210
 
166
211
  # Log error with suggestion
167
212
  self.logger.warning(f"Hook {hook_type} error detected:\n{suggestion}")
213
+
214
+ # Publish event to event log for autotodos processing
215
+ self._publish_error_event(hook_type, error_info, suggestion)
168
216
  elif result.returncode != 0:
169
217
  # Non-zero return without detected pattern
170
218
  self.logger.debug(f"Hook {hook_type} returned code {result.returncode}")
@@ -12,7 +12,7 @@ of InteractiveSession without circular dependency issues.
12
12
 
13
13
  import contextlib
14
14
  import os
15
- import subprocess
15
+ import subprocess # nosec B404
16
16
  import uuid
17
17
  from pathlib import Path
18
18
  from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple
@@ -143,11 +143,12 @@ class InteractiveSession:
143
143
  Tuple of (success, environment_dict)
144
144
  """
145
145
  try:
146
- # Deploy system agents
147
- if not self.runner.setup_agents():
148
- print("Continuing without native agents...")
146
+ # NOTE: System agents are deployed via reconciliation during startup.
147
+ # The reconciliation process respects user configuration and handles
148
+ # both native and custom mode deployment. No need to call setup_agents() here.
149
149
 
150
- # Deploy project-specific agents
150
+ # Deploy project-specific agents from .claude-mpm/agents/
151
+ # This is separate from system agents and handles user-defined agents
151
152
  self.runner.deploy_project_agents_to_claude()
152
153
 
153
154
  # Build command
@@ -359,19 +360,19 @@ class InteractiveSession:
359
360
  osm = self.runner.framework_loader.output_style_manager
360
361
  if osm:
361
362
  if osm.claude_version and osm.supports_output_styles():
362
- # Check if claude-mpm style is active
363
+ # Check if Claude MPM style is active
363
364
  settings_file = osm.settings_file
364
365
  if settings_file.exists():
365
366
  import json
366
367
 
367
368
  settings = json.loads(settings_file.read_text())
368
369
  active_style = settings.get("activeOutputStyle")
369
- if active_style == "claude-mpm":
370
- return "Output Style: claude-mpm ✅"
370
+ if active_style in ("Claude MPM", "Claude MPM Teacher"):
371
+ return f"Output Style: {active_style} ✅"
371
372
  return f"Output Style: {active_style or 'none'}"
372
373
  return "Output Style: Available"
373
374
  return "Output Style: Injected (legacy)"
374
- except Exception:
375
+ except Exception: # nosec B110
375
376
  pass
376
377
  return None
377
378
 
@@ -582,7 +583,7 @@ class InteractiveSession:
582
583
  )
583
584
 
584
585
  # This will not return if successful
585
- os.execvpe(cmd[0], cmd, env)
586
+ os.execvpe(cmd[0], cmd, env) # nosec B606
586
587
  return False # Only reached on failure
587
588
 
588
589
  def _launch_subprocess_mode(self, cmd: list, env: dict) -> bool:
@@ -641,7 +642,7 @@ class InteractiveSession:
641
642
  cmd = environment["command"]
642
643
  env = environment["environment"]
643
644
 
644
- result = subprocess.run(
645
+ result = subprocess.run( # nosec B603
645
646
  cmd, stdin=None, stdout=None, stderr=None, env=env, check=False
646
647
  )
647
648
 
claude_mpm/core/logger.py CHANGED
@@ -214,19 +214,22 @@ def setup_logging(
214
214
 
215
215
  # Console handler
216
216
  if console_output:
217
+ # MUST use stderr to avoid corrupting hook JSON output
218
+ # WHY stderr: Hook handlers output JSON to stdout. Logging to stdout
219
+ # corrupts this JSON and causes "hook error" messages from Claude Code.
217
220
  if use_streaming:
218
221
  # Use streaming handler for single-line INFO messages
219
- console_handler = StreamingHandler(sys.stdout)
222
+ console_handler = StreamingHandler(sys.stderr)
220
223
  console_handler.setFormatter(simple_formatter)
221
224
  elif use_rich and not json_format:
222
225
  # Rich support has been removed, use standard handler
223
- console_handler = logging.StreamHandler(sys.stdout)
226
+ console_handler = logging.StreamHandler(sys.stderr)
224
227
  console_handler.setFormatter(simple_formatter)
225
228
  else:
226
- console_handler = logging.StreamHandler(sys.stdout)
229
+ console_handler = logging.StreamHandler(sys.stderr)
227
230
  console_handler.setFormatter(formatter if json_format else simple_formatter)
228
231
 
229
- console_handler.setLevel(logging.INFO)
232
+ console_handler.setLevel(log_level) # Respect the requested log level
230
233
  logger.addHandler(console_handler)
231
234
 
232
235
  # File handler
@@ -263,7 +266,7 @@ def setup_logging(
263
266
  if deleted_count > 0:
264
267
  # Log to the new file handler that we're about to add
265
268
  pass # Deletion count will be logged when logger is ready
266
- except Exception:
269
+ except Exception: # nosec B110 - intentional: logging should not break app
267
270
  pass # Ignore cleanup errors
268
271
 
269
272
  # Also create a symlink to latest log (with thread safety)
@@ -305,7 +308,7 @@ def setup_logging(
305
308
  # Fallback: try to create a regular file with reference to actual log
306
309
  try:
307
310
  latest_link.write_text(f"Latest log: {log_file.name}\n")
308
- except Exception:
311
+ except Exception: # nosec B110 - intentional: logging should not break app
309
312
  pass # Silently fail - logging should not break the application
310
313
  except Exception as e:
311
314
  # Catch any other unexpected errors to ensure logging doesn't break
@@ -381,15 +384,29 @@ def cleanup_old_mpm_logs(
381
384
  try:
382
385
  log_file.unlink()
383
386
  deleted_count += 1
384
- except Exception:
387
+ except Exception: # nosec B110 - intentional: log cleanup is best-effort
385
388
  pass # Ignore deletion errors
386
389
 
387
390
  return deleted_count
388
391
 
389
392
 
390
393
  def get_logger(name: str) -> logging.Logger:
391
- """Get a logger instance."""
392
- return logging.getLogger(f"claude_mpm.{name}")
394
+ """Get a logger instance.
395
+
396
+ CRITICAL: Respects startup suppression mode (CRITICAL+1) to prevent
397
+ early INFO logs before setup_logging() is called.
398
+ """
399
+ logger = logging.getLogger(f"claude_mpm.{name}")
400
+
401
+ # Check if root logger is suppressed (startup.py sets CRITICAL+1)
402
+ root_logger = logging.getLogger()
403
+ if root_logger.level > logging.CRITICAL:
404
+ # Suppression active - ensure this logger is also suppressed
405
+ logger.setLevel(logging.CRITICAL + 1)
406
+ logger.handlers = []
407
+ logger.propagate = False
408
+
409
+ return logger
393
410
 
394
411
 
395
412
  def setup_streaming_logger(name: str, level: str = "INFO") -> logging.Logger:
@@ -103,21 +103,47 @@ class LoggerFactory:
103
103
 
104
104
  # Set up root logger
105
105
  root_logger = logging.getLogger()
106
- root_logger.setLevel(LoggingConfig.LEVELS.get(cls._log_level, logging.INFO))
107
106
 
108
- # Remove existing handlers
109
- root_logger.handlers = []
110
-
111
- # Console handler
112
- console_handler = logging.StreamHandler(sys.stdout)
113
- console_handler.setLevel(LoggingConfig.LEVELS.get(cls._log_level, logging.INFO))
114
- console_formatter = logging.Formatter(
115
- log_format or LoggingConfig.DEFAULT_FORMAT,
116
- date_format or LoggingConfig.DATE_FORMAT,
107
+ # CRITICAL FIX: Respect existing root logger suppression
108
+ # If root logger is already set to CRITICAL+1 (suppressed by startup.py),
109
+ # don't override it. This prevents logging from appearing during startup
110
+ # before the CLI's setup_logging() runs.
111
+ current_level = root_logger.level
112
+ desired_level = LoggingConfig.LEVELS.get(cls._log_level, logging.INFO)
113
+
114
+ # Only set level if current is unset (0) or lower than desired
115
+ # CRITICAL+1 is 51, so this check preserves suppression
116
+ should_configure_logging = current_level == 0 or (
117
+ current_level < desired_level and current_level <= logging.CRITICAL
117
118
  )
118
- console_handler.setFormatter(console_formatter)
119
- root_logger.addHandler(console_handler)
120
- cls._handlers["console"] = console_handler
119
+
120
+ if should_configure_logging:
121
+ root_logger.setLevel(desired_level)
122
+ # else: root logger is suppressed (CRITICAL+1), keep it suppressed
123
+
124
+ # Preserve FileHandlers (e.g., hooks logging), only remove StreamHandlers
125
+ root_logger.handlers = [
126
+ h for h in root_logger.handlers if isinstance(h, logging.FileHandler)
127
+ ]
128
+
129
+ # CRITICAL FIX: Don't add handlers if logging is suppressed
130
+ # If root logger is at CRITICAL+1 (startup suppression), don't add any handlers
131
+ # This prevents early imports from logging before CLI setup_logging() runs
132
+ if should_configure_logging:
133
+ # Console handler - MUST use stderr to avoid corrupting hook JSON output
134
+ # WHY stderr: Hook handlers output JSON to stdout. Logging to stdout
135
+ # corrupts this JSON and causes "hook error" messages from Claude Code.
136
+ console_handler = logging.StreamHandler(sys.stderr)
137
+ console_handler.setLevel(
138
+ LoggingConfig.LEVELS.get(cls._log_level, logging.INFO)
139
+ )
140
+ console_formatter = logging.Formatter(
141
+ log_format or LoggingConfig.DEFAULT_FORMAT,
142
+ date_format or LoggingConfig.DATE_FORMAT,
143
+ )
144
+ console_handler.setFormatter(console_formatter)
145
+ root_logger.addHandler(console_handler)
146
+ cls._handlers["console"] = console_handler
121
147
 
122
148
  # File handler (optional)
123
149
  if log_to_file and cls._log_dir: