video-editing 2.0.0 → 3.0.0

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "video-editing",
3
- "version": "2.0.0",
4
- "description": "Cloud CLI + client for editing talking-head reels with clipready: transcription, timeline authoring, verify, compose, QA and renders heavy lifting runs in the cloud.",
3
+ "version": "3.0.0",
4
+ "description": "Pure-API cloud CLI + client for editing talking-head reels with clipready: upload once, then transcription, timeline authoring, compile, render, verify and QA all run in the cloud. Node ≥ 20 + an API key — no ffmpeg.",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",
7
7
  "author": "Itay Elgazar",
@@ -1,44 +1,47 @@
1
1
  ---
2
2
  name: video-editing
3
3
  description: >-
4
- Cloud-first agent workflow for editing a talking-head video into a tight,
5
- clean cut with the `video-editing` CLI + the ClipReady cloud. Requires a
6
- ClipReady API key (`CLIPREADY_API_KEY`) every command talks to the cloud.
7
- Transcription and editorial screening run server-side (no ElevenLabs key
8
- needed); the editorial brief arrives from the server as pulled
9
- `prompts/*.md`; the timeline compiles in the cloud; rendering and QA
10
- visuals run locally on your machine (ffmpeg + hyperframes). Use whenever
11
- the user drops a talking-head clip / reel / vlog / interview and wants it
12
- edited or tightened — "edit this reel", "cut the bad retakes", "clean up
13
- this recording", "tighten this", "add captions", or just a video path with
14
- an editing ask — or when working a ClipReady review round. Handles
15
- Hebrew/RTL.
4
+ Cloud agent workflow for editing a talking-head video into a tight, clean
5
+ cut with the `video-editing` CLI + the ClipReady cloud. The CLI is a PURE
6
+ API clientrequirements are Node 20 and a ClipReady API key
7
+ (`CLIPREADY_API_KEY`) only; no ffmpeg, no ffprobe, no local rendering
8
+ tools. The source uploads once at init; transcription, editorial
9
+ screening, timeline compilation, rendering, verification, and QA visuals
10
+ all run server-side; the editorial brief arrives from the server as pulled
11
+ `prompts/*.md`. Use whenever the user drops a talking-head clip / reel /
12
+ vlog / interview and wants it edited or tightened — "edit this reel",
13
+ "cut the bad retakes", "clean up this recording", "tighten this",
14
+ "add captions", or just a video path with an editing ask — or when
15
+ working a ClipReady review round. Handles Hebrew/RTL.
16
16
  ---
17
17
 
18
- # Video Editing (ClipReady cloud + local render)
18
+ # Video Editing (ClipReady cloud pure API client)
19
19
 
20
- Turn a raw talking-head recording into a tight, clean cut. The **`video-editing`**
21
- CLI is a thin client for the ClipReady cloud: the cloud owns transcription,
22
- screening, editorial prompts, timeline compilation, and verification; your
23
- machine owns rendering and QA visuals. **You** read the pulled transcript +
24
- brief and author `timeline.json`; the CLI does everything executable.
20
+ Turn a raw talking-head recording into a tight, clean cut. The
21
+ **`video-editing`** CLI (v3) is a pure API client for the ClipReady cloud: the
22
+ cloud owns EVERYTHING executable — probing, transcription, screening,
23
+ editorial prompts, timeline compilation, rendering, verification, and QA
24
+ visuals. Your machine only streams the source up once and pulls small
25
+ artifacts back. **You** read the pulled transcript + brief and author
26
+ `timeline.json`; the CLI does the rest over HTTP.
25
27
 
26
28
  ## Install & auth
27
29
 
28
30
  ```bash
29
- npm install -g video-editing # the CLI (v2)
31
+ npm install -g video-editing # the CLI (v3)
30
32
  npx skills add ItayElgazar/clipready --skill video-editing # this skill
31
33
  ```
32
34
 
33
- Requirements:
35
+ Requirements — this is the FULL list:
34
36
 
35
37
  - **Node ≥ 20**
