repo-visuals
Turn a repo (GitHub URL, local folder, or free-text brief) into a hero visual that a viewer sees at the top of the README and instantly understands what this project does and why it's interesting. The hero may be an animated GIF, a static PNG, or an animated SVG — the skill recommends one based on the repo's identity, the user picks.
The skill's quality comes from the discovery dialog, not from templates. Every hero is bespoke.
Phases
- Discovery — pick operating mode (Auto / Semi-auto / Manual, §1.1a), scan the repo, summarize findings, recommend a format (animated vs static), ask about vibe/audience/hero moment, propose 2–3 scenarios, converge on a brief. Then Gate A — brief vs README (§1.8): narrow repo-context check on the brief before any pixels exist. The mode controls how many of these the user answers vs. Claude decides silently — it does not skip any of the craft checks.
- Build — write HTML/CSS/JS for the chosen scenario. For static, design one decisive frame; for animated, a loop. No storyboard step. Then Gate B — rendered HTML vs README (§2.6): sample keyframes from the HTML, check what's on screen against the repo's own positioning, allow 1 auto-iteration if it fails. Both gates are deliberately narrow — only repo-context fidelity, not aesthetics or craft.
- Preview & iterate — open the HTML in the user's default browser, iterate in text until the user says ship.
- Export — animated GIF → Puppeteer screencast + ffmpeg palette pipeline. Static PNG → Puppeteer
page.screenshot(withdeviceScaleFactor: 2for retina crispness). Animated SVG → author the SVG directly (CSS@keyframesor SMIL<animate>inside the file); no rasterization step — the source is the artifact. - Output — place the hero in the target repo; optionally open a PR that embeds it in the README.
Dev mode (author-only): Phase 6 — Evaluate exists but only runs in dev mode. Dev mode is for the skill's author iterating on the skill itself; it collects scorecard data and writes run logs under ./evaluations/ in the user's current working directory. Enable it only when the user explicitly says "dev mode" (or sets REPO_VISUALS_DEV=1). In every normal run — including Manual, Semi-auto, and Auto — the skill ends after Phase 5. Do not mention Phase 6 to end users.
Phase 1 — Discovery
Discovery runs before any HTML is written. Its job: go from a vague ask ("make a hero GIF for my repo") to a specific, committed creative brief.
1.1 Activation
Enter discovery mode whenever the user invokes the skill, unless they explicitly say "skip discovery, I have the brief ready."
1.1a Operating mode (ask first, once per run)
Before anything else — before the scan summary, before any direction questions — ask the user which operating mode they want for this run. Use the AskUserQuestion tool so the choice is structured and visible, not buried in free text. Offer three modes; describe each in concrete terms (what gets asked, what gets decided silently) and include pros/cons so the user can pick with open eyes. Default recommendation: Semi-auto.
Note: this "operating mode" is a skill-level concept about how many questions the skill asks. It is distinct from the Claude Code harness's own auto-mode; the two do not replace each other.
Verbatim AskUserQuestion shape (Run mode header, three labeled options with pros/cons): craft/snippets/operating-mode-question.md. Paste as-is; option text is load-bearing.
Rules that apply to every mode regardless of choice (craft non-negotiables):
- §1.3 inventory count is always collected. Auto/semi don't skip it.
- §4.0 scope-match rule is always enforced. If the hero says "all" or shows a grid, on-screen reality must match the real inventory — regardless of mode.
- §1.8 Gate A and §1.8b Gate B are always run on the brief. Gate A covers repo-fidelity, Gate B covers aesthetic-identity match and the wow check. Auto/semi don't skip them before writing HTML.
- §3.0a / §4.4a render self-critique is always run. Every rendered HTML preview screenshot and every exported PNG/GIF gets read and bullet-critiqued before being shown to the user. The user is not the QA pass.
- Any mode can be upgraded mid-run. If Auto drifts, user can say "stop, switch to semi" and we resume from the nearest decision point. Do not silently re-ask everything; pick up at the next unanswered question.
After the user picks a mode, commit it to memory for the run (e.g. "Mode: Semi-auto") and reference it when deciding whether to ask or decide silently at each subsequent step. In Auto and Semi-auto, make decisions with a brief one-line note ("going with the Product-UI marketing archetype per §1.4c — amplication-shape repo") so the user can redirect if they disagree.
1.2 Input triage
User may provide:
- GitHub URL → clone shallow, plus use
gh repo viewfor stars/topics/languages/releases. - Local path → scan the tree directly.
- Free-text brief only → proceed to direction questions immediately.
- Nothing → ask first for one of the above.
1.3 Scan checklist (collect a lot)
Gather as much as possible before asking the user anything. Goal: Claude should already have an opinion about what this repo is before the vibe conversation starts.
- README (full text) — extract tagline from first paragraph.
- Manifest(s):
package.json,Cargo.toml,pyproject.toml,go.mod,*.csproj, etc. — description, keywords, dependencies, entry points. - File tree (depth 3) + top 10 files by size.
- Language breakdown (LOC per language).
- Existing visuals in repo:
assets/,docs/,.github/,public/, any*.png/*.gif/*.svgnear the root. - Brand logo — find it, don't invent it. Look in this order, stop at the first hit: (1) repo files:
public/,assets/,.github/,docs/forlogo.*,favicon.*,icon.*,brand.*; (2) README<img>/srcsetentries near the top (often hosted on the project's domain or GitHub CDN — trycurlwith a browser User-Agent); (3) homepage URL frompackage.json/ GitHub repo metadata — fetch/logo.svg,/logo-dark.svg,/favicon.svg,/favicon.ico, or the og:image; (4) GitHub social-preview image. Save whatever you find to the working dir alongsideindex.html. If nothing turns up, do not generate or stylize a substitute mark in any mode. See §2.4 logo rule for what to do next. LICENSE,CHANGELOG.md— maturity signal.- Recent git log (last 10 commits) — what's active.
- If GitHub: stars, topics, releases, open issues count.
- If
ast-graphis available locally and the repo has supported languages: runscan+hotspots+symbolon top-level exports for structural inventory. - Count the real inventory — if the repo exposes a collection (tools, commands, pages, themes, plugins, routes), count them from source (route files,
src/tools/*, CLI command registrations, etc.). Do not estimate from the README. This number is used later: any hero that says "all", "every", "the whole", or shows a grid meant to represent scope must match this count — or explicitly frame itself as a sample ("10 of 30 shown", scroll affordance, "30+"). An undercount reads as a broken promise. - If the repo's product has a visible runtime UI (CLI tool, TUI, terminal app, IDE plugin, desktop app), collect the real UI vocabulary before drafting any hero with that UI in it. Look for: screenshots in
assets//docs/, GIFs already in the README, source-level UI strings (banner generators, status string constants, hook output messages, prompt formats). Proactively ask the user for a short screen recording (.mov/.mp4) if none are in the repo — extract frames withffmpeg -i recording.mov -vf "fps=0.5,scale=1400:-1" frames/f%02d.pngandReadmultiple keyframes for grounding. A generic terminal mock with inventednpm run typecheck-style lines is a craft failure ev