claude-mpm 4.20.3__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 (454) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +23 -6
  3. claude_mpm/agents/OUTPUT_STYLE.md +3 -48
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +1783 -34
  5. claude_mpm/agents/WORKFLOW.md +75 -2
  6. claude_mpm/agents/base_agent.json +6 -3
  7. claude_mpm/agents/frontmatter_validator.py +1 -1
  8. claude_mpm/agents/templates/api_qa.json +5 -2
  9. claude_mpm/agents/templates/circuit_breakers.md +108 -2
  10. claude_mpm/agents/templates/documentation.json +33 -6
  11. claude_mpm/agents/templates/javascript_engineer_agent.json +380 -0
  12. claude_mpm/agents/templates/php-engineer.json +10 -4
  13. claude_mpm/agents/templates/pm_red_flags.md +89 -19
  14. claude_mpm/agents/templates/project_organizer.json +7 -3
  15. claude_mpm/agents/templates/qa.json +2 -1
  16. claude_mpm/agents/templates/react_engineer.json +1 -0
  17. claude_mpm/agents/templates/research.json +82 -12
  18. claude_mpm/agents/templates/security.json +4 -4
  19. claude_mpm/agents/templates/tauri_engineer.json +274 -0
  20. claude_mpm/agents/templates/ticketing.json +10 -6
  21. claude_mpm/agents/templates/version_control.json +4 -2
  22. claude_mpm/agents/templates/web_qa.json +2 -1
  23. claude_mpm/cli/README.md +253 -0
  24. claude_mpm/cli/__init__.py +11 -1
  25. claude_mpm/cli/commands/aggregate.py +1 -1
  26. claude_mpm/cli/commands/analyze.py +3 -3
  27. claude_mpm/cli/commands/cleanup.py +1 -1
  28. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  29. claude_mpm/cli/commands/debug.py +12 -12
  30. claude_mpm/cli/commands/hook_errors.py +277 -0
  31. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  32. claude_mpm/cli/commands/mcp_install_commands.py.backup +284 -0
  33. claude_mpm/cli/commands/mpm_init/README.md +365 -0
  34. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  35. claude_mpm/cli/commands/mpm_init/core.py +573 -0
  36. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  37. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  38. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  39. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  40. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  41. claude_mpm/cli/commands/mpm_init_handler.py +67 -1
  42. claude_mpm/cli/commands/run.py +124 -128
  43. claude_mpm/cli/commands/skills.py +522 -34
  44. claude_mpm/cli/executor.py +56 -0
  45. claude_mpm/cli/interactive/agent_wizard.py +5 -5
  46. claude_mpm/cli/parsers/base_parser.py +28 -0
  47. claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
  48. claude_mpm/cli/parsers/skills_parser.py +138 -0
  49. claude_mpm/cli/startup.py +111 -8
  50. claude_mpm/cli/startup_display.py +480 -0
  51. claude_mpm/cli/utils.py +1 -1
  52. claude_mpm/cli_module/commands.py +1 -1
  53. claude_mpm/cli_module/refactoring_guide.md +253 -0
  54. claude_mpm/commands/mpm-help.md +3 -0
  55. claude_mpm/commands/mpm-init.md +19 -3
  56. claude_mpm/commands/mpm-resume.md +372 -0
  57. claude_mpm/commands/mpm-tickets.md +56 -7
  58. claude_mpm/commands/mpm.md +1 -0
  59. claude_mpm/config/agent_capabilities.yaml +658 -0
  60. claude_mpm/config/async_logging_config.yaml +145 -0
  61. claude_mpm/constants.py +12 -0
  62. claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +34 -0
  63. claude_mpm/core/api_validator.py +1 -1
  64. claude_mpm/core/claude_runner.py +14 -1
  65. claude_mpm/core/config.py +8 -0
  66. claude_mpm/core/constants.py +1 -1
  67. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  68. claude_mpm/core/hook_error_memory.py +381 -0
  69. claude_mpm/core/hook_manager.py +41 -2
  70. claude_mpm/core/interactive_session.py +48 -3
  71. claude_mpm/core/interfaces.py +56 -1
  72. claude_mpm/core/logger.py +3 -1
  73. claude_mpm/core/oneshot_session.py +39 -0
  74. claude_mpm/d2/.gitignore +22 -0
  75. claude_mpm/d2/ARCHITECTURE_COMPARISON.md +273 -0
  76. claude_mpm/d2/FLASK_INTEGRATION.md +156 -0
  77. claude_mpm/d2/IMPLEMENTATION_SUMMARY.md +452 -0
  78. claude_mpm/d2/QUICKSTART.md +186 -0
  79. claude_mpm/d2/README.md +232 -0
  80. claude_mpm/d2/STORE_FIX_SUMMARY.md +167 -0
  81. claude_mpm/d2/SVELTE5_STORES_GUIDE.md +180 -0
  82. claude_mpm/d2/TESTING.md +288 -0
  83. claude_mpm/d2/index.html +118 -0
  84. claude_mpm/d2/package.json +19 -0
  85. claude_mpm/d2/src/App.svelte +110 -0
  86. claude_mpm/d2/src/components/Header.svelte +153 -0
  87. claude_mpm/d2/src/components/MainContent.svelte +74 -0
  88. claude_mpm/d2/src/components/Sidebar.svelte +85 -0
  89. claude_mpm/d2/src/components/tabs/EventsTab.svelte +326 -0
  90. claude_mpm/d2/src/lib/socketio.js +144 -0
  91. claude_mpm/d2/src/main.js +7 -0
  92. claude_mpm/d2/src/stores/events.js +114 -0
  93. claude_mpm/d2/src/stores/socket.js +108 -0
  94. claude_mpm/d2/src/stores/theme.js +65 -0
  95. claude_mpm/d2/svelte.config.js +12 -0
  96. claude_mpm/d2/vite.config.js +15 -0
  97. claude_mpm/dashboard/.claude-mpm/memories/README.md +36 -0
  98. claude_mpm/dashboard/BUILD_NUMBER +1 -0
  99. claude_mpm/dashboard/README.md +121 -0
  100. claude_mpm/dashboard/VERSION +1 -0
  101. claude_mpm/dashboard/react/components/DataInspector/DataInspector.tsx +273 -0
  102. claude_mpm/dashboard/react/components/ErrorBoundary.tsx +75 -0
  103. claude_mpm/dashboard/react/components/EventViewer/EventViewer.tsx +141 -0
  104. claude_mpm/dashboard/react/components/shared/ConnectionStatus.tsx +36 -0
  105. claude_mpm/dashboard/react/components/shared/FilterBar.tsx +89 -0
  106. claude_mpm/dashboard/react/contexts/DashboardContext.tsx +215 -0
  107. claude_mpm/dashboard/react/entries/events.tsx +165 -0
  108. claude_mpm/dashboard/react/hooks/useEvents.ts +191 -0
  109. claude_mpm/dashboard/react/hooks/useSocket.ts +225 -0
  110. claude_mpm/dashboard/static/built/REFACTORING_SUMMARY.md +170 -0
  111. claude_mpm/dashboard/static/built/components/activity-tree.js.map +1 -0
  112. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +101 -101
  113. claude_mpm/dashboard/static/built/components/agent-inference.js.map +1 -0
  114. claude_mpm/dashboard/static/built/components/build-tracker.js +59 -59
  115. claude_mpm/dashboard/static/built/components/code-simple.js +107 -107
  116. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +29 -29
  117. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +24 -24
  118. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +27 -27
  119. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +25 -25
  120. claude_mpm/dashboard/static/built/components/code-tree.js.map +1 -0
  121. claude_mpm/dashboard/static/built/components/code-viewer.js.map +1 -0
  122. claude_mpm/dashboard/static/built/components/connection-debug.js +101 -101
  123. claude_mpm/dashboard/static/built/components/diff-viewer.js +113 -113
  124. claude_mpm/dashboard/static/built/components/event-processor.js.map +1 -0
  125. claude_mpm/dashboard/static/built/components/event-viewer.js.map +1 -0
  126. claude_mpm/dashboard/static/built/components/export-manager.js.map +1 -0
  127. claude_mpm/dashboard/static/built/components/file-change-tracker.js +57 -57
  128. claude_mpm/dashboard/static/built/components/file-change-viewer.js +74 -74
  129. claude_mpm/dashboard/static/built/components/file-tool-tracker.js.map +1 -0
  130. claude_mpm/dashboard/static/built/components/file-viewer.js.map +1 -0
  131. claude_mpm/dashboard/static/built/components/hud-library-loader.js.map +1 -0
  132. claude_mpm/dashboard/static/built/components/hud-manager.js.map +1 -0
  133. claude_mpm/dashboard/static/built/components/hud-visualizer.js.map +1 -0
  134. claude_mpm/dashboard/static/built/components/module-viewer.js.map +1 -0
  135. claude_mpm/dashboard/static/built/components/session-manager.js.map +1 -0
  136. claude_mpm/dashboard/static/built/components/socket-manager.js.map +1 -0
  137. claude_mpm/dashboard/static/built/components/ui-state-manager.js.map +1 -0
  138. claude_mpm/dashboard/static/built/components/unified-data-viewer.js.map +1 -0
  139. claude_mpm/dashboard/static/built/components/working-directory.js.map +1 -0
  140. claude_mpm/dashboard/static/built/connection-manager.js +76 -76
  141. claude_mpm/dashboard/static/built/dashboard.js.map +1 -0
  142. claude_mpm/dashboard/static/built/extension-error-handler.js +22 -22
  143. claude_mpm/dashboard/static/built/react/events.js.map +1 -0
  144. claude_mpm/dashboard/static/built/shared/dom-helpers.js +9 -9
  145. claude_mpm/dashboard/static/built/shared/event-bus.js +5 -5
  146. claude_mpm/dashboard/static/built/shared/logger.js +16 -16
  147. claude_mpm/dashboard/static/built/shared/tooltip-service.js +6 -6
  148. claude_mpm/dashboard/static/built/socket-client.js.map +1 -0
  149. claude_mpm/dashboard/static/css/activity.css +69 -69
  150. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  151. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  152. claude_mpm/dashboard/static/index.html +22 -22
  153. claude_mpm/dashboard/static/js/REFACTORING_SUMMARY.md +170 -0
  154. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  155. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  156. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  157. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  158. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  159. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  160. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  161. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  162. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  163. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  164. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  165. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  166. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  167. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  168. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  169. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  170. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  171. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  172. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  173. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  174. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  175. claude_mpm/dashboard/static/js/shared/dom-helpers.js +9 -9
  176. claude_mpm/dashboard/static/js/shared/event-bus.js +5 -5
  177. claude_mpm/dashboard/static/js/shared/logger.js +16 -16
  178. claude_mpm/dashboard/static/js/shared/tooltip-service.js +6 -6
  179. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  180. claude_mpm/dashboard/static/navigation-test-results.md +118 -0
  181. claude_mpm/dashboard/static/production/main.html +21 -21
  182. claude_mpm/dashboard/static/test-archive/dashboard.html +22 -22
  183. claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +36 -0
  184. claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +39 -0
  185. claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +38 -0
  186. claude_mpm/dashboard/templates/code_simple.html +23 -23
  187. claude_mpm/dashboard/templates/index.html +18 -18
  188. claude_mpm/hooks/README.md +143 -0
  189. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  190. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  191. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  192. claude_mpm/hooks/templates/README.md +180 -0
  193. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  194. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  195. claude_mpm/hooks/templates/settings.json.example +147 -0
  196. claude_mpm/schemas/agent_schema.json +596 -0
  197. claude_mpm/schemas/frontmatter_schema.json +165 -0
  198. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  199. claude_mpm/scripts/start_activity_logging.py +3 -1
  200. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  201. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  202. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  203. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  204. claude_mpm/services/agents/loading/framework_agent_loader.py +8 -8
  205. claude_mpm/services/agents/local_template_manager.py +3 -1
  206. claude_mpm/services/cli/session_pause_manager.py +504 -0
  207. claude_mpm/services/cli/session_resume_helper.py +36 -16
  208. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  209. claude_mpm/services/core/base.py +26 -11
  210. claude_mpm/services/core/interfaces.py +56 -1
  211. claude_mpm/services/core/models/agent_config.py +3 -0
  212. claude_mpm/services/core/models/process.py +4 -0
  213. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  214. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  215. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  216. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  217. claude_mpm/services/diagnostics/doctor_reporter.py +6 -4
  218. claude_mpm/services/diagnostics/models.py +21 -0
  219. claude_mpm/services/event_bus/README.md +244 -0
  220. claude_mpm/services/event_bus/direct_relay.py +3 -3
  221. claude_mpm/services/event_bus/event_bus.py +36 -3
  222. claude_mpm/services/event_bus/relay.py +23 -7
  223. claude_mpm/services/events/README.md +303 -0
  224. claude_mpm/services/events/consumers/logging.py +1 -2
  225. claude_mpm/services/framework_claude_md_generator/README.md +119 -0
  226. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  227. claude_mpm/services/local_ops/__init__.py +2 -0
  228. claude_mpm/services/local_ops/process_manager.py +1 -1
  229. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  230. claude_mpm/services/mcp_gateway/README.md +185 -0
  231. claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
  232. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  233. claude_mpm/services/mcp_gateway/core/process_pool.py +19 -10
  234. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  235. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  236. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
  237. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  238. claude_mpm/services/memory/failure_tracker.py +19 -4
  239. claude_mpm/services/memory/optimizer.py +1 -1
  240. claude_mpm/services/model/model_router.py +8 -9
  241. claude_mpm/services/monitor/daemon.py +1 -1
  242. claude_mpm/services/monitor/server.py +2 -2
  243. claude_mpm/services/native_agent_converter.py +356 -0
  244. claude_mpm/services/port_manager.py +1 -1
  245. claude_mpm/services/project/documentation_manager.py +2 -1
  246. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  247. claude_mpm/services/runner_configuration_service.py +1 -0
  248. claude_mpm/services/self_upgrade_service.py +165 -7
  249. claude_mpm/services/skills_config.py +547 -0
  250. claude_mpm/services/skills_deployer.py +955 -0
  251. claude_mpm/services/socketio/handlers/connection.py +1 -1
  252. claude_mpm/services/socketio/handlers/connection.py.backup +217 -0
  253. claude_mpm/services/socketio/handlers/git.py +2 -2
  254. claude_mpm/services/socketio/handlers/hook.py.backup +154 -0
  255. claude_mpm/services/static/.gitkeep +2 -0
  256. claude_mpm/services/system_instructions_service.py +1 -3
  257. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  258. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  259. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  260. claude_mpm/services/version_control/VERSION +1 -0
  261. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  262. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  263. claude_mpm/skills/__init__.py +3 -3
  264. claude_mpm/skills/agent_skills_injector.py +42 -49
  265. claude_mpm/skills/bundled/.gitkeep +2 -0
  266. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +4 -0
  267. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +108 -114
  268. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  269. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  270. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  271. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  272. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  273. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +46 -41
  274. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  275. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  276. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +36 -73
  277. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  278. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  279. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +100 -125
  280. claude_mpm/skills/bundled/debugging/root-cause-tracing/find-polluter.sh +63 -0
  281. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  282. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  283. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  284. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  285. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +28 -72
  286. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +11 -0
  287. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  288. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  289. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +272 -0
  290. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  291. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  292. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  293. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  294. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  295. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  296. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  297. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  298. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  299. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  300. claude_mpm/skills/bundled/main/artifacts-builder/LICENSE.txt +202 -0
  301. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +13 -1
  302. claude_mpm/skills/bundled/main/artifacts-builder/scripts/bundle-artifact.sh +54 -0
  303. claude_mpm/skills/bundled/main/artifacts-builder/scripts/init-artifact.sh +322 -0
  304. claude_mpm/skills/bundled/main/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  305. claude_mpm/skills/bundled/main/internal-comms/LICENSE.txt +202 -0
  306. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +11 -0
  307. claude_mpm/skills/bundled/main/mcp-builder/LICENSE.txt +202 -0
  308. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +109 -277
  309. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  310. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  311. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +17 -10
  312. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +92 -39
  313. claude_mpm/skills/bundled/main/mcp-builder/scripts/example_evaluation.xml +22 -0
  314. claude_mpm/skills/bundled/main/mcp-builder/scripts/requirements.txt +2 -0
  315. claude_mpm/skills/bundled/main/skill-creator/LICENSE.txt +202 -0
  316. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +135 -155
  317. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  318. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  319. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  320. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  321. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  322. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +13 -12
  323. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +5 -3
  324. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +19 -12
  325. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  326. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  327. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  328. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  329. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  330. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  331. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  332. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  333. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  334. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  335. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  336. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  337. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  338. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  339. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  340. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  341. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  342. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  343. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  344. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  345. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  346. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  347. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  348. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  349. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  350. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  351. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  352. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +21 -25
  353. claude_mpm/skills/bundled/testing/condition-based-waiting/example.ts +158 -0
  354. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  355. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  356. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  357. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  358. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  359. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  360. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +86 -250
  361. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  362. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  363. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  364. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  365. claude_mpm/skills/bundled/testing/webapp-testing/LICENSE.txt +202 -0
  366. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +145 -57
  367. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  368. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +6 -6
  369. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +13 -9
  370. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +8 -8
  371. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  372. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  373. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +37 -15
  374. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  375. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  376. claude_mpm/skills/skills_registry.py +44 -48
  377. claude_mpm/skills/skills_service.py +117 -108
  378. claude_mpm/templates/questions/EXAMPLES.md +501 -0
  379. claude_mpm/templates/questions/__init__.py +43 -0
  380. claude_mpm/templates/questions/base.py +193 -0
  381. claude_mpm/templates/questions/pr_strategy.py +314 -0
  382. claude_mpm/templates/questions/project_init.py +388 -0
  383. claude_mpm/templates/questions/ticket_mgmt.py +397 -0
  384. claude_mpm/tools/README_SOCKETIO_DEBUG.md +224 -0
  385. claude_mpm/tools/__main__.py +8 -8
  386. claude_mpm/tools/code_tree_analyzer/README.md +64 -0
  387. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  388. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  389. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  390. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  391. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  392. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  393. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  394. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  395. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  396. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  397. claude_mpm/utils/agent_dependency_loader.py +3 -3
  398. claude_mpm/utils/dependency_cache.py +3 -1
  399. claude_mpm/utils/gitignore.py +241 -0
  400. claude_mpm/utils/log_cleanup.py +3 -3
  401. claude_mpm/utils/robust_installer.py +3 -5
  402. claude_mpm/utils/structured_questions.py +619 -0
  403. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/METADATA +218 -31
  404. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/RECORD +409 -246
  405. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  406. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  407. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  408. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  409. claude_mpm/cli/commands/mpm_init.py +0 -2093
  410. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  411. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  412. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  413. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  414. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  415. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  416. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  417. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  418. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  419. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  420. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  421. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  422. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  423. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  424. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  425. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  426. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  427. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  428. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  429. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  430. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  431. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  432. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  433. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  434. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  435. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  436. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  437. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  438. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  439. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  440. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  441. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  442. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  443. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  444. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  445. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  446. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  447. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  448. claude_mpm/skills/bundled/debugging/verification-before-completion/references/common-failures.md +0 -213
  449. claude_mpm/tools/code_tree_analyzer.py +0 -1825
  450. /claude_mpm/skills/bundled/collaboration/requesting-code-review/{code-reviewer.md → references/code-reviewer-template.md} +0 -0
  451. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/WHEEL +0 -0
  452. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/entry_points.txt +0 -0
  453. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/licenses/LICENSE +0 -0
  454. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/top_level.txt +0 -0
