cueframe 0.3.2 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cueframe",
3
- "version": "0.3.2",
3
+ "version": "0.4.2",
4
4
  "description": "Agent-native CLI for CueFrame \u2014 author compositions and render video from the terminal (early-access preview).",
5
5
  "keywords": [
6
6
  "cueframe",
@@ -12,9 +12,9 @@
12
12
  "ffmpeg",
13
13
  "remotion"
14
14
  ],
15
- "homepage": "https://cueframe.ai",
15
+ "homepage": "https://docs.cueframe.ai",
16
16
  "author": "CueFrame",
17
- "license": "UNLICENSED",
17
+ "license": "MIT",
18
18
  "type": "module",
19
19
  "bin": {
20
20
  "cueframe": "dist/cueframe.js"
@@ -47,11 +47,18 @@
47
47
  "prepublishOnly": "tsup"
48
48
  },
49
49
  "devDependencies": {
50
- "@cueframe/cloud-import": "workspace:*",
51
50
  "@cueframe/sdk": "workspace:*",
52
- "@cueframe/shared": "workspace:*",
53
51
  "@types/node": "^22.15.0",
54
52
  "tsup": "^8.5.1",
55
- "vitest": "^4.1.0"
53
+ "vitest": "^4.1.0",
54
+ "@cueframe/component-kit": "workspace:*"
55
+ },
56
+ "repository": {
57
+ "type": "git",
58
+ "url": "git+https://github.com/cueframe-ai/cueframe.git",
59
+ "directory": "packages/cli"
60
+ },
61
+ "bugs": {
62
+ "url": "https://github.com/cueframe-ai/cueframe/issues"
56
63
  }
57
- }
64
+ }
@@ -5,19 +5,15 @@ Not a skill: both readers skip non-directories (generate-skills.mjs checks
5
5
  `entry.isDirectory()`, install.ts checks for `<name>/SKILL.md`), so a bare file
6
6
  here is inert.
7
7
 
8
- Edit THIS file, then run:
8
+ Edit THIS file, then update every skill's `<!-- cueframe:connect -->` block to
9
+ match it — upstream regenerates the copies mechanically.
9
10
 
10
- node services/scripts/generate-skill-connect.mjs
11
+ WHY THIS EXISTS. The block used to live in seven hand-maintained copies, and one
12
+ fact stated in seven places drifts: a correction landed in some copies and not
13
+ the rest, and the untouched lines had already diverged into five phrasings of
14
+ the same step. One fact, seven copies, five versions.
11
15
 
12
- WHY THIS EXISTS. The block lived in 7 hand-maintained copies. On 2026-08-04 the
13
- landing page was corrected to stop telling non-Claude agents to paste
14
- `set up https://cueframe.ai/skill.md` (a Claude Code convention — ChatGPT replies
15
- that it does not support skills files), and all 7 skills kept saying it, because
16
- that sweep searched landing/ and docs/ and never searched packages/cli/skills/.
17
- Worse, the untouched lines had already drifted into FIVE different phrasings of
18
- the Claude Code step. One fact, seven copies, five versions.
19
-
20
- `skill-connect.drift.test.ts` fails if any copy diverges from this file.
16
+ `skillConnect.drift.test.ts` fails if any copy diverges from this file.
21
17
  -->
22
18
  - **Claude Code:** offer to run
23
19
  `claude mcp add --transport http cueframe https://api.cueframe.ai/v1/mcp` — a browser
@@ -28,3 +24,6 @@ the Claude Code step. One fact, seven copies, five versions.
28
24
  run `npx -y cueframe install` — it detects what is on the machine and wires each one.
29
25
  - **ChatGPT:** the CLI cannot wire it (there is no local config to write) — add
30
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.
@@ -32,6 +32,9 @@ the first tool call approaches and CueFrame isn't connected:
32
32
  run `npx -y cueframe install` — it detects what is on the machine and wires each one.
33
33
  - **ChatGPT:** the CLI cannot wire it (there is no local config to write) — add
34
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.
35
38
  <!-- /cueframe:connect -->
36
39
 
37
40
  Then back to the soundtrack — this is usually a one-sitting job.
@@ -24,6 +24,9 @@ the first tool call approaches and CueFrame isn't connected:
24
24
  run `npx -y cueframe install` — it detects what is on the machine and wires each one.
