claude-mpm 4.24.0__py3-none-any.whl → 5.0.9__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 (502) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +12 -0
  3. claude_mpm/agents/OUTPUT_STYLE.md +3 -48
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +721 -911
  5. claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +1322 -0
  6. claude_mpm/agents/WORKFLOW.md +4 -4
  7. claude_mpm/agents/__init__.py +6 -0
  8. claude_mpm/agents/agent_loader.py +1 -4
  9. claude_mpm/agents/base_agent.json +6 -3
  10. claude_mpm/agents/base_agent_loader.py +10 -35
  11. claude_mpm/agents/frontmatter_validator.py +1 -1
  12. claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +370 -3
  13. claude_mpm/agents/templates/context-management-examples.md +544 -0
  14. claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +48 -0
  15. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  16. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  17. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  18. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  19. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  20. claude_mpm/cli/__init__.py +38 -2
  21. claude_mpm/cli/commands/__init__.py +2 -0
  22. claude_mpm/cli/commands/agent_source.py +774 -0
  23. claude_mpm/cli/commands/agent_state_manager.py +188 -30
  24. claude_mpm/cli/commands/agents.py +959 -36
  25. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  26. claude_mpm/cli/commands/agents_discover.py +338 -0
  27. claude_mpm/cli/commands/aggregate.py +1 -1
  28. claude_mpm/cli/commands/analyze.py +3 -3
  29. claude_mpm/cli/commands/auto_configure.py +2 -6
  30. claude_mpm/cli/commands/config.py +7 -4
  31. claude_mpm/cli/commands/configure.py +769 -45
  32. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  33. claude_mpm/cli/commands/configure_navigation.py +63 -46
  34. claude_mpm/cli/commands/debug.py +12 -12
  35. claude_mpm/cli/commands/doctor.py +10 -2
  36. claude_mpm/cli/commands/hook_errors.py +277 -0
  37. claude_mpm/cli/commands/local_deploy.py +1 -4
  38. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  39. claude_mpm/cli/commands/mpm_init/core.py +49 -1
  40. claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
  41. claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
  42. claude_mpm/cli/commands/postmortem.py +401 -0
  43. claude_mpm/cli/commands/run.py +123 -165
  44. claude_mpm/cli/commands/skill_source.py +694 -0
  45. claude_mpm/cli/commands/skills.py +757 -20
  46. claude_mpm/cli/executor.py +78 -3
  47. claude_mpm/cli/interactive/agent_wizard.py +955 -45
  48. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  49. claude_mpm/cli/parsers/agents_parser.py +256 -4
  50. claude_mpm/cli/parsers/base_parser.py +53 -0
  51. claude_mpm/cli/parsers/config_parser.py +96 -43
  52. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  53. claude_mpm/cli/parsers/skills_parser.py +145 -0
  54. claude_mpm/cli/parsers/source_parser.py +138 -0
  55. claude_mpm/cli/startup.py +538 -106
  56. claude_mpm/cli/startup_display.py +480 -0
  57. claude_mpm/cli/utils.py +1 -1
  58. claude_mpm/cli_module/commands.py +1 -1
  59. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  60. claude_mpm/commands/mpm-agents-detect.md +9 -0
  61. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  62. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  63. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  64. claude_mpm/commands/mpm-doctor.md +9 -0
  65. claude_mpm/commands/mpm-help.md +14 -2
  66. claude_mpm/commands/mpm-init.md +27 -2
  67. claude_mpm/commands/mpm-monitor.md +9 -0
  68. claude_mpm/commands/mpm-postmortem.md +123 -0
  69. claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
  70. claude_mpm/commands/mpm-status.md +9 -0
  71. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  72. claude_mpm/commands/mpm-ticket-view.md +552 -0
  73. claude_mpm/commands/mpm-version.md +9 -0
  74. claude_mpm/commands/mpm.md +10 -0
  75. claude_mpm/config/agent_presets.py +488 -0
  76. claude_mpm/config/agent_sources.py +325 -0
  77. claude_mpm/config/skill_presets.py +392 -0
  78. claude_mpm/config/skill_sources.py +590 -0
  79. claude_mpm/constants.py +13 -0
  80. claude_mpm/core/claude_runner.py +5 -34
  81. claude_mpm/core/config.py +16 -0
  82. claude_mpm/core/constants.py +1 -1
  83. claude_mpm/core/framework/__init__.py +3 -16
  84. claude_mpm/core/framework/loaders/file_loader.py +54 -101
  85. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  86. claude_mpm/core/hook_error_memory.py +381 -0
  87. claude_mpm/core/hook_manager.py +41 -2
  88. claude_mpm/core/interactive_session.py +91 -10
  89. claude_mpm/core/logger.py +3 -1
  90. claude_mpm/core/oneshot_session.py +71 -8
  91. claude_mpm/core/protocols/__init__.py +23 -0
  92. claude_mpm/core/protocols/runner_protocol.py +103 -0
  93. claude_mpm/core/protocols/session_protocol.py +131 -0
  94. claude_mpm/core/shared/singleton_manager.py +11 -4
  95. claude_mpm/core/system_context.py +38 -0
  96. claude_mpm/dashboard/static/css/activity.css +69 -69
  97. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  98. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  99. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  100. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  101. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  102. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  103. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  104. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  105. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  106. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  107. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  108. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  109. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  110. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  111. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  112. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  113. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  114. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  115. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  116. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  117. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  118. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  119. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  120. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  121. claude_mpm/dashboard/templates/code_simple.html +23 -23
  122. claude_mpm/dashboard/templates/index.html +18 -18
  123. claude_mpm/experimental/cli_enhancements.py +1 -5
  124. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  125. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  126. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  127. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  128. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  129. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  130. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  131. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  132. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  133. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  134. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  135. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  136. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  137. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  138. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  139. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  140. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  141. claude_mpm/models/git_repository.py +198 -0
  142. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  143. claude_mpm/scripts/start_activity_logging.py +3 -1
  144. claude_mpm/services/agents/agent_builder.py +45 -9
  145. claude_mpm/services/agents/agent_preset_service.py +238 -0
  146. claude_mpm/services/agents/agent_selection_service.py +484 -0
  147. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  148. claude_mpm/services/agents/cache_git_manager.py +621 -0
  149. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  150. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  151. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  152. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  153. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  154. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  155. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  156. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  157. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  158. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  159. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
  160. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  161. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  162. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  163. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  164. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  165. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  166. claude_mpm/services/agents/git_source_manager.py +629 -0
  167. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  168. claude_mpm/services/agents/local_template_manager.py +50 -10
  169. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  170. claude_mpm/services/agents/sources/__init__.py +13 -0
  171. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  172. claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
  173. claude_mpm/services/agents/startup_sync.py +239 -0
  174. claude_mpm/services/agents/toolchain_detector.py +474 -0
  175. claude_mpm/services/analysis/__init__.py +25 -0
  176. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  177. claude_mpm/services/analysis/postmortem_service.py +765 -0
  178. claude_mpm/services/cli/session_pause_manager.py +1 -1
  179. claude_mpm/services/command_deployment_service.py +200 -6
  180. claude_mpm/services/core/base.py +7 -2
  181. claude_mpm/services/core/interfaces/__init__.py +1 -3
  182. claude_mpm/services/core/interfaces/health.py +1 -4
  183. claude_mpm/services/core/models/__init__.py +2 -11
  184. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  185. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  186. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  187. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  188. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  189. claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
  190. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  191. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  192. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  193. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  194. claude_mpm/services/event_bus/direct_relay.py +3 -3
  195. claude_mpm/services/events/consumers/logging.py +1 -2
  196. claude_mpm/services/git/__init__.py +21 -0
  197. claude_mpm/services/git/git_operations_service.py +494 -0
  198. claude_mpm/services/github/__init__.py +21 -0
  199. claude_mpm/services/github/github_cli_service.py +397 -0
  200. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  201. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  202. claude_mpm/services/instructions/__init__.py +9 -0
  203. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  204. claude_mpm/services/local_ops/__init__.py +3 -13
  205. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  206. claude_mpm/services/local_ops/health_manager.py +1 -4
  207. claude_mpm/services/local_ops/resource_monitor.py +1 -1
  208. claude_mpm/services/mcp_config_manager.py +75 -145
  209. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  210. claude_mpm/services/mcp_gateway/core/process_pool.py +22 -16
  211. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  212. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  213. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  214. claude_mpm/services/mcp_service_verifier.py +6 -3
  215. claude_mpm/services/model/model_router.py +1 -2
  216. claude_mpm/services/monitor/daemon.py +29 -9
  217. claude_mpm/services/monitor/daemon_manager.py +96 -19
  218. claude_mpm/services/monitor/server.py +2 -2
  219. claude_mpm/services/port_manager.py +1 -1
  220. claude_mpm/services/pr/__init__.py +14 -0
  221. claude_mpm/services/pr/pr_template_service.py +329 -0
  222. claude_mpm/services/project/documentation_manager.py +2 -1
  223. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  224. claude_mpm/services/runner_configuration_service.py +16 -3
  225. claude_mpm/services/session_management_service.py +16 -4
  226. claude_mpm/services/skills/__init__.py +18 -0
  227. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  228. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  229. claude_mpm/services/skills_config.py +547 -0
  230. claude_mpm/services/skills_deployer.py +955 -0
  231. claude_mpm/services/socketio/handlers/connection.py +1 -1
  232. claude_mpm/services/socketio/handlers/git.py +1 -1
  233. claude_mpm/services/socketio/server/core.py +1 -4
  234. claude_mpm/services/socketio/server/main.py +1 -3
  235. claude_mpm/services/system_instructions_service.py +1 -3
  236. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  237. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  238. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  239. claude_mpm/services/unified/unified_deployment.py +1 -5
  240. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  241. claude_mpm/services/visualization/__init__.py +1 -5
  242. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  243. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
  244. claude_mpm/skills/skills_registry.py +0 -1
  245. claude_mpm/templates/questions/__init__.py +38 -0
  246. claude_mpm/templates/questions/base.py +193 -0
  247. claude_mpm/templates/questions/pr_strategy.py +311 -0
  248. claude_mpm/templates/questions/project_init.py +385 -0
  249. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  250. claude_mpm/tools/__main__.py +8 -8
  251. claude_mpm/utils/agent_dependency_loader.py +77 -10
  252. claude_mpm/utils/agent_filters.py +288 -0
  253. claude_mpm/utils/dependency_cache.py +3 -1
  254. claude_mpm/utils/gitignore.py +241 -0
  255. claude_mpm/utils/migration.py +372 -0
  256. claude_mpm/utils/progress.py +387 -0
  257. claude_mpm/utils/robust_installer.py +2 -4
  258. claude_mpm/utils/structured_questions.py +619 -0
  259. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/METADATA +396 -43
  260. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/RECORD +268 -422
  261. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  262. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  263. claude_mpm/agents/templates/agent-manager.json +0 -273
  264. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  265. claude_mpm/agents/templates/api_qa.json +0 -183
  266. claude_mpm/agents/templates/clerk-ops.json +0 -235
  267. claude_mpm/agents/templates/code_analyzer.json +0 -101
  268. claude_mpm/agents/templates/content-agent.json +0 -358
  269. claude_mpm/agents/templates/dart_engineer.json +0 -307
  270. claude_mpm/agents/templates/data_engineer.json +0 -225
  271. claude_mpm/agents/templates/documentation.json +0 -238
  272. claude_mpm/agents/templates/engineer.json +0 -210
  273. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  274. claude_mpm/agents/templates/golang_engineer.json +0 -270
  275. claude_mpm/agents/templates/imagemagick.json +0 -264
  276. claude_mpm/agents/templates/java_engineer.json +0 -346
  277. claude_mpm/agents/templates/javascript_engineer_agent.json +0 -380
  278. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  279. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  280. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  281. claude_mpm/agents/templates/memory_manager.json +0 -158
  282. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  283. claude_mpm/agents/templates/ops.json +0 -185
  284. claude_mpm/agents/templates/php-engineer.json +0 -287
  285. claude_mpm/agents/templates/product_owner.json +0 -338
  286. claude_mpm/agents/templates/project_organizer.json +0 -144
  287. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  288. claude_mpm/agents/templates/python_engineer.json +0 -387
  289. claude_mpm/agents/templates/qa.json +0 -243
  290. claude_mpm/agents/templates/react_engineer.json +0 -239
  291. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  292. claude_mpm/agents/templates/research.json +0 -188
  293. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  294. claude_mpm/agents/templates/rust_engineer.json +0 -275
  295. claude_mpm/agents/templates/security.json +0 -202
  296. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  297. claude_mpm/agents/templates/tauri_engineer.json +0 -274
  298. claude_mpm/agents/templates/ticketing.json +0 -178
  299. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  300. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  301. claude_mpm/agents/templates/version_control.json +0 -159
  302. claude_mpm/agents/templates/web_qa.json +0 -400
  303. claude_mpm/agents/templates/web_ui.json +0 -189
  304. claude_mpm/commands/mpm-tickets.md +0 -151
  305. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  306. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  307. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  308. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  309. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  310. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  311. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  312. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  313. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  314. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  315. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  316. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  317. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  318. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  319. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  320. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  321. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  322. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  323. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  324. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  325. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  326. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  327. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  328. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  329. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  330. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  331. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  332. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  333. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  334. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  335. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  336. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  337. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  338. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  339. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  340. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  341. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  342. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  343. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  344. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  345. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  346. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  347. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  348. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  349. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  350. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  351. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  352. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  353. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  354. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  355. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  356. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  357. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  358. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  359. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  360. claude_mpm/dashboard/static/built/react/events.js +0 -30
  361. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  362. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  363. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  364. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  365. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  366. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  367. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  368. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  369. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  370. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  371. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  372. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  373. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  374. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  375. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  376. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  377. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  378. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  379. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  380. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  381. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  382. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  383. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  384. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  385. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  386. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  387. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  388. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  389. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  390. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  391. claude_mpm/dashboard/static/events.html +0 -607
  392. claude_mpm/dashboard/static/index.html +0 -635
  393. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  394. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  395. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  396. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  397. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  398. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  399. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  400. claude_mpm/dashboard/static/legacy/files.html +0 -747
  401. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  402. claude_mpm/dashboard/static/monitors.html +0 -431
  403. claude_mpm/dashboard/static/production/events.html +0 -659
  404. claude_mpm/dashboard/static/production/main.html +0 -698
  405. claude_mpm/dashboard/static/production/monitors.html +0 -483
  406. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  407. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  408. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  409. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  410. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  411. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  412. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  413. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  414. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  415. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  416. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  417. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  418. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  419. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  420. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  421. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  422. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  423. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  424. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  425. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  426. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  427. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  428. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  429. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  430. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  431. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  432. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  433. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  434. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  435. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  436. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  437. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  438. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  439. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  440. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  441. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  442. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  443. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  444. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  445. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  446. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  447. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  448. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  449. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  450. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  451. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  452. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  453. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  454. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  455. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  456. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  457. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  458. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  459. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  460. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  461. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  462. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  463. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  464. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  465. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  466. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  467. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  468. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  469. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  470. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  471. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  472. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  473. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  474. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  475. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  476. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  477. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  478. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  479. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  480. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  481. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  482. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  483. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  484. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
  485. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
  486. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
  487. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
  488. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
  489. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
  490. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  491. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  492. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  493. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  494. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  495. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  496. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  497. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  498. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  499. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/WHEEL +0 -0
  500. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/entry_points.txt +0 -0
  501. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/licenses/LICENSE +0 -0
  502. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.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,19 @@ 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
