Skip to content

HeyRenan/showreel

Repository files navigation

Showreel

Turn a URL + CSS selectors into a finished visual — annotated screenshots, flow GIFs, cinematic recordings and terminal captures. One command each. The agent never guesses pixels; every output is pixel-verified before it's saved.

ci version license claude code

English · Português

Showcase

Watch the full showcase

One take, every feature — drawer, camera, loupe, spotlight, live blur, typed form, region pick, live legend panel, one-click deploy. Generated entirely by the plugin against the bundled demo page. (click to play the full MP4)

Every image in this README was generated by Showreel itself, against the bundled "Lumen" demo page. Run the same commands, get the same files.

What it is

A Claude Code plugin for visual documentation: explaining a change, a bug, a feature or a tutorial step with a picture instead of a paragraph.

You point it at a page and name elements by CSS selector. Showreel measures the DOM, draws the annotation exactly on target, and validates the result before exit — a bad capture is an error, never a shipped file. No screenshot → eyeball → retry loop, no pixel coordinates, no tokens burned guessing.

  • Self-contained — bundles its own headless Chromium; no browser MCP, no credentials, no telemetry. The only network is rendering the page URL you ask for, plus a one-time Playwright + Chromium download on first run (from npm and Microsoft's CDN; pre-warm it with preflight.sh).
  • Deterministic — same selectors in, same pixels out. Placement is computed, not guessed.
  • Cheap--batch renders many captures in one browser launch.

Quick start

# install
claude plugin marketplace add HeyRenan/showreel
claude plugin install showreel@showreel

# one-time: check the machine + pre-warm the motor (~90MB Chromium, once)
bash ~/.claude/plugins/showreel/showreel/scripts/preflight.sh
node ~/.claude/plugins/showreel/showreel/scripts/ensure-deps.mjs

Restart Claude Code, then invoke /showreel and describe what to capture. Or run a script directly:

# annotate one element, self-validated
node scripts/prove.mjs https://example.com ".cards .card:first-child" out.png --label "Service card verified"

/showreel:guide opens a visual setup guide. Local-folder install and full paths in INSTALL.md.

Zero config — just a URL

Don't know the selectors? Point Showreel at a page and it finds the salient elements itself — heading, primary action, navigation, metrics, hero, cards — annotates each with a role-based note, and runs the same vcheck gate as prove. One browser launch.

node scripts/auto.mjs https://your-app.example.com
auto-discovered primary action auto-discovered key metric
primary action — discovered + zoomed key metric — discovered
auto-discovered form auto-discovered hero image
key input form — discovered hero image — discovered

All four shots came from one auto.mjs command against the bundled demo page — not a selector written. It prints a PASS line per element, then AUTO <k>/<n> PASS, plus an index.json manifest. A discovered element that vanishes before capture (SPA re-render, themed swap) is a soft skip, never a failure.

Share-ready frames

Wrap any capture in a browser-window or card frame — shadow, rounded corners, gradient background — and export to a social aspect ratio. A raw screenshot becomes something you can drop in a slide, a README, or a launch post.

node scripts/beautify.mjs shot.png --url "your-app.com"        # browser window (default)
node scripts/beautify.mjs shot.png --ratio 16:9 --frame card   # social card

a capture wrapped in a browser-window frame

What it can do

Every capability, one command each. All scripts live in showreel/scripts/. The agent always speaks in selectors + text, never pixels.

Capability Script What you get
Auto (URL only) auto.mjs Discovers the salient elements itself — heading, primary action, nav, hero, metrics, cards — role-based notes, same vcheck gate. One launch; writes PNGs + index.json. No selectors. --max N.
Annotated proof prove.mjs DOM-exact rectangle + callout + arrow, pixel-verified (vcheck) — exits 0 only on PASS. Flags: --circle, --blur "<sel>", --zoom, --batch jobs.json.
Annotation primitives demo.mjs One concept per image: rect, circle, arrow, badge, blur, zoom, callout, label. --batch = 8 captures in one launch.
Flow recording rec.mjs Narrated GIF/MP4 from JSON steps — cursor motion, ripples, scrolling, narration modals, step stamps. The hero GIF above is one call.
Cinematic camera rec.mjs Real viewport move: page glides + scales under an animated transform. camera frames an element, follow chases the cursor, inset is a magnifier loupe.
Spotlight / slow-mo / auto-annotate rec.mjs spotlight dims all but the target; per-step speed slows an animation; --auto-annotate outlines a bare click/fill for free.
Live elements rec.mjs A glossary/modal with an id becomes live — later live steps append/update/recolor/replace/remove rows in place, no rebuild, no blink. Per-item colors, theme-matched text.
Offline render rec.mjs --offline Renders on the page's virtual clock — reading dwells collapse, text-heavy takes finish in a fraction of the time. Best for static/text takes; motion bursts (confetti, sparkline) require a realtime take.
Terminal recording tape.mjs CLI proof via vhs: JSON steps → .tape → GIF. The preflight GIF below is one call.
Before/after compare compose.mjs, lh-ba.sh Two PNGs or two GIFs side by side with labels. lh-ba.sh runs real Lighthouse on both branches.
Size optimizer shrink.mjs Re-encodes gif/png with no visible quality loss; --target-kb walks a quality ladder. Every image here went through it.
Share-ready frames beautify.mjs Wraps any PNG in a browser-window / card frame — shadow, rounded corners, gradient background, and --ratio 16:9|9:16|1:1 social presets.
Tight crop shot.mjs Just the element, no annotation.

Recording: how steps work

rec.mjs takes JSON steps — each names an element and what to do. The script owns all the motion.

node scripts/rec.mjs <url> --steps-json '[
 {"click":"#menu","note":"Drawer opens","badge":1,"screen":"Dashboard"},
 {"scrollTo":".cards","rect":true,"glide":true,"note":"Active services","badge":2},
 {"fill":"#email","text":"dana@example.com"},
 {"camera":{"sel":".kpis","zoom":1.3},"note":"Framing the KPIs"},
 {"click":"#deploy","follow":1.6,"note":"Camera chases the cursor"}
]' out.gif

