/ mlflow / assistant / skill_installer.py
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))