📦 deps(thirdparty): update snapshots

This commit is contained in:
ci[bot]
2026-08-31 05:00:46 +08:00
parent 8fea3d18fe
commit 0b2b056032
347 changed files with 38446 additions and 136 deletions
@@ -0,0 +1,113 @@
#!/usr/bin/env python3
"""validate_skill_pack.py — 纯确定性 Skill 包静态校验(Phase 0 工具,不调用模型)。
校验内容:
1. 每个含 SKILL.md 的目录视为一个 Skillfrontmatter 必须可解析且含非空 name/description
2. name 建议匹配 ^[a-z0-9][a-z0-9-]*$ 且与目录名一致(不一致仅告警);
3. 全部 .md 文件必须是合法 UTF-8;
4. 全部 .md 文件中的相对引用(markdown 链接与裸 references/... 路径)必须存在;
5. 输出每个 Skill 的行数/字节数概览。
用法: python3 scripts/validate_skill_pack.py <dir> [<dir> ...]
退出码: 0 = 无 ERROR1 = 存在 ERROR。
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
import yaml
MD_LINK_RE = re.compile(r"\]\(([^)#\s]+?)(?:#[^)\s]*)?\)")
BARE_REF_RE = re.compile(r"(?<![\w/(])((?:references|assets)/[\w\-./]+\.[a-zA-Z0-9]+)")
NAME_RE = re.compile(r"^[a-z0-9][a-z0-9-]*$")
errors: list[str] = []
warnings: list[str] = []
def parse_frontmatter(text: str) -> dict | None:
if not text.startswith("---"):
return None
end = text.find("\n---", 3)
if end == -1:
return None
try:
data = yaml.safe_load(text[3:end])
except yaml.YAMLError:
return None
return data if isinstance(data, dict) else None
def check_links(md_path: Path, text: str) -> None:
base = md_path.parent
seen: set[str] = set()
for regex in (MD_LINK_RE, BARE_REF_RE):
for m in regex.finditer(text):
target = m.group(1).strip()
if target in seen:
continue
seen.add(target)
if target.startswith(("http://", "https://", "mailto:", "/")):
continue
if not (base / target).exists():
errors.append(f"[broken-ref] {md_path}: `{target}` 不存在")
def check_skill(skill_md: Path) -> None:
text = skill_md.read_text(encoding="utf-8")
fm = parse_frontmatter(text)
if fm is None:
errors.append(f"[frontmatter] {skill_md}: frontmatter 缺失或不可解析")
return
name = fm.get("name")
desc = fm.get("description")
if not (isinstance(name, str) and name.strip()):
errors.append(f"[frontmatter] {skill_md}: 缺少非空 name")
else:
if not NAME_RE.match(name):
warnings.append(f"[name-style] {skill_md}: name `{name}` 不符合小写连字符风格")
if name != skill_md.parent.name:
warnings.append(f"[name-dir] {skill_md}: name `{name}` 与目录名 `{skill_md.parent.name}` 不一致")
if not (isinstance(desc, str) and desc.strip()):
errors.append(f"[frontmatter] {skill_md}: 缺少非空 description")
def main(argv: list[str]) -> int:
if len(argv) < 2:
print(__doc__)
return 2
skill_count = 0
md_count = 0
for root_arg in argv[1:]:
root = Path(root_arg)
if not root.is_dir():
errors.append(f"[input] 目录不存在: {root}")
continue
for md in sorted(root.rglob("*.md")):
md_count += 1
try:
text = md.read_text(encoding="utf-8")
except UnicodeDecodeError:
errors.append(f"[encoding] {md}: 非法 UTF-8")
continue
check_links(md, text)
if md.name == "SKILL.md":
skill_count += 1
check_skill(md)
lines = text.count("\n") + 1
print(f" skill: {md.parent.name:<28} {lines:>4}{len(text.encode('utf-8')):>7} 字节")
print(f"\n共扫描 {md_count} 个 .md,其中 {skill_count} 个 SKILL.md")
for w in warnings:
print(f"WARN {w}")
for e in errors:
print(f"ERROR {e}")
print(f"\n结果: {len(errors)} errors, {len(warnings)} warnings")
return 1 if errors else 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv))