mirror of
https://github.com/HKUDS/CLI-Anything.git
synced 2026-09-18 23:42:43 +08:00
bc536c9beb
validate_root_skills.py compared source and mirror with a symmetric `!=`, so it detected divergence but never direction, and printed the same advice either way: "Run sync_root_skills.py and commit." That advice is only correct when the harness source moved ahead. When the edit is in the generated skills/ mirror -- as in #360 -- sync regenerates the mirror from the source and silently deletes the change. The validator then passes, so CI turns green and certifies the loss. Detect the direction. When the mirror holds lines the source lacks, name them, point at the source file, and never suggest the destructive command. Regenerable drift keeps the old advice. Also make sync_root_skills.py report each file it creates or overwrites instead of writing in silence. Verified: in-sync, mirror-edited, source-edited, missing-mirror, and idempotent no-op.
94 lines
3.0 KiB
Python
94 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Sync repo-root skills/ from harness-local SKILL.md files."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
ROOT_SKILLS_DIR = REPO_ROOT / "skills"
|
|
|
|
|
|
def _canonical_skill_id(source: Path) -> str:
|
|
rel = source.relative_to(REPO_ROOT)
|
|
parts = rel.parts
|
|
if "cli_anything" in parts:
|
|
package_index = parts.index("cli_anything") + 1
|
|
if package_index < len(parts):
|
|
package_name = parts[package_index]
|
|
return f"cli-anything-{package_name.replace('_', '-')}"
|
|
|
|
software_dir = parts[0]
|
|
return f"cli-anything-{software_dir.replace('_', '-')}"
|
|
|
|
|
|
def _rewrite_name_frontmatter(content: str, skill_id: str) -> str:
|
|
if not content.startswith("---\n"):
|
|
return content
|
|
|
|
parts = content.split("---\n", 2)
|
|
if len(parts) < 3:
|
|
return content
|
|
|
|
_, frontmatter, body = parts
|
|
lines = frontmatter.splitlines(keepends=True)
|
|
rewritten: list[str] = []
|
|
replaced = False
|
|
i = 0
|
|
while i < len(lines):
|
|
line = lines[i]
|
|
if not replaced and line.startswith("name:"):
|
|
rewritten.append(f'name: "{skill_id}"\n')
|
|
replaced = True
|
|
i += 1
|
|
while i < len(lines) and (lines[i].startswith(" ") or lines[i].startswith("\t")):
|
|
i += 1
|
|
continue
|
|
rewritten.append(line)
|
|
i += 1
|
|
|
|
if not replaced:
|
|
rewritten.insert(0, f'name: "{skill_id}"\n')
|
|
|
|
frontmatter = "".join(rewritten)
|
|
return f"---\n{frontmatter}---\n{body}"
|
|
|
|
|
|
def _discover_sources() -> list[Path]:
|
|
sources: list[Path] = []
|
|
sources.extend(sorted(REPO_ROOT.glob("*/agent-harness/cli_anything/*/skills/SKILL.md")))
|
|
sources.extend(sorted(REPO_ROOT.glob("*/agent-harness/cli_anything/*/SKILL.md")))
|
|
return [path for path in sources if path.is_file()]
|
|
|
|
|
|
def main() -> int:
|
|
sources = _discover_sources()
|
|
ROOT_SKILLS_DIR.mkdir(parents=True, exist_ok=True)
|
|
|
|
written = 0
|
|
for source in sources:
|
|
skill_id = _canonical_skill_id(source)
|
|
target = ROOT_SKILLS_DIR / skill_id / "SKILL.md"
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
content = source.read_text(encoding="utf-8")
|
|
expected = _rewrite_name_frontmatter(content, skill_id)
|
|
|
|
if target.is_file() and target.read_text(encoding="utf-8") == expected:
|
|
continue
|
|
|
|
# Overwriting is destructive: the mirror may hold edits the source lacks.
|
|
# Say so, so the loss is never silent. validate_root_skills.py refuses
|
|
# in that direction before CI ever reaches here.
|
|
action = "overwrite" if target.is_file() else "create"
|
|
print(f"{action}: {target.relative_to(REPO_ROOT)} <- {source.relative_to(REPO_ROOT)}")
|
|
target.write_text(expected, encoding="utf-8")
|
|
written += 1
|
|
|
|
print(f"Synced {written} root skill(s); {len(sources) - written} already up to date.")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|