| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- from __future__ import annotations
- import re
- from pathlib import Path
- from supply_agent.types import SkillInfo
- class SkillLoader:
- """Load skills from SKILL.md files (Cursor-compatible format)."""
- SKILL_FILENAME = "SKILL.md"
- def __init__(self, skills_dir: Path | str) -> None:
- self.skills_dir = Path(skills_dir)
- def discover(self) -> list[Path]:
- """Find all SKILL.md files in the skills directory."""
- if not self.skills_dir.exists():
- return []
- return sorted(self.skills_dir.rglob(self.SKILL_FILENAME))
- def load(self, skill_path: Path) -> SkillInfo:
- """Load a single skill from a SKILL.md file."""
- content = skill_path.read_text(encoding="utf-8")
- name, description = self._parse_frontmatter(content, skill_path)
- body = self._strip_frontmatter(content)
- return SkillInfo(
- name=name,
- description=description,
- content=body.strip(),
- path=str(skill_path),
- )
- def load_all(self) -> list[SkillInfo]:
- """Load all discovered skills."""
- return [self.load(p) for p in self.discover()]
- def _parse_frontmatter(self, content: str, path: Path) -> tuple[str, str]:
- """Extract name and description from YAML frontmatter or heading."""
- name = path.parent.name
- description = ""
- fm_match = re.match(r"^---\s*\n(.*?)\n---", content, re.DOTALL)
- if fm_match:
- fm = fm_match.group(1)
- for line in fm.splitlines():
- if line.startswith("name:"):
- name = line.split(":", 1)[1].strip().strip('"').strip("'")
- elif line.startswith("description:"):
- description = line.split(":", 1)[1].strip().strip('"').strip("'")
- return name, description
- # Fallback: use directory name; extract description from first paragraph if present
- return name, description
- def _strip_frontmatter(self, content: str) -> str:
- return re.sub(r"^---\s*\n.*?\n---\s*\n?", "", content, count=1, flags=re.DOTALL)
|