25
25
  - **ChatGPT:** the CLI cannot wire it (there is no local config to write) — add
26
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.
27
30
  <!-- /cueframe:connect -->
28
31
 
29
32
  Then pick the brand conversation back up where it paused — connection is the smallest step in
@@ -24,6 +24,9 @@ first tool call is close and CueFrame isn't connected:
24
24
  run `npx -y cueframe install` — it detects what is on the machine and wires each one.
25
25
  - **ChatGPT:** the CLI cannot wire it (there is no local config to write) — add
26
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.
27
30
  <!-- /cueframe:connect -->
28
31
 
29
32
  Then straight back to hunting the moment — setup is a footnote, not a phase.
@@ -13,7 +13,7 @@ CueFrame composes **real footage** into finished video, and that is its edge: it
13
13
 
14
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.
15
15
 
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.
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 launch-video case below.
17
17
 
18
18
  **The loophole to nail shut:** "purposeful graphics" means *specific to this content* — the real mechanism, the real data, a diagram of the actual thing. Animated/kinetic TEXT by itself is not that, no matter how deliberate — it is not grounding. A generic gradient or aurora is NEVER "purposeful"; it is always the slop default. The reframe broadens what counts as good; it does not wave decorative filler through.
19
19
 
@@ -40,7 +40,7 @@ Loading this skill and a sibling together: this one governs *what makes the vide
40
40
 
41
41
  Six non-negotiables. Everything below is the reasoning behind them.
42
42
 
43
- 1. **HUNT for real footage FIRST** — it's the strongest grounding and CueFrame's edge — before building without it; the SIA failure was never looking.
43
+ 1. **HUNT for real footage FIRST** — it's the strongest grounding and CueFrame's edge — before building without it; that failure was never looking.
44
44
  2. **Write a harsh, specific rubric BEFORE you render a single frame** — including the three mandatory kill criteria (K1–K3), meaning preserved.
45
45
  3. **Grounded, specific content must DOMINATE the runtime** — real footage, real UI/data, or purposeful content-specific graphics — never generic/decorative filler. (For footage-based formats, target real footage ≥60%.)
46
46
  4. **Describe every rendered still in words before you score it** — if you can't say what's in the frame, you didn't look.
@@ -54,7 +54,7 @@ Six non-negotiables. Everything below is the reasoning behind them.
54
54
  The order is the forcing function. Steps 2, 3, and 5 are where agents cut corners and ship slop, so they are not optional.
55
55
 
56
56
  ### 1 — Decide the VISION, then the FORMAT
57
- Write the controlling idea as one sentence with a value and a cause — "X wins *because* Y" (McKee, *Story*: a story is a charged value-shift, not a topic). Not "SIA launch" — a claim: "Two founders tell you, to your face, why SIA kills the pipeline step you dread — and you watch it be faster." Then pick the format floor: product-launch / social-clip / explainer / demo / talking-head (playbooks below). The vision is the filter for what belongs; anything that doesn't express it gets cut.
57
+ Write the controlling idea as one sentence with a value and a cause — "X wins *because* Y" (McKee, *Story*: a story is a charged value-shift, not a topic). Not "product launch" — a claim: "Two founders tell you, to your face, why their product kills the pipeline step you dread — and you watch it be faster." Then pick the format floor: product-launch / social-clip / explainer / demo / talking-head (playbooks below). The vision is the filter for what belongs; anything that doesn't express it gets cut.
58
58
 
59
59
  ### 2 — Write a HARSH, SPECIFIC rubric — BEFORE you render anything
60
60
  Authored against the vision, before pixels exist, so it can't be rationalized after the fact. Use the template below: must-haves anchored to named frame timestamps, measurable thresholds, and kill criteria that fail the render outright.
@@ -75,7 +75,7 @@ Real footage is the strongest grounding and CueFrame's edge, so hunt for it FIRS
75
75
  2. Does the subject (company/person/product) already have a launch video, founder clips, demo recordings, or a conference talk you can `import_media` from a public https URL?
76
76
  3. Ask the user directly: *"Do you have a founder clip, screen capture, or event recording? CueFrame is built to compose real footage — it's the difference between a launch film and a slideshow."*
77
77
 
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.
78
+ In the launch-video 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.
79
79
 
80
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:
81
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?"*
@@ -84,7 +84,7 @@ Proceed only on an explicit "proceed." A *purposeful, specific* animation — an
84
84
 
