cueframe 0.4.3 → 0.4.5
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 +41 -1
- package/dist/analyze-243KHBHH.js +2 -0
- package/dist/chunk-MCQRX24V.js +2 -0
- package/dist/chunk-YKPEHNKM.js +12 -0
- package/dist/cueframe.js +109 -40
- package/{skills → dist/skills}/add-music-bed/SKILL.md +6 -16
- package/{skills → dist/skills}/brand-reel/SKILL.md +6 -16
- package/{skills → dist/skills}/clip-a-talking-head/SKILL.md +12 -17
- package/{skills → dist/skills}/composing-video/SKILL.md +20 -8
- package/{skills → dist/skills}/cueframe-brand-demo/SKILL.md +5 -0
- package/{skills → dist/skills}/cueframe-cli/SKILL.md +26 -3
- package/dist/skills/cueframe-component-authoring/SKILL.md +167 -0
- package/{skills → dist/skills}/cueframe-compose-loop/SKILL.md +38 -30
- package/dist/skills/cueframe-compose-loop/references/preview-workflow.md +37 -0
- package/dist/skills/cueframe-connect/SKILL.md +45 -0
- package/{skills → dist/skills}/cueframe-product-video/SKILL.md +19 -2
- package/dist/skills/cueframe-scene-shot/SKILL.md +66 -0
- package/{skills → dist/skills}/cueframe-storyboard/SKILL.md +6 -1
- package/{skills → dist/skills}/every-format-from-one-edit/SKILL.md +5 -16
- package/{skills → dist/skills}/extracting-brand-kits/SKILL.md +6 -3
- package/{skills → dist/skills}/launch-video/SKILL.md +5 -16
- package/{skills → dist/skills}/make-a-social-reel/SKILL.md +5 -15
- package/{skills → dist/skills}/rebrand-a-video/SKILL.md +5 -16
- package/{skills → dist/skills}/video-craft-standards/SKILL.md +6 -0
- package/dist/supportedAgents.js +1 -1
- package/package.json +18 -15
- package/dist/analyze-4EGOBMRV.js +0 -2
- package/dist/chunk-3QSA3EBY.js +0 -2
- package/dist/chunk-QKQNZIRI.js +0 -12
- package/skills/_connect.md +0 -12
- package/skills/cueframe-component-authoring/SKILL.md +0 -68
|
@@ -20,22 +20,8 @@ cuts moved onto its beat grid. Attribution included, levels disciplined, one re-
|
|
|
20
20
|
## Before you start
|
|
21
21
|
|
|
22
22
|
Listen first — identify what audio the composition already has before proposing anything. When
|
|
23
|
-
the first tool call approaches and CueFrame isn't connected
|
|
24
|
-
|
|
25
|
-
<!-- cueframe:connect -->
|
|
26
|
-
- **Claude Code:** offer to run
|
|
27
|
-
`claude mcp add --transport http cueframe https://api.cueframe.ai/v1/mcp` — a browser
|
|
28
|
-
opens and the user clicks **Allow**. No API key.
|
|
29
|
-
- **Claude.ai / Claude Desktop:** Settings → Connectors → add a custom connector with
|
|
30
|
-
`https://api.cueframe.ai/v1/mcp`.
|
|
31
|
-
- **Other agents (Cursor, Codex, VS Code, Windsurf, Zed, Gemini CLI, Copilot CLI, …):**
|
|
32
|
-
run `npx -y cueframe install` — it detects what is on the machine and wires each one.
|
|
33
|
-
- **ChatGPT:** the CLI cannot wire it (there is no local config to write) — add
|
|
34
|
-
`https://api.cueframe.ai/v1/mcp` as a custom connector instead.
|
|
35
|
-
- **No account at all (pay-per-call):** connect
|
|
36
|
-
`https://api.cueframe.ai/v1/mcp/x402` — no sign-up, no API key; priced calls
|
|
37
|
-
settle per-call in USDC over x402 from the agent's wallet.
|
|
38
|
-
<!-- /cueframe:connect -->
|
|
23
|
+
the first tool call approaches and CueFrame isn't connected, load **`cueframe-connect`** and
|
|
24
|
+
follow it once.
|
|
39
25
|
|
|
40
26
|
Then back to the soundtrack — this is usually a one-sitting job.
|
|
41
27
|
|
|
@@ -51,6 +37,10 @@ Then back to the soundtrack — this is usually a one-sitting job.
|
|
|
51
37
|
|
|
52
38
|
## Workflow
|
|
53
39
|
|
|
40
|
+
Use `cueframe-compose-loop`'s [preview workflow](../cueframe-compose-loop/references/preview-workflow.md).
|
|
41
|
+
Listen to a scoped `preview_clip` across speech, ducking, fades, and beat changes before final
|
|
42
|
+
delivery; stills and a visual judge cannot establish the mix. Recheck visuals where cuts moved.
|
|
43
|
+
|
|
54
44
|
1. **Read the composition and its speech.** `list_compositions` / the composition body for
|
|
55
45
|
what's on the timeline; `get_media_context` for transcripts. Speech present → the voice is
|
|
56
46
|
the rhythm authority and the bed serves it. No speech → the bed IS the rhythm authority and
|
|
@@ -12,22 +12,8 @@ beat, tagline lockup — where every graphic could belong to this brand and no o
|
|
|
12
12
|
## Before you start
|
|
13
13
|
|
|
14
14
|
Talk brand first — palette, type, the one line they'd put on a poster — before any setup. When
|
|
15
|
-
the first tool call approaches and CueFrame isn't connected
|
|
16
|
-
|
|
17
|
-
<!-- cueframe:connect -->
|
|
18
|
-
- **Claude Code:** offer to run
|
|
19
|
-
`claude mcp add --transport http cueframe https://api.cueframe.ai/v1/mcp` — a browser
|
|
20
|
-
opens and the user clicks **Allow**. No API key.
|
|
21
|
-
- **Claude.ai / Claude Desktop:** Settings → Connectors → add a custom connector with
|
|
22
|
-
`https://api.cueframe.ai/v1/mcp`.
|
|
23
|
-
- **Other agents (Cursor, Codex, VS Code, Windsurf, Zed, Gemini CLI, Copilot CLI, …):**
|
|
24
|
-
run `npx -y cueframe install` — it detects what is on the machine and wires each one.
|
|
25
|
-
- **ChatGPT:** the CLI cannot wire it (there is no local config to write) — add
|
|
26
|
-
`https://api.cueframe.ai/v1/mcp` as a custom connector instead.
|
|
27
|
-
- **No account at all (pay-per-call):** connect
|
|
28
|
-
`https://api.cueframe.ai/v1/mcp/x402` — no sign-up, no API key; priced calls
|
|
29
|
-
settle per-call in USDC over x402 from the agent's wallet.
|
|
30
|
-
<!-- /cueframe:connect -->
|
|
15
|
+
the first tool call approaches and CueFrame isn't connected, load **`cueframe-connect`** and
|
|
16
|
+
follow it once.
|
|
31
17
|
|
|
32
18
|
Then pick the brand conversation back up where it paused — connection is the smallest step in
|
|
33
19
|
this job.
|
|
@@ -43,6 +29,10 @@ this job.
|
|
|
43
29
|
|
|
44
30
|
## Workflow
|
|
45
31
|
|
|
32
|
+
Use `cueframe-compose-loop`'s [preview workflow](../cueframe-compose-loop/references/preview-workflow.md)
|
|
33
|
+
for stills and motion windows. For a small revision, preserve the approved arc and inspect the
|
|
34
|
+
affected behavior and regressions; reserve full-film judging and export for the relevant review/delivery.
|
|
35
|
+
|
|
46
36
|
|
|
47
37
|
0. **Find the claim (before anything else).** Interrogate the brand/material
|
|
48
38
|
for its tension — what it believes that its category doesn't — and write
|
|
@@ -12,22 +12,8 @@ dead air, and caption every word from the real transcript.
|
|
|
12
12
|
## Before you start
|
|
13
13
|
|
|
14
14
|
Get the source URL and what "best moment" means to the user before any setup ceremony. When the
|
|
15
|
-
first tool call is close and CueFrame isn't connected
|
|
16
|
-
|
|
17
|
-
<!-- cueframe:connect -->
|
|
18
|
-
- **Claude Code:** offer to run
|
|
19
|
-
`claude mcp add --transport http cueframe https://api.cueframe.ai/v1/mcp` — a browser
|
|
20
|
-
opens and the user clicks **Allow**. No API key.
|
|
21
|
-
- **Claude.ai / Claude Desktop:** Settings → Connectors → add a custom connector with
|
|
22
|
-
`https://api.cueframe.ai/v1/mcp`.
|
|
23
|
-
- **Other agents (Cursor, Codex, VS Code, Windsurf, Zed, Gemini CLI, Copilot CLI, …):**
|
|
24
|
-
run `npx -y cueframe install` — it detects what is on the machine and wires each one.
|
|
25
|
-
- **ChatGPT:** the CLI cannot wire it (there is no local config to write) — add
|
|
26
|
-
`https://api.cueframe.ai/v1/mcp` as a custom connector instead.
|
|
27
|
-
- **No account at all (pay-per-call):** connect
|
|
28
|
-
`https://api.cueframe.ai/v1/mcp/x402` — no sign-up, no API key; priced calls
|
|
29
|
-
settle per-call in USDC over x402 from the agent's wallet.
|
|
30
|
-
<!-- /cueframe:connect -->
|
|
15
|
+
first tool call is close and CueFrame isn't connected, load **`cueframe-connect`** and follow it
|
|
16
|
+
once.
|
|
31
17
|
|
|
32
18
|
Then straight back to hunting the moment — setup is a footnote, not a phase.
|
|
33
19
|
|
|
@@ -43,6 +29,10 @@ Then straight back to hunting the moment — setup is a footnote, not a phase.
|
|
|
43
29
|
|
|
44
30
|
## Workflow
|
|
45
31
|
|
|
32
|
+
Use `cueframe-compose-loop`'s [preview workflow](../cueframe-compose-loop/references/preview-workflow.md).
|
|
33
|
+
Watch/listen across changed cuts and caption/subject motion with `preview_clip`. For a small
|
|
34
|
+
correction, retain the approved edit and check relevant regressions without automatically exporting.
|
|
35
|
+
|
|
46
36
|
1. **Import and read.** `import_media` the recording, wait for ready, then `get_media_context`
|
|
47
37
|
— the transcript with word timings and the face roster (with `faceId`s and speaking share)
|
|
48
38
|
are your whole map. For an assisted hunt, `suggest_briefs` proposes clip candidates from the
|
|
@@ -70,7 +60,12 @@ Then straight back to hunting the moment — setup is a footnote, not a phase.
|
|
|
70
60
|
from `search_resources` honoring the brand kit's `musicMood`, ducked under the voice — or
|
|
71
61
|
intentional speech-only, recorded with its reason in the delivery note. Either is fine;
|
|
72
62
|
defaulted silence is not.
|
|
73
|
-
8. **
|
|
63
|
+
8. **Prepare the subject evidence.** If `get_media_context.faces.status` is `not_detected`, call
|
|
64
|
+
`prepare_media` with `kind:"subjectTrack"` and the clip's exact SOURCE trim window; if the
|
|
65
|
+
edit has `zPlane:"behind-subject"`, prepare `kind:"matte"` for that same window. Poll
|
|
66
|
+
`get_media_facts` with kind + startSec + endSec until `exact.state:"ready"`. A flattened
|
|
67
|
+
depth title or ignored speaker crop is not preview evidence.
|
|
68
|
+
9. **Preview, judge, render once per clip.** `preview_frame` at t=0 and each cut; describe each
|
|
74
69
|
still (is the framed person the one talking? is the top of the head in frame?).
|
|
75
70
|
`score_composition` with the clip's claim as `editorialIntent`; fix worst-first to ≥ 7.5,
|
|
76
71
|
then `create_render` → `wait_job (kind:"render")`.
|
|
@@ -5,6 +5,12 @@ description: Use when an agent is asked to make ANY video with CueFrame — a pr
|
|
|
5
5
|
|
|
6
6
|
# Composing Video: craft for CueFrame
|
|
7
7
|
|
|
8
|
+
For preview selection and small revisions, use `cueframe-compose-loop`'s
|
|
9
|
+
[preview workflow](../cueframe-compose-loop/references/preview-workflow.md). Retain the approved
|
|
10
|
+
brief/rubric for a local correction; check the affected behavior and relevant regressions instead
|
|
11
|
+
of restarting the new-film method below. A diagnostic or preview-only request does not require
|
|
12
|
+
a final export or a whole-film judge pass. Explicit user scope takes precedence over craft defaults.
|
|
13
|
+
|
|
8
14
|
> **The bar:** the `video-craft-standards` skill (GET /v1/skills/video-craft-standards) defines DONE for every artifact class — per-class MUST checklists and kill criteria. Read it before composing and score against it before rendering. When this skill and that document disagree, the standards win.
|
|
9
15
|
|
|
10
16
|
## The one idea
|
|
@@ -31,6 +37,7 @@ This skill is the **craft / quality layer** for an agent driving CueFrame over t
|
|
|
31
37
|
- **`cueframe-product-video`** — the click-points → reframe-segment **auto-zoom tiling** + picture-in-picture recipe for screen demos.
|
|
32
38
|
- **`cueframe-brand-demo`** — brand-token vocabulary + auto intro/outro/logo for branded launches.
|
|
33
39
|
- **`cueframe-component-authoring`** — the full fork → preview → push loop for custom components.
|
|
40
|
+
- **`cueframe-scene-shot`** — the 3D product shot authored as JSON (a tilted page screenshot, a lit laptop/phone showing a real app screenshot, camera move, focus). Reach for it *before* hand-writing a WebGL component for a device mockup.
|
|
34
41
|
|
|
35
42
|
Loading this skill and a sibling together: this one governs *what makes the video good*; the sibling governs *how that mechanic works*.
|
|
36
43
|
|
|
@@ -95,17 +102,19 @@ Do not fake the missing footage, and do not dress up generic filler as grounding
|
|
|
95
102
|
### 4 — Author against `get_media_context`
|
|
96
103
|
When you have imported media, pull the detected **faces** (subject boxes per frame, with `faceId`s) and **transcript** before composing. Align reframe/punch-in to the faces, caption words to the transcript timing, and cut points to the speech. Discover primitives with `list_catalog` before hand-placing hex and coordinates — a built-in almost always exists.
|
|
97
104
|
|
|
105
|
+
If `faces.status` is `not_detected` and the edit uses `active-speaker`/`face` framing, call `prepare_media` with `kind:"subjectTrack"` and the clip's exact SOURCE trim window, then poll `get_media_facts` with that same kind/window until `exact.state:"ready"`. Do the same with `kind:"matte"` before sighting a `zPlane:"behind-subject"` graphic. `preview_frame` and `score_composition` fail loud when required perception is unresolved; never treat a flattened title or a static wide crop as acceptable preview evidence.
|
|
106
|
+
|
|
98
107
|
### 5 — Iterate on REAL PIXELS (and prove you looked)
|
|
99
|
-
`preview_frame` PNG stills at your rubric's named timestamps — **always including t=0 and hook-end** — and **look at them**.
|
|
108
|
+
`preview_frame` PNG stills at your rubric's named timestamps — **always including t=0 and hook-end** — and **look at them**. It queues durable capture and returns a `jobId`; call `wait_job(kind:"preview_frame")` until the evidence is terminal.
|
|
100
109
|
|
|
101
110
|
For every still, before you score it, write one literal line of what is visible: *Is there a grounded subject (real footage, real UI/data, or a purposeful content-specific graphic)? Real UI, or a styled div? Is the background mostly empty decoration? Is the text legible over what's behind it? Does any on-screen number match its written source?* If you can't describe the pixels, you did not look — render again. Score only from these descriptions, never from what you intended to author. Grade the first frame hardest: if t=0 is a bare gradient with the product name, K1 trips and you're done.
|
|
102
111
|
|
|
103
112
|
`validate_composition` only checks shape (membership, params, track-family, reframe coverage) — a pass there means nothing about quality. Judge the pixels, not the JSON.
|
|
104
113
|
|
|
105
114
|
### 6 — Get an independent second opinion, then stop
|
|
106
|
-
You grading your own render is the weak link. Call `score_composition`
|
|
115
|
+
You grading your own render is the weak link. Call `score_composition` with your VISION line as `editorialIntent` and brand facts as `brandContext`, then call `wait_job(kind:"verify")`. It renders and grades **four fixed server-side criteria** — editorial, spatial, brand, caption (0–10 each) — plus a weighted composite and a worst-first critique, **on frames it samples itself.** Your `editorialIntent` steers *what "good" means for this video*; it does **not** replace the criteria, and you cannot feed it your own rubric or pick its frames — that un-gameable sampling *is* the independence. Treat a low score on a frame you didn't choose as ground truth, not noise.
|
|
107
116
|
|
|
108
|
-
Fix the worst thing via `apply_composition`,
|
|
117
|
+
Fix the worst thing via `apply_composition`, preview the affected frames and motion, and re-score when useful. For a whole-film review, budget up to 3–5 verify passes; two no-improvement passes are a reason to stop spending and report remaining gaps (`cueframe-compose-loop` owns the convergence loop). The rubric's acceptance criteria still apply; a score around 7.5 is guidance, not permission to ship a known mismatch. Hosted preview and scoring are stateless durable jobs; there is no hosted session to close.
|
|
109
118
|
|
|
110
119
|
---
|
|
111
120
|
|
|
@@ -159,10 +168,10 @@ Chromium captures; the clock never advances). Use these instead:
|
|
|
159
168
|
2. **`transitionIn` on any overlay clip** — `{ transitionIn: { type: "fade", duration: 0.4 } }`
|
|
160
169
|
now applies to overlay-family clips (cards, components, primitives), not just video.
|
|
161
170
|
Use it for entrances; author exits in-card via `--cf-exit`.
|
|
162
|
-
3. **`applyMotionPreset` op** — shell a static card into a
|
|
171
|
+
3. **`applyMotionPreset` op** — shell a static card into a frame-driven component in one op:
|
|
163
172
|
`{ type: "applyMotionPreset", clipId, preset }` (unknown presets are rejected with the
|
|
164
173
|
full preset list). The layout stays verbatim; the preset adds entrance/idle/exit
|
|
165
|
-
choreography. The result is a
|
|
174
|
+
choreography. The result is a component you can `get_component_source` and refine.
|
|
166
175
|
|
|
167
176
|
---
|
|
168
177
|
|
|
@@ -494,10 +503,10 @@ Each playbook is a **floor**, not a template — reason above it. Every beat map
|
|
|
494
503
|
| Craft goal | Do this in CueFrame |
|
|
495
504
|
|---|---|
|
|
496
505
|
| Bring in the real thing | `import_media` — requires `url` (public https) + `filename` + `contentType` (from the fixed enum: `video/mp4`, `video/quicktime`, `image/png`, `audio/mpeg`, …). Poll `list_media` or `create_webhook` on `media.completed` (status inside: complete|failed). |
|
|
497
|
-
| Know where subject + speech are | `get_media_context` → face boxes per frame (with `faceId`) + transcript |
|
|
506
|
+
| 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. |
|
|
498
507
|
| 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**. |
|
|
499
508
|
| 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. |
|
|
500
|
-
| 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. Render resolves the person cutout
|
|
509
|
+
| 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. |
|
|
501
510
|
| Name someone / label a step | `lower-third` scene from `list_catalog` |
|
|
502
511
|
| Title / closing wordmark | `cinematic-title` scene (closing, not opening) |
|
|
503
512
|
| Grade the look | `color-grade` scene/effect |
|
|
@@ -506,11 +515,14 @@ Each playbook is a **floor**, not a template — reason above it. Every beat map
|
|
|
506
515
|
| Auto-reframe to another aspect | `derive_composition` (content-aware 9:16 / 1:1 / 4:5 from a 16:9 master) |
|
|
507
516
|
| Discover what to build with | `list_catalog` — over MCP it takes **NO input params**, so the FULL live catalog + your installed components returns, and you filter the RESULT **client-side** by `category`/`kind`/`tier`/`useCase`/`mood`/`intent`. 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**. |
|
|
508
517
|
| Own / fork a custom graphic | `get_component_source` / `create_component` (self-contained tsxSource) / `update_component` — **see `cueframe-component-authoring`** for the full fork→preview→push loop |
|
|
518
|
+
| Several cells that share space and must reflow together (feature grid, rail + fluid content, cast + type) | An authored component on `FlexLayout` from `@cueframe/animate` — tracks are **weights** (`{ weight: 0, basis: px }` = content-sized, pushes neighbours), `tracksEnd` animates the reflow per frame, `fits` per cell (`stretch`/`contain`/`cover`/`position`/`scale`/`matte`). Static PiP / split is clip `region` + `fit` instead. Never CSS-scale the layout. **See `cueframe-component-authoring`** |
|
|
509
519
|
| 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 |
|
|
510
520
|
| 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. |
|
|
511
521
|
| 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) |
|
|
512
522
|
| Look at real pixels | `preview_frame` at timestamps → PNG stills → LOOK |
|
|
513
|
-
|
|
|
523
|
+
| Judge motion or audio timing | `preview_clip` for the affected `[fromSec, toSec)` window → `wait_job(kind:"render")` → watch/listen; use matching reference timestamps |
|
|
524
|
+
| Check an isolated card | `preview_card` with its HTML and tokens; no scratch composition needed |
|
|
525
|
+
| Preview one graphic | `preview_component` (202 + jobId → `wait_job(kind:"preview")`; returns the verified artifact from the same immutable bundle used by production; compile/runtime/capability errors land on the job's failed terminal with the author-fixable message) |
|
|
514
526
|
| Independent grade (steered, un-gameable) | `score_composition` (sessionless; `editorialIntent`=your vision, `brandContext`=brand facts) → four fixed criteria + composite + worst-first critique, on frames it samples itself |
|
|
515
527
|
| Director ensemble compose | `compose` — set EXACTLY ONE of `fromComposition:true` (author from the seeded composition) or `suggestionId` (clipping path) → `wait_job(kind:"compose")` |
|
|
516
528
|
| Final MP4 | `create_render` → `wait_job(kind:"render")` or `create_webhook` on `render.completed`; `retry_render` (transient only) / `cancel_render` |
|
|
@@ -31,6 +31,11 @@ Two things make this different from `cueframe-product-video`:
|
|
|
31
31
|
Drive the primitives with the `cueframe-cli` skill and converge with
|
|
32
32
|
`cueframe-compose-loop`; this tells you *what brand-demo to author*.
|
|
33
33
|
|
|
34
|
+
Use the compose-loop [preview workflow](../cueframe-compose-loop/references/preview-workflow.md)
|
|
35
|
+
for iteration. Check brand/layout with stills and motion with `preview_clip`; a small revision
|
|
36
|
+
does not require rerunning the Director or exporting the whole film. The pipeline below is for
|
|
37
|
+
a new finished demo; choose the self-driven loop when the user has not asked for Director authoring.
|
|
38
|
+
|
|
34
39
|
## The pipeline
|
|
35
40
|
|
|
36
41
|
```
|
|
@@ -5,6 +5,23 @@ description: Use when editing, clipping, or rendering video via the CueFrame CLI
|
|
|
5
5
|
|
|
6
6
|
# CueFrame CLI
|
|
7
7
|
|
|
8
|
+
## MCP is the primary surface — read this before using the CLI
|
|
9
|
+
|
|
10
|
+
**If you are an agent that can call tools, connect to CueFrame's MCP server instead of shelling
|
|
11
|
+
out to this CLI.** MCP is the supported, maintained integration surface: it hides transport and
|
|
12
|
+
contract details, its tools are generated from the same OpenAPI SSOT the CLI is, and it is where
|
|
13
|
+
new capability lands first. The `cueframe-connect` skill owns the setup for every host
|
|
14
|
+
(Claude Code, Claude/ChatGPT connectors, Cursor/Codex/VS Code/Windsurf/Zed, and the
|
|
15
|
+
no-account pay-per-call path) — load it rather than copying a connection command from here.
|
|
16
|
+
|
|
17
|
+
**Use this CLI when MCP is not available to you:** a terminal or CI job with no MCP host, a
|
|
18
|
+
scripted batch, or a human at a shell. It is a first-class path, not a deprecated one — but it is
|
|
19
|
+
the *second* thing to reach for.
|
|
20
|
+
|
|
21
|
+
**Do not hand-roll `curl` against `/v1`.** Raw REST is the fallback beneath the fallback: it is
|
|
22
|
+
where undocumented contract edges bite (components' runtime params were discovered that way), and
|
|
23
|
+
both MCP and this CLI exist so you do not have to.
|
|
24
|
+
|
|
8
25
|
## Overview
|
|
9
26
|
|
|
10
27
|
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 describe --json`.
|
|
@@ -28,13 +45,19 @@ the real wire schema the server enforces); confirm any draft with
|
|
|
28
45
|
free and instant; a render is neither. The examples here are orientation — the
|
|
29
46
|
schema is the source of truth.
|
|
30
47
|
|
|
31
|
-
**Core principle:**
|
|
48
|
+
**Core principle:** once you are ON this path, drive everything through `cueframe` — never `curl` the v1 API around it, which invalidates the work and hides CLI bugs. (Choosing MCP over the CLI in the first place is not "going around it"; see the banner above.)
|
|
32
49
|
|
|
33
50
|
## Framework workflow (upload → compose → render)
|
|
34
51
|
|
|
35
52
|
The general path for any agent. Author the timeline yourself and render it — no
|
|
36
53
|
clip suggestion required.
|
|
37
54
|
|
|
55
|
+
For iteration, use `cueframe-compose-loop`'s [preview workflow](../cueframe-compose-loop/references/preview-workflow.md).
|
|
56
|
+
Validate first, then use `preview_card` / `preview_component` for isolated graphics,
|
|
57
|
+
`preview_frame` for composition stills, or `preview_clip` for a motion window. Use the available
|
|
58
|
+
MCP tools or the CLI's `api` escape hatch with the live request contract. Full `render` is for
|
|
59
|
+
delivery, not checking each edit. CLI validation does not replace visual evidence.
|
|
60
|
+
|
|
38
61
|
```bash
|
|
39
62
|
# 0. Always use --json for agent-driven runs (NDJSON to stdout, no spinners).
|
|
40
63
|
# Commands run against production; auth is stored in ~/.cueframe/auth.json.
|
|
@@ -174,7 +197,7 @@ npx -y cueframe new component my-badge --json
|
|
|
174
197
|
# cueframe/components/my-badge/index.tsx as your starting point.
|
|
175
198
|
|
|
176
199
|
# 3. Edit cueframe/components/<id>/ — it's standard Remotion. The component is mounted
|
|
177
|
-
# ({ durationInFrames, params }) at render;
|
|
200
|
+
# ({ durationInFrames, params, assets, render }) at render; declare its v2 manifest.
|
|
178
201
|
|
|
179
202
|
# 4. Publish to CueFrame so it can render (uploads index.tsx as the component's tsxSource).
|
|
180
203
|
npx -y cueframe push my-badge --json # one component
|
|
@@ -190,7 +213,7 @@ npx -y cueframe render <projectId> -o ./out.mp4 --json
|
|
|
190
213
|
| Need to… | Command |
|
|
191
214
|
|---|---|
|
|
192
215
|
| See every command + flags | `npx -y cueframe describe --json` |
|
|
193
|
-
|
|
|
216
|
+
| Install/refresh managed skills | `npx -y cueframe install` (shared `~/.agents/skills` and Claude `~/.claude/skills`; locally changed or untracked packages are preserved and reported) |
|
|
194
217
|
| List projects | `npx -y cueframe list -n 50` |
|
|
195
218
|
| List your media | `npx -y cueframe clips` (no mediaId arg) |
|
|
196
219
|
| Discover the live composition schema | `npx -y cueframe schema composition` |
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
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 through the same component-v2 contract. Use BEFORE hand-writing a component from scratch — forking a built-in is usually the faster start.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# CueFrame component authoring (fork / customize / own)
|
|
7
|
+
|
|
8
|
+
Use `cueframe-compose-loop`'s [preview workflow](../cueframe-compose-loop/references/preview-workflow.md)
|
|
9
|
+
to select hosted or local evidence and separate iteration from final delivery.
|
|
10
|
+
|
|
11
|
+
CueFrame ships 87 built-in motion-graphics **primitives** (titles, lower-thirds, captions,
|
|
12
|
+
effects, transitions, scenes). You can **fork any of them as editable source**, customize it,
|
|
13
|
+
and render it on CueFrame — or author a brand-new component. This is shadcn-for-video: own the
|
|
14
|
+
component code; CueFrame is the reliable engine that renders it.
|
|
15
|
+
|
|
16
|
+
**Before you hand-write 3D:** a device mockup or a screenshot floating in a lit 3D scene is a
|
|
17
|
+
**scene shot** — validated JSON with `scene.add` / `scene.update`, not a component you author.
|
|
18
|
+
See the `cueframe-scene-shot` skill and `cueframe://scene-shot`. Author a component here when
|
|
19
|
+
you need behaviour the scene contract does not express.
|
|
20
|
+
|
|
21
|
+
**The two facts that shape everything:**
|
|
22
|
+
- A component is mounted through contract v2 as
|
|
23
|
+
**`({ durationInFrames, params, assets, render }) => JSX`**. `render` contains frame, fps,
|
|
24
|
+
dimensions, deterministic seed, and color space. A from-scratch component must default-export
|
|
25
|
+
this shape; older components may ignore the added properties.
|
|
26
|
+
- Neither renderer runs authored component source in the editor process. Hosted org components are
|
|
27
|
+
baked in an isolated box. A local project compiles source in a separate headless-Chromium child
|
|
28
|
+
process, pins the immutable source version in the project, and uses that version for the editor and export.
|
|
29
|
+
|
|
30
|
+
## Path A — MCP agent (no filesystem; source lives server-side)
|
|
31
|
+
|
|
32
|
+
Single self-contained module per component (`create_component` takes one `tsxSource`).
|
|
33
|
+
|
|
34
|
+
1. **Fork a built-in:** `get_component_source(componentId: "cinematic-title")` → returns the
|
|
35
|
+
primitive's editable single-module `tsxSource` (the named component + the adapter). Discover
|
|
36
|
+
ids from the catalog (`/v1/components`). *(Or author from scratch — skip to step 2.)*
|
|
37
|
+
2. **Author/own it:** edit the `tsxSource`, declare its v2 `manifest`, then call
|
|
38
|
+
`create_component({ componentId, tsxSource, manifest, … })` to store your customer-owned copy.
|
|
39
|
+
If forked, `ejectedFrom` is stamped.
|
|
40
|
+
3. **Iterate (author→preview→fix):** `preview_component({ componentId, params })` queues a durable
|
|
41
|
+
preview and returns a `jobId`; call `wait_job(kind:"preview")`. The typed terminal result is a
|
|
42
|
+
verified artifact produced by the same bundle contract used by final render. A failed
|
|
43
|
+
`component_does_not_compile` job carries the compiler error — read it, fix via `update_component`
|
|
44
|
+
(same id, in place), and preview again.
|
|
45
|
+
Set preview duration deliberately: `durationInFrames` is not a trim window and can retime
|
|
46
|
+
duration-dependent motion. Preserve production timing; inspect the live tool's request shape.
|
|
47
|
+
4. **Check integration:** add it as an `alpha-layer` clip (`apply_composition`), then inspect
|
|
48
|
+
saved-composition stills or a scoped `preview_clip` for placement and motion. Use
|
|
49
|
+
`create_render` → `wait_job kind:"render"` when delivering a finished MP4, not per tweak.
|
|
50
|
+
|
|
51
|
+
## Path B — CLI / coding agent (customer-owned source under git)
|
|
52
|
+
|
|
53
|
+
Source lives in `cueframe/components/<id>/` (the `cueframe.json` workspace); edit locally as
|
|
54
|
+
standard Remotion, push to render.
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npx -y cueframe init --json # scaffold cueframe.json + cueframe/components/
|
|
58
|
+
npx -y cueframe new component my-badge --json # scaffold a component in the workspace
|
|
59
|
+
# to start from a built-in instead of a blank file: fetch its source with the
|
|
60
|
+
# `get_component_source` tool and paste it into cueframe/components/my-badge/index.tsx
|
|
61
|
+
# …edit cueframe/components/<id>/ in your editor (standard Remotion)…
|
|
62
|
+
npx -y cueframe push my-badge --json # upload index.tsx as the component tsxSource
|
|
63
|
+
# or: npx -y cueframe sync --json # push every component in the workspace
|
|
64
|
+
# reference the component id in your composition, then render:
|
|
65
|
+
npx -y cueframe render <projectId> -o ./out.mp4 --json
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The CLI writes a 3-file layout (`index.tsx` = renderable module + adapter; `_config.ts` + `config.ts`
|
|
69
|
+
= local workspace metadata). `push` sends `index.tsx` as the single `tsxSource` — the same shape the
|
|
70
|
+
MCP path stores. To preview before a full render, push it and use the MCP `preview_component` loop.
|
|
71
|
+
|
|
72
|
+
## Path C — Director editing a local desktop project (project-embedded source)
|
|
73
|
+
|
|
74
|
+
When `get_context` reports the project lane as local, motion does not require an account or an org
|
|
75
|
+
component. When exposed, use `open_component_preview` to compile an isolated preview,
|
|
76
|
+
`update_component_preview` to replace its source, and `render_component_preview_frame` for exact
|
|
77
|
+
frame evidence. Inspect playback for motion; `commit_component_preview` commits the checked revision
|
|
78
|
+
with a fresh ETag. Close the preview when finished. This loop does not bake a timeline video and
|
|
79
|
+
does not imply HMR: source updates still compile.
|
|
80
|
+
|
|
81
|
+
If those tools are unavailable, add/update through `apply_composition` and inspect the local
|
|
82
|
+
timeline. An inline custom overlay has this shape:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"type": "clip.add",
|
|
87
|
+
"clip": {
|
|
88
|
+
"id": "local-motion",
|
|
89
|
+
"kind": "overlay",
|
|
90
|
+
"startTime": 0,
|
|
91
|
+
"duration": 3,
|
|
92
|
+
"source": {
|
|
93
|
+
"kind": "overlay",
|
|
94
|
+
"primitiveId": "custom",
|
|
95
|
+
"params": {
|
|
96
|
+
"jsxSource": "export default function Graphic({ durationInFrames, params, assets, render }) { ... }",
|
|
97
|
+
"componentManifest": { "version": 2, "assets": {}, "graphics": { "api": "canvas2d", "required": true, "accelerationPreference": "software-allowed" }, "alphaPolicy": "requires-transparency" },
|
|
98
|
+
"componentAssets": {}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"newTrack": true
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The desktop compiles the module in an isolated child process and persists its immutable source version.
|
|
107
|
+
The timeline and final export render that exact version; no preview media is baked. A compile failure
|
|
108
|
+
refuses the whole batch and leaves the composition untouched. Use `create_component` only for a reusable
|
|
109
|
+
org-catalog component on a reachable cloud lane.
|
|
110
|
+
|
|
111
|
+
For media-backed graphics, declare each slot in `componentManifest.assets`, bind the slot to a
|
|
112
|
+
project media id in `componentAssets`, and read its request-scoped handle from `assets`. The renderer
|
|
113
|
+
localizes and hashes the file before execution. Remote URLs, undeclared assets, arbitrary filesystem
|
|
114
|
+
paths, WebGL substitution, and static/card substitution are not fallback paths.
|
|
115
|
+
|
|
116
|
+
Declare `componentManifest.alphaPolicy` explicitly: `requires-transparency` for overlays and
|
|
117
|
+
`allows-opaque` for intentional full-frame plates. Both adapters verify the same field.
|
|
118
|
+
|
|
119
|
+
Normal static imports are supported only from the runtime allowlist: React, Remotion, Three.js
|
|
120
|
+
WebGPU/TSL, React Three Fiber/Drei, Remotion Three, and CueFrame animation helpers. Use ordinary hooks,
|
|
121
|
+
loops, refs, constructors, typed arrays, canvas, and WebGPU when needed. Drive visible animation from
|
|
122
|
+
`render.frame`/`render.fps` and seed variation from `render.seed`; ambient time/randomness is refused.
|
|
123
|
+
|
|
124
|
+
## Choosing what to fork
|
|
125
|
+
The catalog (`/v1/components`) gives each primitive's `description` / `useWhen` / `tags` / `mood` /
|
|
126
|
+
`tier` / `useCase` / `examples` (example params) + `propSchema` + its source via `get_component_source`.
|
|
127
|
+
Read the spec + the code to pick a starting point. (Rendered preview thumbnails are a separate
|
|
128
|
+
follow-up — today you choose from prose + params + source, or compose+`preview_frame` to see it.)
|
|
129
|
+
|
|
130
|
+
## Layout inside a component — `FlexLayout` / `solveFlex`
|
|
131
|
+
When a graphic has several cells that must share space — a feature grid, a fixed rail beside
|
|
132
|
+
fluid content, a cast of objects next to type — don't hand-place pixels. The layout helpers
|
|
133
|
+
are in `@cueframe/animate` (on the import allowlist):
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
import { FlexLayout } from '@cueframe/animate';
|
|
137
|
+
const R = params.region ?? { x: 0, y: 0, w: 1, h: 1 };
|
|
138
|
+
<FlexLayout
|
|
139
|
+
tracks={[{ weight: 0, basis: 520 }, 1, { weight: 3, split: [1, 1] }]}
|
|
140
|
+
tracksEnd={[{ weight: 0, basis: 520 }, 1, { weight: 1, split: [2, 1] }]}
|
|
141
|
+
fits={[{ mode: 'stretch' }, { mode: 'position' }, { mode: 'matte', aspect: 1 }, { mode: 'stretch' }]}
|
|
142
|
+
gap={16} width={R.w * width} height={R.h * height}>
|
|
143
|
+
<Rail /> <Type /> <Art /> <Block />
|
|
144
|
+
</FlexLayout>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- Tracks are **weights, not pixels**; `{ weight: 0, basis: 520 }` is content-sized and pushes its
|
|
148
|
+
neighbours. Children fill the leaves depth-first (a `split` nests cells on the other axis).
|
|
149
|
+
- `tracksEnd` animates: weights ease across the clip and **every cell re-solves per frame**. A cell
|
|
150
|
+
present on only one side enters from / exits to zero. Layout is the motion — no keyframed positions.
|
|
151
|
+
- `fits`, one per leaf: `stretch | contain | cover | position | scale | matte`. `position` keeps type at
|
|
152
|
+
its natural size; `matte` clips a window instead of resizing the art.
|
|
153
|
+
- Inside a `params.region` container pass `width`/`height` = the region's pixel size so nested splits and
|
|
154
|
+
aspect fits solve against the region, not the frame. **Never CSS-`scale()` the layout** — it resamples;
|
|
155
|
+
size the container instead.
|
|
156
|
+
- 3D in the same rig: `solveFlex(tree, size, weights)` returns the boxes; `flexBoxToThree(box, size)`
|
|
157
|
+
centres a mesh under `<ThreeCanvas orthographic>` (frustum pinned 1:1 to pixels), so one canvas holds
|
|
158
|
+
every object exactly on its cell.
|
|
159
|
+
- Same inputs, same boxes everywhere: the solve is pure and yoga-backed; nothing is measured from the DOM.
|
|
160
|
+
Text is placed, not measured — declare sizes with `basis` when a cell must fit its content.
|
|
161
|
+
|
|
162
|
+
## Don't
|
|
163
|
+
- Don't expect a forked primitive to use rich named props — read `params` inside and use the explicit
|
|
164
|
+
`assets` and `render` bags for media and frame state.
|
|
165
|
+
- Don't hand-roll a graphic from zero when a built-in is close — fork it (fetch the source with
|
|
166
|
+
`get_component_source`, paste it into a `npx -y cueframe new component` scaffold) and edit.
|
|
167
|
+
- Don't `create_component` a fresh id each fix iteration — `update_component` (same id) is the loop.
|
|
@@ -5,23 +5,27 @@ description: Use when an AI agent should DRIVE CueFrame to a high-quality clip i
|
|
|
5
5
|
|
|
6
6
|
# CueFrame — Compose convergence loop
|
|
7
7
|
|
|
8
|
-
> **LANE SCOPE:** this skill is written against the DESKTOP/REST compose-session surface. Over MCP those endpoints do not exist — use the `composing-video` skill (sessionless judge/preview) instead; this document is reference for the REST lane only.
|
|
9
|
-
|
|
10
|
-
|
|
11
8
|
You are the director. CueFrame gives you hands (author), eyes (capture), and a
|
|
12
9
|
judge (verify); you supply the taste and the iteration. The engine does NOT
|
|
13
10
|
auto-compose for you here — you drive the loop and decide when it's done. Drive
|
|
14
11
|
the primitives with the `cueframe-cli` skill; this tells you *how to converge*.
|
|
15
12
|
|
|
13
|
+
Before choosing a preview or export, read [preview-workflow.md](references/preview-workflow.md).
|
|
14
|
+
It owns hosted/local routing, bounded motion evidence, and the distinction between a small edit
|
|
15
|
+
and final delivery. For a minor revision, keep the approved brief and inspect the changed behavior
|
|
16
|
+
plus relevant regressions; do not restart the full planning/judging loop below.
|
|
17
|
+
|
|
16
18
|
## The loop
|
|
17
19
|
|
|
18
20
|
```
|
|
19
|
-
get_context → author →
|
|
20
|
-
↑
|
|
21
|
-
|
|
21
|
+
get_context → author → scoped preview (look) → judge if useful
|
|
22
|
+
↑ │
|
|
23
|
+
└──────── fix the WORST criterion ──────┘ → stop → render
|
|
22
24
|
```
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
Hosted preview and scoring are durable, stateless jobs. Keep their job IDs and
|
|
27
|
+
wait for each terminal result; there is no hosted render box to open, warm, or close.
|
|
28
|
+
Use the local live-preview tools when working in a desktop project that exposes them.
|
|
25
29
|
|
|
26
30
|
## 0. Context — always first
|
|
27
31
|
|
|
@@ -44,24 +48,23 @@ are `.strict()`: a typo'd key is rejected, not silently dropped, so read the
|
|
|
44
48
|
error and fix the key. Reference faces from get_context in your reframe segments;
|
|
45
49
|
time captions/overlays from the transcript word timings.
|
|
46
50
|
|
|
47
|
-
## 2.
|
|
48
|
-
|
|
49
|
-
`POST /v1/projects/:id/compose-session` → `{ sessionId }`. Boots a warm render box
|
|
50
|
-
(~60–120s the first time). Reuse it for every capture/verify in the loop; close
|
|
51
|
-
it (`DELETE …/:sessionId`) when done — it also self-reaps at its TTL.
|
|
52
|
-
|
|
53
|
-
## 3. Capture — look at it
|
|
51
|
+
## 2. Preview — look at it
|
|
54
52
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
Use the curated `preview_frame` MCP tool, or
|
|
54
|
+
`POST /v1/projects/:id/preview-frame-jobs`, with the composition target and the
|
|
55
|
+
timestamps you need to inspect. The operation returns `{ jobId }` immediately.
|
|
56
|
+
Call `wait_job({ kind: "preview_frame", id: jobId })`, then view the image artifact
|
|
57
|
+
URLs in the successful result. Look at the beats you're unsure about: a cut, an
|
|
58
|
+
overlay entrance, or the hook. The stills are real render evidence, not continuous-motion proof.
|
|
59
|
+
Use `preview_clip` for the affected composition window to judge cuts, entrances, camera movement,
|
|
60
|
+
and audio timing; use `preview_component` or `preview_card` for isolated authoring checks.
|
|
59
61
|
|
|
60
|
-
##
|
|
62
|
+
## 3. Score it
|
|
61
63
|
|
|
62
|
-
`POST /v1/projects/:id/
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
Use `score_composition`, or `POST /v1/projects/:id/score-composition`, with the
|
|
65
|
+
composition target plus optional `editorialIntent` and `brandContext`. It returns
|
|
66
|
+
`{ jobId }`; call `wait_job({ kind: "verify", jobId })`. CueFrame's judge samples
|
|
67
|
+
the meaningful beats, renders them, and returns:
|
|
65
68
|
|
|
66
69
|
```
|
|
67
70
|
{ perCriterion: { editorial, spatial, brand, caption } each { score 0–10, critique },
|
|
@@ -83,18 +86,23 @@ You get **scores and the critique, never the rubric** — the taste is CueFrame'
|
|
|
83
86
|
Pass `editorialIntent` (your brief/hook) so editorial is graded against what you
|
|
84
87
|
meant.
|
|
85
88
|
|
|
86
|
-
##
|
|
89
|
+
## 4. Fix the worst — then re-score
|
|
87
90
|
|
|
88
91
|
Read `critique` — it names the lowest criterion first and says why. Fix **that one
|
|
89
|
-
thing** (re-author the relevant ops), then
|
|
92
|
+
thing** (re-author the relevant ops), then score again. One criterion per pass:
|
|
90
93
|
chasing all four at once thrashes. Example: editorial 4 "two subjects off-center
|
|
91
|
-
vs centered intent" → tighten the reframe onto face-0 → re-
|
|
94
|
+
vs centered intent" → tighten the reframe onto face-0 → re-score. A layout critique
|
|
95
|
+
("cramped", "unbalanced", "text crowds the art") on a component built with
|
|
96
|
+
`FlexLayout` is a `tracks` weight or `fits` change — re-author those and re-solve; never
|
|
97
|
+
nudge pixels (see `cueframe-component-authoring`).
|
|
92
98
|
|
|
93
|
-
##
|
|
99
|
+
## 5. Stop — then render
|
|
94
100
|
|
|
95
|
-
|
|
96
|
-
no-improvement passes
|
|
97
|
-
|
|
101
|
+
For a whole-film review, use **composite ≥ ~7.5** as a guide alongside the brief's actual
|
|
102
|
+
acceptance criteria. Two no-improvement passes are a reason to stop spending and report what
|
|
103
|
+
remains, not to declare a rejected result approved. Render with `create_render` only when a
|
|
104
|
+
finished video is requested or the work reaches final delivery. A scoped revision can end with
|
|
105
|
+
verified preview evidence and an explicit note that no new final export was made.
|
|
98
106
|
|
|
99
107
|
## Notes
|
|
100
108
|
|
|
@@ -102,5 +110,5 @@ the final: `createRender` (see `cueframe-cli`) → MP4.
|
|
|
102
110
|
infra (capture/render) + the judge. That's the point — you keep the orchestration.
|
|
103
111
|
- **Don't re-derive the judge or beat sampling** — verify owns both. Your job is
|
|
104
112
|
author → read scores → fix worst → repeat.
|
|
105
|
-
- **Budget the loop:** 3–5
|
|
113
|
+
- **Budget the loop:** 3–5 scoring passes is plenty for most clips. If composite
|
|
106
114
|
won't climb, the limiter is usually the source or the intent, not more passes.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Preview, iteration, and delivery
|
|
2
|
+
|
|
3
|
+
Choose the evidence for the current request. A small revision is not a new-film workflow. Preserve the approved brief, timeline, and unaffected source; inspect the affected behavior and relevant regressions. Export when the user requests a finished video or the work reaches final delivery, not after every preview or parameter edit.
|
|
4
|
+
|
|
5
|
+
## Select the available lane
|
|
6
|
+
|
|
7
|
+
Read the current tool contracts and project context. Do not infer a hosted session from a local desktop tool, or require cloud registration for a local project.
|
|
8
|
+
|
|
9
|
+
| Need | Hosted evidence | Local desktop evidence, when exposed |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| Isolated HTML card layout | `preview_card` with the card's HTML and tokens | Inspect the card in the local project |
|
|
12
|
+
| Authored component layout or motion | `preview_component`, with explicit dimensions, FPS, params, assets, and appropriate duration | `open_component_preview` → `update_component_preview`; inspect playback and `render_component_preview_frame` at exact frames |
|
|
13
|
+
| Saved composition layout and overlap | `preview_frame`, batching the needed timestamps | The local composition preview/capture tools |
|
|
14
|
+
| Cuts, entrances, camera motion, or audio timing | `preview_clip` for the affected `[fromSec, toSec)` window, including its lead-in and settle | Play/seek the affected window; capture matching frames when needed |
|
|
15
|
+
| Finished deliverable | `create_render` and verify the resulting file | The project's export path and verification of its resulting file |
|
|
16
|
+
|
|
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
|
+
|
|
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.
|
|
20
|
+
|
|
21
|
+
## Bound the work without changing the animation
|
|
22
|
+
|
|
23
|
+
- Use a component's existing params for supported changes; update its source in place only when necessary. Do not create a new component ID for each tweak.
|
|
24
|
+
- `durationInFrames` sets the component's render duration; it is **not a generic trim window**. Shortening it can retime animations normalized over duration. Preserve production timing. Use a documented component-specific offset only if it preserves that timing, or use the saved composition's `preview_clip` window. `startFrame` is not a universal preview API parameter.
|
|
25
|
+
- Preserve FPS when judging motion. Choose resolution for the question: a low-resolution motion preview may establish timing but not typography, glass edges, or final-resolution shader quality. Use appropriate stills for those details.
|
|
26
|
+
- Batch related still timestamps. Build contact sheets from returned images for inspection; a grid is a presentation of sampled frames, not proof of continuous motion. Watch the critical window as well. Listen when the change affects sound.
|
|
27
|
+
- Scope output and compute are different: a short composition preview can still trigger preparation or an alpha bake on a cache miss. Inspect progress/receipts before diagnosing cost. Do not promise instant previews, cross-job cache hits, or that every requested still requires a full bake.
|
|
28
|
+
|
|
29
|
+
## Evidence and stopping
|
|
30
|
+
|
|
31
|
+
Keep component source revision/hash, params, asset bindings, dimensions, FPS, requested frames/window, and returned artifact/job identity together. For hosted composition parity, inspect `previewed.source`, composition ID, and ETag where provided. Source can change without changing the composition ETag. Unchanged pixels outside an edit's visible frame range do not by themselves prove a stale cache.
|
|
32
|
+
|
|
33
|
+
Compare affected frames and motion with the reference at matching timestamps. Keep isolated-component proof distinct from saved-composition proof and final-export proof. For a minor edit, stop once the requested behavior and relevant regressions are checked; report the preview and explicitly say if no new final export was made.
|
|
34
|
+
|
|
35
|
+
Use `score_composition` for broader editorial/brand review when useful and within budget. Do not require repeated whole-film judging to verify a known local correction. A judge score does not override a failed acceptance criterion or the user's visual feedback.
|
|
36
|
+
|
|
37
|
+
Check account balance and current quotes before metered hosted work. Record actual job charges separately for preview, judging, and final export; separate those from agent time/token cost and from infrastructure estimates. Compare workflows only after testing equivalent changes and evidence requirements. Existing previews should be exercised before proposing new infrastructure.
|