cueframe 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyze-4EZTZEAG.js +2 -0
- package/dist/chunk-3QSA3EBY.js +2 -0
- package/dist/chunk-4FMFWW74.js +12 -0
- package/dist/cueframe.js +35 -31
- package/dist/supportedAgents.js +2 -0
- package/package.json +4 -3
- package/skills/add-music-bed/SKILL.md +103 -0
- package/skills/brand-reel/SKILL.md +103 -0
- package/skills/clip-a-talking-head/SKILL.md +95 -0
- package/skills/composing-video/SKILL.md +240 -16
- package/skills/cueframe-brand-demo/SKILL.md +3 -0
- package/skills/cueframe-cli/SKILL.md +1 -1
- package/skills/cueframe-component-authoring/SKILL.md +1 -1
- package/skills/cueframe-compose-loop/SKILL.md +3 -0
- package/skills/cueframe-storyboard/SKILL.md +3 -0
- package/skills/every-format-from-one-edit/SKILL.md +91 -0
- package/skills/extracting-brand-kits/SKILL.md +156 -0
- package/skills/launch-video/SKILL.md +95 -0
- package/skills/make-a-social-reel/SKILL.md +103 -0
- package/skills/rebrand-a-video/SKILL.md +99 -0
- package/skills/video-craft-standards/SKILL.md +119 -0
- package/dist/analyze-6ETMHDG5.js +0 -2
- package/dist/chunk-JHOJIRD5.js +0 -12
|
@@ -5,11 +5,13 @@ 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
|
+
> **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
|
+
|
|
8
10
|
## The one idea
|
|
9
11
|
|
|
10
|
-
CueFrame composes **real footage** into finished video, and that is its edge: it detects faces and the active speaker and reframes/punches in on them; it renders titles behind the speaker's head; it times captions to the real transcript; it grades color and renders 4K. Real footage is the strongest grounding you can give a video and CueFrame's home turf — so it is the thing to reach for FIRST and usually your highest-leverage move. But the skill's job is **any good video**, footage or not: an animated explainer,
|
|
12
|
+
CueFrame composes **real footage** into finished video, and that is its edge: it detects faces and the active speaker and reframes/punches in on them; it renders titles behind the speaker's head; it times captions to the real transcript; it grades color and renders 4K. Real footage is the strongest grounding you can give a video and CueFrame's home turf — so it is the thing to reach for FIRST and usually your highest-leverage move. But the skill's job is **any good video**, footage or not: an animated explainer, an animated concept video, a data piece. These are first-class, not a lower tier.
|
|
11
13
|
|
|
12
|
-
What separates good from slop is not "footage vs. no footage" — it is **grounded specificity vs. the generic default**. The enemy is the interchangeable filler that could belong to any video: gradient/aurora backgrounds under kinetic text, stock "AI b-roll," faked UI, unmotivated motion. The antidote is a **controlling idea** plus **grounded, specific content** — real footage, OR real UI/screen captures, OR real data, OR a *purposeful* graphic/animation that DEPICTS THIS content specifically (
|
|
14
|
+
What separates good from slop is not "footage vs. no footage" — it is **grounded specificity vs. the generic default**. The enemy is the interchangeable filler that could belong to any video: gradient/aurora backgrounds under kinetic text, stock "AI b-roll," faked UI, unmotivated motion. The antidote is a **controlling idea** plus **grounded, specific content** — real footage, OR real UI/screen captures, OR real data, OR a *purposeful* graphic/animation that DEPICTS THIS content specifically (an authored diagram of the actual mechanism, a data animation of the real numbers) — a data/mechanism visual, NOT animated copy. Animated/kinetic TEXT by itself is not grounding. A well-crafted animated explainer built on diagrams of the real mechanism is grounded and good; it is not slop.
|
|
13
15
|
|
|
14
16
|
**Generic default ⇒ slop. Grounded specificity ⇒ good.** Real footage is the strongest grounding and CueFrame's home turf — reach for it first — but purposeful, specific graphics count too. This is a mechanical prediction, not a taste call (see *Craft principles*). Your single most expensive mistake is walking past real footage that exists to build generic gradient slides instead — which is precisely what happened in the SIA case below.
|
|
15
17
|
|
|
@@ -76,15 +78,15 @@ Real footage is the strongest grounding and CueFrame's edge, so hunt for it FIRS
|
|
|
76
78
|
In the SIA case, step 2 alone would have surfaced the founders-to-camera launch video and changed everything. Footage is the highest-leverage grounding; don't walk past it.
|
|
77
79
|
|
|
78
80
|
**3b. The stop fires only when the plan is GENERIC filler.** If your plan has no grounded content — no footage, no real UI/data, no purposeful content-specific graphic, just a gradient with kinetic text — STOP and say so, verbatim, before rendering anything:
|
|
79
|
-
> *"This has no grounded content — it's a gradient-and-text motion piece, the generic default, not a video composed from the real thing. I recommend we ground it in [a 30-second founder to-camera clip / a real screen capture /
|
|
81
|
+
> *"This has no grounded content — it's a gradient-and-text motion piece, the generic default, not a video composed from the real thing. I recommend we ground it in [a 30-second founder to-camera clip / a real screen capture / an authored diagram of the actual mechanism]. Want to proceed as generic motion-graphics, or ground it first?"*
|
|
80
82
|
|
|
81
|
-
Proceed only on an explicit "proceed." A *purposeful, specific* animation —
|
|
83
|
+
Proceed only on an explicit "proceed." A *purposeful, specific* animation — an authored diagram of the real mechanism, a data animation of the real numbers — does NOT trip this stop; it is a legitimate grounded choice, not a consolation prize. The stop exists only for decorative, could-be-any-video filler. Silent generic slop is the failure; a stated, chosen tradeoff is fine.
|
|
82
84
|
|
|
83
85
|
**3c. The grounding ladder** (strongest first; every rung is legitimate except the last — degrade the *promise*, never the craft):
|
|
84
86
|
1. **Real footage** — `import_media` a founder clip, event recording, or demo. The strongest grounding and CueFrame's home turf.
|
|
85
87
|
2. **Real screen capture** — `import_media` (CueFrame cannot screen-record; that's the external Kishu client, or the user's own recording).
|
|
86
88
|
3. **Real product screenshots / photos** as held stills with **motivated** motion.
|
|
87
|
-
4. **
|
|
89
|
+
4. **Crafted graphics OF THE ACTUAL THING** — an authored `{kind:'card', html, tokens}` clip diagramming the real mechanism (process/algorithm/data viz), or a data graphic of the real numbers specific to this content, shelled with `applyMotionPreset`. A **first-class grounded path**, not a fallback — a good explainer lives here. The grounding is that it depicts THIS thing — the real mechanism, the real data — not a decorative loop; animated/kinetic TEXT by itself does not qualify.
|
|
88
90
|
5. **Generic `generate_media` texture** as a *supporting* backdrop only (a stage, a texture) — never a fake-cinematic hero, never a re-created product UI (it hallucinates specifics).
|
|
89
91
|
6. **Generic gradient-with-text** is the **last** resort and is exactly what triggers the 3b stop.
|
|
90
92
|
|
|
@@ -94,7 +96,7 @@ Do not fake the missing footage, and do not dress up generic filler as grounding
|
|
|
94
96
|
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.
|
|
95
97
|
|
|
96
98
|
### 5 — Iterate on REAL PIXELS (and prove you looked)
|
|
97
|
-
`preview_frame` PNG stills at your rubric's named timestamps — **always including t=0 and hook-end** — and **look at them**. (Sessionless
|
|
99
|
+
`preview_frame` PNG stills at your rubric's named timestamps — **always including t=0 and hook-end** — and **look at them**. (Sessionless; if a cold first call returns 409 box_warming, retry in a few seconds.)
|
|
98
100
|
|
|
99
101
|
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.
|
|
100
102
|
|
|
@@ -107,6 +109,228 @@ Fix the worst thing via `apply_composition`, re-render the affected frames, re-s
|
|
|
107
109
|
|
|
108
110
|
---
|
|
109
111
|
|
|
112
|
+
## The film spine — how graphics-led video coheres (narration first, always)
|
|
113
|
+
|
|
114
|
+
Benchmarked against a top studio launch film: a scene detector reads theirs as **one continuous 44s shot**, because nothing ever changes the whole frame at once — and its spine is a continuous voiceover whose words run word-synced along the bottom of *every* frame. A film coheres when one thing never stops; visuals are then free to change every 1–2 seconds. Build in this order:
|
|
115
|
+
|
|
116
|
+
1. **Write the narration script FIRST — it is the film.** 10–14 short sentences, one idea each (~2.2 words/sec). Do not author a single visual before the script exists. Then `generate_media { generator: "text-to-speech" }` for one continuous take, transcribe it (or measure sentence boundaries), and **cut every beat boundary to the voice** — never the reverse. A silent text-driven film forces every card to hold long enough to be *read*; that dead time is the slideshow texture. With a voice carrying the through-line, each visual is a 2–3s illustration of the phrase being spoken.
|
|
117
|
+
2. **Author the caption spine with `setCaptions`** — segments of word timings matching the VO, styled small/bottom/`plate:"none"`. The persistent word-synced line is the strongest continuity device the format has; the `caption-spine` cohesion floor flags a vo-role clip without it.
|
|
118
|
+
3. **One world.** A single background system (color, texture, light) across every beat. Chapters are tiny inline corner labels (`01 — INPUTS`) inside the flowing world — **never full-screen interstitial cards**, which hard-stop the film. No beat gets its own room (a black hook, a dark grid finale): a full-frame background change reads as a scene change, and enough of them make a slide deck.
|
|
119
|
+
4. **One part vocabulary + one recurring actor.** Everything on screen is the same part (one card/chip grammar: same radius, shadow, label style) at different densities. Pick one small element (a dot, a mark) that appears in every beat and *hands off* across cuts — end a beat with it where the next beat starts it (an exit that launches it up off-frame matched by an entrance that drops it in is a match cut).
|
|
120
|
+
5. **Exit phases, no dead holds.** Every beat's elements leave the frame during its last ~0.4s; no component ends at rest, so motion carries across every cut. No visual state holds longer than ~3s (the `static-hold` floor fires on cards/still images past 4s). Cards can carry this motion themselves now — see the motion runtime below; components (`create_component`) remain the medium for choreography beyond it.
|
|
121
|
+
6. **The falsifiable bar:** run scene detection (or imagine it) over your cut — if it finds a hard boundary at every beat, you built a deck, not a film. Sparse frames are a tell too: elements sized for a fraction of the canvas leave dead space the reference never has.
|
|
122
|
+
|
|
123
|
+
### The motion runtime — three ways anything you author can move
|
|
124
|
+
|
|
125
|
+
CSS `@keyframes`/`transition` **never animate in a render** (frames are independent
|
|
126
|
+
Chromium captures; the clock never advances). Use these instead:
|
|
127
|
+
|
|
128
|
+
1. **Card motion vars (`--cf-*`)** — every card's wrapper carries frame-driven, unitless
|
|
129
|
+
custom properties: `--cf-progress` (0→1 across the clip), `--cf-ease` (eased progress),
|
|
130
|
+
`--cf-enter` (0→1 over the first ~0.6s), `--cf-exit` (1→0 over the last ~0.6s), plus
|
|
131
|
+
`--cf-frame` / `--cf-t` / `--cf-fps` / `--cf-duration`. Author motion directly in card
|
|
132
|
+
CSS: `opacity: var(--cf-enter)`, `transform: translateY(calc((1 - var(--cf-enter)) * 40px))`,
|
|
133
|
+
an exit slide via `--cf-exit`. This satisfies rule 5's exit phases without leaving the
|
|
134
|
+
card medium — and a `preview_frame` still at time *t* shows the exact *t*-frozen state.
|
|
135
|
+
2. **`transitionIn` on any overlay clip** — `{ transitionIn: { type: "fade", duration: 0.4 } }`
|
|
136
|
+
now applies to overlay-family clips (cards, components, primitives), not just video.
|
|
137
|
+
Use it for entrances; author exits in-card via `--cf-exit`.
|
|
138
|
+
3. **`applyMotionPreset` op** — shell a static card into a live motion component in one op:
|
|
139
|
+
`{ type: "applyMotionPreset", clipId, preset }` (unknown presets are rejected with the
|
|
140
|
+
full preset list). The layout stays verbatim; the preset adds entrance/idle/exit
|
|
141
|
+
choreography. The result is a live component you can `get_component_source` and refine.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## SFX pack — the curated CC0 sound palette
|
|
146
|
+
|
|
147
|
+
CueFrame ships a **closed, versioned pack of CC0 sound effects** (40 sounds, all
|
|
148
|
+
peak-normalized). There are two ways to place them. **Automatically:** the compose
|
|
149
|
+
SFX pass binds them **deterministically** — a hit on every eligible graphic
|
|
150
|
+
entrance (family from the primitive: `impact` for hero/title, `pop` for
|
|
151
|
+
stat/value, `tick` for enumeration items), a `whoosh` on video transitions, and a
|
|
152
|
+
`riser` ending at the hero entrance — timed to the same frames as the overlay,
|
|
153
|
+
ducked under speech. **By hand:** a client author places any pack sound directly —
|
|
154
|
+
`import_resource { kind:"sfx-pack", id:"<soundId>" }` returns the org's media
|
|
155
|
+
receipt (`{ id, status:"ready" }`) for that sound, which you then drop in as a
|
|
156
|
+
normal sfx clip (`mediaId`). Idempotent per (org, soundId); an unknown soundId is
|
|
157
|
+
a loud 422. Same curated bytes either path.
|
|
158
|
+
Restraint (density caps, min spacing, speech collision) comes from the AUDIO_MIX
|
|
159
|
+
SSOT the eval floors grade with, so placement and grading can't disagree.
|
|
160
|
+
|
|
161
|
+
**Variety is a floor, not a nicety.** The `sfx-same-sound-reuse` craft floor fires
|
|
162
|
+
when a dense mix (≥6 SFX hits) draws from too small a palette — distinct sounds ÷
|
|
163
|
+
hits below **0.4**. The pack carries **≥4 distinct sounds per transient family**
|
|
164
|
+
precisely so a memoir-class film satisfies it from the pack alone; leaning every
|
|
165
|
+
hit on one sound is the tell it guards. Browse the full palette structurally on
|
|
166
|
+
`list_catalog` (the `sfx` array — `soundId`, `family`, `envelopeClass`,
|
|
167
|
+
`description`, `durationSec`).
|
|
168
|
+
|
|
169
|
+
**One palette, org sounds first.** `list_catalog` also returns an `audio` array —
|
|
170
|
+
the ONE unified sound palette: the curated packs (SFX one-shots **and** CC0 music
|
|
171
|
+
beds) unioned with THIS org's own uploads/imports (`source:"org"`) and generated
|
|
172
|
+
audio (`source:"generated"`), each entry a uniform `{ref, role, envelopeClass,
|
|
173
|
+
description, durationSec, evidence, source, license, provenance}` (music entries
|
|
174
|
+
carry `bpm`). Provenance rides every entry — pack attribution, `org-owned`, or the
|
|
175
|
+
generator + prompt. **Prefer an org sound when one fits the family/envelope class:**
|
|
176
|
+
an org that uploads its product's real UI sounds hears ITS product, not a generic
|
|
177
|
+
pack tick — the compose SFX pass does this automatically (org sound of the matching
|
|
178
|
+
envelope class beats the pack default, exactly like a brand kit overrides the
|
|
179
|
+
default font), and by hand you place an org `ref` (a `mediaId`) directly. **The
|
|
180
|
+
music tier is curated beds + a generate escape hatch:** browse the `source:"pack"`
|
|
181
|
+
`role:"music"` beds (each with `bpm` + mood, spanning slow/mid/fast) and place one
|
|
182
|
+
via `import_resource { kind:"music-pack", id:"<bedId>" }` (FREE, like sfx-pack); for
|
|
183
|
+
a bed the pack lacks, `generate_media { generator:"text-to-music" }`. Buy/curate SFX,
|
|
184
|
+
curate-or-generate music.
|
|
185
|
+
|
|
186
|
+
**Transient one-shots** (entrance hits, per-element ticks):
|
|
187
|
+
|
|
188
|
+
| family | soundIds (subtle→strong) |
|
|
189
|
+
|---|---|
|
|
190
|
+
| `tick` | `tick-soft` · `tick-toggle` · `tick-scroll` · `tick-select` · `tick-click` · `tick-mouse` · `tick-shutter` · `tick-switch` |
|
|
191
|
+
| `pop` | `pop-drop` · `pop-glass` · `pop-pluck` · `pop-drop-low` · `pop-bong` · `pop-confirm` |
|
|
192
|
+
| `impact` | `impact-generic` · `impact-soft` · `impact-tin` · `impact-metal` · `impact-wood` · `impact-firm` · `impact-punch` · `impact-bell` |
|
|
193
|
+
| `confirm` | `confirm-soft` · `confirm-chime` · `confirm-question` · `confirm-bright` |
|
|
194
|
+
| `error` | `error-soft` · `error-buzz` · `error-tone` · `error-hard` |
|
|
195
|
+
|
|
196
|
+
**Sweeps** (transitions + hero lead-in, ~0.15–1.2s):
|
|
197
|
+
|
|
198
|
+
| family | soundIds |
|
|
199
|
+
|---|---|
|
|
200
|
+
| `whoosh` | `whoosh-air` · `whoosh-whip` · `whoosh-page` · `whoosh-sweep` · `whoosh-phaser` · `whoosh-low` |
|
|
201
|
+
| `riser` | `riser-jump` · `riser-phaser` · `riser-sweep` · `riser-power` |
|
|
202
|
+
|
|
203
|
+
(The SFX pack is transient/sweep one-shots; a sustained bed is a MUSIC-role clip —
|
|
204
|
+
a curated `music-pack` bed or a `text-to-music` generation, not a pack hit; see the
|
|
205
|
+
`audio` palette above.) For a sound the pack lacks, search
|
|
206
|
+
CC0 stock at curation time via `search_resources { kind:"sfx" }` (Freesound,
|
|
207
|
+
duration-bounded) and `import_resource` it — the pack is the fast default, not the
|
|
208
|
+
ceiling. For a sound that doesn't exist anywhere, generate it:
|
|
209
|
+
`generate_media { generator: "text-to-sfx", prompt: "short bright metallic tick, fast decay, no tail" }`
|
|
210
|
+
(0.5–22s; the delivered file is envelope-checked before it goes ready).
|
|
211
|
+
|
|
212
|
+
### Audio design — how to USE sounds (canonical doctrine + our calibration)
|
|
213
|
+
|
|
214
|
+
This is established film/UI sound-design craft — Chion, Murch, Thom, and the
|
|
215
|
+
Material sound guidelines — with the numbers calibrated on our own measured films.
|
|
216
|
+
The stakes are empirical, not aesthetic: films with sound effects measure >3x higher
|
|
217
|
+
perceived immersion than without (Kock & Louven), and audio-aware models consistently
|
|
218
|
+
beat vision-only models at predicting short-video engagement (VQualA 2025) — the
|
|
219
|
+
soundtrack is a measurable share of whether anyone keeps watching.
|
|
220
|
+
|
|
221
|
+
0. **Who owns time — pick the rhythm authority FIRST.** Before any hit or bed,
|
|
222
|
+
decide what the cut serves. A film has ONE rhythm authority (word timings, beat
|
|
223
|
+
maps, and shot boundaries are the same TYPE — a temporal grid; pick which one
|
|
224
|
+
drives). **VO-driven** (a narration film): cut every beat boundary to the
|
|
225
|
+
*voice* — the film-spine rule (author the script first, then read the word grid
|
|
226
|
+
off `get_media_context` — `wordGrid.wordTimesMs`, the word onsets in ms — and
|
|
227
|
+
land each cut/caption on a word). **Music-driven** (a montage/no-VO piece): cut
|
|
228
|
+
on the *beat* — read `beatGrid` off `get_media_context` (bpm + `beatTimesMs`),
|
|
229
|
+
land cut points and transition MIDPOINTS on beats, and resolve risers exactly on
|
|
230
|
+
a downbeat/strong beat (every 4th beat from the grid start). A grid is EVIDENCE,
|
|
231
|
+
not autopilot — you choose which beats carry cuts; on-beat reads as craft,
|
|
232
|
+
off-beat as accident (synchresis, Chion). Trust `beatGrid` for cutting when its
|
|
233
|
+
`confidence` is high; a beatless bed reports low and carries no reliable grid.
|
|
234
|
+
Once you have picked the authority, **materialize its grid onto the timeline
|
|
235
|
+
with the `materializeGrid` op** (`{clipId, grid:"beat"|"word", maxMarkers?}`):
|
|
236
|
+
the server reads that clip's source grid and lands `kind:"beat"|"word"` markers
|
|
237
|
+
at the correct TIMELINE times (projected through the clip's trim/playbackRate/
|
|
238
|
+
excludedRanges — you never do the media→timeline math yourself). Then place cuts
|
|
239
|
+
and transition **midpoints** on the markers — a transition's midpoint IS the cut
|
|
240
|
+
point, so start a 0.5s transition 0.25s *before* the marker so its center lands
|
|
241
|
+
on the beat. Materialize ONCE per authority clip; re-running the op refreshes the
|
|
242
|
+
markers in place (it replaces the prior set from the same clip+grid), so re-run
|
|
243
|
+
after you retrim or restretch the clip. (`grid:"shot"` is reserved — not exposed
|
|
244
|
+
yet.)
|
|
245
|
+
|
|
246
|
+
0b. **Declare the audio's ROLE at ingest — evidence follows the declaration.**
|
|
247
|
+
Uploads/imports accept an optional `audioRole: vo|music|sfx|ambience` (finalize
|
|
248
|
+
and import bodies). Declaring it routes enrichment: `vo` → transcript + word
|
|
249
|
+
grid; `music` → `beatGrid` (detected, no prompt needed); `sfx`/`ambience` →
|
|
250
|
+
`envelope` evidence on `get_media_context` (`envelopeClass:
|
|
251
|
+
transient|sweep|ambient` + attackMs/crest stats — pick pack-style hits by
|
|
252
|
+
class, not by listening). Undeclared audio is transcribed as before, and a
|
|
253
|
+
no-speech file still comes back envelope-classed. **`ambience` is the fourth
|
|
254
|
+
role**: a bed that grounds the SPACE — it loops, sits at the bottom of the mix,
|
|
255
|
+
and HOLDS under VO (it is never ducked; only `music` ducks under speech). Use
|
|
256
|
+
ambience for room tone/atmosphere continuity across cuts (the room-changes
|
|
257
|
+
floor's natural fix), never for anything that must be *noticed*.
|
|
258
|
+
|
|
259
|
+
0c. **The engine owns the default mix — author levels only to deviate.** A clip
|
|
260
|
+
tagged with an `audioRole` but no authored `volumeDb`/`volume` is auto-staged
|
|
261
|
+
to the clarity hierarchy (VO 0 dB, sfx −6, music −16 under VO else −8,
|
|
262
|
+
ambience −22 — keeping VO ≥6 dB over the bed). An authored level always wins,
|
|
263
|
+
a role-less clip stays at unity, and authored levels that invert the hierarchy
|
|
264
|
+
(e.g. music over VO) raise a non-blocking `mix_hierarchy_inverted` warning on
|
|
265
|
+
`create_render` naming the offending clips. Tag roles and let the engine mix;
|
|
266
|
+
reach for `volumeDb` only when you intend to break the hierarchy.
|
|
267
|
+
|
|
268
|
+
0d. **A brand kit can carry a SOUND identity — set it once, it rides every
|
|
269
|
+
compose.** `create_brand_kit`'s `audio` block (echoed on `get_brand_kit` +
|
|
270
|
+
`get_profile`) holds the brand's sonic taste; every ref is a palette reference
|
|
271
|
+
(a pack `soundId` | `bedId` | an org `mediaId` from `list_catalog`'s `audio[]`).
|
|
272
|
+
Four optional fields, resolution precedence **brand > org > pack** (the audio
|
|
273
|
+
analog of how a brand FONT sits above org/pack defaults):
|
|
274
|
+
- **`sonicLogo` `{ ref, placement: intro|outro|both, offsetMs? }`** — the brand
|
|
275
|
+
signature. When the kit ALSO carries the matching bookend (`intro`/`outro`
|
|
276
|
+
bumper), compose binds an sfx-role clip at the body edge that bookend abuts
|
|
277
|
+
(intro → body start; outro → body end − logo length; `offsetMs` shifts
|
|
278
|
+
within). No matching bumper ⇒ a non-blocking `brand_sonic_logo_no_bookend`
|
|
279
|
+
advisory and nothing placed (the sonic logo is the AUDIO companion to the
|
|
280
|
+
VISUAL bookend). A `ref` that no longer resolves fails loud
|
|
281
|
+
`brand_audio_unresolvable` — re-point it or clear the sonic logo.
|
|
282
|
+
- **`uiSoundSet` `{ family → ref }`** — per-family SFX overrides (the brand's
|
|
283
|
+
own tick/pop/impact/…). Consumed by the compose SFX draw as the HIGHEST tier:
|
|
284
|
+
a family the brand overrides plays the brand's sound, everything else falls to
|
|
285
|
+
the org palette then the pack default.
|
|
286
|
+
- **`bedStyle` `{ bedId? | genre?, bpmRange? }`** and **`ambiencePreference`
|
|
287
|
+
`{ ref } | null`** — SURFACED-ONLY today: compose auto-selects neither a music
|
|
288
|
+
bed nor ambience, so these carry the brand's preference for a DRIVING agent to
|
|
289
|
+
honor when it pins/generates a bed (`brief.audio.music`) or places ambience.
|
|
290
|
+
Extraction can't hear: `extract_brand_kit` (website → colors/fonts) never fills
|
|
291
|
+
the `audio` block — set the sound identity explicitly on `create_brand_kit`.
|
|
292
|
+
|
|
293
|
+
1. **Every hit is a SYNC POINT — sound welded to a visible event.** Chion
|
|
294
|
+
(*Audio-Vision*) calls this **synchresis**: the immediate, involuntary weld the
|
|
295
|
+
brain makes between a sound and the image it lands on — that weld is where
|
|
296
|
+
"added value" comes from, and a hit with no visible cause produces none (it's
|
|
297
|
+
the audio version of unmotivated motion, slop tell #6). Bind hits to their
|
|
298
|
+
events via `anchor: { clipId, offsetMs }` so the weld survives re-edits. And
|
|
299
|
+
per Randy Thom (*Designing a Movie for Sound*): sound is a storyteller, not
|
|
300
|
+
decoration — score the moments that matter, let ordinary cuts breathe.
|
|
301
|
+
2. **Class → moment.** `transient` (tick/pop/impact/confirm/error) = entrances,
|
|
302
|
+
cuts, UI semantics — Material's sound guidelines are the reference for UI
|
|
303
|
+
semantics (each sound expresses its place in the hierarchy; decorative sound
|
|
304
|
+
used sparingly). `sweep`: whoosh = motion carrying ACROSS a cut (pair with the
|
|
305
|
+
exit→entrance handoff); riser = tension INTO a reveal — resolve exactly on the
|
|
306
|
+
downbeat, never into nothing (an unresolved riser is a broken promise).
|
|
307
|
+
3. **Density has a perceptual ceiling.** Murch (*Dense Clarity — Clear Density*):
|
|
308
|
+
the brain tracks only ~two-and-a-half simultaneous sound streams; past that,
|
|
309
|
+
individual sounds stop reading and merge into texture — his mixes convey
|
|
310
|
+
complex scenes with a FEW carefully chosen elements. Our calibration: the
|
|
311
|
+
41.6s film that beat its reference carried 9 hits; the rejected cut carried 15
|
|
312
|
+
from 3 sounds. At 6+ hits the variety floor applies (`sfx-same-sound-reuse`
|
|
313
|
+
fires below 0.4 distinct/hits).
|
|
314
|
+
4. **Hierarchy within a family** (Murch's balanced-spectrum principle + Material's
|
|
315
|
+
sound hierarchy): the pack orders soundIds subtle→strong; the biggest beat gets
|
|
316
|
+
the strong impact ONCE, everything else sits a tier down. Fifteen strong hits
|
|
317
|
+
= zero strong hits.
|
|
318
|
+
5. **Gain staging.** SFX under a music bed must READ: target the hit ~≥6 dB above
|
|
319
|
+
the bed at its transient (our measured failure: ticks 1.5 dB over bed =
|
|
320
|
+
inaudible mush). Working precedent: sfx `volumeDb: -12`, bed lower still.
|
|
321
|
+
Author sane levels and STOP — the engine masters to −14 LUFS (the streaming
|
|
322
|
+
loudness standard); never pre-compress or push peaks to compensate.
|
|
323
|
+
6. **The bed is tempo, not wallpaper.** Match bed BPM/energy to the cut rate (our
|
|
324
|
+
fast recut earned a 124 BPM driving bed; a calm film wants sparser pulse), arc
|
|
325
|
+
the energy with the narrative, and always `duck` under VO
|
|
326
|
+
(`duck: { duckDb, attackMs, releaseMs }`) — dialogue sits atop Murch's
|
|
327
|
+
encoded–embodied spectrum; sfx punctuate BETWEEN phrases, never fight words.
|
|
328
|
+
7. **Silence is a device** (Thom: quiet is the most underrated tool in the
|
|
329
|
+
soundtrack). Clean air before the first hit; a dropout before the biggest
|
|
330
|
+
reveal is worth more than any riser. If the whole film is scored, nothing is.
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
110
334
|
## Recognizing slop (the mechanism — so you can predict it, not just avoid it)
|
|
111
335
|
|
|
112
336
|
Slop is the model's most common answer to an under-specified prompt: what the path of least resistance produces once the human decision layers are removed. It has a recognizable signature *because* each missing decision compounds:
|
|
@@ -136,7 +360,7 @@ One controlling idea every clip serves · grounded content of the real thing (re
|
|
|
136
360
|
**Brief:** a product-launch video for Hexo Labs' product "SIA."
|
|
137
361
|
**What the agent shipped (slop):** ~37s of purple-gradient slides with centered kinetic text; a static mocked terminal card pretending to be SIA running; a fabricated "14x faster" (the paper said **12.4%**); zero grounded content. A clean sweep of tells #1, #3, #4, #5, #7, #10.
|
|
138
362
|
**What was sitting right there, ignored:** Hexo's own launch footage — two founders talking to camera in a nice office. *Precisely* CueFrame's home turf: `all-faces` on the two-shot / `active-speaker` on the singles, transcript-timed captions, a lower-third per founder, a color grade, a 4K render.
|
|
139
|
-
**Craft looks like (same tool, same 37s):** `import_media` the founder footage → `get_media_context` for faces + transcript → reframe to whoever is speaking → transcript-tracked captions with a legibility plate → a title behind the head → a `lower-third` naming each founder → SIA's real brand type → if a benchmark appears, the real **12.4%** with source visible, ideally over a real capture of SIA running. One idea, grounded content, motivated cuts, honest data, a payoff. (Even the no-footage version was fixable:
|
|
363
|
+
**Craft looks like (same tool, same 37s):** `import_media` the founder footage → `get_media_context` for faces + transcript → reframe to whoever is speaking → transcript-tracked captions with a legibility plate → a title behind the head → a `lower-third` naming each founder → SIA's real brand type → if a benchmark appears, the real **12.4%** with source visible, ideally over a real capture of SIA running. One idea, grounded content, motivated cuts, honest data, a payoff. (Even the no-footage version was fixable: an authored diagram of SIA's *actual* pipeline step beats a gradient — that's grounded too.)
|
|
140
364
|
|
|
141
365
|
---
|
|
142
366
|
|
|
@@ -202,8 +426,8 @@ Each playbook is a **floor**, not a template — reason above it. Every beat map
|
|
|
202
426
|
| CTA | 62–75s | ~20 | One clear next step. |
|
|
203
427
|
|
|
204
428
|
**Frameworks:** Hook → Problem → Solution → Proof → CTA. Decide the CTA first, script it last; write for the ear.
|
|
205
|
-
**A fully animated explainer is a FIRST-CLASS grounded format**, not a fallback for missing footage.
|
|
206
|
-
**Reach for:** `
|
|
429
|
+
**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."
|
|
430
|
+
**Reach for:** an authored `card` clip (your own HTML/typography, shelled with `applyMotionPreset`) 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.
|
|
207
431
|
**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).
|
|
208
432
|
**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.
|
|
209
433
|
|
|
@@ -248,15 +472,15 @@ Each playbook is a **floor**, not a template — reason above it. Every beat map
|
|
|
248
472
|
| 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). |
|
|
249
473
|
| Know where subject + speech are | `get_media_context` → face boxes per frame (with `faceId`) + transcript |
|
|
250
474
|
| 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**. |
|
|
251
|
-
| Captions that track real speech | `composition.captions.segments[].words[]` = `{text, startMs, endMs, emphasis?, annotate?: circle\|underline}` — word times in **milliseconds**.
|
|
475
|
+
| 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 have NO `zPlane`.** |
|
|
252
476
|
| Text behind the speaker's head | An `overlay` clip (a title/label primitive) with `zPlane:"behind-subject"` — NOT the caption layer. Render bakes the person matte + handles occlusion. |
|
|
253
477
|
| Name someone / label a step | `lower-third` scene from `list_catalog` |
|
|
254
478
|
| Title / closing wordmark | `cinematic-title` scene (closing, not opening) |
|
|
255
479
|
| Grade the look | `color-grade` scene/effect |
|
|
256
|
-
| Anchor an abstract mechanism | `
|
|
480
|
+
| Anchor an abstract mechanism | An authored `card` clip + `applyMotionPreset` (diagrams of the real mechanism — NOT cinematic; a first-class grounded path) |
|
|
257
481
|
| Long-form → clips | `suggest_briefs` → `wait_job(kind:"suggestions")` → `compose({ suggestionId })` |
|
|
258
482
|
| Auto-reframe to another aspect | `derive_composition` (content-aware 9:16 / 1:1 / 4:5 from a 16:9 master) |
|
|
259
|
-
| Discover what to build with | `list_catalog` — over MCP it takes **NO input params**, so the FULL catalog
|
|
483
|
+
| 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**. |
|
|
260
484
|
| 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 |
|
|
261
485
|
| 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 |
|
|
262
486
|
| 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. |
|
|
@@ -270,7 +494,7 @@ Each playbook is a **floor**, not a template — reason above it. Every beat map
|
|
|
270
494
|
|
|
271
495
|
Everything needs a `projectId` — `create_project` is step 0.
|
|
272
496
|
|
|
273
|
-
**Hard limits — respect them, don't fake around them.** No cinematic AI generation: `generate_media` is
|
|
497
|
+
**Hard limits — respect them, don't fake around them.** No cinematic AI generation: `generate_media` is limited text-to-video/text-to-image/image-to-video, plus audio: `text-to-speech` (narration VO) and `text-to-music` (instrumental bed); treat generated *visual* assets as *supporting graphics* (a diagram, a texture), never a fake-cinematic hero. No screen capture: that's Kishu (external). When the right move needs footage CueFrame can't generate, `import_media` real footage — do not synthesize a substitute. **Units trap:** `startTime`/`duration`/`trim`/reframe `startSec`/`endSec`/`ease` are **seconds**; caption word times are **milliseconds**. **Render-time fail-loud errors to expect** (render never ships a wrong frame silently): `content_anchor` (a clip's `trim` frames *different* footage than its captions show — align the trim to the captioned moment), `behind_split_unsupported` (one media used under two *different* behind-subject windows — one behind-subject window per MEDIA; to render two different behind windows of one source, import it as two separate MEDIA ITEMS (distinct mediaIds) — duplicating the same mediaId into two clips still throws), `BehindMatteUnresolved`/`TrajectoryUnresolved` (the behind/face bake found no detectable person — drop the intent or fix the source).
|
|
274
498
|
|
|
275
499
|
**Worked alignment example (the error-prone mechanic).** You want the caption emphasis to land on the founder's stressed word "faster," and the frame to punch in on the same beat. From `get_media_context`, the transcript word "faster" runs `startMs:8120, endMs:8560` (transcript/source time). **For these round numbers, assume an untrimmed clip placed at timeline 0** — then source time, timeline time, and clip-relative time all coincide. So: put that word in `captions.segments[].words[]` with `emphasis:true` at `startMs:8120`; and author reframe with `setCropIntents` as a **contiguous segment list that tiles the whole clip** — e.g. a wide segment `{startSec:0, endSec:8.12, focus:{mode:"active-speaker"}, zoom:1}` then the punch `{startSec:8.12, endSec:<clipEnd>, focus:{mode:"face",faceId:"…",shotScale:"close"}, zoom:0.8, ease:{in:0.4,out:0}}` (ms → s: 8120ms = 8.12s). A lone mid-clip segment that leaves `[0..8.12]` uncovered fails validation with `reframe_coverage_gap`.
|
|
276
500
|
|
|
@@ -304,7 +528,7 @@ These are *archetypes*, not documented cuts of specific films — reason from th
|
|
|
304
528
|
VISION (one line): the ONE controlling idea for THIS video — a value + a cause.
|
|
305
529
|
FORMAT: [product-launch | social-clip | explainer | demo | talking-head]
|
|
306
530
|
SOURCE REALITY CHECK: what GROUNDS this video (after HUNTING for footage — 3a)? Real
|
|
307
|
-
footage, real UI/data, or a purposeful content-specific graphic (e.g.
|
|
531
|
+
footage, real UI/data, or a purposeful content-specific graphic (e.g. an authored diagram
|
|
308
532
|
of the actual mechanism). If the only plan is generic filler, the 3b stop fired and
|
|
309
533
|
the user has explicitly said "proceed."
|
|
310
534
|
|
|
@@ -351,7 +575,7 @@ VISION: "Two founders who clearly believe in SIA tell you, to your face, why it'
|
|
|
351
575
|
faster — and you watch it BE faster."
|
|
352
576
|
FORMAT: talking-head + real demo (NOT slides).
|
|
353
577
|
SOURCE REALITY CHECK: HUNT (3a) → Hexo's real launch = two founders to camera → import
|
|
354
|
-
it. If no footage: a real capture of SIA running, or a first-class
|
|
578
|
+
it. If no footage: a real capture of SIA running, or a first-class authored diagram of
|
|
355
579
|
SIA's actual pipeline (grounded, not a consolation) — NOT a gradient deck. Generic
|
|
356
580
|
filler = fail.
|
|
357
581
|
|
|
@@ -431,7 +655,7 @@ Every line names a frame and asks a question a PNG can answer — is a grounded
|
|
|
431
655
|
|
|
432
656
|
0. `create_project` done; `get_account` shows the render/compose/generate calls are within plan entitlements and cost ceilings.
|
|
433
657
|
1. Vision written as one sentence (value + cause); format chosen.
|
|
434
|
-
2. Footage HUNTED (3a); if the plan is generic filler, the 3b tradeoff stated to the user and an explicit "proceed" received (a purposeful, specific graphic — e.g.
|
|
658
|
+
2. Footage HUNTED (3a); if the plan is generic filler, the 3b tradeoff stated to the user and an explicit "proceed" received (a purposeful, specific graphic — e.g. an authored diagram of the real mechanism — does NOT require the stop).
|
|
435
659
|
3. Rubric written *before* any render — named-frame must-haves, measurable thresholds (grounded content dominates the runtime; footage-based formats real-footage ≥60%), the mandatory K1–K3 (meaning preserved, phrasing adapted to your video), and written provenance for every number.
|
|
436
660
|
4. Real source imported (`list_media` shows it ready); `get_media_context` faces + transcript pulled and used for reframe + caption timing (when the piece uses footage).
|
|
437
661
|
5. Components discovered via `list_catalog` (no hand-placed hex where a built-in exists); `fixedCopy` checked so no baked text lies. Brand set via `brandKitId` on the project if a brand kit exists.
|
|
@@ -5,6 +5,9 @@ description: Use when turning a local app into a brand-consistent product demo w
|
|
|
5
5
|
|
|
6
6
|
# CueFrame — Brand demo recipe
|
|
7
7
|
|
|
8
|
+
> **Kit truth over MCP (current limits):** kit CONTENTS are not yet inspectable over MCP (`get_profile` lists names only), so `$brand:` tokens resolve blind — verify resolved fonts/colors with a `preview_frame` still, and when the kit conflicts with an explicit client spec, the spec wins (hardcode it and note the conflict). Bind kits by the SERVER id from `get_profile` (slug binding is unreliable — it can silently bind nothing); always confirm via the project response `brandKitId`.
|
|
9
|
+
|
|
10
|
+
|
|
8
11
|
A **use-case recipe** that runs end-to-end from inside the user's own project
|
|
9
12
|
folder. You (Claude) already see their code and their running app — that's the
|
|
10
13
|
unfair advantage. This skill turns that context into a brand-consistent product
|
|
@@ -157,7 +157,7 @@ video and composites it (the shared renderer never runs your code).
|
|
|
157
157
|
cueframe init --json
|
|
158
158
|
|
|
159
159
|
# 2a. FORK a built-in primitive into cueframe/components/<id>/ as owned, editable source.
|
|
160
|
-
# Discover ids from the catalog: cueframe api GET /v1/components (
|
|
160
|
+
# Discover ids from the catalog: cueframe api GET /v1/components (the live primitive catalog).
|
|
161
161
|
cueframe eject cinematic-title --json
|
|
162
162
|
|
|
163
163
|
# 2b. …or scaffold a blank custom component.
|
|
@@ -27,7 +27,7 @@ Single self-contained module per component (`create_component` takes one `tsxSou
|
|
|
27
27
|
ids from the catalog (`/v1/components`). *(Or author from scratch — skip to step 2.)*
|
|
28
28
|
2. **Author/own it:** edit the `tsxSource`, then `create_component({ componentId, tsxSource, … })`
|
|
29
29
|
to store your customized copy (origin `server-native`; if forked, `ejectedFrom` is stamped).
|
|
30
|
-
3. **Iterate (author→preview→fix):** `preview_component({ componentId, params })` (sessionless
|
|
30
|
+
3. **Iterate (author→preview→fix):** `preview_component({ componentId, params })` (sessionless; if a cold first call returns 409 box_warming, retry in a few seconds)
|
|
31
31
|
renders ONE still. A 422 `component_does_not_compile` returns the compiler error — read it, fix
|
|
32
32
|
via `update_component` (same id, in place), preview again.
|
|
33
33
|
4. **Render:** add it to a composition as an `alpha-layer` clip (`apply_composition`), then
|
|
@@ -5,6 +5,9 @@ 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
|
+
|
|
8
11
|
You are the director. CueFrame gives you hands (author), eyes (capture), and a
|
|
9
12
|
judge (verify); you supply the taste and the iteration. The engine does NOT
|
|
10
13
|
auto-compose for you here — you drive the loop and decide when it's done. Drive
|
|
@@ -5,6 +5,9 @@ description: Use BEFORE composing when starting a NEW video from scratch and you
|
|
|
5
5
|
|
|
6
6
|
# CueFrame Storyboard: brief → flow
|
|
7
7
|
|
|
8
|
+
> **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
|
+
|
|
10
|
+
|
|
8
11
|
## The one idea
|
|
9
12
|
|
|
10
13
|
**You are the planner.** You have the user, the whole conversation, the brand, and the judgment — you are
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: every-format-from-one-edit
|
|
3
|
+
description: Derives content-aware 9:16, 1:1, and 4:5 siblings from one finished composition — same edit, every platform, no re-editing. Triggers on "make this vertical too", "I need this for TikTok and LinkedIn", "every aspect ratio", "square version of this", "resize for Reels", "one video, all platforms", "port this edit to Shorts".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Every format from one edit
|
|
7
|
+
|
|
8
|
+
You finish ONE edit; you get back its siblings for every platform — 9:16 for
|
|
9
|
+
Reels/TikTok/Shorts, 1:1 and 4:5 for feeds — derived content-aware from the master,
|
|
10
|
+
subject-tracked rather than letterboxed, each judged and rendered on its own. The edit decisions
|
|
11
|
+
are made once; the formats are a job, not a re-edit.
|
|
12
|
+
|
|
13
|
+
## Before you start
|
|
14
|
+
|
|
15
|
+
Confirm which master and which target platforms before setup. When the first tool call
|
|
16
|
+
approaches and CueFrame isn't connected:
|
|
17
|
+
|
|
18
|
+
- **Claude Code:** offer to run
|
|
19
|
+
`claude mcp add --transport http cueframe https://api.cueframe.ai/v1/mcp` — browser OAuth,
|
|
20
|
+
one **Allow** click.
|
|
21
|
+
- **Claude.ai / Claude Desktop:** Settings → Connectors → add a custom connector with
|
|
22
|
+
`https://api.cueframe.ai/v1/mcp`.
|
|
23
|
+
- **Other agents:** paste `set up https://cueframe.ai/skill.md`, or run
|
|
24
|
+
`npx -y cueframe install`.
|
|
25
|
+
|
|
26
|
+
Then straight to deriving — this whole job is minutes when the master is good.
|
|
27
|
+
|
|
28
|
+
## Inputs
|
|
29
|
+
|
|
30
|
+
- **The master composition** (required): a finished, approved edit — find it via
|
|
31
|
+
`list_compositions` if the user doesn't have the id. If the master isn't done, finish it first
|
|
32
|
+
(this skill multiplies quality AND flaws).
|
|
33
|
+
- **Target aspects**: default all three siblings — 9:16, 1:1, 4:5. The documented derive lane
|
|
34
|
+
starts from a 16:9 master.
|
|
35
|
+
- **Per-platform tweaks**: default none — determinism is the point. Take an explicit ask (e.g.
|
|
36
|
+
"shorter for TikTok") as a separate edit on the derived sibling.
|
|
37
|
+
|
|
38
|
+
## Workflow
|
|
39
|
+
|
|
40
|
+
1. **Verify the master is actually done.** It passed its class checklist, its audio was
|
|
41
|
+
decided, its render was approved. Deriving from a draft ships the draft's flaws four times.
|
|
42
|
+
2. **Derive each sibling.** `derive_composition` per target aspect — the reframe is
|
|
43
|
+
content-aware: it tracks the subject into the new frame instead of letterboxing. Each
|
|
44
|
+
sibling is a real composition you can edit independently afterward; the master is never
|
|
45
|
+
touched.
|
|
46
|
+
3. **Audit every sibling on real pixels — required, not optional.** `preview_frame` each
|
|
47
|
+
sibling at t=0, hook-end, and each card's midpoint; describe each still. What to look for
|
|
48
|
+
per aspect: the subject's head fully in the vertical frame; cards and captions inside the
|
|
49
|
+
safe area (no critical copy in the outer ~8%); no beat where the tighter crop lost the thing
|
|
50
|
+
the beat exists to show.
|
|
51
|
+
4. **Fix per-sibling, surgically.** Where a crop or card misbehaves, `apply_composition` on
|
|
52
|
+
THAT sibling — nudge a `setCropIntents` segment, resize a card for the narrower frame
|
|
53
|
+
(re-shell with `applyMotionPreset` in a following call if you replace the card). Don't
|
|
54
|
+
re-edit the story; the story is the master's.
|
|
55
|
+
5. **Confirm the audio carried.** The master's decided audio — bed, ducking, beat-aligned cuts
|
|
56
|
+
(`materializeGrid` markers), or its intentional silence — rides into each sibling. Verify
|
|
57
|
+
the bed is present and the silence decision, if any, still holds; the sibling's delivery
|
|
58
|
+
note repeats it. If a sibling needs a different bed, `search_resources` honoring the brand
|
|
59
|
+
kit's `musicMood` and swap it on that sibling only.
|
|
60
|
+
6. **Judge each sibling as its own artifact.** `score_composition` per sibling with the
|
|
61
|
+
master's vision as `editorialIntent`. A 9:16 sibling is a social reel and answers to that
|
|
62
|
+
class's checklist — hook inside 2 seconds still applies in the new crop. Fix worst-first to
|
|
63
|
+
≥ 7.5.
|
|
64
|
+
7. **Render each approved sibling.** `create_render` → `wait_job (kind:"render")` per
|
|
65
|
+
composition. One final render per approval; iterate with previews.
|
|
66
|
+
|
|
67
|
+
## What good looks like
|
|
68
|
+
|
|
69
|
+
Quoted from `video-craft-standards` (cross-cutting rules — every artifact):
|
|
70
|
+
|
|
71
|
+
> **MUST** Safe-area respected: no critical copy in the outer ~8% of frame.
|
|
72
|
+
|
|
73
|
+
> **MUST** One final render per approval; iterate with previews, not renders.
|
|
74
|
+
|
|
75
|
+
> **MUST** Delivery never ends with "done": the last message carries the output link and where
|
|
76
|
+
> to find it, plus the intentional-silence note if any.
|
|
77
|
+
|
|
78
|
+
And the class rule that governs each sibling: a derived 9:16 answers to §1 (Social reel) —
|
|
79
|
+
*"**MUST (K)** The hook lands inside 2 seconds"* — a derived 16:9 to its own class. Derivation
|
|
80
|
+
changes the frame, never the bar.
|
|
81
|
+
|
|
82
|
+
## Delivering
|
|
83
|
+
|
|
84
|
+
The last message is a manifest, never "done":
|
|
85
|
+
|
|
86
|
+
- Every sibling's render link, labeled by aspect and platform, and where each lives (project +
|
|
87
|
+
composition id — the master's id too, since it stays the source of truth).
|
|
88
|
+
- The master's attribution list (it covers all siblings — same assets).
|
|
89
|
+
- The intentional-silence note, restated once, if the master chose silence.
|
|
90
|
+
- Any sibling-specific edits you made (which crop nudged, which card resized) so future master
|
|
91
|
+
edits know what to re-check after re-deriving.
|