claude-mpm 3.4.10__py3-none-any.whl → 5.4.85__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.
Files changed (1062) hide show
  1. claude_mpm/BUILD_NUMBER +1 -0
  2. claude_mpm/VERSION +1 -0
  3. claude_mpm/__init__.py +50 -12
  4. claude_mpm/__main__.py +7 -2
  5. claude_mpm/agents/BASE_AGENT.md +164 -0
  6. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  7. claude_mpm/agents/CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md +405 -0
  8. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +112 -0
  9. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +186 -0
  10. claude_mpm/agents/MEMORY.md +72 -0
  11. claude_mpm/agents/PM_INSTRUCTIONS.md +1429 -0
  12. claude_mpm/agents/WORKFLOW.md +111 -0
  13. claude_mpm/agents/__init__.py +92 -80
  14. claude_mpm/agents/agent-template.yaml +83 -0
  15. claude_mpm/agents/agent_loader.py +560 -745
  16. claude_mpm/agents/agent_loader_integration.py +53 -55
  17. claude_mpm/agents/agents_metadata.py +186 -27
  18. claude_mpm/agents/async_agent_loader.py +436 -0
  19. claude_mpm/agents/base_agent.json +8 -4
  20. claude_mpm/agents/frontmatter_validator.py +754 -0
  21. claude_mpm/agents/system_agent_config.py +222 -155
  22. claude_mpm/agents/templates/README.md +465 -0
  23. claude_mpm/agents/templates/__init__.py +17 -13
  24. claude_mpm/agents/templates/circuit-breakers.md +1391 -0
  25. claude_mpm/agents/templates/context-management-examples.md +544 -0
  26. claude_mpm/agents/templates/git-file-tracking.md +584 -0
  27. claude_mpm/agents/templates/pm-examples.md +474 -0
  28. claude_mpm/agents/templates/pm-red-flags.md +310 -0
  29. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  30. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  31. claude_mpm/agents/templates/response-format.md +583 -0
  32. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  33. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  34. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  35. claude_mpm/agents/templates/validation-templates.md +312 -0
  36. claude_mpm/cli/__init__.py +94 -128
  37. claude_mpm/cli/__main__.py +33 -0
  38. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  39. claude_mpm/cli/commands/__init__.py +36 -12
  40. claude_mpm/cli/commands/agent_manager.py +1403 -0
  41. claude_mpm/cli/commands/agent_source.py +774 -0
  42. claude_mpm/cli/commands/agent_state_manager.py +335 -0
  43. claude_mpm/cli/commands/agents.py +2501 -168
  44. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  45. claude_mpm/cli/commands/agents_discover.py +338 -0
  46. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  47. claude_mpm/cli/commands/aggregate.py +540 -0
  48. claude_mpm/cli/commands/analyze.py +553 -0
  49. claude_mpm/cli/commands/analyze_code.py +528 -0
  50. claude_mpm/cli/commands/auto_configure.py +1053 -0
  51. claude_mpm/cli/commands/cleanup.py +588 -0
  52. claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
  53. claude_mpm/cli/commands/config.py +586 -0
  54. claude_mpm/cli/commands/configure.py +3253 -0
  55. claude_mpm/cli/commands/configure_agent_display.py +282 -0
  56. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  57. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  58. claude_mpm/cli/commands/configure_models.py +18 -0
  59. claude_mpm/cli/commands/configure_navigation.py +184 -0
  60. claude_mpm/cli/commands/configure_paths.py +104 -0
  61. claude_mpm/cli/commands/configure_persistence.py +254 -0
  62. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  63. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  64. claude_mpm/cli/commands/configure_validators.py +73 -0
  65. claude_mpm/cli/commands/dashboard.py +286 -0
  66. claude_mpm/cli/commands/debug.py +1386 -0
  67. claude_mpm/cli/commands/doctor.py +243 -0
  68. claude_mpm/cli/commands/hook_errors.py +277 -0
  69. claude_mpm/cli/commands/info.py +195 -74
  70. claude_mpm/cli/commands/local_deploy.py +534 -0
  71. claude_mpm/cli/commands/mcp.py +205 -0
  72. claude_mpm/cli/commands/mcp_command_router.py +161 -0
  73. claude_mpm/cli/commands/mcp_config.py +154 -0
  74. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  75. claude_mpm/cli/commands/mcp_external_commands.py +249 -0
  76. claude_mpm/cli/commands/mcp_install_commands.py +346 -0
  77. claude_mpm/cli/commands/mcp_pipx_config.py +208 -0
  78. claude_mpm/cli/commands/mcp_server_commands.py +155 -0
  79. claude_mpm/cli/commands/mcp_setup_external.py +868 -0
  80. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  81. claude_mpm/cli/commands/memory.py +585 -846
  82. claude_mpm/cli/commands/monitor.py +228 -310
  83. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  84. claude_mpm/cli/commands/mpm_init/core.py +759 -0
  85. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  86. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  87. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  88. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  89. claude_mpm/cli/commands/mpm_init/prompts.py +722 -0
  90. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  91. claude_mpm/cli/commands/mpm_init_handler.py +195 -0
  92. claude_mpm/cli/commands/postmortem.py +401 -0
  93. claude_mpm/cli/commands/profile.py +276 -0
  94. claude_mpm/cli/commands/run.py +910 -488
  95. claude_mpm/cli/commands/search.py +458 -0
  96. claude_mpm/cli/commands/skill_source.py +694 -0
  97. claude_mpm/cli/commands/skills.py +1398 -0
  98. claude_mpm/cli/commands/summarize.py +413 -0
  99. claude_mpm/cli/commands/tickets.py +536 -53
  100. claude_mpm/cli/commands/uninstall.py +176 -0
  101. claude_mpm/cli/commands/upgrade.py +152 -0
  102. claude_mpm/cli/commands/verify.py +119 -0
  103. claude_mpm/cli/executor.py +298 -0
  104. claude_mpm/cli/helpers.py +105 -0
  105. claude_mpm/cli/interactive/__init__.py +31 -0
  106. claude_mpm/cli/interactive/agent_wizard.py +1927 -0
  107. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  108. claude_mpm/cli/interactive/skill_selector.py +481 -0
  109. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  110. claude_mpm/cli/parser.py +87 -563
  111. claude_mpm/cli/parsers/__init__.py +35 -0
  112. claude_mpm/cli/parsers/agent_manager_parser.py +393 -0
  113. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  114. claude_mpm/cli/parsers/agents_parser.py +575 -0
  115. claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
  116. claude_mpm/cli/parsers/analyze_parser.py +135 -0
  117. claude_mpm/cli/parsers/auto_configure_parser.py +120 -0
  118. claude_mpm/cli/parsers/base_parser.py +649 -0
  119. claude_mpm/cli/parsers/config_parser.py +208 -0
  120. claude_mpm/cli/parsers/configure_parser.py +138 -0
  121. claude_mpm/cli/parsers/dashboard_parser.py +113 -0
  122. claude_mpm/cli/parsers/debug_parser.py +319 -0
  123. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  124. claude_mpm/cli/parsers/mcp_parser.py +195 -0
  125. claude_mpm/cli/parsers/memory_parser.py +138 -0
  126. claude_mpm/cli/parsers/monitor_parser.py +142 -0
  127. claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
  128. claude_mpm/cli/parsers/profile_parser.py +147 -0
  129. claude_mpm/cli/parsers/run_parser.py +157 -0
  130. claude_mpm/cli/parsers/search_parser.py +245 -0
  131. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  132. claude_mpm/cli/parsers/skills_parser.py +277 -0
  133. claude_mpm/cli/parsers/source_parser.py +138 -0
  134. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  135. claude_mpm/cli/shared/__init__.py +40 -0
  136. claude_mpm/cli/shared/argument_patterns.py +205 -0
  137. claude_mpm/cli/shared/base_command.py +242 -0
  138. claude_mpm/cli/shared/error_handling.py +242 -0
  139. claude_mpm/cli/shared/output_formatters.py +241 -0
  140. claude_mpm/cli/startup.py +1578 -0
  141. claude_mpm/cli/startup_display.py +480 -0
  142. claude_mpm/cli/startup_logging.py +839 -0
  143. claude_mpm/cli/utils.py +136 -47
  144. claude_mpm/cli_module/__init__.py +6 -6
  145. claude_mpm/cli_module/args.py +188 -140
  146. claude_mpm/cli_module/commands.py +79 -70
  147. claude_mpm/cli_module/migration_example.py +42 -64
  148. claude_mpm/commands/__init__.py +14 -0
  149. claude_mpm/commands/mpm-config.md +28 -0
  150. claude_mpm/commands/mpm-doctor.md +20 -0
  151. claude_mpm/commands/mpm-help.md +20 -0
  152. claude_mpm/commands/mpm-init.md +120 -0
  153. claude_mpm/commands/mpm-monitor.md +31 -0
  154. claude_mpm/commands/mpm-organize.md +120 -0
  155. claude_mpm/commands/mpm-postmortem.md +21 -0
  156. claude_mpm/commands/mpm-session-resume.md +30 -0
  157. claude_mpm/commands/mpm-status.md +20 -0
  158. claude_mpm/commands/mpm-ticket-view.md +109 -0
  159. claude_mpm/commands/mpm-version.md +20 -0
  160. claude_mpm/commands/mpm.md +31 -0
  161. claude_mpm/config/__init__.py +42 -2
  162. claude_mpm/config/agent_config.py +402 -0
  163. claude_mpm/config/agent_presets.py +488 -0
  164. claude_mpm/config/agent_sources.py +352 -0
  165. claude_mpm/config/experimental_features.py +217 -0
  166. claude_mpm/config/model_config.py +428 -0
  167. claude_mpm/config/paths.py +258 -0
  168. claude_mpm/config/skill_presets.py +392 -0
  169. claude_mpm/config/skill_sources.py +590 -0
  170. claude_mpm/config/socketio_config.py +125 -83
  171. claude_mpm/constants.py +133 -22
  172. claude_mpm/core/__init__.py +62 -36
  173. claude_mpm/core/agent_name_normalizer.py +71 -73
  174. claude_mpm/core/agent_registry.py +385 -492
  175. claude_mpm/core/agent_session_manager.py +81 -70
  176. claude_mpm/core/api_validator.py +330 -0
  177. claude_mpm/core/base_service.py +159 -122
  178. claude_mpm/core/cache.py +560 -0
  179. claude_mpm/core/claude_runner.py +696 -916
  180. claude_mpm/core/config.py +613 -122
  181. claude_mpm/core/config_aliases.py +74 -73
  182. claude_mpm/core/config_constants.py +314 -0
  183. claude_mpm/core/constants.py +361 -0
  184. claude_mpm/core/container.py +646 -104
  185. claude_mpm/core/enums.py +452 -0
  186. claude_mpm/core/error_handler.py +623 -0
  187. claude_mpm/core/exceptions.py +536 -0
  188. claude_mpm/core/factories.py +105 -109
  189. claude_mpm/core/file_utils.py +764 -0
  190. claude_mpm/core/framework/__init__.py +25 -0
  191. claude_mpm/core/framework/formatters/__init__.py +11 -0
  192. claude_mpm/core/framework/formatters/capability_generator.py +367 -0
  193. claude_mpm/core/framework/formatters/content_formatter.py +278 -0
  194. claude_mpm/core/framework/formatters/context_generator.py +185 -0
  195. claude_mpm/core/framework/loaders/__init__.py +13 -0
  196. claude_mpm/core/framework/loaders/agent_loader.py +213 -0
  197. claude_mpm/core/framework/loaders/file_loader.py +176 -0
  198. claude_mpm/core/framework/loaders/instruction_loader.py +222 -0
  199. claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
  200. claude_mpm/core/framework/processors/__init__.py +11 -0
  201. claude_mpm/core/framework/processors/memory_processor.py +230 -0
  202. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  203. claude_mpm/core/framework/processors/template_processor.py +244 -0
  204. claude_mpm/core/framework_loader.py +485 -414
  205. claude_mpm/core/hook_error_memory.py +381 -0
  206. claude_mpm/core/hook_manager.py +246 -86
  207. claude_mpm/core/hook_performance_config.py +147 -0
  208. claude_mpm/core/injectable_service.py +72 -63
  209. claude_mpm/core/instruction_reinforcement_hook.py +267 -0
  210. claude_mpm/core/interactive_session.py +670 -0
  211. claude_mpm/core/interfaces.py +570 -164
  212. claude_mpm/core/lazy.py +467 -0
  213. claude_mpm/core/log_manager.py +707 -0
  214. claude_mpm/core/logger.py +295 -134
  215. claude_mpm/core/logging_config.py +474 -0
  216. claude_mpm/core/logging_utils.py +520 -0
  217. claude_mpm/core/minimal_framework_loader.py +24 -22
  218. claude_mpm/core/mixins.py +30 -29
  219. claude_mpm/core/oneshot_session.py +594 -0
  220. claude_mpm/core/optimized_agent_loader.py +479 -0
  221. claude_mpm/core/optimized_startup.py +554 -0
  222. claude_mpm/core/output_style_manager.py +491 -0
  223. claude_mpm/core/pm_hook_interceptor.py +197 -82
  224. claude_mpm/core/protocols/__init__.py +23 -0
  225. claude_mpm/core/protocols/runner_protocol.py +103 -0
  226. claude_mpm/core/protocols/session_protocol.py +131 -0
  227. claude_mpm/core/service_registry.py +153 -116
  228. claude_mpm/core/session_manager.py +179 -64
  229. claude_mpm/core/shared/__init__.py +17 -0
  230. claude_mpm/core/shared/config_loader.py +326 -0
  231. claude_mpm/core/shared/path_resolver.py +281 -0
  232. claude_mpm/core/shared/singleton_manager.py +221 -0
  233. claude_mpm/core/socketio_pool.py +400 -137
  234. claude_mpm/core/system_context.py +38 -0
  235. claude_mpm/core/tool_access_control.py +64 -57
  236. claude_mpm/core/types.py +307 -0
  237. claude_mpm/core/typing_utils.py +553 -0
  238. claude_mpm/core/unified_agent_registry.py +969 -0
  239. claude_mpm/core/unified_config.py +612 -0
  240. claude_mpm/core/unified_paths.py +958 -0
  241. claude_mpm/dashboard/__init__.py +12 -0
  242. claude_mpm/dashboard/api/simple_directory.py +261 -0
  243. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  244. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
  245. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
  246. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
  247. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
  248. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
  249. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
  250. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
  251. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
  252. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
  253. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
  254. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  255. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
  256. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
  257. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
  258. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
  259. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
  260. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
  261. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
  262. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
  263. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
  264. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
  265. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
  266. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
  267. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
  268. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  269. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
  270. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
  271. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  272. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
  273. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
  274. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
  275. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
  276. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
  277. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
  278. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
  279. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
  280. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
  281. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  282. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
  283. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
  284. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
  285. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
  286. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
  287. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
  288. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
  289. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
  290. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
  291. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
  292. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  293. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
  294. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
  295. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
  296. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
  297. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
  298. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
  299. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
  300. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
  301. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
  302. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
  303. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
  304. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
  305. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
  306. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
  307. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
  308. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  309. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  310. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  311. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  312. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  313. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  314. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  315. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  316. claude_mpm/experimental/__init__.py +10 -0
  317. claude_mpm/experimental/cli_enhancements.py +104 -89
  318. claude_mpm/generators/__init__.py +1 -1
  319. claude_mpm/generators/agent_profile_generator.py +76 -66
  320. claude_mpm/hooks/__init__.py +37 -1
  321. claude_mpm/hooks/base_hook.py +37 -32
  322. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  323. claude_mpm/hooks/claude_hooks/connection_pool.py +250 -0
  324. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  325. claude_mpm/hooks/claude_hooks/event_handlers.py +888 -0
  326. claude_mpm/hooks/claude_hooks/hook_handler.py +652 -875
  327. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +10 -7
  328. claude_mpm/hooks/claude_hooks/installer.py +806 -0
  329. claude_mpm/hooks/claude_hooks/memory_integration.py +249 -0
  330. claude_mpm/hooks/claude_hooks/response_tracking.py +412 -0
  331. claude_mpm/hooks/claude_hooks/services/__init__.py +15 -0
  332. claude_mpm/hooks/claude_hooks/services/connection_manager.py +229 -0
  333. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +254 -0
  334. claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
  335. claude_mpm/hooks/claude_hooks/services/state_manager.py +284 -0
  336. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
  337. claude_mpm/hooks/claude_hooks/tool_analysis.py +224 -0
  338. claude_mpm/hooks/failure_learning/__init__.py +54 -0
  339. claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
  340. claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
  341. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
  342. claude_mpm/hooks/instruction_reinforcement.py +301 -0
  343. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  344. claude_mpm/hooks/kuzu_memory_hook.py +386 -0
  345. claude_mpm/hooks/kuzu_response_hook.py +179 -0
  346. claude_mpm/hooks/memory_integration_hook.py +201 -107
  347. claude_mpm/hooks/session_resume_hook.py +121 -0
  348. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  349. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  350. claude_mpm/hooks/tool_call_interceptor.py +92 -76
  351. claude_mpm/hooks/validation_hooks.py +62 -54
  352. claude_mpm/init.py +518 -83
  353. claude_mpm/models/__init__.py +9 -9
  354. claude_mpm/models/agent_definition.py +40 -23
  355. claude_mpm/models/agent_session.py +538 -0
  356. claude_mpm/models/git_repository.py +198 -0
  357. claude_mpm/models/resume_log.py +340 -0
  358. claude_mpm/schemas/__init__.py +12 -0
  359. claude_mpm/scripts/__init__.py +15 -0
  360. claude_mpm/scripts/claude-hook-handler.sh +227 -0
  361. claude_mpm/scripts/launch_monitor.py +165 -0
  362. claude_mpm/scripts/mpm_doctor.py +322 -0
  363. claude_mpm/scripts/socketio_daemon.py +189 -200
  364. claude_mpm/scripts/start_activity_logging.py +91 -0
  365. claude_mpm/services/__init__.py +208 -39
  366. claude_mpm/services/agent_capabilities_service.py +266 -0
  367. claude_mpm/services/agents/__init__.py +89 -0
  368. claude_mpm/services/agents/agent_builder.py +514 -0
  369. claude_mpm/services/agents/agent_preset_service.py +238 -0
  370. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  371. claude_mpm/services/agents/agent_review_service.py +280 -0
  372. claude_mpm/services/agents/agent_selection_service.py +484 -0
  373. claude_mpm/services/agents/auto_config_manager.py +796 -0
  374. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  375. claude_mpm/services/agents/cache_git_manager.py +621 -0
  376. claude_mpm/services/agents/deployment/__init__.py +21 -0
  377. claude_mpm/services/agents/deployment/agent_config_provider.py +410 -0
  378. claude_mpm/services/agents/deployment/agent_configuration_manager.py +358 -0
  379. claude_mpm/services/agents/deployment/agent_definition_factory.py +80 -0
  380. claude_mpm/services/agents/deployment/agent_deployment.py +1037 -0
  381. claude_mpm/services/agents/deployment/agent_discovery_service.py +546 -0
  382. claude_mpm/services/agents/deployment/agent_environment_manager.py +288 -0
  383. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +383 -0
  384. claude_mpm/services/agents/deployment/agent_format_converter.py +505 -0
  385. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +160 -0
  386. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +957 -0
  387. claude_mpm/services/agents/deployment/agent_metrics_collector.py +273 -0
  388. claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
  389. claude_mpm/services/agents/deployment/agent_record_service.py +418 -0
  390. claude_mpm/services/agents/deployment/agent_restore_handler.py +84 -0
  391. claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
  392. claude_mpm/services/agents/deployment/agent_template_builder.py +1377 -0
  393. claude_mpm/services/agents/deployment/agent_validator.py +376 -0
  394. claude_mpm/services/agents/deployment/agent_version_manager.py +322 -0
  395. claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +10 -13
  396. claude_mpm/services/agents/deployment/agents_directory_resolver.py +149 -0
  397. claude_mpm/services/agents/deployment/async_agent_deployment.py +768 -0
  398. claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
  399. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  400. claude_mpm/services/agents/deployment/config/deployment_config.py +181 -0
  401. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  402. claude_mpm/services/agents/deployment/deployment_config_loader.py +178 -0
  403. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  404. claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
  405. claude_mpm/services/agents/deployment/deployment_type_detector.py +120 -0
  406. claude_mpm/services/agents/deployment/deployment_wrapper.py +129 -0
  407. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  408. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  409. claude_mpm/services/agents/deployment/facade/deployment_executor.py +70 -0
  410. claude_mpm/services/agents/deployment/facade/deployment_facade.py +269 -0
  411. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  412. claude_mpm/services/agents/deployment/interface_adapter.py +226 -0
  413. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  414. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  415. claude_mpm/services/agents/deployment/local_template_deployment.py +362 -0
  416. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +1478 -0
  417. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  418. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  419. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +162 -0
  420. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  421. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  422. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +240 -0
  423. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +110 -0
  424. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +80 -0
  425. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +92 -0
  426. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +101 -0
  427. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  428. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +102 -0
  429. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  430. claude_mpm/services/agents/deployment/processors/agent_processor.py +269 -0
  431. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +311 -0
  432. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +862 -0
  433. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  434. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  435. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  436. claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
  437. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  438. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  439. claude_mpm/services/agents/deployment/strategies/base_strategy.py +113 -0
  440. claude_mpm/services/agents/deployment/strategies/project_strategy.py +148 -0
  441. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  442. claude_mpm/services/agents/deployment/strategies/system_strategy.py +131 -0
  443. claude_mpm/services/agents/deployment/strategies/user_strategy.py +130 -0
  444. claude_mpm/services/agents/deployment/system_instructions_deployer.py +228 -0
  445. claude_mpm/services/agents/deployment/validation/__init__.py +21 -0
  446. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  447. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  448. claude_mpm/services/agents/deployment/validation/template_validator.py +319 -0
  449. claude_mpm/services/agents/deployment/validation/validation_result.py +214 -0
  450. claude_mpm/services/agents/git_source_manager.py +682 -0
  451. claude_mpm/services/agents/loading/__init__.py +11 -0
  452. claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +306 -228
  453. claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +106 -91
  454. claude_mpm/services/agents/loading/framework_agent_loader.py +433 -0
  455. claude_mpm/services/agents/local_template_manager.py +784 -0
  456. claude_mpm/services/agents/management/__init__.py +9 -0
  457. claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +92 -69
  458. claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +219 -168
  459. claude_mpm/services/agents/memory/__init__.py +22 -0
  460. claude_mpm/services/agents/memory/agent_memory_manager.py +784 -0
  461. claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +20 -18
  462. claude_mpm/services/agents/memory/content_manager.py +470 -0
  463. claude_mpm/services/agents/memory/memory_categorization_service.py +167 -0
  464. claude_mpm/services/agents/memory/memory_file_service.py +129 -0
  465. claude_mpm/services/agents/memory/memory_format_service.py +201 -0
  466. claude_mpm/services/agents/memory/memory_limits_service.py +101 -0
  467. claude_mpm/services/agents/memory/template_generator.py +83 -0
  468. claude_mpm/services/agents/observers.py +547 -0
  469. claude_mpm/services/agents/recommender.py +617 -0
  470. claude_mpm/services/agents/registry/__init__.py +30 -0
  471. claude_mpm/services/agents/registry/deployed_agent_discovery.py +273 -0
  472. claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +370 -295
  473. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  474. claude_mpm/services/agents/sources/__init__.py +13 -0
  475. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  476. claude_mpm/services/agents/sources/git_source_sync_service.py +1205 -0
  477. claude_mpm/services/agents/startup_sync.py +262 -0
  478. claude_mpm/services/agents/toolchain_detector.py +478 -0
  479. claude_mpm/services/analysis/__init__.py +35 -0
  480. claude_mpm/services/analysis/clone_detector.py +1030 -0
  481. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  482. claude_mpm/services/analysis/postmortem_service.py +765 -0
  483. claude_mpm/services/async_session_logger.py +665 -0
  484. claude_mpm/services/claude_session_logger.py +321 -0
  485. claude_mpm/services/cli/__init__.py +18 -0
  486. claude_mpm/services/cli/agent_cleanup_service.py +408 -0
  487. claude_mpm/services/cli/agent_dependency_service.py +395 -0
  488. claude_mpm/services/cli/agent_listing_service.py +463 -0
  489. claude_mpm/services/cli/agent_output_formatter.py +605 -0
  490. claude_mpm/services/cli/agent_validation_service.py +590 -0
  491. claude_mpm/services/cli/memory_crud_service.py +622 -0
  492. claude_mpm/services/cli/memory_output_formatter.py +604 -0
  493. claude_mpm/services/cli/resume_service.py +617 -0
  494. claude_mpm/services/cli/session_manager.py +604 -0
  495. claude_mpm/services/cli/session_pause_manager.py +504 -0
  496. claude_mpm/services/cli/session_resume_helper.py +372 -0
  497. claude_mpm/services/cli/startup_checker.py +362 -0
  498. claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
  499. claude_mpm/services/command_deployment_service.py +446 -0
  500. claude_mpm/services/command_handler_service.py +221 -0
  501. claude_mpm/services/communication/__init__.py +22 -0
  502. claude_mpm/services/core/__init__.py +108 -0
  503. claude_mpm/services/core/base.py +269 -0
  504. claude_mpm/services/core/cache_manager.py +309 -0
  505. claude_mpm/services/core/interfaces/__init__.py +273 -0
  506. claude_mpm/services/core/interfaces/agent.py +514 -0
  507. claude_mpm/services/core/interfaces/communication.py +316 -0
  508. claude_mpm/services/core/interfaces/health.py +169 -0
  509. claude_mpm/services/core/interfaces/infrastructure.py +357 -0
  510. claude_mpm/services/core/interfaces/model.py +281 -0
  511. claude_mpm/services/core/interfaces/process.py +372 -0
  512. claude_mpm/services/core/interfaces/project.py +121 -0
  513. claude_mpm/services/core/interfaces/restart.py +307 -0
  514. claude_mpm/services/core/interfaces/service.py +405 -0
  515. claude_mpm/services/core/interfaces/stability.py +260 -0
  516. claude_mpm/services/core/interfaces.py +81 -0
  517. claude_mpm/services/core/memory_manager.py +682 -0
  518. claude_mpm/services/core/models/__init__.py +70 -0
  519. claude_mpm/services/core/models/agent_config.py +384 -0
  520. claude_mpm/services/core/models/health.py +162 -0
  521. claude_mpm/services/core/models/process.py +239 -0
  522. claude_mpm/services/core/models/restart.py +302 -0
  523. claude_mpm/services/core/models/stability.py +264 -0
  524. claude_mpm/services/core/models/toolchain.py +306 -0
  525. claude_mpm/services/core/path_resolver.py +517 -0
  526. claude_mpm/services/core/service_container.py +520 -0
  527. claude_mpm/services/core/service_interfaces.py +436 -0
  528. claude_mpm/services/diagnostics/__init__.py +18 -0
  529. claude_mpm/services/diagnostics/checks/__init__.py +38 -0
  530. claude_mpm/services/diagnostics/checks/agent_check.py +370 -0
  531. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  532. claude_mpm/services/diagnostics/checks/base_check.py +60 -0
  533. claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
  534. claude_mpm/services/diagnostics/checks/common_issues_check.py +363 -0
  535. claude_mpm/services/diagnostics/checks/configuration_check.py +306 -0
  536. claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
  537. claude_mpm/services/diagnostics/checks/installation_check.py +520 -0
  538. claude_mpm/services/diagnostics/checks/instructions_check.py +415 -0
  539. claude_mpm/services/diagnostics/checks/mcp_check.py +330 -0
  540. claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
  541. claude_mpm/services/diagnostics/checks/monitor_check.py +281 -0
  542. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  543. claude_mpm/services/diagnostics/checks/startup_log_check.py +319 -0
  544. claude_mpm/services/diagnostics/diagnostic_runner.py +286 -0
  545. claude_mpm/services/diagnostics/doctor_reporter.py +578 -0
  546. claude_mpm/services/diagnostics/models.py +138 -0
  547. claude_mpm/services/event_aggregator.py +582 -0
  548. claude_mpm/services/event_bus/__init__.py +18 -0
  549. claude_mpm/services/event_bus/config.py +186 -0
  550. claude_mpm/services/event_bus/direct_relay.py +312 -0
  551. claude_mpm/services/event_bus/event_bus.py +396 -0
  552. claude_mpm/services/event_bus/relay.py +326 -0
  553. claude_mpm/services/events/__init__.py +44 -0
  554. claude_mpm/services/events/consumers/__init__.py +18 -0
  555. claude_mpm/services/events/consumers/dead_letter.py +306 -0
  556. claude_mpm/services/events/consumers/logging.py +184 -0
  557. claude_mpm/services/events/consumers/metrics.py +241 -0
  558. claude_mpm/services/events/consumers/socketio.py +377 -0
  559. claude_mpm/services/events/core.py +480 -0
  560. claude_mpm/services/events/interfaces.py +214 -0
  561. claude_mpm/services/events/producers/__init__.py +14 -0
  562. claude_mpm/services/events/producers/hook.py +269 -0
  563. claude_mpm/services/events/producers/system.py +329 -0
  564. claude_mpm/services/exceptions.py +433 -353
  565. claude_mpm/services/framework_claude_md_generator/__init__.py +81 -80
  566. claude_mpm/services/framework_claude_md_generator/content_assembler.py +74 -67
  567. claude_mpm/services/framework_claude_md_generator/content_validator.py +66 -62
  568. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +82 -60
  569. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +36 -37
  570. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +41 -40
  571. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +15 -15
  572. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +5 -4
  573. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  574. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  575. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  576. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  577. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +5 -4
  578. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  579. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  580. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +26 -30
  581. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +6 -5
  582. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  583. claude_mpm/services/framework_claude_md_generator/version_manager.py +31 -30
  584. claude_mpm/services/git/__init__.py +21 -0
  585. claude_mpm/services/git/git_operations_service.py +579 -0
  586. claude_mpm/services/github/__init__.py +21 -0
  587. claude_mpm/services/github/github_cli_service.py +397 -0
  588. claude_mpm/services/hook_installer_service.py +506 -0
  589. claude_mpm/services/hook_service.py +159 -111
  590. claude_mpm/services/infrastructure/__init__.py +52 -0
  591. claude_mpm/services/infrastructure/context_preservation.py +569 -0
  592. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  593. claude_mpm/services/infrastructure/logging.py +209 -0
  594. claude_mpm/services/infrastructure/monitoring/__init__.py +39 -0
  595. claude_mpm/services/infrastructure/monitoring/aggregator.py +432 -0
  596. claude_mpm/services/infrastructure/monitoring/base.py +122 -0
  597. claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
  598. claude_mpm/services/infrastructure/monitoring/network.py +219 -0
  599. claude_mpm/services/infrastructure/monitoring/process.py +343 -0
  600. claude_mpm/services/infrastructure/monitoring/resources.py +244 -0
  601. claude_mpm/services/infrastructure/monitoring/service.py +368 -0
  602. claude_mpm/services/infrastructure/monitoring.py +71 -0
  603. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  604. claude_mpm/services/instructions/__init__.py +9 -0
  605. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  606. claude_mpm/services/local_ops/__init__.py +155 -0
  607. claude_mpm/services/local_ops/crash_detector.py +257 -0
  608. claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
  609. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  610. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  611. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  612. claude_mpm/services/local_ops/health_manager.py +427 -0
  613. claude_mpm/services/local_ops/log_monitor.py +396 -0
  614. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  615. claude_mpm/services/local_ops/process_manager.py +595 -0
  616. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  617. claude_mpm/services/local_ops/restart_manager.py +401 -0
  618. claude_mpm/services/local_ops/restart_policy.py +387 -0
  619. claude_mpm/services/local_ops/state_manager.py +372 -0
  620. claude_mpm/services/local_ops/unified_manager.py +600 -0
  621. claude_mpm/services/mcp_config_manager.py +1542 -0
  622. claude_mpm/services/mcp_service_verifier.py +732 -0
  623. claude_mpm/services/memory/__init__.py +19 -0
  624. claude_mpm/services/{memory_builder.py → memory/builder.py} +465 -373
  625. claude_mpm/services/memory/cache/__init__.py +14 -0
  626. claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +237 -200
  627. claude_mpm/services/memory/cache/simple_cache.py +331 -0
  628. claude_mpm/services/memory/failure_tracker.py +578 -0
  629. claude_mpm/services/memory/indexed_memory.py +648 -0
  630. claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +272 -243
  631. claude_mpm/services/memory/router.py +951 -0
  632. claude_mpm/services/memory_hook_service.py +470 -0
  633. claude_mpm/services/model/__init__.py +147 -0
  634. claude_mpm/services/model/base_provider.py +365 -0
  635. claude_mpm/services/model/claude_provider.py +412 -0
  636. claude_mpm/services/model/model_router.py +452 -0
  637. claude_mpm/services/model/ollama_provider.py +415 -0
  638. claude_mpm/services/monitor/__init__.py +20 -0
  639. claude_mpm/services/monitor/daemon.py +698 -0
  640. claude_mpm/services/monitor/daemon_manager.py +1076 -0
  641. claude_mpm/services/monitor/event_emitter.py +350 -0
  642. claude_mpm/services/monitor/handlers/__init__.py +21 -0
  643. claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
  644. claude_mpm/services/monitor/handlers/dashboard.py +299 -0
  645. claude_mpm/services/monitor/handlers/file.py +264 -0
  646. claude_mpm/services/monitor/handlers/hooks.py +512 -0
  647. claude_mpm/services/monitor/management/__init__.py +18 -0
  648. claude_mpm/services/monitor/management/health.py +124 -0
  649. claude_mpm/services/monitor/management/lifecycle.py +730 -0
  650. claude_mpm/services/monitor/server.py +1493 -0
  651. claude_mpm/services/monitor_build_service.py +349 -0
  652. claude_mpm/services/native_agent_converter.py +356 -0
  653. claude_mpm/services/orphan_detection.py +786 -0
  654. claude_mpm/services/pm_skills_deployer.py +711 -0
  655. claude_mpm/services/port_manager.py +597 -0
  656. claude_mpm/services/pr/__init__.py +14 -0
  657. claude_mpm/services/pr/pr_template_service.py +329 -0
  658. claude_mpm/services/profile_manager.py +337 -0
  659. claude_mpm/services/project/__init__.py +44 -0
  660. claude_mpm/services/{project_analyzer.py → project/analyzer.py} +541 -291
  661. claude_mpm/services/project/analyzer_v2.py +566 -0
  662. claude_mpm/services/project/architecture_analyzer.py +461 -0
  663. claude_mpm/services/project/archive_manager.py +1045 -0
  664. claude_mpm/services/project/dependency_analyzer.py +462 -0
  665. claude_mpm/services/project/detection_strategies.py +719 -0
  666. claude_mpm/services/project/documentation_manager.py +554 -0
  667. claude_mpm/services/project/enhanced_analyzer.py +572 -0
  668. claude_mpm/services/project/language_analyzer.py +265 -0
  669. claude_mpm/services/project/metrics_collector.py +407 -0
  670. claude_mpm/services/project/project_organizer.py +1009 -0
  671. claude_mpm/services/project/registry.py +636 -0
  672. claude_mpm/services/project/toolchain_analyzer.py +583 -0
  673. claude_mpm/services/project_port_allocator.py +596 -0
  674. claude_mpm/services/recovery_manager.py +293 -240
  675. claude_mpm/services/response_tracker.py +267 -0
  676. claude_mpm/services/runner_configuration_service.py +605 -0
  677. claude_mpm/services/self_upgrade_service.py +608 -0
  678. claude_mpm/services/session_management_service.py +314 -0
  679. claude_mpm/services/session_manager.py +380 -0
  680. claude_mpm/services/shared/__init__.py +21 -0
  681. claude_mpm/services/shared/async_service_base.py +216 -0
  682. claude_mpm/services/shared/config_service_base.py +301 -0
  683. claude_mpm/services/shared/lifecycle_service_base.py +308 -0
  684. claude_mpm/services/shared/manager_base.py +315 -0
  685. claude_mpm/services/shared/service_factory.py +309 -0
  686. claude_mpm/services/skills/__init__.py +21 -0
  687. claude_mpm/services/skills/git_skill_source_manager.py +1340 -0
  688. claude_mpm/services/skills/selective_skill_deployer.py +743 -0
  689. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  690. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  691. claude_mpm/services/skills_config.py +547 -0
  692. claude_mpm/services/skills_deployer.py +1168 -0
  693. claude_mpm/services/socketio/__init__.py +25 -0
  694. claude_mpm/services/socketio/client_proxy.py +229 -0
  695. claude_mpm/services/socketio/dashboard_server.py +362 -0
  696. claude_mpm/services/socketio/event_normalizer.py +798 -0
  697. claude_mpm/services/socketio/handlers/__init__.py +30 -0
  698. claude_mpm/services/socketio/handlers/base.py +136 -0
  699. claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
  700. claude_mpm/services/socketio/handlers/connection.py +643 -0
  701. claude_mpm/services/socketio/handlers/connection_handler.py +333 -0
  702. claude_mpm/services/socketio/handlers/file.py +263 -0
  703. claude_mpm/services/socketio/handlers/git.py +962 -0
  704. claude_mpm/services/socketio/handlers/hook.py +211 -0
  705. claude_mpm/services/socketio/handlers/memory.py +26 -0
  706. claude_mpm/services/socketio/handlers/project.py +24 -0
  707. claude_mpm/services/socketio/handlers/registry.py +214 -0
  708. claude_mpm/services/socketio/migration_utils.py +343 -0
  709. claude_mpm/services/socketio/monitor_client.py +364 -0
  710. claude_mpm/services/socketio/server/__init__.py +18 -0
  711. claude_mpm/services/socketio/server/broadcaster.py +569 -0
  712. claude_mpm/services/socketio/server/connection_manager.py +579 -0
  713. claude_mpm/services/socketio/server/core.py +1079 -0
  714. claude_mpm/services/socketio/server/eventbus_integration.py +245 -0
  715. claude_mpm/services/socketio/server/main.py +501 -0
  716. claude_mpm/services/socketio_client_manager.py +173 -143
  717. claude_mpm/services/socketio_server.py +38 -1657
  718. claude_mpm/services/subprocess_launcher_service.py +322 -0
  719. claude_mpm/services/system_instructions_service.py +270 -0
  720. claude_mpm/services/ticket_manager.py +25 -209
  721. claude_mpm/services/ticket_services/__init__.py +26 -0
  722. claude_mpm/services/ticket_services/crud_service.py +328 -0
  723. claude_mpm/services/ticket_services/formatter_service.py +290 -0
  724. claude_mpm/services/ticket_services/search_service.py +324 -0
  725. claude_mpm/services/ticket_services/validation_service.py +303 -0
  726. claude_mpm/services/ticket_services/workflow_service.py +244 -0
  727. claude_mpm/services/unified/__init__.py +65 -0
  728. claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
  729. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
  730. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
  731. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
  732. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
  733. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
  734. claude_mpm/services/unified/config_strategies/__init__.py +175 -0
  735. claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
  736. claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
  737. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
  738. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
  739. claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
  740. claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
  741. claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
  742. claude_mpm/services/unified/deployment_strategies/base.py +553 -0
  743. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
  744. claude_mpm/services/unified/deployment_strategies/local.py +607 -0
  745. claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
  746. claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
  747. claude_mpm/services/unified/interfaces.py +475 -0
  748. claude_mpm/services/unified/migration.py +509 -0
  749. claude_mpm/services/unified/strategies.py +534 -0
  750. claude_mpm/services/unified/unified_analyzer.py +542 -0
  751. claude_mpm/services/unified/unified_config.py +691 -0
  752. claude_mpm/services/unified/unified_deployment.py +466 -0
  753. claude_mpm/services/utility_service.py +280 -0
  754. claude_mpm/services/version_control/__init__.py +34 -37
  755. claude_mpm/services/version_control/branch_strategy.py +26 -17
  756. claude_mpm/services/version_control/conflict_resolution.py +52 -36
  757. claude_mpm/services/version_control/git_operations.py +183 -49
  758. claude_mpm/services/version_control/semantic_versioning.py +172 -61
  759. claude_mpm/services/version_control/version_parser.py +546 -0
  760. claude_mpm/services/version_service.py +379 -0
  761. claude_mpm/services/visualization/__init__.py +15 -0
  762. claude_mpm/services/visualization/mermaid_generator.py +937 -0
  763. claude_mpm/skills/__init__.py +42 -0
  764. claude_mpm/skills/agent_skills_injector.py +324 -0
  765. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  766. claude_mpm/skills/bundled/__init__.py +6 -0
  767. claude_mpm/skills/bundled/api-documentation.md +393 -0
  768. claude_mpm/skills/bundled/async-testing.md +571 -0
  769. claude_mpm/skills/bundled/code-review.md +143 -0
  770. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  771. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  772. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  773. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  774. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  775. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  776. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  777. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  778. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  779. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  780. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  781. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  782. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  783. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  784. claude_mpm/skills/bundled/database-migration.md +199 -0
  785. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  786. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  787. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  788. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  789. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  790. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  791. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  792. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  793. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  794. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  795. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  796. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  797. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  798. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  799. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  800. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  801. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  802. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  803. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  804. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  805. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  806. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  807. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  808. claude_mpm/skills/bundled/git-workflow.md +414 -0
  809. claude_mpm/skills/bundled/imagemagick.md +204 -0
  810. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  811. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  812. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  813. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  814. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  815. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  816. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  817. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  818. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  819. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  820. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  821. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  822. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  823. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  824. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  825. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  826. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  827. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  828. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  829. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  830. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  831. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  832. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  833. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  834. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  835. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  836. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  837. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  838. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  839. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  840. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  841. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  842. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  843. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  844. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  845. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  846. claude_mpm/skills/bundled/pdf.md +141 -0
  847. claude_mpm/skills/bundled/performance-profiling.md +573 -0
  848. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  849. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  850. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  851. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  852. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  853. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  854. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  855. claude_mpm/skills/bundled/pm/pm-bug-reporting/pm-bug-reporting.md +248 -0
  856. claude_mpm/skills/bundled/pm/pm-delegation-patterns/SKILL.md +167 -0
  857. claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md +113 -0
  858. claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md +124 -0
  859. claude_mpm/skills/bundled/pm/pm-teaching-mode/SKILL.md +657 -0
  860. claude_mpm/skills/bundled/pm/pm-ticketing-integration/SKILL.md +154 -0
  861. claude_mpm/skills/bundled/pm/pm-verification-protocols/SKILL.md +198 -0
  862. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  863. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  864. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  865. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  866. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  867. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  868. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  869. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  870. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  871. claude_mpm/skills/bundled/security-scanning.md +439 -0
  872. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  873. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  874. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  875. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  876. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  877. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  878. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  879. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  880. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  881. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  882. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  883. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  884. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  885. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  886. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  887. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  888. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  889. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  890. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  891. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  892. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  893. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  894. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  895. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  896. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  897. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  898. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  899. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  900. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  901. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  902. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  903. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  904. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  905. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  906. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  907. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  908. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  909. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  910. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  911. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  912. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  913. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  914. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  915. claude_mpm/skills/bundled/xlsx.md +157 -0
  916. claude_mpm/skills/registry.py +286 -0
  917. claude_mpm/skills/skill_manager.py +405 -0
  918. claude_mpm/skills/skills_registry.py +347 -0
  919. claude_mpm/skills/skills_service.py +739 -0
  920. claude_mpm/storage/__init__.py +9 -0
  921. claude_mpm/storage/state_storage.py +546 -0
  922. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  923. claude_mpm/templates/questions/__init__.py +38 -0
  924. claude_mpm/templates/questions/base.py +193 -0
  925. claude_mpm/templates/questions/pr_strategy.py +311 -0
  926. claude_mpm/templates/questions/project_init.py +385 -0
  927. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  928. claude_mpm/ticket_wrapper.py +2 -2
  929. claude_mpm/tools/__init__.py +10 -0
  930. claude_mpm/tools/__main__.py +208 -0
  931. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  932. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  933. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  934. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  935. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  936. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  937. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  938. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  939. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  940. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  941. claude_mpm/tools/code_tree_builder.py +631 -0
  942. claude_mpm/tools/code_tree_events.py +420 -0
  943. claude_mpm/tools/socketio_debug.py +671 -0
  944. claude_mpm/utils/__init__.py +8 -8
  945. claude_mpm/utils/agent_dependency_loader.py +1189 -0
  946. claude_mpm/utils/agent_filters.py +261 -0
  947. claude_mpm/utils/common.py +544 -0
  948. claude_mpm/utils/config_manager.py +168 -126
  949. claude_mpm/utils/console.py +11 -0
  950. claude_mpm/utils/database_connector.py +298 -0
  951. claude_mpm/utils/dependency_cache.py +373 -0
  952. claude_mpm/utils/dependency_manager.py +60 -59
  953. claude_mpm/utils/dependency_strategies.py +381 -0
  954. claude_mpm/utils/display_helper.py +260 -0
  955. claude_mpm/utils/environment_context.py +313 -0
  956. claude_mpm/utils/error_handler.py +78 -66
  957. claude_mpm/utils/file_utils.py +305 -0
  958. claude_mpm/utils/framework_detection.py +12 -11
  959. claude_mpm/utils/git_analyzer.py +407 -0
  960. claude_mpm/utils/gitignore.py +244 -0
  961. claude_mpm/utils/import_migration_example.py +12 -60
  962. claude_mpm/utils/imports.py +48 -45
  963. claude_mpm/utils/log_cleanup.py +627 -0
  964. claude_mpm/utils/migration.py +372 -0
  965. claude_mpm/utils/path_operations.py +110 -104
  966. claude_mpm/utils/progress.py +387 -0
  967. claude_mpm/utils/robust_installer.py +844 -0
  968. claude_mpm/utils/session_logging.py +121 -0
  969. claude_mpm/utils/structured_questions.py +619 -0
  970. claude_mpm/utils/subprocess_utils.py +343 -0
  971. claude_mpm/validation/__init__.py +1 -1
  972. claude_mpm/validation/agent_validator.py +214 -108
  973. claude_mpm/validation/frontmatter_validator.py +252 -0
  974. claude_mpm-5.4.85.dist-info/METADATA +1023 -0
  975. claude_mpm-5.4.85.dist-info/RECORD +980 -0
  976. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/entry_points.txt +1 -3
  977. claude_mpm-5.4.85.dist-info/licenses/LICENSE +94 -0
  978. claude_mpm-5.4.85.dist-info/licenses/LICENSE-FAQ.md +153 -0
  979. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -88
  980. claude_mpm/agents/INSTRUCTIONS.md +0 -352
  981. claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
  982. claude_mpm/agents/base_agent_loader.py +0 -529
  983. claude_mpm/agents/schema/agent_schema.json +0 -314
  984. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
  985. claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -46
  986. claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -45
  987. claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -49
  988. claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -46
  989. claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -45
  990. claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -49
  991. claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -46
  992. claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -46
  993. claude_mpm/agents/templates/data_engineer.json +0 -110
  994. claude_mpm/agents/templates/documentation.json +0 -109
  995. claude_mpm/agents/templates/engineer.json +0 -113
  996. claude_mpm/agents/templates/ops.json +0 -109
  997. claude_mpm/agents/templates/pm.json +0 -25
  998. claude_mpm/agents/templates/qa.json +0 -111
  999. claude_mpm/agents/templates/research.json +0 -65
  1000. claude_mpm/agents/templates/security.json +0 -113
  1001. claude_mpm/agents/templates/test_integration.json +0 -112
  1002. claude_mpm/agents/templates/version_control.json +0 -107
  1003. claude_mpm/cli/commands/ui.py +0 -57
  1004. claude_mpm/core/simple_runner.py +0 -1046
  1005. claude_mpm/dashboard/open_dashboard.py +0 -34
  1006. claude_mpm/deployment_paths.py +0 -261
  1007. claude_mpm/hooks/builtin/__init__.py +0 -1
  1008. claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
  1009. claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
  1010. claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
  1011. claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
  1012. claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
  1013. claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
  1014. claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
  1015. claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
  1016. claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
  1017. claude_mpm/orchestration/__init__.py +0 -6
  1018. claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
  1019. claude_mpm/orchestration/archive/factory.py +0 -215
  1020. claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
  1021. claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
  1022. claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
  1023. claude_mpm/orchestration/archive/orchestrator.py +0 -501
  1024. claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
  1025. claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
  1026. claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
  1027. claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
  1028. claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
  1029. claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
  1030. claude_mpm/schemas/workflow_validator.py +0 -411
  1031. claude_mpm/services/agent_deployment.py +0 -1534
  1032. claude_mpm/services/agent_lifecycle_manager.py +0 -1169
  1033. claude_mpm/services/agent_memory_manager.py +0 -1415
  1034. claude_mpm/services/agent_registry.py +0 -676
  1035. claude_mpm/services/deployed_agent_discovery.py +0 -226
  1036. claude_mpm/services/framework_agent_loader.py +0 -337
  1037. claude_mpm/services/framework_claude_md_generator.py +0 -621
  1038. claude_mpm/services/health_monitor.py +0 -892
  1039. claude_mpm/services/memory_router.py +0 -538
  1040. claude_mpm/services/parent_directory_manager/__init__.py +0 -577
  1041. claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
  1042. claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
  1043. claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
  1044. claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
  1045. claude_mpm/services/parent_directory_manager/operations.py +0 -186
  1046. claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
  1047. claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
  1048. claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
  1049. claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
  1050. claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
  1051. claude_mpm/services/standalone_socketio_server.py +0 -1300
  1052. claude_mpm/services/ticket_manager_di.py +0 -318
  1053. claude_mpm/services/ticketing_service_original.py +0 -508
  1054. claude_mpm/ui/__init__.py +0 -1
  1055. claude_mpm/ui/rich_terminal_ui.py +0 -295
  1056. claude_mpm/ui/terminal_ui.py +0 -328
  1057. claude_mpm/utils/paths.py +0 -289
  1058. claude_mpm-3.4.10.dist-info/METADATA +0 -183
  1059. claude_mpm-3.4.10.dist-info/RECORD +0 -201
  1060. claude_mpm-3.4.10.dist-info/licenses/LICENSE +0 -21
  1061. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/WHEEL +0 -0
  1062. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1076 @@
