claude-mpm 3.4.10__py3-none-any.whl → 5.4.55__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 (950) 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_OUTPUT_STYLE.md +290 -0
  8. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
  9. claude_mpm/agents/MEMORY.md +72 -0
  10. claude_mpm/agents/PM_INSTRUCTIONS.md +1402 -0
  11. claude_mpm/agents/WORKFLOW.md +111 -0
  12. claude_mpm/agents/__init__.py +92 -80
  13. claude_mpm/agents/agent-template.yaml +83 -0
  14. claude_mpm/agents/agent_loader.py +560 -745
  15. claude_mpm/agents/agent_loader_integration.py +53 -55
  16. claude_mpm/agents/agents_metadata.py +186 -27
  17. claude_mpm/agents/async_agent_loader.py +436 -0
  18. claude_mpm/agents/base_agent.json +8 -4
  19. claude_mpm/agents/frontmatter_validator.py +754 -0
  20. claude_mpm/agents/system_agent_config.py +222 -155
  21. claude_mpm/agents/templates/README.md +465 -0
  22. claude_mpm/agents/templates/__init__.py +17 -13
  23. claude_mpm/agents/templates/circuit-breakers.md +1391 -0
  24. claude_mpm/agents/templates/context-management-examples.md +544 -0
  25. claude_mpm/agents/templates/git-file-tracking.md +584 -0
  26. claude_mpm/agents/templates/pm-examples.md +474 -0
  27. claude_mpm/agents/templates/pm-red-flags.md +310 -0
  28. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  29. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  30. claude_mpm/agents/templates/response-format.md +583 -0
  31. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  32. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  33. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  34. claude_mpm/agents/templates/validation-templates.md +312 -0
  35. claude_mpm/cli/__init__.py +90 -128
  36. claude_mpm/cli/__main__.py +33 -0
  37. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  38. claude_mpm/cli/commands/__init__.py +36 -12
  39. claude_mpm/cli/commands/agent_manager.py +1403 -0
  40. claude_mpm/cli/commands/agent_source.py +774 -0
  41. claude_mpm/cli/commands/agent_state_manager.py +335 -0
  42. claude_mpm/cli/commands/agents.py +2503 -168
  43. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  44. claude_mpm/cli/commands/agents_discover.py +338 -0
  45. claude_mpm/cli/commands/aggregate.py +540 -0
  46. claude_mpm/cli/commands/analyze.py +553 -0
  47. claude_mpm/cli/commands/analyze_code.py +528 -0
  48. claude_mpm/cli/commands/auto_configure.py +1053 -0
  49. claude_mpm/cli/commands/cleanup.py +588 -0
  50. claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
  51. claude_mpm/cli/commands/config.py +586 -0
  52. claude_mpm/cli/commands/configure.py +2654 -0
  53. claude_mpm/cli/commands/configure_agent_display.py +282 -0
  54. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  55. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  56. claude_mpm/cli/commands/configure_models.py +18 -0
  57. claude_mpm/cli/commands/configure_navigation.py +184 -0
  58. claude_mpm/cli/commands/configure_paths.py +104 -0
  59. claude_mpm/cli/commands/configure_persistence.py +254 -0
  60. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  61. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  62. claude_mpm/cli/commands/configure_validators.py +73 -0
  63. claude_mpm/cli/commands/dashboard.py +286 -0
  64. claude_mpm/cli/commands/debug.py +1386 -0
  65. claude_mpm/cli/commands/doctor.py +243 -0
  66. claude_mpm/cli/commands/hook_errors.py +277 -0
  67. claude_mpm/cli/commands/info.py +195 -74
  68. claude_mpm/cli/commands/local_deploy.py +534 -0
  69. claude_mpm/cli/commands/mcp.py +205 -0
  70. claude_mpm/cli/commands/mcp_command_router.py +161 -0
  71. claude_mpm/cli/commands/mcp_config.py +154 -0
  72. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  73. claude_mpm/cli/commands/mcp_external_commands.py +249 -0
  74. claude_mpm/cli/commands/mcp_install_commands.py +346 -0
  75. claude_mpm/cli/commands/mcp_pipx_config.py +208 -0
  76. claude_mpm/cli/commands/mcp_server_commands.py +155 -0
  77. claude_mpm/cli/commands/mcp_setup_external.py +868 -0
  78. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  79. claude_mpm/cli/commands/memory.py +585 -846
  80. claude_mpm/cli/commands/monitor.py +228 -310
  81. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  82. claude_mpm/cli/commands/mpm_init/core.py +759 -0
  83. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  84. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  85. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  86. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  87. claude_mpm/cli/commands/mpm_init/prompts.py +722 -0
  88. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  89. claude_mpm/cli/commands/mpm_init_handler.py +195 -0
  90. claude_mpm/cli/commands/postmortem.py +401 -0
  91. claude_mpm/cli/commands/profile.py +276 -0
  92. claude_mpm/cli/commands/run.py +910 -488
  93. claude_mpm/cli/commands/search.py +458 -0
  94. claude_mpm/cli/commands/skill_source.py +694 -0
  95. claude_mpm/cli/commands/skills.py +1246 -0
  96. claude_mpm/cli/commands/summarize.py +413 -0
  97. claude_mpm/cli/commands/tickets.py +536 -53
  98. claude_mpm/cli/commands/uninstall.py +176 -0
  99. claude_mpm/cli/commands/upgrade.py +152 -0
  100. claude_mpm/cli/commands/verify.py +119 -0
  101. claude_mpm/cli/executor.py +297 -0
  102. claude_mpm/cli/helpers.py +105 -0
  103. claude_mpm/cli/interactive/__init__.py +21 -0
  104. claude_mpm/cli/interactive/agent_wizard.py +1947 -0
  105. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  106. claude_mpm/cli/parser.py +87 -563
  107. claude_mpm/cli/parsers/__init__.py +35 -0
  108. claude_mpm/cli/parsers/agent_manager_parser.py +393 -0
  109. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  110. claude_mpm/cli/parsers/agents_parser.py +575 -0
  111. claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
  112. claude_mpm/cli/parsers/analyze_parser.py +135 -0
  113. claude_mpm/cli/parsers/auto_configure_parser.py +120 -0
  114. claude_mpm/cli/parsers/base_parser.py +644 -0
  115. claude_mpm/cli/parsers/config_parser.py +208 -0
  116. claude_mpm/cli/parsers/configure_parser.py +138 -0
  117. claude_mpm/cli/parsers/dashboard_parser.py +113 -0
  118. claude_mpm/cli/parsers/debug_parser.py +319 -0
  119. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  120. claude_mpm/cli/parsers/mcp_parser.py +195 -0
  121. claude_mpm/cli/parsers/memory_parser.py +138 -0
  122. claude_mpm/cli/parsers/monitor_parser.py +142 -0
  123. claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
  124. claude_mpm/cli/parsers/profile_parser.py +147 -0
  125. claude_mpm/cli/parsers/run_parser.py +157 -0
  126. claude_mpm/cli/parsers/search_parser.py +245 -0
  127. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  128. claude_mpm/cli/parsers/skills_parser.py +277 -0
  129. claude_mpm/cli/parsers/source_parser.py +138 -0
  130. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  131. claude_mpm/cli/shared/__init__.py +40 -0
  132. claude_mpm/cli/shared/argument_patterns.py +205 -0
  133. claude_mpm/cli/shared/base_command.py +242 -0
  134. claude_mpm/cli/shared/error_handling.py +242 -0
  135. claude_mpm/cli/shared/output_formatters.py +241 -0
  136. claude_mpm/cli/startup.py +1743 -0
  137. claude_mpm/cli/startup_display.py +480 -0
  138. claude_mpm/cli/startup_logging.py +839 -0
  139. claude_mpm/cli/utils.py +136 -47
  140. claude_mpm/cli_module/__init__.py +6 -6
  141. claude_mpm/cli_module/args.py +188 -140
  142. claude_mpm/cli_module/commands.py +79 -70
  143. claude_mpm/cli_module/migration_example.py +42 -64
  144. claude_mpm/commands/__init__.py +14 -0
  145. claude_mpm/commands/mpm-config.md +28 -0
  146. claude_mpm/commands/mpm-doctor.md +20 -0
  147. claude_mpm/commands/mpm-help.md +20 -0
  148. claude_mpm/commands/mpm-init.md +120 -0
  149. claude_mpm/commands/mpm-monitor.md +31 -0
  150. claude_mpm/commands/mpm-organize.md +120 -0
  151. claude_mpm/commands/mpm-postmortem.md +21 -0
  152. claude_mpm/commands/mpm-session-resume.md +30 -0
  153. claude_mpm/commands/mpm-status.md +20 -0
  154. claude_mpm/commands/mpm-ticket-view.md +109 -0
  155. claude_mpm/commands/mpm-version.md +20 -0
  156. claude_mpm/commands/mpm.md +31 -0
  157. claude_mpm/config/__init__.py +42 -2
  158. claude_mpm/config/agent_config.py +402 -0
  159. claude_mpm/config/agent_presets.py +488 -0
  160. claude_mpm/config/agent_sources.py +352 -0
  161. claude_mpm/config/experimental_features.py +217 -0
  162. claude_mpm/config/model_config.py +428 -0
  163. claude_mpm/config/paths.py +258 -0
  164. claude_mpm/config/skill_presets.py +392 -0
  165. claude_mpm/config/skill_sources.py +590 -0
  166. claude_mpm/config/socketio_config.py +125 -83
  167. claude_mpm/constants.py +132 -22
  168. claude_mpm/core/__init__.py +62 -36
  169. claude_mpm/core/agent_name_normalizer.py +71 -73
  170. claude_mpm/core/agent_registry.py +385 -492
  171. claude_mpm/core/agent_session_manager.py +81 -70
  172. claude_mpm/core/api_validator.py +330 -0
  173. claude_mpm/core/base_service.py +159 -122
  174. claude_mpm/core/cache.py +560 -0
  175. claude_mpm/core/claude_runner.py +696 -916
  176. claude_mpm/core/config.py +613 -122
  177. claude_mpm/core/config_aliases.py +74 -73
  178. claude_mpm/core/config_constants.py +314 -0
  179. claude_mpm/core/constants.py +361 -0
  180. claude_mpm/core/container.py +646 -104
  181. claude_mpm/core/enums.py +452 -0
  182. claude_mpm/core/error_handler.py +623 -0
  183. claude_mpm/core/exceptions.py +536 -0
  184. claude_mpm/core/factories.py +105 -109
  185. claude_mpm/core/file_utils.py +764 -0
  186. claude_mpm/core/framework/__init__.py +25 -0
  187. claude_mpm/core/framework/formatters/__init__.py +11 -0
  188. claude_mpm/core/framework/formatters/capability_generator.py +367 -0
  189. claude_mpm/core/framework/formatters/content_formatter.py +278 -0
  190. claude_mpm/core/framework/formatters/context_generator.py +185 -0
  191. claude_mpm/core/framework/loaders/__init__.py +13 -0
  192. claude_mpm/core/framework/loaders/agent_loader.py +213 -0
  193. claude_mpm/core/framework/loaders/file_loader.py +176 -0
  194. claude_mpm/core/framework/loaders/instruction_loader.py +222 -0
  195. claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
  196. claude_mpm/core/framework/processors/__init__.py +11 -0
  197. claude_mpm/core/framework/processors/memory_processor.py +230 -0
  198. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  199. claude_mpm/core/framework/processors/template_processor.py +244 -0
  200. claude_mpm/core/framework_loader.py +485 -414
  201. claude_mpm/core/hook_error_memory.py +381 -0
  202. claude_mpm/core/hook_manager.py +246 -86
  203. claude_mpm/core/hook_performance_config.py +147 -0
  204. claude_mpm/core/injectable_service.py +72 -63
  205. claude_mpm/core/instruction_reinforcement_hook.py +267 -0
  206. claude_mpm/core/interactive_session.py +670 -0
  207. claude_mpm/core/interfaces.py +570 -164
  208. claude_mpm/core/lazy.py +467 -0
  209. claude_mpm/core/log_manager.py +707 -0
  210. claude_mpm/core/logger.py +295 -134
  211. claude_mpm/core/logging_config.py +474 -0
  212. claude_mpm/core/logging_utils.py +520 -0
  213. claude_mpm/core/minimal_framework_loader.py +24 -22
  214. claude_mpm/core/mixins.py +30 -29
  215. claude_mpm/core/oneshot_session.py +594 -0
  216. claude_mpm/core/optimized_agent_loader.py +479 -0
  217. claude_mpm/core/optimized_startup.py +554 -0
  218. claude_mpm/core/output_style_manager.py +483 -0
  219. claude_mpm/core/pm_hook_interceptor.py +197 -82
  220. claude_mpm/core/protocols/__init__.py +23 -0
  221. claude_mpm/core/protocols/runner_protocol.py +103 -0
  222. claude_mpm/core/protocols/session_protocol.py +131 -0
  223. claude_mpm/core/service_registry.py +153 -116
  224. claude_mpm/core/session_manager.py +179 -64
  225. claude_mpm/core/shared/__init__.py +17 -0
  226. claude_mpm/core/shared/config_loader.py +326 -0
  227. claude_mpm/core/shared/path_resolver.py +281 -0
  228. claude_mpm/core/shared/singleton_manager.py +221 -0
  229. claude_mpm/core/socketio_pool.py +400 -137
  230. claude_mpm/core/system_context.py +38 -0
  231. claude_mpm/core/tool_access_control.py +64 -57
  232. claude_mpm/core/types.py +307 -0
  233. claude_mpm/core/typing_utils.py +553 -0
  234. claude_mpm/core/unified_agent_registry.py +969 -0
  235. claude_mpm/core/unified_config.py +570 -0
  236. claude_mpm/core/unified_paths.py +941 -0
  237. claude_mpm/dashboard/__init__.py +12 -0
  238. claude_mpm/dashboard/api/simple_directory.py +261 -0
  239. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  240. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
  241. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
  242. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
  243. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
  244. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
  245. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
  246. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
  247. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
  248. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
  249. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
  250. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  251. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
  252. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
  253. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
  254. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
  255. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
  256. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
  257. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
  258. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
  259. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
  260. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
  261. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
  262. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
  263. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
  264. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  265. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
  266. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
  267. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  268. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
  269. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
  270. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
  271. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
  272. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
  273. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
  274. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
  275. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
  276. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
  277. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  278. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
  279. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
  280. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
  281. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
  282. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
  283. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
  284. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
  285. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
  286. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
  287. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
  288. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  289. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
  290. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
  291. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
  292. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
  293. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
  294. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
  295. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
  296. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
  297. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
  298. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
  299. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
  300. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
  301. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
  302. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
  303. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
  304. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  305. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  306. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  307. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  308. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  309. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  310. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  311. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  312. claude_mpm/experimental/__init__.py +10 -0
  313. claude_mpm/experimental/cli_enhancements.py +104 -89
  314. claude_mpm/generators/__init__.py +1 -1
  315. claude_mpm/generators/agent_profile_generator.py +76 -66
  316. claude_mpm/hooks/__init__.py +37 -1
  317. claude_mpm/hooks/base_hook.py +37 -32
  318. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  319. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  320. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  321. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  322. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  323. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  324. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  325. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  326. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  327. claude_mpm/hooks/claude_hooks/connection_pool.py +250 -0
  328. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  329. claude_mpm/hooks/claude_hooks/event_handlers.py +888 -0
  330. claude_mpm/hooks/claude_hooks/hook_handler.py +652 -875
  331. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +10 -7
  332. claude_mpm/hooks/claude_hooks/installer.py +806 -0
  333. claude_mpm/hooks/claude_hooks/memory_integration.py +249 -0
  334. claude_mpm/hooks/claude_hooks/response_tracking.py +412 -0
  335. claude_mpm/hooks/claude_hooks/services/__init__.py +15 -0
  336. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  337. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  338. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  339. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  340. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  341. claude_mpm/hooks/claude_hooks/services/connection_manager.py +229 -0
  342. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +254 -0
  343. claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
  344. claude_mpm/hooks/claude_hooks/services/state_manager.py +284 -0
  345. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
  346. claude_mpm/hooks/claude_hooks/tool_analysis.py +224 -0
  347. claude_mpm/hooks/failure_learning/__init__.py +54 -0
  348. claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
  349. claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
  350. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
  351. claude_mpm/hooks/instruction_reinforcement.py +301 -0
  352. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  353. claude_mpm/hooks/kuzu_memory_hook.py +386 -0
  354. claude_mpm/hooks/kuzu_response_hook.py +179 -0
  355. claude_mpm/hooks/memory_integration_hook.py +201 -107
  356. claude_mpm/hooks/session_resume_hook.py +121 -0
  357. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  358. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  359. claude_mpm/hooks/tool_call_interceptor.py +92 -76
  360. claude_mpm/hooks/validation_hooks.py +62 -54
  361. claude_mpm/init.py +518 -83
  362. claude_mpm/models/__init__.py +9 -9
  363. claude_mpm/models/agent_definition.py +40 -23
  364. claude_mpm/models/agent_session.py +538 -0
  365. claude_mpm/models/git_repository.py +198 -0
  366. claude_mpm/models/resume_log.py +340 -0
  367. claude_mpm/schemas/__init__.py +12 -0
  368. claude_mpm/scripts/__init__.py +15 -0
  369. claude_mpm/scripts/claude-hook-handler.sh +227 -0
  370. claude_mpm/scripts/launch_monitor.py +165 -0
  371. claude_mpm/scripts/mpm_doctor.py +322 -0
  372. claude_mpm/scripts/socketio_daemon.py +189 -200
  373. claude_mpm/scripts/start_activity_logging.py +91 -0
  374. claude_mpm/services/__init__.py +208 -39
  375. claude_mpm/services/agent_capabilities_service.py +266 -0
  376. claude_mpm/services/agents/__init__.py +89 -0
  377. claude_mpm/services/agents/agent_builder.py +514 -0
  378. claude_mpm/services/agents/agent_preset_service.py +238 -0
  379. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  380. claude_mpm/services/agents/agent_review_service.py +280 -0
  381. claude_mpm/services/agents/agent_selection_service.py +484 -0
  382. claude_mpm/services/agents/auto_config_manager.py +796 -0
  383. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  384. claude_mpm/services/agents/cache_git_manager.py +621 -0
  385. claude_mpm/services/agents/deployment/__init__.py +21 -0
  386. claude_mpm/services/agents/deployment/agent_config_provider.py +410 -0
  387. claude_mpm/services/agents/deployment/agent_configuration_manager.py +358 -0
  388. claude_mpm/services/agents/deployment/agent_definition_factory.py +80 -0
  389. claude_mpm/services/agents/deployment/agent_deployment.py +1037 -0
  390. claude_mpm/services/agents/deployment/agent_discovery_service.py +546 -0
  391. claude_mpm/services/agents/deployment/agent_environment_manager.py +288 -0
  392. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +383 -0
  393. claude_mpm/services/agents/deployment/agent_format_converter.py +505 -0
  394. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +160 -0
  395. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +957 -0
  396. claude_mpm/services/agents/deployment/agent_metrics_collector.py +273 -0
  397. claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
  398. claude_mpm/services/agents/deployment/agent_record_service.py +418 -0
  399. claude_mpm/services/agents/deployment/agent_restore_handler.py +84 -0
  400. claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
  401. claude_mpm/services/agents/deployment/agent_template_builder.py +1369 -0
  402. claude_mpm/services/agents/deployment/agent_validator.py +376 -0
  403. claude_mpm/services/agents/deployment/agent_version_manager.py +322 -0
  404. claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +10 -13
  405. claude_mpm/services/agents/deployment/agents_directory_resolver.py +149 -0
  406. claude_mpm/services/agents/deployment/async_agent_deployment.py +768 -0
  407. claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
  408. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  409. claude_mpm/services/agents/deployment/config/deployment_config.py +181 -0
  410. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  411. claude_mpm/services/agents/deployment/deployment_config_loader.py +178 -0
  412. claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
  413. claude_mpm/services/agents/deployment/deployment_type_detector.py +120 -0
  414. claude_mpm/services/agents/deployment/deployment_wrapper.py +129 -0
  415. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  416. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  417. claude_mpm/services/agents/deployment/facade/deployment_executor.py +70 -0
  418. claude_mpm/services/agents/deployment/facade/deployment_facade.py +269 -0
  419. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  420. claude_mpm/services/agents/deployment/interface_adapter.py +226 -0
  421. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  422. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  423. claude_mpm/services/agents/deployment/local_template_deployment.py +362 -0
  424. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +1478 -0
  425. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  426. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  427. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +162 -0
  428. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  429. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  430. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +240 -0
  431. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +110 -0
  432. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +80 -0
  433. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +92 -0
  434. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +101 -0
  435. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  436. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +102 -0
  437. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  438. claude_mpm/services/agents/deployment/processors/agent_processor.py +269 -0
  439. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +311 -0
  440. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +862 -0
  441. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  442. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  443. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  444. claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
  445. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  446. claude_mpm/services/agents/deployment/strategies/base_strategy.py +113 -0
  447. claude_mpm/services/agents/deployment/strategies/project_strategy.py +148 -0
  448. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  449. claude_mpm/services/agents/deployment/strategies/system_strategy.py +131 -0
  450. claude_mpm/services/agents/deployment/strategies/user_strategy.py +130 -0
  451. claude_mpm/services/agents/deployment/system_instructions_deployer.py +228 -0
  452. claude_mpm/services/agents/deployment/validation/__init__.py +21 -0
  453. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  454. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  455. claude_mpm/services/agents/deployment/validation/template_validator.py +319 -0
  456. claude_mpm/services/agents/deployment/validation/validation_result.py +214 -0
  457. claude_mpm/services/agents/git_source_manager.py +682 -0
  458. claude_mpm/services/agents/loading/__init__.py +11 -0
  459. claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +306 -228
  460. claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +106 -91
  461. claude_mpm/services/agents/loading/framework_agent_loader.py +433 -0
  462. claude_mpm/services/agents/local_template_manager.py +784 -0
  463. claude_mpm/services/agents/management/__init__.py +9 -0
  464. claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +92 -69
  465. claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +219 -168
  466. claude_mpm/services/agents/memory/__init__.py +22 -0
  467. claude_mpm/services/agents/memory/agent_memory_manager.py +784 -0
  468. claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +20 -18
  469. claude_mpm/services/agents/memory/content_manager.py +470 -0
  470. claude_mpm/services/agents/memory/memory_categorization_service.py +167 -0
  471. claude_mpm/services/agents/memory/memory_file_service.py +129 -0
  472. claude_mpm/services/agents/memory/memory_format_service.py +201 -0
  473. claude_mpm/services/agents/memory/memory_limits_service.py +101 -0
  474. claude_mpm/services/agents/memory/template_generator.py +83 -0
  475. claude_mpm/services/agents/observers.py +547 -0
  476. claude_mpm/services/agents/recommender.py +617 -0
  477. claude_mpm/services/agents/registry/__init__.py +30 -0
  478. claude_mpm/services/agents/registry/deployed_agent_discovery.py +273 -0
  479. claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +370 -295
  480. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  481. claude_mpm/services/agents/sources/__init__.py +13 -0
  482. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  483. claude_mpm/services/agents/sources/git_source_sync_service.py +1202 -0
  484. claude_mpm/services/agents/startup_sync.py +259 -0
  485. claude_mpm/services/agents/toolchain_detector.py +478 -0
  486. claude_mpm/services/analysis/__init__.py +35 -0
  487. claude_mpm/services/analysis/clone_detector.py +1030 -0
  488. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  489. claude_mpm/services/analysis/postmortem_service.py +765 -0
  490. claude_mpm/services/async_session_logger.py +665 -0
  491. claude_mpm/services/claude_session_logger.py +321 -0
  492. claude_mpm/services/cli/__init__.py +18 -0
  493. claude_mpm/services/cli/agent_cleanup_service.py +408 -0
  494. claude_mpm/services/cli/agent_dependency_service.py +395 -0
  495. claude_mpm/services/cli/agent_listing_service.py +463 -0
  496. claude_mpm/services/cli/agent_output_formatter.py +605 -0
  497. claude_mpm/services/cli/agent_validation_service.py +590 -0
  498. claude_mpm/services/cli/memory_crud_service.py +622 -0
  499. claude_mpm/services/cli/memory_output_formatter.py +604 -0
  500. claude_mpm/services/cli/resume_service.py +617 -0
  501. claude_mpm/services/cli/session_manager.py +604 -0
  502. claude_mpm/services/cli/session_pause_manager.py +504 -0
  503. claude_mpm/services/cli/session_resume_helper.py +372 -0
  504. claude_mpm/services/cli/startup_checker.py +362 -0
  505. claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
  506. claude_mpm/services/command_deployment_service.py +446 -0
  507. claude_mpm/services/command_handler_service.py +221 -0
  508. claude_mpm/services/communication/__init__.py +22 -0
  509. claude_mpm/services/core/__init__.py +108 -0
  510. claude_mpm/services/core/base.py +269 -0
  511. claude_mpm/services/core/cache_manager.py +309 -0
  512. claude_mpm/services/core/interfaces/__init__.py +273 -0
  513. claude_mpm/services/core/interfaces/agent.py +514 -0
  514. claude_mpm/services/core/interfaces/communication.py +316 -0
  515. claude_mpm/services/core/interfaces/health.py +169 -0
  516. claude_mpm/services/core/interfaces/infrastructure.py +357 -0
  517. claude_mpm/services/core/interfaces/model.py +281 -0
  518. claude_mpm/services/core/interfaces/process.py +372 -0
  519. claude_mpm/services/core/interfaces/project.py +121 -0
  520. claude_mpm/services/core/interfaces/restart.py +307 -0
  521. claude_mpm/services/core/interfaces/service.py +405 -0
  522. claude_mpm/services/core/interfaces/stability.py +260 -0
  523. claude_mpm/services/core/interfaces.py +81 -0
  524. claude_mpm/services/core/memory_manager.py +682 -0
  525. claude_mpm/services/core/models/__init__.py +70 -0
  526. claude_mpm/services/core/models/agent_config.py +384 -0
  527. claude_mpm/services/core/models/health.py +162 -0
  528. claude_mpm/services/core/models/process.py +239 -0
  529. claude_mpm/services/core/models/restart.py +302 -0
  530. claude_mpm/services/core/models/stability.py +264 -0
  531. claude_mpm/services/core/models/toolchain.py +306 -0
  532. claude_mpm/services/core/path_resolver.py +517 -0
  533. claude_mpm/services/core/service_container.py +520 -0
  534. claude_mpm/services/core/service_interfaces.py +436 -0
  535. claude_mpm/services/diagnostics/__init__.py +18 -0
  536. claude_mpm/services/diagnostics/checks/__init__.py +38 -0
  537. claude_mpm/services/diagnostics/checks/agent_check.py +370 -0
  538. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  539. claude_mpm/services/diagnostics/checks/base_check.py +60 -0
  540. claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
  541. claude_mpm/services/diagnostics/checks/common_issues_check.py +363 -0
  542. claude_mpm/services/diagnostics/checks/configuration_check.py +306 -0
  543. claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
  544. claude_mpm/services/diagnostics/checks/installation_check.py +520 -0
  545. claude_mpm/services/diagnostics/checks/instructions_check.py +415 -0
  546. claude_mpm/services/diagnostics/checks/mcp_check.py +330 -0
  547. claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
  548. claude_mpm/services/diagnostics/checks/monitor_check.py +281 -0
  549. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  550. claude_mpm/services/diagnostics/checks/startup_log_check.py +319 -0
  551. claude_mpm/services/diagnostics/diagnostic_runner.py +286 -0
  552. claude_mpm/services/diagnostics/doctor_reporter.py +578 -0
  553. claude_mpm/services/diagnostics/models.py +138 -0
  554. claude_mpm/services/event_aggregator.py +582 -0
  555. claude_mpm/services/event_bus/__init__.py +18 -0
  556. claude_mpm/services/event_bus/config.py +186 -0
  557. claude_mpm/services/event_bus/direct_relay.py +312 -0
  558. claude_mpm/services/event_bus/event_bus.py +396 -0
  559. claude_mpm/services/event_bus/relay.py +326 -0
  560. claude_mpm/services/events/__init__.py +44 -0
  561. claude_mpm/services/events/consumers/__init__.py +18 -0
  562. claude_mpm/services/events/consumers/dead_letter.py +306 -0
  563. claude_mpm/services/events/consumers/logging.py +184 -0
  564. claude_mpm/services/events/consumers/metrics.py +241 -0
  565. claude_mpm/services/events/consumers/socketio.py +377 -0
  566. claude_mpm/services/events/core.py +480 -0
  567. claude_mpm/services/events/interfaces.py +214 -0
  568. claude_mpm/services/events/producers/__init__.py +14 -0
  569. claude_mpm/services/events/producers/hook.py +269 -0
  570. claude_mpm/services/events/producers/system.py +329 -0
  571. claude_mpm/services/exceptions.py +433 -353
  572. claude_mpm/services/framework_claude_md_generator/__init__.py +81 -80
  573. claude_mpm/services/framework_claude_md_generator/content_assembler.py +74 -67
  574. claude_mpm/services/framework_claude_md_generator/content_validator.py +66 -62
  575. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +82 -60
  576. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +36 -37
  577. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +41 -40
  578. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +15 -15
  579. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +5 -4
  580. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  581. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  582. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  583. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  584. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +5 -4
  585. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  586. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  587. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +26 -30
  588. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +6 -5
  589. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  590. claude_mpm/services/framework_claude_md_generator/version_manager.py +31 -30
  591. claude_mpm/services/git/__init__.py +21 -0
  592. claude_mpm/services/git/git_operations_service.py +579 -0
  593. claude_mpm/services/github/__init__.py +21 -0
  594. claude_mpm/services/github/github_cli_service.py +397 -0
  595. claude_mpm/services/hook_installer_service.py +506 -0
  596. claude_mpm/services/hook_service.py +159 -111
  597. claude_mpm/services/infrastructure/__init__.py +52 -0
  598. claude_mpm/services/infrastructure/context_preservation.py +569 -0
  599. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  600. claude_mpm/services/infrastructure/logging.py +209 -0
  601. claude_mpm/services/infrastructure/monitoring/__init__.py +39 -0
  602. claude_mpm/services/infrastructure/monitoring/aggregator.py +432 -0
  603. claude_mpm/services/infrastructure/monitoring/base.py +122 -0
  604. claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
  605. claude_mpm/services/infrastructure/monitoring/network.py +219 -0
  606. claude_mpm/services/infrastructure/monitoring/process.py +343 -0
  607. claude_mpm/services/infrastructure/monitoring/resources.py +244 -0
  608. claude_mpm/services/infrastructure/monitoring/service.py +368 -0
  609. claude_mpm/services/infrastructure/monitoring.py +71 -0
  610. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  611. claude_mpm/services/instructions/__init__.py +9 -0
  612. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  613. claude_mpm/services/local_ops/__init__.py +155 -0
  614. claude_mpm/services/local_ops/crash_detector.py +257 -0
  615. claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
  616. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  617. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  618. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  619. claude_mpm/services/local_ops/health_manager.py +427 -0
  620. claude_mpm/services/local_ops/log_monitor.py +396 -0
  621. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  622. claude_mpm/services/local_ops/process_manager.py +595 -0
  623. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  624. claude_mpm/services/local_ops/restart_manager.py +401 -0
  625. claude_mpm/services/local_ops/restart_policy.py +387 -0
  626. claude_mpm/services/local_ops/state_manager.py +372 -0
  627. claude_mpm/services/local_ops/unified_manager.py +600 -0
  628. claude_mpm/services/mcp_config_manager.py +1542 -0
  629. claude_mpm/services/mcp_service_verifier.py +732 -0
  630. claude_mpm/services/memory/__init__.py +19 -0
  631. claude_mpm/services/{memory_builder.py → memory/builder.py} +465 -373
  632. claude_mpm/services/memory/cache/__init__.py +14 -0
  633. claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +237 -200
  634. claude_mpm/services/memory/cache/simple_cache.py +331 -0
  635. claude_mpm/services/memory/failure_tracker.py +578 -0
  636. claude_mpm/services/memory/indexed_memory.py +648 -0
  637. claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +272 -243
  638. claude_mpm/services/memory/router.py +951 -0
  639. claude_mpm/services/memory_hook_service.py +470 -0
  640. claude_mpm/services/model/__init__.py +147 -0
  641. claude_mpm/services/model/base_provider.py +365 -0
  642. claude_mpm/services/model/claude_provider.py +412 -0
  643. claude_mpm/services/model/model_router.py +452 -0
  644. claude_mpm/services/model/ollama_provider.py +415 -0
  645. claude_mpm/services/monitor/__init__.py +20 -0
  646. claude_mpm/services/monitor/daemon.py +698 -0
  647. claude_mpm/services/monitor/daemon_manager.py +1076 -0
  648. claude_mpm/services/monitor/event_emitter.py +350 -0
  649. claude_mpm/services/monitor/handlers/__init__.py +21 -0
  650. claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
  651. claude_mpm/services/monitor/handlers/dashboard.py +299 -0
  652. claude_mpm/services/monitor/handlers/file.py +264 -0
  653. claude_mpm/services/monitor/handlers/hooks.py +512 -0
  654. claude_mpm/services/monitor/management/__init__.py +18 -0
  655. claude_mpm/services/monitor/management/health.py +124 -0
  656. claude_mpm/services/monitor/management/lifecycle.py +730 -0
  657. claude_mpm/services/monitor/server.py +1493 -0
  658. claude_mpm/services/monitor_build_service.py +349 -0
  659. claude_mpm/services/native_agent_converter.py +356 -0
  660. claude_mpm/services/orphan_detection.py +786 -0
  661. claude_mpm/services/pm_skills_deployer.py +707 -0
  662. claude_mpm/services/port_manager.py +597 -0
  663. claude_mpm/services/pr/__init__.py +14 -0
  664. claude_mpm/services/pr/pr_template_service.py +329 -0
  665. claude_mpm/services/profile_manager.py +337 -0
  666. claude_mpm/services/project/__init__.py +44 -0
  667. claude_mpm/services/{project_analyzer.py → project/analyzer.py} +541 -291
  668. claude_mpm/services/project/analyzer_v2.py +566 -0
  669. claude_mpm/services/project/architecture_analyzer.py +461 -0
  670. claude_mpm/services/project/archive_manager.py +1045 -0
  671. claude_mpm/services/project/dependency_analyzer.py +462 -0
  672. claude_mpm/services/project/detection_strategies.py +719 -0
  673. claude_mpm/services/project/documentation_manager.py +554 -0
  674. claude_mpm/services/project/enhanced_analyzer.py +572 -0
  675. claude_mpm/services/project/language_analyzer.py +265 -0
  676. claude_mpm/services/project/metrics_collector.py +407 -0
  677. claude_mpm/services/project/project_organizer.py +1009 -0
  678. claude_mpm/services/project/registry.py +636 -0
  679. claude_mpm/services/project/toolchain_analyzer.py +583 -0
  680. claude_mpm/services/project_port_allocator.py +596 -0
  681. claude_mpm/services/recovery_manager.py +293 -240
  682. claude_mpm/services/response_tracker.py +267 -0
  683. claude_mpm/services/runner_configuration_service.py +605 -0
  684. claude_mpm/services/self_upgrade_service.py +608 -0
  685. claude_mpm/services/session_management_service.py +314 -0
  686. claude_mpm/services/session_manager.py +380 -0
  687. claude_mpm/services/shared/__init__.py +21 -0
  688. claude_mpm/services/shared/async_service_base.py +216 -0
  689. claude_mpm/services/shared/config_service_base.py +301 -0
  690. claude_mpm/services/shared/lifecycle_service_base.py +308 -0
  691. claude_mpm/services/shared/manager_base.py +315 -0
  692. claude_mpm/services/shared/service_factory.py +309 -0
  693. claude_mpm/services/skills/__init__.py +21 -0
  694. claude_mpm/services/skills/git_skill_source_manager.py +1324 -0
  695. claude_mpm/services/skills/selective_skill_deployer.py +744 -0
  696. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  697. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  698. claude_mpm/services/skills_config.py +547 -0
  699. claude_mpm/services/skills_deployer.py +1168 -0
  700. claude_mpm/services/socketio/__init__.py +25 -0
  701. claude_mpm/services/socketio/client_proxy.py +229 -0
  702. claude_mpm/services/socketio/dashboard_server.py +362 -0
  703. claude_mpm/services/socketio/event_normalizer.py +798 -0
  704. claude_mpm/services/socketio/handlers/__init__.py +30 -0
  705. claude_mpm/services/socketio/handlers/base.py +136 -0
  706. claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
  707. claude_mpm/services/socketio/handlers/connection.py +643 -0
  708. claude_mpm/services/socketio/handlers/connection_handler.py +333 -0
  709. claude_mpm/services/socketio/handlers/file.py +263 -0
  710. claude_mpm/services/socketio/handlers/git.py +962 -0
  711. claude_mpm/services/socketio/handlers/hook.py +211 -0
  712. claude_mpm/services/socketio/handlers/memory.py +26 -0
  713. claude_mpm/services/socketio/handlers/project.py +24 -0
  714. claude_mpm/services/socketio/handlers/registry.py +214 -0
  715. claude_mpm/services/socketio/migration_utils.py +343 -0
  716. claude_mpm/services/socketio/monitor_client.py +364 -0
  717. claude_mpm/services/socketio/server/__init__.py +18 -0
  718. claude_mpm/services/socketio/server/broadcaster.py +569 -0
  719. claude_mpm/services/socketio/server/connection_manager.py +579 -0
  720. claude_mpm/services/socketio/server/core.py +1079 -0
  721. claude_mpm/services/socketio/server/eventbus_integration.py +245 -0
  722. claude_mpm/services/socketio/server/main.py +501 -0
  723. claude_mpm/services/socketio_client_manager.py +173 -143
  724. claude_mpm/services/socketio_server.py +38 -1657
  725. claude_mpm/services/subprocess_launcher_service.py +322 -0
  726. claude_mpm/services/system_instructions_service.py +270 -0
  727. claude_mpm/services/ticket_manager.py +25 -209
  728. claude_mpm/services/ticket_services/__init__.py +26 -0
  729. claude_mpm/services/ticket_services/crud_service.py +328 -0
  730. claude_mpm/services/ticket_services/formatter_service.py +290 -0
  731. claude_mpm/services/ticket_services/search_service.py +324 -0
  732. claude_mpm/services/ticket_services/validation_service.py +303 -0
  733. claude_mpm/services/ticket_services/workflow_service.py +244 -0
  734. claude_mpm/services/unified/__init__.py +65 -0
  735. claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
  736. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
  737. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
  738. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
  739. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
  740. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
  741. claude_mpm/services/unified/config_strategies/__init__.py +175 -0
  742. claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
  743. claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
  744. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
  745. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
  746. claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
  747. claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
  748. claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
  749. claude_mpm/services/unified/deployment_strategies/base.py +553 -0
  750. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
  751. claude_mpm/services/unified/deployment_strategies/local.py +607 -0
  752. claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
  753. claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
  754. claude_mpm/services/unified/interfaces.py +475 -0
  755. claude_mpm/services/unified/migration.py +509 -0
  756. claude_mpm/services/unified/strategies.py +534 -0
  757. claude_mpm/services/unified/unified_analyzer.py +542 -0
  758. claude_mpm/services/unified/unified_config.py +691 -0
  759. claude_mpm/services/unified/unified_deployment.py +466 -0
  760. claude_mpm/services/utility_service.py +280 -0
  761. claude_mpm/services/version_control/__init__.py +34 -37
  762. claude_mpm/services/version_control/branch_strategy.py +26 -17
  763. claude_mpm/services/version_control/conflict_resolution.py +52 -36
  764. claude_mpm/services/version_control/git_operations.py +183 -49
  765. claude_mpm/services/version_control/semantic_versioning.py +172 -61
  766. claude_mpm/services/version_control/version_parser.py +546 -0
  767. claude_mpm/services/version_service.py +379 -0
  768. claude_mpm/services/visualization/__init__.py +15 -0
  769. claude_mpm/services/visualization/mermaid_generator.py +937 -0
  770. claude_mpm/skills/__init__.py +42 -0
  771. claude_mpm/skills/agent_skills_injector.py +324 -0
  772. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  773. claude_mpm/skills/bundled/__init__.py +6 -0
  774. claude_mpm/skills/bundled/api-documentation.md +393 -0
  775. claude_mpm/skills/bundled/async-testing.md +571 -0
  776. claude_mpm/skills/bundled/code-review.md +143 -0
  777. claude_mpm/skills/bundled/database-migration.md +199 -0
  778. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  779. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  780. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  781. claude_mpm/skills/bundled/git-workflow.md +414 -0
  782. claude_mpm/skills/bundled/imagemagick.md +204 -0
  783. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  784. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  785. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  786. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  787. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  788. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  789. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  790. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  791. claude_mpm/skills/bundled/pdf.md +141 -0
  792. claude_mpm/skills/bundled/performance-profiling.md +573 -0
  793. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  794. claude_mpm/skills/bundled/security-scanning.md +439 -0
  795. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  796. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  797. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  798. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  799. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  800. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  801. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  802. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  803. claude_mpm/skills/bundled/xlsx.md +157 -0
  804. claude_mpm/skills/registry.py +286 -0
  805. claude_mpm/skills/skill_manager.py +405 -0
  806. claude_mpm/skills/skills_registry.py +347 -0
  807. claude_mpm/skills/skills_service.py +739 -0
  808. claude_mpm/storage/__init__.py +9 -0
  809. claude_mpm/storage/state_storage.py +546 -0
  810. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  811. claude_mpm/templates/questions/__init__.py +38 -0
  812. claude_mpm/templates/questions/base.py +193 -0
  813. claude_mpm/templates/questions/pr_strategy.py +311 -0
  814. claude_mpm/templates/questions/project_init.py +385 -0
  815. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  816. claude_mpm/ticket_wrapper.py +2 -2
  817. claude_mpm/tools/__init__.py +10 -0
  818. claude_mpm/tools/__main__.py +208 -0
  819. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  820. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  821. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  822. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  823. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  824. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  825. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  826. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  827. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  828. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  829. claude_mpm/tools/code_tree_builder.py +631 -0
  830. claude_mpm/tools/code_tree_events.py +420 -0
  831. claude_mpm/tools/socketio_debug.py +671 -0
  832. claude_mpm/utils/__init__.py +8 -8
  833. claude_mpm/utils/agent_dependency_loader.py +1090 -0
  834. claude_mpm/utils/agent_filters.py +261 -0
  835. claude_mpm/utils/common.py +544 -0
  836. claude_mpm/utils/config_manager.py +168 -126
  837. claude_mpm/utils/console.py +11 -0
  838. claude_mpm/utils/database_connector.py +298 -0
  839. claude_mpm/utils/dependency_cache.py +373 -0
  840. claude_mpm/utils/dependency_manager.py +60 -59
  841. claude_mpm/utils/dependency_strategies.py +381 -0
  842. claude_mpm/utils/display_helper.py +260 -0
  843. claude_mpm/utils/environment_context.py +313 -0
  844. claude_mpm/utils/error_handler.py +78 -66
  845. claude_mpm/utils/file_utils.py +305 -0
  846. claude_mpm/utils/framework_detection.py +12 -11
  847. claude_mpm/utils/git_analyzer.py +407 -0
  848. claude_mpm/utils/gitignore.py +244 -0
  849. claude_mpm/utils/import_migration_example.py +12 -60
  850. claude_mpm/utils/imports.py +48 -45
  851. claude_mpm/utils/log_cleanup.py +627 -0
  852. claude_mpm/utils/migration.py +372 -0
  853. claude_mpm/utils/path_operations.py +110 -104
  854. claude_mpm/utils/progress.py +387 -0
  855. claude_mpm/utils/robust_installer.py +823 -0
  856. claude_mpm/utils/session_logging.py +121 -0
  857. claude_mpm/utils/structured_questions.py +619 -0
  858. claude_mpm/utils/subprocess_utils.py +343 -0
  859. claude_mpm/validation/__init__.py +1 -1
  860. claude_mpm/validation/agent_validator.py +214 -108
  861. claude_mpm/validation/frontmatter_validator.py +252 -0
  862. claude_mpm-5.4.55.dist-info/METADATA +999 -0
  863. claude_mpm-5.4.55.dist-info/RECORD +868 -0
  864. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/entry_points.txt +1 -3
  865. claude_mpm-5.4.55.dist-info/licenses/LICENSE +94 -0
  866. claude_mpm-5.4.55.dist-info/licenses/LICENSE-FAQ.md +153 -0
  867. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -88
  868. claude_mpm/agents/INSTRUCTIONS.md +0 -352
  869. claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
  870. claude_mpm/agents/base_agent_loader.py +0 -529
  871. claude_mpm/agents/schema/agent_schema.json +0 -314
  872. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
  873. claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -46
  874. claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -45
  875. claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -49
  876. claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -46
  877. claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -45
  878. claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -49
  879. claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -46
  880. claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -46
  881. claude_mpm/agents/templates/data_engineer.json +0 -110
  882. claude_mpm/agents/templates/documentation.json +0 -109
  883. claude_mpm/agents/templates/engineer.json +0 -113
  884. claude_mpm/agents/templates/ops.json +0 -109
  885. claude_mpm/agents/templates/pm.json +0 -25
  886. claude_mpm/agents/templates/qa.json +0 -111
  887. claude_mpm/agents/templates/research.json +0 -65
  888. claude_mpm/agents/templates/security.json +0 -113
  889. claude_mpm/agents/templates/test_integration.json +0 -112
  890. claude_mpm/agents/templates/version_control.json +0 -107
  891. claude_mpm/cli/commands/ui.py +0 -57
  892. claude_mpm/core/simple_runner.py +0 -1046
  893. claude_mpm/dashboard/open_dashboard.py +0 -34
  894. claude_mpm/deployment_paths.py +0 -261
  895. claude_mpm/hooks/builtin/__init__.py +0 -1
  896. claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
  897. claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
  898. claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
  899. claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
  900. claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
  901. claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
  902. claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
  903. claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
  904. claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
  905. claude_mpm/orchestration/__init__.py +0 -6
  906. claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
  907. claude_mpm/orchestration/archive/factory.py +0 -215
  908. claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
  909. claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
  910. claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
  911. claude_mpm/orchestration/archive/orchestrator.py +0 -501
  912. claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
  913. claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
  914. claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
  915. claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
  916. claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
  917. claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
  918. claude_mpm/schemas/workflow_validator.py +0 -411
  919. claude_mpm/services/agent_deployment.py +0 -1534
  920. claude_mpm/services/agent_lifecycle_manager.py +0 -1169
  921. claude_mpm/services/agent_memory_manager.py +0 -1415
  922. claude_mpm/services/agent_registry.py +0 -676
  923. claude_mpm/services/deployed_agent_discovery.py +0 -226
  924. claude_mpm/services/framework_agent_loader.py +0 -337
  925. claude_mpm/services/framework_claude_md_generator.py +0 -621
  926. claude_mpm/services/health_monitor.py +0 -892
  927. claude_mpm/services/memory_router.py +0 -538
  928. claude_mpm/services/parent_directory_manager/__init__.py +0 -577
  929. claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
  930. claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
  931. claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
  932. claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
  933. claude_mpm/services/parent_directory_manager/operations.py +0 -186
  934. claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
  935. claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
  936. claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
  937. claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
  938. claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
  939. claude_mpm/services/standalone_socketio_server.py +0 -1300
  940. claude_mpm/services/ticket_manager_di.py +0 -318
  941. claude_mpm/services/ticketing_service_original.py +0 -508
  942. claude_mpm/ui/__init__.py +0 -1
  943. claude_mpm/ui/rich_terminal_ui.py +0 -295
  944. claude_mpm/ui/terminal_ui.py +0 -328
  945. claude_mpm/utils/paths.py +0 -289
  946. claude_mpm-3.4.10.dist-info/METADATA +0 -183
  947. claude_mpm-3.4.10.dist-info/RECORD +0 -201
  948. claude_mpm-3.4.10.dist-info/licenses/LICENSE +0 -21
  949. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/WHEEL +0 -0
  950. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1090 @@
