@kadj-amoah/showrunner 1.1.6 → 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,191 +1,213 @@
1
- # Showrunner
2
-
3
- Automated product demo recording & production tool.
4
-
5
- Showrunner collapses the demo-video pipeline into a single, repeatable, automatable command. Point it at a running web product, give it a one-page brief, and it produces a finished, captioned MP4 — comprehension, script, recording, voiceover, and mux in one pass.
6
-
7
- ## Status
8
-
9
- v1.1 — usable end-to-end for short demos. The LLM and TTS layers are provider-agnostic so you can bring your own keys or wire in an in-house pipeline. See `prd_showrunner.md` for the full product spec.
10
-
11
- ## What you need on your machine
12
-
13
- - **Node ≥ 20.6** (`process.loadEnvFile` is required)
14
- - **ffmpeg + ffprobe on PATH** (`apt install ffmpeg` on Debian/Ubuntu, `brew install ffmpeg` on macOS, gyan.dev build on Windows)
15
- - **A Chromium binary** — Playwright installs one for you (`npx playwright install chromium`)
16
- - **API keys for the providers you pick**, OR a headless CLI agent like `claude -p` (see _Provider choices_ below)
17
-
18
- Showrunner is built to deploy on Linux but develops fine on WSL2 or macOS.
19
-
20
- ## Install
21
-
22
- Published to both npmjs.org (zero-friction install) and GitHub Packages (mirrors the GitHub Releases timeline). Pick whichever matches your workflow.
23
-
24
- Showrunner ships with `playwright-core`, which means **no browsers are downloaded during `npm install`**. You must run the browser-bootstrap step (`npx playwright install chromium`) after install — otherwise the first recording attempt will fail with a "browser binary missing" error from `doctor`.
25
-
26
- ### npx (no install, recommended for first-time use)
27
-
28
- ```bash
29
- npx @kadj-amoah/showrunner --version # → 1.1.1
30
- npx playwright install chromium # required: bootstraps the browser
31
- ```
32
-
33
- Running `showrunner` with no arguments prints a context-aware welcome with the next command to run — from outside a project it suggests `showrunner init`; inside a project root it suggests `showrunner doctor -c demo.yaml`.
34
-
35
- ### Global install (`npm i -g`)
36
-
37
- ```bash
38
- npm install -g @kadj-amoah/showrunner
39
- npx playwright install chromium # required: bootstraps the browser
40
- showrunner --version # → 1.1.1
41
- ```
42
-
43
- > **Linux note:** if `npm i -g` needs `sudo`, **do not** run `sudo npx playwright install` afterwards — the browser will land in `/root/.cache/ms-playwright` where your user-mode `showrunner` process can't find it. Run `npx playwright install chromium` as your normal user. (`showrunner doctor` will detect and warn about this case.)
44
-
45
- ### GitHub Packages
46
-
47
- Requires a one-time `~/.npmrc` setup since GitHub Packages requires auth even for public packages:
48
-
49
- ```bash
50
- # Generate a Personal Access Token at github.com/settings/tokens
51
- # Scope needed: read:packages
52
- echo "@kadj-amoah:registry=https://npm.pkg.github.com" >> ~/.npmrc
53
- echo "//npm.pkg.github.com/:_authToken=YOUR_TOKEN_HERE" >> ~/.npmrc
54
-
55
- npm install -g @kadj-amoah/showrunner
56
- npx playwright install chromium
57
- ```
58
-
59
- ### Directly from a git tag (no registry at all)
60
-
61
- ```bash
62
- npm install -g github:kadj-amoah/showrunner#v1.1.1
63
- npx playwright install chromium
64
- ```
65
-
66
- ### From source
67
-
68
- ```bash
69
- git clone https://github.com/kadj-amoah/showrunner.git
70
- cd showrunner
71
- npm install
72
- npm run build
73
- npm link # makes `showrunner` available globally
74
- npx playwright install chromium
75
- ```
76
-
77
- Verify any of the above with `showrunner --help`.
78
-
79
- ## First demo in five commands
80
-
81
- ```bash
82
- showrunner init --name my-demo --url http://localhost:3000
83
- cd my-demo
84
- cp .env.example .env # then paste in your provider keys
85
- $EDITOR docs/PRD.md # replace the stub with your product brief
86
- showrunner doctor -c demo.yaml # preflight: 11–12 PASS/FAIL rows
87
- showrunner run -c demo.yaml # the whole pipeline
88
- open output/demo_final.mp4
89
- ```
90
-
91
- If you'd rather not write a PRD upfront, swap the `$EDITOR` step for `showrunner understand -c demo.yaml --interactive` it asks five questions and produces the product model on the spot.
92
-
93
- ## Provider choices
94
-
95
- The two generative stages (LLM for comprehension + script, TTS for voiceover) are pluggable. Pick them at scaffold time with `--llm-provider` and `--tts-provider`, or edit the `llm` and `voiceover.provider` blocks in `demo.yaml` later.
96
-
97
- ### LLM (`llm.default.provider`)
98
-
99
- | Provider | Needs | Notes |
100
- |----------------|--------------------------------------------|-----------------------------------------------------------------------------|
101
- | `anthropic` | `ANTHROPIC_API_KEY` | Default. Uses Claude with structured outputs. |
102
- | `openai` | `OPENAI_API_KEY` | Uses `response_format: json_schema`, falls back to `json_object` if needed. |
103
- | `agent_bridge` | A headless CLI agent on PATH (default `claude -p --output-format json`) | No API key on file — Showrunner spawns the agent per request. |
104
- | `custom` | A dynamic-importable module | Implement the `LLMProvider` interface. |
105
-
106
- Per-stage overrides are supported under `llm.overrides.{comprehension,script,instrument}` so you can, e.g., use `agent_bridge` for the heavy script generation and `anthropic` for the small `instrument` calls.
107
-
108
- ### TTS (`voiceover.provider.name`)
109
-
110
- | Provider | Needs | Alignment? | Default `alignment_strategy` |
111
- |--------------|------------------------|------------|------------------------------|
112
- | `elevenlabs` | `ELEVENLABS_API_KEY` | ✅ | `required` |
113
- | `openai` | `OPENAI_API_KEY` | ❌ | `best_effort` |
114
- | `custom` | A dynamic-import module| Your call | `best_effort` |
115
-
116
- Only ElevenLabs returns per-character alignment. With other providers, Showrunner takes the **best-effort path**: one synthesis call per segment (no slicing), captions collapse to whole-segment cues, and `at_word` action timing degrades to `at`. Set `voiceover.alignment_strategy: required` if you want it to fail loudly instead.
117
-
118
- ## Pipeline
119
-
120
- ```
121
- comprehension script → record + voiceover → mux → demo_final.mp4
122
- ```
123
-
124
- | Stage | What it does | Inputs | Outputs |
125
- |-----------------|----------------------------------------------------------------------------------------------------|-----------------------------------------|---------------------------------------------------------|
126
- | `comprehension` | Reads `docs/`, an optional codebase, or runs the interactive Q&A. Emits `product_model.json`. | `docs/PRD.md` (or `--interactive`) | `product_model.json` |
127
- | `script` | Scrapes the live target's actionable DOM, then asks the LLM for a manifest using only those selectors. | `product_model.json` + live target URL | `scripts/manifest.json`, `vo_script.txt`, Playwright spec |
128
- | `record` | Drives Playwright through the manifest, captures `master.webm` + a slice plan. | manifest, dev server | `segments/video/master.webm`, `slice_plan.json` |
129
- | `voiceover` | TTS for the whole script, slices per segment, writes alignment files (when supported). | manifest | `segments/audio/*.mp3`, `segments/alignment/*.json` |
130
- | `mux` | Normalizes, slices, branding cards, background music, captions. Outputs the MP4. | video + audio + alignment | `output/demo_final.mp4` (+ `.srt`/`.vtt` if enabled) |
131
-
132
- Stages are independently runnable, checkpointed, and idempotent. Existing artifacts are never silently overwritten — use `--force <stage>[,<stage>]` to regenerate.
133
-
134
- ## Daily commands
135
-
136
- ```bash
137
- # preflight — catches missing keys, ffmpeg, dev server down, free disk, RAM cap
138
- showrunner doctor -c demo.yaml
139
-
140
- # generate (or refresh) product_model.json from docs/PRD.md
141
- showrunner understand -c demo.yaml
142
- showrunner understand -c demo.yaml --interactive # 5-question fallback
143
-
144
- # full pipeline (`--skip-doctor` to bypass the implicit preflight)
145
- showrunner run -c demo.yaml
146
-
147
- # re-run just one stage
148
- showrunner run -c demo.yaml --stages script
149
- showrunner run -c demo.yaml --force voiceover,mux # regen, don't reuse
150
-
151
- # the LLM's selectors are wrong for one segment demo it yourself
152
- showrunner record-actions -c demo.yaml --segment fill-form
153
-
154
- # preview the manifest in Playwright UI Mode (no recording)
155
- showrunner preview -c demo.yaml
156
-
157
- # inspect a failed take
158
- showrunner trace -c demo.yaml --segment <id>
159
- ```
160
-
161
- ## When things go wrong
162
-
163
- - **`x264 malloc failed` during mux** — out of RAM. The `doctor` row "free memory: … (ffmpeg thread cap: N)" shows what was budgeted. Drop resolution to 1280x720 (or 854x480 for draft), set `SHOWRUNNER_FFMPEG_THREADS=1`, or close Docker / browsers.
164
- - **Recording fails because a selector doesn't resolve** — usually the LLM picked something fragile. The `script` stage's DOM preflight is supposed to prevent this; if it does happen, run `showrunner record-actions -c demo.yaml --segment <id>` and demonstrate the interaction yourself.
165
- - **`vo_review_gate` halted the pipeline** — by design. Edit `scripts/vo_script.txt`, then `showrunner approve-vo -c demo.yaml`. (The init scaffold ships with this off — you have to opt in via `script.vo_review_gate: true`.)
166
- - **Output file is locked by a media player** — close VLC/QuickTime/your-browser-tab. Showrunner falls back to writing a timestamped sibling MP4 with a warning, but the canonical path needs the lock released.
167
- - **DOM preflight failed** — your dev server isn't on the URL in `demo.yaml`, or it's behind auth. Bring the server up, configure `recording.auth` for session/form/setup-script flows.
168
- - **Playwright warns "your OS is not officially supported"** — on Arch / CachyOS / Fedora during `npx playwright install`. Safe to ignore; Playwright falls back to the Ubuntu 24.04 build, which works fine.
169
- - **`browser binary missing` even though I ran `npx playwright install`** — you likely ran the install under `sudo`, so the browser is in the root cache. Re-run as your normal user: `npx playwright install chromium`. `showrunner doctor` detects this and prints the specific cache it found the browser in.
170
-
171
- ## Configuration reference
172
-
173
- `demo.yaml` is the single source of truth. Sections:
174
-
175
- - `project` — name and optional `product_model` path
176
- - `comprehension` `mode` + `sources` (PRD, README, codebase, OpenAPI, etc.)
177
- - `script` `style`, `duration_target_seconds`, `highlight_features`, `vo_review_gate`
178
- - `recording` — `target_url`, viewport, browser, cursor + segment timing knobs, auth, lifecycle scripts
179
- - `voiceover` `provider` (discriminated by `name`), `alignment_strategy`, output dirs, drift behavior, pause placement
180
- - `llm` — `default` provider + per-stage `overrides` (comprehension, script, instrument)
181
- - `output` — resolution, fps, branding cards, background music, captions, output path
182
-
183
- Legacy v1.0 configs (flat `voiceover.voice_id`, no `llm` block) are auto-migrated by the loader — your existing demos keep working without edits.
184
-
185
- ## Deployment target
186
-
187
- Linux. Local dev runs on WSL2/Docker on Windows or macOS hosts. A Docker image bundling Node 20, Playwright (Chromium), FFmpeg, and `xvfb` is on the roadmap.
188
-
189
- ## License
190
-
191
- MIT
1
+ # Showrunner
2
+
3
+ Automated product demo recording & production tool.
4
+
5
+ Showrunner collapses the demo-video pipeline into a single, repeatable, automatable command. Point it at a running web product, give it a one-page brief, and it produces a finished, captioned MP4 — comprehension, script, recording, voiceover, and mux in one pass.
6
+
7
+ ## Status
8
+
9
+ v1.1 — usable end-to-end for short demos. The LLM and TTS layers are provider-agnostic so you can bring your own keys or wire in an in-house pipeline. See `prd_showrunner.md` for the full product spec.
10
+
11
+ ## What you need on your machine
12
+
13
+ - **Node ≥ 20.6** (`process.loadEnvFile` is required)
14
+ - **ffmpeg + ffprobe on PATH** (`apt install ffmpeg` on Debian/Ubuntu, `brew install ffmpeg` on macOS, gyan.dev build on Windows)
15
+ - **A Chromium binary** — Playwright installs one for you (`npx playwright install chromium`)
16
+ - **API keys for the providers you pick**, OR a headless CLI agent like `claude -p` (see _Provider choices_ below)
17
+
18
+ Showrunner is built to deploy on Linux but develops fine on WSL2 or macOS.
19
+
20
+ ## Install
21
+
22
+ Published to both npmjs.org (zero-friction install) and GitHub Packages (mirrors the GitHub Releases timeline). Pick whichever matches your workflow.
23
+
24
+ Showrunner ships with `playwright-core`, which means **no browsers are downloaded during `npm install`**. You must run the browser-bootstrap step (`npx playwright install chromium`) after install — otherwise the first recording attempt will fail with a "browser binary missing" error from `doctor`.
25
+
26
+ ### npx (no install, recommended for first-time use)
27
+
28
+ ```bash
29
+ npx @kadj-amoah/showrunner --version # → 1.1.1
30
+ npx playwright install chromium # required: bootstraps the browser
31
+ ```
32
+
33
+ Running `showrunner` with no arguments prints a context-aware welcome with the next command to run — from outside a project it suggests `showrunner init`; inside a project root it suggests `showrunner doctor -c demo.yaml`.
34
+
35
+ ### Global install (`npm i -g`)
36
+
37
+ ```bash
38
+ npm install -g @kadj-amoah/showrunner
39
+ npx playwright install chromium # required: bootstraps the browser
40
+ showrunner --version # → 1.1.1
41
+ ```
42
+
43
+ > **Linux note:** if `npm i -g` needs `sudo`, **do not** run `sudo npx playwright install` afterwards — the browser will land in `/root/.cache/ms-playwright` where your user-mode `showrunner` process can't find it. Run `npx playwright install chromium` as your normal user. (`showrunner doctor` will detect and warn about this case.)
44
+
45
+ ### GitHub Packages
46
+
47
+ Requires a one-time `~/.npmrc` setup since GitHub Packages requires auth even for public packages:
48
+
49
+ ```bash
50
+ # Generate a Personal Access Token at github.com/settings/tokens
51
+ # Scope needed: read:packages
52
+ echo "@kadj-amoah:registry=https://npm.pkg.github.com" >> ~/.npmrc
53
+ echo "//npm.pkg.github.com/:_authToken=YOUR_TOKEN_HERE" >> ~/.npmrc
54
+
55
+ npm install -g @kadj-amoah/showrunner
56
+ npx playwright install chromium
57
+ ```
58
+
59
+ ### Directly from a git tag (no registry at all)
60
+
61
+ ```bash
62
+ npm install -g github:kadj-amoah/showrunner#v1.1.1
63
+ npx playwright install chromium
64
+ ```
65
+
66
+ ### From source
67
+
68
+ ```bash
69
+ git clone https://github.com/kadj-amoah/showrunner.git
70
+ cd showrunner
71
+ npm install
72
+ npm run build
73
+ npm link # makes `showrunner` available globally
74
+ npx playwright install chromium
75
+ ```
76
+
77
+ Verify any of the above with `showrunner --help`.
78
+
79
+ ## After installing: run the doctor first
80
+
81
+ Before doing anything else, run a system check. This catches missing prerequisites (ffmpeg, ffprobe, the recording browser) before they bite you mid-pipeline:
82
+
83
+ ```bash
84
+ showrunner doctor # no -c flag yet this is the system-only pass
85
+ ```
86
+
87
+ If it flags anything missing, fix it now. The most common gaps are `ffmpeg` (install via your OS package manager: `apt`, `pacman`, `dnf`, `brew`, or `winget`) and the recording browser (`showrunner install-browser`).
88
+
89
+ ## First demo in six commands
90
+
91
+ **Step 1 is the one most people get wrong: `cd` into the root of the product you want to demo *before* running `init`.** The scaffold creates a `showrunner-demo/` directory inside your current location, and several things in `demo.yaml` (`recording.target_url`, `project.codebase_root`, lifecycle scripts) are wired up assuming the parent directory is your product's root. If you run `init` from a random location (your home directory, `~/Downloads`, etc.), the resulting project will target nothing and you'll get a reel about an empty directory.
92
+
93
+ ```bash
94
+ # 1. Navigate to your product's root directory — the same place your package.json / pyproject.toml / etc. lives.
95
+ cd ~/my-product
96
+
97
+ # 2. Scaffold the demo project (creates ./showrunner-demo/ inside your product).
98
+ # `init` is interactive by default — it'll prompt for provider keys, target URL, etc.
99
+ showrunner init
100
+
101
+ # 3. Move into the scaffold and finish setup. The wizard already wrote .env if you pasted keys.
102
+ cd showrunner-demo
103
+ $EDITOR docs/PRD.md # replace the stub with your product brief
104
+
105
+ # 4. Full preflight (now with project context — ~11–12 PASS/FAIL rows).
106
+ showrunner doctor -c demo.yaml
107
+
108
+ # 5. Run the pipeline.
109
+ showrunner run -c demo.yaml
110
+ open output/demo_final.mp4
111
+ ```
112
+
113
+ If you'd rather not write a PRD upfront, swap the `$EDITOR` step for `showrunner understand -c demo.yaml --interactive` it asks five questions and produces the product model on the spot.
114
+
115
+ ## Provider choices
116
+
117
+ The two generative stages (LLM for comprehension + script, TTS for voiceover) are pluggable. Pick them at scaffold time with `--llm-provider` and `--tts-provider`, or edit the `llm` and `voiceover.provider` blocks in `demo.yaml` later.
118
+
119
+ ### LLM (`llm.default.provider`)
120
+
121
+ | Provider | Needs | Notes |
122
+ |----------------|--------------------------------------------|-----------------------------------------------------------------------------|
123
+ | `anthropic` | `ANTHROPIC_API_KEY` | Default. Uses Claude with structured outputs. |
124
+ | `openai` | `OPENAI_API_KEY` | Uses `response_format: json_schema`, falls back to `json_object` if needed. |
125
+ | `agent_bridge` | A headless CLI agent on PATH (default `claude -p --output-format json`) | No API key on file — Showrunner spawns the agent per request. |
126
+ | `custom` | A dynamic-importable module | Implement the `LLMProvider` interface. |
127
+
128
+ Per-stage overrides are supported under `llm.overrides.{comprehension,script,instrument}` so you can, e.g., use `agent_bridge` for the heavy script generation and `anthropic` for the small `instrument` calls.
129
+
130
+ ### TTS (`voiceover.provider.name`)
131
+
132
+ | Provider | Needs | Alignment? | Default `alignment_strategy` |
133
+ |--------------|------------------------|------------|------------------------------|
134
+ | `elevenlabs` | `ELEVENLABS_API_KEY` | ✅ | `required` |
135
+ | `openai` | `OPENAI_API_KEY` | ❌ | `best_effort` |
136
+ | `custom` | A dynamic-import module| Your call | `best_effort` |
137
+
138
+ Only ElevenLabs returns per-character alignment. With other providers, Showrunner takes the **best-effort path**: one synthesis call per segment (no slicing), captions collapse to whole-segment cues, and `at_word` action timing degrades to `at`. Set `voiceover.alignment_strategy: required` if you want it to fail loudly instead.
139
+
140
+ ## Pipeline
141
+
142
+ ```
143
+ comprehension → script → record + voiceover → mux → demo_final.mp4
144
+ ```
145
+
146
+ | Stage | What it does | Inputs | Outputs |
147
+ |-----------------|----------------------------------------------------------------------------------------------------|-----------------------------------------|---------------------------------------------------------|
148
+ | `comprehension` | Reads `docs/`, an optional codebase, or runs the interactive Q&A. Emits `product_model.json`. | `docs/PRD.md` (or `--interactive`) | `product_model.json` |
149
+ | `script` | Scrapes the live target's actionable DOM, then asks the LLM for a manifest using only those selectors. | `product_model.json` + live target URL | `scripts/manifest.json`, `vo_script.txt`, Playwright spec |
150
+ | `record` | Drives Playwright through the manifest, captures `master.webm` + a slice plan. | manifest, dev server | `segments/video/master.webm`, `slice_plan.json` |
151
+ | `voiceover` | TTS for the whole script, slices per segment, writes alignment files (when supported). | manifest | `segments/audio/*.mp3`, `segments/alignment/*.json` |
152
+ | `mux` | Normalizes, slices, branding cards, background music, captions. Outputs the MP4. | video + audio + alignment | `output/demo_final.mp4` (+ `.srt`/`.vtt` if enabled) |
153
+
154
+ Stages are independently runnable, checkpointed, and idempotent. Existing artifacts are never silently overwritten — use `--force <stage>[,<stage>]` to regenerate.
155
+
156
+ ## Daily commands
157
+
158
+ ```bash
159
+ # preflight — catches missing keys, ffmpeg, dev server down, free disk, RAM cap
160
+ showrunner doctor -c demo.yaml
161
+
162
+ # generate (or refresh) product_model.json from docs/PRD.md
163
+ showrunner understand -c demo.yaml
164
+ showrunner understand -c demo.yaml --interactive # 5-question fallback
165
+
166
+ # full pipeline (`--skip-doctor` to bypass the implicit preflight)
167
+ showrunner run -c demo.yaml
168
+
169
+ # re-run just one stage
170
+ showrunner run -c demo.yaml --stages script
171
+ showrunner run -c demo.yaml --force voiceover,mux # regen, don't reuse
172
+
173
+ # the LLM's selectors are wrong for one segment — demo it yourself
174
+ showrunner record-actions -c demo.yaml --segment fill-form
175
+
176
+ # preview the manifest in Playwright UI Mode (no recording)
177
+ showrunner preview -c demo.yaml
178
+
179
+ # inspect a failed take
180
+ showrunner trace -c demo.yaml --segment <id>
181
+ ```
182
+
183
+ ## When things go wrong
184
+
185
+ - **`x264 malloc failed` during mux** — out of RAM. The `doctor` row "free memory: … (ffmpeg thread cap: N)" shows what was budgeted. Drop resolution to 1280x720 (or 854x480 for draft), set `SHOWRUNNER_FFMPEG_THREADS=1`, or close Docker / browsers.
186
+ - **Recording fails because a selector doesn't resolve** — usually the LLM picked something fragile. The `script` stage's DOM preflight is supposed to prevent this; if it does happen, run `showrunner record-actions -c demo.yaml --segment <id>` and demonstrate the interaction yourself.
187
+ - **`vo_review_gate` halted the pipeline** — by design. Edit `scripts/vo_script.txt`, then `showrunner approve-vo -c demo.yaml`. (The init scaffold ships with this off you have to opt in via `script.vo_review_gate: true`.)
188
+ - **Output file is locked by a media player** — close VLC/QuickTime/your-browser-tab. Showrunner falls back to writing a timestamped sibling MP4 with a warning, but the canonical path needs the lock released.
189
+ - **DOM preflight failed** — your dev server isn't on the URL in `demo.yaml`, or it's behind auth. Bring the server up, configure `recording.auth` for session/form/setup-script flows.
190
+ - **Playwright warns "your OS is not officially supported"** — on Arch / CachyOS / Fedora during `npx playwright install`. Safe to ignore; Playwright falls back to the Ubuntu 24.04 build, which works fine.
191
+ - **`browser binary missing` even though I ran `npx playwright install`** — you likely ran the install under `sudo`, so the browser is in the root cache. Re-run as your normal user: `npx playwright install chromium`. `showrunner doctor` detects this and prints the specific cache it found the browser in.
192
+
193
+ ## Configuration reference
194
+
195
+ `demo.yaml` is the single source of truth. Sections:
196
+
197
+ - `project` — name and optional `product_model` path
198
+ - `comprehension` — `mode` + `sources` (PRD, README, codebase, OpenAPI, etc.)
199
+ - `script` — `style`, `duration_target_seconds`, `highlight_features`, `vo_review_gate`
200
+ - `recording` — `target_url`, viewport, browser, cursor + segment timing knobs, auth, lifecycle scripts
201
+ - `voiceover` — `provider` (discriminated by `name`), `alignment_strategy`, output dirs, drift behavior, pause placement
202
+ - `llm` — `default` provider + per-stage `overrides` (comprehension, script, instrument)
203
+ - `output` — resolution, fps, branding cards, background music, captions, output path
204
+
205
+ Legacy v1.0 configs (flat `voiceover.voice_id`, no `llm` block) are auto-migrated by the loader — your existing demos keep working without edits.
206
+
207
+ ## Deployment target
208
+
209
+ Linux. Local dev runs on WSL2/Docker on Windows or macOS hosts. A Docker image bundling Node 20, Playwright (Chromium), FFmpeg, and `xvfb` is on the roadmap.
210
+
211
+ ## License
212
+
213
+ MIT