https://github.com/cjcsecurity/readme-demo-recorder
Scripted-flow browser demo recorder for Claude Code. YAML in, polished MP4 + GIF out, ready to drop into a README hero.
https://github.com/cjcsecurity/readme-demo-recorder
automation claude-code claude-skill demo-video developer-tools documentation ffmpeg gif mp4 playwright readme screencast
Last synced: 16 days ago
JSON representation
Scripted-flow browser demo recorder for Claude Code. YAML in, polished MP4 + GIF out, ready to drop into a README hero.
- Host: GitHub
- URL: https://github.com/cjcsecurity/readme-demo-recorder
- Owner: cjcsecurity
- License: apache-2.0
- Created: 2026-05-10T23:52:34.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-05-11T00:57:04.000Z (about 1 month ago)
- Last Synced: 2026-05-11T02:32:21.563Z (about 1 month ago)
- Topics: automation, claude-code, claude-skill, demo-video, developer-tools, documentation, ffmpeg, gif, mp4, playwright, readme, screencast
- Language: JavaScript
- Homepage: https://github.com/cjcsecurity/readme-demo-recorder
- Size: 8.12 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
- Security: SECURITY.md
Awesome Lists containing this project
- awesome-claude-code-toolkit - readme-demo-recorder - demo-recorder ~/.claude/skills/readme-demo-recorder` | Scripted-flow browser demo recorder for README hero assets — YAML demo-script in, polished MP4 + GIF out. Visible fake cursor + click pulse, three cursor styles (pulse/minimal/crosshair), timed caption overlays via ffmpeg drawtext, and automatic 7-step GIF size-cap ladder so output lands under GitHub's 10 MB inline cap. Built on Playwright + ffmpeg. Apache-2.0 | (Skills / Community Skills)
README
# readme-demo-recorder
> **Scripted-flow browser demo recorder for Claude Code.**
> YAML in. Polished MP4 + GIF out. Drop into a README hero.
## What it does
Hand it a single-file HTML target (or any URL) plus a YAML demo-script,
and it produces a polished MP4 + GIF ready for a README hero — visible
fake cursor, click pulse, optional timed captions, and an automatic
size-cap ladder so the GIF lands under GitHub's 10 MB inline cap.
The whole pipeline is one command:
```bash
./skills/readme-demo-recorder/scripts/record.sh path/to/demo.yaml
```
In ~30 seconds you get:
```
✓ mp4 1.62 MB docs/demos/tabletop-runbook.mp4
✓ gif 5.21 MB docs/demos/tabletop-runbook.gif (960px @ 12fps)
```
The hero animation above is the dogfood: a 30-line YAML, three captions,
recorded by this skill against the
[`claude-tabletop`](https://github.com/cjcsecurity/claude-tabletop)
catalyst project's runbook.
## Why this exists
Building a polished README demo is a 50-line Playwright + ffmpeg pipeline
that bakes in a handful of not-so-obvious details — cursor injection that
survives `file://` loads, drawtext with `textfile=` to avoid escape hell,
palettegen with `stats_mode=diff` for clean GIFs. This skill makes it a
1-command operation.
The niche it fills is deliberately narrow: **Claude Code skill demos
where the artifact is a single-file HTML target**, with auto-fit logic
tuned for GitHub's specific 10 MB inline-rendering cap and a
`file://`-first workflow. For general product-demo recording with macOS
chrome, branding, zoom, and a richer cursor toolkit, the better-engineered
generalists are [`webreel`](https://github.com/vercel-labs/webreel) and
[`testreel`](https://github.com/greentfrapp/testreel). For the narrow
case of "I just shipped a Claude skill that produces a self-contained
HTML artifact and want its README hero produced by another Claude skill,"
this is the right fit.
For the full backstory and design decisions, see [`PLAN.md`](PLAN.md).
## Quickstart
```bash
# 1. Clone alongside an existing Playwright install (see docs/INSTALL.md
# for fresh-install instructions).
git clone https://github.com/cjcsecurity/readme-demo-recorder.git
cd readme-demo-recorder
export READMEDEMO_NODE_MODULES=/path/to/your/project/node_modules
# 2. Author a YAML somewhere — anywhere.
cat > my-demo.yaml <<'EOF'
target: ./your-app/index.html
flow:
- mouse_park: { x: 0.5, y: 0.4 }
- hold: 1500
- click: '#start'
- wait: 2200
- type:
selector: '#search'
text: 'Hello, world'
delay_ms: 28
- wait: 1500
cursor:
style: pulse # pulse | minimal | crosshair
output:
dir: 'docs/demos/'
basename: 'my-demo'
EOF
# 3. Record it.
./skills/readme-demo-recorder/scripts/record.sh my-demo.yaml
# → docs/demos/my-demo.mp4 + docs/demos/my-demo.gif
```
## Examples
| Demo | Cursor | Showcases |
|-------------------------------------------|-----------|--------------------------------------------|
| [`tabletop-runbook`](examples/tabletop-runbook.yaml) | `pulse` | Captions + click + scroll + nth-selector |
| [`form-submission`](examples/form-submission/demo.yaml) | `minimal` | Typing into form fields + dark theme |
| [`shadcn-button`](examples/shadcn-button/demo.yaml) | `crosshair` | Hover sequencing + light theme |
Walkthrough: [**`docs/EXAMPLES.md`**](docs/EXAMPLES.md).
## Docs map
| File | What it covers |
|-------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|
| [`docs/INSTALL.md`](docs/INSTALL.md) | Prerequisites, three install paths, smoke test, troubleshooting. |
| [`docs/EXAMPLES.md`](docs/EXAMPLES.md) | Walkthrough of each shipped example with output GIFs. |
| [`skills/readme-demo-recorder/SKILL.md`](skills/readme-demo-recorder/SKILL.md) | Claude-facing skill instructions — workflow, defaults, failure modes. |
| [`.../references/demo-script-format.md`](skills/readme-demo-recorder/references/demo-script-format.md) | Full YAML schema: every step type, every field, validation rules, pitfalls. |
| [`.../references/click-pulse-cursor.md`](skills/readme-demo-recorder/references/click-pulse-cursor.md) | Cursor injection recipe: CSS+JS for each style, the `addInitScript` gotcha. |
| [`.../references/ffmpeg-pipeline.md`](skills/readme-demo-recorder/references/ffmpeg-pipeline.md) | Encoding flags, two-pass GIF palette, the size-cap auto-fit ladder. |
| [`.../references/playwright-template.md`](skills/readme-demo-recorder/references/playwright-template.md) | Hand-edit Node template — fallback for flows the YAML can't express. |
## How it works
1. **Playwright** launches headless Chromium at 1280×720 with `recordVideo`.
2. **Cursor inject** runs after `page.goto` (not `addInitScript` — that
silently drops elements on `file://` loads). Three styles to choose from:
`pulse`, `minimal`, `crosshair`. Pure CSS+JS, no external dependencies.
3. **Flow** drives the page from the YAML steps — `hover`, `click`,
`scroll_to`, `type`, `mouse_park`, `wait` — using a smooth-glide
`mouse.move(x, y, { steps: 22 })` so the cursor reads as a person.
4. **ffmpeg** encodes WebM → MP4 (`libx264`, `crf 22`, `+faststart`,
`yuv420p`) and burns in any captions via `drawtext` with `textfile=`
(no escape hell).
5. **GIF cascade** re-encodes the captioned MP4 through a 7-step quality
ladder (`960×12fps` → … → `540×8fps`), stopping at the first step
that fits `output.gif_max_mb`.
6. **Outputs** land at `/.{mp4,gif}` along
with a one-line per-format summary on stderr.
## License
[Apache-2.0](LICENSE).
## Catalyst
This skill exists because [`claude-tabletop`](https://github.com/cjcsecurity/claude-tabletop)
needed a polished README hero, and the author hit the same Playwright +
ffmpeg glue every time they wanted a demo. The technique here is the same
one that produced `claude-tabletop`'s `runbook-demo.{mp4,gif}` — extracted,
generalized, and wrapped in a YAML-driven driver.