/teaser-video
Film, edit, and deliver a launch-quality teaser of any web app - real footage captured at 2x with Playwright + CDP (and Windows Graphics Capture for external windows such as an agent's browser), edited in Remotion with a virtual camera, motion graphics, kinetic type, and a
Claude Code
$ npx -y skills add suxrobGM/jobpilot --skill teaser-video --agent claude-code
Codex
$ npx skills add suxrobGM/jobpilot --skill teaser-video -a codex -y
Cursor
$ npx skills add suxrobGM/jobpilot --skill teaser-video -a cursor -y
Gemini CLI
$ npx skills add suxrobGM/jobpilot --skill teaser-video -a gemini-cli -y
GitHub Copilot
$ npx skills add suxrobGM/jobpilot --skill teaser-video -a github-copilot -y
OpenCode
$ npx skills add suxrobGM/jobpilot --skill teaser-video -a opencode -y
Windsurf
$ npx skills add suxrobGM/jobpilot --skill teaser-video -a windsurf -y
SKILL.md
teaser-video.SKILL.mdname: teaser-video
description: Film, edit, and deliver a launch-quality teaser of any web app - real footage captured at 2x with Playwright + CDP (and Windows Graphics Capture for external windows such as an agent's browser), edited in Remotion with a virtual camera, motion graphics, kinetic type, and a synthesized license-free soundtrack. Use for "make a teaser", "record a demo video", "product launch video", "screen recording for the README".
user-invocable: true
compatibility: Node 24+, ffmpeg 8+ on PATH (gfxcapture + h264_nvenc on Windows; swap `ENCODER` in cam.js elsewhere), and a Chrome channel for Playwright. npm packages come from reference/capture and reference/edit package.json, installed in a scratch dir, never the project.
metadata:
version: "1.2"
updated: "2026-11-08"
portable: "true"
Teaser video
A ~40s teaser that looks like a product film, not a screen recording. The difference is direction: one story, real proof, a camera that moves with intent, graphics that explain cause and effect, and sound cut to a beat.
Pipeline: **capture** real footage (Playwright drives, CDP films at 2x) → **edit** in Remotion (React components rendered frame by frame) → **review** every frame for PII → deliver MP4 + poster + README GIF.
Work in a scratch directory, never in the project:
cp -r <skill>/reference/capture "$SCRATCH/film" && (cd "$SCRATCH/film" && npm install)
cp -r <skill>/reference/edit "$SCRATCH/edit" && (cd "$SCRATCH/edit" && npm install && npm run synth && npm run still)
export TEASER_BASE_URL="https://the-app.example.com"
export TEASER_LOCAL_STORAGE='{"some:ui-pref":"value"}' # optional UI state to pin`npm run still` renders the starter `Teaser.tsx` (no clips needed), proving the toolchain works before any filming. Keep every `remotion` / `@remotion/*` package on the same version; mismatches fail at render time.
**Updating JobPilot's own teaser?** Start from `reference/jobpilot/RECIPE.md`. It overlays the shipped v3 timeline, clock map, music and scenes on this kit, so a re-edit is copy + render and a re-film reuses every script.
The two hard rules
**1. Real side effects need explicit, itemized consent.** Filming a real app clicks real buttons: applications get submitted, emails sent, accounts touched. Agree the scope with the user before rolling. Answer the app's own prompts only within that scope; anything that creates accounts, picks a sign-in method, or answers personal questions (tax, demographics) stays parked for the user. Before stopping a long-running process, let the in-flight unit of work finish instead of cutting it mid-way. Report every outcome, including failures and anything the product did on its own (password resets, etc.).
**2. Every frame is public.** Agree what may show (e.g. name + email) and treat everything else as private: phone numbers, other people's names (chat bubbles), security answers, tokens. Hide by framing, by masking in the edit, or by not filming that part of the page. Dashboards can quote secrets verbatim (a "failure reasons" list once showed a security-question answer) - read every captured screen, not just the part you meant to film.
1. Scout and storyboard
Screenshot every candidate screen with the saved session. Write the storyboard on the music grid (120 BPM → 1 bar = 2s = 120 frames at 60fps), then put the section lengths in `reference/edit/storyboard.json`. `theme.ts` (`SECTIONS`) and `audio/synth.mjs` both read it, so retiming a section moves the cuts and the music together:
| Beat | Length | Job | | --- | --- | --- | | Hook | 2 bars | The pain, as a pure motion graphic (no UI yet) | | Reveal | 1 bar | Logo on the impact | | Start | 4 bars | The one action the user takes | | Hero | 5 bars | The product doing the thing, split-screen if two surfaces | | Payoff | 5 bars | Results landing in the app (counters, lists, charts) | | Trust | 3 bars | Control and where it runs | | Close | 2 bars | Logo, URL, CTA |
The hero is the reason the video exists. Show cause and effect: the agent acts in one pane, the result appears in another, and a graphic (a chip flying from the success state into the counter) connects them.
2. Capture
- `login.js`: headed login once, saves `storageState.json`. In Git Bash set
`MSYS_NO_PATHCONV=1` or path args like `/login` become Windows paths.
- `cam.js`: choreographed takes, and the shared kit `login.js`/`live.js` build
on (`BASE`, `AUTH_PATHS`, `ENCODER`: swap to libx264 there without NVIDIA). `open()`, `roll()` (CDP screencast piped into ffmpeg with wall-clock timestamps), `click()`/`glide()` with an injected cursor, `scrollTo()`/`scrollToEl()` on the app's inner scroll container. Pass `ready` (a selector for the content the shot needs) to `open()`/`go()` so takes start on loaded UI instead of after a guessed sleep.
- `live.js`: long unattended takes of a real run. Films the page, auto-detects
the agent's own Chrome window and records it with `gfxcapture` (works while covered by other windows, not while minimized), and logs status changes with timestamps so you can find the moments afterwards. Stop it by touching `takes/<name>/STOP`. The window capture shows only Chrome's front tab, and Playwright MCP can fill a form in a background tab, so plan the proof of the submit around the agent's terminal and the app, not the form itself. `--do scene.js` runs a scene module (`export default async ({ page, log })`) after rolling, for the user's on-camera clicks inside the same take.
- `scout.js`: screenshots `name=/path` pairs for the storyboard. Set
`TEASER_READY` when the first `<main>` is hidden.
- `tool-calls.mjs`: every Claude Code tool call with its timestamp, from the
session transcripts (subagents included) inside named wall-clock windows. Feed it to an on-screen counter so the number is real, not invented.
- If the agent is Claude Code launched from your own Claude Code session,
unset the inherited `CLAUDE*` env first, or
Read more
name: teaser-video description: Film, edit, and deliver a launch-quality teaser of any web app - real footage captured at 2x with Playwright + CDP (and Windows Graphics Capture for external windows such as an agent's browser), edited in Remotion with a virtual camera, motion graphics, kinetic type, and a synthesized license-free soundtrack. Use for "make a teaser", "record a demo video", "product launch video", "screen recording for the README". user-invocable: true compatibility: Node 24+, ffmpeg 8+ on PATH (gfxcapture + h264_nvenc on Windows; swap `ENCODER` in cam.js elsewhere), and a Chrome channel for Playwright. npm packages come from reference/capture and reference/edit package.json, installed in a scratch dir, never the project. metadata: version: "1.2" updated: "2026-11-08" portable: "true"
Teaser video
A ~40s teaser that looks like a product film, not a screen recording. The difference is direction: one story, real proof, a camera that moves with intent, graphics that explain cause and effect, and sound cut to a beat.
Pipeline: **capture** real footage (Playwright drives, CDP films at 2x) → **edit** in Remotion (React components rendered frame by frame) → **review** every frame for PII → deliver MP4 + poster + README GIF.
Work in a scratch directory, never in the project:
cp -r <skill>/reference/capture "$SCRATCH/film" && (cd "$SCRATCH/film" && npm install)
cp -r <skill>/reference/edit "$SCRATCH/edit" && (cd "$SCRATCH/edit" && npm install && npm run synth && npm run still)
export TEASER_BASE_URL="https://the-app.example.com"
export TEASER_LOCAL_STORAGE='{"some:ui-pref":"value"}' # optional UI state to pin`npm run still` renders the starter `Teaser.tsx` (no clips needed), proving the toolchain works before any filming. Keep every `remotion` / `@remotion/*` package on the same version; mismatches fail at render time.
**Updating JobPilot's own teaser?** Start from `reference/jobpilot/RECIPE.md`. It overlays the shipped v3 timeline, clock map, music and scenes on this kit, so a re-edit is copy + render and a re-film reuses every script.
The two hard rules
**1. Real side effects need explicit, itemized consent.** Filming a real app clicks real buttons: applications get submitted, emails sent, accounts touched. Agree the scope with the user before rolling. Answer the app's own prompts only within that scope; anything that creates accounts, picks a sign-in method, or answers personal questions (tax, demographics) stays parked for the user. Before stopping a long-running process, let the in-flight unit of work finish instead of cutting it mid-way. Report every outcome, including failures and anything the product did on its own (password resets, etc.).
**2. Every frame is public.** Agree what may show (e.g. name + email) and treat everything else as private: phone numbers, other people's names (chat bubbles), security answers, tokens. Hide by framing, by masking in the edit, or by not filming that part of the page. Dashboards can quote secrets verbatim (a "failure reasons" list once showed a security-question answer) - read every captured screen, not just the part you meant to film.
1. Scout and storyboard
Screenshot every candidate screen with the saved session. Write the storyboard on the music grid (120 BPM → 1 bar = 2s = 120 frames at 60fps), then put the section lengths in `reference/edit/storyboard.json`. `theme.ts` (`SECTIONS`) and `audio/synth.mjs` both read it, so retiming a section moves the cuts and the music together:
| Beat | Length | Job | | --- | --- | --- | | Hook | 2 bars | The pain, as a pure motion graphic (no UI yet) | | Reveal | 1 bar | Logo on the impact | | Start | 4 bars | The one action the user takes | | Hero | 5 bars | The product doing the thing, split-screen if two surfaces | | Payoff | 5 bars | Results landing in the app (counters, lists, charts) | | Trust | 3 bars | Control and where it runs | | Close | 2 bars | Logo, URL, CTA |
The hero is the reason the video exists. Show cause and effect: the agent acts in one pane, the result appears in another, and a graphic (a chip flying from the success state into the counter) connects them.
2. Capture
- `login.js`: headed login once, saves `storageState.json`. In Git Bash set
`MSYS_NO_PATHCONV=1` or path args like `/login` become Windows paths.
- `cam.js`: choreographed takes, and the shared kit `login.js`/`live.js` build
on (`BASE`, `AUTH_PATHS`, `ENCODER`: swap to libx264 there without NVIDIA). `open()`, `roll()` (CDP screencast piped into ffmpeg with wall-clock timestamps), `click()`/`glide()` with an injected cursor, `scrollTo()`/`scrollToEl()` on the app's inner scroll container. Pass `ready` (a selector for the content the shot needs) to `open()`/`go()` so takes start on loaded UI instead of after a guessed sleep.
- `live.js`: long unattended takes of a real run. Films the page, auto-detects
the agent's own Chrome window and records it with `gfxcapture` (works while covered by other windows, not while minimized), and logs status changes with timestamps so you can find the moments afterwards. Stop it by touching `takes/<name>/STOP`. The window capture shows only Chrome's front tab, and Playwright MCP can fill a form in a background tab, so plan the proof of the submit around the agent's terminal and the app, not the form itself. `--do scene.js` runs a scene module (`export default async ({ page, log })`) after rolling, for the user's on-camera clicks inside the same take.
- `scout.js`: screenshots `name=/path` pairs for the storyboard. Set
`TEASER_READY` when the first `<main>` is hidden.
- `tool-calls.mjs`: every Claude Code tool call with its timestamp, from the
session transcripts (subagents included) inside named wall-clock windows. Feed it to an on-screen counter so the number is real, not invented.
- If the agent is Claude Code launched from your own Claude Code session,
unset the inherited `CLAUDE*` env first, or
An AI agent that applies to jobs for you, using the Claude or Codex subscription you already have. Open JobPilot → · Docs · How it works · Changelog Watch it full size → Applying for jobs takes hours.
Other skills on jobpilot.
More skills from other plugins.
browser-use
Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…
agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…
Questions about teaser-video.
- Which coding agents can use teaser-video?
- teaser-video installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

