Art-Directing a Site Trailer with Claude Code and webreel
We added the webreel skill to Claude Code, then made a site trailer by describing shots — recording, camera moves, cuts, and a Suno soundtrack — one prompt at a time. Every prompt from the session, verbatim.
We shipped the umwelten dialogue explorer — a page where LLM personas debate a question you pose — and wanted a trailer for it. Instead of screen-capture takes and a video editor, we added the webreel skill to Claude Code and then art-directed: described what should happen on screen, watched the take, gave notes, and let the agent figure out the tooling. The whole edit — recording, virtual camera, fast-forward, cuts, soundtrack — came out of a conversation.
Here’s the result, 76 seconds, regenerated end-to-end by four commands:
What follows is the actual session — every prompt verbatim, typos and all, because that’s the point: none of it needed to be precise. Each note is what the agent did with it.
Setup: give the agent the skill
Two pieces of prep, both one-liners:
npm install webreel # pin the recorder in the project
npx skills add vercel-labs/webreel # teach Claude Code how to use it
The skill matters. On our first attempt Claude reverse-engineered webreel by
reading node_modules — it worked, but slowly. With the skill installed it
knew the config format, the CLI, and the debugging flags up front, and got to
work immediately.
Act I — describe the shot
look inside of @examples/dialogue-web/ and we want to update the @examples/dialogue-web/webreel.config.json to record an example debate. first we want to open up the browser, create a bunch of agents. one that is artistle, Jeremy Bentham, williams james, nietzche, the dali llama, and john adams. have a two round debate. the qeustion is “what is the right legal and regulatory framework to think about developing artifictial intelligence in a global society?” i want to see the view of first adding the agents, selecting the models, then entering the question, and then watching the results stream in.
That’s the whole brief. The agent wrote a 59-step webreel config: typing the
OpenRouter key (into a password field, injected via $OPENROUTER_API_KEY so
it never lands in git), filling six philosopher cards each on a different
model, posing the question, and waiting out the streamed debate.
The first take failed in an interesting way — the recording ran but no debate
started. The agent re-recorded with --frames, looked at the captured
JPEGs, and diagnosed two genuine webreel bugs from the screenshots: type
steps that carry a selector mis-target, and clicking an empty field breaks
the caret so keystrokes silently vanish (fixed with a select-all between
click and type). Take three worked.
where are the bideos gettinb stored?
videos/, next to the config. We watched the take in Finder after every
iteration — that’s the review loop.
Act II — give notes
can we also extract the transcript at the end and then save it/ also there seems to be a bunch of “select all”. Also I want to zoom in on what is added when it’s happening, and i don’t know if there s awya to edit it afterwards
Three notes, three fixes, no re-shoot for two of them:
- Transcript: headless Chrome silently drops file downloads, so the agent
added a
?post=hook to the page and a tiny dev server that saves the exported markdown totranscripts/. - The ⌘A chips: webreel keeps the raw footage and a per-frame timeline in
.webreel/, so the agent nulled the keystroke-HUD track and re-composited — the existing video, cleaned, no re-record. - Zoom: webreel has no dynamic camera, but that timeline records the
cursor position on every frame. That became
cinematic.py.
is there a way taht we can start out fiull zopomed, then dynamically move to where the mouse is focused to, etc? maybe it a bit more theatrical? and zoom in to the text while its getting generated, and then zoom out at the end?
This is where it got fun. The agent wrote a ~150-line Python camera pass driven by the timeline’s cursor track: an establishing shot, a 1.6× close-up that trails the cursor with smoothing like a camera operator, a re-frame onto the streaming text, and an ease-out at the end. Every zoom level is a constant at the top of cinematic.py.
can we speed it up? I want to have it once artistitode is filled out, then we can 5x the speed to fill out the other ones, and then return to normal speed when watching the debate.
Fast-forward as frame-dropping, anchored to click timestamps from the timeline so it survives re-records.
nothing happening with ths epeedup — it jsut stayed on the same image. also its still doing a “select all” or something.
Two notes: the first was a stale QuickTime buffer (the file is rewritten in place — reopen it), but it produced a good fix anyway: a ▸▸ badge burned into the sped-up frames so the fast-forward reads as intentional. The second was real — the page’s blue selection flash — hidden with CSS scoped to recorded runs only.
Act III — redesign and choreography
ok i’m changing the design, so it looks a little better. also lets start the speedup once you enter in the api key. and also show the dropdown select for the model — and swtich out the first one so its not gemini
Mid-project the page got a full redesign. Re-shooting was one command. The
dropdown note surfaced another headless truth: native dropdowns (datalist,
<select>) are browser chrome — invisible on camera. The agent replaced the
model field with a 30-line in-page combobox, which is also just better UX.
ok lets now also open up the markdown file and slowly scroll down it, so we can see what it exported transcrit looks like, and then add that video to the end of the cinamatic on, and then have a closing image of a linkt to https://umwelten.thefocus.ai/guide/agent-dialogues.html
Now it’s an edit: three clips — the demo, a slow scroll of the exported transcript (a styled viewer page serving the newest file), and an end card in the site’s design — concatenated with ffmpeg.
actually, lets speed up the whole thing until the transcript, its too long
One constant changed. The debate becomes something you watch happen; the transcript scroll is where you read it.
Act IV — the song
whoare the phisophers and what are their postions? can you give me highlights of what it in the transcript to write some song lyrics
The agent pulled the best lines from the transcript — Nietzsche calling regulation “parchment chains forged by the weak to hobble the strong,” Aristotle’s “builds weapons, not wonders” — as lyric material. Those went into Suno, which returned Parchment and Pulse.
mix in the audio that we just geneated in @~/Downloads/
Video stream copied untouched, song trimmed to length, fade in and out.
Act V — final cut
ok lets record the video, and first zoom in out the question, and enter it in, and then go up to the api key and continue liek that. then record it, and mix everything together. is there a final sentence from the transcript that is good? some way of summarizing? anyway at the final page, call umwelten the llm toolkit, here we are having agents in dialog
Re-choreographed: the question is now the opening shot. And because each take produces a new debate, the agent recorded first, read the fresh transcript, and picked the closing line for the end card afterward: “…but never the fiction that we can calculate away the need for human excellence.” — Aristotle, closing the dialogue.
can we make the edit tighter? for exampole, the end part of the web recording seems to pause for a couple of seconds, it takes too long to open and scroll throught the final transcript (that should be like 3 second tops) and then it doesn’t cut to the end title very quickly either. we need to tighten up the edit
Editor’s notes, executed in post: hard-cut the recording’s dead tail,
time-compress the transcript scroll to a 3.5-second flythrough
(setpts=0.15*PTS — record at reading pace, ship a whoosh), trim the end
card. 1:43 became 1:16.
make sure that the script is here but the assets etc are it .gitignore, and then commit an dpush everything
Scripts, pages, and config committed; videos and transcripts ignored.
What you actually get
The trailer is a build artifact now. The full pipeline is four commands in examples/dialogue-web:
node serve.mjs # page + transcript capture
dotenvx run -- npx webreel record philosophers-debate # the take (new debate every time)
python3 cinematic.py # camera pass + fast-forward
# concat + soundtrack — one ffmpeg invocation, in the README
When the design changes again, we re-run it. When the debate gets better, we re-run it. The prompts above were the editing suite — see the results at umwelten.thefocus.ai/guide/agent-dialogues.html.