1
+ """
2
+ Unified Daemon Manager Service
3
+ ==============================
4
+
5
+ WHY: This service consolidates ALL daemon lifecycle operations into a single place,
6
+ eliminating duplicate code and race conditions from having daemon management logic
7
+ scattered across multiple files.
8
+
9
+ DESIGN DECISIONS:
10
+ - Single source of truth for all daemon operations
11
+ - Robust port cleanup with retry logic
12
+ - Thread-safe operations with proper locking
13
+ - Comprehensive error handling and recovery
14
+ - Supports both foreground and background/daemon modes
15
+ - Manages PID files, port conflicts, and process lifecycle
16
+
17
+ This replaces duplicate logic that was in:
18
+ - UnifiedMonitorDaemon._cleanup_port_conflicts()
19
+ - UnifiedDashboardManager._cleanup_port_conflicts()
20
+ - Various daemon startup/stop logic spread across files
21
+ """
22
+
23
+ import os
24
+ import signal
25
+ import socket
26
+ import subprocess
27
+ import sys
28
+ import tempfile
29
+ import threading
30
+ import time
31
+ from pathlib import Path
32
+ from typing import Optional, Tuple
33
+
34
+ from ...core.enums import OperationResult
35
+ from ...core.logging_config import get_logger
36
+
37
+ # Exit code constants for signal handling
38
+ EXIT_NORMAL = 0
39
+ EXIT_SIGKILL = 137 # 128 + SIGKILL(9) - forced termination
40
+ EXIT_SIGTERM = 143 # 128 + SIGTERM(15) - graceful shutdown
41
+
42
+
43
+ class DaemonManager:
44
+ """Centralized manager for all daemon lifecycle operations.
45
+
46
+ This is the SINGLE source of truth for:
47
+ - Port conflict resolution
48
+ - Process cleanup
49
+ - Daemon startup/stop
50
+ - PID file management
51
+ - Service detection
52
+ """
53
+
54
+ # Class-level lock for thread safety
55
+ _lock = threading.Lock()
56
+
57
+ def __init__(
58
+ self,
59
+ port: int = 8765,
60
+ host: str = "localhost",
61
+ pid_file: Optional[str] = None,
62
+ log_file: Optional[str] = None,
63
+ ):
64
+ """Initialize the daemon manager.
65
+
66
+ Args:
67
+ port: Port number for the daemon
68
+ host: Host to bind to
69
+ pid_file: Path to PID file (uses default if None)
70
+ log_file: Path to log file for daemon mode
71
+ """
72
+ self.port = port
73
+ self.host = host
74
+ self.logger = get_logger(__name__)
75
+
76
+ # Set up paths
77
+ if pid_file:
78
+ self.pid_file = Path(pid_file)
79
+ else:
80
+ self.pid_file = self._get_default_pid_file()
81
+
82
+ self.log_file = Path(log_file) if log_file else self._get_default_log_file()
83
+
84
+ # Startup status communication
85
+ self.startup_status_file = None
86
+
87
+ def _get_default_pid_file(self) -> Path:
88
+ """Get default PID file path with port number to support multiple daemons."""
89
+ project_root = Path.cwd()
90
+ claude_mpm_dir = project_root / ".claude-mpm"
91
+ claude_mpm_dir.mkdir(exist_ok=True)
92
+ # Include port in filename to support multiple daemon instances
93
+ return claude_mpm_dir / f"monitor-daemon-{self.port}.pid"
94
+
95
+ def _get_default_log_file(self) -> Path:
96
+ """Get default log file path with port number to support multiple daemons."""
97
+ project_root = Path.cwd()
98
+ claude_mpm_dir = project_root / ".claude-mpm"
99
+ claude_mpm_dir.mkdir(exist_ok=True)
100
+ # Include port in filename to support multiple daemon instances
101
+ return claude_mpm_dir / f"monitor-daemon-{self.port}.log"
102
+
103
+ def cleanup_port_conflicts(self, max_retries: int = 3) -> bool:
104
+ """Clean up any processes using the daemon port.
105
+
106
+ This is the SINGLE implementation for port cleanup, replacing
107
+ duplicate logic in multiple files.
108
+
109
+ Args:
110
+ max_retries: Maximum number of cleanup attempts
111
+
112
+ Returns:
113
+ True if port is available after cleanup, False otherwise
114
+ """
115
+ with self._lock:
116
+ for attempt in range(max_retries):
117
+ if attempt > 0:
118
+ self.logger.info(
119
+ f"Port cleanup attempt {attempt + 1}/{max_retries}"
120
+ )
121
+
122
+ # First check if port is actually in use
123
+ if self._is_port_available():
124
+ self.logger.debug(f"Port {self.port} is available")
125
+ return True
126
+
127
+ self.logger.info(f"Port {self.port} is in use, attempting cleanup")
128
+
129
+ # Try to find and kill processes using the port
130
+ if self._kill_processes_on_port():
131
+ # Wait for port to be released
132
+ time.sleep(2 if attempt == 0 else 3)
133
+
134
+ # Verify port is now free
135
+ if self._is_port_available():
136
+ self.logger.info(f"Port {self.port} successfully cleaned up")
137
+ return True
138
+
139
+ if attempt < max_retries - 1:
140
+ # Wait longer between attempts
141
+ time.sleep(3)
142
+
143
+ self.logger.error(
144
+ f"Failed to clean up port {self.port} after {max_retries} attempts"
145
+ )
146
+ return False
147
+
148
+ def _is_port_available(self) -> bool:
149
+ """Check if the port is available for binding.
150
+
151
+ Returns:
152
+ True if port is available, False otherwise
153
+ """
154
+ # Try to bind to the port using the same method as the actual server
155
+ # We only need to check if we can bind to at least one address family
156
+ try:
157
+ # Try IPv4 first (most common)
158
+ test_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
159
+ test_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
160
+
161
+ # Use 127.0.0.1 for localhost to match what the server does
162
+ bind_host = "127.0.0.1" if self.host == "localhost" else self.host
163
+ test_sock.bind((bind_host, self.port))
164
+ test_sock.close()
165
+ return True
166
+ except OSError:
167
+ # IPv4 failed, try IPv6
168
+ try:
169
+ test_sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
170
+ test_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
171
+ test_sock.bind(("::1", self.port))
172
+ test_sock.close()
173
+ return True
174
+ except Exception:
175
+ # Both IPv4 and IPv6 failed - port is in use
176
+ return False
177
+
178
+ def _kill_processes_on_port(self) -> bool:
179
+ """Kill processes using the daemon port.
180
+
181
+ Returns:
182
+ True if processes were killed or none found, False on error
183
+ """
184
+ try:
185
+ # Try using lsof first (most reliable)
186
+ if self._kill_using_lsof():
187
+ return True
188
+
189
+ # Fallback to checking our known PID file
190
+ if self._kill_using_pid_file():
191
+ return True
192
+
193
+ # Try to identify claude-mpm processes
194
+ return bool(self._kill_claude_mpm_processes())
195
+
196
+ except Exception as e:
197
+ self.logger.error(f"Error killing processes on port: {e}")
198
+ return False
199
+
200
+ def _kill_using_lsof(self) -> bool:
201
+ """Kill processes using lsof to find them.
202
+
203
+ Returns:
204
+ True if successful or lsof not available, False on error
205
+ """
206
+ try:
207
+ # Find processes using the port
208
+ result = subprocess.run(
209
+ ["lsof", "-ti", f":{self.port}"],
210
+ capture_output=True,
211
+ text=True,
212
+ check=False,
213
+ )
214
+
215
+ if result.returncode != 0 or not result.stdout.strip():
216
+ self.logger.debug(f"No processes found using port {self.port}")
217
+ return True
218
+
219
+ pids = result.stdout.strip().split("\n")
220
+ self.logger.info(f"Found processes using port {self.port}: {pids}")
221
+
222
+ # Kill each process
223
+ for pid_str in pids:
224
+ try:
225
+ pid = int(pid_str.strip())
226
+
227
+ # Check if it's a Python/Claude process
228
+ process_info = subprocess.run(
229
+ ["ps", "-p", str(pid), "-o", "comm="],
230
+ capture_output=True,
231
+ text=True,
232
+ check=False,
233
+ )
234
+
235
+ # Get full command to check if it's our monitor process
236
+ cmd_info = subprocess.run(
237
+ ["ps", "-p", str(pid), "-o", "command="],
238
+ capture_output=True,
239
+ text=True,
240
+ check=False,
241
+ )
242
+
243
+ if cmd_info.returncode != 0:
244
+ continue
245
+
246
+ full_command = cmd_info.stdout.strip().lower()
247
+ process_name = process_info.stdout.strip().lower()
248
+
249
+ # Check if this is our monitor/socketio process specifically
250
+ # Look for monitor, socketio, dashboard, or our specific port
251
+ is_monitor = any(
252
+ [
253
+ "monitor" in full_command,
254
+ "socketio" in full_command,
255
+ "dashboard" in full_command,
256
+ f"port={self.port}" in full_command,
257
+ f":{self.port}" in full_command,
258
+ "unified_monitor" in full_command,
259
+ ]
260
+ )
261
+
262
+ if is_monitor and "python" in process_name:
263
+ self.logger.info(
264
+ f"Killing monitor process {pid}: {full_command[:100]}"
265
+ )
266
+ os.kill(pid, signal.SIGTERM)
267
+
268
+ # Wait briefly for graceful shutdown
269
+ time.sleep(1)
270
+
271
+ # Check if still alive and force kill if needed
272
+ try:
273
+ os.kill(pid, 0) # Check if process exists
274
+ self.logger.warning(
275
+ f"Process {pid} didn't terminate, force killing"
276
+ )
277
+ os.kill(pid, signal.SIGKILL)
278
+ time.sleep(0.5)
279
+ except ProcessLookupError:
280
+ pass # Process already dead
281
+ else:
282
+ # Not a monitor process - log but don't fail
283
+ self.logger.info(
284
+ f"Skipping non-monitor process {pid} ({process_name})"
285
+ )
286
+ # Continue to next PID - don't return False
287
+ continue
288
+
289
+ except (ValueError, ProcessLookupError) as e:
290
+ self.logger.debug(f"Error handling PID {pid_str}: {e}")
291
+ continue
292
+
293
+ return True
294
+
295
+ except FileNotFoundError:
296
+ # lsof not available
297
+ self.logger.debug("lsof not available, using alternative methods")
298
+ return True
299
+ except Exception as e:
300
+ self.logger.error(f"Error using lsof: {e}")
301
+ return False
302
+
303
+ def _kill_using_pid_file(self) -> bool:
304
+ """Kill process using PID file.
305
+
306
+ Returns:
307
+ True if successful or no PID file, False on error
308
+ """
309
+ try:
310
+ if not self.pid_file.exists():
311
+ return True
312
+
313
+ with self.pid_file.open() as f:
314
+ pid = int(f.read().strip())
315
+
316
+ self.logger.info(f"Found PID {pid} in PID file")
317
+
318
+ # Kill the process
319
+ try:
320
+ os.kill(pid, signal.SIGTERM)
321
+ time.sleep(1)
322
+
323
+ # Check if still alive
324
+ try:
325
+ os.kill(pid, 0)
326
+ os.kill(pid, signal.SIGKILL)
327
+ time.sleep(0.5)
328
+ except ProcessLookupError:
329
+ pass
330
+
331
+ # Remove PID file
332
+ self.pid_file.unlink(missing_ok=True)
333
+ return True
334
+
335
+ except ProcessLookupError:
336
+ # Process doesn't exist, just remove PID file
337
+ self.pid_file.unlink(missing_ok=True)
338
+ return True
339
+
340
+ except Exception as e:
341
+ self.logger.error(f"Error killing process from PID file: {e}")
342
+ return False
343
+
344
+ def _kill_claude_mpm_processes(self) -> bool:
345
+ """Kill any claude-mpm monitor processes specifically.
346
+
347
+ This targets monitor/dashboard/socketio processes only,
348
+ NOT general Claude instances.
349
+
350
+ Returns:
351
+ True if successful, False on error
352
+ """
353
+ try:
354
+ # Look for monitor-specific processes
355
+ result = subprocess.run(
356
+ ["ps", "aux"], capture_output=True, text=True, check=False
357
+ )
358
+
359
+ if result.returncode != 0:
360
+ return False
361
+
362
+ lines = result.stdout.strip().split("\n")
363
+ killed_any = False
364
+
365
+ for line in lines:
366
+ line_lower = line.lower()
367
+ # Only target monitor/dashboard/socketio processes
368
+ if any(
369
+ [
370
+ "monitor" in line_lower and "claude" in line_lower,
371
+ "dashboard" in line_lower and "claude" in line_lower,
372
+ "socketio" in line_lower,
373
+ f":{self.port}" in line_lower and "python" in line_lower,
374
+ ]
375
+ ):
376
+ parts = line.split()
377
+ if len(parts) > 1:
378
+ try:
379
+ pid = int(parts[1])
380
+ self.logger.info(
381
+ f"Killing claude-mpm monitor process {pid}"
382
+ )
383
+ os.kill(pid, signal.SIGTERM)
384
+ killed_any = True
385
+ time.sleep(0.5)
386
+ except (ValueError, ProcessLookupError):
387
+ continue
388
+
389
+ if killed_any:
390
+ time.sleep(1) # Give processes time to exit
391
+
392
+ return True
393
+
394
+ except Exception as e:
395
+ self.logger.error(f"Error killing claude-mpm processes: {e}")
396
+ return False
397
+
398
+ def is_our_service(self) -> Tuple[bool, Optional[int]]:
399
+ """Check if the service on the port is our claude-mpm monitor.
400
+
401
+ Returns:
402
+ Tuple of (is_ours, pid) where is_ours is True if it's our service
403
+ """
404
+ try:
405
+ # First check PID file
406
+ if self.pid_file.exists():
407
+ try:
408
+ with self.pid_file.open() as f:
409
+ pid = int(f.read().strip())
410
+
411
+ # Verify process exists
412
+ os.kill(pid, 0)
413
+
414
+ # Check if it's a Python process
415
+ process_info = subprocess.run(
416
+ ["ps", "-p", str(pid), "-o", "comm="],
417
+ capture_output=True,
418
+ text=True,
419
+ check=False,
420
+ )
421
+
422
+ if "python" in process_info.stdout.lower():
423
+ return True, pid
424
+
425
+ except (ValueError, ProcessLookupError, subprocess.CalledProcessError):
426
+ # PID file exists but process doesn't or isn't Python
427
+ self.pid_file.unlink(missing_ok=True)
428
+
429
+ # Check if service responds to our health endpoint
430
+ try:
431
+ import requests
432
+
433
+ response = requests.get(
434
+ f"http://{self.host}:{self.port}/health", timeout=2
435
+ )
436
+
437
+ if response.status_code == 200:
438
+ # Try to get service info
439
+ try:
440
+ data = response.json()
441
+ if "claude" in str(data).lower() or "mpm" in str(data).lower():
442
+ # It's likely our service, try to find PID
443
+ pid = self._find_service_pid()
444
+ return True, pid
445
+ except Exception:
446
+ pass
447
+
448
+ except Exception:
449
+ pass
450
+
451
+ return False, None
452
+
453
+ except Exception as e:
454
+ self.logger.error(f"Error checking service ownership: {e}")
455
+ return False, None
456
+
457
+ def _find_service_pid(self) -> Optional[int]:
458
+ """Find PID of service on our port using lsof.
459
+
460
+ Returns:
461
+ PID if found, None otherwise
462
+ """
463
+ try:
464
+ result = subprocess.run(
465
+ ["lsof", "-ti", f":{self.port}"],
466
+ capture_output=True,
467
+ text=True,
468
+ check=False,
469
+ )
470
+
471
+ if result.returncode == 0 and result.stdout.strip():
472
+ pids = result.stdout.strip().split("\n")
473
+ if pids:
474
+ return int(pids[0].strip())
475
+
476
+ except Exception:
477
+ pass
478
+
479
+ return None
480
+
481
+ def _verify_daemon_health(self, max_attempts: int = 3) -> bool:
482
+ """Verify daemon is healthy by checking HTTP health endpoint.
483
+
484
+ Args:
485
+ max_attempts: Maximum number of connection attempts
486
+
487
+ Returns:
488
+ True if health check passes, False otherwise
489
+ """
490
+ try:
491
+ import requests
492
+
493
+ for attempt in range(max_attempts):
494
+ try:
495
+ # Try to connect to health endpoint
496
+ response = requests.get(
497
+ f"http://{self.host}:{self.port}/health", timeout=2
498
+ )
499
+
500
+ if response.status_code == 200:
501
+ self.logger.debug(
502
+ f"Health check passed on attempt {attempt + 1}/{max_attempts}"
503
+ )
504
+ return True
505
+
506
+ self.logger.debug(
507
+ f"Health check returned status {response.status_code} on attempt {attempt + 1}/{max_attempts}"
508
+ )
509
+
510
+ except requests.exceptions.RequestException as e:
511
+ self.logger.debug(
512
+ f"Health check attempt {attempt + 1}/{max_attempts} failed: {e}"
513
+ )
514
+
515
+ # Wait before retry (except on last attempt)
516
+ if attempt < max_attempts - 1:
517
+ time.sleep(1)
518
+
519
+ self.logger.debug(f"Health check failed after {max_attempts} attempts")
520
+ return False
521
+
522
+ except ImportError:
523
+ # requests not available, skip health check
524
+ self.logger.debug("requests library not available, skipping health check")
525
+ return True
526
+ except Exception as e:
527
+ self.logger.debug(f"Health check error: {e}")
528
+ return False
529
+
530
+ def start_daemon(self, force_restart: bool = False) -> bool:
531
+ """Start the daemon with automatic cleanup and retry.
532
+
533
+ Args:
534
+ force_restart: Force restart even if already running
535
+
536
+ Returns:
537
+ True if daemon started successfully
538
+ """
539
+ with self._lock:
540
+ # Check if already running
541
+ if self.is_running():
542
+ if not force_restart:
543
+ pid = self.get_pid()
544
+ self.logger.info(f"Daemon already running with PID {pid}")
545
+ return True
546
+
547
+ # Stop existing daemon
548
+ self.logger.info("Force restarting daemon")
549
+ if not self.stop_daemon():
550
+ self.logger.error("Failed to stop existing daemon")
551
+ return False
552
+
553
+ # Wait for cleanup
554
+ time.sleep(2)
555
+
556
+ # Clean up port conflicts
557
+ if not self.cleanup_port_conflicts():
558
+ self.logger.error(f"Cannot start daemon - port {self.port} is in use")
559
+ return False
560
+
561
+ # Use subprocess for clean daemon startup (v4.2.40)
562
+ # This avoids fork() issues with Python threading
563
+ if self.use_subprocess_daemon():
564
+ return self.start_daemon_subprocess(force_restart=force_restart)
565
+ # Fallback to traditional fork (kept for compatibility)
566
+ return self.daemonize()
567
+
568
+ def use_subprocess_daemon(self) -> bool:
569
+ """Check if we should use subprocess instead of fork for daemonization.
570
+
571
+ Returns:
572
+ True to use subprocess (safer), False to use traditional fork
573
+ """
574
+ # Check if we're already in a subprocess to prevent infinite recursion
575
+ if os.environ.get("CLAUDE_MPM_SUBPROCESS_DAEMON") == "1":
576
+ # We're already in a subprocess, use traditional fork
577
+ return False
578
+
579
+ # Otherwise, use subprocess for monitor daemon to avoid threading issues
580
+ return True
581
+
582
+ def start_daemon_subprocess(self, force_restart: bool = False) -> bool:
583
+ """Start daemon using subprocess.Popen for clean process isolation.
584
+
585
+ This avoids all the fork() + threading issues by starting the monitor
586
+ in a completely fresh process with no inherited threads or locks.
587
+
588
+ Args:
589
+ force_restart: Whether this is a force restart (helps interpret exit codes)
590
+
591
+ Returns:
592
+ True if daemon started successfully
593
+ """
594
+ try:
595
+ # Build command to run monitor in foreground mode in subprocess
596
+ import sys
597
+
598
+ python_exe = sys.executable
599
+
600
+ # Run 'claude-mpm monitor start' in subprocess with environment variable
601
+ # to indicate we're already in a subprocess (prevents infinite recursion)
602
+ cmd = [
603
+ python_exe,
604
+ "-m",
605
+ "claude_mpm.cli",
606
+ "monitor",
607
+ "start",
608
+ "--background", # Run as daemon
609
+ "--port",
610
+ str(self.port),
611
+ "--host",
612
+ self.host,
613
+ ]
614
+
615
+ # Set environment variable to prevent recursive subprocess creation
616
+ env = os.environ.copy()
617
+ env["CLAUDE_MPM_SUBPROCESS_DAEMON"] = "1"
618
+
619
+ self.logger.info(f"Starting monitor daemon via subprocess: {' '.join(cmd)}")
620
+
621
+ # Open log file for output redirection
622
+ log_file_handle = None
623
+ if self.log_file:
624
+ log_file_handle = Path(self.log_file).open("a")
625
+ log_file = log_file_handle
626
+ else:
627
+ log_file = subprocess.DEVNULL
628
+
629
+ try:
630
+ # Start the subprocess detached from parent
631
+ # Redirect stdout/stderr to log file to capture output
632
+ process = subprocess.Popen(
633
+ cmd,
634
+ stdin=subprocess.DEVNULL,
635
+ stdout=log_file,
636
+ stderr=subprocess.STDOUT if self.log_file else subprocess.DEVNULL,
637
+ start_new_session=True, # Create new process group
638
+ close_fds=(not self.log_file), # Keep log file open if redirecting
639
+ env=env, # Pass modified environment
640
+ )
641
+
642
+ # Close the log file handle now that subprocess has it
643
+ if log_file_handle:
644
+ log_file_handle.close()
645
+
646
+ # Get the process PID
647
+ pid = process.pid
648
+ self.logger.info(f"Monitor subprocess started with PID {pid}")
649
+
650
+ # Wait for the subprocess to write its PID file and bind to port
651
+ # The subprocess will write the PID file after it starts successfully
652
+ max_wait = 10 # seconds
653
+ start_time = time.time()
654
+ pid_file_found = False
655
+ port_bound = False
656
+
657
+ self.logger.debug(f"Waiting up to {max_wait}s for daemon to start...")
658
+
659
+ while time.time() - start_time < max_wait:
660
+ # Check if process is still running
661
+ returncode = process.poll()
662
+ if returncode is not None:
663
+ # Process exited - interpret exit code with context
664
+ # Exit codes 137 (SIGKILL) and 143 (SIGTERM) are common during daemon replacement
665
+ if returncode == EXIT_SIGKILL:
666
+ # SIGKILL - process was forcefully terminated
667
+ if force_restart:
668
+ # This is expected during force restart - old daemon was killed
669
+ self.logger.info(
670
+ f"Previous monitor instance replaced (exit {EXIT_SIGKILL}: SIGKILL during force restart)"
671
+ )
672
+ else:
673
+ # Unexpected SIGKILL - something else killed our new daemon
674
+ self.logger.warning(
675
+ f"Monitor subprocess terminated unexpectedly (exit {EXIT_SIGKILL}: SIGKILL). "
676
+ f"Check {self.log_file} for details."
677
+ )
678
+ return False
679
+ if returncode == EXIT_SIGTERM:
680
+ # SIGTERM - graceful shutdown requested
681
+ self.logger.info(
682
+ f"Monitor subprocess cleanly terminated (exit {EXIT_SIGTERM}: SIGTERM, graceful shutdown)"
683
+ )
684
+ return False
685
+ if returncode == EXIT_NORMAL:
686
+ # Normal exit
687
+ self.logger.info(
688
+ f"Monitor subprocess exited normally (exit code {EXIT_NORMAL})"
689
+ )
690
+ return False
691
+ # Unexpected exit code - this IS an error
692
+ self.logger.error(
693
+ f"Monitor daemon subprocess exited prematurely with code {returncode}"
694
+ )
695
+ self.logger.error(
696
+ f"Port {self.port} daemon failed to start. Check {self.log_file} for details."
697
+ )
698
+ return False
699
+
700
+ # Check if PID file was written
701
+ if not pid_file_found and self.pid_file.exists():
702
+ try:
703
+ with self.pid_file.open() as f:
704
+ written_pid = int(f.read().strip())
705
+ if written_pid == pid:
706
+ pid_file_found = True
707
+ self.logger.debug(
708
+ f"PID file found with correct PID {pid}"
709
+ )
710
+ except Exception as e:
711
+ self.logger.debug(f"Error reading PID file: {e}")
712
+
713
+ # Check if port is bound (health check)
714
+ if not port_bound and not self._is_port_available():
715
+ # Port NOT available means it's in use (good!)
716
+ port_bound = True
717
+ self.logger.debug(f"Port {self.port} is now bound")
718
+
719
+ # Success criteria: both PID file exists and port is bound
720
+ if pid_file_found and port_bound:
721
+ self.logger.info(
722
+ f"Monitor daemon successfully started on port {self.port} (PID: {pid})"
723
+ )
724
+ # Additional health check: verify we can connect
725
+ if self._verify_daemon_health(max_attempts=3):
726
+ self.logger.info("Daemon health check passed")
727
+ return True
728
+ self.logger.warning(
729
+ "Daemon started but health check failed - may still be initializing"
730
+ )
731
+ return (
732
+ True # Return success anyway if PID file and port are good
733
+ )
734
+
735
+ time.sleep(0.5)
736
+
737
+ # Timeout waiting for daemon to start
738
+ self.logger.error("Timeout waiting for monitor daemon to start")
739
+ # Try to kill the process if it's still running
740
+ if process.poll() is None:
741
+ process.terminate()
742
+ time.sleep(1)
743
+ if process.poll() is None:
744
+ process.kill()
745
+ return False
746
+ finally:
747
+ # Clean up log file handle if still open
748
+ if log_file_handle and not log_file_handle.closed:
749
+ log_file_handle.close()
750
+
751
+ except Exception as e:
752
+ self.logger.error(f"Failed to start daemon via subprocess: {e}")
753
+ return False
754
+
755
+ def daemonize(self) -> bool:
756
+ """Daemonize the current process.
757
+
758
+ Returns:
759
+ True if successful (in parent), doesn't return in child
760
+ """
761
+ # Guard against re-entrant execution after fork
762
+ if hasattr(self, "_forking_in_progress"):
763
+ self.logger.error(
764
+ "CRITICAL: Detected re-entrant daemonize call after fork!"
765
+ )
766
+ return False
767
+
768
+ self._forking_in_progress = True
769
+
770
+ try:
771
+ # Clean up asyncio event loops before forking
772
+ self._cleanup_event_loops()
773
+
774
+ # Create status file for communication
775
+ with tempfile.NamedTemporaryFile(
776
+ mode="w", delete=False, suffix=".status"
777
+ ) as f:
778
+ self.startup_status_file = f.name
779
+ f.write("starting")
780
+
781
+ # First fork
782
+ pid = os.fork()
783
+ if pid > 0:
784
+ # Parent process - wait for child to confirm startup
785
+ del self._forking_in_progress # Clean up in parent
786
+ return self._parent_wait_for_startup(pid)
787
+
788
+ except OSError as e:
789
+ self.logger.error(f"First fork failed: {e}")
790
+ return False
791
+
792
+ # Child process continues...
793
+
794
+ # Decouple from parent
795
+ os.chdir("/")
796
+ os.setsid()
797
+ os.umask(0)
798
+
799
+ try:
800
+ # Second fork
801
+ pid = os.fork()
802
+ if pid > 0:
803
+ # First child exits
804
+ sys.exit(0)
805
+ except OSError as e:
806
+ self.logger.error(f"Second fork failed: {e}")
807
+ self._report_startup_error(f"Second fork failed: {e}")
808
+ sys.exit(1)
809
+
810
+ # Grandchild process - the actual daemon
811
+
812
+ # Write PID file
813
+ self.write_pid_file()
814
+
815
+ # Redirect streams
816
+ self._redirect_streams()
817
+
818
+ # Setup signal handlers
819
+ self._setup_signal_handlers()
820
+
821
+ self.logger.info(f"Daemon process started with PID {os.getpid()}")
822
+
823
+ # DO NOT report success here - let the caller report after starting the service
824
+ # This prevents race conditions where we report success before the server starts
825
+ # self._report_startup_success() # REMOVED - caller must report
826
+
827
+ # Note: Daemon process continues running
828
+ # Caller is responsible for running the actual service AND reporting status
829
+ return True
830
+
831
+ def stop_daemon(self, timeout: int = 10) -> bool:
832
+ """Stop the daemon process.
833
+
834
+ Args:
835
+ timeout: Maximum time to wait for daemon to stop
836
+
837
+ Returns:
838
+ True if stopped successfully
839
+ """
840
+ with self._lock:
841
+ try:
842
+ pid = self.get_pid()
843
+ if not pid:
844
+ self.logger.info("No daemon PID found")
845
+ # Still try to clean up port
846
+ self.cleanup_port_conflicts()
847
+ return True
848
+
849
+ self.logger.info(f"Stopping daemon with PID {pid}")
850
+
851
+ # Send SIGTERM for graceful shutdown
852
+ try:
853
+ os.kill(pid, signal.SIGTERM)
854
+ except ProcessLookupError:
855
+ # Process already dead
856
+ self.cleanup_pid_file()
857
+ return True
858
+
859
+ # Wait for process to exit
860
+ start_time = time.time()
861
+ while time.time() - start_time < timeout:
862
+ try:
863
+ os.kill(pid, 0) # Check if still alive
864
+ time.sleep(0.5)
865
+ except ProcessLookupError:
866
+ # Process exited
867
+ self.cleanup_pid_file()
868
+ return True
869
+
870
+ # Force kill if still running
871
+ self.logger.warning("Daemon didn't stop gracefully, force killing")
872
+ try:
873
+ os.kill(pid, signal.SIGKILL)
874
+ time.sleep(1)
875
+ except ProcessLookupError:
876
+ pass
877
+
878
+ self.cleanup_pid_file()
879
+ return True
880
+
881
+ except Exception as e:
882
+ self.logger.error(f"Error stopping daemon: {e}")
883
+ return False
884
+
885
+ def is_running(self) -> bool:
886
+ """Check if daemon is running.
887
+
888
+ Returns:
889
+ True if daemon is running
890
+ """
891
+ try:
892
+ pid = self.get_pid()
893
+ if not pid:
894
+ return False
895
+
896
+ # Check if process exists
897
+ os.kill(pid, 0)
898
+ return True
899
+
900
+ except ProcessLookupError:
901
+ # Process doesn't exist
902
+ self.cleanup_pid_file()
903
+ return False
904
+
905
+ def get_pid(self) -> Optional[int]:
906
+ """Get daemon PID from PID file.
907
+
908
+ Returns:
909
+ PID if found, None otherwise
910
+ """
911
+ try:
912
+ if not self.pid_file.exists():
913
+ return None
914
+
915
+ with self.pid_file.open() as f:
916
+ return int(f.read().strip())
917
+
918
+ except Exception as e:
919
+ self.logger.error(f"Error reading PID file: {e}")
920
+ return None
921
+
922
+ def write_pid_file(self):
923
+ """Write current PID to PID file."""
924
+ try:
925
+ self.pid_file.parent.mkdir(parents=True, exist_ok=True)
926
+ with self.pid_file.open("w") as f:
927
+ f.write(str(os.getpid()))
928
+ self.logger.debug(f"PID file written: {self.pid_file}")
929
+ except Exception as e:
930
+ self.logger.error(f"Error writing PID file: {e}")
931
+ raise
932
+
933
+ def cleanup_pid_file(self):
934
+ """Remove PID file."""
935
+ try:
936
+ self.pid_file.unlink(missing_ok=True)
937
+ self.logger.debug("PID file removed")
938
+ except Exception as e:
939
+ self.logger.error(f"Error removing PID file: {e}")
940
+
941
+ def _cleanup_event_loops(self):
942
+ """Clean up asyncio event loops before forking."""
943
+ try:
944
+ import asyncio
945
+
946
+ try:
947
+ loop = asyncio.get_event_loop()
948
+ if loop and not loop.is_closed():
949
+ # Cancel pending tasks
950
+ pending = asyncio.all_tasks(loop)
951
+ for task in pending:
952
+ task.cancel()
953
+
954
+ # Stop and close loop
955
+ if loop.is_running():
956
+ loop.stop()
957
+
958
+ asyncio.set_event_loop(None)
959
+ loop.close()
960
+
961
+ except RuntimeError:
962
+ # No event loop
963
+ pass
964
+
965
+ except Exception as e:
966
+ self.logger.debug(f"Error cleaning up event loops: {e}")
967
+
968
+ def _redirect_streams(self):
969
+ """Redirect standard streams for daemon mode."""
970
+ try:
971
+ sys.stdout.flush()
972
+ sys.stderr.flush()
973
+
974
+ # Redirect stdin to /dev/null
975
+ with Path("/dev/null").open() as null_in:
976
+ os.dup2(null_in.fileno(), sys.stdin.fileno())
977
+
978
+ # Redirect stdout and stderr to log file
979
+ self.log_file.parent.mkdir(parents=True, exist_ok=True)
980
+ with self.log_file.open("a") as log_out:
981
+ os.dup2(log_out.fileno(), sys.stdout.fileno())
982
+ os.dup2(log_out.fileno(), sys.stderr.fileno())
983
+
984
+ except Exception as e:
985
+ self.logger.error(f"Error redirecting streams: {e}")
986
+
987
+ def _setup_signal_handlers(self):
988
+ """Setup signal handlers for graceful shutdown."""
989
+
990
+ def signal_handler(signum, frame):
991
+ self.logger.info(f"Received signal {signum}, shutting down")
992
+ self.cleanup_pid_file()
993
+ sys.exit(0)
994
+
995
+ signal.signal(signal.SIGTERM, signal_handler)
996
+ signal.signal(signal.SIGINT, signal_handler)
997
+
998
+ def _parent_wait_for_startup(self, child_pid: int, timeout: float = 10.0) -> bool:
999
+ """Parent process waits for child to confirm startup.
1000
+
1001
+ Args:
1002
+ child_pid: PID of child process
1003
+ timeout: Maximum time to wait
1004
+
1005
+ Returns:
1006
+ True if child started successfully
1007
+ """
1008
+ try:
1009
+ start_time = time.time()
1010
+
1011
+ while time.time() - start_time < timeout:
1012
+ if (
1013
+ not self.startup_status_file
1014
+ or not Path(self.startup_status_file).exists()
1015
+ ):
1016
+ time.sleep(0.1)
1017
+ continue
1018
+
1019
+ try:
1020
+ with self.startup_status_file.open() as f:
1021
+ status = f.read().strip()
1022
+
1023
+ if status == OperationResult.SUCCESS:
1024
+ # Cleanup status file
1025
+ Path(self.startup_status_file).unlink(missing_ok=True)
1026
+ return True
1027
+
1028
+ if status.startswith("error:"):
1029
+ error_msg = status[6:]
1030
+ self.logger.error(f"Daemon startup failed: {error_msg}")
1031
+ Path(self.startup_status_file).unlink(missing_ok=True)
1032
+ return False
1033
+
1034
+ except Exception:
1035
+ pass
1036
+
1037
+ time.sleep(0.1)
1038
+
1039
+ self.logger.error("Daemon startup timed out")
1040
+ return False
1041
+
1042
+ except Exception as e:
1043
+ self.logger.error(f"Error waiting for daemon startup: {e}")
1044
+ return False
1045
+
1046
+ def _report_startup_success(self):
1047
+ """Report successful startup to parent process."""
1048
+ if self.startup_status_file:
1049
+ try:
1050
+ # Don't check if file exists - we need to write to it regardless
1051
+ # The parent created it and is waiting for us to update it
1052
+ with self.startup_status_file.open("w") as f:
1053
+ f.write(OperationResult.SUCCESS)
1054
+ f.flush() # Ensure it's written immediately
1055
+ os.fsync(f.fileno()) # Force write to disk
1056
+ except Exception:
1057
+ # Logging might not work in daemon process after fork
1058
+ pass
1059
+
1060
+ def _report_startup_error(self, error: str):
1061
+ """Report startup error to parent process."""
1062
+ if self.startup_status_file:
1063
+ try:
1064
+ # Don't check if file exists - we need to write to it regardless
1065
+ with self.startup_status_file.open("w") as f:
1066
+ f.write(f"error:{error}")
1067
+ f.flush() # Ensure it's written immediately
1068
+ os.fsync(f.fileno()) # Force write to disk
1069
+ except Exception as e:
1070
+ # Try to write error to a debug file since logging might not work
1071
+ try:
1072
+ with Path("/tmp/daemon_debug_error.txt").open("a") as debug:
1073
+ debug.write(f"Error reporting error: {e}\n")
1074
+ debug.write(f"Status file: {self.startup_status_file}\n")
1075
+ except Exception:
1076
+ pass