# CLI

Every rapid command and option, grouped by what it does.

Every command and option, from `daemon/src/cli/program.ts` and the command groups it adds; `rapid <command> --help` prints one. Job commands talk to the daemon (`rapid video` and `rapid open` start it when none answers); setup, the render commands, `rapid projects`, and the style and format commands run without it. `rapid` is the shim `rapid setup` writes; `node daemon/bin/rapid.ts` from a checkout is the same.

## Environment

| Variable | Means | Default |
|---|---|---|
| `RAPID_URL` | the daemon's address, for every command that talks to it | `http://127.0.0.1:$RAPID_PORT` |
| `RAPID_PORT` | the daemon's port, when `RAPID_URL` isn't set | `4317` |
| `RAPID_HOME` | the state folder: event log, installed packages, `config.json`, the background daemon's log and PID | `~/.rapid` |
| `RAPID_DEBUG` | `1` prints the whole error instead of one line | unset |
| `CHROME_PATH` | the Chrome executable scenes render in | `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome` |
| `ANTHROPIC_API_KEY` | what agents sign in with, when Claude Code isn't signed in | unset |

`$RAPID_HOME/config.json` may hold `slots` (see [lanes](/docs/lanes#setting-slots)), `styles_repo` (the `owner/repo` bare style names come from, see [sharing styles](/docs/sharing-styles#by-name)), and `projects`, the folders rapid finds projects in (see [rapid projects](#rapid-projects)).

Every failure prints one line, `rapid: <what went wrong>`, and exits 1. When no daemon answers, a job command prints ``rapid: No rapid daemon is running at http://127.0.0.1:4317. Start one with `rapid serve`.``

## Setup and the daemon

### rapid setup

```text
rapid setup [options]
```

Writes a shim, `~/.local/bin/rapid`, that runs this checkout's CLI (a file there that isn't rapid's is left alone), builds the screening page (`pnpm --filter @rapid/screen build`) when `screen/dist` is missing, and reports one line per check, `ok` or `missing` with its fix: the `rapid` command and whether its folder is on `PATH`, Node 24 or newer, ffmpeg, ffprobe, Google Chrome (`CHROME_PATH`), Claude Code, the Claude sign-in (`claude auth status --json`, or `ANTHROPIC_API_KEY`), and the page. It never edits a shell profile or installs a tool. Exits 1 while anything is missing.

| Option | Means |
|---|---|
| `--bin-dir <dir>` | where the `rapid` shim goes (default `~/.local/bin`) |
| `--check` | only report: write nothing, build nothing |

Run it the first time as `node daemon/bin/rapid.ts setup` from the checkout.

### rapid daemon

```text
rapid daemon ensure [--timeout <seconds>]
rapid daemon stop
rapid daemon status
```

The daemon in the background. It runs detached, logs to `$RAPID_HOME/daemon.log`, and keeps its PID in `$RAPID_HOME/daemon.pid`.

| Command | Does |
|---|---|
| `ensure` | starts the daemon in the background unless one is running, and waits until it answers; prints `started: rapid daemon <version> at <address> (pid <pid>)`, or `running: …` |
| `stop` | stops the daemon `rapid daemon ensure` started |
| `status` | whether a daemon answers, and where its state and log are; exits 1 when none answers |

| Option | Means |
|---|---|
| `--timeout <seconds>` | for `ensure`: how long to wait (default: 20) |

### rapid serve

```text
rapid serve [options]
```

Runs the daemon in the foreground until Ctrl-C.

| Option | Means |
|---|---|
| `--port <port>` | port on 127.0.0.1 (default: 4317) |
| `--home <dir>` | state folder (default `$RAPID_HOME` or `~/.rapid`) |
| `--plugin <dir>` | the rapid plugin's folder, for agent sessions (default: the checkout's `plugin/`) |
| `--dev` | serve the screening page from Vite's dev server, which reloads it on edit |

### rapid mcp

```text
rapid mcp
```

Serves rapid's tools to a model over MCP on stdio. Claude Code starts it through the plugin; you don't run it yourself. Its eleven tools are in [using the MCP tools](/docs/using-the-mcp-tools). Tools that need the daemon start one in the background, as `rapid daemon ensure` does.

## Videos and jobs

### rapid video

```text
rapid video [options] [project]
```

Makes a video from a project: storyboard, key frames, scenes, reviews, then the video. Starts the daemon in the background when none answers (`started the daemon in the background`). Prints the job's id, then (with `--brief`) `project <folder>`, then the screening page's address.

| Argument or option | Means |
|---|---|
| `project` | the project folder (default: `.`; with `--brief` and none named, a new one under `~/rapid`, named for the brief's first line) |
| `--brief <text>` | the brief: written to the project's `brief.md`, the project made if it is new. A project that already holds a different brief is refused |
| `--style <ref>` | the style: a name, a pinned package, or a folder (default: the project's pinned one, else `swiss`) |
| `--look <dir>` | instead of `--style`, a draft style made by `rapid style extract` (such as `<project>/.rapid/look`): the job finishes it with the extractor agent, holds it to `rapid style check` (sending the check's reasons back to the extractor, three tries in all, then failing), and pins it in `rapid.lock` before the storyboard. A look already pinned as it is isn't finished again |
| `--format <ref>` | the format (default: the project's pinned one, else `reel`) |
| `--review <who>` | `agent`: a reviewer judges each round; `none`: the code checks alone (default: `agent`) |
| `--rounds <n>` | review rounds before a scene asks for you (default: 4) |
| `--keys <who>` | each scene's key frame, its hero as a still, judged before the scene moves. `agent`: the reviewer judges it; `person`: you approve it; `off`: straight to motion. With `--review none`, `agent` means `off` (default: `agent`) |
| `--director <who>` | `agent`: a director judges the storyboard before any scene and the joined video before the mix, and sends either back; `none`: no direction. With `--review none` there is none (default: `agent`) |
| `--stops <where>` | where the video waits for you. `all`: the storyboard, a key frame that doesn't converge, and a scene out of rounds; `storyboard`: the storyboard only; `none`: nowhere, so it runs to the finished video, taking the best try or round of what doesn't converge and recording each choice (`rapid job` lists them). `--keys person` still asks for every key frame (default: `all`, since at a terminal you are there to answer; the MCP tool `new_video` defaults to `none`) |
| `--rebuild` | build every scene again, even those already written |
| `--music <track>` | a track to cut the video to (copied into the project's `assets/` when it is elsewhere): heard before the storyboard (`rapid listen`), planned and checked to its beats, and mixed as the bed. You must own its rights |

### rapid new

```text
rapid new [options]
```

Starts an empty job, for nodes added through the [HTTP API](/docs/http-api#bodies). Prints its id. To start a video, use `rapid video`.

| Option | Means |
|---|---|
| `--title <title>` | required; what the job makes |
| `--project <dir>` | the project folder (default: `.`) |
| `--brief <text>` | the brief (default: empty) |
| `--style <name>` | the style |
| `--format <name>` | the format |

### rapid jobs

Lists jobs: id, state, title.

### rapid open

```text
rapid open [job] [--print]
```

Opens the screening page in your default browser, at the job named or the newest one, starting the daemon first when none answers. It prints the address; `--print` prints it and opens nothing.

### rapid projects

```text
rapid projects
rapid projects add <dir>
rapid projects remove <dir>
```

The folders rapid finds your projects in, and the projects in each: every folder directly inside one is a project, titled by its `brief.md`'s first heading (or its name), and a chosen folder that holds a `brief.md` is a project itself (`node_modules` and dot folders are skipped). With none chosen, it's `~/rapid`, where new videos go. `add` looks in another folder too; `remove` stops looking in one and leaves the folder as it is. The list is `projects` in `$RAPID_HOME/config.json`; the first `add` writes `~/rapid` there with the new folder, so it keeps being found. These commands need no daemon; the screening page's jobs page lists what they find, with each project's jobs, and can add a folder and start a video in one too.

### rapid job

```text
rapid job <id>
```

A job's nodes: id, state, lane, type, label, wait and run times, and the first line of any error; then each choice the video made without you (`chose: …`).

### rapid approve

```text
rapid approve <node>
```

Approves a node that needs you. Only an approval node in `needs_you` can be approved.

### rapid redo

```text
rapid redo [options] <node>
```

Runs a node again, whatever its fingerprint says. A redo of a scene's build with a note starts the scene again, with your marks.

| Option | Means |
|---|---|
| `--note <text>` | a note for the next attempt |

### rapid replan

```text
rapid replan --note <text> <job>
```

Asks a video's storyboarder for the storyboard again, with a note saying what to change. The new storyboard waits for your approval like the first. Every scene whose storyboard entry changes is built again from its key frame, and the video is joined again.

| Option | Means |
|---|---|
| `--note <text>` | required; what to change |

### rapid revise

```text
rapid revise --note <text> [--scene <id> [--at <t> [--to <t>]]] <job>
```

Acts on your note on a video, done or still running, and runs it to the video again with no stops. With `--scene` and `--at`, a mark at that moment (or over the span to `--to`, in seconds from the scene's start) and a new round of that scene only; with `--scene` alone, that scene built again to the note; with neither, the storyboard again (pacing, order, length, the story) and the scenes it changes. Each scene round is numbered after the scene's earlier ones, so no earlier render is overwritten. Then the video is joined, mixed, and exported again.

| Option | Means |
|---|---|
| `--note <text>` | required; what to change, as a direction |
| `--scene <id>` | the scene it is about |
| `--at <t>` | the moment, in seconds from the scene's start |
| `--to <t>` | with `--at`, the end of a span |

### rapid cancel

```text
rapid cancel <job>
```

Stops a job's running nodes and marks it cancelled.

### rapid lanes

Slots, running, and queued, per lane.

### rapid events

```text
rapid events [options]
```

Streams events until Ctrl-C.

| Option | Means |
|---|---|
| `--after <seq>` | resume after this seq (default: 0) |
| `--job <id>` | only this job |
| `--json` | one JSON event per line |
| `--once` | print the events so far and exit |

### rapid lane

```text
rapid lane <lane> -- <cmd...>
```

Runs one command through a lane as a one-node job, streams its output, and exits with its code. `<lane>` is `think`, `gpu`, `web`, `encode`, or `cpu`. Ctrl-C cancels the job and exits 130.

## Rendering

These run without a daemon. Each prints one JSON line saying what it wrote. A scene is an `.html` file or a canvas module (`.js`, `.mjs`, `.ts`). `--format` and `--style` take a name (built in, installed, or pinned) or a folder; `--project <dir>` resolves them through that project's `rapid.lock`. A scene that links `rapid:style` needs `--style`.

### rapid render

```text
rapid render [options] <scene>
```

Renders a scene to MP4, with its box log (`<out>.boxes.json`) and cue scan (`<out>.cues.json`) beside it. An HTML scene whose meta names another frame than the format's is refused.

| Option | Means |
|---|---|
| `--out <file>` | required; the MP4 to write |
| `--format <ref>` | the format (needed for a canvas scene) (default: `reel`) |
| `--project <dir>` | resolve the format through this project |
| `--chunks <n>` | pages in parallel (default: 4) |
| `--style <ref>` | the style the scene links as `rapid:style` |

### rapid still

```text
rapid still [options] <scene>
```

Writes one frame of a scene as PNG.

| Option | Means |
|---|---|
| `--t <seconds>` | the moment; give this or `--key` |
| `--key` | the scene's key frame: the moment its meta block names as `key`; an error if it names none |
| `--out <file>` | required |
| `--format <ref>` | the format (needed for a canvas scene) (default: `reel`) |
| `--project <dir>` | |
| `--style <ref>` | the style the scene links as `rapid:style` |

### rapid measure

```text
rapid measure [options] <lines...>
```

Measures lines of type in the style's real faces. Each line is one argument; it prints one JSON line per line of type: `text`, `class`, `px`, `width`, `height`, `measure` (the frame less both margins), `fit_px` (the size that fills the measure), and `fits`.

| Option | Means |
|---|---|
| `--style <ref>` | required; the style whose faces set the type |
| `--kit <class>` | the kit class to set them in (default: `display`) |
| `--px <n>` | the size to set them at (default: the class's own) |
| `--format <ref>` | the format (default: `reel`) |
| `--project <dir>` | resolve the style and format through this project |

### rapid sheet

```text
rapid sheet [options] <scene>
```

Writes a contact sheet of a scene; with no times, the review times.

| Option | Means |
|---|---|
| `--out <file>` | required |
| `--times <list>` | seconds, comma separated |
| `--render <base>` | a render (its path without `.mp4`) whose cues pick the times |
| `--changed <spans>` | spans `a:b,c:d` whose starts and ends the times must cover |
| `--max <n>` | at most this many frames (default: 12) |
| `--micro` | a micro strip: 0.3 s either side of the key and of every mark in `--marks`, and a second after the key |
| `--marks <files>` | with `--micro`, reviews or directions whose marks on this scene the strip covers |
| `--format <ref>` | the format (needed for a canvas scene) (default: `reel`) |
| `--project <dir>` | |
| `--style <ref>` | the style the scene links as `rapid:style` |

### rapid check

```text
rapid check [options] <scene>
```

Runs the code checks on a scene's render, or on its key frame's still, and writes them as marks: `{ "pass": boolean, "marks": Mark[] }`. On a still it runs only what a still can answer: placement, fonts, problems, and the layout checks (empty, with a bare top or bottom third; grid; scale) at the scene's `meta.key`.

| Option | Means |
|---|---|
| `--render <base>` | the render, its path without `.mp4`; this or `--still` |
| `--still <png>` | the key frame's still, from `rapid still --key` |
| `--room <share>` | the most of the key frame that may be empty field, over the scene's own `room` |
| `--out <file>` | required; the checks to write |
| `--format <ref>` | the format (default: `reel`) |
| `--style <ref>` | required; the style |
| `--project <dir>` | |
| `--music` | the video is cut to a track: each landing cue (`land`, `hit`, `enter`, `drop`, `pop`, `kick`) and each ducked cue more than two frames off the scene's beats is a mark, and more than five fails it |

### rapid join

```text
rapid join [options] <renders...>
```

Joins scene renders (MP4s, in order) into one video. When every hand-off is a cut it copies them without re-encoding; otherwise it draws each transition from both scenes' frames, overlapping them by its duration, and encodes once at the render's quality. A `match` whose element moves across the cut by more than 8 px, or is missing on one side, is reported on stderr.

| Option | Means |
|---|---|
| `--out <file>` | required |
| `--transitions <spec>` | one per hand-off (see [transitions](/docs/transitions)), `kind[:dur[:dir or el]]`: `cut`, `dissolve:0.5`, `snap-push:0.15:up`, `glyph-swallow:0.9:<data-el>`, ...; or the list as JSON when a move carries an ease, a point, a colour, or settings. Every kind but a cut and a match overlaps at least 0.1 s |
| `--style <ref>` | the style a transition's `color` token is read from |
| `--project <dir>` | the project a style is resolved in |

### rapid video-sheet

```text
rapid video-sheet [options] <scenes...>
```

The director's sheet of the cut: one row per scene (in video order) with its first, key, and last frames and where it sits in the cut, then every hand-off as the pair a viewer sees across it.

| Option | Means |
|---|---|
| `--out <file>` | required |
| `--transitions <spec>` | as `rapid join` takes them |
| `--format <ref>` | the format (default: `reel`) |
| `--style <ref>` | the style the scenes link |
| `--project <dir>` | |

### rapid mix

```text
rapid mix [options] <renders...>
```

Mixes a video's sound from its scenes' cue scans, each shifted to where its scene starts. Each render is its path without `.mp4`, in video order.

Cues with no instrument play nothing; the mix counts them by kind on stderr, and fails (exit 1) when the video has cues and none of them could be played.

| Option | Means |
|---|---|
| `--durations <list>` | required; each scene's seconds, in the same order |
| `--style <ref>` | required; its sound map picks the instruments |
| `--out <file>` | required; the WAV to write |
| `--music <file>` | a music bed |
| `--music-at <seconds>` | where the bed enters (default: 0) |
| `--music-from <seconds>` | where in the track the bed starts (default: 0) |
| `--music-lufs <lufs>` | bring the track to this loudness first |
| `--music-tail <seconds>` | fade the bed out over the video's last seconds (default: 0) |
| `--map <file>` | the track's map, so a video that outlasts the track loops it from a downbeat |
| `--transitions <spec>` | the join's transitions, so each scene's sound starts where its picture does |
| `--format <ref>` | the format whose rate the overlaps are held to (default: `reel`) |
| `--project <dir>` | |

### rapid mux

```text
rapid mux [options] <video> <wav>
```

Puts the mix under the picture.

| Option | Means |
|---|---|
| `--out <file>` | required |

### rapid phone

```text
rapid phone [options] <video>
```

Makes a copy that fits the format's phone size.

| Option | Means |
|---|---|
| `--out <file>` | required |
| `--format <ref>` | the format (default: `reel`) |
| `--project <dir>` | |

## Music and shots

### rapid listen

```text
rapid listen [options] <track>
```

[Hears a track](/docs/music) on this machine (allin1, run through `uv` in its own environment under `$RAPID_HOME/listen`, made on first use) and writes its map beside it, `<track>.music.json`: the tempo, every beat and downbeat, the labelled sections with their energy, and the moments (each `build` and `drop`), with a picture of them, `<track>.music.png`. A track is heard once: what the model heard is kept by the track's hash. A three-minute track takes a few minutes on the CPU.

| Option | Means |
|---|---|
| `--out <file>` | the map to write (default: `<track>.music.json`) |
| `--again` | hear it again, even if this track was heard before |
| `--no-picture` | write the map only |

### rapid beats

```text
rapid beats [options] [scene]
```

Prints the music under a video's scenes in each scene's own seconds (beats, downbeats, sections, builds, drops), from `storyboard.json`'s `music` and the track's map, laid out the way the join lays the scenes. One scene, or every scene when none is named.

| Option | Means |
|---|---|
| `--project <dir>` | the video project (default: `.`) |
| `--format <ref>` | the format whose rate the overlaps are held to (default: `reel`) |

### rapid shot

```text
rapid shot [options] <recipe>
```

Renders a [Blender product shot](/docs/blender-shots) from its recipe (`shots/<id>.json`): `turntable`, `clay-metal`, `macro`, or `build`. Writes the key stills (`stills/front.png`, `hero.png`, `side.png`, `back.png`), each pass's frames with alpha (`<pass>/0001.png` on), each pass as a VP9 clip with alpha (`<pass>.webm`), and `manifest.json`. Blender comes from `RAPID_BLENDER`, else the Mac's `/Applications/Blender.app`.

| Option | Means |
|---|---|
| `--project <dir>` | the project the recipe and its model are in (default: `.`) |
| `--out <dir>` | the shot folder (default: `renders/shots/<id>`) |
| `--stills` | only the key stills |
| `--pass <name>`, `--from <frame>`, `--to <frame>` | only these frames of one pass |
| `--encode` | only encode the rendered passes as clips and write the manifest |

## Styles and formats

`rapid style` and `rapid format` take the same subcommands; `extract` and `proof` are style only. Each acts on packages of its own kind, and a failed one exits 1.

### add

```text
rapid style add [options] <source>
```

Installs from a folder, a `.zip`, an https address, `github:owner/repo[/path][@ref]`, or `<name>[@ref]`: the folder `styles/<name>` (`formats/<name>` for a format) of rapid's GitHub repository, at a tag, branch, or commit, else the default branch. Prints `<name>@<version> <sha256>` and the installed folder.

### list

```text
rapid style list
```

The installed packages: name, version, the start of the hash, and the source.

### use

```text
rapid style use [options] <spec>
```

Pins `<name>[@ref]` in the project's `rapid.lock`, installing it if needed, as `add` does.

| Option | Means |
|---|---|
| `--project <dir>` | the project folder (default: `.`) |
| `--look` | `<spec>` is a draft folder, the project's own look: its version is stamped with what it holds (`0.1.0-look.<hash>`), then it is installed from the folder and pinned, so each change pins anew. A video made with `--look` runs this itself |

### check

```text
rapid style check [options] [dir]
```

Checks a package folder (default `.`): its schema, hashes, and files, and for a style, that `style.css` styles [the kit](/docs/styles-and-formats#the-kit). Prints `<name>@<version> ok <sha256>`, or every reason it failed.

| Option | Means |
|---|---|
| `--write` | recompute the manifest's file list first |
| `--publish` | check as a pull request to the styles repository is, proof required |
| `--out <file>` | write the result as JSON, `{ "pass": true/false, "reasons": [...] }`, and exit 0 either way, for a job that reads it |

### pack

```text
rapid style pack [options] [dir]
```

Checks and packs a folder into its zip.

| Option | Means |
|---|---|
| `--out <file>` | where to write it (default `<name>-<version>.zip`) |

### proof

```text
rapid style proof [options] [dir]
```

Renders a style's sample scene (`proof/scene.html`, default dir `.`) into `proof/example.mp4`, `proof/poster.png`, and `proof/golden-<n>.png`, and records them in the manifest's `proof`. Prints `<name>@<version>: <n> golden frames, example and poster written`. See [making a style](/docs/making-a-style#8-prove-it).

| Option | Means |
|---|---|
| `--format <ref>` | the format to render in (default: the first the style lists) |
| `--times <list>` | golden frames at these seconds (default: a quarter, half, three quarters, and 95% of the scene) |
| `--check` | render the golden frames again and compare, changing nothing; prints `ok` or `DIFF` per frame and exits 1 on drift |

### extract

```text
rapid style extract [options] <sources...>
```

Drafts a style from reference stills and clips, live web pages, and folders of front-end code. See [extracting a style](/docs/extracting-a-style).

| Argument or option | Means |
|---|---|
| `sources` | stills and clips to measure, `https://` pages to read in headless Chrome, and folders of theme code (a folder holding only stills and clips is taken as references) |
| `--name <name>` | required; the draft style's name |
| `--out <dir>` | required; an empty or new folder for the draft |
| `--frames <n>` | frames sampled from each clip, 1–120 (default: 12) |
| `--timeout <seconds>` | how long to wait for each web page at each width, 1–120 (default: 30) |
| `--assets <dir>` | keep a web page's pictures, clips, backgrounds, vectors, and icons in a new or empty folder, with `assets.json`, `screens/`, and `contact.png` |