85
85
  **3c. The grounding ladder** (strongest first; every rung is legitimate except the last — degrade the *promise*, never the craft):
86
86
  1. **Real footage** — `import_media` a founder clip, event recording, or demo. The strongest grounding and CueFrame's home turf.
87
- 2. **Real screen capture** — `import_media` (CueFrame cannot screen-record; that's the external Kishu client, or the user's own recording).
87
+ 2. **Real screen capture** — `import_media` (CueFrame cannot screen-record; that needs an external screen-capture client — e.g. a headed Playwright walkthrough recorded to MP4 — or the user's own recording).
88
88
  3. **Real product screenshots / photos** as held stills with **motivated** motion.
89
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.
90
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).
@@ -120,6 +120,30 @@ Benchmarked against a top studio launch film: a scene detector reads theirs as *
120
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
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
122
 
123
+ ### The card token contract — `tokens` key `x` is read as `var(--cf-x)`
124
+
125
+ A `{kind:'card', html, tokens}` clip binds brand-swappable values through `tokens`. Each
126
+ **key** is projected onto the card's wrapper as a CSS custom property with a `--cf-`
127
+ prefix, so the html reads it back **prefixed**:
128
+
129
+ ```jsonc
130
+ { "kind": "card", "tokens": { "plate": "#0af", "fg": "$brand:colors.text" },
131
+ "html": "<div style=\"background:var(--cf-plate);color:var(--cf-fg)\">…</div>" }
132
+ ```
133
+
134
+ Values may be literals or whole-string `$brand:<path>` refs (resolved against the
135
+ project's brand kit at render).
136
+
137
+ **Do not put dashes in the key.** `tokens: {"--plate": …}` projects to `--cf---plate`, so
138
+ the card's `var(--plate)` matches nothing — and CSS treats an undefined custom property as
139
+ *invalid at computed-value time*, which means it does not error, it **degrades**:
140
+ `background` falls back to transparent and `color` inherits (usually black). The render
141
+ succeeds and the graphic is unreadable. `apply_composition` returns `warnings[]` when it
142
+ catches this, but the fix is to never write the dashes.
143
+
144
+ Two `--cf-*` families share the wrapper: **your token vars** (above) and the **motion
145
+ vars** below, which are always injected and are not yours to declare.
146
+
123
147
  ### The motion runtime — three ways anything you author can move
124
148
 
125
149
  CSS `@keyframes`/`transition` **never animate in a render** (frames are independent
@@ -336,7 +360,7 @@ soundtrack is a measurable share of whether anyone keeps watching.
336
360
  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:
337
361
 
338
362
  - **No juxtaposition, no meaning.** Meaning in video is manufactured by adjacency — the same neutral shot reads as grief or desire depending only on the shot next to it (Kuleshov effect; Eisenstein's montage of collision). A gradient next to a gradient creates nothing. Grounded, specific shots in sequence (problem-shot → product-shot → relief-shot) make a claim the individual shots never state. Compose in **pairs and triads**, ordered so adjacency does the arguing.
339
- - **No specificity, no belief.** Images are encoded more deeply than abstract words (picture-superiority effect, Paivio), and — a separate, stronger mechanism — a real human face is among the most attention-binding things a screen can show. "14x faster" on a card is an abstraction the viewer can't feel; two real founders in a real office, or a diagram of the *actual* mechanism, is embodied and credible — it *shows*.
363
+ - **No specificity, no belief.** Images are encoded more deeply than abstract words (picture-superiority effect, Paivio), and — a separate, stronger mechanism — a real human face is among the most attention-binding things a screen can show. "10x faster" on a card is an abstraction the viewer can't feel; real people talking in a real room, or a diagram of the *actual* mechanism, is embodied and credible — it *shows*.
340
364
  - **No subject, no eye-trace, no peak.** With nothing specific on screen there's no focus of interest to cut on (Murch's eye-trace) and no candidate for the one emotional peak the viewer remembers (Kahneman's Peak-End Rule). A flat decorated slideshow has no peak and a whimper ending.
341
365
 
342
366
  So grounding the video (step 3) is load-bearing, not a preference. Missing it guarantees the rest.
@@ -345,7 +369,7 @@ So grounding the video (step 3) is load-bearing, not a preference. Missing it gu
345
369
  1. **Gradient/aurora background under centered kinetic text**, no grounded subject. The literal default of every text-to-video toy. Zero information per frame — animating the text, or calling it "purposeful kinetic typography," does NOT ground it; only a visual of the real mechanism or real data does.
346
370
  2. **Generic AI b-roll** — glowing brains, blue circuit boards, particle networks, rotating server racks, holographic dashboards. "Technology" as a vibe; interchangeable across a thousand companies.
347
371
  3. **Faked or mocked UI/terminals** — a styled `<div>` pretending to be the product. The cursor doesn't blink, nothing scrolls, the output is too clean. A real 4-second capture beats it every time.
348
- 4. **On-screen numbers with no real source** — "14x", "10x", "99.9%" over a gradient. Unsourced is the content-farm tell; *wrong* is a credibility bomb.
372
+ 4. **On-screen numbers with no real source** — "10x", "5x", "99.9%" over a gradient. Unsourced is the content-farm tell; *wrong* is a credibility bomb.
349
373
  5. **All generic filler, nothing grounded** — 100% decorative generated backgrounds and kinetic text, with no real footage, no real UI/data, and no purposeful content-specific graphic. The master failure that produces all the others. (A *purposeful* animated explainer — one built on diagrams of the real mechanism or animations of the real data, NOT animated copy — is grounded and does NOT count as this tell.)
350
374
  6. **Unmotivated motion** — everything drifts, floats, Ken-Burns-pans, swoosh-transitions for no reason. The screensaver aesthetic: soft, well-oiled, no harsh edges, regardless of content.
351
375
  7. **Template rhythm** — title card → 3 bullet slides → CTA, every beat the same length and entrance. The eye recognizes the mold.
@@ -354,13 +378,13 @@ So grounding the video (step 3) is load-bearing, not a preference. Missing it gu
354
378
  10. **Dead-center symmetry, one z-plane** — subject and text fighting for the same pixels, throwing away the depth CueFrame gives you (an overlay title at `zPlane:"behind-subject"`).
355
379
 
356
380
  ### The positive inverse — author toward these
357
- One controlling idea every clip serves · grounded content of the real thing (real footage, real UI/data, or a purposeful diagram of the actual mechanism) · motivated motion (the frame moves because the subject moved or the idea turned) · restraint (fewer elements, held longer) · typographic discipline (brand type, ≤2 weights, one hierarchy) · honest data with visible provenance ("12.4% (Table 3)" beats "14x") · varied pace that builds to one memorable beat · real depth (a title behind the head, layered z-planes).
381
+ One controlling idea every clip serves · grounded content of the real thing (real footage, real UI/data, or a purposeful diagram of the actual mechanism) · motivated motion (the frame moves because the subject moved or the idea turned) · restraint (fewer elements, held longer) · typographic discipline (brand type, ≤2 weights, one hierarchy) · honest data with visible provenance ("8.5%, with the source on screen" beats "10x") · varied pace that builds to one memorable beat · real depth (a title behind the head, layered z-planes).
358
382
 
359
- ### The SIA case — the exact contrast to burn in
360
- **Brief:** a product-launch video for Hexo Labs' product "SIA."
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.
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.
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.)
383
+ ### The launch-video case — the exact contrast to burn in
384
+ **Brief:** a product-launch video for a developer-tools product. (Composite example.)
385
+ **What the agent shipped (slop):** ~37s of purple-gradient slides with centered kinetic text; a static mocked terminal card pretending to be the product running; a fabricated "10x faster" where the sourced result was **8.5%**; zero grounded content. A clean sweep of tells #1, #3, #4, #5, #7, #10.
386
+ **What was sitting right there, ignored:** the team's own launch footage — people talking to camera in a nice office. *Precisely* CueFrame's home turf: `all-faces` on a two-shot / `active-speaker` on the singles, transcript-timed captions, a lower-third per speaker, a color grade, a 4K render.
387
+ **Craft looks like (same tool, same 37s):** `import_media` the interview 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 speaker → the team's real brand type → if a benchmark appears, the real **8.5%** with its source visible, ideally over a real capture of the product running. One idea, grounded content, motivated cuts, honest data, a payoff. (Even the no-footage version was fixable: an authored diagram of the product's *actual* pipeline step beats a gradient — that's grounded too.)
364
388
 
365
389
  ---
366
390
 
@@ -443,12 +467,12 @@ Each playbook is a **floor**, not a template — reason above it. Every beat map
443
467
  | CTA | 110–120s | One action: start free / book / docs. |
444
468
 
445
469
  **Frameworks:** Problem → Product-in-action → Outcome, wrapped in one completed task, not a feature tour. ~2 min is a good ceiling; chapter beyond that.
446
- **Reach for:** `import_media` a REAL screen recording (captured by the user or Kishu — CueFrame does not screen-record) · reframe punch-in to the active UI element each step (`focus:{mode:"point",x,y}` on the click target, or a `face` focus for a founder inset) — the single biggest amateur→pro delta in demos, because the click target is ~30px in a 3840px 4K frame and nobody sees it unzoomed (**see `cueframe-product-video`** for the full click-point→reframe-segment auto-zoom tiling + PiP recipe) · a `lower-third` label per step.
470
+ **Reach for:** `import_media` a REAL screen recording (captured by the user, or by an external screen-capture client such as a headed Playwright walkthrough recorded to MP4 — CueFrame does not screen-record) · reframe punch-in to the active UI element each step (`focus:{mode:"point",x,y}` on the click target, or a `face` focus for a founder inset) — the single biggest amateur→pro delta in demos, because the click target is ~30px in a 3840px 4K frame and nobody sees it unzoomed (**see `cueframe-product-video`** for the full click-point→reframe-segment auto-zoom tiling + PiP recipe) · a `lower-third` label per step.
447
471
  **Anti-patterns:** the cardinal demo sin — a mocked/fake terminal or static UI card instead of the real app; showing the full 4K screen unzoomed; narrating every menu.
448
472
  **Quality bar:** every UI/terminal on screen is a real capture; the actual action is visibly punched-in, not lost in a wide frame.
449
473
 
450
474
  ### 5 — Founder / talking-head (CueFrame's home turf)
451
- **When:** a real person speaking to camera — founder update, announcement, testimonial. The format CueFrame composes best, and the one the SIA agent walked past.
475
+ **When:** a real person speaking to camera — founder update, announcement, testimonial. The format CueFrame composes best, and the one that agent walked past.
452
476
  **Beat sheet (75s, 16:9 for web; 9:16 cutdown for social):**
453
477
  | Beat | Time | Content |
454
478
  |---|---|---|
@@ -490,11 +514,11 @@ Each playbook is a **floor**, not a template — reason above it. Every beat map
490
514
  | 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 |
491
515
  | Director ensemble compose | `compose` — set EXACTLY ONE of `fromComposition:true` (author from the seeded composition) or `suggestionId` (clipping path) → `wait_job(kind:"compose")` |
492
516
  | Final MP4 | `create_render` → `wait_job(kind:"render")` or `create_webhook` on `render.completed`; `retry_render` (transient only) / `cancel_render` |
493
- | Orient before spending | `get_account` FIRST — plan, entitlements, per-call cost ceilings; metered calls (`create_render`, `compose`, `generate_media`, `create_brand_kit`) 402 `billing_required`; `generate_media` 402 over its USD ceiling |
517
+ | Orient before spending | `get_account` FIRST — read `balance`, NOT `included`. Rendering / generation / previews / judge / Director share ONE credit wallet (`fundedBy`); each `balance` restates that same wallet in that feature's unit. Balance > 0 = proceed — never tell the user a capability is missing, never send them to checkout. New orgs get a free credit grant, so an empty usage history is not a blocker. 402 `billing_required` fires once the balance is spent; `generate_media` also 402s over its USD ceiling |
494
518
 
495
519
  Everything needs a `projectId` — `create_project` is step 0.
496
520
 
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).
521
+ **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 needs an external screen-capture client (e.g. a headed Playwright walkthrough recorded to MP4). 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).
498
522
 
