feat: add skiff
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
"""自研 skill 发现与解析。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from skiff.paths import SKILLS_DIR, TEMPLATE_DIR, ensure_skills_home
|
||||
from skiff.registry import external_skill_path, load_registry
|
||||
|
||||
|
||||
def list_owned_skills() -> list[str]:
|
||||
ensure_skills_home()
|
||||
if not SKILLS_DIR.is_dir():
|
||||
return []
|
||||
names: list[str] = []
|
||||
for entry in sorted(SKILLS_DIR.iterdir()):
|
||||
if not entry.is_dir():
|
||||
continue
|
||||
if entry.name.startswith("_"):
|
||||
continue
|
||||
if (entry / "SKILL.md").is_file():
|
||||
names.append(entry.name)
|
||||
return names
|
||||
|
||||
|
||||
def owned_skill_path(name: str) -> Path:
|
||||
path = SKILLS_DIR / name
|
||||
if not (path / "SKILL.md").is_file():
|
||||
raise SystemExit(f"自研 skill 不存在: {name}")
|
||||
return path
|
||||
|
||||
|
||||
def resolve_skill_source(name: str, *, source: str | None = None) -> tuple[Path, str]:
|
||||
"""返回 (skill_path, kind),kind 为 owned 或 external。"""
|
||||
ensure_skills_home()
|
||||
|
||||
owned = SKILLS_DIR / name
|
||||
if source in (None, "owned") and (owned / "SKILL.md").is_file():
|
||||
return owned, "owned"
|
||||
|
||||
registry = load_registry()
|
||||
if source in (None, "registry") and name in registry:
|
||||
path = external_skill_path(name, registry[name])
|
||||
if not path.exists():
|
||||
raise SystemExit(
|
||||
f"外部 skill {name!r} 尚未 fetch。请先运行: skiff fetch {name}"
|
||||
)
|
||||
return path, "external"
|
||||
|
||||
if (owned / "SKILL.md").is_file():
|
||||
return owned, "owned"
|
||||
|
||||
raise SystemExit(f"找不到 skill: {name}")
|
||||
|
||||
|
||||
def validate_skill_name(name: str) -> None:
|
||||
import re
|
||||
|
||||
if not re.fullmatch(r"[a-z0-9]+(?:-[a-z0-9]+)*", name):
|
||||
raise SystemExit(
|
||||
f"skill 名称无效: {name!r}(小写 + 连字符,如 security-review)"
|
||||
)
|
||||
if name == "_template":
|
||||
raise SystemExit("不能使用保留名 _template")
|
||||
Reference in New Issue
Block a user