Contents

Command line

Run the core with node core/src/cli/main.ts <command> from the repository. This page is the CLI's own help, so it always matches the code.

reelwright <command> [options]

reelwright validate [--json] <showDir>

Check a Show Pack: schemas, references, timing, screenplay.

reelwright fmt [--check] <paths...>

Rewrite spec files in canonical form (--check: only report).

reelwright hash <file>

Print a document's content hash (sha256 over RFC 8785 JSON).

reelwright compile <showDir> --episode <id> [--out timeline.json] [--estimate-takes] [--fps R]
           [--language tag]

Compile an episode to a Timeline (.reelwright/timelines/). --estimate-takes times unvoiced lines from their text. --fps resolves it at another rate (12, 23.976, 24, 25, 29.97, 30, 48, 50, 59.94, 60, or 30000/1001): its lines, lip sync and sound keep their times in seconds. --language compiles one of its dubs (es, ja...).

reelwright render <showDir> --episode <id> [--out dir] [--size WxH | --preview] [--frames a:b]
           [--capture frame_server|movie_maker] [--chunks N] [--timeout-sec N]
           [--farm dir [--assemble]] [--deliver preset,...] [--fps R] [--alpha] [--language tag]

Voice lines with no take, then render, mix and encode an episode to renders/<episode>/. --preview is a light proxy (CRF 28, capped) at the show's preview size; a full render is the master and delivers show.json's deliverables, or --deliver's: master_prores_422hq, master_prores_4444, png_frames, exr_frames, stems_wav, captions_srt, otio. png_frames writes frame-export.json beside them (FrameExport 1.0); asked only for frames and stems, no H.264 is made. --alpha draws RGBA frames with straight alpha, transparent where nothing is drawn (a see-through set): PNG and EXR frames and the ProRes 4444 master keep it; the MP4 and the 422 HQ master show the picture over black. --farm writes each chunk's job to dir for render workers; --assemble then verifies their frames and mixes and encodes. --language renders one of its dubs, voiced, lip-synced and captioned in that language, to renders/<episode>.<tag>/.

reelwright stills <showDir> --episode <id> --frames 0,120,... [--out dir] [--size WxH | --preview]
           [--estimate-takes] [--fps R] [--alpha] [--language tag] [--json]

Render single frames as PNG storyboards (--alpha: RGBA, straight alpha; of a dub, with --language). It says what the compiler and the renderer warned; --json prints the stills and those warnings as JSON.

reelwright export otio <showDir> --episode <id> [--out file.otio] [--estimate-takes] [--fps R]

The episode's cut as OpenTimelineIO for an editor: shots from the render, audio by kind, captions as markers.

reelwright import otio <showDir> --episode <id> --file <cut.otio> [--rationale <text>]

Propose an editor's trimmed cut (from export otio) as edits: moved cuts and lifted shots; what edits cannot carry is listed.

reelwright asset import <file> --show <dir> --license <spdx> [--for set.<id>/backdrop/<id>]
           [--as card|decal|backdrop [--set set.<id>] [--width <m>]] [--height <m>]
           [--units auto|m|cm|mm|in] [--name <text>] [--id <slug>] [--role <role>]
           [--kit kit.<name>] [--strength 0..1] [--attribution <text>] [--rationale <text>]
           [--json]

Freeze a PNG or JPEG into the show's assets/ (sRGB, at most 4096 px, snapped to the palette when the style snaps, QA'd) with its provenance. --for proposes it as that set backdrop (a 2:1 equirectangular panorama); --as proposes it as a piece of the show's kit: a standing card, a decal for a wall, or a painted flat (a 2:1 panorama with --set: that set's backdrop). A .glb, .gltf or .obj model is proposed as a piece, in meters (--units, or judged by its size) or scaled to --height, its colors snapped to the palette. A .cube LUT (3D, 2 to 65 points a side, values in 0 to 1) is proposed as the style's LUT, or with --for <episode>/<scene> a scene's, at --strength. Approve with changes approve.

reelwright asset import-clip <dir> --show <dir> --license <spdx> [--name <text>] [--attribution <text>]
           [--rationale <text>] [--json]

Bring in a clip Cutwright cut (a folder with clip.json, its frames and its sound): every file checked against its hash, frozen into assets/ with Cutwright's version and the clip's provenance, and its ClipInstance (clips/<slug>.clip.json) proposed. A screen cue then plays it on a set element.

reelwright drift --show <dir> [--json]

Draw every character with an approved model sheet again and compare: who moved, how much and why, with approved | now | difference sheets in .reelwright/drift/; exit 1 when a locked character moved.

reelwright voice --show <dir> --episode <id> [--keep] [--json] [--language <tag>] [--estimate]

