Show HN: Shotlist – Make your AI agent prove its work with real screenshots
Shotlist is an open-source tool that generates documentation screenshots (web pages, terminal windows, CLI sessions) from a single committed config file. It ensures reproducibility, integrates with CI, and supports multiple capture modes, keeping screenshots always up to date.
Notifications You must be signed in to change notification settings
Fork 0
Star 0
BranchesTags
Open more actions menu
Folders and files
NameName
Last commit message
Last commit date
Latest commit
History
36 Commits
36 Commits
.github
.github
demo
demo
docs
docs
integrations/claude
integrations/claude
src/shotlist
src/shotlist
tests
tests
.gitignore
.gitignore
.shotlist.yaml
.shotlist.yaml
CONTRIBUTING.md
CONTRIBUTING.md
LICENSE
LICENSE
README.md
README.md
action.yml
action.yml
demo.tape
demo.tape
pyproject.toml
pyproject.toml
Repository files navigation
Screenshots for your docs — as code. One committed shot list captures your web pages, your real terminal windows, and stateful CLI sessions — and regenerates them all with a single command.
Contents
The problem
Quickstart
One shot list, four kinds of shot
Use cases
Proof reports & pipelines
Why shotlist, and not the others
How it works
Use with Claude
Commands
Develop
The problem
Documenting a feature means launching the app, clicking to the right state, screenshotting, naming the file, and embedding it — every time the UI changes. The screenshots drift out of date the moment you ship, and nobody notices until they're embarrassingly wrong.
shotlist makes them reproducible: describe how to start your app and what to shoot once, in a committed .shotlist.yaml, then regenerate the whole set on demand — locally or in CI. Same config + same app state → same screenshots.
Quickstart
pip install shotlist # installs the shotlist command
playwright install chromium # one-time browser download
shotlist init # writes a starter .shotlist.yaml shotlist run # boots your app, captures every shot, tears it all down
One shot list, four kinds of shot
output: dir: docs/screenshots readme: README.md # optional: splice snippets straight into the README
app: # optional — omit for static sites or pure-CLI shots command: "npm run dev" ready: { url: http://localhost:5173, timeout: 30 } # never shoot a half-booted app
shots:
- { name: dashboard, kind: web, url: http://localhost:5173/dashboard, full_page: true, alt: "Dashboard" }
- { name: cli-help, kind: cli, command: "mytool --help", alt: "Top-level help" }
Kind Captures How
web a browser page — with optional click/fill/wait steps first Playwright / Chromium
cli · native (macOS default) a real screenshot of your Terminal.app window — your font, your theme AppleScript + screencapture
cli · rendered (any OS, CI-safe) the command's output drawn as a styled terminal card PTY → ANSI→HTML → Chromium
session a stateful, multi-command flow in one persistent terminal — one shot per step one Terminal window, captured after each step
A session is how you screenshot a flow whose later steps depend on earlier ones — the shell state (cwd, env, background processes) carries across. Background a long-running process with & and a small wait_ms, keep capturing, and the session tears it down on close.
Use cases
shotlist fits anywhere a screenshot would otherwise go stale:
README & docs screenshots — the core: regenerate the whole set on every UI change.
Test-evidence / proof — capture a feature flow step by step (a session) and share the generated index.html as proof it works.
CI drift-checking — shotlist check fails the build when a screenshot changes unexpectedly (with a visual --diff).
Blog posts & tutorials — polished web and CLI shots from one config.
Onboarding & demo galleries — versioned sets you keep across releases.
Long-running processes — background a dev server with & + wait_ms and shoot it live.
Each one has a complete, copy-paste .shotlist.yaml in the recipes cookbook, docs/recipes.md.
Proof reports & pipelines
Every shotlist run also writes, next to the PNGs:
index.html — a self-contained gallery you can open and share as a proof report;
manifest.json — a machine-readable record of the run (a pipeline artifact).
Attach manifest.json to a CI job, or open index.html as test-evidence. Gate CI with shotlist check — it re-captures and fails when a screenshot drifts from the committed baseline (shotlist check --update to accept intended changes; add --diff DIR to render baseline·current·diff images) — or drop in the bundled GitHub Action. Turn the report off with --no-report (or output.report: false). Details in docs/pipeline.md.
Why shotlist, and not the others
The pieces exist in isolation; shotlist is the one tool that does all of it under a single committed config.
web pages real terminal CLI sessions README auto-embed reproducible / CI
shotlist ✅ ✅ ✅ ✅ ✅
shot-scraper ✅ ❌ ❌ ❌ ✅
freeze / carbon ❌ synthetic ❌ ❌ ✅
Percy / Chromatic ✅ ❌ ❌ ❌ ✅ (cloud, paid)
doing it by hand 😖 😖 😖 ❌ ❌
No cloud, no paid services, no special OS permissions for web/rendered shots. (Native Terminal capture needs macOS Screen-Recording permission; everything else needs nothing.)
How it works
.shotlist.yaml ─► load + validate ─► [ boot app, wait until ready ] ─► one engine routes each shot by kind: web ───────► Playwright / Chromium cli·native ► a real Terminal.app window cli·render ► PTY → ANSI→HTML → Chromium session ───► one persistent Terminal, a shot per step ─► NN-name.png + README splice
The clever part is what isn't here: no AI runs at capture time. Claude's only job is to author the .shotlist.yaml once by reading your repo; after that the engine is a plain, deterministic program — fast, free, and re-runnable in CI with no model in the loop. See the full design in docs/design.md.
Robust by design. The readiness probe (HTTP / TCP port / log line) means you never screenshot a half-booted app, and the app is launched in its own process group and torn down — even on a crash or Ctrl-C — so a shotlist run never leaves an orphaned dev server behind.
shotlist, captured by shotlist
This repo dogfoods itself: the shots below are produced by running shotlist run on its own .shotlist.yaml and spliced in automatically.
The shotlist CLI
Run options
Use with Claude
shotlist ships an optional Claude integration in integrations/claude/:
a /shotlist skill that inspects your repo (routes, --help, README), writes the .shotlist.yaml for you, and runs it;
an optional auto-snapshot hook that drops a raw snapshot when a dev server starts (the honest "dumb snapshot"; the curated set always comes from shotlist run).
Commands
Command What it does
shotlist init Scaffold a starter .shotlist.yaml
shotlist validate Check the shot list is well-formed
shotlist run Capture every shot and write outputs
shotlist run --only dashboard Capture a single shot by name
shotlist run --version v2 Write into a versioned subfolder
shotlist check Fail if a screenshot drifted from the committed baseline
shotlist check --update Re-shoot and accept the current screenshots as the baseline
shotlist check --diff DIR Also render baseline·current·diff images for changed shots
Develop
git clone https://github.com/varmabudharaju/shotlist && cd shotlist python3 -m venv .venv && source .venv/bin/activate pip install -e ".[dev]" playwright install chromium pytest # the suite is fully offline
CI runs ruff, mypy, and pytest on Python 3.11 and 3.12. A separate verify-action workflow dogfoods the bundled GitHub Action on every PR — running shotlist run then shotlist check on a Linux runner — so a regression in the action is caught before it ships. Releases publish to PyPI automatically via Trusted Publishing.
The hero GIF is itself reproducible — demo.tape + vhs demo.tape.
License
MIT © Varma Budharaju
About
Screenshots for your docs, as code — web pages, real terminal windows, and stateful CLI sessions, from one committed shot list.
pypi.org/project/shotlist/
Topics
python
cli
readme
screenshots
documentation
automation
developer-tools
playwright
Resources
Readme
License
MIT license
Contributing
Contributing
Uh oh!
There was an error while loading. Please reload this page.
Activity
Stars
0 stars
Watchers
0 watching
Forks
0 forks
Report repository
Releases 2
shotlist v0.2.0
Latest
Jun 26, 2026
+ 1 release
Packages 0
Uh oh!
There was an error while loading. Please reload this page.
Contributors
Uh oh!
There was an error while loading. Please reload this page.
Languages
Python 99.2%
Shell 0.8%