36
- - **ffmpeg**/**ffprobe** on PATH (local render + QA visuals)
37
- - **`CLIPREADY_API_KEY`** from the ClipReady settings page
38
- - **`CLIPREADY_API_BASE`** the ClipReady API base URL
38
+ - **A ClipReady API key** one-time login: `video-editing auth api-key` (paste
39
+ the key from the ClipReady settings page; the base URL defaults to the hosted
40
+ cloud). Env vars `CLIPREADY_API_KEY`/`CLIPREADY_API_BASE` override when set.
39
41
 
40
- **No ElevenLabs key.** Transcription runs in the ClipReady cloud with
41
- ClipReady's own transcription — do not set or ask for `ELEVENLABS_API_KEY`.
42
+ **No ffmpeg. No ffprobe. No hyperframes. No ElevenLabs key.** Nothing runs on
43
+ the local machine except the CLI itself — do not install media tools, and do
44
+ not set or ask for `ELEVENLABS_API_KEY`.
42
45
 
43
46
  **Every command fails without the API key.** If a verb errors with a
44
47
  missing-key message, stop and ask the user for their ClipReady API key;
@@ -48,79 +51,105 @@ never work around it.
48
51
 
49
52
  - Use **only** the `video-editing` CLI (`video-editing <subcommand>`). Run
50
53
  `video-editing --help` to see commands.
51
- - **NEVER** run ffmpeg/ffprobe/transcription by hand — the CLI owns all execution.
52
- - If a capability seems missing, STOP and report it as a CLI gap. Do not reach around the CLI.
54
+ - **NEVER** run ffmpeg/ffprobe/transcription by hand — there is simply no
55
+ local media in this workflow at all; every frame lives in the cloud. If you
56
+ have a memory of local renders, `compose`, `--master`, or "extract the WAV
57
+ first", that memory is from a retired pipeline — discard it.
58
+ - If a capability seems missing, STOP and report it as a CLI gap. Do not
59
+ reach around the CLI.
53
60
  - Your only hand-authored artifact is `<job>/timeline.json`.
61
+ - **Captions are timeline-authored and rendered by the cloud renderer —
62
+ NEVER ffmpeg subtitle filters, libass, `.srt` sidecars, or `drawtext`.**
54
63
 
55
64
  ## The workflow
56
65
 
57
- 1. **Init** — `video-editing init --video "<path>"` (add `--job-dir "<dir>"` to
58
- choose the working dir). Uploads the source and creates the cloud job;
59
- writes `<job>/job.json` with the `video_id` every later verb uses.
60
- 2. **Transcribe** `video-editing transcribe --job-dir "<job>"`. Uploads the
61
- audio; the cloud transcribes **and screens** it, then the CLI pulls the
62
- results into the job dir: `transcripts/`, `word_dump.txt`,
63
- `takes_packed.md`, `flags.txt`, `coverage.json` — **and
64
- `prompts/author-edl.prompt.md`**, your editorial brief.
65
- 3. **READ the pulled `prompts/*.md` and follow them** they are your
66
+ 1. **Init** — `video-editing init --source "<path>"` (add `--job-dir "<dir>"`
67
+ to choose the working dir). ONE command does everything through
68
+ transcription: it streams the source up (chunked, retried, 2GB-safe),
69
+ creates the cloud job, runs server-side ingest (probe + transcription +
70
+ editorial screening), and pulls the results into the job dir:
71
+ `transcripts/`, `word_dump.txt`, `takes_packed.md`, `flags.txt`,
72
+ `coverage.json`, `probe.json` — **and `prompts/author-edl.prompt.md`**,
73
+ your editorial brief. Writes `<job>/job.json` (the `video_id` every later
74
+ verb uses) and prints the video's web link. There is no separate
75
+ transcribe step — `transcribe` exists only to re-pull/re-run later.
76
+ Filenames with apostrophes, spaces, or unicode are safe — the internal
77
+ stem is sanitized automatically; never rename the user's file.
78
+ 2. **READ the pulled `prompts/*.md` and follow them** — they are your
66
79
  editorial brief (what to cut, what to keep, the screening gate, the pad
67
80
  and boundary rules). They are authoritative and may change between runs;
68
81
  never edit them, never substitute a remembered brief.
69
- 4. **Author `<job>/timeline.json`** per the pulled brief plus
82
+ 3. **Author `<job>/timeline.json`** per the pulled brief plus
70
83
  `references/timeline-v2-vocabulary.md` (cut ranges, captions, zooms,
71
- overlays, audio). Resolve phrase seconds ONLY with
72
- `video-editing timeline resolve --phrase "…" [--near <t> | --occurrence <n>]`
84
+ overlays, audio). The **sources KEY must equal the transcript stem** (the
85
+ filename of `transcripts/<stem>.json`) captions and resolve bind
86
+ through it. Resolve phrase → seconds ONLY with
87
+ `video-editing timeline resolve --phrase "…" [--occurrence <n>]`
73
88
  — never eyeball `word_dump.txt`. Sanity-check locally anytime with
74
89
  `video-editing timeline validate --job-dir "<job>" --json`.
75
- 5. **Compile** — `video-editing timeline compile --job-dir "<job>" --json`.
90
+ 4. **Compile** — `video-editing timeline compile --job-dir "<job>" --json`.
76
91
  Compiles in the cloud; writes `resolved/plan.json` +
77
- `resolved/diagnostics.json`. Read the diagnostics and fix until it exits
78
- `0` (`2` = validation failed fix the reported paths; `3` = ambiguous
79
- anchor disambiguate with `timeline resolve`). Never hand-edit `resolved/`.
80
- 6. **Render the preview** `video-editing compose --job-dir "<job>"` builds
81
- the local HyperFrames composition in `<job>/composition/` (with
82
- `index.html`), then render it locally with the `hyperframes` CLI
83
- (`npm install -g hyperframes`; `compose` prints the exact command, or pass
84
- `--render`). No hyperframes / no local horsepower? Use
85
- `video-editing cloud render --job-dir "<job>" --mode preview --wait` instead.
86
- 7. **Verify** — `video-editing verify --job-dir "<job>" --json`. Cloud
87
- verification of the rendered preview (catches retakes left in across a
88
- join and dead air a visual check misses). Fix `timeline.json`, re-compile,
92
+ `resolved/diagnostics.json` and prints the `View & comment` watch link
93
+ the user can already watch/comment on the compiled cut. Read the
94
+ diagnostics and fix until it exits `0` (`2` = validation failed — fix the
95
+ reported paths; `3` = ambiguous anchor disambiguate with
96
+ `timeline resolve`). Never hand-edit `resolved/`.
97
+ 5. **Render the preview** `video-editing render --job-dir "<job>"`
98
+ (cloud render, preview mode, waits and downloads `<job>/preview.mp4` by
99
+ default; it works right after `timeline compile`). Share the printed
100
+ watch link with the user.
101
+ 6. **Verify** — `video-editing verify --job-dir "<job>" --json`. Fully
102
+ server-side verification of the rendered preview (catches retakes left in
103
+ across a join and dead air a visual check misses); nothing is uploaded.
104
+ Can run while the user reviews. Fix `timeline.json`, re-compile,
89
105
  re-render, re-verify until clean; cap at ~3 fix passes and surface
90
106
  remaining findings rather than looping.
91
- 8. **QA looks** — spot-check any window locally:
92
- `video-editing qa frames --range <a>-<b> --job-dir "<job>"` (filmstrip PNG)
93
- and `video-editing qa waveform --range <a>-<b> --job-dir "<job>"`
94
- (waveform PNG + word-timing sidecar JSON). Local ffmpeg free and fast;
95
- Read the PNGs to adjudicate.
96
- 9. **Final** `video-editing cloud render --job-dir "<job>" --mode final --wait`
97
- (or render the composition locally at final quality).
107
+ 7. **QA looks** — spot-check any window with server-rendered visuals.
108
+ THE close-look tool is
109
+ `video-editing qa inspect --start <a> --end <b> --job-dir "<job>"`:
110
+ one composite PNG with the filmstrip, the waveform, word labels, AND
111
+ the compiled plan's cut regions shaded red ("cut") — everything needed
112
+ to adjudicate a moment in a single image. Same addressing as frames:
113
+ `qa inspect --join <i>` (the two sides of plan join i → `-a`/`-b`
114
+ PNGs) and `qa inspect --out-start <a> --out-end <b>` (OUTPUT seconds
115
+ mapped through the compiled plan). The narrower views still exist:
116
+ `video-editing qa frames …` (filmstrip only, same addressing modes)
117
+ and `video-editing qa waveform --start <a> --end <b>` (waveform PNG +
118
+ word-timing sidecar JSON). Read the PNGs to adjudicate.
119
+ 8. **Final** — `video-editing render --mode final --job-dir "<job>"`.
98
120
 
99
121
  ## Your editorial brief arrives from the cloud
100
122
 
101
123
  The deep editorial brief — retake/keep rules, pause tightening, cold-open,
102
124
  screening and verification procedure — is **not in this skill**. It is pulled
103
- from the server into `<job>/prompts/*.md` by `transcribe` (and refreshed by
125
+ from the server into `<job>/prompts/*.md` by `init` (and refreshed by
104
126
  `files pull`). Old references in this skill (`editing-brief.md`,
105
127
  `hard-rules.md`, `adversarial-review.md`, `scribe-collapse.md`) are stubs
106
128
  pointing there. If `prompts/author-edl.prompt.md` is missing, run
107
129
  `video-editing files pull --job-dir "<job>"` — do not improvise a brief.
108
130
 
109
- ## Vertical master
131
+ ## Known caveats
110
132
 
111
- `init --video` uploads the source as-is. When the deliverable is a vertical
112
- 9:16 reel from a non-vertical source, pass `--master` to `init` so the
113
- vertical master is baked before upload (needs local ffmpeg). Check
114
- `video-editing init --help` for the current flag surface.
133
+ - **`verify` over-triggers on thematically narrow monologues.** The
134
+ duplicated-phrase join check flags legitimately repeated wording as
135
+ "retake left in". If EVERY join comes back flagged — including plain
136
+ pause-tightening joins that obviously aren't retakes adjudicate each
137
+ finding against `flags.txt` (the screening output) instead of blindly
138
+ recutting; only recut joins that flags.txt corroborates as real retakes.
139
+ - **Caption mistranscriptions** are fixed with a captions override in
140
+ `timeline.json` (anchored on the MIS-transcribed text — see
141
+ `references/timeline-v2-vocabulary.md`), then recompile + re-render.
142
+ Never with subtitle files or filters.
115
143
 
116
144
  ## File sync
117
145
 
118
146
  `video-editing files pull --job-dir "<job>" [--only <name,name>]` fetches the
119
147
  cloud job's artifacts into the job dir preserving relative paths (transcripts,
120
148
  `prompts/*.md`, `resolved/plan.json`, `timeline.json`, …);
121
- `video-editing files push --job-dir "<job>"` uploads local artifacts (e.g. a
122
- hand-authored `timeline.json`, referenced assets) back to the job. Use `pull`
123
- to recover state on a fresh machine — the cloud job is the source of truth.
149
+ `video-editing files push --job-dir "<job>" <paths…>` uploads local artifacts
150
+ (e.g. a hand-authored `timeline.json`, referenced assets) back to the job. Use
151
+ `pull` to recover state on a fresh machine — the cloud job is the source of
152
+ truth.
124
153
 
125
154
  ## Working a ClipReady review round
126
155
 
@@ -130,13 +159,12 @@ When the job is a clipready review round (the video has an active round):
130
159
  `<job>/review/round.json` (round/run ids, requested changes) and
131
160
  `<job>/review/instruction.md`; hydrates `<job>/timeline.json` from the
132
161
  server only when you don't already have one (never overwrites yours).
133
- Add `--source` if the source video isn't local yet.
134
162
  2. Edit `timeline.json` per the instruction, then
135
163
  `video-editing review push --timeline --job-dir "<job>"` after each
136
- meaningful change — it compiles (diagnostics; exit `2` if not clean) and
137
- the review page updates live. Referenced assets (stickers, audio beds)
138
- upload automatically, sha256-cached.
139
- 3. Preview + verify exactly as in the workflow above.
164
+ meaningful change — it compiles in the cloud (diagnostics; exit `2` if
165
+ not clean) and the review page updates live. Referenced assets (stickers,
166
+ audio beds) upload automatically, sha256-cached.
167
+ 3. Render + verify exactly as in the workflow above.
140
168
  4. `video-editing review push --complete --duration <s> --outcomes outcomes.json --job-dir "<job>"`
141
169
  — compiles fresh (must be clean) and delivers the terminal payload.
142
170
  `outcomes.json` is `[{"change_id": "chg_…", "ok": true, "note": "…"}]`,
@@ -152,7 +180,7 @@ caption grouping is the same characters in Hebrew.
152
180
 
153
181
  ## References
154
182
 
155
- - `references/cli-reference.md` — every v2 subcommand + flag.
183
+ - `references/cli-reference.md` — every v3 subcommand + flag.
156
184
  - `references/timeline-v2-vocabulary.md` — the full `timeline.json` v2
157
185
  vocabulary, one JSON example per feature (captions + word styling, karaoke,
158
186
  zoom ramps, stickers, enter/exit, audio beds, grade).
@@ -1,71 +1,86 @@
1
- # `video-editing` CLI reference (v2cloud-only)
1
+ # `video-editing` CLI reference (v3pure API client)
2
2
 
3
- All execution goes through this CLI. Quote paths (they contain spaces).
3
+ All execution goes through this CLI, and the CLI runs NOTHING locally: every
4
+ verb is HTTP against the ClipReady cloud plus small artifact pulls. Quote
5
+ paths (they contain spaces).
4
6
 
5
7
  **Every verb requires ClipReady credentials.** Resolution:
6
8
 
7
- - **base**: `--api-base` → env `CLIPREADY_API_BASE`
8
- - **key** (sent as `Authorization: Bearer <key>`): `--api-key` → env `CLIPREADY_API_KEY`
9
+ - **base**: `--api-base` → env `CLIPREADY_API_BASE` → the hosted cloud (default)
10
+ - **key** (sent as `Authorization: Bearer <key>`): `--api-key` → env `CLIPREADY_API_KEY` → the config file written by `video-editing auth api-key`
9
11
  - **video id**: `--video-id` → `<job>/job.json` (written by `init`) → env `VIDEO_ID`
10
12
 
11
13
  A missing base or key is a clear error → non-zero exit, nothing runs. There is
12
- **no ElevenLabs configuration** transcription is server-side in the ClipReady
13
- cloud.
14
+ **no ffmpeg/ffprobe/hyperframes requirement and no ElevenLabs
15
+ configuration** — media work is server-side in the ClipReady cloud.
14
16
 
15
17
  Most verbs support `--json` for a machine-readable result. Exit codes: `0` ok,
16
18
  `1` error (incl. missing credentials), `2` validation failed, `3` ambiguous
17
19
  anchor (timeline group).
18
20
 
19
- ## Pipeline commands
21
+ **Large uploads are chunked automatically** (no flag needed): the init source
22
+ streams up in 8MB parts with per-part retry — a 2GB file is never buffered in
23
+ memory — and on networks where direct storage PUTs keep dying, parts fall back
24
+ to an authenticated relay through the API. Servers without chunked-upload
25
+ support transparently fall back to a single retried upload.
20
26
 
21
- - **`init --video <path> [--job-dir <dir>] [--master] [--force]`**
22
- Upload the source and create the cloud job. Writes the job dir (default: a
23
- new dir named for the clip) with `job.json` (`video_id`, api base) and
24
- `source.json`. `--master` bakes the vertical 9:16 master locally (ffmpeg)
25
- before upload, for non-vertical sources destined for a vertical deliverable.
27
+ ## Pipeline commands
26
28
 
27
- - **`transcribe --job-dir <dir> [--language <iso>] [--num-speakers <n>] [--force]`**
28
- Upload the audio; the **cloud** transcribes and screens it, then the CLI
29
- pulls the results into the job dir: `transcripts/*.json`, `word_dump.txt`,
30
- `takes_packed.md`, `flags.txt`, `coverage.json`, and the editorial brief
31
- `prompts/author-edl.prompt.md` (plus any other `prompts/*.md` the server sends).
32
- Cached server-side per source; `--force` re-transcribes.
29
+ - **`init --source <path> [--job-dir <dir>] [--title <t>] [--poll-interval 5]`**
30
+ ONE command covers what init+transcribe used to do. Streams the source up,
31
+ creates the cloud job, runs server-side **ingest** (probe + audio
32
+ extraction + transcription + editorial screening), polls with progress
33
+ lines, then pulls into the job dir: `transcripts/*.json`, `word_dump.txt`,
34
+ `takes_packed.md`, `flags.txt`, `coverage.json`, `probe.json`, and the
35
+ editorial brief `prompts/author-edl.prompt.md` (plus any other
36
+ `prompts/*.md`). Writes `job.json` (`video_id`, api base, stem,
37
+ `duration_s` from the server probe, `source_path`) and prints the video's
38
+ web page link (`web_url` in `--json`). The internal stem is sanitized to a
39
+ filename-safe charset, so apostrophe/space/unicode filenames work end to
40
+ end with no rename.
41
+
42
+ - **`transcribe --job-dir <dir> [--poll-interval 5]`**
43
+ Re-run/pull only (init already transcribed): when the transcript artifacts
44
+ exist server-side it just pulls them; otherwise it starts a fresh
45
+ server-side ingest, polls, and pulls. No media flags — there is no local
46
+ extraction.
33
47
 
34
48
  ## Timeline commands (`timeline.json` v2)
35
49
 
36
50
  - **`timeline validate --job-dir <dir> [--json]`**
37
- Local schema + semantic + capability validation of `<job>/timeline.json`.
38
- Exit `2` if invalid.
51
+ Local schema + semantic + capability validation of `<job>/timeline.json`
52
+ (the one purely local verb — it touches no media). Exit `2` if invalid.
39
53
 
40
- - **`timeline resolve --job-dir <dir> --phrase <text> [--near <srcSeconds>] [--occurrence <n>] [--source <name>] [--json]`**
41
- Resolve a transcript phrase to **exact source seconds** (word-accurate).
42
- The ONLY way to turn a phrase into an anchor time. Multiple hits → exit `3`
43
- with per-occurrence context; pick one with `--near` or `--occurrence`
54
+ - **`timeline resolve --job-dir <dir> --phrase <text> [--occurrence <n>] [--source <name>] [--json]`**
55
+ Resolve a transcript phrase to **exact source seconds** (word-accurate,
56
+ server-side). The ONLY way to turn a phrase into an anchor time. Multiple
57
+ hits → exit `3` with per-occurrence context; pick one with `--occurrence`
44
58
  (1-based). Not found → fuzzy suggestions, exit `1`.
45
59
 
46
60
  - **`timeline compile --job-dir <dir> [--json]`**
47
61
  **Cloud compile**: uploads `timeline.json`, the server validates, resolves
48
- anchors, derives caption cues, and returns `resolved/plan.json` +
49
- `resolved/diagnostics.json` (written into the job dir). Iterate until exit
50
- `0`. Exit `2` = validation failed (fix the reported `path`s), `3` =
62
+ anchors, sources silences from the job's cloud files, derives caption
63
+ cues, and returns `resolved/plan.json` + `resolved/diagnostics.json`
64
+ (written into the job dir). On success prints the `View & comment` watch
65
+ link — the compiled cut is already watchable in the web app. Iterate until
66
+ exit `0`. Exit `2` = validation failed (fix the reported `path`s), `3` =
51
67
  ambiguous anchor (disambiguate with `timeline resolve`). Never hand-edit
52
68
  anything under `resolved/`.
53
69
 
54
- ## Preview / render commands
70
+ - **`timeline captions generate --job-dir <dir> [--preset grouped|opus-karaoke] [--json]`**
71
+ Enable captions in `timeline.json` (preset only), then server-compile to
72
+ derive/report cues.
73
+
74
+ ## Render commands
55
75
 
56
- - **`compose --job-dir <dir> [--render] [--quality draft|standard|high] [--fps 30] [--out <path>] [--json]`**
57
- Build the local HyperFrames composition from `resolved/plan.json` (cut +
58
- captions/zooms/overlays) in `<job>/composition/` media proxies, referenced
59
- assets, and `index.html`. Without `--render`, prints the composition dir +
60
- the exact `hyperframes render` command to run. With `--render`, runs it
61
- (requires the `hyperframes` CLI on PATH: `npm install -g hyperframes`);
62
- default output `<job>/preview.mp4` (the render IS the preview in the cloud-first flow). This is the LOCAL delivery path.
76
+ - **`render [--mode preview|final] --job-dir <dir> [--no-wait] [--poll-interval 10] [--out <path>] [--json]`**
77
+ THE render verb: submits a cloud render of the compiled plan (works right
78
+ after `timeline compile`), **waits by default**, and downloads the result
79
+ to `<job>/preview.mp4` / `<job>/final.mp4`. Mode defaults to `preview`.
80
+ `--no-wait` submits and prints `render_id` only.
63
81
 
64
- - **`cloud render --job-dir <dir> --mode preview|final [--wait] [--poll-interval 10] [--out <path>] [--json]`**
65
- Submit a server-side render of the compiled plan. Without `--wait`: prints
66
- `render_id` and exits `0`. With `--wait`: polls until terminal; on
67
- `completed`, downloads the video to `--out` (default `<job>/preview.mp4` or
68
- `<job>/final.mp4`). `failed` → exit `1` with the error.
82
+ - **`cloud render --mode preview|final --job-dir <dir> [--wait] [--poll-interval 10] [--out <path>] [--json]`**
83
+ Same implementation, legacy spelling (`--wait` is opt-in here).
69
84
 
70
85
  - **`cloud status <render_id> [--json]`**
71
86
  One status GET: `pending|running|completed|failed` (+ `video_url` when
@@ -73,36 +88,56 @@ anchor (timeline group).
73
88
 
74
89
  ## Verification / QA commands
75
90
 
76
- - **`verify --job-dir <dir> [--json]`**
77
- **Cloud verification** of the rendered preview: uploads/points at the
78
- preview and the server re-checks every join for duplicated phrases (a
79
- retake left in → error) and over-long gaps (dead air → warning/error).
80
- Writes `verify.json`; exit `2` on needs-fixes. Requires a rendered preview
81
- (`compose` + hyperframes render, or `cloud render --mode preview`).
82
-
83
- - **`qa frames --range <start>-<end> [--cols <n>] [--interval <s>] --job-dir <dir> [--json]`**
84
- **Local ffmpeg** filmstrip PNG for the window →
85
- `<job>/qa/frames_<start>_<end>.png`. Read the PNG to inspect frames.
86
-
87
- - **`qa waveform --range <start>-<end> --job-dir <dir> [--json]`**
88
- **Local ffmpeg** waveform PNG + word-timing sidecar
91
+ - **`verify --job-dir <dir> [--full] [--window <s>] [--json]`**
92
+ **Fully server-side verification** of the rendered preview: the server
93
+ re-checks every join for duplicated phrases (a retake left in → error) and
94
+ over-long gaps (dead air → warning/error) against its own copy of the
95
+ preview — nothing is uploaded. Writes `verify.json`; exit `2` on
96
+ needs-fixes. Caveat: the duplicated-phrase check over-triggers on
97
+ thematically narrow monologues — if every join is flagged (including plain
98
+ pause-tightening joins), adjudicate against `flags.txt` instead of blindly
99
+ recutting.
100
+
101
+ - **`qa frames (--start <s> --end <s> | --join <i> [--span 2] | --out-start <s> --out-end <s>) [--cols <n>] [--interval <s>] --job-dir <dir> [--json]`**
102
+ **Server-rendered** filmstrip PNG(s) `<job>/qa/frames_<start>_<end>.png`.
103
+ Three addressing modes (exactly one): `--start/--end` in SOURCE seconds;
104
+ `--join <i>` renders the two sides of compiled-plan join `i` (1-based —
105
+ the last/first `--span` seconds of the segments meeting there) as
106
+ `…-a.png` (tail) + `…-b.png` (head); `--out-start/--out-end` in OUTPUT
107
+ seconds, mapped through `resolved/plan.json` (windows crossing a join
108
+ split into `-a`/`-b`/… PNGs). Read the PNGs to inspect frames.
109
+
110
+ - **`qa waveform --start <s> --end <s> --job-dir <dir> [--json]`**
111
+ **Server-rendered** waveform PNG + word-timing sidecar →
89
112
  `<job>/qa/waveform_<start>_<end>.png` and
90
113
  `<job>/qa/waveform_<start>_<end>.words.json` (word list with timings for
91
- the window). Free and fast — use for cut-edge adjudication.
114
+ the window, SOURCE seconds). Use for cut-edge adjudication.
115
+
116
+ - **`qa inspect (--start <s> --end <s> | --join <i> [--span 2] | --out-start <s> --out-end <s>) [--n-frames <n>] --job-dir <dir> [--json]`**
117
+ **THE close-look tool** — a **server-rendered** combined composite PNG →
118
+ `<job>/qa/inspect_<start>_<end>.png`: filmstrip + waveform + word labels
119
+ in one image, with the compiled plan's cut regions shaded translucent
120
+ red (labeled "cut") over the waveform. Same three addressing modes as
121
+ `qa frames` (exactly one): `--start/--end` in SOURCE seconds; `--join <i>`
122
+ renders the two sides of compiled-plan join `i` as `…-a.png` (tail) +
123
+ `…-b.png` (head) — the sides are discontiguous in source time, hence two
124
+ PNGs; `--out-start/--out-end` in OUTPUT seconds mapped through
125
+ `resolved/plan.json`. `--n-frames` sets the filmstrip frame count
126
+ (default 10). Prefer this over separate frames + waveform calls when
127
+ adjudicating a cut.
92
128
 
93
129
  ## File sync commands
94
130
 
95
131
  - **`files pull --job-dir <dir> [--only <name,name>] [--json]`**
96
- List the cloud job's artifacts and fetch each (or the `--only` subset) into
132
+ List the cloud job's files and fetch each (or the `--only` subset) into
97
133
  the job dir, **preserving relative paths** (`resolved/plan.json` →
98
134
  `<job>/resolved/plan.json`, `prompts/author-edl.prompt.md` →
99
- `<job>/prompts/author-edl.prompt.md`). `.json` artifacts pretty-printed. Use to
135
+ `<job>/prompts/author-edl.prompt.md`). Byte-exact, sha256-skipped. Use to
100
136
  recover job state on a fresh machine.
101
137
 
102
- - **`files push --job-dir <dir> [--only <name,name>] [--json]`**
103
- Upload local job artifacts (e.g. `timeline.json`, referenced assets under
104
- `assets/`) to the cloud job. Content-hash-cached — unchanged files are not
105
- re-uploaded.
138
+ - **`files push --job-dir <dir> <paths…> [--json]`**
139
+ Upload local job files (e.g. `timeline.json`, referenced assets) to the
140
+ cloud job. Content-hash-cached — unchanged files are not re-uploaded.
106
141
 
107
142
  ## Review round commands (ClipReady review sessions)
108
143
 
@@ -116,31 +151,36 @@ anchor (timeline group).
116
151
  Push review-round events (one mode per call; run id defaults to
117
152
  `review/round.json`). `--stage` posts a progress event
118
153
  (`provisioning|transcribing|edl|render_preview|qc|render_final|uploading|log`).
119
- `--timeline` compiles `<job>/timeline.json` (same as `timeline compile`,
120
- exit `2` if not clean) and pushes a `timeline_update` — the review page
121
- updates live. `--complete` compiles fresh (must be clean) and pushes the
122
- terminal `completed` event (`{edl, timeline, plan, duration_s, outcomes?}`;
154
+ `--timeline` compiles `<job>/timeline.json` in the cloud (exit `2` if not
155
+ clean) and pushes a `timeline_update` — the review page updates live.
156
+ `--complete` compiles fresh (must be clean) and pushes the terminal
157
+ `completed` event (`{edl, timeline, plan, duration_s, outcomes?}`;
123
158
  `--outcomes` is a JSON file of `[{change_id, ok, note?}]`). Both
124
159
  `--timeline` and `--complete` upload the timeline's referenced assets
125
160
  automatically (sha256-cached in `<job>/review/assets.json`).
126
161
 
162
+ - **`review prompt --job-dir <dir> [--json]`** — print the pulled round
163
+ instruction.
164
+
127
165
  ## Utility
128
166
 
129
167
  - **`--version`** — print the CLI version.
130
168
  - **`status --job-dir <dir> [--json]`** — cloud job state + local artifact existence.
131
169
  - **`skill install [--target <dir>] [--json]`** — copy the bundled
132
170
  `video-editing` agent skill into `<target|~/.claude/skills>/video-editing`.
171
+ - **`config set-key <key> | set-base <url> | path`** — store credentials in
172
+ `~/.config/video-editing/.env` (the only verb that runs without one).
133
173
 
134
174
  ## Typical session
135
175
 
136
176
  ```
137
- export CLIPREADY_API_BASE=https://… CLIPREADY_API_KEY=…
138
- video-editing init --video "clip.mp4" --job-dir jobs/clip
139
- video-editing transcribe --job-dir jobs/clip
177
+ video-editing auth api-key # once per machine (skip if already logged in)
178
+ video-editing init --source "clip.mp4" --job-dir jobs/clip # upload + ingest + pull (transcribe included)
140
179
  # READ jobs/clip/prompts/author-edl.prompt.md — it is the editorial brief. Author timeline.json.
141
- video-editing timeline compile --job-dir jobs/clip --json # fix until exit 0
142
- video-editing compose --job-dir jobs/clip --render # local preview render
143
- video-editing verify --job-dir jobs/clip --json # fix recompile re-render → re-verify
144
- video-editing qa frames --range 0-5 --job-dir jobs/clip # spot-check looks
145
- video-editing cloud render --job-dir jobs/clip --mode final --wait
180
+ video-editing timeline validate --job-dir jobs/clip --json
181
+ video-editing timeline compile --job-dir jobs/clip --json # fix until exit 0; prints the watch link
182
+ video-editing render --job-dir jobs/clip # cloud preview render (waits + downloads)
183
+ video-editing verify --job-dir jobs/clip --json # fix → recompile → re-render → re-verify
184
+ video-editing qa inspect --join 1 --job-dir jobs/clip # close-look at the first join's two sides (filmstrip+waveform+cuts)
185
+ video-editing render --mode final --job-dir jobs/clip
146
186
  ```