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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (950) hide show
  1. claude_mpm/BUILD_NUMBER +1 -0
  2. claude_mpm/VERSION +1 -0
  3. claude_mpm/__init__.py +50 -12
  4. claude_mpm/__main__.py +7 -2
  5. claude_mpm/agents/BASE_AGENT.md +164 -0
  6. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  7. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +290 -0
  8. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
  9. claude_mpm/agents/MEMORY.md +72 -0
  10. claude_mpm/agents/PM_INSTRUCTIONS.md +1402 -0
  11. claude_mpm/agents/WORKFLOW.md +111 -0
  12. claude_mpm/agents/__init__.py +92 -80
  13. claude_mpm/agents/agent-template.yaml +83 -0
  14. claude_mpm/agents/agent_loader.py +560 -745
  15. claude_mpm/agents/agent_loader_integration.py +53 -55
  16. claude_mpm/agents/agents_metadata.py +186 -27
  17. claude_mpm/agents/async_agent_loader.py +436 -0
  18. claude_mpm/agents/base_agent.json +8 -4
  19. claude_mpm/agents/frontmatter_validator.py +754 -0
  20. claude_mpm/agents/system_agent_config.py +222 -155
  21. claude_mpm/agents/templates/README.md +465 -0
  22. claude_mpm/agents/templates/__init__.py +17 -13
  23. claude_mpm/agents/templates/circuit-breakers.md +1391 -0
  24. claude_mpm/agents/templates/context-management-examples.md +544 -0
  25. claude_mpm/agents/templates/git-file-tracking.md +584 -0
  26. claude_mpm/agents/templates/pm-examples.md +474 -0
  27. claude_mpm/agents/templates/pm-red-flags.md +310 -0
  28. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  29. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  30. claude_mpm/agents/templates/response-format.md +583 -0
  31. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  32. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  33. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  34. claude_mpm/agents/templates/validation-templates.md +312 -0
  35. claude_mpm/cli/__init__.py +90 -128
  36. claude_mpm/cli/__main__.py +33 -0
  37. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  38. claude_mpm/cli/commands/__init__.py +36 -12
  39. claude_mpm/cli/commands/agent_manager.py +1403 -0
  40. claude_mpm/cli/commands/agent_source.py +774 -0
  41. claude_mpm/cli/commands/agent_state_manager.py +335 -0
  42. claude_mpm/cli/commands/agents.py +2503 -168
  43. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  44. claude_mpm/cli/commands/agents_discover.py +338 -0
  45. claude_mpm/cli/commands/aggregate.py +540 -0
  46. claude_mpm/cli/commands/analyze.py +553 -0
  47. claude_mpm/cli/commands/analyze_code.py +528 -0
  48. claude_mpm/cli/commands/auto_configure.py +1053 -0
  49. claude_mpm/cli/commands/cleanup.py +588 -0
  50. claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
  51. claude_mpm/cli/commands/config.py +586 -0
  52. claude_mpm/cli/commands/configure.py +2654 -0
  53. claude_mpm/cli/commands/configure_agent_display.py +282 -0
  54. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  55. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  56. claude_mpm/cli/commands/configure_models.py +18 -0
  57. claude_mpm/cli/commands/configure_navigation.py +184 -0
  58. claude_mpm/cli/commands/configure_paths.py +104 -0
  59. claude_mpm/cli/commands/configure_persistence.py +254 -0
  60. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  61. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  62. claude_mpm/cli/commands/configure_validators.py +73 -0
  63. claude_mpm/cli/commands/dashboard.py +286 -0
  64. claude_mpm/cli/commands/debug.py +1386 -0
  65. claude_mpm/cli/commands/doctor.py +243 -0
  66. claude_mpm/cli/commands/hook_errors.py +277 -0
  67. claude_mpm/cli/commands/info.py +195 -74
  68. claude_mpm/cli/commands/local_deploy.py +534 -0
  69. claude_mpm/cli/commands/mcp.py +205 -0
  70. claude_mpm/cli/commands/mcp_command_router.py +161 -0
  71. claude_mpm/cli/commands/mcp_config.py +154 -0
  72. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  73. claude_mpm/cli/commands/mcp_external_commands.py +249 -0
  74. claude_mpm/cli/commands/mcp_install_commands.py +346 -0
  75. claude_mpm/cli/commands/mcp_pipx_config.py +208 -0
  76. claude_mpm/cli/commands/mcp_server_commands.py +155 -0
  77. claude_mpm/cli/commands/mcp_setup_external.py +868 -0
  78. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  79. claude_mpm/cli/commands/memory.py +585 -846
  80. claude_mpm/cli/commands/monitor.py +228 -310
  81. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  82. claude_mpm/cli/commands/mpm_init/core.py +759 -0
  83. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  84. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  85. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  86. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  87. claude_mpm/cli/commands/mpm_init/prompts.py +722 -0
  88. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  89. claude_mpm/cli/commands/mpm_init_handler.py +195 -0
  90. claude_mpm/cli/commands/postmortem.py +401 -0
  91. claude_mpm/cli/commands/profile.py +276 -0
  92. claude_mpm/cli/commands/run.py +910 -488
  93. claude_mpm/cli/commands/search.py +458 -0
  94. claude_mpm/cli/commands/skill_source.py +694 -0
  95. claude_mpm/cli/commands/skills.py +1246 -0
  96. claude_mpm/cli/commands/summarize.py +413 -0
  97. claude_mpm/cli/commands/tickets.py +536 -53
  98. claude_mpm/cli/commands/uninstall.py +176 -0
  99. claude_mpm/cli/commands/upgrade.py +152 -0
  100. claude_mpm/cli/commands/verify.py +119 -0
  101. claude_mpm/cli/executor.py +297 -0
  102. claude_mpm/cli/helpers.py +105 -0
  103. claude_mpm/cli/interactive/__init__.py +21 -0
  104. claude_mpm/cli/interactive/agent_wizard.py +1947 -0
  105. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  106. claude_mpm/cli/parser.py +87 -563
  107. claude_mpm/cli/parsers/__init__.py +35 -0
  108. claude_mpm/cli/parsers/agent_manager_parser.py +393 -0
  109. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  110. claude_mpm/cli/parsers/agents_parser.py +575 -0
  111. claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
  112. claude_mpm/cli/parsers/analyze_parser.py +135 -0
  113. claude_mpm/cli/parsers/auto_configure_parser.py +120 -0
  114. claude_mpm/cli/parsers/base_parser.py +644 -0
  115. claude_mpm/cli/parsers/config_parser.py +208 -0
  116. claude_mpm/cli/parsers/configure_parser.py +138 -0
  117. claude_mpm/cli/parsers/dashboard_parser.py +113 -0
  118. claude_mpm/cli/parsers/debug_parser.py +319 -0
  119. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  120. claude_mpm/cli/parsers/mcp_parser.py +195 -0
  121. claude_mpm/cli/parsers/memory_parser.py +138 -0
  122. claude_mpm/cli/parsers/monitor_parser.py +142 -0
  123. claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
  124. claude_mpm/cli/parsers/profile_parser.py +147 -0
  125. claude_mpm/cli/parsers/run_parser.py +157 -0
  126. claude_mpm/cli/parsers/search_parser.py +245 -0
  127. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  128. claude_mpm/cli/parsers/skills_parser.py +277 -0
  129. claude_mpm/cli/parsers/source_parser.py +138 -0
  130. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  131. claude_mpm/cli/shared/__init__.py +40 -0
  132. claude_mpm/cli/shared/argument_patterns.py +205 -0
  133. claude_mpm/cli/shared/base_command.py +242 -0
  134. claude_mpm/cli/shared/error_handling.py +242 -0
  135. claude_mpm/cli/shared/output_formatters.py +241 -0
  136. claude_mpm/cli/startup.py +1743 -0
  137. claude_mpm/cli/startup_display.py +480 -0
  138. claude_mpm/cli/startup_logging.py +839 -0
  139. claude_mpm/cli/utils.py +136 -47
  140. claude_mpm/cli_module/__init__.py +6 -6
  141. claude_mpm/cli_module/args.py +188 -140
  142. claude_mpm/cli_module/commands.py +79 -70
  143. claude_mpm/cli_module/migration_example.py +42 -64
  144. claude_mpm/commands/__init__.py +14 -0
  145. claude_mpm/commands/mpm-config.md +28 -0
  146. claude_mpm/commands/mpm-doctor.md +20 -0
  147. claude_mpm/commands/mpm-help.md +20 -0
  148. claude_mpm/commands/mpm-init.md +120 -0
  149. claude_mpm/commands/mpm-monitor.md +31 -0
  150. claude_mpm/commands/mpm-organize.md +120 -0
  151. claude_mpm/commands/mpm-postmortem.md +21 -0
  152. claude_mpm/commands/mpm-session-resume.md +30 -0
  153. claude_mpm/commands/mpm-status.md +20 -0
  154. claude_mpm/commands/mpm-ticket-view.md +109 -0
  155. claude_mpm/commands/mpm-version.md +20 -0
  156. claude_mpm/commands/mpm.md +31 -0
  157. claude_mpm/config/__init__.py +42 -2
  158. claude_mpm/config/agent_config.py +402 -0
  159. claude_mpm/config/agent_presets.py +488 -0
  160. claude_mpm/config/agent_sources.py +352 -0
  161. claude_mpm/config/experimental_features.py +217 -0
  162. claude_mpm/config/model_config.py +428 -0
  163. claude_mpm/config/paths.py +258 -0
  164. claude_mpm/config/skill_presets.py +392 -0
  165. claude_mpm/config/skill_sources.py +590 -0
  166. claude_mpm/config/socketio_config.py +125 -83
  167. claude_mpm/constants.py +132 -22
  168. claude_mpm/core/__init__.py +62 -36
  169. claude_mpm/core/agent_name_normalizer.py +71 -73
  170. claude_mpm/core/agent_registry.py +385 -492
  171. claude_mpm/core/agent_session_manager.py +81 -70
  172. claude_mpm/core/api_validator.py +330 -0
  173. claude_mpm/core/base_service.py +159 -122
  174. claude_mpm/core/cache.py +560 -0
  175. claude_mpm/core/claude_runner.py +696 -916
  176. claude_mpm/core/config.py +613 -122
  177. claude_mpm/core/config_aliases.py +74 -73
  178. claude_mpm/core/config_constants.py +314 -0
  179. claude_mpm/core/constants.py +361 -0
  180. claude_mpm/core/container.py +646 -104
  181. claude_mpm/core/enums.py +452 -0
  182. claude_mpm/core/error_handler.py +623 -0
  183. claude_mpm/core/exceptions.py +536 -0
  184. claude_mpm/core/factories.py +105 -109
  185. claude_mpm/core/file_utils.py +764 -0
  186. claude_mpm/core/framework/__init__.py +25 -0
  187. claude_mpm/core/framework/formatters/__init__.py +11 -0
  188. claude_mpm/core/framework/formatters/capability_generator.py +367 -0
  189. claude_mpm/core/framework/formatters/content_formatter.py +278 -0
  190. claude_mpm/core/framework/formatters/context_generator.py +185 -0
  191. claude_mpm/core/framework/loaders/__init__.py +13 -0
  192. claude_mpm/core/framework/loaders/agent_loader.py +213 -0
  193. claude_mpm/core/framework/loaders/file_loader.py +176 -0
  194. claude_mpm/core/framework/loaders/instruction_loader.py +222 -0
  195. claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
  196. claude_mpm/core/framework/processors/__init__.py +11 -0
  197. claude_mpm/core/framework/processors/memory_processor.py +230 -0
  198. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  199. claude_mpm/core/framework/processors/template_processor.py +244 -0
  200. claude_mpm/core/framework_loader.py +485 -414
  201. claude_mpm/core/hook_error_memory.py +381 -0
  202. claude_mpm/core/hook_manager.py +246 -86
  203. claude_mpm/core/hook_performance_config.py +147 -0
  204. claude_mpm/core/injectable_service.py +72 -63
  205. claude_mpm/core/instruction_reinforcement_hook.py +267 -0
  206. claude_mpm/core/interactive_session.py +670 -0
  207. claude_mpm/core/interfaces.py +570 -164
  208. claude_mpm/core/lazy.py +467 -0
  209. claude_mpm/core/log_manager.py +707 -0
  210. claude_mpm/core/logger.py +295 -134
  211. claude_mpm/core/logging_config.py +474 -0
  212. claude_mpm/core/logging_utils.py +520 -0
  213. claude_mpm/core/minimal_framework_loader.py +24 -22
  214. claude_mpm/core/mixins.py +30 -29
  215. claude_mpm/core/oneshot_session.py +594 -0
  216. claude_mpm/core/optimized_agent_loader.py +479 -0
  217. claude_mpm/core/optimized_startup.py +554 -0
  218. claude_mpm/core/output_style_manager.py +483 -0
  219. claude_mpm/core/pm_hook_interceptor.py +197 -82
  220. claude_mpm/core/protocols/__init__.py +23 -0
  221. claude_mpm/core/protocols/runner_protocol.py +103 -0
  222. claude_mpm/core/protocols/session_protocol.py +131 -0
  223. claude_mpm/core/service_registry.py +153 -116
  224. claude_mpm/core/session_manager.py +179 -64
  225. claude_mpm/core/shared/__init__.py +17 -0
  226. claude_mpm/core/shared/config_loader.py +326 -0
  227. claude_mpm/core/shared/path_resolver.py +281 -0
  228. claude_mpm/core/shared/singleton_manager.py +221 -0
  229. claude_mpm/core/socketio_pool.py +400 -137
  230. claude_mpm/core/system_context.py +38 -0
  231. claude_mpm/core/tool_access_control.py +64 -57
  232. claude_mpm/core/types.py +307 -0
  233. claude_mpm/core/typing_utils.py +553 -0
  234. claude_mpm/core/unified_agent_registry.py +969 -0
  235. claude_mpm/core/unified_config.py +570 -0
  236. claude_mpm/core/unified_paths.py +941 -0
  237. claude_mpm/dashboard/__init__.py +12 -0
  238. claude_mpm/dashboard/api/simple_directory.py +261 -0
  239. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  240. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
  241. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
  242. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
  243. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
  244. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
  245. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
  246. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
  247. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
  248. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
  249. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
  250. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  251. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
  252. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
  253. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
  254. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
  255. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
  256. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
  257. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
  258. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
  259. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
  260. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
  261. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
  262. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
  263. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
  264. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  265. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
  266. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
  267. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  268. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
  269. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
  270. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
  271. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
  272. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
  273. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
  274. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
  275. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
  276. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
  277. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  278. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
  279. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
  280. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
  281. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
  282. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
  283. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
  284. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
  285. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
  286. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
  287. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
  288. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  289. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
  290. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
  291. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
  292. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
  293. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
  294. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
  295. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
  296. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
  297. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
  298. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
  299. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
  300. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
  301. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
  302. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
  303. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
  304. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  305. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  306. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  307. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  308. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  309. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  310. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  311. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  312. claude_mpm/experimental/__init__.py +10 -0
  313. claude_mpm/experimental/cli_enhancements.py +104 -89
  314. claude_mpm/generators/__init__.py +1 -1
  315. claude_mpm/generators/agent_profile_generator.py +76 -66
  316. claude_mpm/hooks/__init__.py +37 -1
  317. claude_mpm/hooks/base_hook.py +37 -32
  318. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  319. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  320. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  321. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  322. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  323. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  324. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  325. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  326. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  327. claude_mpm/hooks/claude_hooks/connection_pool.py +250 -0
  328. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  329. claude_mpm/hooks/claude_hooks/event_handlers.py +888 -0
  330. claude_mpm/hooks/claude_hooks/hook_handler.py +652 -875
  331. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +10 -7
  332. claude_mpm/hooks/claude_hooks/installer.py +806 -0
  333. claude_mpm/hooks/claude_hooks/memory_integration.py +249 -0
  334. claude_mpm/hooks/claude_hooks/response_tracking.py +412 -0
  335. claude_mpm/hooks/claude_hooks/services/__init__.py +15 -0
  336. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  337. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  338. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  339. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  340. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  341. claude_mpm/hooks/claude_hooks/services/connection_manager.py +229 -0
  342. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +254 -0
  343. claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
  344. claude_mpm/hooks/claude_hooks/services/state_manager.py +284 -0
  345. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
  346. claude_mpm/hooks/claude_hooks/tool_analysis.py +224 -0
  347. claude_mpm/hooks/failure_learning/__init__.py +54 -0
  348. claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
  349. claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
  350. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
  351. claude_mpm/hooks/instruction_reinforcement.py +301 -0
  352. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  353. claude_mpm/hooks/kuzu_memory_hook.py +386 -0
  354. claude_mpm/hooks/kuzu_response_hook.py +179 -0
  355. claude_mpm/hooks/memory_integration_hook.py +201 -107
  356. claude_mpm/hooks/session_resume_hook.py +121 -0
  357. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  358. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  359. claude_mpm/hooks/tool_call_interceptor.py +92 -76
  360. claude_mpm/hooks/validation_hooks.py +62 -54
  361. claude_mpm/init.py +518 -83
  362. claude_mpm/models/__init__.py +9 -9
  363. claude_mpm/models/agent_definition.py +40 -23
  364. claude_mpm/models/agent_session.py +538 -0
  365. claude_mpm/models/git_repository.py +198 -0
  366. claude_mpm/models/resume_log.py +340 -0
  367. claude_mpm/schemas/__init__.py +12 -0
  368. claude_mpm/scripts/__init__.py +15 -0
  369. claude_mpm/scripts/claude-hook-handler.sh +227 -0
  370. claude_mpm/scripts/launch_monitor.py +165 -0
  371. claude_mpm/scripts/mpm_doctor.py +322 -0
  372. claude_mpm/scripts/socketio_daemon.py +189 -200
  373. claude_mpm/scripts/start_activity_logging.py +91 -0
  374. claude_mpm/services/__init__.py +208 -39
  375. claude_mpm/services/agent_capabilities_service.py +266 -0
  376. claude_mpm/services/agents/__init__.py +89 -0
  377. claude_mpm/services/agents/agent_builder.py +514 -0
  378. claude_mpm/services/agents/agent_preset_service.py +238 -0
  379. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  380. claude_mpm/services/agents/agent_review_service.py +280 -0
  381. claude_mpm/services/agents/agent_selection_service.py +484 -0
  382. claude_mpm/services/agents/auto_config_manager.py +796 -0
  383. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  384. claude_mpm/services/agents/cache_git_manager.py +621 -0
  385. claude_mpm/services/agents/deployment/__init__.py +21 -0
  386. claude_mpm/services/agents/deployment/agent_config_provider.py +410 -0
  387. claude_mpm/services/agents/deployment/agent_configuration_manager.py +358 -0
  388. claude_mpm/services/agents/deployment/agent_definition_factory.py +80 -0
  389. claude_mpm/services/agents/deployment/agent_deployment.py +1037 -0
  390. claude_mpm/services/agents/deployment/agent_discovery_service.py +546 -0
  391. claude_mpm/services/agents/deployment/agent_environment_manager.py +288 -0
  392. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +383 -0
  393. claude_mpm/services/agents/deployment/agent_format_converter.py +505 -0
  394. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +160 -0
  395. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +957 -0
  396. claude_mpm/services/agents/deployment/agent_metrics_collector.py +273 -0
  397. claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
  398. claude_mpm/services/agents/deployment/agent_record_service.py +418 -0
  399. claude_mpm/services/agents/deployment/agent_restore_handler.py +84 -0
  400. claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
  401. claude_mpm/services/agents/deployment/agent_template_builder.py +1369 -0
  402. claude_mpm/services/agents/deployment/agent_validator.py +376 -0
  403. claude_mpm/services/agents/deployment/agent_version_manager.py +322 -0
  404. claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +10 -13
  405. claude_mpm/services/agents/deployment/agents_directory_resolver.py +149 -0
  406. claude_mpm/services/agents/deployment/async_agent_deployment.py +768 -0
  407. claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
  408. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  409. claude_mpm/services/agents/deployment/config/deployment_config.py +181 -0
  410. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  411. claude_mpm/services/agents/deployment/deployment_config_loader.py +178 -0
  412. claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
  413. claude_mpm/services/agents/deployment/deployment_type_detector.py +120 -0
  414. claude_mpm/services/agents/deployment/deployment_wrapper.py +129 -0
  415. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  416. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  417. claude_mpm/services/agents/deployment/facade/deployment_executor.py +70 -0
  418. claude_mpm/services/agents/deployment/facade/deployment_facade.py +269 -0
  419. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  420. claude_mpm/services/agents/deployment/interface_adapter.py +226 -0
  421. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  422. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  423. claude_mpm/services/agents/deployment/local_template_deployment.py +362 -0
  424. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +1478 -0
  425. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  426. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  427. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +162 -0
  428. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  429. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  430. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +240 -0
  431. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +110 -0
  432. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +80 -0
  433. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +92 -0
  434. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +101 -0
  435. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  436. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +102 -0
  437. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  438. claude_mpm/services/agents/deployment/processors/agent_processor.py +269 -0
  439. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +311 -0
  440. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +862 -0
  441. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  442. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  443. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  444. claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
  445. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  446. claude_mpm/services/agents/deployment/strategies/base_strategy.py +113 -0
  447. claude_mpm/services/agents/deployment/strategies/project_strategy.py +148 -0
  448. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  449. claude_mpm/services/agents/deployment/strategies/system_strategy.py +131 -0
  450. claude_mpm/services/agents/deployment/strategies/user_strategy.py +130 -0
  451. claude_mpm/services/agents/deployment/system_instructions_deployer.py +228 -0
  452. claude_mpm/services/agents/deployment/validation/__init__.py +21 -0
  453. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  454. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  455. claude_mpm/services/agents/deployment/validation/template_validator.py +319 -0
  456. claude_mpm/services/agents/deployment/validation/validation_result.py +214 -0
  457. claude_mpm/services/agents/git_source_manager.py +682 -0
  458. claude_mpm/services/agents/loading/__init__.py +11 -0
  459. claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +306 -228
  460. claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +106 -91
  461. claude_mpm/services/agents/loading/framework_agent_loader.py +433 -0
  462. claude_mpm/services/agents/local_template_manager.py +784 -0
  463. claude_mpm/services/agents/management/__init__.py +9 -0
  464. claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +92 -69
  465. claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +219 -168
  466. claude_mpm/services/agents/memory/__init__.py +22 -0
  467. claude_mpm/services/agents/memory/agent_memory_manager.py +784 -0
  468. claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +20 -18
  469. claude_mpm/services/agents/memory/content_manager.py +470 -0
  470. claude_mpm/services/agents/memory/memory_categorization_service.py +167 -0
  471. claude_mpm/services/agents/memory/memory_file_service.py +129 -0
  472. claude_mpm/services/agents/memory/memory_format_service.py +201 -0
  473. claude_mpm/services/agents/memory/memory_limits_service.py +101 -0
  474. claude_mpm/services/agents/memory/template_generator.py +83 -0
  475. claude_mpm/services/agents/observers.py +547 -0
  476. claude_mpm/services/agents/recommender.py +617 -0
  477. claude_mpm/services/agents/registry/__init__.py +30 -0
  478. claude_mpm/services/agents/registry/deployed_agent_discovery.py +273 -0
  479. claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +370 -295
  480. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  481. claude_mpm/services/agents/sources/__init__.py +13 -0
  482. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  483. claude_mpm/services/agents/sources/git_source_sync_service.py +1202 -0
  484. claude_mpm/services/agents/startup_sync.py +259 -0
  485. claude_mpm/services/agents/toolchain_detector.py +478 -0
  486. claude_mpm/services/analysis/__init__.py +35 -0
  487. claude_mpm/services/analysis/clone_detector.py +1030 -0
  488. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  489. claude_mpm/services/analysis/postmortem_service.py +765 -0
  490. claude_mpm/services/async_session_logger.py +665 -0
  491. claude_mpm/services/claude_session_logger.py +321 -0
  492. claude_mpm/services/cli/__init__.py +18 -0
  493. claude_mpm/services/cli/agent_cleanup_service.py +408 -0
  494. claude_mpm/services/cli/agent_dependency_service.py +395 -0
  495. claude_mpm/services/cli/agent_listing_service.py +463 -0
  496. claude_mpm/services/cli/agent_output_formatter.py +605 -0
  497. claude_mpm/services/cli/agent_validation_service.py +590 -0
  498. claude_mpm/services/cli/memory_crud_service.py +622 -0
  499. claude_mpm/services/cli/memory_output_formatter.py +604 -0
  500. claude_mpm/services/cli/resume_service.py +617 -0
  501. claude_mpm/services/cli/session_manager.py +604 -0
  502. claude_mpm/services/cli/session_pause_manager.py +504 -0
  503. claude_mpm/services/cli/session_resume_helper.py +372 -0
  504. claude_mpm/services/cli/startup_checker.py +362 -0
  505. claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
  506. claude_mpm/services/command_deployment_service.py +446 -0
  507. claude_mpm/services/command_handler_service.py +221 -0
  508. claude_mpm/services/communication/__init__.py +22 -0
  509. claude_mpm/services/core/__init__.py +108 -0
  510. claude_mpm/services/core/base.py +269 -0
  511. claude_mpm/services/core/cache_manager.py +309 -0
  512. claude_mpm/services/core/interfaces/__init__.py +273 -0
  513. claude_mpm/services/core/interfaces/agent.py +514 -0
  514. claude_mpm/services/core/interfaces/communication.py +316 -0
  515. claude_mpm/services/core/interfaces/health.py +169 -0
  516. claude_mpm/services/core/interfaces/infrastructure.py +357 -0
  517. claude_mpm/services/core/interfaces/model.py +281 -0
  518. claude_mpm/services/core/interfaces/process.py +372 -0
  519. claude_mpm/services/core/interfaces/project.py +121 -0
  520. claude_mpm/services/core/interfaces/restart.py +307 -0
  521. claude_mpm/services/core/interfaces/service.py +405 -0
  522. claude_mpm/services/core/interfaces/stability.py +260 -0
  523. claude_mpm/services/core/interfaces.py +81 -0
  524. claude_mpm/services/core/memory_manager.py +682 -0
  525. claude_mpm/services/core/models/__init__.py +70 -0
  526. claude_mpm/services/core/models/agent_config.py +384 -0
  527. claude_mpm/services/core/models/health.py +162 -0
  528. claude_mpm/services/core/models/process.py +239 -0
  529. claude_mpm/services/core/models/restart.py +302 -0
  530. claude_mpm/services/core/models/stability.py +264 -0
  531. claude_mpm/services/core/models/toolchain.py +306 -0
  532. claude_mpm/services/core/path_resolver.py +517 -0
  533. claude_mpm/services/core/service_container.py +520 -0
  534. claude_mpm/services/core/service_interfaces.py +436 -0
  535. claude_mpm/services/diagnostics/__init__.py +18 -0
  536. claude_mpm/services/diagnostics/checks/__init__.py +38 -0
  537. claude_mpm/services/diagnostics/checks/agent_check.py +370 -0
  538. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  539. claude_mpm/services/diagnostics/checks/base_check.py +60 -0
  540. claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
  541. claude_mpm/services/diagnostics/checks/common_issues_check.py +363 -0
  542. claude_mpm/services/diagnostics/checks/configuration_check.py +306 -0
  543. claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
  544. claude_mpm/services/diagnostics/checks/installation_check.py +520 -0
  545. claude_mpm/services/diagnostics/checks/instructions_check.py +415 -0
  546. claude_mpm/services/diagnostics/checks/mcp_check.py +330 -0
  547. claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
  548. claude_mpm/services/diagnostics/checks/monitor_check.py +281 -0
  549. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  550. claude_mpm/services/diagnostics/checks/startup_log_check.py +319 -0
  551. claude_mpm/services/diagnostics/diagnostic_runner.py +286 -0
  552. claude_mpm/services/diagnostics/doctor_reporter.py +578 -0
  553. claude_mpm/services/diagnostics/models.py +138 -0
  554. claude_mpm/services/event_aggregator.py +582 -0
  555. claude_mpm/services/event_bus/__init__.py +18 -0
  556. claude_mpm/services/event_bus/config.py +186 -0
  557. claude_mpm/services/event_bus/direct_relay.py +312 -0
  558. claude_mpm/services/event_bus/event_bus.py +396 -0
  559. claude_mpm/services/event_bus/relay.py +326 -0
  560. claude_mpm/services/events/__init__.py +44 -0
  561. claude_mpm/services/events/consumers/__init__.py +18 -0
  562. claude_mpm/services/events/consumers/dead_letter.py +306 -0
  563. claude_mpm/services/events/consumers/logging.py +184 -0
  564. claude_mpm/services/events/consumers/metrics.py +241 -0
  565. claude_mpm/services/events/consumers/socketio.py +377 -0
  566. claude_mpm/services/events/core.py +480 -0
  567. claude_mpm/services/events/interfaces.py +214 -0
  568. claude_mpm/services/events/producers/__init__.py +14 -0
  569. claude_mpm/services/events/producers/hook.py +269 -0
  570. claude_mpm/services/events/producers/system.py +329 -0
  571. claude_mpm/services/exceptions.py +433 -353
  572. claude_mpm/services/framework_claude_md_generator/__init__.py +81 -80
  573. claude_mpm/services/framework_claude_md_generator/content_assembler.py +74 -67
  574. claude_mpm/services/framework_claude_md_generator/content_validator.py +66 -62
  575. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +82 -60
  576. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +36 -37
  577. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +41 -40
  578. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +15 -15
  579. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +5 -4
  580. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  581. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  582. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  583. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  584. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +5 -4
  585. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  586. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  587. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +26 -30
  588. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +6 -5
  589. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  590. claude_mpm/services/framework_claude_md_generator/version_manager.py +31 -30
  591. claude_mpm/services/git/__init__.py +21 -0
  592. claude_mpm/services/git/git_operations_service.py +579 -0
  593. claude_mpm/services/github/__init__.py +21 -0
  594. claude_mpm/services/github/github_cli_service.py +397 -0
  595. claude_mpm/services/hook_installer_service.py +506 -0
  596. claude_mpm/services/hook_service.py +159 -111
  597. claude_mpm/services/infrastructure/__init__.py +52 -0
  598. claude_mpm/services/infrastructure/context_preservation.py +569 -0
  599. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  600. claude_mpm/services/infrastructure/logging.py +209 -0
  601. claude_mpm/services/infrastructure/monitoring/__init__.py +39 -0
  602. claude_mpm/services/infrastructure/monitoring/aggregator.py +432 -0
  603. claude_mpm/services/infrastructure/monitoring/base.py +122 -0
  604. claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
  605. claude_mpm/services/infrastructure/monitoring/network.py +219 -0
  606. claude_mpm/services/infrastructure/monitoring/process.py +343 -0
  607. claude_mpm/services/infrastructure/monitoring/resources.py +244 -0
  608. claude_mpm/services/infrastructure/monitoring/service.py +368 -0
  609. claude_mpm/services/infrastructure/monitoring.py +71 -0
  610. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  611. claude_mpm/services/instructions/__init__.py +9 -0
  612. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  613. claude_mpm/services/local_ops/__init__.py +155 -0
  614. claude_mpm/services/local_ops/crash_detector.py +257 -0
  615. claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
  616. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  617. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  618. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  619. claude_mpm/services/local_ops/health_manager.py +427 -0
  620. claude_mpm/services/local_ops/log_monitor.py +396 -0
  621. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  622. claude_mpm/services/local_ops/process_manager.py +595 -0
  623. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  624. claude_mpm/services/local_ops/restart_manager.py +401 -0
  625. claude_mpm/services/local_ops/restart_policy.py +387 -0
  626. claude_mpm/services/local_ops/state_manager.py +372 -0
  627. claude_mpm/services/local_ops/unified_manager.py +600 -0
  628. claude_mpm/services/mcp_config_manager.py +1542 -0
  629. claude_mpm/services/mcp_service_verifier.py +732 -0
  630. claude_mpm/services/memory/__init__.py +19 -0
  631. claude_mpm/services/{memory_builder.py → memory/builder.py} +465 -373
  632. claude_mpm/services/memory/cache/__init__.py +14 -0
  633. claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +237 -200
  634. claude_mpm/services/memory/cache/simple_cache.py +331 -0
  635. claude_mpm/services/memory/failure_tracker.py +578 -0
  636. claude_mpm/services/memory/indexed_memory.py +648 -0
  637. claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +272 -243
  638. claude_mpm/services/memory/router.py +951 -0
  639. claude_mpm/services/memory_hook_service.py +470 -0
  640. claude_mpm/services/model/__init__.py +147 -0
  641. claude_mpm/services/model/base_provider.py +365 -0
  642. claude_mpm/services/model/claude_provider.py +412 -0
  643. claude_mpm/services/model/model_router.py +452 -0
  644. claude_mpm/services/model/ollama_provider.py +415 -0
  645. claude_mpm/services/monitor/__init__.py +20 -0
  646. claude_mpm/services/monitor/daemon.py +698 -0
  647. claude_mpm/services/monitor/daemon_manager.py +1076 -0
  648. claude_mpm/services/monitor/event_emitter.py +350 -0
  649. claude_mpm/services/monitor/handlers/__init__.py +21 -0
  650. claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
  651. claude_mpm/services/monitor/handlers/dashboard.py +299 -0
  652. claude_mpm/services/monitor/handlers/file.py +264 -0
  653. claude_mpm/services/monitor/handlers/hooks.py +512 -0
  654. claude_mpm/services/monitor/management/__init__.py +18 -0
  655. claude_mpm/services/monitor/management/health.py +124 -0
  656. claude_mpm/services/monitor/management/lifecycle.py +730 -0
  657. claude_mpm/services/monitor/server.py +1493 -0
  658. claude_mpm/services/monitor_build_service.py +349 -0
  659. claude_mpm/services/native_agent_converter.py +356 -0
  660. claude_mpm/services/orphan_detection.py +786 -0
  661. claude_mpm/services/pm_skills_deployer.py +707 -0
  662. claude_mpm/services/port_manager.py +597 -0
  663. claude_mpm/services/pr/__init__.py +14 -0
  664. claude_mpm/services/pr/pr_template_service.py +329 -0
  665. claude_mpm/services/profile_manager.py +337 -0
  666. claude_mpm/services/project/__init__.py +44 -0
  667. claude_mpm/services/{project_analyzer.py → project/analyzer.py} +541 -291
  668. claude_mpm/services/project/analyzer_v2.py +566 -0
  669. claude_mpm/services/project/architecture_analyzer.py +461 -0
  670. claude_mpm/services/project/archive_manager.py +1045 -0
  671. claude_mpm/services/project/dependency_analyzer.py +462 -0
  672. claude_mpm/services/project/detection_strategies.py +719 -0
  673. claude_mpm/services/project/documentation_manager.py +554 -0
  674. claude_mpm/services/project/enhanced_analyzer.py +572 -0
  675. claude_mpm/services/project/language_analyzer.py +265 -0
  676. claude_mpm/services/project/metrics_collector.py +407 -0
  677. claude_mpm/services/project/project_organizer.py +1009 -0
  678. claude_mpm/services/project/registry.py +636 -0
  679. claude_mpm/services/project/toolchain_analyzer.py +583 -0
  680. claude_mpm/services/project_port_allocator.py +596 -0
  681. claude_mpm/services/recovery_manager.py +293 -240
  682. claude_mpm/services/response_tracker.py +267 -0
  683. claude_mpm/services/runner_configuration_service.py +605 -0
  684. claude_mpm/services/self_upgrade_service.py +608 -0
  685. claude_mpm/services/session_management_service.py +314 -0
  686. claude_mpm/services/session_manager.py +380 -0
  687. claude_mpm/services/shared/__init__.py +21 -0
  688. claude_mpm/services/shared/async_service_base.py +216 -0
  689. claude_mpm/services/shared/config_service_base.py +301 -0
  690. claude_mpm/services/shared/lifecycle_service_base.py +308 -0
  691. claude_mpm/services/shared/manager_base.py +315 -0
  692. claude_mpm/services/shared/service_factory.py +309 -0
  693. claude_mpm/services/skills/__init__.py +21 -0
  694. claude_mpm/services/skills/git_skill_source_manager.py +1324 -0
  695. claude_mpm/services/skills/selective_skill_deployer.py +744 -0
  696. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  697. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  698. claude_mpm/services/skills_config.py +547 -0
  699. claude_mpm/services/skills_deployer.py +1168 -0
  700. claude_mpm/services/socketio/__init__.py +25 -0
  701. claude_mpm/services/socketio/client_proxy.py +229 -0
  702. claude_mpm/services/socketio/dashboard_server.py +362 -0
  703. claude_mpm/services/socketio/event_normalizer.py +798 -0
  704. claude_mpm/services/socketio/handlers/__init__.py +30 -0
  705. claude_mpm/services/socketio/handlers/base.py +136 -0
  706. claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
  707. claude_mpm/services/socketio/handlers/connection.py +643 -0
  708. claude_mpm/services/socketio/handlers/connection_handler.py +333 -0
  709. claude_mpm/services/socketio/handlers/file.py +263 -0
  710. claude_mpm/services/socketio/handlers/git.py +962 -0
  711. claude_mpm/services/socketio/handlers/hook.py +211 -0
  712. claude_mpm/services/socketio/handlers/memory.py +26 -0
  713. claude_mpm/services/socketio/handlers/project.py +24 -0
  714. claude_mpm/services/socketio/handlers/registry.py +214 -0
  715. claude_mpm/services/socketio/migration_utils.py +343 -0
  716. claude_mpm/services/socketio/monitor_client.py +364 -0
  717. claude_mpm/services/socketio/server/__init__.py +18 -0
  718. claude_mpm/services/socketio/server/broadcaster.py +569 -0
  719. claude_mpm/services/socketio/server/connection_manager.py +579 -0
  720. claude_mpm/services/socketio/server/core.py +1079 -0
  721. claude_mpm/services/socketio/server/eventbus_integration.py +245 -0
  722. claude_mpm/services/socketio/server/main.py +501 -0
  723. claude_mpm/services/socketio_client_manager.py +173 -143
  724. claude_mpm/services/socketio_server.py +38 -1657
  725. claude_mpm/services/subprocess_launcher_service.py +322 -0
  726. claude_mpm/services/system_instructions_service.py +270 -0
  727. claude_mpm/services/ticket_manager.py +25 -209
  728. claude_mpm/services/ticket_services/__init__.py +26 -0
  729. claude_mpm/services/ticket_services/crud_service.py +328 -0
  730. claude_mpm/services/ticket_services/formatter_service.py +290 -0
  731. claude_mpm/services/ticket_services/search_service.py +324 -0
  732. claude_mpm/services/ticket_services/validation_service.py +303 -0
  733. claude_mpm/services/ticket_services/workflow_service.py +244 -0
  734. claude_mpm/services/unified/__init__.py +65 -0
  735. claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
  736. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
  737. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
  738. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
  739. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
  740. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
  741. claude_mpm/services/unified/config_strategies/__init__.py +175 -0
  742. claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
  743. claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
  744. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
  745. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
  746. claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
  747. claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
  748. claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
  749. claude_mpm/services/unified/deployment_strategies/base.py +553 -0
  750. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
  751. claude_mpm/services/unified/deployment_strategies/local.py +607 -0
  752. claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
  753. claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
  754. claude_mpm/services/unified/interfaces.py +475 -0
  755. claude_mpm/services/unified/migration.py +509 -0
  756. claude_mpm/services/unified/strategies.py +534 -0
  757. claude_mpm/services/unified/unified_analyzer.py +542 -0
  758. claude_mpm/services/unified/unified_config.py +691 -0
  759. claude_mpm/services/unified/unified_deployment.py +466 -0
  760. claude_mpm/services/utility_service.py +280 -0
  761. claude_mpm/services/version_control/__init__.py +34 -37
  762. claude_mpm/services/version_control/branch_strategy.py +26 -17
  763. claude_mpm/services/version_control/conflict_resolution.py +52 -36
  764. claude_mpm/services/version_control/git_operations.py +183 -49
  765. claude_mpm/services/version_control/semantic_versioning.py +172 -61
  766. claude_mpm/services/version_control/version_parser.py +546 -0
  767. claude_mpm/services/version_service.py +379 -0
  768. claude_mpm/services/visualization/__init__.py +15 -0
  769. claude_mpm/services/visualization/mermaid_generator.py +937 -0
  770. claude_mpm/skills/__init__.py +42 -0
  771. claude_mpm/skills/agent_skills_injector.py +324 -0
  772. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  773. claude_mpm/skills/bundled/__init__.py +6 -0
  774. claude_mpm/skills/bundled/api-documentation.md +393 -0
  775. claude_mpm/skills/bundled/async-testing.md +571 -0
  776. claude_mpm/skills/bundled/code-review.md +143 -0
  777. claude_mpm/skills/bundled/database-migration.md +199 -0
  778. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  779. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  780. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  781. claude_mpm/skills/bundled/git-workflow.md +414 -0
  782. claude_mpm/skills/bundled/imagemagick.md +204 -0
  783. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  784. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  785. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  786. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  787. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  788. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  789. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  790. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  791. claude_mpm/skills/bundled/pdf.md +141 -0
  792. claude_mpm/skills/bundled/performance-profiling.md +573 -0
  793. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  794. claude_mpm/skills/bundled/security-scanning.md +439 -0
  795. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  796. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  797. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  798. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  799. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  800. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  801. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  802. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  803. claude_mpm/skills/bundled/xlsx.md +157 -0
  804. claude_mpm/skills/registry.py +286 -0
  805. claude_mpm/skills/skill_manager.py +405 -0
  806. claude_mpm/skills/skills_registry.py +347 -0
  807. claude_mpm/skills/skills_service.py +739 -0
  808. claude_mpm/storage/__init__.py +9 -0
  809. claude_mpm/storage/state_storage.py +546 -0
  810. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  811. claude_mpm/templates/questions/__init__.py +38 -0
  812. claude_mpm/templates/questions/base.py +193 -0
  813. claude_mpm/templates/questions/pr_strategy.py +311 -0
  814. claude_mpm/templates/questions/project_init.py +385 -0
  815. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  816. claude_mpm/ticket_wrapper.py +2 -2
  817. claude_mpm/tools/__init__.py +10 -0
  818. claude_mpm/tools/__main__.py +208 -0
  819. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  820. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  821. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  822. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  823. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  824. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  825. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  826. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  827. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  828. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  829. claude_mpm/tools/code_tree_builder.py +631 -0
  830. claude_mpm/tools/code_tree_events.py +420 -0
  831. claude_mpm/tools/socketio_debug.py +671 -0
  832. claude_mpm/utils/__init__.py +8 -8
  833. claude_mpm/utils/agent_dependency_loader.py +1090 -0
  834. claude_mpm/utils/agent_filters.py +261 -0
  835. claude_mpm/utils/common.py +544 -0
  836. claude_mpm/utils/config_manager.py +168 -126
  837. claude_mpm/utils/console.py +11 -0
  838. claude_mpm/utils/database_connector.py +298 -0
  839. claude_mpm/utils/dependency_cache.py +373 -0
  840. claude_mpm/utils/dependency_manager.py +60 -59
  841. claude_mpm/utils/dependency_strategies.py +381 -0
  842. claude_mpm/utils/display_helper.py +260 -0
  843. claude_mpm/utils/environment_context.py +313 -0
  844. claude_mpm/utils/error_handler.py +78 -66
  845. claude_mpm/utils/file_utils.py +305 -0
  846. claude_mpm/utils/framework_detection.py +12 -11
  847. claude_mpm/utils/git_analyzer.py +407 -0
  848. claude_mpm/utils/gitignore.py +244 -0
  849. claude_mpm/utils/import_migration_example.py +12 -60
  850. claude_mpm/utils/imports.py +48 -45
  851. claude_mpm/utils/log_cleanup.py +627 -0
  852. claude_mpm/utils/migration.py +372 -0
  853. claude_mpm/utils/path_operations.py +110 -104
  854. claude_mpm/utils/progress.py +387 -0
  855. claude_mpm/utils/robust_installer.py +823 -0
  856. claude_mpm/utils/session_logging.py +121 -0
  857. claude_mpm/utils/structured_questions.py +619 -0
  858. claude_mpm/utils/subprocess_utils.py +343 -0
  859. claude_mpm/validation/__init__.py +1 -1
  860. claude_mpm/validation/agent_validator.py +214 -108
  861. claude_mpm/validation/frontmatter_validator.py +252 -0
  862. claude_mpm-5.4.55.dist-info/METADATA +999 -0
  863. claude_mpm-5.4.55.dist-info/RECORD +868 -0
  864. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/entry_points.txt +1 -3
  865. claude_mpm-5.4.55.dist-info/licenses/LICENSE +94 -0
  866. claude_mpm-5.4.55.dist-info/licenses/LICENSE-FAQ.md +153 -0
  867. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -88
  868. claude_mpm/agents/INSTRUCTIONS.md +0 -352
  869. claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
  870. claude_mpm/agents/base_agent_loader.py +0 -529
  871. claude_mpm/agents/schema/agent_schema.json +0 -314
  872. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
  873. claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -46
  874. claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -45
  875. claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -49
  876. claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -46
  877. claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -45
  878. claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -49
  879. claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -46
  880. claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -46
  881. claude_mpm/agents/templates/data_engineer.json +0 -110
  882. claude_mpm/agents/templates/documentation.json +0 -109
  883. claude_mpm/agents/templates/engineer.json +0 -113
  884. claude_mpm/agents/templates/ops.json +0 -109
  885. claude_mpm/agents/templates/pm.json +0 -25
  886. claude_mpm/agents/templates/qa.json +0 -111
  887. claude_mpm/agents/templates/research.json +0 -65
  888. claude_mpm/agents/templates/security.json +0 -113
  889. claude_mpm/agents/templates/test_integration.json +0 -112
  890. claude_mpm/agents/templates/version_control.json +0 -107
  891. claude_mpm/cli/commands/ui.py +0 -57
  892. claude_mpm/core/simple_runner.py +0 -1046
  893. claude_mpm/dashboard/open_dashboard.py +0 -34
  894. claude_mpm/deployment_paths.py +0 -261
  895. claude_mpm/hooks/builtin/__init__.py +0 -1
  896. claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
  897. claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
  898. claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
  899. claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
  900. claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
  901. claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
  902. claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
  903. claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
  904. claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
  905. claude_mpm/orchestration/__init__.py +0 -6
  906. claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
  907. claude_mpm/orchestration/archive/factory.py +0 -215
  908. claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
  909. claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
  910. claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
  911. claude_mpm/orchestration/archive/orchestrator.py +0 -501
  912. claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
  913. claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
  914. claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
  915. claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
  916. claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
  917. claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
  918. claude_mpm/schemas/workflow_validator.py +0 -411
  919. claude_mpm/services/agent_deployment.py +0 -1534
  920. claude_mpm/services/agent_lifecycle_manager.py +0 -1169
  921. claude_mpm/services/agent_memory_manager.py +0 -1415
  922. claude_mpm/services/agent_registry.py +0 -676
  923. claude_mpm/services/deployed_agent_discovery.py +0 -226
  924. claude_mpm/services/framework_agent_loader.py +0 -337
  925. claude_mpm/services/framework_claude_md_generator.py +0 -621
  926. claude_mpm/services/health_monitor.py +0 -892
  927. claude_mpm/services/memory_router.py +0 -538
  928. claude_mpm/services/parent_directory_manager/__init__.py +0 -577
  929. claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
  930. claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
  931. claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
  932. claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
  933. claude_mpm/services/parent_directory_manager/operations.py +0 -186
  934. claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
  935. claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
  936. claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
  937. claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
  938. claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
  939. claude_mpm/services/standalone_socketio_server.py +0 -1300
  940. claude_mpm/services/ticket_manager_di.py +0 -318
  941. claude_mpm/services/ticketing_service_original.py +0 -508
  942. claude_mpm/ui/__init__.py +0 -1
  943. claude_mpm/ui/rich_terminal_ui.py +0 -295
  944. claude_mpm/ui/terminal_ui.py +0 -328
  945. claude_mpm/utils/paths.py +0 -289
  946. claude_mpm-3.4.10.dist-info/METADATA +0 -183
  947. claude_mpm-3.4.10.dist-info/RECORD +0 -201
  948. claude_mpm-3.4.10.dist-info/licenses/LICENSE +0 -21
  949. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/WHEEL +0 -0
  950. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/top_level.txt +0 -0
