claude-mpm 5.4.36__py3-none-any.whl → 5.4.62__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_TEACHER_OUTPUT_STYLE.md +5 -0
- claude_mpm/agents/PM_INSTRUCTIONS.md +489 -177
- claude_mpm/agents/base_agent.json +1 -1
- claude_mpm/agents/frontmatter_validator.py +2 -2
- claude_mpm/cli/commands/configure_agent_display.py +12 -0
- claude_mpm/cli/commands/mpm_init/core.py +72 -0
- claude_mpm/cli/commands/profile.py +276 -0
- claude_mpm/cli/commands/skills.py +14 -18
- claude_mpm/cli/executor.py +10 -0
- claude_mpm/cli/parsers/base_parser.py +7 -0
- claude_mpm/cli/parsers/profile_parser.py +147 -0
- claude_mpm/cli/parsers/skills_parser.py +0 -6
- claude_mpm/cli/startup.py +433 -147
- claude_mpm/commands/mpm-config.md +13 -250
- claude_mpm/commands/mpm-doctor.md +9 -22
- claude_mpm/commands/mpm-help.md +5 -206
- claude_mpm/commands/mpm-init.md +81 -507
- claude_mpm/commands/mpm-monitor.md +15 -402
- claude_mpm/commands/mpm-organize.md +61 -441
- claude_mpm/commands/mpm-postmortem.md +6 -108
- claude_mpm/commands/mpm-session-resume.md +12 -363
- claude_mpm/commands/mpm-status.md +5 -69
- claude_mpm/commands/mpm-ticket-view.md +52 -495
- claude_mpm/commands/mpm-version.md +5 -107
- claude_mpm/core/optimized_startup.py +61 -0
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CWc5urbQ.js → 4TdZjIqw.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.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/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -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/RJiighC3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{N4qtv3Hx.js → Vzk33B_K.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.CAGBuiOw.js → 0.m1gL8KXf.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
- claude_mpm/dashboard/static/svelte-build/index.html +10 -10
- 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/hooks/kuzu_memory_hook.py +5 -5
- claude_mpm/init.py +276 -0
- claude_mpm/services/agents/agent_builder.py +3 -3
- claude_mpm/services/agents/deployment/agent_deployment.py +22 -0
- 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/local_template_deployment.py +3 -1
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +149 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +47 -26
- claude_mpm/services/agents/git_source_manager.py +21 -2
- claude_mpm/services/agents/sources/git_source_sync_service.py +116 -5
- claude_mpm/services/monitor/management/lifecycle.py +7 -1
- claude_mpm/services/pm_skills_deployer.py +711 -0
- claude_mpm/services/profile_manager.py +337 -0
- claude_mpm/services/skills/git_skill_source_manager.py +148 -11
- claude_mpm/services/skills/selective_skill_deployer.py +97 -48
- claude_mpm/services/skills_deployer.py +161 -65
- 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/pm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/pm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/pm-verification-protocols/SKILL.md +198 -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/skill_manager.py +98 -3
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/METADATA +3 -2
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/RECORD +244 -68
- 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/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/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.62.dist-info}/top_level.txt +0 -0
claude_mpm/cli/startup.py
CHANGED
|
@@ -59,6 +59,73 @@ def sync_hooks_on_startup(quiet: bool = False) -> bool:
|
|
|
59
59
|
return False
|
|
60
60
|
|
|
61
61
|
|
|
62
|
+
def cleanup_legacy_agent_cache() -> None:
|
|
63
|
+
"""Remove legacy hierarchical agent cache directories.
|
|
64
|
+
|
|
65
|
+
WHY: Old agent cache used category-based directory structure directly in cache.
|
|
66
|
+
New structure uses remote source paths. This cleanup prevents confusion from
|
|
67
|
+
stale cache directories.
|
|
68
|
+
|
|
69
|
+
Old structure (removed):
|
|
70
|
+
~/.claude-mpm/cache/agents/engineer/
|
|
71
|
+
~/.claude-mpm/cache/agents/ops/
|
|
72
|
+
~/.claude-mpm/cache/agents/qa/
|
|
73
|
+
...
|
|
74
|
+
|
|
75
|
+
New structure (kept):
|
|
76
|
+
~/.claude-mpm/cache/agents/bobmatnyc/claude-mpm-agents/agents/...
|
|
77
|
+
|
|
78
|
+
DESIGN DECISION: Runs early in startup before agent deployment to ensure
|
|
79
|
+
clean cache state. Removes only known legacy directories to avoid deleting
|
|
80
|
+
user data.
|
|
81
|
+
"""
|
|
82
|
+
import shutil
|
|
83
|
+
from pathlib import Path
|
|
84
|
+
|
|
85
|
+
from ..core.logger import get_logger
|
|
86
|
+
|
|
87
|
+
logger = get_logger("startup")
|
|
88
|
+
|
|
89
|
+
cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
90
|
+
if not cache_dir.exists():
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
# Known legacy category directories (from old hierarchical structure)
|
|
94
|
+
legacy_dirs = [
|
|
95
|
+
"claude-mpm",
|
|
96
|
+
"documentation",
|
|
97
|
+
"engineer",
|
|
98
|
+
"ops",
|
|
99
|
+
"qa",
|
|
100
|
+
"security",
|
|
101
|
+
"universal",
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
removed = []
|
|
105
|
+
|
|
106
|
+
# Remove legacy category directories
|
|
107
|
+
for dir_name in legacy_dirs:
|
|
108
|
+
legacy_path = cache_dir / dir_name
|
|
109
|
+
if legacy_path.exists() and legacy_path.is_dir():
|
|
110
|
+
try:
|
|
111
|
+
shutil.rmtree(legacy_path)
|
|
112
|
+
removed.append(dir_name)
|
|
113
|
+
except Exception as e:
|
|
114
|
+
logger.debug(f"Failed to remove legacy directory {dir_name}: {e}")
|
|
115
|
+
|
|
116
|
+
# Also remove stray BASE-AGENT.md in cache root
|
|
117
|
+
base_agent = cache_dir / "BASE-AGENT.md"
|
|
118
|
+
if base_agent.exists():
|
|
119
|
+
try:
|
|
120
|
+
base_agent.unlink()
|
|
121
|
+
removed.append("BASE-AGENT.md")
|
|
122
|
+
except Exception as e:
|
|
123
|
+
logger.debug(f"Failed to remove BASE-AGENT.md: {e}")
|
|
124
|
+
|
|
125
|
+
if removed:
|
|
126
|
+
logger.info(f"Cleaned up legacy agent cache: {', '.join(removed)}")
|
|
127
|
+
|
|
128
|
+
|
|
62
129
|
def check_legacy_cache() -> None:
|
|
63
130
|
"""Deprecated: Legacy cache checking is no longer needed.
|
|
64
131
|
|
|
@@ -399,19 +466,48 @@ def sync_remote_agents_on_startup():
|
|
|
399
466
|
block startup to ensure claude-mpm remains functional.
|
|
400
467
|
|
|
401
468
|
Workflow:
|
|
402
|
-
1.
|
|
403
|
-
2.
|
|
404
|
-
3.
|
|
405
|
-
4.
|
|
469
|
+
1. Cleanup legacy agent cache directories (if any)
|
|
470
|
+
2. Sync all enabled Git sources (download/cache files) - Phase 1 progress bar
|
|
471
|
+
3. Deploy agents to ~/.claude/agents/ - Phase 2 progress bar
|
|
472
|
+
4. Cleanup orphaned agents (ours but no longer deployed) - Phase 3
|
|
473
|
+
5. Log deployment results
|
|
406
474
|
"""
|
|
407
|
-
#
|
|
475
|
+
# Cleanup legacy cache directories first (before syncing)
|
|
476
|
+
cleanup_legacy_agent_cache()
|
|
477
|
+
|
|
478
|
+
# DEPRECATED: Legacy warning - replaced by automatic cleanup above
|
|
408
479
|
check_legacy_cache()
|
|
409
480
|
|
|
410
481
|
try:
|
|
482
|
+
# Load active profile if configured
|
|
483
|
+
# Get project root (where .claude-mpm exists)
|
|
484
|
+
from pathlib import Path
|
|
485
|
+
|
|
486
|
+
from ..core.shared.config_loader import ConfigLoader
|
|
411
487
|
from ..services.agents.deployment.agent_deployment import AgentDeploymentService
|
|
412
488
|
from ..services.agents.startup_sync import sync_agents_on_startup
|
|
489
|
+
from ..services.profile_manager import ProfileManager
|
|
413
490
|
from ..utils.progress import ProgressBar
|
|
414
491
|
|
|
492
|
+
project_root = Path.cwd()
|
|
493
|
+
|
|
494
|
+
profile_manager = ProfileManager(project_dir=project_root)
|
|
495
|
+
config_loader = ConfigLoader()
|
|
496
|
+
main_config = config_loader.load_main_config()
|
|
497
|
+
active_profile = main_config.get("active_profile")
|
|
498
|
+
|
|
499
|
+
if active_profile:
|
|
500
|
+
success = profile_manager.load_profile(active_profile)
|
|
501
|
+
if success:
|
|
502
|
+
summary = profile_manager.get_filtering_summary()
|
|
503
|
+
from ..core.logger import get_logger
|
|
504
|
+
|
|
505
|
+
logger = get_logger("cli")
|
|
506
|
+
logger.info(
|
|
507
|
+
f"Profile '{active_profile}' active: "
|
|
508
|
+
f"{summary['enabled_agents_count']} agents enabled"
|
|
509
|
+
)
|
|
510
|
+
|
|
415
511
|
# Phase 1: Sync files from Git sources
|
|
416
512
|
result = sync_agents_on_startup()
|
|
417
513
|
|
|
@@ -438,8 +534,55 @@ def sync_remote_agents_on_startup():
|
|
|
438
534
|
# Phase 2: Deploy agents from cache to ~/.claude/agents/
|
|
439
535
|
# This mirrors the skills deployment pattern (lines 371-407)
|
|
440
536
|
try:
|
|
441
|
-
# Initialize deployment service
|
|
442
|
-
|
|
537
|
+
# Initialize deployment service with profile-filtered configuration
|
|
538
|
+
from ..core.config import Config
|
|
539
|
+
|
|
540
|
+
deploy_config = None
|
|
541
|
+
if active_profile and profile_manager.active_profile:
|
|
542
|
+
# Create config with excluded agents based on profile
|
|
543
|
+
# Get all agents that should be excluded (not in enabled list)
|
|
544
|
+
from pathlib import Path
|
|
545
|
+
|
|
546
|
+
cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
547
|
+
if cache_dir.exists():
|
|
548
|
+
# Find all agent files
|
|
549
|
+
# Supports both flat cache and {owner}/{repo}/agents/ structure
|
|
550
|
+
all_agent_files = [
|
|
551
|
+
f
|
|
552
|
+
for f in cache_dir.rglob("*.md")
|
|
553
|
+
if "/agents/" in str(f)
|
|
554
|
+
and f.stem.lower() != "base-agent"
|
|
555
|
+
and f.name.lower()
|
|
556
|
+
not in {"readme.md", "changelog.md", "contributing.md"}
|
|
557
|
+
]
|
|
558
|
+
|
|
559
|
+
# Build exclusion list for agents not in profile
|
|
560
|
+
excluded_agents = []
|
|
561
|
+
for agent_file in all_agent_files:
|
|
562
|
+
agent_name = agent_file.stem
|
|
563
|
+
if not profile_manager.is_agent_enabled(agent_name):
|
|
564
|
+
excluded_agents.append(agent_name)
|
|
565
|
+
|
|
566
|
+
if excluded_agents:
|
|
567
|
+
# Get singleton config and update with profile settings
|
|
568
|
+
# BUGFIX: Config is a singleton that ignores dict parameter if already initialized.
|
|
569
|
+
# Creating Config({...}) doesn't store excluded_agents - use set() instead.
|
|
570
|
+
deploy_config = Config()
|
|
571
|
+
deploy_config.set(
|
|
572
|
+
"agent_deployment.excluded_agents", excluded_agents
|
|
573
|
+
)
|
|
574
|
+
deploy_config.set(
|
|
575
|
+
"agent_deployment.filter_non_mpm_agents", False
|
|
576
|
+
)
|
|
577
|
+
deploy_config.set("agent_deployment.case_sensitive", False)
|
|
578
|
+
deploy_config.set(
|
|
579
|
+
"agent_deployment.exclude_dependencies", False
|
|
580
|
+
)
|
|
581
|
+
logger.info(
|
|
582
|
+
f"Profile '{active_profile}': Excluding {len(excluded_agents)} agents from deployment"
|
|
583
|
+
)
|
|
584
|
+
|
|
585
|
+
deployment_service = AgentDeploymentService(config=deploy_config)
|
|
443
586
|
|
|
444
587
|
# Count agents in cache to show accurate progress
|
|
445
588
|
from pathlib import Path
|
|
@@ -461,12 +604,15 @@ def sync_remote_agents_on_startup():
|
|
|
461
604
|
stale_dirs = set()
|
|
462
605
|
|
|
463
606
|
for md_file in cache_dir.rglob("*.md"):
|
|
464
|
-
# Stale cache files have multiple /agents/ in their path
|
|
465
|
-
# Current:
|
|
466
|
-
# (1 occurrence)
|
|
467
|
-
# Old:
|
|
468
|
-
#
|
|
469
|
-
|
|
607
|
+
# Stale cache files have multiple /agents/ in their path RELATIVE to cache_dir
|
|
608
|
+
# Current: cache/agents/bobmatnyc/claude-mpm-agents/agents/engineer/...
|
|
609
|
+
# (1 occurrence in relative path: /agents/)
|
|
610
|
+
# Old flat: cache/agents/engineer/...
|
|
611
|
+
# (0 occurrences in relative path - no repo structure)
|
|
612
|
+
# The issue: str(md_file).count("/agents/") counts BOTH cache/agents/ AND repo/agents/
|
|
613
|
+
# Fix: Count /agents/ in path RELATIVE to cache_dir (after cache/agents/)
|
|
614
|
+
relative_path = str(md_file.relative_to(cache_dir))
|
|
615
|
+
if relative_path.count("/agents/") > 1:
|
|
470
616
|
# Track parent directory for cleanup
|
|
471
617
|
# Extract subdirectory under cache/agents/
|
|
472
618
|
# (e.g., "bobmatnyc")
|
|
@@ -540,8 +686,8 @@ def sync_remote_agents_on_startup():
|
|
|
540
686
|
all_md_files = list(cache_dir.rglob("*.md"))
|
|
541
687
|
|
|
542
688
|
# Filter to only agent files:
|
|
543
|
-
# 1. Must have "/agents/" in path
|
|
544
|
-
#
|
|
689
|
+
# 1. Must have "/agents/" in path (current structure supports
|
|
690
|
+
# both flat and {owner}/{repo}/agents/ patterns)
|
|
545
691
|
# 2. Must not be in PM templates or doc files
|
|
546
692
|
# 3. Exclude BASE-AGENT.md which is not a deployable agent
|
|
547
693
|
# 4. Exclude build artifacts (dist/, build/, .cache/)
|
|
@@ -550,14 +696,10 @@ def sync_remote_agents_on_startup():
|
|
|
550
696
|
f
|
|
551
697
|
for f in all_md_files
|
|
552
698
|
if (
|
|
553
|
-
# Must be in an agent directory
|
|
554
|
-
# cache
|
|
699
|
+
# Must be in an agent directory
|
|
700
|
+
# Supports: cache/agents/{category}/... (flat)
|
|
701
|
+
# Supports: cache/agents/{owner}/{repo}/agents/{category}/... (GitHub sync)
|
|
555
702
|
"/agents/" in str(f)
|
|
556
|
-
# NEW: Only ONE /agents/ in path (excludes old
|
|
557
|
-
# nested repos)
|
|
558
|
-
# This prevents counting old caches like
|
|
559
|
-
# bobmatnyc/claude-mpm-agents/agents/...
|
|
560
|
-
and str(f).count("/agents/") == 1
|
|
561
703
|
# Exclude PM templates, doc files, and BASE-AGENT
|
|
562
704
|
and f.name.lower() not in pm_templates
|
|
563
705
|
and f.name.lower() not in doc_files
|
|
@@ -579,6 +721,7 @@ def sync_remote_agents_on_startup():
|
|
|
579
721
|
target_dir=deploy_target,
|
|
580
722
|
force_rebuild=False, # Only deploy if versions differ
|
|
581
723
|
deployment_mode="update", # Version-aware updates
|
|
724
|
+
config=deploy_config, # Pass config to respect profile filtering
|
|
582
725
|
)
|
|
583
726
|
|
|
584
727
|
# Get actual counts from deployment result (reflects configured agents)
|
|
@@ -719,13 +862,16 @@ def sync_remote_skills_on_startup():
|
|
|
719
862
|
1. Sync all enabled Git sources (download/cache files) - Phase 1 progress bar
|
|
720
863
|
2. Scan deployed agents for skill requirements → save to configuration.yaml
|
|
721
864
|
3. Resolve which skills to deploy (user_defined vs agent_referenced)
|
|
722
|
-
4.
|
|
723
|
-
5.
|
|
865
|
+
4. Apply profile filtering if active
|
|
866
|
+
5. Deploy resolved skills to ~/.claude/skills/ - Phase 2 progress bar
|
|
867
|
+
6. Log deployment results with source indication
|
|
724
868
|
"""
|
|
725
869
|
try:
|
|
726
870
|
from pathlib import Path
|
|
727
871
|
|
|
728
872
|
from ..config.skill_sources import SkillSourceConfiguration
|
|
873
|
+
from ..core.shared.config_loader import ConfigLoader
|
|
874
|
+
from ..services.profile_manager import ProfileManager
|
|
729
875
|
from ..services.skills.git_skill_source_manager import GitSkillSourceManager
|
|
730
876
|
from ..services.skills.selective_skill_deployer import (
|
|
731
877
|
get_required_skills_from_agents,
|
|
@@ -734,6 +880,28 @@ def sync_remote_skills_on_startup():
|
|
|
734
880
|
)
|
|
735
881
|
from ..utils.progress import ProgressBar
|
|
736
882
|
|
|
883
|
+
# Load active profile if configured
|
|
884
|
+
# Get project root (where .claude-mpm exists)
|
|
885
|
+
project_root = Path.cwd()
|
|
886
|
+
|
|
887
|
+
profile_manager = ProfileManager(project_dir=project_root)
|
|
888
|
+
config_loader = ConfigLoader()
|
|
889
|
+
main_config = config_loader.load_main_config()
|
|
890
|
+
active_profile = main_config.get("active_profile")
|
|
891
|
+
|
|
892
|
+
if active_profile:
|
|
893
|
+
success = profile_manager.load_profile(active_profile)
|
|
894
|
+
if success:
|
|
895
|
+
from ..core.logger import get_logger
|
|
896
|
+
|
|
897
|
+
logger = get_logger("cli")
|
|
898
|
+
summary = profile_manager.get_filtering_summary()
|
|
899
|
+
logger.info(
|
|
900
|
+
f"Profile '{active_profile}' active: "
|
|
901
|
+
f"{summary['enabled_skills_count']} skills enabled, "
|
|
902
|
+
f"{summary['disabled_patterns_count']} patterns disabled"
|
|
903
|
+
)
|
|
904
|
+
|
|
737
905
|
config = SkillSourceConfiguration()
|
|
738
906
|
manager = GitSkillSourceManager(config)
|
|
739
907
|
|
|
@@ -822,108 +990,191 @@ def sync_remote_skills_on_startup():
|
|
|
822
990
|
|
|
823
991
|
# Phase 2: Scan agents and save to configuration.yaml
|
|
824
992
|
# This step populates configuration.yaml with agent-referenced skills
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
993
|
+
# CRITICAL: Always scan agents to populate agent_referenced, even when using cached skills.
|
|
994
|
+
# Without this, skill_filter=None causes ALL skills to deploy and NO cleanup to run.
|
|
995
|
+
agents_dir = Path.cwd() / ".claude" / "agents"
|
|
996
|
+
|
|
997
|
+
# Scan agents for skill requirements (ALWAYS run to ensure cleanup works)
|
|
998
|
+
agent_skills = get_required_skills_from_agents(agents_dir)
|
|
999
|
+
logger.info(
|
|
1000
|
+
f"Agent scan found {len(agent_skills)} unique skills across deployed agents"
|
|
1001
|
+
)
|
|
834
1002
|
|
|
835
|
-
|
|
836
|
-
|
|
1003
|
+
# Save to project-level configuration.yaml
|
|
1004
|
+
project_config_path = Path.cwd() / ".claude-mpm" / "configuration.yaml"
|
|
1005
|
+
save_agent_skills_to_config(list(agent_skills), project_config_path)
|
|
1006
|
+
logger.debug(
|
|
1007
|
+
f"Saved {len(agent_skills)} agent-referenced skills to {project_config_path}"
|
|
1008
|
+
)
|
|
837
1009
|
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
total_skill_count = len(all_skills)
|
|
1010
|
+
# Phase 3: Resolve which skills to deploy (user_defined or agent_referenced)
|
|
1011
|
+
skills_to_deploy, skill_source = get_skills_to_deploy(project_config_path)
|
|
841
1012
|
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
1013
|
+
# CRITICAL DEBUG: Log deployment resolution to diagnose cleanup issues
|
|
1014
|
+
if skills_to_deploy:
|
|
1015
|
+
logger.info(
|
|
1016
|
+
f"Resolved {len(skills_to_deploy)} skills from {skill_source} (cleanup will run)"
|
|
1017
|
+
)
|
|
1018
|
+
else:
|
|
1019
|
+
logger.warning(
|
|
1020
|
+
f"No skills resolved from {skill_source} - will deploy ALL skills WITHOUT cleanup! "
|
|
1021
|
+
f"This may indicate agent_referenced is empty in configuration.yaml."
|
|
845
1022
|
)
|
|
846
1023
|
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
1024
|
+
# Phase 4: Apply profile filtering if active
|
|
1025
|
+
if active_profile and profile_manager.active_profile:
|
|
1026
|
+
# Filter skills based on profile
|
|
1027
|
+
if skills_to_deploy:
|
|
1028
|
+
# Filter the resolved skill list
|
|
1029
|
+
original_count = len(skills_to_deploy)
|
|
1030
|
+
filtered_skills = [
|
|
1031
|
+
skill
|
|
1032
|
+
for skill in skills_to_deploy
|
|
1033
|
+
if profile_manager.is_skill_enabled(skill)
|
|
1034
|
+
]
|
|
1035
|
+
filtered_count = original_count - len(filtered_skills)
|
|
1036
|
+
|
|
1037
|
+
# SAFEGUARD: Warn if all skills were filtered out (misconfiguration)
|
|
1038
|
+
if not filtered_skills and original_count > 0:
|
|
1039
|
+
logger.warning(
|
|
1040
|
+
f"Profile '{active_profile}' filtered ALL {original_count} skills. "
|
|
1041
|
+
f"This may indicate a naming mismatch in the profile."
|
|
1042
|
+
)
|
|
1043
|
+
elif filtered_count > 0:
|
|
1044
|
+
logger.info(
|
|
1045
|
+
f"Profile '{active_profile}' filtered {filtered_count} skills "
|
|
1046
|
+
f"({len(filtered_skills)} remaining)"
|
|
1047
|
+
)
|
|
1048
|
+
|
|
1049
|
+
skills_to_deploy = filtered_skills
|
|
1050
|
+
skill_source = f"{skill_source} + profile filtered"
|
|
1051
|
+
else:
|
|
1052
|
+
# No explicit skill list - filter from all available
|
|
1053
|
+
all_skills = manager.get_all_skills()
|
|
1054
|
+
filtered_skills = [
|
|
1055
|
+
skill["name"]
|
|
1056
|
+
for skill in all_skills
|
|
1057
|
+
if profile_manager.is_skill_enabled(skill["name"])
|
|
1058
|
+
]
|
|
1059
|
+
skills_to_deploy = filtered_skills
|
|
1060
|
+
skill_source = "profile filtered"
|
|
1061
|
+
logger.info(
|
|
1062
|
+
f"Profile '{active_profile}': "
|
|
1063
|
+
f"{len(filtered_skills)} skills enabled from {len(all_skills)} available"
|
|
854
1064
|
)
|
|
855
1065
|
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
filtered = deployment_result.get("filtered_count", 0)
|
|
860
|
-
total_available = deployed + skipped
|
|
1066
|
+
# Get all skills to determine counts
|
|
1067
|
+
all_skills = manager.get_all_skills()
|
|
1068
|
+
total_skill_count = len(all_skills)
|
|
861
1069
|
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
1070
|
+
# Determine skill count based on resolution
|
|
1071
|
+
skill_count = (
|
|
1072
|
+
len(skills_to_deploy) if skills_to_deploy else total_skill_count
|
|
1073
|
+
)
|
|
1074
|
+
|
|
1075
|
+
if skill_count > 0:
|
|
1076
|
+
# Deploy skills with resolved filter
|
|
1077
|
+
# Deploy ONLY to project directory (not user-level)
|
|
1078
|
+
# DESIGN DECISION: Project-level deployment keeps skills isolated per project,
|
|
1079
|
+
# avoiding pollution of user's global ~/.claude/skills/ directory.
|
|
1080
|
+
|
|
1081
|
+
# Deploy to project-local directory with cleanup
|
|
1082
|
+
deployment_result = manager.deploy_skills(
|
|
1083
|
+
target_dir=Path.cwd() / ".claude" / "skills",
|
|
1084
|
+
force=False,
|
|
1085
|
+
# CRITICAL FIX: Empty list should mean "deploy no skills", not "deploy all"
|
|
1086
|
+
# When skills_to_deploy is [], we want skill_filter=set() NOT skill_filter=None
|
|
1087
|
+
# None means "no filtering" (deploy all), empty set means "filter to nothing"
|
|
1088
|
+
skill_filter=set(skills_to_deploy) if skills_to_deploy is not None else None,
|
|
1089
|
+
)
|
|
881
1090
|
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
1091
|
+
# REMOVED: User-level deployment (lines 1068-1074)
|
|
1092
|
+
# Reason: Skills should be project-specific, not user-global.
|
|
1093
|
+
# Claude Code can read from project-level .claude/skills/ directory.
|
|
1094
|
+
|
|
1095
|
+
# Get actual counts from deployment result (use project-local for display)
|
|
1096
|
+
deployed = deployment_result.get("deployed_count", 0)
|
|
1097
|
+
skipped = deployment_result.get("skipped_count", 0)
|
|
1098
|
+
filtered = deployment_result.get("filtered_count", 0)
|
|
1099
|
+
removed = deployment_result.get("removed_count", 0)
|
|
1100
|
+
total_available = deployed + skipped
|
|
1101
|
+
|
|
1102
|
+
# Only show progress bar if there are skills to deploy
|
|
1103
|
+
if total_available > 0:
|
|
1104
|
+
deploy_progress = ProgressBar(
|
|
1105
|
+
total=total_available,
|
|
1106
|
+
prefix="Deploying skill directories",
|
|
1107
|
+
show_percentage=True,
|
|
1108
|
+
show_counter=True,
|
|
1109
|
+
)
|
|
1110
|
+
# Update progress bar to completion
|
|
1111
|
+
deploy_progress.update(total_available)
|
|
1112
|
+
else:
|
|
1113
|
+
# No skills to deploy - create dummy progress for message only
|
|
1114
|
+
deploy_progress = ProgressBar(
|
|
1115
|
+
total=1,
|
|
1116
|
+
prefix="Deploying skill directories",
|
|
1117
|
+
show_percentage=False,
|
|
1118
|
+
show_counter=False,
|
|
887
1119
|
)
|
|
1120
|
+
deploy_progress.update(1)
|
|
1121
|
+
|
|
1122
|
+
# Show total available skills (deployed + already existing)
|
|
1123
|
+
# Include source indication (user_defined vs agent_referenced)
|
|
1124
|
+
# Note: total_skill_count is from cache, total_available is what's deployed/needed
|
|
1125
|
+
source_label = (
|
|
1126
|
+
"user override" if skill_source == "user_defined" else "from agents"
|
|
1127
|
+
)
|
|
888
1128
|
|
|
1129
|
+
# Build finish message with cleanup info
|
|
1130
|
+
if deployed > 0 or removed > 0:
|
|
1131
|
+
parts = []
|
|
889
1132
|
if deployed > 0:
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
)
|
|
900
|
-
elif filtered > 0:
|
|
901
|
-
# Skills filtered means agents require fewer skills than available
|
|
1133
|
+
parts.append(f"{deployed} new")
|
|
1134
|
+
if skipped > 0:
|
|
1135
|
+
parts.append(f"{skipped} unchanged")
|
|
1136
|
+
if removed > 0:
|
|
1137
|
+
parts.append(f"{removed} removed")
|
|
1138
|
+
|
|
1139
|
+
status = ", ".join(parts)
|
|
1140
|
+
|
|
1141
|
+
if filtered > 0:
|
|
902
1142
|
deploy_progress.finish(
|
|
903
|
-
f"
|
|
1143
|
+
f"Complete: {status} ({total_available} {source_label}, {filtered} files in cache)"
|
|
904
1144
|
)
|
|
905
1145
|
else:
|
|
906
1146
|
deploy_progress.finish(
|
|
907
|
-
f"Complete: {total_available} skills {source_label} "
|
|
908
|
-
f"({total_skill_count} files in cache)"
|
|
1147
|
+
f"Complete: {status} ({total_available} skills {source_label} from {total_skill_count} files in cache)"
|
|
909
1148
|
)
|
|
1149
|
+
elif filtered > 0:
|
|
1150
|
+
# Skills filtered means agents require fewer skills than available
|
|
1151
|
+
deploy_progress.finish(
|
|
1152
|
+
f"No skills needed ({source_label}, {total_skill_count} files in cache)"
|
|
1153
|
+
)
|
|
1154
|
+
else:
|
|
1155
|
+
# No changes - all skills already deployed
|
|
1156
|
+
msg = f"Complete: {total_available} skills {source_label}"
|
|
1157
|
+
if removed > 0:
|
|
1158
|
+
msg += f", {removed} removed"
|
|
1159
|
+
msg += f" ({total_skill_count} files in cache)"
|
|
1160
|
+
deploy_progress.finish(msg)
|
|
1161
|
+
|
|
1162
|
+
# Log deployment errors if any
|
|
1163
|
+
from ..core.logger import get_logger
|
|
910
1164
|
|
|
911
|
-
|
|
912
|
-
from ..core.logger import get_logger
|
|
913
|
-
|
|
914
|
-
logger = get_logger("cli")
|
|
1165
|
+
logger = get_logger("cli")
|
|
915
1166
|
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1167
|
+
errors = deployment_result.get("errors", [])
|
|
1168
|
+
if errors:
|
|
1169
|
+
logger.warning(
|
|
1170
|
+
f"Skill deployment completed with {len(errors)} errors: {errors}"
|
|
1171
|
+
)
|
|
921
1172
|
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
1173
|
+
# Log sync errors if any
|
|
1174
|
+
if results["failed_count"] > 0:
|
|
1175
|
+
logger.warning(
|
|
1176
|
+
f"Skill sync completed with {results['failed_count']} failures"
|
|
1177
|
+
)
|
|
927
1178
|
|
|
928
1179
|
except Exception as e:
|
|
929
1180
|
# Non-critical - log but don't fail startup
|
|
@@ -1006,7 +1257,7 @@ def show_agent_summary():
|
|
|
1006
1257
|
# Display summary if we have agents
|
|
1007
1258
|
if installed_count > 0 or available_count > 0:
|
|
1008
1259
|
print(
|
|
1009
|
-
f"✓ Agents: {installed_count} deployed / {available_count} cached",
|
|
1260
|
+
f"✓ Agents: {installed_count} deployed / {max(0, available_count - installed_count)} cached",
|
|
1010
1261
|
flush=True,
|
|
1011
1262
|
)
|
|
1012
1263
|
|
|
@@ -1023,61 +1274,64 @@ def show_skill_summary():
|
|
|
1023
1274
|
Display skill availability summary on startup.
|
|
1024
1275
|
|
|
1025
1276
|
WHY: Users should see at a glance how many skills are deployed and available
|
|
1026
|
-
from
|
|
1277
|
+
from cache, similar to the agent summary showing "X deployed / Y cached".
|
|
1278
|
+
|
|
1279
|
+
DESIGN DECISION: Fast, non-blocking check that counts skills from:
|
|
1280
|
+
- Deployed skills: PROJECT-level .claude/skills/ directory
|
|
1281
|
+
- Cached skills: ~/.claude-mpm/cache/skills/ directory (from remote sources)
|
|
1027
1282
|
|
|
1028
|
-
|
|
1029
|
-
directory and collection repos. Shows "X installed (Y available)" format.
|
|
1283
|
+
Shows format: "✓ Skills: X deployed / Y cached"
|
|
1030
1284
|
Failures are silent to avoid blocking startup.
|
|
1031
1285
|
"""
|
|
1032
1286
|
try:
|
|
1033
1287
|
from pathlib import Path
|
|
1034
1288
|
|
|
1035
|
-
# Count deployed skills (
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
if
|
|
1289
|
+
# Count deployed skills (PROJECT-level, not user-level)
|
|
1290
|
+
project_skills_dir = Path.cwd() / ".claude" / "skills"
|
|
1291
|
+
deployed_count = 0
|
|
1292
|
+
if project_skills_dir.exists():
|
|
1039
1293
|
# Count directories with SKILL.md (excludes collection repos)
|
|
1040
1294
|
# Exclude collection directories (obra-superpowers, etc.)
|
|
1041
1295
|
skill_dirs = [
|
|
1042
1296
|
d
|
|
1043
|
-
for d in
|
|
1297
|
+
for d in project_skills_dir.iterdir()
|
|
1044
1298
|
if d.is_dir()
|
|
1045
1299
|
and (d / "SKILL.md").exists()
|
|
1046
1300
|
and not (d / ".git").exists() # Exclude collection repos
|
|
1047
1301
|
]
|
|
1048
|
-
|
|
1302
|
+
deployed_count = len(skill_dirs)
|
|
1049
1303
|
|
|
1050
|
-
# Count
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
):
|
|
1304
|
+
# Count cached skills (from remote sources, not deployed yet)
|
|
1305
|
+
# This matches the agent summary pattern: deployed vs cached
|
|
1306
|
+
cache_dir = Path.home() / ".claude-mpm" / "cache" / "skills"
|
|
1307
|
+
cached_count = 0
|
|
1308
|
+
if cache_dir.exists():
|
|
1309
|
+
# Scan all repository directories in cache
|
|
1310
|
+
# Cache structure: ~/.claude-mpm/cache/skills/{owner}/{repo}/...
|
|
1311
|
+
for repo_dir in cache_dir.rglob("*"):
|
|
1312
|
+
if not repo_dir.is_dir():
|
|
1059
1313
|
continue
|
|
1060
1314
|
|
|
1061
|
-
# Count skill directories
|
|
1315
|
+
# Count skill directories (those with SKILL.md)
|
|
1062
1316
|
# Skills can be nested in: skills/category/skill-name/SKILL.md
|
|
1063
1317
|
# or in flat structure: skill-name/SKILL.md
|
|
1064
|
-
for root, dirs, files in os.walk(
|
|
1318
|
+
for root, dirs, files in os.walk(repo_dir):
|
|
1065
1319
|
if "SKILL.md" in files:
|
|
1066
|
-
# Exclude build artifacts and hidden directories
|
|
1067
|
-
# Get relative path from collection_dir to avoid excluding based on .claude parent
|
|
1320
|
+
# Exclude build artifacts and hidden directories
|
|
1068
1321
|
root_path = Path(root)
|
|
1069
|
-
relative_parts = root_path.relative_to(collection_dir).parts
|
|
1070
1322
|
if not any(
|
|
1071
1323
|
part.startswith(".")
|
|
1072
1324
|
or part in ["dist", "build", "__pycache__"]
|
|
1073
|
-
for part in
|
|
1325
|
+
for part in root_path.parts
|
|
1074
1326
|
):
|
|
1075
|
-
|
|
1327
|
+
cached_count += 1
|
|
1076
1328
|
|
|
1077
|
-
# Display summary
|
|
1078
|
-
|
|
1329
|
+
# Display summary using agent summary format: "X deployed / Y cached"
|
|
1330
|
+
# Only show non-deployed cached skills (subtract deployed from cached)
|
|
1331
|
+
non_deployed_cached = max(0, cached_count - deployed_count)
|
|
1332
|
+
if deployed_count > 0 or non_deployed_cached > 0:
|
|
1079
1333
|
print(
|
|
1080
|
-
f"✓ Skills: {
|
|
1334
|
+
f"✓ Skills: {deployed_count} deployed / {non_deployed_cached} cached",
|
|
1081
1335
|
flush=True,
|
|
1082
1336
|
)
|
|
1083
1337
|
|
|
@@ -1089,6 +1343,45 @@ def show_skill_summary():
|
|
|
1089
1343
|
logger.debug(f"Failed to generate skill summary: {e}")
|
|
1090
1344
|
|
|
1091
1345
|
|
|
1346
|
+
def verify_and_show_pm_skills():
|
|
1347
|
+
"""Verify PM skills and display status.
|
|
1348
|
+
|
|
1349
|
+
WHY: PM skills are essential for PM agent operation.
|
|
1350
|
+
Shows deployment status and auto-deploys if missing.
|
|
1351
|
+
"""
|
|
1352
|
+
try:
|
|
1353
|
+
from pathlib import Path
|
|
1354
|
+
|
|
1355
|
+
from ..services.pm_skills_deployer import PMSkillsDeployerService
|
|
1356
|
+
|
|
1357
|
+
deployer = PMSkillsDeployerService()
|
|
1358
|
+
project_dir = Path.cwd()
|
|
1359
|
+
|
|
1360
|
+
result = deployer.verify_pm_skills(project_dir)
|
|
1361
|
+
|
|
1362
|
+
if result.verified:
|
|
1363
|
+
# Show verified status
|
|
1364
|
+
print(f"✓ PM skills: {result.skill_count} verified", flush=True)
|
|
1365
|
+
else:
|
|
1366
|
+
# Auto-deploy if missing
|
|
1367
|
+
print("Deploying PM skills...", end="", flush=True)
|
|
1368
|
+
deploy_result = deployer.deploy_pm_skills(project_dir)
|
|
1369
|
+
if deploy_result.success:
|
|
1370
|
+
total = len(deploy_result.deployed) + len(deploy_result.skipped)
|
|
1371
|
+
print(f"\r✓ PM skills: {total} deployed" + " " * 20, flush=True)
|
|
1372
|
+
else:
|
|
1373
|
+
print("\r⚠ PM skills: deployment failed" + " " * 20, flush=True)
|
|
1374
|
+
|
|
1375
|
+
except ImportError:
|
|
1376
|
+
# PM skills deployer not available - skip silently
|
|
1377
|
+
pass
|
|
1378
|
+
except Exception as e:
|
|
1379
|
+
from ..core.logger import get_logger
|
|
1380
|
+
|
|
1381
|
+
logger = get_logger("cli")
|
|
1382
|
+
logger.debug(f"PM skills verification failed: {e}")
|
|
1383
|
+
|
|
1384
|
+
|
|
1092
1385
|
def auto_install_chrome_devtools_on_startup():
|
|
1093
1386
|
"""
|
|
1094
1387
|
Automatically install chrome-devtools-mcp on startup if enabled.
|
|
@@ -1163,6 +1456,7 @@ def run_background_services():
|
|
|
1163
1456
|
sync_remote_skills_on_startup() # Override layer: Git-based skills (takes precedence)
|
|
1164
1457
|
discover_and_link_runtime_skills() # Discovery: user-added skills
|
|
1165
1458
|
show_skill_summary() # Display skill counts after deployment
|
|
1459
|
+
verify_and_show_pm_skills() # PM skills verification and status
|
|
1166
1460
|
|
|
1167
1461
|
deploy_output_style_on_startup()
|
|
1168
1462
|
|
|
@@ -1296,18 +1590,10 @@ def verify_mcp_gateway_startup():
|
|
|
1296
1590
|
DESIGN DECISION: This is non-blocking - failures are logged but don't prevent
|
|
1297
1591
|
startup to ensure claude-mpm remains functional even if MCP gateway has issues.
|
|
1298
1592
|
"""
|
|
1299
|
-
#
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
logger = get_logger("mcp_verify")
|
|
1305
|
-
all_ok, message = verify_mcp_services_on_startup()
|
|
1306
|
-
if not all_ok:
|
|
1307
|
-
logger.warning(message)
|
|
1308
|
-
except Exception:
|
|
1309
|
-
# Non-critical - continue with startup
|
|
1310
|
-
pass
|
|
1593
|
+
# DISABLED: MCP service verification removed - Claude Code handles MCP natively
|
|
1594
|
+
# The previous check warned about missing MCP services, but users should configure
|
|
1595
|
+
# MCP servers through Claude Code's native MCP management, not through claude-mpm.
|
|
1596
|
+
# See: https://docs.anthropic.com/en/docs/claude-code/mcp
|
|
1311
1597
|
|
|
1312
1598
|
try:
|
|
1313
1599
|
import asyncio
|