1
+ from pathlib import Path
2
+
3
+ """
4
+ Dynamic agent dependency loader for runtime dependency management.
5
+
6
+ This module handles loading and checking dependencies for deployed agents
7
+ at runtime, rather than requiring all possible agent dependencies to be
8
+ installed upfront.
9
+ """
10
+
11
+ import hashlib
12
+ import json
13
+ import logging
14
+ import subprocess
15
+ import sys
16
+ import time
17
+ from typing import Any, Dict, List, Optional, Set, Tuple
18
+
19
+ import yaml
20
+ from packaging.requirements import InvalidRequirement, Requirement
21
+
22
+ from ..core.logger import get_logger
23
+
24
+ logger = get_logger(__name__)
25
+
26
+
27
+ class AgentDependencyLoader:
28
+ """
29
+ Dynamically loads and manages dependencies for deployed agents.
30
+
31
+ Only checks/installs dependencies for agents that are actually deployed
32
+ and being used, rather than all possible agents.
33
+ """
34
+
35
+ # Optional database packages - if one fails, try alternatives
36
+ OPTIONAL_DB_PACKAGES = {
37
+ "mysqlclient": ["pymysql"], # PyMySQL is a pure Python alternative
38
+ "psycopg2": ["psycopg2-binary"], # Binary version doesn't require compilation
39
+ "cx_Oracle": [], # No good alternative, mark as optional
40
+ }
41
+
42
+ # Packages that commonly fail compilation on certain platforms
43
+ COMPILATION_PRONE = [
44
+ "mysqlclient", # Requires MySQL development headers
45
+ "psycopg2", # Requires PostgreSQL development headers (use psycopg2-binary instead)
46
+ "cx_Oracle", # Requires Oracle client libraries
47
+ "pycairo", # Requires Cairo development headers
48
+ "lxml", # Can fail if libxml2 dev headers missing
49
+ ]
50
+
51
+ def __init__(self, auto_install: bool = False):
52
+ """
53
+ Initialize the agent dependency loader.
54
+
55
+ Args:
56
+ auto_install: If True, automatically install missing dependencies.
57
+ If False, only check and report missing dependencies.
58
+ """
59
+ self.auto_install = auto_install
60
+ self.deployed_agents: Dict[str, Path] = {}
61
+ self.agent_dependencies: Dict[str, Dict] = {}
62
+ self.missing_dependencies: Dict[str, List[str]] = {}
63
+ self.checked_packages: Set[str] = set()
64
+ self.optional_failed: Dict[str, str] = {} # Track optional packages that failed
65
+ self.deployment_state_file = (
66
+ Path.cwd() / ".claude" / "agents" / ".mpm_deployment_state"
67
+ )
68
+
69
+ def discover_deployed_agents(self) -> Dict[str, Path]:
70
+ """
71
+ Discover which agents are currently deployed in .claude/agents/
72
+
73
+ Returns:
74
+ Dictionary mapping agent IDs to their file paths
75
+ """
76
+ deployed_agents: Dict[str, Path] = {}
77
+ claude_agents_dir = Path.cwd() / ".claude" / "agents"
78
+
79
+ if not claude_agents_dir.exists():
80
+ logger.debug("No .claude/agents directory found")
81
+ return deployed_agents
82
+
83
+ # Scan for deployed agent markdown files
84
+ for agent_file in claude_agents_dir.glob("*.md"):
85
+ agent_id = agent_file.stem
86
+ deployed_agents[agent_id] = agent_file
87
+ logger.debug(f"Found deployed agent: {agent_id}")
88
+
89
+ logger.debug(f"Discovered {len(deployed_agents)} deployed agents")
90
+ self.deployed_agents = deployed_agents
91
+ return deployed_agents
92
+
93
+ def _extract_yaml_frontmatter(self, content: str) -> Optional[Dict[str, Any]]:
94
+ """
95
+ Extract and parse YAML frontmatter from markdown.
96
+
97
+ Frontmatter must be at the start of the file, delimited by '---'.
98
+ Example:
99
+ ---
100
+ name: agent_name
101
+ dependencies:
102
+ python:
103
+ - package>=1.0.0
104
+ ---
105
+ # Agent content...
106
+
107
+ Args:
108
+ content: File content to parse
109
+
110
+ Returns:
111
+ Parsed YAML frontmatter as dict, or None if not found/invalid
112
+ """
113
+ if not content.strip().startswith("---"):
114
+ return None
115
+
116
+ # Split on --- delimiters
117
+ parts = content.split("---", 2)
118
+ if len(parts) < 3:
119
+ return None
120
+
121
+ try:
122
+ return yaml.safe_load(parts[1])
123
+ except yaml.YAMLError as e:
124
+ logger.warning(f"Failed to parse YAML frontmatter: {e}")
125
+ return None
126
+
127
+ def load_agent_dependencies(self) -> Dict[str, Dict]:
128
+ """
129
+ Load dependency information for deployed agents from their source configs.
130
+
131
+ Searches for agent configuration in both markdown (.md) and JSON (.json) formats.
132
+ Markdown files with YAML frontmatter are searched first for better maintainability.
133
+ Falls back to JSON format for backward compatibility.
134
+
135
+ Returns:
136
+ Dictionary mapping agent IDs to their dependency requirements
137
+ """
138
+ agent_dependencies = {}
139
+
140
+ # Define paths to check for agent configs (in precedence order)
141
+ config_paths = [
142
+ Path.cwd() / ".claude-mpm" / "agents", # PROJECT
143
+ Path.home() / ".claude-mpm" / "agents", # USER
144
+ Path.cwd() / "src" / "claude_mpm" / "agents" / "templates", # SYSTEM
145
+ ]
146
+
147
+ for agent_id in self.deployed_agents:
148
+ found = False
149
+
150
+ # Try to find the agent's config (markdown first, then JSON)
151
+ for config_dir in config_paths:
152
+ if found:
153
+ break
154
+
155
+ # Try markdown first (current format with YAML frontmatter)
156
+ md_file = config_dir / f"{agent_id}.md"
157
+ if md_file.exists():
158
+ try:
159
+ content = md_file.read_text(encoding="utf-8")
160
+ frontmatter = self._extract_yaml_frontmatter(content)
161
+ if frontmatter and "dependencies" in frontmatter:
162
+ agent_dependencies[agent_id] = frontmatter["dependencies"]
163
+ logger.debug(
164
+ f"Loaded dependencies for {agent_id} from markdown"
165
+ )
166
+ found = True
167
+ break
168
+ except Exception as e:
169
+ logger.warning(f"Failed to load markdown for {agent_id}: {e}")
170
+
171
+ # Fall back to JSON for backward compatibility
172
+ if not found:
173
+ json_file = config_dir / f"{agent_id}.json"
174
+ if json_file.exists():
175
+ try:
176
+ with json_file.open() as f:
177
+ config = json.load(f)
178
+ if "dependencies" in config:
179
+ agent_dependencies[agent_id] = config[
180
+ "dependencies"
181
+ ]
182
+ logger.debug(
183
+ f"Loaded dependencies for {agent_id} from JSON"
184
+ )
185
+ found = True
186
+ break
187
+ except Exception as e:
188
+ logger.warning(f"Failed to load JSON for {agent_id}: {e}")
189
+
190
+ self.agent_dependencies = agent_dependencies
191
+ logger.debug(f"Loaded dependencies for {len(agent_dependencies)} agents")
192
+ return agent_dependencies
193
+
194
+ def check_python_dependency(self, package_spec: str) -> Tuple[bool, Optional[str]]:
195
+ """
196
+ Check if a Python package dependency is satisfied.
197
+
198
+ Args:
199
+ package_spec: Package specification (e.g., "pandas>=2.0.0")
200
+
201
+ Returns:
202
+ Tuple of (is_satisfied, installed_version)
203
+ """
204
+ try:
205
+ req = Requirement(package_spec)
206
+ package_name = req.name
207
+
208
+ # Skip if already checked
209
+ if package_name in self.checked_packages:
210
+ return True, None
211
+
212
+ # Check if it's a built-in module first
213
+ if self._is_builtin_module(package_name):
214
+ self.checked_packages.add(package_name)
215
+ return True, "built-in"
216
+
217
+ # Check if this is an optional package that already failed
218
+ if package_name in self.optional_failed:
219
+ logger.debug(
220
+ f"Skipping optional package {package_name} (previously failed)"
221
+ )
222
+ return True, "optional-skipped"
223
+
224
+ # Try to import and check version
225
+ try:
226
+ import importlib.metadata
227
+
228
+ try:
229
+ version = importlib.metadata.version(package_name)
230
+ self.checked_packages.add(package_name)
231
+
232
+ # Check if version satisfies requirement
233
+ if req.specifier.contains(version):
234
+ return True, version
235
+ logger.debug(
236
+ f"{package_name} {version} does not satisfy {req.specifier}"
237
+ )
238
+ return False, version
239
+
240
+ except importlib.metadata.PackageNotFoundError:
241
+ # Check if there's an alternative for this optional package
242
+ if package_name in self.OPTIONAL_DB_PACKAGES:
243
+ for alternative in self.OPTIONAL_DB_PACKAGES[package_name]:
244
+ try:
245
+ alt_version = importlib.metadata.version(alternative)
246
+ logger.info(
247
+ f"Using {alternative} as alternative to {package_name}"
248
+ )
249
+ self.checked_packages.add(package_name)
250
+ return True, f"{alternative}:{alt_version}"
251
+ except importlib.metadata.PackageNotFoundError:
252
+ continue
253
+ # If no alternatives work, mark as optional failure
254
+ self.optional_failed[package_name] = "No alternatives available"
255
+ logger.warning(
256
+ f"Optional package {package_name} not found, marking as optional"
257
+ )
258
+ return True, "optional-not-found"
259
+ return False, None
260
+
261
+ except ImportError:
262
+ # Fallback for older Python versions
263
+ try:
264
+ import pkg_resources
265
+
266
+ version = pkg_resources.get_distribution(package_name).version
267
+ self.checked_packages.add(package_name)
268
+
269
+ if req.specifier.contains(version):
270
+ return True, version
271
+ return False, version
272
+
273
+ except pkg_resources.DistributionNotFound:
274
+ # Check alternatives for optional packages
275
+ if package_name in self.OPTIONAL_DB_PACKAGES:
276
+ for alternative in self.OPTIONAL_DB_PACKAGES[package_name]:
277
+ try:
278
+ alt_version = pkg_resources.get_distribution(
279
+ alternative
280
+ ).version
281
+ logger.info(
282
+ f"Using {alternative} as alternative to {package_name}"
283
+ )
284
+ self.checked_packages.add(package_name)
285
+ return True, f"{alternative}:{alt_version}"
286
+ except pkg_resources.DistributionNotFound:
287
+ continue
288
+ self.optional_failed[package_name] = "No alternatives available"
289
+ logger.warning(
290
+ f"Optional package {package_name} not found, marking as optional"
291
+ )
292
+ return True, "optional-not-found"
293
+ return False, None
294
+
295
+ except InvalidRequirement as e:
296
+ logger.warning(f"Invalid requirement specification: {package_spec}: {e}")
297
+ return False, None
298
+
299
+ def _is_builtin_module(self, module_name: str) -> bool:
300
+ """
301
+ Check if a module is a built-in Python module.
302
+
303
+ Args:
304
+ module_name: Name of the module to check
305
+
306
+ Returns:
307
+ True if the module is built-in, False otherwise
308
+ """
309
+ # List of common built-in modules that don't have distribution metadata
310
+ builtin_modules = {
311
+ "json",
312
+ "pathlib",
313
+ "os",
314
+ "sys",
315
+ "datetime",
316
+ "time",
317
+ "math",
318
+ "random",
319
+ "collections",
320
+ "itertools",
321
+ "functools",
322
+ "operator",
323
+ "copy",
324
+ "pickle",
325
+ "sqlite3",
326
+ "urllib",
327
+ "http",
328
+ "email",
329
+ "html",
330
+ "xml",
331
+ "csv",
332
+ "configparser",
333
+ "logging",
334
+ "unittest",
335
+ "doctest",
336
+ "pdb",
337
+ "profile",
338
+ "timeit",
339
+ "trace",
340
+ "gc",
341
+ "weakref",
342
+ "types",
343
+ "inspect",
344
+ "importlib",
345
+ "pkgutil",
346
+ "modulefinder",
347
+ "runpy",
348
+ "ast",
349
+ "symtable",
350
+ "keyword",
351
+ "token",
352
+ "tokenize",
353
+ "tabnanny",
354
+ "pyclbr",
355
+ "py_compile",
356
+ "compileall",
357
+ "dis",
358
+ "pickletools",
359
+ "platform",
360
+ "ctypes",
361
+ "struct",
362
+ "codecs",
363
+ "unicodedata",
364
+ "stringprep",
365
+ "readline",
366
+ "rlcompleter",
367
+ "subprocess",
368
+ "sched",
369
+ "queue",
370
+ "threading",
371
+ "multiprocessing",
372
+ "concurrent",
373
+ "asyncio",
374
+ "socket",
375
+ "ssl",
376
+ "select",
377
+ "selectors",
378
+ "signal",
379
+ "mmap",
380
+ "errno",
381
+ "io",
382
+ "tempfile",
383
+ "glob",
384
+ "fnmatch",
385
+ "linecache",
386
+ "shutil",
387
+ "stat",
388
+ "filecmp",
389
+ "tarfile",
390
+ "zipfile",
391
+ "gzip",
392
+ "bz2",
393
+ "lzma",
394
+ "zlib",
395
+ "hashlib",
396
+ "hmac",
397
+ "secrets",
398
+ "base64",
399
+ "binascii",
400
+ "quopri",
401
+ "uu",
402
+ "string",
403
+ "re",
404
+ "difflib",
405
+ "textwrap",
406
+ "calendar",
407
+ "locale",
408
+ "gettext",
409
+ "argparse",
410
+ "optparse",
411
+ "getopt",
412
+ "shlex",
413
+ "cmd",
414
+ "pprint",
415
+ "reprlib",
416
+ "enum",
417
+ "numbers",
418
+ "decimal",
419
+ "fractions",
420
+ "statistics",
421
+ "array",
422
+ "bisect",
423
+ "heapq",
424
+ "contextlib",
425
+ "abc",
426
+ "atexit",
427
+ "traceback",
428
+ "warnings",
429
+ "dataclasses",
430
+ "graphlib",
431
+ }
432
+
433
+ # Check if it's in our known built-in modules
434
+ if module_name in builtin_modules:
435
+ return True
436
+
437
+ # Try to import it and check if it's a built-in module
438
+ try:
439
+ import importlib.util
440
+
441
+ spec = importlib.util.find_spec(module_name)
442
+ if spec is not None and spec.origin is None:
443
+ # Built-in modules have spec.origin as None
444
+ return True
445
+ except (ImportError, ModuleNotFoundError, ValueError):
446
+ pass
447
+
448
+ return False
449
+
450
+ def check_system_dependency(self, command: str) -> bool:
451
+ """
452
+ Check if a system command is available in PATH.
453
+
454
+ Args:
455
+ command: System command to check (e.g., "git")
456
+
457
+ Returns:
458
+ True if command is available, False otherwise
459
+ """
460
+ try:
461
+ result = subprocess.run(
462
+ ["which", command],
463
+ capture_output=True,
464
+ text=True,
465
+ timeout=5,
466
+ check=False,
467
+ )
468
+ return result.returncode == 0
469
+ except Exception:
470
+ return False
471
+
472
+ def analyze_dependencies(self) -> Dict[str, Dict]:
473
+ """
474
+ Analyze dependencies for all deployed agents.
475
+
476
+ Returns:
477
+ Analysis results including missing and satisfied dependencies
478
+ """
479
+ results: Dict[str, Any] = {
480
+ "agents": {},
481
+ "summary": {
482
+ "total_agents": len(self.deployed_agents),
483
+ "agents_with_deps": 0,
484
+ "missing_python": [],
485
+ "missing_system": [],
486
+ "satisfied_python": [],
487
+ "satisfied_system": [],
488
+ },
489
+ }
490
+
491
+ for agent_id, deps in self.agent_dependencies.items():
492
+ agent_result: Dict[str, Dict[str, List[str]]] = {
493
+ "python": {"satisfied": [], "missing": [], "outdated": []},
494
+ "system": {"satisfied": [], "missing": []},
495
+ }
496
+
497
+ # Check Python dependencies
498
+ if "python" in deps:
499
+ for dep_spec in deps["python"]:
500
+ is_satisfied, version = self.check_python_dependency(dep_spec)
501
+ if is_satisfied:
502
+ agent_result["python"]["satisfied"].append(dep_spec)
503
+ if dep_spec not in results["summary"]["satisfied_python"]:
504
+ results["summary"]["satisfied_python"].append(dep_spec)
505
+ elif version: # Installed but wrong version
506
+ agent_result["python"]["outdated"].append(
507
+ f"{dep_spec} (have {version})"
508
+ )
509
+ else: # Not installed
510
+ agent_result["python"]["missing"].append(dep_spec)
511
+ if dep_spec not in results["summary"]["missing_python"]:
512
+ results["summary"]["missing_python"].append(dep_spec)
513
+
514
+ # Check system dependencies
515
+ if "system" in deps:
516
+ for command in deps["system"]:
517
+ if self.check_system_dependency(command):
518
+ agent_result["system"]["satisfied"].append(command)
519
+ if command not in results["summary"]["satisfied_system"]:
520
+ results["summary"]["satisfied_system"].append(command)
521
+ else:
522
+ agent_result["system"]["missing"].append(command)
523
+ if command not in results["summary"]["missing_system"]:
524
+ results["summary"]["missing_system"].append(command)
525
+
526
+ results["agents"][agent_id] = agent_result
527
+ if "python" in deps or "system" in deps:
528
+ results["summary"]["agents_with_deps"] += 1
529
+
530
+ return results
531
+
532
+ def check_python_compatibility(
533
+ self, dependencies: List[str]
534
+ ) -> Tuple[List[str], List[str]]:
535
+ """
536
+ Check which dependencies are compatible with current Python version.
537
+
538
+ Args:
539
+ dependencies: List of package specifications to check
540
+
541
+ Returns:
542
+ Tuple of (compatible_deps, incompatible_deps)
543
+ """
544
+ import sys
545
+
546
+ compatible: List[str] = []
547
+ incompatible: List[str] = []
548
+
549
+ for dep in dependencies:
550
+ try:
551
+ # For known problematic packages in Python 3.13
552
+ req = Requirement(dep)
553
+ package_name = req.name.lower()
554
+
555
+ # Known Python 3.13 incompatibilities
556
+ if sys.version_info >= (3, 13):
557
+ if (
558
+ package_name in ["ydata-profiling", "pandas-profiling"]
559
+ or package_name == "apache-airflow"
560
+ ):
561
+ incompatible.append(f"{dep} (requires Python <3.13)")
562
+ continue
563
+
564
+ # Default to compatible if we don't know
565
+ compatible.append(dep)
566
+
567
+ except Exception as e:
568
+ logger.warning(f"Could not check compatibility for {dep}: {e}")
569
+ compatible.append(dep) # Assume compatible if we can't check
570
+
571
+ return compatible, incompatible
572
+
573
+ def install_missing_dependencies(self, dependencies: List[str]) -> Tuple[bool, str]:
574
+ """
575
+ Install missing Python dependencies using robust retry logic.
576
+
577
+ WHY: Network issues and temporary package unavailability can cause
578
+ installation failures. Using the robust installer with retries
579
+ significantly improves success rate.
580
+
581
+ Args:
582
+ dependencies: List of package specifications to install
583
+
584
+ Returns:
585
+ Tuple of (success, error_message)
586
+ """
587
+ if not dependencies:
588
+ return True, ""
589
+
590
+ # Check Python version compatibility first
591
+ compatible, incompatible = self.check_python_compatibility(dependencies)
592
+
593
+ if incompatible:
594
+ logger.warning(f"Skipping {len(incompatible)} incompatible packages:")
595
+ for dep in incompatible:
596
+ logger.warning(f" - {dep}")
597
+
598
+ if not compatible:
599
+ return True, "No compatible packages to install"
600
+
601
+ # Use robust installer with retry logic
602
+ try:
603
+ from .robust_installer import RobustPackageInstaller
604
+
605
+ logger.info(
606
+ f"Installing {len(compatible)} compatible dependencies with retry logic..."
607
+ )
608
+ if incompatible:
609
+ logger.info(
610
+ f"(Skipping {len(incompatible)} incompatible with Python {sys.version_info.major}.{sys.version_info.minor})"
611
+ )
612
+
613
+ # Create installer with sensible defaults
614
+ installer = RobustPackageInstaller(
615
+ max_retries=3, retry_delay=2.0, timeout=300
616
+ )
617
+
618
+ # Install packages
619
+ successful, failed, errors = installer.install_packages(compatible)
620
+
621
+ if failed:
622
+ # Provide detailed error information
623
+ error_details = []
624
+ for pkg in failed:
625
+ error_details.append(f"{pkg}: {errors.get(pkg, 'Unknown error')}")
626
+
627
+ error_msg = f"Failed to install {len(failed)} packages:\n" + "\n".join(
628
+ error_details
629
+ )
630
+ logger.error(error_msg)
631
+
632
+ # Partial success handling
633
+ if successful:
634
+ partial_msg = f"Partially successful: installed {len(successful)} of {len(compatible)} packages"
635
+ logger.info(partial_msg)
636
+ if incompatible:
637
+ return (
638
+ True,
639
+ f"{partial_msg}. Also skipped {len(incompatible)} incompatible",
640
+ )
641
+ return True, partial_msg
642
+
643
+ return False, error_msg
644
+
645
+ logger.info(
646
+ f"Successfully installed all {len(successful)} compatible dependencies"
647
+ )
648
+ if incompatible:
649
+ return (
650
+ True,
651
+ f"Installed {len(compatible)} packages, skipped {len(incompatible)} incompatible",
652
+ )
653
+ return True, ""
654
+
655
+ except ImportError:
656
+ # Fallback to simple installation if robust installer not available
657
+ logger.warning(
658
+ "Robust installer not available, falling back to simple installation"
659
+ )
660
+ try:
661
+ # Check environment and add appropriate flags
662
+ import os
663
+ import sysconfig
664
+
665
+ # Check if in UV tool environment (no pip available)
666
+ uv_tool_dir = os.environ.get("UV_TOOL_DIR", "")
667
+ is_uv_tool = (
668
+ (uv_tool_dir and "claude-mpm" in uv_tool_dir)
669
+ or ".local/share/uv/tools/" in sys.executable
670
+ or "/uv/tools/" in sys.executable
671
+ )
672
+
673
+ if is_uv_tool:
674
+ cmd = ["uv", "pip", "install"]
675
+ logger.debug("Using 'uv pip install' for UV tool environment")
676
+ else:
677
+ cmd = [sys.executable, "-m", "pip", "install"]
678
+
679
+ # Check if in virtualenv
680
+ in_virtualenv = (
681
+ (hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix)
682
+ or (hasattr(sys, "real_prefix"))
683
+ or (os.environ.get("VIRTUAL_ENV") is not None)
684
+ )
685
+
686
+ if in_virtualenv:
687
+ # In virtualenv - no special flags needed
688
+ logger.debug("Installing in virtualenv (no special flags)")
689
+ else:
690
+ # Check for PEP 668 managed environment
691
+ stdlib_path = sysconfig.get_path("stdlib")
692
+ marker_file = Path(stdlib_path) / "EXTERNALLY-MANAGED"
693
+ parent_marker = marker_file.parent.parent / "EXTERNALLY-MANAGED"
694
+
695
+ if marker_file.exists() or parent_marker.exists():
696
+ logger.warning(
697
+ "PEP 668 managed environment detected. "
698
+ "Installing with --break-system-packages flag. "
699
+ "Consider using a virtual environment instead."
700
+ )
701
+ cmd.append("--break-system-packages")
702
+ else:
703
+ # Normal system Python - use --user
704
+ cmd.append("--user")
705
+ logger.debug("Installing with --user flag")
706
+
707
+ cmd.extend(compatible)
708
+
709
+ result = subprocess.run(
710
+ cmd, capture_output=True, text=True, timeout=300, check=False
711
+ )
712
+
713
+ if result.returncode == 0:
714
+ logger.info("Successfully installed compatible dependencies")
715
+ if incompatible:
716
+ return (
717
+ True,
718
+ f"Installed {len(compatible)} packages, skipped {len(incompatible)} incompatible",
719
+ )
720
+ return True, ""
721
+ error_msg = f"Installation failed: {result.stderr}"
722
+ logger.error(error_msg)
723
+ return False, error_msg
724
+
725
+ except Exception as e:
726
+ error_msg = f"Failed to install dependencies: {e}"
727
+ logger.error(error_msg)
728
+ return False, error_msg
729
+
730
+ except Exception as e:
731
+ error_msg = f"Failed to install dependencies: {e}"
732
+ logger.error(error_msg)
733
+ return False, error_msg
734
+
735
+ def load_and_check(self) -> Dict[str, Dict]:
736
+ """
737
+ Complete workflow: discover agents, load dependencies, and check them.
738
+
739
+ Returns:
740
+ Complete analysis results
741
+ """
742
+ # Discover deployed agents
743
+ self.discover_deployed_agents()
744
+
745
+ if not self.deployed_agents:
746
+ logger.info("No deployed agents found")
747
+ return {"agents": {}, "summary": {"total_agents": 0}}
748
+
749
+ # Load their dependencies
750
+ self.load_agent_dependencies()
751
+
752
+ # Analyze what's missing
753
+ results = self.analyze_dependencies()
754
+
755
+ # Optionally auto-install missing dependencies
756
+ if self.auto_install and results["summary"]["missing_python"]:
757
+ logger.info(
758
+ f"Auto-installing {len(results['summary']['missing_python'])} missing dependencies..."
759
+ )
760
+ success, _error = self.install_missing_dependencies(
761
+ results["summary"]["missing_python"]
762
+ )
763
+ if success:
764
+ # Re-analyze after installation
765
+ self.checked_packages.clear()
766
+ results = self.analyze_dependencies()
767
+
768
+ return results
769
+
770
+ def format_report(self, results: Dict[str, Dict]) -> str:
771
+ """
772
+ Format a human-readable dependency report.
773
+
774
+ Args:
775
+ results: Analysis results from analyze_dependencies()
776
+
777
+ Returns:
778
+ Formatted report string
779
+ """
780
+ import sys
781
+
782
+ lines = []
783
+ lines.append("=" * 80)
784
+ lines.append("AGENT DEPENDENCY ANALYSIS REPORT")
785
+ lines.append("=" * 80)
786
+ lines.append("")
787
+
788
+ # Python version info
789
+ lines.append(
790
+ f"Python Version: {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
791
+ )
792
+ lines.append("")
793
+
794
+ # Summary
795
+ summary = results["summary"]
796
+ lines.append(f"Deployed Agents: {summary['total_agents']}")
797
+ lines.append(f"Agents with Dependencies: {summary['agents_with_deps']}")
798
+ lines.append("")
799
+
800
+ # Missing dependencies summary
801
+ if summary["missing_python"] or summary["missing_system"]:
802
+ lines.append("⚠️ MISSING DEPENDENCIES:")
803
+ if summary["missing_python"]:
804
+ lines.append(f" Python packages: {len(summary['missing_python'])}")
805
+ for dep in summary["missing_python"][:5]: # Show first 5
806
+ lines.append(f" - {dep}")
807
+ if len(summary["missing_python"]) > 5:
808
+ lines.append(
809
+ f" ... and {len(summary['missing_python']) - 5} more"
810
+ )
811
+
812
+ if summary["missing_system"]:
813
+ lines.append(f" System commands: {len(summary['missing_system'])}")
814
+ for cmd in summary["missing_system"]:
815
+ lines.append(f" - {cmd}")
816
+ lines.append("")
817
+
818
+ # Per-agent details (only for agents with issues)
819
+ agents_with_issues = {
820
+ agent_id: info
821
+ for agent_id, info in results["agents"].items()
822
+ if info["python"]["missing"]
823
+ or info["python"]["outdated"]
824
+ or info["system"]["missing"]
825
+ }
826
+
827
+ if agents_with_issues:
828
+ lines.append("AGENT-SPECIFIC ISSUES:")
829
+ lines.append("-" * 40)
830
+ for agent_id, info in agents_with_issues.items():
831
+ lines.append(f"\n📦 {agent_id}:")
832
+
833
+ if info["python"]["missing"]:
834
+ lines.append(
835
+ f" Missing Python: {', '.join(info['python']['missing'])}"
836
+ )
837
+ if info["python"]["outdated"]:
838
+ lines.append(
839
+ f" Outdated Python: {', '.join(info['python']['outdated'])}"
840
+ )
841
+ if info["system"]["missing"]:
842
+ lines.append(
843
+ f" Missing System: {', '.join(info['system']['missing'])}"
844
+ )
845
+
846
+ else:
847
+ lines.append("✅ All agent dependencies are satisfied!")
848
+
849
+ # Installation instructions
850
+ if summary["missing_python"]:
851
+ lines.append("")
852
+ lines.append("TO INSTALL MISSING PYTHON DEPENDENCIES:")
853
+ lines.append("-" * 40)
854
+
855
+ # Check for Python 3.13 compatibility issues
856
+ import sys
857
+
858
+ if sys.version_info >= (3, 13):
859
+ _compatible, incompatible = self.check_python_compatibility(
860
+ summary["missing_python"]
861
+ )
862
+ if incompatible:
863
+ lines.append("⚠️ Python 3.13 Compatibility Warning:")
864
+ lines.append(
865
+ f" {len(incompatible)} packages are not yet compatible with Python 3.13:"
866
+ )
867
+ for dep in incompatible[:3]:
868
+ lines.append(f" - {dep}")
869
+ if len(incompatible) > 3:
870
+ lines.append(f" ... and {len(incompatible) - 3} more")
871
+ lines.append("")
872
+ lines.append(
873
+ " Consider using Python 3.12 or earlier for full compatibility."
874
+ )
875
+ lines.append("")
876
+
877
+ lines.append("Option 1: Install all agent dependencies:")
878
+ lines.append(' pip install "claude-mpm[agents]"')
879
+ lines.append("")
880
+ lines.append("Option 2: Install only what's needed:")
881
+ deps_str = " ".join(f'"{dep}"' for dep in summary["missing_python"][:3])
882
+ lines.append(f" pip install {deps_str}")
883
+ if len(summary["missing_python"]) > 3:
884
+ lines.append(f" # ... and {len(summary['missing_python']) - 3} more")
885
+
886
+ if summary["missing_system"]:
887
+ lines.append("")
888
+ lines.append("TO INSTALL MISSING SYSTEM DEPENDENCIES:")
889
+ lines.append("-" * 40)
890
+ lines.append("Use your system package manager:")
891
+ lines.append(
892
+ " # macOS: brew install " + " ".join(summary["missing_system"])
893
+ )
894
+ lines.append(
895
+ " # Ubuntu: apt-get install " + " ".join(summary["missing_system"])
896
+ )
897
+
898
+ lines.append("")
899
+ lines.append("=" * 80)
900
+
901
+ return "\n".join(lines)
902
+
903
+ def calculate_deployment_hash(self) -> str:
904
+ """
905
+ Calculate a hash of the current agent deployment state.
906
+
907
+ WHY: We use SHA256 hash of agent files to detect when agents have changed.
908
+ This allows us to skip dependency checks when nothing has changed,
909
+ improving startup performance.
910
+
911
+ Returns:
912
+ SHA256 hash of all deployed agent files and their content.
913
+ """
914
+ hash_obj = hashlib.sha256()
915
+
916
+ # Discover current agents if not already done
917
+ if not self.deployed_agents:
918
+ self.discover_deployed_agents()
919
+
920
+ # Sort agent IDs for consistent hashing
921
+ for agent_id in sorted(self.deployed_agents.keys()):
922
+ agent_path = self.deployed_agents[agent_id]
923
+
924
+ # Include agent ID in hash
925
+ hash_obj.update(agent_id.encode("utf-8"))
926
+
927
+ # Include file modification time and size for quick change detection
928
+ try:
929
+ stat = agent_path.stat()
930
+ hash_obj.update(str(stat.st_mtime).encode("utf-8"))
931
+ hash_obj.update(str(stat.st_size).encode("utf-8"))
932
+
933
+ # Include file content for comprehensive change detection
934
+ with agent_path.open("rb") as f:
935
+ hash_obj.update(f.read())
936
+ except Exception as e:
937
+ logger.debug(f"Could not hash agent file {agent_path}: {e}")
938
+ # Include error in hash to force recheck on next run
939
+ hash_obj.update(f"error:{agent_id}:{e}".encode())
940
+
941
+ return hash_obj.hexdigest()
942
+
943
+ def load_deployment_state(self) -> Dict:
944
+ """
945
+ Load the saved deployment state.
946
+
947
+ Returns:
948
+ Dictionary with deployment state or empty dict if not found.
949
+ """
950
+ if not self.deployment_state_file.exists():
951
+ return {}
952
+
953
+ try:
954
+ with self.deployment_state_file.open() as f:
955
+ return json.load(f)
956
+ except Exception as e:
957
+ logger.debug(f"Could not load deployment state: {e}")
958
+ return {}
959
+
960
+ def save_deployment_state(self, state: Dict) -> None:
961
+ """
962
+ Save the deployment state to disk.
963
+
964
+ Args:
965
+ state: Deployment state dictionary to save.
966
+ """
967
+ try:
968
+ # Ensure directory exists
969
+ self.deployment_state_file.parent.mkdir(parents=True, exist_ok=True)
970
+
971
+ with self.deployment_state_file.open("w") as f:
972
+ json.dump(state, f, indent=2)
973
+ except Exception as e:
974
+ logger.debug(f"Could not save deployment state: {e}")
975
+
976
+ def has_agents_changed(self) -> Tuple[bool, str]:
977
+ """
978
+ Check if agents have changed since last dependency check.
979
+
980
+ WHY: This is the core of our smart checking system. We only want to
981
+ check dependencies when agents have actually changed, not on every run.
982
+
983
+ Returns:
984
+ Tuple of (has_changed, current_hash)
985
+ """
986
+ current_hash = self.calculate_deployment_hash()
987
+ state = self.load_deployment_state()
988
+
989
+ last_hash = state.get("deployment_hash")
990
+ last_check_time = state.get("last_check_time", 0)
991
+
992
+ # Check if hash has changed
993
+ if last_hash != current_hash:
994
+ logger.info("Agent deployment has changed since last check")
995
+ return True, current_hash
996
+
997
+ # Also check if it's been more than 24 hours (optional staleness check)
998
+ current_time = time.time()
999
+ if current_time - last_check_time > 86400: # 24 hours
1000
+ logger.debug("Over 24 hours since last dependency check")
1001
+ return True, current_hash
1002
+
1003
+ logger.debug("No agent changes detected, skipping dependency check")
1004
+ return False, current_hash
1005
+
1006
+ def mark_deployment_checked(
1007
+ self, deployment_hash: str, check_results: Dict
1008
+ ) -> None:
1009
+ """
1010
+ Mark the current deployment as checked.
1011
+
1012
+ Args:
1013
+ deployment_hash: Hash of the current deployment
1014
+ check_results: Results of the dependency check
1015
+ """
1016
+ state = {
1017
+ "deployment_hash": deployment_hash,
1018
+ "last_check_time": time.time(),
1019
+ "last_check_results": check_results,
1020
+ "agent_count": len(self.deployed_agents),
1021
+ }
1022
+ self.save_deployment_state(state)
1023
+
1024
+ def get_cached_check_results(self) -> Optional[Dict]:
1025
+ """
1026
+ Get cached dependency check results if still valid.
1027
+
1028
+ Returns:
1029
+ Cached results or None if not available/valid.
1030
+ """
1031
+ has_changed, _current_hash = self.has_agents_changed()
1032
+
1033
+ if not has_changed:
1034
+ state = self.load_deployment_state()
1035
+ cached_results = state.get("last_check_results")
1036
+ if cached_results:
1037
+ logger.debug("Using cached dependency check results")
1038
+ return cached_results
1039
+
1040
+ return None
1041
+
1042
+
1043
+ def check_deployed_agent_dependencies(
1044
+ auto_install: bool = False, verbose: bool = False
1045
+ ) -> int:
1046
+ """
1047
+ Check dependencies for currently deployed agents.
1048
+
1049
+ Args:
1050
+ auto_install: If True, automatically install missing Python dependencies
1051
+ verbose: If True, enable verbose logging
1052
+
1053
+ Returns:
1054
+ Status code: 0 if all dependencies satisfied, 1 if missing dependencies
1055
+ """
1056
+ if verbose:
1057
+ logging.getLogger().setLevel(logging.DEBUG)
1058
+
1059
+ loader = AgentDependencyLoader(auto_install=auto_install)
1060
+ results = loader.load_and_check()
1061
+
1062
+ # Print report
1063
+ report = loader.format_report(results)
1064
+ print(report)
1065
+
1066
+ # Return status code based on missing dependencies
1067
+ if results["summary"]["missing_python"] or results["summary"]["missing_system"]:
1068
+ return 1 # Missing dependencies
1069
+ return 0 # All satisfied
1070
+
1071
+
1072
+ if __name__ == "__main__":
1073
+ import argparse
1074
+
1075
+ parser = argparse.ArgumentParser(
1076
+ description="Check and manage dependencies for deployed agents"
1077
+ )
1078
+ parser.add_argument(
1079
+ "--auto-install",
1080
+ action="store_true",
1081
+ help="Automatically install missing Python dependencies",
1082
+ )
1083
+ parser.add_argument("--verbose", action="store_true", help="Enable verbose logging")
1084
+
1085
+ args = parser.parse_args()
1086
+
1087
+ exit_code = check_deployed_agent_dependencies(
1088
+ auto_install=args.auto_install, verbose=args.verbose
1089
+ )
1090
+ sys.exit(exit_code)