feat: support registry collections and docker publishing

This commit is contained in:
2026-07-27 23:25:46 +08:00
parent b78126830b
commit 983183d5b3
13 changed files with 891 additions and 53 deletions
+49
View File
@@ -56,3 +56,52 @@ def external_skill_path(name: str, entry: dict[str, Any] | None = None) -> Path:
f"registry 条目 {name!r} 的 path 超出外部仓库: {subpath!r}"
) from exc
return skill_path
def discover_external_skills(
name: str,
entry: dict[str, Any] | None = None,
) -> dict[str, Path]:
"""Discover a single registry skill or a collection of sibling skills."""
entry = entry or load_registry().get(name, {})
root = external_skill_path(name, entry)
if (root / "SKILL.md").is_file():
return {name: root}
if not root.is_dir():
return {}
resolved_root = root.resolve()
skills: dict[str, Path] = {}
for item in sorted(root.iterdir()):
skill_md = item / "SKILL.md"
if (
item.name.startswith("_")
or item.is_symlink()
or not item.is_dir()
or skill_md.is_symlink()
or not skill_md.is_file()
):
continue
resolved_item = item.resolve()
resolved_skill_md = skill_md.resolve()
try:
resolved_item.relative_to(resolved_root)
resolved_skill_md.relative_to(resolved_item)
except ValueError:
continue
skills[item.name] = item
return skills
def external_collection_skill_path(
collection: str,
skill_name: str,
entry: dict[str, Any] | None = None,
) -> Path:
skills = discover_external_skills(collection, entry)
if skill_name not in skills:
available = ", ".join(skills) or "(无)"
raise SystemExit(
f"registry collection {collection!r} 中找不到 skill {skill_name!r}"
f"可用: {available}"
)
return skills[skill_name]