@cueframe/skills 0.1.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.
Files changed (80) hide show
  1. package/.agents/plugins/marketplace.json +12 -0
  2. package/.claude-plugin/marketplace.json +6 -0
  3. package/.claude-plugin/plugin.json +15 -0
  4. package/.codex-plugin/plugin.json +30 -0
  5. package/.cursor-plugin/plugin.json +1 -0
  6. package/.mcp.json +1 -0
  7. package/AGENTS.md +20 -0
  8. package/LICENSE +202 -0
  9. package/NOTICE +4 -0
  10. package/README.md +111 -0
  11. package/assets/icon.svg +16 -0
  12. package/assets/logo-400.png +0 -0
  13. package/gemini-extension.json +1 -0
  14. package/glama.json +1 -0
  15. package/hooks/hooks.json +7 -0
  16. package/hooks/session-inject.md +15 -0
  17. package/hooks/session-start.sh +6 -0
  18. package/llms-install.md +47 -0
  19. package/mcp.json +1 -0
  20. package/package.json +57 -0
  21. package/plugin.json +46 -0
  22. package/rules/cueframe.mdc +19 -0
  23. package/skills/add-music-bed/SKILL.md +100 -0
  24. package/skills/add-music-bed/agents/openai.yaml +6 -0
  25. package/skills/add-music-bed/assets/icon.svg +16 -0
  26. package/skills/brand-reel/SKILL.md +100 -0
  27. package/skills/brand-reel/agents/openai.yaml +6 -0
  28. package/skills/brand-reel/assets/icon.svg +16 -0
  29. package/skills/clip-a-talking-head/SKILL.md +101 -0
  30. package/skills/clip-a-talking-head/agents/openai.yaml +6 -0
  31. package/skills/clip-a-talking-head/assets/icon.svg +16 -0
  32. package/skills/composing-video/SKILL.md +702 -0
  33. package/skills/composing-video/agents/openai.yaml +6 -0
  34. package/skills/composing-video/assets/icon.svg +16 -0
  35. package/skills/cueframe-brand-demo/SKILL.md +257 -0
  36. package/skills/cueframe-brand-demo/agents/openai.yaml +6 -0
  37. package/skills/cueframe-brand-demo/assets/icon.svg +16 -0
  38. package/skills/cueframe-cli/SKILL.md +265 -0
  39. package/skills/cueframe-cli/agents/openai.yaml +6 -0
  40. package/skills/cueframe-cli/assets/icon.svg +16 -0
  41. package/skills/cueframe-component-authoring/SKILL.md +179 -0
  42. package/skills/cueframe-component-authoring/agents/openai.yaml +6 -0
  43. package/skills/cueframe-component-authoring/assets/icon.svg +16 -0
  44. package/skills/cueframe-compose-loop/SKILL.md +114 -0
  45. package/skills/cueframe-compose-loop/agents/openai.yaml +6 -0
  46. package/skills/cueframe-compose-loop/assets/icon.svg +16 -0
  47. package/skills/cueframe-compose-loop/references/preview-workflow.md +37 -0
  48. package/skills/cueframe-connect/SKILL.md +45 -0
  49. package/skills/cueframe-connect/agents/openai.yaml +6 -0
  50. package/skills/cueframe-connect/assets/icon.svg +16 -0
  51. package/skills/cueframe-product-video/SKILL.md +293 -0
  52. package/skills/cueframe-product-video/agents/openai.yaml +6 -0
  53. package/skills/cueframe-product-video/assets/icon.svg +16 -0
  54. package/skills/cueframe-scene-shot/SKILL.md +68 -0
  55. package/skills/cueframe-scene-shot/agents/openai.yaml +6 -0
  56. package/skills/cueframe-scene-shot/assets/icon.svg +16 -0
  57. package/skills/cueframe-storyboard/SKILL.md +104 -0
  58. package/skills/cueframe-storyboard/agents/openai.yaml +6 -0
  59. package/skills/cueframe-storyboard/assets/icon.svg +16 -0
  60. package/skills/every-format-from-one-edit/SKILL.md +87 -0
  61. package/skills/every-format-from-one-edit/agents/openai.yaml +6 -0
  62. package/skills/every-format-from-one-edit/assets/icon.svg +16 -0
  63. package/skills/extracting-brand-kits/SKILL.md +159 -0
  64. package/skills/extracting-brand-kits/agents/openai.yaml +6 -0
  65. package/skills/extracting-brand-kits/assets/icon.svg +16 -0
  66. package/skills/launch-video/SKILL.md +93 -0
  67. package/skills/launch-video/agents/openai.yaml +6 -0
  68. package/skills/launch-video/assets/icon.svg +16 -0
  69. package/skills/make-a-social-reel/SKILL.md +105 -0
  70. package/skills/make-a-social-reel/agents/openai.yaml +6 -0
  71. package/skills/make-a-social-reel/assets/icon.svg +16 -0
  72. package/skills/rebrand-a-video/SKILL.md +95 -0
  73. package/skills/rebrand-a-video/agents/openai.yaml +6 -0
  74. package/skills/rebrand-a-video/assets/icon.svg +16 -0
  75. package/skills/video-craft-standards/SKILL.md +128 -0
  76. package/skills/video-craft-standards/agents/openai.yaml +6 -0
  77. package/skills/video-craft-standards/assets/icon.svg +16 -0
  78. package/skills-dir.d.ts +1 -0
  79. package/skills-dir.js +2 -0
  80. package/skills.sh.json +1 -0
