--- name: demo description: Write, record and narrate a product demo video with recital, a scenario file that clicks through a web app or Figma plugin with a calm cursor, spoken lines and captions. Use when asked to make, script, record, re-record or narrate a demo, walkthrough or screencast of an app or Figma plugin, or to fix or update a recital scenario. --- # Making a demo with recital A demo is a scenario, `scenarios/.js` in a workspace (a folder with `scenarios/`): the page to open, the steps to take, and the lines to say. recital records it in Chromium at 3200×1800 (a 1600×900 page at 2×; `viewport` and `scale` change it) and 60 fps, waits for each line before the step it belongs to, and makes the final video with burned-in captions. ## References Read these before writing a scenario; they're in the installed package: - `node_modules/recitaljs/types.d.ts`: every scenario key, action, target and option, with what each does. The source of truth for the format. - `node_modules/recitaljs/README.md`: the commands and an example. - `node_modules/recitaljs/docs/narration.md`: the full guide to the spoken lines. - `node_modules/recitaljs/docs/figma.md`: Figma plugins, through the built-in Figma adapter (`file`, `plugin`, `canvas` targets). - `node_modules/recitaljs/docs/adapters.md`: an adapter of your own, for an app whose canvas or windows `ui` and `frame` targets can't reach. - `node_modules/recitaljs/docs/ci.md`: recording again in CI after each deployment. ## Setup In the folder the user wants the demos in (not inside the app's source, unless they ask): ```sh npm init -y # if there's no package.json npm i -D recitaljs npx playwright install chromium npx recital init # scenarios/example.js and a .gitignore npx recital doctor # ffmpeg, Chromium, the voice, keys ``` Apps behind a login: ask the user to run `npx recital demo login ` (or `npx recital demo login figma`) and sign in themselves. The login is kept, so it's needed only once. Never ask for their password. ## Running the browser `demo` opens Chromium. Run each `npx recital demo …` as the whole command, with no pipe and no `cd … &&`. If Chromium exits straight away (code 21, "ProcessSingleton", a sandbox error), the agent's sandbox is blocking it: tell the user, and suggest they allow the command outside the sandbox (in Claude Code, `sandbox.excludedCommands`, such as `"npx recital demo:*"`). Don't work around the sandbox. ## The workflow 1. **Plan the demo.** A task start to finish, a tour of a site or app, or one new feature, in 3 to 6 narrated steps and 15 to 45 seconds. Settle what the viewer should see and in what state the app starts. Draft the narration now, by the rules below: it is the plan, and each line becomes a labelled step. 2. **See the page.** Write the scenario with its `url` and one step, `{ hold: 500 }`, then: `npx recital demo --inspect node_modules/recitaljs/examples/inspect/page.js`. It lists the headings, links and buttons with their boxes, and screenshots the page top to bottom into `output/probe/`. Look at the screenshots. 3. **Write the steps.** Start the file with `// @ts-check` and `/** @type {import("recitaljs").Scenario} */`. - Prefer selectors a person would read: `role=button[name='Save']`, `text=Welcome`, `[name=email]`. Avoid `nth=` and generated class names. - Put what the viewer shouldn't see (dismissing a banner, resetting data) in `setup`. - Give a `label` to every step a line or a camera framing starts at. - After a click that loads something, `waitFor` what appears, so the take doesn't run ahead. - Don't click what is already right: guard with `unless`, or use `check` for checkboxes. 4. **Check.** `npx recital validate `, then `npx recital demo --dry`, which runs the steps without recording. A target it can't find names the closest ones on screen. 5. **Record and look.** `npx recital demo ` records `output//take.mp4`. Then `npx recital frames --steps` and look at `output//frames/take/sheet.png`, one frame at the end of each step. Fix what's off (a step ending mid-scroll, a hold too short to read, a popup in the way) and record again. Look at the sheet every time: a take that ran without errors can still show the wrong thing. 6. **Zoom, if it helps.** Small UI reads better closer. Add `camera` framings (`{ at: "