claude-mpm 4.16.0__py3-none-any.whl → 4.25.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_ENGINEER.md +286 -0
- claude_mpm/agents/BASE_PM.md +272 -23
- claude_mpm/agents/OUTPUT_STYLE.md +3 -48
- claude_mpm/agents/PM_INSTRUCTIONS.md +1821 -32
- claude_mpm/agents/WORKFLOW.md +75 -2
- claude_mpm/agents/agent_loader.py +4 -4
- claude_mpm/agents/base_agent.json +6 -3
- claude_mpm/agents/frontmatter_validator.py +1 -1
- claude_mpm/agents/templates/api_qa.json +5 -2
- claude_mpm/agents/templates/circuit_breakers.md +108 -2
- claude_mpm/agents/templates/documentation.json +33 -6
- claude_mpm/agents/templates/engineer.json +5 -1
- claude_mpm/agents/templates/javascript_engineer_agent.json +380 -0
- claude_mpm/agents/templates/php-engineer.json +10 -4
- claude_mpm/agents/templates/pm_red_flags.md +89 -19
- claude_mpm/agents/templates/project_organizer.json +7 -3
- claude_mpm/agents/templates/python_engineer.json +8 -3
- claude_mpm/agents/templates/qa.json +2 -1
- claude_mpm/agents/templates/react_engineer.json +1 -0
- claude_mpm/agents/templates/research.json +82 -12
- claude_mpm/agents/templates/rust_engineer.json +12 -7
- claude_mpm/agents/templates/security.json +4 -4
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/agents/templates/tauri_engineer.json +274 -0
- claude_mpm/agents/templates/ticketing.json +10 -6
- claude_mpm/agents/templates/version_control.json +4 -2
- claude_mpm/agents/templates/web_qa.json +2 -1
- claude_mpm/cli/README.md +253 -0
- claude_mpm/cli/__init__.py +11 -1
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/cleanup.py +1 -1
- claude_mpm/cli/commands/configure_agent_display.py +4 -4
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mcp_install_commands.py.backup +284 -0
- claude_mpm/cli/commands/mpm_init/README.md +365 -0
- claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
- claude_mpm/cli/commands/mpm_init/core.py +573 -0
- claude_mpm/cli/commands/mpm_init/display.py +341 -0
- claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
- claude_mpm/cli/commands/mpm_init/modes.py +397 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
- claude_mpm/cli/commands/mpm_init_cli.py +396 -0
- claude_mpm/cli/commands/mpm_init_handler.py +67 -1
- claude_mpm/cli/commands/run.py +124 -128
- claude_mpm/cli/commands/skills.py +922 -0
- claude_mpm/cli/executor.py +58 -0
- claude_mpm/cli/interactive/agent_wizard.py +5 -5
- claude_mpm/cli/parsers/base_parser.py +35 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
- claude_mpm/cli/parsers/skills_parser.py +275 -0
- claude_mpm/cli/startup.py +168 -8
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/cli_module/commands.py +1 -1
- claude_mpm/cli_module/refactoring_guide.md +253 -0
- claude_mpm/commands/mpm-auto-configure.md +52 -0
- claude_mpm/commands/mpm-help.md +6 -0
- claude_mpm/commands/mpm-init.md +130 -8
- claude_mpm/commands/mpm-resume.md +372 -0
- claude_mpm/commands/mpm-tickets.md +56 -7
- claude_mpm/commands/mpm-version.md +113 -0
- claude_mpm/commands/mpm.md +2 -0
- claude_mpm/config/agent_capabilities.yaml +658 -0
- claude_mpm/config/agent_config.py +2 -2
- claude_mpm/config/async_logging_config.yaml +145 -0
- claude_mpm/constants.py +24 -0
- claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +34 -0
- claude_mpm/core/api_validator.py +1 -1
- claude_mpm/core/claude_runner.py +14 -1
- claude_mpm/core/config.py +50 -0
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/framework/processors/metadata_processor.py +1 -1
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +48 -3
- claude_mpm/core/interfaces.py +56 -1
- claude_mpm/core/logger.py +3 -1
- claude_mpm/core/oneshot_session.py +39 -0
- claude_mpm/core/optimized_agent_loader.py +3 -3
- claude_mpm/d2/.gitignore +22 -0
- claude_mpm/d2/ARCHITECTURE_COMPARISON.md +273 -0
- claude_mpm/d2/FLASK_INTEGRATION.md +156 -0
- claude_mpm/d2/IMPLEMENTATION_SUMMARY.md +452 -0
- claude_mpm/d2/QUICKSTART.md +186 -0
- claude_mpm/d2/README.md +232 -0
- claude_mpm/d2/STORE_FIX_SUMMARY.md +167 -0
- claude_mpm/d2/SVELTE5_STORES_GUIDE.md +180 -0
- claude_mpm/d2/TESTING.md +288 -0
- claude_mpm/d2/index.html +118 -0
- claude_mpm/d2/package.json +19 -0
- claude_mpm/d2/src/App.svelte +110 -0
- claude_mpm/d2/src/components/Header.svelte +153 -0
- claude_mpm/d2/src/components/MainContent.svelte +74 -0
- claude_mpm/d2/src/components/Sidebar.svelte +85 -0
- claude_mpm/d2/src/components/tabs/EventsTab.svelte +326 -0
- claude_mpm/d2/src/lib/socketio.js +144 -0
- claude_mpm/d2/src/main.js +7 -0
- claude_mpm/d2/src/stores/events.js +114 -0
- claude_mpm/d2/src/stores/socket.js +108 -0
- claude_mpm/d2/src/stores/theme.js +65 -0
- claude_mpm/d2/svelte.config.js +12 -0
- claude_mpm/d2/vite.config.js +15 -0
- claude_mpm/dashboard/.claude-mpm/memories/README.md +36 -0
- claude_mpm/dashboard/BUILD_NUMBER +1 -0
- claude_mpm/dashboard/README.md +121 -0
- claude_mpm/dashboard/VERSION +1 -0
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.tsx +273 -0
- claude_mpm/dashboard/react/components/ErrorBoundary.tsx +75 -0
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.tsx +141 -0
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.tsx +36 -0
- claude_mpm/dashboard/react/components/shared/FilterBar.tsx +89 -0
- claude_mpm/dashboard/react/contexts/DashboardContext.tsx +215 -0
- claude_mpm/dashboard/react/entries/events.tsx +165 -0
- claude_mpm/dashboard/react/hooks/useEvents.ts +191 -0
- claude_mpm/dashboard/react/hooks/useSocket.ts +225 -0
- claude_mpm/dashboard/static/built/REFACTORING_SUMMARY.md +170 -0
- claude_mpm/dashboard/static/built/components/activity-tree.js.map +1 -0
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/built/components/agent-inference.js.map +1 -0
- claude_mpm/dashboard/static/built/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/built/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +29 -29
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +24 -24
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +27 -27
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +25 -25
- claude_mpm/dashboard/static/built/components/code-tree.js.map +1 -0
- claude_mpm/dashboard/static/built/components/code-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/built/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/built/components/event-processor.js.map +1 -0
- claude_mpm/dashboard/static/built/components/event-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/export-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js.map +1 -0
- claude_mpm/dashboard/static/built/components/file-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/hud-library-loader.js.map +1 -0
- claude_mpm/dashboard/static/built/components/hud-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/hud-visualizer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/module-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/session-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/socket-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/ui-state-manager.js.map +1 -0
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js.map +1 -0
- claude_mpm/dashboard/static/built/components/working-directory.js.map +1 -0
- claude_mpm/dashboard/static/built/connection-manager.js +76 -76
- claude_mpm/dashboard/static/built/dashboard.js.map +1 -0
- claude_mpm/dashboard/static/built/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/built/react/events.js.map +1 -0
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +9 -9
- claude_mpm/dashboard/static/built/shared/event-bus.js +5 -5
- claude_mpm/dashboard/static/built/shared/logger.js +16 -16
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +6 -6
- claude_mpm/dashboard/static/built/socket-client.js.map +1 -0
- claude_mpm/dashboard/static/css/activity.css +69 -69
- claude_mpm/dashboard/static/css/connection-status.css +10 -10
- claude_mpm/dashboard/static/css/dashboard.css +15 -15
- claude_mpm/dashboard/static/index.html +22 -22
- claude_mpm/dashboard/static/js/REFACTORING_SUMMARY.md +170 -0
- claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
- claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
- claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
- claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
- claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
- claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
- claude_mpm/dashboard/static/js/connection-manager.js +76 -76
- claude_mpm/dashboard/static/js/dashboard.js +76 -58
- claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +9 -9
- claude_mpm/dashboard/static/js/shared/event-bus.js +5 -5
- claude_mpm/dashboard/static/js/shared/logger.js +16 -16
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +6 -6
- claude_mpm/dashboard/static/js/socket-client.js +138 -121
- claude_mpm/dashboard/static/navigation-test-results.md +118 -0
- claude_mpm/dashboard/static/production/main.html +21 -21
- claude_mpm/dashboard/static/test-archive/dashboard.html +22 -22
- claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +36 -0
- claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +39 -0
- claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +38 -0
- claude_mpm/dashboard/templates/code_simple.html +23 -23
- claude_mpm/dashboard/templates/index.html +18 -18
- claude_mpm/hooks/README.md +143 -0
- claude_mpm/hooks/__init__.py +8 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
- claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
- claude_mpm/hooks/claude_hooks/installer.py +45 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
- claude_mpm/hooks/session_resume_hook.py +121 -0
- claude_mpm/hooks/templates/README.md +180 -0
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/hooks/templates/settings.json.example +147 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/schemas/agent_schema.json +596 -0
- claude_mpm/schemas/frontmatter_schema.json +165 -0
- claude_mpm/scripts/claude-hook-handler.sh +3 -3
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/auto_config_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
- claude_mpm/services/agents/deployment/agent_validator.py +17 -1
- claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/loading/framework_agent_loader.py +8 -8
- claude_mpm/services/agents/local_template_manager.py +4 -2
- claude_mpm/services/agents/recommender.py +47 -0
- claude_mpm/services/cli/resume_service.py +617 -0
- claude_mpm/services/cli/session_manager.py +87 -0
- claude_mpm/services/cli/session_pause_manager.py +504 -0
- claude_mpm/services/cli/session_resume_helper.py +372 -0
- claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/core/base.py +26 -11
- claude_mpm/services/core/interfaces.py +56 -1
- claude_mpm/services/core/models/agent_config.py +3 -0
- claude_mpm/services/core/models/process.py +4 -0
- claude_mpm/services/core/path_resolver.py +1 -1
- claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
- claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
- claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/doctor_reporter.py +6 -4
- claude_mpm/services/diagnostics/models.py +21 -0
- claude_mpm/services/event_bus/README.md +244 -0
- claude_mpm/services/event_bus/direct_relay.py +3 -3
- claude_mpm/services/event_bus/event_bus.py +36 -3
- claude_mpm/services/event_bus/relay.py +23 -7
- claude_mpm/services/events/README.md +303 -0
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/framework_claude_md_generator/README.md +119 -0
- claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/local_ops/__init__.py +2 -0
- claude_mpm/services/local_ops/process_manager.py +1 -1
- claude_mpm/services/local_ops/resource_monitor.py +2 -2
- claude_mpm/services/mcp_config_manager.py +7 -131
- claude_mpm/services/mcp_gateway/README.md +185 -0
- claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
- claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
- claude_mpm/services/mcp_gateway/core/process_pool.py +19 -10
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
- claude_mpm/services/memory/failure_tracker.py +19 -4
- claude_mpm/services/memory/optimizer.py +1 -1
- claude_mpm/services/model/model_router.py +8 -9
- claude_mpm/services/monitor/daemon.py +1 -1
- claude_mpm/services/monitor/server.py +2 -2
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/port_manager.py +1 -1
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +1 -0
- claude_mpm/services/self_upgrade_service.py +165 -7
- claude_mpm/services/session_manager.py +205 -1
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +955 -0
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/connection.py.backup +217 -0
- claude_mpm/services/socketio/handlers/git.py +2 -2
- claude_mpm/services/socketio/handlers/hook.py.backup +154 -0
- claude_mpm/services/static/.gitkeep +2 -0
- claude_mpm/services/system_instructions_service.py +1 -3
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
- claude_mpm/services/unified/deployment_strategies/local.py +1 -1
- claude_mpm/services/version_control/VERSION +1 -0
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/version_service.py +104 -1
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/__init__.py +21 -0
- claude_mpm/skills/agent_skills_injector.py +324 -0
- claude_mpm/skills/bundled/.gitkeep +2 -0
- claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/find-polluter.sh +63 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/main/artifacts-builder/LICENSE.txt +202 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/artifacts-builder/scripts/bundle-artifact.sh +54 -0
- claude_mpm/skills/bundled/main/artifacts-builder/scripts/init-artifact.sh +322 -0
- claude_mpm/skills/bundled/main/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- claude_mpm/skills/bundled/main/internal-comms/LICENSE.txt +202 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/LICENSE.txt +202 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/example_evaluation.xml +22 -0
- claude_mpm/skills/bundled/main/mcp-builder/scripts/requirements.txt +2 -0
- claude_mpm/skills/bundled/main/skill-creator/LICENSE.txt +202 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
- claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +573 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/security-scanning.md +327 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
- claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
- claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
- claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
- claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
- claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
- claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
- claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
- claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
- claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
- claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/example.ts +158 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/LICENSE.txt +202 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
- claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +97 -9
- claude_mpm/skills/skills_registry.py +347 -0
- claude_mpm/skills/skills_service.py +739 -0
- claude_mpm/templates/questions/EXAMPLES.md +501 -0
- claude_mpm/templates/questions/__init__.py +43 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +314 -0
- claude_mpm/templates/questions/project_init.py +388 -0
- claude_mpm/templates/questions/ticket_mgmt.py +397 -0
- claude_mpm/tools/README_SOCKETIO_DEBUG.md +224 -0
- claude_mpm/tools/__main__.py +8 -8
- claude_mpm/tools/code_tree_analyzer/README.md +64 -0
- claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
- claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
- claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
- claude_mpm/tools/code_tree_analyzer/core.py +380 -0
- claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
- claude_mpm/tools/code_tree_analyzer/events.py +168 -0
- claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
- claude_mpm/tools/code_tree_analyzer/models.py +39 -0
- claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
- claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
- claude_mpm/utils/agent_dependency_loader.py +5 -5
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +241 -0
- claude_mpm/utils/log_cleanup.py +3 -3
- claude_mpm/utils/robust_installer.py +3 -5
- claude_mpm/utils/structured_questions.py +619 -0
- claude_mpm-4.25.10.dist-info/METADATA +789 -0
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/RECORD +485 -240
- claude_mpm/agents/INSTRUCTIONS_OLD_DEPRECATED.md +0 -602
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
- claude_mpm/cli/commands/mpm_init.py +0 -2008
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
- claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
- claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
- claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
- claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
- claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
- claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/dist/dashboard.js +0 -2
- claude_mpm/dashboard/static/dist/react/events.js +0 -30
- claude_mpm/dashboard/static/dist/socket-client.js +0 -2
- claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
- claude_mpm/tools/code_tree_analyzer.py +0 -1825
- claude_mpm-4.16.0.dist-info/METADATA +0 -453
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/WHEEL +0 -0
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.16.0.dist-info → claude_mpm-4.25.10.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill_id: xlsx
|
|
3
|
+
skill_version: 0.1.0
|
|
4
|
+
description: Working with Excel files programmatically.
|
|
5
|
+
updated_at: 2025-10-30T17:00:00Z
|
|
6
|
+
tags: [excel, xlsx, spreadsheet, data]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Excel/XLSX Manipulation
|
|
10
|
+
|
|
11
|
+
Working with Excel files programmatically.
|
|
12
|
+
|
|
13
|
+
## Python (openpyxl)
|
|
14
|
+
|
|
15
|
+
### Reading Excel
|
|
16
|
+
```python
|
|
17
|
+
from openpyxl import load_workbook
|
|
18
|
+
|
|
19
|
+
wb = load_workbook('data.xlsx')
|
|
20
|
+
ws = wb.active # Get active sheet
|
|
21
|
+
|
|
22
|
+
# Read cell
|
|
23
|
+
value = ws['A1'].value
|
|
24
|
+
|
|
25
|
+
# Iterate rows
|
|
26
|
+
for row in ws.iter_rows(min_row=2, values_only=True):
|
|
27
|
+
print(row)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Writing Excel
|
|
31
|
+
```python
|
|
32
|
+
from openpyxl import Workbook
|
|
33
|
+
|
|
34
|
+
wb = Workbook()
|
|
35
|
+
ws = wb.active
|
|
36
|
+
ws.title = "Data"
|
|
37
|
+
|
|
38
|
+
# Write data
|
|
39
|
+
ws['A1'] = 'Name'
|
|
40
|
+
ws['B1'] = 'Age'
|
|
41
|
+
ws.append(['John', 30])
|
|
42
|
+
ws.append(['Jane', 25])
|
|
43
|
+
|
|
44
|
+
wb.save('output.xlsx')
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Formatting
|
|
48
|
+
```python
|
|
49
|
+
from openpyxl.styles import Font, PatternFill
|
|
50
|
+
|
|
51
|
+
# Bold header
|
|
52
|
+
ws['A1'].font = Font(bold=True)
|
|
53
|
+
|
|
54
|
+
# Background color
|
|
55
|
+
ws['A1'].fill = PatternFill(start_color="FFFF00", fill_type="solid")
|
|
56
|
+
|
|
57
|
+
# Number format
|
|
58
|
+
ws['B2'].number_format = '0.00' # Two decimals
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Formulas
|
|
62
|
+
```python
|
|
63
|
+
# Add formula
|
|
64
|
+
ws['C2'] = '=A2+B2'
|
|
65
|
+
|
|
66
|
+
# Sum column
|
|
67
|
+
ws['D10'] = '=SUM(D2:D9)'
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Python (pandas)
|
|
71
|
+
|
|
72
|
+
### Reading Excel
|
|
73
|
+
```python
|
|
74
|
+
import pandas as pd
|
|
75
|
+
|
|
76
|
+
# Read sheet
|
|
77
|
+
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')
|
|
78
|
+
|
|
79
|
+
# Read multiple sheets
|
|
80
|
+
dfs = pd.read_excel('data.xlsx', sheet_name=None)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Writing Excel
|
|
84
|
+
```python
|
|
85
|
+
# Write DataFrame
|
|
86
|
+
df.to_excel('output.xlsx', index=False)
|
|
87
|
+
|
|
88
|
+
# Multiple sheets
|
|
89
|
+
with pd.ExcelWriter('output.xlsx') as writer:
|
|
90
|
+
df1.to_excel(writer, sheet_name='Sheet1')
|
|
91
|
+
df2.to_excel(writer, sheet_name='Sheet2')
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Data Transformation
|
|
95
|
+
```python
|
|
96
|
+
# Filter
|
|
97
|
+
filtered = df[df['Age'] > 25]
|
|
98
|
+
|
|
99
|
+
# Group by
|
|
100
|
+
grouped = df.groupby('Department')['Salary'].mean()
|
|
101
|
+
|
|
102
|
+
# Pivot
|
|
103
|
+
pivot = df.pivot_table(values='Sales', index='Region', columns='Product')
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## JavaScript (xlsx)
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
import XLSX from 'xlsx';
|
|
110
|
+
|
|
111
|
+
// Read file
|
|
112
|
+
const workbook = XLSX.readFile('data.xlsx');
|
|
113
|
+
const sheetName = workbook.SheetNames[0];
|
|
114
|
+
const worksheet = workbook.Sheets[sheetName];
|
|
115
|
+
|
|
116
|
+
// Convert to JSON
|
|
117
|
+
const data = XLSX.utils.sheet_to_json(worksheet);
|
|
118
|
+
|
|
119
|
+
// Write file
|
|
120
|
+
const newWorksheet = XLSX.utils.json_to_sheet(data);
|
|
121
|
+
const newWorkbook = XLSX.utils.book_new();
|
|
122
|
+
XLSX.utils.book_append_sheet(newWorkbook, newWorksheet, 'Data');
|
|
123
|
+
XLSX.writeFile(newWorkbook, 'output.xlsx');
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Common Operations
|
|
127
|
+
|
|
128
|
+
### CSV to Excel
|
|
129
|
+
```python
|
|
130
|
+
import pandas as pd
|
|
131
|
+
|
|
132
|
+
df = pd.read_csv('data.csv')
|
|
133
|
+
df.to_excel('data.xlsx', index=False)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Excel to CSV
|
|
137
|
+
```python
|
|
138
|
+
df = pd.read_excel('data.xlsx')
|
|
139
|
+
df.to_csv('data.csv', index=False)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Merging Excel Files
|
|
143
|
+
```python
|
|
144
|
+
dfs = []
|
|
145
|
+
for file in ['file1.xlsx', 'file2.xlsx', 'file3.xlsx']:
|
|
146
|
+
df = pd.read_excel(file)
|
|
147
|
+
dfs.append(df)
|
|
148
|
+
|
|
149
|
+
combined = pd.concat(dfs, ignore_index=True)
|
|
150
|
+
combined.to_excel('merged.xlsx', index=False)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Remember
|
|
154
|
+
- Close workbooks after use
|
|
155
|
+
- Handle large files in chunks
|
|
156
|
+
- Validate data before writing
|
|
157
|
+
- Use pandas for data analysis, openpyxl for formatting
|
claude_mpm/skills/registry.py
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"""Skills registry - manages bundled and discovered skills."""
|
|
2
2
|
|
|
3
|
+
import re
|
|
3
4
|
from dataclasses import dataclass
|
|
4
5
|
from pathlib import Path
|
|
5
|
-
from typing import Dict, List, Optional
|
|
6
|
+
from typing import Any, Dict, List, Optional
|
|
7
|
+
|
|
8
|
+
import yaml
|
|
6
9
|
|
|
7
10
|
from claude_mpm.core.logging_utils import get_logger
|
|
8
11
|
|
|
@@ -17,13 +20,27 @@ class Skill:
|
|
|
17
20
|
path: Path
|
|
18
21
|
content: str
|
|
19
22
|
source: str # 'bundled', 'user', or 'project'
|
|
23
|
+
|
|
24
|
+
# Version tracking fields
|
|
25
|
+
version: str = "0.1.0"
|
|
26
|
+
skill_id: str = "" # defaults to name if not provided
|
|
27
|
+
|
|
28
|
+
# Existing fields
|
|
20
29
|
description: str = ""
|
|
21
30
|
agent_types: List[str] = None # Which agent types can use this skill
|
|
22
31
|
|
|
32
|
+
# Optional metadata
|
|
33
|
+
updated_at: Optional[str] = None
|
|
34
|
+
tags: List[str] = None
|
|
35
|
+
|
|
23
36
|
def __post_init__(self):
|
|
24
|
-
"""Initialize
|
|
37
|
+
"""Initialize default values if not provided."""
|
|
25
38
|
if self.agent_types is None:
|
|
26
39
|
self.agent_types = []
|
|
40
|
+
if self.tags is None:
|
|
41
|
+
self.tags = []
|
|
42
|
+
if not self.skill_id:
|
|
43
|
+
self.skill_id = self.name
|
|
27
44
|
|
|
28
45
|
|
|
29
46
|
class SkillsRegistry:
|
|
@@ -36,6 +53,28 @@ class SkillsRegistry:
|
|
|
36
53
|
self._load_user_skills()
|
|
37
54
|
self._load_project_skills()
|
|
38
55
|
|
|
56
|
+
def _parse_skill_frontmatter(self, content: str) -> Dict[str, Any]:
|
|
57
|
+
"""Parse YAML frontmatter from skill markdown file.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
Dict with frontmatter fields or empty dict if no frontmatter
|
|
61
|
+
"""
|
|
62
|
+
# Check for YAML frontmatter
|
|
63
|
+
if not content.startswith("---"):
|
|
64
|
+
return {}
|
|
65
|
+
|
|
66
|
+
# Extract frontmatter (match: ---\n...yaml...\n---\nrest)
|
|
67
|
+
match = re.match(r"^---\n(.*?)\n---\n(.*)$", content, re.DOTALL)
|
|
68
|
+
if not match:
|
|
69
|
+
return {}
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
frontmatter = yaml.safe_load(match.group(1))
|
|
73
|
+
return frontmatter or {}
|
|
74
|
+
except yaml.YAMLError as e:
|
|
75
|
+
logger.warning(f"Failed to parse skill frontmatter: {e}")
|
|
76
|
+
return {}
|
|
77
|
+
|
|
39
78
|
def _load_bundled_skills(self):
|
|
40
79
|
"""Load skills bundled with MPM."""
|
|
41
80
|
bundled_dir = Path(__file__).parent / "bundled"
|
|
@@ -49,21 +88,36 @@ class SkillsRegistry:
|
|
|
49
88
|
skill_name = skill_file.stem
|
|
50
89
|
content = skill_file.read_text(encoding="utf-8")
|
|
51
90
|
|
|
52
|
-
#
|
|
53
|
-
|
|
91
|
+
# Parse frontmatter
|
|
92
|
+
frontmatter = self._parse_skill_frontmatter(content)
|
|
93
|
+
|
|
94
|
+
# Extract version fields from frontmatter
|
|
95
|
+
version = frontmatter.get("skill_version", "0.1.0")
|
|
96
|
+
skill_id = frontmatter.get("skill_id", skill_name)
|
|
97
|
+
updated_at = frontmatter.get("updated_at")
|
|
98
|
+
tags = frontmatter.get("tags", [])
|
|
99
|
+
|
|
100
|
+
# Extract description (from frontmatter or fallback to content parsing)
|
|
101
|
+
description = frontmatter.get("description", "")
|
|
102
|
+
if not description:
|
|
103
|
+
description = self._extract_description(content)
|
|
54
104
|
|
|
55
105
|
self.skills[skill_name] = Skill(
|
|
56
106
|
name=skill_name,
|
|
57
107
|
path=skill_file,
|
|
58
108
|
content=content,
|
|
59
109
|
source="bundled",
|
|
110
|
+
version=version,
|
|
111
|
+
skill_id=skill_id,
|
|
60
112
|
description=description,
|
|
113
|
+
updated_at=updated_at,
|
|
114
|
+
tags=tags,
|
|
61
115
|
)
|
|
62
116
|
skill_count += 1
|
|
63
117
|
except Exception as e:
|
|
64
118
|
logger.error(f"Error loading bundled skill {skill_file}: {e}")
|
|
65
119
|
|
|
66
|
-
logger.
|
|
120
|
+
logger.debug(f"Loaded {skill_count} bundled skills")
|
|
67
121
|
|
|
68
122
|
def _load_user_skills(self):
|
|
69
123
|
"""Load user-installed skills from ~/.claude/skills/"""
|
|
@@ -78,14 +132,31 @@ class SkillsRegistry:
|
|
|
78
132
|
skill_name = skill_file.stem
|
|
79
133
|
# User skills override bundled skills
|
|
80
134
|
content = skill_file.read_text(encoding="utf-8")
|
|
81
|
-
|
|
135
|
+
|
|
136
|
+
# Parse frontmatter
|
|
137
|
+
frontmatter = self._parse_skill_frontmatter(content)
|
|
138
|
+
|
|
139
|
+
# Extract version fields from frontmatter
|
|
140
|
+
version = frontmatter.get("skill_version", "0.1.0")
|
|
141
|
+
skill_id = frontmatter.get("skill_id", skill_name)
|
|
142
|
+
updated_at = frontmatter.get("updated_at")
|
|
143
|
+
tags = frontmatter.get("tags", [])
|
|
144
|
+
|
|
145
|
+
# Extract description (from frontmatter or fallback to content parsing)
|
|
146
|
+
description = frontmatter.get("description", "")
|
|
147
|
+
if not description:
|
|
148
|
+
description = self._extract_description(content)
|
|
82
149
|
|
|
83
150
|
self.skills[skill_name] = Skill(
|
|
84
151
|
name=skill_name,
|
|
85
152
|
path=skill_file,
|
|
86
153
|
content=content,
|
|
87
154
|
source="user",
|
|
155
|
+
version=version,
|
|
156
|
+
skill_id=skill_id,
|
|
88
157
|
description=description,
|
|
158
|
+
updated_at=updated_at,
|
|
159
|
+
tags=tags,
|
|
89
160
|
)
|
|
90
161
|
skill_count += 1
|
|
91
162
|
logger.debug(f"User skill '{skill_name}' overrides bundled version")
|
|
@@ -93,7 +164,7 @@ class SkillsRegistry:
|
|
|
93
164
|
logger.error(f"Error loading user skill {skill_file}: {e}")
|
|
94
165
|
|
|
95
166
|
if skill_count > 0:
|
|
96
|
-
logger.
|
|
167
|
+
logger.debug(f"Loaded {skill_count} user skills")
|
|
97
168
|
|
|
98
169
|
def _load_project_skills(self):
|
|
99
170
|
"""Load project-specific skills from .claude/skills/"""
|
|
@@ -108,14 +179,31 @@ class SkillsRegistry:
|
|
|
108
179
|
skill_name = skill_file.stem
|
|
109
180
|
# Project skills override both user and bundled skills
|
|
110
181
|
content = skill_file.read_text(encoding="utf-8")
|
|
111
|
-
|
|
182
|
+
|
|
183
|
+
# Parse frontmatter
|
|
184
|
+
frontmatter = self._parse_skill_frontmatter(content)
|
|
185
|
+
|
|
186
|
+
# Extract version fields from frontmatter
|
|
187
|
+
version = frontmatter.get("skill_version", "0.1.0")
|
|
188
|
+
skill_id = frontmatter.get("skill_id", skill_name)
|
|
189
|
+
updated_at = frontmatter.get("updated_at")
|
|
190
|
+
tags = frontmatter.get("tags", [])
|
|
191
|
+
|
|
192
|
+
# Extract description (from frontmatter or fallback to content parsing)
|
|
193
|
+
description = frontmatter.get("description", "")
|
|
194
|
+
if not description:
|
|
195
|
+
description = self._extract_description(content)
|
|
112
196
|
|
|
113
197
|
self.skills[skill_name] = Skill(
|
|
114
198
|
name=skill_name,
|
|
115
199
|
path=skill_file,
|
|
116
200
|
content=content,
|
|
117
201
|
source="project",
|
|
202
|
+
version=version,
|
|
203
|
+
skill_id=skill_id,
|
|
118
204
|
description=description,
|
|
205
|
+
updated_at=updated_at,
|
|
206
|
+
tags=tags,
|
|
119
207
|
)
|
|
120
208
|
skill_count += 1
|
|
121
209
|
logger.debug(f"Project skill '{skill_name}' overrides other versions")
|
|
@@ -123,7 +211,7 @@ class SkillsRegistry:
|
|
|
123
211
|
logger.error(f"Error loading project skill {skill_file}: {e}")
|
|
124
212
|
|
|
125
213
|
if skill_count > 0:
|
|
126
|
-
logger.
|
|
214
|
+
logger.debug(f"Loaded {skill_count} project skills")
|
|
127
215
|
|
|
128
216
|
def _extract_description(self, content: str) -> str:
|
|
129
217
|
"""Extract description from skill content (first paragraph or summary)."""
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
"""Skills Registry - Helper class for registry operations.
|
|
2
|
+
|
|
3
|
+
This module provides a helper class for working with the skills registry YAML file.
|
|
4
|
+
It offers convenient methods for loading, querying, and validating the registry.
|
|
5
|
+
|
|
6
|
+
The skills registry (config/skills_registry.yaml) is the source of truth for:
|
|
7
|
+
- Skill-to-agent mappings
|
|
8
|
+
- Skill metadata (descriptions, categories, sources)
|
|
9
|
+
- Skill source repositories
|
|
10
|
+
- Version information
|
|
11
|
+
|
|
12
|
+
Design:
|
|
13
|
+
- Read-only registry operations (no modifications)
|
|
14
|
+
- Structured access to registry data
|
|
15
|
+
- Validation of registry structure
|
|
16
|
+
- Error handling with fallback to empty results
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Any, Dict, List, Optional
|
|
21
|
+
|
|
22
|
+
import yaml
|
|
23
|
+
|
|
24
|
+
from claude_mpm.core.mixins import LoggerMixin
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SkillsRegistry(LoggerMixin):
|
|
28
|
+
"""Helper class for skills registry operations.
|
|
29
|
+
|
|
30
|
+
Provides structured access to the skills registry YAML file with
|
|
31
|
+
methods for querying agent skills, skill metadata, and validation.
|
|
32
|
+
|
|
33
|
+
Example:
|
|
34
|
+
>>> registry = SkillsRegistry()
|
|
35
|
+
>>> skills = registry.get_agent_skills('engineer')
|
|
36
|
+
>>> print(skills) # ['test-driven-development', 'systematic-debugging', ...]
|
|
37
|
+
>>>
|
|
38
|
+
>>> metadata = registry.get_skill_metadata('test-driven-development')
|
|
39
|
+
>>> print(metadata['category']) # 'testing'
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(self, registry_path: Optional[Path] = None) -> None:
|
|
43
|
+
"""Initialize Skills Registry.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
registry_path: Optional path to registry YAML file.
|
|
47
|
+
If None, uses default config/skills_registry.yaml
|
|
48
|
+
"""
|
|
49
|
+
super().__init__()
|
|
50
|
+
|
|
51
|
+
if registry_path is None:
|
|
52
|
+
# Default to config/skills_registry.yaml
|
|
53
|
+
registry_path = (
|
|
54
|
+
Path(__file__).parent.parent.parent.parent
|
|
55
|
+
/ "config"
|
|
56
|
+
/ "skills_registry.yaml"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
self.registry_path: Path = registry_path
|
|
60
|
+
self.data: Dict[str, Any] = self.load_registry(registry_path)
|
|
61
|
+
|
|
62
|
+
@staticmethod
|
|
63
|
+
def load_registry(registry_path: Path) -> Dict[str, Any]:
|
|
64
|
+
"""Load and parse registry YAML file.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
registry_path: Path to skills_registry.yaml
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
Dict containing parsed registry data, or empty dict on error
|
|
71
|
+
|
|
72
|
+
Example:
|
|
73
|
+
>>> data = SkillsRegistry.load_registry(Path('config/skills_registry.yaml'))
|
|
74
|
+
>>> print(data['version']) # '1.0.0'
|
|
75
|
+
"""
|
|
76
|
+
if not registry_path.exists():
|
|
77
|
+
return {}
|
|
78
|
+
|
|
79
|
+
try:
|
|
80
|
+
with open(registry_path, encoding="utf-8") as f:
|
|
81
|
+
data = yaml.safe_load(f)
|
|
82
|
+
return data if data is not None else {}
|
|
83
|
+
except (OSError, yaml.YAMLError):
|
|
84
|
+
# Graceful degradation - return empty dict
|
|
85
|
+
return {}
|
|
86
|
+
|
|
87
|
+
def get_agent_skills(self, agent_id: str) -> List[str]:
|
|
88
|
+
"""Get skills for a specific agent.
|
|
89
|
+
|
|
90
|
+
Reads from registry['agent_skills'][agent_id] and combines
|
|
91
|
+
'required' and 'optional' skill lists.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
agent_id: Agent identifier (e.g., 'engineer', 'python_engineer')
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
List of skill names assigned to this agent (required + optional)
|
|
98
|
+
|
|
99
|
+
Example:
|
|
100
|
+
>>> registry = SkillsRegistry()
|
|
101
|
+
>>> skills = registry.get_agent_skills('engineer')
|
|
102
|
+
>>> print(skills)
|
|
103
|
+
['test-driven-development', 'systematic-debugging', 'code-review', 'git-worktrees']
|
|
104
|
+
"""
|
|
105
|
+
agent_skills = self.data.get("agent_skills", {}).get(agent_id, {})
|
|
106
|
+
|
|
107
|
+
required = agent_skills.get("required", [])
|
|
108
|
+
optional = agent_skills.get("optional", [])
|
|
109
|
+
|
|
110
|
+
return required + optional
|
|
111
|
+
|
|
112
|
+
def get_skill_metadata(self, skill_name: str) -> Dict[str, Any]:
|
|
113
|
+
"""Get metadata for a specific skill.
|
|
114
|
+
|
|
115
|
+
Retrieves skill information from registry['skills_metadata'][skill_name].
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
skill_name: Skill identifier (e.g., 'test-driven-development')
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
Dict containing skill metadata:
|
|
122
|
+
- category: Skill category
|
|
123
|
+
- source: Source repository name
|
|
124
|
+
- url: Source URL
|
|
125
|
+
- description: Brief description
|
|
126
|
+
|
|
127
|
+
Example:
|
|
128
|
+
>>> registry = SkillsRegistry()
|
|
129
|
+
>>> metadata = registry.get_skill_metadata('test-driven-development')
|
|
130
|
+
>>> print(f"{metadata['category']}: {metadata['description']}")
|
|
131
|
+
testing: Enforces RED/GREEN/REFACTOR TDD cycle
|
|
132
|
+
"""
|
|
133
|
+
return self.data.get("skills_metadata", {}).get(skill_name, {})
|
|
134
|
+
|
|
135
|
+
def list_all_skills(self) -> List[str]:
|
|
136
|
+
"""List all skills in the registry.
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
List of all skill names defined in skills_metadata
|
|
140
|
+
|
|
141
|
+
Example:
|
|
142
|
+
>>> registry = SkillsRegistry()
|
|
143
|
+
>>> all_skills = registry.list_all_skills()
|
|
144
|
+
>>> print(f"Total skills: {len(all_skills)}")
|
|
145
|
+
Total skills: 15
|
|
146
|
+
"""
|
|
147
|
+
return list(self.data.get("skills_metadata", {}).keys())
|
|
148
|
+
|
|
149
|
+
def list_all_agents(self) -> List[str]:
|
|
150
|
+
"""List all agents in the registry.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
List of all agent IDs with skill assignments
|
|
154
|
+
|
|
155
|
+
Example:
|
|
156
|
+
>>> registry = SkillsRegistry()
|
|
157
|
+
>>> agents = registry.list_all_agents()
|
|
158
|
+
>>> print(f"Agents with skills: {len(agents)}")
|
|
159
|
+
"""
|
|
160
|
+
return list(self.data.get("agent_skills", {}).keys())
|
|
161
|
+
|
|
162
|
+
def get_skills_by_category(self, category: str) -> List[str]:
|
|
163
|
+
"""Get all skills in a specific category.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
category: Category name (e.g., 'testing', 'debugging', 'development')
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
List of skill names in this category
|
|
170
|
+
|
|
171
|
+
Example:
|
|
172
|
+
>>> registry = SkillsRegistry()
|
|
173
|
+
>>> testing_skills = registry.get_skills_by_category('testing')
|
|
174
|
+
>>> print(testing_skills)
|
|
175
|
+
['test-driven-development', 'webapp-testing', 'async-testing', ...]
|
|
176
|
+
"""
|
|
177
|
+
skills = []
|
|
178
|
+
for skill_name, metadata in self.data.get("skills_metadata", {}).items():
|
|
179
|
+
if metadata.get("category") == category:
|
|
180
|
+
skills.append(skill_name)
|
|
181
|
+
|
|
182
|
+
return skills
|
|
183
|
+
|
|
184
|
+
def get_skills_by_source(self, source: str) -> List[str]:
|
|
185
|
+
"""Get all skills from a specific source repository.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
source: Source repository name (e.g., 'superpowers', 'anthropic', 'community')
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
List of skill names from this source
|
|
192
|
+
|
|
193
|
+
Example:
|
|
194
|
+
>>> registry = SkillsRegistry()
|
|
195
|
+
>>> superpowers_skills = registry.get_skills_by_source('superpowers')
|
|
196
|
+
>>> print(f"Skills from superpowers: {len(superpowers_skills)}")
|
|
197
|
+
"""
|
|
198
|
+
skills = []
|
|
199
|
+
for skill_name, metadata in self.data.get("skills_metadata", {}).items():
|
|
200
|
+
if metadata.get("source") == source:
|
|
201
|
+
skills.append(skill_name)
|
|
202
|
+
|
|
203
|
+
return skills
|
|
204
|
+
|
|
205
|
+
def validate_registry(self) -> Dict[str, Any]:
|
|
206
|
+
"""Validate registry structure and content.
|
|
207
|
+
|
|
208
|
+
Checks:
|
|
209
|
+
- Required top-level keys present
|
|
210
|
+
- Version format valid
|
|
211
|
+
- Agent skills references valid
|
|
212
|
+
- Skill metadata complete
|
|
213
|
+
- No orphaned references
|
|
214
|
+
|
|
215
|
+
Returns:
|
|
216
|
+
Dict containing:
|
|
217
|
+
- valid: True if all checks pass
|
|
218
|
+
- errors: List of error messages
|
|
219
|
+
- warnings: List of warning messages
|
|
220
|
+
|
|
221
|
+
Example:
|
|
222
|
+
>>> registry = SkillsRegistry()
|
|
223
|
+
>>> result = registry.validate_registry()
|
|
224
|
+
>>> if not result['valid']:
|
|
225
|
+
... print(f"Registry errors: {result['errors']}")
|
|
226
|
+
"""
|
|
227
|
+
errors = []
|
|
228
|
+
warnings = []
|
|
229
|
+
|
|
230
|
+
# Check required top-level keys
|
|
231
|
+
required_keys = ["version", "last_updated", "agent_skills", "skills_metadata"]
|
|
232
|
+
for key in required_keys:
|
|
233
|
+
if key not in self.data:
|
|
234
|
+
errors.append(f"Missing required key: {key}")
|
|
235
|
+
|
|
236
|
+
# Validate version format
|
|
237
|
+
version = self.data.get("version", "")
|
|
238
|
+
if not version or not isinstance(version, str):
|
|
239
|
+
errors.append("Invalid or missing version field")
|
|
240
|
+
|
|
241
|
+
# Check agent skill references
|
|
242
|
+
agent_skills = self.data.get("agent_skills", {})
|
|
243
|
+
skills_metadata = self.data.get("skills_metadata", {})
|
|
244
|
+
|
|
245
|
+
for agent_id, agent_data in agent_skills.items():
|
|
246
|
+
# Validate structure
|
|
247
|
+
if not isinstance(agent_data, dict):
|
|
248
|
+
errors.append(f"Agent '{agent_id}' has invalid structure")
|
|
249
|
+
continue
|
|
250
|
+
|
|
251
|
+
# Check skill references
|
|
252
|
+
all_skills = agent_data.get("required", []) + agent_data.get("optional", [])
|
|
253
|
+
|
|
254
|
+
for skill in all_skills:
|
|
255
|
+
if skill not in skills_metadata:
|
|
256
|
+
warnings.append(
|
|
257
|
+
f"Agent '{agent_id}' references undefined skill: {skill}"
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
# Check for orphaned skills (in metadata but not assigned to any agent)
|
|
261
|
+
assigned_skills = set()
|
|
262
|
+
for agent_data in agent_skills.values():
|
|
263
|
+
assigned_skills.update(agent_data.get("required", []))
|
|
264
|
+
assigned_skills.update(agent_data.get("optional", []))
|
|
265
|
+
|
|
266
|
+
for skill_name in skills_metadata:
|
|
267
|
+
if skill_name not in assigned_skills:
|
|
268
|
+
warnings.append(f"Skill '{skill_name}' not assigned to any agent")
|
|
269
|
+
|
|
270
|
+
# Validate skill metadata completeness
|
|
271
|
+
required_metadata_fields = ["category", "source", "description"]
|
|
272
|
+
for skill_name, metadata in skills_metadata.items():
|
|
273
|
+
for field in required_metadata_fields:
|
|
274
|
+
if field not in metadata or not metadata[field]:
|
|
275
|
+
warnings.append(f"Skill '{skill_name}' missing {field} in metadata")
|
|
276
|
+
|
|
277
|
+
return {"valid": len(errors) == 0, "errors": errors, "warnings": warnings}
|
|
278
|
+
|
|
279
|
+
def get_registry_info(self) -> Dict[str, Any]:
|
|
280
|
+
"""Get summary information about the registry.
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
Dict containing:
|
|
284
|
+
- version: Registry version
|
|
285
|
+
- last_updated: Last update timestamp
|
|
286
|
+
- total_skills: Count of skills
|
|
287
|
+
- total_agents: Count of agents with skills
|
|
288
|
+
- categories: List of skill categories
|
|
289
|
+
- sources: List of skill sources
|
|
290
|
+
|
|
291
|
+
Example:
|
|
292
|
+
>>> registry = SkillsRegistry()
|
|
293
|
+
>>> info = registry.get_registry_info()
|
|
294
|
+
>>> print(f"Registry v{info['version']}")
|
|
295
|
+
>>> print(f"Total skills: {info['total_skills']}")
|
|
296
|
+
"""
|
|
297
|
+
skills_metadata = self.data.get("skills_metadata", {})
|
|
298
|
+
agent_skills = self.data.get("agent_skills", {})
|
|
299
|
+
|
|
300
|
+
# Get unique categories
|
|
301
|
+
categories = set()
|
|
302
|
+
for metadata in skills_metadata.values():
|
|
303
|
+
if "category" in metadata:
|
|
304
|
+
categories.add(metadata["category"])
|
|
305
|
+
|
|
306
|
+
# Get unique sources
|
|
307
|
+
sources = set()
|
|
308
|
+
for metadata in skills_metadata.values():
|
|
309
|
+
if "source" in metadata:
|
|
310
|
+
sources.add(metadata["source"])
|
|
311
|
+
|
|
312
|
+
return {
|
|
313
|
+
"version": self.data.get("version", "unknown"),
|
|
314
|
+
"last_updated": self.data.get("last_updated", "unknown"),
|
|
315
|
+
"total_skills": len(skills_metadata),
|
|
316
|
+
"total_agents": len(agent_skills),
|
|
317
|
+
"categories": sorted(categories),
|
|
318
|
+
"sources": sorted(sources),
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
def search_skills(self, query: str) -> List[Dict[str, Any]]:
|
|
322
|
+
"""Search skills by name or description.
|
|
323
|
+
|
|
324
|
+
Args:
|
|
325
|
+
query: Search query string
|
|
326
|
+
|
|
327
|
+
Returns:
|
|
328
|
+
List of matching skills with their metadata
|
|
329
|
+
|
|
330
|
+
Example:
|
|
331
|
+
>>> registry = SkillsRegistry()
|
|
332
|
+
>>> results = registry.search_skills('debug')
|
|
333
|
+
>>> for skill in results:
|
|
334
|
+
... print(f"{skill['name']}: {skill['description']}")
|
|
335
|
+
"""
|
|
336
|
+
query_lower = query.lower()
|
|
337
|
+
results = []
|
|
338
|
+
|
|
339
|
+
for skill_name, metadata in self.data.get("skills_metadata", {}).items():
|
|
340
|
+
# Search in name and description
|
|
341
|
+
if (
|
|
342
|
+
query_lower in skill_name.lower()
|
|
343
|
+
or query_lower in metadata.get("description", "").lower()
|
|
344
|
+
):
|
|
345
|
+
results.append({"name": skill_name, **metadata})
|
|
346
|
+
|
|
347
|
+
return results
|