499
523
  **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`.
500
524
 
@@ -515,7 +539,7 @@ Everything needs a `projectId` — `create_project` is step 0.
515
539
  These are *archetypes*, not documented cuts of specific films — reason from the grammar, don't cargo-cult a company.
516
540
 
517
541
  - **The hardware-reveal grammar → "the product is the opening shot."** Open on black; the product materializes — no logo splash, no title card. One capability per shot. Numbers rationed, each on its own held frame. Negative space around one object = confidence. *CueFrame:* `import_media` real product footage → `preview_frame` the opening frame and ask "would this survive with zero text?" · `cinematic-title` for the *closing* wordmark only · `color-grade` for the hero look.
518
- - **The founder-to-camera grammar → CueFrame's home field (the shape the SIA agent walked past).** Founder, medium shot, direct address: "Hey, I want to show you something." No sting, just a face and eye contact. Screen-share woven in as real capture under the continuing VO. Captions burned in, plated. Lower-third names the founder once. Imperfect on purpose — that's the credibility. *CueFrame:* `get_media_context` → `active-speaker`/`all-faces` reframe → transcript-timed captions with an `emphasisPlate` → a `zPlane:"behind-subject"` title → `lower-third` → `color-grade`. Zero generation.
542
+ - **The founder-to-camera grammar → CueFrame's home field (the shape that agent walked past).** Founder, medium shot, direct address: "Hey, I want to show you something." No sting, just a face and eye contact. Screen-share woven in as real capture under the continuing VO. Captions burned in, plated. Lower-third names the founder once. Imperfect on purpose — that's the credibility. *CueFrame:* `get_media_context` → `active-speaker`/`all-faces` reframe → transcript-timed captions with an `emphasisPlate` → a `zPlane:"behind-subject"` title → `lower-third` → `color-grade`. Zero generation.
519
543
  - **The dark-kinetic-product grammar → "a gradient is a stage, not a subject."** Hard cut in on the UI in motion. Feature montage ~2–4s each, every beat a *real* UI interaction, cut on the music. The UI floats on a near-black stage with a subtle gradient — but the gradient is the *stage*; the real UI is always on top. One hero feature gets 8–10s to breathe. *CueFrame:* `import_media` UI captures → tight per-clip `trim`, cut on beat via clip durations → a dark `color-grade` + a `backgrounds` primitive as the *stage*, real footage on top. `preview_frame` a mid-montage frame: if there's no product on it, it's slop.
520
544
 
521
545
  *The compressed lessons:* the product/human is the opening shot, not a title card · a real screen recording beats a beautiful fake · a gradient is a stage, not a subject · open on your single most satisfying real moment in the first 5s · founder-to-camera + real footage is home field · a purposeful diagram of the real mechanism is grounded too · show one task completed end-to-end, not a feature grid.
@@ -548,7 +572,7 @@ KILL CRITERIA (any TRUE on any sampled frame = FAIL, regardless of score):
548
572
  K4+. … (add your own; encode this video's specific slop modes as disqualifiers)
549
573
 
550
574
  PROVENANCE: for every on-screen number, write the source next to it here
551
- (e.g. "12.4% — Table 3, arXiv:xxxx"). No written source → it does not go on screen.
575
+ (e.g. "8.5% — benchmark table, <link to the writeup>"). No written source → it does not go on screen.
552
576
 
553
577
  PER-BEAT CHECKS: B1 (0:00–0:0X) … B2 … (each beat exists and lands, with a duration)
554
578
 
@@ -569,14 +593,14 @@ SCORING: (a) your own frame-by-frame descriptions pass every MUST-HAVE with ZERO
569
593
  (never set your bar below 7.5). Sample frames at [list incl t=0]. Budget 3–5 passes.
570
594
  ```
