# One-shot launch videos: what the skill decides, what the model writes

> Satyajit Ghana — Head of Engineering @ Inkers Technology
> canonical: https://ai.thesatyajit.com/articles/one-shot-launch-videos
> date: 2026-09-26
> tags: explainer, agents, open-source, code-generation, audio, video

Three GitHub links went round this week as launch videos that Claude made in one shot. The first,
[`latent-spaces/brag`](https://github.com/latent-spaces/brag), was pitched as a skill that "analyzes
your repo and outputs a complete motion-graphics teaser with sound design and launch copy in a single
run." The second, [`arimanyus/hophopnopenope`](https://github.com/arimanyus/hophopnopenope), is "the
code behind the coderabbit music video", a 128-second cartoon about a code-review rabbit whose
comments nobody reads. The third, [`arimanyus/warrenduffer`](https://github.com/arimanyus/warrenduffer),
came from the same author two days earlier and is not a video: it is an MIT-licensed trading bot, 54
tracked files, none about pictures or sound. I leave it there.

I cloned the other two, read every text file, counted lines and assets, and walked the git history.
I did not run their code. Every number is labelled: **measured** (I counted it), **reported** (the
repo or its author says so) or **reasoned** (I derived it; check my working).

The short version: "one shot" names the last step. What sits under that step differs by two orders of
magnitude, and that is where the engineering is.

<RepoCard repo="latent-spaces/brag" />

<RepoCard repo="arimanyus/hophopnopenope" />

## The shape they share

Strip the branding and both repos run the same five-stage pipeline (reasoned from the code; `/brag-slim`
leaves the tools open but assumes the same shape):

1. Read something: a project's pages and stylesheet, or a song.
2. Write a plan to a file: a storyboard with scenes and durations.
3. Write code that paints frame `n` as a pure function of time.
4. Drive a headless browser to call that code once per frame and save the picture.
5. Hand the frames and an audio track to `ffmpeg`, which muxes them into an MP4.

No image or video model draws anything; the music video's README says so outright. What differs is
who writes stage 3, where the audio comes from, and which clock is the master.

## /brag: a skill that writes a brief

`/brag` is a Claude Code plugin (version 0.4.0) by Shunit Haviv Hakimi. The skill is a 179-line
`SKILL.md` plus six reference files of 1,283 lines, so the agent is handed 1,462 lines of instructions
(measured). It runs four steps, each ending in a gate.

**Inspect.** The agent reads in a fixed order: `index.html` in full, the stylesheet (CSS custom
properties become the exact brand colours), `README.md`, `package.json`, routes and components, then
the user flow as three beats, "entry → key action → result". It skips lock files, `.env` files and
key material under a rule titled "nothing secret leaves this step", because anything read here can
end up on screen. The gate is a nine-question rubric: what the app is, its funniest claim, the visual
hook, which real UI to show, the shortest satisfying length, tone, audio, share caption, and the user
flow.

**Plan.** It writes `brag-plan.md`: angle, hook, two or three highlights, punchline, one of seven tone
presets, exact colours and fonts, audio direction, and a storyboard where every scene carries a
duration, its text, an audio intent and a transition. The gate is arithmetic: durations must sum to
15–25 s. A reading-time floor holds a short label about 0.8 s and a sentence about 0.3 s per word,
because pace should come "from fast motion, fast transitions, and tight cuts — NOT from pulling text
off screen before it can be read."

**Brief.** It writes `composition-brief.md` and loads five skills from
[Hyperframes](https://github.com/heygen-com/hyperframes), HeyGen's Apache-2.0 framework for
rendering HTML to video. `/brag` owns "the product angle, source material, storyboard, tone, format,
audio selection"; Hyperframes owns "the concrete composition structure, exact animation timing,
animation mechanics". The gate is `npx hyperframes check` with zero errors: lint, layout overflow,
and WCAG contrast as an error, not a warning.

**Deliver.** Render `brag.mp4`, pick a poster from the strongest settled beat, and bake it into frame
0 with an `ffmpeg` overlay (`enable='eq(n,0)'`), because "Slack, Twitter/X, and Discord regenerate
thumbnails server-side and ignore embedded cover-art metadata." At 30 fps the poster shows for
1/30 s. Then write `share-copy.txt`.

<Figure
  src="/articles/one-shot-launch-videos/fig1.png"
  alt="The brag launch page on an orange background. A huge black headline reads 'you built it. now brag.' with 'brag.' reversed out of a black block. Below it: 'A Claude Code skill that turns the project you created into a twenty-second launch video. One command. Music, motion, share copy included.' A dark install box shows two plugin commands. On the right, a tilted phone-shaped card plays a vertical video whose frame reads 'your site, now a launch video.' with a 'tap for sound' button."
  caption="The launch page, whose looping video the README says /brag made about its own repo. The pitch is a twenty-second video from one command; the skill's gate is 15–25 s. (latent-spaces/brag, docs/assets/hero.png, MIT, Figure 1)."
/>

### How it picks what to show

The planning reference ranks four ways to fill a scene: recreate a working-app moment ("the product
*doing* its thing beats the product *describing* its thing"), recreate one UI element in HTML,
animate the core concept, or let the copy be the visual. It bans "abstract patterns, color washes, or
generic motion graphics that could belong to any video."

The repo ships five absurd product sites in `examples/` as a benchmark, each with its render. The five
renders run 20 to 23 seconds at 1920x1080 and 30 fps (measured with `ffprobe`). One input and its
output:

<Figure
  src="/articles/one-shot-launch-videos/fig2.png"
  alt="A dark landing page for 'Taxi for Taxis', eyebrow 'Cab-to-cab dispatch, live in 12 metros', headline 'When your taxi needs a ride.', a yellow Request pickup button, and on the right a dispatch panel: a midtown street grid, taxi #4821 and taxi #2207 joined by a yellow route, and an ETA card reading 3:08."
  caption="The input: the Taxi for Taxis example site as a visitor sees it. (latent-spaces/brag, docs/examples/taxi-for-taxis/site.jpg, MIT, Figure 2)."
/>

<Figure
  src="/articles/one-shot-launch-videos/fig3.png"
  alt="Four frames from the rendered launch video in a two-by-two grid, all on the site's near-black and yellow palette. Top left, the hook: 'Every day, taxis carry us. But who carries the taxis?'. Top right, the dispatch panel rebuilt full-frame with the same taxi numbers and the 3:08 ETA. Bottom left, a testimonial: 'I used to drive all night. Now sometimes I get driven.' Bottom right, the outro: the T4T logo, 'Taxi for Taxis', 'The ride-hailing app for ride-hailing assets.', 'Live in 12 metros.'"
  caption="The output, frames pulled at 3, 7, 13 and 17 s from the 21-second render: hook, the product's own UI, a line of its copy, logo. (latent-spaces/brag, docs/examples/taxi-for-taxis/brag.mp4, MIT, Figure 3)."
/>

The shape is the skill's pattern and the material is the site's: the taxi numbers `#4821` and
`#2207`, the 3:08 ETA and the testimonial are verbatim from `index.html` (measured). The hook line is
not on the site. It is the worked example of share copy in the skill's own `step-4-deliver.md`. Both
arrived in the first commit on 2026-06-16, so I cannot tell which informed which, but the benchmark's
best line is printed in the prompt.

## The render stacks

| | draws with | timeline | clock while rendering | audio joins |
|---|---|---|---|---|
| `/brag` | HTML and CSS in a Hyperframes composition | one paused GSAP timeline per composition, clips timed by `data-start` and `data-duration` | the composition time the framework seeks to | inside the composition, as timed `<audio>` clips (reported) |
| `/brag-slim` | "whatever works on this machine" | whatever the model writes | "make every frame a pure function of time" | the model's choice |
| music video | Canvas 2D in headless Chrome, driven by `puppeteer-core` | a registry of chapters and shots, each a function of song time | frame index over 24 | at the final `ffmpeg` mux, and only there |

None of them uses Remotion, Three.js, Tone.js or the Web Audio API (measured, case-insensitive search
of every tracked text file). GSAP enters `/brag` only through the framework, whose core skill requires
"exactly one `gsap.timeline({ paused: true })`" per composition and bans render-time clocks, unseeded
`Math.random` and network access. That is what lets a headless browser seek to any frame and get the
same picture twice.

The music video's `render.mjs` is 78 lines. It calls `window.renderAt(t)` in several Chrome pages at
once, writes JPEGs into `out/frames`, skips frames already on disk so a crashed render resumes, and
encodes x264 at CRF 16 with the song as 256 kbit/s AAC. At 24 fps its 128.64 s come to 3,087 frames
(reasoned from the frame loop).

## Keeping time with the audio

### /brag: the music is a cue sheet

The five bundled tracks each ship a precomputed cue preset, generated by a 309-line
`analyze_music_cues.py` that uses librosa's onset strength, RMS loudness, a 30–180 Hz bass band and
its beat tracker. A preset holds a tempo, a beat grid and 64 `strongCues` per track (measured). The
rules are tolerances: a major reveal may move toward a strong cue by ±0.15 s, a smaller entrance may
snap to a beat within ±0.10 s, a video gets one to three strong locks, and readability wins every
conflict. At 110+ BPM, text that must be read snaps to every other beat or holds as a set, a rule the file
traces to a benchmark whose sequence "rushed the bicycles spec rows."

The audio sits inside the composition as `<audio data-start data-track-index data-volume>` clips,
music at 0.3–0.4 and effects at 0.55–0.85. The framework owns media playback, so sound and animation
read one timeline.

### The music video: measure the song, then read the tables

Here the song came first, and `tools/` is a small forced-alignment pipeline (measured, reading the
scripts):

1. Demucs splits vocals from band; both stems are committed, two 22.7 MB WAVs.
2. `transcribe.py` runs faster-whisper large-v3 through stable-ts on the vocal stem.
3. `align.py` force-aligns the 32 known lyric lines, word by word.
4. `transcribe_windows.py` re-transcribes short windows, because "whole-song passes skip the ad-lib
   tags".
5. `refine.py` snaps hit words (`hop`, `nope`, `click`, `tick`) to the strongest vocal onset within
   0.18 s and measures held notes with pYIN.
6. `finalize.py` applies 12 "Hand-checked fixes"; `build_data.mjs` bakes the tables into
   `src/data.js`.

The result is 32 lines, 239 word onsets and 301 tracked beats at about 142.2 BPM, with a warning that
the grid drifts up to about 0.13 s from a constant tempo.

The author's post says "the alignment also found a sung 'as mentioned above' at 2:00 that wasn't in
the lyric sheet." The data has it at 120.0–122.25 s. One precision: forced alignment only places
words you hand it, and `refine.py` credits those three words to the per-window pass. The post also
says its template's karaoke "estimates word timing from line length". That checks out: the template
times whole lines from burned-in subtitles and fills letters at a fixed rate, the sung duration being
the smaller of the line length minus 0.1 s and 0.45 s + 0.075 s per character.

Two rules turn the tables into sync. Cuts snap "to the frame that *contains* their time, so a cut on a
downbeat is never late." And every beat and hit helper looks one frame ahead (`VLEAD = 1 / 24`), the
"sync law": "a visual hit lands on the frame of the sound or one frame early, never late." In preview
the `<audio>` element's `currentTime` drives the drawing; in the render the frame number does.

<SongTimeline />

The chapter files register 85 shots in 8 chapters. The mean shot lasts 1.51 s, the median 1.42 s;
the shortest is 0.17 s before the opening stab, the longest the intro's 4.92 s `fall` (measured). Of
the 85 cuts, 72 land within 50 ms of a tracked beat or a measured word onset, allowing for the
one-frame lead: 36 near a beat, 55 near a word. A random cut manages that about 51% of the time, so
the alignment is deliberate, not total (measured over 200,000 random times).

## Sound design: bought, made, or sung

**`/brag` buys it.** It bundles 260 effect files, 3.1 MB: 51 card and chip sounds, 109 impacts, 20
interface sounds, 48 clicks and switches, 32 keypresses (measured), all CC0, mostly Kenney's. A
generated `sfx-analysis.md` scores each for "high-frequency risk" so the agent keeps harsh sounds off
anything that repeats. Music is five tracks from ende.app, 13 MB. Narration is opt-in: `--voice`
runs Kokoro through `npx hyperframes tts` and ducks the music to 0.12–0.15.

**`/brag-slim` makes it.** No assets. The one sound instruction: "Write the music and sound effects
as one piece: effects in the same key and the same space as the music, blended in rather than laid
on top." With nothing bundled, the model must synthesise or source the score with what the machine
has (reasoned; the skill does not say how). Its demo is 22.5 s of 1080x1080 video with AAC audio
(measured).

**The music video sings it.** The audio is the finished song; a tools comment mentions "the unlisted
Suno tags", placing its origin in a music generator (reported). `render.mjs` muxes exactly one audio
input, so no effects are added (measured).

## What "one shot" measures

| | `/brag` | `/brag-slim` | music video |
|---|---|---|---|
| Instructions or briefs | 1,462 lines | 101 lines | 1,688 lines of docs: style sheet, storyboard, animation guide, two research files |
| Bundled assets | 260 effects, 5 tracks, about 16 MB | none | the song twice, two stems, 10 fonts |
| Framework underneath | five Hyperframes skills: 166 markdown files, 20,616 lines at today's head | none | `puppeteer-core` only |
| Video code committed | 0 lines (`brag-output*/` is ignored) | 0 lines | 4,819 lines of chapters on 1,640 lines of shared library and render code |
| History | 34 commits over 100 days, 7 contributors | added in 1 commit, 2026-09-24 | 5 commits in 3 h 49 min, then a README edit |

All measured. The Hyperframes figure is a ceiling: its reference files are read on demand.

For `/brag`, one shot is literal at run time: one command, four gates. But the skill has a hundred
days of commits behind it, growing from 1,395 lines of instructions to 1,462 and picking up the
best-beat poster, the frame-0 bake, the secrets rule and narration. The full skill now hands off to
`/brag-slim` on its own when it detects one particular newer model, unless the user asks for the full
workflow or for narration. The maintainer's bet, then, is that one model needs 101 lines and no
assets while every other model gets 1,462 lines, 260 sound files and a framework. The generated half,
the composition written on each run, is never committed, so I cannot measure it.

For the music video, the history reads like an orchestrated build on 2026-09-24. At 18:02, only the
song, stems and timing data. At 18:38, 754 lines of shared library and eight chapter files of one
line each. At 19:46, seven chapters with code, 3,438 lines, and the intro still a stub. At 20:14, a commit titled "subagent 2/8 completed",
all eight, 4,699 lines. At 21:51, "full code", 4,819. The animation guide tells each chapter author
"Only edit your own chapter file", to report shared-file bugs "in your final message", and to check
contact sheets before finishing: a brief for parallel sub-agents. The template's README says its own
guide was written "to brief the subagents it ran in parallel" (reported). So one shot here means one
session: an orchestrator, eight chapter agents and at least four checkpoints (reasoned).

## The music video: whose template

The post credits the template to two creators' earlier videos. The README credits one project,
[`JohnHeibel/PDoomVideo`](https://github.com/JohnHeibel/PDoomVideo), and its shape: "a storyboard,
then a shared drawing library and character rig, then one file per chapter, then a frame render, then
an ffmpeg mux." I could not map the post's two handles to repositories, so I measured against the one
the README names. The layout matches file for file. Identical non-blank lines, in order:

| file | lines matching the template |
|---|---|
| `render.mjs` | 33 of 74 |
| `studio.html` | 19 of 52 |
| `src/timeline.js` | 7 of 49 |
| `src/core.js` | 10 of 104 |
| `src/props.js` | 11 of 398 |

The render driver and page are inherited; the drawing is new. The template paints watercolour with
p5.brush. The music video depends on `puppeteer-core` alone and prints riso in plain Canvas 2D: named
inks, halftone instead of gradients, colour plates offset for depth, outlines that re-seed ("boil")
12 times a second, characters on twos and cameras on ones. That is the swap the post describes.

What is hand-authored, git cannot say. All six commits come from one account, and the README makes no
claim, while the template's README says everything in it was generated. "Hand-checked" timing fixes
are not necessarily hand-typed. The certainly external pieces are the song, the fonts and the
pattern. That pattern has a descendant this site vendors: the template's README points to John
Heibel's [Claude Animation Base](https://github.com/JohnHeibel/ClaudeAnimationBase), which lives in
`brand-crew/skills/claude-animation-base/`.

## Licences

- `/brag` is MIT, copyright 2026 Shunit Haviv Hakimi, and its effects are CC0. Its music is not
  covered: the repo's `assets/music/README.md` says "Before publishing or redistributing the skill,
  verify and document the exact music license terms alongside these files," and no terms are
  committed (measured). So 13 MB of the plugin ships under undocumented terms.
- Hyperframes is Apache-2.0.
- The music video has no `LICENSE` file: default copyright, no grant to reuse. It also commits the
  song twice, 45 MB of separated stems (its `.gitignore` arrived one commit after them), and ten
  fonts, 22 MB, without their licence texts. So this page shows no frames from it; the widget carries
  its timing tables, not its pictures or lyrics.
- PDoomVideo has no `LICENSE` file either. Claude Animation Base and `warrenduffer` are MIT.

Every image here comes from `/brag`'s MIT-licensed repo.

## Against this site's own films

This site makes two kinds of film, one on each side of the divide.

The hand-drawn ones, like the narrated film opening [the Kalman filter
article](/articles/kalman-filter), are per-film code: the vendored hand-drawn-canvas-animation skill
has the model write one Canvas 2D file per film over a shared core, with a generated Web Audio score.
That is the music video's design.

The explainer films, like the one on [the figures4papers audit](/articles/figures4papers), are the
other design. The model writes only data: a storyboard in `data/films/<slug>.json`, built from 15
scene types with at most 280 words of narration. A fixed engine of about 4,400 lines (measured) owns
the rest: eighteen drawn styles, the motion, the host, the Kokoro voice, and a score `audio.py`
synthesises from sine waves, noise and a plucked-string model. Sync is the engine's problem: it made
the score, so it knows the beat grid and rounds every scene up to the next beat.

- **A storyboard can be checked.** `pnpm validate:films` fails when a digit in the film is not in the
  article, a quote is not verbatim or diagram nodes collide, and a hash marks a film stale when its
  inputs change. The music video's 4,819 lines of chapter code have no such spec, only a prose
  storyboard and contact sheets.
- **A storyboard is bounded.** Fifteen scene types cannot express a rabbit buried under four hundred
  comment-bunnies on twos. Per-film code can express anything the model can write, which is the point
  and also the review burden.
- **`/brag` sits between.** It fixes the story contract and generates the implementation inside a
  framework whose contract a linter checks before anything renders.

| decision | `/brag` | `/brag-slim` | music video | explainer films here |
|---|---|---|---|---|
| what it says | model, inside the rubric | model | the song's lyrics | author's storyboard, checked against the article |
| scenes and durations | model, gated to 15–25 s | model | model, locked to measured times | storyboard; engine rounds to the beat |
| frame code | model, as a Hyperframes composition | model, any tool | model, eight chapter files | engine; none per film |
| music | one of 5 bundled tracks | model | the song | engine, synthesised per style |
| effects | picked from 260 bundled files | model | none | engine, synthesised per cue |
| voice | off; Kokoro if asked | none | the sung vocal | Kokoro, always |
| gate before render | `hyperframes check` | the model looks at stills | contact sheets | `validate:films` |

Nothing in any of these repos scores a finished video except the person watching it; for what judging
generated brushwork takes, see [the article on a model that paints in p5.brush](/articles/paint-with-code).

## What I would take from each

- **Measure the audio before animating to it.** Forced-alignment word onsets beat a formula on line
  length, and a one-frame lead keeps every hit on or before its sound.
- **Gate before the render.** `/brag`'s nine questions, its 15–25 s sum and its contrast check are
  cheap. A failed render is not.
- **Bake the poster into frame 0.** One `ffmpeg` filter, and in the skill's words "the *only* reliable
  way to control the idle image everywhere".
- **Licences before assets.** One repo ships 13 MB of music under terms its own README calls
  unverified; the other has no licence at all.

"One shot" is accurate about the final run. It is silent about the 1,462 lines, the 260 sound files,
the framework, the aligned song and the eight sub-agents behind it. Those are the parts worth copying.