@@ -1,1534 +0,0 @@
1
- """Agent deployment service for Claude Code native subagents.
2
-
3
- This service handles the complete lifecycle of agent deployment:
4
- 1. Building agent YAML files from JSON templates
5
- 2. Managing versioning and updates
6
- 3. Deploying to Claude Code's .claude/agents directory
7
- 4. Environment configuration for agent discovery
8
- 5. Deployment verification and cleanup
9
-
10
- OPERATIONAL CONSIDERATIONS:
11
- - Deployment is idempotent - safe to run multiple times
12
- - Version checking prevents unnecessary rebuilds (saves I/O)
13
- - Supports force rebuild for troubleshooting
14
- - Maintains backward compatibility with legacy versions
15
- - Handles migration from old serial versioning to semantic versioning
16
-
17
- MONITORING:
18
- - Check logs for deployment status and errors
19
- - Monitor disk space in .claude/agents directory
20
- - Track version migration progress
21
- - Verify agent discovery after deployment
22
-
23
- ROLLBACK PROCEDURES:
24
- - Keep backups of .claude/agents before major updates
25
- - Use clean_deployment() to remove system agents
26
- - User-created agents are preserved during cleanup
27
- - Version tracking allows targeted rollbacks
28
- """
29
-
30
- import os
31
- import shutil
32
- import logging
33
- import time
34
- from pathlib import Path
35
- from typing import Optional, List, Dict, Any
36
-
37
- from claude_mpm.core.logger import get_logger
38
- from claude_mpm.constants import EnvironmentVars, Paths, AgentMetadata
39
-
40
-
41
- class AgentDeploymentService:
42
- """Service for deploying Claude Code native agents.
43
-
44
- METRICS COLLECTION OPPORTUNITIES:
45
- This service could collect valuable deployment metrics including:
46
- - Agent deployment frequency and success rates
47
- - Template validation performance
48
- - Version migration patterns
49
- - Deployment duration by agent type
50
- - Cache hit rates for agent templates
51
- - Resource usage during deployment (memory, CPU)
52
- - Agent file sizes and complexity metrics
53
- - Deployment failure reasons and patterns
54
-
55
- DEPLOYMENT PIPELINE:
56
- 1. Initialize with template and base agent paths
57
- 2. Load base agent configuration (shared settings)
58
- 3. Iterate through agent templates
59
- 4. Check version and update requirements
60
- 5. Build YAML files with proper formatting
61
- 6. Deploy to target directory
62
- 7. Set environment variables for discovery
63
- 8. Verify deployment success
64
-
65
- ENVIRONMENT REQUIREMENTS:
66
- - Write access to .claude/agents directory
67
- - Python 3.8+ for pathlib and typing features
68
- - JSON parsing for template files
69
- - YAML generation capabilities
70
- """
71
-
72
- def __init__(self, templates_dir: Optional[Path] = None, base_agent_path: Optional[Path] = None):
73
- """
74
- Initialize agent deployment service.
75
-
76
- Args:
77
- templates_dir: Directory containing agent template files
78
- base_agent_path: Path to base_agent.md file
79
-
80
- METRICS OPPORTUNITY: Track initialization performance:
81
- - Template directory scan time
82
- - Base agent loading time
83
- - Initial validation overhead
84
- """
85
- self.logger = get_logger(self.__class__.__name__)
86
-
87
- # METRICS: Initialize deployment metrics tracking
88
- # This data structure would be used for collecting deployment telemetry
89
- self._deployment_metrics = {
90
- 'total_deployments': 0,
91
- 'successful_deployments': 0,
92
- 'failed_deployments': 0,
93
- 'migrations_performed': 0,
94
- 'average_deployment_time_ms': 0.0,
95
- 'deployment_times': [], # Keep last 100 for rolling average
96
- 'agent_type_counts': {}, # Track deployments by agent type
97
- 'version_migration_count': 0,
98
- 'template_validation_times': {}, # Track validation performance
99
- 'deployment_errors': {} # Track error types and frequencies
100
- }
101
-
102
- # Find templates directory
103
- module_path = Path(__file__).parent.parent
104
- if templates_dir:
105
- self.templates_dir = Path(templates_dir)
106
- else:
107
- # Default to src/claude_mpm/agents/templates/
108
- self.templates_dir = module_path / "agents" / "templates"
109
-
110
- # Find base agent file
111
- if base_agent_path:
112
- self.base_agent_path = Path(base_agent_path)
113
- else:
114
- # Default to src/claude_mpm/agents/base_agent.json
115
- self.base_agent_path = module_path / "agents" / "base_agent.json"
116
-
117
- self.logger.info(f"Templates directory: {self.templates_dir}")
118
- self.logger.info(f"Base agent path: {self.base_agent_path}")
119
-
120
- def deploy_agents(self, target_dir: Optional[Path] = None, force_rebuild: bool = False) -> Dict[str, Any]:
121
- """
122
- Build and deploy agents by combining base_agent.md with templates.
123
- Also deploys system instructions for PM framework.
124
-
125
- METRICS COLLECTED:
126
- - Deployment start/end timestamps
127
- - Individual agent deployment durations
128
- - Success/failure rates by agent type
129
- - Version migration statistics
130
- - Template validation performance
131
- - Error type frequencies
132
-
133
- OPERATIONAL FLOW:
134
- 1. Validates target directory (creates if needed)
135
- 2. Loads base agent configuration
136
- 3. Discovers all agent templates
137
- 4. For each agent:
138
- - Checks if update needed (version comparison)
139
- - Builds YAML configuration
140
- - Writes to target directory
141
- - Tracks deployment status
142
-
143
- PERFORMANCE CONSIDERATIONS:
144
- - Skips unchanged agents (version-based caching)
145
- - Batch processes all agents in single pass
146
- - Minimal file I/O with in-memory building
147
- - Parallel-safe (no shared state mutations)
148
-
149
- ERROR HANDLING:
150
- - Continues deployment on individual agent failures
151
- - Collects all errors for reporting
152
- - Logs detailed error context
153
- - Returns comprehensive results dict
154
-
155
- MONITORING POINTS:
156
- - Track total deployment time
157
- - Monitor skipped vs updated vs new agents
158
- - Check error rates and patterns
159
- - Verify migration completion
160
-
161
- Args:
162
- target_dir: Target directory for agents (default: .claude/agents/)
163
- force_rebuild: Force rebuild even if agents exist (useful for troubleshooting)
164
-
165
- Returns:
166
- Dictionary with deployment results:
167
- - target_dir: Deployment location
168
- - deployed: List of newly deployed agents
169
- - updated: List of updated agents
170
- - migrated: List of agents migrated to new version format
171
- - skipped: List of unchanged agents
172
- - errors: List of deployment errors
173
- - total: Total number of agents processed
174
- """
175
- # METRICS: Record deployment start time for performance tracking
176
- deployment_start_time = time.time()
177
-
178
- if not target_dir:
179
- target_dir = Path(Paths.CLAUDE_AGENTS_DIR.value).expanduser()
180
-
181
- target_dir = Path(target_dir)
182
- results = {
183
- "target_dir": str(target_dir),
184
- "deployed": [],
185
- "errors": [],
186
- "skipped": [],
187
- "updated": [],
188
- "migrated": [], # Track agents migrated from old format
189
- "total": 0,
190
- # METRICS: Add detailed timing and performance data to results
191
- "metrics": {
192
- "start_time": deployment_start_time,
193
- "end_time": None,
194
- "duration_ms": None,
195
- "agent_timings": {}, # Track individual agent deployment times
196
- "validation_times": {}, # Track template validation times
197
- "resource_usage": {} # Could track memory/CPU if needed
198
- }
199
- }
200
-
201
- try:
202
- # Create target directory if needed
203
- target_dir.mkdir(parents=True, exist_ok=True)
204
- self.logger.info(f"Building and deploying agents to: {target_dir}")
205
-
206
- # Note: System instructions are now loaded directly by SimpleClaudeRunner
207
-
208
- # Check if templates directory exists
209
- if not self.templates_dir.exists():
210
- error_msg = f"Templates directory not found: {self.templates_dir}"
211
- self.logger.error(error_msg)
212
- results["errors"].append(error_msg)
213
- return results
214
-
215
- # Load base agent content
216
- # OPERATIONAL NOTE: Base agent contains shared configuration and instructions
217
- # that all agents inherit. This reduces duplication and ensures consistency.
218
- # If base agent fails to load, deployment continues with agent-specific configs only.
219
- base_agent_data = {}
220
- base_agent_version = 0
221
- if self.base_agent_path.exists():
222
- try:
223
- import json
224
- base_agent_data = json.loads(self.base_agent_path.read_text())
225
- # Handle both 'base_version' (new format) and 'version' (old format)
226
- # MIGRATION PATH: Supporting both formats during transition period
227
- base_agent_version = self._parse_version(base_agent_data.get('base_version') or base_agent_data.get('version', 0))
228
- self.logger.info(f"Loaded base agent template (version {self._format_version_display(base_agent_version)})")
229
- except Exception as e:
230
- # NON-FATAL: Base agent is optional enhancement, not required
231
- self.logger.warning(f"Could not load base agent: {e}")
232
-
233
- # Get all template files
234
- template_files = list(self.templates_dir.glob("*.json"))
235
- # Filter out non-agent files
236
- template_files = [f for f in template_files if f.stem != "__init__" and not f.stem.startswith(".")]
237
- results["total"] = len(template_files)
238
-
239
- for template_file in template_files:
240
- try:
241
- # METRICS: Track individual agent deployment time
242
- agent_start_time = time.time()
243
-
244
- agent_name = template_file.stem
245
- target_file = target_dir / f"{agent_name}.yaml"
246
-
247
- # Check if agent needs update
248
- needs_update = force_rebuild
249
- is_migration = False
250
- if not needs_update and target_file.exists():
251
- needs_update, reason = self._check_agent_needs_update(
252
- target_file, template_file, base_agent_version
253
- )
254
- if needs_update:
255
- # Check if this is a migration from old format
256
- if "migration needed" in reason:
257
- is_migration = True
258
- self.logger.info(f"Migrating agent {agent_name}: {reason}")
259
- else:
260
- self.logger.info(f"Agent {agent_name} needs update: {reason}")
261
-
262
- # Skip if exists and doesn't need update
263
- if target_file.exists() and not needs_update:
264
- results["skipped"].append(agent_name)
265
- self.logger.debug(f"Skipped up-to-date agent: {agent_name}")
266
- continue
267
-
268
- # Build the agent file
269
- agent_yaml = self._build_agent_yaml(agent_name, template_file, base_agent_data)
270
-
271
- # Write the agent file
272
- is_update = target_file.exists()
273
- target_file.write_text(agent_yaml)
274
-
275
- # METRICS: Record deployment time for this agent
276
- agent_deployment_time = (time.time() - agent_start_time) * 1000 # Convert to ms
277
- results["metrics"]["agent_timings"][agent_name] = agent_deployment_time
278
-
279
- # METRICS: Update agent type deployment counts
280
- self._deployment_metrics['agent_type_counts'][agent_name] = \
281
- self._deployment_metrics['agent_type_counts'].get(agent_name, 0) + 1
282
-
283
- if is_migration:
284
- results["migrated"].append({
285
- "name": agent_name,
286
- "template": str(template_file),
287
- "target": str(target_file),
288
- "reason": reason,
289
- "deployment_time_ms": agent_deployment_time # METRICS: Include timing
290
- })
291
- self.logger.info(f"Successfully migrated agent: {agent_name} to semantic versioning")
292
-
293
- # METRICS: Track migration statistics
294
- self._deployment_metrics['migrations_performed'] += 1
295
- self._deployment_metrics['version_migration_count'] += 1
296
-
297
- elif is_update:
298
- results["updated"].append({
299
- "name": agent_name,
300
- "template": str(template_file),
301
- "target": str(target_file),
302
- "deployment_time_ms": agent_deployment_time # METRICS: Include timing
303
- })
304
- self.logger.debug(f"Updated agent: {agent_name}")
305
- else:
306
- results["deployed"].append({
307
- "name": agent_name,
308
- "template": str(template_file),
309
- "target": str(target_file),
310
- "deployment_time_ms": agent_deployment_time # METRICS: Include timing
311
- })
312
- self.logger.debug(f"Built and deployed agent: {agent_name}")
313
-
314
- except Exception as e:
315
- error_msg = f"Failed to build {template_file.name}: {e}"
316
- self.logger.error(error_msg)
317
- results["errors"].append(error_msg)
318
-
319
- self.logger.info(
320
- f"Deployed {len(results['deployed'])} agents, "
321
- f"updated {len(results['updated'])}, "
322
- f"migrated {len(results['migrated'])}, "
323
- f"skipped {len(results['skipped'])}, "
324
- f"errors: {len(results['errors'])}"
325
- )
326
-
327
- except Exception as e:
328
- error_msg = f"Agent deployment failed: {e}"
329
- self.logger.error(error_msg)
330
- results["errors"].append(error_msg)
331
-
332
- # METRICS: Track deployment failure
333
- self._deployment_metrics['failed_deployments'] += 1
334
- error_type = type(e).__name__
335
- self._deployment_metrics['deployment_errors'][error_type] = \
336
- self._deployment_metrics['deployment_errors'].get(error_type, 0) + 1
337
-
338
- # METRICS: Calculate final deployment metrics
339
- deployment_end_time = time.time()
340
- deployment_duration = (deployment_end_time - deployment_start_time) * 1000 # ms
341
-
342
- results["metrics"]["end_time"] = deployment_end_time
343
- results["metrics"]["duration_ms"] = deployment_duration
344
-
345
- # METRICS: Update rolling averages and statistics
346
- self._update_deployment_metrics(deployment_duration, results)
347
-
348
- return results
349
-
350
- def _update_deployment_metrics(self, duration_ms: float, results: Dict[str, Any]) -> None:
351
- """
352
- Update internal deployment metrics.
353
-
354
- METRICS TRACKING:
355
- - Rolling average of deployment times (last 100)
356
- - Success/failure rates
357
- - Agent type distribution
358
- - Version migration patterns
359
- - Error frequency analysis
360
-
361
- This method demonstrates ETL-like processing:
362
- 1. Extract: Gather raw metrics from deployment results
363
- 2. Transform: Calculate averages, rates, and distributions
364
- 3. Load: Store in internal metrics structure for reporting
365
- """
366
- # Update total deployment count
367
- self._deployment_metrics['total_deployments'] += 1
368
-
369
- # Track success/failure
370
- if not results.get('errors'):
371
- self._deployment_metrics['successful_deployments'] += 1
372
- else:
373
- self._deployment_metrics['failed_deployments'] += 1
374
-
375
- # Update rolling average deployment time
376
- self._deployment_metrics['deployment_times'].append(duration_ms)
377
- if len(self._deployment_metrics['deployment_times']) > 100:
378
- # Keep only last 100 for memory efficiency
379
- self._deployment_metrics['deployment_times'] = \
380
- self._deployment_metrics['deployment_times'][-100:]
381
-
382
- # Calculate new average
383
- if self._deployment_metrics['deployment_times']:
384
- self._deployment_metrics['average_deployment_time_ms'] = \
385
- sum(self._deployment_metrics['deployment_times']) / \
386
- len(self._deployment_metrics['deployment_times'])
387
-
388
- def get_deployment_metrics(self) -> Dict[str, Any]:
389
- """
390
- Get current deployment metrics.
391
-
392
- Returns:
393
- Dictionary containing:
394
- - Total deployments and success rates
395
- - Average deployment time
396
- - Agent type distribution
397
- - Migration statistics
398
- - Error analysis
399
-
400
- This demonstrates a metrics API endpoint that could be:
401
- - Exposed via REST API for monitoring tools
402
- - Pushed to time-series databases (Prometheus, InfluxDB)
403
- - Used for dashboards and alerting
404
- - Integrated with AI observability platforms
405
- """
406
- success_rate = 0.0
407
- if self._deployment_metrics['total_deployments'] > 0:
408
- success_rate = (self._deployment_metrics['successful_deployments'] /
409
- self._deployment_metrics['total_deployments']) * 100
410
-
411
- return {
412
- 'total_deployments': self._deployment_metrics['total_deployments'],
413
- 'successful_deployments': self._deployment_metrics['successful_deployments'],
414
- 'failed_deployments': self._deployment_metrics['failed_deployments'],
415
- 'success_rate_percent': success_rate,
416
- 'average_deployment_time_ms': self._deployment_metrics['average_deployment_time_ms'],
417
- 'migrations_performed': self._deployment_metrics['migrations_performed'],
418
- 'agent_type_distribution': self._deployment_metrics['agent_type_counts'].copy(),
419
- 'version_migrations': self._deployment_metrics['version_migration_count'],
420
- 'error_distribution': self._deployment_metrics['deployment_errors'].copy(),
421
- 'recent_deployment_times': self._deployment_metrics['deployment_times'][-10:] # Last 10
422
- }
423
-
424
- def reset_metrics(self) -> None:
425
- """
426
- Reset deployment metrics.
427
-
428
- Useful for:
429
- - Starting fresh metrics collection periods
430
- - Testing and development
431
- - Scheduled metric rotation (e.g., daily reset)
432
- """
433
- self._deployment_metrics = {
434
- 'total_deployments': 0,
435
- 'successful_deployments': 0,
436
- 'failed_deployments': 0,
437
- 'migrations_performed': 0,
438
- 'average_deployment_time_ms': 0.0,
439
- 'deployment_times': [],
440
- 'agent_type_counts': {},
441
- 'version_migration_count': 0,
442
- 'template_validation_times': {},
443
- 'deployment_errors': {}
444
- }
445
- self.logger.info("Deployment metrics reset")
446
-
447
- def _extract_version(self, content: str, version_marker: str) -> int:
448
- """
449
- Extract version number from content.
450
-
451
- Args:
452
- content: File content
453
- version_marker: Version marker to look for (e.g., "AGENT_VERSION:" or "BASE_AGENT_VERSION:")
454
-
455
- Returns:
456
- Version number or 0 if not found
457
- """
458
- import re
459
- pattern = rf"<!-- {version_marker} (\d+) -->"
460
- match = re.search(pattern, content)
461
- if match:
462
- return int(match.group(1))
463
- return 0
464
-
465
- def _build_agent_markdown(self, agent_name: str, template_path: Path, base_agent_data: dict) -> str:
466
- """
467
- Build a complete agent markdown file with YAML frontmatter.
468
-
469
- Args:
470
- agent_name: Name of the agent
471
- template_path: Path to the agent template JSON file
472
- base_agent_data: Base agent data from JSON
473
-
474
- Returns:
475
- Complete agent markdown content with YAML frontmatter
476
- """
477
- import json
478
- from datetime import datetime
479
-
480
- # Read template JSON
481
- template_data = json.loads(template_path.read_text())
482
-
483
- # Extract basic info
484
- # Handle both 'agent_version' (new format) and 'version' (old format)
485
- agent_version = self._parse_version(template_data.get('agent_version') or template_data.get('version', 0))
486
- base_version = self._parse_version(base_agent_data.get('base_version') or base_agent_data.get('version', 0))
487
-
488
- # Format version string as semantic version
489
- # Combine base and agent versions for a unified semantic version
490
- # Use agent version as primary, with base version in metadata
491
- version_string = self._format_version_display(agent_version)
492
-
493
- # Build YAML frontmatter
494
- # Check new format first (metadata.description), then old format
495
- description = (
496
- template_data.get('metadata', {}).get('description') or
497
- template_data.get('configuration_fields', {}).get('description') or
498
- template_data.get('description') or
499
- 'Agent for specialized tasks'
500
- )
501
-
502
- # Get tags from new format (metadata.tags) or old format
503
- tags = (
504
- template_data.get('metadata', {}).get('tags') or
505
- template_data.get('configuration_fields', {}).get('tags') or
506
- template_data.get('tags') or
507
- [agent_name, 'mpm-framework']
508
- )
509
-
510
- # Get tools from capabilities.tools in new format
511
- tools = (
512
- template_data.get('capabilities', {}).get('tools') or
513
- template_data.get('configuration_fields', {}).get('tools') or
514
- ["Read", "Write", "Edit", "Grep", "Glob", "LS"] # Default fallback
515
- )
516
-
517
- frontmatter = f"""---
518
- name: {agent_name}
519
- description: "{description}"
520
- version: "{version_string}"
521
- author: "{template_data.get('author', 'claude-mpm@anthropic.com')}"
522
- created: "{datetime.now().isoformat()}Z"
523
- updated: "{datetime.now().isoformat()}Z"
524
- tags: {tags}
525
- tools: {tools}
526
- metadata:
527
- base_version: "{self._format_version_display(base_version)}"
528
- agent_version: "{self._format_version_display(agent_version)}"
529
- deployment_type: "system"
530
- ---
531
-
532
- """
533
-
534
- # Get the main content (instructions)
535
- # Check multiple possible locations for instructions
536
- content = (
537
- template_data.get('instructions') or
538
- template_data.get('narrative_fields', {}).get('instructions') or
539
- template_data.get('content') or
540
- f"You are the {agent_name} agent. Perform tasks related to {template_data.get('description', 'your specialization')}."
541
- )
542
-
543
- return frontmatter + content
544
-
545
- def _build_agent_yaml(self, agent_name: str, template_path: Path, base_agent_data: dict) -> str:
546
- """
547
- Build a complete agent YAML file by combining base agent and template.
548
- Only includes essential fields for Claude Code best practices.
549
-
550
- Args:
551
- agent_name: Name of the agent
552
- template_path: Path to the agent template JSON file
553
- base_agent_data: Base agent data from JSON
554
-
555
- Returns:
556
- Complete agent YAML content
557
- """
558
- import json
559
-
560
- # Read template JSON
561
- template_data = json.loads(template_path.read_text())
562
-
563
- # Extract capabilities
564
- capabilities = template_data.get('capabilities', {})
565
- metadata = template_data.get('metadata', {})
566
-
567
- # Extract version information
568
- agent_version = self._parse_version(template_data.get('agent_version') or template_data.get('version', 0))
569
- version_string = self._format_version_display(agent_version)
570
-
571
- # Get tools list
572
- tools = capabilities.get('tools', [])
573
- tools_str = ', '.join(tools) if tools else 'Read, Write, Edit, Grep, Glob, LS'
574
-
575
- # Get description
576
- description = (
577
- metadata.get('description') or
578
- template_data.get('description') or
579
- f'{agent_name.title()} agent for specialized tasks'
580
- )
581
-
582
- # Get priority based on agent type
583
- priority_map = {
584
- 'security': 'high',
585
- 'qa': 'high',
586
- 'engineer': 'high',
587
- 'documentation': 'medium',
588
- 'research': 'medium',
589
- 'ops': 'high',
590
- 'data_engineer': 'medium',
591
- 'version_control': 'high'
592
- }
593
- priority = priority_map.get(agent_name, 'medium')
594
-
595
- # Get model
596
- model = capabilities.get('model', 'claude-3-5-sonnet-20241022')
597
-
598
- # Get temperature
599
- temperature = capabilities.get('temperature', 0.3)
600
-
601
- # Build clean YAML frontmatter with only essential fields
602
- yaml_content = f"""---
603
- name: {agent_name}
604
- description: "{description}"
605
- version: "{version_string}"
606
- tools: {tools_str}
607
- priority: {priority}
608
- model: {model}
609
- temperature: {temperature}"""
610
-
611
- # Add allowed_tools if present
612
- if 'allowed_tools' in capabilities:
613
- yaml_content += f"\nallowed_tools: {json.dumps(capabilities['allowed_tools'])}"
614
-
615
- # Add disallowed_tools if present
616
- if 'disallowed_tools' in capabilities:
617
- yaml_content += f"\ndisallowed_tools: {json.dumps(capabilities['disallowed_tools'])}"
618
-
619
- yaml_content += "\n---\n"
620
-
621
- # Get instructions from template
622
- instructions = (
623
- template_data.get('instructions') or
624
- base_agent_data.get('narrative_fields', {}).get('instructions', '')
625
- )
626
-
627
- # Add base instructions if not already included
628
- base_instructions = base_agent_data.get('narrative_fields', {}).get('instructions', '')
629
- if base_instructions and base_instructions not in instructions:
630
- yaml_content += base_instructions + "\n\n---\n\n"
631
-
632
- yaml_content += instructions
633
-
634
- return yaml_content
635
-
636
- def _merge_narrative_fields(self, base_data: dict, template_data: dict) -> dict:
637
- """
638
- Merge narrative fields from base and template, combining arrays.
639
-
640
- Args:
641
- base_data: Base agent data
642
- template_data: Agent template data
643
-
644
- Returns:
645
- Merged narrative fields
646
- """
647
- base_narrative = base_data.get('narrative_fields', {})
648
- template_narrative = template_data.get('narrative_fields', {})
649
-
650
- merged = {}
651
-
652
- # For narrative fields, combine base + template
653
- for field in ['when_to_use', 'specialized_knowledge', 'unique_capabilities']:
654
- base_items = base_narrative.get(field, [])
655
- template_items = template_narrative.get(field, [])
656
- merged[field] = base_items + template_items
657
-
658
- # For instructions, combine with separator
659
- base_instructions = base_narrative.get('instructions', '')
660
- template_instructions = template_narrative.get('instructions', '')
661
-
662
- if base_instructions and template_instructions:
663
- merged['instructions'] = base_instructions + "\n\n---\n\n" + template_instructions
664
- elif template_instructions:
665
- merged['instructions'] = template_instructions
666
- elif base_instructions:
667
- merged['instructions'] = base_instructions
668
- else:
669
- merged['instructions'] = ''
670
-
671
- return merged
672
-
673
- def _merge_configuration_fields(self, base_data: dict, template_data: dict) -> dict:
674
- """
675
- Merge configuration fields, with template overriding base.
676
-
677
- Args:
678
- base_data: Base agent data
679
- template_data: Agent template data
680
-
681
- Returns:
682
- Merged configuration fields
683
- """
684
- base_config = base_data.get('configuration_fields', {})
685
- template_config = template_data.get('configuration_fields', {})
686
-
687
- # Start with base configuration
688
- merged = base_config.copy()
689
-
690
- # Override with template-specific configuration
691
- merged.update(template_config)
692
-
693
- # Also merge in capabilities from new format if not already in config
694
- capabilities = template_data.get('capabilities', {})
695
- if capabilities:
696
- # Map capabilities fields to configuration fields
697
- if 'tools' not in merged and 'tools' in capabilities:
698
- merged['tools'] = capabilities['tools']
699
- if 'max_tokens' not in merged and 'max_tokens' in capabilities:
700
- merged['max_tokens'] = capabilities['max_tokens']
701
- if 'temperature' not in merged and 'temperature' in capabilities:
702
- merged['temperature'] = capabilities['temperature']
703
- if 'timeout' not in merged and 'timeout' in capabilities:
704
- merged['timeout'] = capabilities['timeout']
705
- if 'memory_limit' not in merged and 'memory_limit' in capabilities:
706
- merged['memory_limit'] = capabilities['memory_limit']
707
- if 'cpu_limit' not in merged and 'cpu_limit' in capabilities:
708
- merged['cpu_limit'] = capabilities['cpu_limit']
709
- if 'network_access' not in merged and 'network_access' in capabilities:
710
- merged['network_access'] = capabilities['network_access']
711
- if 'model' not in merged and 'model' in capabilities:
712
- merged['model'] = capabilities['model']
713
-
714
- # Also check metadata for description and tags in new format
715
- metadata = template_data.get('metadata', {})
716
- if metadata:
717
- if 'description' not in merged and 'description' in metadata:
718
- merged['description'] = metadata['description']
719
- if 'tags' not in merged and 'tags' in metadata:
720
- merged['tags'] = metadata['tags']
721
-
722
- return merged
723
-
724
- def set_claude_environment(self, config_dir: Optional[Path] = None) -> Dict[str, str]:
725
- """
726
- Set Claude environment variables for agent discovery.
727
-
728
- OPERATIONAL PURPOSE:
729
- Claude Code discovers agents through environment variables that
730
- point to configuration directories. This method ensures proper
731
- environment setup for agent runtime discovery.
732
-
733
- ENVIRONMENT VARIABLES SET:
734
- 1. CLAUDE_CONFIG_DIR: Root configuration directory path
735
- 2. CLAUDE_MAX_PARALLEL_SUBAGENTS: Concurrency limit (default: 5)
736
- 3. CLAUDE_TIMEOUT: Agent execution timeout (default: 600s)
737
-
738
- DEPLOYMENT CONSIDERATIONS:
739
- - Call after agent deployment for immediate availability
740
- - Environment changes affect current process and children
741
- - Does not persist across system restarts
742
- - Add to shell profile for permanent configuration
743
-
744
- TROUBLESHOOTING:
745
- - Verify with: echo $CLAUDE_CONFIG_DIR
746
- - Check agent discovery: ls $CLAUDE_CONFIG_DIR/agents/
747
- - Monitor timeout issues in production
748
- - Adjust parallel limits based on system resources
749
-
750
- PERFORMANCE TUNING:
751
- - Increase parallel agents for CPU-bound tasks
752
- - Reduce for memory-constrained environments
753
- - Balance timeout with longest expected operations
754
- - Monitor resource usage during parallel execution
755
-
756
- Args:
757
- config_dir: Claude configuration directory (default: .claude/)
758
-
759
- Returns:
760
- Dictionary of environment variables set for verification
761
- """
762
- if not config_dir:
763
- config_dir = Path.cwd() / Paths.CLAUDE_CONFIG_DIR.value
764
-
765
- env_vars = {}
766
-
767
- # Set Claude configuration directory
768
- env_vars[EnvironmentVars.CLAUDE_CONFIG_DIR.value] = str(config_dir.absolute())
769
-
770
- # Set parallel agent limits
771
- env_vars[EnvironmentVars.CLAUDE_MAX_PARALLEL_SUBAGENTS.value] = EnvironmentVars.DEFAULT_MAX_AGENTS.value
772
-
773
- # Set timeout for agent execution
774
- env_vars[EnvironmentVars.CLAUDE_TIMEOUT.value] = EnvironmentVars.DEFAULT_TIMEOUT.value
775
-
776
- # Apply environment variables
777
- for key, value in env_vars.items():
778
- os.environ[key] = value
779
- self.logger.debug(f"Set environment: {key}={value}")
780
-
781
- return env_vars
782
-
783
- def verify_deployment(self, config_dir: Optional[Path] = None) -> Dict[str, Any]:
784
- """
785
- Verify agent deployment and Claude configuration.
786
-
787
- OPERATIONAL PURPOSE:
788
- Post-deployment verification ensures agents are correctly deployed
789
- and discoverable by Claude Code. Critical for deployment validation
790
- and troubleshooting runtime issues.
791
-
792
- VERIFICATION CHECKS:
793
- 1. Configuration directory exists and is accessible
794
- 2. Agents directory contains expected YAML files
795
- 3. Agent files have valid YAML frontmatter
796
- 4. Version format is current (identifies migration needs)
797
- 5. Environment variables are properly set
798
-
799
- MONITORING INTEGRATION:
800
- - Call after deployment for health checks
801
- - Include in deployment pipelines
802
- - Log results for audit trails
803
- - Alert on missing agents or errors
804
-
805
- TROUBLESHOOTING GUIDE:
806
- - Missing config_dir: Check deployment target path
807
- - No agents found: Verify deployment completed
808
- - Migration needed: Run with force_rebuild
809
- - Environment warnings: Call set_claude_environment()
810
-
811
- RESULT INTERPRETATION:
812
- - agents_found: Successfully deployed agents
813
- - agents_needing_migration: Require version update
814
- - warnings: Non-critical issues to address
815
- - environment: Current runtime configuration
816
-
817
- Args:
818
- config_dir: Claude configuration directory (default: .claude/)
819
-
820
- Returns:
821
- Verification results dictionary:
822
- - config_dir: Checked directory path
823
- - agents_found: List of discovered agents with metadata
824
- - agents_needing_migration: Agents with old version format
825
- - environment: Current environment variables
826
- - warnings: List of potential issues
827
- """
828
- if not config_dir:
829
- config_dir = Path.cwd() / ".claude"
830
-
831
- results = {
832
- "config_dir": str(config_dir),
833
- "agents_found": [],
834
- "agents_needing_migration": [],
835
- "environment": {},
836
- "warnings": []
837
- }
838
-
839
- # Check configuration directory
840
- if not config_dir.exists():
841
- results["warnings"].append(f"Configuration directory not found: {config_dir}")
842
- return results
843
-
844
- # Check agents directory
845
- agents_dir = config_dir / "agents"
846
- if not agents_dir.exists():
847
- results["warnings"].append(f"Agents directory not found: {agents_dir}")
848
- return results
849
-
850
- # List deployed agents
851
- agent_files = list(agents_dir.glob("*.yaml"))
852
- for agent_file in agent_files:
853
- try:
854
- # Read first few lines to get agent name from YAML
855
- with open(agent_file, 'r') as f:
856
- lines = f.readlines()[:10]
857
-
858
- agent_info = {
859
- "file": agent_file.name,
860
- "path": str(agent_file)
861
- }
862
-
863
- # Extract name and version from YAML frontmatter
864
- version_str = None
865
- for line in lines:
866
- if line.startswith("name:"):
867
- agent_info["name"] = line.split(":", 1)[1].strip().strip('"\'')
868
- elif line.startswith("version:"):
869
- version_str = line.split(":", 1)[1].strip().strip('"\'')
870
- agent_info["version"] = version_str
871
-
872
- # Check if agent needs migration
873
- if version_str and self._is_old_version_format(version_str):
874
- agent_info["needs_migration"] = True
875
- results["agents_needing_migration"].append(agent_info["name"])
876
-
877
- results["agents_found"].append(agent_info)
878
-
879
- except Exception as e:
880
- results["warnings"].append(f"Failed to read {agent_file.name}: {e}")
881
-
882
- # Check environment variables
883
- env_vars = ["CLAUDE_CONFIG_DIR", "CLAUDE_MAX_PARALLEL_SUBAGENTS", "CLAUDE_TIMEOUT"]
884
- for var in env_vars:
885
- value = os.environ.get(var)
886
- if value:
887
- results["environment"][var] = value
888
- else:
889
- results["warnings"].append(f"Environment variable not set: {var}")
890
-
891
- return results
892
-
893
- def list_available_agents(self) -> List[Dict[str, Any]]:
894
- """
895
- List available agent templates.
896
-
897
- Returns:
898
- List of agent information dictionaries
899
- """
900
- agents = []
901
-
902
- if not self.templates_dir.exists():
903
- self.logger.warning(f"Templates directory not found: {self.templates_dir}")
904
- return agents
905
-
906
- template_files = sorted(self.templates_dir.glob("*.json"))
907
- # Filter out non-agent files
908
- template_files = [f for f in template_files if f.stem != "__init__" and not f.stem.startswith(".")]
909
-
910
- for template_file in template_files:
911
- try:
912
- agent_name = template_file.stem
913
- agent_info = {
914
- "name": agent_name,
915
- "file": template_file.name,
916
- "path": str(template_file),
917
- "size": template_file.stat().st_size,
918
- "description": f"{agent_name.title()} agent for specialized tasks"
919
- }
920
-
921
- # Try to extract metadata from template JSON
922
- try:
923
- import json
924
- template_data = json.loads(template_file.read_text())
925
-
926
- # Handle different schema formats
927
- if 'metadata' in template_data:
928
- # New schema format
929
- metadata = template_data.get('metadata', {})
930
- agent_info["description"] = metadata.get('description', agent_info["description"])
931
- agent_info["role"] = metadata.get('specializations', [''])[0] if metadata.get('specializations') else ''
932
- elif 'configuration_fields' in template_data:
933
- # Old schema format
934
- config_fields = template_data.get('configuration_fields', {})
935
- agent_info["role"] = config_fields.get('primary_role', '')
936
- agent_info["description"] = config_fields.get('description', agent_info["description"])
937
-
938
- # Handle both 'agent_version' (new format) and 'version' (old format)
939
- version_tuple = self._parse_version(template_data.get('agent_version') or template_data.get('version', 0))
940
- agent_info["version"] = self._format_version_display(version_tuple)
941
-
942
- except Exception:
943
- pass # Use defaults if can't parse
944
-
945
- agents.append(agent_info)
946
-
947
- except Exception as e:
948
- self.logger.error(f"Failed to read template {template_file.name}: {e}")
949
-
950
- return agents
951
-
952
- def _check_agent_needs_update(self, deployed_file: Path, template_file: Path, current_base_version: tuple) -> tuple:
953
- """
954
- Check if a deployed agent needs to be updated.
955
-
956
- OPERATIONAL LOGIC:
957
- 1. Verifies agent is system-managed (claude-mpm authored)
958
- 2. Extracts version from deployed YAML frontmatter
959
- 3. Detects old version formats requiring migration
960
- 4. Compares semantic versions for update decision
961
- 5. Returns detailed reason for update/skip decision
962
-
963
- VERSION MIGRATION STRATEGY:
964
- - Old serial format (0002-0005) -> Semantic (2.5.0)
965
- - Missing versions -> Force update to latest
966
- - Non-semantic formats -> Trigger migration
967
- - Preserves user modifications (non-system agents)
968
-
969
- PERFORMANCE OPTIMIZATION:
970
- - Early exit for non-system agents
971
- - Regex compilation cached by Python
972
- - Minimal file reads (frontmatter only)
973
- - Version comparison without full parse
974
-
975
- ERROR RECOVERY:
976
- - Assumes update needed on parse failures
977
- - Logs warnings for investigation
978
- - Never blocks deployment pipeline
979
- - Safe fallback to force update
980
-
981
- Args:
982
- deployed_file: Path to the deployed agent file
983
- template_file: Path to the template file
984
- current_base_version: Current base agent version (unused in new strategy)
985
-
986
- Returns:
987
- Tuple of (needs_update: bool, reason: str)
988
- - needs_update: True if agent should be redeployed
989
- - reason: Human-readable explanation for decision
990
- """
991
- try:
992
- # Read deployed agent content
993
- deployed_content = deployed_file.read_text()
994
-
995
- # Check if it's a system agent (authored by claude-mpm)
996
- if "claude-mpm" not in deployed_content:
997
- return (False, "not a system agent")
998
-
999
- # Extract version info from YAML frontmatter
1000
- import re
1001
-
1002
- # Check if using old serial format first
1003
- is_old_format = False
1004
- old_version_str = None
1005
-
1006
- # Try legacy combined format (e.g., "0002-0005")
1007
- legacy_match = re.search(r'^version:\s*["\']?(\d+)-(\d+)["\']?', deployed_content, re.MULTILINE)
1008
- if legacy_match:
1009
- is_old_format = True
1010
- old_version_str = f"{legacy_match.group(1)}-{legacy_match.group(2)}"
1011
- # Convert legacy format to semantic version
1012
- # Treat the agent version (second number) as minor version
1013
- deployed_agent_version = (0, int(legacy_match.group(2)), 0)
1014
- self.logger.info(f"Detected old serial version format: {old_version_str}")
1015
- else:
1016
- # Try to extract semantic version format (e.g., "2.1.0")
1017
- version_match = re.search(r'^version:\s*["\']?v?(\d+)\.(\d+)\.(\d+)["\']?', deployed_content, re.MULTILINE)
1018
- if version_match:
1019
- deployed_agent_version = (int(version_match.group(1)), int(version_match.group(2)), int(version_match.group(3)))
1020
- else:
1021
- # Fallback: try separate fields (very old format)
1022
- agent_version_match = re.search(r"^agent_version:\s*(\d+)", deployed_content, re.MULTILINE)
1023
- if agent_version_match:
1024
- is_old_format = True
1025
- old_version_str = f"agent_version: {agent_version_match.group(1)}"
1026
- deployed_agent_version = (0, int(agent_version_match.group(1)), 0)
1027
- self.logger.info(f"Detected old separate version format: {old_version_str}")
1028
- else:
1029
- # Check for missing version field
1030
- if "version:" not in deployed_content:
1031
- is_old_format = True
1032
- old_version_str = "missing"
1033
- deployed_agent_version = (0, 0, 0)
1034
- self.logger.info("Detected missing version field")
1035
- else:
1036
- deployed_agent_version = (0, 0, 0)
1037
-
1038
- # For base version, we don't need to extract from deployed file anymore
1039
- # as it's tracked in metadata
1040
-
1041
- # Read template to get current agent version
1042
- import json
1043
- template_data = json.loads(template_file.read_text())
1044
-
1045
- # Extract agent version from template (handle both numeric and semantic versioning)
1046
- current_agent_version = self._parse_version(template_data.get('agent_version') or template_data.get('version', 0))
1047
-
1048
- # Compare semantic versions properly
1049
- # Semantic version comparison: compare major, then minor, then patch
1050
- def compare_versions(v1: tuple, v2: tuple) -> int:
1051
- """Compare two version tuples. Returns -1 if v1 < v2, 0 if equal, 1 if v1 > v2."""
1052
- for a, b in zip(v1, v2):
1053
- if a < b:
1054
- return -1
1055
- elif a > b:
1056
- return 1
1057
- return 0
1058
-
1059
- # If old format detected, always trigger update for migration
1060
- if is_old_format:
1061
- new_version_str = self._format_version_display(current_agent_version)
1062
- return (True, f"migration needed from old format ({old_version_str}) to semantic version ({new_version_str})")
1063
-
1064
- # Check if agent template version is newer
1065
- if compare_versions(current_agent_version, deployed_agent_version) > 0:
1066
- deployed_str = self._format_version_display(deployed_agent_version)
1067
- current_str = self._format_version_display(current_agent_version)
1068
- return (True, f"agent template updated ({deployed_str} -> {current_str})")
1069
-
1070
- # Note: We no longer check base agent version separately since we're using
1071
- # a unified semantic version for the agent
1072
-
1073
- return (False, "up to date")
1074
-
1075
- except Exception as e:
1076
- self.logger.warning(f"Error checking agent update status: {e}")
1077
- # On error, assume update is needed
1078
- return (True, "version check failed")
1079
-
1080
- def clean_deployment(self, config_dir: Optional[Path] = None) -> Dict[str, Any]:
1081
- """
1082
- Clean up deployed agents.
1083
-
1084
- Args:
1085
- config_dir: Claude configuration directory (default: .claude/)
1086
-
1087
- Returns:
1088
- Cleanup results
1089
- """
1090
- if not config_dir:
1091
- config_dir = Path.cwd() / ".claude"
1092
-
1093
- results = {
1094
- "removed": [],
1095
- "errors": []
1096
- }
1097
-
1098
- agents_dir = config_dir / "agents"
1099
- if not agents_dir.exists():
1100
- results["errors"].append(f"Agents directory not found: {agents_dir}")
1101
- return results
1102
-
1103
- # Remove system agents only (identified by claude-mpm author)
1104
- agent_files = list(agents_dir.glob("*.yaml"))
1105
-
1106
- for agent_file in agent_files:
1107
- try:
1108
- # Check if it's a system agent
1109
- with open(agent_file, 'r') as f:
1110
- content = f.read()
1111
- if "author: claude-mpm" in content or "author: 'claude-mpm'" in content:
1112
- agent_file.unlink()
1113
- results["removed"].append(str(agent_file))
1114
- self.logger.debug(f"Removed agent: {agent_file.name}")
1115
-
1116
- except Exception as e:
1117
- error_msg = f"Failed to remove {agent_file.name}: {e}"
1118
- self.logger.error(error_msg)
1119
- results["errors"].append(error_msg)
1120
-
1121
- return results
1122
-
1123
- def _extract_agent_metadata(self, template_content: str) -> Dict[str, Any]:
1124
- """
1125
- Extract metadata from simplified agent template content.
1126
-
1127
- Args:
1128
- template_content: Agent template markdown content
1129
-
1130
- Returns:
1131
- Dictionary of extracted metadata
1132
- """
1133
- metadata = {}
1134
- lines = template_content.split('\n')
1135
-
1136
- # Extract sections based on the new simplified format
1137
- current_section = None
1138
- section_content = []
1139
-
1140
- for line in lines:
1141
- line = line.strip()
1142
-
1143
- if line.startswith('## When to Use'):
1144
- # Save previous section before starting new one
1145
- if current_section and section_content:
1146
- metadata[current_section] = section_content.copy()
1147
- current_section = 'when_to_use'
1148
- section_content = []
1149
- elif line.startswith('## Specialized Knowledge'):
1150
- # Save previous section before starting new one
1151
- if current_section and section_content:
1152
- metadata[current_section] = section_content.copy()
1153
- current_section = 'specialized_knowledge'
1154
- section_content = []
1155
- elif line.startswith('## Unique Capabilities'):
1156
- # Save previous section before starting new one
1157
- if current_section and section_content:
1158
- metadata[current_section] = section_content.copy()
1159
- current_section = 'unique_capabilities'
1160
- section_content = []
1161
- elif line.startswith('## ') or line.startswith('# '):
1162
- # End of section - save current section
1163
- if current_section and section_content:
1164
- metadata[current_section] = section_content.copy()
1165
- current_section = None
1166
- section_content = []
1167
- elif current_section and line.startswith('- '):
1168
- # Extract list item, removing the "- " prefix
1169
- item = line[2:].strip()
1170
- if item:
1171
- section_content.append(item)
1172
-
1173
- # Handle last section if file ends without another header
1174
- if current_section and section_content:
1175
- metadata[current_section] = section_content.copy()
1176
-
1177
- # Ensure all required fields have defaults
1178
- metadata.setdefault('when_to_use', [])
1179
- metadata.setdefault('specialized_knowledge', [])
1180
- metadata.setdefault('unique_capabilities', [])
1181
-
1182
- return metadata
1183
-
1184
- def _get_agent_tools(self, agent_name: str, metadata: Dict[str, Any]) -> List[str]:
1185
- """
1186
- Get appropriate tools for an agent based on its type.
1187
-
1188
- Args:
1189
- agent_name: Name of the agent
1190
- metadata: Agent metadata
1191
-
1192
- Returns:
1193
- List of tool names
1194
- """
1195
- # Base tools all agents should have
1196
- base_tools = [
1197
- "Read",
1198
- "Write",
1199
- "Edit",
1200
- "MultiEdit",
1201
- "Grep",
1202
- "Glob",
1203
- "LS",
1204
- "TodoWrite"
1205
- ]
1206
-
1207
- # Agent-specific tools
1208
- agent_tools = {
1209
- 'engineer': base_tools + ["Bash", "WebSearch", "WebFetch"],
1210
- 'qa': base_tools + ["Bash", "WebSearch"],
1211
- 'documentation': base_tools + ["WebSearch", "WebFetch"],
1212
- 'research': base_tools + ["WebSearch", "WebFetch", "Bash"],
1213
- 'security': base_tools + ["Bash", "WebSearch", "Grep"],
1214
- 'ops': base_tools + ["Bash", "WebSearch"],
1215
- 'data_engineer': base_tools + ["Bash", "WebSearch"],
1216
- 'version_control': base_tools + ["Bash"]
1217
- }
1218
-
1219
- # Return specific tools or default set
1220
- return agent_tools.get(agent_name, base_tools + ["Bash", "WebSearch"])
1221
-
1222
- def _format_version_display(self, version_tuple: tuple) -> str:
1223
- """
1224
- Format version tuple for display.
1225
-
1226
- Args:
1227
- version_tuple: Tuple of (major, minor, patch)
1228
-
1229
- Returns:
1230
- Formatted version string
1231
- """
1232
- if isinstance(version_tuple, tuple) and len(version_tuple) == 3:
1233
- major, minor, patch = version_tuple
1234
- return f"{major}.{minor}.{patch}"
1235
- else:
1236
- # Fallback for legacy format
1237
- return str(version_tuple)
1238
-
1239
- def _is_old_version_format(self, version_str: str) -> bool:
1240
- """
1241
- Check if a version string is in the old serial format.
1242
-
1243
- Old formats include:
1244
- - Serial format: "0002-0005" (contains hyphen, all digits)
1245
- - Missing version field
1246
- - Non-semantic version formats
1247
-
1248
- Args:
1249
- version_str: Version string to check
1250
-
1251
- Returns:
1252
- True if old format, False if semantic version
1253
- """
1254
- if not version_str:
1255
- return True
1256
-
1257
- import re
1258
-
1259
- # Check for serial format (e.g., "0002-0005")
1260
- if re.match(r'^\d+-\d+$', version_str):
1261
- return True
1262
-
1263
- # Check for semantic version format (e.g., "2.1.0")
1264
- if re.match(r'^v?\d+\.\d+\.\d+$', version_str):
1265
- return False
1266
-
1267
- # Any other format is considered old
1268
- return True
1269
-
1270
- def _parse_version(self, version_value: Any) -> tuple:
1271
- """
1272
- Parse version from various formats to semantic version tuple.
1273
-
1274
- Handles:
1275
- - Integer values: 5 -> (0, 5, 0)
1276
- - String integers: "5" -> (0, 5, 0)
1277
- - Semantic versions: "2.1.0" -> (2, 1, 0)
1278
- - Invalid formats: returns (0, 0, 0)
1279
-
1280
- Args:
1281
- version_value: Version in various formats
1282
-
1283
- Returns:
1284
- Tuple of (major, minor, patch) for comparison
1285
- """
1286
- if isinstance(version_value, int):
1287
- # Legacy integer version - treat as minor version
1288
- return (0, version_value, 0)
1289
-
1290
- if isinstance(version_value, str):
1291
- # Try to parse as simple integer
1292
- if version_value.isdigit():
1293
- return (0, int(version_value), 0)
1294
-
1295
- # Try to parse semantic version (e.g., "2.1.0" or "v2.1.0")
1296
- import re
1297
- sem_ver_match = re.match(r'^v?(\d+)\.(\d+)\.(\d+)', version_value)
1298
- if sem_ver_match:
1299
- major = int(sem_ver_match.group(1))
1300
- minor = int(sem_ver_match.group(2))
1301
- patch = int(sem_ver_match.group(3))
1302
- return (major, minor, patch)
1303
-
1304
- # Try to extract first number from string as minor version
1305
- num_match = re.search(r'(\d+)', version_value)
1306
- if num_match:
1307
- return (0, int(num_match.group(1)), 0)
1308
-
1309
- # Default to 0.0.0 for invalid formats
1310
- return (0, 0, 0)
1311
-
1312
- def _format_yaml_list(self, items: List[str], indent: int) -> str:
1313
- """
1314
- Format a list for YAML with proper indentation.
1315
-
1316
- Args:
1317
- items: List of items
1318
- indent: Number of spaces to indent
1319
-
1320
- Returns:
1321
- Formatted YAML list string
1322
- """
1323
- if not items:
1324
- items = ["No items specified"]
1325
-
1326
- indent_str = " " * indent
1327
- formatted_items = []
1328
-
1329
- for item in items:
1330
- # Escape quotes in the item
1331
- item = item.replace('"', '\\"')
1332
- formatted_items.append(f'{indent_str}- "{item}"')
1333
-
1334
- return '\n'.join(formatted_items)
1335
-
1336
- def _get_agent_specific_config(self, agent_name: str) -> Dict[str, Any]:
1337
- """
1338
- Get agent-specific configuration based on agent type.
1339
-
1340
- Args:
1341
- agent_name: Name of the agent
1342
-
1343
- Returns:
1344
- Dictionary of agent-specific configuration
1345
- """
1346
- # Base configuration all agents share
1347
- base_config = {
1348
- 'timeout': 600,
1349
- 'max_tokens': 8192,
1350
- 'memory_limit': 2048,
1351
- 'cpu_limit': 50,
1352
- 'network_access': True,
1353
- }
1354
-
1355
- # Agent-specific configurations
1356
- configs = {
1357
- 'engineer': {
1358
- **base_config,
1359
- 'description': 'Code implementation, development, and inline documentation',
1360
- 'tags': '["engineer", "development", "coding", "implementation"]',
1361
- 'tools': '["Read", "Write", "Edit", "MultiEdit", "Bash", "Grep", "Glob", "LS", "WebSearch", "TodoWrite"]',
1362
- 'temperature': 0.2,
1363
- 'when_to_use': ['Code implementation needed', 'Bug fixes required', 'Refactoring tasks'],
1364
- 'specialized_knowledge': ['Programming best practices', 'Design patterns', 'Code optimization'],
1365
- 'unique_capabilities': ['Write production code', 'Debug complex issues', 'Refactor codebases'],
1366
- 'primary_role': 'Code implementation and development',
1367
- 'specializations': '["coding", "debugging", "refactoring", "optimization"]',
1368
- 'authority': 'ALL code implementation decisions',
1369
- },
1370
- 'qa': {
1371
- **base_config,
1372
- 'description': 'Quality assurance, testing, and validation',
1373
- 'tags': '["qa", "testing", "quality", "validation"]',
1374
- 'tools': '["Read", "Write", "Edit", "Bash", "Grep", "Glob", "LS", "TodoWrite"]',
1375
- 'temperature': 0.1,
1376
- 'when_to_use': ['Testing needed', 'Quality validation', 'Test coverage analysis'],
1377
- 'specialized_knowledge': ['Testing methodologies', 'Quality metrics', 'Test automation'],
1378
- 'unique_capabilities': ['Execute test suites', 'Identify edge cases', 'Validate quality'],
1379
- 'primary_role': 'Testing and quality assurance',
1380
- 'specializations': '["testing", "validation", "quality-assurance", "coverage"]',
1381
- 'authority': 'ALL testing and quality decisions',
1382
- },
1383
- 'documentation': {
1384
- **base_config,
1385
- 'description': 'Documentation creation, maintenance, and changelog generation',
1386
- 'tags': '["documentation", "writing", "changelog", "docs"]',
1387
- 'tools': '["Read", "Write", "Edit", "MultiEdit", "Grep", "Glob", "LS", "WebSearch", "TodoWrite"]',
1388
- 'temperature': 0.3,
1389
- 'when_to_use': ['Documentation updates needed', 'Changelog generation', 'README updates'],
1390
- 'specialized_knowledge': ['Technical writing', 'Documentation standards', 'Semantic versioning'],
1391
- 'unique_capabilities': ['Create clear documentation', 'Generate changelogs', 'Maintain docs'],
1392
- 'primary_role': 'Documentation and technical writing',
1393
- 'specializations': '["technical-writing", "changelog", "api-docs", "guides"]',
1394
- 'authority': 'ALL documentation decisions',
1395
- },
1396
- 'research': {
1397
- **base_config,
1398
- 'description': 'Technical research, analysis, and investigation',
1399
- 'tags': '["research", "analysis", "investigation", "evaluation"]',
1400
- 'tools': '["Read", "Grep", "Glob", "LS", "WebSearch", "WebFetch", "TodoWrite"]',
1401
- 'temperature': 0.4,
1402
- 'when_to_use': ['Technical research needed', 'Solution evaluation', 'Best practices investigation'],
1403
- 'specialized_knowledge': ['Research methodologies', 'Technical analysis', 'Evaluation frameworks'],
1404
- 'unique_capabilities': ['Deep investigation', 'Comparative analysis', 'Evidence-based recommendations'],
1405
- 'primary_role': 'Research and technical analysis',
1406
- 'specializations': '["investigation", "analysis", "evaluation", "recommendations"]',
1407
- 'authority': 'ALL research decisions',
1408
- },
1409
- 'security': {
1410
- **base_config,
1411
- 'description': 'Security analysis, vulnerability assessment, and protection',
1412
- 'tags': '["security", "vulnerability", "protection", "audit"]',
1413
- 'tools': '["Read", "Grep", "Glob", "LS", "Bash", "WebSearch", "TodoWrite"]',
1414
- 'temperature': 0.1,
1415
- 'when_to_use': ['Security review needed', 'Vulnerability assessment', 'Security audit'],
1416
- 'specialized_knowledge': ['Security best practices', 'OWASP guidelines', 'Vulnerability patterns'],
1417
- 'unique_capabilities': ['Identify vulnerabilities', 'Security auditing', 'Threat modeling'],
1418
- 'primary_role': 'Security analysis and protection',
1419
- 'specializations': '["vulnerability-assessment", "security-audit", "threat-modeling", "protection"]',
1420
- 'authority': 'ALL security decisions',
1421
- },
1422
- 'ops': {
1423
- **base_config,
1424
- 'description': 'Deployment, operations, and infrastructure management',
1425
- 'tags': '["ops", "deployment", "infrastructure", "devops"]',
1426
- 'tools': '["Read", "Write", "Edit", "Bash", "Grep", "Glob", "LS", "TodoWrite"]',
1427
- 'temperature': 0.2,
1428
- 'when_to_use': ['Deployment configuration', 'Infrastructure setup', 'CI/CD pipeline work'],
1429
- 'specialized_knowledge': ['Deployment best practices', 'Infrastructure as code', 'CI/CD'],
1430
- 'unique_capabilities': ['Configure deployments', 'Manage infrastructure', 'Automate operations'],
1431
- 'primary_role': 'Operations and deployment management',
1432
- 'specializations': '["deployment", "infrastructure", "automation", "monitoring"]',
1433
- 'authority': 'ALL operations decisions',
1434
- },
1435
- 'data_engineer': {
1436
- **base_config,
1437
- 'description': 'Data pipeline management and AI API integrations',
1438
- 'tags': '["data", "pipeline", "etl", "ai-integration"]',
1439
- 'tools': '["Read", "Write", "Edit", "Bash", "Grep", "Glob", "LS", "WebSearch", "TodoWrite"]',
1440
- 'temperature': 0.2,
1441
- 'when_to_use': ['Data pipeline setup', 'Database design', 'AI API integration'],
1442
- 'specialized_knowledge': ['Data architectures', 'ETL processes', 'AI/ML APIs'],
1443
- 'unique_capabilities': ['Design data schemas', 'Build pipelines', 'Integrate AI services'],
1444
- 'primary_role': 'Data engineering and AI integration',
1445
- 'specializations': '["data-pipelines", "etl", "database", "ai-integration"]',
1446
- 'authority': 'ALL data engineering decisions',
1447
- },
1448
- 'version_control': {
1449
- **base_config,
1450
- 'description': 'Git operations, version management, and release coordination',
1451
- 'tags': '["git", "version-control", "release", "branching"]',
1452
- 'tools': '["Read", "Bash", "Grep", "Glob", "LS", "TodoWrite"]',
1453
- 'temperature': 0.1,
1454
- 'network_access': False, # Git operations are local
1455
- 'when_to_use': ['Git operations needed', 'Version bumping', 'Release management'],
1456
- 'specialized_knowledge': ['Git workflows', 'Semantic versioning', 'Release processes'],
1457
- 'unique_capabilities': ['Complex git operations', 'Version management', 'Release coordination'],
1458
- 'primary_role': 'Version control and release management',
1459
- 'specializations': '["git", "versioning", "branching", "releases"]',
1460
- 'authority': 'ALL version control decisions',
1461
- }
1462
- }
1463
-
1464
- # Return the specific config or a default
1465
- return configs.get(agent_name, {
1466
- **base_config,
1467
- 'description': f'{agent_name.title()} agent for specialized tasks',
1468
- 'tags': f'["{agent_name}", "specialized", "mpm"]',
1469
- 'tools': '["Read", "Write", "Edit", "Grep", "Glob", "LS", "TodoWrite"]',
1470
- 'temperature': 0.3,
1471
- 'when_to_use': [f'When {agent_name} expertise is needed'],
1472
- 'specialized_knowledge': [f'{agent_name.title()} domain knowledge'],
1473
- 'unique_capabilities': [f'{agent_name.title()} specialized operations'],
1474
- 'primary_role': f'{agent_name.title()} operations',
1475
- 'specializations': f'["{agent_name}"]',
1476
- 'authority': f'ALL {agent_name} decisions',
1477
- })
1478
-
1479
- def _deploy_system_instructions(self, target_dir: Path, force_rebuild: bool, results: Dict[str, Any]) -> None:
1480
- """
1481
- Deploy system instructions for PM framework.
1482
-
1483
- Args:
1484
- target_dir: Target directory for deployment
1485
- force_rebuild: Force rebuild even if exists
1486
- results: Results dictionary to update
1487
- """
1488
- try:
1489
- # Find the INSTRUCTIONS.md file
1490
- module_path = Path(__file__).parent.parent
1491
- instructions_path = module_path / "agents" / "INSTRUCTIONS.md"
1492
-
1493
- if not instructions_path.exists():
1494
- self.logger.warning(f"System instructions not found: {instructions_path}")
1495
- return
1496
-
1497
- # Target file for system instructions - use CLAUDE.md in user's home .claude directory
1498
- target_file = Path("~/.claude/CLAUDE.md").expanduser()
1499
-
1500
- # Ensure .claude directory exists
1501
- target_file.parent.mkdir(exist_ok=True)
1502
-
1503
- # Check if update needed
1504
- if not force_rebuild and target_file.exists():
1505
- # Compare modification times
1506
- if target_file.stat().st_mtime >= instructions_path.stat().st_mtime:
1507
- results["skipped"].append("CLAUDE.md")
1508
- self.logger.debug("System instructions up to date")
1509
- return
1510
-
1511
- # Read and deploy system instructions
1512
- instructions_content = instructions_path.read_text()
1513
- target_file.write_text(instructions_content)
1514
-
1515
- is_update = target_file.exists()
1516
- if is_update:
1517
- results["updated"].append({
1518
- "name": "CLAUDE.md",
1519
- "template": str(instructions_path),
1520
- "target": str(target_file)
1521
- })
1522
- self.logger.info("Updated system instructions")
1523
- else:
1524
- results["deployed"].append({
1525
- "name": "CLAUDE.md",
1526
- "template": str(instructions_path),
1527
- "target": str(target_file)
1528
- })
1529
- self.logger.info("Deployed system instructions")
1530
-
1531
- except Exception as e:
1532
- error_msg = f"Failed to deploy system instructions: {e}"
1533
- self.logger.error(error_msg)
1534
- results["errors"].append(error_msg)