#!/usr/bin/env python3 import argparse import html import json import re from datetime import date from pathlib import Path try: import yaml except ImportError: # pragma: no cover yaml = None KNOWN_ENTRIES = [ ("SKILL.md", "Skill entrypoint"), ("README.md", "Human-readable usage guide"), ("agents/interface.yaml", "Neutral interface metadata"), ("manifest.json", "Lifecycle and portability metadata"), ("references", "Extended guidance and reusable notes"), ("scripts", "Deterministic helpers or local tooling"), ("evals", "Trigger and quality checks"), ("reports", "Generated evidence and overview artifacts"), ] def parse_frontmatter(text: str) -> tuple[dict, str]: lines = text.splitlines() if not lines or lines[0].strip() != "---": return {}, text try: end_index = lines[1:].index("---") + 1 except ValueError: return {}, text frontmatter_text = "\n".join(lines[1:end_index]) body = "\n".join(lines[end_index + 1 :]).lstrip() if yaml is not None: data = yaml.safe_load(frontmatter_text) or {} return data if isinstance(data, dict) else {}, body data = {} for line in frontmatter_text.splitlines(): if ":" not in line: continue key, value = line.split(":", 1) data[key.strip()] = value.strip().strip('"') return data, body def load_yaml(path: Path) -> dict: if not path.exists(): return {} text = path.read_text(encoding="utf-8") if yaml is not None: payload = yaml.safe_load(text) or {} return payload if isinstance(payload, dict) else {} return {} def load_json(path: Path) -> dict: if not path.exists(): return {} return json.loads(path.read_text(encoding="utf-8")) def load_benchmark(skill_dir: Path) -> dict: return load_json(skill_dir / "reports" / "github-benchmark-scan.json") def load_reference_synthesis(skill_dir: Path) -> dict: return load_json(skill_dir / "reports" / "reference-synthesis.json") def extract_title(body: str, fallback: str) -> str: for line in body.splitlines(): if line.startswith("# "): return line[2:].strip() return fallback def parse_sections(body: str) -> dict[str, str]: sections: dict[str, list[str]] = {} current = "_preamble" sections[current] = [] for line in body.splitlines(): if line.startswith("## "): current = line[3:].strip() sections[current] = [] continue sections[current].append(line) return {name: "\n".join(lines).strip() for name, lines in sections.items()} def extract_list_items(text: str) -> list[str]: items = [] for line in text.splitlines(): stripped = line.strip() if not stripped: continue ordered = re.match(r"^\d+\.\s+(.*)$", stripped) bullet = re.match(r"^[-*]\s+(.*)$", stripped) match = ordered or bullet if match: items.append(match.group(1).strip()) return items def summarize_logic(sections: dict[str, str]) -> list[str]: for key in ("Compact Workflow", "Workflow", "How It Works", "Logic", "Quick Start"): if key in sections: items = extract_list_items(sections[key]) if items: return items[:5] preamble_items = extract_list_items(sections.get("_preamble", "")) return preamble_items[:5] def summarize_usage(sections: dict[str, str], default_prompt: str, description: str) -> list[str]: usage = [] for key in ("How To Use", "Quick Start", "Usage", "Runbook"): if key in sections: usage = extract_list_items(sections[key]) if usage: return usage[:5] if default_prompt: usage.append(default_prompt) usage.append(f"Use this skill when the request matches: {description}") return usage[:4] def package_entries(skill_dir: Path) -> list[dict]: items = [] for rel_path, label in KNOWN_ENTRIES: target = skill_dir / rel_path if target.exists(): kind = "folder" if target.is_dir() else "file" items.append({"path": rel_path, "label": label, "kind": kind}) return items def derive_strengths(skill_dir: Path, metadata: dict) -> list[str]: strengths = ["Lean trigger surface anchored in frontmatter description."] if (skill_dir / "agents" / "interface.yaml").exists(): strengths.append("Portable interface metadata is already packaged for adapter-based export.") if (skill_dir / "references").exists() and any((skill_dir / "references").iterdir()): strengths.append("Long guidance is separated into references so the entrypoint can stay compact.") if (skill_dir / "scripts").exists() and any((skill_dir / "scripts").iterdir()): strengths.append("Deterministic helpers are packaged with the skill instead of hidden in prompt text.") if (skill_dir / "evals").exists() and any((skill_dir / "evals").iterdir()): strengths.append("The package includes quality gates or trigger checks that can travel with the skill.") if metadata.get("maturity_tier"): strengths.append(f"Lifecycle metadata is explicit, with maturity tier set to `{metadata['maturity_tier']}`.") return strengths[:5] def card_items(interface_data: dict, logic_steps: list[str], package_map: list[dict], usage_steps: list[str], description: str) -> list[dict]: compatibility = interface_data.get("compatibility", {}) execution = compatibility.get("execution", {}) activation = compatibility.get("activation", {}) return [ { "title": "Trigger", "body": description, "meta": [ f"Activation: {activation.get('mode', 'manual')}", f"Context: {execution.get('context', 'inline')}", ], }, { "title": "Logic", "body": logic_steps or ["Understand the request", "Execute the task", "Validate the result"], "meta": [], }, { "title": "Usage", "body": usage_steps, "meta": [], }, { "title": "Package", "body": [entry["path"] for entry in package_map[:6]], "meta": [f"{len(package_map)} structured entries detected"], }, ] def introduction_lines(description: str) -> list[str]: return [ f"This skill is designed to handle: {description}", "Start by clarifying the recurring job, the real input shape, and the output that lets the next person keep moving.", "If the idea is still fuzzy, use the intent dialogue first and let the structure come second.", ] def benchmark_highlights(benchmark: dict) -> list[dict]: highlights = [] for repo in benchmark.get("repositories", [])[:3]: highlights.append( { "name": repo.get("full_name", "Unknown repo"), "borrow": repo.get("borrow", [])[:2], "avoid": repo.get("avoid", [])[:1], } ) return highlights def synthesis_highlights(synthesis: dict) -> list[str]: return synthesis.get("synthesis", {}).get("borrow_now", [])[:3] def build_summary(skill_dir: Path) -> dict: skill_text = (skill_dir / "SKILL.md").read_text(encoding="utf-8") frontmatter, body = parse_frontmatter(skill_text) interface_data = load_yaml(skill_dir / "agents" / "interface.yaml") manifest = load_json(skill_dir / "manifest.json") sections = parse_sections(body) name = frontmatter.get("name", skill_dir.name) description = frontmatter.get("description", "No description found.") title = extract_title(body, name.replace("-", " ").title()) display_name = interface_data.get("interface", {}).get("display_name", title) default_prompt = interface_data.get("interface", {}).get("default_prompt", "") logic_steps = summarize_logic(sections) usage_steps = summarize_usage(sections, default_prompt, description) package_map = package_entries(skill_dir) strengths = derive_strengths(skill_dir, manifest) benchmark = load_benchmark(skill_dir) reference_synthesis = load_reference_synthesis(skill_dir) return { "name": name, "title": title, "display_name": display_name, "description": description, "logic_steps": logic_steps, "usage_steps": usage_steps, "package_map": package_map, "strengths": strengths, "cards": card_items(interface_data, logic_steps, package_map, usage_steps, description), "introduction": introduction_lines(description), "benchmark_highlights": benchmark_highlights(benchmark), "synthesis_highlights": synthesis_highlights(reference_synthesis), "metadata": { "canonical_format": interface_data.get("compatibility", {}).get("canonical_format", "agent-skills"), "targets": interface_data.get("compatibility", {}).get("adapter_targets", []), "maturity_tier": manifest.get("maturity_tier", "scaffold"), "skill_archetype": manifest.get("skill_archetype", manifest.get("maturity_tier", "scaffold")), "updated_at": manifest.get("updated_at", str(date.today())), }, } def render_card_body(card: dict) -> str: body = card["body"] if isinstance(body, list): items = "".join(f"
  • {html.escape(str(item))}
  • " for item in body) body_html = f"
      {items}
    " else: body_html = f"

    {html.escape(str(body))}

    " meta = "".join(f"{html.escape(str(item))}" for item in card.get("meta", [])) meta_html = f"
    {meta}
    " if meta else "" return f"

    {html.escape(card['title'])}

    {body_html}{meta_html}
    " def render_html(summary: dict) -> str: target_badges = "".join(f"{html.escape(str(target))}" for target in summary["metadata"]["targets"]) cards_html = "".join(render_card_body(card) for card in summary["cards"]) strengths_html = "".join(f"
  • {html.escape(item)}
  • " for item in summary["strengths"]) introduction_html = "".join(f"
  • {html.escape(item)}
  • " for item in summary.get("introduction", [])) package_rows = "".join( f"{html.escape(item['path'])}{html.escape(item['label'])}{html.escape(item['kind'])}" for item in summary["package_map"] ) benchmark_cards = "".join( ( "
    " f"

    {html.escape(item['name'])}

    " "

    Borrow now

    " + ("" if item.get("borrow") else "

    None yet.

    ") + "

    Avoid

    " + ("" if item.get("avoid") else "

    None yet.

    ") + "
    " ) for item in summary.get("benchmark_highlights", []) ) synthesis_html = "".join(f"
  • {html.escape(item)}
  • " for item in summary.get("synthesis_highlights", [])) return f""" {html.escape(summary['display_name'])} Overview

    Skill Overview

    {html.escape(summary["display_name"])}

    {html.escape(summary["description"])}

    Skill name: {html.escape(summary["name"])} Maturity: {html.escape(summary["metadata"]["maturity_tier"])} Format: {html.escape(summary["metadata"]["canonical_format"])} Updated: {html.escape(summary["metadata"]["updated_at"])}
    {target_badges}

    Architecture

    One clear flow: define the boundary, choose the right structure, run the checks, then ship a reusable package.

    {cards_html}

    How to introduce this skill

    Use this section when a first-time reader needs the shape and intent quickly, before reading the full package.

      {introduction_html}

    Why It Works

    These are the strengths the package already makes explicit instead of leaving hidden in prompt text.

      {strengths_html}

    Package Map

    Use this map to understand what lives where before you read the whole package.

    {package_rows}
    PathRoleType

    Patterns worth borrowing now

    If a GitHub benchmark scan exists, surface the strongest borrow and avoid cues here instead of hiding them in raw report files.

    {benchmark_cards or "

    No benchmark scan recorded yet. Run the GitHub benchmark scan first.

    "}

    Reference synthesis

    These are the strongest cross-source patterns to borrow now after combining GitHub benchmarks with curated official, research, and principle tracks.

      {synthesis_html or "
    • No synthesis has been generated yet. Run the reference synthesis after the benchmark scan.
    • "}
    """ def render_skill_overview(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-overview.html" output_json = output_json or reports_dir / "skill-overview.json" summary = build_summary(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), }, "summary": summary, } def main() -> None: parser = argparse.ArgumentParser(description="Render a visual overview 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_overview( 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()