Voice every line with no take (Kokoro, or ElevenLabs when show.json lists it, cached by content); --keep copies the takes into audio/takes/ and proposes pinning them in the episode (approve with changes approve); --language voices one of the episode's dubs (es, ja...); --estimate says what ElevenLabs would cost and sends nothing.

reelwright capture <showDir> --episode <id> --line <scene>/<line> --clip <file> [--actor <name>]
           [--rest <from>:<to>]

A line acted on video: its sound becomes the line's take and the performance it shows (the head's turn, the eyes, the face) keys beside it, which the line plays (docs/design/ perf-capture.md). --rest is when the actor rests before acting (default 0:1 seconds). The picture is not kept.

reelwright voices prepare [--json]

Fetch Kokoro's model and voices into the cache if they are not there yet, so no first voice waits for them (330 MB).

reelwright voices list [--json]

The voices your ElevenLabs key may use, to give a character.

reelwright voices try "<line>" [--voice <id or name>] [--emotion <e>] [--intensity N] [--volume <v>]
           [--pace N] [--parenthetical "(…)"] [--note "…"] [--max-usd N] [--out <file.flac>]
           [--record <dir>] [--dry-run] [--json]

One line read by an ElevenLabs voice as directed, with your key: it says what it sends and costs first, and stops at --max-usd ($0.05); --record keeps the call for the tests.

reelwright direct <screenplay> --show <showDir> [--out <file.json>] [--episode <id>] [--scene n[,n]]
           [--recut] [--note <text>] [--heuristic] [--with-key] [--dry-run] [--json]

Direct a screenplay into an EpisodeIR, print each scene's film-grammar counts and propose the episode (approve with changes approve); --out writes it to a file instead. The model director (show.json stage "director") stages and covers each scene, repaired against film grammar, with the heuristic director as its fallback. Its model is the Claude Code here, signed in with your Claude plan, before any key; --with-key uses your API key instead, --heuristic uses no model, --recut redoes only the coverage (with either director), --dry-run prints the plan and its cost without calling it.

reelwright generate characters <showDir> --pattern <id> (--count N | --roles <id>,<id>…) [--seed S] [...]

Draw a cast from a CharacterPattern (see docs/design/m2-generation.md); --roles casts one character per listed archetype, in order.

reelwright generate set <showDir> --pattern <id> [--seed S] [...]

Draw a set from a SetPattern.

reelwright preview <kind> <target> --show <showDir> [--json] [--frames 0,120,...] [--episode <id>]

Render (or reuse) a preview and print its files. Kinds: model_sheet <char>, lineup <char|show>, set_view <set>, style_swatch <style>, still <episode>, storyboard <episode> (a still of every shot, one row per scene, on one sheet), panels <episode> (the same stills, one file per shot), prop <prop> (held, then set down, front and side).

reelwright chat --show <dir> [--dry-run]

Talk to the showrunner in the terminal; /approve, /reject, /undo.

reelwright serve --show <dir> [--claude-plan]

