From merge-movies
Record a browser demo video using Playwright and add it as a VideoView scene in a merge.mov movie.
How this skill is triggered — by the user, by Claude, or both
Slash command
/merge-movies:record-demoThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Record a browser demo video using Playwright and add it as a VideoView scene in a merge.mov movie.
Record a browser demo video using Playwright and add it as a VideoView scene in a merge.mov movie.
$ARGUMENTS
This skill records a browser viewport video by:
.merge-movies/demos/Scripts and videos are persisted in .merge-movies/demos/ so they can be reviewed, re-run, or debugged.
This skill uses the merge-movies MCP server. All tools are available automatically. Authentication is handled automatically via OAuth — on first use, a browser window opens for you to log in, and tokens are managed by Claude Code.
Key tools for this skill:
| Tool | Description |
|---|---|
create_video_upload | Get a presigned upload URL for a video file |
create_scene | Create a VideoView scene with the uploaded video |
list_movies | List movies to find the target movie |
get_movie | Get movie details |
Parse $ARGUMENTS to determine:
npm install playwright 2>/dev/null && npx playwright install chromium --with-deps 2>/dev/null || npx playwright install chromium
This installs the playwright npm package and downloads Chromium (~150MB) on first run. If already installed, it exits quickly.
Choose a descriptive kebab-case name for the demo (e.g., login-flow, search-feature, theme-picker). Use the Write tool to create the script at .merge-movies/demos/<name>.mjs.
The script should follow this template:
// .merge-movies/demos/<name>.mjs
import { chromium } from 'playwright';
import { dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const browser = await chromium.launch();
const context = await browser.newContext({
recordVideo: { dir: __dirname, size: { width: 1280, height: 720 } },
viewport: { width: 1280, height: 720 },
});
const page = await context.newPage();
// === Customize this section for the specific demo ===
await page.goto('http://localhost:5173');
// Perform the demo actions: clicks, fills, navigations, waits...
// Example:
// await page.fill('#email', '[email protected]');
// await page.click('button[type="submit"]');
// await page.waitForSelector('.dashboard');
// === End custom section ===
// Final pause so the viewer can see the end state
await page.waitForTimeout(2000);
// Close context to finalize the video
await context.close();
const videoPath = await page.video().path();
console.log('VIDEO_PATH:' + videoPath);
await browser.close();
Tips for the script:
page.waitForTimeout(ms) between actions for pacing (500-1500ms between steps)page.waitForSelector(selector) instead of fixed waits when possiblestorageState to save the browser session after the first login and reuse it for subsequent recordings:
// After logging in:
await context.storageState({ path: '.merge-movies/demos/auth-state.json' });
// For future recordings:
const context = await browser.newContext({ storageState: '.merge-movies/demos/auth-state.json', ... });
node .merge-movies/demos/<name>.mjs
Parse the video file path from the VIDEO_PATH: line in stdout. The .webm file will be saved in .merge-movies/demos/ alongside the script.
If the script fails, read the error output, fix the script file, and re-run. The script persists on disk so you can iterate without rewriting from scratch.
create_video_upload with the movie ID:create_video_upload({ movieId: "<movie-id>" })
-> { presignedUploadUrl, videoSource, filename, uploadInstructions }
curl -X PUT "<presignedUploadUrl>" \
-H "Content-Type: video/webm" \
--data-binary @<video-path>
create_scene({
movieId: "<movie-id>",
scene: {
title: "Demo: <feature name>",
narration: "<description of what the video shows>",
view: {
type: "video",
source: "<videoSource from step 5>",
aspectRatio: 1.778
}
}
})
Note: aspectRatio should be 1.778 (16:9) to match the 1280x720 recording.
Tell the user the demo video has been recorded and added to the movie. Provide the studio URL so they can preview it.
Note: The script and video remain in .merge-movies/demos/ for future reference. This folder is gitignored.
/merge-movies:record-demo movie:abc123 Demo the login flow at localhost:5173
/merge-movies:record-demo movie:abc123 Demo the new search feature we just built
/merge-movies:record-demo movie:abc123 Navigate to localhost:5173/settings and show the new theme picker
npm install playwright && npx playwright install chromium manuallycontext.close() is called before accessing the video path.merge-movies/demos/<name>.mjs — read the error, fix the file, and re-runnpx claudepluginhub marked-gold/merge-movies-claude-code --plugin merge-moviesRecords polished UI demo videos of web applications using Playwright, following a three-phase discover-rehearse-record process. Best for creating walkthroughs, tutorials, or feature showcase videos for documentation or presentations.
Records browser interactions into MP4 feature demo video, uploads to GitHub, and embeds in PR description for reviewer walkthroughs.
Records polished UI demo videos with Playwright, including visible cursor overlays, natural pacing, and professional WebM output. Uses a three-stage process of discovery, rehearsal, and recording.