ncrispino/reelplanner
Review implementation plans as narrated videos, record your answers in the repo, and review a walkthrough of what the agent built.
Changelog
0.4.0 (unreleased)
- Codex CLI, as Claude Code is (#29, docs/agents.md). reelplanner's native Codex plugin
(
codex plugin marketplace add "$(npm root -g)/reelplanner", thencodex plugin add reelplanner@reelplanner; run the second again after updating reelplanner, as Codex keeps its own copy). Codex plans, reviews, takes saved reviews in, recovers interrupted work and exports its own conversation through the same workflow, with a Codex conversation profile for the skill's teaching style. - Review beside your agent in the terminal, end to end (README,
docs/terminal-review.md). The video opens in a terminal-browser split next to the agent;
Send wakes the agent with the review; the split closes; the new version opens beside it once it is built.
review-setup --workspace terminal-browserremembers the workspace;--codex-allow-opensaves a Codex rule for the one opener command, so opening a ready review asks nothing. Codex applies a rule only to a command whose first word is unquoted, so the opener is printed with the program bare (the quoted form ran in the sandbox and was refused localhost,EPERM), and--checkno longer fails falsely inside Codex's Linux sandbox.- Codex 0.164 runs commands in a background server no terminal is attached to: the opener finds the Codex window in the folder and runs terminal-browser on that window's terminal, so the split lands beside it (under tmux, the window's own pane). terminal-browser's own error line is shown when it cannot open.
reviewrun by Codex connects that session, so Send queues it a message (codex queue) that starts its next turn; Claude Code wakes as before, when its backgroundreview --waitends.- The opener tells the review server which split it opened; after a Send a session took, the server closes that split a few seconds later, the way you would: Ctrl+Q typed into it, then the terminal closes the emptied split. Only that split, and only while it still shows the server's page.
- The README says what this setup allows: a command outside Codex's sandbox, macOS's broad permission to script Ghostty, and a local server any program on the machine can post a review to, which now wakes your agent.
- Codex ignores saved allow rules for models it marks as cyber; the docs and the
EPERMmessage say so. review --detachopens the page from the command itself, in the agent's terminal, not from the server it starts, which has none: in Ghostty on macOS, terminal-browser finds the pane to split by the terminal, and Claude Code's review had opened in the browser instead.
- A repeatable trial of it on Linux:
scripts/release/terminal-review.shstarts a fresh EC2 machine, runs the loop for Codex and Claude Code with a scripted reviewer (--recordrecords the screen), and deletes the machine. - On Ubuntu 24.04, Codex's sandbox needs unprivileged user namespaces, which AppArmor restricts. The docs point to the narrower fix Codex documents (an AppArmor profile; not tried here, and 24.04 does not ship the one it names) and say not to turn the protection off on a machine you keep.
0.3.0 (2026-10-24)
-
Scenes to start a frame from (
templates/reelplanner/theme/scenes/,reelplanner scene). A frame drawn from a blank page tends to come out as cards of words, as the bakery bench's low-depth videos did. Eight scenes, each taken from the two videos that showed the most, the Dylan plan video and a long explainer, rebuilt in the theme's tokens and motion: a count with its part drawn to scale, one record labelled part by part, who does what in lanes, a rule's verdicts with the tally, someone's own words at size, a decision as two futures of the same thing, a choice of two looks, and a person's path through the real pages. Each is a template: every word in it is a{{slot}}for the plan's own, so a frame starts with no one else's content, andframe-lintfails a slot left unfilled; the spec fills each with a worked example and checks that it passes.reelplanner scene <video-dir> 3=count 7=two-futureswrites those frames from them, with each frame's id, length and marks; the skill, the style guide and the frame packet point to them. So that videos do not all look alike,variety(andbuild) warn when over half a video's frames start from scenes, or one scene starts two. -
The product in its own look. A plan's step that makes something people see now has a Look block: its palette, type, imagery and the one thing that makes it recognisable. A page or option mock in a video (
data-plan-component="page") may write the product's own colours, whereframe-lintfailed any colour but the theme's: a bench run's bakery site was drawn in the video's own cream, ink and coral, its plan said nothing of its look, and every product the videos showed looked the same. Only a frame's script is read for a tween's target, so a picture'sfill="#C99A63"in a mock is no longer a missing id (the next bench run hit it). -
A depth for a video: low, medium or high (#34). Every video got the checks a plan video needs; an explainer measured at 3.5 h and about $128 spent most of it on 26 scenes and two whole redraws after fresh eyes (
eval/pipeline-cost/2026-10-21-research-explainer.md).depth:in BRIEF.md (scripts/lib/depth.mjs) now sets it.- low: about two minutes and at most 8 scenes, with nothing taking it past them. No fresh eyes but the fact check of an explainer with a long source, and no strict checks.
- medium, what the skill writes when the person names none: its kind's budget and at most 15 scenes, past them only on the person's words, quoted. The script's newcomer, then one round of the newcomer and the fact checker, whose second round looks at what the answers rewrote. A cosmetic finding is kept with its fix, not redrawn.
- high: as before. A brief with no depth line reads as high, so videos made before keep their checks.
build's length stage andfresh-eyeshold to it, andreelplanner explain --depthstarts an explainer at one. The bench takes--depth, so a depth is measured against the same request. The bakery at low depth, its third run: the first video in 10.8 minutes and $2.78, against 35.9 and $9.53 (eval/pipeline-cost/2026-10-22-bench-low.md). At medium, two runs: 23.8 and 27.1 minutes, $5.90 and $6.97 (eval/pipeline-cost/2026-10-22-bench-medium.md). -
frame-checkruns HyperFrames' own lint on the frame, and fails it on an error there: the build stops on that lint, andframe-checknever ran it. Lint findings name their file by its full path, so the layout check dropped them too. In a bench run, two frame workers styled every frame's root by its class,frame-checkpassed all seven frames, and the build stopped on them. -
frame-checkchecks several frames in one go (frame-check <video-dir> 3 5, orall): one lint, one layout check and one picture call for them all, each frame's findings and picture under its name. In a bench run, eight frames checked one by one took two minutes; all eight at once take 18 seconds here. It leaves out HyperFrames' wish for an id on every element, which is for editing in HyperFrames' Studio: an agent added the ids and built again. -
buildstops on frame-lint in a frame changed since the last build, in its first stage, before anything is voiced, also when the storyboard or script changed.frame-checkfails a frame on it, but the build only said it, and not at all once the script had changed: in a bench run at medium, a build passed such a frame, and the agent built again onceframe-checkshowed it. The skill now says to look at every frame while fresh eyes read, and to check the frames you changed before building: that run built 11 times, 5 of them again for what a check before the build would have shown. -
The guide dropped words written in code that looked like an HTML comment. A bench run's plan said a page's first line is
<!-- title: Visit -->. The page took every comment out before drawing the text, the ones in a code span or a code block too, soguide --checkfound the paragraph missing and stopped the build, 1.5 minutes in. The agent rewrote the plan's file format to get past it. A comment in code is now shown as written; one outside code is still left out, and the check and a step's lead read plan.md the same way. -
A revision's build had no fresh eyes when the video it revised was not committed. A build's fresh eyes belong to it, and
plan-difftells builds apart against the last committed video: with none, the revision was the first build again, and its round was "done". In a medium bench run, the agent opened the first video without committing it.reel-intakenow says to commit the video as reviewed before revising it when it is not, and the skill says to commit it before opening it. -
The guide's check failed a plan whose "Decisions in force" says none. The page drew the section under its own headings and left out its words that are no line of it. So a first plan's "None yet", or a section citing the plan's own decision, failed
guide --check, and the build stopped. Agents got past it by deleting the section from plan.md. The page now shows the section under its heading, with its words. -
The review link named a port another server held. With its port taken,
reviewmoves to the next one, but the first try's listener fired when the next one listened, so the link kept the taken port. That link opened the other server's page, or one that refused this video. The link now names the port the page is on. -
Narration that plays on after a seek or a speed change (#30). The review server sent every file as one
200with no byte ranges, so Chrome could not seek its narration: after a seek, a start in the middle of a scene, or a speed change, the scene went silent until the next one. Files are now sent with byte ranges (206,416,If-Range;scripts/lib/http-file.mjs), by the review server and by the specs' static server alike, andmedia-seek.specchecks that the playing clip keeps step with the video through a seek, 1× to 1.5×, a pause and a rewind. -
Cheaper, faster videos (plans/2026-10-10-cheaper-videos, from the first pipeline-cost audits: making and checking a video was 80–90% of the time before the person saw it).
- One round of fresh eyes, and a second only on the scenes whose words the first's answers changed: rounds 2
and 3 found little and cost as much. A finding marked
[plan](the plan leaves something out, or the video only describes what the person needs to see) is answeredplan:(plan.md changed) orask:(a question shown first on Before you watch), never kept: fresh eyes found what reviewers later flagged, and the builder kept it. The designer lists only what stops a viewer; other notes go under## Advisory, with no answer needed. - The script, read against the ask, before any frame:
fresh-eyes <video-dir> --script, from BRIEF.md's new- Ask:line (the person's words) and the last review. - Frame packets:
reelplanner frame-packet <video-dir> <frames…>gives a frame worker everything in one file (its storyboard blocks, its line word by word with timings, the marks it needs, the theme by path, a sibling to match);reelplanner frame-check <video-dir> <frame>lints it and takes one picture at rest;references/frames.mdstates the formats. The skill draws a short video with one builder and a long one with workers of 3–5 frames, never reading reelplanner's source: one-frame workers spent a median 9 minutes learning the tools. - Values that agree: check-terms warns when one thing differs across scenes (two phone numbers, an address a letter from another, "5 pages" against four).
- Length before the voice:
buildestimates the length from the script and stops past 1.5 times the budget unless BRIEF.md's- Length:says why; the style guide puts the whole before the steps. - The way to the page:
buildends with the command that puts this build on the review page, and where a running server is. The video's builder starts fresh with a short brief, not as a fork of the conversation; once a video is shown, the agent waits for the review. A headless run's prompt names the skill's path and asks no verify of an approval. - Revisions build once.
frame-checkalso runs HyperFrames' layout check on the frame's slot, as advice (text overflowing its box, said in about 10 seconds);build's new first stage,frames, runs verify's own check before anything is voiced when frames changed since a build last passed, and stops only on what verify would. The skill gathers every fix before touching a frame, patches only the frames they touch (checked withframe-check, never a build), and builds once; fresh eyes start in the background. The frame packet names fonts by family, which HyperFrames loads, so no worker searches the disk for one.
- One round of fresh eyes, and a second only on the scenes whose words the first's answers changed: rounds 2
and 3 found little and cost as much. A finding marked
-
pipeline-cost (
.claude/skills/pipeline-cost/, for contributors): measures where a run's time and tokens go from its transcripts, intoeval/pipeline-cost/'s ledger. -
No headless agent unless you ask.
reel initwrote a command that starts the agent it ran in, unattended, whenever a review was sent with no session waiting; Claude Code's auto mode refused thatreel initin a person's first session, as an agent setting itself up to start unattended.reel initnow writes none: the session that ran it is an agent already, and a review sent while none waits stays in the inbox for the next one.--agent claude|codexturns the headless run on, and now works in a repo set up already too, changingconfig.json's agent and nothing else (--agent noneturns it off);initnames the one to pass, the agent it runs inside. -
Allow reelplanner's commands once, in Claude Code. The README, docs/agents.md (a Claude Code section) and
setup(whenclaudeis on PATH and no rule names reelplanner) say how: the allow rulesBash(reelplanner:*)andBash(reel:*), in/permissionsor~/.claude/settings.json, which Claude Code checks before auto mode's classifier. The skill runs each command in a call of its own (a chain likereel new-plan … && reel check …is judged by its every part), says what a command will write into the repo before running it, and, when one is stopped, names the two rules and/permissions→ Recently denied, and never edits the settings itself. -
A whole session on a fresh machine.
scripts/release/ec2-fresh.sh --shellstarts an EC2 machine with the package copied over and runs nothing, for a session tried by hand (Claude Code logged in, the README's Install, a plan and its review);--hourssets when it shuts itself down (2 by default). -
Fresh eyes and the guide's check get a browser on an install.
playwright-corewas a development dependency, so an installed reelplanner had none: fresh eyes' pictures lacked the player's captions and controls, and the guide was not opened in a browser. It is a dependency now, and with no Playwright browser it drives the Chrome headless shellsetupinstalls for HyperFrames. -
Finish no longer counts an approval as a comment. With nothing said, the Finish panel said "Your 1 comment goes with it": the approval it had picked is kept as an annotation, and the panel counted it.
-
A faster first
setup. On Linux, whisper.cpp is whisper.cpp's own prebuilt build (v1.9.5, x64 or arm64, its checksum checked) instead of compiled frommain: a second instead of two minutes on two cores, and no compiler installed. Where it cannot run (older than Ubuntu 22.04's glibc) it is built from source, pinned to v1.9.5, on every core. The local voice's 840 MB of models download in the background from the moment setup knows they are needed, beside pip, whisper.cpp and the skills, instead of after them; andpython3-pipcomes without its recommended compiler. On a 2-vCPU EC2 machine, a first setup went from 282 s to 124 s (the README's whole Install, 315 s to 139 s). -
Chrome starts, or setup says why. On a bare Debian or Ubuntu (a container), Chrome's download lacked shared libraries (
libnss3,libnspr4) and video builds could not start it, while setup said ✓. Setup now loads a page with it, and installs whatlddsays is missing, by each release's package name. It no longer runshyperframes doctorat the end, whose ✗ lines were for what reelplanner never uses (Docker, a music model) and whose Docker probe printeddocker: not found. -
The skill installs with no question. The README's
npx skills add … -g -yinstalls it for every agent found; without-yit asked which agents, and with no terminal it cancelled. -
Fresh machines on demand, timed.
scripts/release/ec2-fresh.shruns the fresh-install check on a new EC2 machine with your AWS credentials (--profile,--region,--arch arm64,--container ubuntu:24.04), on this checkout packed or a pushed ref, copies the log back and deletes all it made. The check times each step (--timesfor every line), loads a page with the Chrome setup found, runs a README line's command without its comment (the comment swallowed its</dev/null), and keeps agithub:owner/repo#refsource's#ref; the workflow puts the times on the run's page and adds a macOS job (--here: as the runner's user). -
Send works for a quick video too. With no set-up
.reelplanner/(the skill's first level, one video), the Finish panel offered only Download annotations.json, and the person then told the agent where the file was. Now the review server keeps that repo's inbox in this machine's folder,~/.reelplanner/inbox/<repo-key>/(the repo folder's name and a short hash of its path;REELPLANNER_HOMEmoves it), so Send hands the review to the session waiting on it (review --wait) with nothing added to the repo. There is no agent command at that level, so with no session waiting the panel says plainly it is saved on this machine until you tell your agent;inboxlists it.review --detachand--stopwork there too (its.server.jsonand log go in the same folder). The download is left for a page no server takes the review for (none behind it, or a Send that failed). A repo set up later uses its own.reelplanner/inbox/; a review left in the machine's is named byinboxand finished byinbox done, never picked up twice. -
The system video says reelplanner, in its narration and on its frames, and its install is shot again from the public repo on a fresh Ubuntu machine (
npm i -g github:ncrispino/reelplanner, a firstsetup, the skill,reel init); the README's GIF is its opening, made again. The voice says the name as "reel planner": Kokoro read "reelplanner" as "reopliner", sosay.mjshands it over apart (NAME_SAID), alone, in code and in a path, and the captions still show it as written.reelplanninghas a meaning in Terms (the glossary's Other words) for the pages and videos made before the rename. -
reelplanning is now reelplanner (D-312: reelplanning.com is already a business). The package, the command (
reelplanner;reelstays), the repo (github:ncrispino/reelplanner), the case-studies repo, the Claude Code plugin (/plugin install reelplanner@reelplanner), a repo's.reelplanner/, the machine's~/.reelplannerand the settings (REELPLANNER_*) take the new name, and the review player isreelplanner-player.js. The old names are still read: a repo's.reelplanning/(each command says so once, with thegit mvthat renames it),~/.reelplanningwhile there is no~/.reelplanner(then itsyou.jsonland.envare named, with themvthat moves them), aREELPLANNING_*setting in the shell or a .env file (a line that says where a setting came from names it as it was set:from the shell's REELPLANNING_TTS (its old name), not its new name), and thereelplanningcommand, which says the new name and runs it. A review begun on the page before the rename keeps its marks. To move over:npm rm -g reelplanning(npm stops atEEXISTotherwise;install.shdoes it), then install reelplanner. The entries below keep the old name. -
The Claude Code plugin is the skill's folder alone. Its marketplace entry's source was the whole repository, so installing it copied all of it into
~/.claude/plugins/cache(117 MB), and Claude Code npm-installed the root'spackage.jsonthere (177 MB more), beside the marketplace's own clone (172 MB). The source is nowskills/plan-to-video(108 KB,SKILL.mdand its style guide), and the entry inmarketplace.jsonis its manifest (.claude-plugin/plugin.jsonis gone;sync-version.mjscarries the version into the entry, andversion.speckeeps the plugin that folder alone). An install made before keeps its copy until the version moves. -
setup's summary names a narration problem once: a narration setting that cannot work was listed asnarration: narration: …under "still missing". -
A fresh-install check (
.github/workflows/fresh-install.yml,scripts/release/fresh-install.sh): the README's Install run as written in a bareubuntu:24.04container, by a user with sudo, with Node 22 from nvm and with Ubuntu's own older Node, which the CLI must refuse. On a PR that changes the install's path, on each version tag, each week, and by hand; it reports, it does not block a merge. Its first run found thatsetupcould not install the local voice on a stock Ubuntu: itspython3has no pip.setupnow installspython3-pipwith apt, as it does ffmpeg, and says how when it cannot. Andsetupread a libwebp ffmpeg as one without (grep -qin a pipe underpipefail), so on Ubuntu it installedcwebpit did not need. -
Node 22.20 or later. HyperFrames needs Node 22 and the
skillsinstaller 22.20, sopackage.json's engines,setup, the curl installer and the docs say 22.20 (they said 18, and on Ubuntu's own Node 18 the install failed innpx skills).reelplanningandreelrefuse a Node older than 22 before anything runs and say how to update, instead of failing later on an import it does not have; on 22.0 to 22.19 they run, andsetupand the curl installer say thatskillsasks for 22.20.version.speckeeps the docs and checks on the engines' version. -
PRs are merged with a merge commit, not squashed: main keeps a PR's own commits. CONTRIBUTING, the PR template, the templates the skill copies into a repo, the skill and
docs/lifecycle.mdsay so;reel pr-check --tidystill takes the contributor's own reviews off the branch before the merge. -
The README's quick start begins in a project you already have, then a new one (a neighborhood bakery's site, in place of Bob Dylan's albums). Its Install names the Claude Code plugin (
/plugin marketplace add ncrispino/reelplanning), and says the plugin is the skill only;marketplace.jsondescribes it asplugin.jsondoes (it said "90-second" videos). -
A repo reached through a link works as one reached directly. On macOS a temp folder is
/var/…, a link to the/private/var/…that git and the working directory report, and the same happens to a linked home or projects folder. Code that measured one spelling against the other found no history or the wrong folder: a review's approval, narration reused from git,spec-diff,reel status's rebuild check, review's Send line,bundle-player's repo id,code-check, and fresh eyes' check of where findings were written. They now compare real paths (realPath()inscripts/lib/env.mjs). -
Playwright's Chromium is found on macOS and in its current layouts (
chromiumPath()): each OS's own store (~/Library/Caches/ms-playwrighton a Mac) and Chrome for Testing's folders, the full browser before the headless shell. -
Guide pictures on a Mac. Homebrew's ffmpeg is built without libwebp, so guides there had no pictures; they are made with
cwebpwhen ffmpeg cannot, andsetupinstalls it (brew install webp) when neither is there. -
The case-study kit on a Mac:
arm.shparses under macOS's/bin/sh(bash 3.2), andpreflight.shfinds~howeverHOMEand the folder are spelled. -
The test suite passes on CI and on macOS, not only in the development containers: CI runs on Node 22 (which HyperFrames needs) with ffmpeg, and the specs no longer lean on the machine's tools, its temp folder's spelling, the development history, a page measured before it came to rest, or a paused video read before its pause landed.
-
The full suite runs on every push to a pull request, instead of failing until a maintainer added
ready-to-merge: a PR's checks are green or red for its code, and a maintainer's approving review is what else it needs. The tests (.github/workflows/ci.yml) start only on pushes, andreel pr-checkmoved to.github/workflows/pr.yml, so an edited PR text or a label never records a skipped test check, which GitHub counts as passed. -
The public repo is
ncrispino/reelplanning, one commit (D-310).scripts/release/make-public.mjsbuilds it in a scratch folder: a new repo whosemainis one commit,reelplanning <version>, holding exactly a ref's tracked tree, taggedv<version>; it refuses a tree with a.wav,.mp4orrenders/path, adds a line to.reelplanning/README.mdsaying the record's commit ids name the development history (not public), and prints the push without running it. It replacesslim-history.mjs; this repo keeps its full history. The package, the plugin manifests, the installer, the skill, the docs and the issue forms name the repo in lowercase, anddocs/releasing.mdhas the steps to go public, in order. -
A shorter top level. The repo's root lists 22 entries instead of 28:
CONTRIBUTING.md,SECURITY.mdandCODE_OF_CONDUCT.mdare in.github/(GitHub still links them from the repo page),RESEARCH.mdisdocs/research.md, the README's pictures are indocs/media/, and the curl installer isscripts/release/install.sh(its URL:…/main/scripts/release/install.sh; not areelplanningcommand, and not in the package). -
Every version you reviewed can be built again. Opening a video for review and recording a review keep that version: its commit, and the files git leaves out that nothing makes again (screenshots shown in scenes, the text the video was captured from), committed once per content in
.reelplanning/media/(a PNG as lossless WebP), with a small record of the version in<plan-dir>/versions/. No voice, video or render is kept (D-305).reel rebuild <video-dir>lists the versions;--version <n>builds one in a git worktree at its commit, with its plan, ledger, guide and screenshots as they were, the voice made again, and says what differs or could not come back. A check that has grown stricter since is said and does not stop it. What is kept and why:docs/project-dir.md. -
The local voice is optional.
reelplanning setupinstalls Kokoro, its 840 MB of models and whisper.cpp only when narration here runs them: with a hosted engine set (read asnarratereads it), it skips them and the speed check and says so in one line.setup --hosted-voiceskips them before the key is set and prints the two lines for~/.reelplanning/.env;setup --local-voiceinstalls them anyway.narratewithout the local voice it needs stops first, naming both ways on, andtranscribe-missingre-times a hosted line with the hosted transcriber, not local whisper. The README's Install says the choice and what each costs. -
A small download: no voice file or render is committed (D-305). The repo stops tracking its 819 .wav, .mp4 and
renders/files (451 MB; they stay on disk), so the package is about 64 MB instead of about 440 MB..gitignoreand the.reelplanning/.gitignorethatreel initwrites leave out*.wavand*.mp4, andreel pr-checkfails a PR that adds a .wav, .mp4 orrenders/file anywhere. The five sample videos play their committed .mp3 from a clone, andnarratekeeps a line from that mp3 (writing a newly voiced one as mp3 too) instead of voicing every line again. -
One
.envfor the machine, and a folder of setup files is not a set-up repo.~/.reelplanning/.env($REELPLANNING_HOME/.env) is read last, after the shell, the repo's.reelplanning/.envand a.envbeside the project: two lines there,REELPLANNING_TTS=openrouterandOPENROUTER_API_KEY=…, give every repo the hosted voice with noconfig.json. The slow verdict andsetup --dry-runnow point there, and the engine line says which file a setting or key came from (never the key). A repo is set up when.reelplanning/decisions.jsonexists, not the folder:reel initover a folder with only.envandconfig.jsonkeeps the.envand merges the config (your keys win),reel statussays "not set up yet" instead of crashing, andreviewdownloads the review there instead of filing it in an inbox no one reads. -
A README a newcomer reads. Two sentences and the GIF, install in three commands, then examples in plain words: a new project from an empty folder first, then a change, a plan file and an explainer in a repo you have. The three ways to use it as a list, where the hosted voice's key goes (
.reelplanning/.env), and a short comparison. The full loop's detail moved todocs/lifecycle.md("The full loop, in short"). Works with names GitHub Copilot, Cursor, OpenCode and Antigravity CLI (untested);docs/agents.mdreplaces Gemini CLI with Antigravity CLI (agy) and says each agent gets the skill throughnpx skills' link into its own folder. -
The record stays within reach, and so does what you asked for. Reading the guide under the video, the record's bar stays at the window's foot (the small player sits above it), and pulled up it lists every comment, the ones on the guide's words too. A comment's time goes to it on the video, the video back in its place and the comment named on the frame; a guide comment's place goes to it in the guide. Your comments show as short strokes on the timeline, and Marks: on | off (beside Clear, or
V, remembered per viewer) hides them and the marks drawn on the frame. After a rebuild, Your last review in the record lists the round you sent, read-only, each line going to where it is now (or saying it is not in this version), so you can check every request was handled. -
The page says the review is being worked on. After Send, a line above the video says where the review is: waiting for your agent, being worked on (with its step), done, or stopped (with the run's log), with the time since Send and a quiet pulse (still under reduced motion). It survives a reload and a closed panel. When the agent is done and the video was rebuilt, "The new version is ready" opens over the player: Watch what changed reloads into just the changes. The local page asks the review server's new
GET /api/review/status?id=; the hosted page follows its row. -
Narration through hosted APIs.
.reelplanning/config.json'snarration(orREELPLANNING_TTS) can name a hosted voice: OpenRouter (recommended), OpenAI, any OpenAI-compatible server, ElevenLabs, or Kokoro on DeepInfra (the local build's voice; slow, not recommended). Word timings come from the provider, from a hosted whisper (Groq or OpenAI), or from local whisper at a smaller model, so a small machine no longer spends minutes a line in whisper. Hosted lines run 4 at a time, retried on 429 and 5xx. Keys come from the environment only; a missing one stopsnarrateand says what to set.setup --dry-runsays which engine narrates. Without the setting nothing changes: local Kokoro + whisper small.en. -
OpenRouter, one key for the voice and the timings.
"tts": "openrouter"voices with Deepgram Aura-2 (a line in 1–3 s, checked with a real key) or another of its speech models (not its Kokoro: 47–125 s a line), and times the words with itsopenai/whisper-1, all onOPENROUTER_API_KEY;"timings_api": "openrouter"times any provider's speech there. -
reelplanning narration-checkvoices one sentence with the narration engine you name (or the onenarratewould use) and says, a line each, whether the speech and the word timings work, how long they took, what a minute costs, and on a failure the API's answer and what to set. A minute's test of a hosted provider with a real key. -
Is local narration fast enough here? And keys in
.reelplanning/.env.reelplanning setup(andnarration-check --local) times one plan-video line through local Kokoro + whisper, at most 30 s, and says in one line whether that is fine for a plan video or slow (over 20 s a line), and then exactly how to switch to the hosted voice:OPENROUTER_API_KEYin.reelplanning/.env,"narration": { "tts": "openrouter" }in config.json,narration-check. Local still works either way. Keys now belong in the repo's.reelplanning/.env(git ignores it):narrate,narration-checkandsetupread it from anywhere in the repo, after the shell's environment and before a.envbeside the project, and warn when git would commit it. -
The guide shows what a revision changed, as the video does. After a review asks for changes, each part of
plan.mdwhose words changed since the version the review watched (a step's words, a case, a question, a section) is marked "Changed since your review", with "What changed": the old and new words, and the review's own words that asked for it. In short lists them; "Show only the changes" folds the rest.guide --checkfails a change left unmarked, or a mark on a part that is the same. -
Install from GitHub, for now. reelplanning is not on npm yet: install it with
npm i -g github:ncrispino/reelplanning, thenreelplanning setup, and the skill runsreelplanning …where it says$RP.scripts/release/install.shfalls back to the GitHub install whennpm viewfinds no version, andsetup's fix lines sayreelplanning …first. On Linux,setupinstallsunzipbefore the Chrome download, which hung at 100% without it. The README,docs/reference.md,docs/project-dir.mdand the case-study kit use this install. -
Choose how much you take on. The skill opens with three levels, and with no
.reelplanning/the agent asks which: Quick, one video (a plan video or an explainer, 1–3 minutes, nothing in the repo butvideos/<slug>/); a plan video and a walkthrough after the build; or the whole loop (decisions, reviews, the system video). In the full loop a reviewer can skip a plan's walkthrough video:**Walkthrough video:** skippedinwalkthrough.md, andreel statusreads the plan as done. The skill runs thereelplanningalready on the PATH before tryingnpx. The README starts with install, then a quick start. From first quick runs:explainrunshyperframes initbefore writing intovideo/, a new project gets the caption code font, and a backticked word is one code run in the captions. -
Claude Code first, basic Codex support (docs/agents.md says what each agent is tested for).
reel init --agent claude|codex|nonewrites the headless command for the agent (by default, the one it runs inside). Codex getscodex exec -s workspace-write. The skill names skills per agent (/faceless-explainerin Claude Code,$faceless-explainerin Codex). Fresh eyes and the code check say how to start an agent with none of the conversation's context in each agent.AGENTS.mdholds this repo's agent instructions, andCLAUDE.mdpoints to it. -
The decision log scales (D-306). The owner's answers are rules and stay binding. Accepted agent calls are history:
reel checkasks a plan to cite only the rules, and with--baseit names each accepted call whose lines the diff changes (pr-checkand the code check do the same). Each call is placed on the lines its plan's commits wrote.reel statusandreel memoryname the calls none of whose lines is left.reel fold <component>drafts that component's rules as a section ofspec.mdfor the owner's approval, and--applyputs it there. -
reel recordfiles a review given in conversation ("source": "conversation","by","said"). It is recorded by the reviewer's id, not an email, says "accepted in conversation" and quotes the owner instead of a watch percentage, andreel memorycounts it as untimed. The plan-guide, walkthroughs-that-help and contributing walkthroughs were accepted this way (D-267 to D-302), and the ledger's supersedes links were corrected with the owner's approval (D-194 is now superseded by D-266). -
The system video, redone (D-003, D-303, D-304): about 9½ minutes in seven chapters, from a
spec.md,system.jsonand glossary brought up to date first. It shows the real install (GitHub,reelplanning setup, the skill,reel init), says which commands your agent runs for you, and defines the words a newcomer lacks. Its voice and renders are no longer committed (D-305), and the README shows a GIF of its first 48 s. It has no guide yet:plans/2026-10-04-system-video-guideis a draft. -
Video building: a rebuild without
--speedkeeps the speed the video was voiced at.holds.jsontakes a"tail"held after every line.chapters --no-checkscuts the quick checks out of the chapter MP4s. A code span of several words is one code run in the captions.finish-projectworks with macOS'ssed. -
reel init's.gitignoreleaves out each video's voice, its guide, the plan's guide page and the system video's renders. -
--helpeverywhere.reel --help,reel help <command>,reel <command> --helpandreelplanning <script> --helpprint the usage and run nothing (reel init --helpused to make a folder named--help). Areelcommand run without its arguments prints its usage.reel init,new-planandprereqssay what to do when the folder already exists or has noplan.md. So doesguidefor a folder it cannot build. The test runner takes--helptoo. -
Ready to publish. A new
package.spec(innpm test) checks what npm ships: no media, tests, videos or plans, every shipped import resolvable, the licences in. It replacespublish.yml's own check, which refused the case-study files the package ships and would have failed the first release. ANOTICEcovers the fonts, GSAP and HyperFrames. New: issue forms, a code of conduct, a CONTRIBUTING with setup, tests and how to find work, a README rewritten for the public,docs/comparison.md(similar projects, with sources),llms.txt, and topics to apply..gitattributeskeeps the plan videos' HTML out of GitHub's language bar. The owner's email address is gone from the current files. -
The case-study kit installs reelplanning the way it installs today.
smoke.shruns a ten-second check. Each arm keeps voice files and renders out of the site's history, andreel case-study keeprefuses a history that holds them. The Bob Dylan case study has a runbook for running it on fresh compute. -
Fixes:
narratefinds its sibling scripts in an install path with a space.retime-framesno longer prints "✓ retimed" when it wrote nothing. A secondreview --detachgives a busy server 15 s before it starts another. A guide build keeps pictures another build is still writing. The test runner hands out ports below the range the system uses for outgoing connections.quiz.specwaits until the video is past the quick check. A mark on the frame is live once its thing is in and some of it shows, not once its last line or row is (a terminal's run held it back to the scene's last seconds). A guide carries the words of plan.md's open questions section and any words before its first section, soguide --checkpasses on every plan.npm run bundle:checkserves the bundle it is given again (a relative folder was read twice). Play on the poster plays, instead of opening the guide of a mark under it, and a click on a marked thing that fills most of the frame pauses the video (only its label opens the guide). -
Cleanup: removed the unused
theme-tokens,motion-coverageandrebuild-narrationscripts,frame-lint --expect-stage, and the guide's unread step pictures. Code written two or three times now has one helper. Comments and docs say what the code does now. The skill and style guide no longer cite reelplanning's own decision numbers, which would mean other decisions in another repo. The glossary new repos get no longer describes the ten-in-a-row rule, which is gone. -
The plan guide. Behind each plan's video, a page that shows more than the video can and that you work with, built from
plan.md(the one source, D-244) byreelplanning guide <video-dir>, whichbuildruns and checks: each step's cases with their traces, its whole interface (a try-it for its flags), its example, its decisions and its question; after the build, each kind of change with every line of it from git, each file whole with its changed lines marked, and the runs saved inruns/, whole. Things to do, each checked against the plan or the real run: drag each case onto what happens, put a trace in order, fill in what a command prints, predict a question's option, sort the files by kind. A scene's- guide: <part>opens that part over the paused frame, as a detail opens (a click on it during a question, too: D-246); each part opens the full page at its place, and "Watch this moment" goes back to the video. Highlight any words to comment, suggest an edit or ask. An explainer's source markedneedsPartgets a part: the source itself, whole.reel checkholds a plan written from 2026-09-30 to the four blocks (Cases, Interface, Example; Decisions generated), andreel recordfiles a suggested edit under "Edits to apply", with the scenes it rebuilds (the guide only, when none says it). Never committed (D-213). -
Explain first. A video of what is already there, before any plan:
reelplanning explain "<what you asked>" <source> …pins the sources that hold the answer (a file or a folder, a range of commits,worktree,since:<date>,pr:<n>,ci:<run-id>,this-session, a decision) in.reelplanning/explainers/<date>-<slug>/, each by its shape and size, with no list of kinds (D-250).buildrunscheck-sources: a quoted line its source does not hold, an unpinned source, a secret, an email address or a home path stops it. Finish ends an explainer's review with Done, Explain more or Plan this; nothing goes into the decision log.reel new-plan --fromstarts a plan from it, andreel prereqslists it first (D-248). Fresh eyes add a fact check where a source is far longer than the video. The review page has an Explainer row: the commit it explains, and how many have landed since. -
The guide under the video (D-264, superseding D-228). The review page shows the open video's guide under its player, on the same page: scroll down to read it, and the video shrinks to a small player in the corner (a slim bar on a phone) that keeps playing, with play/pause, the time and the way back up; scroll back and it is back in its place. It is never replaced. "Watch this moment" seeks that player; a marked thing on the frame scrolls to its part of the guide, pausing the video, the part lit a moment; notes and questions in the guide go into the same review. A plan's Guide link opens its video with the page down at its guide.
-
Highlight anything in the guide. Let go of a selection anywhere in it (prose, a heading, a table cell, a diff's lines, a run's output, a caption, a diagram's label), or click a labelled shape or a line's number, and the box a mark on the video opens pops up beside it: the same look, keys and words, the quote above; Suggest an edit and Ask are in it. Kept, the words stay highlighted, and the note sits in the review's list with the video's marks, labelled with its section and step (a click goes to it), goes with Finish, and
reel recordfiles it under its step with the quote. A phone's selection docks the box at the foot;Nopens it with the keyboard; the page opened on its own keeps notes the same way and exports them. -
Answer in the frame. Each option card and the question open into more detail; a choice is judged on its card. The answer band grows up over the frame and never cuts text; the video never resizes.
-
A size control for the video: Fit, smaller down to 40% (drag, corner handle, or
-/=), and zoomed past Fit up to 200%. Remembered per browser. -
Words you can follow. What a viewer sees and hears uses plain words (a choice, a label, a chapter, a scene; D-127) while files and commands keep theirs. A terms panel (
G) and underlined terms; ids never shown alone; "Walk me through it" after a wrong quick check; a "Before you watch" card fromreel prereqs.buildrunscheck-termsbefore the voice. -
Fewer, better stops. The choices that stop in a step share one stop (an off-plan change keeps its own); a late fix stops only choices sharing its label.
reel auditwarns past 12 choices and fails a step with five and no question about it inplan.md. -
Better visuals. Scenes show the real thing (the brief picks which), with the theme's
code-diffandterminal-runblocks and a written motion language; the review page's type and colour are fixed up, with its fonts shipped. -
Tool names shown one way.
.reelplanning/names.mdlists how each name is shown: a tool's name (reelplanning,reel audit,git) is lowercase in code markup, in captions and on screen; others (GitHub, Kokoro) take their own case.check-termswarns on one shown otherwise. -
Details in the frame. A frame marks the thing a detail page explains (
data-detail="<name>"); once it has landed, a click on it opens the page over the frame, and the corner chip is only for frames with no mark.frame-lintchecks the marks;reelplanning detail restyle <video-dir>brings pages built earlier to today's look. -
The guide in the player (the plan guide, prototype v5). What a beat opens over the frame is a part of the video's guide ("Guide · step 2"); its header has "Open the full guide", the video's full guide page beside it (
<video>/guide/index.htmlin a bundle, made from its parts when the video has no guide of its own), whose "Watch this moment" goes back to the player at that time; the plan's row has Guide beside Plan | Built. Words selected in a part open a note box on them (comment, suggested edit on plan text, Ask, answered in the box and kept with the review's questions); the detail pages' bridge is v2 (select,size), anddetail restylebrings it to older pages. While a question is up, a click on a marked thing opens its part and closing it brings the question back as it was (D-246). -
Contributing with several people.
reel pr-checksays whether a pull request needs a walkthrough video (choices or size, D-214) and what it carries;reel renumbermoves a branch's decisions after the ones that landed first whendecisions.jsonconflicts on a rebase. ACONTRIBUTING.md, a pull request template,config.json'smaintainers, and a CI workflow (not yet run on GitHub); the skill copies their templates into a repo that takes contributions. -
Jargon found by the build.
check-termsfinds words a viewer may not know that have no meaning in the glossary (acronyms, code, technical compounds): a warning, failing onterms_check: strict(D-216, D-217). A word stays underlined until you know it (D-218). -
Quick checks later, on a new case (D-197 to D-199):
check-termswarns on a quick check right after the beat that explains it, or on that beat's own example. -
Captions show spoken forms written (
/work, not "slash work"), and the size control steps 5% up to Fit, 25% past it. -
Tests:
npm testruns the fast specs;npm run test:fullruns every spec, sharded, in about 5 minutes. -
reel checkjudges a plan by the ledger it was approved under: decisions recorded later no longer fail an approved plan (a plan approved in conversation dates from its walkthrough's start commit).reel stopsgives each ask outside the plan's steps its own stop instead of one "step ?". -
Maintainers by id.
config.json'smaintainerslists the idreel recordprints (or an email);ownerstill matches, with a warning, since anyone's own review page calls them owner. -
Player fixes: the caption code chip is solid and full size; own words on the frame hold two lines and scroll; answering on the frame never covers the frame's own words or puts "Full question" inside a diagram;
?part=Nopens at that part on a slow network too. -
Removed: the uncalled
check-darkandrender-darkscripts; the worked examples' full renders (71 MB; their chapters stay) andpackages/player/design/. -
Licensed under Apache-2.0 (was ISC in
package.json, with no license file), and a short.github/SECURITY.md: what reelplanning adds to an agent run, and how to report a problem. -
Walkthroughs that help. The walkthrough video shows the change running, before and after, in about two minutes: the real page, or a real run (the saved file, a command's output);
buildsays it is long past 3 minutes. It pauses only for an off-plan change or a choice you'd notice or can't easily undo (reel stops: the labelsvisibleandhard-to-undo; no count, no ten-in-a-row rule); every other choice is one list at the end (- autonomy_list:), each with a Flag, and Go on or Approve logs the rest as listed, not judged: a later plan is not warned by them. A quick check comes only where the change has something to predict (a saved file or a command's output counts), just before the scene that runs it; the review ends on one open question, "Seeing it run, anything you'd change?", in Finish. A pull request needs the video over 300 lines or for a choice you'd notice or can't easily undo; its other choices are lines under "Other choices" in its text, whichreel pr-checkwaits on until a maintainer ticks them accepted. The review page shows each plan on one row with a Plan | Built switch, which the header carries too and which lands on the same step (the walkthrough's running scene, or "Nothing to run for this step"); every plan waiting on you comes first (its row says what: plan to review, walkthrough to review), older plans fold behind "Earlier plans (N)", and names wrap instead of being cut. While a question is up, the captions stay hidden behind its answer row, met again after going back too. Each verdict carriesshownAt, when its pause began;reel memory's newafter-buildline says how long a pause held you, the flags and words, and reviews sent before the video could play through; three timed walkthroughs that all miss the bar (5 s and some words) makereel statussay a plan to drop the walkthrough video is due. -
Videos that make sense. Before a video reaches you,
reelplanning fresh-eyeshas two fresh agents look at it with only what a viewer gets (each scene's narration and a picture of it at rest, through the review page): a newcomer lists what it could not follow, from what the video had shown by then and what viewers were lost on before; a designer what breaks the style guide's seven frame rules. Every finding is answered under it (fixed, a meaning, or kept with the reason) andverifystops on one that isn't (D-225); at most three rounds, and what is left is said on "Before you watch" and in the notification. Every new video gets it, a rebuild of an older one too, and the system video was checked now (D-227). Rounds belong to a build: a rebuild starts a new set (the last kept infresh-eyes/build-<n>/), whose agents look at the scenes it changed, with their neighbours for context, and Before you watch lists that build's kept findings only;--allfor the whole video. Each agent writes one file, at the absolute path its prompt names, and--checkrefuses one written anywhere else. Ask about this (Q): paused on a scene, ask in your own words; the answer comes from the plan, the glossary and the scene, and says where from: on a hosted page from Claude (the page declaressample), on your machine from the session waiting on the page (inbox answer), otherwise with your review (D-226). Questions are kept in the review, listed inreviews/<id>.mdand counted inreel memory lost.frame-lintfails empty bars standing where words go and anything within 40 px above a detail's thing; the stage templates hold words.
0.2.0 (2026-09-25)
Everything since 0.1.0. The skill now pins npx -y reelplanning@0.2.0.
Breaking changes
- Reviews live in
reviews/. Each review is filed once as<plan-dir>/reviews/<plan|walkthrough>-<time>.json, never overwritten, withreviews/<id>.mdbeside it saying what to act on. That replacesannotations.json,walkthrough-annotations.json,plan.resolved.md,walkthrough.resolved.mdand the*-scope.jsonfiles. Move an existing repo withreelplanning migrate-reviews [<dir>] [--dry-run]: it files every old review, including earlier rounds it finds in git history, and removes the old files. Running it twice changes nothing. resolve-planandresolve-walkthroughare removed.reel record <plan-dir> <review.json>files the review, adds its decisions and judged calls to the ledger, and writes thereviews/<id>.md.- The GitHub Action is gone.
reel initno longer installs.github/workflows/reelplanning-revise.yml, and nothing writes theplan.resolved.mdit triggered on. Delete the workflow from repos that have it. A review now goes to the local review server, which hands it to a waiting session or starts your agent headless (below). - No plan
README.mdchecklist.reel new-planno longer writes one.reel statusworks out each plan's stage from its files,reviews/and the ledger. - The player's handoff is two lines, not three:
reel record <plan-dir> ~/Downloads/annotations.jsonreads the download where it is.
Review player
- Answer on the video itself: click the frame's option cards, answer in a thin band inside the frame, and the video never resizes. Answers can be edited in place.
- After a revise, the player says what changed, marks it on the timeline and plays just the changes (a toggle plays the whole video). A revised video starts a new review round.
- Arrow keys scrub. Answered questions come back when you revisit them. A quick check can be disagreed with, and a missed one is marked apart.
- Marks can be selected, erased and edited. "Explain this more" on a plan question asks for more without recording a decision.
- Deep dives: an Open chip on a frame opens an HTML detail beside the video, and comments made there point at the right beat. The plan text beside the video is off until you turn it on.
- Autoplay across parts; copy any one answer; a calmer page with one line of controls.
- Fixes: a Play pressed while narration is loading is no longer dropped; sound works in the Claude desktop app.
The loop and headless runs
reelplanning reviewis a review server: Finish, then Send, files the review in.reelplanning/inbox/. A session waiting onreelplanning review --waitpicks it up; with none waiting, the server starts the command in.reelplanning/config.json(agent.command) once.--detachkeeps the server running after the session ends.- The default command is Claude Code in auto mode inside its sandbox, with a hook that refuses file
writes outside the repo.
git commitruns outside the sandbox so commits stay signed. Where the sandbox can't run (a root container, native Windows) the run goes ahead with it off and says so. Codex and opencode commands are documented, untested. reelplanning notify: a desktop notification when a run ends, with what is waiting.- Reviewing the system video changes the system:
reelplanning system-reviewsorts each comment for the agent.
Walkthroughs
- Only the calls a reviewer might overturn stop the walkthrough video; the rest are grouped at the end
of each part.
reel stops <plan-dir>shows which stop and why. reelplanning code-check <plan-dir> --base <ref>writes a brief for a second agent to check the diff against the plan and the ledger;reel auditreads its findings.- Details (deep dives):
reelplanning detail new <video-dir> <name> --kind <kind>from six templates (explore, try, evidence, table, code, fresh);reelplanning check-detailschecks them.
Memory
- Every recorded review carries who reviewed it and the reelplanning version.
reel statusends with at most five lines of what your reviews show (recommendations taken, own words, rewinds, wrong quick checks, misses), and says when a retro is due.reel memory [<repo>] [<id>] [--you]prints those lines or the evidence behind one.--youworks across repos from~/.reelplanning/you.jsonl(REELPLANNING_HOMEmoves it).- A call of a kind that was recently missed stops the walkthrough.
reel retrostarts a retro plan listing the evidence, with proposed skill edits to fill in.
The CLI
reelplanning build <video-dir>(alsoreel build) runs narrate, sfx, timings, holds, retime, finish-project and verify, one line per stage.rebuild-narrationis now an alias for it.reelplanning narratevoices only the lines that changed and keeps the rest (one edited line: about 30 s instead of 11 minutes). A killed run keeps the lines it already voiced.- New commands:
build,narrate,notify,inbox,system-review,code-check,detail,check-details,migrate-reviews;reel stops,reel memory,reel retro,reel build. reel checkreads steps as### Step Nwith a dash, en/em dash or colon, and no longer asks a plan to cite its own decisions.reelplanningforwards SIGINT/SIGTERM/SIGHUP to the command it runs, so stopping a backgroundreviewleaves no orphan.- The review page bundle shares fonts and GSAP across videos and copies every asset a frame points at.
Skill and style guide
SKILL.mdand the style guide are rewritten at about half the length.- A length budget: plan and walkthrough videos aim for 3 to 5 minutes, the system video 5 to 8.
- The skill covers running the loop, reviewing the system video, the second agent's code check, and the quick-check rule.
0.1.0
The first version number: npx reelplanning runs every script from the npm cache with your repo as
the working directory, and npx skills add installs the plan-to-video skill.