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.

Potentially problematic release.


This version of claude-mpm might be problematic. Click here for more details.

Files changed (950) hide show
  1. claude_mpm/BUILD_NUMBER +1 -0
  2. claude_mpm/VERSION +1 -0
  3. claude_mpm/__init__.py +50 -12
  4. claude_mpm/__main__.py +7 -2
  5. claude_mpm/agents/BASE_AGENT.md +164 -0
  6. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  7. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +290 -0
  8. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
  9. claude_mpm/agents/MEMORY.md +72 -0
  10. claude_mpm/agents/PM_INSTRUCTIONS.md +1402 -0
  11. claude_mpm/agents/WORKFLOW.md +111 -0
  12. claude_mpm/agents/__init__.py +92 -80
  13. claude_mpm/agents/agent-template.yaml +83 -0
  14. claude_mpm/agents/agent_loader.py +560 -745
  15. claude_mpm/agents/agent_loader_integration.py +53 -55
  16. claude_mpm/agents/agents_metadata.py +186 -27
  17. claude_mpm/agents/async_agent_loader.py +436 -0
  18. claude_mpm/agents/base_agent.json +8 -4
  19. claude_mpm/agents/frontmatter_validator.py +754 -0
  20. claude_mpm/agents/system_agent_config.py +222 -155
  21. claude_mpm/agents/templates/README.md +465 -0
  22. claude_mpm/agents/templates/__init__.py +17 -13
  23. claude_mpm/agents/templates/circuit-breakers.md +1391 -0
  24. claude_mpm/agents/templates/context-management-examples.md +544 -0
  25. claude_mpm/agents/templates/git-file-tracking.md +584 -0
  26. claude_mpm/agents/templates/pm-examples.md +474 -0
  27. claude_mpm/agents/templates/pm-red-flags.md +310 -0
  28. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  29. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  30. claude_mpm/agents/templates/response-format.md +583 -0
  31. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  32. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  33. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  34. claude_mpm/agents/templates/validation-templates.md +312 -0
  35. claude_mpm/cli/__init__.py +90 -128
  36. claude_mpm/cli/__main__.py +33 -0
  37. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  38. claude_mpm/cli/commands/__init__.py +36 -12
  39. claude_mpm/cli/commands/agent_manager.py +1403 -0
  40. claude_mpm/cli/commands/agent_source.py +774 -0
  41. claude_mpm/cli/commands/agent_state_manager.py +335 -0
  42. claude_mpm/cli/commands/agents.py +2503 -168
  43. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  44. claude_mpm/cli/commands/agents_discover.py +338 -0
  45. claude_mpm/cli/commands/aggregate.py +540 -0
  46. claude_mpm/cli/commands/analyze.py +553 -0
  47. claude_mpm/cli/commands/analyze_code.py +528 -0
  48. claude_mpm/cli/commands/auto_configure.py +1053 -0
  49. claude_mpm/cli/commands/cleanup.py +588 -0
  50. claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
  51. claude_mpm/cli/commands/config.py +586 -0
  52. claude_mpm/cli/commands/configure.py +2654 -0
  53. claude_mpm/cli/commands/configure_agent_display.py +282 -0
  54. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  55. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  56. claude_mpm/cli/commands/configure_models.py +18 -0
  57. claude_mpm/cli/commands/configure_navigation.py +184 -0
  58. claude_mpm/cli/commands/configure_paths.py +104 -0
  59. claude_mpm/cli/commands/configure_persistence.py +254 -0
  60. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  61. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  62. claude_mpm/cli/commands/configure_validators.py +73 -0
  63. claude_mpm/cli/commands/dashboard.py +286 -0
  64. claude_mpm/cli/commands/debug.py +1386 -0
  65. claude_mpm/cli/commands/doctor.py +243 -0
  66. claude_mpm/cli/commands/hook_errors.py +277 -0
  67. claude_mpm/cli/commands/info.py +195 -74
  68. claude_mpm/cli/commands/local_deploy.py +534 -0
  69. claude_mpm/cli/commands/mcp.py +205 -0
  70. claude_mpm/cli/commands/mcp_command_router.py +161 -0
  71. claude_mpm/cli/commands/mcp_config.py +154 -0
  72. claude_mpm/cli/commands/mcp_config_commands.py +20 -0
  73. claude_mpm/cli/commands/mcp_external_commands.py +249 -0
  74. claude_mpm/cli/commands/mcp_install_commands.py +346 -0
  75. claude_mpm/cli/commands/mcp_pipx_config.py +208 -0
  76. claude_mpm/cli/commands/mcp_server_commands.py +155 -0
  77. claude_mpm/cli/commands/mcp_setup_external.py +868 -0
  78. claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
  79. claude_mpm/cli/commands/memory.py +585 -846
  80. claude_mpm/cli/commands/monitor.py +228 -310
  81. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  82. claude_mpm/cli/commands/mpm_init/core.py +759 -0
  83. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  84. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  85. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  86. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  87. claude_mpm/cli/commands/mpm_init/prompts.py +722 -0
  88. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  89. claude_mpm/cli/commands/mpm_init_handler.py +195 -0
  90. claude_mpm/cli/commands/postmortem.py +401 -0
  91. claude_mpm/cli/commands/profile.py +276 -0
  92. claude_mpm/cli/commands/run.py +910 -488
  93. claude_mpm/cli/commands/search.py +458 -0
  94. claude_mpm/cli/commands/skill_source.py +694 -0
  95. claude_mpm/cli/commands/skills.py +1246 -0
  96. claude_mpm/cli/commands/summarize.py +413 -0
  97. claude_mpm/cli/commands/tickets.py +536 -53
  98. claude_mpm/cli/commands/uninstall.py +176 -0
  99. claude_mpm/cli/commands/upgrade.py +152 -0
  100. claude_mpm/cli/commands/verify.py +119 -0
  101. claude_mpm/cli/executor.py +297 -0
  102. claude_mpm/cli/helpers.py +105 -0
  103. claude_mpm/cli/interactive/__init__.py +21 -0
  104. claude_mpm/cli/interactive/agent_wizard.py +1947 -0
  105. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  106. claude_mpm/cli/parser.py +87 -563
  107. claude_mpm/cli/parsers/__init__.py +35 -0
  108. claude_mpm/cli/parsers/agent_manager_parser.py +393 -0
  109. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  110. claude_mpm/cli/parsers/agents_parser.py +575 -0
  111. claude_mpm/cli/parsers/analyze_code_parser.py +170 -0
  112. claude_mpm/cli/parsers/analyze_parser.py +135 -0
  113. claude_mpm/cli/parsers/auto_configure_parser.py +120 -0
  114. claude_mpm/cli/parsers/base_parser.py +644 -0
  115. claude_mpm/cli/parsers/config_parser.py +208 -0
  116. claude_mpm/cli/parsers/configure_parser.py +138 -0
  117. claude_mpm/cli/parsers/dashboard_parser.py +113 -0
  118. claude_mpm/cli/parsers/debug_parser.py +319 -0
  119. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  120. claude_mpm/cli/parsers/mcp_parser.py +195 -0
  121. claude_mpm/cli/parsers/memory_parser.py +138 -0
  122. claude_mpm/cli/parsers/monitor_parser.py +142 -0
  123. claude_mpm/cli/parsers/mpm_init_parser.py +311 -0
  124. claude_mpm/cli/parsers/profile_parser.py +147 -0
  125. claude_mpm/cli/parsers/run_parser.py +157 -0
  126. claude_mpm/cli/parsers/search_parser.py +245 -0
  127. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  128. claude_mpm/cli/parsers/skills_parser.py +277 -0
  129. claude_mpm/cli/parsers/source_parser.py +138 -0
  130. claude_mpm/cli/parsers/tickets_parser.py +203 -0
  131. claude_mpm/cli/shared/__init__.py +40 -0
  132. claude_mpm/cli/shared/argument_patterns.py +205 -0
  133. claude_mpm/cli/shared/base_command.py +242 -0
  134. claude_mpm/cli/shared/error_handling.py +242 -0
  135. claude_mpm/cli/shared/output_formatters.py +241 -0
  136. claude_mpm/cli/startup.py +1743 -0
  137. claude_mpm/cli/startup_display.py +480 -0
  138. claude_mpm/cli/startup_logging.py +839 -0
  139. claude_mpm/cli/utils.py +136 -47
  140. claude_mpm/cli_module/__init__.py +6 -6
  141. claude_mpm/cli_module/args.py +188 -140
  142. claude_mpm/cli_module/commands.py +79 -70
  143. claude_mpm/cli_module/migration_example.py +42 -64
  144. claude_mpm/commands/__init__.py +14 -0
  145. claude_mpm/commands/mpm-config.md +28 -0
  146. claude_mpm/commands/mpm-doctor.md +20 -0
  147. claude_mpm/commands/mpm-help.md +20 -0
  148. claude_mpm/commands/mpm-init.md +120 -0
  149. claude_mpm/commands/mpm-monitor.md +31 -0
  150. claude_mpm/commands/mpm-organize.md +120 -0
  151. claude_mpm/commands/mpm-postmortem.md +21 -0
  152. claude_mpm/commands/mpm-session-resume.md +30 -0
  153. claude_mpm/commands/mpm-status.md +20 -0
  154. claude_mpm/commands/mpm-ticket-view.md +109 -0
  155. claude_mpm/commands/mpm-version.md +20 -0
  156. claude_mpm/commands/mpm.md +31 -0
  157. claude_mpm/config/__init__.py +42 -2
  158. claude_mpm/config/agent_config.py +402 -0
  159. claude_mpm/config/agent_presets.py +488 -0
  160. claude_mpm/config/agent_sources.py +352 -0
  161. claude_mpm/config/experimental_features.py +217 -0
  162. claude_mpm/config/model_config.py +428 -0
  163. claude_mpm/config/paths.py +258 -0
  164. claude_mpm/config/skill_presets.py +392 -0
  165. claude_mpm/config/skill_sources.py +590 -0
  166. claude_mpm/config/socketio_config.py +125 -83
  167. claude_mpm/constants.py +132 -22
  168. claude_mpm/core/__init__.py +62 -36
  169. claude_mpm/core/agent_name_normalizer.py +71 -73
  170. claude_mpm/core/agent_registry.py +385 -492
  171. claude_mpm/core/agent_session_manager.py +81 -70
  172. claude_mpm/core/api_validator.py +330 -0
  173. claude_mpm/core/base_service.py +159 -122
  174. claude_mpm/core/cache.py +560 -0
  175. claude_mpm/core/claude_runner.py +696 -916
  176. claude_mpm/core/config.py +613 -122
  177. claude_mpm/core/config_aliases.py +74 -73
  178. claude_mpm/core/config_constants.py +314 -0
  179. claude_mpm/core/constants.py +361 -0
  180. claude_mpm/core/container.py +646 -104
  181. claude_mpm/core/enums.py +452 -0
  182. claude_mpm/core/error_handler.py +623 -0
  183. claude_mpm/core/exceptions.py +536 -0
  184. claude_mpm/core/factories.py +105 -109
  185. claude_mpm/core/file_utils.py +764 -0
  186. claude_mpm/core/framework/__init__.py +25 -0
  187. claude_mpm/core/framework/formatters/__init__.py +11 -0
  188. claude_mpm/core/framework/formatters/capability_generator.py +367 -0
  189. claude_mpm/core/framework/formatters/content_formatter.py +278 -0
  190. claude_mpm/core/framework/formatters/context_generator.py +185 -0
  191. claude_mpm/core/framework/loaders/__init__.py +13 -0
  192. claude_mpm/core/framework/loaders/agent_loader.py +213 -0
  193. claude_mpm/core/framework/loaders/file_loader.py +176 -0
  194. claude_mpm/core/framework/loaders/instruction_loader.py +222 -0
  195. claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
  196. claude_mpm/core/framework/processors/__init__.py +11 -0
  197. claude_mpm/core/framework/processors/memory_processor.py +230 -0
  198. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  199. claude_mpm/core/framework/processors/template_processor.py +244 -0
  200. claude_mpm/core/framework_loader.py +485 -414
  201. claude_mpm/core/hook_error_memory.py +381 -0
  202. claude_mpm/core/hook_manager.py +246 -86
  203. claude_mpm/core/hook_performance_config.py +147 -0
  204. claude_mpm/core/injectable_service.py +72 -63
  205. claude_mpm/core/instruction_reinforcement_hook.py +267 -0
  206. claude_mpm/core/interactive_session.py +670 -0
  207. claude_mpm/core/interfaces.py +570 -164
  208. claude_mpm/core/lazy.py +467 -0
  209. claude_mpm/core/log_manager.py +707 -0
  210. claude_mpm/core/logger.py +295 -134
  211. claude_mpm/core/logging_config.py +474 -0
  212. claude_mpm/core/logging_utils.py +520 -0
  213. claude_mpm/core/minimal_framework_loader.py +24 -22
  214. claude_mpm/core/mixins.py +30 -29
  215. claude_mpm/core/oneshot_session.py +594 -0
  216. claude_mpm/core/optimized_agent_loader.py +479 -0
  217. claude_mpm/core/optimized_startup.py +554 -0
  218. claude_mpm/core/output_style_manager.py +483 -0
  219. claude_mpm/core/pm_hook_interceptor.py +197 -82
  220. claude_mpm/core/protocols/__init__.py +23 -0
  221. claude_mpm/core/protocols/runner_protocol.py +103 -0
  222. claude_mpm/core/protocols/session_protocol.py +131 -0
  223. claude_mpm/core/service_registry.py +153 -116
  224. claude_mpm/core/session_manager.py +179 -64
  225. claude_mpm/core/shared/__init__.py +17 -0
  226. claude_mpm/core/shared/config_loader.py +326 -0
  227. claude_mpm/core/shared/path_resolver.py +281 -0
  228. claude_mpm/core/shared/singleton_manager.py +221 -0
  229. claude_mpm/core/socketio_pool.py +400 -137
  230. claude_mpm/core/system_context.py +38 -0
  231. claude_mpm/core/tool_access_control.py +64 -57
  232. claude_mpm/core/types.py +307 -0
  233. claude_mpm/core/typing_utils.py +553 -0
  234. claude_mpm/core/unified_agent_registry.py +969 -0
  235. claude_mpm/core/unified_config.py +570 -0
  236. claude_mpm/core/unified_paths.py +941 -0
  237. claude_mpm/dashboard/__init__.py +12 -0
  238. claude_mpm/dashboard/api/simple_directory.py +261 -0
  239. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  240. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
  241. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
  242. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +1 -0
  243. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
  244. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
  245. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
  246. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
  247. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
  248. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
  249. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
  250. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  251. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
  252. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
  253. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
  254. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
  255. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
  256. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
  257. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
  258. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
  259. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
  260. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
  261. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
  262. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
  263. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
  264. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  265. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
  266. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
  267. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  268. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
  269. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
  270. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
  271. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
  272. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
  273. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
  274. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
  275. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
  276. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
  277. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  278. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
  279. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
  280. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
  281. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
  282. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
  283. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
  284. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
  285. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
  286. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
  287. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
  288. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  289. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
  290. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
  291. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Vzk33B_K.js +2 -0
  292. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
  293. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
  294. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
  295. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
  296. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
  297. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
  298. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
  299. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
  300. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
  301. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.m1gL8KXf.js +1 -0
  302. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
  303. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
  304. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  305. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  306. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  307. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  308. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  309. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  310. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  311. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  312. claude_mpm/experimental/__init__.py +10 -0
  313. claude_mpm/experimental/cli_enhancements.py +104 -89
  314. claude_mpm/generators/__init__.py +1 -1
  315. claude_mpm/generators/agent_profile_generator.py +76 -66
  316. claude_mpm/hooks/__init__.py +37 -1
  317. claude_mpm/hooks/base_hook.py +37 -32
  318. claude_mpm/hooks/claude_hooks/__init__.py +1 -1
  319. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  320. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  321. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  322. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  323. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  324. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  325. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  326. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  327. claude_mpm/hooks/claude_hooks/connection_pool.py +250 -0
  328. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  329. claude_mpm/hooks/claude_hooks/event_handlers.py +888 -0
  330. claude_mpm/hooks/claude_hooks/hook_handler.py +652 -875
  331. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +10 -7
  332. claude_mpm/hooks/claude_hooks/installer.py +806 -0
  333. claude_mpm/hooks/claude_hooks/memory_integration.py +249 -0
  334. claude_mpm/hooks/claude_hooks/response_tracking.py +412 -0
  335. claude_mpm/hooks/claude_hooks/services/__init__.py +15 -0
  336. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  337. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  338. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  339. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  340. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  341. claude_mpm/hooks/claude_hooks/services/connection_manager.py +229 -0
  342. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +254 -0
  343. claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
  344. claude_mpm/hooks/claude_hooks/services/state_manager.py +284 -0
  345. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
  346. claude_mpm/hooks/claude_hooks/tool_analysis.py +224 -0
  347. claude_mpm/hooks/failure_learning/__init__.py +54 -0
  348. claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
  349. claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
  350. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
  351. claude_mpm/hooks/instruction_reinforcement.py +301 -0
  352. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  353. claude_mpm/hooks/kuzu_memory_hook.py +386 -0
  354. claude_mpm/hooks/kuzu_response_hook.py +179 -0
  355. claude_mpm/hooks/memory_integration_hook.py +201 -107
  356. claude_mpm/hooks/session_resume_hook.py +121 -0
  357. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  358. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  359. claude_mpm/hooks/tool_call_interceptor.py +92 -76
  360. claude_mpm/hooks/validation_hooks.py +62 -54
  361. claude_mpm/init.py +518 -83
  362. claude_mpm/models/__init__.py +9 -9
  363. claude_mpm/models/agent_definition.py +40 -23
  364. claude_mpm/models/agent_session.py +538 -0
  365. claude_mpm/models/git_repository.py +198 -0
  366. claude_mpm/models/resume_log.py +340 -0
  367. claude_mpm/schemas/__init__.py +12 -0
  368. claude_mpm/scripts/__init__.py +15 -0
  369. claude_mpm/scripts/claude-hook-handler.sh +227 -0
  370. claude_mpm/scripts/launch_monitor.py +165 -0
  371. claude_mpm/scripts/mpm_doctor.py +322 -0
  372. claude_mpm/scripts/socketio_daemon.py +189 -200
  373. claude_mpm/scripts/start_activity_logging.py +91 -0
  374. claude_mpm/services/__init__.py +208 -39
  375. claude_mpm/services/agent_capabilities_service.py +266 -0
  376. claude_mpm/services/agents/__init__.py +89 -0
  377. claude_mpm/services/agents/agent_builder.py +514 -0
  378. claude_mpm/services/agents/agent_preset_service.py +238 -0
  379. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  380. claude_mpm/services/agents/agent_review_service.py +280 -0
  381. claude_mpm/services/agents/agent_selection_service.py +484 -0
  382. claude_mpm/services/agents/auto_config_manager.py +796 -0
  383. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  384. claude_mpm/services/agents/cache_git_manager.py +621 -0
  385. claude_mpm/services/agents/deployment/__init__.py +21 -0
  386. claude_mpm/services/agents/deployment/agent_config_provider.py +410 -0
  387. claude_mpm/services/agents/deployment/agent_configuration_manager.py +358 -0
  388. claude_mpm/services/agents/deployment/agent_definition_factory.py +80 -0
  389. claude_mpm/services/agents/deployment/agent_deployment.py +1037 -0
  390. claude_mpm/services/agents/deployment/agent_discovery_service.py +546 -0
  391. claude_mpm/services/agents/deployment/agent_environment_manager.py +288 -0
  392. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +383 -0
  393. claude_mpm/services/agents/deployment/agent_format_converter.py +505 -0
  394. claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +160 -0
  395. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +957 -0
  396. claude_mpm/services/agents/deployment/agent_metrics_collector.py +273 -0
  397. claude_mpm/services/agents/deployment/agent_operation_service.py +573 -0
  398. claude_mpm/services/agents/deployment/agent_record_service.py +418 -0
  399. claude_mpm/services/agents/deployment/agent_restore_handler.py +84 -0
  400. claude_mpm/services/agents/deployment/agent_state_service.py +381 -0
  401. claude_mpm/services/agents/deployment/agent_template_builder.py +1369 -0
  402. claude_mpm/services/agents/deployment/agent_validator.py +376 -0
  403. claude_mpm/services/agents/deployment/agent_version_manager.py +322 -0
  404. claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +10 -13
  405. claude_mpm/services/agents/deployment/agents_directory_resolver.py +149 -0
  406. claude_mpm/services/agents/deployment/async_agent_deployment.py +768 -0
  407. claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
  408. claude_mpm/services/agents/deployment/config/__init__.py +13 -0
  409. claude_mpm/services/agents/deployment/config/deployment_config.py +181 -0
  410. claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
  411. claude_mpm/services/agents/deployment/deployment_config_loader.py +178 -0
  412. claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
  413. claude_mpm/services/agents/deployment/deployment_type_detector.py +120 -0
  414. claude_mpm/services/agents/deployment/deployment_wrapper.py +129 -0
  415. claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
  416. claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
  417. claude_mpm/services/agents/deployment/facade/deployment_executor.py +70 -0
  418. claude_mpm/services/agents/deployment/facade/deployment_facade.py +269 -0
  419. claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
  420. claude_mpm/services/agents/deployment/interface_adapter.py +226 -0
  421. claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
  422. claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
  423. claude_mpm/services/agents/deployment/local_template_deployment.py +362 -0
  424. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +1478 -0
  425. claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
  426. claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
  427. claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +162 -0
  428. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
  429. claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
  430. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +240 -0
  431. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +110 -0
  432. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +80 -0
  433. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +92 -0
  434. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +101 -0
  435. claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
  436. claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +102 -0
  437. claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
  438. claude_mpm/services/agents/deployment/processors/agent_processor.py +269 -0
  439. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +311 -0
  440. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +862 -0
  441. claude_mpm/services/agents/deployment/results/__init__.py +13 -0
  442. claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
  443. claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
  444. claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
  445. claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
  446. claude_mpm/services/agents/deployment/strategies/base_strategy.py +113 -0
  447. claude_mpm/services/agents/deployment/strategies/project_strategy.py +148 -0
  448. claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
  449. claude_mpm/services/agents/deployment/strategies/system_strategy.py +131 -0
  450. claude_mpm/services/agents/deployment/strategies/user_strategy.py +130 -0
  451. claude_mpm/services/agents/deployment/system_instructions_deployer.py +228 -0
  452. claude_mpm/services/agents/deployment/validation/__init__.py +21 -0
  453. claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
  454. claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
  455. claude_mpm/services/agents/deployment/validation/template_validator.py +319 -0
  456. claude_mpm/services/agents/deployment/validation/validation_result.py +214 -0
  457. claude_mpm/services/agents/git_source_manager.py +682 -0
  458. claude_mpm/services/agents/loading/__init__.py +11 -0
  459. claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +306 -228
  460. claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +106 -91
  461. claude_mpm/services/agents/loading/framework_agent_loader.py +433 -0
  462. claude_mpm/services/agents/local_template_manager.py +784 -0
  463. claude_mpm/services/agents/management/__init__.py +9 -0
  464. claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +92 -69
  465. claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +219 -168
  466. claude_mpm/services/agents/memory/__init__.py +22 -0
  467. claude_mpm/services/agents/memory/agent_memory_manager.py +784 -0
  468. claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +20 -18
  469. claude_mpm/services/agents/memory/content_manager.py +470 -0
  470. claude_mpm/services/agents/memory/memory_categorization_service.py +167 -0
  471. claude_mpm/services/agents/memory/memory_file_service.py +129 -0
  472. claude_mpm/services/agents/memory/memory_format_service.py +201 -0
  473. claude_mpm/services/agents/memory/memory_limits_service.py +101 -0
  474. claude_mpm/services/agents/memory/template_generator.py +83 -0
  475. claude_mpm/services/agents/observers.py +547 -0
  476. claude_mpm/services/agents/recommender.py +617 -0
  477. claude_mpm/services/agents/registry/__init__.py +30 -0
  478. claude_mpm/services/agents/registry/deployed_agent_discovery.py +273 -0
  479. claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +370 -295
  480. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  481. claude_mpm/services/agents/sources/__init__.py +13 -0
  482. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  483. claude_mpm/services/agents/sources/git_source_sync_service.py +1202 -0
  484. claude_mpm/services/agents/startup_sync.py +259 -0
  485. claude_mpm/services/agents/toolchain_detector.py +478 -0
  486. claude_mpm/services/analysis/__init__.py +35 -0
  487. claude_mpm/services/analysis/clone_detector.py +1030 -0
  488. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  489. claude_mpm/services/analysis/postmortem_service.py +765 -0
  490. claude_mpm/services/async_session_logger.py +665 -0
  491. claude_mpm/services/claude_session_logger.py +321 -0
  492. claude_mpm/services/cli/__init__.py +18 -0
  493. claude_mpm/services/cli/agent_cleanup_service.py +408 -0
  494. claude_mpm/services/cli/agent_dependency_service.py +395 -0
  495. claude_mpm/services/cli/agent_listing_service.py +463 -0
  496. claude_mpm/services/cli/agent_output_formatter.py +605 -0
  497. claude_mpm/services/cli/agent_validation_service.py +590 -0
  498. claude_mpm/services/cli/memory_crud_service.py +622 -0
  499. claude_mpm/services/cli/memory_output_formatter.py +604 -0
  500. claude_mpm/services/cli/resume_service.py +617 -0
  501. claude_mpm/services/cli/session_manager.py +604 -0
  502. claude_mpm/services/cli/session_pause_manager.py +504 -0
  503. claude_mpm/services/cli/session_resume_helper.py +372 -0
  504. claude_mpm/services/cli/startup_checker.py +362 -0
  505. claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
  506. claude_mpm/services/command_deployment_service.py +446 -0
  507. claude_mpm/services/command_handler_service.py +221 -0
  508. claude_mpm/services/communication/__init__.py +22 -0
  509. claude_mpm/services/core/__init__.py +108 -0
  510. claude_mpm/services/core/base.py +269 -0
  511. claude_mpm/services/core/cache_manager.py +309 -0
  512. claude_mpm/services/core/interfaces/__init__.py +273 -0
  513. claude_mpm/services/core/interfaces/agent.py +514 -0
  514. claude_mpm/services/core/interfaces/communication.py +316 -0
  515. claude_mpm/services/core/interfaces/health.py +169 -0
  516. claude_mpm/services/core/interfaces/infrastructure.py +357 -0
  517. claude_mpm/services/core/interfaces/model.py +281 -0
  518. claude_mpm/services/core/interfaces/process.py +372 -0
  519. claude_mpm/services/core/interfaces/project.py +121 -0
  520. claude_mpm/services/core/interfaces/restart.py +307 -0
  521. claude_mpm/services/core/interfaces/service.py +405 -0
  522. claude_mpm/services/core/interfaces/stability.py +260 -0
  523. claude_mpm/services/core/interfaces.py +81 -0
  524. claude_mpm/services/core/memory_manager.py +682 -0
  525. claude_mpm/services/core/models/__init__.py +70 -0
  526. claude_mpm/services/core/models/agent_config.py +384 -0
  527. claude_mpm/services/core/models/health.py +162 -0
  528. claude_mpm/services/core/models/process.py +239 -0
  529. claude_mpm/services/core/models/restart.py +302 -0
  530. claude_mpm/services/core/models/stability.py +264 -0
  531. claude_mpm/services/core/models/toolchain.py +306 -0
  532. claude_mpm/services/core/path_resolver.py +517 -0
  533. claude_mpm/services/core/service_container.py +520 -0
  534. claude_mpm/services/core/service_interfaces.py +436 -0
  535. claude_mpm/services/diagnostics/__init__.py +18 -0
  536. claude_mpm/services/diagnostics/checks/__init__.py +38 -0
  537. claude_mpm/services/diagnostics/checks/agent_check.py +370 -0
  538. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  539. claude_mpm/services/diagnostics/checks/base_check.py +60 -0
  540. claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
  541. claude_mpm/services/diagnostics/checks/common_issues_check.py +363 -0
  542. claude_mpm/services/diagnostics/checks/configuration_check.py +306 -0
  543. claude_mpm/services/diagnostics/checks/filesystem_check.py +233 -0
  544. claude_mpm/services/diagnostics/checks/installation_check.py +520 -0
  545. claude_mpm/services/diagnostics/checks/instructions_check.py +415 -0
  546. claude_mpm/services/diagnostics/checks/mcp_check.py +330 -0
  547. claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
  548. claude_mpm/services/diagnostics/checks/monitor_check.py +281 -0
  549. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  550. claude_mpm/services/diagnostics/checks/startup_log_check.py +319 -0
  551. claude_mpm/services/diagnostics/diagnostic_runner.py +286 -0
  552. claude_mpm/services/diagnostics/doctor_reporter.py +578 -0
  553. claude_mpm/services/diagnostics/models.py +138 -0
  554. claude_mpm/services/event_aggregator.py +582 -0
  555. claude_mpm/services/event_bus/__init__.py +18 -0
  556. claude_mpm/services/event_bus/config.py +186 -0
  557. claude_mpm/services/event_bus/direct_relay.py +312 -0
  558. claude_mpm/services/event_bus/event_bus.py +396 -0
  559. claude_mpm/services/event_bus/relay.py +326 -0
  560. claude_mpm/services/events/__init__.py +44 -0
  561. claude_mpm/services/events/consumers/__init__.py +18 -0
  562. claude_mpm/services/events/consumers/dead_letter.py +306 -0
  563. claude_mpm/services/events/consumers/logging.py +184 -0
  564. claude_mpm/services/events/consumers/metrics.py +241 -0
  565. claude_mpm/services/events/consumers/socketio.py +377 -0
  566. claude_mpm/services/events/core.py +480 -0
  567. claude_mpm/services/events/interfaces.py +214 -0
  568. claude_mpm/services/events/producers/__init__.py +14 -0
  569. claude_mpm/services/events/producers/hook.py +269 -0
  570. claude_mpm/services/events/producers/system.py +329 -0
  571. claude_mpm/services/exceptions.py +433 -353
  572. claude_mpm/services/framework_claude_md_generator/__init__.py +81 -80
  573. claude_mpm/services/framework_claude_md_generator/content_assembler.py +74 -67
  574. claude_mpm/services/framework_claude_md_generator/content_validator.py +66 -62
  575. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +82 -60
  576. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +36 -37
  577. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +41 -40
  578. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +15 -15
  579. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +5 -4
  580. claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
  581. claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
  582. claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
  583. claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
  584. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +5 -4
  585. claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
  586. claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
  587. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +26 -30
  588. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +6 -5
  589. claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
  590. claude_mpm/services/framework_claude_md_generator/version_manager.py +31 -30
  591. claude_mpm/services/git/__init__.py +21 -0
  592. claude_mpm/services/git/git_operations_service.py +579 -0
  593. claude_mpm/services/github/__init__.py +21 -0
  594. claude_mpm/services/github/github_cli_service.py +397 -0
  595. claude_mpm/services/hook_installer_service.py +506 -0
  596. claude_mpm/services/hook_service.py +159 -111
  597. claude_mpm/services/infrastructure/__init__.py +52 -0
  598. claude_mpm/services/infrastructure/context_preservation.py +569 -0
  599. claude_mpm/services/infrastructure/daemon_manager.py +279 -0
  600. claude_mpm/services/infrastructure/logging.py +209 -0
  601. claude_mpm/services/infrastructure/monitoring/__init__.py +39 -0
  602. claude_mpm/services/infrastructure/monitoring/aggregator.py +432 -0
  603. claude_mpm/services/infrastructure/monitoring/base.py +122 -0
  604. claude_mpm/services/infrastructure/monitoring/legacy.py +203 -0
  605. claude_mpm/services/infrastructure/monitoring/network.py +219 -0
  606. claude_mpm/services/infrastructure/monitoring/process.py +343 -0
  607. claude_mpm/services/infrastructure/monitoring/resources.py +244 -0
  608. claude_mpm/services/infrastructure/monitoring/service.py +368 -0
  609. claude_mpm/services/infrastructure/monitoring.py +71 -0
  610. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  611. claude_mpm/services/instructions/__init__.py +9 -0
  612. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  613. claude_mpm/services/local_ops/__init__.py +155 -0
  614. claude_mpm/services/local_ops/crash_detector.py +257 -0
  615. claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
  616. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  617. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  618. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  619. claude_mpm/services/local_ops/health_manager.py +427 -0
  620. claude_mpm/services/local_ops/log_monitor.py +396 -0
  621. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  622. claude_mpm/services/local_ops/process_manager.py +595 -0
  623. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  624. claude_mpm/services/local_ops/restart_manager.py +401 -0
  625. claude_mpm/services/local_ops/restart_policy.py +387 -0
  626. claude_mpm/services/local_ops/state_manager.py +372 -0
  627. claude_mpm/services/local_ops/unified_manager.py +600 -0
  628. claude_mpm/services/mcp_config_manager.py +1542 -0
  629. claude_mpm/services/mcp_service_verifier.py +732 -0
  630. claude_mpm/services/memory/__init__.py +19 -0
  631. claude_mpm/services/{memory_builder.py → memory/builder.py} +465 -373
  632. claude_mpm/services/memory/cache/__init__.py +14 -0
  633. claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +237 -200
  634. claude_mpm/services/memory/cache/simple_cache.py +331 -0
  635. claude_mpm/services/memory/failure_tracker.py +578 -0
  636. claude_mpm/services/memory/indexed_memory.py +648 -0
  637. claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +272 -243
  638. claude_mpm/services/memory/router.py +951 -0
  639. claude_mpm/services/memory_hook_service.py +470 -0
  640. claude_mpm/services/model/__init__.py +147 -0
  641. claude_mpm/services/model/base_provider.py +365 -0
  642. claude_mpm/services/model/claude_provider.py +412 -0
  643. claude_mpm/services/model/model_router.py +452 -0
  644. claude_mpm/services/model/ollama_provider.py +415 -0
  645. claude_mpm/services/monitor/__init__.py +20 -0
  646. claude_mpm/services/monitor/daemon.py +698 -0
  647. claude_mpm/services/monitor/daemon_manager.py +1076 -0
  648. claude_mpm/services/monitor/event_emitter.py +350 -0
  649. claude_mpm/services/monitor/handlers/__init__.py +21 -0
  650. claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
  651. claude_mpm/services/monitor/handlers/dashboard.py +299 -0
  652. claude_mpm/services/monitor/handlers/file.py +264 -0
  653. claude_mpm/services/monitor/handlers/hooks.py +512 -0
  654. claude_mpm/services/monitor/management/__init__.py +18 -0
  655. claude_mpm/services/monitor/management/health.py +124 -0
  656. claude_mpm/services/monitor/management/lifecycle.py +730 -0
  657. claude_mpm/services/monitor/server.py +1493 -0
  658. claude_mpm/services/monitor_build_service.py +349 -0
  659. claude_mpm/services/native_agent_converter.py +356 -0
  660. claude_mpm/services/orphan_detection.py +786 -0
  661. claude_mpm/services/pm_skills_deployer.py +707 -0
  662. claude_mpm/services/port_manager.py +597 -0
  663. claude_mpm/services/pr/__init__.py +14 -0
  664. claude_mpm/services/pr/pr_template_service.py +329 -0
  665. claude_mpm/services/profile_manager.py +337 -0
  666. claude_mpm/services/project/__init__.py +44 -0
  667. claude_mpm/services/{project_analyzer.py → project/analyzer.py} +541 -291
  668. claude_mpm/services/project/analyzer_v2.py +566 -0
  669. claude_mpm/services/project/architecture_analyzer.py +461 -0
  670. claude_mpm/services/project/archive_manager.py +1045 -0
  671. claude_mpm/services/project/dependency_analyzer.py +462 -0
  672. claude_mpm/services/project/detection_strategies.py +719 -0
  673. claude_mpm/services/project/documentation_manager.py +554 -0
  674. claude_mpm/services/project/enhanced_analyzer.py +572 -0
  675. claude_mpm/services/project/language_analyzer.py +265 -0
  676. claude_mpm/services/project/metrics_collector.py +407 -0
  677. claude_mpm/services/project/project_organizer.py +1009 -0
  678. claude_mpm/services/project/registry.py +636 -0
  679. claude_mpm/services/project/toolchain_analyzer.py +583 -0
  680. claude_mpm/services/project_port_allocator.py +596 -0
  681. claude_mpm/services/recovery_manager.py +293 -240
  682. claude_mpm/services/response_tracker.py +267 -0
  683. claude_mpm/services/runner_configuration_service.py +605 -0
  684. claude_mpm/services/self_upgrade_service.py +608 -0
  685. claude_mpm/services/session_management_service.py +314 -0
  686. claude_mpm/services/session_manager.py +380 -0
  687. claude_mpm/services/shared/__init__.py +21 -0
  688. claude_mpm/services/shared/async_service_base.py +216 -0
  689. claude_mpm/services/shared/config_service_base.py +301 -0
  690. claude_mpm/services/shared/lifecycle_service_base.py +308 -0
  691. claude_mpm/services/shared/manager_base.py +315 -0
  692. claude_mpm/services/shared/service_factory.py +309 -0
  693. claude_mpm/services/skills/__init__.py +21 -0
  694. claude_mpm/services/skills/git_skill_source_manager.py +1324 -0
  695. claude_mpm/services/skills/selective_skill_deployer.py +744 -0
  696. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  697. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  698. claude_mpm/services/skills_config.py +547 -0
  699. claude_mpm/services/skills_deployer.py +1168 -0
  700. claude_mpm/services/socketio/__init__.py +25 -0
  701. claude_mpm/services/socketio/client_proxy.py +229 -0
  702. claude_mpm/services/socketio/dashboard_server.py +362 -0
  703. claude_mpm/services/socketio/event_normalizer.py +798 -0
  704. claude_mpm/services/socketio/handlers/__init__.py +30 -0
  705. claude_mpm/services/socketio/handlers/base.py +136 -0
  706. claude_mpm/services/socketio/handlers/code_analysis.py +682 -0
  707. claude_mpm/services/socketio/handlers/connection.py +643 -0
  708. claude_mpm/services/socketio/handlers/connection_handler.py +333 -0
  709. claude_mpm/services/socketio/handlers/file.py +263 -0
  710. claude_mpm/services/socketio/handlers/git.py +962 -0
  711. claude_mpm/services/socketio/handlers/hook.py +211 -0
  712. claude_mpm/services/socketio/handlers/memory.py +26 -0
  713. claude_mpm/services/socketio/handlers/project.py +24 -0
  714. claude_mpm/services/socketio/handlers/registry.py +214 -0
  715. claude_mpm/services/socketio/migration_utils.py +343 -0
  716. claude_mpm/services/socketio/monitor_client.py +364 -0
  717. claude_mpm/services/socketio/server/__init__.py +18 -0
  718. claude_mpm/services/socketio/server/broadcaster.py +569 -0
  719. claude_mpm/services/socketio/server/connection_manager.py +579 -0
  720. claude_mpm/services/socketio/server/core.py +1079 -0
  721. claude_mpm/services/socketio/server/eventbus_integration.py +245 -0
  722. claude_mpm/services/socketio/server/main.py +501 -0
  723. claude_mpm/services/socketio_client_manager.py +173 -143
  724. claude_mpm/services/socketio_server.py +38 -1657
  725. claude_mpm/services/subprocess_launcher_service.py +322 -0
  726. claude_mpm/services/system_instructions_service.py +270 -0
  727. claude_mpm/services/ticket_manager.py +25 -209
  728. claude_mpm/services/ticket_services/__init__.py +26 -0
  729. claude_mpm/services/ticket_services/crud_service.py +328 -0
  730. claude_mpm/services/ticket_services/formatter_service.py +290 -0
  731. claude_mpm/services/ticket_services/search_service.py +324 -0
  732. claude_mpm/services/ticket_services/validation_service.py +303 -0
  733. claude_mpm/services/ticket_services/workflow_service.py +244 -0
  734. claude_mpm/services/unified/__init__.py +65 -0
  735. claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
  736. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
  737. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
  738. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
  739. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
  740. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
  741. claude_mpm/services/unified/config_strategies/__init__.py +175 -0
  742. claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
  743. claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
  744. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
  745. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
  746. claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
  747. claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
  748. claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
  749. claude_mpm/services/unified/deployment_strategies/base.py +553 -0
  750. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
  751. claude_mpm/services/unified/deployment_strategies/local.py +607 -0
  752. claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
  753. claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
  754. claude_mpm/services/unified/interfaces.py +475 -0
  755. claude_mpm/services/unified/migration.py +509 -0
  756. claude_mpm/services/unified/strategies.py +534 -0
  757. claude_mpm/services/unified/unified_analyzer.py +542 -0
  758. claude_mpm/services/unified/unified_config.py +691 -0
  759. claude_mpm/services/unified/unified_deployment.py +466 -0
  760. claude_mpm/services/utility_service.py +280 -0
  761. claude_mpm/services/version_control/__init__.py +34 -37
  762. claude_mpm/services/version_control/branch_strategy.py +26 -17
  763. claude_mpm/services/version_control/conflict_resolution.py +52 -36
  764. claude_mpm/services/version_control/git_operations.py +183 -49
  765. claude_mpm/services/version_control/semantic_versioning.py +172 -61
  766. claude_mpm/services/version_control/version_parser.py +546 -0
  767. claude_mpm/services/version_service.py +379 -0
  768. claude_mpm/services/visualization/__init__.py +15 -0
  769. claude_mpm/services/visualization/mermaid_generator.py +937 -0
  770. claude_mpm/skills/__init__.py +42 -0
  771. claude_mpm/skills/agent_skills_injector.py +324 -0
  772. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  773. claude_mpm/skills/bundled/__init__.py +6 -0
  774. claude_mpm/skills/bundled/api-documentation.md +393 -0
  775. claude_mpm/skills/bundled/async-testing.md +571 -0
  776. claude_mpm/skills/bundled/code-review.md +143 -0
  777. claude_mpm/skills/bundled/database-migration.md +199 -0
  778. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  779. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  780. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  781. claude_mpm/skills/bundled/git-workflow.md +414 -0
  782. claude_mpm/skills/bundled/imagemagick.md +204 -0
  783. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  784. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  785. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  786. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  787. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  788. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  789. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  790. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  791. claude_mpm/skills/bundled/pdf.md +141 -0
  792. claude_mpm/skills/bundled/performance-profiling.md +573 -0
  793. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  794. claude_mpm/skills/bundled/security-scanning.md +439 -0
  795. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  796. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  797. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  798. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  799. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  800. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  801. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  802. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  803. claude_mpm/skills/bundled/xlsx.md +157 -0
  804. claude_mpm/skills/registry.py +286 -0
  805. claude_mpm/skills/skill_manager.py +405 -0
  806. claude_mpm/skills/skills_registry.py +347 -0
  807. claude_mpm/skills/skills_service.py +739 -0
  808. claude_mpm/storage/__init__.py +9 -0
  809. claude_mpm/storage/state_storage.py +546 -0
  810. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  811. claude_mpm/templates/questions/__init__.py +38 -0
  812. claude_mpm/templates/questions/base.py +193 -0
  813. claude_mpm/templates/questions/pr_strategy.py +311 -0
  814. claude_mpm/templates/questions/project_init.py +385 -0
  815. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  816. claude_mpm/ticket_wrapper.py +2 -2
  817. claude_mpm/tools/__init__.py +10 -0
  818. claude_mpm/tools/__main__.py +208 -0
  819. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  820. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  821. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  822. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  823. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  824. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  825. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  826. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  827. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  828. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  829. claude_mpm/tools/code_tree_builder.py +631 -0
  830. claude_mpm/tools/code_tree_events.py +420 -0
  831. claude_mpm/tools/socketio_debug.py +671 -0
  832. claude_mpm/utils/__init__.py +8 -8
  833. claude_mpm/utils/agent_dependency_loader.py +1090 -0
  834. claude_mpm/utils/agent_filters.py +261 -0
  835. claude_mpm/utils/common.py +544 -0
  836. claude_mpm/utils/config_manager.py +168 -126
  837. claude_mpm/utils/console.py +11 -0
  838. claude_mpm/utils/database_connector.py +298 -0
  839. claude_mpm/utils/dependency_cache.py +373 -0
  840. claude_mpm/utils/dependency_manager.py +60 -59
  841. claude_mpm/utils/dependency_strategies.py +381 -0
  842. claude_mpm/utils/display_helper.py +260 -0
  843. claude_mpm/utils/environment_context.py +313 -0
  844. claude_mpm/utils/error_handler.py +78 -66
  845. claude_mpm/utils/file_utils.py +305 -0
  846. claude_mpm/utils/framework_detection.py +12 -11
  847. claude_mpm/utils/git_analyzer.py +407 -0
  848. claude_mpm/utils/gitignore.py +244 -0
  849. claude_mpm/utils/import_migration_example.py +12 -60
  850. claude_mpm/utils/imports.py +48 -45
  851. claude_mpm/utils/log_cleanup.py +627 -0
  852. claude_mpm/utils/migration.py +372 -0
  853. claude_mpm/utils/path_operations.py +110 -104
  854. claude_mpm/utils/progress.py +387 -0
  855. claude_mpm/utils/robust_installer.py +823 -0
  856. claude_mpm/utils/session_logging.py +121 -0
  857. claude_mpm/utils/structured_questions.py +619 -0
  858. claude_mpm/utils/subprocess_utils.py +343 -0
  859. claude_mpm/validation/__init__.py +1 -1
  860. claude_mpm/validation/agent_validator.py +214 -108
  861. claude_mpm/validation/frontmatter_validator.py +252 -0
  862. claude_mpm-5.4.55.dist-info/METADATA +999 -0
  863. claude_mpm-5.4.55.dist-info/RECORD +868 -0
  864. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/entry_points.txt +1 -3
  865. claude_mpm-5.4.55.dist-info/licenses/LICENSE +94 -0
  866. claude_mpm-5.4.55.dist-info/licenses/LICENSE-FAQ.md +153 -0
  867. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -88
  868. claude_mpm/agents/INSTRUCTIONS.md +0 -352
  869. claude_mpm/agents/backups/INSTRUCTIONS.md +0 -352
  870. claude_mpm/agents/base_agent_loader.py +0 -529
  871. claude_mpm/agents/schema/agent_schema.json +0 -314
  872. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -36
  873. claude_mpm/agents/templates/backup/data_engineer_agent_20250726_234551.json +0 -46
  874. claude_mpm/agents/templates/backup/documentation_agent_20250726_234551.json +0 -45
  875. claude_mpm/agents/templates/backup/engineer_agent_20250726_234551.json +0 -49
  876. claude_mpm/agents/templates/backup/ops_agent_20250726_234551.json +0 -46
  877. claude_mpm/agents/templates/backup/qa_agent_20250726_234551.json +0 -45
  878. claude_mpm/agents/templates/backup/research_agent_20250726_234551.json +0 -49
  879. claude_mpm/agents/templates/backup/security_agent_20250726_234551.json +0 -46
  880. claude_mpm/agents/templates/backup/version_control_agent_20250726_234551.json +0 -46
  881. claude_mpm/agents/templates/data_engineer.json +0 -110
  882. claude_mpm/agents/templates/documentation.json +0 -109
  883. claude_mpm/agents/templates/engineer.json +0 -113
  884. claude_mpm/agents/templates/ops.json +0 -109
  885. claude_mpm/agents/templates/pm.json +0 -25
  886. claude_mpm/agents/templates/qa.json +0 -111
  887. claude_mpm/agents/templates/research.json +0 -65
  888. claude_mpm/agents/templates/security.json +0 -113
  889. claude_mpm/agents/templates/test_integration.json +0 -112
  890. claude_mpm/agents/templates/version_control.json +0 -107
  891. claude_mpm/cli/commands/ui.py +0 -57
  892. claude_mpm/core/simple_runner.py +0 -1046
  893. claude_mpm/dashboard/open_dashboard.py +0 -34
  894. claude_mpm/deployment_paths.py +0 -261
  895. claude_mpm/hooks/builtin/__init__.py +0 -1
  896. claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
  897. claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
  898. claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
  899. claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
  900. claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
  901. claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
  902. claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
  903. claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
  904. claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
  905. claude_mpm/orchestration/__init__.py +0 -6
  906. claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
  907. claude_mpm/orchestration/archive/factory.py +0 -215
  908. claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
  909. claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
  910. claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
  911. claude_mpm/orchestration/archive/orchestrator.py +0 -501
  912. claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
  913. claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
  914. claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
  915. claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
  916. claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
  917. claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
  918. claude_mpm/schemas/workflow_validator.py +0 -411
  919. claude_mpm/services/agent_deployment.py +0 -1534
  920. claude_mpm/services/agent_lifecycle_manager.py +0 -1169
  921. claude_mpm/services/agent_memory_manager.py +0 -1415
  922. claude_mpm/services/agent_registry.py +0 -676
  923. claude_mpm/services/deployed_agent_discovery.py +0 -226
  924. claude_mpm/services/framework_agent_loader.py +0 -337
  925. claude_mpm/services/framework_claude_md_generator.py +0 -621
  926. claude_mpm/services/health_monitor.py +0 -892
  927. claude_mpm/services/memory_router.py +0 -538
  928. claude_mpm/services/parent_directory_manager/__init__.py +0 -577
  929. claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
  930. claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
  931. claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
  932. claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
  933. claude_mpm/services/parent_directory_manager/operations.py +0 -186
  934. claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
  935. claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
  936. claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
  937. claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
  938. claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
  939. claude_mpm/services/standalone_socketio_server.py +0 -1300
  940. claude_mpm/services/ticket_manager_di.py +0 -318
  941. claude_mpm/services/ticketing_service_original.py +0 -508
  942. claude_mpm/ui/__init__.py +0 -1
  943. claude_mpm/ui/rich_terminal_ui.py +0 -295
  944. claude_mpm/ui/terminal_ui.py +0 -328
  945. claude_mpm/utils/paths.py +0 -289
  946. claude_mpm-3.4.10.dist-info/METADATA +0 -183
  947. claude_mpm-3.4.10.dist-info/RECORD +0 -201
  948. claude_mpm-3.4.10.dist-info/licenses/LICENSE +0 -21
  949. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/WHEEL +0 -0
  950. {claude_mpm-3.4.10.dist-info → claude_mpm-5.4.55.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1246 @@
1
+ """
2
+ Skills command implementation for claude-mpm.
3
+
4
+ WHY: This module provides CLI commands for managing Claude Code skills,
5
+ exposing SkillsService functionality for skill discovery, deployment, validation,
6
+ updates, and configuration. Also provides GitHub skills deployment via SkillsDeployer.
7
+
8
+ DESIGN DECISIONS:
9
+ - Use BaseCommand pattern for consistency with other CLI commands
10
+ - Rich output formatting for user-friendly display
11
+ - Graceful error handling with informative messages
12
+ - Support for verbose output and structured formats
13
+ - Dual service approach: SkillsService for bundled, SkillsDeployer for GitHub
14
+
15
+ ARCHITECTURE:
16
+ - SkillsService: Manages bundled skills (in project .claude/skills/)
17
+ - SkillsDeployer: Downloads from GitHub to ~/.claude/skills/ for Claude Code
18
+ """
19
+
20
+ import os
21
+ import subprocess
22
+ from typing import Optional
23
+
24
+ from rich.console import Console
25
+ from rich.markdown import Markdown
26
+ from rich.panel import Panel
27
+ from rich.table import Table
28
+
29
+ from ...constants import SkillsCommands
30
+ from ...services.skills_deployer import SkillsDeployerService
31
+ from ...skills.skills_service import SkillsService
32
+ from ..shared import BaseCommand, CommandResult
33
+
34
+ console = Console()
35
+
36
+
37
+ class SkillsManagementCommand(BaseCommand):
38
+ """Skills management command for Claude Code skills."""
39
+
40
+ def __init__(self):
41
+ super().__init__("skills")
42
+ self._skills_service = None
43
+ self._skills_deployer = None
44
+
45
+ @property
46
+ def skills_service(self) -> SkillsService:
47
+ """Get skills service instance (lazy loaded)."""
48
+ if self._skills_service is None:
49
+ self._skills_service = SkillsService()
50
+ return self._skills_service
51
+
52
+ @property
53
+ def skills_deployer(self) -> SkillsDeployerService:
54
+ """Get skills deployer instance (lazy loaded)."""
55
+ if self._skills_deployer is None:
56
+ self._skills_deployer = SkillsDeployerService()
57
+ return self._skills_deployer
58
+
59
+ def validate_args(self, args) -> Optional[str]:
60
+ """Validate command arguments."""
61
+ # Most skills commands are optional, basic validation
62
+ if hasattr(args, "skills_command") and args.skills_command:
63
+ if args.skills_command == SkillsCommands.VALIDATE.value:
64
+ if not hasattr(args, "skill_name") or not args.skill_name:
65
+ return "Validate command requires a skill name"
66
+ elif args.skills_command == SkillsCommands.INFO.value:
67
+ if not hasattr(args, "skill_name") or not args.skill_name:
68
+ return "Info command requires a skill name"
69
+ return None
70
+
71
+ def run(self, args) -> CommandResult:
72
+ """Execute the skills command."""
73
+ try:
74
+ # Handle default case (no subcommand) - show list
75
+ if not hasattr(args, "skills_command") or not args.skills_command:
76
+ return self._list_skills(args)
77
+
78
+ # Route to appropriate subcommand
79
+ command_map = {
80
+ SkillsCommands.LIST.value: self._list_skills,
81
+ SkillsCommands.DEPLOY.value: self._deploy_skills,
82
+ SkillsCommands.VALIDATE.value: self._validate_skill,
83
+ SkillsCommands.UPDATE.value: self._update_skills,
84
+ SkillsCommands.INFO.value: self._show_skill_info,
85
+ SkillsCommands.CONFIG.value: self._manage_config,
86
+ SkillsCommands.CONFIGURE.value: self._configure_skills,
87
+ # GitHub deployment commands
88
+ SkillsCommands.DEPLOY_FROM_GITHUB.value: self._deploy_from_github,
89
+ SkillsCommands.LIST_AVAILABLE.value: self._list_available_github_skills,
90
+ SkillsCommands.CHECK_DEPLOYED.value: self._check_deployed_skills,
91
+ SkillsCommands.REMOVE.value: self._remove_skills,
92
+ # Collection management commands
93
+ SkillsCommands.COLLECTION_LIST.value: self._collection_list,
94
+ SkillsCommands.COLLECTION_ADD.value: self._collection_add,
95
+ SkillsCommands.COLLECTION_REMOVE.value: self._collection_remove,
96
+ SkillsCommands.COLLECTION_ENABLE.value: self._collection_enable,
97
+ SkillsCommands.COLLECTION_DISABLE.value: self._collection_disable,
98
+ SkillsCommands.COLLECTION_SET_DEFAULT.value: self._collection_set_default,
99
+ }
100
+
101
+ handler = command_map.get(args.skills_command)
102
+ if handler:
103
+ return handler(args)
104
+ return CommandResult(
105
+ success=False,
106
+ message=f"Unknown skills command: {args.skills_command}",
107
+ exit_code=1,
108
+ )
109
+
110
+ except Exception as e:
111
+ self.logger.error(f"Skills command failed: {e}")
112
+ if hasattr(args, "debug") and args.debug:
113
+ import traceback
114
+
115
+ traceback.print_exc()
116
+ return CommandResult(
117
+ success=False, message=f"Skills command failed: {e}", exit_code=1
118
+ )
119
+
120
+ def _list_skills(self, args) -> CommandResult:
121
+ """List available skills."""
122
+ try:
123
+ # Get skills based on filter
124
+ if hasattr(args, "agent") and args.agent:
125
+ skills = self.skills_service.get_skills_for_agent(args.agent)
126
+ console.print(
127
+ f"\n[bold cyan]Skills for agent '{args.agent}':[/bold cyan]\n"
128
+ )
129
+
130
+ if not skills:
131
+ console.print(
132
+ f"[yellow]No skills found for agent '{args.agent}'[/yellow]"
133
+ )
134
+ return CommandResult(success=True, exit_code=0)
135
+
136
+ for skill_name in skills:
137
+ # Get skill metadata
138
+ skill_info = self._get_skill_metadata(skill_name)
139
+ if skill_info:
140
+ console.print(f" [green]•[/green] {skill_name}")
141
+ if (
142
+ hasattr(args, "verbose")
143
+ and args.verbose
144
+ and skill_info.get("description")
145
+ ):
146
+ console.print(f" {skill_info['description']}")
147
+ else:
148
+ console.print(f" [green]•[/green] {skill_name}")
149
+
150
+ else:
151
+ # Discover all bundled skills
152
+ skills = self.skills_service.discover_bundled_skills()
153
+
154
+ # Filter by category if specified
155
+ if hasattr(args, "category") and args.category:
156
+ skills = [s for s in skills if s.get("category") == args.category]
157
+ console.print(
158
+ f"\n[bold cyan]Skills in category '{args.category}':[/bold cyan]\n"
159
+ )
160
+ else:
161
+ console.print("\n[bold cyan]Available Skills:[/bold cyan]\n")
162
+
163
+ if not skills:
164
+ console.print("[yellow]No skills found[/yellow]")
165
+ return CommandResult(success=True, exit_code=0)
166
+
167
+ # Group by category
168
+ by_category = {}
169
+ for skill in skills:
170
+ category = skill.get("category", "uncategorized")
171
+ if category not in by_category:
172
+ by_category[category] = []
173
+ by_category[category].append(skill)
174
+
175
+ # Display by category
176
+ for category, category_skills in sorted(by_category.items()):
177
+ console.print(f"[bold yellow]{category}[/bold yellow]")
178
+ for skill in sorted(
179
+ category_skills, key=lambda s: s.get("name", "")
180
+ ):
181
+ name = skill.get("name", "unknown")
182
+ console.print(f" [green]•[/green] {name}")
183
+
184
+ if hasattr(args, "verbose") and args.verbose:
185
+ metadata = skill.get("metadata", {})
186
+ if desc := metadata.get("description"):
187
+ console.print(f" {desc}")
188
+ if version := metadata.get("version"):
189
+ console.print(f" [dim]Version: {version}[/dim]")
190
+ console.print()
191
+
192
+ return CommandResult(success=True, exit_code=0)
193
+
194
+ except Exception as e:
195
+ console.print(f"[red]Error listing skills: {e}[/red]")
196
+ return CommandResult(success=False, message=str(e), exit_code=1)
197
+
198
+ def _deploy_skills(self, args) -> CommandResult:
199
+ """Deploy skills using two-phase sync: cache → deploy.
200
+
201
+ Phase 3 Integration (1M-486): Uses Git skill source manager for deployment.
202
+ - Phase 1: Sync skills to ~/.claude-mpm/cache/skills/ (if needed)
203
+ - Phase 2: Deploy from cache to project .claude-mpm/skills/
204
+
205
+ This replaces bundled skill deployment with a multi-project
206
+ architecture where one cache serves multiple project deployments.
207
+ """
208
+ try:
209
+ from pathlib import Path
210
+
211
+ from ...config.skill_sources import SkillSourceConfiguration
212
+ from ...services.skills.git_skill_source_manager import (
213
+ GitSkillSourceManager,
214
+ )
215
+
216
+ force = getattr(args, "force", False)
217
+ specific_skills = getattr(args, "skills", None)
218
+
219
+ console.print("\n[bold cyan]Deploying skills...[/bold cyan]\n")
220
+
221
+ # Initialize git skill source manager
222
+ config = SkillSourceConfiguration.load()
223
+ git_skill_manager = GitSkillSourceManager(config)
224
+ project_dir = Path.cwd()
225
+
226
+ # Phase 1: Sync skills to cache
227
+ console.print("[dim]Phase 1: Syncing skills to cache...[/dim]")
228
+ sync_results = git_skill_manager.sync_all_sources(force=force)
229
+
230
+ synced_count = sum(
231
+ 1 for result in sync_results.values() if result.get("synced")
232
+ )
233
+ console.print(f"[dim]Synced {synced_count} skill source(s)[/dim]\n")
234
+
235
+ # Phase 2: Deploy from cache to project
236
+ console.print("[dim]Phase 2: Deploying from cache to project...[/dim]\n")
237
+ deploy_result = git_skill_manager.deploy_skills_to_project(
238
+ project_dir=project_dir,
239
+ skill_list=specific_skills,
240
+ force=force,
241
+ )
242
+
243
+ # Display results
244
+ if deploy_result["deployed"]:
245
+ console.print(
246
+ f"[green]✓ Deployed {len(deploy_result['deployed'])} skill(s):[/green]"
247
+ )
248
+ for skill in deploy_result["deployed"]:
249
+ console.print(f" • {skill}")
250
+ console.print()
251
+
252
+ if deploy_result["updated"]:
253
+ console.print(
254
+ f"[green]⟳ Updated {len(deploy_result['updated'])} skill(s):[/green]"
255
+ )
256
+ for skill in deploy_result["updated"]:
257
+ console.print(f" • {skill}")
258
+ console.print()
259
+
260
+ if deploy_result["skipped"]:
261
+ console.print(
262
+ f"[yellow]⊘ Skipped {len(deploy_result['skipped'])} skill(s) (already up-to-date):[/yellow]"
263
+ )
264
+ for skill in deploy_result["skipped"]:
265
+ console.print(f" • {skill}")
266
+ console.print("[dim]Use --force to redeploy[/dim]\n")
267
+
268
+ if deploy_result["failed"]:
269
+ console.print(
270
+ f"[red]✗ Failed to deploy {len(deploy_result['failed'])} skill(s):[/red]"
271
+ )
272
+ for skill in deploy_result["failed"]:
273
+ console.print(f" • {skill}")
274
+ console.print()
275
+
276
+ # Summary
277
+ success_count = len(deploy_result["deployed"]) + len(
278
+ deploy_result["updated"]
279
+ )
280
+ total = (
281
+ success_count
282
+ + len(deploy_result["skipped"])
283
+ + len(deploy_result["failed"])
284
+ )
285
+ console.print(
286
+ f"[bold]Summary:[/bold] {success_count} deployed/updated, "
287
+ f"{len(deploy_result['skipped'])} skipped, "
288
+ f"{len(deploy_result['failed'])} errors (Total: {total})\n"
289
+ )
290
+
291
+ console.print(
292
+ f"[dim]Deployment directory: {deploy_result['deployment_dir']}[/dim]\n"
293
+ )
294
+
295
+ # Exit with error if any deployments failed
296
+ exit_code = 1 if deploy_result["failed"] else 0
297
+ return CommandResult(
298
+ success=not deploy_result["failed"],
299
+ message=f"Deployed {success_count} skills from cache",
300
+ exit_code=exit_code,
301
+ )
302
+
303
+ except Exception as e:
304
+ console.print(f"[red]Error deploying skills: {e}[/red]")
305
+ return CommandResult(success=False, message=str(e), exit_code=1)
306
+
307
+ def _validate_skill(self, args) -> CommandResult:
308
+ """Validate skill structure and metadata."""
309
+ try:
310
+ skill_name = args.skill_name
311
+ strict = getattr(args, "strict", False)
312
+
313
+ console.print(
314
+ f"\n[bold cyan]Validating skill '{skill_name}'...[/bold cyan]\n"
315
+ )
316
+
317
+ result = self.skills_service.validate_skill(skill_name)
318
+
319
+ if result["valid"]:
320
+ console.print(f"[green]✓ {skill_name} is valid[/green]\n")
321
+
322
+ if result.get("warnings"):
323
+ console.print(
324
+ f"[yellow]Warnings ({len(result['warnings'])}):[/yellow]"
325
+ )
326
+ for warning in result["warnings"]:
327
+ console.print(f" • {warning}")
328
+ console.print()
329
+
330
+ # Treat warnings as errors in strict mode
331
+ if strict:
332
+ console.print(
333
+ "[red]Strict mode: treating warnings as errors[/red]"
334
+ )
335
+ return CommandResult(success=False, exit_code=1)
336
+
337
+ return CommandResult(success=True, exit_code=0)
338
+ console.print(f"[red]✗ {skill_name} has validation errors:[/red]")
339
+ for error in result.get("errors", []):
340
+ console.print(f" • {error}")
341
+ console.print()
342
+
343
+ if result.get("warnings"):
344
+ console.print("[yellow]Warnings:[/yellow]")
345
+ for warning in result["warnings"]:
346
+ console.print(f" • {warning}")
347
+ console.print()
348
+
349
+ return CommandResult(success=False, exit_code=1)
350
+
351
+ except Exception as e:
352
+ console.print(f"[red]Error validating skill: {e}[/red]")
353
+ return CommandResult(success=False, message=str(e), exit_code=1)
354
+
355
+ def _update_skills(self, args) -> CommandResult:
356
+ """Check for and install skill updates."""
357
+ try:
358
+ skill_names = getattr(args, "skill_names", [])
359
+ check_only = getattr(args, "check_only", False)
360
+ force = getattr(args, "force", False)
361
+
362
+ action = "Checking" if check_only else "Updating"
363
+ console.print(f"\n[bold cyan]{action} skills...[/bold cyan]\n")
364
+
365
+ result = self.skills_service.check_for_updates(skill_names)
366
+
367
+ if not result.get("updates_available"):
368
+ console.print("[green]All skills are up to date[/green]\n")
369
+ return CommandResult(success=True, exit_code=0)
370
+
371
+ # Display available updates
372
+ console.print(
373
+ f"[yellow]Updates available for {len(result['updates_available'])} skill(s):[/yellow]"
374
+ )
375
+ for update_info in result["updates_available"]:
376
+ skill_name = update_info["skill"]
377
+ current = update_info["current_version"]
378
+ latest = update_info["latest_version"]
379
+ console.print(f" • {skill_name}: {current} → {latest}")
380
+ console.print()
381
+
382
+ if check_only:
383
+ console.print(
384
+ "[dim]Run without --check-only to install updates[/dim]\n"
385
+ )
386
+ return CommandResult(success=True, exit_code=0)
387
+
388
+ # Install updates
389
+ console.print("[bold cyan]Installing updates...[/bold cyan]\n")
390
+ install_result = self.skills_service.install_updates(
391
+ result["updates_available"], force=force
392
+ )
393
+
394
+ if install_result["updated"]:
395
+ console.print(
396
+ f"[green]✓ Updated {len(install_result['updated'])} skill(s)[/green]\n"
397
+ )
398
+
399
+ if install_result.get("errors"):
400
+ console.print(
401
+ f"[red]✗ Failed to update {len(install_result['errors'])} skill(s)[/red]"
402
+ )
403
+ for skill, error in install_result["errors"].items():
404
+ console.print(f" • {skill}: {error}")
405
+ console.print()
406
+
407
+ exit_code = 1 if install_result.get("errors") else 0
408
+ return CommandResult(
409
+ success=not install_result.get("errors"), exit_code=exit_code
410
+ )
411
+
412
+ except Exception as e:
413
+ console.print(f"[red]Error updating skills: {e}[/red]")
414
+ return CommandResult(success=False, message=str(e), exit_code=1)
415
+
416
+ def _show_skill_info(self, args) -> CommandResult:
417
+ """Show detailed skill information."""
418
+ try:
419
+ skill_name = args.skill_name
420
+ show_content = getattr(args, "show_content", False)
421
+
422
+ skill_info = self._get_skill_metadata(skill_name)
423
+
424
+ if not skill_info:
425
+ console.print(f"[red]Skill '{skill_name}' not found[/red]")
426
+ return CommandResult(success=False, exit_code=1)
427
+
428
+ # Display skill info in a panel
429
+ info_text = f"[bold cyan]{skill_name}[/bold cyan]\n\n"
430
+
431
+ if desc := skill_info.get("description"):
432
+ info_text += f"{desc}\n\n"
433
+
434
+ if category := skill_info.get("category"):
435
+ info_text += f"[bold]Category:[/bold] {category}\n"
436
+
437
+ if version := skill_info.get("version"):
438
+ info_text += f"[bold]Version:[/bold] {version}\n"
439
+
440
+ if source := skill_info.get("source"):
441
+ info_text += f"[bold]Source:[/bold] {source}\n"
442
+
443
+ # Show agents using this skill
444
+ agents_using = self.skills_service.get_agents_for_skill(skill_name)
445
+ if agents_using:
446
+ info_text += (
447
+ f"\n[bold]Used by agents:[/bold] {', '.join(agents_using)}\n"
448
+ )
449
+
450
+ console.print(
451
+ Panel(info_text, title="Skill Information", border_style="cyan")
452
+ )
453
+
454
+ # Show content if requested
455
+ if show_content:
456
+ skill_path = self.skills_service.get_skill_path(skill_name)
457
+ skill_md = skill_path / "SKILL.md"
458
+
459
+ if skill_md.exists():
460
+ console.print("\n[bold cyan]Skill Content:[/bold cyan]\n")
461
+ content = skill_md.read_text()
462
+ console.print(Markdown(content))
463
+ else:
464
+ console.print(
465
+ f"\n[yellow]SKILL.md not found at {skill_md}[/yellow]"
466
+ )
467
+
468
+ return CommandResult(success=True, exit_code=0)
469
+
470
+ except Exception as e:
471
+ console.print(f"[red]Error showing skill info: {e}[/red]")
472
+ return CommandResult(success=False, message=str(e), exit_code=1)
473
+
474
+ def _manage_config(self, args) -> CommandResult:
475
+ """View or edit skills configuration."""
476
+ try:
477
+ scope = getattr(args, "scope", "project")
478
+ edit = getattr(args, "edit", False)
479
+ show_path = getattr(args, "path", False)
480
+
481
+ config_path = self.skills_service.get_config_path(scope)
482
+
483
+ if show_path:
484
+ console.print(
485
+ f"\n[cyan]Configuration path ({scope}):[/cyan] {config_path}\n"
486
+ )
487
+ return CommandResult(success=True, exit_code=0)
488
+
489
+ if not config_path.exists():
490
+ console.print(
491
+ f"\n[yellow]Configuration file does not exist: {config_path}[/yellow]"
492
+ )
493
+ console.print("[dim]Would you like to create it? (y/n):[/dim] ", end="")
494
+
495
+ if input().lower() == "y":
496
+ self.skills_service.create_default_config(scope)
497
+ console.print(
498
+ f"[green]Created default configuration at {config_path}[/green]\n"
499
+ )
500
+ else:
501
+ return CommandResult(success=False, exit_code=1)
502
+
503
+ if edit:
504
+ # Open in editor
505
+ editor = os.environ.get("EDITOR", "nano")
506
+ try:
507
+ subprocess.run([editor, str(config_path)], check=True)
508
+ console.print(
509
+ f"\n[green]Configuration saved to {config_path}[/green]\n"
510
+ )
511
+ return CommandResult(success=True, exit_code=0)
512
+ except subprocess.CalledProcessError as e:
513
+ console.print(f"[red]Error opening editor: {e}[/red]")
514
+ return CommandResult(success=False, exit_code=1)
515
+ else:
516
+ # Display config
517
+ console.print(
518
+ f"\n[bold cyan]Skills Configuration ({scope}):[/bold cyan]\n"
519
+ )
520
+ console.print(f"[dim]Path: {config_path}[/dim]\n")
521
+
522
+ import yaml
523
+
524
+ config = yaml.safe_load(config_path.read_text())
525
+ console.print(yaml.dump(config, default_flow_style=False))
526
+
527
+ return CommandResult(success=True, exit_code=0)
528
+
529
+ except Exception as e:
530
+ console.print(f"[red]Error managing configuration: {e}[/red]")
531
+ return CommandResult(success=False, message=str(e), exit_code=1)
532
+
533
+ def _deploy_from_github(self, args) -> CommandResult:
534
+ """Deploy skills from GitHub repository."""
535
+ try:
536
+ collection = getattr(args, "collection", None)
537
+ toolchain = getattr(args, "toolchain", None)
538
+ categories = getattr(args, "categories", None)
539
+ force = getattr(args, "force", False)
540
+
541
+ if collection:
542
+ console.print(
543
+ f"\n[bold cyan]Deploying skills from collection '{collection}'...[/bold cyan]\n"
544
+ )
545
+ else:
546
+ console.print(
547
+ "\n[bold cyan]Deploying skills from default collection...[/bold cyan]\n"
548
+ )
549
+
550
+ # Selective deployment is ALWAYS enabled (deploy only agent-referenced skills)
551
+ # This ensures only skills linked to deployed agents are deployed
552
+ result = self.skills_deployer.deploy_skills(
553
+ collection=collection,
554
+ toolchain=toolchain,
555
+ categories=categories,
556
+ force=force,
557
+ selective=True, # Always use selective deployment
558
+ )
559
+
560
+ # Display results
561
+ # Show selective mode summary
562
+ if result.get("selective_mode"):
563
+ total_available = result.get("total_available", 0)
564
+ deployed_count = result["deployed_count"]
565
+ console.print(
566
+ f"[cyan]📌 Selective deployment: {deployed_count} agent-referenced skills "
567
+ f"(out of {total_available} available)[/cyan]"
568
+ )
569
+ console.print(
570
+ "[dim]Use 'claude-mpm skills configure' to manually select skills[/dim]\n"
571
+ )
572
+
573
+ if result["deployed_count"] > 0:
574
+ console.print(
575
+ f"[green]✓ Deployed {result['deployed_count']} skill(s):[/green]"
576
+ )
577
+ for skill in result["deployed_skills"]:
578
+ console.print(f" • {skill}")
579
+ console.print()
580
+
581
+ if result["skipped_count"] > 0:
582
+ console.print(
583
+ f"[yellow]⊘ Skipped {result['skipped_count']} skill(s) (already deployed):[/yellow]"
584
+ )
585
+ for skill in result["skipped_skills"]:
586
+ console.print(f" • {skill}")
587
+ console.print("[dim]Use --force to redeploy[/dim]\n")
588
+
589
+ if result["errors"]:
590
+ console.print(f"[red]✗ {len(result['errors'])} error(s):[/red]")
591
+ for error in result["errors"]:
592
+ console.print(f" • {error}")
593
+ console.print()
594
+
595
+ # Show cleanup results
596
+ cleanup = result.get("cleanup", {})
597
+ if cleanup.get("removed_count", 0) > 0:
598
+ console.print(
599
+ f"[yellow]🧹 Removed {cleanup['removed_count']} orphaned skill(s):[/yellow]"
600
+ )
601
+ for skill in cleanup.get("removed_skills", []):
602
+ console.print(f" • {skill}")
603
+ console.print()
604
+
605
+ # Show restart instructions
606
+ if result["restart_instructions"]:
607
+ console.print(
608
+ Panel(
609
+ result["restart_instructions"],
610
+ title="⚠️ Important",
611
+ border_style="yellow",
612
+ )
613
+ )
614
+ console.print()
615
+
616
+ exit_code = 1 if result["errors"] else 0
617
+ return CommandResult(success=not result["errors"], exit_code=exit_code)
618
+
619
+ except Exception as e:
620
+ console.print(f"[red]Error deploying from GitHub: {e}[/red]")
621
+ return CommandResult(success=False, message=str(e), exit_code=1)
622
+
623
+ def _list_available_github_skills(self, args) -> CommandResult:
624
+ """List available skills from GitHub repository."""
625
+ try:
626
+ collection = getattr(args, "collection", None)
627
+
628
+ if collection:
629
+ console.print(
630
+ f"\n[bold cyan]Fetching skills from collection '{collection}'...[/bold cyan]\n"
631
+ )
632
+ else:
633
+ console.print(
634
+ "\n[bold cyan]Fetching skills from default collection...[/bold cyan]\n"
635
+ )
636
+
637
+ result = self.skills_deployer.list_available_skills(collection=collection)
638
+
639
+ if result.get("error"):
640
+ console.print(f"[red]Error: {result['error']}[/red]")
641
+ return CommandResult(
642
+ success=False, message=result["error"], exit_code=1
643
+ )
644
+
645
+ console.print(
646
+ f"[green]Found {result['total_skills']} available skills[/green]\n"
647
+ )
648
+
649
+ # Display by category
650
+ console.print("[bold yellow]By Category:[/bold yellow]\n")
651
+ for category, skills in sorted(result["by_category"].items()):
652
+ console.print(f" [cyan]{category}[/cyan] ({len(skills)} skills)")
653
+ if hasattr(args, "verbose") and args.verbose:
654
+ for skill in sorted(skills, key=lambda s: s.get("name", "")):
655
+ console.print(f" • {skill.get('name', 'unknown')}")
656
+ console.print()
657
+
658
+ # Display by toolchain
659
+ console.print("[bold yellow]By Toolchain:[/bold yellow]\n")
660
+ for toolchain, skills in sorted(result["by_toolchain"].items()):
661
+ console.print(f" [cyan]{toolchain}[/cyan] ({len(skills)} skills)")
662
+ if hasattr(args, "verbose") and args.verbose:
663
+ for skill in sorted(skills, key=lambda s: s.get("name", "")):
664
+ console.print(f" • {skill.get('name', 'unknown')}")
665
+ console.print()
666
+
667
+ return CommandResult(success=True, exit_code=0)
668
+
669
+ except Exception as e:
670
+ console.print(f"[red]Error listing available skills: {e}[/red]")
671
+ return CommandResult(success=False, message=str(e), exit_code=1)
672
+
673
+ def _check_deployed_skills(self, args) -> CommandResult:
674
+ """Check currently deployed skills in ~/.claude/skills/."""
675
+ try:
676
+ result = self.skills_deployer.check_deployed_skills()
677
+
678
+ console.print("\n[bold cyan]Claude Code Skills Status:[/bold cyan]\n")
679
+ console.print(f"[dim]Directory: {result['claude_skills_dir']}[/dim]\n")
680
+
681
+ if result["deployed_count"] == 0:
682
+ console.print("[yellow]No skills currently deployed.[/yellow]")
683
+ console.print(
684
+ "[dim]Use 'claude-mpm skills deploy-github' to deploy skills.[/dim]\n"
685
+ )
686
+ return CommandResult(success=True, exit_code=0)
687
+
688
+ console.print(
689
+ f"[green]{result['deployed_count']} skill(s) deployed:[/green]\n"
690
+ )
691
+
692
+ # Create table for deployed skills
693
+ table = Table(show_header=True, header_style="bold cyan")
694
+ table.add_column("Skill Name", style="green")
695
+ table.add_column("Path", style="dim")
696
+
697
+ for skill in sorted(result["skills"], key=lambda s: s["name"]):
698
+ table.add_row(skill["name"], skill["path"])
699
+
700
+ console.print(table)
701
+ console.print()
702
+
703
+ return CommandResult(success=True, exit_code=0)
704
+
705
+ except Exception as e:
706
+ console.print(f"[red]Error checking deployed skills: {e}[/red]")
707
+ return CommandResult(success=False, message=str(e), exit_code=1)
708
+
709
+ def _remove_skills(self, args) -> CommandResult:
710
+ """Remove deployed skills."""
711
+ try:
712
+ skill_names = getattr(args, "skill_names", None)
713
+ remove_all = getattr(args, "all", False)
714
+
715
+ if remove_all:
716
+ skill_names = None
717
+ console.print(
718
+ "\n[bold yellow]Removing ALL deployed skills...[/bold yellow]\n"
719
+ )
720
+ elif skill_names:
721
+ console.print(
722
+ f"\n[bold cyan]Removing {len(skill_names)} skill(s)...[/bold cyan]\n"
723
+ )
724
+ else:
725
+ console.print("[red]Error: Specify skill names or use --all[/red]")
726
+ return CommandResult(success=False, exit_code=1)
727
+
728
+ result = self.skills_deployer.remove_skills(skill_names)
729
+
730
+ if result["removed_count"] > 0:
731
+ console.print(
732
+ f"[green]✓ Removed {result['removed_count']} skill(s):[/green]"
733
+ )
734
+ for skill in result["removed_skills"]:
735
+ console.print(f" • {skill}")
736
+ console.print()
737
+
738
+ if result["errors"]:
739
+ console.print(f"[red]✗ {len(result['errors'])} error(s):[/red]")
740
+ for error in result["errors"]:
741
+ console.print(f" • {error}")
742
+ console.print()
743
+
744
+ exit_code = 1 if result["errors"] else 0
745
+ return CommandResult(success=not result["errors"], exit_code=exit_code)
746
+
747
+ except Exception as e:
748
+ console.print(f"[red]Error removing skills: {e}[/red]")
749
+ return CommandResult(success=False, message=str(e), exit_code=1)
750
+
751
+ def _get_skill_metadata(self, skill_name: str) -> Optional[dict]:
752
+ """Get skill metadata from SKILL.md file."""
753
+ try:
754
+ skill_path = self.skills_service.get_skill_path(skill_name)
755
+ skill_md = skill_path / "SKILL.md"
756
+
757
+ if not skill_md.exists():
758
+ return None
759
+
760
+ # Parse SKILL.md metadata
761
+ content = skill_md.read_text()
762
+ return self.skills_service.parse_skill_metadata(content)
763
+
764
+ except Exception:
765
+ return None
766
+
767
+ # === Collection Management Commands ===
768
+
769
+ def _collection_list(self, args) -> CommandResult:
770
+ """List all configured skill collections."""
771
+ try:
772
+ result = self.skills_deployer.list_collections()
773
+
774
+ console.print("\n[bold cyan]Skill Collections:[/bold cyan]\n")
775
+ console.print(
776
+ f"[dim]Default collection: {result['default_collection']}[/dim]"
777
+ )
778
+ console.print(
779
+ f"[dim]Enabled: {result['enabled_count']} / {result['total_count']}[/dim]\n"
780
+ )
781
+
782
+ if not result["collections"]:
783
+ console.print("[yellow]No collections configured.[/yellow]")
784
+ console.print(
785
+ "[dim]Use 'claude-mpm skills collection-add' to add a collection.[/dim]\n"
786
+ )
787
+ return CommandResult(success=True, exit_code=0)
788
+
789
+ # Create table for collections
790
+ table = Table(show_header=True, header_style="bold cyan")
791
+ table.add_column("Name", style="green")
792
+ table.add_column("URL", style="white")
793
+ table.add_column("Priority", justify="center")
794
+ table.add_column("Enabled", justify="center")
795
+ table.add_column("Last Update", style="dim")
796
+ table.add_column("Default", justify="center")
797
+
798
+ # Sort by priority
799
+ sorted_collections = sorted(
800
+ result["collections"].items(), key=lambda x: x[1].get("priority", 999)
801
+ )
802
+
803
+ for name, config in sorted_collections:
804
+ enabled_icon = "✓" if config.get("enabled", True) else "✗"
805
+ default_icon = "⭐" if name == result["default_collection"] else ""
806
+ last_update = config.get("last_update") or "Never"
807
+
808
+ table.add_row(
809
+ name,
810
+ config["url"],
811
+ str(config.get("priority", "N/A")),
812
+ enabled_icon,
813
+ last_update,
814
+ default_icon,
815
+ )
816
+
817
+ console.print(table)
818
+ console.print()
819
+
820
+ return CommandResult(success=True, exit_code=0)
821
+
822
+ except Exception as e:
823
+ console.print(f"[red]Error listing collections: {e}[/red]")
824
+ return CommandResult(success=False, message=str(e), exit_code=1)
825
+
826
+ def _collection_add(self, args) -> CommandResult:
827
+ """Add a new skill collection."""
828
+ try:
829
+ name = getattr(args, "collection_name", None)
830
+ url = getattr(args, "collection_url", None)
831
+ priority = getattr(args, "priority", 99)
832
+
833
+ if not name or not url:
834
+ console.print("[red]Error: Collection name and URL are required[/red]")
835
+ console.print(
836
+ "[dim]Usage: claude-mpm skills collection-add NAME URL [--priority N][/dim]"
837
+ )
838
+ return CommandResult(success=False, exit_code=1)
839
+
840
+ console.print(f"\n[bold cyan]Adding collection '{name}'...[/bold cyan]\n")
841
+
842
+ result = self.skills_deployer.add_collection(name, url, priority)
843
+
844
+ console.print(f"[green]✓ {result['message']}[/green]")
845
+ console.print(f" [dim]URL: {url}[/dim]")
846
+ console.print(f" [dim]Priority: {priority}[/dim]\n")
847
+
848
+ return CommandResult(success=True, exit_code=0)
849
+
850
+ except ValueError as e:
851
+ console.print(f"[red]Error: {e}[/red]")
852
+ return CommandResult(success=False, message=str(e), exit_code=1)
853
+ except Exception as e:
854
+ console.print(f"[red]Unexpected error: {e}[/red]")
855
+ return CommandResult(success=False, message=str(e), exit_code=1)
856
+
857
+ def _collection_remove(self, args) -> CommandResult:
858
+ """Remove a skill collection."""
859
+ try:
860
+ name = getattr(args, "collection_name", None)
861
+
862
+ if not name:
863
+ console.print("[red]Error: Collection name is required[/red]")
864
+ console.print(
865
+ "[dim]Usage: claude-mpm skills collection-remove NAME[/dim]"
866
+ )
867
+ return CommandResult(success=False, exit_code=1)
868
+
869
+ console.print(
870
+ f"\n[bold yellow]Removing collection '{name}'...[/bold yellow]\n"
871
+ )
872
+
873
+ result = self.skills_deployer.remove_collection(name)
874
+
875
+ console.print(f"[green]✓ {result['message']}[/green]")
876
+ if result.get("directory_removed"):
877
+ console.print(" [dim]Collection directory removed[/dim]")
878
+ elif result.get("directory_error"):
879
+ console.print(
880
+ f" [yellow]Warning: {result['directory_error']}[/yellow]"
881
+ )
882
+ console.print()
883
+
884
+ return CommandResult(success=True, exit_code=0)
885
+
886
+ except ValueError as e:
887
+ console.print(f"[red]Error: {e}[/red]")
888
+ return CommandResult(success=False, message=str(e), exit_code=1)
889
+ except Exception as e:
890
+ console.print(f"[red]Unexpected error: {e}[/red]")
891
+ return CommandResult(success=False, message=str(e), exit_code=1)
892
+
893
+ def _collection_enable(self, args) -> CommandResult:
894
+ """Enable a disabled collection."""
895
+ try:
896
+ name = getattr(args, "collection_name", None)
897
+
898
+ if not name:
899
+ console.print("[red]Error: Collection name is required[/red]")
900
+ console.print(
901
+ "[dim]Usage: claude-mpm skills collection-enable NAME[/dim]"
902
+ )
903
+ return CommandResult(success=False, exit_code=1)
904
+
905
+ result = self.skills_deployer.enable_collection(name)
906
+
907
+ console.print(f"\n[green]✓ {result['message']}[/green]\n")
908
+
909
+ return CommandResult(success=True, exit_code=0)
910
+
911
+ except ValueError as e:
912
+ console.print(f"[red]Error: {e}[/red]")
913
+ return CommandResult(success=False, message=str(e), exit_code=1)
914
+ except Exception as e:
915
+ console.print(f"[red]Unexpected error: {e}[/red]")
916
+ return CommandResult(success=False, message=str(e), exit_code=1)
917
+
918
+ def _collection_disable(self, args) -> CommandResult:
919
+ """Disable a collection."""
920
+ try:
921
+ name = getattr(args, "collection_name", None)
922
+
923
+ if not name:
924
+ console.print("[red]Error: Collection name is required[/red]")
925
+ console.print(
926
+ "[dim]Usage: claude-mpm skills collection-disable NAME[/dim]"
927
+ )
928
+ return CommandResult(success=False, exit_code=1)
929
+
930
+ result = self.skills_deployer.disable_collection(name)
931
+
932
+ console.print(f"\n[green]✓ {result['message']}[/green]\n")
933
+
934
+ return CommandResult(success=True, exit_code=0)
935
+
936
+ except ValueError as e:
937
+ console.print(f"[red]Error: {e}[/red]")
938
+ return CommandResult(success=False, message=str(e), exit_code=1)
939
+ except Exception as e:
940
+ console.print(f"[red]Unexpected error: {e}[/red]")
941
+ return CommandResult(success=False, message=str(e), exit_code=1)
942
+
943
+ def _collection_set_default(self, args) -> CommandResult:
944
+ """Set the default collection."""
945
+ try:
946
+ name = getattr(args, "collection_name", None)
947
+
948
+ if not name:
949
+ console.print("[red]Error: Collection name is required[/red]")
950
+ console.print(
951
+ "[dim]Usage: claude-mpm skills collection-set-default NAME[/dim]"
952
+ )
953
+ return CommandResult(success=False, exit_code=1)
954
+
955
+ result = self.skills_deployer.set_default_collection(name)
956
+
957
+ console.print(f"\n[green]✓ {result['message']}[/green]")
958
+ if result.get("previous_default"):
959
+ console.print(f" [dim]Previous: {result['previous_default']}[/dim]")
960
+ console.print()
961
+
962
+ return CommandResult(success=True, exit_code=0)
963
+
964
+ except ValueError as e:
965
+ console.print(f"[red]Error: {e}[/red]")
966
+ return CommandResult(success=False, message=str(e), exit_code=1)
967
+ except Exception as e:
968
+ console.print(f"[red]Unexpected error: {e}[/red]")
969
+
970
+ def _configure_skills(self, args) -> CommandResult:
971
+ """Interactive skills configuration using configuration.yaml.
972
+
973
+ Provides checkbox-based selection interface matching agents configure UX:
974
+ - Shows current mode (user_defined vs agent_referenced)
975
+ - If agent mode: shows agent-scanned skills
976
+ - Allows switching to user_defined mode and selecting skills
977
+ - Can reset to agent mode (clears user_defined)
978
+ - Saves selections to configuration.yaml
979
+
980
+ Configuration structure:
981
+ ```yaml
982
+ skills:
983
+ agent_referenced: # Auto-populated from agent scan (read-only)
984
+ - systematic-debugging
985
+ - typescript-core
986
+ user_defined: # User override - if set, ONLY these are deployed
987
+ [] # Empty = use agent_referenced
988
+ ```
989
+ """
990
+ try:
991
+ from pathlib import Path
992
+
993
+ import questionary
994
+ import yaml
995
+ from questionary import Choice, Style
996
+ from rich.prompt import Prompt
997
+
998
+ from ...services.skills.selective_skill_deployer import (
999
+ get_skills_to_deploy,
1000
+ )
1001
+
1002
+ # Questionary style (matching agents configure)
1003
+ QUESTIONARY_STYLE = Style(
1004
+ [
1005
+ (
1006
+ "selected",
1007
+ "fg:#e0e0e0 bold",
1008
+ ), # Light gray - excellent readability
1009
+ (
1010
+ "pointer",
1011
+ "fg:#ffd700 bold",
1012
+ ), # Gold/yellow - highly visible pointer
1013
+ ("highlighted", "fg:#e0e0e0"), # Light gray - clear hover state
1014
+ (
1015
+ "question",
1016
+ "fg:#e0e0e0 bold",
1017
+ ), # Light gray bold - prominent questions
1018
+ ("checkbox", "fg:#00ff00"), # Green - for checked boxes
1019
+ (
1020
+ "checkbox-selected",
1021
+ "fg:#00ff00 bold",
1022
+ ), # Green bold - for checked selected boxes
1023
+ ]
1024
+ )
1025
+
1026
+ console.print("\n[bold cyan]Skills Configuration Manager[/bold cyan]\n")
1027
+
1028
+ # Load current configuration
1029
+ project_config_path = Path.cwd() / ".claude-mpm" / "configuration.yaml"
1030
+ skills_to_deploy, current_mode = get_skills_to_deploy(project_config_path)
1031
+
1032
+ # Display current mode and skill count
1033
+ console.print(f"[bold]Current Mode:[/bold] [cyan]{current_mode}[/cyan]")
1034
+ console.print(
1035
+ f"[bold]Active Skills:[/bold] {len(skills_to_deploy)} skills\n"
1036
+ )
1037
+
1038
+ if current_mode == "agent_referenced":
1039
+ console.print(
1040
+ "[dim]Agent mode: Skills are auto-detected from deployed agents[/dim]"
1041
+ )
1042
+ console.print(
1043
+ "[dim]Switch to user mode to manually select skills[/dim]\n"
1044
+ )
1045
+ else:
1046
+ console.print(
1047
+ "[dim]User mode: You've manually selected which skills to deploy[/dim]"
1048
+ )
1049
+ console.print("[dim]Reset to agent mode to use auto-detection[/dim]\n")
1050
+
1051
+ # Offer mode switching
1052
+ action_choices = [
1053
+ Choice("View current skills", value="view"),
1054
+ Choice("Switch to user mode (manual selection)", value="switch_user"),
1055
+ Choice("Reset to agent mode (auto-detection)", value="reset_agent"),
1056
+ Choice("Cancel", value="cancel"),
1057
+ ]
1058
+
1059
+ action = questionary.select(
1060
+ "What would you like to do?",
1061
+ choices=action_choices,
1062
+ style=QUESTIONARY_STYLE,
1063
+ ).ask()
1064
+
1065
+ if action == "cancel" or action is None:
1066
+ console.print("[yellow]Configuration cancelled[/yellow]")
1067
+ return CommandResult(success=True, exit_code=0)
1068
+
1069
+ if action == "view":
1070
+ # Display current skills
1071
+ console.print("\n[bold]Current Skills:[/bold]\n")
1072
+ for skill in sorted(skills_to_deploy):
1073
+ console.print(f" • {skill}")
1074
+ console.print()
1075
+ Prompt.ask("\nPress Enter to continue")
1076
+ return CommandResult(success=True, exit_code=0)
1077
+
1078
+ if action == "reset_agent":
1079
+ # Reset to agent mode by clearing user_defined
1080
+ with open(project_config_path, encoding="utf-8") as f:
1081
+ config = yaml.safe_load(f) or {}
1082
+
1083
+ if "skills" not in config:
1084
+ config["skills"] = {}
1085
+
1086
+ config["skills"]["user_defined"] = []
1087
+
1088
+ with open(project_config_path, "w", encoding="utf-8") as f:
1089
+ yaml.dump(config, f, default_flow_style=False, sort_keys=False)
1090
+
1091
+ console.print(
1092
+ "\n[green]✓ Reset to agent mode - skills will be auto-detected from agents[/green]\n"
1093
+ )
1094
+ Prompt.ask("\nPress Enter to continue")
1095
+ return CommandResult(success=True, exit_code=0)
1096
+
1097
+ # Switch to user mode - manual skill selection
1098
+ if action == "switch_user":
1099
+ console.print(
1100
+ "\n[bold cyan]Switching to User Mode - Manual Skill Selection[/bold cyan]\n"
1101
+ )
1102
+ console.print("[dim]Fetching available skills from GitHub...[/dim]\n")
1103
+
1104
+ # Get available skills
1105
+ available_result = self.skills_deployer.list_available_skills()
1106
+
1107
+ if available_result.get("error"):
1108
+ console.print(f"[red]Error: {available_result['error']}[/red]")
1109
+ return CommandResult(
1110
+ success=False, message=available_result["error"], exit_code=1
1111
+ )
1112
+
1113
+ # Flatten skills by category
1114
+ all_skills = []
1115
+ for category, skills in available_result.get("by_category", {}).items():
1116
+ for skill in skills:
1117
+ skill_name = skill.get("name", "unknown")
1118
+ is_currently_selected = skill_name in skills_to_deploy
1119
+ skill_info = {
1120
+ "name": skill_name,
1121
+ "category": category,
1122
+ "is_selected": is_currently_selected,
1123
+ }
1124
+ all_skills.append(skill_info)
1125
+
1126
+ # Sort by selection status (selected first), then by name
1127
+ all_skills.sort(key=lambda s: (not s["is_selected"], s["name"]))
1128
+
1129
+ # Build checkbox choices
1130
+ while True:
1131
+ skill_choices = []
1132
+
1133
+ for skill in all_skills:
1134
+ skill_name = skill["name"]
1135
+ category = skill["category"]
1136
+ is_selected = skill["is_selected"]
1137
+
1138
+ # Format: "skill-name (category)"
1139
+ choice_text = f"{skill_name} ({category})"
1140
+
1141
+ # Pre-select if currently in skills_to_deploy
1142
+ choice = Choice(
1143
+ title=choice_text, value=skill_name, checked=is_selected
1144
+ )
1145
+
1146
+ skill_choices.append(choice)
1147
+
1148
+ # Display checkbox selection
1149
+ selected_skills = questionary.checkbox(
1150
+ "Select skills (Space to toggle, Enter to confirm):",
1151
+ choices=skill_choices,
1152
+ style=QUESTIONARY_STYLE,
1153
+ ).ask()
1154
+
1155
+ if selected_skills is None:
1156
+ # User cancelled (Ctrl+C)
1157
+ console.print("[yellow]Skills configuration cancelled[/yellow]")
1158
+ return CommandResult(success=True, exit_code=0)
1159
+
1160
+ # Show summary
1161
+ console.print("\n[bold]Selected Skills:[/bold]")
1162
+ console.print(f" {len(selected_skills)} skills selected\n")
1163
+
1164
+ if selected_skills:
1165
+ for skill in sorted(selected_skills):
1166
+ console.print(f" • {skill}")
1167
+ console.print()
1168
+
1169
+ # Ask user to confirm, adjust, or cancel
1170
+ confirm_action = questionary.select(
1171
+ "\nWhat would you like to do?",
1172
+ choices=[
1173
+ Choice("Save to configuration", value="apply"),
1174
+ Choice("Adjust selection", value="adjust"),
1175
+ Choice("Cancel", value="cancel"),
1176
+ ],
1177
+ default="apply",
1178
+ style=QUESTIONARY_STYLE,
1179
+ ).ask()
1180
+
1181
+ if confirm_action == "cancel":
1182
+ console.print("[yellow]Configuration cancelled[/yellow]")
1183
+ Prompt.ask("\nPress Enter to continue")
1184
+ return CommandResult(success=True, exit_code=0)
1185
+
1186
+ if confirm_action == "adjust":
1187
+ # Update selection state and loop back
1188
+ for skill in all_skills:
1189
+ skill["is_selected"] = skill["name"] in selected_skills
1190
+ console.print("\n[dim]Adjusting selection...[/dim]\n")
1191
+ continue
1192
+
1193
+ # Save to configuration.yaml
1194
+ with open(project_config_path, encoding="utf-8") as f:
1195
+ config = yaml.safe_load(f) or {}
1196
+
1197
+ if "skills" not in config:
1198
+ config["skills"] = {}
1199
+
1200
+ config["skills"]["user_defined"] = sorted(selected_skills)
1201
+
1202
+ with open(project_config_path, "w", encoding="utf-8") as f:
1203
+ yaml.dump(config, f, default_flow_style=False, sort_keys=False)
1204
+
1205
+ console.print(
1206
+ f"\n[green]✓ Saved {len(selected_skills)} skills to user_defined mode[/green]"
1207
+ )
1208
+ console.print(
1209
+ "[yellow]⚠️ Important:[/yellow] Run [cyan]claude-mpm init[/cyan] to deploy these skills\n"
1210
+ )
1211
+ Prompt.ask("\nPress Enter to continue")
1212
+
1213
+ # Exit the loop after successful save
1214
+ break
1215
+
1216
+ return CommandResult(success=True, exit_code=0)
1217
+
1218
+ except Exception as e:
1219
+ console.print(f"[red]Error in skills configuration: {e}[/red]")
1220
+ import traceback
1221
+
1222
+ console.print(f"[dim]{traceback.format_exc()}[/dim]")
1223
+ return CommandResult(success=False, message=str(e), exit_code=1)
1224
+
1225
+
1226
+ def manage_skills(args) -> int:
1227
+ """
1228
+ Main entry point for skills command.
1229
+
1230
+ Args:
1231
+ args: Parsed command-line arguments
1232
+
1233
+ Returns:
1234
+ Exit code (0 for success, non-zero for failure)
1235
+ """
1236
+ command = SkillsManagementCommand()
1237
+
1238
+ # Validate arguments
1239
+ error = command.validate_args(args)
1240
+ if error:
1241
+ console.print(f"[red]Error: {error}[/red]")
1242
+ return 1
1243
+
1244
+ # Run command
1245
+ result = command.run(args)
1246
+ return result.exit_code