claude-mpm 4.20.3__py3-none-any.whl → 4.25.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (454) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +23 -6
  3. claude_mpm/agents/OUTPUT_STYLE.md +3 -48
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +1783 -34
  5. claude_mpm/agents/WORKFLOW.md +75 -2
  6. claude_mpm/agents/base_agent.json +6 -3
  7. claude_mpm/agents/frontmatter_validator.py +1 -1
  8. claude_mpm/agents/templates/api_qa.json +5 -2
  9. claude_mpm/agents/templates/circuit_breakers.md +108 -2
  10. claude_mpm/agents/templates/documentation.json +33 -6
  11. claude_mpm/agents/templates/javascript_engineer_agent.json +380 -0
  12. claude_mpm/agents/templates/php-engineer.json +10 -4
  13. claude_mpm/agents/templates/pm_red_flags.md +89 -19
  14. claude_mpm/agents/templates/project_organizer.json +7 -3
  15. claude_mpm/agents/templates/qa.json +2 -1
  16. claude_mpm/agents/templates/react_engineer.json +1 -0
  17. claude_mpm/agents/templates/research.json +82 -12
  18. claude_mpm/agents/templates/security.json +4 -4
  19. claude_mpm/agents/templates/tauri_engineer.json +274 -0
  20. claude_mpm/agents/templates/ticketing.json +10 -6
  21. claude_mpm/agents/templates/version_control.json +4 -2
  22. claude_mpm/agents/templates/web_qa.json +2 -1
  23. claude_mpm/cli/README.md +253 -0
  24. claude_mpm/cli/__init__.py +11 -1
  25. claude_mpm/cli/commands/aggregate.py +1 -1
  26. claude_mpm/cli/commands/analyze.py +3 -3
  27. claude_mpm/cli/commands/cleanup.py +1 -1
  28. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  29. claude_mpm/cli/commands/debug.py +12 -12
  30. claude_mpm/cli/commands/hook_errors.py +277 -0
  31. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  32. claude_mpm/cli/commands/mcp_install_commands.py.backup +284 -0
  33. claude_mpm/cli/commands/mpm_init/README.md +365 -0
  34. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  35. claude_mpm/cli/commands/mpm_init/core.py +573 -0
  36. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  37. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  38. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  39. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  40. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  41. claude_mpm/cli/commands/mpm_init_handler.py +67 -1
  42. claude_mpm/cli/commands/run.py +124 -128
  43. claude_mpm/cli/commands/skills.py +522 -34
  44. claude_mpm/cli/executor.py +56 -0
  45. claude_mpm/cli/interactive/agent_wizard.py +5 -5
  46. claude_mpm/cli/parsers/base_parser.py +28 -0
  47. claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
  48. claude_mpm/cli/parsers/skills_parser.py +138 -0
  49. claude_mpm/cli/startup.py +111 -8
  50. claude_mpm/cli/startup_display.py +480 -0
  51. claude_mpm/cli/utils.py +1 -1
  52. claude_mpm/cli_module/commands.py +1 -1
  53. claude_mpm/cli_module/refactoring_guide.md +253 -0
  54. claude_mpm/commands/mpm-help.md +3 -0
  55. claude_mpm/commands/mpm-init.md +19 -3
  56. claude_mpm/commands/mpm-resume.md +372 -0
  57. claude_mpm/commands/mpm-tickets.md +56 -7
  58. claude_mpm/commands/mpm.md +1 -0
  59. claude_mpm/config/agent_capabilities.yaml +658 -0
  60. claude_mpm/config/async_logging_config.yaml +145 -0
  61. claude_mpm/constants.py +12 -0
  62. claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +34 -0
  63. claude_mpm/core/api_validator.py +1 -1
  64. claude_mpm/core/claude_runner.py +14 -1
  65. claude_mpm/core/config.py +8 -0
  66. claude_mpm/core/constants.py +1 -1
  67. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  68. claude_mpm/core/hook_error_memory.py +381 -0
  69. claude_mpm/core/hook_manager.py +41 -2
  70. claude_mpm/core/interactive_session.py +48 -3
  71. claude_mpm/core/interfaces.py +56 -1
  72. claude_mpm/core/logger.py +3 -1
  73. claude_mpm/core/oneshot_session.py +39 -0
  74. claude_mpm/d2/.gitignore +22 -0
  75. claude_mpm/d2/ARCHITECTURE_COMPARISON.md +273 -0
  76. claude_mpm/d2/FLASK_INTEGRATION.md +156 -0
  77. claude_mpm/d2/IMPLEMENTATION_SUMMARY.md +452 -0
  78. claude_mpm/d2/QUICKSTART.md +186 -0
  79. claude_mpm/d2/README.md +232 -0
  80. claude_mpm/d2/STORE_FIX_SUMMARY.md +167 -0
  81. claude_mpm/d2/SVELTE5_STORES_GUIDE.md +180 -0
  82. claude_mpm/d2/TESTING.md +288 -0
  83. claude_mpm/d2/index.html +118 -0
  84. claude_mpm/d2/package.json +19 -0
  85. claude_mpm/d2/src/App.svelte +110 -0
  86. claude_mpm/d2/src/components/Header.svelte +153 -0
  87. claude_mpm/d2/src/components/MainContent.svelte +74 -0
  88. claude_mpm/d2/src/components/Sidebar.svelte +85 -0
  89. claude_mpm/d2/src/components/tabs/EventsTab.svelte +326 -0
  90. claude_mpm/d2/src/lib/socketio.js +144 -0
  91. claude_mpm/d2/src/main.js +7 -0
  92. claude_mpm/d2/src/stores/events.js +114 -0
  93. claude_mpm/d2/src/stores/socket.js +108 -0
  94. claude_mpm/d2/src/stores/theme.js +65 -0
  95. claude_mpm/d2/svelte.config.js +12 -0
  96. claude_mpm/d2/vite.config.js +15 -0
  97. claude_mpm/dashboard/.claude-mpm/memories/README.md +36 -0
  98. claude_mpm/dashboard/BUILD_NUMBER +1 -0
  99. claude_mpm/dashboard/README.md +121 -0
  100. claude_mpm/dashboard/VERSION +1 -0
  101. claude_mpm/dashboard/react/components/DataInspector/DataInspector.tsx +273 -0
  102. claude_mpm/dashboard/react/components/ErrorBoundary.tsx +75 -0
  103. claude_mpm/dashboard/react/components/EventViewer/EventViewer.tsx +141 -0
  104. claude_mpm/dashboard/react/components/shared/ConnectionStatus.tsx +36 -0
  105. claude_mpm/dashboard/react/components/shared/FilterBar.tsx +89 -0
  106. claude_mpm/dashboard/react/contexts/DashboardContext.tsx +215 -0
  107. claude_mpm/dashboard/react/entries/events.tsx +165 -0
  108. claude_mpm/dashboard/react/hooks/useEvents.ts +191 -0
  109. claude_mpm/dashboard/react/hooks/useSocket.ts +225 -0
  110. claude_mpm/dashboard/static/built/REFACTORING_SUMMARY.md +170 -0
  111. claude_mpm/dashboard/static/built/components/activity-tree.js.map +1 -0
  112. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +101 -101
  113. claude_mpm/dashboard/static/built/components/agent-inference.js.map +1 -0
  114. claude_mpm/dashboard/static/built/components/build-tracker.js +59 -59
  115. claude_mpm/dashboard/static/built/components/code-simple.js +107 -107
  116. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +29 -29
  117. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +24 -24
  118. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +27 -27
  119. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +25 -25
  120. claude_mpm/dashboard/static/built/components/code-tree.js.map +1 -0
  121. claude_mpm/dashboard/static/built/components/code-viewer.js.map +1 -0
  122. claude_mpm/dashboard/static/built/components/connection-debug.js +101 -101
  123. claude_mpm/dashboard/static/built/components/diff-viewer.js +113 -113
  124. claude_mpm/dashboard/static/built/components/event-processor.js.map +1 -0
  125. claude_mpm/dashboard/static/built/components/event-viewer.js.map +1 -0
  126. claude_mpm/dashboard/static/built/components/export-manager.js.map +1 -0
  127. claude_mpm/dashboard/static/built/components/file-change-tracker.js +57 -57
  128. claude_mpm/dashboard/static/built/components/file-change-viewer.js +74 -74
  129. claude_mpm/dashboard/static/built/components/file-tool-tracker.js.map +1 -0
  130. claude_mpm/dashboard/static/built/components/file-viewer.js.map +1 -0
  131. claude_mpm/dashboard/static/built/components/hud-library-loader.js.map +1 -0
  132. claude_mpm/dashboard/static/built/components/hud-manager.js.map +1 -0
  133. claude_mpm/dashboard/static/built/components/hud-visualizer.js.map +1 -0
  134. claude_mpm/dashboard/static/built/components/module-viewer.js.map +1 -0
  135. claude_mpm/dashboard/static/built/components/session-manager.js.map +1 -0
  136. claude_mpm/dashboard/static/built/components/socket-manager.js.map +1 -0
  137. claude_mpm/dashboard/static/built/components/ui-state-manager.js.map +1 -0
  138. claude_mpm/dashboard/static/built/components/unified-data-viewer.js.map +1 -0
  139. claude_mpm/dashboard/static/built/components/working-directory.js.map +1 -0
  140. claude_mpm/dashboard/static/built/connection-manager.js +76 -76
  141. claude_mpm/dashboard/static/built/dashboard.js.map +1 -0
  142. claude_mpm/dashboard/static/built/extension-error-handler.js +22 -22
  143. claude_mpm/dashboard/static/built/react/events.js.map +1 -0
  144. claude_mpm/dashboard/static/built/shared/dom-helpers.js +9 -9
  145. claude_mpm/dashboard/static/built/shared/event-bus.js +5 -5
  146. claude_mpm/dashboard/static/built/shared/logger.js +16 -16
  147. claude_mpm/dashboard/static/built/shared/tooltip-service.js +6 -6
  148. claude_mpm/dashboard/static/built/socket-client.js.map +1 -0
  149. claude_mpm/dashboard/static/css/activity.css +69 -69
  150. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  151. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  152. claude_mpm/dashboard/static/index.html +22 -22
  153. claude_mpm/dashboard/static/js/REFACTORING_SUMMARY.md +170 -0
  154. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  155. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  156. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  157. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  158. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  159. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  160. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  161. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  162. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  163. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  164. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  165. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  166. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  167. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  168. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  169. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  170. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  171. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  172. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  173. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  174. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  175. claude_mpm/dashboard/static/js/shared/dom-helpers.js +9 -9
  176. claude_mpm/dashboard/static/js/shared/event-bus.js +5 -5
  177. claude_mpm/dashboard/static/js/shared/logger.js +16 -16
  178. claude_mpm/dashboard/static/js/shared/tooltip-service.js +6 -6
  179. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  180. claude_mpm/dashboard/static/navigation-test-results.md +118 -0
  181. claude_mpm/dashboard/static/production/main.html +21 -21
  182. claude_mpm/dashboard/static/test-archive/dashboard.html +22 -22
  183. claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +36 -0
  184. claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +39 -0
  185. claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +38 -0
  186. claude_mpm/dashboard/templates/code_simple.html +23 -23
  187. claude_mpm/dashboard/templates/index.html +18 -18
  188. claude_mpm/hooks/README.md +143 -0
  189. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  190. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  191. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  192. claude_mpm/hooks/templates/README.md +180 -0
  193. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  194. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  195. claude_mpm/hooks/templates/settings.json.example +147 -0
  196. claude_mpm/schemas/agent_schema.json +596 -0
  197. claude_mpm/schemas/frontmatter_schema.json +165 -0
  198. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  199. claude_mpm/scripts/start_activity_logging.py +3 -1
  200. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  201. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  202. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  203. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  204. claude_mpm/services/agents/loading/framework_agent_loader.py +8 -8
  205. claude_mpm/services/agents/local_template_manager.py +3 -1
  206. claude_mpm/services/cli/session_pause_manager.py +504 -0
  207. claude_mpm/services/cli/session_resume_helper.py +36 -16
  208. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  209. claude_mpm/services/core/base.py +26 -11
  210. claude_mpm/services/core/interfaces.py +56 -1
  211. claude_mpm/services/core/models/agent_config.py +3 -0
  212. claude_mpm/services/core/models/process.py +4 -0
  213. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  214. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  215. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  216. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  217. claude_mpm/services/diagnostics/doctor_reporter.py +6 -4
  218. claude_mpm/services/diagnostics/models.py +21 -0
  219. claude_mpm/services/event_bus/README.md +244 -0
  220. claude_mpm/services/event_bus/direct_relay.py +3 -3
  221. claude_mpm/services/event_bus/event_bus.py +36 -3
  222. claude_mpm/services/event_bus/relay.py +23 -7
  223. claude_mpm/services/events/README.md +303 -0
  224. claude_mpm/services/events/consumers/logging.py +1 -2
  225. claude_mpm/services/framework_claude_md_generator/README.md +119 -0
  226. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  227. claude_mpm/services/local_ops/__init__.py +2 -0
  228. claude_mpm/services/local_ops/process_manager.py +1 -1
  229. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  230. claude_mpm/services/mcp_gateway/README.md +185 -0
  231. claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
  232. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  233. claude_mpm/services/mcp_gateway/core/process_pool.py +19 -10
  234. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  235. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  236. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
  237. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  238. claude_mpm/services/memory/failure_tracker.py +19 -4
  239. claude_mpm/services/memory/optimizer.py +1 -1
  240. claude_mpm/services/model/model_router.py +8 -9
  241. claude_mpm/services/monitor/daemon.py +1 -1
  242. claude_mpm/services/monitor/server.py +2 -2
  243. claude_mpm/services/native_agent_converter.py +356 -0
  244. claude_mpm/services/port_manager.py +1 -1
  245. claude_mpm/services/project/documentation_manager.py +2 -1
  246. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  247. claude_mpm/services/runner_configuration_service.py +1 -0
  248. claude_mpm/services/self_upgrade_service.py +165 -7
  249. claude_mpm/services/skills_config.py +547 -0
  250. claude_mpm/services/skills_deployer.py +955 -0
  251. claude_mpm/services/socketio/handlers/connection.py +1 -1
  252. claude_mpm/services/socketio/handlers/connection.py.backup +217 -0
  253. claude_mpm/services/socketio/handlers/git.py +2 -2
  254. claude_mpm/services/socketio/handlers/hook.py.backup +154 -0
  255. claude_mpm/services/static/.gitkeep +2 -0
  256. claude_mpm/services/system_instructions_service.py +1 -3
  257. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  258. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  259. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  260. claude_mpm/services/version_control/VERSION +1 -0
  261. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  262. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  263. claude_mpm/skills/__init__.py +3 -3
  264. claude_mpm/skills/agent_skills_injector.py +42 -49
  265. claude_mpm/skills/bundled/.gitkeep +2 -0
  266. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +4 -0
  267. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +108 -114
  268. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  269. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  270. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  271. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  272. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  273. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +46 -41
  274. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  275. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  276. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +36 -73
  277. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  278. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  279. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +100 -125
  280. claude_mpm/skills/bundled/debugging/root-cause-tracing/find-polluter.sh +63 -0
  281. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  282. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  283. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  284. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  285. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +28 -72
  286. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +11 -0
  287. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  288. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  289. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +272 -0
  290. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  291. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  292. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  293. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  294. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  295. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  296. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  297. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  298. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  299. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  300. claude_mpm/skills/bundled/main/artifacts-builder/LICENSE.txt +202 -0
  301. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +13 -1
  302. claude_mpm/skills/bundled/main/artifacts-builder/scripts/bundle-artifact.sh +54 -0
  303. claude_mpm/skills/bundled/main/artifacts-builder/scripts/init-artifact.sh +322 -0
  304. claude_mpm/skills/bundled/main/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  305. claude_mpm/skills/bundled/main/internal-comms/LICENSE.txt +202 -0
  306. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +11 -0
  307. claude_mpm/skills/bundled/main/mcp-builder/LICENSE.txt +202 -0
  308. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +109 -277
  309. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  310. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  311. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +17 -10
  312. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +92 -39
  313. claude_mpm/skills/bundled/main/mcp-builder/scripts/example_evaluation.xml +22 -0
  314. claude_mpm/skills/bundled/main/mcp-builder/scripts/requirements.txt +2 -0
  315. claude_mpm/skills/bundled/main/skill-creator/LICENSE.txt +202 -0
  316. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +135 -155
  317. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  318. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  319. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  320. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  321. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  322. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +13 -12
  323. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +5 -3
  324. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +19 -12
  325. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  326. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  327. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  328. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  329. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  330. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  331. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  332. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  333. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  334. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  335. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  336. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  337. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  338. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  339. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  340. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  341. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  342. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  343. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  344. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  345. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  346. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  347. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  348. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  349. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  350. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  351. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  352. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +21 -25
  353. claude_mpm/skills/bundled/testing/condition-based-waiting/example.ts +158 -0
  354. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  355. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  356. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  357. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  358. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  359. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  360. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +86 -250
  361. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  362. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  363. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  364. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  365. claude_mpm/skills/bundled/testing/webapp-testing/LICENSE.txt +202 -0
  366. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +145 -57
  367. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  368. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +6 -6
  369. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +13 -9
  370. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +8 -8
  371. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  372. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  373. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +37 -15
  374. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  375. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  376. claude_mpm/skills/skills_registry.py +44 -48
  377. claude_mpm/skills/skills_service.py +117 -108
  378. claude_mpm/templates/questions/EXAMPLES.md +501 -0
  379. claude_mpm/templates/questions/__init__.py +43 -0
  380. claude_mpm/templates/questions/base.py +193 -0
  381. claude_mpm/templates/questions/pr_strategy.py +314 -0
  382. claude_mpm/templates/questions/project_init.py +388 -0
  383. claude_mpm/templates/questions/ticket_mgmt.py +397 -0
  384. claude_mpm/tools/README_SOCKETIO_DEBUG.md +224 -0
  385. claude_mpm/tools/__main__.py +8 -8
  386. claude_mpm/tools/code_tree_analyzer/README.md +64 -0
  387. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  388. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  389. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  390. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  391. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  392. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  393. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  394. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  395. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  396. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  397. claude_mpm/utils/agent_dependency_loader.py +3 -3
  398. claude_mpm/utils/dependency_cache.py +3 -1
  399. claude_mpm/utils/gitignore.py +241 -0
  400. claude_mpm/utils/log_cleanup.py +3 -3
  401. claude_mpm/utils/robust_installer.py +3 -5
  402. claude_mpm/utils/structured_questions.py +619 -0
  403. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/METADATA +218 -31
  404. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/RECORD +409 -246
  405. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  406. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  407. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  408. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  409. claude_mpm/cli/commands/mpm_init.py +0 -2093
  410. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  411. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  412. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  413. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  414. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  415. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  416. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  417. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  418. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  419. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  420. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  421. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  422. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  423. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  424. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  425. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  426. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  427. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  428. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  429. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  430. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  431. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  432. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  433. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  434. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  435. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  436. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  437. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  438. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  439. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  440. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  441. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  442. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  443. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  444. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  445. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  446. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  447. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  448. claude_mpm/skills/bundled/debugging/verification-before-completion/references/common-failures.md +0 -213
  449. claude_mpm/tools/code_tree_analyzer.py +0 -1825
  450. /claude_mpm/skills/bundled/collaboration/requesting-code-review/{code-reviewer.md → references/code-reviewer-template.md} +0 -0
  451. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/WHEEL +0 -0
  452. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/entry_points.txt +0 -0
  453. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/licenses/LICENSE +0 -0
  454. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/top_level.txt +0 -0
@@ -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