with one click
storybook-record-video
// Record MP4 videos of a Storybook component story in all four themes (light, dark, hc-light, hc-dark). Use when the user asks to record, capture, or grab a video of a Storybook story or component animation.
// Record MP4 videos of a Storybook component story in all four themes (light, dark, hc-light, hc-dark). Use when the user asks to record, capture, or grab a video of a Storybook story or component animation.
| name | storybook-record-video |
| description | Record MP4 videos of a Storybook component story in all four themes (light, dark, hc-light, hc-dark). Use when the user asks to record, capture, or grab a video of a Storybook story or component animation. |
Record MP4 videos of a specific Storybook story across all four themes: light, dark, high-contrast light, and high-contrast dark. Produces GitHub-compatible H.264 MP4 files.
pnpm --filter storybook dev)ffmpeg available on the system PATHmcp__plugin_playwright_playwright__* tools)Ask the user for anything not provided:
| Input | Example | Notes |
|---|---|---|
| Story ID | progress-linearprogress--basic | The Storybook story ID (from the URL ?id=...) |
| Output directory | . (project root) | Where to save the MP4 files |
| Filename prefix | linear-progress-old | Files will be named {prefix}-{theme}.mp4 |
| Duration | 20 | Recording duration in seconds (default: 20) |
| Viewport width | 800 | CSS pixel width (default: 800) |
| Viewport height | 200 | CSS pixel height (default: 200) |
The four Storybook themes and their URL global values:
| Theme | Global value | Description |
|---|---|---|
| Light | light | Standard light theme |
| Dark | dark | Standard dark theme |
| HC Light | hc-light | High-contrast light theme |
| HC Dark | hc-dark | High-contrast dark theme |
lsof -i :6006 | head -3 # Storybook running?
which ffmpeg # ffmpeg available?
For each theme in [light, dark, hc-light, hc-dark]:
First, create the temp frame directory:
mkdir -p "${TMPDIR:-/tmp}/sb-video-{THEME}"
Then use a single browser_run_code_unsafe call that:
Story iframe URL pattern:
http://localhost:6006/iframe.html?id={STORY_ID}&viewMode=story&globals=theme:{THEME}
Frame capture code pattern:
async page => {
await page.goto('http://localhost:6006/iframe.html?id={STORY_ID}&viewMode=story&globals=theme:{THEME}', {
waitUntil: 'networkidle',
});
await page.setViewportSize({ width: { WIDTH }, height: { HEIGHT } });
await page.waitForTimeout(500);
const dir = `${process.env['TMPDIR'] ?? '/tmp'}/sb-video-{THEME}`;
const totalMs = { DURATION } * 1000;
const interval = 16; // ~60fps
const count = Math.floor(totalMs / interval);
for (let i = 0; i < count; i++) {
await page.screenshot({
path: `${dir}/frame-${String(i).padStart(5, '0')}.png`,
type: 'png',
});
if (i < count - 1) {
await page.waitForTimeout(interval);
}
}
return `Saved ${count} frames to ${dir}`;
};
For each theme, encode the frames into a GitHub-compatible MP4:
ffmpeg -y -framerate 60 \
-i "${TMPDIR:-/tmp}/sb-video-{THEME}/frame-%05d.png" \
-c:v libx264 -pix_fmt yuv420p \
-movflags +faststart \
{OUTPUT_DIR}/{PREFIX}-{THEME}.mp4
The -movflags +faststart flag is required for GitHub inline playback.
# Verify all four files
ffprobe -v quiet -show_entries stream=width,height,r_frame_rate,duration {OUTPUT_DIR}/{PREFIX}-light.mp4
ls -lh {OUTPUT_DIR}/{PREFIX}-*.mp4
# Clean up temp frames
rm -rf "${TMPDIR:-/tmp}/sb-video-light" "${TMPDIR:-/tmp}/sb-video-dark" "${TMPDIR:-/tmp}/sb-video-hc-light" "${TMPDIR:-/tmp}/sb-video-hc-dark"
List all produced files with their dimensions, framerate, duration, and file size.
mkdir -p "${TMPDIR:-/tmp}/sb-video-{THEME}"browser_run_code_unsafe call is independent - global state does not persist between callsrequire() or dynamic import() - use page.screenshot({ path }) to write filesEmulation.setDeviceMetricsOverride for video - use page.setViewportSize() instead for correct frame dimensionsGuide for working with the Podman Desktop extension feature mechanism: declaring features in an extension manifest, how the registry propagates them to the renderer, and how Svelte components detect active features. Use when adding a new feature declaration to an extension, writing renderer code that reacts to an extension being active/inactive, or debugging why a feature flag is not being picked up.
Reads a GitHub issue and all its linked issues, PRs, and comments to extract requirements and context. Invoke for any request combining a GitHub issue reference (#123, owner/repo#123, or URL) with a need to understand what the issue asks for — extracting acceptance criteria, understanding scope, gathering requirements before implementation or testing, or analyzing what changed. Extracts only what is explicitly stated in the issue and its linked references — does not invent or assume. Not for writing code, running tests, or debugging.
Set up or tear down the UX prototype screen switcher in the Podman Desktop titlebar. Use when the user wants to start a new UI/UX prototype, add prototype screen states, or remove the prototype infrastructure after a prototype ships. Triggers: "set up a prototype", "new prototype", "prototype switcher", "remove prototype", "tear down prototype".
Prepare and execute Design System component modernization. Drafts GitHub subtask issues, applies the Storybook HMR patch, and guides the modernization workflow. Use when starting work on a new component modernization, creating subtask issues, or when the user mentions design system modernization.
Apply or revert the local Storybook HMR patch that auto-rebuilds the UI package when source files change. Use when starting Storybook work, component modernization, or when the user mentions Storybook HMR or hot reload not working for UI components.
Capture a full-page HiDPI (retina, 2x) screenshot of a Storybook component's Docs page in all four themes (light, dark, hc-light, hc-dark). Use when the user asks to screenshot, capture, or grab the Docs page, autodocs, or full documentation view of a Storybook component.