▶ readme2demo generating its own tutorial: an AI agent runs this repo's README in a sandbox, a fresh container replays every step, then the demo is rendered. Full self-run output in examples/readme2demo · run against another project in examples/toolhive.
AI-verified tutorial and demo video generator. Point it at a repo. An AI agent reads the README and actually runs it inside a hardened Docker sandbox. Only after a clean-room replay passes does it render a demo video (VHS) and publish the tutorial, step-by-step guide, and troubleshooting doc.
The value is not "AI writes a tutorial" — it's that the tutorial ran, twice, before you saw it.
See it in action: browse verified example runs — real tutorials, step-by-step guides, and demo videos, each independently replayed in a clean container before publishing.
repo URL → ingest/plan → agent run (in Docker) → normalize transcript
→ distill minimal path → VERIFY replay in fresh container
→ render VHS video → generate tutorial.md + troubleshooting.md
See IMPLEMENTATION_PLAN.md for the full architecture.
- Python ≥ 3.10, Docker
- Auth, one of:
Your Claude subscription (no API key): a local Claude Code install. The planner/distiller/tutorial passes run on your subscription via
--llm-backend claude-cli
(claude -p
), and the in-sandbox agent authenticates withCLAUDE_CODE_OAUTH_TOKEN
(create one:claude setup-token
). Fully supported forself-hosted, single-operator runs against your own repos — Pro/Max plans include a monthly Agent SDK credit that coversclaude -p
.ANTHROPIC_API_KEY
— metered API billing; best for scale and concurrency, andrequired if you host readme2demo as a service for others(per Anthropic's terms, subscription auth may not power a multi-tenant product — seeROADMAP.md).
- Optional:
LLM_API_KEY
+LLM_MODEL
for--engine openhands
(experimental)
claude setup-token # interactive: approve in browser, then COPY the
export CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-...
readme2demo run <repo-url> --llm-backend claude-cli
export ANTHROPIC_API_KEY=sk-ant-...
readme2demo run <repo-url> # --llm-backend auto picks api
pip install -e ".[dev]"
docker build -t readme2demo/base:latest images/base/
readme2demo run https://github.com/example/tool
readme2demo run -gr https://github.com/example/tool # same, via the flag
readme2demo run -s my_guide.md # guide-only: no repo, your guide is self-contained
readme2demo run -gr https://github.com/example/tool -s my_guide.md # both: your guide drives everything
readme2demo run https://github.com/example/tool --allow-docker-socket # for tools that manage containers (SECURITY TRADEOFF: pierces sandbox isolation — trusted repos only)
readme2demo run https://github.com/example/tool --skip-video --budget-usd 3
readme2demo resume runs/tool-20260702-... --from-stage render
readme2demo report runs/tool-20260702-...
The repo is optional: pass it positionally or with -gr/--github-repo
, supply a guide with -s/--step-by-step
, or both. At least one is required. With a guide alone, no repo is cloned — the guide must be self-contained (install a published package, or clone what it needs as an explicit step); the fresh-container replay still verifies every command.
Outputs land in runs/<run-id>/
: tutorial.md
, step_by_step.md
, troubleshooting.md
, commands.sh
, demo.tape
, demo.mp4
, demo.gif
, plus manifest.json
with stage statuses and total cost.
The demo video is always built from step_by_step.md
: its steps are parsed, and every demo-safe, grounded command becomes a typed command in the video with the step title shown as an on-screen comment. Three ways it comes to exist, in priority order:
You pass one:readme2demo run <url> -s my_guide.md
— injected into the clone as the authoritative guide; planner and agent follow it, video plays it. The<url>
is optional here:readme2demo run -s my_guide.md
runs guide-only against an empty sandbox.The repo ships one(step_by_step.md
/step-by-step.md
at root ordocs/
, any case): same treatment, automatically.Neither exists: the pipelinegeneratesa detailedstep_by_step.md
— every command from the verifiedcommands.sh
as a numbered step with real captured outputs — then builds the video from it. Ready to contribute back to the repo.
Setup steps (clones, installs, builds) are documented in the guide but kept out of the video — it plays against the verified, already-built worktree, showing the payoff.
Every tutorial carries a verification badge: ✅ Verified on <date> · image <digest> · commit <sha>
— or a loud ⚠ UNVERIFIED
if the replay didn't pass. Unverified output is never silently published.
CLI flags > readme2demo.toml
defaults:
engine = "claude-code" # or "openhands"
model = "claude-sonnet-5" # planner/distiller/tutorial passes
max_turns = 60
budget_usd = 5.0
base_image = "readme2demo/base:latest"
skip_video = false
python -m pytest tests/ -q # 175 unit tests, no docker/network needed
ruff check src/ tests/ # correctness lint (matches CI)
python -m pytest -m integration # requires docker + API keys (none yet)
READMEs are untrusted code. The agent runs inside a hardened container (cap-drop ALL, no-new-privileges, memory/cpu/pids limits, non-root) — that container is the permission boundary. Known MVP tradeoff: the API key enters the sandbox; use a dedicated low-limit key. A host-side key-injecting egress proxy is planned (Milestone 4).
Full threat model and private vulnerability reporting: SECURITY.md.
Examples— verified output committed as proofRoadmap— where this is headed (including the exploratory hosted/SaaS direction)Contributing— the one non-negotiable rule, and how to get set upSecurity policy·Code of ConductArchitecture— stage boundaries and diagrams
MIT licensed. The CLI and verification pipeline are, and will stay, free and open source.