@@ -3,13 +3,18 @@ Skills command implementation for claude-mpm.
3
3
 
4
4
  WHY: This module provides CLI commands for managing Claude Code skills,
5
5
  exposing SkillsService functionality for skill discovery, deployment, validation,
6
- updates, and configuration.
6
+ updates, and configuration. Also provides GitHub skills deployment via SkillsDeployer.
7
7
 
8
8
  DESIGN DECISIONS:
9
9
  - Use BaseCommand pattern for consistency with other CLI commands
10
10
  - Rich output formatting for user-friendly display
11
11
  - Graceful error handling with informative messages
12
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
13
18
  """
14
19
 
15
20
  import os
@@ -19,8 +24,10 @@ from typing import Optional
19
24
  from rich.console import Console
20
25
  from rich.markdown import Markdown
21
26
  from rich.panel import Panel
27
+ from rich.table import Table
22
28
 
23
29
  from ...constants import SkillsCommands
30
+ from ...services.skills_deployer import SkillsDeployerService
24
31
  from ...skills.skills_service import SkillsService
25
32
  from ..shared import BaseCommand, CommandResult
26
33
 
@@ -33,6 +40,7 @@ class SkillsManagementCommand(BaseCommand):
33
40
  def __init__(self):
34
41
  super().__init__("skills")
35
42
  self._skills_service = None
43
+ self._skills_deployer = None
36
44
 
37
45
  @property
38
46
  def skills_service(self) -> SkillsService:
@@ -41,6 +49,13 @@ class SkillsManagementCommand(BaseCommand):
41
49
  self._skills_service = SkillsService()
42
50
  return self._skills_service
43
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
+
44
59
  def validate_args(self, args) -> Optional[str]:
45
60
  """Validate command arguments."""
46
61
  # Most skills commands are optional, basic validation
@@ -68,6 +83,18 @@ class SkillsManagementCommand(BaseCommand):
68
83
  SkillsCommands.UPDATE.value: self._update_skills,
69
84
  SkillsCommands.INFO.value: self._show_skill_info,
70
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,
71
98
  }
72
99
 
73
100
  handler = command_map.get(args.skills_command)
@@ -83,6 +110,7 @@ class SkillsManagementCommand(BaseCommand):
83
110
  self.logger.error(f"Skills command failed: {e}")
84
111
  if hasattr(args, "debug") and args.debug:
85
112
  import traceback
113
+
86
114
  traceback.print_exc()
87
115
  return CommandResult(
88
116
  success=False, message=f"Skills command failed: {e}", exit_code=1
@@ -94,10 +122,14 @@ class SkillsManagementCommand(BaseCommand):
94
122
  # Get skills based on filter
95
123
  if hasattr(args, "agent") and args.agent:
96
124
  skills = self.skills_service.get_skills_for_agent(args.agent)
97
- console.print(f"\n[bold cyan]Skills for agent '{args.agent}':[/bold cyan]\n")
125
+ console.print(
126
+ f"\n[bold cyan]Skills for agent '{args.agent}':[/bold cyan]\n"
127
+ )
98
128
 
99
129
  if not skills:
100
- console.print(f"[yellow]No skills found for agent '{args.agent}'[/yellow]")
130
+ console.print(
131
+ f"[yellow]No skills found for agent '{args.agent}'[/yellow]"
132
+ )
101
133
  return CommandResult(success=True, exit_code=0)
102
134
 
103
135
  for skill_name in skills:
@@ -105,7 +137,11 @@ class SkillsManagementCommand(BaseCommand):
105
137
  skill_info = self._get_skill_metadata(skill_name)
106
138
  if skill_info:
107
139
  console.print(f" [green]•[/green] {skill_name}")
108
- if hasattr(args, "verbose") and args.verbose and skill_info.get("description"):
140
+ if (
141
+ hasattr(args, "verbose")
142
+ and args.verbose
143
+ and skill_info.get("description")
144
+ ):
109
145
  console.print(f" {skill_info['description']}")
110
146
  else:
111
147
  console.print(f" [green]•[/green] {skill_name}")
@@ -117,7 +153,9 @@ class SkillsManagementCommand(BaseCommand):
117
153
  # Filter by category if specified
118
154
  if hasattr(args, "category") and args.category:
119
155
  skills = [s for s in skills if s.get("category") == args.category]
120
- console.print(f"\n[bold cyan]Skills in category '{args.category}':[/bold cyan]\n")
156
+ console.print(
157
+ f"\n[bold cyan]Skills in category '{args.category}':[/bold cyan]\n"
158
+ )
121
159
  else:
122
160
  console.print("\n[bold cyan]Available Skills:[/bold cyan]\n")
123
161
 
@@ -136,7 +174,9 @@ class SkillsManagementCommand(BaseCommand):
136
174
  # Display by category
137
175
  for category, category_skills in sorted(by_category.items()):
138
176
  console.print(f"[bold yellow]{category}[/bold yellow]")
139
- for skill in sorted(category_skills, key=lambda s: s.get("name", "")):
177
+ for skill in sorted(
178
+ category_skills, key=lambda s: s.get("name", "")
179
+ ):
140
180
  name = skill.get("name", "unknown")
141
181
  console.print(f" [green]•[/green] {name}")
142
182
 
@@ -163,34 +203,43 @@ class SkillsManagementCommand(BaseCommand):
163
203
  console.print("\n[bold cyan]Deploying skills...[/bold cyan]\n")
164
204
 
165
205
  result = self.skills_service.deploy_bundled_skills(
166
- force=force,
167
- skill_names=specific_skills
206
+ force=force, skill_names=specific_skills
168
207
  )
169
208
 
170
209
  # Display results
171
210
  if result["deployed"]:
172
- console.print(f"[green]✓ Deployed {len(result['deployed'])} skill(s):[/green]")
211
+ console.print(
212
+ f"[green]✓ Deployed {len(result['deployed'])} skill(s):[/green]"
213
+ )
173
214
  for skill in result["deployed"]:
174
215
  console.print(f" • {skill}")
175
216
  console.print()
176
217
 
177
218
  if result["skipped"]:
178
- console.print(f"[yellow]⊘ Skipped {len(result['skipped'])} skill(s) (already deployed):[/yellow]")
219
+ console.print(
220
+ f"[yellow]⊘ Skipped {len(result['skipped'])} skill(s) (already deployed):[/yellow]"
221
+ )
179
222
  for skill in result["skipped"]:
180
223
  console.print(f" • {skill}")
181
224
  console.print("[dim]Use --force to redeploy[/dim]\n")
182
225
 
183
226
  if result["errors"]:
184
- console.print(f"[red]✗ Failed to deploy {len(result['errors'])} skill(s):[/red]")
227
+ console.print(
228
+ f"[red]✗ Failed to deploy {len(result['errors'])} skill(s):[/red]"
229
+ )
185
230
  for skill, error in result["errors"].items():
186
231
  console.print(f" • {skill}: {error}")
187
232
  console.print()
188
233
 
189
234
  # Summary
190
- total = len(result["deployed"]) + len(result["skipped"]) + len(result["errors"])
191
- console.print(f"[bold]Summary:[/bold] {len(result['deployed'])} deployed, "
192
- f"{len(result['skipped'])} skipped, {len(result['errors'])} errors "
193
- f"(Total: {total})\n")
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
+ )
194
243
 
195
244
  # Exit with error if any deployments failed
196
245
  exit_code = 1 if result["errors"] else 0
@@ -206,7 +255,9 @@ class SkillsManagementCommand(BaseCommand):
206
255
  skill_name = args.skill_name
207
256
  strict = getattr(args, "strict", False)
208
257
 
209
- console.print(f"\n[bold cyan]Validating skill '{skill_name}'...[/bold cyan]\n")
258
+ console.print(
259
+ f"\n[bold cyan]Validating skill '{skill_name}'...[/bold cyan]\n"
260
+ )
210
261
 
211
262
  result = self.skills_service.validate_skill(skill_name)
212
263
 
@@ -214,14 +265,18 @@ class SkillsManagementCommand(BaseCommand):
214
265
  console.print(f"[green]✓ {skill_name} is valid[/green]\n")
215
266
 
216
267
  if result.get("warnings"):
217
- console.print(f"[yellow]Warnings ({len(result['warnings'])}):[/yellow]")
268
+ console.print(
269
+ f"[yellow]Warnings ({len(result['warnings'])}):[/yellow]"
270
+ )
218
271
  for warning in result["warnings"]:
219
272
  console.print(f" • {warning}")
220
273
  console.print()
221
274
 
222
275
  # Treat warnings as errors in strict mode
223
276
  if strict:
224
- console.print("[red]Strict mode: treating warnings as errors[/red]")
277
+ console.print(
278
+ "[red]Strict mode: treating warnings as errors[/red]"
279
+ )
225
280
  return CommandResult(success=False, exit_code=1)
226
281
 
227
282
  return CommandResult(success=True, exit_code=0)
@@ -259,7 +314,9 @@ class SkillsManagementCommand(BaseCommand):
259
314
  return CommandResult(success=True, exit_code=0)
260
315
 
261
316
  # Display available updates
262
- console.print(f"[yellow]Updates available for {len(result['updates_available'])} skill(s):[/yellow]")
317
+ console.print(
318
+ f"[yellow]Updates available for {len(result['updates_available'])} skill(s):[/yellow]"
319
+ )
263
320
  for update_info in result["updates_available"]:
264
321
  skill_name = update_info["skill"]
265
322
  current = update_info["current_version"]
@@ -268,7 +325,9 @@ class SkillsManagementCommand(BaseCommand):
268
325
  console.print()
269
326
 
270
327
  if check_only:
271
- console.print("[dim]Run without --check-only to install updates[/dim]\n")
328
+ console.print(
329
+ "[dim]Run without --check-only to install updates[/dim]\n"
330
+ )
272
331
  return CommandResult(success=True, exit_code=0)
273
332
 
274
333
  # Install updates
@@ -278,16 +337,22 @@ class SkillsManagementCommand(BaseCommand):
278
337
  )
279
338
 
280
339
  if install_result["updated"]:
281
- console.print(f"[green]✓ Updated {len(install_result['updated'])} skill(s)[/green]\n")
340
+ console.print(
341
+ f"[green]✓ Updated {len(install_result['updated'])} skill(s)[/green]\n"
342
+ )
282
343
 
283
344
  if install_result.get("errors"):
284
- console.print(f"[red]✗ Failed to update {len(install_result['errors'])} skill(s)[/red]")
345
+ console.print(
346
+ f"[red]✗ Failed to update {len(install_result['errors'])} skill(s)[/red]"
347
+ )
285
348
  for skill, error in install_result["errors"].items():
286
349
  console.print(f" • {skill}: {error}")
287
350
  console.print()
288
351
 
289
352
  exit_code = 1 if install_result.get("errors") else 0
290
- return CommandResult(success=not install_result.get("errors"), exit_code=exit_code)
353
+ return CommandResult(
354
+ success=not install_result.get("errors"), exit_code=exit_code
355
+ )
291
356
 
292
357
  except Exception as e:
293
358
  console.print(f"[red]Error updating skills: {e}[/red]")
@@ -323,9 +388,13 @@ class SkillsManagementCommand(BaseCommand):
323
388
  # Show agents using this skill
324
389
  agents_using = self.skills_service.get_agents_for_skill(skill_name)
325
390
  if agents_using:
326
- info_text += f"\n[bold]Used by agents:[/bold] {', '.join(agents_using)}\n"
391
+ info_text += (
392
+ f"\n[bold]Used by agents:[/bold] {', '.join(agents_using)}\n"
393
+ )
327
394
 
328
- console.print(Panel(info_text, title="Skill Information", border_style="cyan"))
395
+ console.print(
396
+ Panel(info_text, title="Skill Information", border_style="cyan")
397
+ )
329
398
 
330
399
  # Show content if requested
331
400
  if show_content:
@@ -337,7 +406,9 @@ class SkillsManagementCommand(BaseCommand):
337
406
  content = skill_md.read_text()
338
407
  console.print(Markdown(content))
339
408
  else:
340
- console.print(f"\n[yellow]SKILL.md not found at {skill_md}[/yellow]")
409
+ console.print(
410
+ f"\n[yellow]SKILL.md not found at {skill_md}[/yellow]"
411
+ )
341
412
 
342
413
  return CommandResult(success=True, exit_code=0)
343
414
 
@@ -355,16 +426,22 @@ class SkillsManagementCommand(BaseCommand):
355
426
  config_path = self.skills_service.get_config_path(scope)
356
427
 
357
428
  if show_path:
358
- console.print(f"\n[cyan]Configuration path ({scope}):[/cyan] {config_path}\n")
429
+ console.print(
430
+ f"\n[cyan]Configuration path ({scope}):[/cyan] {config_path}\n"
431
+ )
359
432
  return CommandResult(success=True, exit_code=0)
360
433
 
361
434
  if not config_path.exists():
362
- console.print(f"\n[yellow]Configuration file does not exist: {config_path}[/yellow]")
435
+ console.print(
436
+ f"\n[yellow]Configuration file does not exist: {config_path}[/yellow]"
437
+ )
363
438
  console.print("[dim]Would you like to create it? (y/n):[/dim] ", end="")
364
439
 
365
- if input().lower() == 'y':
440
+ if input().lower() == "y":
366
441
  self.skills_service.create_default_config(scope)
367
- console.print(f"[green]Created default configuration at {config_path}[/green]\n")
442
+ console.print(
443
+ f"[green]Created default configuration at {config_path}[/green]\n"
444
+ )
368
445
  else:
369
446
  return CommandResult(success=False, exit_code=1)
370
447
 
@@ -373,17 +450,22 @@ class SkillsManagementCommand(BaseCommand):
373
450
  editor = os.environ.get("EDITOR", "nano")
374
451
  try:
375
452
  subprocess.run([editor, str(config_path)], check=True)
376
- console.print(f"\n[green]Configuration saved to {config_path}[/green]\n")
453
+ console.print(
454
+ f"\n[green]Configuration saved to {config_path}[/green]\n"
455
+ )
377
456
  return CommandResult(success=True, exit_code=0)
378
457
  except subprocess.CalledProcessError as e:
379
458
  console.print(f"[red]Error opening editor: {e}[/red]")
380
459
  return CommandResult(success=False, exit_code=1)
381
460
  else:
382
461
  # Display config
383
- console.print(f"\n[bold cyan]Skills Configuration ({scope}):[/bold cyan]\n")
462
+ console.print(
463
+ f"\n[bold cyan]Skills Configuration ({scope}):[/bold cyan]\n"
464
+ )
384
465
  console.print(f"[dim]Path: {config_path}[/dim]\n")
385
466
 
386
467
  import yaml
468
+
387
469
  config = yaml.safe_load(config_path.read_text())
388
470
  console.print(yaml.dump(config, default_flow_style=False))
389
471
 
@@ -393,6 +475,209 @@ class SkillsManagementCommand(BaseCommand):
393
475
  console.print(f"[red]Error managing configuration: {e}[/red]")
394
476
  return CommandResult(success=False, message=str(e), exit_code=1)
395
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
+
396
681
  def _get_skill_metadata(self, skill_name: str) -> Optional[dict]:
397
682
  """Get skill metadata from SKILL.md file."""
398
683
  try:
@@ -404,12 +689,215 @@ class SkillsManagementCommand(BaseCommand):
404
689
 
405
690
  # Parse SKILL.md metadata
406
691
  content = skill_md.read_text()
407
- metadata = self.skills_service.parse_skill_metadata(content)
408
- return metadata
692
+ return self.skills_service.parse_skill_metadata(content)
409
693
 
410
694
  except Exception:
411
695
  return None
412
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
+
413
901
 
414
902
  def manage_skills(args) -> int:
415
903
  """