56 step keys (unknown keys rejected up front):

  • actionsclick, fill, text, select, option, scrollTo, scrollIn, to, hide
  • annotationnote, arrow, badge, rect, circle, marks, glossary, inset, modal
  • camera / motioncamera, zoom, follow, glide, speed
  • emphasisspotlight, blur, redact, highlight, pulse, ripple, shake, glow, flash
  • state / datacheckmark, typeon, reveal, orbit, kenburns, progress, countdown, countup, sparkline, confetti, trail
  • livelive (mutate a glossary/modal in place across steps — append/update/recolor/replace/remove)
  • chrome / timingscreen, topbar, bottombar, wait, delay, fade, stagger, accent
  • per-effect knobssize, dur, count, intensity

Author fast: --dry resolves every selector against the live page in <1s ([ok]/[MISS] per step, no recording) — fix misses, record once. --pace fast trims holds ~45% for drafts. --contact-sheet writes a tile of ~24 frames so the take reviews itself.

See each one

Every feature, demonstrated — each image generated by the plugin against the demo page.

prove camera marks
prove — annotated proof camera — viewport move marks — sub-badges
modal bars spotlight
modal — narration bars — top/bottom context spotlight — dim all but target
speed auto-annotate stamp
speed — per-step slow-mo auto-annotate — free outline stamp — step counter
fill select inset
fill — typed input select — dropdown pick inset — magnifier loupe
glossary hide glide
glossary — badge legend panel hide — drop an element glide — animated scroll
compose terminal compose-static
compose — before/after (motion) tape — terminal capture compose — before/after (static)

Live elements & state — a panel that grows in place, plus the full motion/state kit:

live confetti countup
live — append rows in place confetti — celebrate a success countup — roll a number up
sparkline progress countdown
sparkline — draw a trend progress — rollout bar countdown — ticking pre-action
pulse ripple glow
pulse — attention ring ripple — tap feedback glow — active emphasis
checkmark reveal flash
checkmark — stage done reveal — new content enters flash — status blink
orbit trail shake
orbit — working spinner trail — A→B connector shake — blocked/error
typeon kenburns redact
typeon — streaming text kenburns — slow zoom redact — hide sensitive data
highlight
highlight — marker swipe

Annotation primitives (demo.mjs)

Eight callout styles, one concept per image — all eight from a single demo --batch launch:

rect circle arrow badge
rect circle arrow badge
blur zoom callout label
blur zoom callout label

Why it's fast

Measured on this codebase (Apple Silicon, warm motor):

Naive Showreel
8 annotated captures 8 browser launches ≈ 60 s demo --batch6 s, one launch
Annotation placement read PNG → guess pixels → retry deterministic autoplace, 0 retries
Contrast on dark/light pages manual color picking adaptive from page luminance
Overlapping annotations manual nudging collision-aware, never covers the target

How it works

The agent sends selectors + text. The motor (self-contained Chromium in scripts/.deps/) measures the DOM, places every annotation deterministically (lib/autoplace.mjs), and self-validates (vcheck) before saving — so there's no guess/retry loop. Web captures run through Chromium; terminal captures through vhs. rec.mjs is modular: single-responsibility modules (rec-steps, cam-inject, rec-camera, rec-motion, rec-annotate, rec-input, rec-encode, rec-page) over one clock that makes realtime and offline two implementations of the same time contract.

Requirements

node 18+. Optional: ffmpeg (best GIF quality), vhs (terminal recordings). No git, no tokens, nothing to configure. preflight.sh prints exact setup commands for anything missing. Full matrix in INSTALL.md, version history in CHANGELOG.md.

Tests

cd showreel && node --test 'scripts/__tests__/*.test.mjs'   # no network or browser

License

MIT

About

Claude Code plugin for visual docs — annotated screenshots, feature demos, cinematic flow recordings (gif/mp4), terminal captures and before/after composites, one command each. Self-contained Chromium, self-validated output, no MCP.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors