Files
yao-meta-skill/scripts/render_skill_interpretation.py
T
YAO 31ce04c655 Split meta skill CLI and review gates
Merge the beta-ready Yao Meta Skill architecture, report, evidence gate, and release-boundary updates.\n\nRelease boundary: beta/public testing is allowed; formal world-class, fully reviewed, or superiority claims remain blocked until the pending evidence gates are accepted.
2026-06-17 18:43:02 +08:00

109 lines
4.2 KiB
Python

#!/usr/bin/env python3
import argparse
import json
from pathlib import Path
from render_skill_overview import render_html
from skill_report_model import build_report_model
SCRIPT_INTERFACE = "cli"
SCRIPT_INTERFACE_REASON = "Renders the first-class skill interpretation report while reusing the Skill Overview v2 model and layout."
def build_interpretation_model(skill_dir: Path) -> dict:
summary = build_report_model(skill_dir)
contract = dict(summary.get("report_contract", {}))
contract.update(
{
"schema_version": "2.0",
"report_kind": "skill-interpretation",
"canonical_overview_report": "reports/skill-overview.html",
"html_report": "reports/skill-interpretation.html",
"json_report": "reports/skill-interpretation.json",
"layout": "kami-white-audit-v2",
"default_language": "zh-CN",
"languages": ["zh-CN", "en"],
"purpose": "Explain the generated skill's role, principles, usage scenarios, trigger contract, inputs, outputs, quality evidence, risks, assets, highlights, and next upgrade directions.",
}
)
summary["report_contract"] = contract
summary["interpretation_contract"] = {
"schema_version": "2.0",
"source_model": "skill-overview-v2",
"source_model_reused": True,
"overview_report": "reports/skill-overview.html",
"html_report": "reports/skill-interpretation.html",
"json_report": "reports/skill-interpretation.json",
"default_language": "zh-CN",
"languages": ["zh-CN", "en"],
"includes": [
"skill role",
"principles",
"usage scenarios",
"trigger contract",
"inputs and outputs",
"quality evidence",
"risk governance",
"package assets",
"highlights",
"upgrade roadmap",
],
}
deliverables = summary.get("skill_summary", {}).get("deliverables", [])
for artifact in ["reports/skill-interpretation.html", "reports/skill-interpretation.json"]:
if artifact not in deliverables:
deliverables.append(artifact)
if "skill_summary" in summary:
summary["skill_summary"]["deliverables"] = deliverables
return summary
def render_skill_interpretation(skill_dir: Path, output_html: Path | None = None, output_json: Path | None = None) -> dict:
skill_dir = skill_dir.resolve()
reports_dir = skill_dir / "reports"
reports_dir.mkdir(parents=True, exist_ok=True)
output_html = output_html or reports_dir / "skill-interpretation.html"
output_json = output_json or reports_dir / "skill-interpretation.json"
summary = build_interpretation_model(skill_dir)
output_html.write_text(render_html(summary), encoding="utf-8")
output_json.write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
return {
"ok": True,
"skill_dir": str(skill_dir),
"artifacts": {
"html": str(output_html),
"json": str(output_json),
"overview_html": str(skill_dir / "reports" / "skill-overview.html"),
},
"summary": {
"name": summary.get("name"),
"report_kind": summary.get("report_contract", {}).get("report_kind"),
"default_language": summary.get("report_contract", {}).get("default_language"),
"section_count": len(summary.get("report_contract", {}).get("nav_labels", [])),
"source_model_reused": summary.get("interpretation_contract", {}).get("source_model_reused"),
},
}
def main() -> None:
parser = argparse.ArgumentParser(description="Render the first-class HTML skill interpretation report for a skill package.")
parser.add_argument("skill_dir", nargs="?", default=".")
parser.add_argument("--output-html")
parser.add_argument("--output-json")
args = parser.parse_args()
result = render_skill_interpretation(
Path(args.skill_dir),
Path(args.output_html).resolve() if args.output_html else None,
Path(args.output_json).resolve() if args.output_json else None,
)
print(json.dumps(result, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()