claude-mpm 3.4.10__py3-none-any.whl → 5.4.85__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1062) hide show
  1. claude_mpm/BUILD_NUMBER +1 -0
  2. claude_mpm/VERSION +1 -0
  3. claude_mpm/__init__.py +50 -12
  4. claude_mpm/__main__.py +7 -2
  5. claude_mpm/agents/BASE_AGENT.md +164 -0
  6. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  7. claude_mpm/agents/CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md +405 -0
  8. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +112 -0
  9. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +186 -0
  10. claude_mpm/agents/MEMORY.md +72 -0
  11. claude_mpm/agents/PM_INSTRUCTIONS.md +1429 -0
  12. claude_mpm/agents/WORKFLOW.md +111 -0
  13. claude_mpm/agents/__init__.py +92 -80
  14. claude_mpm/agents/agent-template.yaml +83 -0
  15. claude_mpm/agents/agent_loader.py +560 -745
  16. claude_mpm/agents/agent_loader_integration.py +53 -55
  17. claude_mpm/agents/agents_metadata.py +186 -27
  18. claude_mpm/agents/async_agent_loader.py +436 -0
  19. claude_mpm/agents/base_agent.json +8 -4
  20. claude_mpm/agents/frontmatter_validator.py +754 -0
  21. claude_mpm/agents/system_agent_config.py +222 -155
  22. claude_mpm/agents/templates/README.md +465 -0
  23. claude_mpm/agents/templates/__init__.py +17 -13
  24. claude_mpm/agents/templates/circuit-breakers.md +1391 -0
  25. claude_mpm/agents/templates/context-management-examples.md +544 -0
  26. claude_mpm/agents/templates/git-file-tracking.md +584 -0
  27. claude_mpm/agents/templates/pm-examples.md +474 -0
  28. claude_mpm/agents/templates/pm-red-flags.md +310 -0
  29. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  30. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  31. claude_mpm/agents/templates/response-format.md +583 -0
  32. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  33. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  34. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  35. claude_mpm/agents/templates/validation-templates.md +312 -0
  36. claude_mpm/cli/__init__.py +94 -128
  37. claude_mpm/cli/__main__.py +33 -0
  38. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  39. claude_mpm/cli/commands/__init__.py +36 -12
  40. claude_mpm/cli/commands/agent_manager.py +1403 -0
  41. claude_mpm/cli/commands/agent_source.py +774 -0
  42. claude_mpm/cli/commands/agent_state_manager.py +335 -0
  43. claude_mpm/cli/commands/agents.py +2501 -168
  44. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  45. claude_mpm/cli/commands/agents_discover.py +338 -0
  46. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  47. claude_mpm/cli/commands/aggregate.py +540 -0
  48. claude_mpm/cli/commands/analyze.py +553 -0
  49. claude_mpm/cli/commands/analyze_code.py +528 -0
  50. claude_mpm/cli/commands/auto_configure.py +1053 -0
  51. claude_mpm/cli/commands/cleanup.py +588 -0
  52. claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
  53. claude_mpm/cli/commands/config.py +586 -0
  54. claude_mpm/cli/commands/configure.py +3253 -0
  55. claude_mpm/cli/commands/configure_agent_display.py +282 -0
  56. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  57. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  58. claude_mpm/cli/commands/configure_models.py +18 -0
  59. claude_mpm/cli/commands/configure_navigation.py +184 -0
  60. claude_mpm/cli/commands/configure_paths.py +104 -0
  61. claude_mpm/cli/commands/configure_persistence.py +254 -0
  62. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  63. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  64. claude_mpm/cli/commands/configure_validators.py +73 -0
  65. claude_mpm/cli/commands/dashboard.py +286 -0
  66. claude_mpm/cli/commands/debug.py +1386 -0
  67. claude_mpm/cli/commands/doctor.py +243 -0
  68. claude_mpm/cli/commands/hook_errors.py +277 -0
  69. claude_mpm/cli/commands/info.py +195 -74
  70. claude_mpm/cli/commands/local_deploy.py +534 -0
  71. claude_mpm/cli/commands/mcp.py +205 -0
  72. claude_mpm/cli/commands/mcp_command_router.py +161 -0
  73. claude_mpm/cli/commands/mcp_config.py +154 -0
  74. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  75. claude_mpm/cli/commands/mcp_external_commands.py +249 -0
  76. claude_mpm/cli/commands/mcp_install_commands.py +346 -0
  77. claude_mpm/cli/commands/mcp_pipx_config.py +208 -0
  78. claude_mpm/cli/commands/mcp_server_commands.py +155 -0
  79. claude_mpm/cli/commands/mcp_setup_external.py +868 -0
  80. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  81. claude_mpm/cli/commands/memory.py +585 -846
  82. claude_mpm/cli/commands/monitor.py +228 -310
  83. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  84. claude_mpm/cli/commands/mpm_init/core.py +759 -0
  85. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  86. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  87. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  88. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  89. claude_mpm/cli/commands/mpm_init/prompts.py +722 -0
  90. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  91. claude_mpm/cli/commands/mpm_init_handler.py +195 -0
  92. claude_mpm/cli/commands/postmortem.py +401 -0
  93. claude_mpm/cli/commands/profile.py +276 -0
  94. claude_mpm/cli/commands/run.py +910 -488
  95. claude_mpm/cli/commands/search.py +458 -0
  96. claude_mpm/cli/commands/skill_source.py +694 -0
  97. claude_mpm/cli/commands/skills.py +1398 -0
  98. claude_mpm/cli/commands/summarize.py +413 -0
  99. claude_mpm/cli/commands/tickets.py +536 -53
  100. claude_mpm/cli/commands/uninstall.py +176 -0
  101. claude_mpm/cli/commands/upgrade.py +152 -0
  102. claude_mpm/cli/commands/verify.py +119 -0
  103. claude_mpm/cli/executor.py +298 -0
  104. claude_mpm/cli/helpers.py +105 -0
  105. claude_mpm/cli/interactive/__init__.py +31 -0
  106. claude_mpm/cli/interactive/agent_wizard.py +1927 -0
  107. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  108. claude_mpm/cli/interactive/skill_selector.py +481 -0
  109. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  110. claude_mpm/cli/parser.py +87 -563
  111. claude_mpm/cli/parsers/__init__.py +35 -0
  112. claude_mpm/cli/parsers/agent_manager_parser.py +393 -0
  113. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  114. claude_mpm/cli/parsers/agents_parser.py +575 -0
  115. claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
  116. claude_mpm/cli/parsers/analyze_parser.py +135 -0
  117. claude_mpm/cli/parsers/auto_configure_parser.py +120 -0
  118. claude_mpm/cli/parsers/base_parser.py +649 -0
  119. claude_mpm/cli/parsers/config_parser.py +208 -0
  120. claude_mpm/cli/parsers/configure_parser.py +138 -0
  121. claude_mpm/cli/parsers/dashboard_parser.py +113 -0
  122. claude_mpm/cli/parsers/debug_parser.py +319 -0
  123. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  124. claude_mpm/cli/parsers/mcp_parser.py +195 -0
  125. claude_mpm/cli/parsers/memory_parser.py +138 -0
  126. claude_mpm/cli/parsers/monitor_parser.py +142 -0
  127. claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
  128. claude_mpm/cli/parsers/profile_parser.py +147 -0
  129. claude_mpm/cli/parsers/run_parser.py +157 -0
  130. claude_mpm/cli/parsers/search_parser.py +245 -0
  131. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  132. claude_mpm/cli/parsers/skills_parser.py +277 -0
  133. claude_mpm/cli/parsers/source_parser.py +138 -0
  134. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  135. claude_mpm/cli/shared/__init__.py +40 -0
  136. claude_mpm/cli/shared/argument_patterns.py +205 -0
  137. claude_mpm/cli/shared/base_command.py +242 -0
  138. claude_mpm/cli/shared/error_handling.py +242 -0
  139. claude_mpm/cli/shared/output_formatters.py +241 -0
  140. claude_mpm/cli/startup.py +1578 -0
  141. claude_mpm/cli/startup_display.py +480 -0
  142. claude_mpm/cli/startup_logging.py +839 -0
  143. claude_mpm/cli/utils.py +136 -47
  144. claude_mpm/cli_module/__init__.py +6 -6
  145. claude_mpm/cli_module/args.py +188 -140
  146. claude_mpm/cli_module/commands.py +79 -70
  147. claude_mpm/cli_module/migration_example.py +42 -64
  148. claude_mpm/commands/__init__.py +14 -0
  149. claude_mpm/commands/mpm-config.md +28 -0
  150. claude_mpm/commands/mpm-doctor.md +20 -0
  151. claude_mpm/commands/mpm-help.md +20 -0
  152. claude_mpm/commands/mpm-init.md +120 -0
  153. claude_mpm/commands/mpm-monitor.md +31 -0
  154. claude_mpm/commands/mpm-organize.md +120 -0
  155. claude_mpm/commands/mpm-postmortem.md +21 -0
  156. claude_mpm/commands/mpm-session-resume.md +30 -0
  157. claude_mpm/commands/mpm-status.md +20 -0
  158. claude_mpm/commands/mpm-ticket-view.md +109 -0
  159. claude_mpm/commands/mpm-version.md +20 -0
  160. claude_mpm/commands/mpm.md +31 -0
  161. claude_mpm/config/__init__.py +42 -2
  162. claude_mpm/config/agent_config.py +402 -0
  163. claude_mpm/config/agent_presets.py +488 -0
  164. claude_mpm/config/agent_sources.py +352 -0
  165. claude_mpm/config/experimental_features.py +217 -0
  166. claude_mpm/config/model_config.py +428 -0
  167. claude_mpm/config/paths.py +258 -0
  168. claude_mpm/config/skill_presets.py +392 -0
  169. claude_mpm/config/skill_sources.py +590 -0
  170. claude_mpm/config/socketio_config.py +125 -83
  171. claude_mpm/constants.py +133 -22
  172. claude_mpm/core/__init__.py +62 -36
  173. claude_mpm/core/agent_name_normalizer.py +71 -73
  174. claude_mpm/core/agent_registry.py +385 -492
  175. claude_mpm/core/agent_session_manager.py +81 -70
  176. claude_mpm/core/api_validator.py +330 -0
  177. claude_mpm/core/base_service.py +159 -122
  178. claude_mpm/core/cache.py +560 -0
  179. claude_mpm/core/claude_runner.py +696 -916
  180. claude_mpm/core/config.py +613 -122
  181. claude_mpm/core/config_aliases.py +74 -73
  182. claude_mpm/core/config_constants.py +314 -0
  183. claude_mpm/core/constants.py +361 -0
  184. claude_mpm/core/container.py +646 -104
  185. claude_mpm/core/enums.py +452 -0
  186. claude_mpm/core/error_handler.py +623 -0
  187. claude_mpm/core/exceptions.py +536 -0
  188. claude_mpm/core/factories.py +105 -109
  189. claude_mpm/core/file_utils.py +764 -0
  190. claude_mpm/core/framework/__init__.py +25 -0
  191. claude_mpm/core/framework/formatters/__init__.py +11 -0
  192. claude_mpm/core/framework/formatters/capability_generator.py +367 -0
  193. claude_mpm/core/framework/formatters/content_formatter.py +278 -0
  194. claude_mpm/core/framework/formatters/context_generator.py +185 -0
  195. claude_mpm/core/framework/loaders/__init__.py +13 -0
  196. claude_mpm/core/framework/loaders/agent_loader.py +213 -0
  197. claude_mpm/core/framework/loaders/file_loader.py +176 -0
  198. claude_mpm/core/framework/loaders/instruction_loader.py +222 -0
  199. claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
  200. claude_mpm/core/framework/processors/__init__.py +11 -0
  201. claude_mpm/core/framework/processors/memory_processor.py +230 -0
  202. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  203. claude_mpm/core/framework/processors/template_processor.py +244 -0
  204. claude_mpm/core/framework_loader.py +485 -414
  205. claude_mpm/core/hook_error_memory.py +381 -0
  206. claude_mpm/core/hook_manager.py +246 -86
  207. claude_mpm/core/hook_performance_config.py +147 -0
  208. claude_mpm/core/injectable_service.py +72 -63
  209. claude_mpm/core/instruction_reinforcement_hook.py +267 -0
  210. claude_mpm/core/interactive_session.py +670 -0
  211. claude_mpm/core/interfaces.py +570 -164
  212. claude_mpm/core/lazy.py +467 -0
  213. claude_mpm/core/log_manager.py +707 -0
  214. claude_mpm/core/logger.py +295 -134
  215. claude_mpm/core/logging_config.py +474 -0
  216. claude_mpm/core/logging_utils.py +520 -0
  217. claude_mpm/core/minimal_framework_loader.py +24 -22
  218. claude_mpm/core/mixins.py +30 -29
  219. claude_mpm/core/oneshot_session.py +594 -0
  220. claude_mpm/core/optimized_agent_loader.py +479 -0
  221. claude_mpm/core/optimized_startup.py +554 -0
  222. claude_mpm/core/output_style_manager.py +491 -0
  223. claude_mpm/core/pm_hook_interceptor.py +197 -82
  224. claude_mpm/core/protocols/__init__.py +23 -0
  225. claude_mpm/core/protocols/runner_protocol.py +103 -0
  226. claude_mpm/core/protocols/session_protocol.py +131 -0
  227. claude_mpm/core/service_registry.py +153 -116
  228. claude_mpm/core/session_manager.py +179 -64
  229. claude_mpm/core/shared/__init__.py +17 -0
  230. claude_mpm/core/shared/config_loader.py +326 -0
  231. claude_mpm/core/shared/path_resolver.py +281 -0
  232. claude_mpm/core/shared/singleton_manager.py +221 -0
  233. claude_mpm/core/socketio_pool.py +400 -137
  234. claude_mpm/core/system_context.py +38 -0
  235. claude_mpm/core/tool_access_control.py +64 -57
  236. claude_mpm/core/types.py +307 -0
  237. claude_mpm/core/typing_utils.py +553 -0
  238. claude_mpm/core/unified_agent_registry.py +969 -0
  239. claude_mpm/core/unified_config.py +612 -0
  240. claude_mpm/core/unified_paths.py +958 -0
  241. claude_mpm/dashboard/__init__.py +12 -0
  242. claude_mpm/dashboard/api/simple_directory.py +261 -0
  243. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  244. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
  245. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
  246. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
  247. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
  248. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
  249. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
  250. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
  251. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
  252. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
  253. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
  254. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  255. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
  256. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
  257. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
  258. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
  259. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
  260. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
  261. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
  262. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
  263. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
  264. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
  265. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
  266. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
  267. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
  268. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  269. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
  270. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
  271. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  272. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
  273. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
  274. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
  275. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
  276. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
  277. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
  278. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
  279. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
  280. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
  281. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  282. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
  283. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
  284. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
  285. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
  286. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
  287. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
  288. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
  289. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
  290. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
  291. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
  292. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  293. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
  294. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
  295. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
  296. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
  297. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
  298. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
  299. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
  300. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
  301. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
  302. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
  303. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
  304. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
  305. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
  306. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
  307. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
  308. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  309. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  310. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  311. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  312. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  313. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  314. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  315. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  316. claude_mpm/experimental/__init__.py +10 -0
  317. claude_mpm/experimental/cli_enhancements.py +104 -89
  318. claude_mpm/generators/__init__.py +1 -1
  319. claude_mpm/generators/agent_profile_generator.py +76 -66
  320. claude_mpm/hooks/__init__.py +37 -1
  321. claude_mpm/hooks/base_hook.py +37 -32
  322. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  323. claude_mpm/hooks/claude_hooks/connection_pool.py +250 -0
  324. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  325. claude_mpm/hooks/claude_hooks/event_handlers.py +888 -0
  326. claude_mpm/hooks/claude_hooks/hook_handler.py +652 -875
  327. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +10 -7
  328. claude_mpm/hooks/claude_hooks/installer.py +806 -0
  329. claude_mpm/hooks/claude_hooks/memory_integration.py +249 -0
  330. claude_mpm/hooks/claude_hooks/response_tracking.py +412 -0
  331. claude_mpm/hooks/claude_hooks/services/__init__.py +15 -0
  332. claude_mpm/hooks/claude_hooks/services/connection_manager.py +229 -0
  333. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +254 -0
  334. claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
  335. claude_mpm/hooks/claude_hooks/services/state_manager.py +284 -0
  336. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
  337. claude_mpm/hooks/claude_hooks/tool_analysis.py +224 -0
  338. claude_mpm/hooks/failure_learning/__init__.py +54 -0
  339. claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
  340. claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
  341. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
  342. claude_mpm/hooks/instruction_reinforcement.py +301 -0
  343. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  344. claude_mpm/hooks/kuzu_memory_hook.py +386 -0
  345. claude_mpm/hooks/kuzu_response_hook.py +179 -0
  346. claude_mpm/hooks/memory_integration_hook.py +201 -107
  347. claude_mpm/hooks/session_resume_hook.py +121 -0
  348. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  349. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  350. claude_mpm/hooks/tool_call_interceptor.py +92 -76
  351. claude_mpm/hooks/validation_hooks.py +62 -54
  352. claude_mpm/init.py +518 -83
  353. claude_mpm/models/__init__.py +9 -9
  354. claude_mpm/models/agent_definition.py +40 -23
  355. claude_mpm/models/agent_session.py +538 -0
  356. claude_mpm/models/git_repository.py +198 -0
  357. claude_mpm/models/resume_log.py +340 -0
  358. claude_mpm/schemas/__init__.py +12 -0
  359. claude_mpm/scripts/__init__.py +15 -0
  360. claude_mpm/scripts/claude-hook-handler.sh +227 -0
  361. claude_mpm/scripts/launch_monitor.py +165 -0
  362. claude_mpm/scripts/mpm_doctor.py +322 -0
  363. claude_mpm/scripts/socketio_daemon.py +189 -200
  364. claude_mpm/scripts/start_activity_logging.py +91 -0
  365. claude_mpm/services/__init__.py +208 -39
  366. claude_mpm/services/agent_capabilities_service.py +266 -0
  367. claude_mpm/services/agents/__init__.py +89 -0
  368. claude_mpm/services/agents/agent_builder.py +514 -0
  369. claude_mpm/services/agents/agent_preset_service.py +238 -0
  370. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  371. claude_mpm/services/agents/agent_review_service.py +280 -0
  372. claude_mpm/services/agents/agent_selection_service.py +484 -0
  373. claude_mpm/services/agents/auto_config_manager.py +796 -0
  374. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  375. claude_mpm/services/agents/cache_git_manager.py +621 -0
  376. claude_mpm/services/agents/deployment/__init__.py +21 -0
  377. claude_mpm/services/agents/deployment/agent_config_provider.py +410 -0
  378. claude_mpm/services/agents/deployment/agent_configuration_manager.py +358 -0
  379. claude_mpm/services/agents/deployment/agent_definition_factory.py +80 -0
  380. claude_mpm/services/agents/deployment/agent_deployment.py +1037 -0
  381. claude_mpm/services/agents/deployment/agent_discovery_service.py +546 -0
  382. claude_mpm/services/agents/deployment/agent_environment_manager.py +288 -0
  383. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +383 -0
  384. claude_mpm/services/agents/deployment/agent_format_converter.py +505 -0
  385. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +160 -0
  386. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +957 -0
  387. claude_mpm/services/agents/deployment/agent_metrics_collector.py +273 -0
  388. claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
  389. claude_mpm/services/agents/deployment/agent_record_service.py +418 -0
  390. claude_mpm/services/agents/deployment/agent_restore_handler.py +84 -0
  391. claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
  392. claude_mpm/services/agents/deployment/agent_template_builder.py +1377 -0
  393. claude_mpm/services/agents/deployment/agent_validator.py +376 -0
  394. claude_mpm/services/agents/deployment/agent_version_manager.py +322 -0
  395. claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +10 -13
  396. claude_mpm/services/agents/deployment/agents_directory_resolver.py +149 -0
  397. claude_mpm/services/agents/deployment/async_agent_deployment.py +768 -0
  398. claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
  399. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  400. claude_mpm/services/agents/deployment/config/deployment_config.py +181 -0
  401. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  402. claude_mpm/services/agents/deployment/deployment_config_loader.py +178 -0
  403. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  404. claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
  405. claude_mpm/services/agents/deployment/deployment_type_detector.py +120 -0
  406. claude_mpm/services/agents/deployment/deployment_wrapper.py +129 -0
  407. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  408. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  409. claude_mpm/services/agents/deployment/facade/deployment_executor.py +70 -0
  410. claude_mpm/services/agents/deployment/facade/deployment_facade.py +269 -0
  411. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  412. claude_mpm/services/agents/deployment/interface_adapter.py +226 -0
  413. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  414. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  415. claude_mpm/services/agents/deployment/local_template_deployment.py +362 -0
  416. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +1478 -0
  417. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  418. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  419. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +162 -0
  420. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  421. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  422. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +240 -0
  423. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +110 -0
  424. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +80 -0
  425. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +92 -0
  426. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +101 -0
  427. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  428. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +102 -0
  429. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  430. claude_mpm/services/agents/deployment/processors/agent_processor.py +269 -0
  431. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +311 -0
  432. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +862 -0
  433. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  434. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  435. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  436. claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
  437. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  438. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  439. claude_mpm/services/agents/deployment/strategies/base_strategy.py +113 -0
  440. claude_mpm/services/agents/deployment/strategies/project_strategy.py +148 -0
  441. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  442. claude_mpm/services/agents/deployment/strategies/system_strategy.py +131 -0
  443. claude_mpm/services/agents/deployment/strategies/user_strategy.py +130 -0
  444. claude_mpm/services/agents/deployment/system_instructions_deployer.py +228 -0
  445. claude_mpm/services/agents/deployment/validation/__init__.py +21 -0
  446. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  447. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  448. claude_mpm/services/agents/deployment/validation/template_validator.py +319 -0
  449. claude_mpm/services/agents/deployment/validation/validation_result.py +214 -0
  450. claude_mpm/services/agents/git_source_manager.py +682 -0
  451. claude_mpm/services/agents/loading/__init__.py +11 -0
  452. claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +306 -228
  453. claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +106 -91
  454. claude_mpm/services/agents/loading/framework_agent_loader.py +433 -0
  455. claude_mpm/services/agents/local_template_manager.py +784 -0
  456. claude_mpm/services/agents/management/__init__.py +9 -0
  457. claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +92 -69
  458. claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +219 -168
  459. claude_mpm/services/agents/memory/__init__.py +22 -0
  460. claude_mpm/services/agents/memory/agent_memory_manager.py +784 -0
  461. claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +20 -18
  462. claude_mpm/services/agents/memory/content_manager.py +470 -0
  463. claude_mpm/services/agents/memory/memory_categorization_service.py +167 -0
  464. claude_mpm/services/agents/memory/memory_file_service.py +129 -0
  465. claude_mpm/services/agents/memory/memory_format_service.py +201 -0
  466. claude_mpm/services/agents/memory/memory_limits_service.py +101 -0
  467. claude_mpm/services/agents/memory/template_generator.py +83 -0
  468. claude_mpm/services/agents/observers.py +547 -0
  469. claude_mpm/services/agents/recommender.py +617 -0
  470. claude_mpm/services/agents/registry/__init__.py +30 -0
  471. claude_mpm/services/agents/registry/deployed_agent_discovery.py +273 -0
  472. claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +370 -295
  473. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  474. claude_mpm/services/agents/sources/__init__.py +13 -0
  475. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  476. claude_mpm/services/agents/sources/git_source_sync_service.py +1205 -0
  477. claude_mpm/services/agents/startup_sync.py +262 -0
  478. claude_mpm/services/agents/toolchain_detector.py +478 -0
  479. claude_mpm/services/analysis/__init__.py +35 -0
  480. claude_mpm/services/analysis/clone_detector.py +1030 -0
  481. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  482. claude_mpm/services/analysis/postmortem_service.py +765 -0
  483. claude_mpm/services/async_session_logger.py +665 -0
  484. claude_mpm/services/claude_session_logger.py +321 -0
  485. claude_mpm/services/cli/__init__.py +18 -0
  486. claude_mpm/services/cli/agent_cleanup_service.py +408 -0
  487. claude_mpm/services/cli/agent_dependency_service.py +395 -0
  488. claude_mpm/services/cli/agent_listing_service.py +463 -0
  489. claude_mpm/services/cli/agent_output_formatter.py +605 -0
  490. claude_mpm/services/cli/agent_validation_service.py +590 -0
  491. claude_mpm/services/cli/memory_crud_service.py +622 -0
  492. claude_mpm/services/cli/memory_output_formatter.py +604 -0
  493. claude_mpm/services/cli/resume_service.py +617 -0
  494. claude_mpm/services/cli/session_manager.py +604 -0
  495. claude_mpm/services/cli/session_pause_manager.py +504 -0
  496. claude_mpm/services/cli/session_resume_helper.py +372 -0
  497. claude_mpm/services/cli/startup_checker.py +362 -0
  498. claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
  499. claude_mpm/services/command_deployment_service.py +446 -0
  500. claude_mpm/services/command_handler_service.py +221 -0
  501. claude_mpm/services/communication/__init__.py +22 -0
  502. claude_mpm/services/core/__init__.py +108 -0
  503. claude_mpm/services/core/base.py +269 -0
  504. claude_mpm/services/core/cache_manager.py +309 -0
  505. claude_mpm/services/core/interfaces/__init__.py +273 -0
  506. claude_mpm/services/core/interfaces/agent.py +514 -0
  507. claude_mpm/services/core/interfaces/communication.py +316 -0
  508. claude_mpm/services/core/interfaces/health.py +169 -0
  509. claude_mpm/services/core/interfaces/infrastructure.py +357 -0
  510. claude_mpm/services/core/interfaces/model.py +281 -0
  511. claude_mpm/services/core/interfaces/process.py +372 -0
  512. claude_mpm/services/core/interfaces/project.py +121 -0
  513. claude_mpm/services/core/interfaces/restart.py +307 -0
  514. claude_mpm/services/core/interfaces/service.py +405 -0
  515. claude_mpm/services/core/interfaces/stability.py +260 -0
  516. claude_mpm/services/core/interfaces.py +81 -0
  517. claude_mpm/services/core/memory_manager.py +682 -0
  518. claude_mpm/services/core/models/__init__.py +70 -0
  519. claude_mpm/services/core/models/agent_config.py +384 -0
  520. claude_mpm/services/core/models/health.py +162 -0
  521. claude_mpm/services/core/models/process.py +239 -0
  522. claude_mpm/services/core/models/restart.py +302 -0
  523. claude_mpm/services/core/models/stability.py +264 -0
  524. claude_mpm/services/core/models/toolchain.py +306 -0
  525. claude_mpm/services/core/path_resolver.py +517 -0
  526. claude_mpm/services/core/service_container.py +520 -0
  527. claude_mpm/services/core/service_interfaces.py +436 -0
  528. claude_mpm/services/diagnostics/__init__.py +18 -0
  529. claude_mpm/services/diagnostics/checks/__init__.py +38 -0
  530. claude_mpm/services/diagnostics/checks/agent_check.py +370 -0
  531. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  532. claude_mpm/services/diagnostics/checks/base_check.py +60 -0
  533. claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
  534. claude_mpm/services/diagnostics/checks/common_issues_check.py +363 -0
  535. claude_mpm/services/diagnostics/checks/configuration_check.py +306 -0
  536. claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
  537. claude_mpm/services/diagnostics/checks/installation_check.py +520 -0
  538. claude_mpm/services/diagnostics/checks/instructions_check.py +415 -0
  539. claude_mpm/services/diagnostics/checks/mcp_check.py +330 -0
  540. claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
  541. claude_mpm/services/diagnostics/checks/monitor_check.py +281 -0
  542. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  543. claude_mpm/services/diagnostics/checks/startup_log_check.py +319 -0
  544. claude_mpm/services/diagnostics/diagnostic_runner.py +286 -0
  545. claude_mpm/services/diagnostics/doctor_reporter.py +578 -0
  546. claude_mpm/services/diagnostics/models.py +138 -0
  547. claude_mpm/services/event_aggregator.py +582 -0
  548. claude_mpm/services/event_bus/__init__.py +18 -0
  549. claude_mpm/services/event_bus/config.py +186 -0
  550. claude_mpm/services/event_bus/direct_relay.py +312 -0
  551. claude_mpm/services/event_bus/event_bus.py +396 -0
  552. claude_mpm/services/event_bus/relay.py +326 -0
  553. claude_mpm/services/events/__init__.py +44 -0
  554. claude_mpm/services/events/consumers/__init__.py +18 -0
  555. claude_mpm/services/events/consumers/dead_letter.py +306 -0
  556. claude_mpm/services/events/consumers/logging.py +184 -0
  557. claude_mpm/services/events/consumers/metrics.py +241 -0
  558. claude_mpm/services/events/consumers/socketio.py +377 -0
  559. claude_mpm/services/events/core.py +480 -0
  560. claude_mpm/services/events/interfaces.py +214 -0
  561. claude_mpm/services/events/producers/__init__.py +14 -0
  562. claude_mpm/services/events/producers/hook.py +269 -0
  563. claude_mpm/services/events/producers/system.py +329 -0
  564. claude_mpm/services/exceptions.py +433 -353
  565. claude_mpm/services/framework_claude_md_generator/__init__.py +81 -80
  566. claude_mpm/services/framework_claude_md_generator/content_assembler.py +74 -67
  567. claude_mpm/services/framework_claude_md_generator/content_validator.py +66 -62
  568. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +82 -60
  569. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +36 -37
  570. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +41 -40
  571. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +15 -15
  572. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +5 -4
  573. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  574. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  575. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  576. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  577. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +5 -4
  578. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  579. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  580. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +26 -30
  581. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +6 -5
  582. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  583. claude_mpm/services/framework_claude_md_generator/version_manager.py +31 -30
  584. claude_mpm/services/git/__init__.py +21 -0
  585. claude_mpm/services/git/git_operations_service.py +579 -0
  586. claude_mpm/services/github/__init__.py +21 -0
  587. claude_mpm/services/github/github_cli_service.py +397 -0
  588. claude_mpm/services/hook_installer_service.py +506 -0
  589. claude_mpm/services/hook_service.py +159 -111
  590. claude_mpm/services/infrastructure/__init__.py +52 -0
  591. claude_mpm/services/infrastructure/context_preservation.py +569 -0
  592. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  593. claude_mpm/services/infrastructure/logging.py +209 -0
  594. claude_mpm/services/infrastructure/monitoring/__init__.py +39 -0
  595. claude_mpm/services/infrastructure/monitoring/aggregator.py +432 -0
  596. claude_mpm/services/infrastructure/monitoring/base.py +122 -0
  597. claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
  598. claude_mpm/services/infrastructure/monitoring/network.py +219 -0
  599. claude_mpm/services/infrastructure/monitoring/process.py +343 -0
  600. claude_mpm/services/infrastructure/monitoring/resources.py +244 -0
  601. claude_mpm/services/infrastructure/monitoring/service.py +368 -0
  602. claude_mpm/services/infrastructure/monitoring.py +71 -0
  603. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  604. claude_mpm/services/instructions/__init__.py +9 -0
  605. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  606. claude_mpm/services/local_ops/__init__.py +155 -0
  607. claude_mpm/services/local_ops/crash_detector.py +257 -0
  608. claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
  609. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  610. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  611. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  612. claude_mpm/services/local_ops/health_manager.py +427 -0
  613. claude_mpm/services/local_ops/log_monitor.py +396 -0
  614. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  615. claude_mpm/services/local_ops/process_manager.py +595 -0
  616. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  617. claude_mpm/services/local_ops/restart_manager.py +401 -0
  618. claude_mpm/services/local_ops/restart_policy.py +387 -0
  619. claude_mpm/services/local_ops/state_manager.py +372 -0
  620. claude_mpm/services/local_ops/unified_manager.py +600 -0
  621. claude_mpm/services/mcp_config_manager.py +1542 -0
  622. claude_mpm/services/mcp_service_verifier.py +732 -0
  623. claude_mpm/services/memory/__init__.py +19 -0
  624. claude_mpm/services/{memory_builder.py → memory/builder.py} +465 -373
  625. claude_mpm/services/memory/cache/__init__.py +14 -0
  626. claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +237 -200
  627. claude_mpm/services/memory/cache/simple_cache.py +331 -0
  628. claude_mpm/services/memory/failure_tracker.py +578 -0
  629. claude_mpm/services/memory/indexed_memory.py +648 -0
  630. claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +272 -243
  631. claude_mpm/services/memory/router.py +951 -0
  632. claude_mpm/services/memory_hook_service.py +470 -0
  633. claude_mpm/services/model/__init__.py +147 -0
  634. claude_mpm/services/model/base_provider.py +365 -0
  635. claude_mpm/services/model/claude_provider.py +412 -0
  636. claude_mpm/services/model/model_router.py +452 -0
  637. claude_mpm/services/model/ollama_provider.py +415 -0
  638. claude_mpm/services/monitor/__init__.py +20 -0
  639. claude_mpm/services/monitor/daemon.py +698 -0
  640. claude_mpm/services/monitor/daemon_manager.py +1076 -0
  641. claude_mpm/services/monitor/event_emitter.py +350 -0
  642. claude_mpm/services/monitor/handlers/__init__.py +21 -0
  643. claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
  644. claude_mpm/services/monitor/handlers/dashboard.py +299 -0
  645. claude_mpm/services/monitor/handlers/file.py +264 -0
  646. claude_mpm/services/monitor/handlers/hooks.py +512 -0
  647. claude_mpm/services/monitor/management/__init__.py +18 -0
  648. claude_mpm/services/monitor/management/health.py +124 -0
  649. claude_mpm/services/monitor/management/lifecycle.py +730 -0
  650. claude_mpm/services/monitor/server.py +1493 -0
  651. claude_mpm/services/monitor_build_service.py +349 -0
  652. claude_mpm/services/native_agent_converter.py +356 -0
  653. claude_mpm/services/orphan_detection.py +786 -0
  654. claude_mpm/services/pm_skills_deployer.py +711 -0
  655. claude_mpm/services/port_manager.py +597 -0
  656. claude_mpm/services/pr/__init__.py +14 -0
  657. claude_mpm/services/pr/pr_template_service.py +329 -0
  658. claude_mpm/services/profile_manager.py +337 -0
  659. claude_mpm/services/project/__init__.py +44 -0
  660. claude_mpm/services/{project_analyzer.py → project/analyzer.py} +541 -291
  661. claude_mpm/services/project/analyzer_v2.py +566 -0
  662. claude_mpm/services/project/architecture_analyzer.py +461 -0
  663. claude_mpm/services/project/archive_manager.py +1045 -0
  664. claude_mpm/services/project/dependency_analyzer.py +462 -0
  665. claude_mpm/services/project/detection_strategies.py +719 -0
  666. claude_mpm/services/project/documentation_manager.py +554 -0
  667. claude_mpm/services/project/enhanced_analyzer.py +572 -0
  668. claude_mpm/services/project/language_analyzer.py +265 -0
  669. claude_mpm/services/project/metrics_collector.py +407 -0
  670. claude_mpm/services/project/project_organizer.py +1009 -0
  671. claude_mpm/services/project/registry.py +636 -0
  672. claude_mpm/services/project/toolchain_analyzer.py +583 -0
  673. claude_mpm/services/project_port_allocator.py +596 -0
  674. claude_mpm/services/recovery_manager.py +293 -240
  675. claude_mpm/services/response_tracker.py +267 -0
  676. claude_mpm/services/runner_configuration_service.py +605 -0
  677. claude_mpm/services/self_upgrade_service.py +608 -0
  678. claude_mpm/services/session_management_service.py +314 -0
  679. claude_mpm/services/session_manager.py +380 -0
  680. claude_mpm/services/shared/__init__.py +21 -0
  681. claude_mpm/services/shared/async_service_base.py +216 -0
  682. claude_mpm/services/shared/config_service_base.py +301 -0
  683. claude_mpm/services/shared/lifecycle_service_base.py +308 -0
  684. claude_mpm/services/shared/manager_base.py +315 -0
  685. claude_mpm/services/shared/service_factory.py +309 -0
  686. claude_mpm/services/skills/__init__.py +21 -0
  687. claude_mpm/services/skills/git_skill_source_manager.py +1340 -0
  688. claude_mpm/services/skills/selective_skill_deployer.py +743 -0
  689. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  690. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  691. claude_mpm/services/skills_config.py +547 -0
  692. claude_mpm/services/skills_deployer.py +1168 -0
  693. claude_mpm/services/socketio/__init__.py +25 -0
  694. claude_mpm/services/socketio/client_proxy.py +229 -0
  695. claude_mpm/services/socketio/dashboard_server.py +362 -0
  696. claude_mpm/services/socketio/event_normalizer.py +798 -0
  697. claude_mpm/services/socketio/handlers/__init__.py +30 -0
  698. claude_mpm/services/socketio/handlers/base.py +136 -0
  699. claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
  700. claude_mpm/services/socketio/handlers/connection.py +643 -0
  701. claude_mpm/services/socketio/handlers/connection_handler.py +333 -0
  702. claude_mpm/services/socketio/handlers/file.py +263 -0
  703. claude_mpm/services/socketio/handlers/git.py +962 -0
  704. claude_mpm/services/socketio/handlers/hook.py +211 -0
  705. claude_mpm/services/socketio/handlers/memory.py +26 -0
  706. claude_mpm/services/socketio/handlers/project.py +24 -0
  707. claude_mpm/services/socketio/handlers/registry.py +214 -0
  708. claude_mpm/services/socketio/migration_utils.py +343 -0
  709. claude_mpm/services/socketio/monitor_client.py +364 -0
  710. claude_mpm/services/socketio/server/__init__.py +18 -0
  711. claude_mpm/services/socketio/server/broadcaster.py +569 -0
  712. claude_mpm/services/socketio/server/connection_manager.py +579 -0
  713. claude_mpm/services/socketio/server/core.py +1079 -0
  714. claude_mpm/services/socketio/server/eventbus_integration.py +245 -0
  715. claude_mpm/services/socketio/server/main.py +501 -0
  716. claude_mpm/services/socketio_client_manager.py +173 -143
  717. claude_mpm/services/socketio_server.py +38 -1657
  718. claude_mpm/services/subprocess_launcher_service.py +322 -0
  719. claude_mpm/services/system_instructions_service.py +270 -0
  720. claude_mpm/services/ticket_manager.py +25 -209
  721. claude_mpm/services/ticket_services/__init__.py +26 -0
  722. claude_mpm/services/ticket_services/crud_service.py +328 -0
  723. claude_mpm/services/ticket_services/formatter_service.py +290 -0
  724. claude_mpm/services/ticket_services/search_service.py +324 -0
  725. claude_mpm/services/ticket_services/validation_service.py +303 -0
  726. claude_mpm/services/ticket_services/workflow_service.py +244 -0
  727. claude_mpm/services/unified/__init__.py +65 -0
  728. claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
  729. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
  730. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
  731. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
  732. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
  733. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
  734. claude_mpm/services/unified/config_strategies/__init__.py +175 -0
  735. claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
  736. claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
  737. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
  738. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
  739. claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
  740. claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
  741. claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
  742. claude_mpm/services/unified/deployment_strategies/base.py +553 -0
  743. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
  744. claude_mpm/services/unified/deployment_strategies/local.py +607 -0
  745. claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
  746. claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
  747. claude_mpm/services/unified/interfaces.py +475 -0
  748. claude_mpm/services/unified/migration.py +509 -0
  749. claude_mpm/services/unified/strategies.py +534 -0
  750. claude_mpm/services/unified/unified_analyzer.py +542 -0
  751. claude_mpm/services/unified/unified_config.py +691 -0
  752. claude_mpm/services/unified/unified_deployment.py +466 -0
  753. claude_mpm/services/utility_service.py +280 -0
  754. claude_mpm/services/version_control/__init__.py +34 -37
  755. claude_mpm/services/version_control/branch_strategy.py +26 -17
  756. claude_mpm/services/version_control/conflict_resolution.py +52 -36
  757. claude_mpm/services/version_control/git_operations.py +183 -49
  758. claude_mpm/services/version_control/semantic_versioning.py +172 -61
  759. claude_mpm/services/version_control/version_parser.py +546 -0
  760. claude_mpm/services/version_service.py +379 -0
  761. claude_mpm/services/visualization/__init__.py +15 -0
  762. claude_mpm/services/visualization/mermaid_generator.py +937 -0
  763. claude_mpm/skills/__init__.py +42 -0
  764. claude_mpm/skills/agent_skills_injector.py +324 -0
  765. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  766. claude_mpm/skills/bundled/__init__.py +6 -0
  767. claude_mpm/skills/bundled/api-documentation.md +393 -0
  768. claude_mpm/skills/bundled/async-testing.md +571 -0
  769. claude_mpm/skills/bundled/code-review.md +143 -0
  770. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  771. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  772. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  773. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  774. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  775. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  776. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  777. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  778. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  779. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  780. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  781. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  782. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  783. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  784. claude_mpm/skills/bundled/database-migration.md +199 -0
  785. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  786. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  787. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  788. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  789. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  790. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  791. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  792. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  793. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  794. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  795. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  796. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  797. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  798. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  799. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  800. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  801. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  802. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  803. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  804. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  805. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  806. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  807. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  808. claude_mpm/skills/bundled/git-workflow.md +414 -0
  809. claude_mpm/skills/bundled/imagemagick.md +204 -0
  810. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  811. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  812. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  813. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  814. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  815. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  816. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  817. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  818. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  819. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  820. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  821. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  822. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  823. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  824. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  825. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  826. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  827. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  828. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  829. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  830. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  831. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  832. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  833. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  834. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  835. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  836. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  837. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  838. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  839. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  840. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  841. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  842. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  843. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  844. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  845. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  846. claude_mpm/skills/bundled/pdf.md +141 -0
  847. claude_mpm/skills/bundled/performance-profiling.md +573 -0
  848. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  849. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  850. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  851. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  852. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  853. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  854. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  855. claude_mpm/skills/bundled/pm/pm-bug-reporting/pm-bug-reporting.md +248 -0
  856. claude_mpm/skills/bundled/pm/pm-delegation-patterns/SKILL.md +167 -0
  857. claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md +113 -0
  858. claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md +124 -0
  859. claude_mpm/skills/bundled/pm/pm-teaching-mode/SKILL.md +657 -0
  860. claude_mpm/skills/bundled/pm/pm-ticketing-integration/SKILL.md +154 -0
  861. claude_mpm/skills/bundled/pm/pm-verification-protocols/SKILL.md +198 -0
  862. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  863. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  864. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  865. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  866. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  867. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  868. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  869. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  870. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  871. claude_mpm/skills/bundled/security-scanning.md +439 -0
  872. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  873. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  874. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  875. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  876. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  877. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  878. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  879. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  880. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  881. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  882. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  883. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  884. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  885. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  886. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  887. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  888. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  889. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  890. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  891. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  892. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  893. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  894. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  895. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  896. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  897. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  898. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  899. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  900. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  901. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  902. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  903. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  904. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  905. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  906. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  907. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  908. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  909. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  910. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  911. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  912. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  913. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  914. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  915. claude_mpm/skills/bundled/xlsx.md +157 -0
  916. claude_mpm/skills/registry.py +286 -0
  917. claude_mpm/skills/skill_manager.py +405 -0
  918. claude_mpm/skills/skills_registry.py +347 -0
  919. claude_mpm/skills/skills_service.py +739 -0
  920. claude_mpm/storage/__init__.py +9 -0
  921. claude_mpm/storage/state_storage.py +546 -0
  922. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  923. claude_mpm/templates/questions/__init__.py +38 -0
  924. claude_mpm/templates/questions/base.py +193 -0
  925. claude_mpm/templates/questions/pr_strategy.py +311 -0
  926. claude_mpm/templates/questions/project_init.py +385 -0
  927. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  928. claude_mpm/ticket_wrapper.py +2 -2
  929. claude_mpm/tools/__init__.py +10 -0
  930. claude_mpm/tools/__main__.py +208 -0
  931. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  932. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  933. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  934. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  935. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  936. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  937. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  938. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  939. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  940. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  941. claude_mpm/tools/code_tree_builder.py +631 -0
  942. claude_mpm/tools/code_tree_events.py +420 -0
  943. claude_mpm/tools/socketio_debug.py +671 -0
  944. claude_mpm/utils/__init__.py +8 -8
  945. claude_mpm/utils/agent_dependency_loader.py +1189 -0
  946. claude_mpm/utils/agent_filters.py +261 -0
  947. claude_mpm/utils/common.py +544 -0
  948. claude_mpm/utils/config_manager.py +168 -126
  949. claude_mpm/utils/console.py +11 -0
  950. claude_mpm/utils/database_connector.py +298 -0
  951. claude_mpm/utils/dependency_cache.py +373 -0
  952. claude_mpm/utils/dependency_manager.py +60 -59
  953. claude_mpm/utils/dependency_strategies.py +381 -0
  954. claude_mpm/utils/display_helper.py +260 -0
  955. claude_mpm/utils/environment_context.py +313 -0
  956. claude_mpm/utils/error_handler.py +78 -66
  957. claude_mpm/utils/file_utils.py +305 -0
  958. claude_mpm/utils/framework_detection.py +12 -11
  959. claude_mpm/utils/git_analyzer.py +407 -0
  960. claude_mpm/utils/gitignore.py +244 -0
  961. claude_mpm/utils/import_migration_example.py +12 -60
  962. claude_mpm/utils/imports.py +48 -45
  963. claude_mpm/utils/log_cleanup.py +627 -0
  964. claude_mpm/utils/migration.py +372 -0
  965. claude_mpm/utils/path_operations.py +110 -104
  966. claude_mpm/utils/progress.py +387 -0
  967. claude_mpm/utils/robust_installer.py +844 -0
  968. claude_mpm/utils/session_logging.py +121 -0
  969. claude_mpm/utils/structured_questions.py +619 -0
  970. claude_mpm/utils/subprocess_utils.py +343 -0
  971. claude_mpm/validation/__init__.py +1 -1
  972. claude_mpm/validation/agent_validator.py +214 -108
  973. claude_mpm/validation/frontmatter_validator.py +252 -0
  974. claude_mpm-5.4.85.dist-info/METADATA +1023 -0
  975. claude_mpm-5.4.85.dist-info/RECORD +980 -0
  976. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/entry_points.txt +1 -3
  977. claude_mpm-5.4.85.dist-info/licenses/LICENSE +94 -0
  978. claude_mpm-5.4.85.dist-info/licenses/LICENSE-FAQ.md +153 -0
  979. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -88
  980. claude_mpm/agents/INSTRUCTIONS.md +0 -352
  981. claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
  982. claude_mpm/agents/base_agent_loader.py +0 -529
  983. claude_mpm/agents/schema/agent_schema.json +0 -314
  984. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
  985. claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -46
  986. claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -45
  987. claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -49
  988. claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -46
  989. claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -45
  990. claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -49
  991. claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -46
  992. claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -46
  993. claude_mpm/agents/templates/data_engineer.json +0 -110
  994. claude_mpm/agents/templates/documentation.json +0 -109
  995. claude_mpm/agents/templates/engineer.json +0 -113
  996. claude_mpm/agents/templates/ops.json +0 -109
  997. claude_mpm/agents/templates/pm.json +0 -25
  998. claude_mpm/agents/templates/qa.json +0 -111
  999. claude_mpm/agents/templates/research.json +0 -65
  1000. claude_mpm/agents/templates/security.json +0 -113
  1001. claude_mpm/agents/templates/test_integration.json +0 -112
  1002. claude_mpm/agents/templates/version_control.json +0 -107
  1003. claude_mpm/cli/commands/ui.py +0 -57
  1004. claude_mpm/core/simple_runner.py +0 -1046
  1005. claude_mpm/dashboard/open_dashboard.py +0 -34
  1006. claude_mpm/deployment_paths.py +0 -261
  1007. claude_mpm/hooks/builtin/__init__.py +0 -1
  1008. claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
  1009. claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
  1010. claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
  1011. claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
  1012. claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
  1013. claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
  1014. claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
  1015. claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
  1016. claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
  1017. claude_mpm/orchestration/__init__.py +0 -6
  1018. claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
  1019. claude_mpm/orchestration/archive/factory.py +0 -215
  1020. claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
  1021. claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
  1022. claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
  1023. claude_mpm/orchestration/archive/orchestrator.py +0 -501
  1024. claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
  1025. claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
  1026. claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
  1027. claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
  1028. claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
  1029. claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
  1030. claude_mpm/schemas/workflow_validator.py +0 -411
  1031. claude_mpm/services/agent_deployment.py +0 -1534
  1032. claude_mpm/services/agent_lifecycle_manager.py +0 -1169
  1033. claude_mpm/services/agent_memory_manager.py +0 -1415
  1034. claude_mpm/services/agent_registry.py +0 -676
  1035. claude_mpm/services/deployed_agent_discovery.py +0 -226
  1036. claude_mpm/services/framework_agent_loader.py +0 -337
  1037. claude_mpm/services/framework_claude_md_generator.py +0 -621
  1038. claude_mpm/services/health_monitor.py +0 -892
  1039. claude_mpm/services/memory_router.py +0 -538
  1040. claude_mpm/services/parent_directory_manager/__init__.py +0 -577
  1041. claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
  1042. claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
  1043. claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
  1044. claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
  1045. claude_mpm/services/parent_directory_manager/operations.py +0 -186
  1046. claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
  1047. claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
  1048. claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
  1049. claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
  1050. claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
  1051. claude_mpm/services/standalone_socketio_server.py +0 -1300
  1052. claude_mpm/services/ticket_manager_di.py +0 -318
  1053. claude_mpm/services/ticketing_service_original.py +0 -508
  1054. claude_mpm/ui/__init__.py +0 -1
  1055. claude_mpm/ui/rich_terminal_ui.py +0 -295
  1056. claude_mpm/ui/terminal_ui.py +0 -328
  1057. claude_mpm/utils/paths.py +0 -289
  1058. claude_mpm-3.4.10.dist-info/METADATA +0 -183
  1059. claude_mpm-3.4.10.dist-info/RECORD +0 -201
  1060. claude_mpm-3.4.10.dist-info/licenses/LICENSE +0 -21
  1061. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/WHEEL +0 -0
  1062. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.85.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1927 @@
