claude-mpm 4.16.0__py3-none-any.whl → 4.25.10__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 (531) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_ENGINEER.md +286 -0
  3. claude_mpm/agents/BASE_PM.md +272 -23
  4. claude_mpm/agents/OUTPUT_STYLE.md +3 -48
  5. claude_mpm/agents/PM_INSTRUCTIONS.md +1821 -32
  6. claude_mpm/agents/WORKFLOW.md +75 -2
  7. claude_mpm/agents/agent_loader.py +4 -4
  8. claude_mpm/agents/base_agent.json +6 -3
  9. claude_mpm/agents/frontmatter_validator.py +1 -1
  10. claude_mpm/agents/templates/api_qa.json +5 -2
  11. claude_mpm/agents/templates/circuit_breakers.md +108 -2
  12. claude_mpm/agents/templates/documentation.json +33 -6
  13. claude_mpm/agents/templates/engineer.json +5 -1
  14. claude_mpm/agents/templates/javascript_engineer_agent.json +380 -0
  15. claude_mpm/agents/templates/php-engineer.json +10 -4
  16. claude_mpm/agents/templates/pm_red_flags.md +89 -19
  17. claude_mpm/agents/templates/project_organizer.json +7 -3
  18. claude_mpm/agents/templates/python_engineer.json +8 -3
  19. claude_mpm/agents/templates/qa.json +2 -1
  20. claude_mpm/agents/templates/react_engineer.json +1 -0
  21. claude_mpm/agents/templates/research.json +82 -12
  22. claude_mpm/agents/templates/rust_engineer.json +12 -7
  23. claude_mpm/agents/templates/security.json +4 -4
  24. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  25. claude_mpm/agents/templates/tauri_engineer.json +274 -0
  26. claude_mpm/agents/templates/ticketing.json +10 -6
  27. claude_mpm/agents/templates/version_control.json +4 -2
  28. claude_mpm/agents/templates/web_qa.json +2 -1
  29. claude_mpm/cli/README.md +253 -0
  30. claude_mpm/cli/__init__.py +11 -1
  31. claude_mpm/cli/commands/__init__.py +2 -0
  32. claude_mpm/cli/commands/aggregate.py +1 -1
  33. claude_mpm/cli/commands/analyze.py +3 -3
  34. claude_mpm/cli/commands/cleanup.py +1 -1
  35. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  36. claude_mpm/cli/commands/debug.py +12 -12
  37. claude_mpm/cli/commands/hook_errors.py +277 -0
  38. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  39. claude_mpm/cli/commands/mcp_install_commands.py.backup +284 -0
  40. claude_mpm/cli/commands/mpm_init/README.md +365 -0
  41. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  42. claude_mpm/cli/commands/mpm_init/core.py +573 -0
  43. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  44. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  45. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  46. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  47. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  48. claude_mpm/cli/commands/mpm_init_handler.py +67 -1
  49. claude_mpm/cli/commands/run.py +124 -128
  50. claude_mpm/cli/commands/skills.py +922 -0
  51. claude_mpm/cli/executor.py +58 -0
  52. claude_mpm/cli/interactive/agent_wizard.py +5 -5
  53. claude_mpm/cli/parsers/base_parser.py +35 -0
  54. claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
  55. claude_mpm/cli/parsers/skills_parser.py +275 -0
  56. claude_mpm/cli/startup.py +168 -8
  57. claude_mpm/cli/startup_display.py +480 -0
  58. claude_mpm/cli/utils.py +1 -1
  59. claude_mpm/cli_module/commands.py +1 -1
  60. claude_mpm/cli_module/refactoring_guide.md +253 -0
  61. claude_mpm/commands/mpm-auto-configure.md +52 -0
  62. claude_mpm/commands/mpm-help.md +6 -0
  63. claude_mpm/commands/mpm-init.md +130 -8
  64. claude_mpm/commands/mpm-resume.md +372 -0
  65. claude_mpm/commands/mpm-tickets.md +56 -7
  66. claude_mpm/commands/mpm-version.md +113 -0
  67. claude_mpm/commands/mpm.md +2 -0
  68. claude_mpm/config/agent_capabilities.yaml +658 -0
  69. claude_mpm/config/agent_config.py +2 -2
  70. claude_mpm/config/async_logging_config.yaml +145 -0
  71. claude_mpm/constants.py +24 -0
  72. claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +34 -0
  73. claude_mpm/core/api_validator.py +1 -1
  74. claude_mpm/core/claude_runner.py +14 -1
  75. claude_mpm/core/config.py +50 -0
  76. claude_mpm/core/constants.py +1 -1
  77. claude_mpm/core/factories.py +1 -1
  78. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  79. claude_mpm/core/hook_error_memory.py +381 -0
  80. claude_mpm/core/hook_manager.py +41 -2
  81. claude_mpm/core/interactive_session.py +48 -3
  82. claude_mpm/core/interfaces.py +56 -1
  83. claude_mpm/core/logger.py +3 -1
  84. claude_mpm/core/oneshot_session.py +39 -0
  85. claude_mpm/core/optimized_agent_loader.py +3 -3
  86. claude_mpm/d2/.gitignore +22 -0
  87. claude_mpm/d2/ARCHITECTURE_COMPARISON.md +273 -0
  88. claude_mpm/d2/FLASK_INTEGRATION.md +156 -0
  89. claude_mpm/d2/IMPLEMENTATION_SUMMARY.md +452 -0
  90. claude_mpm/d2/QUICKSTART.md +186 -0
  91. claude_mpm/d2/README.md +232 -0
  92. claude_mpm/d2/STORE_FIX_SUMMARY.md +167 -0
  93. claude_mpm/d2/SVELTE5_STORES_GUIDE.md +180 -0
  94. claude_mpm/d2/TESTING.md +288 -0
  95. claude_mpm/d2/index.html +118 -0
  96. claude_mpm/d2/package.json +19 -0
  97. claude_mpm/d2/src/App.svelte +110 -0
  98. claude_mpm/d2/src/components/Header.svelte +153 -0
  99. claude_mpm/d2/src/components/MainContent.svelte +74 -0
  100. claude_mpm/d2/src/components/Sidebar.svelte +85 -0
  101. claude_mpm/d2/src/components/tabs/EventsTab.svelte +326 -0
  102. claude_mpm/d2/src/lib/socketio.js +144 -0
  103. claude_mpm/d2/src/main.js +7 -0
  104. claude_mpm/d2/src/stores/events.js +114 -0
  105. claude_mpm/d2/src/stores/socket.js +108 -0
  106. claude_mpm/d2/src/stores/theme.js +65 -0
  107. claude_mpm/d2/svelte.config.js +12 -0
  108. claude_mpm/d2/vite.config.js +15 -0
  109. claude_mpm/dashboard/.claude-mpm/memories/README.md +36 -0
  110. claude_mpm/dashboard/BUILD_NUMBER +1 -0
  111. claude_mpm/dashboard/README.md +121 -0
  112. claude_mpm/dashboard/VERSION +1 -0
  113. claude_mpm/dashboard/react/components/DataInspector/DataInspector.tsx +273 -0
  114. claude_mpm/dashboard/react/components/ErrorBoundary.tsx +75 -0
  115. claude_mpm/dashboard/react/components/EventViewer/EventViewer.tsx +141 -0
  116. claude_mpm/dashboard/react/components/shared/ConnectionStatus.tsx +36 -0
  117. claude_mpm/dashboard/react/components/shared/FilterBar.tsx +89 -0
  118. claude_mpm/dashboard/react/contexts/DashboardContext.tsx +215 -0
  119. claude_mpm/dashboard/react/entries/events.tsx +165 -0
  120. claude_mpm/dashboard/react/hooks/useEvents.ts +191 -0
  121. claude_mpm/dashboard/react/hooks/useSocket.ts +225 -0
  122. claude_mpm/dashboard/static/built/REFACTORING_SUMMARY.md +170 -0
  123. claude_mpm/dashboard/static/built/components/activity-tree.js.map +1 -0
  124. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +101 -101
  125. claude_mpm/dashboard/static/built/components/agent-inference.js.map +1 -0
  126. claude_mpm/dashboard/static/built/components/build-tracker.js +59 -59
  127. claude_mpm/dashboard/static/built/components/code-simple.js +107 -107
  128. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +29 -29
  129. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +24 -24
  130. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +27 -27
  131. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +25 -25
  132. claude_mpm/dashboard/static/built/components/code-tree.js.map +1 -0
  133. claude_mpm/dashboard/static/built/components/code-viewer.js.map +1 -0
  134. claude_mpm/dashboard/static/built/components/connection-debug.js +101 -101
  135. claude_mpm/dashboard/static/built/components/diff-viewer.js +113 -113
  136. claude_mpm/dashboard/static/built/components/event-processor.js.map +1 -0
  137. claude_mpm/dashboard/static/built/components/event-viewer.js.map +1 -0
  138. claude_mpm/dashboard/static/built/components/export-manager.js.map +1 -0
  139. claude_mpm/dashboard/static/built/components/file-change-tracker.js +57 -57
  140. claude_mpm/dashboard/static/built/components/file-change-viewer.js +74 -74
  141. claude_mpm/dashboard/static/built/components/file-tool-tracker.js.map +1 -0
  142. claude_mpm/dashboard/static/built/components/file-viewer.js.map +1 -0
  143. claude_mpm/dashboard/static/built/components/hud-library-loader.js.map +1 -0
  144. claude_mpm/dashboard/static/built/components/hud-manager.js.map +1 -0
  145. claude_mpm/dashboard/static/built/components/hud-visualizer.js.map +1 -0
  146. claude_mpm/dashboard/static/built/components/module-viewer.js.map +1 -0
  147. claude_mpm/dashboard/static/built/components/session-manager.js.map +1 -0
  148. claude_mpm/dashboard/static/built/components/socket-manager.js.map +1 -0
  149. claude_mpm/dashboard/static/built/components/ui-state-manager.js.map +1 -0
  150. claude_mpm/dashboard/static/built/components/unified-data-viewer.js.map +1 -0
  151. claude_mpm/dashboard/static/built/components/working-directory.js.map +1 -0
  152. claude_mpm/dashboard/static/built/connection-manager.js +76 -76
  153. claude_mpm/dashboard/static/built/dashboard.js.map +1 -0
  154. claude_mpm/dashboard/static/built/extension-error-handler.js +22 -22
  155. claude_mpm/dashboard/static/built/react/events.js.map +1 -0
  156. claude_mpm/dashboard/static/built/shared/dom-helpers.js +9 -9
  157. claude_mpm/dashboard/static/built/shared/event-bus.js +5 -5
  158. claude_mpm/dashboard/static/built/shared/logger.js +16 -16
  159. claude_mpm/dashboard/static/built/shared/tooltip-service.js +6 -6
  160. claude_mpm/dashboard/static/built/socket-client.js.map +1 -0
  161. claude_mpm/dashboard/static/css/activity.css +69 -69
  162. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  163. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  164. claude_mpm/dashboard/static/index.html +22 -22
  165. claude_mpm/dashboard/static/js/REFACTORING_SUMMARY.md +170 -0
  166. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  167. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  168. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  169. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  170. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  171. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  172. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  173. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  174. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  175. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  176. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  177. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  178. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  179. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  180. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  181. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  182. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  183. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  184. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  185. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  186. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  187. claude_mpm/dashboard/static/js/shared/dom-helpers.js +9 -9
  188. claude_mpm/dashboard/static/js/shared/event-bus.js +5 -5
  189. claude_mpm/dashboard/static/js/shared/logger.js +16 -16
  190. claude_mpm/dashboard/static/js/shared/tooltip-service.js +6 -6
  191. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  192. claude_mpm/dashboard/static/navigation-test-results.md +118 -0
  193. claude_mpm/dashboard/static/production/main.html +21 -21
  194. claude_mpm/dashboard/static/test-archive/dashboard.html +22 -22
  195. claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +36 -0
  196. claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +39 -0
  197. claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +38 -0
  198. claude_mpm/dashboard/templates/code_simple.html +23 -23
  199. claude_mpm/dashboard/templates/index.html +18 -18
  200. claude_mpm/hooks/README.md +143 -0
  201. claude_mpm/hooks/__init__.py +8 -0
  202. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  203. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  204. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  205. claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
  206. claude_mpm/hooks/session_resume_hook.py +121 -0
  207. claude_mpm/hooks/templates/README.md +180 -0
  208. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  209. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  210. claude_mpm/hooks/templates/settings.json.example +147 -0
  211. claude_mpm/models/resume_log.py +340 -0
  212. claude_mpm/schemas/agent_schema.json +596 -0
  213. claude_mpm/schemas/frontmatter_schema.json +165 -0
  214. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  215. claude_mpm/scripts/start_activity_logging.py +3 -1
  216. claude_mpm/services/agents/auto_config_manager.py +1 -1
  217. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  218. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  219. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  220. claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
  221. claude_mpm/services/agents/deployment/agent_validator.py +17 -1
  222. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  223. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  224. claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
  225. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  226. claude_mpm/services/agents/loading/framework_agent_loader.py +8 -8
  227. claude_mpm/services/agents/local_template_manager.py +4 -2
  228. claude_mpm/services/agents/recommender.py +47 -0
  229. claude_mpm/services/cli/resume_service.py +617 -0
  230. claude_mpm/services/cli/session_manager.py +87 -0
  231. claude_mpm/services/cli/session_pause_manager.py +504 -0
  232. claude_mpm/services/cli/session_resume_helper.py +372 -0
  233. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  234. claude_mpm/services/core/base.py +26 -11
  235. claude_mpm/services/core/interfaces.py +56 -1
  236. claude_mpm/services/core/models/agent_config.py +3 -0
  237. claude_mpm/services/core/models/process.py +4 -0
  238. claude_mpm/services/core/path_resolver.py +1 -1
  239. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  240. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  241. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  242. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  243. claude_mpm/services/diagnostics/doctor_reporter.py +6 -4
  244. claude_mpm/services/diagnostics/models.py +21 -0
  245. claude_mpm/services/event_bus/README.md +244 -0
  246. claude_mpm/services/event_bus/direct_relay.py +3 -3
  247. claude_mpm/services/event_bus/event_bus.py +36 -3
  248. claude_mpm/services/event_bus/relay.py +23 -7
  249. claude_mpm/services/events/README.md +303 -0
  250. claude_mpm/services/events/consumers/logging.py +1 -2
  251. claude_mpm/services/framework_claude_md_generator/README.md +119 -0
  252. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  253. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  254. claude_mpm/services/local_ops/__init__.py +2 -0
  255. claude_mpm/services/local_ops/process_manager.py +1 -1
  256. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  257. claude_mpm/services/mcp_config_manager.py +7 -131
  258. claude_mpm/services/mcp_gateway/README.md +185 -0
  259. claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
  260. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  261. claude_mpm/services/mcp_gateway/core/process_pool.py +19 -10
  262. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  263. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  264. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
  265. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  266. claude_mpm/services/memory/failure_tracker.py +19 -4
  267. claude_mpm/services/memory/optimizer.py +1 -1
  268. claude_mpm/services/model/model_router.py +8 -9
  269. claude_mpm/services/monitor/daemon.py +1 -1
  270. claude_mpm/services/monitor/server.py +2 -2
  271. claude_mpm/services/native_agent_converter.py +356 -0
  272. claude_mpm/services/port_manager.py +1 -1
  273. claude_mpm/services/project/documentation_manager.py +2 -1
  274. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  275. claude_mpm/services/runner_configuration_service.py +1 -0
  276. claude_mpm/services/self_upgrade_service.py +165 -7
  277. claude_mpm/services/session_manager.py +205 -1
  278. claude_mpm/services/skills_config.py +547 -0
  279. claude_mpm/services/skills_deployer.py +955 -0
  280. claude_mpm/services/socketio/handlers/connection.py +1 -1
  281. claude_mpm/services/socketio/handlers/connection.py.backup +217 -0
  282. claude_mpm/services/socketio/handlers/git.py +2 -2
  283. claude_mpm/services/socketio/handlers/hook.py.backup +154 -0
  284. claude_mpm/services/static/.gitkeep +2 -0
  285. claude_mpm/services/system_instructions_service.py +1 -3
  286. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  287. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  288. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  289. claude_mpm/services/unified/deployment_strategies/local.py +1 -1
  290. claude_mpm/services/version_control/VERSION +1 -0
  291. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  292. claude_mpm/services/version_service.py +104 -1
  293. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  294. claude_mpm/skills/__init__.py +21 -0
  295. claude_mpm/skills/agent_skills_injector.py +324 -0
  296. claude_mpm/skills/bundled/.gitkeep +2 -0
  297. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  298. claude_mpm/skills/bundled/api-documentation.md +393 -0
  299. claude_mpm/skills/bundled/async-testing.md +571 -0
  300. claude_mpm/skills/bundled/code-review.md +143 -0
  301. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  302. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  303. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  304. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  305. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  306. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  307. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  308. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  309. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  310. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  311. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  312. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  313. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  314. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  315. claude_mpm/skills/bundled/database-migration.md +199 -0
  316. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  317. claude_mpm/skills/bundled/debugging/root-cause-tracing/find-polluter.sh +63 -0
  318. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  319. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  320. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  321. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  322. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  323. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  324. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  325. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  326. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  327. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  328. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  329. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  330. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  331. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  332. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  333. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  334. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  335. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  336. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  337. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  338. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  339. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  340. claude_mpm/skills/bundled/git-workflow.md +414 -0
  341. claude_mpm/skills/bundled/imagemagick.md +204 -0
  342. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  343. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  344. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  345. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  346. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  347. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  348. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  349. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  350. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  351. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  352. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  353. claude_mpm/skills/bundled/main/artifacts-builder/LICENSE.txt +202 -0
  354. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  355. claude_mpm/skills/bundled/main/artifacts-builder/scripts/bundle-artifact.sh +54 -0
  356. claude_mpm/skills/bundled/main/artifacts-builder/scripts/init-artifact.sh +322 -0
  357. claude_mpm/skills/bundled/main/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  358. claude_mpm/skills/bundled/main/internal-comms/LICENSE.txt +202 -0
  359. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  360. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  361. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  362. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  363. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  364. claude_mpm/skills/bundled/main/mcp-builder/LICENSE.txt +202 -0
  365. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  366. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  367. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  368. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  369. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  370. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  371. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  372. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  373. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  374. claude_mpm/skills/bundled/main/mcp-builder/scripts/example_evaluation.xml +22 -0
  375. claude_mpm/skills/bundled/main/mcp-builder/scripts/requirements.txt +2 -0
  376. claude_mpm/skills/bundled/main/skill-creator/LICENSE.txt +202 -0
  377. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  378. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  379. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  380. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  381. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  382. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  383. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  384. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  385. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  386. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  387. claude_mpm/skills/bundled/pdf.md +141 -0
  388. claude_mpm/skills/bundled/performance-profiling.md +573 -0
  389. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  390. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  391. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  392. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  393. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  394. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  395. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  396. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  397. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  398. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  399. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  400. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  401. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  402. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  403. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  404. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  405. claude_mpm/skills/bundled/security-scanning.md +327 -0
  406. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  407. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  408. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  409. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  410. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  411. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  412. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  413. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  414. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  415. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  416. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  417. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  418. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  419. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  420. claude_mpm/skills/bundled/testing/condition-based-waiting/example.ts +158 -0
  421. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  422. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  423. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  424. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  425. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  426. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  427. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  428. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  429. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  430. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  431. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  432. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  433. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  434. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  435. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  436. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  437. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  438. claude_mpm/skills/bundled/testing/webapp-testing/LICENSE.txt +202 -0
  439. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  440. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  441. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  442. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  443. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  444. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  445. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  446. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  447. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  448. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  449. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  450. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  451. claude_mpm/skills/bundled/xlsx.md +157 -0
  452. claude_mpm/skills/registry.py +97 -9
  453. claude_mpm/skills/skills_registry.py +347 -0
  454. claude_mpm/skills/skills_service.py +739 -0
  455. claude_mpm/templates/questions/EXAMPLES.md +501 -0
  456. claude_mpm/templates/questions/__init__.py +43 -0
  457. claude_mpm/templates/questions/base.py +193 -0
  458. claude_mpm/templates/questions/pr_strategy.py +314 -0
  459. claude_mpm/templates/questions/project_init.py +388 -0
  460. claude_mpm/templates/questions/ticket_mgmt.py +397 -0
  461. claude_mpm/tools/README_SOCKETIO_DEBUG.md +224 -0
  462. claude_mpm/tools/__main__.py +8 -8
  463. claude_mpm/tools/code_tree_analyzer/README.md +64 -0
  464. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  465. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  466. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  467. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  468. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  469. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  470. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  471. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  472. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  473. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  474. claude_mpm/utils/agent_dependency_loader.py +5 -5
  475. claude_mpm/utils/dependency_cache.py +3 -1
  476. claude_mpm/utils/gitignore.py +241 -0
  477. claude_mpm/utils/log_cleanup.py +3 -3
  478. claude_mpm/utils/robust_installer.py +3 -5
  479. claude_mpm/utils/structured_questions.py +619 -0
  480. claude_mpm-4.25.10.dist-info/METADATA +789 -0
  481. {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/RECORD +485 -240
  482. claude_mpm/agents/INSTRUCTIONS_OLD_DEPRECATED.md +0 -602
  483. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  484. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  485. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  486. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  487. claude_mpm/cli/commands/mpm_init.py +0 -2008
  488. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  489. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  490. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  491. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  492. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  493. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  494. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  495. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  496. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  497. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  498. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  499. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  500. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  501. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  502. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  503. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  504. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  505. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  506. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  507. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  508. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  509. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  510. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  511. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  512. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  513. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  514. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  515. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  516. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  517. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  518. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  519. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  520. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  521. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  522. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  523. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  524. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  525. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  526. claude_mpm/tools/code_tree_analyzer.py +0 -1825
  527. claude_mpm-4.16.0.dist-info/METADATA +0 -453
  528. {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/WHEEL +0 -0
  529. {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/entry_points.txt +0 -0
  530. {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/licenses/LICENSE +0 -0
  531. {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,922 @@
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
+ # GitHub deployment commands
87
+ SkillsCommands.DEPLOY_FROM_GITHUB.value: self._deploy_from_github,
88
+ SkillsCommands.LIST_AVAILABLE.value: self._list_available_github_skills,
89
+ SkillsCommands.CHECK_DEPLOYED.value: self._check_deployed_skills,
90
+ SkillsCommands.REMOVE.value: self._remove_skills,
91
+ # Collection management commands
92
+ SkillsCommands.COLLECTION_LIST.value: self._collection_list,
93
+ SkillsCommands.COLLECTION_ADD.value: self._collection_add,
94
+ SkillsCommands.COLLECTION_REMOVE.value: self._collection_remove,
95
+ SkillsCommands.COLLECTION_ENABLE.value: self._collection_enable,
96
+ SkillsCommands.COLLECTION_DISABLE.value: self._collection_disable,
97
+ SkillsCommands.COLLECTION_SET_DEFAULT.value: self._collection_set_default,
98
+ }
99
+
100
+ handler = command_map.get(args.skills_command)
101
+ if handler:
102
+ return handler(args)
103
+ return CommandResult(
104
+ success=False,
105
+ message=f"Unknown skills command: {args.skills_command}",
106
+ exit_code=1,
107
+ )
108
+
109
+ except Exception as e:
110
+ self.logger.error(f"Skills command failed: {e}")
111
+ if hasattr(args, "debug") and args.debug:
112
+ import traceback
113
+
114
+ traceback.print_exc()
115
+ return CommandResult(
116
+ success=False, message=f"Skills command failed: {e}", exit_code=1
117
+ )
118
+
119
+ def _list_skills(self, args) -> CommandResult:
120
+ """List available skills."""
121
+ try:
122
+ # Get skills based on filter
123
+ if hasattr(args, "agent") and args.agent:
124
+ skills = self.skills_service.get_skills_for_agent(args.agent)
125
+ console.print(
126
+ f"\n[bold cyan]Skills for agent '{args.agent}':[/bold cyan]\n"
127
+ )
128
+
129
+ if not skills:
130
+ console.print(
131
+ f"[yellow]No skills found for agent '{args.agent}'[/yellow]"
132
+ )
133
+ return CommandResult(success=True, exit_code=0)
134
+
135
+ for skill_name in skills:
136
+ # Get skill metadata
137
+ skill_info = self._get_skill_metadata(skill_name)
138
+ if skill_info:
139
+ console.print(f" [green]•[/green] {skill_name}")
140
+ if (
141
+ hasattr(args, "verbose")
142
+ and args.verbose
143
+ and skill_info.get("description")
144
+ ):
145
+ console.print(f" {skill_info['description']}")
146
+ else:
147
+ console.print(f" [green]•[/green] {skill_name}")
148
+
149
+ else:
150
+ # Discover all bundled skills
151
+ skills = self.skills_service.discover_bundled_skills()
152
+
153
+ # Filter by category if specified
154
+ if hasattr(args, "category") and args.category:
155
+ skills = [s for s in skills if s.get("category") == args.category]
156
+ console.print(
157
+ f"\n[bold cyan]Skills in category '{args.category}':[/bold cyan]\n"
158
+ )
159
+ else:
160
+ console.print("\n[bold cyan]Available Skills:[/bold cyan]\n")
161
+
162
+ if not skills:
163
+ console.print("[yellow]No skills found[/yellow]")
164
+ return CommandResult(success=True, exit_code=0)
165
+
166
+ # Group by category
167
+ by_category = {}
168
+ for skill in skills:
169
+ category = skill.get("category", "uncategorized")
170
+ if category not in by_category:
171
+ by_category[category] = []
172
+ by_category[category].append(skill)
173
+
174
+ # Display by category
175
+ for category, category_skills in sorted(by_category.items()):
176
+ console.print(f"[bold yellow]{category}[/bold yellow]")
177
+ for skill in sorted(
178
+ category_skills, key=lambda s: s.get("name", "")
179
+ ):
180
+ name = skill.get("name", "unknown")
181
+ console.print(f" [green]•[/green] {name}")
182
+
183
+ if hasattr(args, "verbose") and args.verbose:
184
+ metadata = skill.get("metadata", {})
185
+ if desc := metadata.get("description"):
186
+ console.print(f" {desc}")
187
+ if version := metadata.get("version"):
188
+ console.print(f" [dim]Version: {version}[/dim]")
189
+ console.print()
190
+
191
+ return CommandResult(success=True, exit_code=0)
192
+
193
+ except Exception as e:
194
+ console.print(f"[red]Error listing skills: {e}[/red]")
195
+ return CommandResult(success=False, message=str(e), exit_code=1)
196
+
197
+ def _deploy_skills(self, args) -> CommandResult:
198
+ """Deploy bundled skills to project."""
199
+ try:
200
+ force = getattr(args, "force", False)
201
+ specific_skills = getattr(args, "skills", None)
202
+
203
+ console.print("\n[bold cyan]Deploying skills...[/bold cyan]\n")
204
+
205
+ result = self.skills_service.deploy_bundled_skills(
206
+ force=force, skill_names=specific_skills
207
+ )
208
+
209
+ # Display results
210
+ if result["deployed"]:
211
+ console.print(
212
+ f"[green]✓ Deployed {len(result['deployed'])} skill(s):[/green]"
213
+ )
214
+ for skill in result["deployed"]:
215
+ console.print(f" • {skill}")
216
+ console.print()
217
+
218
+ if result["skipped"]:
219
+ console.print(
220
+ f"[yellow]⊘ Skipped {len(result['skipped'])} skill(s) (already deployed):[/yellow]"
221
+ )
222
+ for skill in result["skipped"]:
223
+ console.print(f" • {skill}")
224
+ console.print("[dim]Use --force to redeploy[/dim]\n")
225
+
226
+ if result["errors"]:
227
+ console.print(
228
+ f"[red]✗ Failed to deploy {len(result['errors'])} skill(s):[/red]"
229
+ )
230
+ for skill, error in result["errors"].items():
231
+ console.print(f" • {skill}: {error}")
232
+ console.print()
233
+
234
+ # Summary
235
+ total = (
236
+ len(result["deployed"]) + len(result["skipped"]) + len(result["errors"])
237
+ )
238
+ console.print(
239
+ f"[bold]Summary:[/bold] {len(result['deployed'])} deployed, "
240
+ f"{len(result['skipped'])} skipped, {len(result['errors'])} errors "
241
+ f"(Total: {total})\n"
242
+ )
243
+
244
+ # Exit with error if any deployments failed
245
+ exit_code = 1 if result["errors"] else 0
246
+ return CommandResult(success=not result["errors"], exit_code=exit_code)
247
+
248
+ except Exception as e:
249
+ console.print(f"[red]Error deploying skills: {e}[/red]")
250
+ return CommandResult(success=False, message=str(e), exit_code=1)
251
+
252
+ def _validate_skill(self, args) -> CommandResult:
253
+ """Validate skill structure and metadata."""
254
+ try:
255
+ skill_name = args.skill_name
256
+ strict = getattr(args, "strict", False)
257
+
258
+ console.print(
259
+ f"\n[bold cyan]Validating skill '{skill_name}'...[/bold cyan]\n"
260
+ )
261
+
262
+ result = self.skills_service.validate_skill(skill_name)
263
+
264
+ if result["valid"]:
265
+ console.print(f"[green]✓ {skill_name} is valid[/green]\n")
266
+
267
+ if result.get("warnings"):
268
+ console.print(
269
+ f"[yellow]Warnings ({len(result['warnings'])}):[/yellow]"
270
+ )
271
+ for warning in result["warnings"]:
272
+ console.print(f" • {warning}")
273
+ console.print()
274
+
275
+ # Treat warnings as errors in strict mode
276
+ if strict:
277
+ console.print(
278
+ "[red]Strict mode: treating warnings as errors[/red]"
279
+ )
280
+ return CommandResult(success=False, exit_code=1)
281
+
282
+ return CommandResult(success=True, exit_code=0)
283
+ console.print(f"[red]✗ {skill_name} has validation errors:[/red]")
284
+ for error in result.get("errors", []):
285
+ console.print(f" • {error}")
286
+ console.print()
287
+
288
+ if result.get("warnings"):
289
+ console.print("[yellow]Warnings:[/yellow]")
290
+ for warning in result["warnings"]:
291
+ console.print(f" • {warning}")
292
+ console.print()
293
+
294
+ return CommandResult(success=False, exit_code=1)
295
+
296
+ except Exception as e:
297
+ console.print(f"[red]Error validating skill: {e}[/red]")
298
+ return CommandResult(success=False, message=str(e), exit_code=1)
299
+
300
+ def _update_skills(self, args) -> CommandResult:
301
+ """Check for and install skill updates."""
302
+ try:
303
+ skill_names = getattr(args, "skill_names", [])
304
+ check_only = getattr(args, "check_only", False)
305
+ force = getattr(args, "force", False)
306
+
307
+ action = "Checking" if check_only else "Updating"
308
+ console.print(f"\n[bold cyan]{action} skills...[/bold cyan]\n")
309
+
310
+ result = self.skills_service.check_for_updates(skill_names)
311
+
312
+ if not result.get("updates_available"):
313
+ console.print("[green]All skills are up to date[/green]\n")
314
+ return CommandResult(success=True, exit_code=0)
315
+
316
+ # Display available updates
317
+ console.print(
318
+ f"[yellow]Updates available for {len(result['updates_available'])} skill(s):[/yellow]"
319
+ )
320
+ for update_info in result["updates_available"]:
321
+ skill_name = update_info["skill"]
322
+ current = update_info["current_version"]
323
+ latest = update_info["latest_version"]
324
+ console.print(f" • {skill_name}: {current} → {latest}")
325
+ console.print()
326
+
327
+ if check_only:
328
+ console.print(
329
+ "[dim]Run without --check-only to install updates[/dim]\n"
330
+ )
331
+ return CommandResult(success=True, exit_code=0)
332
+
333
+ # Install updates
334
+ console.print("[bold cyan]Installing updates...[/bold cyan]\n")
335
+ install_result = self.skills_service.install_updates(
336
+ result["updates_available"], force=force
337
+ )
338
+
339
+ if install_result["updated"]:
340
+ console.print(
341
+ f"[green]✓ Updated {len(install_result['updated'])} skill(s)[/green]\n"
342
+ )
343
+
344
+ if install_result.get("errors"):
345
+ console.print(
346
+ f"[red]✗ Failed to update {len(install_result['errors'])} skill(s)[/red]"
347
+ )
348
+ for skill, error in install_result["errors"].items():
349
+ console.print(f" • {skill}: {error}")
350
+ console.print()
351
+
352
+ exit_code = 1 if install_result.get("errors") else 0
353
+ return CommandResult(
354
+ success=not install_result.get("errors"), exit_code=exit_code
355
+ )
356
+
357
+ except Exception as e:
358
+ console.print(f"[red]Error updating skills: {e}[/red]")
359
+ return CommandResult(success=False, message=str(e), exit_code=1)
360
+
361
+ def _show_skill_info(self, args) -> CommandResult:
362
+ """Show detailed skill information."""
363
+ try:
364
+ skill_name = args.skill_name
365
+ show_content = getattr(args, "show_content", False)
366
+
367
+ skill_info = self._get_skill_metadata(skill_name)
368
+
369
+ if not skill_info:
370
+ console.print(f"[red]Skill '{skill_name}' not found[/red]")
371
+ return CommandResult(success=False, exit_code=1)
372
+
373
+ # Display skill info in a panel
374
+ info_text = f"[bold cyan]{skill_name}[/bold cyan]\n\n"
375
+
376
+ if desc := skill_info.get("description"):
377
+ info_text += f"{desc}\n\n"
378
+
379
+ if category := skill_info.get("category"):
380
+ info_text += f"[bold]Category:[/bold] {category}\n"
381
+
382
+ if version := skill_info.get("version"):
383
+ info_text += f"[bold]Version:[/bold] {version}\n"
384
+
385
+ if source := skill_info.get("source"):
386
+ info_text += f"[bold]Source:[/bold] {source}\n"
387
+
388
+ # Show agents using this skill
389
+ agents_using = self.skills_service.get_agents_for_skill(skill_name)
390
+ if agents_using:
391
+ info_text += (
392
+ f"\n[bold]Used by agents:[/bold] {', '.join(agents_using)}\n"
393
+ )
394
+
395
+ console.print(
396
+ Panel(info_text, title="Skill Information", border_style="cyan")
397
+ )
398
+
399
+ # Show content if requested
400
+ if show_content:
401
+ skill_path = self.skills_service.get_skill_path(skill_name)
402
+ skill_md = skill_path / "SKILL.md"
403
+
404
+ if skill_md.exists():
405
+ console.print("\n[bold cyan]Skill Content:[/bold cyan]\n")
406
+ content = skill_md.read_text()
407
+ console.print(Markdown(content))
408
+ else:
409
+ console.print(
410
+ f"\n[yellow]SKILL.md not found at {skill_md}[/yellow]"
411
+ )
412
+
413
+ return CommandResult(success=True, exit_code=0)
414
+
415
+ except Exception as e:
416
+ console.print(f"[red]Error showing skill info: {e}[/red]")
417
+ return CommandResult(success=False, message=str(e), exit_code=1)
418
+
419
+ def _manage_config(self, args) -> CommandResult:
420
+ """View or edit skills configuration."""
421
+ try:
422
+ scope = getattr(args, "scope", "project")
423
+ edit = getattr(args, "edit", False)
424
+ show_path = getattr(args, "path", False)
425
+
426
+ config_path = self.skills_service.get_config_path(scope)
427
+
428
+ if show_path:
429
+ console.print(
430
+ f"\n[cyan]Configuration path ({scope}):[/cyan] {config_path}\n"
431
+ )
432
+ return CommandResult(success=True, exit_code=0)
433
+
434
+ if not config_path.exists():
435
+ console.print(
436
+ f"\n[yellow]Configuration file does not exist: {config_path}[/yellow]"
437
+ )
438
+ console.print("[dim]Would you like to create it? (y/n):[/dim] ", end="")
439
+
440
+ if input().lower() == "y":
441
+ self.skills_service.create_default_config(scope)
442
+ console.print(
443
+ f"[green]Created default configuration at {config_path}[/green]\n"
444
+ )
445
+ else:
446
+ return CommandResult(success=False, exit_code=1)
447
+
448
+ if edit:
449
+ # Open in editor
450
+ editor = os.environ.get("EDITOR", "nano")
451
+ try:
452
+ subprocess.run([editor, str(config_path)], check=True)
453
+ console.print(
454
+ f"\n[green]Configuration saved to {config_path}[/green]\n"
455
+ )
456
+ return CommandResult(success=True, exit_code=0)
457
+ except subprocess.CalledProcessError as e:
458
+ console.print(f"[red]Error opening editor: {e}[/red]")
459
+ return CommandResult(success=False, exit_code=1)
460
+ else:
461
+ # Display config
462
+ console.print(
463
+ f"\n[bold cyan]Skills Configuration ({scope}):[/bold cyan]\n"
464
+ )
465
+ console.print(f"[dim]Path: {config_path}[/dim]\n")
466
+
467
+ import yaml
468
+
469
+ config = yaml.safe_load(config_path.read_text())
470
+ console.print(yaml.dump(config, default_flow_style=False))
471
+
472
+ return CommandResult(success=True, exit_code=0)
473
+
474
+ except Exception as e:
475
+ console.print(f"[red]Error managing configuration: {e}[/red]")
476
+ return CommandResult(success=False, message=str(e), exit_code=1)
477
+
478
+ def _deploy_from_github(self, args) -> CommandResult:
479
+ """Deploy skills from GitHub repository."""
480
+ try:
481
+ collection = getattr(args, "collection", None)
482
+ toolchain = getattr(args, "toolchain", None)
483
+ categories = getattr(args, "categories", None)
484
+ force = getattr(args, "force", False)
485
+ all_skills = getattr(args, "all", False)
486
+
487
+ if collection:
488
+ console.print(
489
+ f"\n[bold cyan]Deploying skills from collection '{collection}'...[/bold cyan]\n"
490
+ )
491
+ else:
492
+ console.print(
493
+ "\n[bold cyan]Deploying skills from default collection...[/bold cyan]\n"
494
+ )
495
+
496
+ # Auto-detect toolchain if not specified and not deploying all
497
+ if not toolchain and not all_skills:
498
+ console.print(
499
+ "[yellow]No toolchain specified. Use --toolchain to filter by language,[/yellow]"
500
+ )
501
+ console.print(
502
+ "[yellow]or --all to deploy all available skills.[/yellow]\n"
503
+ )
504
+
505
+ result = self.skills_deployer.deploy_skills(
506
+ collection=collection,
507
+ toolchain=toolchain,
508
+ categories=categories,
509
+ force=force,
510
+ )
511
+
512
+ # Display results
513
+ if result["deployed_count"] > 0:
514
+ console.print(
515
+ f"[green]✓ Deployed {result['deployed_count']} skill(s):[/green]"
516
+ )
517
+ for skill in result["deployed_skills"]:
518
+ console.print(f" • {skill}")
519
+ console.print()
520
+
521
+ if result["skipped_count"] > 0:
522
+ console.print(
523
+ f"[yellow]⊘ Skipped {result['skipped_count']} skill(s) (already deployed):[/yellow]"
524
+ )
525
+ for skill in result["skipped_skills"]:
526
+ console.print(f" • {skill}")
527
+ console.print("[dim]Use --force to redeploy[/dim]\n")
528
+
529
+ if result["errors"]:
530
+ console.print(f"[red]✗ {len(result['errors'])} error(s):[/red]")
531
+ for error in result["errors"]:
532
+ console.print(f" • {error}")
533
+ console.print()
534
+
535
+ # Show restart instructions
536
+ if result["restart_instructions"]:
537
+ console.print(
538
+ Panel(
539
+ result["restart_instructions"],
540
+ title="⚠️ Important",
541
+ border_style="yellow",
542
+ )
543
+ )
544
+ console.print()
545
+
546
+ exit_code = 1 if result["errors"] else 0
547
+ return CommandResult(success=not result["errors"], exit_code=exit_code)
548
+
549
+ except Exception as e:
550
+ console.print(f"[red]Error deploying from GitHub: {e}[/red]")
551
+ return CommandResult(success=False, message=str(e), exit_code=1)
552
+
553
+ def _list_available_github_skills(self, args) -> CommandResult:
554
+ """List available skills from GitHub repository."""
555
+ try:
556
+ collection = getattr(args, "collection", None)
557
+
558
+ if collection:
559
+ console.print(
560
+ f"\n[bold cyan]Fetching skills from collection '{collection}'...[/bold cyan]\n"
561
+ )
562
+ else:
563
+ console.print(
564
+ "\n[bold cyan]Fetching skills from default collection...[/bold cyan]\n"
565
+ )
566
+
567
+ result = self.skills_deployer.list_available_skills(collection=collection)
568
+
569
+ if result.get("error"):
570
+ console.print(f"[red]Error: {result['error']}[/red]")
571
+ return CommandResult(
572
+ success=False, message=result["error"], exit_code=1
573
+ )
574
+
575
+ console.print(
576
+ f"[green]Found {result['total_skills']} available skills[/green]\n"
577
+ )
578
+
579
+ # Display by category
580
+ console.print("[bold yellow]By Category:[/bold yellow]\n")
581
+ for category, skills in sorted(result["by_category"].items()):
582
+ console.print(f" [cyan]{category}[/cyan] ({len(skills)} skills)")
583
+ if hasattr(args, "verbose") and args.verbose:
584
+ for skill in sorted(skills, key=lambda s: s.get("name", "")):
585
+ console.print(f" • {skill.get('name', 'unknown')}")
586
+ console.print()
587
+
588
+ # Display by toolchain
589
+ console.print("[bold yellow]By Toolchain:[/bold yellow]\n")
590
+ for toolchain, skills in sorted(result["by_toolchain"].items()):
591
+ console.print(f" [cyan]{toolchain}[/cyan] ({len(skills)} skills)")
592
+ if hasattr(args, "verbose") and args.verbose:
593
+ for skill in sorted(skills, key=lambda s: s.get("name", "")):
594
+ console.print(f" • {skill.get('name', 'unknown')}")
595
+ console.print()
596
+
597
+ return CommandResult(success=True, exit_code=0)
598
+
599
+ except Exception as e:
600
+ console.print(f"[red]Error listing available skills: {e}[/red]")
601
+ return CommandResult(success=False, message=str(e), exit_code=1)
602
+
603
+ def _check_deployed_skills(self, args) -> CommandResult:
604
+ """Check currently deployed skills in ~/.claude/skills/."""
605
+ try:
606
+ result = self.skills_deployer.check_deployed_skills()
607
+
608
+ console.print("\n[bold cyan]Claude Code Skills Status:[/bold cyan]\n")
609
+ console.print(f"[dim]Directory: {result['claude_skills_dir']}[/dim]\n")
610
+
611
+ if result["deployed_count"] == 0:
612
+ console.print("[yellow]No skills currently deployed.[/yellow]")
613
+ console.print(
614
+ "[dim]Use 'claude-mpm skills deploy-github' to deploy skills.[/dim]\n"
615
+ )
616
+ return CommandResult(success=True, exit_code=0)
617
+
618
+ console.print(
619
+ f"[green]{result['deployed_count']} skill(s) deployed:[/green]\n"
620
+ )
621
+
622
+ # Create table for deployed skills
623
+ table = Table(show_header=True, header_style="bold cyan")
624
+ table.add_column("Skill Name", style="green")
625
+ table.add_column("Path", style="dim")
626
+
627
+ for skill in sorted(result["skills"], key=lambda s: s["name"]):
628
+ table.add_row(skill["name"], skill["path"])
629
+
630
+ console.print(table)
631
+ console.print()
632
+
633
+ return CommandResult(success=True, exit_code=0)
634
+
635
+ except Exception as e:
636
+ console.print(f"[red]Error checking deployed skills: {e}[/red]")
637
+ return CommandResult(success=False, message=str(e), exit_code=1)
638
+
639
+ def _remove_skills(self, args) -> CommandResult:
640
+ """Remove deployed skills."""
641
+ try:
642
+ skill_names = getattr(args, "skill_names", None)
643
+ remove_all = getattr(args, "all", False)
644
+
645
+ if remove_all:
646
+ skill_names = None
647
+ console.print(
648
+ "\n[bold yellow]Removing ALL deployed skills...[/bold yellow]\n"
649
+ )
650
+ elif skill_names:
651
+ console.print(
652
+ f"\n[bold cyan]Removing {len(skill_names)} skill(s)...[/bold cyan]\n"
653
+ )
654
+ else:
655
+ console.print("[red]Error: Specify skill names or use --all[/red]")
656
+ return CommandResult(success=False, exit_code=1)
657
+
658
+ result = self.skills_deployer.remove_skills(skill_names)
659
+
660
+ if result["removed_count"] > 0:
661
+ console.print(
662
+ f"[green]✓ Removed {result['removed_count']} skill(s):[/green]"
663
+ )
664
+ for skill in result["removed_skills"]:
665
+ console.print(f" • {skill}")
666
+ console.print()
667
+
668
+ if result["errors"]:
669
+ console.print(f"[red]✗ {len(result['errors'])} error(s):[/red]")
670
+ for error in result["errors"]:
671
+ console.print(f" • {error}")
672
+ console.print()
673
+
674
+ exit_code = 1 if result["errors"] else 0
675
+ return CommandResult(success=not result["errors"], exit_code=exit_code)
676
+
677
+ except Exception as e:
678
+ console.print(f"[red]Error removing skills: {e}[/red]")
679
+ return CommandResult(success=False, message=str(e), exit_code=1)
680
+
681
+ def _get_skill_metadata(self, skill_name: str) -> Optional[dict]:
682
+ """Get skill metadata from SKILL.md file."""
683
+ try:
684
+ skill_path = self.skills_service.get_skill_path(skill_name)
685
+ skill_md = skill_path / "SKILL.md"
686
+
687
+ if not skill_md.exists():
688
+ return None
689
+
690
+ # Parse SKILL.md metadata
691
+ content = skill_md.read_text()
692
+ return self.skills_service.parse_skill_metadata(content)
693
+
694
+ except Exception:
695
+ return None
696
+
697
+ # === Collection Management Commands ===
698
+
699
+ def _collection_list(self, args) -> CommandResult:
700
+ """List all configured skill collections."""
701
+ try:
702
+ result = self.skills_deployer.list_collections()
703
+
704
+ console.print("\n[bold cyan]Skill Collections:[/bold cyan]\n")
705
+ console.print(
706
+ f"[dim]Default collection: {result['default_collection']}[/dim]"
707
+ )
708
+ console.print(
709
+ f"[dim]Enabled: {result['enabled_count']} / {result['total_count']}[/dim]\n"
710
+ )
711
+
712
+ if not result["collections"]:
713
+ console.print("[yellow]No collections configured.[/yellow]")
714
+ console.print(
715
+ "[dim]Use 'claude-mpm skills collection-add' to add a collection.[/dim]\n"
716
+ )
717
+ return CommandResult(success=True, exit_code=0)
718
+
719
+ # Create table for collections
720
+ table = Table(show_header=True, header_style="bold cyan")
721
+ table.add_column("Name", style="green")
722
+ table.add_column("URL", style="white")
723
+ table.add_column("Priority", justify="center")
724
+ table.add_column("Enabled", justify="center")
725
+ table.add_column("Last Update", style="dim")
726
+ table.add_column("Default", justify="center")
727
+
728
+ # Sort by priority
729
+ sorted_collections = sorted(
730
+ result["collections"].items(), key=lambda x: x[1].get("priority", 999)
731
+ )
732
+
733
+ for name, config in sorted_collections:
734
+ enabled_icon = "✓" if config.get("enabled", True) else "✗"
735
+ default_icon = "⭐" if name == result["default_collection"] else ""
736
+ last_update = config.get("last_update") or "Never"
737
+
738
+ table.add_row(
739
+ name,
740
+ config["url"],
741
+ str(config.get("priority", "N/A")),
742
+ enabled_icon,
743
+ last_update,
744
+ default_icon,
745
+ )
746
+
747
+ console.print(table)
748
+ console.print()
749
+
750
+ return CommandResult(success=True, exit_code=0)
751
+
752
+ except Exception as e:
753
+ console.print(f"[red]Error listing collections: {e}[/red]")
754
+ return CommandResult(success=False, message=str(e), exit_code=1)
755
+
756
+ def _collection_add(self, args) -> CommandResult:
757
+ """Add a new skill collection."""
758
+ try:
759
+ name = getattr(args, "collection_name", None)
760
+ url = getattr(args, "collection_url", None)
761
+ priority = getattr(args, "priority", 99)
762
+
763
+ if not name or not url:
764
+ console.print("[red]Error: Collection name and URL are required[/red]")
765
+ console.print(
766
+ "[dim]Usage: claude-mpm skills collection-add NAME URL [--priority N][/dim]"
767
+ )
768
+ return CommandResult(success=False, exit_code=1)
769
+
770
+ console.print(f"\n[bold cyan]Adding collection '{name}'...[/bold cyan]\n")
771
+
772
+ result = self.skills_deployer.add_collection(name, url, priority)
773
+
774
+ console.print(f"[green]✓ {result['message']}[/green]")
775
+ console.print(f" [dim]URL: {url}[/dim]")
776
+ console.print(f" [dim]Priority: {priority}[/dim]\n")
777
+
778
+ return CommandResult(success=True, exit_code=0)
779
+
780
+ except ValueError as e:
781
+ console.print(f"[red]Error: {e}[/red]")
782
+ return CommandResult(success=False, message=str(e), exit_code=1)
783
+ except Exception as e:
784
+ console.print(f"[red]Unexpected error: {e}[/red]")
785
+ return CommandResult(success=False, message=str(e), exit_code=1)
786
+
787
+ def _collection_remove(self, args) -> CommandResult:
788
+ """Remove a skill collection."""
789
+ try:
790
+ name = getattr(args, "collection_name", None)
791
+
792
+ if not name:
793
+ console.print("[red]Error: Collection name is required[/red]")
794
+ console.print(
795
+ "[dim]Usage: claude-mpm skills collection-remove NAME[/dim]"
796
+ )
797
+ return CommandResult(success=False, exit_code=1)
798
+
799
+ console.print(
800
+ f"\n[bold yellow]Removing collection '{name}'...[/bold yellow]\n"
801
+ )
802
+
803
+ result = self.skills_deployer.remove_collection(name)
804
+
805
+ console.print(f"[green]✓ {result['message']}[/green]")
806
+ if result.get("directory_removed"):
807
+ console.print(" [dim]Collection directory removed[/dim]")
808
+ elif result.get("directory_error"):
809
+ console.print(
810
+ f" [yellow]Warning: {result['directory_error']}[/yellow]"
811
+ )
812
+ console.print()
813
+
814
+ return CommandResult(success=True, exit_code=0)
815
+
816
+ except ValueError as e:
817
+ console.print(f"[red]Error: {e}[/red]")
818
+ return CommandResult(success=False, message=str(e), exit_code=1)
819
+ except Exception as e:
820
+ console.print(f"[red]Unexpected error: {e}[/red]")
821
+ return CommandResult(success=False, message=str(e), exit_code=1)
822
+
823
+ def _collection_enable(self, args) -> CommandResult:
824
+ """Enable a disabled collection."""
825
+ try:
826
+ name = getattr(args, "collection_name", None)
827
+
828
+ if not name:
829
+ console.print("[red]Error: Collection name is required[/red]")
830
+ console.print(
831
+ "[dim]Usage: claude-mpm skills collection-enable NAME[/dim]"
832
+ )
833
+ return CommandResult(success=False, exit_code=1)
834
+
835
+ result = self.skills_deployer.enable_collection(name)
836
+
837
+ console.print(f"\n[green]✓ {result['message']}[/green]\n")
838
+
839
+ return CommandResult(success=True, exit_code=0)
840
+
841
+ except ValueError as e:
842
+ console.print(f"[red]Error: {e}[/red]")
843
+ return CommandResult(success=False, message=str(e), exit_code=1)
844
+ except Exception as e:
845
+ console.print(f"[red]Unexpected error: {e}[/red]")
846
+ return CommandResult(success=False, message=str(e), exit_code=1)
847
+
848
+ def _collection_disable(self, args) -> CommandResult:
849
+ """Disable a collection."""
850
+ try:
851
+ name = getattr(args, "collection_name", None)
852
+
853
+ if not name:
854
+ console.print("[red]Error: Collection name is required[/red]")
855
+ console.print(
856
+ "[dim]Usage: claude-mpm skills collection-disable NAME[/dim]"
857
+ )
858
+ return CommandResult(success=False, exit_code=1)
859
+
860
+ result = self.skills_deployer.disable_collection(name)
861
+
862
+ console.print(f"\n[green]✓ {result['message']}[/green]\n")
863
+
864
+ return CommandResult(success=True, exit_code=0)
865
+
866
+ except ValueError as e:
867
+ console.print(f"[red]Error: {e}[/red]")
868
+ return CommandResult(success=False, message=str(e), exit_code=1)
869
+ except Exception as e:
870
+ console.print(f"[red]Unexpected error: {e}[/red]")
871
+ return CommandResult(success=False, message=str(e), exit_code=1)
872
+
873
+ def _collection_set_default(self, args) -> CommandResult:
874
+ """Set the default collection."""
875
+ try:
876
+ name = getattr(args, "collection_name", None)
877
+
878
+ if not name:
879
+ console.print("[red]Error: Collection name is required[/red]")
880
+ console.print(
881
+ "[dim]Usage: claude-mpm skills collection-set-default NAME[/dim]"
882
+ )
883
+ return CommandResult(success=False, exit_code=1)
884
+
885
+ result = self.skills_deployer.set_default_collection(name)
886
+
887
+ console.print(f"\n[green]✓ {result['message']}[/green]")
888
+ if result.get("previous_default"):
889
+ console.print(f" [dim]Previous: {result['previous_default']}[/dim]")
890
+ console.print()
891
+
892
+ return CommandResult(success=True, exit_code=0)
893
+
894
+ except ValueError as e:
895
+ console.print(f"[red]Error: {e}[/red]")
896
+ return CommandResult(success=False, message=str(e), exit_code=1)
897
+ except Exception as e:
898
+ console.print(f"[red]Unexpected error: {e}[/red]")
899
+ return CommandResult(success=False, message=str(e), exit_code=1)
900
+
901
+
902
+ def manage_skills(args) -> int:
903
+ """
904
+ Main entry point for skills command.
905
+
906
+ Args:
907
+ args: Parsed command-line arguments
908
+
909
+ Returns:
910
+ Exit code (0 for success, non-zero for failure)
911
+ """
912
+ command = SkillsManagementCommand()
913
+
914
+ # Validate arguments
915
+ error = command.validate_args(args)
916
+ if error:
917
+ console.print(f"[red]Error: {error}[/red]")
918
+ return 1
919
+
920
+ # Run command
921
+ result = command.run(args)
922
+ return result.exit_code