claude-mpm 5.4.41__py3-none-any.whl → 5.6.72__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/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/PM_INSTRUCTIONS.md +161 -298
- claude_mpm/agents/WORKFLOW.md +2 -0
- claude_mpm/agents/templates/circuit-breakers.md +26 -17
- claude_mpm/auth/__init__.py +35 -0
- claude_mpm/auth/callback_server.py +328 -0
- claude_mpm/auth/models.py +104 -0
- claude_mpm/auth/oauth_manager.py +266 -0
- claude_mpm/auth/providers/__init__.py +12 -0
- claude_mpm/auth/providers/base.py +165 -0
- claude_mpm/auth/providers/google.py +261 -0
- claude_mpm/auth/token_storage.py +252 -0
- claude_mpm/cli/__init__.py +5 -1
- claude_mpm/cli/commands/agents.py +2 -4
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/autotodos.py +566 -0
- claude_mpm/cli/commands/commander.py +216 -0
- claude_mpm/cli/commands/configure.py +620 -21
- claude_mpm/cli/commands/configure_agent_display.py +3 -1
- claude_mpm/cli/commands/hook_errors.py +60 -60
- claude_mpm/cli/commands/mcp.py +29 -17
- claude_mpm/cli/commands/mcp_command_router.py +39 -0
- claude_mpm/cli/commands/mcp_service_commands.py +304 -0
- claude_mpm/cli/commands/monitor.py +2 -2
- claude_mpm/cli/commands/mpm_init/core.py +15 -8
- claude_mpm/cli/commands/oauth.py +481 -0
- claude_mpm/cli/commands/profile.py +9 -10
- 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 +129 -16
- claude_mpm/cli/helpers.py +1 -1
- claude_mpm/cli/interactive/__init__.py +10 -0
- claude_mpm/cli/interactive/agent_wizard.py +30 -50
- 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 +89 -1
- claude_mpm/cli/parsers/commander_parser.py +116 -0
- claude_mpm/cli/parsers/mcp_parser.py +79 -0
- claude_mpm/cli/parsers/oauth_parser.py +165 -0
- claude_mpm/cli/parsers/profile_parser.py +0 -1
- 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 +662 -524
- claude_mpm/cli/startup_display.py +76 -7
- 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 +149 -0
- claude_mpm/commander/chat/commands.py +122 -0
- claude_mpm/commander/chat/repl.py +1821 -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 +392 -0
- claude_mpm/commander/frameworks/__init__.py +12 -0
- claude_mpm/commander/frameworks/base.py +233 -0
- claude_mpm/commander/frameworks/claude_code.py +58 -0
- claude_mpm/commander/frameworks/mpm.py +57 -0
- claude_mpm/commander/git/__init__.py +5 -0
- claude_mpm/commander/git/worktree_manager.py +212 -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 +865 -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 +127 -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 +403 -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 +362 -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 +8 -0
- claude_mpm/commands/mpm-doctor.md +8 -0
- claude_mpm/commands/mpm-help.md +8 -0
- claude_mpm/commands/mpm-init.md +8 -0
- claude_mpm/commands/mpm-monitor.md +8 -0
- claude_mpm/commands/mpm-organize.md +8 -0
- claude_mpm/commands/mpm-postmortem.md +8 -0
- claude_mpm/commands/mpm-session-resume.md +9 -1
- claude_mpm/commands/mpm-status.md +8 -0
- claude_mpm/commands/mpm-ticket-view.md +8 -0
- claude_mpm/commands/mpm-version.md +8 -0
- 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 +6 -0
- claude_mpm/core/claude_runner.py +154 -2
- claude_mpm/core/config.py +35 -22
- claude_mpm/core/config_constants.py +74 -9
- claude_mpm/core/constants.py +56 -12
- claude_mpm/core/hook_manager.py +53 -4
- 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 +3 -1
- 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_config.py +54 -8
- claude_mpm/core/unified_paths.py +95 -90
- 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/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
- 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/{N4qtv3Hx.js → DR8nis88.js} +2 -2
- 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/{DjhvlsAc.js → NqQ1dWOy.js} +1 -1
- 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.CAGBuiOw.js → 0.RgBboRvH.js} +1 -1
- 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 -1
- claude_mpm/dashboard/static/svelte-build/index.html +11 -11
- 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__/auto_pause_handler.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/auto_pause_handler.py +485 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +466 -136
- claude_mpm/hooks/claude_hooks/hook_handler.py +204 -104
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
- claude_mpm/hooks/claude_hooks/installer.py +291 -59
- 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__/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 +41 -26
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
- claude_mpm/hooks/claude_hooks/services/container.py +326 -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 +224 -4
- claude_mpm/mcp/__init__.py +9 -0
- claude_mpm/mcp/google_workspace_server.py +610 -0
- claude_mpm/scripts/claude-hook-handler.sh +46 -19
- 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 +1 -1
- claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -1
- claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
- claude_mpm/services/agents/deployment/agent_template_builder.py +37 -17
- 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 +36 -8
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +50 -26
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/git_source_manager.py +21 -2
- claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
- claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
- claude_mpm/services/agents/sources/git_source_sync_service.py +116 -5
- claude_mpm/services/agents/startup_sync.py +5 -2
- 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_sources_check.py +30 -0
- 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/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/mcp_config_manager.py +99 -19
- claude_mpm/services/mcp_service_registry.py +294 -0
- claude_mpm/services/monitor/daemon_manager.py +15 -4
- claude_mpm/services/monitor/management/lifecycle.py +8 -3
- claude_mpm/services/monitor/server.py +111 -16
- claude_mpm/services/pm_skills_deployer.py +302 -94
- claude_mpm/services/profile_manager.py +10 -4
- claude_mpm/services/skills/git_skill_source_manager.py +192 -29
- 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/handlers/hook.py +14 -7
- 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 +29 -23
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- claude_mpm/utils/agent_dependency_loader.py +103 -4
- claude_mpm/utils/robust_installer.py +45 -24
- claude_mpm-5.6.72.dist-info/METADATA +416 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/RECORD +477 -159
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/WHEEL +1 -1
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/entry_points.txt +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- claude_mpm-5.4.41.dist-info/METADATA +0 -998
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.41.dist-info → claude_mpm-5.6.72.dist-info}/top_level.txt +0 -0
|
@@ -1,23 +1,35 @@
|
|
|
1
1
|
"""PM Skills Deployer Service - Deploy bundled PM skills to projects.
|
|
2
2
|
|
|
3
|
-
WHY: PM agents require specific
|
|
3
|
+
WHY: PM agents require specific framework management skills for proper operation.
|
|
4
4
|
This service manages deployment of bundled PM skills from the claude-mpm
|
|
5
|
-
package to
|
|
5
|
+
package to the Claude Code skills directory with version tracking.
|
|
6
6
|
|
|
7
7
|
DESIGN DECISIONS:
|
|
8
|
-
- Deploys from src/claude_mpm/skills/bundled/pm/ to .claude
|
|
9
|
-
-
|
|
8
|
+
- Deploys from src/claude_mpm/skills/bundled/pm/ to .claude/skills/
|
|
9
|
+
- Skills named mpm-* (framework management skills)
|
|
10
|
+
- Direct deployment (no intermediate .claude-mpm/skills/pm/ step)
|
|
11
|
+
- Uses package-relative paths (works for both installed and dev mode)
|
|
12
|
+
- Supports directory structure: mpm-skill-name/SKILL.md
|
|
13
|
+
- Per-project deployment to .claude/skills/ (Claude Code location)
|
|
10
14
|
- Version tracking via .claude-mpm/pm_skills_registry.yaml
|
|
11
15
|
- Checksum validation for integrity verification
|
|
16
|
+
- Conflict resolution: mpm-* skills from src WIN (overwrite existing)
|
|
17
|
+
- Non-mpm-* skills in .claude/skills/ are untouched (user/git managed)
|
|
12
18
|
- Non-blocking verification (returns warnings, doesn't halt execution)
|
|
13
19
|
- Force flag to redeploy even if versions match
|
|
14
20
|
|
|
15
21
|
ARCHITECTURE:
|
|
16
|
-
1. Discovery: Find bundled PM skills in package
|
|
17
|
-
2. Deployment: Copy to
|
|
18
|
-
3.
|
|
19
|
-
4.
|
|
20
|
-
5.
|
|
22
|
+
1. Discovery: Find bundled PM skills in package (skills/bundled/pm/)
|
|
23
|
+
2. Deployment: Copy SKILL.md files to .claude/skills/{name}/SKILL.md
|
|
24
|
+
3. Conflict Check: Overwrite mpm-* skills, preserve non-mpm-* skills
|
|
25
|
+
4. Registry: Track deployed versions and checksums
|
|
26
|
+
5. Verification: Check deployment status (non-blocking)
|
|
27
|
+
6. Updates: Compare bundled vs deployed versions
|
|
28
|
+
|
|
29
|
+
PATH RESOLUTION:
|
|
30
|
+
- Installed package: Uses __file__ to find skills/bundled/pm/
|
|
31
|
+
- Dev mode fallback: .claude-mpm/templates/ at project root
|
|
32
|
+
- Works correctly in both site-packages and development environments
|
|
21
33
|
|
|
22
34
|
References:
|
|
23
35
|
- Parent Service: src/claude_mpm/services/skills_deployer.py
|
|
@@ -27,7 +39,7 @@ References:
|
|
|
27
39
|
import hashlib
|
|
28
40
|
import shutil
|
|
29
41
|
from dataclasses import dataclass
|
|
30
|
-
from datetime import datetime
|
|
42
|
+
from datetime import datetime, timezone
|
|
31
43
|
from pathlib import Path
|
|
32
44
|
from typing import Any, Callable, Dict, List, Optional
|
|
33
45
|
|
|
@@ -38,6 +50,46 @@ from claude_mpm.core.mixins import LoggerMixin
|
|
|
38
50
|
# Security constants
|
|
39
51
|
MAX_YAML_SIZE = 10 * 1024 * 1024 # 10MB limit to prevent YAML bombs
|
|
40
52
|
|
|
53
|
+
# Tier 1: Required PM skills that MUST be deployed for PM agent to function properly
|
|
54
|
+
# These are core framework management skills for basic PM operation
|
|
55
|
+
REQUIRED_PM_SKILLS = [
|
|
56
|
+
# Core command-based skills (new consolidated CLI)
|
|
57
|
+
"mpm",
|
|
58
|
+
"mpm-init",
|
|
59
|
+
"mpm-status",
|
|
60
|
+
"mpm-help",
|
|
61
|
+
"mpm-doctor",
|
|
62
|
+
# Legacy framework management skills
|
|
63
|
+
"mpm-git-file-tracking",
|
|
64
|
+
"mpm-pr-workflow",
|
|
65
|
+
"mpm-ticketing-integration",
|
|
66
|
+
"mpm-delegation-patterns",
|
|
67
|
+
"mpm-verification-protocols",
|
|
68
|
+
"mpm-bug-reporting",
|
|
69
|
+
"mpm-teaching-mode",
|
|
70
|
+
"mpm-agent-update-workflow",
|
|
71
|
+
"mpm-circuit-breaker-enforcement",
|
|
72
|
+
"mpm-tool-usage-guide",
|
|
73
|
+
"mpm-session-management",
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
# Tier 2: Recommended skills (deployed with standard install)
|
|
77
|
+
# These provide enhanced functionality for common workflows
|
|
78
|
+
RECOMMENDED_PM_SKILLS = [
|
|
79
|
+
"mpm-config",
|
|
80
|
+
"mpm-ticket-view",
|
|
81
|
+
"mpm-session-resume",
|
|
82
|
+
"mpm-postmortem",
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
# Tier 3: Optional skills (deployed with full install)
|
|
86
|
+
# These provide additional features for advanced use cases
|
|
87
|
+
OPTIONAL_PM_SKILLS = [
|
|
88
|
+
"mpm-monitor",
|
|
89
|
+
"mpm-version",
|
|
90
|
+
"mpm-organize",
|
|
91
|
+
]
|
|
92
|
+
|
|
41
93
|
|
|
42
94
|
@dataclass
|
|
43
95
|
class PMSkillInfo:
|
|
@@ -87,15 +139,19 @@ class VerificationResult:
|
|
|
87
139
|
verified: Whether all skills are properly deployed
|
|
88
140
|
warnings: List of warning messages
|
|
89
141
|
missing_skills: List of missing skill names
|
|
142
|
+
corrupted_skills: List of corrupted skill names (checksum mismatch)
|
|
90
143
|
outdated_skills: List of outdated skill names
|
|
91
144
|
message: Summary message
|
|
145
|
+
skill_count: Total number of deployed skills
|
|
92
146
|
"""
|
|
93
147
|
|
|
94
148
|
verified: bool
|
|
95
149
|
warnings: List[str]
|
|
96
150
|
missing_skills: List[str]
|
|
151
|
+
corrupted_skills: List[str]
|
|
97
152
|
outdated_skills: List[str]
|
|
98
153
|
message: str
|
|
154
|
+
skill_count: int = 0
|
|
99
155
|
|
|
100
156
|
|
|
101
157
|
@dataclass
|
|
@@ -119,8 +175,9 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
119
175
|
"""Deploy and manage PM skills from bundled sources to projects.
|
|
120
176
|
|
|
121
177
|
This service provides:
|
|
122
|
-
- Discovery of bundled PM skills (
|
|
123
|
-
- Deployment to .claude
|
|
178
|
+
- Discovery of bundled PM skills (mpm-* framework management skills)
|
|
179
|
+
- Deployment to .claude/skills/ (Claude Code location)
|
|
180
|
+
- Conflict resolution (mpm-* skills from src WIN)
|
|
124
181
|
- Version tracking via pm_skills_registry.yaml
|
|
125
182
|
- Checksum validation for integrity
|
|
126
183
|
- Non-blocking verification (warnings only)
|
|
@@ -129,7 +186,7 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
129
186
|
Example:
|
|
130
187
|
>>> deployer = PMSkillsDeployerService()
|
|
131
188
|
>>> result = deployer.deploy_pm_skills(Path("/project/root"))
|
|
132
|
-
>>> print(f"Deployed {len(result.deployed)} skills")
|
|
189
|
+
>>> print(f"Deployed {len(result.deployed)} skills to .claude/skills/")
|
|
133
190
|
>>>
|
|
134
191
|
>>> verify_result = deployer.verify_pm_skills(Path("/project/root"))
|
|
135
192
|
>>> if not verify_result.verified:
|
|
@@ -143,22 +200,27 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
143
200
|
"""Initialize PM Skills Deployer Service.
|
|
144
201
|
|
|
145
202
|
Sets up paths for:
|
|
146
|
-
- bundled_pm_skills_path: Source bundled PM skills (
|
|
203
|
+
- bundled_pm_skills_path: Source bundled PM skills (skills/bundled/pm/)
|
|
147
204
|
- Deployment paths are project-specific (passed to methods)
|
|
148
205
|
"""
|
|
149
206
|
super().__init__()
|
|
150
207
|
|
|
151
|
-
# Bundled PM skills are in
|
|
152
|
-
#
|
|
153
|
-
|
|
154
|
-
self.bundled_pm_skills_path =
|
|
155
|
-
self.project_root / ".claude-mpm" / "templates"
|
|
156
|
-
)
|
|
208
|
+
# Bundled PM skills are in the package's skills/bundled/pm/ directory
|
|
209
|
+
# This works for both installed packages and development mode
|
|
210
|
+
package_dir = Path(__file__).resolve().parent.parent # Go up to claude_mpm
|
|
211
|
+
self.bundled_pm_skills_path = package_dir / "skills" / "bundled" / "pm"
|
|
157
212
|
|
|
158
213
|
if not self.bundled_pm_skills_path.exists():
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
214
|
+
# Fallback: try .claude-mpm/templates/ at project root for dev mode
|
|
215
|
+
self.project_root = self._find_project_root()
|
|
216
|
+
alt_path = self.project_root / ".claude-mpm" / "templates"
|
|
217
|
+
if alt_path.exists():
|
|
218
|
+
self.bundled_pm_skills_path = alt_path
|
|
219
|
+
self.logger.debug(f"Using dev templates path: {alt_path}")
|
|
220
|
+
else:
|
|
221
|
+
self.logger.warning(
|
|
222
|
+
"PM skills templates path not found (non-critical, uses defaults)"
|
|
223
|
+
)
|
|
162
224
|
|
|
163
225
|
def _find_project_root(self) -> Path:
|
|
164
226
|
"""Find project root by traversing up from current file.
|
|
@@ -230,9 +292,9 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
230
292
|
project_dir: Project root directory
|
|
231
293
|
|
|
232
294
|
Returns:
|
|
233
|
-
Path to .claude
|
|
295
|
+
Path to .claude/skills/
|
|
234
296
|
"""
|
|
235
|
-
return project_dir / ".claude
|
|
297
|
+
return project_dir / ".claude" / "skills"
|
|
236
298
|
|
|
237
299
|
def _load_registry(self, project_dir: Path) -> Dict[str, Any]:
|
|
238
300
|
"""Load PM skills registry with security checks.
|
|
@@ -306,11 +368,13 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
306
368
|
def _discover_bundled_pm_skills(self) -> List[Dict[str, Any]]:
|
|
307
369
|
"""Discover all PM skills in bundled templates directory.
|
|
308
370
|
|
|
371
|
+
PM skills follow mpm-skill-name/SKILL.md structure.
|
|
372
|
+
|
|
309
373
|
Returns:
|
|
310
374
|
List of skill dictionaries containing:
|
|
311
|
-
- name: Skill name (
|
|
312
|
-
- path: Full path to skill file
|
|
313
|
-
- type: File type (md
|
|
375
|
+
- name: Skill name (directory name, e.g., mpm-git-file-tracking)
|
|
376
|
+
- path: Full path to skill file (SKILL.md)
|
|
377
|
+
- type: File type (always 'md')
|
|
314
378
|
"""
|
|
315
379
|
skills = []
|
|
316
380
|
|
|
@@ -320,46 +384,112 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
320
384
|
)
|
|
321
385
|
return skills
|
|
322
386
|
|
|
323
|
-
# Scan for skill
|
|
324
|
-
for
|
|
325
|
-
if
|
|
387
|
+
# Scan for skill directories containing SKILL.md
|
|
388
|
+
for skill_dir in self.bundled_pm_skills_path.iterdir():
|
|
389
|
+
if not skill_dir.is_dir() or skill_dir.name.startswith("."):
|
|
326
390
|
continue
|
|
327
391
|
|
|
328
|
-
skills
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
392
|
+
# Only process mpm* skills (framework management)
|
|
393
|
+
# Note: Includes both 'mpm' (core skill) and 'mpm-*' (other PM skills)
|
|
394
|
+
if not skill_dir.name.startswith("mpm"):
|
|
395
|
+
self.logger.debug(f"Skipping non-mpm skill: {skill_dir.name}")
|
|
396
|
+
continue
|
|
397
|
+
|
|
398
|
+
skill_file = skill_dir / "SKILL.md"
|
|
399
|
+
if skill_file.exists():
|
|
400
|
+
skills.append(
|
|
401
|
+
{
|
|
402
|
+
"name": skill_dir.name,
|
|
403
|
+
"path": skill_file,
|
|
404
|
+
"type": "md",
|
|
405
|
+
}
|
|
406
|
+
)
|
|
335
407
|
|
|
336
408
|
self.logger.info(f"Discovered {len(skills)} bundled PM skills")
|
|
337
409
|
return skills
|
|
338
410
|
|
|
411
|
+
def _get_skills_for_tier(self, tier: str) -> List[str]:
|
|
412
|
+
"""Get list of skills to deploy based on tier.
|
|
413
|
+
|
|
414
|
+
Args:
|
|
415
|
+
tier: Deployment tier - "minimal", "standard", or "full"
|
|
416
|
+
|
|
417
|
+
Returns:
|
|
418
|
+
List of skill names to deploy
|
|
419
|
+
|
|
420
|
+
Raises:
|
|
421
|
+
ValueError: If tier is invalid
|
|
422
|
+
"""
|
|
423
|
+
if tier == "minimal":
|
|
424
|
+
return REQUIRED_PM_SKILLS
|
|
425
|
+
if tier == "standard":
|
|
426
|
+
return REQUIRED_PM_SKILLS + RECOMMENDED_PM_SKILLS
|
|
427
|
+
if tier == "full":
|
|
428
|
+
return REQUIRED_PM_SKILLS + RECOMMENDED_PM_SKILLS + OPTIONAL_PM_SKILLS
|
|
429
|
+
raise ValueError(
|
|
430
|
+
f"Invalid tier '{tier}'. Must be 'minimal', 'standard', or 'full'"
|
|
431
|
+
)
|
|
432
|
+
|
|
339
433
|
def deploy_pm_skills(
|
|
340
434
|
self,
|
|
341
435
|
project_dir: Path,
|
|
342
436
|
force: bool = False,
|
|
437
|
+
tier: str = "standard",
|
|
343
438
|
progress_callback: Optional[Callable[[str, int, int], None]] = None,
|
|
344
439
|
) -> DeploymentResult:
|
|
345
|
-
"""Deploy bundled PM skills to project directory.
|
|
440
|
+
"""Deploy bundled PM skills to project directory with tier-based selection.
|
|
346
441
|
|
|
347
|
-
Copies PM skills from bundled templates to .claude
|
|
442
|
+
Copies PM skills from bundled templates to .claude/skills/{name}/SKILL.md
|
|
348
443
|
and updates registry with version and checksum information.
|
|
349
444
|
|
|
445
|
+
Deployment Tiers:
|
|
446
|
+
- "minimal": Only REQUIRED_PM_SKILLS (Tier 1 - core functionality)
|
|
447
|
+
- "standard": REQUIRED_PM_SKILLS + RECOMMENDED_PM_SKILLS (Tier 1+2 - common workflows)
|
|
448
|
+
- "full": All skills (Tier 1+2+3 - advanced features)
|
|
449
|
+
|
|
450
|
+
Conflict Resolution:
|
|
451
|
+
- mpm-* skills from src WIN (overwrite existing)
|
|
452
|
+
- Non-mpm-* skills in .claude/skills/ are untouched
|
|
453
|
+
|
|
350
454
|
Args:
|
|
351
455
|
project_dir: Project root directory
|
|
352
456
|
force: If True, redeploy even if skill already exists
|
|
457
|
+
tier: Deployment tier - "minimal", "standard" (default), or "full"
|
|
353
458
|
progress_callback: Optional callback(skill_name, current, total) for progress
|
|
354
459
|
|
|
355
460
|
Returns:
|
|
356
461
|
DeploymentResult with deployment status and details
|
|
357
462
|
|
|
358
463
|
Example:
|
|
359
|
-
>>>
|
|
360
|
-
>>>
|
|
464
|
+
>>> # Standard deployment (Tier 1 + Tier 2)
|
|
465
|
+
>>> result = deployer.deploy_pm_skills(Path("/project"))
|
|
466
|
+
>>> print(f"Deployed: {len(result.deployed)} to .claude/skills/")
|
|
467
|
+
>>>
|
|
468
|
+
>>> # Minimal deployment (Tier 1 only)
|
|
469
|
+
>>> result = deployer.deploy_pm_skills(Path("/project"), tier="minimal")
|
|
470
|
+
>>>
|
|
471
|
+
>>> # Full deployment (all tiers)
|
|
472
|
+
>>> result = deployer.deploy_pm_skills(Path("/project"), tier="full")
|
|
361
473
|
"""
|
|
362
|
-
|
|
474
|
+
# Get tier-based skill filter
|
|
475
|
+
try:
|
|
476
|
+
tier_skills = self._get_skills_for_tier(tier)
|
|
477
|
+
except ValueError as e:
|
|
478
|
+
return DeploymentResult(
|
|
479
|
+
success=False,
|
|
480
|
+
deployed=[],
|
|
481
|
+
skipped=[],
|
|
482
|
+
errors=[{"skill": "all", "error": str(e)}],
|
|
483
|
+
message=str(e),
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
# Discover all bundled skills, then filter by tier
|
|
487
|
+
all_skills = self._discover_bundled_pm_skills()
|
|
488
|
+
skills = [s for s in all_skills if s["name"] in tier_skills]
|
|
489
|
+
|
|
490
|
+
self.logger.info(
|
|
491
|
+
f"Deploying {len(skills)}/{len(all_skills)} skills for tier '{tier}'"
|
|
492
|
+
)
|
|
363
493
|
deployed = []
|
|
364
494
|
skipped = []
|
|
365
495
|
errors = []
|
|
@@ -397,12 +527,10 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
397
527
|
deployed_skills = registry.get("skills", [])
|
|
398
528
|
|
|
399
529
|
# Create lookup for existing deployments
|
|
400
|
-
existing_deployments = {
|
|
401
|
-
skill["name"]: skill for skill in deployed_skills
|
|
402
|
-
}
|
|
530
|
+
existing_deployments = {skill["name"]: skill for skill in deployed_skills}
|
|
403
531
|
|
|
404
532
|
new_deployed_skills = []
|
|
405
|
-
timestamp = datetime.
|
|
533
|
+
timestamp = datetime.now(tz=timezone.utc).isoformat()
|
|
406
534
|
total_skills = len(skills)
|
|
407
535
|
|
|
408
536
|
for idx, skill in enumerate(skills):
|
|
@@ -413,7 +541,13 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
413
541
|
# Report progress if callback provided
|
|
414
542
|
if progress_callback:
|
|
415
543
|
progress_callback(skill_name, idx + 1, total_skills)
|
|
416
|
-
|
|
544
|
+
|
|
545
|
+
# Create skill directory: .claude/skills/{skill_name}/
|
|
546
|
+
skill_dir = deployment_dir / skill_name
|
|
547
|
+
skill_dir.mkdir(parents=True, exist_ok=True)
|
|
548
|
+
|
|
549
|
+
# Target path: .claude/skills/{skill_name}/SKILL.md
|
|
550
|
+
target_path = skill_dir / "SKILL.md"
|
|
417
551
|
|
|
418
552
|
# SECURITY: Validate target path
|
|
419
553
|
if not self._validate_safe_path(deployment_dir, target_path):
|
|
@@ -433,7 +567,7 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
433
567
|
)
|
|
434
568
|
continue
|
|
435
569
|
|
|
436
|
-
# Deploy skill
|
|
570
|
+
# Deploy skill (overwrites if exists - mpm-* skills WIN)
|
|
437
571
|
shutil.copy2(source_path, target_path)
|
|
438
572
|
|
|
439
573
|
# Add to deployed list
|
|
@@ -471,7 +605,7 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
471
605
|
|
|
472
606
|
success = len(errors) == 0
|
|
473
607
|
message = (
|
|
474
|
-
f"Deployed {len(deployed)} skills, skipped {len(skipped)}, "
|
|
608
|
+
f"Deployed {len(deployed)} skills (tier: {tier}), skipped {len(skipped)}, "
|
|
475
609
|
f"{len(errors)} errors"
|
|
476
610
|
)
|
|
477
611
|
|
|
@@ -485,75 +619,107 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
485
619
|
message=message,
|
|
486
620
|
)
|
|
487
621
|
|
|
488
|
-
def verify_pm_skills(
|
|
489
|
-
|
|
622
|
+
def verify_pm_skills(
|
|
623
|
+
self, project_dir: Path, auto_repair: bool = True
|
|
624
|
+
) -> VerificationResult:
|
|
625
|
+
"""Verify PM skills are properly deployed with enhanced validation.
|
|
490
626
|
|
|
491
|
-
Checks
|
|
492
|
-
|
|
627
|
+
Checks ALL required PM skills for:
|
|
628
|
+
- Existence in deployment directory
|
|
629
|
+
- File integrity (non-empty, valid checksums)
|
|
630
|
+
- Version currency (compared to bundled source)
|
|
631
|
+
|
|
632
|
+
Auto-repair logic:
|
|
633
|
+
- If auto_repair=True (default), automatically deploys missing/corrupted skills
|
|
634
|
+
- Reports what was fixed in the result
|
|
493
635
|
|
|
494
636
|
Args:
|
|
495
637
|
project_dir: Project root directory
|
|
638
|
+
auto_repair: If True, auto-deploy missing/corrupted skills (default: True)
|
|
496
639
|
|
|
497
640
|
Returns:
|
|
498
|
-
VerificationResult with verification status
|
|
641
|
+
VerificationResult with detailed verification status:
|
|
642
|
+
- verified: True if all required skills are deployed and valid
|
|
643
|
+
- missing_skills: List of required skills not deployed
|
|
644
|
+
- corrupted_skills: List of skills with checksum mismatches
|
|
645
|
+
- warnings: List of warning messages
|
|
646
|
+
- skill_count: Total number of deployed skills
|
|
499
647
|
|
|
500
648
|
Example:
|
|
501
649
|
>>> result = deployer.verify_pm_skills(Path("/project"))
|
|
502
650
|
>>> if not result.verified:
|
|
503
|
-
...
|
|
504
|
-
...
|
|
651
|
+
... print(f"Missing: {result.missing_skills}")
|
|
652
|
+
... print(f"Corrupted: {result.corrupted_skills}")
|
|
505
653
|
"""
|
|
506
654
|
warnings = []
|
|
507
655
|
missing_skills = []
|
|
656
|
+
corrupted_skills = []
|
|
508
657
|
outdated_skills = []
|
|
509
658
|
|
|
510
659
|
# Check if registry exists
|
|
511
660
|
registry = self._load_registry(project_dir)
|
|
512
|
-
if not registry:
|
|
513
|
-
warnings.append("PM skills registry not found or invalid")
|
|
514
|
-
missing_skills.append("all")
|
|
515
|
-
return VerificationResult(
|
|
516
|
-
verified=False,
|
|
517
|
-
warnings=warnings,
|
|
518
|
-
missing_skills=missing_skills,
|
|
519
|
-
outdated_skills=outdated_skills,
|
|
520
|
-
message="PM skills not deployed. Run 'claude-mpm init' to deploy.",
|
|
521
|
-
)
|
|
522
|
-
|
|
523
|
-
# Check each registered skill exists
|
|
524
661
|
deployment_dir = self._get_deployment_dir(project_dir)
|
|
525
|
-
|
|
662
|
+
deployed_skills_data = registry.get("skills", []) if registry else []
|
|
526
663
|
|
|
527
|
-
for
|
|
528
|
-
|
|
529
|
-
skill_file = deployment_dir / f"{skill_name}.md"
|
|
664
|
+
# Build lookup for deployed skills
|
|
665
|
+
deployed_lookup = {skill["name"]: skill for skill in deployed_skills_data}
|
|
530
666
|
|
|
667
|
+
# Check ALL required PM skills
|
|
668
|
+
for required_skill in REQUIRED_PM_SKILLS:
|
|
669
|
+
# Check if skill is in registry
|
|
670
|
+
if required_skill not in deployed_lookup:
|
|
671
|
+
warnings.append(f"Required PM skill missing: {required_skill}")
|
|
672
|
+
missing_skills.append(required_skill)
|
|
673
|
+
continue
|
|
674
|
+
|
|
675
|
+
# Check if skill file exists
|
|
676
|
+
skill_file = deployment_dir / required_skill / "SKILL.md"
|
|
531
677
|
if not skill_file.exists():
|
|
532
|
-
warnings.append(
|
|
533
|
-
|
|
678
|
+
warnings.append(
|
|
679
|
+
f"Required PM skill file missing: {required_skill}/SKILL.md"
|
|
680
|
+
)
|
|
681
|
+
missing_skills.append(required_skill)
|
|
682
|
+
continue
|
|
683
|
+
|
|
684
|
+
# Check if skill file is empty/corrupted
|
|
685
|
+
try:
|
|
686
|
+
file_size = skill_file.stat().st_size
|
|
687
|
+
if file_size == 0:
|
|
688
|
+
warnings.append(
|
|
689
|
+
f"Required PM skill file is empty: {required_skill}/SKILL.md"
|
|
690
|
+
)
|
|
691
|
+
corrupted_skills.append(required_skill)
|
|
692
|
+
continue
|
|
693
|
+
except OSError as e:
|
|
694
|
+
warnings.append(
|
|
695
|
+
f"Cannot read required PM skill file: {required_skill}/SKILL.md - {e}"
|
|
696
|
+
)
|
|
697
|
+
corrupted_skills.append(required_skill)
|
|
534
698
|
continue
|
|
535
699
|
|
|
536
700
|
# Verify checksum
|
|
701
|
+
deployed_skill = deployed_lookup[required_skill]
|
|
537
702
|
current_checksum = self._compute_checksum(skill_file)
|
|
538
|
-
expected_checksum =
|
|
703
|
+
expected_checksum = deployed_skill.get("checksum", "")
|
|
539
704
|
|
|
540
705
|
if current_checksum != expected_checksum:
|
|
541
706
|
warnings.append(
|
|
542
|
-
f"
|
|
707
|
+
f"Required PM skill checksum mismatch: {required_skill} (file may be corrupted)"
|
|
543
708
|
)
|
|
544
|
-
|
|
709
|
+
corrupted_skills.append(required_skill)
|
|
545
710
|
|
|
546
|
-
# Check for available updates
|
|
711
|
+
# Check for available updates (bundled skills newer than deployed)
|
|
547
712
|
bundled_skills = {s["name"]: s for s in self._discover_bundled_pm_skills()}
|
|
548
713
|
for skill_name, bundled_skill in bundled_skills.items():
|
|
714
|
+
# Skip non-required skills
|
|
715
|
+
if skill_name not in REQUIRED_PM_SKILLS:
|
|
716
|
+
continue
|
|
717
|
+
|
|
549
718
|
# Find corresponding deployed skill
|
|
550
|
-
deployed_skill =
|
|
551
|
-
(s for s in deployed_skills if s["name"] == skill_name), None
|
|
552
|
-
)
|
|
719
|
+
deployed_skill = deployed_lookup.get(skill_name)
|
|
553
720
|
|
|
554
721
|
if not deployed_skill:
|
|
555
|
-
|
|
556
|
-
missing_skills.append(skill_name)
|
|
722
|
+
# Already tracked as missing
|
|
557
723
|
continue
|
|
558
724
|
|
|
559
725
|
# Check if checksums differ
|
|
@@ -561,22 +727,66 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
561
727
|
deployed_checksum = deployed_skill.get("checksum", "")
|
|
562
728
|
|
|
563
729
|
if bundled_checksum != deployed_checksum:
|
|
564
|
-
|
|
565
|
-
|
|
730
|
+
# Don't add to outdated_skills if already in corrupted_skills
|
|
731
|
+
if skill_name not in corrupted_skills:
|
|
732
|
+
warnings.append(f"PM skill update available: {skill_name}")
|
|
733
|
+
outdated_skills.append(skill_name)
|
|
734
|
+
|
|
735
|
+
# Auto-repair if enabled and issues found
|
|
736
|
+
repaired_skills = []
|
|
737
|
+
if auto_repair and (missing_skills or corrupted_skills):
|
|
738
|
+
self.logger.info(
|
|
739
|
+
f"Auto-repairing PM skills: {len(missing_skills)} missing, "
|
|
740
|
+
f"{len(corrupted_skills)} corrupted"
|
|
741
|
+
)
|
|
742
|
+
|
|
743
|
+
# Deploy missing and corrupted skills
|
|
744
|
+
repair_result = self.deploy_pm_skills(project_dir, force=True)
|
|
745
|
+
|
|
746
|
+
if repair_result.success:
|
|
747
|
+
repaired_skills = repair_result.deployed
|
|
748
|
+
self.logger.info(f"Auto-repaired {len(repaired_skills)} PM skills")
|
|
566
749
|
|
|
567
|
-
|
|
750
|
+
# Remove repaired skills from missing/corrupted lists
|
|
751
|
+
missing_skills = [s for s in missing_skills if s not in repaired_skills]
|
|
752
|
+
corrupted_skills = [
|
|
753
|
+
s for s in corrupted_skills if s not in repaired_skills
|
|
754
|
+
]
|
|
568
755
|
|
|
756
|
+
# Update warnings
|
|
757
|
+
if repaired_skills:
|
|
758
|
+
warnings.append(
|
|
759
|
+
f"Auto-repaired {len(repaired_skills)} PM skills: {', '.join(repaired_skills)}"
|
|
760
|
+
)
|
|
761
|
+
else:
|
|
762
|
+
warnings.append(
|
|
763
|
+
f"Auto-repair failed: {len(repair_result.errors)} errors"
|
|
764
|
+
)
|
|
765
|
+
self.logger.error(
|
|
766
|
+
f"Auto-repair failed with errors: {repair_result.errors}"
|
|
767
|
+
)
|
|
768
|
+
|
|
769
|
+
# Determine verification status
|
|
770
|
+
verified = len(missing_skills) == 0 and len(corrupted_skills) == 0
|
|
771
|
+
|
|
772
|
+
# Build message
|
|
569
773
|
if verified:
|
|
570
|
-
|
|
774
|
+
if repaired_skills:
|
|
775
|
+
message = f"All PM skills verified (auto-repaired {len(repaired_skills)} skills)"
|
|
776
|
+
else:
|
|
777
|
+
message = "All PM skills verified and up-to-date"
|
|
571
778
|
else:
|
|
572
|
-
|
|
779
|
+
issue_count = len(missing_skills) + len(corrupted_skills)
|
|
780
|
+
message = f"{issue_count} PM skill issues found"
|
|
573
781
|
|
|
574
782
|
return VerificationResult(
|
|
575
783
|
verified=verified,
|
|
576
784
|
warnings=warnings,
|
|
577
785
|
missing_skills=missing_skills,
|
|
786
|
+
corrupted_skills=corrupted_skills,
|
|
578
787
|
outdated_skills=outdated_skills,
|
|
579
788
|
message=message,
|
|
789
|
+
skill_count=len(deployed_skills_data),
|
|
580
790
|
)
|
|
581
791
|
|
|
582
792
|
def get_deployed_skills(self, project_dir: Path) -> List[PMSkillInfo]:
|
|
@@ -599,10 +809,10 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
599
809
|
skills = []
|
|
600
810
|
for skill_data in registry.get("skills", []):
|
|
601
811
|
skill_name = skill_data["name"]
|
|
602
|
-
deployed_path = deployment_dir /
|
|
812
|
+
deployed_path = deployment_dir / skill_name / "SKILL.md"
|
|
603
813
|
|
|
604
814
|
# Find source path (may not exist if bundled skills changed)
|
|
605
|
-
source_path = self.bundled_pm_skills_path /
|
|
815
|
+
source_path = self.bundled_pm_skills_path / skill_name / "SKILL.md"
|
|
606
816
|
|
|
607
817
|
skills.append(
|
|
608
818
|
PMSkillInfo(
|
|
@@ -634,9 +844,7 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
634
844
|
... print(f"{update.skill_name}: {update.current_version} -> {update.new_version}")
|
|
635
845
|
"""
|
|
636
846
|
registry = self._load_registry(project_dir)
|
|
637
|
-
deployed_skills = {
|
|
638
|
-
skill["name"]: skill for skill in registry.get("skills", [])
|
|
639
|
-
}
|
|
847
|
+
deployed_skills = {skill["name"]: skill for skill in registry.get("skills", [])}
|
|
640
848
|
|
|
641
849
|
bundled_skills = self._discover_bundled_pm_skills()
|
|
642
850
|
|
|
@@ -49,7 +49,7 @@ Usage:
|
|
|
49
49
|
|
|
50
50
|
import fnmatch
|
|
51
51
|
from pathlib import Path
|
|
52
|
-
from typing import
|
|
52
|
+
from typing import Any, Dict, Optional, Set
|
|
53
53
|
|
|
54
54
|
import yaml
|
|
55
55
|
|
|
@@ -69,7 +69,9 @@ class ProfileManager:
|
|
|
69
69
|
- Get lists of enabled/disabled entities
|
|
70
70
|
"""
|
|
71
71
|
|
|
72
|
-
def __init__(
|
|
72
|
+
def __init__(
|
|
73
|
+
self, project_dir: Optional[Path] = None, profiles_dir: Optional[Path] = None
|
|
74
|
+
):
|
|
73
75
|
"""
|
|
74
76
|
Initialize ProfileManager.
|
|
75
77
|
|
|
@@ -212,7 +214,9 @@ class ProfileManager:
|
|
|
212
214
|
# Check if skill is explicitly disabled by pattern
|
|
213
215
|
for pattern in self._disabled_skill_patterns:
|
|
214
216
|
if fnmatch.fnmatch(skill_name, pattern):
|
|
215
|
-
logger.debug(
|
|
217
|
+
logger.debug(
|
|
218
|
+
f"Skill '{skill_name}' matched disabled pattern '{pattern}'"
|
|
219
|
+
)
|
|
216
220
|
return False
|
|
217
221
|
|
|
218
222
|
# If enabled list exists, check for match
|
|
@@ -227,7 +231,9 @@ class ProfileManager:
|
|
|
227
231
|
if skill_name.endswith(f"-{short_name}"):
|
|
228
232
|
return True
|
|
229
233
|
# Also check if short name is contained as a segment
|
|
230
|
-
if f"-{short_name}-" in skill_name or skill_name.startswith(
|
|
234
|
+
if f"-{short_name}-" in skill_name or skill_name.startswith(
|
|
235
|
+
f"{short_name}-"
|
|
236
|
+
):
|
|
231
237
|
return True
|
|
232
238
|
|
|
233
239
|
return False
|