@@ -0,0 +1,293 @@
1
+ ---
2
+ name: cueframe-product-video
3
+ description: Use when turning a screen recording (with cursor/click events) into a polished, auto-zooming product video or demo reel via CueFrame — e.g. "make a product demo from this Browserbase capture", "auto-zoom this screen recording to where the user clicked", "turn this walkthrough into a social demo". This is a USE-CASE recipe over the CueFrame primitives in the `cueframe-cli` skill.
4
+ ---
5
+
6
+ # CueFrame — Product Video recipe
7
+
8
+ A **use-case recipe**, not new framework surface. CueFrame's engine only knows
9
+ primitives (`upload` → `composition put` → `render`, the `reframe` viewport, the
10
+ overlay/effect primitives). This skill is the *judgment* on top: how to turn a
11
+ captured walkthrough into a product video that looks good. This tells you *what*
12
+ to author, not how to transport it.
13
+
14
+ **Drive the primitives over MCP if you can call tools** (`new_composition` /
15
+ `apply_composition` / `validate_composition` / `create_render` — see the
16
+ `cueframe-connect` skill for the one-line setup). The `npx -y cueframe@0.5 …` commands
17
+ written out below are the same operations for a terminal or CI job with no MCP
18
+ host; see the `cueframe-cli` skill.
19
+
20
+ ## The pipeline
21
+
22
+ ```
23
+ capture (video + cursor/click points) → auto-zoom (points → reframe)
24
+ → compose (video track + per-clip reframe) → polish (overlay primitives)
25
+ → render
26
+ ```
27
+
28
+ ## 1. Capture → timed focus points
29
+
30
+ Get a screen recording **plus** the cursor/click events with viewport
31
+ coordinates and timestamps (e.g. from a browser-automation capture). Normalize
32
+ every point to `{ t: seconds, x: 0..1, y: 0..1 }` against the **real captured
33
+ viewport** — these are the *focus points* the zoom follows. Measure the rendered
34
+ video's true duration (ffprobe) and map point times onto it.
35
+
36
+ ## 2. Points → reframe (auto-zoom)
37
+
38
+ The framework owns the tuning. Canonical implementation:
39
+ `autoZoom(points, style)` in `@cueframe/composition` (timed focus points →
40
+ gapless `reframe` segments; never re-derive this with an LLM — it drifts). Pick a
41
+ **style**, never raw numbers:
42
+
43
+ | style | zoom (`<1` punches in) | feel |
44
+ |---|---|---|
45
+ | `subtle` | 0.80 | gentle, corporate |
46
+ | `standard` | 0.67 | default |
47
+ | `punchy` | 0.55 | snappy, social |
48
+
49
+ The tiling rule (what `autoZoom` does — use this until it's exposed as
50
+ `cueframe compose from-points`): sort points by `t`; group points within
51
+ `mergeGap`s; pad each group `prePad` before / `postPad` after; drop groups
52
+ shorter than `minZoom`; merge overlapping windows; emit `frame-center` zoom 1
53
+ in the gaps and a `point` punch-in (`focus:{mode:"point",x,y}`, `zoom` = the
54
+ style's) over each window. Result → `source.reframe.segments` on the clip.
55
+
56
+ ## 3. Compose
57
+
58
+ One video track, the screen recording as a media clip carrying the reframe.
59
+ `npx -y cueframe@0.5 composition put <projectId> -b @composition.json` (see `cueframe-cli`).
60
+ Choose `-a 16:9` for landscape product video, `9:16` for social.
61
+
62
+ ## 4. Polish — layer overlay primitives (this is what makes it look "produced")
63
+
64
+ A bare auto-zoom reads as a raw screen-grab. Add overlay/effect clips referencing
65
+ registered primitives (`registry/params-required.json` lists each one's params;
66
+ `$brand:` tokens bind brand colors/fonts at render). Tasteful default set for a
67
+ product demo:
68
+
69
+ | Goal | primitiveId | kind |
70
+ |---|---|---|
71
+ | animated cursor tracing the click path | `cursor-flow` / `simulated-cursor` | overlay |
72
+ | title / context | `lower-third` or `heroText` | overlay |
73
+ | highlight a clicked element | `marker-highlight` / `pulsing-indicator` | overlay |
74
+ | device/browser frame | `device-mockup-zoom` / `browser-flow` | overlay |
75
+ | captions (if narrated) | the top-level `captions` field | — |
76
+ | finish/look | `color-grade` + `vignette` | effect |
77
+ | several cells sharing space that should reflow (feature grid, rail + fluid content) | author a component on `FlexLayout` from `@cueframe/animate` (see `cueframe-component-authoring`) | overlay (authored) |
78
+
79
+ Static PiP / split-screen is `region` + `fit` on the clips (EX3 / EX4). Cells that must
80
+ **reflow together** or hold mixed content are one authored component built on `FlexLayout`;
81
+ the catalog `flex-layout` primitive is that same layout, but a bare composition overlay has
82
+ no children, so on its own it draws only the rig outlines.
83
+
84
+ A primitive is the `source` of a clip; the clip wraps it with `id`/`startTime`/`duration`:
85
+ - Overlay clip (on a `kind:"overlay"` track): `{ "id":"t1", "startTime":1, "duration":3, "source":{ "kind":"overlay", "primitiveId":"lower-third", "params":{…}, "zPlane":"front" } }`.
86
+ - Effect clip (on a `kind:"effect"` track): `{ "id":"e1", "startTime":0, "duration":9, "source":{ "kind":"effect", "primitiveId":"color-grade", "params":{…} } }`.
87
+ Simultaneous overlays go on **separate tracks** — clips on one track can't overlap in time.
88
+ **Don't over-decorate** — 2–4 primitives. Cursor + title + grade is usually enough.
89
+
90
+ ## 5. Render
91
+
92
+ First use `cueframe-compose-loop`'s [preview workflow](../cueframe-compose-loop/references/preview-workflow.md):
93
+ check framing with `preview_frame` and click/zoom timing with an affected-window `preview_clip`.
94
+ For a small revision, verify that change and relevant regressions without exporting the whole film.
95
+ When delivering the finished video:
96
+
97
+ `npx -y cueframe@0.5 render <projectId> -o out.mp4 --json`. Verify the output (ffprobe +
98
+ sample frames) before declaring done.
99
+
100
+ ## Worked examples — composition JSON
101
+
102
+ These are **orientation, not the contract.** The live wire schema is
103
+ `npx -y cueframe@0.5 schema composition`, and the way to know a draft is correct is
104
+ `npx -y cueframe@0.5 composition validate -b @composition.json` — it runs the same
105
+ validator the server enforces, with no save and no render. Discover + validate
106
+ before you render; never spend a render to find a schema mistake.
107
+
108
+ Each block below is a complete `@composition.json` (the bare object `composition put`
109
+ accepts: top-level `v`, `format`, `tracks`, optional `captions`). All five validate
110
+ against the real wire schema + save invariants (swap the `<…MediaId>` placeholders for
111
+ real `npx -y cueframe@0.5 upload` ids). Conventions that keep them valid:
112
+
113
+ - Tracks hold **`contents`** (not `clips`); each clip wraps a `source`.
114
+ - A clip's `source.kind` must match the track `kind`: `media` → `video`/`image`/`audio`
115
+ tracks, `overlay` → `overlay` tracks, `effect` → `effect` tracks.
116
+ - Clip/segment times are **seconds** (`startTime`, `duration`, `startSec`, `endSec`,
117
+ `trim`); caption word times are **milliseconds** (`startMs`/`endMs`).
118
+ - `region`/`fit` are **clip-level** (siblings of `source`); `reframe` lives on the media `source`.
119
+ - Clips on one track can't overlap — put simultaneous layers on **separate tracks**.
120
+ - `zoom < 1` punches in (range `[0.1, 1]`, default `1`). Durations are illustrative — match your source.
121
+
122
+ ### EX1 · Auto-zoom screen demo (16:9)
123
+ One screen recording with `reframe` punch-ins (the `autoZoom` output: `frame-center` in the gaps, `point` over each click) + a cinematic grade.
124
+
125
+ ```json
126
+ {
127
+ "v": 1,
128
+ "format": { "aspectRatio": "16:9", "fps": 30 },
129
+ "tracks": [
130
+ {
131
+ "id": "v-screen", "kind": "video", "contents": [
132
+ {
133
+ "id": "rec", "startTime": 0, "duration": 12,
134
+ "source": {
135
+ "kind": "media", "mediaId": "<mediaId>",
136
+ "reframe": { "segments": [
137
+ { "startSec": 0, "endSec": 2, "focus": { "mode": "frame-center" }, "zoom": 1 },
138
+ { "startSec": 2, "endSec": 5, "focus": { "mode": "point", "x": 0.28, "y": 0.42 }, "zoom": 0.6, "ease": { "in": 0.4, "out": 0.4 } },
139
+ { "startSec": 5, "endSec": 7, "focus": { "mode": "frame-center" }, "zoom": 1, "ease": { "in": 0.4, "out": 0.4 } },
140
+ { "startSec": 7, "endSec": 10, "focus": { "mode": "point", "x": 0.72, "y": 0.66 }, "zoom": 0.55, "ease": { "in": 0.4, "out": 0.4 } },
141
+ { "startSec": 10, "endSec": 12, "focus": { "mode": "frame-center" }, "zoom": 1, "ease": { "in": 0.4, "out": 0.4 } }
142
+ ] }
143
+ }
144
+ }
145
+ ]
146
+ },
147
+ {
148
+ "id": "fx", "kind": "effect", "contents": [
149
+ { "id": "grade", "startTime": 0, "duration": 12, "source": { "kind": "effect", "primitiveId": "color-grade", "params": { "preset": "cinematic" } } }
150
+ ]
151
+ }
152
+ ]
153
+ }
154
+ ```
155
+
156
+ ### EX2 · Social vertical with captions (9:16)
157
+ Reframe + a `lower-third` title, then a `cursor-flow` overlay (non-overlapping on one overlay track), transcript `captions` (ms timing), warm grade. `$brand:` refs bind brand colors/fonts at render.
158
+
159
+ ```json
160
+ {
161
+ "v": 1,
162
+ "format": { "aspectRatio": "9:16", "fps": 30, "platform": "tiktok" },
163
+ "tracks": [
164
+ {
165
+ "id": "v", "kind": "video", "contents": [
166
+ {
167
+ "id": "rec", "startTime": 0, "duration": 10,
168
+ "source": {
169
+ "kind": "media", "mediaId": "<mediaId>",
170
+ "reframe": { "segments": [
171
+ { "startSec": 0, "endSec": 4, "focus": { "mode": "point", "x": 0.3, "y": 0.4 }, "zoom": 0.7, "ease": { "in": 0.4, "out": 0.4 } },
172
+ { "startSec": 4, "endSec": 10, "focus": { "mode": "point", "x": 0.62, "y": 0.55 }, "zoom": 0.62, "ease": { "in": 0.4, "out": 0.4 } }
173
+ ] }
174
+ }
175
+ }
176
+ ]
177
+ },
178
+ {
179
+ "id": "ov", "kind": "overlay", "contents": [
180
+ {
181
+ "id": "title", "startTime": 0, "duration": 3.5,
182
+ "source": {
183
+ "kind": "overlay", "primitiveId": "lower-third",
184
+ "params": {
185
+ "text": "AI video, one command", "subtitle": "cueframe", "variant": "modern",
186
+ "tokens": { "textColor": "$brand:colors.textOnMedia", "accentColor": "$brand:colors.accent", "fontFamily": "$brand:fonts.heading.family" }
187
+ }
188
+ }
189
+ },
190
+ {
191
+ "id": "cursor", "startTime": 3.5, "duration": 6,
192
+ "source": {
193
+ "kind": "overlay", "primitiveId": "cursor-flow",
194
+ "params": {
195
+ "waypoints": [ { "x": 200, "y": 180 }, { "x": 540, "y": 240, "click": true, "label": "Generate" }, { "x": 1040, "y": 520, "click": true, "label": "Publish" } ],
196
+ "cursorColor": "$brand:colors.text", "showTargets": true
197
+ }
198
+ }
199
+ }
200
+ ]
201
+ },
202
+ {
203
+ "id": "fx", "kind": "effect", "contents": [
204
+ { "id": "grade", "startTime": 0, "duration": 10, "source": { "kind": "effect", "primitiveId": "color-grade", "params": { "preset": "warm" } } }
205
+ ]
206
+ }
207
+ ],
208
+ "captions": {
209
+ "segments": [
210
+ { "words": [
211
+ { "text": "Watch", "startMs": 0, "endMs": 320 },
212
+ { "text": "this", "startMs": 320, "endMs": 560, "emphasis": true },
213
+ { "text": "render", "startMs": 560, "endMs": 980 },
214
+ { "text": "in", "startMs": 980, "endMs": 1120 },
215
+ { "text": "one", "startMs": 1120, "endMs": 1360, "emphasis": true },
216
+ { "text": "command", "startMs": 1360, "endMs": 1900 }
217
+ ] }
218
+ ],
219
+ "style": { "fontFamily": "Inter", "fontSize": 6.5, "fontWeight": 900, "color": "#ffffff", "highlightColor": "#10B981", "position": "bottom", "textTransform": "uppercase" }
220
+ }
221
+ }
222
+ ```
223
+
224
+ ### EX3 · Picture-in-picture (16:9)
225
+ Full-frame screen recording + a webcam **inset** placed with `region`/`fit` on a second video track (composites on top by track order). Two uploads → two `mediaId`s.
226
+
227
+ ```json
228
+ {
229
+ "v": 1,
230
+ "format": { "aspectRatio": "16:9", "fps": 30 },
231
+ "tracks": [
232
+ { "id": "v-screen", "kind": "video", "contents": [
233
+ { "id": "screen", "startTime": 0, "duration": 10, "source": { "kind": "media", "mediaId": "<screenMediaId>" } }
234
+ ] },
235
+ { "id": "v-cam", "kind": "video", "contents": [
236
+ { "id": "cam", "startTime": 0, "duration": 10, "source": { "kind": "media", "mediaId": "<webcamMediaId>" }, "region": { "x": 0.68, "y": 0.04, "w": 0.3, "h": 0.3 }, "fit": "cover" }
237
+ ] }
238
+ ]
239
+ }
240
+ ```
241
+
242
+ ### EX4 · Split-screen (16:9)
243
+ Two sources side-by-side, each with a half-frame `region` on its own video track.
244
+
245
+ ```json
246
+ {
247
+ "v": 1,
248
+ "format": { "aspectRatio": "16:9", "fps": 30 },
249
+ "tracks": [
250
+ { "id": "v-left", "kind": "video", "contents": [
251
+ { "id": "left", "startTime": 0, "duration": 8, "source": { "kind": "media", "mediaId": "<leftMediaId>" }, "region": { "x": 0, "y": 0, "w": 0.5, "h": 1 }, "fit": "cover" }
252
+ ] },
253
+ { "id": "v-right", "kind": "video", "contents": [
254
+ { "id": "right", "startTime": 0, "duration": 8, "source": { "kind": "media", "mediaId": "<rightMediaId>" }, "region": { "x": 0.5, "y": 0, "w": 0.5, "h": 1 }, "fit": "cover" }
255
+ ] }
256
+ ]
257
+ }
258
+ ```
259
+
260
+ ### EX5 · Presenter intro — title behind the speaker (9:16)
261
+ Talking-head with an `active-speaker` reframe and a `heroText` title at `zPlane:"behind-subject"`. The speaker **detection** and the person **matte** are both resolved automatically at render (see the `cueframe-cli` skill's "Render resolves expensive intents" section) — author the intent, render, done.
262
+
263
+ ```json
264
+ {
265
+ "v": 1,
266
+ "format": { "aspectRatio": "9:16", "fps": 30 },
267
+ "tracks": [
268
+ { "id": "v", "kind": "video", "contents": [
269
+ { "id": "cam", "startTime": 0, "duration": 6, "source": { "kind": "media", "mediaId": "<mediaId>", "reframe": { "segments": [ { "startSec": 0, "endSec": 6, "focus": { "mode": "active-speaker" }, "zoom": 0.8 } ] } } }
270
+ ] },
271
+ { "id": "ov", "kind": "overlay", "contents": [
272
+ { "id": "hero", "startTime": 0.5, "duration": 5, "source": {
273
+ "kind": "overlay", "primitiveId": "heroText",
274
+ "params": { "text": "SHIP IN MINUTES", "fontSizePct": 14, "textColor": "$brand:colors.textOnMedia", "fontFamily": "$brand:fonts.heading.family" },
275
+ "zPlane": "behind-subject", "anchor": { "space": "scene", "x": 0.5, "y": 0.42 }
276
+ } }
277
+ ] }
278
+ ]
279
+ }
280
+ ```
281
+
282
+ ## Notes / honesty
283
+
284
+ - **Picture-in-picture / inset cards render** — per-clip output-space placement
285
+ (`region:{x,y,w,h}` in `[0,1]` + `fit`) is wired for PiP / inset / split-screen,
286
+ for video, image, and overlay clips. Set `region`/`fit` on the **clip** (siblings
287
+ of `source`, not inside it — as an agent, patch them with an `apply_composition`
288
+ `clip.update` op: `{ type: 'clip.update', clipId, patch: { region, fit } }`); two
289
+ clips with different placement composite by track order instead of occluding the
290
+ background. See EX3 / EX4 below.
291
+ - This recipe lives in a skill on purpose: the engine stays use-case-free; the
292
+ product opinions (style, which primitives, layout) live here and ship via
293
+ `npx -y cueframe@0.5 install`. Add sibling recipes (`cueframe-podcast-clip`, …) the same way.
@@ -0,0 +1,6 @@
1
+ interface:
2
+ display_name: "CueFrame — Product Video recipe"
3
+ short_description: "Use when turning a screen recording (with cursor/click events) into a…"
4
+ icon_small: "./assets/icon.svg"
5
+ icon_large: "./assets/icon.svg"
6
+ default_prompt: "Use $cueframe-product-video when turning a screen recording (with cursor/click events) into a polished, auto-zooming product video or demo reel via CueFrame — e.g. \"make a product demo from this Browserbase capture\", \"auto-zoom this screen recording to where the user clicked\", \"turn this walkthrough into a social demo\"."
@@ -0,0 +1,16 @@
1
+ <svg viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
2
+ <clipPath id="cf-favicon-clip"><circle cx="128" cy="128" r="118"/></clipPath>
3
+ <circle cx="128" cy="128" r="118" fill="#f7c948"/>
4
+ <g clip-path="url(#cf-favicon-clip)">
5
+ <path d="M88 128Q160 40 300-40" fill="none" stroke="#160f08" stroke-width="5"/>
6
+ <path d="M88 128Q170 60 310 20" fill="none" stroke="#160f08" stroke-width="4.5"/>
7
+ <path d="M88 128Q180 80 316 70" fill="none" stroke="#160f08" stroke-width="4.5"/>
8
+ <path d="M88 128Q186 110 320 110" fill="none" stroke="#160f08" stroke-width="4.5"/>
9
+ <path d="M88 128Q186 146 320 146" fill="none" stroke="#160f08" stroke-width="4.5"/>
10
+ <path d="M88 128Q180 176 316 186" fill="none" stroke="#160f08" stroke-width="4.5"/>
11
+ <path d="M88 128Q170 196 310 236" fill="none" stroke="#160f08" stroke-width="4.5"/>
12
+ <path d="M88 128Q160 216 300 296" fill="none" stroke="#160f08" stroke-width="5"/>
13
+ </g>
14
+ <circle cx="88" cy="128" r="20" fill="#160f08"/>
15
+ <circle cx="88" cy="128" r="8" fill="#f7c948"/>
16
+ </svg>
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: cueframe-scene-shot
3
+ description: Author a CueFrame 3D world-object shot as canonical SceneShotSpecV2 JSON. Use for slabs, pages, phones, laptops, captured component or video surfaces, world text, camera motion, studio lighting, focus, and product-shot recipes.
4
+ ---
5
+
6
+ # CueFrame scene shots
7
+
8
+ Use `scene.add` and `scene.update` through `apply_composition`. Author the scene JSON; CueFrame owns the generated wrapper, preparation, resource admission, previews, and export.
9
+
10
+ Before authoring, read `cueframe://scene-shot`. It serves the canonical generated `SceneShotSpecV2` schema, exact operation contracts, supported brand tokens, refusal rules, and a copyable nested slab-and-page recipe. Do not infer fields from an older example.
11
+
12
+ On the CueFrame desktop app that resource is unreachable — its MCP surface is tools-only and no `cueframe://` URI resolves there. Call the `get_scene_contract` tool instead: same document, served in sections (`essentials` by default, then `rules` and `schema`).
13
+
14
+ ## Workflow
15
+
16
+ Use `cueframe-compose-loop`'s [preview workflow](../cueframe-compose-loop/references/preview-workflow.md)
17
+ for the available hosted/local lane. Inspect affected camera/focus/entrance windows in motion,
18
+ not only keyframes. A scene tweak can finish with preview evidence; export for final delivery.
19
+
20
+ 1. Create or open a composition at the target aspect and FPS.
21
+ 2. Register every image or video source. Capture-backed component surfaces use an exact component id, source version id, capture frame, layout, and optional bake scale.
22
+ 3. Read `cueframe://scene-shot` (desktop: `get_scene_contract`), copy its `world-objects` recipe, and replace placeholder ids and copy.
23
+ 4. Send `apply_composition` with `dry_run: true`. Fix the exact reported field path.
24
+ 5. Apply the same batch for real. Preview the first frame, object entrances, focus transitions, and the last frame.
25
+ 6. Revise with `scene.update`; do not hand-edit a generated wrapper.
26
+ 7. Render only after surfaces report ready and the previews show the intended pixels.
27
+
28
+ ## Ownership boundaries
29
+
30
+ The composition owns clip start, duration, ordering, cuts, and transitions. The scene owns objects, camera, environment, backdrop, post effects, constraints, and normalized animation. Scene clips occupy a dedicated full-frame front overlay track. Outer region, position, scale, rotation, fit, clip effects, and internal fades are refused because they would create two transform or timing owners.
31
+
32
+ `referenceSize` must have the same aspect ratio as the composition. Coordinates are reference pixels with origin at frame center, +X right, +Y down, and +Z toward the viewer. Equal-aspect outputs scale uniformly.
33
+
34
+ Animation keyframe `at` is normalized over clip duration. Easing belongs to the keyframe it arrives at. The first keyframe has no easing; each later keyframe supplies `linear`, `hold`, or cubic `bezier` easing. Topology, bindings, text content, fonts, material roles, and object kind remain static within a shot.
35
+
36
+ ## Objects and surfaces
37
+
38
+ V2 supports nested `group` layers and canonical `slab`, `page`, `phone`, `laptop`, and `text` layers. Use each object's declared surface slot:
39
+
40
+ - `source: "image"` binds an admitted PNG, JPEG, or WebP through the outer `assets` map.
41
+ - `source: "component"` captures an immutable component source at the declared frame and layout. Omitted `bakeScale` lets preparation select 2× or 3×; an explicit insufficient scale refuses.
42
+ - `source: "video"` binds an admitted media id with frame-addressed start/end facts. Video decoding and committed-frame readiness are sealed before drawing.
43
+ - `source: "color"` supplies an unlit solid surface.
44
+
45
+ Never insert a URL, raw HTML, shader source, or placeholder art into a surface. Every required slot must resolve before capture. UI surfaces and world text are unlit and color-managed; bodies use declared physical material roles. Invisible objects do not write depth.
46
+
47
+ World text participates in camera, depth, occlusion, and focus. Screen text stays fixed above the world result. Both are line-authored with no automatic reflow. Every exact font family, weight, and style used by base or emphasized runs must be admitted.
48
+
49
+ ## Lighting and post
50
+
51
+ Choose the generated studio environment for named studio profiles or `{kind:"photographic-studio-v1"}` for the fixed photographic recipe. Arbitrary HDR fields are refused. Backdrops may be transparent, solid, linear, or radial. Focus is per-pixel world depth; sample the actual object face rather than its layer origin when choosing distance and range.
52
+
53
+ Brand tokens are allowed only in schema-declared color and font-family fields. Read the token enums from the resource. A font token resolves the family only; authored weight and style still require exact admitted bytes.
54
+
55
+ ## Limits and refusals
56
+
57
+ The contract admits at most 32 layers, 4 devices, 16 distinct image slots, 256 keyframes per channel, and 2048 keyframes per shot. Raw HTML, custom shader properties, imported GLB models, arbitrary external HDR environments, skeletal animation, and physics are unsupported. Unknown keys, duplicate ids, missing bindings, non-finite values, aspect mismatch, budget overflow, and unsupported capabilities fail with a named code and exact path.
58
+
59
+ Composition-level global wrap effects do not reach front-overlay scene clips. Author grain, vignette, focus, backdrop, and environment inside the scene.
60
+
61
+ ## Delivery checks
62
+
63
+ - The rendered subject is a real object with a real admitted surface.
64
+ - Every key entrance, reflection sweep, screen update, and focus transition was previewed.
65
+ - Device and slab bodies receive the intended light while UI colors remain unchanged.
66
+ - Text uses the intended admitted face and remains legible.
67
+ - The output aspect matches the authored reference aspect.
68
+ - The final response identifies the composition, render, source provenance, and any intentional unsupported boundary.
@@ -0,0 +1,6 @@
1
+ interface:
2
+ display_name: "CueFrame scene shots"
3
+ short_description: "Author a CueFrame 3D world-object shot as canonical SceneShotSpecV2 JSON. Use…"
4
+ icon_small: "./assets/icon.svg"
5
+ icon_large: "./assets/icon.svg"
6
+ default_prompt: "Use $cueframe-scene-shot to author a CueFrame 3D world-object shot as canonical SceneShotSpecV2 JSON."
@@ -0,0 +1,16 @@
1
+ <svg viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
2
+ <clipPath id="cf-favicon-clip"><circle cx="128" cy="128" r="118"/></clipPath>
3
+ <circle cx="128" cy="128" r="118" fill="#f7c948"/>
4
+ <g clip-path="url(#cf-favicon-clip)">
5
+ <path d="M88 128Q160 40 300-40" fill="none" stroke="#160f08" stroke-width="5"/>
6
+ <path d="M88 128Q170 60 310 20" fill="none" stroke="#160f08" stroke-width="4.5"/>
7
+ <path d="M88 128Q180 80 316 70" fill="none" stroke="#160f08" stroke-width="4.5"/>
8
+ <path d="M88 128Q186 110 320 110" fill="none" stroke="#160f08" stroke-width="4.5"/>
9
+ <path d="M88 128Q186 146 320 146" fill="none" stroke="#160f08" stroke-width="4.5"/>
10
+ <path d="M88 128Q180 176 316 186" fill="none" stroke="#160f08" stroke-width="4.5"/>
11
+ <path d="M88 128Q170 196 310 236" fill="none" stroke="#160f08" stroke-width="4.5"/>
12
+ <path d="M88 128Q160 216 300 296" fill="none" stroke="#160f08" stroke-width="5"/>
13
+ </g>
14
+ <circle cx="88" cy="128" r="20" fill="#160f08"/>
15
+ <circle cx="88" cy="128" r="8" fill="#f7c948"/>
16
+ </svg>
@@ -0,0 +1,104 @@
1
+ ---
2
+ name: cueframe-storyboard
3
+ description: >-
4
+ Use BEFORE composing when starting a NEW video from scratch and you need to plan its structure — turning a rough ask ("make a launch video", "30s promo", "an explainer for our API") into a concrete beat flow. Owns the intake + storyboard step: interview the user for the brief, resolve the format from the platform, and lay out the hook→body→cta beats that drive the compose workflow. Triggers on "plan a video", "storyboard", "structure this video", "outline the video", "where do I start", or any new-video ask that has no structure yet. Hand off to composing-video for per-beat craft.
5
+ ---
6
+
7
+ # CueFrame Storyboard: brief → flow
8
+
9
+ This is a new-video planning workflow. For revisions to an approved plan, preserve its structure
10
+ and use `cueframe-compose-loop`'s [preview workflow](../cueframe-compose-loop/references/preview-workflow.md)
11
+ to verify the requested change; do not restart intake, Director authoring, or final export by default.
12
+
13
+ > **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.
14
+
15
+
16
+ ## The one idea
17
+
18
+ **You are the planner.** You have the user, the whole conversation, the brand, and the judgment — you are
19
+ the smartest thing in this loop. CueFrame is the hands. This skill is the **intake + structure** step:
20
+ turn intent into a concrete **beat flow** *before* you seed a composition, so the curated workflow (media →
21
+ components → seed) executes a plan instead of a guess. Craft — grounded-vs-slop, the verify loop — belongs
22
+ to the sibling **composing-video** skill; this skill gets you a flow, then hands off to it.
23
+
24
+ Do not offload the *thinking* to CueFrame. There is no server that plans the video for you, and you would
25
+ not want one — it would be a blind model with none of your context. Plan here, in the open, with the user.
26
+
27
+ ## 1. Interview for the brief — ask only what you can't infer
28
+
29
+ Fill the brief from the conversation first; ask the user **only for the 1–2 things you genuinely cannot
30
+ infer**, and STATE what you assume for the rest. Never wall them with a form.
31
+
32
+ - **Goal / intent** *(required)* — what is this video FOR? launch, promo, explainer, demo, teaser, recap.
33
+ - **Platform** *(sets the format)* — reels / tiktok / shorts → **9:16, ~20s** · youtube → **16:9, ~45s** ·
34
+ linkedin / x → **1:1, ~20s** · web → **16:9, ~30s**. (Or an explicit aspect ratio + duration.)
35
+ - **Audience**, **tone** (punchy / premium-calm / playful / authoritative), **CTA**, **must-includes**
36
+ (a number, a name, a screen), **references** (a style to echo), **brand kit**.
37
+
38
+ If the ask is "make a launch video for our API," you already have goal + a hint of audience — ask "Reels,
39
+ YouTube, or your site?" and infer the rest: *"I'll assume a developer audience and a punchy tone — say if
40
+ you'd rather it feel calm/premium."* One or two questions, not seven.
41
+
42
+ ## 2. Structure the flow — the storyboard
43
+
44
+ Lay the duration into **beats** using the fixed editorial vocabulary
45
+ **hook → context → body → proof → cta → outro** (use what the piece needs — most short-form is
46
+ hook → body → cta). For each beat decide:
47
+
48
+ - a one-line **intent** (what this beat does for the viewer),
49
+ - a **duration** (they sum to the target; the hook earns attention in ~3s),
50
+ - a **media need** — real footage is the strongest grounding and CueFrame's home turf, so reach for it
51
+ first; otherwise `generate` a *purposeful* clip (a diagram of the real mechanism, the real UI) or `find`
52
+ stock. Animated text over a gradient is not grounding — it's the slop default,
53
+ - an optional **graphic** (a lower-third, title, CTA card),
54
+ - a **caption** and/or a **VO/script** line.
55
+
56
+ **Ground it, don't invent it.** Pick every graphic/scene from `list_catalog` (filter by `useCase`/`tier`)
57
+ — never hardcode hex or positions or name a component that doesn't exist. Theme from the brand kit. If
58
+ you're planning over real footage, read `get_media_context` (detected faces + transcript) so beat timing,
59
+ crops, and captions land on what's actually there.
60
+
61
+ ## 3. Show the flow, then persist it as a Brief
62
+
63
+ Show the user the beat list **first** — a five-line outline. It is cheap to change here and expensive to
64
+ change after a render, so this is where you converge on structure. On their go, **persist the plan with
65
+ `create_brief`** — the beats/goal/format/gates you just elicited map 1:1 onto its fields, and the plan stops
66
+ being chat-ephemeral (it survives the session, carries a cost quote, and is honored field-by-field):
67
+
68
+ 1. `import_media` / `generate_media` for each beat's media need,
69
+ 2. `create_brief` — goal, audience, platform/format, durationSec, tone, cta, locale, and the beats
70
+ (each with its editorial intent and, when you're cutting real footage, MOMENT PINNING
71
+ `source: {mediaId, startSec, endSec}` from the transcript — honored to-the-frame or refused).
72
+ Relay the response's **quote** (compose + estimated render) BEFORE composing.
73
+ 3. `compose { briefId }` — the Director authors FROM your brief; every field is honored or the
74
+ compose is refused loudly naming the field. Gates: put `holdAt: ["layout"]` in the brief's `gates` when
75
+ the user wants to approve the storyboard mid-flight; `autoApprove: true` for hands-off.
76
+ 4. `score_composition` / `consult` to fix the weakest beat,
77
+ 5. `create_render` for the MP4.
78
+
79
+ **Two graphic media — pick per beat, and review accordingly:** a `card` (verbatim HTML in
80
+ `seededGraphics`) is a STATIC graphic — cheap, approve it from a still; a **component**
81
+ (`create_component`, `useCurrentFrame`) is MOTION — a still is one frame, so preview it before trusting it.
82
+ Seeded graphics you author into the brief are carried VERBATIM as locked clips — the Director never
83
+ re-authors them; `exclusions` bans graphic kinds you never want it to author.
84
+
85
+ Then load **composing-video** and apply its craft to make each beat good.
86
+
87
+ ## Related skills & positioning
88
+
89
+ This skill owns **structure/intake**; its siblings own execution and craft — defer to them:
90
+
91
+ - **composing-video** — the craft/quality layer (grounded specificity vs. slop, the vision → rubric →
92
+ verify loop). Load it *after* you have a flow; it makes each beat good.
93
+ - **cueframe-compose-loop** — the author → render → verify → fix convergence loop + the ship bar.
94
+ - **cueframe-product-video** — click-points → auto-zoom tiling + PiP for screen demos.
95
+ - **cueframe-brand-demo** — brand-token vocabulary + auto intro/outro/logo for branded launches.
96
+ - **cueframe-component-authoring** — fork → preview → push for a custom graphic a beat needs.
97
+ - **cueframe-cli** — the `cueframe` binary + wire mechanics.
98
+
99
+ ## The boundary
100
+
101
+ You own the **vision** (the one idea and the flow for *this* video) and **data correctness** (a wrong
102
+ number you supply is rendered faithfully — the mistake is yours). CueFrame owns being faithful, legible,
103
+ and giving you real footage + real components to plan against. Reason from this; skip the whole flow only
104
+ for a re-render of an approved composition or a single trivial one-off.
@@ -0,0 +1,6 @@
1
+ interface:
2
+ display_name: "CueFrame Storyboard: brief → flow"
3
+ short_description: "Use BEFORE composing when starting a NEW video from scratch and you need to…"
4
+ icon_small: "./assets/icon.svg"
5
+ icon_large: "./assets/icon.svg"
6
+ default_prompt: "Use $cueframe-storyboard before composing when starting a NEW video from scratch and you need to plan its structure — turning a rough ask (\"make a launch video\", \"30s promo\", \"an explainer for our API\") into a concrete beat flow."
@@ -0,0 +1,16 @@
1
+ <svg viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
2
+ <clipPath id="cf-favicon-clip"><circle cx="128" cy="128" r="118"/></clipPath>
3
+ <circle cx="128" cy="128" r="118" fill="#f7c948"/>
4
+ <g clip-path="url(#cf-favicon-clip)">
5
+ <path d="M88 128Q160 40 300-40" fill="none" stroke="#160f08" stroke-width="5"/>
6
+ <path d="M88 128Q170 60 310 20" fill="none" stroke="#160f08" stroke-width="4.5"/>
7
+ <path d="M88 128Q180 80 316 70" fill="none" stroke="#160f08" stroke-width="4.5"/>
8
+ <path d="M88 128Q186 110 320 110" fill="none" stroke="#160f08" stroke-width="4.5"/>
9
+ <path d="M88 128Q186 146 320 146" fill="none" stroke="#160f08" stroke-width="4.5"/>
10
+ <path d="M88 128Q180 176 316 186" fill="none" stroke="#160f08" stroke-width="4.5"/>
11
+ <path d="M88 128Q170 196 310 236" fill="none" stroke="#160f08" stroke-width="4.5"/>
12
+ <path d="M88 128Q160 216 300 296" fill="none" stroke="#160f08" stroke-width="5"/>
13
+ </g>
14
+ <circle cx="88" cy="128" r="20" fill="#160f08"/>
15
+ <circle cx="88" cy="128" r="8" fill="#f7c948"/>
16
+ </svg>
@@ -0,0 +1,87 @@
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, load **`cueframe-connect`** and follow it once.
17
+
18
+ Then straight to deriving — this whole job is minutes when the master is good.
19
+
20
+ ## Inputs
21
+
22
+ - **The master composition** (required): a finished, approved edit — find it via
23
+ `list_compositions` if the user doesn't have the id. If the master isn't done, finish it first
24
+ (this skill multiplies quality AND flaws).
25
+ - **Target aspects**: default all three siblings — 9:16, 1:1, 4:5. The documented derive lane
26
+ starts from a 16:9 master.
27
+ - **Per-platform tweaks**: default none — determinism is the point. Take an explicit ask (e.g.
28
+ "shorter for TikTok") as a separate edit on the derived sibling.
29
+
30
+ ## Workflow
31
+
32
+ Use `cueframe-compose-loop`'s [preview workflow](../cueframe-compose-loop/references/preview-workflow.md)
33
+ for each affected sibling. Check motion as well as layout where the new crop changes visibility.
34
+ A correction to one sibling does not require rendering the master or the other unchanged siblings.
35
+
36
+ 1. **Verify the master is actually done.** It passed its class checklist, its audio was
37
+ decided, its render was approved. Deriving from a draft ships the draft's flaws four times.
38
+ 2. **Derive each sibling.** `derive_composition` per target aspect — the reframe is
39
+ content-aware: it tracks the subject into the new frame instead of letterboxing. Each
40
+ sibling is a real composition you can edit independently afterward; the master is never
41
+ touched.
42
+ 3. **Audit every sibling on real pixels — required, not optional.** `preview_frame` each
43
+ sibling at t=0, hook-end, and each card's midpoint; describe each still. What to look for
44
+ per aspect: the subject's head fully in the vertical frame; cards and captions inside the
45
+ safe area (no critical copy in the outer ~8%); no beat where the tighter crop lost the thing
46
+ the beat exists to show.
47
+ 4. **Fix per-sibling, surgically.** Where a crop or card misbehaves, `apply_composition` on
48
+ THAT sibling — nudge a `setCropIntents` segment, resize a card for the narrower frame
49
+ (re-shell with `applyMotionPreset` in a following call if you replace the card). Don't
50
+ re-edit the story; the story is the master's.
51
+ 5. **Confirm the audio carried.** The master's decided audio — bed, ducking, beat-aligned cuts
52
+ (`materializeGrid` markers), or its intentional silence — rides into each sibling. Verify
53
+ the bed is present and the silence decision, if any, still holds; the sibling's delivery
54
+ note repeats it. If a sibling needs a different bed, `search_resources` honoring the brand
55
+ kit's `musicMood` and swap it on that sibling only.
56
+ 6. **Judge each sibling as its own artifact.** `score_composition` per sibling with the
57
+ master's vision as `editorialIntent`. A 9:16 sibling is a social reel and answers to that
58
+ class's checklist — hook inside 2 seconds still applies in the new crop. Fix worst-first to
59
+ ≥ 7.5.
60
+ 7. **Render each approved sibling.** `create_render` → `wait_job (kind:"render")` per
61
+ composition. One final render per approval; iterate with previews.
62
+
63
+ ## What good looks like
64
+
65
+ Quoted from `video-craft-standards` (cross-cutting rules — every artifact):
66
+
67
+ > **MUST** Safe-area respected: no critical copy in the outer ~8% of frame.
68
+
69
+ > **MUST** One final render per approval; iterate with previews, not renders.
70
+
71
+ > **MUST** Delivery never ends with "done": the last message carries the output link and where
72
+ > to find it, plus the intentional-silence note if any.
73
+
74
+ And the class rule that governs each sibling: a derived 9:16 answers to §1 (Social reel) —
75
+ *"**MUST (K)** The hook lands inside 2 seconds"* — a derived 16:9 to its own class. Derivation
76
+ changes the frame, never the bar.
77
+
78
+ ## Delivering
79
+
80
+ The last message is a manifest, never "done":
81
+
82
+ - Every sibling's render link, labeled by aspect and platform, and where each lives (project +
83
+ composition id — the master's id too, since it stays the source of truth).
84
+ - The master's attribution list (it covers all siblings — same assets).
85
+ - The intentional-silence note, restated once, if the master chose silence.
86
+ - Any sibling-specific edits you made (which crop nudged, which card resized) so future master
87
+ edits know what to re-check after re-deriving.