571
595
 
572
- ### Filled example — product launch (the anti-SIA rubric)
596
+ ### Filled example — product launch (the anti-slop rubric)
573
597
  ```
574
- VISION: "Two founders who clearly believe in SIA tell you, to your face, why it's
598
+ VISION: "Two founders who clearly believe in the product tell you, to your face, why it's
575
599
  faster — and you watch it BE faster."
576
600
  FORMAT: talking-head + real demo (NOT slides).
577
- SOURCE REALITY CHECK: HUNT (3a) → Hexo's real launch = two founders to camera → import
578
- it. If no footage: a real capture of SIA running, or a first-class authored diagram of
579
- SIA's actual pipeline (grounded, not a consolation) — NOT a gradient deck. Generic
601
+ SOURCE REALITY CHECK: HUNT (3a) → the team's real launch footage = people to camera → import
602
+ it. If no footage: a real capture of the product running, or a first-class authored diagram of
603
+ its actual pipeline (grounded, not a consolation) — NOT a gradient deck. Generic
580
604
  filler = fail.
581
605
 
582
606
  MUST-HAVES:
@@ -585,25 +609,25 @@ MUST-HAVES:
585
609
  H3. [any speaking frame] The person framed is the person talking (reframe to
586
610
  get_media_context faces; all-faces on the two-shot, active-speaker on singles).
587
611
  H4. [speaking frames] Legible transcript captions, plated, never over the face.
588
- H5. [one frame] Founder name in a lower-third, shown once, spelled correctly.
589
- H6. [demo beat] Real SIA running (captured pixels), not a re-created UI card.
590
- H7. [stat beat] Any number matches the source exactly (paper says 12.4% → the frame
591
- says 12.4%, not 14x).
612
+ H5. [one frame] Speaker name in a lower-third, shown once, spelled correctly.
613
+ H6. [demo beat] The real product running (captured pixels), not a re-created UI card.
614
+ H7. [stat beat] Any number matches the source exactly (source says 8.5% → the frame
615
+ says 8.5%, not 10x).
592
616
  H8. [final] Wordmark + one line lands LAST, held ≥1.5s.
593
617
 
594
618
  KILL CRITERIA:
595
619
  K1. [mandatory] Gradient/solid + only text, no grounded subject (no real footage,
596
620
  real UI/data, or purposeful content-specific graphic).
597
- K2. [mandatory] Untraceable number (e.g. "14x") or a fake/static terminal.
621
+ K2. [mandatory] Untraceable number (e.g. "10x") or a fake/static terminal.
598
622
  K3. [mandatory] Generic/decorative filler dominates; grounded content does not.
599
623
  K4. On >2 consecutive sampled beats, the frame's largest element is text on a
600
624
  flat/gradient field with no grounded subject behind or beside it.
601
625
 
602
- PROVENANCE: "12.4%" — Table 3 of the SIA paper. (No other on-screen numbers.)
626
+ PROVENANCE: "8.5%" — the benchmark table in the sourced writeup. (No other on-screen numbers.)
603
627
 
604
- PER-BEAT: B1(0:00–0:05) cold open on founder, direct address, caption running ·
628
+ PER-BEAT: B1(0:00–0:05) cold open on a speaker, direct address, caption running ·
605
629
  B2(0:05–0:20) the "why," problem in one sentence, on the face · B3(0:20–0:35) real
606
- SIA demo, the one satisfying moment, captioned · B4(0:35–0:45) the honest 12.4% on a
630
+ product demo, the one satisfying moment, captioned · B4(0:35–0:45) the honest 8.5% on a
607
631
  clean held frame · B5(0:45–0:50) face again + CTA + wordmark.
608
632
 
609
633
  THRESHOLDS: T1 first grounded frame ≤ 3s · T2 real footage ≥ 60% of runtime · T3 ≤ 2
@@ -634,13 +658,13 @@ SCORING: own descriptions pass, zero kills; score_composition (editorialIntent =
634
658
  VISION) composite ≥ 7.5/10 on its sampled frames. Sample 0,1.5,5,10,18s. Budget 3–5 passes.
635
659
  ```
