54 lines
1.9 KiB
Python
54 lines
1.9 KiB
Python
"""Skills Scanner — Scan skills/ directory and generate SKILLS_SNAPSHOT.md."""
|
|
|
|
from pathlib import Path
|
|
|
|
import yaml
|
|
|
|
|
|
def discover_skills(base_dir: Path) -> list[dict]:
|
|
"""Read the native Skills catalog without changing its generated snapshot."""
|
|
root = (base_dir / "skills").resolve()
|
|
entries = []
|
|
for file in sorted(root.rglob("SKILL.md")):
|
|
resolved = file.resolve()
|
|
if not resolved.is_relative_to(root):
|
|
continue
|
|
try:
|
|
content = file.read_text(encoding="utf-8")
|
|
if not content.startswith("---"):
|
|
continue
|
|
parts = content.split("---", 2)
|
|
meta = yaml.safe_load(parts[1]) if len(parts) == 3 else None
|
|
if not isinstance(meta, dict):
|
|
continue
|
|
entries.append({"id":file.relative_to(root).as_posix(),"name":str(meta.get("name",file.parent.name)),"description":str(meta.get("description","")),"content":content})
|
|
except (OSError, ValueError, yaml.YAMLError):
|
|
continue
|
|
return entries
|
|
|
|
|
|
def scan_skills(base_dir: Path) -> str:
|
|
"""Scan all SKILL.md files and generate SKILLS_SNAPSHOT.md."""
|
|
skills_dir = base_dir / "skills"
|
|
snapshot_path = base_dir / "SKILLS_SNAPSHOT.md"
|
|
|
|
if not skills_dir.exists():
|
|
skills_dir.mkdir(parents=True)
|
|
|
|
skills = [{**s, "location":f"./backend/skills/{s['id']}"} for s in discover_skills(base_dir)]
|
|
|
|
# Build XML-style snapshot
|
|
lines = ["<available_skills>"]
|
|
for s in skills:
|
|
lines.append(" <skill>")
|
|
lines.append(f" <name>{s['name']}</name>")
|
|
lines.append(f" <description>{s['description']}</description>")
|
|
lines.append(f" <location>{s['location']}</location>")
|
|
lines.append(" </skill>")
|
|
lines.append("</available_skills>")
|
|
|
|
snapshot = "\n".join(lines)
|
|
snapshot_path.write_text(snapshot, encoding="utf-8")
|
|
print(f"📋 Skills snapshot: {len(skills)} skills found")
|
|
return snapshot
|