+ SkillsCommands.CONFIGURE.value: self._configure_skills,
87
+ # GitHub deployment commands
88
+ SkillsCommands.DEPLOY_FROM_GITHUB.value: self._deploy_from_github,
89
+ SkillsCommands.LIST_AVAILABLE.value: self._list_available_github_skills,
90
+ SkillsCommands.CHECK_DEPLOYED.value: self._check_deployed_skills,
91
+ SkillsCommands.REMOVE.value: self._remove_skills,
92
+ # Collection management commands
93
+ SkillsCommands.COLLECTION_LIST.value: self._collection_list,
94
+ SkillsCommands.COLLECTION_ADD.value: self._collection_add,
95
+ SkillsCommands.COLLECTION_REMOVE.value: self._collection_remove,
96
+ SkillsCommands.COLLECTION_ENABLE.value: self._collection_enable,
97
+ SkillsCommands.COLLECTION_DISABLE.value: self._collection_disable,
98
+ SkillsCommands.COLLECTION_SET_DEFAULT.value: self._collection_set_default,
71
99
  }
72
100
 
73
101
  handler = command_map.get(args.skills_command)
@@ -168,55 +196,109 @@ class SkillsManagementCommand(BaseCommand):
168
196
  return CommandResult(success=False, message=str(e), exit_code=1)
