claude-mpm 5.4.55__py3-none-any.whl → 5.6.1__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.
- 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 +111 -686
- claude_mpm/agents/WORKFLOW.md +2 -0
- claude_mpm/agents/templates/circuit-breakers.md +26 -17
- 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 +46 -0
- claude_mpm/cli/commands/configure.py +620 -21
- 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 +2 -2
- claude_mpm/cli/commands/run.py +35 -3
- claude_mpm/cli/commands/skills.py +166 -14
- claude_mpm/cli/executor.py +120 -16
- 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 +76 -1
- claude_mpm/cli/parsers/commander_parser.py +83 -0
- claude_mpm/cli/parsers/run_parser.py +10 -0
- claude_mpm/cli/startup.py +276 -403
- claude_mpm/cli/startup_display.py +72 -5
- claude_mpm/cli/startup_logging.py +2 -2
- claude_mpm/cli/utils.py +7 -3
- claude_mpm/commander/__init__.py +72 -0
- claude_mpm/commander/adapters/__init__.py +31 -0
- claude_mpm/commander/adapters/base.py +191 -0
- claude_mpm/commander/adapters/claude_code.py +361 -0
- claude_mpm/commander/adapters/communication.py +366 -0
- claude_mpm/commander/api/__init__.py +16 -0
- claude_mpm/commander/api/app.py +105 -0
- claude_mpm/commander/api/errors.py +112 -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 +215 -0
- claude_mpm/commander/api/routes/work.py +260 -0
- claude_mpm/commander/api/schemas.py +182 -0
- claude_mpm/commander/chat/__init__.py +7 -0
- claude_mpm/commander/chat/cli.py +107 -0
- claude_mpm/commander/chat/commands.py +96 -0
- claude_mpm/commander/chat/repl.py +310 -0
- claude_mpm/commander/config.py +49 -0
- claude_mpm/commander/config_loader.py +115 -0
- claude_mpm/commander/daemon.py +398 -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 +143 -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 +337 -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/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 +404 -0
- claude_mpm/commander/runtime/__init__.py +10 -0
- claude_mpm/commander/runtime/executor.py +191 -0
- claude_mpm/commander/runtime/monitor.py +316 -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 +189 -0
- claude_mpm/commander/work/queue.py +405 -0
- claude_mpm/commander/workflow/__init__.py +27 -0
- claude_mpm/commander/workflow/event_handler.py +219 -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/constants.py +1 -0
- claude_mpm/core/claude_runner.py +2 -2
- claude_mpm/core/config.py +5 -0
- claude_mpm/core/hook_manager.py +51 -3
- claude_mpm/core/interactive_session.py +7 -7
- claude_mpm/core/logger.py +10 -7
- claude_mpm/core/logging_utils.py +4 -2
- claude_mpm/core/output_style_manager.py +31 -13
- claude_mpm/core/unified_config.py +54 -8
- claude_mpm/core/unified_paths.py +30 -13
- 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/{Cs_tUR18.js → 1WZnGYqX.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CDuw-vjf.js → 67pF3qNn.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bTOqqlTd.js → 6RxdMKe4.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DwBR2MJi.js → 8cZrfX0h.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{ZGh7QtNv.js → 9a6T2nm-.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D9lljYKQ.js → B443AUzu.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{RJiighC3.js → B8AwtY2H.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uuIeMWc-.js → BF15LAsF.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{D3k0OPJN.js → BRcwIQNr.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CyWMqx4W.js → BV6nKitt.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CiIAseT4.js → BViJ8lZt.js} +5 -5
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CBBdVcY8.js → BcQ-Q0FE.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BovzEFCE.js → Bpyvgze_.js} +1 -1
- 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/{eNVUfhuA.js → C3rbW_a-.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{GYwsonyD.js → C8WYN38h.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BIF9m_hv.js → C9I8FlXH.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B0uc0UOD.js → CIQcWgO2.js} +3 -3
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Be7GpZd6.js → CIctN7YN.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Bh0LDWpI.js → CKrS_JZW.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DUrLdbGD.js → CR6P9C4A.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7xVLGWV.js → CRRR9MD_.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dhb8PKl3.js → CSXtMOf0.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BPYeabCQ.js → CT-sbxSk.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{sQeU3Y1z.js → CWm6DJsp.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CnA0NrzZ.js → CpqQ1Kzn.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4B-KCzX.js → D2nGpDRe.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DGkLK5U1.js → D9iCMida.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{BofRWZRR.js → D9ykgMoY.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DmxopI1J.js → DL2Ldur1.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C30mlcqg.js → DPfltzjH.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Vzk33B_K.js → DR8nis88.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DI7hHRFL.js → DUliQN2b.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C4JcI4KD.js → DXlhR01x.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{bT1r9zLR.js → D_lyTybS.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DZX00Y4g.js → DngoTTgh.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzZX-COe.js → DqkmHtDC.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{B7RN905-.js → DsDh8EYs.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DLVjFsZ3.js → DypDmXgd.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{iEWssX7S.js → IPYC-LnN.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DaimHw_p.js → JpevfAFt.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DY1XQ8fi.js → R8CEIRAd.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Dle-35c7.js → Zxy7qc-l.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{C_Usid8X.js → qtd3IeO4.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CzeYkLYB.js → ulBFON_C.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{Cfqx1Qun.js → wQVh1CoA.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/{app.D6-I5TpK.js → app.Dr7t0z2J.js} +2 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.m1gL8KXf.js → 0.RgBboRvH.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{1.CgNOuw-d.js → 1.DG-KkbDf.js} +1 -1
- 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 +9 -9
- 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/auto_pause_handler.py +486 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +250 -11
- claude_mpm/hooks/claude_hooks/hook_handler.py +106 -89
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
- claude_mpm/hooks/claude_hooks/installer.py +69 -5
- claude_mpm/hooks/claude_hooks/response_tracking.py +3 -1
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +20 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +14 -77
- claude_mpm/hooks/claude_hooks/services/subagent_processor.py +30 -6
- claude_mpm/hooks/session_resume_hook.py +85 -1
- claude_mpm/init.py +1 -1
- claude_mpm/scripts/claude-hook-handler.sh +36 -10
- claude_mpm/scripts/start_activity_logging.py +0 -0
- claude_mpm/services/agents/agent_recommendation_service.py +8 -8
- claude_mpm/services/agents/cache_git_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_template_builder.py +8 -0
- claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +3 -0
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
- claude_mpm/services/agents/sources/git_source_sync_service.py +7 -4
- 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/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/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 +8 -2
- claude_mpm/services/monitor/server.py +106 -16
- claude_mpm/services/pm_skills_deployer.py +261 -85
- claude_mpm/services/skills/git_skill_source_manager.py +75 -10
- claude_mpm/services/skills/selective_skill_deployer.py +177 -80
- claude_mpm/services/skills/skill_discovery_service.py +57 -3
- claude_mpm/services/socketio/handlers/hook.py +14 -7
- claude_mpm/services/socketio/server/main.py +12 -4
- 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-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/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/skill_manager.py +4 -4
- claude_mpm/utils/agent_dependency_loader.py +103 -4
- claude_mpm/utils/robust_installer.py +45 -24
- claude_mpm-5.6.1.dist-info/METADATA +391 -0
- {claude_mpm-5.4.55.dist-info → claude_mpm-5.6.1.dist-info}/RECORD +377 -166
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/4TdZjIqw.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +0 -24
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +0 -323
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +0 -1
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.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__/installer.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/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__/duplicate_detector.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-5.4.55.dist-info/METADATA +0 -999
- {claude_mpm-5.4.55.dist-info → claude_mpm-5.6.1.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.55.dist-info → claude_mpm-5.6.1.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.55.dist-info → claude_mpm-5.6.1.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.55.dist-info → claude_mpm-5.6.1.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.55.dist-info → claude_mpm-5.6.1.dist-info}/top_level.txt +0 -0
|
@@ -1,27 +1,30 @@
|
|
|
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
|
|
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)
|
|
9
11
|
- Uses package-relative paths (works for both installed and dev mode)
|
|
10
|
-
- Supports
|
|
11
|
-
|
|
12
|
-
2. Flat files: skill-name.md (legacy format in .claude-mpm/templates/)
|
|
13
|
-
- Per-project deployment (NOT global like Claude Code skills)
|
|
12
|
+
- Supports directory structure: mpm-skill-name/SKILL.md
|
|
13
|
+
- Per-project deployment to .claude/skills/ (Claude Code location)
|
|
14
14
|
- Version tracking via .claude-mpm/pm_skills_registry.yaml
|
|
15
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)
|
|
16
18
|
- Non-blocking verification (returns warnings, doesn't halt execution)
|
|
17
19
|
- Force flag to redeploy even if versions match
|
|
18
20
|
|
|
19
21
|
ARCHITECTURE:
|
|
20
22
|
1. Discovery: Find bundled PM skills in package (skills/bundled/pm/)
|
|
21
|
-
2. Deployment: Copy SKILL.md files to .claude
|
|
22
|
-
3.
|
|
23
|
-
4.
|
|
24
|
-
5.
|
|
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
|
|
25
28
|
|
|
26
29
|
PATH RESOLUTION:
|
|
27
30
|
- Installed package: Uses __file__ to find skills/bundled/pm/
|
|
@@ -47,6 +50,46 @@ from claude_mpm.core.mixins import LoggerMixin
|
|
|
47
50
|
# Security constants
|
|
48
51
|
MAX_YAML_SIZE = 10 * 1024 * 1024 # 10MB limit to prevent YAML bombs
|
|
49
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
|
+
|
|
50
93
|
|
|
51
94
|
@dataclass
|
|
52
95
|
class PMSkillInfo:
|
|
@@ -96,15 +139,19 @@ class VerificationResult:
|
|
|
96
139
|
verified: Whether all skills are properly deployed
|
|
97
140
|
warnings: List of warning messages
|
|
98
141
|
missing_skills: List of missing skill names
|
|
142
|
+
corrupted_skills: List of corrupted skill names (checksum mismatch)
|
|
99
143
|
outdated_skills: List of outdated skill names
|
|
100
144
|
message: Summary message
|
|
145
|
+
skill_count: Total number of deployed skills
|
|
101
146
|
"""
|
|
102
147
|
|
|
103
148
|
verified: bool
|
|
104
149
|
warnings: List[str]
|
|
105
150
|
missing_skills: List[str]
|
|
151
|
+
corrupted_skills: List[str]
|
|
106
152
|
outdated_skills: List[str]
|
|
107
153
|
message: str
|
|
154
|
+
skill_count: int = 0
|
|
108
155
|
|
|
109
156
|
|
|
110
157
|
@dataclass
|
|
@@ -128,8 +175,9 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
128
175
|
"""Deploy and manage PM skills from bundled sources to projects.
|
|
129
176
|
|
|
130
177
|
This service provides:
|
|
131
|
-
- Discovery of bundled PM skills (
|
|
132
|
-
- 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)
|
|
133
181
|
- Version tracking via pm_skills_registry.yaml
|
|
134
182
|
- Checksum validation for integrity
|
|
135
183
|
- Non-blocking verification (warnings only)
|
|
@@ -138,7 +186,7 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
138
186
|
Example:
|
|
139
187
|
>>> deployer = PMSkillsDeployerService()
|
|
140
188
|
>>> result = deployer.deploy_pm_skills(Path("/project/root"))
|
|
141
|
-
>>> print(f"Deployed {len(result.deployed)} skills")
|
|
189
|
+
>>> print(f"Deployed {len(result.deployed)} skills to .claude/skills/")
|
|
142
190
|
>>>
|
|
143
191
|
>>> verify_result = deployer.verify_pm_skills(Path("/project/root"))
|
|
144
192
|
>>> if not verify_result.verified:
|
|
@@ -244,9 +292,9 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
244
292
|
project_dir: Project root directory
|
|
245
293
|
|
|
246
294
|
Returns:
|
|
247
|
-
Path to .claude
|
|
295
|
+
Path to .claude/skills/
|
|
248
296
|
"""
|
|
249
|
-
return project_dir / ".claude
|
|
297
|
+
return project_dir / ".claude" / "skills"
|
|
250
298
|
|
|
251
299
|
def _load_registry(self, project_dir: Path) -> Dict[str, Any]:
|
|
252
300
|
"""Load PM skills registry with security checks.
|
|
@@ -320,14 +368,12 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
320
368
|
def _discover_bundled_pm_skills(self) -> List[Dict[str, Any]]:
|
|
321
369
|
"""Discover all PM skills in bundled templates directory.
|
|
322
370
|
|
|
323
|
-
PM skills
|
|
324
|
-
1. Directory structure: pm-skill-name/SKILL.md (new format)
|
|
325
|
-
2. Flat files: skill-name.md (legacy format for .claude-mpm/templates/)
|
|
371
|
+
PM skills follow mpm-skill-name/SKILL.md structure.
|
|
326
372
|
|
|
327
373
|
Returns:
|
|
328
374
|
List of skill dictionaries containing:
|
|
329
|
-
- name: Skill name (directory
|
|
330
|
-
- path: Full path to skill file (SKILL.md
|
|
375
|
+
- name: Skill name (directory name, e.g., mpm-git-file-tracking)
|
|
376
|
+
- path: Full path to skill file (SKILL.md)
|
|
331
377
|
- type: File type (always 'md')
|
|
332
378
|
"""
|
|
333
379
|
skills = []
|
|
@@ -338,11 +384,16 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
338
384
|
)
|
|
339
385
|
return skills
|
|
340
386
|
|
|
341
|
-
# Scan for skill directories containing SKILL.md
|
|
387
|
+
# Scan for skill directories containing SKILL.md
|
|
342
388
|
for skill_dir in self.bundled_pm_skills_path.iterdir():
|
|
343
389
|
if not skill_dir.is_dir() or skill_dir.name.startswith("."):
|
|
344
390
|
continue
|
|
345
391
|
|
|
392
|
+
# Only process mpm-* skills (framework management)
|
|
393
|
+
if not skill_dir.name.startswith("mpm-"):
|
|
394
|
+
self.logger.debug(f"Skipping non-mpm skill: {skill_dir.name}")
|
|
395
|
+
continue
|
|
396
|
+
|
|
346
397
|
skill_file = skill_dir / "SKILL.md"
|
|
347
398
|
if skill_file.exists():
|
|
348
399
|
skills.append(
|
|
@@ -353,46 +404,91 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
353
404
|
}
|
|
354
405
|
)
|
|
355
406
|
|
|
356
|
-
# Fallback: Scan for .md files directly (legacy format)
|
|
357
|
-
for skill_file in self.bundled_pm_skills_path.glob("*.md"):
|
|
358
|
-
if skill_file.name.startswith("."):
|
|
359
|
-
continue
|
|
360
|
-
|
|
361
|
-
skills.append(
|
|
362
|
-
{
|
|
363
|
-
"name": skill_file.stem,
|
|
364
|
-
"path": skill_file,
|
|
365
|
-
"type": "md",
|
|
366
|
-
}
|
|
367
|
-
)
|
|
368
|
-
|
|
369
407
|
self.logger.info(f"Discovered {len(skills)} bundled PM skills")
|
|
370
408
|
return skills
|
|
371
409
|
|
|
410
|
+
def _get_skills_for_tier(self, tier: str) -> List[str]:
|
|
411
|
+
"""Get list of skills to deploy based on tier.
|
|
412
|
+
|
|
413
|
+
Args:
|
|
414
|
+
tier: Deployment tier - "minimal", "standard", or "full"
|
|
415
|
+
|
|
416
|
+
Returns:
|
|
417
|
+
List of skill names to deploy
|
|
418
|
+
|
|
419
|
+
Raises:
|
|
420
|
+
ValueError: If tier is invalid
|
|
421
|
+
"""
|
|
422
|
+
if tier == "minimal":
|
|
423
|
+
return REQUIRED_PM_SKILLS
|
|
424
|
+
if tier == "standard":
|
|
425
|
+
return REQUIRED_PM_SKILLS + RECOMMENDED_PM_SKILLS
|
|
426
|
+
if tier == "full":
|
|
427
|
+
return REQUIRED_PM_SKILLS + RECOMMENDED_PM_SKILLS + OPTIONAL_PM_SKILLS
|
|
428
|
+
raise ValueError(
|
|
429
|
+
f"Invalid tier '{tier}'. Must be 'minimal', 'standard', or 'full'"
|
|
430
|
+
)
|
|
431
|
+
|
|
372
432
|
def deploy_pm_skills(
|
|
373
433
|
self,
|
|
374
434
|
project_dir: Path,
|
|
375
435
|
force: bool = False,
|
|
436
|
+
tier: str = "standard",
|
|
376
437
|
progress_callback: Optional[Callable[[str, int, int], None]] = None,
|
|
377
438
|
) -> DeploymentResult:
|
|
378
|
-
"""Deploy bundled PM skills to project directory.
|
|
439
|
+
"""Deploy bundled PM skills to project directory with tier-based selection.
|
|
379
440
|
|
|
380
|
-
Copies PM skills from bundled templates to .claude
|
|
441
|
+
Copies PM skills from bundled templates to .claude/skills/{name}/SKILL.md
|
|
381
442
|
and updates registry with version and checksum information.
|
|
382
443
|
|
|
444
|
+
Deployment Tiers:
|
|
445
|
+
- "minimal": Only REQUIRED_PM_SKILLS (Tier 1 - core functionality)
|
|
446
|
+
- "standard": REQUIRED_PM_SKILLS + RECOMMENDED_PM_SKILLS (Tier 1+2 - common workflows)
|
|
447
|
+
- "full": All skills (Tier 1+2+3 - advanced features)
|
|
448
|
+
|
|
449
|
+
Conflict Resolution:
|
|
450
|
+
- mpm-* skills from src WIN (overwrite existing)
|
|
451
|
+
- Non-mpm-* skills in .claude/skills/ are untouched
|
|
452
|
+
|
|
383
453
|
Args:
|
|
384
454
|
project_dir: Project root directory
|
|
385
455
|
force: If True, redeploy even if skill already exists
|
|
456
|
+
tier: Deployment tier - "minimal", "standard" (default), or "full"
|
|
386
457
|
progress_callback: Optional callback(skill_name, current, total) for progress
|
|
387
458
|
|
|
388
459
|
Returns:
|
|
389
460
|
DeploymentResult with deployment status and details
|
|
390
461
|
|
|
391
462
|
Example:
|
|
392
|
-
>>>
|
|
393
|
-
>>>
|
|
463
|
+
>>> # Standard deployment (Tier 1 + Tier 2)
|
|
464
|
+
>>> result = deployer.deploy_pm_skills(Path("/project"))
|
|
465
|
+
>>> print(f"Deployed: {len(result.deployed)} to .claude/skills/")
|
|
466
|
+
>>>
|
|
467
|
+
>>> # Minimal deployment (Tier 1 only)
|
|
468
|
+
>>> result = deployer.deploy_pm_skills(Path("/project"), tier="minimal")
|
|
469
|
+
>>>
|
|
470
|
+
>>> # Full deployment (all tiers)
|
|
471
|
+
>>> result = deployer.deploy_pm_skills(Path("/project"), tier="full")
|
|
394
472
|
"""
|
|
395
|
-
|
|
473
|
+
# Get tier-based skill filter
|
|
474
|
+
try:
|
|
475
|
+
tier_skills = self._get_skills_for_tier(tier)
|
|
476
|
+
except ValueError as e:
|
|
477
|
+
return DeploymentResult(
|
|
478
|
+
success=False,
|
|
479
|
+
deployed=[],
|
|
480
|
+
skipped=[],
|
|
481
|
+
errors=[{"skill": "all", "error": str(e)}],
|
|
482
|
+
message=str(e),
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
# Discover all bundled skills, then filter by tier
|
|
486
|
+
all_skills = self._discover_bundled_pm_skills()
|
|
487
|
+
skills = [s for s in all_skills if s["name"] in tier_skills]
|
|
488
|
+
|
|
489
|
+
self.logger.info(
|
|
490
|
+
f"Deploying {len(skills)}/{len(all_skills)} skills for tier '{tier}'"
|
|
491
|
+
)
|
|
396
492
|
deployed = []
|
|
397
493
|
skipped = []
|
|
398
494
|
errors = []
|
|
@@ -445,8 +541,12 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
445
541
|
if progress_callback:
|
|
446
542
|
progress_callback(skill_name, idx + 1, total_skills)
|
|
447
543
|
|
|
448
|
-
#
|
|
449
|
-
|
|
544
|
+
# Create skill directory: .claude/skills/{skill_name}/
|
|
545
|
+
skill_dir = deployment_dir / skill_name
|
|
546
|
+
skill_dir.mkdir(parents=True, exist_ok=True)
|
|
547
|
+
|
|
548
|
+
# Target path: .claude/skills/{skill_name}/SKILL.md
|
|
549
|
+
target_path = skill_dir / "SKILL.md"
|
|
450
550
|
|
|
451
551
|
# SECURITY: Validate target path
|
|
452
552
|
if not self._validate_safe_path(deployment_dir, target_path):
|
|
@@ -466,7 +566,7 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
466
566
|
)
|
|
467
567
|
continue
|
|
468
568
|
|
|
469
|
-
# Deploy skill
|
|
569
|
+
# Deploy skill (overwrites if exists - mpm-* skills WIN)
|
|
470
570
|
shutil.copy2(source_path, target_path)
|
|
471
571
|
|
|
472
572
|
# Add to deployed list
|
|
@@ -504,7 +604,7 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
504
604
|
|
|
505
605
|
success = len(errors) == 0
|
|
506
606
|
message = (
|
|
507
|
-
f"Deployed {len(deployed)} skills, skipped {len(skipped)}, "
|
|
607
|
+
f"Deployed {len(deployed)} skills (tier: {tier}), skipped {len(skipped)}, "
|
|
508
608
|
f"{len(errors)} errors"
|
|
509
609
|
)
|
|
510
610
|
|
|
@@ -518,75 +618,107 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
518
618
|
message=message,
|
|
519
619
|
)
|
|
520
620
|
|
|
521
|
-
def verify_pm_skills(
|
|
522
|
-
|
|
621
|
+
def verify_pm_skills(
|
|
622
|
+
self, project_dir: Path, auto_repair: bool = True
|
|
623
|
+
) -> VerificationResult:
|
|
624
|
+
"""Verify PM skills are properly deployed with enhanced validation.
|
|
523
625
|
|
|
524
|
-
Checks
|
|
525
|
-
|
|
626
|
+
Checks ALL required PM skills for:
|
|
627
|
+
- Existence in deployment directory
|
|
628
|
+
- File integrity (non-empty, valid checksums)
|
|
629
|
+
- Version currency (compared to bundled source)
|
|
630
|
+
|
|
631
|
+
Auto-repair logic:
|
|
632
|
+
- If auto_repair=True (default), automatically deploys missing/corrupted skills
|
|
633
|
+
- Reports what was fixed in the result
|
|
526
634
|
|
|
527
635
|
Args:
|
|
528
636
|
project_dir: Project root directory
|
|
637
|
+
auto_repair: If True, auto-deploy missing/corrupted skills (default: True)
|
|
529
638
|
|
|
530
639
|
Returns:
|
|
531
|
-
VerificationResult with verification status
|
|
640
|
+
VerificationResult with detailed verification status:
|
|
641
|
+
- verified: True if all required skills are deployed and valid
|
|
642
|
+
- missing_skills: List of required skills not deployed
|
|
643
|
+
- corrupted_skills: List of skills with checksum mismatches
|
|
644
|
+
- warnings: List of warning messages
|
|
645
|
+
- skill_count: Total number of deployed skills
|
|
532
646
|
|
|
533
647
|
Example:
|
|
534
648
|
>>> result = deployer.verify_pm_skills(Path("/project"))
|
|
535
649
|
>>> if not result.verified:
|
|
536
|
-
...
|
|
537
|
-
...
|
|
650
|
+
... print(f"Missing: {result.missing_skills}")
|
|
651
|
+
... print(f"Corrupted: {result.corrupted_skills}")
|
|
538
652
|
"""
|
|
539
653
|
warnings = []
|
|
540
654
|
missing_skills = []
|
|
655
|
+
corrupted_skills = []
|
|
541
656
|
outdated_skills = []
|
|
542
657
|
|
|
543
658
|
# Check if registry exists
|
|
544
659
|
registry = self._load_registry(project_dir)
|
|
545
|
-
if not registry:
|
|
546
|
-
warnings.append("PM skills registry not found or invalid")
|
|
547
|
-
missing_skills.append("all")
|
|
548
|
-
return VerificationResult(
|
|
549
|
-
verified=False,
|
|
550
|
-
warnings=warnings,
|
|
551
|
-
missing_skills=missing_skills,
|
|
552
|
-
outdated_skills=outdated_skills,
|
|
553
|
-
message="PM skills not deployed. Run 'claude-mpm init' to deploy.",
|
|
554
|
-
)
|
|
555
|
-
|
|
556
|
-
# Check each registered skill exists
|
|
557
660
|
deployment_dir = self._get_deployment_dir(project_dir)
|
|
558
|
-
|
|
661
|
+
deployed_skills_data = registry.get("skills", []) if registry else []
|
|
559
662
|
|
|
560
|
-
for
|
|
561
|
-
|
|
562
|
-
skill_file = deployment_dir / f"{skill_name}.md"
|
|
663
|
+
# Build lookup for deployed skills
|
|
664
|
+
deployed_lookup = {skill["name"]: skill for skill in deployed_skills_data}
|
|
563
665
|
|
|
666
|
+
# Check ALL required PM skills
|
|
667
|
+
for required_skill in REQUIRED_PM_SKILLS:
|
|
668
|
+
# Check if skill is in registry
|
|
669
|
+
if required_skill not in deployed_lookup:
|
|
670
|
+
warnings.append(f"Required PM skill missing: {required_skill}")
|
|
671
|
+
missing_skills.append(required_skill)
|
|
672
|
+
continue
|
|
673
|
+
|
|
674
|
+
# Check if skill file exists
|
|
675
|
+
skill_file = deployment_dir / required_skill / "SKILL.md"
|
|
564
676
|
if not skill_file.exists():
|
|
565
|
-
warnings.append(
|
|
566
|
-
|
|
677
|
+
warnings.append(
|
|
678
|
+
f"Required PM skill file missing: {required_skill}/SKILL.md"
|
|
679
|
+
)
|
|
680
|
+
missing_skills.append(required_skill)
|
|
681
|
+
continue
|
|
682
|
+
|
|
683
|
+
# Check if skill file is empty/corrupted
|
|
684
|
+
try:
|
|
685
|
+
file_size = skill_file.stat().st_size
|
|
686
|
+
if file_size == 0:
|
|
687
|
+
warnings.append(
|
|
688
|
+
f"Required PM skill file is empty: {required_skill}/SKILL.md"
|
|
689
|
+
)
|
|
690
|
+
corrupted_skills.append(required_skill)
|
|
691
|
+
continue
|
|
692
|
+
except OSError as e:
|
|
693
|
+
warnings.append(
|
|
694
|
+
f"Cannot read required PM skill file: {required_skill}/SKILL.md - {e}"
|
|
695
|
+
)
|
|
696
|
+
corrupted_skills.append(required_skill)
|
|
567
697
|
continue
|
|
568
698
|
|
|
569
699
|
# Verify checksum
|
|
700
|
+
deployed_skill = deployed_lookup[required_skill]
|
|
570
701
|
current_checksum = self._compute_checksum(skill_file)
|
|
571
|
-
expected_checksum =
|
|
702
|
+
expected_checksum = deployed_skill.get("checksum", "")
|
|
572
703
|
|
|
573
704
|
if current_checksum != expected_checksum:
|
|
574
705
|
warnings.append(
|
|
575
|
-
f"
|
|
706
|
+
f"Required PM skill checksum mismatch: {required_skill} (file may be corrupted)"
|
|
576
707
|
)
|
|
577
|
-
|
|
708
|
+
corrupted_skills.append(required_skill)
|
|
578
709
|
|
|
579
|
-
# Check for available updates
|
|
710
|
+
# Check for available updates (bundled skills newer than deployed)
|
|
580
711
|
bundled_skills = {s["name"]: s for s in self._discover_bundled_pm_skills()}
|
|
581
712
|
for skill_name, bundled_skill in bundled_skills.items():
|
|
713
|
+
# Skip non-required skills
|
|
714
|
+
if skill_name not in REQUIRED_PM_SKILLS:
|
|
715
|
+
continue
|
|
716
|
+
|
|
582
717
|
# Find corresponding deployed skill
|
|
583
|
-
deployed_skill =
|
|
584
|
-
(s for s in deployed_skills if s["name"] == skill_name), None
|
|
585
|
-
)
|
|
718
|
+
deployed_skill = deployed_lookup.get(skill_name)
|
|
586
719
|
|
|
587
720
|
if not deployed_skill:
|
|
588
|
-
|
|
589
|
-
missing_skills.append(skill_name)
|
|
721
|
+
# Already tracked as missing
|
|
590
722
|
continue
|
|
591
723
|
|
|
592
724
|
# Check if checksums differ
|
|
@@ -594,22 +726,66 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
594
726
|
deployed_checksum = deployed_skill.get("checksum", "")
|
|
595
727
|
|
|
596
728
|
if bundled_checksum != deployed_checksum:
|
|
597
|
-
|
|
598
|
-
|
|
729
|
+
# Don't add to outdated_skills if already in corrupted_skills
|
|
730
|
+
if skill_name not in corrupted_skills:
|
|
731
|
+
warnings.append(f"PM skill update available: {skill_name}")
|
|
732
|
+
outdated_skills.append(skill_name)
|
|
733
|
+
|
|
734
|
+
# Auto-repair if enabled and issues found
|
|
735
|
+
repaired_skills = []
|
|
736
|
+
if auto_repair and (missing_skills or corrupted_skills):
|
|
737
|
+
self.logger.info(
|
|
738
|
+
f"Auto-repairing PM skills: {len(missing_skills)} missing, "
|
|
739
|
+
f"{len(corrupted_skills)} corrupted"
|
|
740
|
+
)
|
|
741
|
+
|
|
742
|
+
# Deploy missing and corrupted skills
|
|
743
|
+
repair_result = self.deploy_pm_skills(project_dir, force=True)
|
|
744
|
+
|
|
745
|
+
if repair_result.success:
|
|
746
|
+
repaired_skills = repair_result.deployed
|
|
747
|
+
self.logger.info(f"Auto-repaired {len(repaired_skills)} PM skills")
|
|
748
|
+
|
|
749
|
+
# Remove repaired skills from missing/corrupted lists
|
|
750
|
+
missing_skills = [s for s in missing_skills if s not in repaired_skills]
|
|
751
|
+
corrupted_skills = [
|
|
752
|
+
s for s in corrupted_skills if s not in repaired_skills
|
|
753
|
+
]
|
|
754
|
+
|
|
755
|
+
# Update warnings
|
|
756
|
+
if repaired_skills:
|
|
757
|
+
warnings.append(
|
|
758
|
+
f"Auto-repaired {len(repaired_skills)} PM skills: {', '.join(repaired_skills)}"
|
|
759
|
+
)
|
|
760
|
+
else:
|
|
761
|
+
warnings.append(
|
|
762
|
+
f"Auto-repair failed: {len(repair_result.errors)} errors"
|
|
763
|
+
)
|
|
764
|
+
self.logger.error(
|
|
765
|
+
f"Auto-repair failed with errors: {repair_result.errors}"
|
|
766
|
+
)
|
|
599
767
|
|
|
600
|
-
|
|
768
|
+
# Determine verification status
|
|
769
|
+
verified = len(missing_skills) == 0 and len(corrupted_skills) == 0
|
|
601
770
|
|
|
771
|
+
# Build message
|
|
602
772
|
if verified:
|
|
603
|
-
|
|
773
|
+
if repaired_skills:
|
|
774
|
+
message = f"All PM skills verified (auto-repaired {len(repaired_skills)} skills)"
|
|
775
|
+
else:
|
|
776
|
+
message = "All PM skills verified and up-to-date"
|
|
604
777
|
else:
|
|
605
|
-
|
|
778
|
+
issue_count = len(missing_skills) + len(corrupted_skills)
|
|
779
|
+
message = f"{issue_count} PM skill issues found"
|
|
606
780
|
|
|
607
781
|
return VerificationResult(
|
|
608
782
|
verified=verified,
|
|
609
783
|
warnings=warnings,
|
|
610
784
|
missing_skills=missing_skills,
|
|
785
|
+
corrupted_skills=corrupted_skills,
|
|
611
786
|
outdated_skills=outdated_skills,
|
|
612
787
|
message=message,
|
|
788
|
+
skill_count=len(deployed_skills_data),
|
|
613
789
|
)
|
|
614
790
|
|
|
615
791
|
def get_deployed_skills(self, project_dir: Path) -> List[PMSkillInfo]:
|
|
@@ -632,10 +808,10 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
632
808
|
skills = []
|
|
633
809
|
for skill_data in registry.get("skills", []):
|
|
634
810
|
skill_name = skill_data["name"]
|
|
635
|
-
deployed_path = deployment_dir /
|
|
811
|
+
deployed_path = deployment_dir / skill_name / "SKILL.md"
|
|
636
812
|
|
|
637
813
|
# Find source path (may not exist if bundled skills changed)
|
|
638
|
-
source_path = self.bundled_pm_skills_path /
|
|
814
|
+
source_path = self.bundled_pm_skills_path / skill_name / "SKILL.md"
|
|
639
815
|
|
|
640
816
|
skills.append(
|
|
641
817
|
PMSkillInfo(
|