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,1542 @@
1
+ """
2
+ MCP Configuration Manager
3
+ ========================
4
+
5
+ Manages MCP service configurations, preferring pipx installations
6
+ over local virtual environments for better isolation and management.
7
+
8
+ This module provides utilities to detect, configure, and validate
9
+ MCP service installations.
10
+ """
11
+
12
+ import json
13
+ import subprocess
14
+ import sys
15
+ from enum import Enum
16
+ from pathlib import Path
17
+ from typing import Dict, Optional, Tuple
18
+
19
+ from ..core.logger import get_logger
20
+
21
+
22
+ class ConfigLocation(Enum):
23
+ """Enumeration of Claude configuration file locations."""
24
+
25
+ CLAUDE_JSON = Path.home() / ".claude.json" # Primary Claude config
26
+ CLAUDE_DESKTOP = (
27
+ Path.home() / ".claude" / "claude_desktop_config.json"
28
+ ) # Not used by Claude Code
29
+ PROJECT_MCP = ".mcp.json" # Project-level MCP config (deprecated)
30
+
31
+
32
+ class MCPConfigManager:
33
+ """Manages MCP service configurations with pipx preference."""
34
+
35
+ # Standard MCP services that should use pipx
36
+ PIPX_SERVICES = {
37
+ "mcp-vector-search",
38
+ "mcp-browser",
39
+ "mcp-ticketer",
40
+ "kuzu-memory",
41
+ }
42
+
43
+ # Known missing dependencies for MCP services that pipx doesn't handle automatically
44
+ # Maps service names to list of missing dependencies that need injection
45
+ SERVICE_MISSING_DEPENDENCIES = {
46
+ "mcp-ticketer": [
47
+ "gql"
48
+ ], # mcp-ticketer v0.1.8+ needs gql but doesn't declare it
49
+ # Add more services here as needed, e.g.:
50
+ # "another-service": ["dep1", "dep2"],
51
+ }
52
+
53
+ # Static known-good MCP service configurations
54
+ # These are the correct, tested configurations that work reliably
55
+ # Note: Commands will be resolved to full paths dynamically in get_static_service_config()
56
+ STATIC_MCP_CONFIGS = {
57
+ "kuzu-memory": {
58
+ "type": "stdio",
59
+ # Use full path to kuzu-memory binary from pipx venv
60
+ # This ensures it runs with the correct Python version
61
+ "command": "kuzu-memory", # Will be resolved to pipx venv path
62
+ "args": ["mcp", "serve"], # v1.1.0+ uses 'mcp serve' command
63
+ },
64
+ "mcp-ticketer": {
65
+ "type": "stdio",
66
+ "command": "mcp-ticketer", # Will be resolved to full path
67
+ "args": ["mcp"],
68
+ },
69
+ "mcp-browser": {
70
+ "type": "stdio",
71
+ "command": "mcp-browser", # Will be resolved to full path
72
+ "args": ["mcp"],
73
+ "env": {"MCP_BROWSER_HOME": str(Path.home() / ".mcp-browser")},
74
+ },
75
+ "mcp-vector-search": {
76
+ "type": "stdio",
77
+ # Special handling: needs Python interpreter from pipx venv
78
+ "command": "python", # Will be resolved to pipx venv Python
79
+ "args": ["-m", "mcp_vector_search.mcp.server", "{project_root}"],
80
+ "env": {},
81
+ },
82
+ }
83
+
84
+ def __init__(self, config=None):
85
+ """Initialize the MCP configuration manager.
86
+
87
+ Args:
88
+ config: Optional Config object for filtering services
89
+ """
90
+ self.logger = get_logger(__name__)
91
+ self.pipx_base = Path.home() / ".local" / "pipx" / "venvs"
92
+ self.project_root = Path.cwd()
93
+
94
+ # Validate config type if provided
95
+ if config is not None:
96
+ from ..core.config import Config
97
+
98
+ if not isinstance(config, Config):
99
+ self.logger.warning(
100
+ f"Invalid config type provided to MCPConfigManager: "
101
+ f"{type(config).__name__}. Expected Config. "
102
+ f"Proceeding with config=None (all services enabled)."
103
+ )
104
+ config = None
105
+
106
+ self.config = config
107
+
108
+ # Use the proper Claude config file location
109
+ self.claude_config_path = ConfigLocation.CLAUDE_JSON.value
110
+
111
+ def should_enable_service(self, service_name: str) -> bool:
112
+ """
113
+ Check if an MCP service should be enabled based on startup configuration.
114
+
115
+ Args:
116
+ service_name: Name of the MCP service
117
+
118
+ Returns:
119
+ True if the service should be enabled, False otherwise
120
+ """
121
+ # If no config provided, enable all services by default
122
+ if self.config is None:
123
+ return True
124
+
125
+ # Import Config here to avoid circular import at module level
126
+ from ..core.config import Config
127
+
128
+ # Validate config type
129
+ if not isinstance(self.config, Config):
130
+ self.logger.warning(
131
+ f"Invalid config type: {type(self.config).__name__}, "
132
+ f"expected Config. Enabling all services by default."
133
+ )
134
+ return True
135
+
136
+ # Get startup configuration
137
+ enabled_services = self.config.get("startup.enabled_mcp_services", None)
138
+
139
+ # If no startup preferences configured, enable all services
140
+ if enabled_services is None:
141
+ return True
142
+
143
+ # Check if this service is in the enabled list
144
+ is_enabled = service_name in enabled_services
145
+
146
+ if not is_enabled:
147
+ self.logger.debug(
148
+ f"MCP service '{service_name}' disabled by startup configuration"
149
+ )
150
+
151
+ return is_enabled
152
+
153
+ def detect_service_path(self, service_name: str) -> Optional[str]:
154
+ """
155
+ Detect the best path for an MCP service.
156
+
157
+ Priority order:
158
+ 1. For kuzu-memory: prefer v1.1.0+ with MCP support
159
+ 2. Pipx installation (preferred)
160
+ 3. System PATH (likely from pipx or homebrew)
161
+ 4. Local venv (fallback)
162
+
163
+ Args:
164
+ service_name: Name of the MCP service
165
+
166
+ Returns:
167
+ Path to the service executable or None if not found
168
+ """
169
+ # Special handling for kuzu-memory - prefer v1.1.0+ with MCP support
170
+ if service_name == "kuzu-memory":
171
+ candidates = []
172
+
173
+ # Check pipx installation
174
+ pipx_path = self._check_pipx_installation(service_name)
175
+ if pipx_path:
176
+ candidates.append(pipx_path)
177
+
178
+ # Check system PATH (including homebrew)
179
+ import shutil
180
+
181
+ system_path = shutil.which(service_name)
182
+ if system_path and system_path not in candidates:
183
+ candidates.append(system_path)
184
+
185
+ # Choose the best candidate (prefer v1.1.0+ with MCP support)
186
+ for path in candidates:
187
+ try:
188
+ result = subprocess.run(
189
+ [path, "--help"],
190
+ capture_output=True,
191
+ text=True,
192
+ timeout=5,
193
+ check=False,
194
+ )
195
+ # Check if this version has MCP support
196
+ if "claude" in result.stdout or "mcp" in result.stdout:
197
+ self.logger.debug(
198
+ f"Found kuzu-memory with MCP support at {path}"
199
+ )
200
+ return path
201
+ except (subprocess.SubprocessError, subprocess.TimeoutExpired, OSError):
202
+ pass
203
+
204
+ # If no MCP-capable version found, log warning but return None
205
+ if candidates:
206
+ self.logger.warning(
207
+ f"Found kuzu-memory at {candidates[0]} but it lacks MCP support. "
208
+ f"Upgrade to v1.1.0+ for MCP integration: pipx upgrade kuzu-memory"
209
+ )
210
+ return None # Don't configure MCP for incompatible versions
211
+
212
+ # Standard detection for other services
213
+ # Check pipx installation first
214
+ pipx_path = self._check_pipx_installation(service_name)
215
+ if pipx_path:
216
+ self.logger.debug(f"Found {service_name} via pipx: {pipx_path}")
217
+ return pipx_path
218
+
219
+ # Check system PATH
220
+ system_path = self._check_system_path(service_name)
221
+ if system_path:
222
+ self.logger.debug(f"Found {service_name} in PATH: {system_path}")
223
+ return system_path
224
+
225
+ # Fallback to local venv
226
+ local_path = self._check_local_venv(service_name)
227
+ if local_path:
228
+ self.logger.warning(
229
+ f"Using local venv for {service_name} (consider installing via pipx)"
230
+ )
231
+ return local_path
232
+
233
+ self.logger.debug(
234
+ f"Service {service_name} not found - will auto-install when needed"
235
+ )
236
+ return None
237
+
238
+ def _check_pipx_installation(self, service_name: str) -> Optional[str]:
239
+ """Check if service is installed via pipx."""
240
+ pipx_venv = self.pipx_base / service_name
241
+
242
+ if not pipx_venv.exists():
243
+ return None
244
+
245
+ # Special handling for mcp-vector-search (needs Python interpreter)
246
+ if service_name == "mcp-vector-search":
247
+ python_bin = pipx_venv / "bin" / "python"
248
+ if python_bin.exists() and python_bin.is_file():
249
+ return str(python_bin)
250
+ else:
251
+ # Other services use direct binary
252
+ service_bin = pipx_venv / "bin" / service_name
253
+ if service_bin.exists() and service_bin.is_file():
254
+ return str(service_bin)
255
+
256
+ return None
257
+
258
+ def _check_system_path(self, service_name: str) -> Optional[str]:
259
+ """Check if service is available in system PATH."""
260
+ try:
261
+ result = subprocess.run(
262
+ ["which", service_name],
263
+ capture_output=True,
264
+ text=True,
265
+ check=False,
266
+ )
267
+ if result.returncode == 0:
268
+ path = result.stdout.strip()
269
+ # Verify it's from pipx
270
+ if "/.local/bin/" in path or "/pipx/" in path:
271
+ return path
272
+ except Exception as e:
273
+ self.logger.debug(f"Error checking system PATH: {e}")
274
+
275
+ return None
276
+
277
+ def _check_local_venv(self, service_name: str) -> Optional[str]:
278
+ """Check for local virtual environment installation (fallback)."""
279
+ # Common local development paths
280
+ possible_paths = [
281
+ Path.home() / "Projects" / "managed" / service_name / ".venv" / "bin",
282
+ self.project_root / ".venv" / "bin",
283
+ self.project_root / "venv" / "bin",
284
+ ]
285
+
286
+ for base_path in possible_paths:
287
+ if service_name == "mcp-vector-search":
288
+ python_bin = base_path / "python"
289
+ if python_bin.exists():
290
+ return str(python_bin)
291
+ else:
292
+ service_bin = base_path / service_name
293
+ if service_bin.exists():
294
+ return str(service_bin)
295
+
296
+ return None
297
+
298
+ def test_service_command(self, service_name: str, config: Dict) -> bool:
299
+ """
300
+ Test if a service configuration actually works.
301
+
302
+ Args:
303
+ service_name: Name of the MCP service
304
+ config: Service configuration to test
305
+
306
+ Returns:
307
+ True if service responds correctly, False otherwise
308
+ """
309
+ try:
310
+ import shutil
311
+
312
+ # Build command - handle pipx PATH issues
313
+ command = config["command"]
314
+
315
+ # If command is pipx and not found, try common paths
316
+ if command == "pipx":
317
+ pipx_path = shutil.which("pipx")
318
+ if not pipx_path:
319
+ # Try common pipx locations
320
+ for possible_path in [
321
+ "/opt/homebrew/bin/pipx",
322
+ "/usr/local/bin/pipx",
323
+ str(Path.home() / ".local" / "bin" / "pipx"),
324
+ ]:
325
+ if Path(possible_path).exists():
326
+ command = possible_path
327
+ break
328
+ else:
329
+ command = pipx_path
330
+
331
+ cmd = [command]
332
+
333
+ # Add test args (--help or --version)
334
+ if "args" in config:
335
+ # For MCP services, test with --help after the subcommand
336
+ test_args = config["args"].copy()
337
+ # Replace project root placeholder for testing
338
+ test_args = [
339
+ (
340
+ arg.replace("{project_root}", str(self.project_root))
341
+ if "{project_root}" in arg
342
+ else arg
343
+ )
344
+ for arg in test_args
345
+ ]
346
+
347
+ # Add --help at the end
348
+ if service_name == "mcp-vector-search":
349
+ # For Python module invocation, just test if Python can import the module
350
+ cmd.extend(test_args[:2]) # Just python -m module_name
351
+ cmd.extend(["--help"])
352
+ else:
353
+ cmd.extend(test_args)
354
+ cmd.append("--help")
355
+ else:
356
+ cmd.append("--help")
357
+
358
+ # Run test command with timeout
359
+ result = subprocess.run(
360
+ cmd,
361
+ capture_output=True,
362
+ text=True,
363
+ timeout=5,
364
+ check=False,
365
+ env=config.get("env", {}),
366
+ )
367
+
368
+ # Check if command executed (exit code 0 or 1 for help)
369
+ if result.returncode in [0, 1]:
370
+ # Additional check for import errors in stderr
371
+ if (
372
+ "ModuleNotFoundError" in result.stderr
373
+ or "ImportError" in result.stderr
374
+ ):
375
+ self.logger.debug(f"Service {service_name} has import errors")
376
+ return False
377
+ return True
378
+
379
+ except subprocess.TimeoutExpired:
380
+ # Timeout might mean the service started successfully and is waiting for input
381
+ return True
382
+ except Exception as e:
383
+ self.logger.debug(f"Error testing {service_name}: {e}")
384
+
385
+ return False
386
+
387
+ def get_static_service_config(
388
+ self, service_name: str, project_path: Optional[str] = None
389
+ ) -> Optional[Dict]:
390
+ """
391
+ Get the static, known-good configuration for an MCP service.
392
+
393
+ Args:
394
+ service_name: Name of the MCP service
395
+ project_path: Optional project path to use (defaults to current project)
396
+
397
+ Returns:
398
+ Static service configuration dict or None if service not known
399
+ """
400
+ if service_name not in self.STATIC_MCP_CONFIGS:
401
+ return None
402
+
403
+ config = self.STATIC_MCP_CONFIGS[service_name].copy()
404
+ import shutil
405
+
406
+ # Resolve service binary commands to full paths
407
+ if service_name in ["kuzu-memory", "mcp-ticketer", "mcp-browser"]:
408
+ # Try to find the full path of the binary
409
+ binary_name = config["command"]
410
+
411
+ # First check pipx location
412
+ pipx_bin = (
413
+ Path.home()
414
+ / ".local"
415
+ / "pipx"
416
+ / "venvs"
417
+ / service_name
418
+ / "bin"
419
+ / binary_name
420
+ )
421
+ if pipx_bin.exists():
422
+ binary_path = str(pipx_bin)
423
+ else:
424
+ # Try which command
425
+ binary_path = shutil.which(binary_name)
426
+
427
+ if not binary_path:
428
+ # Try common installation locations
429
+ possible_paths = [
430
+ Path.home() / ".local" / "bin" / binary_name,
431
+ Path("/opt/homebrew/bin") / binary_name,
432
+ Path("/usr/local/bin") / binary_name,
433
+ ]
434
+ for path in possible_paths:
435
+ if path.exists():
436
+ binary_path = str(path)
437
+ break
438
+
439
+ if binary_path:
440
+ config["command"] = binary_path
441
+ else:
442
+ # Fall back to pipx run method if binary not found
443
+ self.logger.debug(
444
+ f"Could not find {binary_name}, using pipx run fallback"
445
+ )
446
+ config["command"] = "pipx"
447
+ config["args"] = ["run", service_name] + config["args"]
448
+
449
+ # Resolve pipx command to full path if needed (for fallback configs)
450
+ if config.get("command") == "pipx":
451
+ pipx_path = shutil.which("pipx")
452
+ if not pipx_path:
453
+ # Try common pipx locations
454
+ possible_pipx_paths = [
455
+ Path.home() / ".local" / "bin" / "pipx",
456
+ Path("/opt/homebrew/bin/pipx"),
457
+ Path("/usr/local/bin/pipx"),
458
+ ]
459
+ for path in possible_pipx_paths:
460
+ if path.exists():
461
+ pipx_path = str(path)
462
+ break
463
+ if pipx_path:
464
+ config["command"] = pipx_path
465
+
466
+ # Handle user-specific paths for mcp-vector-search
467
+ if service_name == "mcp-vector-search":
468
+ # Get the correct pipx venv path for the current user
469
+ home = Path.home()
470
+ python_path = (
471
+ home
472
+ / ".local"
473
+ / "pipx"
474
+ / "venvs"
475
+ / "mcp-vector-search"
476
+ / "bin"
477
+ / "python"
478
+ )
479
+
480
+ # Check if the Python interpreter exists
481
+ if python_path.exists():
482
+ config["command"] = str(python_path)
483
+ else:
484
+ # Fallback to pipx run method
485
+ pipx_path = shutil.which("pipx")
486
+ if not pipx_path:
487
+ # Try common pipx locations
488
+ possible_pipx_paths = [
489
+ Path.home() / ".local" / "bin" / "pipx",
490
+ Path("/opt/homebrew/bin/pipx"),
491
+ Path("/usr/local/bin/pipx"),
492
+ ]
493
+ for path in possible_pipx_paths:
494
+ if path.exists():
495
+ pipx_path = str(path)
496
+ break
497
+
498
+ if pipx_path:
499
+ config["command"] = pipx_path
500
+ else:
501
+ config["command"] = "pipx" # Hope it's in PATH
502
+
503
+ # Use pipx run with the spec argument
504
+ config["args"] = [
505
+ "run",
506
+ "--spec",
507
+ "mcp-vector-search",
508
+ "python",
509
+ "-m",
510
+ "mcp_vector_search.mcp.server",
511
+ "{project_root}",
512
+ ]
513
+
514
+ # Use provided project path or current project
515
+ project_root = project_path if project_path else str(self.project_root)
516
+ config["args"] = [
517
+ (
518
+ arg.replace("{project_root}", project_root)
519
+ if "{project_root}" in arg
520
+ else arg
521
+ )
522
+ for arg in config["args"]
523
+ ]
524
+
525
+ return config
526
+
527
+ def generate_service_config(self, service_name: str) -> Optional[Dict]:
528
+ """
529
+ Generate configuration for a specific MCP service.
530
+
531
+ Prefers static configurations over detection. Falls back to detection
532
+ only for unknown services.
533
+
534
+ Args:
535
+ service_name: Name of the MCP service
536
+
537
+ Returns:
538
+ Service configuration dict or None if service not found
539
+ """
540
+ # First try to get static configuration
541
+ static_config = self.get_static_service_config(service_name)
542
+ if static_config:
543
+ # Validate that the static config actually works
544
+ if self.test_service_command(service_name, static_config):
545
+ self.logger.debug(
546
+ f"Static config for {service_name} validated successfully"
547
+ )
548
+ return static_config
549
+ self.logger.warning(
550
+ f"Static config for {service_name} failed validation, trying fallback"
551
+ )
552
+
553
+ # Fall back to detection-based configuration for unknown services
554
+ import shutil
555
+
556
+ # Check for pipx run first (preferred for isolation)
557
+ use_pipx_run = False
558
+ use_uvx = False
559
+
560
+ # Try pipx run test
561
+ if shutil.which("pipx"):
562
+ try:
563
+ result = subprocess.run(
564
+ ["pipx", "run", service_name, "--version"],
565
+ capture_output=True,
566
+ text=True,
567
+ timeout=5,
568
+ check=False,
569
+ )
570
+ if result.returncode == 0 or "version" in result.stdout.lower():
571
+ use_pipx_run = True
572
+ self.logger.debug(f"Will use 'pipx run' for {service_name}")
573
+ except (subprocess.SubprocessError, subprocess.TimeoutExpired, OSError):
574
+ pass
575
+
576
+ # Try uvx if pipx run not available
577
+ if not use_pipx_run and shutil.which("uvx"):
578
+ try:
579
+ result = subprocess.run(
580
+ ["uvx", service_name, "--version"],
581
+ capture_output=True,
582
+ text=True,
583
+ timeout=5,
584
+ check=False,
585
+ )
586
+ if result.returncode == 0 or "version" in result.stdout.lower():
587
+ use_uvx = True
588
+ self.logger.debug(f"Will use 'uvx' for {service_name}")
589
+ except (subprocess.SubprocessError, subprocess.TimeoutExpired, OSError):
590
+ pass
591
+
592
+ # If neither work, try to find direct path
593
+ service_path = None
594
+ if not use_pipx_run and not use_uvx:
595
+ service_path = self.detect_service_path(service_name)
596
+ if not service_path:
597
+ return None
598
+
599
+ # Build configuration
600
+ config = {"type": "stdio"}
601
+
602
+ # Service-specific configurations
603
+ if service_name == "mcp-vector-search":
604
+ if use_pipx_run:
605
+ config["command"] = "pipx"
606
+ config["args"] = [
607
+ "run",
608
+ "mcp-vector-search",
609
+ "-m",
610
+ "mcp_vector_search.mcp.server",
611
+ str(self.project_root),
612
+ ]
613
+ elif use_uvx:
614
+ config["command"] = "uvx"
615
+ config["args"] = [
616
+ "mcp-vector-search",
617
+ "-m",
618
+ "mcp_vector_search.mcp.server",
619
+ str(self.project_root),
620
+ ]
621
+ else:
622
+ config["command"] = service_path
623
+ config["args"] = [
624
+ "-m",
625
+ "mcp_vector_search.mcp.server",
626
+ str(self.project_root),
627
+ ]
628
+ config["env"] = {}
629
+
630
+ elif service_name == "mcp-browser":
631
+ if use_pipx_run:
632
+ config["command"] = "pipx"
633
+ config["args"] = ["run", "mcp-browser", "mcp"]
634
+ elif use_uvx:
635
+ config["command"] = "uvx"
636
+ config["args"] = ["mcp-browser", "mcp"]
637
+ else:
638
+ config["command"] = service_path
639
+ config["args"] = ["mcp"]
640
+ config["env"] = {"MCP_BROWSER_HOME": str(Path.home() / ".mcp-browser")}
641
+
642
+ elif service_name == "mcp-ticketer":
643
+ if use_pipx_run:
644
+ config["command"] = "pipx"
645
+ config["args"] = ["run", "mcp-ticketer", "mcp"]
646
+ elif use_uvx:
647
+ config["command"] = "uvx"
648
+ config["args"] = ["mcp-ticketer", "mcp"]
649
+ else:
650
+ config["command"] = service_path
651
+ config["args"] = ["mcp"]
652
+
653
+ elif service_name == "kuzu-memory":
654
+ # For kuzu-memory, prefer using the binary from pipx venv
655
+ # This ensures it runs with Python 3.12 instead of system Python 3.13
656
+ pipx_binary = (
657
+ Path.home()
658
+ / ".local"
659
+ / "pipx"
660
+ / "venvs"
661
+ / "kuzu-memory"
662
+ / "bin"
663
+ / "kuzu-memory"
664
+ )
665
+
666
+ if pipx_binary.exists():
667
+ # Use pipx venv binary directly - this runs with the correct Python
668
+ config["command"] = str(pipx_binary)
669
+ config["args"] = ["mcp", "serve"]
670
+ elif use_pipx_run:
671
+ # Fallback to pipx run
672
+ config["command"] = "pipx"
673
+ config["args"] = ["run", "kuzu-memory", "mcp", "serve"]
674
+ elif use_uvx:
675
+ # UVX fallback
676
+ config["command"] = "uvx"
677
+ config["args"] = ["kuzu-memory", "mcp", "serve"]
678
+ elif service_path:
679
+ # Direct binary path
680
+ config["command"] = service_path
681
+ config["args"] = ["mcp", "serve"]
682
+ else:
683
+ # Default fallback
684
+ config["command"] = "pipx"
685
+ config["args"] = ["run", "kuzu-memory", "mcp", "serve"]
686
+
687
+ # Generic config for unknown services
688
+ elif use_pipx_run:
689
+ config["command"] = "pipx"
690
+ config["args"] = ["run", service_name]
691
+ elif use_uvx:
692
+ config["command"] = "uvx"
693
+ config["args"] = [service_name]
694
+ else:
695
+ config["command"] = service_path
696
+ config["args"] = []
697
+
698
+ return config
699
+
700
+ def check_mcp_services_available(self) -> Tuple[bool, str]:
701
+ """
702
+ Check if required MCP services are available in ~/.claude.json (READ-ONLY).
703
+
704
+ This method performs a READ-ONLY check of MCP service availability.
705
+ It does NOT modify ~/.claude.json. Users should install and configure
706
+ MCP services themselves via pip, npx, or Claude Desktop.
707
+
708
+ Returns:
709
+ Tuple of (all_available: bool, message: str)
710
+ """
711
+ # Get services Claude MPM expects to use (from ~/.claude-mpm/config/)
712
+ expected_services = self.get_filtered_services()
713
+
714
+ if not expected_services:
715
+ return True, "No MCP services configured in Claude MPM"
716
+
717
+ # Load Claude config (read-only)
718
+ if not self.claude_config_path.exists():
719
+ return False, f"Claude config not found at {self.claude_config_path}"
720
+
721
+ try:
722
+ with self.claude_config_path.open() as f:
723
+ claude_config = json.load(f)
724
+ except Exception as e:
725
+ return False, f"Failed to read Claude config: {e}"
726
+
727
+ # Check current project
728
+ current_project_key = str(self.project_root)
729
+ project_config = claude_config.get("projects", {}).get(current_project_key)
730
+
731
+ if not project_config:
732
+ missing = list(expected_services.keys())
733
+ return (
734
+ False,
735
+ f"Current project not configured in Claude. Missing services: {', '.join(missing)}",
736
+ )
737
+
738
+ # Check which services are missing
739
+ mcp_servers = project_config.get("mcpServers", {})
740
+ missing_services = [
741
+ name for name in expected_services if name not in mcp_servers
742
+ ]
743
+
744
+ if missing_services:
745
+ msg = (
746
+ f"Missing MCP services: {', '.join(missing_services)}. "
747
+ f"Install via: pip install {' '.join(missing_services)} "
748
+ f"or configure in Claude Desktop"
749
+ )
750
+ return False, msg
751
+
752
+ return (
753
+ True,
754
+ f"All required MCP services available ({len(expected_services)} services)",
755
+ )
756
+
757
+ def ensure_mcp_services_configured(self) -> Tuple[bool, str]:
758
+ """
759
+ DEPRECATED: Auto-configuring ~/.claude.json is no longer supported.
760
+
761
+ As of v4.15.0+, MCP services are user-controlled. Users should install
762
+ and configure MCP services themselves via:
763
+ - pip install <service-name>
764
+ - npx @modelcontextprotocol/...
765
+ - Claude Desktop UI
766
+
767
+ This method now only performs a read-only check and logs a deprecation warning.
768
+ Use check_mcp_services_available() for read-only checks.
769
+
770
+ Returns:
771
+ Tuple of (success, message)
772
+ """
773
+ import warnings
774
+
775
+ warnings.warn(
776
+ "ensure_mcp_services_configured() is deprecated and will be removed in v6.0.0. "
777
+ "MCP services are now user-controlled. Use check_mcp_services_available() instead.",
778
+ DeprecationWarning,
779
+ stacklevel=2,
780
+ )
781
+
782
+ # Delegate to read-only check
783
+ return self.check_mcp_services_available()
784
+
785
+ def update_mcp_config(self, force_pipx: bool = True) -> Tuple[bool, str]:
786
+ """
787
+ DEPRECATED: Check MCP configuration in ~/.claude.json (READ-ONLY).
788
+
789
+ This method no longer modifies ~/.claude.json. Users should install
790
+ and configure MCP services themselves.
791
+
792
+ Args:
793
+ force_pipx: Ignored (kept for backward compatibility)
794
+
795
+ Returns:
796
+ Tuple of (success, message) from read-only check
797
+ """
798
+ # Delegate to read-only check
799
+ return self.check_mcp_services_available()
800
+
801
+ def update_project_mcp_config(self, force_pipx: bool = True) -> Tuple[bool, str]:
802
+ """
803
+ Update the .mcp.json configuration file (legacy method).
804
+
805
+ Args:
806
+ force_pipx: If True, only use pipx installations
807
+
808
+ Returns:
809
+ Tuple of (success, message)
810
+ """
811
+ mcp_config_path = self.project_root / ConfigLocation.PROJECT_MCP.value
812
+
813
+ # Load existing config if it exists
814
+ existing_config = {}
815
+ if mcp_config_path.exists():
816
+ try:
817
+ with mcp_config_path.open() as f:
818
+ existing_config = json.load(f)
819
+ except Exception as e:
820
+ self.logger.error(f"Error reading existing config: {e}")
821
+
822
+ # Generate new configurations
823
+ new_config = {"mcpServers": {}}
824
+ missing_services = []
825
+
826
+ for service_name in self.PIPX_SERVICES:
827
+ config = self.generate_service_config(service_name)
828
+ if config:
829
+ new_config["mcpServers"][service_name] = config
830
+ elif force_pipx:
831
+ missing_services.append(service_name)
832
+ # Keep existing config if not forcing pipx
833
+ elif service_name in existing_config.get("mcpServers", {}):
834
+ new_config["mcpServers"][service_name] = existing_config["mcpServers"][
835
+ service_name
836
+ ]
837
+
838
+ # Add any additional services from existing config
839
+ for service_name, config in existing_config.get("mcpServers", {}).items():
840
+ if service_name not in new_config["mcpServers"]:
841
+ new_config["mcpServers"][service_name] = config
842
+
843
+ # Write the updated configuration
844
+ try:
845
+ with mcp_config_path.open("w") as f:
846
+ json.dump(new_config, f, indent=2)
847
+
848
+ if missing_services:
849
+ message = f"Updated .mcp.json. Missing services (install via pipx): {', '.join(missing_services)}"
850
+ return True, message
851
+ return True, "Successfully updated .mcp.json with pipx paths"
852
+ except Exception as e:
853
+ return False, f"Failed to update .mcp.json: {e}"
854
+
855
+ def validate_configuration(self) -> Dict[str, bool]:
856
+ """
857
+ Validate that all configured MCP services are accessible.
858
+
859
+ Returns:
860
+ Dict mapping service names to availability status
861
+ """
862
+ project_key = str(self.project_root)
863
+
864
+ # Check Claude config
865
+ if not self.claude_config_path.exists():
866
+ # Also check legacy .mcp.json
867
+ mcp_config_path = self.project_root / ConfigLocation.PROJECT_MCP.value
868
+ if mcp_config_path.exists():
869
+ try:
870
+ with mcp_config_path.open() as f:
871
+ config = json.load(f)
872
+ results = {}
873
+ for service_name, service_config in config.get(
874
+ "mcpServers", {}
875
+ ).items():
876
+ command_path = service_config.get("command", "")
877
+ results[service_name] = Path(command_path).exists()
878
+ return results
879
+ except Exception:
880
+ pass
881
+ return {}
882
+
883
+ try:
884
+ with self.claude_config_path.open() as f:
885
+ claude_config = json.load(f)
886
+
887
+ # Get project's MCP servers
888
+ if "projects" in claude_config and project_key in claude_config["projects"]:
889
+ mcp_servers = claude_config["projects"][project_key].get(
890
+ "mcpServers", {}
891
+ )
892
+ results = {}
893
+ for service_name, service_config in mcp_servers.items():
894
+ command_path = service_config.get("command", "")
895
+ results[service_name] = Path(command_path).exists()
896
+ return results
897
+ except Exception as e:
898
+ self.logger.error(f"Error reading config: {e}")
899
+
900
+ return {}
901
+
902
+ def install_missing_services(self) -> Tuple[bool, str]:
903
+ """
904
+ Install missing MCP services via pipx with verification and fallbacks.
905
+
906
+ Returns:
907
+ Tuple of (success, message)
908
+ """
909
+ missing = []
910
+ for service_name in self.PIPX_SERVICES:
911
+ if not self.detect_service_path(service_name):
912
+ missing.append(service_name)
913
+
914
+ if not missing:
915
+ return True, "All MCP services are already installed"
916
+
917
+ installed = []
918
+ failed = []
919
+
920
+ for service_name in missing:
921
+ # Try pipx install first
922
+ success, method = self._install_service_with_fallback(service_name)
923
+ if success:
924
+ installed.append(f"{service_name} ({method})")
925
+ self.logger.info(f"Successfully installed {service_name} via {method}")
926
+ else:
927
+ failed.append(service_name)
928
+ self.logger.error(f"Failed to install {service_name}")
929
+
930
+ if failed:
931
+ return False, f"Failed to install: {', '.join(failed)}"
932
+ if installed:
933
+ return True, f"Successfully installed: {', '.join(installed)}"
934
+ return True, "No services needed installation"
935
+
936
+ def _install_service_with_fallback(self, service_name: str) -> Tuple[bool, str]:
937
+ """
938
+ Install a service with multiple fallback methods.
939
+
940
+ Returns:
941
+ Tuple of (success, installation_method)
942
+ """
943
+ import shutil
944
+
945
+ # Method 1: Try pipx install
946
+ if shutil.which("pipx"):
947
+ try:
948
+ self.logger.debug(f"Attempting to install {service_name} via pipx...")
949
+ result = subprocess.run(
950
+ ["pipx", "install", service_name],
951
+ capture_output=True,
952
+ text=True,
953
+ timeout=120, # 2 minute timeout
954
+ check=False,
955
+ )
956
+
957
+ if result.returncode == 0:
958
+ # Inject any missing dependencies if needed
959
+ if service_name in self.SERVICE_MISSING_DEPENDENCIES:
960
+ self.logger.debug(
961
+ f"Injecting missing dependencies for newly installed {service_name}..."
962
+ )
963
+ self._inject_missing_dependencies(service_name)
964
+
965
+ # Verify installation worked
966
+ if self._verify_service_installed(service_name, "pipx"):
967
+ return True, "pipx"
968
+
969
+ self.logger.warning(
970
+ f"pipx install succeeded but verification failed for {service_name}"
971
+ )
972
+ else:
973
+ self.logger.debug(f"pipx install failed: {result.stderr}")
974
+ except subprocess.TimeoutExpired:
975
+ self.logger.warning(f"pipx install timed out for {service_name}")
976
+ except Exception as e:
977
+ self.logger.debug(f"pipx install error: {e}")
978
+
979
+ # Method 2: Try uvx (if available)
980
+ if shutil.which("uvx"):
981
+ try:
982
+ self.logger.debug(f"Attempting to install {service_name} via uvx...")
983
+ result = subprocess.run(
984
+ ["uvx", "install", service_name],
985
+ capture_output=True,
986
+ text=True,
987
+ timeout=120,
988
+ check=False,
989
+ )
990
+
991
+ if result.returncode == 0:
992
+ if self._verify_service_installed(service_name, "uvx"):
993
+ return True, "uvx"
994
+ except Exception as e:
995
+ self.logger.debug(f"uvx install error: {e}")
996
+
997
+ # Method 3: Try pip install --user
998
+ try:
999
+ self.logger.debug(f"Attempting to install {service_name} via pip --user...")
1000
+ result = subprocess.run(
1001
+ [sys.executable, "-m", "pip", "install", "--user", service_name],
1002
+ capture_output=True,
1003
+ text=True,
1004
+ timeout=120,
1005
+ check=False,
1006
+ )
1007
+
1008
+ if result.returncode == 0:
1009
+ if self._verify_service_installed(service_name, "pip"):
1010
+ return True, "pip --user"
1011
+
1012
+ self.logger.warning(
1013
+ f"pip install succeeded but verification failed for {service_name}"
1014
+ )
1015
+ except Exception as e:
1016
+ self.logger.debug(f"pip install error: {e}")
1017
+
1018
+ return False, "none"
1019
+
1020
+ # COMMENTED OUT: These functions are no longer used
1021
+ # Package maintainers should fix dependency declarations in their packages
1022
+ # Automatic dependency injection can cause conflicts and is not recommended
1023
+
1024
+ # def _get_mcp_ticketer_version(self) -> Optional[str]:
1025
+ # """Get the installed version of mcp-ticketer.
1026
+ #
1027
+ # Returns:
1028
+ # Version string (e.g., "0.1.8") or None if not installed
1029
+ # """
1030
+ # try:
1031
+ # result = subprocess.run(
1032
+ # ["pipx", "runpip", "mcp-ticketer", "show", "mcp-ticketer"],
1033
+ # capture_output=True,
1034
+ # text=True,
1035
+ # timeout=5,
1036
+ # check=False,
1037
+ # )
1038
+ #
1039
+ # if result.returncode == 0:
1040
+ # # Parse version from output
1041
+ # for line in result.stdout.split("\n"):
1042
+ # if line.startswith("Version:"):
1043
+ # return line.split(":", 1)[1].strip()
1044
+ # return None
1045
+ # except Exception:
1046
+ # return None
1047
+ #
1048
+ # def _check_and_fix_mcp_ticketer_dependencies(self) -> bool:
1049
+ # """Check and fix mcp-ticketer missing gql dependency.
1050
+ #
1051
+ # DEPRECATED: This workaround is no longer used.
1052
+ # Package maintainers should fix dependency declarations.
1053
+ #
1054
+ # Returns:
1055
+ # False (no longer performs injection)
1056
+ # """
1057
+ # return False
1058
+
1059
+ def fix_mcp_service_issues(self) -> Tuple[bool, str]:
1060
+ """
1061
+ Detect and fix corrupted MCP service installations.
1062
+
1063
+ NOTE: Proactive health checking has been disabled.
1064
+ Each MCP service should stand on its own and handle its own issues.
1065
+ This function now only returns success without checking services.
1066
+
1067
+ Returns:
1068
+ Tuple of (success, message)
1069
+ """
1070
+ # Services should stand on their own - no proactive health checking
1071
+ return True, "MCP services managing their own health"
1072
+
1073
+ def _detect_service_issue(self, service_name: str) -> Optional[str]:
1074
+ """
1075
+ Detect what type of issue a service has.
1076
+
1077
+ Returns:
1078
+ Issue type: 'not_installed', 'import_error', 'missing_dependency', 'path_issue', or None
1079
+ """
1080
+ import shutil
1081
+
1082
+ # First check if pipx is available
1083
+ if not shutil.which("pipx"):
1084
+ return "not_installed" # Can't use pipx services without pipx
1085
+
1086
+ # Try to run the service with --help to detect issues
1087
+ try:
1088
+ # First check if service is installed in pipx venv
1089
+ pipx_venv_bin = self.pipx_base / service_name / "bin" / service_name
1090
+ if pipx_venv_bin.exists():
1091
+ # Test the installed version directly (has injected dependencies)
1092
+ # This avoids using pipx run which downloads a fresh cache copy without dependencies
1093
+ self.logger.debug(
1094
+ f" Testing {service_name} from installed pipx venv: {pipx_venv_bin}"
1095
+ )
1096
+ result = subprocess.run(
1097
+ [str(pipx_venv_bin), "--help"],
1098
+ capture_output=True,
1099
+ text=True,
1100
+ timeout=10,
1101
+ check=False,
1102
+ )
1103
+
1104
+ # Check for specific error patterns in installed version
1105
+ stderr_lower = result.stderr.lower()
1106
+ stdout_lower = result.stdout.lower()
1107
+ combined_output = stderr_lower + stdout_lower
1108
+
1109
+ # Import errors in installed version (should be rare if dependencies injected)
1110
+ if (
1111
+ "modulenotfounderror" in combined_output
1112
+ or "importerror" in combined_output
1113
+ ):
1114
+ # Check if it's specifically the gql dependency for mcp-ticketer
1115
+ if service_name == "mcp-ticketer" and "gql" in combined_output:
1116
+ return "missing_dependency"
1117
+ return "import_error"
1118
+
1119
+ # Path issues
1120
+ if "no such file or directory" in combined_output:
1121
+ return "path_issue"
1122
+
1123
+ # If help text appears, service is working
1124
+ if (
1125
+ "usage:" in combined_output
1126
+ or "help" in combined_output
1127
+ or result.returncode in [0, 1]
1128
+ ):
1129
+ self.logger.debug(
1130
+ f" {service_name} is working correctly (installed in venv)"
1131
+ )
1132
+ return None # Service is working
1133
+
1134
+ # Unknown issue
1135
+ if result.returncode not in [0, 1]:
1136
+ self.logger.debug(
1137
+ f"{service_name} returned unexpected exit code: {result.returncode}"
1138
+ )
1139
+ return "unknown_error"
1140
+
1141
+ return None # Default to working if no issues detected
1142
+
1143
+ # Service not installed in pipx venv - use pipx run for detection
1144
+ # Note: pipx run uses cache which may not have injected dependencies
1145
+ self.logger.debug(
1146
+ f" Testing {service_name} via pipx run (not installed in venv)"
1147
+ )
1148
+ result = subprocess.run(
1149
+ ["pipx", "run", service_name, "--help"],
1150
+ capture_output=True,
1151
+ text=True,
1152
+ timeout=10,
1153
+ check=False,
1154
+ )
1155
+
1156
+ # Check for specific error patterns
1157
+ stderr_lower = result.stderr.lower()
1158
+ stdout_lower = result.stdout.lower()
1159
+ combined_output = stderr_lower + stdout_lower
1160
+
1161
+ # Not installed
1162
+ if (
1163
+ "no apps associated" in combined_output
1164
+ or "not found" in combined_output
1165
+ ):
1166
+ return "not_installed"
1167
+
1168
+ # Import errors when using pipx run (cache version)
1169
+ if (
1170
+ "modulenotfounderror" in combined_output
1171
+ or "importerror" in combined_output
1172
+ ):
1173
+ # Don't report missing_dependency for cache version - it may be missing injected deps
1174
+ # Just report that service needs to be installed properly
1175
+ self.logger.debug(
1176
+ f"{service_name} has import errors in pipx run cache - needs proper installation"
1177
+ )
1178
+ return "not_installed"
1179
+
1180
+ # Path issues
1181
+ if "no such file or directory" in combined_output:
1182
+ return "path_issue"
1183
+
1184
+ # If help text appears, service is working
1185
+ if (
1186
+ "usage:" in combined_output
1187
+ or "help" in combined_output
1188
+ or result.returncode in [0, 1]
1189
+ ):
1190
+ return None # Service is working
1191
+
1192
+ # Unknown issue
1193
+ if result.returncode not in [0, 1]:
1194
+ return "unknown_error"
1195
+
1196
+ except subprocess.TimeoutExpired:
1197
+ # Timeout might mean service is actually working but waiting for input
1198
+ return None
1199
+ except Exception as e:
1200
+ self.logger.debug(f"Error detecting issue for {service_name}: {e}")
1201
+ return "unknown_error"
1202
+
1203
+ return None
1204
+
1205
+ def _reinstall_service(self, service_name: str) -> bool:
1206
+ """
1207
+ Reinstall a corrupted MCP service.
1208
+
1209
+ Args:
1210
+ service_name: Name of the service to reinstall
1211
+
1212
+ Returns:
1213
+ True if successful, False otherwise
1214
+ """
1215
+ try:
1216
+ self.logger.debug(f"Uninstalling {service_name}...")
1217
+
1218
+ # First uninstall the corrupted version
1219
+ uninstall_result = subprocess.run(
1220
+ ["pipx", "uninstall", service_name],
1221
+ capture_output=True,
1222
+ text=True,
1223
+ timeout=30,
1224
+ check=False,
1225
+ )
1226
+
1227
+ # Don't check return code - uninstall might fail if partially corrupted
1228
+ self.logger.debug(f"Uninstall result: {uninstall_result.returncode}")
1229
+
1230
+ # Now reinstall
1231
+ self.logger.debug(f"Installing fresh {service_name}...")
1232
+ install_result = subprocess.run(
1233
+ ["pipx", "install", service_name],
1234
+ capture_output=True,
1235
+ text=True,
1236
+ timeout=120,
1237
+ check=False,
1238
+ )
1239
+
1240
+ if install_result.returncode == 0:
1241
+ # Inject any missing dependencies if needed
1242
+ if service_name in self.SERVICE_MISSING_DEPENDENCIES:
1243
+ self.logger.debug(
1244
+ f"Injecting missing dependencies for {service_name}..."
1245
+ )
1246
+ self._inject_missing_dependencies(service_name)
1247
+
1248
+ # Verify the reinstall worked
1249
+ issue = self._detect_service_issue(service_name)
1250
+ if issue is None:
1251
+ self.logger.info(f"✅ Successfully reinstalled {service_name}")
1252
+ return True
1253
+ self.logger.warning(
1254
+ f"Reinstalled {service_name} but still has issue: {issue}"
1255
+ )
1256
+ return False
1257
+ self.logger.error(
1258
+ f"Failed to reinstall {service_name}: {install_result.stderr}"
1259
+ )
1260
+ return False
1261
+
1262
+ except Exception as e:
1263
+ self.logger.error(f"Error reinstalling {service_name}: {e}")
1264
+ return False
1265
+
1266
+ def _inject_missing_dependencies(self, service_name: str) -> bool:
1267
+ """
1268
+ Inject missing dependencies into a pipx-installed MCP service.
1269
+
1270
+ Some MCP services don't properly declare all their dependencies in their
1271
+ package metadata, which causes import errors when pipx creates isolated
1272
+ virtual environments. This method injects the missing dependencies using
1273
+ pipx inject.
1274
+
1275
+ Args:
1276
+ service_name: Name of the MCP service to fix
1277
+
1278
+ Returns:
1279
+ True if dependencies were injected successfully or no injection needed, False otherwise
1280
+ """
1281
+ # Check if this service has known missing dependencies
1282
+ if service_name not in self.SERVICE_MISSING_DEPENDENCIES:
1283
+ return True # No dependencies to inject
1284
+
1285
+ missing_deps = self.SERVICE_MISSING_DEPENDENCIES[service_name]
1286
+ if not missing_deps:
1287
+ return True # No dependencies to inject
1288
+
1289
+ self.logger.info(
1290
+ f" → Injecting missing dependencies for {service_name}: {', '.join(missing_deps)}"
1291
+ )
1292
+
1293
+ all_successful = True
1294
+ for dep in missing_deps:
1295
+ try:
1296
+ self.logger.debug(f" Injecting {dep} into {service_name}...")
1297
+ result = subprocess.run(
1298
+ ["pipx", "inject", service_name, dep],
1299
+ capture_output=True,
1300
+ text=True,
1301
+ timeout=60,
1302
+ check=False,
1303
+ )
1304
+
1305
+ if result.returncode == 0:
1306
+ self.logger.debug(f" ✅ Successfully injected {dep}")
1307
+ # Check if already injected (pipx will complain if package already exists)
1308
+ elif (
1309
+ "already satisfied" in result.stderr.lower()
1310
+ or "already installed" in result.stderr.lower()
1311
+ ):
1312
+ self.logger.debug(f" {dep} already present in {service_name}")
1313
+ else:
1314
+ self.logger.error(f" Failed to inject {dep}: {result.stderr}")
1315
+ all_successful = False
1316
+
1317
+ except subprocess.TimeoutExpired:
1318
+ self.logger.error(f" Timeout while injecting {dep}")
1319
+ all_successful = False
1320
+ except Exception as e:
1321
+ self.logger.error(f" Error injecting {dep}: {e}")
1322
+ all_successful = False
1323
+
1324
+ return all_successful
1325
+
1326
+ def _auto_reinstall_mcp_service(self, service_name: str) -> bool:
1327
+ """
1328
+ Automatically reinstall an MCP service with missing dependencies.
1329
+
1330
+ This method:
1331
+ 1. Uninstalls the corrupted/incomplete service
1332
+ 2. Reinstalls it fresh from pipx
1333
+ 3. Verifies the reinstall was successful
1334
+ 4. Updates status after successful reinstall
1335
+
1336
+ Args:
1337
+ service_name: Name of the MCP service to reinstall
1338
+
1339
+ Returns:
1340
+ True if reinstall successful, False otherwise
1341
+ """
1342
+ try:
1343
+ import shutil
1344
+
1345
+ # Verify pipx is available
1346
+ if not shutil.which("pipx"):
1347
+ self.logger.error("pipx not found - cannot auto-reinstall")
1348
+ return False
1349
+
1350
+ self.logger.info(f" → Uninstalling {service_name}...")
1351
+ uninstall_result = subprocess.run(
1352
+ ["pipx", "uninstall", service_name],
1353
+ capture_output=True,
1354
+ text=True,
1355
+ timeout=30,
1356
+ check=False,
1357
+ )
1358
+
1359
+ # Log result but don't fail if uninstall had issues
1360
+ if uninstall_result.returncode != 0:
1361
+ self.logger.debug(
1362
+ f"Uninstall had warnings (expected if corrupted): {uninstall_result.stderr}"
1363
+ )
1364
+
1365
+ self.logger.info(f" → Installing fresh {service_name}...")
1366
+ install_result = subprocess.run(
1367
+ ["pipx", "install", service_name],
1368
+ capture_output=True,
1369
+ text=True,
1370
+ timeout=120,
1371
+ check=False,
1372
+ )
1373
+
1374
+ if install_result.returncode != 0:
1375
+ self.logger.error(
1376
+ f"Install failed for {service_name}: {install_result.stderr}"
1377
+ )
1378
+ return False
1379
+
1380
+ # Inject any missing dependencies that pipx doesn't handle automatically
1381
+ if service_name in self.SERVICE_MISSING_DEPENDENCIES:
1382
+ self.logger.info(
1383
+ f" → Fixing missing dependencies for {service_name}..."
1384
+ )
1385
+ if not self._inject_missing_dependencies(service_name):
1386
+ self.logger.warning(
1387
+ f"Failed to inject all dependencies for {service_name}, but continuing..."
1388
+ )
1389
+
1390
+ # Verify the reinstall worked
1391
+ self.logger.debug(f" → Verifying {service_name} installation...")
1392
+ issue = self._detect_service_issue(service_name)
1393
+
1394
+ if issue is None:
1395
+ self.logger.info(f" ✅ Successfully reinstalled {service_name}")
1396
+ return True
1397
+
1398
+ # If still has missing dependency issue after injection, log specific instructions
1399
+ if issue == "missing_dependency" and service_name == "mcp-ticketer":
1400
+ self.logger.error(
1401
+ f" {service_name} still has missing dependencies after injection. "
1402
+ f"Manual fix: pipx inject {service_name} gql"
1403
+ )
1404
+ else:
1405
+ self.logger.warning(
1406
+ f"Reinstalled {service_name} but still has issue: {issue}"
1407
+ )
1408
+ return False
1409
+
1410
+ except subprocess.TimeoutExpired:
1411
+ self.logger.error(f"Timeout while reinstalling {service_name}")
1412
+ return False
1413
+ except Exception as e:
1414
+ self.logger.error(f"Error auto-reinstalling {service_name}: {e}")
1415
+ return False
1416
+
1417
+ def _verify_service_installed(self, service_name: str, method: str) -> bool:
1418
+ """
1419
+ Verify that a service was successfully installed and is functional.
1420
+
1421
+ Args:
1422
+ service_name: Name of the service
1423
+ method: Installation method used
1424
+
1425
+ Returns:
1426
+ True if service is installed and functional
1427
+ """
1428
+ import time
1429
+
1430
+ # Give the installation a moment to settle
1431
+ time.sleep(1)
1432
+
1433
+ # Note: mcp-ticketer dependency fix is now handled once in ensure_mcp_services_configured()
1434
+ # to avoid running the same pipx inject command multiple times
1435
+
1436
+ # Check if we can find the service
1437
+ service_path = self.detect_service_path(service_name)
1438
+ if not service_path:
1439
+ # Try pipx run as fallback for pipx installations
1440
+ if method == "pipx":
1441
+ try:
1442
+ result = subprocess.run(
1443
+ ["pipx", "run", service_name, "--version"],
1444
+ capture_output=True,
1445
+ text=True,
1446
+ timeout=10,
1447
+ check=False,
1448
+ )
1449
+ if result.returncode == 0 or "version" in result.stdout.lower():
1450
+ self.logger.debug(f"{service_name} accessible via 'pipx run'")
1451
+ return True
1452
+ except (subprocess.SubprocessError, subprocess.TimeoutExpired, OSError):
1453
+ pass
1454
+ return False
1455
+
1456
+ # Try to verify it works
1457
+ try:
1458
+ # Different services may need different verification
1459
+ test_commands = [
1460
+ [service_path, "--version"],
1461
+ [service_path, "--help"],
1462
+ ]
1463
+
1464
+ for cmd in test_commands:
1465
+ result = subprocess.run(
1466
+ cmd,
1467
+ capture_output=True,
1468
+ text=True,
1469
+ timeout=10,
1470
+ check=False,
1471
+ )
1472
+
1473
+ output = (result.stdout + result.stderr).lower()
1474
+ # Check for signs of success
1475
+ if result.returncode == 0:
1476
+ return True
1477
+ # Some tools return non-zero but still work
1478
+ if any(
1479
+ indicator in output
1480
+ for indicator in ["version", "usage", "help", service_name.lower()]
1481
+ ):
1482
+ # Make sure it's not an error message
1483
+ if not any(
1484
+ error in output
1485
+ for error in ["error", "not found", "traceback", "no such"]
1486
+ ):
1487
+ return True
1488
+ except Exception as e:
1489
+ self.logger.debug(f"Verification error for {service_name}: {e}")
1490
+
1491
+ return False
1492
+
1493
+ def _get_fallback_config(
1494
+ self, service_name: str, project_path: str
1495
+ ) -> Optional[Dict]:
1496
+ """
1497
+ Get a fallback configuration for a service if the primary config fails.
1498
+
1499
+ Args:
1500
+ service_name: Name of the MCP service
1501
+ project_path: Project path to use
1502
+
1503
+ Returns:
1504
+ Fallback configuration or None
1505
+ """
1506
+ # Special fallback for mcp-vector-search using pipx run
1507
+ if service_name == "mcp-vector-search":
1508
+ return {
1509
+ "type": "stdio",
1510
+ "command": "pipx",
1511
+ "args": [
1512
+ "run",
1513
+ "--spec",
1514
+ "mcp-vector-search",
1515
+ "python",
1516
+ "-m",
1517
+ "mcp_vector_search.mcp.server",
1518
+ project_path,
1519
+ ],
1520
+ "env": {},
1521
+ }
1522
+
1523
+ # For other services, try pipx run
1524
+ return None
1525
+
1526
+ def get_filtered_services(self) -> Dict[str, Dict]:
1527
+ """Get all MCP service configurations filtered by startup configuration.
1528
+
1529
+ Returns:
1530
+ Dictionary of service configurations, filtered based on startup settings
1531
+ """
1532
+ filtered_services = {}
1533
+
1534
+ for service_name in self.STATIC_MCP_CONFIGS:
1535
+ if self.should_enable_service(service_name):
1536
+ # Get the actual service configuration with proper paths
1537
+ service_config = self.get_static_service_config(service_name)
1538
+ if service_config:
1539
+ filtered_services[service_name] = service_config
1540
+ # Removed noisy debug logging that was called multiple times per startup
1541
+
1542
+ return filtered_services