636
660
 
637
- Every line names a frame and asks a question a PNG can answer — is a grounded subject present, is text legible, is the background mostly empty decoration, does the number match its written source, is the hook first. None require reading the composition JSON. The kill criteria *are* the enforcement: K1–K3 encode the SIA failure modes as automatic disqualifiers a render can't be rationalized past.
661
+ Every line names a frame and asks a question a PNG can answer — is a grounded subject present, is text legible, is the background mostly empty decoration, does the number match its written source, is the hook first. None require reading the composition JSON. The kill criteria *are* the enforcement: K1–K3 encode that trial's failure modes as automatic disqualifiers a render can't be rationalized past.
638
662
 
639
663
  ---
640
664
 
641
665
  ## Red flags — stop and fix if any is true
642
666
 
643
- - **You concluded "no footage" without hunting** → run step 3a (user-attached? subject's existing footage? ask). The SIA agent's whole failure was skipping this — footage is the strongest grounding.
667
+ - **You concluded "no footage" without hunting** → run step 3a (user-attached? subject's existing footage? ask). That agent's whole failure was skipping this — footage is the strongest grounding.
644
668
  - **Generic/decorative filler dominates the runtime** → grounded, specific content (real footage, real UI/data, or a purposeful content-specific graphic) doesn't. K3 trips. (For footage-based formats, real footage under ~60% is the usual symptom.)
645
669
  - **An on-screen number the user didn't give you** → you fabricated it. CueFrame renders your number faithfully, so a wrong one is on you — write every stat's source in the rubric; no written source → it doesn't go on screen.
646
670
  - **A terminal/UI that's a styled component, not a real capture** → it's a mock. Import the real capture or drop it.
@@ -653,7 +677,7 @@ Every line names a frame and asks a question a PNG can answer — is a grounded
653
677
 
654
678
  ## Pre-render checklist (before `create_render`)
655
679
 
656
- 0. `create_project` done; `get_account` shows the render/compose/generate calls are within plan entitlements and cost ceilings.
680
+ 0. `create_project` done; `get_account` shows enough `balance` on the wallet funding render/compose/generate (and the generate cost ceiling clears). Judge inclusion by balance, not by `included`.
657
681
  1. Vision written as one sentence (value + cause); format chosen.
658
682
  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).
659
683
  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.
@@ -23,9 +23,9 @@ Two things make this different from `cueframe-product-video`:
23
23
  every overlay that binds a `$brand:` token resolves against the kit. Edit the
24
24
  kit, re-render, the whole video re-themes. You don't hand-paint brand colors
25
25
  onto each clip.
26
- 2. **Drive CueFrame directly — Vaaya-free.** Brand consistency is a first-class
27
- CueFrame capability now. Don't reach for an external generator to "make it
28
- look branded"; author the intent against the brand kit and let render
26
+ 2. **Drive CueFrame directly.** Brand consistency is a first-class CueFrame
27
+ capability now. Don't reach for an external generator to "make it look
28
+ branded"; author the intent against the brand kit and let render
29
29
  materialize it.
30
30
 
31
31
  Drive the primitives with the `cueframe-cli` skill and converge with
@@ -35,7 +35,7 @@ Drive the primitives with the `cueframe-cli` skill and converge with
35
35
 
36
36
  ```
37
37
  extract brand (repo + live UI) → create_brand_kit
38
- → capture (Kishu: Playwright walkthrough of localhost → MP4) → import_media
38
+ → capture (screen-capture client: Playwright walkthrough of localhost → MP4) → import_media
39
39
  → get_media_context (faces + transcript)
40
40
  → apply_composition (edit plan + brand template, refs brandKitId + $brand:)
41
41
  → compose { fromComposition:true } → wait_job kind:compose
@@ -89,8 +89,9 @@ contract for every clip.
89
89
 
90
90
  ## 2. Capture → one clean MP4
91
91
 
92
- Record a walkthrough of the **running local app** with Kishu: a headed Playwright
93
- script drives `localhost`, native screen-record captures it, and you get one
92
+ Record a walkthrough of the **running local app** with an external screen-capture
93
+ client: a headed Playwright script drives `localhost` while a native screen
94
+ recorder captures it, and you get one
94
95
  CFR / faststart MP4 plus the cursor/click events (timed viewport coordinates —
95
96
  the focus points the auto-zoom follows; see `cueframe-product-video` §1–2). Use
96
97
  your codebase knowledge to script the walkthrough: open the real flows that
@@ -240,12 +241,12 @@ frames) before declaring done.
240
241
  — it's just skipped, never an error.
241
242
  - **`watermark` is accepted by `create_brand_kit` and persisted, but render does
242
243
  NOT yet auto-composite the kit's watermark asset** (the only watermark painted
243
- today is CueFrame's product mark). Set it for forward-compat, but don't promise
244
- the founder a custom watermark in the output yet.
245
- - **Drive CueFrame directly.** This whole recipe is Vaaya-free: the brand, the
246
- capture, the compose, the render are all CueFrame. Reach for an external
247
- generator only for footage CueFrame genuinely can't produce — not to "make it
248
- look branded," which is the engine's job now.
244
+ today is CueFrame's product mark). Set it for forward-compat, but custom
245
+ watermarks are not composited into the output yet — don't promise one.
246
+ - **Drive CueFrame directly.** Everything downstream of the capture — the brand,
247
+ the compose, the render — is CueFrame. Reach for an external generator only for
248
+ footage CueFrame genuinely can't produce — not to "make it look branded,"
249
+ which is the engine's job now.
249
250
  - This recipe lives in a skill on purpose: the engine stays use-case-free; the
250
251
  product opinions (what to extract, which overlays, how to brand) live here and
251
- ship via `cueframe install`.
252
+ ship via `npx -y cueframe install`.