169
197
 
170
198
  def _deploy_skills(self, args) -> CommandResult:
171
- """Deploy bundled skills to project."""
199
+ """Deploy skills using two-phase sync: cache → deploy.
200
+
201
+ Phase 3 Integration (1M-486): Uses Git skill source manager for deployment.
202
+ - Phase 1: Sync skills to ~/.claude-mpm/cache/skills/ (if needed)
203
+ - Phase 2: Deploy from cache to project .claude-mpm/skills/
204
+
205
+ This replaces bundled skill deployment with a multi-project
206
+ architecture where one cache serves multiple project deployments.
207
+ """
172
208
  try:
209
+ from pathlib import Path
210
+
211
+ from ...config.skill_sources import SkillSourceConfiguration
212
+ from ...services.skills.git_skill_source_manager import (
213
+ GitSkillSourceManager,
214
+ )
215
+
173
216
  force = getattr(args, "force", False)
174
217
  specific_skills = getattr(args, "skills", None)
175
218
 
176
219
  console.print("\n[bold cyan]Deploying skills...[/bold cyan]\n")
177
220
 
178
- result = self.skills_service.deploy_bundled_skills(
179
- force=force, skill_names=specific_skills
221
+ # Initialize git skill source manager
222
+ config = SkillSourceConfiguration.load()
223
+ git_skill_manager = GitSkillSourceManager(config)
224
+ project_dir = Path.cwd()
225
+
226
+ # Phase 1: Sync skills to cache
227
+ console.print("[dim]Phase 1: Syncing skills to cache...[/dim]")
228
+ sync_results = git_skill_manager.sync_all_sources(force=force)
229
+
230
+ synced_count = sum(
231
+ 1 for result in sync_results.values() if result.get("synced")
232
+ )
233
+ console.print(f"[dim]Synced {synced_count} skill source(s)[/dim]\n")
234
+
235
+ # Phase 2: Deploy from cache to project
236
+ console.print("[dim]Phase 2: Deploying from cache to project...[/dim]\n")
237
+ deploy_result = git_skill_manager.deploy_skills_to_project(
238
+ project_dir=project_dir,
239
+ skill_list=specific_skills,
240
+ force=force,
180
241
  )
181
242
 
182
243
  # Display results
183
- if result["deployed"]:
244
+ if deploy_result["deployed"]:
184
245
  console.print(
185
- f"[green]✓ Deployed {len(result['deployed'])} skill(s):[/green]"
246
+ f"[green]✓ Deployed {len(deploy_result['deployed'])} skill(s):[/green]"
186
247
  )
187
- for skill in result["deployed"]:
248
+ for skill in deploy_result["deployed"]:
188
249
  console.print(f" • {skill}")
189
250
  console.print()
190
251
 
191
- if result["skipped"]:
252
+ if deploy_result["updated"]:
192
253
  console.print(
193
- f"[yellow] Skipped {len(result['skipped'])} skill(s) (already deployed):[/yellow]"
254
+ f"[green] Updated {len(deploy_result['updated'])} skill(s):[/green]"
194
255
  )
195
- for skill in result["skipped"]:
256
+ for skill in deploy_result["updated"]:
257
+ console.print(f" • {skill}")
258
+ console.print()
259
+
260
+ if deploy_result["skipped"]:
261
+ console.print(
262
+ f"[yellow]⊘ Skipped {len(deploy_result['skipped'])} skill(s) (already up-to-date):[/yellow]"
263
+ )
264
+ for skill in deploy_result["skipped"]:
196
265
  console.print(f" • {skill}")
197
266
  console.print("[dim]Use --force to redeploy[/dim]\n")
198
267
 
199
- if result["errors"]:
268
+ if deploy_result["failed"]:
200
269
  console.print(
201
- f"[red]✗ Failed to deploy {len(result['errors'])} skill(s):[/red]"
270
+ f"[red]✗ Failed to deploy {len(deploy_result['failed'])} skill(s):[/red]"
202
271
  )
203
- for skill, error in result["errors"].items():
204
- console.print(f" • {skill}: {error}")
272
+ for skill in deploy_result["failed"]:
273
+ console.print(f" • {skill}")
205
274
  console.print()
206
275
 
207
276
  # Summary
277
+ success_count = len(deploy_result["deployed"]) + len(
278
+ deploy_result["updated"]
279
+ )
208
280
  total = (
209
- len(result["deployed"]) + len(result["skipped"]) + len(result["errors"])
281
+ success_count
282
+ + len(deploy_result["skipped"])
283
+ + len(deploy_result["failed"])
210
284
  )
211
285
  console.print(
212
- f"[bold]Summary:[/bold] {len(result['deployed'])} deployed, "
213
- f"{len(result['skipped'])} skipped, {len(result['errors'])} errors "
214
- f"(Total: {total})\n"
286
+ f"[bold]Summary:[/bold] {success_count} deployed/updated, "
287
+ f"{len(deploy_result['skipped'])} skipped, "
288
+ f"{len(deploy_result['failed'])} errors (Total: {total})\n"
289
+ )
290
+
291
+ console.print(
292
+ f"[dim]Deployment directory: {deploy_result['deployment_dir']}[/dim]\n"
215
293
  )
216
294
 
217
295
  # Exit with error if any deployments failed
218
- exit_code = 1 if result["errors"] else 0
219
- return CommandResult(success=not result["errors"], exit_code=exit_code)
296
+ exit_code = 1 if deploy_result["failed"] else 0
297
+ return CommandResult(
298
+ success=not deploy_result["failed"],
299
+ message=f"Deployed {success_count} skills from cache",
300
+ exit_code=exit_code,
301
+ )
220
302
 
221
303
  except Exception as e:
222
304
  console.print(f"[red]Error deploying skills: {e}[/red]")
@@ -448,6 +530,209 @@ class SkillsManagementCommand(BaseCommand):
448
530
  console.print(f"[red]Error managing configuration: {e}[/red]")
449
531
  return CommandResult(success=False, message=str(e), exit_code=1)
450
532
 
533
+ def _deploy_from_github(self, args) -> CommandResult:
534
+ """Deploy skills from GitHub repository."""
535
+ try:
536
+ collection = getattr(args, "collection", None)
537
+ toolchain = getattr(args, "toolchain", None)
538
+ categories = getattr(args, "categories", None)
539
+ force = getattr(args, "force", False)
540
+ all_skills = getattr(args, "all", False)
541
+
542
+ if collection:
543
+ console.print(
544
+ f"\n[bold cyan]Deploying skills from collection '{collection}'...[/bold cyan]\n"
545
+ )
546
+ else:
547
+ console.print(
548
+ "\n[bold cyan]Deploying skills from default collection...[/bold cyan]\n"
549
+ )
550
+
551
+ # Auto-detect toolchain if not specified and not deploying all
552
+ if not toolchain and not all_skills:
553
+ console.print(
554
+ "[yellow]No toolchain specified. Use --toolchain to filter by language,[/yellow]"
555
+ )
556
+ console.print(
557
+ "[yellow]or --all to deploy all available skills.[/yellow]\n"
558
+ )
559
+
560
+ result = self.skills_deployer.deploy_skills(
561
+ collection=collection,
562
+ toolchain=toolchain,
563
+ categories=categories,
564
+ force=force,
565
+ )
566
+
567
+ # Display results
568
+ if result["deployed_count"] > 0:
569
+ console.print(
570
+ f"[green]✓ Deployed {result['deployed_count']} skill(s):[/green]"
571
+ )
572
+ for skill in result["deployed_skills"]:
573
+ console.print(f" • {skill}")
574
+ console.print()
575
+
576
+ if result["skipped_count"] > 0:
577
+ console.print(
578
+ f"[yellow]⊘ Skipped {result['skipped_count']} skill(s) (already deployed):[/yellow]"
579
+ )
580
+ for skill in result["skipped_skills"]:
581
+ console.print(f" • {skill}")
582
+ console.print("[dim]Use --force to redeploy[/dim]\n")
583
+
584
+ if result["errors"]:
585
+ console.print(f"[red]✗ {len(result['errors'])} error(s):[/red]")
586
+ for error in result["errors"]:
587
+ console.print(f" • {error}")
588
+ console.print()
589
+
590
+ # Show restart instructions
591
+ if result["restart_instructions"]:
592
+ console.print(
593
+ Panel(
594
+ result["restart_instructions"],
595
+ title="⚠️ Important",
596
+ border_style="yellow",
597
+ )
598
+ )
599
+ console.print()
600
+
601
+ exit_code = 1 if result["errors"] else 0
602
+ return CommandResult(success=not result["errors"], exit_code=exit_code)
603
+
604
+ except Exception as e:
605
+ console.print(f"[red]Error deploying from GitHub: {e}[/red]")
606
+ return CommandResult(success=False, message=str(e), exit_code=1)
607
+
608
+ def _list_available_github_skills(self, args) -> CommandResult:
609
+ """List available skills from GitHub repository."""
610
+ try:
611
+ collection = getattr(args, "collection", None)
612
+
613
+ if collection:
614
+ console.print(
615
+ f"\n[bold cyan]Fetching skills from collection '{collection}'...[/bold cyan]\n"
616
+ )
617
+ else:
618
+ console.print(
619
+ "\n[bold cyan]Fetching skills from default collection...[/bold cyan]\n"
620
+ )
621
+
622
+ result = self.skills_deployer.list_available_skills(collection=collection)
623
+
624
+ if result.get("error"):
625
+ console.print(f"[red]Error: {result['error']}[/red]")
626
+ return CommandResult(
627
+ success=False, message=result["error"], exit_code=1
628
+ )
629
+
630
+ console.print(
631
+ f"[green]Found {result['total_skills']} available skills[/green]\n"
632
+ )
633
+
634
+ # Display by category
635
+ console.print("[bold yellow]By Category:[/bold yellow]\n")
636
+ for category, skills in sorted(result["by_category"].items()):
637
+ console.print(f" [cyan]{category}[/cyan] ({len(skills)} skills)")
638
+ if hasattr(args, "verbose") and args.verbose:
639
+ for skill in sorted(skills, key=lambda s: s.get("name", "")):
640
+ console.print(f" • {skill.get('name', 'unknown')}")
641
+ console.print()
642
+
643
+ # Display by toolchain
644
+ console.print("[bold yellow]By Toolchain:[/bold yellow]\n")
645
+ for toolchain, skills in sorted(result["by_toolchain"].items()):
646
+ console.print(f" [cyan]{toolchain}[/cyan] ({len(skills)} skills)")
647
+ if hasattr(args, "verbose") and args.verbose:
648
+ for skill in sorted(skills, key=lambda s: s.get("name", "")):
649
+ console.print(f" • {skill.get('name', 'unknown')}")
650
+ console.print()
651
+
652
+ return CommandResult(success=True, exit_code=0)
653
+
654
+ except Exception as e:
655
+ console.print(f"[red]Error listing available skills: {e}[/red]")
656
+ return CommandResult(success=False, message=str(e), exit_code=1)
657
+
658
+ def _check_deployed_skills(self, args) -> CommandResult:
659
+ """Check currently deployed skills in ~/.claude/skills/."""
660
+ try:
661
+ result = self.skills_deployer.check_deployed_skills()
662
+
663
+ console.print("\n[bold cyan]Claude Code Skills Status:[/bold cyan]\n")
664
+ console.print(f"[dim]Directory: {result['claude_skills_dir']}[/dim]\n")
665
+
666
+ if result["deployed_count"] == 0:
667
+ console.print("[yellow]No skills currently deployed.[/yellow]")
668
+ console.print(
669
+ "[dim]Use 'claude-mpm skills deploy-github' to deploy skills.[/dim]\n"
670
+ )
671
+ return CommandResult(success=True, exit_code=0)
672
+
673
+ console.print(
674
+ f"[green]{result['deployed_count']} skill(s) deployed:[/green]\n"
675
+ )
676
+
677
+ # Create table for deployed skills
678
+ table = Table(show_header=True, header_style="bold cyan")
679
+ table.add_column("Skill Name", style="green")
680
+ table.add_column("Path", style="dim")
681
+
682
+ for skill in sorted(result["skills"], key=lambda s: s["name"]):
683
+ table.add_row(skill["name"], skill["path"])
684
+
685
+ console.print(table)
686
+ console.print()
687
+
688
+ return CommandResult(success=True, exit_code=0)
689
+
690
+ except Exception as e:
691
+ console.print(f"[red]Error checking deployed skills: {e}[/red]")
692
+ return CommandResult(success=False, message=str(e), exit_code=1)
693
+
694
+ def _remove_skills(self, args) -> CommandResult:
695
+ """Remove deployed skills."""
696
+ try:
697
+ skill_names = getattr(args, "skill_names", None)
698
+ remove_all = getattr(args, "all", False)
699
+
700
+ if remove_all:
701
+ skill_names = None
702
+ console.print(
703
+ "\n[bold yellow]Removing ALL deployed skills...[/bold yellow]\n"
704
+ )
705
+ elif skill_names:
706
+ console.print(
707
+ f"\n[bold cyan]Removing {len(skill_names)} skill(s)...[/bold cyan]\n"
708
+ )
709
+ else:
710
+ console.print("[red]Error: Specify skill names or use --all[/red]")
711
+ return CommandResult(success=False, exit_code=1)
712
+
713
+ result = self.skills_deployer.remove_skills(skill_names)
714
+
715
+ if result["removed_count"] > 0:
716
+ console.print(
717
+ f"[green]✓ Removed {result['removed_count']} skill(s):[/green]"
718
+ )
719
+ for skill in result["removed_skills"]:
720
+ console.print(f" • {skill}")
721
+ console.print()
722
+
723
+ if result["errors"]:
724
+ console.print(f"[red]✗ {len(result['errors'])} error(s):[/red]")
725
+ for error in result["errors"]:
726
+ console.print(f" • {error}")
727
+ console.print()
728
+
729
+ exit_code = 1 if result["errors"] else 0
730
+ return CommandResult(success=not result["errors"], exit_code=exit_code)
731
+
732
+ except Exception as e:
733
+ console.print(f"[red]Error removing skills: {e}[/red]")
734
+ return CommandResult(success=False, message=str(e), exit_code=1)
735
+
451
736
  def _get_skill_metadata(self, skill_name: str) -> Optional[dict]:
452
737
  """Get skill metadata from SKILL.md file."""
453
738
  try:
@@ -464,6 +749,458 @@ class SkillsManagementCommand(BaseCommand):
464
749
  except Exception:
465
750
  return None
466
751
 
752
+ # === Collection Management Commands ===
753
+
754
+ def _collection_list(self, args) -> CommandResult:
755
+ """List all configured skill collections."""
756
+ try:
757
+ result = self.skills_deployer.list_collections()
758
+
759
+ console.print("\n[bold cyan]Skill Collections:[/bold cyan]\n")
760
+ console.print(
761
+ f"[dim]Default collection: {result['default_collection']}[/dim]"
762
+ )
763
+ console.print(
764
+ f"[dim]Enabled: {result['enabled_count']} / {result['total_count']}[/dim]\n"
765
+ )
766
+
767
+ if not result["collections"]:
768
+ console.print("[yellow]No collections configured.[/yellow]")
769
+ console.print(
770
+ "[dim]Use 'claude-mpm skills collection-add' to add a collection.[/dim]\n"
771
+ )
772
+ return CommandResult(success=True, exit_code=0)
773
+
774
+ # Create table for collections
775
+ table = Table(show_header=True, header_style="bold cyan")
776
+ table.add_column("Name", style="green")
777
+ table.add_column("URL", style="white")
778
+ table.add_column("Priority", justify="center")
779
+ table.add_column("Enabled", justify="center")
780
+ table.add_column("Last Update", style="dim")
781
+ table.add_column("Default", justify="center")
782
+
783
+ # Sort by priority
784
+ sorted_collections = sorted(
785
+ result["collections"].items(), key=lambda x: x[1].get("priority", 999)
786
+ )
787
+
788
+ for name, config in sorted_collections:
789
+ enabled_icon = "✓" if config.get("enabled", True) else "✗"
790
+ default_icon = "⭐" if name == result["default_collection"] else ""
791
+ last_update = config.get("last_update") or "Never"
792
+
793
+ table.add_row(
794
+ name,
795
+ config["url"],
796
+ str(config.get("priority", "N/A")),
797
+ enabled_icon,
798
+ last_update,
799
+ default_icon,
800
+ )
801
+
802
+ console.print(table)
803
+ console.print()
804
+
805
+ return CommandResult(success=True, exit_code=0)
806
+
807
+ except Exception as e:
808
+ console.print(f"[red]Error listing collections: {e}[/red]")
809
+ return CommandResult(success=False, message=str(e), exit_code=1)
810
+
811
+ def _collection_add(self, args) -> CommandResult:
812
+ """Add a new skill collection."""
813
+ try:
814
+ name = getattr(args, "collection_name", None)
815
+ url = getattr(args, "collection_url", None)
816
+ priority = getattr(args, "priority", 99)
817
+
818
+ if not name or not url:
819
+ console.print("[red]Error: Collection name and URL are required[/red]")
820
+ console.print(
821
+ "[dim]Usage: claude-mpm skills collection-add NAME URL [--priority N][/dim]"
822
+ )
823
+ return CommandResult(success=False, exit_code=1)
824
+
825
+ console.print(f"\n[bold cyan]Adding collection '{name}'...[/bold cyan]\n")
826
+
827
+ result = self.skills_deployer.add_collection(name, url, priority)
828
+
829
+ console.print(f"[green]✓ {result['message']}[/green]")
830
+ console.print(f" [dim]URL: {url}[/dim]")
831
+ console.print(f" [dim]Priority: {priority}[/dim]\n")
832
+
833
+ return CommandResult(success=True, exit_code=0)
834
+
835
+ except ValueError as e:
836
+ console.print(f"[red]Error: {e}[/red]")
837
+ return CommandResult(success=False, message=str(e), exit_code=1)
838
+ except Exception as e:
839
+ console.print(f"[red]Unexpected error: {e}[/red]")
840
+ return CommandResult(success=False, message=str(e), exit_code=1)
841
+
842
+ def _collection_remove(self, args) -> CommandResult:
843
+ """Remove a skill collection."""
844
+ try:
845
+ name = getattr(args, "collection_name", None)
846
+
847
+ if not name:
848
+ console.print("[red]Error: Collection name is required[/red]")
849
+ console.print(
850
+ "[dim]Usage: claude-mpm skills collection-remove NAME[/dim]"
851
+ )
852
+ return CommandResult(success=False, exit_code=1)
853
+
854
+ console.print(
855
+ f"\n[bold yellow]Removing collection '{name}'...[/bold yellow]\n"
856
+ )
857
+
858
+ result = self.skills_deployer.remove_collection(name)
859
+
860
+ console.print(f"[green]✓ {result['message']}[/green]")
861
+ if result.get("directory_removed"):
862
+ console.print(" [dim]Collection directory removed[/dim]")
863
+ elif result.get("directory_error"):
864
+ console.print(
865
+ f" [yellow]Warning: {result['directory_error']}[/yellow]"
866
+ )
867
+ console.print()
868
+
869
+ return CommandResult(success=True, exit_code=0)
870
+
871
+ except ValueError as e:
872
+ console.print(f"[red]Error: {e}[/red]")
873
+ return CommandResult(success=False, message=str(e), exit_code=1)
874
+ except Exception as e:
875
+ console.print(f"[red]Unexpected error: {e}[/red]")
876
+ return CommandResult(success=False, message=str(e), exit_code=1)
877
+
878
+ def _collection_enable(self, args) -> CommandResult:
879
+ """Enable a disabled collection."""
880
+ try:
881
+ name = getattr(args, "collection_name", None)
882
+
883
+ if not name:
884
+ console.print("[red]Error: Collection name is required[/red]")
885
+ console.print(
886
+ "[dim]Usage: claude-mpm skills collection-enable NAME[/dim]"
887
+ )
888
+ return CommandResult(success=False, exit_code=1)
889
+
890
+ result = self.skills_deployer.enable_collection(name)
891
+
892
+ console.print(f"\n[green]✓ {result['message']}[/green]\n")
893
+
894
+ return CommandResult(success=True, exit_code=0)
895
+
896
+ except ValueError as e:
897
+ console.print(f"[red]Error: {e}[/red]")
898
+ return CommandResult(success=False, message=str(e), exit_code=1)
899
+ except Exception as e:
900
+ console.print(f"[red]Unexpected error: {e}[/red]")
901
+ return CommandResult(success=False, message=str(e), exit_code=1)
902
+
903
+ def _collection_disable(self, args) -> CommandResult:
904
+ """Disable a collection."""
905
+ try:
906
+ name = getattr(args, "collection_name", None)
907
+
908
+ if not name:
909
+ console.print("[red]Error: Collection name is required[/red]")
910
+ console.print(
911
+ "[dim]Usage: claude-mpm skills collection-disable NAME[/dim]"
912
+ )
913
+ return CommandResult(success=False, exit_code=1)
914
+
915
+ result = self.skills_deployer.disable_collection(name)
916
+
917
+ console.print(f"\n[green]✓ {result['message']}[/green]\n")
918
+
919
+ return CommandResult(success=True, exit_code=0)
920
+
921
+ except ValueError as e:
922
+ console.print(f"[red]Error: {e}[/red]")
923
+ return CommandResult(success=False, message=str(e), exit_code=1)
924
+ except Exception as e:
925
+ console.print(f"[red]Unexpected error: {e}[/red]")
926
+ return CommandResult(success=False, message=str(e), exit_code=1)
927
+
928
+ def _collection_set_default(self, args) -> CommandResult:
929
+ """Set the default collection."""
930
+ try:
931
+ name = getattr(args, "collection_name", None)
932
+
933
+ if not name:
934
+ console.print("[red]Error: Collection name is required[/red]")
935
+ console.print(
936
+ "[dim]Usage: claude-mpm skills collection-set-default NAME[/dim]"
937
+ )
938
+ return CommandResult(success=False, exit_code=1)
939
+
940
+ result = self.skills_deployer.set_default_collection(name)
941
+
942
+ console.print(f"\n[green]✓ {result['message']}[/green]")
943
+ if result.get("previous_default"):
944
+ console.print(f" [dim]Previous: {result['previous_default']}[/dim]")
945
+ console.print()
946
+
947
+ return CommandResult(success=True, exit_code=0)
948
+
949
+ except ValueError as e:
950
+ console.print(f"[red]Error: {e}[/red]")
951
+ return CommandResult(success=False, message=str(e), exit_code=1)
952
+ except Exception as e:
953
+ console.print(f"[red]Unexpected error: {e}[/red]")
954
+
955
+ def _configure_skills(self, args) -> CommandResult:
956
+ """Interactive skills configuration with checkbox selection.
957
+
958
+ Provides checkbox-based selection interface matching agents configure UX:
959
+ - Status column showing Installed/Available
960
+ - Pre-selection for installed skills
961
+ - Apply/Adjust/Cancel menu
962
+ - While loop for adjustment
963
+ - Simplified labels (checkbox state only)
964
+
965
+ This is Option 3 (Hybrid approach): Separate command for interactive mode
966
+ while keeping deploy-github for CLI automation.
967
+ """
968
+ try:
969
+ import questionary
970
+ from questionary import Choice, Style
971
+ from rich.prompt import Prompt
972
+
973
+ # Questionary style (matching agents configure)
974
+ QUESTIONARY_STYLE = Style(
975
+ [
976
+ (
977
+ "selected",
978
+ "fg:#e0e0e0 bold",
979
+ ), # Light gray - excellent readability
980
+ (
981
+ "pointer",
982
+ "fg:#ffd700 bold",
983
+ ), # Gold/yellow - highly visible pointer
984
+ ("highlighted", "fg:#e0e0e0"), # Light gray - clear hover state
985
+ (
986
+ "question",
987
+ "fg:#e0e0e0 bold",
988
+ ), # Light gray bold - prominent questions
989
+ ("checkbox", "fg:#00ff00"), # Green - for checked boxes
990
+ (
991
+ "checkbox-selected",
992
+ "fg:#00ff00 bold",
993
+ ), # Green bold - for checked selected boxes
994
+ ]
995
+ )
996
+
997
+ console.print("\n[bold cyan]Interactive Skills Configuration[/bold cyan]\n")
998
+ console.print(
999
+ "[dim]Select skills to install/uninstall using checkboxes[/dim]"
1000
+ )
1001
+ console.print("[dim]● = Installed, ○ = Available[/dim]\n")
1002
+
1003
+ # Get deployed skills for status detection
1004
+ deployed_result = self.skills_deployer.check_deployed_skills()
1005
+ deployed_skills = {
1006
+ skill["name"] for skill in deployed_result.get("skills", [])
1007
+ }
1008
+
1009
+ # Get available skills from GitHub
1010
+ console.print("[dim]Fetching available skills from GitHub...[/dim]\n")
1011
+ available_result = self.skills_deployer.list_available_skills()
1012
+
1013
+ if available_result.get("error"):
1014
+ console.print(f"[red]Error: {available_result['error']}[/red]")
1015
+ return CommandResult(
1016
+ success=False, message=available_result["error"], exit_code=1
1017
+ )
1018
+
1019
+ # Flatten skills by category
1020
+ all_skills = []
1021
+ for category, skills in available_result.get("by_category", {}).items():
1022
+ for skill in skills:
1023
+ skill_info = {
1024
+ "name": skill.get("name", "unknown"),
1025
+ "category": category,
1026
+ "is_deployed": skill.get("name", "unknown") in deployed_skills,
1027
+ }
1028
+ all_skills.append(skill_info)
1029
+
1030
+ # Sort by deployed status (deployed first), then by name
1031
+ all_skills.sort(key=lambda s: (not s["is_deployed"], s["name"]))
1032
+
1033
+ # Build checkbox choices with pre-selection
1034
+ # Loop to allow adjusting selection
1035
+ while True:
1036
+ skill_choices = []
1037
+ skill_map = {} # For lookup after selection
1038
+
1039
+ for skill in all_skills:
1040
+ skill_name = skill["name"]
1041
+ category = skill["category"]
1042
+ is_deployed = skill["is_deployed"]
1043
+
1044
+ # Simple format: "skill-name (category)"
1045
+ # Checkbox state (checked/unchecked) indicates installed status
1046
+ choice_text = f"{skill_name} ({category})"
1047
+
1048
+ # Pre-select if deployed
1049
+ choice = Choice(
1050
+ title=choice_text, value=skill_name, checked=is_deployed
1051
+ )
1052
+
1053
+ skill_choices.append(choice)
1054
+ skill_map[skill_name] = skill
1055
+
1056
+ # Display checkbox selection
1057
+ selected_skills = questionary.checkbox(
1058
+ "Select skills (Space to toggle, Enter to confirm):",
1059
+ choices=skill_choices,
1060
+ style=QUESTIONARY_STYLE,
1061
+ ).ask()
1062
+
1063
+ if selected_skills is None:
1064
+ # User cancelled (Ctrl+C)
1065
+ console.print("[yellow]Skills configuration cancelled[/yellow]")
1066
+ return CommandResult(success=True, exit_code=0)
1067
+
1068
+ # Determine changes
1069
+ to_install = []
1070
+ to_remove = []
1071
+
1072
+ for skill in all_skills:
1073
+ skill_name = skill["name"]
1074
+ is_deployed = skill["is_deployed"]
1075
+ is_selected = skill_name in selected_skills
1076
+
1077
+ if is_selected and not is_deployed:
1078
+ to_install.append(skill_name)
1079
+ elif not is_selected and is_deployed:
1080
+ to_remove.append(skill_name)
1081
+
1082
+ # Show summary of changes
1083
+ console.print("\n[bold]Changes to apply:[/bold]")
1084
+ if to_install:
1085
+ console.print(
1086
+ f"\n[green]✓ Install ({len(to_install)} skills):[/green]"
1087
+ )
1088
+ for skill in to_install:
1089
+ console.print(f" • {skill}")
1090
+
1091
+ if to_remove:
1092
+ console.print(
1093
+ f"\n[yellow]✗ Remove ({len(to_remove)} skills):[/yellow]"
1094
+ )
1095
+ for skill in to_remove:
1096
+ console.print(f" • {skill}")
1097
+
1098
+ if not to_install and not to_remove:
1099
+ console.print(
1100
+ "\n[dim]No changes (selection matches current deployment)[/dim]"
1101
+ )
1102
+
1103
+ console.print()
1104
+
1105
+ # Ask user to confirm, adjust, or cancel
1106
+ action = questionary.select(
1107
+ "\nWhat would you like to do?",
1108
+ choices=[
1109
+ Choice("Apply these changes", value="apply"),
1110
+ Choice("Adjust selection", value="adjust"),
1111
+ Choice("Cancel", value="cancel"),
1112
+ ],
1113
+ default="apply",
1114
+ style=QUESTIONARY_STYLE,
1115
+ ).ask()
1116
+
1117
+ if action == "cancel":
1118
+ console.print("[yellow]Changes cancelled[/yellow]")
1119
+ Prompt.ask("\nPress Enter to continue")
1120
+ return CommandResult(success=True, exit_code=0)
1121
+ if action == "adjust":
1122
+ # Loop back to skill selection
1123
+ console.print("\n[dim]Adjusting selection...[/dim]\n")
1124
+ continue
1125
+
1126
+ # Apply changes
1127
+ success = True
1128
+ errors = []
1129
+
1130
+ # Install skills
1131
+ if to_install:
1132
+ console.print("\n[bold cyan]Installing skills...[/bold cyan]\n")
1133
+ for skill_name in to_install:
1134
+ try:
1135
+ # Deploy single skill
1136
+ result = self.skills_deployer.deploy_skills(
1137
+ skill_names=[skill_name], force=False
1138
+ )
1139
+
1140
+ if result.get("errors"):
1141
+ errors.extend(result["errors"])
1142
+ success = False
1143
+ else:
1144
+ console.print(
1145
+ f"[green]✓ Installed: {skill_name}[/green]"
1146
+ )
1147
+ except Exception as e:
1148
+ errors.append(f"Failed to install {skill_name}: {e}")
1149
+ success = False
1150
+
1151
+ # Remove skills
1152
+ if to_remove:
1153
+ console.print("\n[bold yellow]Removing skills...[/bold yellow]\n")
1154
+ for skill_name in to_remove:
1155
+ try:
1156
+ # Remove single skill
1157
+ result = self.skills_deployer.remove_skills(
1158
+ skill_names=[skill_name]
1159
+ )
1160
+
1161
+ if result.get("errors"):
1162
+ errors.extend(result["errors"])
1163
+ success = False
1164
+ else:
1165
+ console.print(
1166
+ f"[yellow]✗ Removed: {skill_name}[/yellow]"
1167
+ )
1168
+ except Exception as e:
1169
+ errors.append(f"Failed to remove {skill_name}: {e}")
1170
+ success = False
1171
+
1172
+ # Show errors if any
1173
+ if errors:
1174
+ console.print(f"\n[red]✗ {len(errors)} error(s):[/red]")
1175
+ for error in errors:
1176
+ console.print(f" • {error}")
1177
+
1178
+ # Show restart instructions
1179
+ if success and (to_install or to_remove):
1180
+ console.print(
1181
+ "\n[bold green]✓ Changes applied successfully![/bold green]"
1182
+ )
1183
+ console.print("\n[yellow]⚠️ Important:[/yellow]")
1184
+ console.print(" Restart Claude Code for changes to take effect")
1185
+
1186
+ console.print()
1187
+ Prompt.ask("\nPress Enter to continue")
1188
+
1189
+ # Exit the loop after successful execution
1190
+ break
1191
+
1192
+ exit_code = 0 if success else 1
1193
+ return CommandResult(success=success, exit_code=exit_code)
1194
+
1195
+ except Exception as e:
1196
+ console.print(f"[red]Error in skills configuration: {e}[/red]")
1197
+ import traceback
1198
+
1199
+ console.print(f"[dim]{traceback.format_exc()}[/dim]")
1200
+ return CommandResult(success=False, message=str(e), exit_code=1)
1201
+
1202
+ return CommandResult(success=False, message=str(e), exit_code=1)
1203
+
467
1204
 
468
1205
  def manage_skills(args) -> int:
469
1206
  """