claude-mpm 5.4.22__py3-none-any.whl → 5.6.34__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_AGENT.md +164 -0
- claude_mpm/agents/BASE_ENGINEER.md +658 -0
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
- claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
- claude_mpm/agents/MEMORY.md +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +374 -1257
- claude_mpm/agents/WORKFLOW.md +6 -253
- claude_mpm/agents/agent_loader.py +1 -1
- claude_mpm/agents/base_agent.json +31 -0
- claude_mpm/agents/frontmatter_validator.py +2 -2
- claude_mpm/agents/templates/circuit-breakers.md +26 -17
- claude_mpm/cli/__init__.py +5 -1
- claude_mpm/cli/commands/agent_state_manager.py +10 -10
- claude_mpm/cli/commands/agents.py +11 -13
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/auto_configure.py +4 -4
- claude_mpm/cli/commands/autotodos.py +566 -0
- claude_mpm/cli/commands/commander.py +216 -0
- claude_mpm/cli/commands/configure.py +621 -22
- claude_mpm/cli/commands/configure_agent_display.py +12 -0
- claude_mpm/cli/commands/hook_errors.py +60 -60
- claude_mpm/cli/commands/monitor.py +2 -2
- claude_mpm/cli/commands/mpm_init/core.py +72 -0
- claude_mpm/cli/commands/postmortem.py +1 -1
- claude_mpm/cli/commands/profile.py +276 -0
- claude_mpm/cli/commands/run.py +35 -3
- claude_mpm/cli/commands/skill_source.py +51 -2
- claude_mpm/cli/commands/skills.py +182 -32
- claude_mpm/cli/executor.py +130 -16
- claude_mpm/cli/interactive/__init__.py +10 -0
- claude_mpm/cli/interactive/agent_wizard.py +32 -52
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -0
- claude_mpm/cli/parsers/base_parser.py +83 -1
- claude_mpm/cli/parsers/commander_parser.py +116 -0
- claude_mpm/cli/parsers/profile_parser.py +147 -0
- claude_mpm/cli/parsers/run_parser.py +10 -0
- claude_mpm/cli/parsers/skill_source_parser.py +4 -0
- claude_mpm/cli/parsers/skills_parser.py +2 -3
- claude_mpm/cli/startup.py +690 -386
- claude_mpm/cli/startup_display.py +74 -6
- claude_mpm/cli/startup_logging.py +2 -2
- claude_mpm/cli/utils.py +7 -3
- claude_mpm/commander/__init__.py +78 -0
- claude_mpm/commander/adapters/__init__.py +60 -0
- claude_mpm/commander/adapters/auggie.py +260 -0
- claude_mpm/commander/adapters/base.py +288 -0
- claude_mpm/commander/adapters/claude_code.py +392 -0
- claude_mpm/commander/adapters/codex.py +237 -0
- claude_mpm/commander/adapters/communication.py +366 -0
- claude_mpm/commander/adapters/example_usage.py +310 -0
- claude_mpm/commander/adapters/mpm.py +389 -0
- claude_mpm/commander/adapters/registry.py +204 -0
- claude_mpm/commander/api/__init__.py +16 -0
- claude_mpm/commander/api/app.py +121 -0
- claude_mpm/commander/api/errors.py +133 -0
- claude_mpm/commander/api/routes/__init__.py +8 -0
- claude_mpm/commander/api/routes/events.py +184 -0
- claude_mpm/commander/api/routes/inbox.py +171 -0
- claude_mpm/commander/api/routes/messages.py +148 -0
- claude_mpm/commander/api/routes/projects.py +271 -0
- claude_mpm/commander/api/routes/sessions.py +226 -0
- claude_mpm/commander/api/routes/work.py +296 -0
- claude_mpm/commander/api/schemas.py +186 -0
- claude_mpm/commander/chat/__init__.py +7 -0
- claude_mpm/commander/chat/cli.py +146 -0
- claude_mpm/commander/chat/commands.py +96 -0
- claude_mpm/commander/chat/repl.py +310 -0
- claude_mpm/commander/config.py +51 -0
- claude_mpm/commander/config_loader.py +115 -0
- claude_mpm/commander/core/__init__.py +10 -0
- claude_mpm/commander/core/block_manager.py +325 -0
- claude_mpm/commander/core/response_manager.py +323 -0
- claude_mpm/commander/daemon.py +603 -0
- claude_mpm/commander/env_loader.py +59 -0
- claude_mpm/commander/events/__init__.py +26 -0
- claude_mpm/commander/events/manager.py +332 -0
- claude_mpm/commander/frameworks/__init__.py +12 -0
- claude_mpm/commander/frameworks/base.py +146 -0
- claude_mpm/commander/frameworks/claude_code.py +58 -0
- claude_mpm/commander/frameworks/mpm.py +62 -0
- claude_mpm/commander/inbox/__init__.py +16 -0
- claude_mpm/commander/inbox/dedup.py +128 -0
- claude_mpm/commander/inbox/inbox.py +224 -0
- claude_mpm/commander/inbox/models.py +70 -0
- claude_mpm/commander/instance_manager.py +450 -0
- claude_mpm/commander/llm/__init__.py +6 -0
- claude_mpm/commander/llm/openrouter_client.py +167 -0
- claude_mpm/commander/llm/summarizer.py +70 -0
- claude_mpm/commander/memory/__init__.py +45 -0
- claude_mpm/commander/memory/compression.py +347 -0
- claude_mpm/commander/memory/embeddings.py +230 -0
- claude_mpm/commander/memory/entities.py +310 -0
- claude_mpm/commander/memory/example_usage.py +290 -0
- claude_mpm/commander/memory/integration.py +325 -0
- claude_mpm/commander/memory/search.py +381 -0
- claude_mpm/commander/memory/store.py +657 -0
- claude_mpm/commander/models/__init__.py +18 -0
- claude_mpm/commander/models/events.py +121 -0
- claude_mpm/commander/models/project.py +162 -0
- claude_mpm/commander/models/work.py +214 -0
- claude_mpm/commander/parsing/__init__.py +20 -0
- claude_mpm/commander/parsing/extractor.py +132 -0
- claude_mpm/commander/parsing/output_parser.py +270 -0
- claude_mpm/commander/parsing/patterns.py +100 -0
- claude_mpm/commander/persistence/__init__.py +11 -0
- claude_mpm/commander/persistence/event_store.py +274 -0
- claude_mpm/commander/persistence/state_store.py +309 -0
- claude_mpm/commander/persistence/work_store.py +164 -0
- claude_mpm/commander/polling/__init__.py +13 -0
- claude_mpm/commander/polling/event_detector.py +104 -0
- claude_mpm/commander/polling/output_buffer.py +49 -0
- claude_mpm/commander/polling/output_poller.py +153 -0
- claude_mpm/commander/project_session.py +268 -0
- claude_mpm/commander/proxy/__init__.py +12 -0
- claude_mpm/commander/proxy/formatter.py +89 -0
- claude_mpm/commander/proxy/output_handler.py +191 -0
- claude_mpm/commander/proxy/relay.py +155 -0
- claude_mpm/commander/registry.py +410 -0
- claude_mpm/commander/runtime/__init__.py +10 -0
- claude_mpm/commander/runtime/executor.py +191 -0
- claude_mpm/commander/runtime/monitor.py +346 -0
- claude_mpm/commander/session/__init__.py +6 -0
- claude_mpm/commander/session/context.py +81 -0
- claude_mpm/commander/session/manager.py +59 -0
- claude_mpm/commander/tmux_orchestrator.py +361 -0
- claude_mpm/commander/web/__init__.py +1 -0
- claude_mpm/commander/work/__init__.py +30 -0
- claude_mpm/commander/work/executor.py +207 -0
- claude_mpm/commander/work/queue.py +405 -0
- claude_mpm/commander/workflow/__init__.py +27 -0
- claude_mpm/commander/workflow/event_handler.py +241 -0
- claude_mpm/commander/workflow/notifier.py +146 -0
- claude_mpm/commands/mpm-config.md +20 -249
- claude_mpm/commands/mpm-doctor.md +16 -21
- claude_mpm/commands/mpm-help.md +12 -205
- claude_mpm/commands/mpm-init.md +88 -506
- claude_mpm/commands/mpm-monitor.md +22 -401
- claude_mpm/commands/mpm-organize.md +70 -442
- claude_mpm/commands/mpm-postmortem.md +13 -107
- claude_mpm/commands/mpm-session-resume.md +20 -363
- claude_mpm/commands/mpm-status.md +13 -69
- claude_mpm/commands/mpm-ticket-view.md +60 -495
- claude_mpm/commands/mpm-version.md +13 -107
- claude_mpm/commands/mpm.md +8 -0
- claude_mpm/config/agent_presets.py +8 -7
- claude_mpm/config/skill_sources.py +16 -0
- claude_mpm/constants.py +1 -0
- claude_mpm/core/claude_runner.py +154 -2
- claude_mpm/core/config.py +37 -26
- claude_mpm/core/config_constants.py +74 -9
- claude_mpm/core/constants.py +56 -12
- claude_mpm/core/framework/loaders/agent_loader.py +1 -1
- claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
- claude_mpm/core/hook_manager.py +51 -3
- claude_mpm/core/interactive_session.py +12 -11
- claude_mpm/core/logger.py +26 -9
- claude_mpm/core/logging_utils.py +39 -13
- claude_mpm/core/network_config.py +148 -0
- claude_mpm/core/oneshot_session.py +7 -6
- claude_mpm/core/optimized_startup.py +61 -0
- claude_mpm/core/output_style_manager.py +66 -18
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/core/socketio_pool.py +47 -15
- claude_mpm/core/unified_agent_registry.py +1 -1
- claude_mpm/core/unified_config.py +54 -8
- claude_mpm/core/unified_paths.py +95 -90
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DR8nis88.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.RgBboRvH.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
- claude_mpm/experimental/cli_enhancements.py +2 -1
- claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
- claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +527 -136
- claude_mpm/hooks/claude_hooks/hook_handler.py +313 -99
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
- claude_mpm/hooks/claude_hooks/installer.py +206 -36
- claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
- claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
- claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/container.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/protocols.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +67 -32
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
- claude_mpm/hooks/claude_hooks/services/container.py +310 -0
- claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
- claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
- claude_mpm/hooks/kuzu_memory_hook.py +5 -5
- claude_mpm/hooks/session_resume_hook.py +89 -1
- claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
- claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
- claude_mpm/init.py +276 -0
- claude_mpm/models/git_repository.py +3 -3
- claude_mpm/scripts/claude-hook-handler.sh +46 -19
- claude_mpm/services/agents/agent_builder.py +3 -3
- claude_mpm/services/agents/agent_recommendation_service.py +8 -8
- claude_mpm/services/agents/agent_selection_service.py +2 -2
- claude_mpm/services/agents/cache_git_manager.py +7 -7
- claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
- claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -2
- claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
- claude_mpm/services/agents/deployment/agent_template_builder.py +39 -19
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
- claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
- claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
- claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +169 -26
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +101 -75
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/git_source_manager.py +23 -4
- claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
- claude_mpm/services/agents/recommender.py +5 -3
- claude_mpm/services/agents/single_tier_deployment_service.py +6 -6
- claude_mpm/services/agents/sources/git_source_sync_service.py +121 -10
- claude_mpm/services/agents/startup_sync.py +27 -4
- claude_mpm/services/cli/__init__.py +3 -0
- claude_mpm/services/cli/incremental_pause_manager.py +561 -0
- claude_mpm/services/cli/session_resume_helper.py +10 -2
- claude_mpm/services/command_deployment_service.py +44 -26
- claude_mpm/services/delegation_detector.py +175 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +31 -1
- claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
- claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
- claude_mpm/services/diagnostics/models.py +14 -1
- claude_mpm/services/event_log.py +325 -0
- claude_mpm/services/git/git_operations_service.py +8 -8
- claude_mpm/services/hook_installer_service.py +77 -8
- claude_mpm/services/infrastructure/__init__.py +4 -0
- claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
- claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
- claude_mpm/services/monitor/daemon_manager.py +15 -4
- claude_mpm/services/monitor/management/lifecycle.py +15 -3
- claude_mpm/services/monitor/server.py +571 -11
- claude_mpm/services/pm_skills_deployer.py +884 -0
- claude_mpm/services/profile_manager.py +337 -0
- claude_mpm/services/skills/git_skill_source_manager.py +281 -20
- claude_mpm/services/skills/selective_skill_deployer.py +211 -46
- claude_mpm/services/skills/skill_discovery_service.py +74 -4
- claude_mpm/services/skills_deployer.py +192 -70
- claude_mpm/services/socketio/dashboard_server.py +1 -0
- claude_mpm/services/socketio/event_normalizer.py +37 -6
- claude_mpm/services/socketio/handlers/hook.py +14 -7
- claude_mpm/services/socketio/server/core.py +262 -123
- claude_mpm/services/socketio/server/main.py +12 -4
- claude_mpm/skills/__init__.py +2 -1
- 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/debugging/root-cause-tracing/SKILL.md +152 -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/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/main/artifacts-builder/SKILL.md +86 -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/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/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/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/pm/mpm/SKILL.md +38 -0
- claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
- claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
- claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
- claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
- claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
- claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
- claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
- claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
- claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
- claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
- claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
- claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
- claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
- claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
- claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
- claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
- claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
- claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
- claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -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 +112 -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/testing/condition-based-waiting/SKILL.md +119 -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/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -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/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/skills/registry.py +295 -90
- claude_mpm/skills/skill_manager.py +98 -3
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/utils/agent_dependency_loader.py +115 -4
- claude_mpm/utils/agent_filters.py +1 -1
- claude_mpm/utils/migration.py +4 -4
- claude_mpm/utils/robust_installer.py +86 -21
- claude_mpm-5.6.34.dist-info/METADATA +393 -0
- {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/RECORD +486 -145
- claude_mpm-5.4.22.dist-info/METADATA +0 -996
- {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/top_level.txt +0 -0
claude_mpm/skills/registry.py
CHANGED
|
@@ -14,35 +14,144 @@ logger = get_logger(__name__)
|
|
|
14
14
|
|
|
15
15
|
@dataclass
|
|
16
16
|
class Skill:
|
|
17
|
-
"""Represents a skill that can be used by agents.
|
|
18
|
-
|
|
17
|
+
"""Represents a skill that can be used by agents.
|
|
18
|
+
|
|
19
|
+
Supports agentskills.io specification with backward compatibility for legacy claude-mpm format.
|
|
20
|
+
|
|
21
|
+
Spec fields (agentskills.io):
|
|
22
|
+
- name: Required, 1-64 chars, lowercase alphanumeric + hyphens
|
|
23
|
+
- description: Required, 1-1024 chars
|
|
24
|
+
- license: Optional, license name or reference
|
|
25
|
+
- compatibility: Optional, max 500 chars, environment requirements
|
|
26
|
+
- metadata: Optional, key-value mapping for arbitrary data
|
|
27
|
+
- allowed_tools: Optional, list of pre-approved tools
|
|
28
|
+
|
|
29
|
+
Internal fields:
|
|
30
|
+
- path: Path to skill file
|
|
31
|
+
- content: Skill content (markdown)
|
|
32
|
+
- source: Origin of skill ('bundled', 'user', 'project', 'pm')
|
|
33
|
+
- version: Skill version (from metadata.version or top-level)
|
|
34
|
+
- skill_id: Internal ID (defaults to name)
|
|
35
|
+
- agent_types: Which agent types can use this skill
|
|
36
|
+
- updated_at: Last update timestamp (from metadata.updated)
|
|
37
|
+
- tags: Tags for discovery (from metadata.tags or top-level)
|
|
38
|
+
|
|
39
|
+
Claude-mpm extensions (preserved for backward compat):
|
|
40
|
+
- category: Skill category for organization
|
|
41
|
+
- toolchain: Associated toolchain (python, javascript, etc.)
|
|
42
|
+
- progressive_disclosure: Progressive disclosure configuration
|
|
43
|
+
- user_invocable: Whether skill can be manually invoked
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
# Core spec fields (agentskills.io)
|
|
19
47
|
name: str
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
48
|
+
description: str
|
|
49
|
+
license: Optional[str] = None
|
|
50
|
+
compatibility: Optional[str] = None
|
|
51
|
+
metadata: Dict[str, Any] = None
|
|
52
|
+
allowed_tools: List[str] = None
|
|
53
|
+
|
|
54
|
+
# Internal fields (not in frontmatter spec)
|
|
55
|
+
path: Path = None
|
|
56
|
+
content: str = ""
|
|
57
|
+
source: str = "bundled" # 'bundled', 'user', 'project', 'pm'
|
|
58
|
+
|
|
59
|
+
# Derived fields (from metadata or fallback)
|
|
60
|
+
version: str = "0.1.0" # From metadata.version or top-level
|
|
61
|
+
skill_id: str = "" # Internal ID (defaults to name)
|
|
30
62
|
agent_types: List[str] = None # Which agent types can use this skill
|
|
63
|
+
updated_at: Optional[str] = None # From metadata.updated
|
|
64
|
+
tags: List[str] = None # From metadata.tags or top-level
|
|
31
65
|
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
|
|
66
|
+
# Claude-mpm extensions (preserved for backward compat)
|
|
67
|
+
category: Optional[str] = None
|
|
68
|
+
toolchain: Optional[str] = None
|
|
69
|
+
progressive_disclosure: Optional[Dict[str, Any]] = None
|
|
70
|
+
user_invocable: bool = False
|
|
35
71
|
|
|
36
72
|
def __post_init__(self):
|
|
37
73
|
"""Initialize default values if not provided."""
|
|
74
|
+
if self.metadata is None:
|
|
75
|
+
self.metadata = {}
|
|
38
76
|
if self.agent_types is None:
|
|
39
77
|
self.agent_types = []
|
|
40
78
|
if self.tags is None:
|
|
41
79
|
self.tags = []
|
|
80
|
+
if self.allowed_tools is None:
|
|
81
|
+
self.allowed_tools = []
|
|
42
82
|
if not self.skill_id:
|
|
43
83
|
self.skill_id = self.name
|
|
44
84
|
|
|
45
85
|
|
|
86
|
+
def validate_agentskills_spec(skill: Skill) -> tuple[bool, List[str]]:
|
|
87
|
+
"""Validate skill against agentskills.io specification.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
skill: Skill object to validate
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
Tuple of (is_valid, list_of_warnings)
|
|
94
|
+
- is_valid: True if skill meets spec requirements
|
|
95
|
+
- warnings: List of warning messages for spec violations
|
|
96
|
+
"""
|
|
97
|
+
warnings = []
|
|
98
|
+
|
|
99
|
+
# Validate name (required field)
|
|
100
|
+
if not skill.name:
|
|
101
|
+
warnings.append("Missing required field: name")
|
|
102
|
+
return False, warnings
|
|
103
|
+
|
|
104
|
+
# Validate name format: lowercase alphanumeric + hyphens, no leading/trailing hyphens
|
|
105
|
+
if not re.match(r"^[a-z0-9]+(-[a-z0-9]+)*$", skill.name):
|
|
106
|
+
warnings.append(
|
|
107
|
+
f"Invalid name format: '{skill.name}' (must be lowercase alphanumeric with hyphens, "
|
|
108
|
+
"no leading/trailing hyphens, no consecutive hyphens)"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# Validate name length (max 64 chars)
|
|
112
|
+
if len(skill.name) > 64:
|
|
113
|
+
warnings.append(
|
|
114
|
+
f"Name too long: {len(skill.name)} chars (max 64 per agentskills.io spec)"
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Validate description (required field)
|
|
118
|
+
if not skill.description:
|
|
119
|
+
warnings.append("Missing required field: description")
|
|
120
|
+
return False, warnings
|
|
121
|
+
|
|
122
|
+
# Validate description length (1-1024 chars)
|
|
123
|
+
desc_len = len(skill.description)
|
|
124
|
+
if desc_len < 1 or desc_len > 1024:
|
|
125
|
+
warnings.append(
|
|
126
|
+
f"Description length {desc_len} chars is outside spec range (1-1024 chars)"
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# Validate compatibility length (max 500 chars)
|
|
130
|
+
if skill.compatibility and len(skill.compatibility) > 500:
|
|
131
|
+
warnings.append(
|
|
132
|
+
f"Compatibility field too long: {len(skill.compatibility)} chars (max 500)"
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
# Validate metadata is dict
|
|
136
|
+
if skill.metadata is not None and not isinstance(skill.metadata, dict):
|
|
137
|
+
warnings.append("Metadata must be a key-value mapping (dict)")
|
|
138
|
+
|
|
139
|
+
# Check for spec-compliant metadata structure
|
|
140
|
+
spec_metadata_fields = ["version", "author", "updated", "tags"]
|
|
141
|
+
for field in spec_metadata_fields:
|
|
142
|
+
if hasattr(skill, field):
|
|
143
|
+
field_value = getattr(skill, field)
|
|
144
|
+
if field_value and field not in skill.metadata:
|
|
145
|
+
warnings.append(
|
|
146
|
+
f"Field '{field}' should be in metadata block per agentskills.io spec "
|
|
147
|
+
f"(found as top-level field)"
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# Valid if no errors (only warnings allowed)
|
|
151
|
+
is_valid = len(warnings) == 0 or all("should be in metadata" in w for w in warnings)
|
|
152
|
+
return is_valid, warnings
|
|
153
|
+
|
|
154
|
+
|
|
46
155
|
class SkillsRegistry:
|
|
47
156
|
"""Registry for managing skills across all tiers."""
|
|
48
157
|
|
|
@@ -54,7 +163,10 @@ class SkillsRegistry:
|
|
|
54
163
|
self._load_project_skills()
|
|
55
164
|
|
|
56
165
|
def _parse_skill_frontmatter(self, content: str) -> Dict[str, Any]:
|
|
57
|
-
"""Parse YAML frontmatter from skill markdown file.
|
|
166
|
+
"""Parse YAML frontmatter from skill markdown file with spec validation.
|
|
167
|
+
|
|
168
|
+
Supports both agentskills.io spec format and legacy claude-mpm format
|
|
169
|
+
with automatic migration.
|
|
58
170
|
|
|
59
171
|
Returns:
|
|
60
172
|
Dict with frontmatter fields or empty dict if no frontmatter
|
|
@@ -70,11 +182,150 @@ class SkillsRegistry:
|
|
|
70
182
|
|
|
71
183
|
try:
|
|
72
184
|
frontmatter = yaml.safe_load(match.group(1))
|
|
73
|
-
|
|
185
|
+
if not frontmatter:
|
|
186
|
+
return {}
|
|
187
|
+
|
|
188
|
+
# Apply backward compatibility migration
|
|
189
|
+
return self._apply_backward_compatibility(frontmatter)
|
|
74
190
|
except yaml.YAMLError as e:
|
|
75
191
|
logger.warning(f"Failed to parse skill frontmatter: {e}")
|
|
76
192
|
return {}
|
|
77
193
|
|
|
194
|
+
def _apply_backward_compatibility(
|
|
195
|
+
self, frontmatter: Dict[str, Any]
|
|
196
|
+
) -> Dict[str, Any]:
|
|
197
|
+
"""Apply backward compatibility transformations to legacy frontmatter.
|
|
198
|
+
|
|
199
|
+
Auto-migrates legacy claude-mpm fields to agentskills.io spec format:
|
|
200
|
+
- version → metadata.version
|
|
201
|
+
- author → metadata.author
|
|
202
|
+
- updated → metadata.updated
|
|
203
|
+
- tags → metadata.tags (if not already present)
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
frontmatter: Parsed frontmatter dict
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
Transformed frontmatter with spec-compliant structure
|
|
210
|
+
"""
|
|
211
|
+
# Initialize metadata if not present
|
|
212
|
+
if "metadata" not in frontmatter:
|
|
213
|
+
frontmatter["metadata"] = {}
|
|
214
|
+
|
|
215
|
+
metadata = frontmatter["metadata"]
|
|
216
|
+
|
|
217
|
+
# Auto-migrate version (top-level → metadata.version)
|
|
218
|
+
if "version" in frontmatter and "version" not in metadata:
|
|
219
|
+
metadata["version"] = frontmatter["version"]
|
|
220
|
+
logger.debug(
|
|
221
|
+
f"Auto-migrated 'version' to metadata for skill '{frontmatter.get('name', 'unknown')}'"
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
# Auto-migrate author (top-level → metadata.author)
|
|
225
|
+
if "author" in frontmatter and "author" not in metadata:
|
|
226
|
+
metadata["author"] = frontmatter["author"]
|
|
227
|
+
logger.debug(
|
|
228
|
+
f"Auto-migrated 'author' to metadata for skill '{frontmatter.get('name', 'unknown')}'"
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
# Auto-migrate updated (top-level → metadata.updated)
|
|
232
|
+
if "updated" in frontmatter and "updated" not in metadata:
|
|
233
|
+
metadata["updated"] = frontmatter["updated"]
|
|
234
|
+
logger.debug(
|
|
235
|
+
f"Auto-migrated 'updated' to metadata for skill '{frontmatter.get('name', 'unknown')}'"
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
# Auto-migrate tags (top-level → metadata.tags)
|
|
239
|
+
if "tags" in frontmatter and "tags" not in metadata:
|
|
240
|
+
metadata["tags"] = frontmatter["tags"]
|
|
241
|
+
logger.debug(
|
|
242
|
+
f"Auto-migrated 'tags' to metadata for skill '{frontmatter.get('name', 'unknown')}'"
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
# Parse allowed-tools from space-delimited string to list
|
|
246
|
+
if "allowed-tools" in frontmatter:
|
|
247
|
+
allowed_tools = frontmatter["allowed-tools"]
|
|
248
|
+
if isinstance(allowed_tools, str):
|
|
249
|
+
frontmatter["allowed-tools"] = allowed_tools.split()
|
|
250
|
+
|
|
251
|
+
# Set default compatibility for claude-code if not present
|
|
252
|
+
if "compatibility" not in frontmatter:
|
|
253
|
+
frontmatter["compatibility"] = "claude-code"
|
|
254
|
+
|
|
255
|
+
return frontmatter
|
|
256
|
+
|
|
257
|
+
def _create_skill_from_frontmatter(
|
|
258
|
+
self, frontmatter: Dict[str, Any], path: Path, content: str, source: str
|
|
259
|
+
) -> Optional[Skill]:
|
|
260
|
+
"""Create Skill object from frontmatter with spec compliance.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
frontmatter: Parsed and migrated frontmatter dict
|
|
264
|
+
path: Path to skill file
|
|
265
|
+
content: Full skill content
|
|
266
|
+
source: Source type ('bundled', 'user', 'project', 'pm')
|
|
267
|
+
|
|
268
|
+
Returns:
|
|
269
|
+
Skill object or None if required fields missing
|
|
270
|
+
"""
|
|
271
|
+
# Extract spec fields (required)
|
|
272
|
+
name = frontmatter.get("name")
|
|
273
|
+
description = frontmatter.get("description", "")
|
|
274
|
+
|
|
275
|
+
# If name not in frontmatter, use filename stem
|
|
276
|
+
if not name:
|
|
277
|
+
name = path.stem
|
|
278
|
+
|
|
279
|
+
# If description not in frontmatter, extract from content
|
|
280
|
+
if not description:
|
|
281
|
+
description = self._extract_description(content)
|
|
282
|
+
|
|
283
|
+
# Validate required fields
|
|
284
|
+
if not name or not description:
|
|
285
|
+
logger.warning(
|
|
286
|
+
f"Skipping skill at {path}: missing required field (name or description)"
|
|
287
|
+
)
|
|
288
|
+
return None
|
|
289
|
+
|
|
290
|
+
# Extract spec fields (optional)
|
|
291
|
+
license_field = frontmatter.get("license")
|
|
292
|
+
compatibility = frontmatter.get("compatibility", "claude-code")
|
|
293
|
+
metadata = frontmatter.get("metadata", {})
|
|
294
|
+
allowed_tools = frontmatter.get("allowed-tools", [])
|
|
295
|
+
|
|
296
|
+
# Extract derived fields from metadata or top-level
|
|
297
|
+
version = frontmatter.get("version") or metadata.get("version", "0.1.0")
|
|
298
|
+
skill_id = frontmatter.get("skill_id", name)
|
|
299
|
+
updated_at = frontmatter.get("updated_at") or metadata.get("updated")
|
|
300
|
+
tags = frontmatter.get("tags", []) or metadata.get("tags", [])
|
|
301
|
+
|
|
302
|
+
# Extract claude-mpm extensions
|
|
303
|
+
category = frontmatter.get("category")
|
|
304
|
+
toolchain = frontmatter.get("toolchain")
|
|
305
|
+
progressive_disclosure = frontmatter.get("progressive_disclosure")
|
|
306
|
+
user_invocable = frontmatter.get("user-invocable", False)
|
|
307
|
+
|
|
308
|
+
# Create skill object
|
|
309
|
+
return Skill(
|
|
310
|
+
name=name,
|
|
311
|
+
description=description,
|
|
312
|
+
license=license_field,
|
|
313
|
+
compatibility=compatibility,
|
|
314
|
+
metadata=metadata,
|
|
315
|
+
allowed_tools=allowed_tools,
|
|
316
|
+
path=path,
|
|
317
|
+
content=content,
|
|
318
|
+
source=source,
|
|
319
|
+
version=version,
|
|
320
|
+
skill_id=skill_id,
|
|
321
|
+
updated_at=updated_at,
|
|
322
|
+
tags=tags,
|
|
323
|
+
category=category,
|
|
324
|
+
toolchain=toolchain,
|
|
325
|
+
progressive_disclosure=progressive_disclosure,
|
|
326
|
+
user_invocable=user_invocable,
|
|
327
|
+
)
|
|
328
|
+
|
|
78
329
|
def _load_bundled_skills(self):
|
|
79
330
|
"""Load skills bundled with MPM."""
|
|
80
331
|
bundled_dir = Path(__file__).parent / "bundled"
|
|
@@ -88,32 +339,16 @@ class SkillsRegistry:
|
|
|
88
339
|
skill_name = skill_file.stem
|
|
89
340
|
content = skill_file.read_text(encoding="utf-8")
|
|
90
341
|
|
|
91
|
-
# Parse frontmatter
|
|
342
|
+
# Parse frontmatter with backward compatibility
|
|
92
343
|
frontmatter = self._parse_skill_frontmatter(content)
|
|
93
344
|
|
|
94
|
-
#
|
|
95
|
-
|
|
96
|
-
|
|
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)
|
|
104
|
-
|
|
105
|
-
self.skills[skill_name] = Skill(
|
|
106
|
-
name=skill_name,
|
|
107
|
-
path=skill_file,
|
|
108
|
-
content=content,
|
|
109
|
-
source="bundled",
|
|
110
|
-
version=version,
|
|
111
|
-
skill_id=skill_id,
|
|
112
|
-
description=description,
|
|
113
|
-
updated_at=updated_at,
|
|
114
|
-
tags=tags,
|
|
345
|
+
# Create skill from frontmatter
|
|
346
|
+
skill = self._create_skill_from_frontmatter(
|
|
347
|
+
frontmatter, skill_file, content, "bundled"
|
|
115
348
|
)
|
|
116
|
-
|
|
349
|
+
if skill:
|
|
350
|
+
self.skills[skill_name] = skill
|
|
351
|
+
skill_count += 1
|
|
117
352
|
except Exception as e:
|
|
118
353
|
logger.error(f"Error loading bundled skill {skill_file}: {e}")
|
|
119
354
|
|
|
@@ -130,36 +365,20 @@ class SkillsRegistry:
|
|
|
130
365
|
for skill_file in user_skills_dir.glob("*.md"):
|
|
131
366
|
try:
|
|
132
367
|
skill_name = skill_file.stem
|
|
133
|
-
# User skills override bundled skills
|
|
134
368
|
content = skill_file.read_text(encoding="utf-8")
|
|
135
369
|
|
|
136
|
-
# Parse frontmatter
|
|
370
|
+
# Parse frontmatter with backward compatibility
|
|
137
371
|
frontmatter = self._parse_skill_frontmatter(content)
|
|
138
372
|
|
|
139
|
-
#
|
|
140
|
-
|
|
141
|
-
|
|
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)
|
|
149
|
-
|
|
150
|
-
self.skills[skill_name] = Skill(
|
|
151
|
-
name=skill_name,
|
|
152
|
-
path=skill_file,
|
|
153
|
-
content=content,
|
|
154
|
-
source="user",
|
|
155
|
-
version=version,
|
|
156
|
-
skill_id=skill_id,
|
|
157
|
-
description=description,
|
|
158
|
-
updated_at=updated_at,
|
|
159
|
-
tags=tags,
|
|
373
|
+
# Create skill from frontmatter
|
|
374
|
+
skill = self._create_skill_from_frontmatter(
|
|
375
|
+
frontmatter, skill_file, content, "user"
|
|
160
376
|
)
|
|
161
|
-
|
|
162
|
-
|
|
377
|
+
if skill:
|
|
378
|
+
# User skills override bundled skills
|
|
379
|
+
self.skills[skill_name] = skill
|
|
380
|
+
skill_count += 1
|
|
381
|
+
logger.debug(f"User skill '{skill_name}' overrides bundled version")
|
|
163
382
|
except Exception as e:
|
|
164
383
|
logger.error(f"Error loading user skill {skill_file}: {e}")
|
|
165
384
|
|
|
@@ -177,36 +396,22 @@ class SkillsRegistry:
|
|
|
177
396
|
for skill_file in project_skills_dir.glob("*.md"):
|
|
178
397
|
try:
|
|
179
398
|
skill_name = skill_file.stem
|
|
180
|
-
# Project skills override both user and bundled skills
|
|
181
399
|
content = skill_file.read_text(encoding="utf-8")
|
|
182
400
|
|
|
183
|
-
# Parse frontmatter
|
|
401
|
+
# Parse frontmatter with backward compatibility
|
|
184
402
|
frontmatter = self._parse_skill_frontmatter(content)
|
|
185
403
|
|
|
186
|
-
#
|
|
187
|
-
|
|
188
|
-
|
|
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)
|
|
196
|
-
|
|
197
|
-
self.skills[skill_name] = Skill(
|
|
198
|
-
name=skill_name,
|
|
199
|
-
path=skill_file,
|
|
200
|
-
content=content,
|
|
201
|
-
source="project",
|
|
202
|
-
version=version,
|
|
203
|
-
skill_id=skill_id,
|
|
204
|
-
description=description,
|
|
205
|
-
updated_at=updated_at,
|
|
206
|
-
tags=tags,
|
|
404
|
+
# Create skill from frontmatter
|
|
405
|
+
skill = self._create_skill_from_frontmatter(
|
|
406
|
+
frontmatter, skill_file, content, "project"
|
|
207
407
|
)
|
|
208
|
-
|
|
209
|
-
|
|
408
|
+
if skill:
|
|
409
|
+
# Project skills override both user and bundled skills
|
|
410
|
+
self.skills[skill_name] = skill
|
|
411
|
+
skill_count += 1
|
|
412
|
+
logger.debug(
|
|
413
|
+
f"Project skill '{skill_name}' overrides other versions"
|
|
414
|
+
)
|
|
210
415
|
except Exception as e:
|
|
211
416
|
logger.error(f"Error loading project skill {skill_file}: {e}")
|
|
212
417
|
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import Dict, List, Optional
|
|
5
|
+
from typing import Any, Dict, List, Optional
|
|
6
|
+
|
|
7
|
+
import yaml
|
|
6
8
|
|
|
7
9
|
from claude_mpm.core.logging_utils import get_logger
|
|
8
10
|
|
|
@@ -56,12 +58,81 @@ class SkillManager:
|
|
|
56
58
|
if mapping_count > 0:
|
|
57
59
|
logger.info(f"Loaded skill mappings for {mapping_count} agents")
|
|
58
60
|
|
|
61
|
+
def _get_pm_skills(
|
|
62
|
+
self, project_dir: Optional[Path] = None
|
|
63
|
+
) -> List[Dict[str, Any]]:
|
|
64
|
+
"""Load PM skills from project's .claude/skills/ directory.
|
|
65
|
+
|
|
66
|
+
PM skills are special framework management skills (mpm-*) deployed
|
|
67
|
+
per-project to .claude/skills/, NOT fetched from the skills repository.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
project_dir: Project directory. Defaults to current working directory.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
List of PM skill dictionaries with metadata
|
|
74
|
+
"""
|
|
75
|
+
if project_dir is None:
|
|
76
|
+
project_dir = Path.cwd()
|
|
77
|
+
|
|
78
|
+
pm_skills_dir = project_dir / ".claude" / "skills"
|
|
79
|
+
|
|
80
|
+
if not pm_skills_dir.exists():
|
|
81
|
+
logger.debug("PM skills directory not found")
|
|
82
|
+
return []
|
|
83
|
+
|
|
84
|
+
skills = []
|
|
85
|
+
for skill_dir in pm_skills_dir.iterdir():
|
|
86
|
+
if skill_dir.is_dir():
|
|
87
|
+
skill_file = skill_dir / "SKILL.md"
|
|
88
|
+
if skill_file.exists():
|
|
89
|
+
skill = self._load_pm_skill(skill_file)
|
|
90
|
+
if skill:
|
|
91
|
+
skills.append(skill)
|
|
92
|
+
|
|
93
|
+
if skills:
|
|
94
|
+
logger.debug(f"Loaded {len(skills)} PM skills from {pm_skills_dir}")
|
|
95
|
+
|
|
96
|
+
return skills
|
|
97
|
+
|
|
98
|
+
def _load_pm_skill(self, skill_file: Path) -> Optional[Dict[str, Any]]:
|
|
99
|
+
"""Load a single PM skill from SKILL.md file.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
skill_file: Path to SKILL.md file
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
Dictionary with skill metadata and content, or None if failed
|
|
106
|
+
"""
|
|
107
|
+
try:
|
|
108
|
+
content = skill_file.read_text(encoding="utf-8")
|
|
109
|
+
|
|
110
|
+
# Parse YAML frontmatter
|
|
111
|
+
if content.startswith("---"):
|
|
112
|
+
parts = content.split("---", 2)
|
|
113
|
+
if len(parts) >= 3:
|
|
114
|
+
metadata = yaml.safe_load(parts[1])
|
|
115
|
+
body = parts[2].strip()
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
"name": metadata.get("name", skill_file.parent.name),
|
|
119
|
+
"version": metadata.get("version", "1.0.0"),
|
|
120
|
+
"description": metadata.get("description", ""),
|
|
121
|
+
"when_to_use": metadata.get("when_to_use", ""),
|
|
122
|
+
"content": body,
|
|
123
|
+
"is_pm_skill": True,
|
|
124
|
+
}
|
|
125
|
+
except Exception as e:
|
|
126
|
+
logger.warning(f"Failed to load PM skill {skill_file}: {e}")
|
|
127
|
+
|
|
128
|
+
return None
|
|
129
|
+
|
|
59
130
|
def get_agent_skills(self, agent_type: str) -> List[Skill]:
|
|
60
131
|
"""
|
|
61
|
-
Get all skills for an agent (bundled + discovered).
|
|
132
|
+
Get all skills for an agent (bundled + discovered + PM skills if PM agent).
|
|
62
133
|
|
|
63
134
|
Args:
|
|
64
|
-
agent_type: Agent type/ID (e.g., 'engineer', 'python_engineer')
|
|
135
|
+
agent_type: Agent type/ID (e.g., 'engineer', 'python_engineer', 'pm')
|
|
65
136
|
|
|
66
137
|
Returns:
|
|
67
138
|
List of Skill objects for this agent
|
|
@@ -86,6 +157,30 @@ class SkillManager:
|
|
|
86
157
|
if skill not in skills:
|
|
87
158
|
skills.append(skill)
|
|
88
159
|
|
|
160
|
+
# Add PM skills for PM agent only
|
|
161
|
+
if agent_type.lower() in ("pm", "project-manager", "project_manager"):
|
|
162
|
+
pm_skill_dicts = self._get_pm_skills()
|
|
163
|
+
for pm_skill_dict in pm_skill_dicts:
|
|
164
|
+
# Convert PM skill dict to Skill object
|
|
165
|
+
pm_skill = Skill(
|
|
166
|
+
name=pm_skill_dict["name"],
|
|
167
|
+
path=Path.cwd()
|
|
168
|
+
/ ".claude-mpm"
|
|
169
|
+
/ "skills"
|
|
170
|
+
/ "pm"
|
|
171
|
+
/ pm_skill_dict["name"],
|
|
172
|
+
content=pm_skill_dict["content"],
|
|
173
|
+
source="pm", # Special source type for PM skills
|
|
174
|
+
version=pm_skill_dict["version"],
|
|
175
|
+
skill_id=pm_skill_dict["name"],
|
|
176
|
+
description=pm_skill_dict["description"],
|
|
177
|
+
agent_types=["pm", "project-manager", "project_manager"],
|
|
178
|
+
)
|
|
179
|
+
skills.append(pm_skill)
|
|
180
|
+
|
|
181
|
+
if pm_skill_dicts:
|
|
182
|
+
logger.debug(f"Added {len(pm_skill_dicts)} PM skills for PM agent")
|
|
183
|
+
|
|
89
184
|
return skills
|
|
90
185
|
|
|
91
186
|
def enhance_agent_prompt(
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Pre-commit hooks configuration for claude-mpm
|
|
2
|
+
# See https://pre-commit.com for more information
|
|
3
|
+
# See https://pre-commit.com/hooks.html for more hooks
|
|
4
|
+
|
|
5
|
+
repos:
|
|
6
|
+
# Standard pre-commit hooks
|
|
7
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
8
|
+
rev: v4.5.0
|
|
9
|
+
hooks:
|
|
10
|
+
- id: trailing-whitespace
|
|
11
|
+
exclude: ^(.*\.md|.*\.txt)$
|
|
12
|
+
- id: end-of-file-fixer
|
|
13
|
+
exclude: ^(.*\.md|.*\.txt)$
|
|
14
|
+
- id: check-yaml
|
|
15
|
+
args: ['--unsafe'] # Allow custom YAML tags
|
|
16
|
+
- id: check-json
|
|
17
|
+
- id: check-toml
|
|
18
|
+
- id: check-merge-conflict
|
|
19
|
+
- id: check-added-large-files
|
|
20
|
+
args: ['--maxkb=1000']
|
|
21
|
+
- id: check-case-conflict
|
|
22
|
+
- id: check-executables-have-shebangs
|
|
23
|
+
- id: check-shebang-scripts-are-executable
|
|
24
|
+
- id: mixed-line-ending
|
|
25
|
+
args: ['--fix=lf']
|
|
26
|
+
|
|
27
|
+
# Ruff - replaces black, isort, flake8, pyupgrade (10-200x faster)
|
|
28
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
29
|
+
rev: v0.8.4 # Use latest version
|
|
30
|
+
hooks:
|
|
31
|
+
# Run the linter
|
|
32
|
+
- id: ruff
|
|
33
|
+
args: [--fix]
|
|
34
|
+
# Run the formatter
|
|
35
|
+
- id: ruff-format
|
|
36
|
+
|
|
37
|
+
# Type checking with mypy
|
|
38
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
39
|
+
rev: v1.8.0
|
|
40
|
+
hooks:
|
|
41
|
+
- id: mypy
|
|
42
|
+
additional_dependencies: [types-PyYAML, types-requests]
|
|
43
|
+
args: ['--config-file=mypy.ini']
|
|
44
|
+
exclude: ^(venv/|\.venv/|env/|\.env/|build/|dist/|\.git/|tests/.*\.py|scripts/.*\.py)
|
|
45
|
+
|
|
46
|
+
# Security scanning with bandit
|
|
47
|
+
- repo: https://github.com/pycqa/bandit
|
|
48
|
+
rev: 1.7.5
|
|
49
|
+
hooks:
|
|
50
|
+
- id: bandit
|
|
51
|
+
args: ['-r', '-f', 'json']
|
|
52
|
+
exclude: ^(venv/|\.venv/|env/|\.env/|build/|dist/|\.git/|tests/.*\.py)
|
|
53
|
+
|
|
54
|
+
# Secret detection with detect-secrets
|
|
55
|
+
- repo: https://github.com/Yelp/detect-secrets
|
|
56
|
+
rev: v1.5.0
|
|
57
|
+
hooks:
|
|
58
|
+
- id: detect-secrets
|
|
59
|
+
args: ['--baseline', '.secrets.baseline']
|
|
60
|
+
exclude: |
|
|
61
|
+
(?x)^(
|
|
62
|
+
venv/.*|
|
|
63
|
+
\.venv/.*|
|
|
64
|
+
node_modules/.*|
|
|
65
|
+
\.git/.*|
|
|
66
|
+
__pycache__/.*|
|
|
67
|
+
.*\.lock|
|
|
68
|
+
.*package-lock\.json|
|
|
69
|
+
.*\.pyc
|
|
70
|
+
)$
|
|
71
|
+
|
|
72
|
+
# Documentation linting
|
|
73
|
+
- repo: https://github.com/pycqa/doc8
|
|
74
|
+
rev: v1.1.1
|
|
75
|
+
hooks:
|
|
76
|
+
- id: doc8
|
|
77
|
+
args: ['--max-line-length=88']
|
|
78
|
+
files: \.rst$
|
|
79
|
+
|
|
80
|
+
# Commitizen for conventional commits
|
|
81
|
+
- repo: https://github.com/commitizen-tools/commitizen
|
|
82
|
+
rev: v3.13.0
|
|
83
|
+
hooks:
|
|
84
|
+
- id: commitizen
|
|
85
|
+
stages: [commit-msg]
|
|
86
|
+
|
|
87
|
+
# Configuration for specific file types
|
|
88
|
+
exclude: |
|
|
89
|
+
(?x)^(
|
|
90
|
+
venv/.*|
|
|
91
|
+
\.venv/.*|
|
|
92
|
+
env/.*|
|
|
93
|
+
\.env/.*|
|
|
94
|
+
build/.*|
|
|
95
|
+
dist/.*|
|
|
96
|
+
\.git/.*|
|
|
97
|
+
__pycache__/.*|
|
|
98
|
+
.*\.pyc|
|
|
99
|
+
.*\.pyo|
|
|
100
|
+
.*\.egg-info/.*|
|
|
101
|
+
\.coverage|
|
|
102
|
+
\.pytest_cache/.*|
|
|
103
|
+
\.mypy_cache/.*|
|
|
104
|
+
node_modules/.*|
|
|
105
|
+
\.DS_Store|
|
|
106
|
+
\.vscode/.*|
|
|
107
|
+
\.idea/.*
|
|
108
|
+
)$
|
|
109
|
+
|
|
110
|
+
# Global settings
|
|
111
|
+
default_stages: [pre-commit]
|
|
112
|
+
fail_fast: false
|