claude-mpm 4.21.3__py3-none-any.whl → 5.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (484) 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 +632 -334
  5. claude_mpm/agents/WORKFLOW.md +75 -2
  6. claude_mpm/agents/__init__.py +6 -0
  7. claude_mpm/agents/agent_loader.py +1 -4
  8. claude_mpm/agents/base_agent.json +6 -3
  9. claude_mpm/agents/frontmatter_validator.py +1 -1
  10. claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +370 -3
  11. claude_mpm/agents/templates/context-management-examples.md +544 -0
  12. claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
  13. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  14. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  15. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  16. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  17. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  18. claude_mpm/cli/__init__.py +38 -2
  19. claude_mpm/cli/commands/agent_source.py +774 -0
  20. claude_mpm/cli/commands/agent_state_manager.py +125 -20
  21. claude_mpm/cli/commands/agents.py +684 -13
  22. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  23. claude_mpm/cli/commands/agents_discover.py +338 -0
  24. claude_mpm/cli/commands/aggregate.py +1 -1
  25. claude_mpm/cli/commands/analyze.py +3 -3
  26. claude_mpm/cli/commands/auto_configure.py +2 -6
  27. claude_mpm/cli/commands/cleanup.py +1 -1
  28. claude_mpm/cli/commands/config.py +7 -4
  29. claude_mpm/cli/commands/configure.py +478 -44
  30. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  31. claude_mpm/cli/commands/configure_navigation.py +63 -46
  32. claude_mpm/cli/commands/debug.py +12 -12
  33. claude_mpm/cli/commands/doctor.py +10 -2
  34. claude_mpm/cli/commands/hook_errors.py +277 -0
  35. claude_mpm/cli/commands/local_deploy.py +1 -4
  36. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  37. claude_mpm/cli/commands/mpm_init/core.py +50 -2
  38. claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
  39. claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
  40. claude_mpm/cli/commands/run.py +124 -128
  41. claude_mpm/cli/commands/skill_source.py +694 -0
  42. claude_mpm/cli/commands/skills.py +435 -1
  43. claude_mpm/cli/executor.py +78 -3
  44. claude_mpm/cli/interactive/agent_wizard.py +919 -41
  45. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  46. claude_mpm/cli/parsers/agents_parser.py +173 -4
  47. claude_mpm/cli/parsers/base_parser.py +49 -0
  48. claude_mpm/cli/parsers/config_parser.py +96 -43
  49. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  50. claude_mpm/cli/parsers/skills_parser.py +138 -0
  51. claude_mpm/cli/parsers/source_parser.py +138 -0
  52. claude_mpm/cli/startup.py +499 -84
  53. claude_mpm/cli/startup_display.py +480 -0
  54. claude_mpm/cli/utils.py +1 -1
  55. claude_mpm/cli_module/commands.py +1 -1
  56. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  57. claude_mpm/commands/mpm-agents-detect.md +9 -0
  58. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  59. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  60. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  61. claude_mpm/commands/mpm-doctor.md +9 -0
  62. claude_mpm/commands/mpm-help.md +11 -2
  63. claude_mpm/commands/mpm-init.md +27 -2
  64. claude_mpm/commands/mpm-monitor.md +9 -0
  65. claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
  66. claude_mpm/commands/mpm-status.md +9 -0
  67. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  68. claude_mpm/commands/mpm-ticket-view.md +552 -0
  69. claude_mpm/commands/mpm-version.md +9 -0
  70. claude_mpm/commands/mpm.md +10 -0
  71. claude_mpm/config/agent_presets.py +258 -0
  72. claude_mpm/config/agent_sources.py +325 -0
  73. claude_mpm/config/skill_sources.py +590 -0
  74. claude_mpm/constants.py +12 -0
  75. claude_mpm/core/api_validator.py +1 -1
  76. claude_mpm/core/claude_runner.py +17 -10
  77. claude_mpm/core/config.py +24 -0
  78. claude_mpm/core/constants.py +1 -1
  79. claude_mpm/core/framework/__init__.py +3 -16
  80. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  81. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  82. claude_mpm/core/hook_error_memory.py +381 -0
  83. claude_mpm/core/hook_manager.py +41 -2
  84. claude_mpm/core/interactive_session.py +112 -5
  85. claude_mpm/core/logger.py +3 -1
  86. claude_mpm/core/oneshot_session.py +94 -4
  87. claude_mpm/dashboard/static/css/activity.css +69 -69
  88. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  89. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  90. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  91. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  92. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  93. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  94. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  95. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  96. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  97. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  98. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  99. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  100. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  101. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  102. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  103. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  104. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  105. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  106. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  107. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  108. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  109. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  110. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  111. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  112. claude_mpm/dashboard/templates/code_simple.html +23 -23
  113. claude_mpm/dashboard/templates/index.html +18 -18
  114. claude_mpm/experimental/cli_enhancements.py +1 -5
  115. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  116. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  117. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  118. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  119. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  120. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  121. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  122. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  123. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  124. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  125. claude_mpm/models/git_repository.py +198 -0
  126. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  127. claude_mpm/scripts/start_activity_logging.py +3 -1
  128. claude_mpm/services/agents/agent_builder.py +45 -9
  129. claude_mpm/services/agents/agent_preset_service.py +238 -0
  130. claude_mpm/services/agents/agent_selection_service.py +484 -0
  131. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  132. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  133. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  134. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  135. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  136. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  137. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  138. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  139. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  140. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  141. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  142. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
  143. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  144. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  145. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  146. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  147. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  148. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  149. claude_mpm/services/agents/git_source_manager.py +629 -0
  150. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  151. claude_mpm/services/agents/local_template_manager.py +50 -10
  152. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  153. claude_mpm/services/agents/sources/__init__.py +13 -0
  154. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  155. claude_mpm/services/agents/sources/git_source_sync_service.py +1055 -0
  156. claude_mpm/services/agents/startup_sync.py +239 -0
  157. claude_mpm/services/agents/toolchain_detector.py +474 -0
  158. claude_mpm/services/cli/session_pause_manager.py +1 -1
  159. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  160. claude_mpm/services/command_deployment_service.py +92 -1
  161. claude_mpm/services/core/interfaces/__init__.py +1 -3
  162. claude_mpm/services/core/interfaces/health.py +1 -4
  163. claude_mpm/services/core/models/__init__.py +2 -11
  164. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  165. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  166. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  167. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  168. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  169. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  170. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  171. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  172. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  173. claude_mpm/services/event_bus/direct_relay.py +3 -3
  174. claude_mpm/services/event_bus/event_bus.py +36 -3
  175. claude_mpm/services/events/consumers/logging.py +1 -2
  176. claude_mpm/services/git/__init__.py +21 -0
  177. claude_mpm/services/git/git_operations_service.py +494 -0
  178. claude_mpm/services/github/__init__.py +21 -0
  179. claude_mpm/services/github/github_cli_service.py +397 -0
  180. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  181. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  182. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  183. claude_mpm/services/instructions/__init__.py +9 -0
  184. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  185. claude_mpm/services/local_ops/__init__.py +3 -13
  186. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  187. claude_mpm/services/local_ops/health_manager.py +1 -4
  188. claude_mpm/services/local_ops/process_manager.py +1 -1
  189. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  190. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  191. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  192. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  193. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  194. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  195. claude_mpm/services/memory/optimizer.py +1 -1
  196. claude_mpm/services/model/model_router.py +8 -9
  197. claude_mpm/services/monitor/daemon.py +1 -1
  198. claude_mpm/services/monitor/server.py +2 -2
  199. claude_mpm/services/native_agent_converter.py +356 -0
  200. claude_mpm/services/port_manager.py +1 -1
  201. claude_mpm/services/pr/__init__.py +14 -0
  202. claude_mpm/services/pr/pr_template_service.py +329 -0
  203. claude_mpm/services/project/documentation_manager.py +2 -1
  204. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  205. claude_mpm/services/runner_configuration_service.py +1 -0
  206. claude_mpm/services/self_upgrade_service.py +165 -7
  207. claude_mpm/services/skills/__init__.py +18 -0
  208. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  209. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  210. claude_mpm/services/skills_config.py +547 -0
  211. claude_mpm/services/skills_deployer.py +955 -0
  212. claude_mpm/services/socketio/handlers/connection.py +1 -1
  213. claude_mpm/services/socketio/handlers/git.py +2 -2
  214. claude_mpm/services/socketio/server/core.py +1 -4
  215. claude_mpm/services/socketio/server/main.py +1 -3
  216. claude_mpm/services/system_instructions_service.py +1 -3
  217. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  218. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  219. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  220. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  221. claude_mpm/services/unified/unified_deployment.py +1 -5
  222. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  223. claude_mpm/services/visualization/__init__.py +1 -5
  224. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  225. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  226. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  227. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
  228. claude_mpm/skills/skills_registry.py +0 -1
  229. claude_mpm/templates/questions/__init__.py +38 -0
  230. claude_mpm/templates/questions/base.py +193 -0
  231. claude_mpm/templates/questions/pr_strategy.py +311 -0
  232. claude_mpm/templates/questions/project_init.py +385 -0
  233. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  234. claude_mpm/tools/__main__.py +8 -8
  235. claude_mpm/tools/code_tree_analyzer/analysis.py +1 -1
  236. claude_mpm/utils/agent_dependency_loader.py +80 -13
  237. claude_mpm/utils/dependency_cache.py +3 -1
  238. claude_mpm/utils/gitignore.py +241 -0
  239. claude_mpm/utils/log_cleanup.py +3 -3
  240. claude_mpm/utils/progress.py +383 -0
  241. claude_mpm/utils/robust_installer.py +3 -5
  242. claude_mpm/utils/structured_questions.py +619 -0
  243. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/METADATA +429 -59
  244. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/RECORD +252 -425
  245. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  246. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  247. claude_mpm/agents/templates/agent-manager.json +0 -273
  248. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  249. claude_mpm/agents/templates/api_qa.json +0 -180
  250. claude_mpm/agents/templates/clerk-ops.json +0 -235
  251. claude_mpm/agents/templates/code_analyzer.json +0 -101
  252. claude_mpm/agents/templates/content-agent.json +0 -358
  253. claude_mpm/agents/templates/dart_engineer.json +0 -307
  254. claude_mpm/agents/templates/data_engineer.json +0 -225
  255. claude_mpm/agents/templates/documentation.json +0 -211
  256. claude_mpm/agents/templates/engineer.json +0 -210
  257. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  258. claude_mpm/agents/templates/golang_engineer.json +0 -270
  259. claude_mpm/agents/templates/imagemagick.json +0 -264
  260. claude_mpm/agents/templates/java_engineer.json +0 -346
  261. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  262. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  263. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  264. claude_mpm/agents/templates/memory_manager.json +0 -158
  265. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  266. claude_mpm/agents/templates/ops.json +0 -185
  267. claude_mpm/agents/templates/php-engineer.json +0 -287
  268. claude_mpm/agents/templates/product_owner.json +0 -338
  269. claude_mpm/agents/templates/project_organizer.json +0 -140
  270. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  271. claude_mpm/agents/templates/python_engineer.json +0 -387
  272. claude_mpm/agents/templates/qa.json +0 -242
  273. claude_mpm/agents/templates/react_engineer.json +0 -238
  274. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  275. claude_mpm/agents/templates/research.json +0 -188
  276. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  277. claude_mpm/agents/templates/rust_engineer.json +0 -275
  278. claude_mpm/agents/templates/security.json +0 -202
  279. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  280. claude_mpm/agents/templates/ticketing.json +0 -177
  281. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  282. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  283. claude_mpm/agents/templates/version_control.json +0 -157
  284. claude_mpm/agents/templates/web_qa.json +0 -399
  285. claude_mpm/agents/templates/web_ui.json +0 -189
  286. claude_mpm/commands/mpm-tickets.md +0 -102
  287. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  288. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  289. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  290. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  291. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  292. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  293. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  294. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  295. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  296. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  297. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  298. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  299. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  300. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  301. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  302. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  303. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  304. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  305. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  306. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  307. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  308. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  309. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  310. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  311. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  312. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  313. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  314. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  315. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  316. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  317. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  318. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  319. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  320. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  321. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  322. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  323. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  324. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  325. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  326. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  327. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  328. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  329. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  330. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  331. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  332. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  333. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  334. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  335. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  336. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  337. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  338. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  339. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  340. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  341. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  342. claude_mpm/dashboard/static/built/react/events.js +0 -30
  343. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  344. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  345. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  346. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  347. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  348. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  349. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  350. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  351. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  352. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  353. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  354. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  355. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  356. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  357. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  358. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  359. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  360. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  361. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  362. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  363. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  364. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  365. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  366. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  367. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  368. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  369. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  370. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  371. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  372. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  373. claude_mpm/dashboard/static/events.html +0 -607
  374. claude_mpm/dashboard/static/index.html +0 -635
  375. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  376. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  377. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  378. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  379. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  380. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  381. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  382. claude_mpm/dashboard/static/legacy/files.html +0 -747
  383. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  384. claude_mpm/dashboard/static/monitors.html +0 -431
  385. claude_mpm/dashboard/static/production/events.html +0 -659
  386. claude_mpm/dashboard/static/production/main.html +0 -698
  387. claude_mpm/dashboard/static/production/monitors.html +0 -483
  388. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  389. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  390. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  391. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  392. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  393. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  394. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  395. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  396. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  397. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  398. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  399. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  400. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  401. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  402. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  403. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  404. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  405. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  406. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  407. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  408. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  409. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  410. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  411. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  412. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  413. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  414. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  415. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  416. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  417. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  418. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  419. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  420. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  421. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  422. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  423. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  424. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  425. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  426. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  427. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  428. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  429. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  430. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  431. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  432. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  433. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  434. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  435. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  436. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  437. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  438. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  439. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  440. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  441. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  442. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  443. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  444. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  445. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  446. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  447. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  448. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  449. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  450. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  451. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  452. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  453. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  454. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  455. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  456. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  457. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  458. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  459. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  460. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  461. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  462. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  463. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  464. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  465. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  466. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
  467. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
  468. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
  469. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
  470. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
  471. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
  472. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  473. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  474. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  475. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  476. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  477. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  478. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  479. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  480. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  481. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/WHEEL +0 -0
  482. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/entry_points.txt +0 -0
  483. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/licenses/LICENSE +0 -0
  484. {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,547 @@
1
+ """Skills Configuration Service - Manage skill collections and settings.
2
+
3
+ WHY: Skills can come from multiple GitHub repositories (collections). This service
4
+ manages collection configurations, priorities, and enables/disables collections.
5
+
6
+ DESIGN DECISIONS:
7
+ - Store config in ~/.claude-mpm/config.json under "skills" key
8
+ - Support multiple collections with priority ordering
9
+ - Enable/disable collections without removing them
10
+ - Default collection for implicit deployments
11
+ - Backward compatible with single-collection usage
12
+
13
+ ARCHITECTURE:
14
+ 1. Configuration Management: Load/save collection settings
15
+ 2. Collection CRUD: Add, remove, update collections
16
+ 3. Default Management: Set default collection for implicit deployments
17
+ 4. Timestamp Tracking: Track last update time for each collection
18
+
19
+ Example config structure:
20
+ {
21
+ "skills": {
22
+ "collections": {
23
+ "claude-mpm": {
24
+ "url": "https://github.com/bobmatnyc/claude-mpm-skills",
25
+ "enabled": true,
26
+ "priority": 1,
27
+ "last_update": "2025-11-21T15:30:00Z"
28
+ },
29
+ "obra-superpowers": {
30
+ "url": "https://github.com/obra/superpowers",
31
+ "enabled": true,
32
+ "priority": 2,
33
+ "last_update": null
34
+ }
35
+ },
36
+ "default_collection": "claude-mpm"
37
+ }
38
+ }
39
+ """
40
+
41
+ from datetime import datetime, timezone
42
+ from pathlib import Path
43
+ from typing import Any, Dict, List, Optional
44
+
45
+ from claude_mpm.core.mixins import LoggerMixin
46
+ from claude_mpm.utils.config_manager import ConfigurationManager
47
+
48
+
49
+ class SkillsConfig(LoggerMixin):
50
+ """Manage skills configuration including collections.
51
+
52
+ This service provides:
53
+ - Collection CRUD operations (add, remove, update, list)
54
+ - Enable/disable collections
55
+ - Default collection management
56
+ - Timestamp tracking for updates
57
+ - Priority-based ordering
58
+
59
+ Example:
60
+ >>> config = SkillsConfig()
61
+ >>> config.add_collection("custom", "https://github.com/user/skills", priority=3)
62
+ >>> collections = config.get_collections()
63
+ >>> config.set_default_collection("custom")
64
+ """
65
+
66
+ DEFAULT_REPO_URL = "https://github.com/bobmatnyc/claude-mpm-skills"
67
+
68
+ def __init__(self):
69
+ """Initialize Skills Configuration Service."""
70
+ super().__init__()
71
+ self.config_path = Path.home() / ".claude-mpm" / "config.json"
72
+ self.config_manager = ConfigurationManager()
73
+ self._ensure_config_exists()
74
+
75
+ def _ensure_config_exists(self) -> None:
76
+ """Create default config if not exists.
77
+
78
+ Creates initial configuration with default claude-mpm collection.
79
+ """
80
+ if not self.config_path.exists():
81
+ self.logger.info(
82
+ f"Creating default skills configuration at {self.config_path}"
83
+ )
84
+ self.config_path.parent.mkdir(parents=True, exist_ok=True)
85
+
86
+ default_config = {
87
+ "version": "1.0",
88
+ "skills": {
89
+ "collections": {
90
+ "claude-mpm": {
91
+ "url": self.DEFAULT_REPO_URL,
92
+ "enabled": True,
93
+ "priority": 1,
94
+ "last_update": None,
95
+ }
96
+ },
97
+ "default_collection": "claude-mpm",
98
+ },
99
+ }
100
+
101
+ self._save_config(default_config)
102
+ else:
103
+ # Ensure skills section exists in existing config
104
+ config = self._load_config()
105
+ if "skills" not in config:
106
+ self.logger.info("Adding skills section to existing config")
107
+ config["skills"] = {
108
+ "collections": {
109
+ "claude-mpm": {
110
+ "url": self.DEFAULT_REPO_URL,
111
+ "enabled": True,
112
+ "priority": 1,
113
+ "last_update": None,
114
+ }
115
+ },
116
+ "default_collection": "claude-mpm",
117
+ }
118
+ self._save_config(config)
119
+
120
+ def _load_config(self) -> Dict[str, Any]:
121
+ """Load configuration from disk.
122
+
123
+ Returns:
124
+ Configuration dictionary
125
+
126
+ Raises:
127
+ FileNotFoundError: If config file doesn't exist
128
+ json.JSONDecodeError: If config is invalid JSON
129
+ """
130
+ return self.config_manager.load_json(self.config_path)
131
+
132
+ def _save_config(self, config: Dict[str, Any]) -> None:
133
+ """Save configuration to disk.
134
+
135
+ Args:
136
+ config: Configuration dictionary to save
137
+ """
138
+ self.config_manager.save_json(config, self.config_path, indent=2)
139
+ self.logger.debug(f"Configuration saved to {self.config_path}")
140
+
141
+ def get_collections(self) -> Dict[str, Dict[str, Any]]:
142
+ """Get all collections.
143
+
144
+ Returns:
145
+ Dict mapping collection names to their configurations
146
+
147
+ Example:
148
+ >>> config.get_collections()
149
+ {
150
+ "claude-mpm": {
151
+ "url": "https://github.com/bobmatnyc/claude-mpm-skills",
152
+ "enabled": True,
153
+ "priority": 1,
154
+ "last_update": "2025-11-21T15:30:00Z"
155
+ },
156
+ "obra-superpowers": {
157
+ "url": "https://github.com/obra/superpowers",
158
+ "enabled": True,
159
+ "priority": 2,
160
+ "last_update": null
161
+ }
162
+ }
163
+ """
164
+ config = self._load_config()
165
+ return config.get("skills", {}).get("collections", {})
166
+
167
+ def get_enabled_collections(self) -> Dict[str, Dict[str, Any]]:
168
+ """Get only enabled collections.
169
+
170
+ Returns:
171
+ Dict mapping enabled collection names to their configurations
172
+ """
173
+ all_collections = self.get_collections()
174
+ return {
175
+ name: details
176
+ for name, details in all_collections.items()
177
+ if details.get("enabled", True)
178
+ }
179
+
180
+ def get_collections_by_priority(
181
+ self, enabled_only: bool = True
182
+ ) -> List[tuple[str, Dict[str, Any]]]:
183
+ """Get collections sorted by priority (lower number = higher priority).
184
+
185
+ Args:
186
+ enabled_only: Only return enabled collections
187
+
188
+ Returns:
189
+ List of (name, config) tuples sorted by priority
190
+
191
+ Example:
192
+ >>> collections = config.get_collections_by_priority()
193
+ >>> [(name, details['priority']) for name, details in collections]
194
+ [('claude-mpm', 1), ('obra-superpowers', 2), ('custom', 3)]
195
+ """
196
+ collections = (
197
+ self.get_enabled_collections() if enabled_only else self.get_collections()
198
+ )
199
+
200
+ # Sort by priority (lower = higher priority)
201
+ return sorted(collections.items(), key=lambda x: x[1].get("priority", 999))
202
+
203
+ def get_collection(self, name: str) -> Optional[Dict[str, Any]]:
204
+ """Get specific collection.
205
+
206
+ Args:
207
+ name: Collection name
208
+
209
+ Returns:
210
+ Collection configuration or None if not found
211
+
212
+ Example:
213
+ >>> config.get_collection("claude-mpm")
214
+ {
215
+ "url": "https://github.com/bobmatnyc/claude-mpm-skills",
216
+ "enabled": True,
217
+ "priority": 1,
218
+ "last_update": "2025-11-21T15:30:00Z"
219
+ }
220
+ """
221
+ collections = self.get_collections()
222
+ return collections.get(name)
223
+
224
+ def add_collection(
225
+ self,
226
+ name: str,
227
+ url: str,
228
+ priority: int = 99,
229
+ enabled: bool = True,
230
+ ) -> Dict[str, Any]:
231
+ """Add new collection.
232
+
233
+ Args:
234
+ name: Collection name (must be unique)
235
+ url: GitHub repository URL
236
+ priority: Collection priority (lower = higher priority, default: 99)
237
+ enabled: Whether collection is enabled (default: True)
238
+
239
+ Returns:
240
+ Dict with operation result
241
+
242
+ Raises:
243
+ ValueError: If collection already exists
244
+
245
+ Example:
246
+ >>> config.add_collection(
247
+ ... "obra-superpowers",
248
+ ... "https://github.com/obra/superpowers",
249
+ ... priority=2
250
+ ... )
251
+ {"status": "success", "message": "Collection 'obra-superpowers' added"}
252
+ """
253
+ config = self._load_config()
254
+ collections = config.get("skills", {}).get("collections", {})
255
+
256
+ if name in collections:
257
+ raise ValueError(f"Collection '{name}' already exists")
258
+
259
+ # Validate URL format
260
+ if not url.startswith("https://github.com/"):
261
+ raise ValueError(
262
+ f"Invalid GitHub URL: {url}. Must start with 'https://github.com/'"
263
+ )
264
+
265
+ collections[name] = {
266
+ "url": url,
267
+ "enabled": enabled,
268
+ "priority": priority,
269
+ "last_update": None,
270
+ }
271
+
272
+ config.setdefault("skills", {})["collections"] = collections
273
+ self._save_config(config)
274
+
275
+ self.logger.info(
276
+ f"Added collection '{name}' with priority {priority}, enabled={enabled}"
277
+ )
278
+ return {
279
+ "status": "success",
280
+ "message": f"Collection '{name}' added successfully",
281
+ "collection": collections[name],
282
+ }
283
+
284
+ def remove_collection(self, name: str) -> Dict[str, Any]:
285
+ """Remove collection.
286
+
287
+ Args:
288
+ name: Collection name to remove
289
+
290
+ Returns:
291
+ Dict with operation result
292
+
293
+ Raises:
294
+ ValueError: If collection doesn't exist or is default collection
295
+
296
+ Example:
297
+ >>> config.remove_collection("obra-superpowers")
298
+ {"status": "success", "message": "Collection 'obra-superpowers' removed"}
299
+ """
300
+ config = self._load_config()
301
+ collections = config.get("skills", {}).get("collections", {})
302
+
303
+ if name not in collections:
304
+ raise ValueError(f"Collection '{name}' not found")
305
+
306
+ # Prevent removing default collection
307
+ default_collection = config.get("skills", {}).get("default_collection")
308
+ if name == default_collection:
309
+ raise ValueError(
310
+ f"Cannot remove default collection '{name}'. "
311
+ f"Set a different default collection first."
312
+ )
313
+
314
+ del collections[name]
315
+ config["skills"]["collections"] = collections
316
+ self._save_config(config)
317
+
318
+ self.logger.info(f"Removed collection '{name}'")
319
+ return {
320
+ "status": "success",
321
+ "message": f"Collection '{name}' removed successfully",
322
+ }
323
+
324
+ def update_collection(self, name: str, updates: Dict[str, Any]) -> Dict[str, Any]:
325
+ """Update collection properties.
326
+
327
+ Args:
328
+ name: Collection name
329
+ updates: Dict of properties to update (url, enabled, priority)
330
+
331
+ Returns:
332
+ Dict with operation result
333
+
334
+ Raises:
335
+ ValueError: If collection doesn't exist
336
+
337
+ Example:
338
+ >>> config.update_collection("obra-superpowers", {"priority": 1})
339
+ {"status": "success", "message": "Collection 'obra-superpowers' updated"}
340
+ """
341
+ config = self._load_config()
342
+ collections = config.get("skills", {}).get("collections", {})
343
+
344
+ if name not in collections:
345
+ raise ValueError(f"Collection '{name}' not found")
346
+
347
+ # Update allowed fields only
348
+ allowed_fields = {"url", "enabled", "priority"}
349
+ for key, value in updates.items():
350
+ if key in allowed_fields:
351
+ collections[name][key] = value
352
+ else:
353
+ self.logger.warning(f"Ignoring unknown field '{key}' in update")
354
+
355
+ config["skills"]["collections"] = collections
356
+ self._save_config(config)
357
+
358
+ self.logger.info(f"Updated collection '{name}': {updates}")
359
+ return {
360
+ "status": "success",
361
+ "message": f"Collection '{name}' updated successfully",
362
+ "collection": collections[name],
363
+ }
364
+
365
+ def enable_collection(self, name: str) -> Dict[str, Any]:
366
+ """Enable a disabled collection.
367
+
368
+ Args:
369
+ name: Collection name
370
+
371
+ Returns:
372
+ Dict with operation result
373
+
374
+ Example:
375
+ >>> config.enable_collection("obra-superpowers")
376
+ {"status": "success", "message": "Collection 'obra-superpowers' enabled"}
377
+ """
378
+ return self.update_collection(name, {"enabled": True})
379
+
380
+ def disable_collection(self, name: str) -> Dict[str, Any]:
381
+ """Disable a collection without removing it.
382
+
383
+ Args:
384
+ name: Collection name
385
+
386
+ Returns:
387
+ Dict with operation result
388
+
389
+ Raises:
390
+ ValueError: If trying to disable default collection
391
+
392
+ Example:
393
+ >>> config.disable_collection("obra-superpowers")
394
+ {"status": "success", "message": "Collection 'obra-superpowers' disabled"}
395
+ """
396
+ config = self._load_config()
397
+ default_collection = config.get("skills", {}).get("default_collection")
398
+
399
+ if name == default_collection:
400
+ raise ValueError(
401
+ f"Cannot disable default collection '{name}'. "
402
+ f"Set a different default collection first."
403
+ )
404
+
405
+ return self.update_collection(name, {"enabled": False})
406
+
407
+ def get_default_collection(self) -> str:
408
+ """Get the default collection name.
409
+
410
+ Returns:
411
+ Default collection name
412
+
413
+ Example:
414
+ >>> config.get_default_collection()
415
+ "claude-mpm"
416
+ """
417
+ config = self._load_config()
418
+ return config.get("skills", {}).get("default_collection", "claude-mpm")
419
+
420
+ def set_default_collection(self, name: str) -> Dict[str, Any]:
421
+ """Set the default collection.
422
+
423
+ Args:
424
+ name: Collection name to set as default
425
+
426
+ Returns:
427
+ Dict with operation result
428
+
429
+ Raises:
430
+ ValueError: If collection doesn't exist or is disabled
431
+
432
+ Example:
433
+ >>> config.set_default_collection("obra-superpowers")
434
+ {
435
+ "status": "success",
436
+ "message": "Default collection set to 'obra-superpowers'",
437
+ "previous_default": "claude-mpm"
438
+ }
439
+ """
440
+ config = self._load_config()
441
+ collections = config.get("skills", {}).get("collections", {})
442
+
443
+ if name not in collections:
444
+ raise ValueError(f"Collection '{name}' not found")
445
+
446
+ if not collections[name].get("enabled", True):
447
+ raise ValueError(
448
+ f"Cannot set disabled collection '{name}' as default. Enable it first."
449
+ )
450
+
451
+ previous_default = config.get("skills", {}).get("default_collection")
452
+
453
+ config.setdefault("skills", {})["default_collection"] = name
454
+ self._save_config(config)
455
+
456
+ self.logger.info(
457
+ f"Set default collection to '{name}' (was: '{previous_default}')"
458
+ )
459
+ return {
460
+ "status": "success",
461
+ "message": f"Default collection set to '{name}'",
462
+ "previous_default": previous_default,
463
+ "new_default": name,
464
+ }
465
+
466
+ def update_collection_timestamp(self, name: str) -> Dict[str, Any]:
467
+ """Update the last_update timestamp for a collection.
468
+
469
+ Args:
470
+ name: Collection name
471
+
472
+ Returns:
473
+ Dict with operation result
474
+
475
+ Example:
476
+ >>> config.update_collection_timestamp("claude-mpm")
477
+ {
478
+ "status": "success",
479
+ "message": "Timestamp updated for 'claude-mpm'",
480
+ "timestamp": "2025-11-21T15:30:00Z"
481
+ }
482
+ """
483
+ timestamp = datetime.now(timezone.utc).isoformat()
484
+
485
+ result = self.update_collection(name, {"last_update": timestamp})
486
+ result["timestamp"] = timestamp
487
+ result["message"] = f"Timestamp updated for '{name}'"
488
+
489
+ return result
490
+
491
+ def get_config_path(self) -> Path:
492
+ """Get path to configuration file.
493
+
494
+ Returns:
495
+ Path to config file
496
+
497
+ Example:
498
+ >>> config.get_config_path()
499
+ PosixPath('/Users/username/.claude-mpm/config.json')
500
+ """
501
+ return self.config_path
502
+
503
+ def validate_collection_config(
504
+ self, collection_config: Dict[str, Any]
505
+ ) -> List[str]:
506
+ """Validate a collection configuration.
507
+
508
+ Args:
509
+ collection_config: Collection configuration to validate
510
+
511
+ Returns:
512
+ List of validation errors (empty if valid)
513
+
514
+ Example:
515
+ >>> errors = config.validate_collection_config({
516
+ ... "url": "https://github.com/user/repo",
517
+ ... "enabled": True,
518
+ ... "priority": 1
519
+ ... })
520
+ >>> errors
521
+ []
522
+ """
523
+ errors = []
524
+
525
+ # Required fields
526
+ if "url" not in collection_config:
527
+ errors.append("Missing required field: url")
528
+ elif not collection_config["url"].startswith("https://github.com/"):
529
+ errors.append(
530
+ f"Invalid URL: {collection_config['url']}. "
531
+ f"Must be a GitHub repository URL."
532
+ )
533
+
534
+ # Optional field validations
535
+ if "enabled" in collection_config and not isinstance(
536
+ collection_config["enabled"], bool
537
+ ):
538
+ errors.append("Field 'enabled' must be a boolean")
539
+
540
+ if "priority" in collection_config:
541
+ priority = collection_config["priority"]
542
+ if not isinstance(priority, int):
543
+ errors.append("Field 'priority' must be an integer")
544
+ elif priority < 1:
545
+ errors.append("Field 'priority' must be >= 1")
546
+
547
+ return errors