claude-mpm 5.0.9__py3-none-any.whl → 5.4.41__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/__init__.py +4 -0
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/{PM_INSTRUCTIONS_TEACH.md → CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md} +721 -41
- claude_mpm/agents/MEMORY.md +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +468 -468
- claude_mpm/agents/WORKFLOW.md +5 -254
- claude_mpm/agents/agent_loader.py +13 -44
- claude_mpm/agents/base_agent.json +1 -1
- claude_mpm/agents/frontmatter_validator.py +70 -2
- claude_mpm/agents/templates/circuit-breakers.md +431 -45
- claude_mpm/cli/__init__.py +0 -1
- claude_mpm/cli/__main__.py +4 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/agent_state_manager.py +18 -27
- claude_mpm/cli/commands/agents.py +175 -37
- claude_mpm/cli/commands/auto_configure.py +723 -236
- claude_mpm/cli/commands/config.py +88 -2
- claude_mpm/cli/commands/configure.py +1262 -157
- claude_mpm/cli/commands/configure_agent_display.py +25 -6
- claude_mpm/cli/commands/mpm_init/core.py +225 -46
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +280 -0
- claude_mpm/cli/commands/postmortem.py +1 -1
- claude_mpm/cli/commands/profile.py +277 -0
- claude_mpm/cli/commands/skills.py +214 -189
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/executor.py +21 -3
- claude_mpm/cli/interactive/agent_wizard.py +85 -10
- claude_mpm/cli/parsers/agents_parser.py +54 -9
- claude_mpm/cli/parsers/auto_configure_parser.py +13 -138
- claude_mpm/cli/parsers/base_parser.py +12 -0
- claude_mpm/cli/parsers/config_parser.py +153 -83
- claude_mpm/cli/parsers/profile_parser.py +148 -0
- claude_mpm/cli/parsers/skills_parser.py +3 -2
- claude_mpm/cli/startup.py +879 -149
- claude_mpm/commands/mpm-config.md +28 -0
- claude_mpm/commands/mpm-doctor.md +9 -22
- claude_mpm/commands/mpm-help.md +5 -287
- claude_mpm/commands/mpm-init.md +81 -507
- claude_mpm/commands/mpm-monitor.md +15 -402
- claude_mpm/commands/mpm-organize.md +120 -0
- 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/config/agent_sources.py +27 -0
- claude_mpm/core/config.py +2 -4
- claude_mpm/core/framework/formatters/content_formatter.py +3 -13
- claude_mpm/core/framework/loaders/agent_loader.py +8 -5
- claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
- claude_mpm/core/framework_loader.py +4 -2
- claude_mpm/core/logger.py +13 -0
- claude_mpm/core/optimized_startup.py +59 -0
- claude_mpm/core/output_style_manager.py +173 -43
- claude_mpm/core/shared/config_loader.py +1 -1
- claude_mpm/core/socketio_pool.py +3 -3
- claude_mpm/core/unified_agent_registry.py +134 -16
- claude_mpm/core/unified_config.py +22 -0
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DjhvlsAc.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/N4qtv3Hx.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uj46x2Wr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.CAGBuiOw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/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/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +211 -78
- claude_mpm/hooks/claude_hooks/hook_handler.py +155 -1
- claude_mpm/hooks/claude_hooks/installer.py +33 -10
- claude_mpm/hooks/claude_hooks/memory_integration.py +28 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.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/hooks/claude_hooks/services/connection_manager.py +30 -6
- claude_mpm/hooks/memory_integration_hook.py +46 -1
- claude_mpm/init.py +63 -19
- claude_mpm/models/agent_definition.py +7 -0
- claude_mpm/models/git_repository.py +3 -3
- claude_mpm/scripts/claude-hook-handler.sh +58 -18
- claude_mpm/scripts/launch_monitor.py +93 -13
- claude_mpm/scripts/start_activity_logging.py +0 -0
- claude_mpm/services/agents/agent_builder.py +3 -3
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/cache_git_manager.py +6 -6
- claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
- claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -5
- claude_mpm/services/agents/deployment/agent_template_builder.py +5 -3
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +320 -29
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +546 -68
- claude_mpm/services/agents/git_source_manager.py +36 -2
- claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
- claude_mpm/services/agents/recommender.py +5 -3
- claude_mpm/services/agents/single_tier_deployment_service.py +2 -2
- claude_mpm/services/agents/sources/git_source_sync_service.py +13 -6
- claude_mpm/services/agents/startup_sync.py +22 -2
- claude_mpm/services/agents/toolchain_detector.py +10 -6
- claude_mpm/services/analysis/__init__.py +11 -1
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/command_deployment_service.py +81 -10
- claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +1 -1
- claude_mpm/services/event_bus/config.py +3 -1
- claude_mpm/services/git/git_operations_service.py +101 -16
- claude_mpm/services/monitor/daemon.py +9 -2
- claude_mpm/services/monitor/daemon_manager.py +39 -3
- claude_mpm/services/monitor/management/lifecycle.py +8 -1
- claude_mpm/services/monitor/server.py +698 -22
- claude_mpm/services/pm_skills_deployer.py +676 -0
- claude_mpm/services/profile_manager.py +331 -0
- claude_mpm/services/project/project_organizer.py +4 -0
- claude_mpm/services/self_upgrade_service.py +120 -12
- claude_mpm/services/skills/__init__.py +3 -0
- claude_mpm/services/skills/git_skill_source_manager.py +130 -2
- claude_mpm/services/skills/selective_skill_deployer.py +704 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_deployer.py +126 -9
- claude_mpm/services/socketio/dashboard_server.py +1 -0
- claude_mpm/services/socketio/event_normalizer.py +51 -6
- claude_mpm/services/socketio/server/core.py +386 -108
- claude_mpm/services/version_control/git_operations.py +103 -0
- claude_mpm/skills/skill_manager.py +92 -3
- claude_mpm/utils/agent_dependency_loader.py +14 -2
- claude_mpm/utils/agent_filters.py +17 -44
- claude_mpm/utils/gitignore.py +3 -0
- claude_mpm/utils/migration.py +4 -4
- claude_mpm/utils/robust_installer.py +47 -3
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/METADATA +57 -87
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/RECORD +160 -211
- claude_mpm-5.4.41.dist-info/entry_points.txt +5 -0
- claude_mpm-5.4.41.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.41.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
- claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
- claude_mpm/agents/BASE_OPS.md +0 -219
- claude_mpm/agents/BASE_PM.md +0 -480
- claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
- claude_mpm/agents/BASE_QA.md +0 -167
- claude_mpm/agents/BASE_RESEARCH.md +0 -53
- claude_mpm/agents/base_agent_loader.py +0 -601
- claude_mpm/cli/commands/agents_detect.py +0 -380
- claude_mpm/cli/commands/agents_recommend.py +0 -309
- claude_mpm/cli/ticket_cli.py +0 -35
- claude_mpm/commands/mpm-agents-auto-configure.md +0 -278
- claude_mpm/commands/mpm-agents-detect.md +0 -177
- claude_mpm/commands/mpm-agents-list.md +0 -131
- claude_mpm/commands/mpm-agents-recommend.md +0 -223
- claude_mpm/commands/mpm-config-view.md +0 -150
- claude_mpm/commands/mpm-ticket-organize.md +0 -304
- claude_mpm/dashboard/analysis_runner.py +0 -455
- claude_mpm/dashboard/index.html +0 -13
- claude_mpm/dashboard/open_dashboard.py +0 -66
- claude_mpm/dashboard/static/css/activity.css +0 -1958
- claude_mpm/dashboard/static/css/connection-status.css +0 -370
- claude_mpm/dashboard/static/css/dashboard.css +0 -4701
- claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
- claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
- claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
- claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
- claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
- claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
- claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
- claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
- claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
- claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
- claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
- claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
- claude_mpm/dashboard/static/js/connection-manager.js +0 -536
- claude_mpm/dashboard/static/js/dashboard.js +0 -1914
- claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/js/socket-client.js +0 -1474
- claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/socket.io.min.js +0 -7
- claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
- claude_mpm/dashboard/templates/code_simple.html +0 -153
- claude_mpm/dashboard/templates/index.html +0 -606
- claude_mpm/dashboard/test_dashboard.html +0 -372
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
- claude_mpm/scripts/mcp_server.py +0 -75
- claude_mpm/scripts/mcp_wrapper.py +0 -39
- claude_mpm/services/mcp_gateway/__init__.py +0 -159
- claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
- claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
- claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
- claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
- claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
- claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
- claude_mpm/services/mcp_gateway/core/base.py +0 -312
- claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
- claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
- claude_mpm/services/mcp_gateway/core/process_pool.py +0 -977
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
- claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
- claude_mpm/services/mcp_gateway/main.py +0 -589
- claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
- claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
- claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -414
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -712
- claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
- claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -555
- claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
- claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
- claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
- claude_mpm-5.0.9.dist-info/entry_points.txt +0 -10
- claude_mpm-5.0.9.dist-info/licenses/LICENSE +0 -21
- /claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +0 -0
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/WHEEL +0 -0
- {claude_mpm-5.0.9.dist-info → claude_mpm-5.4.41.dist-info}/top_level.txt +0 -0
|
@@ -20,7 +20,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
|
20
20
|
from datetime import datetime, timezone
|
|
21
21
|
from pathlib import Path
|
|
22
22
|
from threading import Lock
|
|
23
|
-
from typing import Any, Dict, List, Optional, Tuple
|
|
23
|
+
from typing import Any, Dict, List, Optional, Set, Tuple
|
|
24
24
|
|
|
25
25
|
from claude_mpm.config.skill_sources import SkillSource, SkillSourceConfiguration
|
|
26
26
|
from claude_mpm.core.logging_config import get_logger
|
|
@@ -989,6 +989,7 @@ class GitSkillSourceManager:
|
|
|
989
989
|
target_dir: Optional[Path] = None,
|
|
990
990
|
force: bool = False,
|
|
991
991
|
progress_callback=None,
|
|
992
|
+
skill_filter: Optional[Set[str]] = None,
|
|
992
993
|
) -> Dict[str, Any]:
|
|
993
994
|
"""Deploy skills from cache to target directory with flat structure.
|
|
994
995
|
|
|
@@ -1004,6 +1005,9 @@ class GitSkillSourceManager:
|
|
|
1004
1005
|
target_dir: Target deployment directory (default: ~/.claude/skills/)
|
|
1005
1006
|
force: Overwrite existing skills
|
|
1006
1007
|
progress_callback: Optional callback(increment: int) called for each skill deployed
|
|
1008
|
+
skill_filter: Optional set of skill names to deploy (selective deployment).
|
|
1009
|
+
If None, deploys all skills. If provided, only deploys skills
|
|
1010
|
+
whose name matches an entry in the filter set.
|
|
1007
1011
|
|
|
1008
1012
|
Returns:
|
|
1009
1013
|
Dict with deployment results:
|
|
@@ -1013,13 +1017,19 @@ class GitSkillSourceManager:
|
|
|
1013
1017
|
"failed_count": int,
|
|
1014
1018
|
"deployed_skills": List[str],
|
|
1015
1019
|
"skipped_skills": List[str],
|
|
1016
|
-
"errors": List[str]
|
|
1020
|
+
"errors": List[str],
|
|
1021
|
+
"filtered_count": int # Number of skills filtered out
|
|
1017
1022
|
}
|
|
1018
1023
|
|
|
1019
1024
|
Example:
|
|
1020
1025
|
>>> manager = GitSkillSourceManager(config)
|
|
1021
1026
|
>>> result = manager.deploy_skills()
|
|
1022
1027
|
>>> print(f"Deployed {result['deployed_count']} skills")
|
|
1028
|
+
|
|
1029
|
+
# Selective deployment based on agent requirements:
|
|
1030
|
+
>>> required = {"typescript-core", "react-patterns"}
|
|
1031
|
+
>>> result = manager.deploy_skills(skill_filter=required)
|
|
1032
|
+
>>> print(f"Deployed {result['deployed_count']} of {len(required)} required skills")
|
|
1023
1033
|
"""
|
|
1024
1034
|
if target_dir is None:
|
|
1025
1035
|
target_dir = Path.home() / ".claude" / "skills"
|
|
@@ -1029,10 +1039,60 @@ class GitSkillSourceManager:
|
|
|
1029
1039
|
deployed = []
|
|
1030
1040
|
skipped = []
|
|
1031
1041
|
errors = []
|
|
1042
|
+
filtered_count = 0
|
|
1032
1043
|
|
|
1033
1044
|
# Get all skills from all sources
|
|
1034
1045
|
all_skills = self.get_all_skills()
|
|
1035
1046
|
|
|
1047
|
+
# Apply skill filter if provided (selective deployment)
|
|
1048
|
+
if skill_filter is not None:
|
|
1049
|
+
original_count = len(all_skills)
|
|
1050
|
+
# Normalize filter to lowercase for case-insensitive matching
|
|
1051
|
+
normalized_filter = {s.lower() for s in skill_filter}
|
|
1052
|
+
|
|
1053
|
+
def matches_filter(deployment_name: str) -> bool:
|
|
1054
|
+
"""Match using same fuzzy logic as ProfileManager.is_skill_enabled()"""
|
|
1055
|
+
deployment_lower = deployment_name.lower()
|
|
1056
|
+
|
|
1057
|
+
# Exact match
|
|
1058
|
+
if deployment_lower in normalized_filter:
|
|
1059
|
+
return True
|
|
1060
|
+
|
|
1061
|
+
# Fuzzy match: check if deployment name ends with or contains short name
|
|
1062
|
+
# Example: "toolchains-python-frameworks-flask" matches "flask"
|
|
1063
|
+
for short_name in normalized_filter:
|
|
1064
|
+
if deployment_lower.endswith(f"-{short_name}"):
|
|
1065
|
+
return True
|
|
1066
|
+
# Check if short name is contained as a segment
|
|
1067
|
+
if f"-{short_name}-" in deployment_lower:
|
|
1068
|
+
return True
|
|
1069
|
+
if deployment_lower.startswith(f"{short_name}-"):
|
|
1070
|
+
return True
|
|
1071
|
+
|
|
1072
|
+
return False
|
|
1073
|
+
|
|
1074
|
+
# Match against deployment_name using fuzzy matching
|
|
1075
|
+
all_skills = [
|
|
1076
|
+
s
|
|
1077
|
+
for s in all_skills
|
|
1078
|
+
if matches_filter(s.get("deployment_name", ""))
|
|
1079
|
+
]
|
|
1080
|
+
filtered_count = original_count - len(all_skills)
|
|
1081
|
+
self.logger.info(
|
|
1082
|
+
f"Selective deployment: {len(all_skills)} of {original_count} skills "
|
|
1083
|
+
f"match agent requirements ({filtered_count} filtered out)"
|
|
1084
|
+
)
|
|
1085
|
+
|
|
1086
|
+
# Cleanup: Remove skills from target directory that aren't in the filtered set
|
|
1087
|
+
# This ensures only the skills in the profile are deployed
|
|
1088
|
+
removed_skills = self._cleanup_unfiltered_skills(
|
|
1089
|
+
target_dir, all_skills
|
|
1090
|
+
)
|
|
1091
|
+
if removed_skills:
|
|
1092
|
+
self.logger.info(
|
|
1093
|
+
f"Removed {len(removed_skills)} skills not in profile filter: {removed_skills}"
|
|
1094
|
+
)
|
|
1095
|
+
|
|
1036
1096
|
self.logger.info(
|
|
1037
1097
|
f"Deploying {len(all_skills)} skills to {target_dir} (force={force})"
|
|
1038
1098
|
)
|
|
@@ -1083,8 +1143,76 @@ class GitSkillSourceManager:
|
|
|
1083
1143
|
"deployed_skills": deployed,
|
|
1084
1144
|
"skipped_skills": skipped,
|
|
1085
1145
|
"errors": errors,
|
|
1146
|
+
"filtered_count": filtered_count,
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
def _cleanup_unfiltered_skills(
|
|
1150
|
+
self, target_dir: Path, filtered_skills: List[Dict[str, Any]]
|
|
1151
|
+
) -> List[str]:
|
|
1152
|
+
"""Remove skills from target directory that aren't in the filtered skill list.
|
|
1153
|
+
|
|
1154
|
+
Args:
|
|
1155
|
+
target_dir: Target deployment directory
|
|
1156
|
+
filtered_skills: List of skills that should remain deployed
|
|
1157
|
+
|
|
1158
|
+
Returns:
|
|
1159
|
+
List of skill names that were removed
|
|
1160
|
+
"""
|
|
1161
|
+
import shutil
|
|
1162
|
+
|
|
1163
|
+
removed_skills = []
|
|
1164
|
+
|
|
1165
|
+
# Build set of deployment names that should exist
|
|
1166
|
+
expected_deployments = {
|
|
1167
|
+
skill.get("deployment_name") for skill in filtered_skills
|
|
1168
|
+
if skill.get("deployment_name")
|
|
1086
1169
|
}
|
|
1087
1170
|
|
|
1171
|
+
# Check each directory in target_dir
|
|
1172
|
+
if not target_dir.exists():
|
|
1173
|
+
return removed_skills
|
|
1174
|
+
|
|
1175
|
+
try:
|
|
1176
|
+
for item in target_dir.iterdir():
|
|
1177
|
+
# Skip files, only process directories
|
|
1178
|
+
if not item.is_dir():
|
|
1179
|
+
continue
|
|
1180
|
+
|
|
1181
|
+
# Skip hidden directories
|
|
1182
|
+
if item.name.startswith("."):
|
|
1183
|
+
continue
|
|
1184
|
+
|
|
1185
|
+
# Check if this skill directory should be kept
|
|
1186
|
+
if item.name not in expected_deployments:
|
|
1187
|
+
try:
|
|
1188
|
+
# Security: Validate path is within target_dir
|
|
1189
|
+
if not self._validate_safe_path(target_dir, item):
|
|
1190
|
+
self.logger.error(
|
|
1191
|
+
f"Refusing to remove path outside target directory: {item}"
|
|
1192
|
+
)
|
|
1193
|
+
continue
|
|
1194
|
+
|
|
1195
|
+
# Remove the skill directory
|
|
1196
|
+
if item.is_symlink():
|
|
1197
|
+
item.unlink()
|
|
1198
|
+
else:
|
|
1199
|
+
shutil.rmtree(item)
|
|
1200
|
+
|
|
1201
|
+
removed_skills.append(item.name)
|
|
1202
|
+
self.logger.debug(
|
|
1203
|
+
f"Removed unfiltered skill: {item.name}"
|
|
1204
|
+
)
|
|
1205
|
+
|
|
1206
|
+
except Exception as e:
|
|
1207
|
+
self.logger.warning(
|
|
1208
|
+
f"Failed to remove skill directory {item.name}: {e}"
|
|
1209
|
+
)
|
|
1210
|
+
|
|
1211
|
+
except Exception as e:
|
|
1212
|
+
self.logger.error(f"Error during skill cleanup: {e}")
|
|
1213
|
+
|
|
1214
|
+
return removed_skills
|
|
1215
|
+
|
|
1088
1216
|
def _deploy_single_skill(
|
|
1089
1217
|
self, skill: Dict[str, Any], target_dir: Path, deployment_name: str, force: bool
|
|
1090
1218
|
) -> Dict[str, Any]:
|