skill_installer.py
1 """ 2 Manage skill installation 3 4 Skills are maintained in the mlflow/assistant/skills subtree in the MLflow repository, 5 which points to the https://github.com/mlflow/skills repository. 6 """ 7 8 import shutil 9 from importlib import resources 10 from pathlib import Path 11 12 SKILL_MANIFEST_FILE = "SKILL.md" 13 14 15 def _find_skill_directories(path: Path) -> list[Path]: 16 return [item.parent for item in path.rglob(SKILL_MANIFEST_FILE)] 17 18 19 def install_skills(destination_path: Path) -> list[str]: 20 """ 21 Install MLflow skills to the specified destination path (e.g., ~/.claude/skills). 22 23 Args: 24 destination_path: The path where skills should be installed. 25 26 Returns: 27 A list of installed skill names. 28 """ 29 destination_dir = destination_path.expanduser() 30 skills_pkg = resources.files("mlflow.assistant.skills") 31 installed_skills = [] 32 33 for item in skills_pkg.iterdir(): 34 if not item.is_dir(): 35 continue 36 skill_manifest = item.joinpath(SKILL_MANIFEST_FILE) 37 if not skill_manifest.is_file(): 38 continue 39 40 # Use resources.as_file() on the manifest to get a real path 41 with resources.as_file(skill_manifest) as manifest_path: 42 skill_dir = manifest_path.parent 43 target_dir = destination_dir / skill_dir.name 44 destination_dir.mkdir(parents=True, exist_ok=True) 45 shutil.copytree(skill_dir, target_dir, dirs_exist_ok=True) 46 installed_skills.append(skill_dir.name) 47 48 return sorted(installed_skills) 49 50 51 def list_installed_skills(destination_path: Path) -> list[str]: 52 """ 53 List installed skills in the specified destination path. 54 55 Args: 56 destination_path: The path where skills are installed. 57 58 Returns: 59 A list of installed skill names. 60 """ 61 if not destination_path.exists(): 62 return [] 63 return sorted(d.name for d in _find_skill_directories(destination_path))