{"id":50084230,"url":"https://github.com/cjcsecurity/readme-demo-recorder","last_synced_at":"2026-06-08T09:01:12.298Z","repository":{"id":357028949,"uuid":"1235022405","full_name":"cjcsecurity/readme-demo-recorder","owner":"cjcsecurity","description":"Scripted-flow browser demo recorder for Claude Code. YAML in, polished MP4 + GIF out, ready to drop into a README hero.","archived":false,"fork":false,"pushed_at":"2026-05-11T00:57:04.000Z","size":8512,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-11T02:32:21.563Z","etag":null,"topics":["automation","claude-code","claude-skill","demo-video","developer-tools","documentation","ffmpeg","gif","mp4","playwright","readme","screencast"],"latest_commit_sha":null,"homepage":"https://github.com/cjcsecurity/readme-demo-recorder","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cjcsecurity.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-10T23:52:34.000Z","updated_at":"2026-05-11T00:57:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cjcsecurity/readme-demo-recorder","commit_stats":null,"previous_names":["cjcsecurity/readme-demo-recorder"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/cjcsecurity/readme-demo-recorder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjcsecurity%2Freadme-demo-recorder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjcsecurity%2Freadme-demo-recorder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjcsecurity%2Freadme-demo-recorder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjcsecurity%2Freadme-demo-recorder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cjcsecurity","download_url":"https://codeload.github.com/cjcsecurity/readme-demo-recorder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjcsecurity%2Freadme-demo-recorder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34055249,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","claude-code","claude-skill","demo-video","developer-tools","documentation","ffmpeg","gif","mp4","playwright","readme","screencast"],"created_at":"2026-05-22T18:00:36.857Z","updated_at":"2026-06-08T09:01:12.290Z","avatar_url":"https://github.com/cjcsecurity.png","language":"JavaScript","funding_links":[],"categories":["Skills"],"sub_categories":["Community Skills"],"readme":"# readme-demo-recorder\n\n\u003e **Scripted-flow browser demo recorder for Claude Code.**\n\u003e YAML in. Polished MP4 + GIF out. Drop into a README hero.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/demos/tabletop-runbook.gif\" alt=\"Demo: a captioned recording of a tabletop exercise runbook, produced from a 30-line YAML file by this skill itself.\" width=\"100%\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg alt=\"License: Apache 2.0\" src=\"https://img.shields.io/badge/license-Apache%202.0-blue.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"docs/INSTALL.md\"\u003e\u003cimg alt=\"Status: v0.1 ready\" src=\"https://img.shields.io/badge/status-v0.1-green\"\u003e\u003c/a\u003e\n  \u003cimg alt=\"Output: MP4 + GIF\" src=\"https://img.shields.io/badge/output-MP4%20%2B%20GIF-orange\"\u003e\n  \u003cimg alt=\"Engine: Playwright + ffmpeg\" src=\"https://img.shields.io/badge/engine-Playwright%20%2B%20ffmpeg-black\"\u003e\n  \u003ca href=\"https://github.com/cjcsecurity/claude-tabletop\"\u003e\u003cimg alt=\"Catalyst: claude-tabletop\" src=\"https://img.shields.io/badge/catalyst-claude--tabletop-purple\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## What it does\n\nHand it a single-file HTML target (or any URL) plus a YAML demo-script,\nand it produces a polished MP4 + GIF ready for a README hero — visible\nfake cursor, click pulse, optional timed captions, and an automatic\nsize-cap ladder so the GIF lands under GitHub's 10 MB inline cap.\n\nThe whole pipeline is one command:\n\n```bash\n./skills/readme-demo-recorder/scripts/record.sh path/to/demo.yaml\n```\n\nIn ~30 seconds you get:\n\n```\n✓ mp4  1.62 MB  docs/demos/tabletop-runbook.mp4\n✓ gif  5.21 MB  docs/demos/tabletop-runbook.gif  (960px @ 12fps)\n```\n\nThe hero animation above is the dogfood: a 30-line YAML, three captions,\nrecorded by this skill against the\n[`claude-tabletop`](https://github.com/cjcsecurity/claude-tabletop)\ncatalyst project's runbook.\n\n## Why this exists\n\nBuilding a polished README demo is a 50-line Playwright + ffmpeg pipeline\nthat bakes in a handful of not-so-obvious details — cursor injection that\nsurvives `file://` loads, drawtext with `textfile=` to avoid escape hell,\npalettegen with `stats_mode=diff` for clean GIFs. This skill makes it a\n1-command operation.\n\nThe niche it fills is deliberately narrow: **Claude Code skill demos\nwhere the artifact is a single-file HTML target**, with auto-fit logic\ntuned for GitHub's specific 10 MB inline-rendering cap and a\n`file://`-first workflow. For general product-demo recording with macOS\nchrome, branding, zoom, and a richer cursor toolkit, the better-engineered\ngeneralists are [`webreel`](https://github.com/vercel-labs/webreel) and\n[`testreel`](https://github.com/greentfrapp/testreel). For the narrow\ncase of \"I just shipped a Claude skill that produces a self-contained\nHTML artifact and want its README hero produced by another Claude skill,\"\nthis is the right fit.\n\nFor the full backstory and design decisions, see [`PLAN.md`](PLAN.md).\n\n## Quickstart\n\n```bash\n# 1. Clone alongside an existing Playwright install (see docs/INSTALL.md\n#    for fresh-install instructions).\ngit clone https://github.com/cjcsecurity/readme-demo-recorder.git\ncd readme-demo-recorder\nexport READMEDEMO_NODE_MODULES=/path/to/your/project/node_modules\n\n# 2. Author a YAML somewhere — anywhere.\ncat \u003e my-demo.yaml \u003c\u003c'EOF'\ntarget: ./your-app/index.html\nflow:\n  - mouse_park: { x: 0.5, y: 0.4 }\n  - hold: 1500\n  - click: '#start'\n  - wait: 2200\n  - type:\n      selector: '#search'\n      text: 'Hello, world'\n      delay_ms: 28\n  - wait: 1500\n\ncursor:\n  style: pulse        # pulse | minimal | crosshair\n\noutput:\n  dir: 'docs/demos/'\n  basename: 'my-demo'\nEOF\n\n# 3. Record it.\n./skills/readme-demo-recorder/scripts/record.sh my-demo.yaml\n# → docs/demos/my-demo.mp4 + docs/demos/my-demo.gif\n```\n\n## Examples\n\n| Demo                                      | Cursor    | Showcases                                  |\n|-------------------------------------------|-----------|--------------------------------------------|\n| [`tabletop-runbook`](examples/tabletop-runbook.yaml) | `pulse`     | Captions + click + scroll + nth-selector   |\n| [`form-submission`](examples/form-submission/demo.yaml) | `minimal`   | Typing into form fields + dark theme       |\n| [`shadcn-button`](examples/shadcn-button/demo.yaml)    | `crosshair` | Hover sequencing + light theme             |\n\nWalkthrough: [**`docs/EXAMPLES.md`**](docs/EXAMPLES.md).\n\n## Docs map\n\n| File                                                                                                              | What it covers                                                                 |\n|-------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|\n| [`docs/INSTALL.md`](docs/INSTALL.md)                                                                              | Prerequisites, three install paths, smoke test, troubleshooting.               |\n| [`docs/EXAMPLES.md`](docs/EXAMPLES.md)                                                                            | Walkthrough of each shipped example with output GIFs.                          |\n| [`skills/readme-demo-recorder/SKILL.md`](skills/readme-demo-recorder/SKILL.md)                                    | Claude-facing skill instructions — workflow, defaults, failure modes.          |\n| [`.../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.    |\n| [`.../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.    |\n| [`.../references/ffmpeg-pipeline.md`](skills/readme-demo-recorder/references/ffmpeg-pipeline.md)                  | Encoding flags, two-pass GIF palette, the size-cap auto-fit ladder.            |\n| [`.../references/playwright-template.md`](skills/readme-demo-recorder/references/playwright-template.md)          | Hand-edit Node template — fallback for flows the YAML can't express.           |\n\n## How it works\n\n1. **Playwright** launches headless Chromium at 1280×720 with `recordVideo`.\n2. **Cursor inject** runs after `page.goto` (not `addInitScript` — that\n   silently drops elements on `file://` loads). Three styles to choose from:\n   `pulse`, `minimal`, `crosshair`. Pure CSS+JS, no external dependencies.\n3. **Flow** drives the page from the YAML steps — `hover`, `click`,\n   `scroll_to`, `type`, `mouse_park`, `wait` — using a smooth-glide\n   `mouse.move(x, y, { steps: 22 })` so the cursor reads as a person.\n4. **ffmpeg** encodes WebM → MP4 (`libx264`, `crf 22`, `+faststart`,\n   `yuv420p`) and burns in any captions via `drawtext` with `textfile=`\n   (no escape hell).\n5. **GIF cascade** re-encodes the captioned MP4 through a 7-step quality\n   ladder (`960×12fps` → … → `540×8fps`), stopping at the first step\n   that fits `output.gif_max_mb`.\n6. **Outputs** land at `\u003coutput.dir\u003e/\u003coutput.basename\u003e.{mp4,gif}` along\n   with a one-line per-format summary on stderr.\n\n## License\n\n[Apache-2.0](LICENSE).\n\n## Catalyst\n\nThis skill exists because [`claude-tabletop`](https://github.com/cjcsecurity/claude-tabletop)\nneeded a polished README hero, and the author hit the same Playwright +\nffmpeg glue every time they wanted a demo. The technique here is the same\none that produced `claude-tabletop`'s `runbook-demo.{mp4,gif}` — extracted,\ngeneralized, and wrapped in a YAML-driven driver.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcjcsecurity%2Freadme-demo-recorder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcjcsecurity%2Freadme-demo-recorder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcjcsecurity%2Freadme-demo-recorder/lists"}