cueframe 0.9.2 → 0.11.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.
@@ -19,6 +19,14 @@ brief/rubric for a local correction; check the affected behavior and relevant re
19
19
  of restarting the new-film method below. A diagnostic or preview-only request does not require
20
20
  a final export or a whole-film judge pass. Explicit user scope takes precedence over craft defaults.
21
21
 
22
+ ## Learned taste: the org's saved style preferences
23
+
24
+ Before composing for an org, read its learned taste: `get_profile` returns it as `taste`, and Eve recalls it into every turn. It is advice, never instruction. Precedence, highest first: the current request, the brief, the project, the brand kit, exclusions and registered critics, then learned taste. When learned taste conflicts with any of those, follow the higher one and say which preference you set aside; never resolve a conflict silently.
25
+
26
+ Save a preference only when the user states a durable one: a revise comment, a correction in chat, or an explicit "remember this". Never save one-off brief content, facts about footage, approval notes or anything secret. Every save names its source (the job, checkpoint or chat, plus the date). Save with your runtime's taste tool (Eve: `taste__remember`; MCP: `remember_taste`; HTTP: `POST /v1/profile/taste`).
27
+
28
+ Tell the user every time you save or forget: "Added to your profile: <preference>. Say undo to remove it." Undo forgets that entry (`taste__forget`, `forget_taste`, or `DELETE /v1/profile/taste/{id}`). When the user says not to learn from this job, save nothing for the rest of it. A refusal (the entry is too long, the org's taste is full, or the owner turned learned taste off) is final: tell the user, and do not retry or shorten the preference silently.
29
+
22
30
  ## Plan and author to the request
23
31
 
24
32
  Use `cueframe-storyboard` only when new work lacks structure. For an existing title correction, retain the approved brief and edit the title directly; no whole-film rubric, paid judge or final export is required.
@@ -295,7 +303,7 @@ Each playbook is an illustrative format default; explicit intent and scope gover
295
303
  | CTA + date | 40–45s | Exact action + launch date. Logo last. | ≤12 |
296
304
 
297
305
  **Frameworks:** 3-act teaser (Tease → Reveal → CTA) or StoryBrand SB7 (customer is hero, you are guide). One pain or one wow — not five diluted features.
298
- **Reach for:** `import_media` a real demo capture or founder clip · `list_catalog` → the `product-launch-trailer` and `cinematic-title` scenes (use `cinematic-title` for a wordmark where the brief calls for it) · `color-grade` for the hero look · date + CTA on the final held frame.
306
+ **Reach for:** `import_media` a real demo capture or founder clip · `list_catalog` with `projection:"component-library", origin:"builtin"` to discover a maintained preset or recipe that fits the footage; resolve its exact scoped identity before `apply_template` · an authored card or native component for the closing wordmark, date and CTA on the final held frame.
299
307
  **Anti-patterns:** opening on a logo animation; stacking five features; narrating specs; a fabricated/rounded stat; a mocked terminal standing in for a real screen.
300
308
  **Quality bar:** the first frame survives with zero text on it. If your open is a gradient with the product name, you've already lost.
301
309
 
@@ -328,7 +336,7 @@ Each playbook is an illustrative format default; explicit intent and scope gover
328
336
 
329
337
  **Frameworks:** Hook → Problem → Solution → Proof → CTA. Decide the CTA first, script it last; write for the ear.
330
338
  **A fully animated explainer is a FIRST-CLASS grounded format**, not a fallback for missing footage. An explainer built on authored diagrams of the *actual* mechanism (its real pipeline, the real data) is grounded — the grounding is that each visual depicts THIS thing specifically, not a decorative loop. Reach for it deliberately, not as a consolation for "no footage."
331
- **Reach for:** an authored `card` clip (your own HTML/typography, animated in its CSS or with `clip.setKeyframes`) to anchor an abstract mechanism with a real diagram — process/algorithm/data viz, not cinematic footage · `lower-third` for term labels · one idea per beat · when using real footage, narrate to the detected transcript timing.
339
+ **Reach for:** an authored `card` clip (your own HTML/typography, animated in its CSS or with `clip.setKeyframes`) to anchor an abstract mechanism with a real diagram — process/algorithm/data viz, not cinematic footage · an authored card for term labels · one idea per beat · when using real footage, narrate to the detected transcript timing.
332
340
  **Anti-patterns:** a wall of narration over stock gradient loops with no visual keyed to the words (the generic-filler tell — a purposeful diagram of the real mechanism is the opposite); explaining features before establishing the problem; using `generate_media` text-to-video to fake a "product" that doesn't match the real UI (it hallucinates specifics).
333
341
  **Quality bar:** every beat has a visual keyed to what's being said — grounded and specific to this content, not decoration; the hook lands in 3s.
334
342
 
@@ -344,7 +352,7 @@ Each playbook is an illustrative format default; explicit intent and scope gover
344
352
  | CTA | 110–120s | One action: start free / book / docs. |
345
353
 
346
354
  **Frameworks:** Problem → Product-in-action → Outcome, wrapped in one completed task, not a feature tour. ~2 min is a good ceiling; chapter beyond that.
347
- **Reach for:** `import_media` a REAL screen recording (captured by the user, or by an external screen-capture client such as a headed Playwright walkthrough recorded to MP4 — CueFrame does not screen-record) · reframe punch-in to the active UI element each step (`focus:{mode:"point",x,y}` on the click target, or a `face` focus for a founder inset) — the single biggest amateur→pro delta in demos, because the click target is ~30px in a 3840px 4K frame and nobody sees it unzoomed (**see `cueframe-product-video`** for the full click-point→reframe-segment auto-zoom tiling + PiP recipe) · a `lower-third` label per step.
355
+ **Reach for:** `import_media` a REAL screen recording (captured by the user, or by an external screen-capture client such as a headed Playwright walkthrough recorded to MP4 — CueFrame does not screen-record) · reframe punch-in to the active UI element each step (`focus:{mode:"point",x,y}` on the click target, or a `face` focus for a founder inset) — the single biggest amateur→pro delta in demos, because the click target is ~30px in a 3840px 4K frame and nobody sees it unzoomed (**see `cueframe-product-video`** for the full click-point→reframe-segment auto-zoom tiling + PiP recipe) · an authored step-label card.
348
356
  **Anti-patterns:** the cardinal demo sin — a mocked/fake terminal or static UI card instead of the real app; showing the full 4K screen unzoomed; narrating every menu.
349
357
  **Quality bar:** every UI/terminal on screen is a real capture; the actual action is visibly punched-in, not lost in a wide frame.
350
358
 
@@ -360,7 +368,7 @@ Each playbook is an illustrative format default; explicit intent and scope gover
360
368
  | Action | 68–75s | One CTA. |
361
369
 
362
370
  **Frameworks:** PAS (Problem → Agitate → Solution) or AIDA. Framing: eyes on the upper-third line, small headroom, subject looks into the lens; break every ~5–8s of pure talking head with a cutaway.
363
- **Reach for:** THE canonical CueFrame job. `get_media_context` for faces + transcript → reframe `focus:{mode:"active-speaker"}` for a solo speaker, `{mode:"all-faces"}` to hold a two-shot, or `{mode:"face",faceId,shotScale:"close"}` to punch in on emphasis → transcript-timed `captions` with a legibility plate (`setCaptionStyle` `emphasisPlate`, `position:"bottom"`) → a text overlay at `zPlane:"behind-subject"` when you want a title/word to sit *behind* the head (the signature look; render bakes the person matte) → a `lower-third` for name/title, shown once → `color-grade`. Zero generation needed.
371
+ **Reach for:** THE canonical CueFrame job. `get_media_context` for faces + transcript → reframe `focus:{mode:"active-speaker"}` for a solo speaker, `{mode:"all-faces"}` to hold a two-shot, or `{mode:"face",faceId,shotScale:"close"}` to punch in on emphasis → transcript-timed `captions` with a legibility plate (`setCaptionStyle` `emphasisPlate`, `position:"bottom"`) → a text overlay at `zPlane:"behind-subject"` when you want a title/word to sit *behind* the head (the signature look; render bakes the person matte) → an authored card or owned native component for name/title, shown once; use the selected component’s documented color inputs. Zero generation needed.
364
372
  **Anti-patterns:** a static wide talking head running 30s uncut (reads as a raw webcam upload); captions slapped over the chin with no plate; head dead-center or too much headroom; missing the lower-third identity.
365
373
  **Quality bar:** a face is on screen within 3s; the person framed is the person speaking; captions never cover the mouth or eyes.
366
374
 
@@ -374,17 +382,17 @@ Each playbook is an illustrative format default; explicit intent and scope gover
374
382
  | Know where subject + speech are | `get_media_context` → face boxes per frame (with `faceId`) + transcript. If faces are not detected, `prepare_media(kind:"subjectTrack", intent:{startSec,endSec})` → poll `get_media_facts` for the same SOURCE window until ready. |
375
383
  | Keep the speaker framed / punch-in | `setCropIntents` op (the PREFERRED authoring path) or inline `reframe.segments` on a `clip.add` source. Each segment needs `startSec`/`endSec`/`focus`/`zoom`; **segments must TILE the clip** (an uncovered span → `reframe_coverage_gap` at validate). `focus.mode`: `frame-center` \| `point{x,y}` \| `face{faceId, shotScale?: close\|standard\|wide}` \| `all-faces` \| `active-speaker`. `zoom<1` punches in, `=1` full frame, `>1` rejected (min 0.1). Times in **seconds**. |
376
384
  | Captions that track real speech | `composition.captions.segments[].words[]` = `{text, startMs, endMs, emphasis?, annotate?: circle\|underline}` — word times in **milliseconds**. Author the words directly with the `setCaptions` op (segments wholesale — how a generated-VO film gets its word-synced spine without a source transcript); style via `setCaptionStyle`: `position` (top\|center\|bottom), `entrance` (fade\|word-pop\|stagger-up), `emphasisPlate` + plate colors for legibility. Captions default to front; set top-level `composition.captions.zPlane:"behind-subject"` only when the user wants the whole caption layer behind the speaker. It resolves person cutouts for every overlapping source window and degrades visibly to front where the legibility gate refuses the effect. |
377
- | Text behind the speaker's head | An `overlay` clip (a title/label primitive) with `zPlane:"behind-subject"`. This is the focused hero treatment; caption-layer depth is a separate whole-layer choice. Before preview/judgment, `prepare_media(kind:"matte", intent:{startSec,endSec})` for the overlapping clip's SOURCE trim and poll `get_media_facts` until ready. Render also resolves the person cutout on miss. |
378
- | Name someone / label a step | `lower-third` scene from `list_catalog` |
379
- | Title / closing wordmark | `cinematic-title` scene (closing, not opening) |
380
- | Grade the look | `color-grade` scene/effect |
385
+ | Text behind the speaker's head | An `overlay` clip using the built-in `heroText` primitive with `zPlane:"behind-subject"`. This is the focused hero treatment; caption-layer depth is a separate whole-layer choice. Before preview/judgment, `prepare_media(kind:"matte", intent:{startSec,endSec})` for the overlapping clip's SOURCE trim and poll `get_media_facts` until ready. Render also resolves the person cutout on miss. |
386
+ | Name someone / label a step | An authored `card` or owned native component with the intended name, typography and placement. |
387
+ | Title / closing wordmark | An authored `card` or owned native component for the closing wordmark, held long enough to read. |
388
+ | Set a graphic's palette | The selected component's documented color inputs, or an authored treatment in its complete native source. |
381
389
  | Anchor an abstract mechanism | An authored `card` clip animated in its CSS or with `clip.setKeyframes` (diagrams of the real mechanism — NOT cinematic; a first-class grounded path) |
382
390
  | Long-form → clips | `suggest_briefs` → `wait_job(kind:"suggestions")` → `compose({ suggestionId })` |
383
391
  | Auto-reframe to another aspect | `derive_composition` (content-aware 9:16 / 1:1 / 4:5 from a 16:9 master) |
384
- | Discover what to build with | `list_catalog` — pass filters such as `category`/`kind`/`tier`/`useCase`/`mood`/`intent`, plus `limit` and the returned pagination cursor. For builtin packages, request `projection:"component-library"` and `origin:"builtin"`, then resolve the selected exact identity before insertion. Each entry carries `placement` (how to author it), `tier`/`useCase`, and `fixedCopy` (baked text no param changes). Read `cueframe://component/{id}` for the full **prop schema**. |
385
- | Own / fork a custom graphic | `get_component_source` (exact scoped v3 pin for builtins) / `create_component` / `update_component` (preserve the complete source snapshot) — **see `cueframe-component-authoring`** for the full fork→preview→push loop |
392
+ | Discover what to build with | `list_catalog` with `projection:"component-library", origin:"builtin"` discovers maintained preset/recipe cards. Preserve each card's complete identity and resolve its exact collection, id and revision with `resolve_builtin_component` before `apply_template`; retain the returned `documentSha256` and source pins. Page with `limit` and the returned cursor. The default catalog and `cueframe://component/{id}` describe the one primitive (`heroText`) and org-installed components. |
393
+ | Own / fork a custom graphic | Discover a definition with `list_catalog` projection `component-library`; `get_component_source` with its exact `componentId`, `sourceVersionId` and `builtinCollection`, then `create_component` / `update_component` with the complete native version-4 source snapshot — **see `cueframe-component-authoring`** for the full fork→preview→push loop |
386
394
  | Several cells that share space and must reflow together (feature grid, rail + fluid content, cast + type) | An authored card or native component laid out with CSS flex/grid (fixed tracks for content-sized cells, `fr` for the rest), animated from the frame. Static PiP / split is clip `region` + `fit` instead. Never CSS-scale the layout. **See `cueframe-component-authoring`** |
387
- | Seed + edit the timeline | `apply_composition` (atomic batch ops; `dry_run:true` to check, `if_match` for OCC) — this is where clips, reframe, captions, and format are authored |
395
+ | Seed + edit the timeline | `apply_composition` (atomic batch ops; `dry_run:true` to check; every committing batch needs `if_match` from `get_composition`, or it is refused 428; on a 409, read `get_composition` again and rebuild the batch before retrying, never resend it with the 409's `currentEtag`) — this is where clips, reframe, captions, and format are authored |
388
396
  | Set the brand | `create_brand_kit` (402-gated) → set `brandKitId` on the **project** (`create_project` / `update_project`). It lives on the project, NOT on a composition op — trying to set it elsewhere is silently dropped. |
389
397
  | Shape-check (NOT quality) | `validate_composition` → `{ valid, errors[] }` (`unknown_primitive`, `invalid_primitive_params`, `clip_source_track_mismatch`, `reframe_coverage_gap`, …); does **not** check trim bounds or image-on-video-track (those fail at save/render) |
390
398
  | Look at real pixels | `preview_frame` at timestamps → PNG stills → LOOK |
@@ -261,4 +261,4 @@ frames) before declaring done.
261
261
  which is the engine's job now.
262
262
  - This recipe lives in a skill on purpose: the engine stays use-case-free; the
263
263
  product opinions (what to extract, which overlays, how to brand) live here and
264
- ship via `npx -y cueframe@0.9 install`.
264
+ ship via `npx -y cueframe@0.11 install`.
@@ -31,11 +31,11 @@ both MCP and this CLI exist so you do not have to.
31
31
 
32
32
  ## Overview
33
33
 
34
- The `cueframe` CLI drives the CueFrame platform from the terminal. Optimized for agents — every command supports `--json` (NDJSON event stream) and the binary self-describes via `npx -y cueframe@0.9 describe --json`.
34
+ The `cueframe` CLI drives the CueFrame platform from the terminal. Optimized for agents — every command supports `--json` (NDJSON event stream) and the binary self-describes via `npx -y cueframe@0.11 describe --json`.
35
35
 
36
- **Run it as `npx -y cueframe@0.9 …` — every command in this skill is written that way, and
36
+ **Run it as `npx -y cueframe@0.11 …` — every command in this skill is written that way, and
37
37
  that form is executable verbatim.** There is no `cueframe` on your PATH unless you put it
38
- there: `npx -y cueframe@0.9 install` wires the MCP server and drops these skills, but npx
38
+ there: `npx -y cueframe@0.11 install` wires the MCP server and drops these skills, but npx
39
39
  unpacks to an ephemeral cache, so it installs no binary. `npx` re-resolves the current
40
40
  version on each call (~0.5s warm, ~5s cold), which also means these commands never go
41
41
  stale. If you are running many in a row and want to skip that, `npm i -g cueframe` once
@@ -46,9 +46,9 @@ the documented path.
46
46
  **The framework is three verbs:** `upload` (register media) → `composition put` (author the timeline) → `render` (→ MP4). The `Composition` is the contract — render takes the saved composition, nothing else. Everything domain-specific (AI clip suggestions, FCPXML/Premiere export) is a **use-case on-ramp** layered on top, not part of the core.
47
47
 
48
48
  **Core principle — discover, don't guess.** Never author a composition from the
49
- examples below alone. The live contract is `npx -y cueframe@0.9 schema composition` (prints
49
+ examples below alone. The live contract is `npx -y cueframe@0.11 schema composition` (prints
50
50
  the real wire schema the server enforces); confirm any draft with
51
- `npx -y cueframe@0.9 composition validate -b @file.json` BEFORE you render. Validation is
51
+ `npx -y cueframe@0.11 composition validate -b @file.json` BEFORE you render. Validation is
52
52
  free and instant; a render is neither. The examples here are orientation — the
53
53
  schema is the source of truth.
54
54
 
@@ -70,39 +70,49 @@ delivery, not checking each edit. CLI validation does not replace visual evidenc
70
70
  # Commands run against production; auth is stored in ~/.cueframe/auth.json.
71
71
 
72
72
  # 1. Register media (one or many — mixed video / image / audio).
73
- npx -y cueframe@0.9 upload "/path/to/source.mp4" --json # → mediaItemId (process_complete)
73
+ npx -y cueframe@0.11 upload "/path/to/source.mp4" --json # → mediaItemId (process_complete)
74
74
 
75
75
  # 2. Create a project (sets aspect/format).
76
- npx -y cueframe@0.9 project create -n "promo" -a 9:16 --json # → projectId
76
+ npx -y cueframe@0.11 project create -n "promo" -a 9:16 --json # → projectId
77
77
 
78
78
  # 3. Author the composition: tracks of clips (per-clip reframe/trim), optional
79
79
  # captions (captions.segments), brandKitId. The composition is the SSOT.
80
80
  # Discover the live schema, then validate the draft BEFORE saving/rendering:
81
- npx -y cueframe@0.9 schema composition # → live wire schema
82
- npx -y cueframe@0.9 composition validate -b @composition.json # → ✓ valid | per-field errors (no render)
83
- npx -y cueframe@0.9 composition put <projectId> -b @composition.json # ETag auto
81
+ npx -y cueframe@0.11 schema composition # → live wire schema
82
+ npx -y cueframe@0.11 composition validate -b @composition.json # → ✓ valid | per-field errors (no render)
83
+ npx -y cueframe@0.11 composition get <projectId> --json # → etag (not found = no composition yet)
84
+ npx -y cueframe@0.11 composition put <projectId> -b @composition.json --if-match <etag>
85
+ # --if-match is required: a save made since your `get` fails with 409 stale_etag
86
+ # instead of being overwritten. Re-`get`, re-apply your edit, retry. Use --create
87
+ # only for the first composition of a project (refused 409 if one exists).
84
88
 
85
89
  # 4. Render the saved composition to MP4. SSE-watches + downloads when done.
86
- npx -y cueframe@0.9 render <projectId> -o ./out.mp4 --json
90
+ npx -y cueframe@0.11 render <projectId> -o ./out.mp4 --json
87
91
  # → render_queued → render_progress* → render_complete
88
92
  #
89
93
  # `render` takes ONLY a projectId and renders the SAVED composition (tracks +
90
- # captions). A clip suggestion is NOT required. Same project → same MP4 (idempotent).
94
+ # captions). A clip suggestion is NOT required. Re-running the same command on an
95
+ # unchanged composition replays the same render (the Idempotency-Key hashes the
96
+ # project, the composition ETag and the request: --aspect/--fps/--resolution/
97
+ # --priority/--intent); editing the composition or changing a flag starts a new one.
98
+ # Without --aspect it renders the composition's own format. --aspect must match the
99
+ # composition's aspect (a new aspect is a `derive_composition`, not a render flag);
100
+ # pass it with --resolution hd|fhd|4k to change only the output resolution.
91
101
  # Captions: render reads composition.captions — put caption words there to caption
92
102
  # a hand-authored composition; if absent, the clip is rendered without captions.
93
103
 
94
104
  # Reattach to an in-flight render later (e.g. after disconnect):
95
- npx -y cueframe@0.9 render watch <renderId> -p <projectId> -o ./out.mp4 --json
105
+ npx -y cueframe@0.11 render watch <renderId> -p <projectId> -o ./out.mp4 --json
96
106
  ```
97
107
 
98
108
  ## Anatomy of a composition.json
99
109
 
100
110
  This section orients you to the shape; the authoritative contract is
101
- `npx -y cueframe@0.9 schema composition` (the live wire schema) — run it when a field is
102
- unclear, and `npx -y cueframe@0.9 composition validate -b @file.json` to check a draft.
111
+ `npx -y cueframe@0.11 schema composition` (the live wire schema) — run it when a field is
112
+ unclear, and `npx -y cueframe@0.11 composition validate -b @file.json` to check a draft.
103
113
 
104
- `composition put` takes the **bare** `Composition` object (no wrapper; the CLI POSTs
105
- the `@file` verbatim and handles the ETag). Minimal valid shape:
114
+ `composition put` takes the **bare** `Composition` object (no wrapper; the CLI PUTs
115
+ the `@file` verbatim with your `--if-match` ETag). Minimal valid shape:
106
116
 
107
117
  ```json
108
118
  {
@@ -166,18 +176,18 @@ the composition yourself (above).
166
176
 
167
177
  ```bash
168
178
  # 1. Upload + chain the AI clip pass.
169
- npx -y cueframe@0.9 upload "/path/to/source.mp4" --analyze --json # mediaItemId + suggestions
170
- # (or run it explicitly: npx -y cueframe@0.9 analyze <mediaItemId> --wait --json)
179
+ npx -y cueframe@0.11 upload "/path/to/source.mp4" --analyze --json # mediaItemId + suggestions
180
+ # (or run it explicitly: npx -y cueframe@0.11 analyze <mediaItemId> --wait --json)
171
181
 
172
182
  # 2. List clip suggestions (publicId sug_…, title, startMs/endMs, score).
173
- npx -y cueframe@0.9 clips <mediaItemId> --json
183
+ npx -y cueframe@0.11 clips <mediaItemId> --json
174
184
 
175
185
  # 3. Create a project AND author its composition from the chosen suggestion.
176
- npx -y cueframe@0.9 project create -n "paul-klein-shorts" -a 9:16 --from-suggestion <sug_…> --json
177
- # (or, on an existing project: npx -y cueframe@0.9 composition from-suggestion <projectId> -s <sug_…>)
186
+ npx -y cueframe@0.11 project create -n "paul-klein-shorts" -a 9:16 --from-suggestion <sug_…> --json
187
+ # (or, on an existing project: npx -y cueframe@0.11 composition from-suggestion <projectId> -s <sug_…>)
178
188
 
179
189
  # 4. Render — same framework verb as above.
180
- npx -y cueframe@0.9 render <projectId> -o ./out.mp4 --json
190
+ npx -y cueframe@0.11 render <projectId> -o ./out.mp4 --json
181
191
  ```
182
192
 
183
193
  Both flows converge on `composition put` → `render`; the on-ramp just authors the
@@ -185,59 +195,61 @@ composition from a suggestion instead of you hand-writing it.
185
195
 
186
196
  Pipe `--json` output through `jq -c 'select(.event=="…")'` to grab specific lifecycle events.
187
197
 
188
- ## Component authoring — fork a built-in primitive or scaffold your own
198
+ ## Component authoring: scaffold your own
189
199
 
190
- Own the motion-graphics components you render (shadcn-style): fork a built-in CueFrame
191
- primitive as editable source, customize it, and render it on CueFrame — or scaffold a blank
192
- one. The source lives in your repo under version control; CueFrame bakes it to a transparent
193
- video and composites it (the shared renderer never runs your code).
200
+ Own the motion-graphics components you render (shadcn-style): scaffold a native component as
201
+ editable source, customize it, and render it on CueFrame. The source lives in your repo under
202
+ version control; CueFrame bakes it to a transparent video and composites it (the shared
203
+ renderer never runs your code). The CLI does not fork built-ins: the maintained builtin
204
+ presets and recipes are placed as they are (list them with `list_catalog`
205
+ projection `component-library`).
194
206
 
195
207
  ```bash
196
208
  # 1. Scaffold a workspace (writes cueframe.json + cueframe/components/). Idempotent.
197
- npx -y cueframe@0.9 init --json
209
+ npx -y cueframe@0.11 init --json
198
210
 
199
211
  # 2a. Scaffold a component in cueframe/components/<id>/ as owned, editable source.
200
- npx -y cueframe@0.9 new component my-badge --category ui-blocks --json
212
+ npx -y cueframe@0.11 new component my-badge --category ui-blocks --json
201
213
 
202
214
  # The scaffold is a native (version 4) source: template.html + definition.json, with its
203
- # manifest in cueframe.json. Built-in forks copy the exact template, definition and manifest.
215
+ # manifest in cueframe.json.
204
216
 
205
217
  # 3. Edit cueframe/components/<id>/template.html (one HyperFrames sub-composition ending in
206
218
  # __cfScene.mount(...)) and definition.json (inputs, defaults, timing, capabilities).
207
219
 
208
220
  # 4. Publish to CueFrame so it can render (the server admits the source or names the rule it breaks).
209
- npx -y cueframe@0.9 push my-badge --json # one component
210
- npx -y cueframe@0.9 sync --json # every component in the workspace
221
+ npx -y cueframe@0.11 push my-badge --json # one component
222
+ npx -y cueframe@0.11 sync --json # every component in the workspace
211
223
 
212
224
  # 5. Reference the component id in your composition as a {kind:'component', componentId, props}
213
225
  # clip, then render with the same verb. Preview a single component first via the MCP
214
226
  # preview_component loop.
215
- npx -y cueframe@0.9 render <projectId> -o ./out.mp4 --json
227
+ npx -y cueframe@0.11 render <projectId> -o ./out.mp4 --json
216
228
  ```
217
229
 
218
230
  ## Quick reference
219
231
 
220
232
  | Need to… | Command |
221
233
  |---|---|
222
- | See every command + flags | `npx -y cueframe@0.9 describe --json` |
223
- | Install/refresh managed skills | `npx -y cueframe@0.9 install` (shared `~/.agents/skills` and Claude `~/.claude/skills`; locally changed or untracked packages are preserved and reported) |
224
- | List projects | `npx -y cueframe@0.9 list -n 50` |
225
- | List your media | `npx -y cueframe@0.9 clips` (no mediaId arg) |
226
- | Discover the live composition schema | `npx -y cueframe@0.9 schema composition` |
227
- | Validate a draft (no save, no render) | `npx -y cueframe@0.9 composition validate -b @plan.json` |
228
- | Read composition + ETag | `npx -y cueframe@0.9 composition get <projectId> --json` |
229
- | Write composition | `npx -y cueframe@0.9 composition put <projectId> -b @plan.json` (ETag auto) |
230
- | Export to Final Cut | `npx -y cueframe@0.9 export fcpxml <projectId> -s <sug> --wait -o cut.zip` |
231
- | Export to Premiere | `npx -y cueframe@0.9 export premiere <projectId> -s <sug> --wait -o cut.zip` |
232
- | Anything not wrapped | `npx -y cueframe@0.9 api GET /v1/... -i` (escape hatch, like `gh api`) |
233
- | Validate a composition without mutating | `npx -y cueframe@0.9 composition validate -b @plan.json` |
234
+ | See every command + flags | `npx -y cueframe@0.11 describe --json` |
235
+ | Install/refresh managed skills | `npx -y cueframe@0.11 install` (shared `~/.agents/skills` and Claude `~/.claude/skills`; locally changed or untracked packages are preserved and reported) |
236
+ | List projects | `npx -y cueframe@0.11 list -n 50` |
237
+ | List your media | `npx -y cueframe@0.11 clips` (no mediaId arg) |
238
+ | Discover the live composition schema | `npx -y cueframe@0.11 schema composition` |
239
+ | Validate a draft (no save, no render) | `npx -y cueframe@0.11 composition validate -b @plan.json` |
240
+ | Read composition + ETag | `npx -y cueframe@0.11 composition get <projectId> --json` |
241
+ | Write composition | `npx -y cueframe@0.11 composition put <projectId> -b @plan.json --if-match <etag>` (`--create` for the first composition) |
242
+ | Export to Final Cut | `npx -y cueframe@0.11 export fcpxml <projectId> -s <sug> --wait -o cut.zip` |
243
+ | Export to Premiere | `npx -y cueframe@0.11 export premiere <projectId> -s <sug> --wait -o cut.zip` |
244
+ | Anything not wrapped | `npx -y cueframe@0.11 api GET /v1/... -i` (escape hatch, like `gh api`) |
245
+ | Validate a composition without mutating | `npx -y cueframe@0.11 composition validate -b @plan.json` |
234
246
 
235
247
  ## Auth
236
248
 
237
249
  Commands run against production. Authenticate once:
238
250
 
239
- - `npx -y cueframe@0.9 login` — OAuth device flow (laptops).
240
- - `npx -y cueframe@0.9 auth <cf_live_… key>` — save a static API key (CI / headless).
251
+ - `npx -y cueframe@0.11 login` — OAuth device flow (laptops).
252
+ - `npx -y cueframe@0.11 auth <cf_live_… key>` — save a static API key (CI / headless).
241
253
 
242
254
  Creds are stored in `~/.cueframe/auth.json`; the key can also come from the `CUEFRAME_API_KEY` env var.
243
255
 
@@ -255,11 +267,11 @@ Errors come as `{"event":"error", "phase":"<step>", "message":"...", "code":"...
255
267
 
256
268
  | Mistake | Reality |
257
269
  |---|---|
258
- | Reaching for `curl …/v1/...` because the CLI didn't have a command | Use `npx -y cueframe@0.9 api METHOD /v1/...` — same auth, same JSON pipeline. |
259
- | Polling for render completion with a sleep loop | `npx -y cueframe@0.9 render` already SSE-watches and exits when done. Use `render watch <id>` to reattach. |
270
+ | Reaching for `curl …/v1/...` because the CLI didn't have a command | Use `npx -y cueframe@0.11 api METHOD /v1/...` — same auth, same JSON pipeline. |
271
+ | Polling for render completion with a sleep loop | `npx -y cueframe@0.11 render` already SSE-watches and exits when done. Use `render watch <id>` to reattach. |
260
272
  | Skipping `--json` and trying to parse human output | Human output is for humans. Agents always use `--json`. |
261
- | Hand-editing the composition without an ETag | `composition put` GETs the ETag for you; `from-suggestion` rebuilds from a clip. Don't hand-craft unless you have to. |
262
- | Calling `npx -y cueframe@0.9 render <projectId> <suggestionId>` (old two-positional shape) | `render` takes ONLY a projectId; commander rejects the extra arg. It renders the SAVED composition — author it first via `composition put` (hand-author) or `project create --from-suggestion <sug>` (clip-finder on-ramp). |
273
+ | Hand-editing the composition without an ETag | `composition put` refuses without `--if-match <etag>` from the `composition get` your edit started from. Don't fetch a fresh ETag right before the put: that overwrites anyone who saved in between. `--create` is only for a project's first composition; there is no unconditional overwrite. |
274
+ | Calling `npx -y cueframe@0.11 render <projectId> <suggestionId>` (old two-positional shape) | `render` takes ONLY a projectId; commander rejects the extra arg. It renders the SAVED composition — author it first via `composition put` (hand-author) or `project create --from-suggestion <sug>` (clip-finder on-ramp). |
263
275
  | Assuming `render` needs a clip suggestion / that captions only come from a suggestion | No — `render` renders the saved composition directly; a suggestion is optional. Captions come from `composition.captions` (author them in the `put` JSON). The clip-suggestion on-ramp just fills those captions for you by slicing the transcript at author time. |
264
276
 
265
277
  ## When this skill applies (routing)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: cueframe-component-authoring
3
- description: Use when authoring, forking, or customizing a CueFrame motion-graphics component/primitive/graphic — e.g. "customize the cinematic-title primitive", "make my own animated lower-third", "fork a CueFrame template and edit it", "author a custom graphic and render it". Covers cloud MCP, local desktop, and CLI project paths using complete versioned source snapshots. Use BEFORE hand-writing a component from scratch — forking a built-in is usually the faster start.
3
+ description: Use when authoring, forking, or customizing a CueFrame motion-graphics component/primitive/graphic — e.g. "customize the parallax look", "make my own animated lower-third", "fork a CueFrame template and edit it", "author a custom graphic and render it". Covers cloud MCP, local desktop, and CLI project paths using complete versioned source snapshots. Use BEFORE hand-writing a component from scratch — forking a built-in is usually the faster start.
4
4
  ---
5
5
 
6
6
  # CueFrame component authoring (fork / customize / own)
@@ -80,14 +80,14 @@ Source lives in `cueframe/components/<id>/` (the `cueframe.json` workspace); edi
80
80
  template locally, push to render.
81
81
 
82
82
  ```bash
83
- npx -y cueframe@0.9 init --json # scaffold cueframe.json + cueframe/components/
84
- npx -y cueframe@0.9 new component my-badge --category ui-blocks --json # scaffold a component in the workspace
83
+ npx -y cueframe@0.11 init --json # scaffold cueframe.json + cueframe/components/
84
+ npx -y cueframe@0.11 new component my-badge --category ui-blocks --json # scaffold a component in the workspace
85
85
  # New scaffolds contain template.html and definition.json (native source, version 4).
86
86
  # …edit cueframe/components/<id>/template.html and definition.json in your editor…
87
- npx -y cueframe@0.9 push my-badge --json # send the native source; the server admits it
88
- # or: npx -y cueframe@0.9 sync --json # push every component in the workspace
87
+ npx -y cueframe@0.11 push my-badge --json # send the native source; the server admits it
88
+ # or: npx -y cueframe@0.11 sync --json # push every component in the workspace
89
89
  # reference the component id in your composition, then render:
90
- npx -y cueframe@0.9 render <projectId> -o ./out.mp4 --json
90
+ npx -y cueframe@0.11 render <projectId> -o ./out.mp4 --json
91
91
  ```
92
92
 
93
93
  The CLI writes `template.html` and `definition.json` (input schema, defaults, timing and
@@ -116,9 +116,9 @@ properties, then the manifest's slots).
116
116
 
117
117
  Edit the draft with `update_component_preview` (exact-text `{oldText, newText, replaceAll?}`
118
118
  edits). Check exact frames with `render_component_preview_frame`, and inspect playback for motion.
119
- `commit_component_preview` publishes the checked source to the library and pins the clip, with a
120
- fresh ETag. `read_component` and `edit_component` read and edit the library directly. Close the
121
- preview when finished.
119
+ `commit_component_preview` publishes the checked source to the library and pins the clip, and
120
+ returns the project's new ETag. `read_component` and `edit_component` read and edit the library
121
+ directly. Close the preview when finished.
122
122
 
123
123
  Media slots are image or video, declared in `component_manifest.assets` and bound to project
124
124
  media ids in `component_assets`. The template passes them to `MediaTileScene` as
@@ -56,7 +56,10 @@ before authoring custom source.
56
56
  Build/modify the working composition with the op vocabulary —
57
57
  the curated `apply_composition({ projectId, body: { ops: [...] } })`. Read
58
58
  `describe_composition_ops` for supported operations and `get_composition` for
59
- current revision and brand witnesses before editing. Op keys
59
+ current revision and brand witnesses before editing. Pass that revision as `if_match`
60
+ on every committing call. A 409 means someone saved after your read: call `get_composition`
61
+ again, rebuild your ops against what it returns, and send them with its revision. Never resend
62
+ the same ops with the 409's `currentEtag`; that overwrites a save you have not read. Op keys
60
63
  are `.strict()`: a typo'd key is rejected, not silently dropped, so read the
61
64
  error and fix the key. Reference faces from get_context in your reframe segments;
62
65
  time captions/overlays from the transcript word timings.
@@ -16,7 +16,7 @@ Read the current tool contracts and project context. Do not infer a hosted sessi
16
16
 
17
17
  Hosted calls use `projectId` and the request shape declared by the live tool. `preview_component` returns a job ID: wait with `kind:"preview"`. `preview_frame` uses `kind:"preview_frame"`. `preview_clip` returns a render job: wait with `kind:"render"`, even though it is a preview. Reuse the returned job ID; do not submit duplicate jobs while waiting. Hosted evidence jobs do not require opening or warming a compose session.
18
18
 
19
- The local component preview compiles replacement source revisions; it is not a promise of browser HMR or zero compilation work. `commit_component_preview` commits the inspected revision with a fresh project ETag. An isolated preview does not itself edit the saved timeline. Close the preview when finished if that tool is available.
19
+ The local component preview compiles replacement source revisions; it is not a promise of browser HMR or zero compilation work. `commit_component_preview` commits the inspected revision and returns the project's new ETag. An isolated preview does not itself edit the saved timeline. Close the preview when finished if that tool is available.
20
20
 
21
21
  ## Bound the work without changing the animation
22
22
 
@@ -23,7 +23,7 @@ When a required capability is missing, explain the limitation and the supported
23
23
  - **Claude.ai / Claude Desktop:** Settings → Connectors → add a custom connector with
24
24
  `https://api.cueframe.ai/v1/mcp`.
25
25
  - **Other agents (Cursor, Codex, VS Code, Windsurf, Zed, Antigravity CLI, Copilot CLI, …):**
26
- use `npx -y cueframe@0.9 install --help` to select the intended client; preserve existing configuration and avoid duplicate installs.
26
+ use `npx -y cueframe@0.11 install --help` to select the intended client; preserve existing configuration and avoid duplicate installs.
27
27
  - **ChatGPT:** the CLI cannot wire it because there is no local config to write; add
28
28
  `https://api.cueframe.ai/v1/mcp` as a custom connector instead.
29
29
  - **No account (pay per call):** connect
@@ -42,7 +42,8 @@ way. Use available read-only discovery for the selected lane:
42
42
  (`new_composition`, `apply_composition`, `validate_composition`, `create_render`) alongside
43
43
  discovery reads (`list_catalog`, `list_media`, `get_account`). There are also resources
44
44
  (`cueframe://scene-shot` for 3D product shots) and workflow prompts — a flat tool list is not
45
- the whole surface.
45
+ the whole surface. Every tool, whether it reads or writes, and the surfaces that serve it
46
+ are in the generated [tool reference](references/tools.md).
46
47
  2. **For hosted work, smoke-call `get_account` before spending.** It takes no arguments, costs nothing, and answers the questions
47
48
  worth knowing before you spend: which org the key is bound to, the plan, per-feature
48
49
  entitlements and — the one that matters — `balance`, not `included`. CueFrame is credit-funded,
@@ -0,0 +1,145 @@
1
+ # CueFrame tool reference
2
+
3
+ Generated from the @cueframe/mcp 0.11.0 catalog (commit a3fb82e59). Do not edit it by hand.
4
+
5
+ Every CueFrame tool by its catalog name. A host may show it with a connection prefix (`mcp__cueframe__get_account`, `cueframe-read__get_account`); the name after the last `__` is the catalog name. **read** tools change no state, though some are metered; **write** tools change state, and a composition write takes the revision it edits.
6
+
7
+ Hosted surfaces: `api` is the MCP server at `https://api.cueframe.ai/v1/mcp`; `editor` and `compose` are the hosted Director's editor and compose sessions. Desktop surfaces: `director` is the desktop app's agent, `plan` its planning mode, `external` an outside MCP client connected to the desktop app, and `cli` the Director running as a CLI agent such as Claude Code. A tool is callable only on the surfaces listed for it; list your host's tools for what this connection serves.
8
+
9
+ | Tool | Access | Hosted | Desktop |
10
+ | --- | --- | --- | --- |
11
+ | `analyze_transcript` | read | editor, compose | director, plan, external, cli |
12
+ | `apply_composition` | write | api, editor, compose | director, external, cli |
13
+ | `apply_template` | write | api, editor | director, external, cli |
14
+ | `cancel_compose` | write | api | - |
15
+ | `cancel_export` | write | api | - |
16
+ | `cancel_job` | write | api | - |
17
+ | `cancel_render` | write | api | - |
18
+ | `check_template` | write | - | external |
19
+ | `close_component_preview` | write | - | director, plan, external, cli |
20
+ | `close_project` | write | - | external |
21
+ | `commit_component_preview` | write | - | director, external, cli |
22
+ | `compose` | write | api | - |
23
+ | `consult` | write | api | - |
24
+ | `create_brand_kit` | write | api | - |
25
+ | `create_brief` | write | api | - |
26
+ | `create_checkout` | write | api | - |
27
+ | `create_component` | write | api, editor, compose | director, external, cli |
28
+ | `create_project` | write | api | external |
29
+ | `create_render` | write | api, editor, compose | director, external, cli |
30
+ | `create_upload` | write | api | - |
31
+ | `create_webhook` | write | api | - |
32
+ | `delete_brief` | write | api | - |
33
+ | `delete_composition` | write | api | - |
34
+ | `delete_critic` | write | api | - |
35
+ | `delete_media` | write | api | - |
36
+ | `delete_project` | write | api | external |
37
+ | `delete_webhook` | write | api | - |
38
+ | `derive_composition` | write | api, editor, compose | director, external, cli |
39
+ | `describe_composition_ops` | read | api, editor, compose | director, plan, external, cli |
40
+ | `download_media` | read | api | - |
41
+ | `edit_component` | write | - | director, external, cli |
42
+ | `editorial_apply` | write | api, editor, compose | director, cli |
43
+ | `editorial_begin` | write | - | director, cli |
44
+ | `editorial_create_brief` | write | api, editor, compose | - |
45
+ | `editorial_create_run` | write | api, editor, compose | - |
46
+ | `editorial_findings_append` | write | api, editor, compose | director, cli |
47
+ | `editorial_findings_list` | read | api, editor, compose | director, plan, cli |
48
+ | `editorial_get_run` | read | api, editor, compose | director, plan, cli |
49
+ | `editorial_inspect_audio` | write | api, editor, compose | director, cli |
50
+ | `editorial_inspect_source` | write | api, editor, compose | director, cli |
51
+ | `editorial_inspect_transcript` | write | api, editor, compose | director, cli |
52
+ | `editorial_integrate` | write | api, editor, compose | director, cli |
53
+ | `editorial_list_briefs` | read | api, editor, compose | director, plan, cli |
54
+ | `editorial_list_evidence` | read | api, editor, compose | director, plan, cli |
55
+ | `editorial_list_runs` | read | api, editor, compose | director, plan, cli |
56
+ | `editorial_run_source` | read | api, editor, compose | - |
57
+ | `editorial_sample_motion` | write | api, editor, compose | director, cli |
58
+ | `export_project` | write | - | external |
59
+ | `extract_brand_kit` | write | api | - |
60
+ | `finalize_upload` | write | api | - |
61
+ | `forget_taste` | write | api, editor, compose | director, external, cli |
62
+ | `generate_media` | write | api, editor, compose | director, external, cli |
63
+ | `get_account` | read | api, editor, compose | director, plan, external, cli |
64
+ | `get_app_state` | read | - | director, plan, external, cli |
65
+ | `get_brief` | read | api | - |
66
+ | `get_checkpoint` | read | api | - |
67
+ | `get_component_source` | read | api, editor, compose | director, plan, external, cli |
68
+ | `get_composition` | read | api, editor, compose | director, plan, external, cli |
69
+ | `get_context` | read | editor, compose | director, plan, external, cli |
70
+ | `get_director_state` | read | - | external |
71
+ | `get_editor_state` | read | - | director, plan, external, cli |
72
+ | `get_import_status` | read | - | director, plan, external, cli |
73
+ | `get_media_context` | read | api, editor, compose | director, plan, external, cli |
74
+ | `get_media_facts` | read | api | director, plan, external, cli |
75
+ | `get_profile` | read | api, editor, compose | director, plan, external, cli |
76
+ | `get_project_settings` | read | - | external |
77
+ | `get_render` | read | api | - |
78
+ | `get_scene_contract` | read | - | director, plan, external, cli |
79
+ | `get_template` | read | api, editor | director, plan, external, cli |
80
+ | `get_transcript` | read | api, editor, compose | director, plan, external, cli |
81
+ | `get_usage` | read | api, editor, compose | director, plan, external, cli |
82
+ | `import_local_media` | write | - | director, external, cli |
83
+ | `import_media` | write | api, editor, compose | director, external, cli |
84
+ | `import_resource` | write | api, editor, compose | director, external, cli |
85
+ | `install_local_person_runtime` | write | - | director, external, cli |
86
+ | `list_briefs` | read | api | - |
87
+ | `list_catalog` | read | api, editor, compose | director, plan, external, cli |
88
+ | `list_checkpoints` | read | api | - |
89
+ | `list_component_packages` | read | - | external |
90
+ | `list_compositions` | read | api | - |
91
+ | `list_critics` | read | api | - |
92
+ | `list_media` | read | api, editor, compose | director, plan, external, cli |
93
+ | `list_plans` | read | api | - |
94
+ | `list_projects` | read | api | external |
95
+ | `list_render_fonts` | read | api | - |
96
+ | `list_taste` | read | api, editor, compose | director, plan, external, cli |
97
+ | `list_templates` | read | api, editor | - |
98
+ | `new_composition` | write | api, editor, compose | director, external, cli |
99
+ | `open_component_preview` | write | - | director, plan, external, cli |
100
+ | `open_project` | write | - | external |
101
+ | `play_pause` | write | - | director, plan, external, cli |
102
+ | `prepare_component_library_previews` | write | - | external |
103
+ | `prepare_component_media` | read | - | external |
104
+ | `prepare_media` | write | api | director, external, cli |
105
+ | `preview_card` | read | api, editor, compose | - |
106
+ | `preview_clip` | write | api | - |
107
+ | `preview_component` | read | api | - |
108
+ | `preview_frame` | read | api, editor, compose | director, plan, external, cli |
109
+ | `propose_plan` | write | - | director, plan, cli |
110
+ | `publish_component` | write | - | external |
111
+ | `read_component` | read | - | director, plan, external, cli |
112
+ | `redo_edit` | write | - | external |
113
+ | `refresh_render_url` | write | api | - |
114
+ | `register_critic` | write | api | - |
115
+ | `remember_taste` | write | api, editor, compose | director, external, cli |
116
+ | `rename_project` | write | - | external |
117
+ | `render_component_preview_frame` | read | - | director, plan, external, cli |
118
+ | `repin_component` | write | api | director, external, cli |
119
+ | `resolve_builtin_component` | read | api | - |
120
+ | `resume` | write | api | - |
121
+ | `retry_render` | write | api | - |
122
+ | `save_as_template` | write | - | director, external, cli |
123
+ | `score_composition` | write | api, editor, compose | director, external, cli |
124
+ | `search_fonts` | read | api, editor, compose | director, plan, external, cli |
125
+ | `search_library` | read | editor, compose | director, plan, external, cli |
126
+ | `search_resources` | read | api, editor, compose | director, plan, external, cli |
127
+ | `seek` | write | - | director, plan, external, cli |
128
+ | `select_candidate` | write | api | - |
129
+ | `send_director_prompt` | write | - | external |
130
+ | `set_playback_rate` | write | - | director, plan, external, cli |
131
+ | `start_template` | write | api, editor | - |
132
+ | `submit_plan` | write | - | director, plan, cli |
133
+ | `suggest_briefs` | write | api | - |
134
+ | `undo_edit` | write | - | external |
135
+ | `update_brief` | write | api | - |
136
+ | `update_component` | write | api | - |
137
+ | `update_component_preview` | write | - | director, plan, external, cli |
138
+ | `update_project` | write | api | - |
139
+ | `update_project_settings` | write | - | external |
140
+ | `update_webhook` | write | api | - |
141
+ | `validate_composition` | read | api, editor, compose | director, plan, external, cli |
142
+ | `verify_webhook` | write | api | - |
143
+ | `view_asset` | read | - | director, plan, external, cli |
144
+ | `view_style_reference` | read | compose | - |
145
+ | `wait_job` | read | api, editor, compose | director, plan, external, cli |
@@ -21,7 +21,7 @@ to author, not how to transport it.
21
21
 
22
22
  **Drive the primitives over MCP if you can call tools** (`new_composition` /
23
23
  `apply_composition` / `validate_composition` / `create_render` — see the
24
- `cueframe-connect` skill for the one-line setup). The `npx -y cueframe@0.9 …` commands
24
+ `cueframe-connect` skill for the one-line setup). The `npx -y cueframe@0.11 …` commands
25
25
  written out below are the same operations for a terminal or CI job with no MCP
26
26
  host; see the `cueframe-cli` skill.
27
27
 
@@ -64,7 +64,8 @@ style's) over each window. Result → `source.reframe.segments` on the clip.
64
64
  ## 3. Compose
65
65
 
66
66
  One video track, the screen recording as a media clip carrying the reframe.
67
- `npx -y cueframe@0.9 composition put <projectId> -b @composition.json` (see `cueframe-cli`).
67
+ `npx -y cueframe@0.11 composition put <projectId> -b @composition.json --if-match <etag>`, with the
68
+ ETag from `composition get` (`--create` for the project's first composition; see `cueframe-cli`).
68
69
  Choose `-a 16:9` for landscape product video, `9:16` for social.
69
70
 
70
71
  ## 4. Polish — layer overlay primitives (this is what makes it look "produced")
@@ -101,21 +102,21 @@ check framing with `preview_frame` and click/zoom timing with an affected-window
101
102
  For a small revision, verify that change and relevant regressions without exporting the whole film.
102
103
  When delivering the finished video:
103
104
 
104
- `npx -y cueframe@0.9 render <projectId> -o out.mp4 --json`. Verify the output (ffprobe +
105
+ `npx -y cueframe@0.11 render <projectId> -o out.mp4 --json`. Verify the output (ffprobe +
105
106
  sample frames) before declaring done.
106
107
 
107
108
  ## Worked examples — composition JSON
108
109
 
109
110
  These are **orientation, not the contract.** The live wire schema is
110
- `npx -y cueframe@0.9 schema composition`, and the way to know a draft is correct is
111
- `npx -y cueframe@0.9 composition validate -b @composition.json` — it runs the same
111
+ `npx -y cueframe@0.11 schema composition`, and the way to know a draft is correct is
112
+ `npx -y cueframe@0.11 composition validate -b @composition.json` — it runs the same
112
113
  validator the server enforces, with no save and no render. Discover + validate
113
114
  before you render; never spend a render to find a schema mistake.
114
115
 
115
116
  Each block below is a complete `@composition.json` (the bare object `composition put`
116
117
  accepts: top-level `v`, `format`, `tracks`, optional `captions`). All five validate
117
118
  against the real wire schema + save invariants (swap the `<…MediaId>` placeholders for
118
- real `npx -y cueframe@0.9 upload` ids). Conventions that keep them valid:
119
+ real `npx -y cueframe@0.11 upload` ids). Conventions that keep them valid:
119
120
 
120
121
  - Tracks hold **`contents`** (not `clips`); each clip wraps a `source`.
121
122
  - A clip's `source.kind` must match the track `kind`: `media` → `video`/`image`/`audio`
@@ -297,4 +298,4 @@ Talking-head with an `active-speaker` reframe and a `heroText` title at `zPlane:
297
298
  background. See EX3 / EX4 below.
298
299
  - This recipe lives in a skill on purpose: the engine stays use-case-free; the
299
300
  product opinions (style, which primitives, layout) live here and ship via
300
- `npx -y cueframe@0.9 install`. Add sibling recipes (`cueframe-podcast-clip`, …) the same way.
301
+ `npx -y cueframe@0.11 install`. Add sibling recipes (`cueframe-podcast-clip`, …) the same way.