Run the session daemon for Reelwright Studio; prints {"port","token"}. --claude-plan (opt-in, off by default): chat runs through the Claude Code installed here, signed in with your own Claude plan. --grant-fd N (the web service's daemons): the person's key and account, read from that pipe.

reelwright host --data <dir> [--port N]

Run Reelwright as a web service: accounts (emailed sign-in codes, invite-only), an admin panel, a daemon per user and the web Studio. host users list|add|remove and host session <email> manage accounts from the server's shell, host waitlist list|admit|remove its waitlist, and host settings get|set <section>.<field> <value> its settings; host pack <show> makes the upload that puts a show on the service, and host upload <show> --to <address> sends it (token on stdin).

reelwright mcp --show <dir>

Serve the show's tools and documents to an MCP client over stdio. Studio then says that AI is on the show, and names it on what it proposes. --studio-chat: for Studio's own chat on your Claude plan, which Studio shows in its chat instead. --studio-work: for Studio's own work there (Direct with Claude, memory, looks), which Studio shows itself; its proposals still name the AI.

reelwright claude status [--show <dir>] [--json]

Is Claude Code installed here, and signed in with a Claude plan (it is asked: no file of its own is read)? With --show, is Reelwright added to it for that show, and the Claude Desktop config that would add it there.

reelwright claude connect --show <dir> [--scope local|user|project] [--json]

Add the show to Claude Code as its "reelwright" MCP server (claude mcp add, in the show's folder), so Claude Code started there works on it with your own plan. Again changes nothing. local (default): only you, only there; project writes .mcp.json into the show.

reelwright claude disconnect --show <dir> [--scope local|user|project] [--json]

Take it out again.

reelwright claude login

Claude Code's own sign-in (claude auth login), in a terminal.

reelwright claude open --show <dir> [--desktop]

Claude Code in the show's folder, in a terminal (--desktop: in the Claude desktop app, on macOS and Windows).

reelwright claude bridge --service <url> [--token-file <file> | --token-stdin] [--json]

The web edition's own chat on your Claude plan, run here by the Claude Code on this computer, until you stop it (Ctrl-C). It signs in to the service (https://reelwright.diy/app) with a personal token from the web edition's Connect Claude, in REELWRIGHT_TOKEN or the file --token-file names, and ends (exit 1) if the service refuses the token. The installed Studio runs it with --token-stdin (the token on stdin; it stops when stdin ends), --json (its state as JSON lines) and --runner.

reelwright runner --service <url> [--pair <code>] [--name <name>]
           [--accept render,voice,preview,chat] [--shows <dir>[:<dir>…]] [--renders N]
           [--chunks N] [--work <dir>] [--config <file>] [--token-stdin] [--json]

This machine runs your heavy Reelwright work for the web Studio: renders, voicing and previews of your shows, and with --accept …,chat the chat, the director and memory on your Claude plan. --shows offers the shows in those folders, which the web Studio then opens here, their files never leaving this machine. It connects outward only. Pair it once with a code from Studio (Your computers, Add a computer): --pair ABCD-EFGH; it keeps its token in --config (default ~/.config/reelwright/runner.json, readable by you only). Stops on Ctrl-C; exits 1 when the service refuses it.

reelwright worker --service <url> [--parts N] [--work <dir>]

One of the web service's own render workers, on a machine the service started: it draws parts of the service's renders. Its token is in REELWRIGHT_WORKER_TOKEN; the service starts and stops it (docs/design/render-capacity.md).

reelwright fixtures record <scenario>

Record a scenario's model calls for replay (spends real money).

reelwright eval record [--out <dir>] [--with-key] [--max-usd N] [--dry-run]

Record the evaluation set (ten scripts directed by Claude, twenty asks to the showrunner) for the tests to score against the heuristic: on the Claude Code here, signed in with your Claude plan, with nothing charged; or with --with-key (or no such Claude Code) your key, saying what it will cost first and stopping at --max-usd ($8). --dry-run sends nothing.

reelwright eval release [--out <file>] [--max-usd N] [--dry-run]

One real message and one real direction on the demo, with your key (at most $3): writes the result the release keeps.

reelwright changes list|show|approve|reject|undo|redo [id] [--show dir] [--json]

Review and decide proposed change sets (--status a,b to filter).

reelwright changes lock|unlock <docId> [--pointers /a,/b] [--reason text] [--show dir]

Lock canon (no pointers: the whole document), as a change set.

reelwright status [--show dir] [--json]

What drifted: patterns, locked canon, stale proposals.

reelwright impact <id> [--show dir] [--json]

What a change to a document would re-derive, re-render or re-check.

reelwright init <dir> [--no-git] [--blank | --starter | --demo | --copy <show>] [--title T]
           [--logline <text>] [--setting <words>]
           [--style-from words|pictures|blank|preset]
           [--look <words>] [--reference <picture>]... [--style <id>] [--language <tag>]

Make a show's folder (a git repository by default): empty, for the showrunner's create_show; --blank: a show of your own (--title, --logline, --setting in a few words) with its own theme, a look of its own (from --look words, --reference pictures, the blank look, or --style one of Reelwright's styles to start from) and Reelwright's starting patterns, made in --language (es, ja...; English by default), nothing from the demo; --starter: one from the Marigold's kit, its theme, styles and patterns; --demo: a copy of the Marigold demo show; --copy: a copy of another show. Renders and .reelwright/ caches are never copied.

reelwright pack <showDir> [--out file.zip]

The show as a Show Pack: a zip of its files, without caches, renders or its git history.

reelwright clean [--show dir] [--previews] [--dry-run] [--json]

Remove what can be made again from .reelwright/: copies of decided proposals, old job and work folders (--previews: the preview cache too). Show files, changes and takes stay.

reelwright engine <command> [args]

Run the engine itself (version, smoke, job, compare): Godot on the checkout's engine/, or REELWRIGHT_ENGINE, an exported one.

reelwright key status|set|forget [elevenlabs] [--check] [--json]

The Anthropic API key the showrunner uses (or, with elevenlabs, the ElevenLabs key cloud voices use): where it comes from, save one (read from stdin, never printed), or remove it. --check asks whether it works (free), and ElevenLabs which plan it is on.

reelwright doctor [--show dir] [--report file.zip] [--json]

Check that Reelwright can make a show here: the engine, ffmpeg, Rhubarb, voices, disk; --report writes them into one zip for a problem report (no keys, takes or show text).

reelwright update check|get [--feed url] [--target file] [--json]

Studio's update: check reads the release feed, checks its signature and says whether a newer release is out and whether this install can put it in place; get downloads its AppImage beside this one, checks it against the signed feed, and writes the script that swaps it in when Studio restarts.

reelwright version

Print the Reelwright version.

reelwright help

Show this help.