1
+ """Interactive Agent Creation Wizard for Claude MPM.
2
+
3
+ This module provides a step-by-step interactive wizard for creating and managing
4
+ local agents with user-friendly prompts, intelligent defaults, and validation.
5
+ """
6
+
7
+ import json
8
+ import re
9
+ import shutil
10
+ import sys
11
+ from pathlib import Path
12
+ from typing import Any, Dict, List, Optional, Tuple
13
+
14
+ import questionary
15
+
16
+ from claude_mpm.cli.interactive.questionary_styles import (
17
+ BANNER_WIDTH,
18
+ MPM_STYLE,
19
+ print_section_header,
20
+ )
21
+ from claude_mpm.core.logging_config import get_logger
22
+ from claude_mpm.services.agents.local_template_manager import (
23
+ LocalAgentTemplate,
24
+ LocalAgentTemplateManager,
25
+ )
26
+ from claude_mpm.utils.agent_filters import apply_all_filters
27
+
28
+ logger = get_logger(__name__)
29
+
30
+
31
+ class AgentWizard:
32
+ """
33
+ Interactive wizard for agent creation and management.
34
+
35
+ DEPRECATED: This interface has been superseded by the unified
36
+ configuration interface. Please use 'claude-mpm config' instead.
37
+
38
+ This class is retained for backward compatibility but will be
39
+ removed in a future version.
40
+ """
41
+
42
+ def __init__(self):
43
+ """Initialize the agent wizard."""
44
+ self.manager = LocalAgentTemplateManager()
45
+ self.logger = logger
46
+
47
+ # Initialize remote discovery services
48
+ try:
49
+ from claude_mpm.services.agents.git_source_manager import GitSourceManager
50
+
51
+ self.source_manager = GitSourceManager()
52
+ self.discovery_enabled = True
53
+ self.logger.debug("Remote agent discovery enabled")
54
+ except Exception as e:
55
+ self.logger.warning(f"Failed to initialize remote discovery: {e}")
56
+ self.source_manager = None
57
+ self.discovery_enabled = False
58
+
59
+ @staticmethod
60
+ def _calculate_column_widths(
61
+ terminal_width: int, columns: Dict[str, int]
62
+ ) -> Dict[str, int]:
63
+ """Calculate dynamic column widths based on terminal size.
64
+
65
+ Args:
66
+ terminal_width: Current terminal width in characters
67
+ columns: Dict mapping column names to minimum widths
68
+
69
+ Returns:
70
+ Dict mapping column names to calculated widths
71
+
72
+ Design:
73
+ - Ensures minimum widths are respected
74
+ - Distributes extra space proportionally
75
+ - Handles narrow terminals gracefully (minimum 80 chars)
76
+ """
77
+ # Ensure minimum terminal width
78
+ min_terminal_width = 80
79
+ terminal_width = max(terminal_width, min_terminal_width)
80
+
81
+ # Calculate total minimum width needed
82
+ total_min_width = sum(columns.values())
83
+
84
+ # Account for spacing between columns
85
+ overhead = len(columns) + 1
86
+ available_width = terminal_width - overhead
87
+
88
+ # If we have extra space, distribute proportionally
89
+ if available_width > total_min_width:
90
+ extra_space = available_width - total_min_width
91
+ total_weight = sum(columns.values())
92
+
93
+ result = {}
94
+ for col_name, min_width in columns.items():
95
+ # Distribute extra space based on minimum width proportion
96
+ proportion = min_width / total_weight
97
+ extra = int(extra_space * proportion)
98
+ result[col_name] = min_width + extra
99
+ return result
100
+ # Terminal too narrow, use minimum widths
101
+ return columns.copy()
102
+
103
+ def run_interactive_create(self) -> Tuple[bool, str]:
104
+ """Run interactive agent creation wizard.
105
+
106
+ Returns:
107
+ Tuple of (success, message)
108
+ """
109
+ try:
110
+ print_section_header("🧙‍♂️", "Agent Creation Wizard", width=BANNER_WIDTH)
111
+ print("\nI'll guide you through creating a custom local agent.")
112
+ print("Press Ctrl+C anytime to cancel.\n")
113
+
114
+ # Step 1: Agent ID
115
+ agent_id = self._get_agent_id()
116
+ if not agent_id:
117
+ return False, "Agent creation cancelled"
118
+
119
+ # Step 2: Agent Name
120
+ agent_name = self._get_agent_name(agent_id)
121
+
122
+ # Step 3: Agent Type/Category
123
+ agent_type = self._get_agent_type()
124
+
125
+ # Step 4: Model Selection
126
+ model = self._get_model_choice()
127
+
128
+ # Step 5: Inheritance Option
129
+ parent_agent, _base_template = self._get_inheritance_option()
130
+
131
+ # Step 6: Capabilities Configuration
132
+ capabilities = self._get_capabilities_configuration()
133
+
134
+ # Step 7: Description
135
+ description = self._get_agent_description(agent_type)
136
+
137
+ # Step 8: Instructions
138
+ instructions = self._get_agent_instructions(
139
+ agent_id, agent_type, parent_agent
140
+ )
141
+
142
+ # Step 9: Preview Configuration
143
+ config_preview = self._create_preview_config(
144
+ agent_id,
145
+ agent_name,
146
+ agent_type,
147
+ model,
148
+ parent_agent,
149
+ capabilities,
150
+ description,
151
+ instructions,
152
+ )
153
+
154
+ # Step 10: Confirmation
155
+ if not self._confirm_creation(config_preview):
156
+ return False, "Agent creation cancelled"
157
+
158
+ # Step 11: Create and Save Agent
159
+ template = self._create_agent_template(
160
+ agent_id,
161
+ agent_name,
162
+ agent_type,
163
+ model,
164
+ parent_agent,
165
+ capabilities,
166
+ description,
167
+ instructions,
168
+ )
169
+
170
+ template_file = self.manager.save_local_template(template, "project")
171
+
172
+ print(f"\n✅ Agent '{agent_id}' created successfully!")
173
+ print(f"📁 Saved to: {template_file}")
174
+ print("\n💡 Next steps:")
175
+ print(
176
+ f" • Deploy: claude-mpm agent-manager deploy-local --agent-id {agent_id}"
177
+ )
178
+ print(f" • Edit: Edit {template_file} directly")
179
+ print(f" • Test: claude-mpm run --agent {agent_id}")
180
+
181
+ return True, f"Agent '{agent_id}' created successfully"
182
+
183
+ except KeyboardInterrupt:
184
+ print("\n\n❌ Agent creation cancelled by user")
185
+ return False, "Agent creation cancelled"
186
+ except Exception as e:
187
+ error_msg = f"Failed to create agent: {e}"
188
+ self.logger.error(error_msg, exc_info=True)
189
+ return False, error_msg
190
+
191
+ def _merge_agent_sources(self) -> List[Dict[str, Any]]:
192
+ """
193
+ Merge agents from all sources with precedence: local > discovered.
194
+
195
+ Returns list of agents with metadata:
196
+ {
197
+ "agent_id": "engineer/backend/python-engineer",
198
+ "name": "Python Engineer",
199
+ "description": "...",
200
+ "source_type": "system" | "project",
201
+ "source_identifier": "bobmatnyc/claude-mpm-agents",
202
+ "category": "engineer/backend",
203
+ "deployed": True | False,
204
+ "path": "/path/to/agent.md"
205
+ }
206
+ """
207
+ agents = {}
208
+
209
+ # Get discovered agents (system/user sources)
210
+ if self.discovery_enabled and self.source_manager:
211
+ try:
212
+ discovered = self.source_manager.list_cached_agents()
213
+ self.logger.debug(f"Discovered {len(discovered)} remote agents")
214
+
215
+ for agent in discovered:
216
+ agent_id = agent.get("agent_id", "")
217
+ if not agent_id:
218
+ continue
219
+
220
+ # Extract metadata
221
+ metadata = agent.get("metadata", {})
222
+ agents[agent_id] = {
223
+ "agent_id": agent_id,
224
+ "name": metadata.get("name", agent_id),
225
+ "description": metadata.get("description", ""),
226
+ "source_type": "system",
227
+ "source_identifier": agent.get("source", "unknown"),
228
+ "category": agent.get("category", ""),
229
+ "deployed": False, # Will be updated below
230
+ "path": agent.get("path", agent.get("source_file", "")),
231
+ }
232
+ except Exception as e:
233
+ self.logger.warning(f"Failed to discover remote agents: {e}")
234
+
235
+ # Get local agents (project-level, highest precedence)
236
+ local_templates = self.manager.list_local_templates()
237
+ for template in local_templates:
238
+ agent_id = template.agent_id
239
+ agents[agent_id] = {
240
+ "agent_id": agent_id,
241
+ "name": template.metadata.get("name", agent_id),
242
+ "description": template.metadata.get("description", ""),
243
+ "source_type": "project",
244
+ "source_identifier": "local",
245
+ "category": template.metadata.get("category", ""),
246
+ "deployed": True, # Local templates are deployed
247
+ "path": str(self._get_template_path(template)),
248
+ }
249
+
250
+ # Check deployment status for discovered agents
251
+ deployed_dir = Path.cwd() / ".claude" / "agents"
252
+ if deployed_dir.exists():
253
+ for agent_id, agent_data in agents.items():
254
+ deployed_file = deployed_dir / f"{agent_id.replace('/', '-')}.md"
255
+ # Also check hierarchical path
256
+ deployed_file_alt = deployed_dir / f"{agent_id.split('/')[-1]}.md"
257
+ if deployed_file.exists() or deployed_file_alt.exists():
258
+ agent_data["deployed"] = True
259
+
260
+ # Filter BASE_AGENT from all agent lists (1M-502 Phase 1)
261
+ # BASE_AGENT is a build tool, not a deployable agent
262
+ agent_list = list(agents.values())
263
+ return apply_all_filters(agent_list, filter_base=True, filter_deployed=False)
264
+
265
+ def run_interactive_manage(self) -> Tuple[bool, str]:
266
+ """Run interactive agent management menu.
267
+
268
+ Returns:
269
+ Tuple of (success, message)
270
+ """
271
+ try:
272
+ while True:
273
+ # Get merged agents from all sources
274
+ all_agents = self._merge_agent_sources()
275
+
276
+ print_section_header("🔧", "Agent Management Menu", width=BANNER_WIDTH)
277
+
278
+ if not all_agents:
279
+ print(
280
+ "\n📭 No agents found. Configure sources with 'claude-mpm agents discover'"
281
+ )
282
+ print("\n1. Create new agent")
283
+ print("2. Import agents")
284
+ print("3. Exit")
285
+
286
+ choice = input("\nSelect option [1-3]: ").strip()
287
+
288
+ if choice == "1":
289
+ return self.run_interactive_create()
290
+ if choice == "2":
291
+ return self._interactive_import()
292
+ if choice == "3":
293
+ return True, "Management menu exited"
294
+ print("❌ Invalid choice. Please try again.")
295
+ continue
296
+
297
+ # Show existing agents in a table with dynamic widths
298
+ print(f"\n📋 Found {len(all_agents)} agent(s):\n")
299
+
300
+ # Calculate dynamic column widths based on terminal size
301
+ terminal_width = shutil.get_terminal_size().columns
302
+ min_widths = {
303
+ "#": 4,
304
+ "Agent ID": 30,
305
+ "Name": 20,
306
+ "Source": 15,
307
+ "Status": 10,
308
+ }
309
+ widths = self._calculate_column_widths(terminal_width, min_widths)
310
+
311
+ # Print header with dynamic widths
312
+ print(
313
+ f"{'#':<{widths['#']}} "
314
+ f"{'Agent ID':<{widths['Agent ID']}} "
315
+ f"{'Name':<{widths['Name']}} "
316
+ f"{'Source':<{widths['Source']}} "
317
+ f"{'Status':<{widths['Status']}}"
318
+ )
319
+ separator_width = sum(widths.values()) + len(widths) - 1
320
+ print("-" * separator_width)
321
+
322
+ for i, agent in enumerate(all_agents, 1):
323
+ agent_id = agent["agent_id"]
324
+ # Truncate to fit dynamic width
325
+ if len(agent_id) > widths["Agent ID"]:
326
+ agent_id = agent_id[: widths["Agent ID"] - 1] + "…"
327
+
328
+ name = agent["name"]
329
+ if len(name) > widths["Name"]:
330
+ name = name[: widths["Name"] - 1] + "…"
331
+
332
+ source_label = (
333
+ f"[{agent['source_type']}] {agent['source_identifier']}"
334
+ )
335
+ if len(source_label) > widths["Source"]:
336
+ source_label = source_label[: widths["Source"] - 1] + "…"
337
+
338
+ status = "✓ Deployed" if agent["deployed"] else "Available"
339
+
340
+ print(
341
+ f"{i:<{widths['#']}} "
342
+ f"{agent_id:<{widths['Agent ID']}} "
343
+ f"{name:<{widths['Name']}} "
344
+ f"{source_label:<{widths['Source']}} "
345
+ f"{status:<{widths['Status']}}"
346
+ )
347
+
348
+ # Build menu choices with arrow-key navigation
349
+ menu_choices = []
350
+
351
+ # Add agent viewing options (1-N)
352
+ for i, agent in enumerate(all_agents, 1):
353
+ menu_choices.append(f"{i}. View agent: {agent['agent_id']}")
354
+
355
+ # Add action options
356
+ menu_choices.append(f"{len(all_agents) + 1}. Deploy agent")
357
+ menu_choices.append(f"{len(all_agents) + 2}. Create new agent")
358
+ menu_choices.append(f"{len(all_agents) + 3}. Delete agent(s)")
359
+ menu_choices.append(f"{len(all_agents) + 4}. Import agents")
360
+ menu_choices.append(f"{len(all_agents) + 5}. Export all agents")
361
+
362
+ if self.discovery_enabled:
363
+ menu_choices.append(
364
+ f"{len(all_agents) + 6}. Browse & filter agents"
365
+ )
366
+ menu_choices.append(f"{len(all_agents) + 7}. Deploy preset")
367
+ menu_choices.append(f"{len(all_agents) + 8}. Manage agent sources")
368
+ menu_choices.append(f"{len(all_agents) + 9}. Exit")
369
+ exit_num = len(all_agents) + 9
370
+ else:
371
+ menu_choices.append(f"{len(all_agents) + 6}. Exit")
372
+ exit_num = len(all_agents) + 6
373
+
374
+ choice = questionary.select(
375
+ "Agent Management Menu:",
376
+ choices=menu_choices,
377
+ style=MPM_STYLE,
378
+ ).ask()
379
+
380
+ if not choice: # User pressed Esc
381
+ return True, "Management menu exited"
382
+
383
+ # Parse choice number from "N. Description" format
384
+ choice_num = int(choice.split(".")[0])
385
+
386
+ if 1 <= choice_num <= len(all_agents):
387
+ # View agent details
388
+ selected_agent = all_agents[choice_num - 1]
389
+ self._show_agent_details(selected_agent)
390
+ continue
391
+ if choice_num == len(all_agents) + 1:
392
+ self._deploy_agent_interactive(all_agents)
393
+ elif choice_num == len(all_agents) + 2:
394
+ _, message = self.run_interactive_create()
395
+ if message:
396
+ print(f"\n{message}")
397
+ continue
398
+ elif choice_num == len(all_agents) + 3:
399
+ local_templates = self.manager.list_local_templates()
400
+ _, message = self._interactive_delete_menu(local_templates)
401
+ if message:
402
+ print(f"\n{message}")
403
+ continue
404
+ elif choice_num == len(all_agents) + 4:
405
+ _, message = self._interactive_import()
406
+ if message:
407
+ print(f"\n{message}")
408
+ continue
409
+ elif choice_num == len(all_agents) + 5:
410
+ _success, message = self._interactive_export()
411
+ if message:
412
+ print(f"\n{message}")
413
+ continue
414
+ elif choice_num == len(all_agents) + 6 and self.discovery_enabled:
415
+ self._browse_agents_interactive()
416
+ continue
417
+ elif choice_num == len(all_agents) + 7 and self.discovery_enabled:
418
+ self._deploy_preset_interactive()
419
+ continue
420
+ elif choice_num == len(all_agents) + 8 and self.discovery_enabled:
421
+ self._manage_sources_interactive()
422
+ continue
423
+ elif choice_num == exit_num:
424
+ return True, "Management menu exited"
425
+ else:
426
+ print("❌ Invalid choice. Please try again.")
427
+
428
+ except KeyboardInterrupt:
429
+ print("\n\n❌ Management menu cancelled")
430
+ return False, "Management cancelled"
431
+ except Exception as e:
432
+ error_msg = f"Management menu error: {e}"
433
+ self.logger.error(error_msg, exc_info=True)
434
+ return False, error_msg
435
+
436
+ def _get_agent_id(self) -> Optional[str]:
437
+ """Get and validate agent ID from user."""
438
+ while True:
439
+ agent_id = input(
440
+ "1. What would you like to name your agent?\n Agent ID (lowercase, hyphens): "
441
+ ).strip()
442
+
443
+ if not agent_id:
444
+ print("❌ Agent ID is required.")
445
+ continue
446
+
447
+ # Validate format
448
+ if (
449
+ not re.match(r"^[a-z][a-z0-9-]*[a-z0-9]$", agent_id)
450
+ or len(agent_id) > 50
451
+ ):
452
+ print("❌ Agent ID must:")
453
+ print(" • Start with a letter")
454
+ print(" • Contain only lowercase letters, numbers, and hyphens")
455
+ print(" • End with a letter or number")
456
+ print(" • Be 50 characters or less")
457
+ continue
458
+
459
+ # Check for conflicts
460
+ existing_template = self.manager.get_local_template(agent_id)
461
+ if existing_template:
462
+ print(f"❌ Agent '{agent_id}' already exists.")
463
+ overwrite = (
464
+ input(" Overwrite existing agent? [y/N]: ").strip().lower()
465
+ )
466
+ if overwrite not in ["y", "yes"]:
467
+ continue
468
+
469
+ return agent_id
470
+
471
+ def _get_agent_name(self, agent_id: str) -> str:
472
+ """Get agent display name."""
473
+ default_name = agent_id.replace("-", " ").title()
474
+ agent_name = input(
475
+ f"\n2. What should be the display name? [{default_name}]: "
476
+ ).strip()
477
+ return agent_name or default_name
478
+
479
+ def _get_agent_type(self) -> str:
480
+ """Get agent type/category from user."""
481
+ print("\n3. What type of agent is this?")
482
+ agent_types = [
483
+ (
484
+ "research",
485
+ "Research & Analysis",
486
+ "Gathering information, analyzing data, investigating topics",
487
+ ),
488
+ (
489
+ "engineer",
490
+ "Implementation & Engineering",
491
+ "Writing code, building features, technical development",
492
+ ),
493
+ (
494
+ "qa",
495
+ "Quality Assurance & Testing",
496
+ "Testing code, reviewing quality, finding bugs",
497
+ ),
498
+ (
499
+ "docs",
500
+ "Documentation & Writing",
501
+ "Creating docs, writing content, technical writing",
502
+ ),
503
+ (
504
+ "ops",
505
+ "Operations & Deployment",
506
+ "DevOps, deployment, system administration",
507
+ ),
508
+ ("custom", "Custom/Other", "Specialized or unique functionality"),
509
+ ]
510
+
511
+ for i, (_type_id, name, desc) in enumerate(agent_types, 1):
512
+ print(f" [{i}] {name}")
513
+ print(f" {desc}")
514
+
515
+ while True:
516
+ choice = input(f"\nSelect type [1-{len(agent_types)}]: ").strip()
517
+
518
+ try:
519
+ choice_num = int(choice)
520
+ if 1 <= choice_num <= len(agent_types):
521
+ return agent_types[choice_num - 1][0]
522
+ except ValueError:
523
+ pass
524
+
525
+ print("❌ Invalid choice. Please select a number from the list.")
526
+
527
+ def _get_model_choice(self) -> str:
528
+ """Get model selection from user."""
529
+ print("\n4. Which model should this agent use?")
530
+ models = [
531
+ (
532
+ "sonnet",
533
+ "claude-3-sonnet (balanced - recommended)",
534
+ "Good balance of capability and speed",
535
+ ),
536
+ (
537
+ "opus",
538
+ "claude-3-opus (powerful)",
539
+ "Most capable but slower and more expensive",
540
+ ),
541
+ ("haiku", "claude-3-haiku (fast)", "Fastest and most economical"),
542
+ ]
543
+
544
+ for i, (_model_id, name, desc) in enumerate(models, 1):
545
+ print(f" [{i}] {name}")
546
+ print(f" {desc}")
547
+
548
+ while True:
549
+ choice = input(f"\nSelect model [1-{len(models)}] [1]: ").strip() or "1"
550
+
551
+ try:
552
+ choice_num = int(choice)
553
+ if 1 <= choice_num <= len(models):
554
+ return models[choice_num - 1][0]
555
+ except ValueError:
556
+ pass
557
+
558
+ print("❌ Invalid choice. Please select a number from the list.")
559
+
560
+ def _get_inheritance_option(self) -> Tuple[Optional[str], Optional[Dict]]:
561
+ """Get inheritance option from user."""
562
+ print("\n5. Would you like to inherit from an existing agent?")
563
+ print(" [1] No, start fresh")
564
+ print(" [2] Yes, inherit from system agent")
565
+
566
+ while True:
567
+ choice = input("\nSelect option [1-2] [1]: ").strip() or "1"
568
+
569
+ if choice == "1":
570
+ return None, None
571
+ if choice == "2":
572
+ return self._select_system_agent()
573
+ print("❌ Invalid choice. Please select 1 or 2.")
574
+
575
+ def _select_system_agent(self) -> Tuple[Optional[str], Optional[Dict]]:
576
+ """Let user select a system agent to inherit from."""
577
+ try:
578
+ # Get available system agents
579
+ from claude_mpm.services.agents.agent_builder import AgentBuilderService
580
+
581
+ builder = AgentBuilderService()
582
+ templates = builder.list_available_templates()
583
+
584
+ if not templates:
585
+ print("❌ No system agents found to inherit from.")
586
+ return None, None
587
+
588
+ print("\n Select system agent to inherit from:")
589
+ for i, template in enumerate(templates, 1):
590
+ name = template.get("name", template.get("id", "Unknown"))
591
+ description = template.get("description", "")
592
+ print(f" [{i}] {name}")
593
+ if description:
594
+ print(f" {description[:80]}...")
595
+
596
+ while True:
597
+ choice = input(f"\n Select agent [1-{len(templates)}]: ").strip()
598
+
599
+ try:
600
+ choice_num = int(choice)
601
+ if 1 <= choice_num <= len(templates):
602
+ selected = templates[choice_num - 1]
603
+ return selected.get("id"), selected
604
+ except ValueError:
605
+ pass
606
+
607
+ print("❌ Invalid choice. Please select a number from the list.")
608
+
609
+ except Exception as e:
610
+ self.logger.warning(f"Failed to load system agents: {e}")
611
+ print("❌ Could not load system agents for inheritance.")
612
+ return None, None
613
+
614
+ def _get_capabilities_configuration(self) -> Dict[str, Any]:
615
+ """Get capabilities configuration from user."""
616
+ print("\n6. What additional capabilities should this agent have?")
617
+
618
+ capabilities_options = [
619
+ ("code_analysis", "Code analysis and review"),
620
+ ("test_generation", "Test generation and validation"),
621
+ ("security_scanning", "Security analysis and scanning"),
622
+ ("performance_profiling", "Performance analysis and optimization"),
623
+ ("documentation", "Documentation generation"),
624
+ ("api_design", "API design and documentation"),
625
+ ("data_processing", "Data processing and analysis"),
626
+ ("web_scraping", "Web scraping and data extraction"),
627
+ ]
628
+
629
+ print(" Select capabilities (enter multiple numbers separated by spaces):")
630
+ for i, (_cap_id, desc) in enumerate(capabilities_options, 1):
631
+ print(f" [{i}] {desc}")
632
+
633
+ selected_capabilities = []
634
+ while True:
635
+ choices = input(
636
+ f"\nSelect capabilities [1-{len(capabilities_options)}] (space-separated) [none]: "
637
+ ).strip()
638
+
639
+ if not choices or choices.lower() == "none":
640
+ break
641
+
642
+ try:
643
+ choice_nums = [int(x) for x in choices.split()]
644
+ valid_choices = []
645
+
646
+ for num in choice_nums:
647
+ if 1 <= num <= len(capabilities_options):
648
+ selected_capabilities.append(capabilities_options[num - 1][0])
649
+ valid_choices.append(str(num))
650
+
651
+ if valid_choices:
652
+ print(f"✅ Selected: {', '.join(selected_capabilities)}")
653
+ break
654
+ print("❌ No valid choices selected.")
655
+ except ValueError:
656
+ print("❌ Please enter numbers separated by spaces.")
657
+
658
+ return {"specializations": selected_capabilities}
659
+
660
+ def _get_agent_description(self, agent_type: str) -> str:
661
+ """Get agent description from user."""
662
+ type_examples = {
663
+ "research": "Specializes in analyzing market trends and competitive intelligence",
664
+ "engineer": "Focused on building scalable web applications using React and Node.js",
665
+ "qa": "Expert in automated testing and code quality assurance",
666
+ "docs": "Creates clear technical documentation and user guides",
667
+ "ops": "Manages CI/CD pipelines and cloud infrastructure",
668
+ "custom": "Handles specialized domain-specific tasks",
669
+ }
670
+
671
+ example = type_examples.get(agent_type, "Performs specialized tasks")
672
+
673
+ print("\n7. Describe this agent's specialty (one line):")
674
+ print(f" Example: {example}")
675
+
676
+ while True:
677
+ description = input("\n Description: ").strip()
678
+
679
+ if not description:
680
+ print("❌ Description is required.")
681
+ continue
682
+
683
+ if len(description) > 200:
684
+ print("❌ Description should be 200 characters or less.")
685
+ continue
686
+
687
+ return description
688
+
689
+ def _get_agent_instructions(
690
+ self, agent_id: str, agent_type: str, parent_agent: Optional[str]
691
+ ) -> str:
692
+ """Get agent instructions from user."""
693
+ print("\n8. Agent Instructions:")
694
+
695
+ if parent_agent:
696
+ print(f" Since you're inheriting from '{parent_agent}', you can:")
697
+ print(" [1] Use default inherited instructions")
698
+ print(" [2] Add custom instructions")
699
+ print(" [3] Write completely new instructions")
700
+
701
+ choice = input("\n Select option [1-3] [1]: ").strip() or "1"
702
+
703
+ if choice == "1":
704
+ return f"Extends the {parent_agent} agent with project-specific enhancements."
705
+ if choice == "2":
706
+ additional = input("\n Enter additional instructions: ").strip()
707
+ return f"Extends the {parent_agent} agent.\n\nAdditional instructions:\n{additional}"
708
+
709
+ # Get custom instructions
710
+ print(" Enter custom instructions for this agent:")
711
+ print(" (Type 'DONE' on a new line when finished)")
712
+
713
+ lines = []
714
+ while True:
715
+ line = input(" ")
716
+ if line.strip() == "DONE":
717
+ break
718
+ lines.append(line)
719
+
720
+ instructions = "\n".join(lines).strip()
721
+
722
+ if not instructions:
723
+ # Provide default based on type
724
+ type_defaults = {
725
+ "research": f"You are {agent_id}, a research and analysis agent. Focus on gathering accurate information, analyzing data, and providing well-researched insights.",
726
+ "engineer": f"You are {agent_id}, a software engineering agent. Focus on writing clean, efficient code and implementing technical solutions.",
727
+ "qa": f"You are {agent_id}, a quality assurance agent. Focus on testing, code review, and ensuring high quality standards.",
728
+ "docs": f"You are {agent_id}, a documentation agent. Focus on creating clear, comprehensive documentation and technical writing.",
729
+ "ops": f"You are {agent_id}, an operations agent. Focus on deployment, infrastructure, and system administration tasks.",
730
+ "custom": f"You are {agent_id}, a specialized agent. Focus on your specific domain expertise.",
731
+ }
732
+ instructions = type_defaults.get(
733
+ agent_type, f"You are {agent_id}, a specialized agent."
734
+ )
735
+
736
+ return instructions
737
+
738
+ def _create_preview_config(
739
+ self,
740
+ agent_id: str,
741
+ agent_name: str,
742
+ agent_type: str,
743
+ model: str,
744
+ parent_agent: Optional[str],
745
+ capabilities: Dict,
746
+ description: str,
747
+ instructions: str,
748
+ ) -> Dict[str, Any]:
749
+ """Create preview configuration dictionary."""
750
+ config = {
751
+ "agent_id": agent_id,
752
+ "name": agent_name,
753
+ "type": agent_type,
754
+ "model": model,
755
+ "description": description,
756
+ "capabilities": capabilities.get("specializations", []),
757
+ "instructions_preview": (
758
+ instructions[:100] + "..." if len(instructions) > 100 else instructions
759
+ ),
760
+ }
761
+
762
+ if parent_agent:
763
+ config["inherits_from"] = parent_agent
764
+
765
+ return config
766
+
767
+ def _confirm_creation(self, config: Dict[str, Any]) -> bool:
768
+ """Show preview and get confirmation from user."""
769
+ print_section_header("📋", "Agent Configuration Preview", width=BANNER_WIDTH)
770
+
771
+ print(f"Agent ID: {config['agent_id']}")
772
+ print(f"Name: {config['name']}")
773
+ print(f"Type: {config['type']}")
774
+ print(f"Model: {config['model']}")
775
+ print(f"Description: {config['description']}")
776
+
777
+ if config.get("inherits_from"):
778
+ print(f"Inherits: {config['inherits_from']}")
779
+
780
+ if config.get("capabilities"):
781
+ print(f"Capabilities: {', '.join(config['capabilities'])}")
782
+
783
+ print("\nInstructions Preview:")
784
+ print(f" {config['instructions_preview']}")
785
+
786
+ print()
787
+ print("=" * BANNER_WIDTH)
788
+
789
+ while True:
790
+ confirm = input("\nCreate this agent? [Y/n]: ").strip().lower()
791
+
792
+ if confirm in ["", "y", "yes"]:
793
+ return True
794
+ if confirm in ["n", "no"]:
795
+ return False
796
+ print("❌ Please enter 'y' for yes or 'n' for no.")
797
+
798
+ def _create_agent_template(
799
+ self,
800
+ agent_id: str,
801
+ agent_name: str,
802
+ agent_type: str,
803
+ model: str,
804
+ parent_agent: Optional[str],
805
+ capabilities: Dict,
806
+ description: str,
807
+ instructions: str,
808
+ ) -> LocalAgentTemplate:
809
+ """Create the actual agent template."""
810
+ return self.manager.create_local_template(
811
+ agent_id=agent_id,
812
+ name=agent_name,
813
+ description=description,
814
+ instructions=instructions,
815
+ model=model,
816
+ tools="*",
817
+ parent_agent=parent_agent,
818
+ tier="project",
819
+ )
820
+
821
+ def _manage_single_agent(self, template: LocalAgentTemplate) -> Tuple[bool, str]:
822
+ """Manage a single agent."""
823
+ print(f"\n🔧 Managing Agent: {template.agent_id}")
824
+ print(f" Name: {template.metadata.get('name', template.agent_id)}")
825
+ print(f" Tier: {template.tier}")
826
+ print(f" Version: {template.agent_version}")
827
+
828
+ print("\n1. View details")
829
+ print("2. Edit configuration")
830
+ print("3. Deploy agent")
831
+ print("4. Delete agent")
832
+ print("5. Export agent")
833
+ print("6. Back to menu")
834
+
835
+ choice = input("\nSelect option [1-6]: ").strip()
836
+
837
+ if choice == "1":
838
+ return self._view_agent_details(template)
839
+ if choice == "2":
840
+ return self._edit_agent_config(template)
841
+ if choice == "3":
842
+ return self._deploy_single_agent(template)
843
+ if choice == "4":
844
+ return self._delete_agent(template)
845
+ if choice == "5":
846
+ return self._export_single_agent(template)
847
+ if choice == "6":
848
+ return True, "Back to menu"
849
+ return False, "Invalid choice"
850
+
851
+ def _view_agent_details(self, template: LocalAgentTemplate) -> Tuple[bool, str]:
852
+ """View detailed agent information."""
853
+ print(f"\n📄 Agent Details: {template.agent_id}")
854
+ print("=" * 50)
855
+ print(f"Name: {template.metadata.get('name', template.agent_id)}")
856
+ print(f"Version: {template.agent_version}")
857
+ print(f"Author: {template.author}")
858
+ print(f"Tier: {template.tier}")
859
+ print(f"Model: {template.capabilities.get('model', 'unknown')}")
860
+ print(f"Tools: {template.capabilities.get('tools', '*')}")
861
+
862
+ if template.parent_agent:
863
+ print(f"Inherits: {template.parent_agent}")
864
+
865
+ print("\nDescription:")
866
+ print(f" {template.metadata.get('description', 'No description')}")
867
+
868
+ print("\nInstructions:")
869
+ print(
870
+ f" {template.instructions[:200]}{'...' if len(template.instructions) > 200 else ''}"
871
+ )
872
+
873
+ input("\nPress Enter to continue...")
874
+ return True, "Agent details viewed"
875
+
876
+ def _edit_agent_config(self, template: LocalAgentTemplate) -> Tuple[bool, str]:
877
+ """Edit agent configuration."""
878
+ print(f"\n✏️ Editing Agent: {template.agent_id}")
879
+ print("This will open the JSON file in your default editor.")
880
+
881
+ confirm = input("Continue? [y/N]: ").strip().lower()
882
+ if confirm not in ["y", "yes"]:
883
+ return False, "Edit cancelled"
884
+
885
+ # Get template file path
886
+ if template.tier == "project":
887
+ template_file = (
888
+ self.manager.project_agents_dir / f"{template.agent_id}.json"
889
+ )
890
+ else:
891
+ template_file = self.manager.user_agents_dir / f"{template.agent_id}.json"
892
+
893
+ # Open in editor
894
+ import os
895
+ import subprocess
896
+
897
+ editor = os.environ.get("EDITOR", "nano")
898
+ try:
899
+ subprocess.run([editor, str(template_file)], check=True)
900
+ return True, f"Agent {template.agent_id} edited"
901
+ except Exception as e:
902
+ return False, f"Failed to open editor: {e}"
903
+
904
+ def _deploy_single_agent(self, template: LocalAgentTemplate) -> Tuple[bool, str]:
905
+ """Deploy a single agent."""
906
+ try:
907
+ from claude_mpm.services.agents.deployment.local_template_deployment import (
908
+ LocalTemplateDeploymentService,
909
+ )
910
+
911
+ service = LocalTemplateDeploymentService()
912
+ success = service.deploy_single_local_template(
913
+ template.agent_id, force=True
914
+ )
915
+
916
+ if success:
917
+ return True, f"Agent '{template.agent_id}' deployed successfully"
918
+ return False, f"Failed to deploy agent '{template.agent_id}'"
919
+
920
+ except Exception as e:
921
+ return False, f"Deployment error: {e}"
922
+
923
+ def _delete_agent(self, template: LocalAgentTemplate) -> Tuple[bool, str]:
924
+ """Delete an agent with comprehensive options."""
925
+ print(f"\n🗑️ Delete Agent: {template.agent_id}")
926
+ print(f" Name: {template.metadata.get('name', template.agent_id)}")
927
+ print(f" Tier: {template.tier}")
928
+ print(f" Location: {self._get_template_path(template)}")
929
+
930
+ # Check if deployed
931
+ deployment_file = Path.cwd() / ".claude" / "agents" / f"{template.agent_id}.md"
932
+ if deployment_file.exists():
933
+ print(f" Deployed: Yes ({deployment_file})")
934
+ else:
935
+ print(" Deployed: No")
936
+
937
+ print("\nDelete options:")
938
+ print(" [1] Delete template and deployment")
939
+ print(" [2] Delete template only (keep deployment)")
940
+ print(" [3] Cancel")
941
+
942
+ option = input("\nSelect option [1-3]: ").strip()
943
+
944
+ if option == "3":
945
+ return False, "Deletion cancelled"
946
+
947
+ delete_deployment = option == "1"
948
+
949
+ # Confirmation
950
+ print("\n⚠️ This will permanently delete:")
951
+ print(f" - Template: {self._get_template_path(template)}")
952
+ if delete_deployment and deployment_file.exists():
953
+ print(f" - Deployment: {deployment_file}")
954
+
955
+ # Ask about backup
956
+ backup_choice = (
957
+ input("\nCreate backup before deletion? [y/N]: ").strip().lower()
958
+ )
959
+ backup_first = backup_choice in ["y", "yes"]
960
+
961
+ confirm = input("\nAre you sure? Type 'DELETE' to confirm: ").strip()
962
+
963
+ if confirm != "DELETE":
964
+ return False, "Deletion cancelled"
965
+
966
+ # Perform deletion
967
+ result = self.manager.delete_local_template(
968
+ agent_id=template.agent_id,
969
+ tier=template.tier,
970
+ delete_deployment=delete_deployment,
971
+ backup_first=backup_first,
972
+ )
973
+
974
+ if result["success"]:
975
+ message = f"✅ Agent '{template.agent_id}' deleted successfully"
976
+ if result["backup_location"]:
977
+ message += f"\n Backup saved to: {result['backup_location']}"
978
+ message += f"\n Removed {len(result['deleted_files'])} file(s)"
979
+ return True, message
980
+ errors = "\n".join(result["errors"])
981
+ return False, f"Failed to delete agent:\n{errors}"
982
+
983
+ def _export_single_agent(self, template: LocalAgentTemplate) -> Tuple[bool, str]:
984
+ """Export a single agent."""
985
+ output_dir = Path("./exported-agents")
986
+ output_dir.mkdir(exist_ok=True)
987
+
988
+ output_file = output_dir / f"{template.agent_id}.json"
989
+
990
+ with output_file.open("w") as f:
991
+ json.dump(template.to_json(), f, indent=2)
992
+
993
+ return True, f"Agent exported to {output_file}"
994
+
995
+ def _interactive_import(self) -> Tuple[bool, str]:
996
+ """Interactive agent import."""
997
+ input_dir = input("\nEnter directory path to import from: ").strip()
998
+
999
+ if not input_dir:
1000
+ return False, "Import cancelled"
1001
+
1002
+ input_path = Path(input_dir)
1003
+ if not input_path.exists():
1004
+ return False, f"Directory does not exist: {input_path}"
1005
+
1006
+ # Select tier
1007
+ print("\nImport to which tier?")
1008
+ print(" [1] Project (recommended)")
1009
+ print(" [2] User")
1010
+
1011
+ tier_choice = input("Select tier [1-2] [1]: ").strip() or "1"
1012
+ tier = "project" if tier_choice == "1" else "user"
1013
+
1014
+ count = self.manager.import_local_templates(input_path, tier)
1015
+ return True, f"Imported {count} agents from {input_path}"
1016
+
1017
+ def _interactive_export(self) -> Tuple[bool, str]:
1018
+ """Interactive agent export."""
1019
+ output_dir = input(
1020
+ "\nEnter directory path to export to [./exported-agents]: "
1021
+ ).strip()
1022
+
1023
+ if not output_dir:
1024
+ output_dir = "./exported-agents"
1025
+
1026
+ output_path = Path(output_dir)
1027
+ count = self.manager.export_local_templates(output_path)
1028
+ return True, f"Exported {count} agents to {output_path}"
1029
+
1030
+ def _get_template_path(self, template: LocalAgentTemplate) -> Path:
1031
+ """Get the file path for a template."""
1032
+ if template.tier == "project":
1033
+ return self.manager.project_agents_dir / f"{template.agent_id}.json"
1034
+ return self.manager.user_agents_dir / f"{template.agent_id}.json"
1035
+
1036
+ def _interactive_delete_menu(self, templates: list) -> Tuple[bool, str]:
1037
+ """Interactive deletion menu for multiple agents."""
1038
+ print_section_header("🗑️", "Delete Agents", width=BANNER_WIDTH)
1039
+
1040
+ if not templates:
1041
+ return False, "No agents available to delete"
1042
+
1043
+ print("\nAvailable agents:")
1044
+ for i, template in enumerate(templates, 1):
1045
+ tier_icon = "🏢" if template.tier == "project" else "👤"
1046
+ print(
1047
+ f" [{i}] {tier_icon} {template.agent_id} - {template.metadata.get('name', template.agent_id)}"
1048
+ )
1049
+
1050
+ print("\n[all] Select all agents")
1051
+ print("[0] Cancel")
1052
+
1053
+ selection = input(
1054
+ "\nSelect agents to delete (comma-separated numbers or 'all'): "
1055
+ ).strip()
1056
+
1057
+ if selection == "0" or not selection:
1058
+ return False, "Deletion cancelled"
1059
+
1060
+ # Parse selection
1061
+ selected_templates = []
1062
+ if selection.lower() == "all":
1063
+ selected_templates = templates
1064
+ else:
1065
+ try:
1066
+ indices = [int(x.strip()) - 1 for x in selection.split(",")]
1067
+ for idx in indices:
1068
+ if 0 <= idx < len(templates):
1069
+ selected_templates.append(templates[idx])
1070
+ else:
1071
+ print(f"⚠️ Invalid selection: {idx + 1}")
1072
+ except ValueError:
1073
+ return False, "Invalid selection format"
1074
+
1075
+ if not selected_templates:
1076
+ return False, "No valid agents selected"
1077
+
1078
+ # Show what will be deleted
1079
+ print(f"\n📋 Selected {len(selected_templates)} agent(s) for deletion:")
1080
+ for template in selected_templates:
1081
+ tier_icon = "🏢" if template.tier == "project" else "👤"
1082
+ print(f" - {tier_icon} {template.agent_id}")
1083
+
1084
+ # Deletion options
1085
+ print("\nDelete options:")
1086
+ print(" [1] Delete templates and deployments")
1087
+ print(" [2] Delete templates only (keep deployments)")
1088
+ print(" [3] Cancel")
1089
+
1090
+ option = input("\nSelect option [1-3]: ").strip()
1091
+
1092
+ if option == "3":
1093
+ return False, "Deletion cancelled"
1094
+
1095
+ delete_deployment = option == "1"
1096
+
1097
+ # Ask about backup
1098
+ backup_choice = (
1099
+ input("\nCreate backups before deletion? [y/N]: ").strip().lower()
1100
+ )
1101
+ backup_first = backup_choice in ["y", "yes"]
1102
+
1103
+ # Strong confirmation for multiple deletions
1104
+ if len(selected_templates) > 1:
1105
+ print(f"\n⚠️ WARNING: This will delete {len(selected_templates)} agents!")
1106
+
1107
+ confirm = input("\nAre you sure? Type 'DELETE ALL' to confirm: ").strip()
1108
+
1109
+ if confirm != "DELETE ALL":
1110
+ return False, "Deletion cancelled"
1111
+
1112
+ # Perform bulk deletion
1113
+ agent_ids = [t.agent_id for t in selected_templates]
1114
+ results = self.manager.delete_multiple_templates(
1115
+ agent_ids=agent_ids,
1116
+ tier="all", # Check all tiers since we have mixed selection
1117
+ delete_deployment=delete_deployment,
1118
+ backup_first=backup_first,
1119
+ )
1120
+
1121
+ # Format results
1122
+ if results["successful"]:
1123
+ message = (
1124
+ f"✅ Successfully deleted {len(results['successful'])} agent(s):\n"
1125
+ )
1126
+ for agent_id in results["successful"]:
1127
+ message += f" - {agent_id}\n"
1128
+ else:
1129
+ message = ""
1130
+
1131
+ if results["failed"]:
1132
+ message += f"❌ Failed to delete {len(results['failed'])} agent(s):\n"
1133
+ for agent_id in results["failed"]:
1134
+ errors = results["details"][agent_id]["errors"]
1135
+ message += f" - {agent_id}: {', '.join(errors)}\n"
1136
+
1137
+ return len(results["successful"]) > 0, message.strip()
1138
+
1139
+ def _show_agent_details(self, agent: Dict[str, Any]) -> None:
1140
+ """Show detailed information about an agent.
1141
+
1142
+ Args:
1143
+ agent: Agent metadata dictionary
1144
+ """
1145
+ print_section_header(
1146
+ "📄", f"Agent Details: {agent['agent_id']}", width=BANNER_WIDTH
1147
+ )
1148
+ print(f"Name: {agent['name']}")
1149
+ print(f"Category: {agent['category'] or 'N/A'}")
1150
+ print(f"Source: [{agent['source_type']}] {agent['source_identifier']}")
1151
+ print(f"Status: {'✓ Deployed' if agent['deployed'] else 'Available'}")
1152
+ print(f"Path: {agent['path']}")
1153
+
1154
+ if agent["description"]:
1155
+ print("\nDescription:")
1156
+ print(
1157
+ f" {agent['description'][:200]}{'...' if len(agent['description']) > 200 else ''}"
1158
+ )
1159
+
1160
+ input("\nPress Enter to continue...")
1161
+
1162
+ def _deploy_agent_interactive(self, available_agents: List[Dict[str, Any]]):
1163
+ """Interactive agent deployment.
1164
+
1165
+ Args:
1166
+ available_agents: List of all available agents
1167
+ """
1168
+ # Filter to non-deployed agents using improved detection (1M-502 Phase 1)
1169
+ # This checks both .claude-mpm/agents/ and .claude/agents/
1170
+ deployable = apply_all_filters(
1171
+ available_agents, filter_base=True, filter_deployed=True
1172
+ )
1173
+
1174
+ if not deployable:
1175
+ print("\n✅ All agents are already deployed!")
1176
+ input("\nPress Enter to continue...")
1177
+ return
1178
+
1179
+ print_section_header("📦", "Deploy Agent", width=BANNER_WIDTH)
1180
+ print(f"\n{len(deployable)} agent(s) available to deploy:\n")
1181
+
1182
+ # Build agent selection choices with arrow-key navigation
1183
+ agent_choices = [
1184
+ f"{i}. {agent['agent_id']} - {agent['description'][:60]}{'...' if len(agent['description']) > 60 else ''}"
1185
+ for i, agent in enumerate(deployable, 1)
1186
+ ]
1187
+
1188
+ choice = questionary.select(
1189
+ "Select agent to deploy:", choices=agent_choices, style=MPM_STYLE
1190
+ ).ask()
1191
+
1192
+ if not choice: # User pressed Esc
1193
+ return
1194
+
1195
+ # Parse agent index from "N. agent_id - description" format
1196
+ idx = int(choice.split(".")[0]) - 1
1197
+ agent = deployable[idx]
1198
+
1199
+ # Deploy agent using deployment service
1200
+ print(f"\n🚀 Deploying {agent['agent_id']}...")
1201
+
1202
+ try:
1203
+ # Use SingleAgentDeployer for deployment
1204
+ from claude_mpm.services.agents.deployment.agent_template_builder import (
1205
+ AgentTemplateBuilder,
1206
+ )
1207
+ from claude_mpm.services.agents.deployment.agent_version_manager import (
1208
+ AgentVersionManager,
1209
+ )
1210
+ from claude_mpm.services.agents.deployment.deployment_results_manager import (
1211
+ DeploymentResultsManager,
1212
+ )
1213
+ from claude_mpm.services.agents.deployment.single_agent_deployer import (
1214
+ SingleAgentDeployer,
1215
+ )
1216
+
1217
+ # Initialize deployment services
1218
+ template_builder = AgentTemplateBuilder()
1219
+ version_manager = AgentVersionManager()
1220
+ results_manager = DeploymentResultsManager(self.logger)
1221
+ deployer = SingleAgentDeployer(
1222
+ template_builder=template_builder,
1223
+ version_manager=version_manager,
1224
+ results_manager=results_manager,
1225
+ logger=self.logger,
1226
+ )
1227
+
1228
+ # Prepare deployment parameters
1229
+ template_path = Path(agent["path"])
1230
+ target_dir = Path.cwd() / ".claude" / "agents"
1231
+
1232
+ # Find base_agent.json in multiple possible locations
1233
+ base_agent_candidates = [
1234
+ Path.home()
1235
+ / ".claude-mpm"
1236
+ / "agents"
1237
+ / "templates"
1238
+ / "base_agent.json",
1239
+ Path.home() / ".claude-mpm" / "cache" / "base_agent.json",
1240
+ Path(__file__).parent.parent.parent
1241
+ / "agents"
1242
+ / "templates"
1243
+ / "base_agent.json",
1244
+ ]
1245
+ base_agent_path = None
1246
+ for candidate in base_agent_candidates:
1247
+ if candidate.exists():
1248
+ base_agent_path = candidate
1249
+ break
1250
+
1251
+ if not base_agent_path:
1252
+ base_agent_path = base_agent_candidates[
1253
+ 0
1254
+ ] # Use default even if not exists
1255
+
1256
+ # Deploy the agent
1257
+ success = deployer.deploy_agent(
1258
+ agent_name=agent["agent_id"],
1259
+ templates_dir=template_path.parent,
1260
+ target_dir=target_dir,
1261
+ base_agent_path=base_agent_path,
1262
+ force_rebuild=True,
1263
+ working_directory=Path.cwd(),
1264
+ )
1265
+
1266
+ if success:
1267
+ print(f"\n✅ Successfully deployed {agent['agent_id']}")
1268
+ else:
1269
+ print(f"\n❌ Failed to deploy {agent['agent_id']}")
1270
+
1271
+ except Exception as e:
1272
+ self.logger.error(f"Deployment failed: {e}", exc_info=True)
1273
+ print(f"\n❌ Deployment error: {e}")
1274
+
1275
+ input("\nPress Enter to continue...")
1276
+
1277
+ def _browse_agents_interactive(self):
1278
+ """Interactive agent browsing with filters."""
1279
+ if not self.discovery_enabled or not self.source_manager:
1280
+ print("\n❌ Discovery service not available")
1281
+ input("\nPress Enter to continue...")
1282
+ return
1283
+
1284
+ while True:
1285
+ print_section_header("🔍", "Browse & Filter Agents", width=BANNER_WIDTH)
1286
+
1287
+ # Show filter menu with arrow-key navigation
1288
+ print("\n[bold]Filter by:[/bold]")
1289
+
1290
+ filter_choices = [
1291
+ "1. Category (engineer/backend, qa, ops, etc.)",
1292
+ "2. Language (python, typescript, rust, etc.)",
1293
+ "3. Framework (react, nextjs, flask, etc.)",
1294
+ "4. Show all agents",
1295
+ "← Back to main menu",
1296
+ ]
1297
+
1298
+ choice = questionary.select(
1299
+ "Browse & Filter Agents:",
1300
+ choices=filter_choices,
1301
+ style=MPM_STYLE,
1302
+ ).ask()
1303
+
1304
+ if not choice or "Back" in choice:
1305
+ break
1306
+
1307
+ # Parse choice number if it starts with a digit
1308
+ if choice[0].isdigit():
1309
+ choice_num = choice.split(".")[0]
1310
+ else:
1311
+ break
1312
+
1313
+ filtered_agents = []
1314
+ filter_description = ""
1315
+
1316
+ if choice_num == "1":
1317
+ # Category filtering with arrow-key navigation
1318
+ categories = [
1319
+ "engineer/backend",
1320
+ "engineer/frontend",
1321
+ "qa",
1322
+ "ops",
1323
+ "documentation",
1324
+ "universal",
1325
+ ]
1326
+
1327
+ cat_choices = [f"{idx}. {cat}" for idx, cat in enumerate(categories, 1)]
1328
+
1329
+ cat_choice = questionary.select(
1330
+ "Select category:", choices=cat_choices, style=MPM_STYLE
1331
+ ).ask()
1332
+
1333
+ if not cat_choice: # User pressed Esc
1334
+ continue
1335
+
1336
+ # Parse category from "N. category" format
1337
+ cat_idx = int(cat_choice.split(".")[0]) - 1
1338
+ category = categories[cat_idx]
1339
+ all_agents = self._merge_agent_sources()
1340
+ filtered_agents = [
1341
+ a for a in all_agents if a.get("category", "").startswith(category)
1342
+ ]
1343
+ filter_description = f"Category: {category}"
1344
+
1345
+ elif choice_num == "2":
1346
+ # Language filtering (using AUTO-DEPLOY-INDEX if available)
1347
+ language = input(
1348
+ "\nEnter language (python, typescript, rust, go, etc.): "
1349
+ ).strip()
1350
+
1351
+ try:
1352
+ # Find AUTO-DEPLOY-INDEX.md in agent repository
1353
+ from claude_mpm.services.agents.auto_deploy_index_parser import (
1354
+ AutoDeployIndexParser,
1355
+ )
1356
+
1357
+ index_path = (
1358
+ Path.home()
1359
+ / ".claude-mpm"
1360
+ / "cache"
1361
+ / "agents"
1362
+ / "bobmatnyc"
1363
+ / "claude-mpm-agents"
1364
+ / "AUTO-DEPLOY-INDEX.md"
1365
+ )
1366
+ if not index_path.exists():
1367
+ print(
1368
+ f"[yellow]Could not find AUTO-DEPLOY-INDEX.md at: {index_path}[/yellow]"
1369
+ )
1370
+ input("\nPress Enter to continue...")
1371
+ continue
1372
+
1373
+ parser = AutoDeployIndexParser(index_path)
1374
+ lang_agents = parser.get_agents_by_language(language.lower())
1375
+
1376
+ # Get full agent details from discovery
1377
+ all_agents = self._merge_agent_sources()
1378
+ agent_ids = lang_agents.get("core", []) + lang_agents.get(
1379
+ "optional", []
1380
+ )
1381
+ filtered_agents = [
1382
+ a for a in all_agents if a["agent_id"] in agent_ids
1383
+ ]
1384
+ filter_description = f"Language: {language}"
1385
+ except Exception as e:
1386
+ self.logger.error(f"Language filter error: {e}", exc_info=True)
1387
+ print(f"[yellow]Could not filter by language: {e}[/yellow]")
1388
+ input("\nPress Enter to continue...")
1389
+ continue
1390
+
1391
+ elif choice_num == "3":
1392
+ # Framework filtering
1393
+ framework = input(
1394
+ "\nEnter framework (react, nextjs, flask, django, etc.): "
1395
+ ).strip()
1396
+
1397
+ try:
1398
+ from claude_mpm.services.agents.auto_deploy_index_parser import (
1399
+ AutoDeployIndexParser,
1400
+ )
1401
+
1402
+ index_path = (
1403
+ Path.home()
1404
+ / ".claude-mpm"
1405
+ / "cache"
1406
+ / "agents"
1407
+ / "bobmatnyc"
1408
+ / "claude-mpm-agents"
1409
+ / "AUTO-DEPLOY-INDEX.md"
1410
+ )
1411
+ if not index_path.exists():
1412
+ print(
1413
+ f"[yellow]Could not find AUTO-DEPLOY-INDEX.md at: {index_path}[/yellow]"
1414
+ )
1415
+ input("\nPress Enter to continue...")
1416
+ continue
1417
+
1418
+ parser = AutoDeployIndexParser(index_path)
1419
+ framework_agent_ids = parser.get_agents_by_framework(
1420
+ framework.lower()
1421
+ )
1422
+
1423
+ all_agents = self._merge_agent_sources()
1424
+ filtered_agents = [
1425
+ a for a in all_agents if a["agent_id"] in framework_agent_ids
1426
+ ]
1427
+ filter_description = f"Framework: {framework}"
1428
+ except Exception as e:
1429
+ self.logger.error(f"Framework filter error: {e}", exc_info=True)
1430
+ print(f"[yellow]Could not filter by framework: {e}[/yellow]")
1431
+ input("\nPress Enter to continue...")
1432
+ continue
1433
+
1434
+ elif choice_num == "4":
1435
+ # Show all agents
1436
+ filtered_agents = self._merge_agent_sources()
1437
+ filter_description = "All agents"
1438
+ else:
1439
+ print("❌ Invalid choice")
1440
+ input("\nPress Enter to continue...")
1441
+ continue
1442
+
1443
+ # Display filtered results
1444
+ print_section_header(
1445
+ "📋",
1446
+ f"{filter_description} ({len(filtered_agents)} agents)",
1447
+ width=BANNER_WIDTH,
1448
+ )
1449
+
1450
+ if not filtered_agents:
1451
+ print("\n[yellow]No agents found matching filter[/yellow]")
1452
+ else:
1453
+ print(f"\n{'#':<4} {'Agent ID':<40} {'Name':<25} {'Status':<12}")
1454
+ print("-" * 85)
1455
+
1456
+ for idx, agent in enumerate(filtered_agents, 1):
1457
+ agent_id = (
1458
+ agent["agent_id"][:39]
1459
+ if len(agent["agent_id"]) > 39
1460
+ else agent["agent_id"]
1461
+ )
1462
+ name = (
1463
+ agent["name"][:24] if len(agent["name"]) > 24 else agent["name"]
1464
+ )
1465
+ status = "✓ Deployed" if agent.get("deployed") else "Available"
1466
+ print(f"{idx:<4} {agent_id:<40} {name:<25} {status:<12}")
1467
+
1468
+ print("\n[bold]Actions:[/bold]")
1469
+ print(" [d] Deploy agent from this list")
1470
+ print(" [v] View agent details")
1471
+ print(" [n] New filter")
1472
+ print(" [b] Back to main menu")
1473
+
1474
+ action = input("\nSelect action: ").strip()
1475
+
1476
+ if action == "b":
1477
+ break
1478
+ if action == "n":
1479
+ continue
1480
+ if action == "d":
1481
+ self._deploy_from_filtered_list(filtered_agents)
1482
+ elif action == "v":
1483
+ self._view_from_filtered_list(filtered_agents)
1484
+ else:
1485
+ print("❌ Invalid choice")
1486
+ input("\nPress Enter to continue...")
1487
+
1488
+ def _deploy_from_filtered_list(self, agents: List[Dict[str, Any]]):
1489
+ """Deploy an agent from a filtered list.
1490
+
1491
+ Args:
1492
+ agents: List of agent dictionaries with metadata
1493
+ """
1494
+ if not agents:
1495
+ print("\n[yellow]No agents in list[/yellow]")
1496
+ input("\nPress Enter to continue...")
1497
+ return
1498
+
1499
+ deployable = [a for a in agents if not a.get("deployed")]
1500
+
1501
+ if not deployable:
1502
+ print("\n[yellow]All agents in this list are already deployed[/yellow]")
1503
+ input("\nPress Enter to continue...")
1504
+ return
1505
+
1506
+ # Build agent selection choices
1507
+ agent_choices = [
1508
+ f"{i}. {agent['agent_id']}" for i, agent in enumerate(agents, 1)
1509
+ ]
1510
+
1511
+ agent_choice = questionary.select(
1512
+ "Select agent to deploy:", choices=agent_choices, style=MPM_STYLE
1513
+ ).ask()
1514
+
1515
+ if not agent_choice: # User pressed Esc
1516
+ return
1517
+
1518
+ # Parse agent index from "N. agent_id" format
1519
+ idx = int(agent_choice.split(".")[0]) - 1
1520
+ agent = agents[idx]
1521
+
1522
+ if agent.get("deployed"):
1523
+ print(f"\n[yellow]{agent['agent_id']} is already deployed[/yellow]")
1524
+ else:
1525
+ print(f"\n🚀 Deploying {agent['agent_id']}...")
1526
+
1527
+ try:
1528
+ from claude_mpm.services.agents.deployment.agent_template_builder import (
1529
+ AgentTemplateBuilder,
1530
+ )
1531
+ from claude_mpm.services.agents.deployment.agent_version_manager import (
1532
+ AgentVersionManager,
1533
+ )
1534
+ from claude_mpm.services.agents.deployment.deployment_results_manager import (
1535
+ DeploymentResultsManager,
1536
+ )
1537
+ from claude_mpm.services.agents.deployment.single_agent_deployer import (
1538
+ SingleAgentDeployer,
1539
+ )
1540
+
1541
+ # Initialize deployment services
1542
+ template_builder = AgentTemplateBuilder()
1543
+ version_manager = AgentVersionManager()
1544
+ results_manager = DeploymentResultsManager(self.logger)
1545
+ deployer = SingleAgentDeployer(
1546
+ template_builder=template_builder,
1547
+ version_manager=version_manager,
1548
+ results_manager=results_manager,
1549
+ logger=self.logger,
1550
+ )
1551
+
1552
+ # Prepare deployment parameters
1553
+ template_path = Path(agent["path"])
1554
+ target_dir = Path.cwd() / ".claude" / "agents"
1555
+
1556
+ # Find base_agent.json in multiple possible locations
1557
+ base_agent_candidates = [
1558
+ Path.home()
1559
+ / ".claude-mpm"
1560
+ / "agents"
1561
+ / "templates"
1562
+ / "base_agent.json",
1563
+ Path.home() / ".claude-mpm" / "cache" / "base_agent.json",
1564
+ Path(__file__).parent.parent.parent
1565
+ / "agents"
1566
+ / "templates"
1567
+ / "base_agent.json",
1568
+ ]
1569
+ base_agent_path = None
1570
+ for candidate in base_agent_candidates:
1571
+ if candidate.exists():
1572
+ base_agent_path = candidate
1573
+ break
1574
+
1575
+ if not base_agent_path:
1576
+ base_agent_path = base_agent_candidates[
1577
+ 0
1578
+ ] # Use default even if not exists
1579
+
1580
+ # Deploy the agent
1581
+ success = deployer.deploy_agent(
1582
+ agent_name=agent["agent_id"],
1583
+ templates_dir=template_path.parent,
1584
+ target_dir=target_dir,
1585
+ base_agent_path=base_agent_path,
1586
+ force_rebuild=True,
1587
+ working_directory=Path.cwd(),
1588
+ )
1589
+
1590
+ if success:
1591
+ print(f"[green]✓ Successfully deployed {agent['agent_id']}[/green]")
1592
+ else:
1593
+ print(f"[red]✗ Failed to deploy {agent['agent_id']}[/red]")
1594
+
1595
+ except Exception as e:
1596
+ self.logger.error(f"Deployment error: {e}", exc_info=True)
1597
+ print(f"❌ Deployment error: {e}")
1598
+
1599
+ input("\nPress Enter to continue...")
1600
+
1601
+ def _view_from_filtered_list(self, agents: List[Dict[str, Any]]):
1602
+ """View details of an agent from filtered list.
1603
+
1604
+ Args:
1605
+ agents: List of agent dictionaries with metadata
1606
+ """
1607
+ if not agents:
1608
+ print("\n[yellow]No agents in list[/yellow]")
1609
+ input("\nPress Enter to continue...")
1610
+ return
1611
+
1612
+ # Build agent selection choices
1613
+ agent_choices = [
1614
+ f"{i}. {agent['agent_id']}" for i, agent in enumerate(agents, 1)
1615
+ ]
1616
+
1617
+ agent_choice = questionary.select(
1618
+ "Select agent to view:", choices=agent_choices, style=MPM_STYLE
1619
+ ).ask()
1620
+
1621
+ if not agent_choice: # User pressed Esc
1622
+ return
1623
+
1624
+ # Parse agent index from "N. agent_id" format
1625
+ idx = int(agent_choice.split(".")[0]) - 1
1626
+ agent = agents[idx]
1627
+ self._show_agent_details(agent)
1628
+
1629
+ def _deploy_preset_interactive(self):
1630
+ """Interactive preset deployment with preview and confirmation."""
1631
+ from claude_mpm.services.agents.agent_preset_service import AgentPresetService
1632
+
1633
+ if not self.source_manager:
1634
+ print("\n❌ Source manager not available")
1635
+ input("\nPress Enter to continue...")
1636
+ return
1637
+
1638
+ preset_service = AgentPresetService(self.source_manager)
1639
+
1640
+ while True:
1641
+ print_section_header("📦", "Deploy Agent Preset", width=BANNER_WIDTH)
1642
+
1643
+ # List available presets
1644
+ presets = preset_service.list_presets()
1645
+
1646
+ print(f"\n{len(presets)} preset(s) available:\n")
1647
+ print(f"{'#':<4} {'Preset':<20} {'Agents':<10} {'Description':<50}")
1648
+ print("-" * 90)
1649
+
1650
+ for idx, preset in enumerate(presets, 1):
1651
+ description = (
1652
+ preset["description"][:48] + "..."
1653
+ if len(preset["description"]) > 50
1654
+ else preset["description"]
1655
+ )
1656
+ print(
1657
+ f"{idx:<4} {preset['name']:<20} {len(preset.get('agents', [])):<10} {description:<50}"
1658
+ )
1659
+
1660
+ print("\n[bold]Actions:[/bold]")
1661
+ print(" [1-11] Select preset number")
1662
+ print(" [b] Back to main menu")
1663
+
1664
+ choice = input("\nSelect preset number or action: ").strip()
1665
+
1666
+ if choice.lower() == "b":
1667
+ break
1668
+
1669
+ try:
1670
+ idx = int(choice) - 1
1671
+ if idx < 0 or idx >= len(presets):
1672
+ raise ValueError("Out of range")
1673
+
1674
+ preset_name = presets[idx]["name"]
1675
+
1676
+ # Show preset details
1677
+ print_section_header("📦", f"Preset: {preset_name}", width=BANNER_WIDTH)
1678
+ print(f"\n[bold]Description:[/bold] {presets[idx]['description']}\n")
1679
+
1680
+ # Resolve preset
1681
+ print("🔍 Resolving preset agents...")
1682
+ resolution = preset_service.resolve_agents(
1683
+ preset_name, validate_availability=True
1684
+ )
1685
+
1686
+ if resolution.get("missing_agents"):
1687
+ print(
1688
+ f"\n⚠️ [red]Missing agents ({len(resolution['missing_agents'])}):[/red]"
1689
+ )
1690
+ for agent_id in resolution["missing_agents"]:
1691
+ print(f" • {agent_id}")
1692
+ print("\n[yellow]Cannot deploy preset with missing agents[/yellow]")
1693
+ input("\nPress Enter to continue...")
1694
+ continue
1695
+
1696
+ # Show agents to deploy
1697
+ agents = resolution.get("agents", [])
1698
+ print(f"\n[bold]Agents to deploy ({len(agents)}):[/bold]\n")
1699
+
1700
+ print(f"{'Agent ID':<40} {'Name':<25} {'Source':<25}")
1701
+ print("-" * 95)
1702
+
1703
+ for agent in agents:
1704
+ # Get agent metadata
1705
+ agent_metadata = agent.get("metadata", {})
1706
+ agent_meta_data = agent_metadata.get("metadata", {})
1707
+
1708
+ agent_id = (
1709
+ agent.get("agent_id", "")[:39]
1710
+ if len(agent.get("agent_id", "")) > 39
1711
+ else agent.get("agent_id", "")
1712
+ )
1713
+ name = (
1714
+ agent_meta_data.get("name", "")[:24]
1715
+ if len(agent_meta_data.get("name", "")) > 24
1716
+ else agent_meta_data.get("name", "")
1717
+ )
1718
+ source = (
1719
+ agent.get("source", "unknown")[:24]
1720
+ if len(agent.get("source", "unknown")) > 24
1721
+ else agent.get("source", "unknown")
1722
+ )
1723
+
1724
+ print(f"{agent_id:<40} {name:<25} {source:<25}")
1725
+
1726
+ # Confirm deployment
1727
+ print("\n[bold]Options:[/bold]")
1728
+ print(" [y] Deploy all agents")
1729
+ print(" [n] Cancel")
1730
+
1731
+ confirm = input("\nProceed with deployment? ").strip()
1732
+
1733
+ if confirm.lower() == "y":
1734
+ print(f"\n🚀 Deploying preset '{preset_name}'...\n")
1735
+
1736
+ from claude_mpm.services.agents.deployment.agent_template_builder import (
1737
+ AgentTemplateBuilder,
1738
+ )
1739
+ from claude_mpm.services.agents.deployment.agent_version_manager import (
1740
+ AgentVersionManager,
1741
+ )
1742
+ from claude_mpm.services.agents.deployment.deployment_results_manager import (
1743
+ DeploymentResultsManager,
1744
+ )
1745
+ from claude_mpm.services.agents.deployment.single_agent_deployer import (
1746
+ SingleAgentDeployer,
1747
+ )
1748
+
1749
+ # Initialize deployment services once for all agents
1750
+ template_builder = AgentTemplateBuilder()
1751
+ version_manager = AgentVersionManager()
1752
+ results_manager = DeploymentResultsManager(self.logger)
1753
+ deployer = SingleAgentDeployer(
1754
+ template_builder=template_builder,
1755
+ version_manager=version_manager,
1756
+ results_manager=results_manager,
1757
+ logger=self.logger,
1758
+ )
1759
+
1760
+ target_dir = Path.cwd() / ".claude" / "agents"
1761
+
1762
+ # Find base_agent.json
1763
+ base_agent_candidates = [
1764
+ Path.home()
1765
+ / ".claude-mpm"
1766
+ / "agents"
1767
+ / "templates"
1768
+ / "base_agent.json",
1769
+ Path.home() / ".claude-mpm" / "cache" / "base_agent.json",
1770
+ Path(__file__).parent.parent.parent
1771
+ / "agents"
1772
+ / "templates"
1773
+ / "base_agent.json",
1774
+ ]
1775
+ base_agent_path = None
1776
+ for candidate in base_agent_candidates:
1777
+ if candidate.exists():
1778
+ base_agent_path = candidate
1779
+ break
1780
+
1781
+ if not base_agent_path:
1782
+ base_agent_path = base_agent_candidates[0]
1783
+
1784
+ deployed = 0
1785
+ failed = 0
1786
+
1787
+ for agent in agents:
1788
+ agent_id = agent["agent_id"]
1789
+ agent_metadata = agent.get("metadata", {})
1790
+ agent_path = agent_metadata.get(
1791
+ "path", agent_metadata.get("source_file", "")
1792
+ )
1793
+
1794
+ if not agent_path:
1795
+ print(f" Deploying {agent_id}... [red]✗ (no path)[/red]")
1796
+ failed += 1
1797
+ continue
1798
+
1799
+ print(f" Deploying {agent_id}...", end=" ", flush=True)
1800
+
1801
+ try:
1802
+ template_path = Path(agent_path)
1803
+ success = deployer.deploy_agent(
1804
+ agent_name=agent_id,
1805
+ templates_dir=template_path.parent,
1806
+ target_dir=target_dir,
1807
+ base_agent_path=base_agent_path,
1808
+ force_rebuild=True,
1809
+ working_directory=Path.cwd(),
1810
+ )
1811
+
1812
+ if success:
1813
+ print("[green]✓[/green]")
1814
+ deployed += 1
1815
+ else:
1816
+ print("[red]✗[/red]")
1817
+ failed += 1
1818
+ except Exception as e:
1819
+ print(f"[red]✗ ({e})[/red]")
1820
+ self.logger.error(
1821
+ f"Failed to deploy {agent_id}: {e}", exc_info=True
1822
+ )
1823
+ failed += 1
1824
+
1825
+ print("\n[bold]Summary:[/bold]")
1826
+ print(f" • Deployed: {deployed}")
1827
+ print(f" • Failed: {failed}")
1828
+ print(f" • Total: {len(agents)}")
1829
+
1830
+ if failed == 0:
1831
+ print(
1832
+ f"\n[green]✓ Preset '{preset_name}' deployed successfully![/green]"
1833
+ )
1834
+ else:
1835
+ print(
1836
+ f"\n[yellow]⚠ Preset deployed with {failed} failures[/yellow]"
1837
+ )
1838
+
1839
+ input("\nPress Enter to continue...")
1840
+ break
1841
+
1842
+ except (ValueError, IndexError):
1843
+ print("❌ Invalid preset selection")
1844
+ input("\nPress Enter to continue...")
1845
+ except Exception as e:
1846
+ self.logger.error(f"Preset deployment error: {e}", exc_info=True)
1847
+ print(f"❌ Error: {e}")
1848
+ input("\nPress Enter to continue...")
1849
+
1850
+ def _manage_sources_interactive(self):
1851
+ """Interactive source management."""
1852
+ if not self.discovery_enabled or not self.source_manager:
1853
+ print("\n❌ Source manager not available")
1854
+ input("\nPress Enter to continue...")
1855
+ return
1856
+
1857
+ print_section_header("🔗", "Manage Agent Sources", width=BANNER_WIDTH)
1858
+
1859
+ try:
1860
+ from claude_mpm.config.agent_sources import AgentSourceConfiguration
1861
+
1862
+ config = AgentSourceConfiguration()
1863
+ sources = config.list_sources()
1864
+
1865
+ if not sources:
1866
+ print("\n📭 No sources configured.")
1867
+ else:
1868
+ print(f"\n{len(sources)} source(s) configured:\n")
1869
+ print(f"{'Source':<40} {'Priority':<10} {'Status':<10}")
1870
+ print("-" * 60)
1871
+
1872
+ for source in sources:
1873
+ identifier = source.get("identifier", "unknown")[:39]
1874
+ priority = str(source.get("priority", 100))
1875
+ status = "✓ Active" if source.get("enabled", True) else "Disabled"
1876
+ print(f"{identifier:<40} {priority:<10} {status:<10}")
1877
+
1878
+ print("\n💡 Use 'claude-mpm agent-source' command to add/remove sources")
1879
+ print("💡 Use 'claude-mpm agents discover' command to refresh agent cache")
1880
+
1881
+ except Exception as e:
1882
+ self.logger.error(f"Failed to list sources: {e}", exc_info=True)
1883
+ print(f"\n❌ Error: {e}")
1884
+
1885
+ input("\nPress Enter to continue...")
1886
+
1887
+
1888
+ def run_interactive_agent_wizard() -> int:
1889
+ """Entry point for interactive agent wizard.
1890
+
1891
+ Returns:
1892
+ Exit code (0 for success, non-zero for failure)
1893
+ """
1894
+ try:
1895
+ wizard = AgentWizard()
1896
+ success, message = wizard.run_interactive_create()
1897
+
1898
+ if success:
1899
+ print(f"\n✅ {message}")
1900
+ return 0
1901
+ print(f"\n❌ {message}", file=sys.stderr)
1902
+ return 1
1903
+
1904
+ except Exception as e:
1905
+ print(f"\n❌ Wizard error: {e}", file=sys.stderr)
1906
+ return 1
1907
+
1908
+
1909
+ def run_interactive_agent_manager() -> int:
1910
+ """Entry point for interactive agent management.
1911
+
1912
+ Returns:
1913
+ Exit code (0 for success, non-zero for failure)
1914
+ """
1915
+ try:
1916
+ wizard = AgentWizard()
1917
+ success, message = wizard.run_interactive_manage()
1918
+
1919
+ if success:
1920
+ print(f"\n✅ {message}")
1921
+ return 0
1922
+ print(f"\n❌ {message}", file=sys.stderr)
1923
+ return 1
1924
+
1925
+ except Exception as e:
1926
+ print(f"\n❌ Management error: {e}", file=sys.stderr)
1927
+ return 1