@cueframe/kernel 0.2.21 → 0.2.23

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 (47) hide show
  1. package/dist/_members/composition/scene/schema.d.ts +76 -1
  2. package/dist/_members/mcp/core.d.ts +16 -1
  3. package/dist/animate/preparation-facts.js +2 -2
  4. package/dist/animate.js +3 -3
  5. package/dist/authoring/scene.js +2 -2
  6. package/dist/authoring.js +2 -2
  7. package/dist/{chunk-DFAESPHN.js → chunk-3OOMVQ6I.js} +11 -5
  8. package/dist/{chunk-IRVRWQWD.js → chunk-7YL7NJJF.js} +9 -4
  9. package/dist/{chunk-TWI22U3C.js → chunk-AMKPFIF4.js} +4 -4
  10. package/dist/{chunk-PSMIDGQA.js → chunk-CDZBSLVA.js} +2 -2
  11. package/dist/{chunk-XUU5PK6J.js → chunk-DEDZKZ6G.js} +2 -2
  12. package/dist/{chunk-EGR6QWLX.js → chunk-E54DK225.js} +1 -1
  13. package/dist/{chunk-OTZDVUAM.js → chunk-EDR75OU7.js} +1 -1
  14. package/dist/{chunk-7UVN36UK.js → chunk-LPFVUT3S.js} +11 -9
  15. package/dist/{chunk-WDJGMAZK.js → chunk-PQDALM2G.js} +5 -5
  16. package/dist/{chunk-VHCP4OLA.js → chunk-PRSRV7AT.js} +6 -6
  17. package/dist/{chunk-STTZC7NN.js → chunk-RGKDDR7H.js} +2475 -2298
  18. package/dist/{chunk-OAVJUZIC.js → chunk-TZ7DKL2G.js} +1 -1
  19. package/dist/{chunk-BWLYZQ7I.js → chunk-VDSO2KZY.js} +1 -1
  20. package/dist/{chunk-IHMKU4PM.js → chunk-WLU5XPDG.js} +2 -2
  21. package/dist/{chunk-HPWJQNBU.js → chunk-YV5AYMNK.js} +1 -1
  22. package/dist/component-runtime/browserOptions.js +2 -2
  23. package/dist/component-runtime/render.js +3 -3
  24. package/dist/component-runtime.js +4 -4
  25. package/dist/compose.js +23 -23
  26. package/dist/composition/scene/schema.json +2 -1
  27. package/dist/composition/scene.js +3 -1
  28. package/dist/composition-ops.js +94 -33
  29. package/dist/core/render.js +3 -3
  30. package/dist/core.js +3 -3
  31. package/dist/mcp/adapter.js +5 -5
  32. package/dist/mcp/core.js +3 -1
  33. package/dist/mcp/curation.js +1 -1
  34. package/dist/mcp/server.js +4 -4
  35. package/dist/mcp.js +8 -8
  36. package/dist/primitives/effects.js +5 -5
  37. package/dist/primitives/hero-text.js +2 -2
  38. package/dist/primitives/layouts.js +4 -4
  39. package/dist/primitives/scenes.js +5 -5
  40. package/dist/primitives/text.js +2 -2
  41. package/dist/primitives/ui-blocks.js +2 -2
  42. package/dist/primitives.js +23 -23
  43. package/dist/render-harness.js +7 -7
  44. package/package.json +10 -10
  45. package/dist/{chunk-VLJOIUHL.js → chunk-A76GTLSA.js} +3 -3
  46. package/dist/{chunk-7SQOXIWR.js → chunk-RL5SO653.js} +3 -3
  47. package/dist/{chunk-ZDL7XEXW.js → chunk-ZS3A3QUM.js} +4 -4
@@ -347,7 +347,82 @@ export declare function sceneShotImageSlots(spec: Pick<SceneShotSpecV2, 'layers'
347
347
  /** Distinct video media ids in first-use order, recursively through groups. */
348
348
  export declare function sceneShotVideoSlots(spec: Pick<SceneShotSpecV2, 'layers'>): string[];
349
349
  export declare function sceneShotSurfaceCount(spec: Pick<SceneShotSpecV2, 'layers'>): number;
350
+ /**
351
+ * What a scene shot IS, for a caller reading the published contract.
352
+ *
353
+ * It lives HERE, on the schema, because it is generated from here into
354
+ * `scene/schema.json` and on into `api/openapi.json`. It used to exist only
355
+ * inside the published `api/openapi.json`, kept alive by the public repo's
356
+ * `vendor-scene-schema.mjs` reading its own previous output and writing it
357
+ * back — a hand-authored value surviving inside a generated artifact, which
358
+ * meant regenerating the contract from source would silently delete the only
359
+ * description of the feature.
360
+ */
361
+ export declare const SCENE_SHOT_SPEC_V2_DESCRIPTION = "A version-2 scene shot: a self-contained 3D world-object shot that scene.add / scene.update materializes into an ordinary component clip. The shot owns its layers, camera, lighting, backdrop and normalized local animation; the composition owns start, duration, ordering, cuts and transitions. Coordinates are REFERENCE PIXELS: origin at frame centre, +X right, +Y down, +Z toward the viewer. referenceSize must have the SAME aspect ratio as the composition format; mismatch fails instead of cropping. At equal aspect ratio the shot scales uniformly by outputWidth/referenceWidth. A segment's easing belongs to the keyframe it ARRIVES at; the first keyframe has no easing. Authoring limits: 32 layers, 4 devices, 16 distinct image slots, 256 keyframes per channel, 2048 keyframes per shot. Version 2 supports nested groups, procedural slab/page/phone/laptop objects, screen- and world-space text, admitted image/component/video surfaces, fixed photographic and generated studio environments, transparent/solid/linear/radial backdrops, constraints, focus, grain and vignette. Raw HTML, custom shader props, imported GLB models, arbitrary external HDR environments, skeletal animation and physics are refused with an exact field path.";
350
362
  /** Agent-facing schema generated from the same Zod contract used by runtime parsing. */
351
- export declare const sceneShotJsonSchema: z.core.ZodStandardJSONSchemaPayload<z.ZodType<SceneShotSpecV2, unknown, z.core.$ZodTypeInternals<SceneShotSpecV2, unknown>>>;
363
+ export declare const sceneShotJsonSchema: {
364
+ description: string;
365
+ "~standard": z.core.ZodStandardSchemaWithJSON<z.ZodType<SceneShotSpecV2, unknown, z.core.$ZodTypeInternals<SceneShotSpecV2, unknown>>>;
366
+ $schema?: "https://json-schema.org/draft/2020-12/schema" | "http://json-schema.org/draft-07/schema#" | "http://json-schema.org/draft-04/schema#";
367
+ $id?: string;
368
+ $anchor?: string;
369
+ $ref?: string;
370
+ $dynamicRef?: string;
371
+ $dynamicAnchor?: string;
372
+ $vocabulary?: Record<string, boolean>;
373
+ $comment?: string;
374
+ $defs?: Record<string, z.core.JSONSchema.JSONSchema>;
375
+ type?: z.core.JSONSchema.SchemaType | z.core.JSONSchema.SchemaType[];
376
+ additionalItems?: z.core.JSONSchema._JSONSchema;
377
+ unevaluatedItems?: z.core.JSONSchema._JSONSchema;
378
+ prefixItems?: z.core.JSONSchema._JSONSchema[];
379
+ items?: z.core.JSONSchema._JSONSchema | z.core.JSONSchema._JSONSchema[];
380
+ contains?: z.core.JSONSchema._JSONSchema;
381
+ additionalProperties?: z.core.JSONSchema._JSONSchema;
382
+ unevaluatedProperties?: z.core.JSONSchema._JSONSchema;
383
+ properties?: Record<string, z.core.JSONSchema._JSONSchema>;
384
+ patternProperties?: Record<string, z.core.JSONSchema._JSONSchema>;
385
+ dependentSchemas?: Record<string, z.core.JSONSchema._JSONSchema>;
386
+ propertyNames?: z.core.JSONSchema._JSONSchema;
387
+ if?: z.core.JSONSchema._JSONSchema;
388
+ then?: z.core.JSONSchema._JSONSchema;
389
+ else?: z.core.JSONSchema._JSONSchema;
390
+ allOf?: z.core.JSONSchema.JSONSchema[];
391
+ anyOf?: z.core.JSONSchema.JSONSchema[];
392
+ oneOf?: z.core.JSONSchema.JSONSchema[];
393
+ not?: z.core.JSONSchema._JSONSchema;
394
+ multipleOf?: number;
395
+ maximum?: number;
396
+ exclusiveMaximum?: number | boolean;
397
+ minimum?: number;
398
+ exclusiveMinimum?: number | boolean;
399
+ maxLength?: number;
400
+ minLength?: number;
401
+ pattern?: string;
402
+ maxItems?: number;
403
+ minItems?: number;
404
+ uniqueItems?: boolean;
405
+ maxContains?: number;
406
+ minContains?: number;
407
+ maxProperties?: number;
408
+ minProperties?: number;
409
+ required?: string[];
410
+ dependentRequired?: Record<string, string[]>;
411
+ enum?: Array<string | number | boolean | null>;
412
+ const?: string | number | boolean | null;
413
+ id?: string;
414
+ title?: string;
415
+ default?: unknown;
416
+ deprecated?: boolean;
417
+ readOnly?: boolean;
418
+ writeOnly?: boolean;
419
+ nullable?: boolean;
420
+ examples?: unknown[];
421
+ format?: string;
422
+ contentMediaType?: string;
423
+ contentEncoding?: string;
424
+ contentSchema?: z.core.JSONSchema.JSONSchema;
425
+ _prefault?: unknown;
426
+ };
352
427
  export declare function sceneShotJsonSchemaText(): string;
353
428
  export {};
@@ -38,6 +38,19 @@ export type ToolResult = {
38
38
  structuredContent?: Record<string, unknown>;
39
39
  };
40
40
  export declare function text(s: string): ToolResult;
41
+ /**
42
+ * A JSON response, carried BOTH ways: the rendered prose a human reads, and the
43
+ * parsed object a program can consume.
44
+ *
45
+ * Curated tools used to return prose only, so `create_render` promised
46
+ * `{id,status,warnings?}` and delivered "Render queued.\n\nrenderId: …". A
47
+ * generic MCP consumer had to scrape it (CUE-15 P0). `structuredContent` is the
48
+ * protocol's channel for exactly this; the text block stays as display.
49
+ *
50
+ * Attached only for a non-null, non-array OBJECT, which is what the protocol
51
+ * allows — a bare array or scalar would be rejected by a validating client.
52
+ */
53
+ export declare function textWithData(s: string, data: unknown): ToolResult;
41
54
  export declare function errText(s: string): ToolResult;
42
55
  export declare function firstText(r: ToolResult): string;
43
56
  export declare function sniffImageMediaType(base64: string): string | undefined;
@@ -45,7 +58,9 @@ export declare function sniffAudioMediaType(base64: string): string | undefined;
45
58
  export declare function withMedia(payload: string, media: {
46
59
  data: string;
47
60
  kind: 'image' | 'audio';
48
- }[]): ToolResult;
61
+ }[],
62
+ /** The parsed response, carried alongside the media for programmatic callers. */
63
+ data?: unknown): ToolResult;
49
64
  export declare function fetchAsBase64(url: string, opts?: {
50
65
  timeoutMs?: number;
51
66
  maxBytes?: number;
@@ -4,11 +4,11 @@ import {
4
4
  sceneGrainPreparationCpuAllocationV1,
5
5
  scenePresetBuilderDescriptorV1,
6
6
  sceneSlabPreparationFactsV1
7
- } from "../chunk-OAVJUZIC.js";
7
+ } from "../chunk-TZ7DKL2G.js";
8
8
  import {
9
9
  photographicStudioPreparationFactsV1,
10
10
  sceneFocusPreparationAllocationsV1
11
- } from "../chunk-IRVRWQWD.js";
11
+ } from "../chunk-7YL7NJJF.js";
12
12
  import "../chunk-2L7PYYJK.js";
13
13
  import "../chunk-2ESYSVXG.js";
14
14
  export {
package/dist/animate.js CHANGED
@@ -102,7 +102,7 @@ import {
102
102
  useStage,
103
103
  weightsAt,
104
104
  worldTransform
105
- } from "./chunk-XUU5PK6J.js";
105
+ } from "./chunk-DEDZKZ6G.js";
106
106
  import {
107
107
  DEFAULT_LIGHTING_PROFILE,
108
108
  DEVICE_GLASS_OPACITY_ENCODED,
@@ -161,7 +161,7 @@ import {
161
161
  studioShadowFrustum,
162
162
  verifyPhotographicStudioHdr,
163
163
  withNormalisedFaceUv
164
- } from "./chunk-OAVJUZIC.js";
164
+ } from "./chunk-TZ7DKL2G.js";
165
165
  import {
166
166
  ALLOWED_BAKE_SCALES,
167
167
  DEFAULT_BAKE_SCALE,
@@ -183,7 +183,7 @@ import {
183
183
  projectedSlotEdges,
184
184
  sceneFocusPreparationAllocationsV1,
185
185
  selectSceneBakeScale
186
- } from "./chunk-IRVRWQWD.js";
186
+ } from "./chunk-7YL7NJJF.js";
187
187
  import "./chunk-2L7PYYJK.js";
188
188
  import "./chunk-AVTEPAWI.js";
189
189
  import "./chunk-2ESYSVXG.js";
@@ -13,7 +13,7 @@ import {
13
13
  sceneTrackIdFor,
14
14
  validateSceneAdd,
15
15
  validateSceneUpdate
16
- } from "../chunk-EGR6QWLX.js";
16
+ } from "../chunk-E54DK225.js";
17
17
  import {
18
18
  SCENE_TRANSITION_KINDS,
19
19
  collectSceneClipIssues,
@@ -22,7 +22,7 @@ import {
22
22
  offFrameLattice,
23
23
  readSceneSourceRef,
24
24
  sceneClipShapeIssues
25
- } from "../chunk-IRVRWQWD.js";
25
+ } from "../chunk-7YL7NJJF.js";
26
26
  import "../chunk-2L7PYYJK.js";
27
27
  import "../chunk-2ESYSVXG.js";
28
28
  export {
package/dist/authoring.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  hasSceneOp,
5
5
  isSceneOp,
6
6
  materializeSceneOpsCore
7
- } from "./chunk-EGR6QWLX.js";
7
+ } from "./chunk-E54DK225.js";
8
8
  import {
9
9
  ZERO_USAGE,
10
10
  buildDirectorTools,
@@ -67,7 +67,7 @@ import "./chunk-7PA7FGLD.js";
67
67
  import {
68
68
  collectSceneClipIssues,
69
69
  isSceneShotClip
70
- } from "./chunk-IRVRWQWD.js";
70
+ } from "./chunk-7YL7NJJF.js";
71
71
  import "./chunk-2L7PYYJK.js";
72
72
  import "./chunk-AVTEPAWI.js";
73
73
  import "./chunk-2ESYSVXG.js";
@@ -312,7 +312,7 @@ Call wait_job(kind="compose", id="${j.composeJobId}", projectId="${a.projectId}"
312
312
  name: "apply_composition",
313
313
  operationId: "applyComposition",
314
314
  pathArgs: { projectId: "id" },
315
- description: 'Atomically apply an array of CompositionOps to a project composition. All ops succeed or none do (transactional). Pass `if_match` for optimistic-concurrency control (409 stale_etag on mismatch) and `dry_run: true` to validate the batch without persisting. Use this to seed a composition (add media clips) or make targeted edits (set a crop intent, reorder clips, set the format). CAPTIONS: attach content with {type:"captions.fromTranscript", mediaId, window?} \u2014 the server slices the cached word-timed transcript, rebases times, and sentence-splits into segments (no pasting words; 422 media_no_transcript if the media has no speech); style it with {type:"setCaptionStyle", style}; or set explicit words with {type:"setCaptions", segments, style?} (e.g. translations or your own VO timings). Brand is NOT set here \u2014 it lives on the project (create_project / PATCH /projects/:id with brandKitId). CARDS: a {kind:"card", html, tokens} clip projects each `tokens` KEY `x` to the CSS custom property `--cf-x`, so the html must read it as `var(--cf-x)` \u2014 write `tokens:{"plate":"#0af"}` + `background:var(--cf-plate)`. Do NOT put dashes in the key: `"--plate"` becomes `--cf---plate` and your `var(--plate)` then resolves to NOTHING, which CSS silently degrades to a transparent background and black text. Responses carry `warnings[]` when a card reads a var nothing defines. SCENE SHOTS: for a 3D product shot \u2014 a tilted page screenshot, a lit laptop/phone showing a real screenshot, two-colour type, a colour-field backdrop, focus/grain/vignette and a camera move \u2014 use {type:"scene.add", clipId, newTrack|trackId, startTime, duration, scene, assets} and revise it with {type:"scene.update", clipId, scene?, assets?, startTime?, duration?}. You author a scene SPEC, never wrapper TSX; the server registers the component for you. There is NO built-in scene primitive in list_catalog \u2014 READ cueframe://scene-shot first for the JSON schema, the canonical V2 world-objects recipe with nested groups, slabs, pages, phones, laptops, world/screen text, admitted surfaces, camera motion, lighting, and the current resource limits.',
315
+ description: 'Atomically apply an array of CompositionOps to a project composition. All ops succeed or none do (transactional). Pass `if_match` for optimistic-concurrency control (409 stale_etag on mismatch) and `dry_run: true` to validate the batch without persisting. Use this to seed a composition (add media clips) or make targeted edits (set a crop intent, reorder clips, set the format). CAPTIONS: attach content with {type:"captions.fromTranscript", mediaId, window?} \u2014 the server slices the cached word-timed transcript, rebases times, and sentence-splits into segments (no pasting words; 422 media_no_transcript if the media has no speech); style it with {type:"setCaptionStyle", style}; or set explicit words with {type:"setCaptions", segments, style?} (e.g. translations or your own VO timings). Brand is NOT set here \u2014 it lives on the project (create_project / update_project with brandKitId \u2014 or PATCH /projects/:id over REST). CARDS: a {kind:"card", html, tokens} clip projects each `tokens` KEY `x` to the CSS custom property `--cf-x`, so the html must read it as `var(--cf-x)` \u2014 write `tokens:{"plate":"#0af"}` + `background:var(--cf-plate)`. Do NOT put dashes in the key: `"--plate"` becomes `--cf---plate` and your `var(--plate)` then resolves to NOTHING, which CSS silently degrades to a transparent background and black text. Responses carry `warnings[]` when a card reads a var nothing defines. SCENE SHOTS: for a 3D product shot \u2014 a tilted page screenshot, a lit laptop/phone showing a real screenshot, two-colour type, a colour-field backdrop, focus/grain/vignette and a camera move \u2014 use {type:"scene.add", clipId, newTrack|trackId, startTime, duration, scene, assets} and revise it with {type:"scene.update", clipId, scene?, assets?, startTime?, duration?}. You author a scene SPEC, never wrapper TSX; the server registers the component for you. There is NO built-in scene primitive in list_catalog \u2014 READ cueframe://scene-shot first for the JSON schema, the canonical V2 world-objects recipe with nested groups, slabs, pages, phones, laptops, world/screen text, admitted surfaces, camera motion, lighting, and the current resource limits.',
316
316
  okFormat: (j, a) => {
317
317
  const warns = formatWarnings(j);
318
318
  if (j && typeof j.valid === "boolean") {
@@ -348,7 +348,7 @@ ${JSON.stringify(r.errors ?? [], null, 2)}${warns}`;
348
348
  name: "create_render",
349
349
  operationId: "createRender",
350
350
  pathArgs: { projectId: "id" },
351
- description: "Queue an MP4 render of a project's composition. Returns { id (renderId), status, warnings? } \u2014 `warnings[]` carries non-fatal advisories (omitted when none). The render themes from the project's brand kit (bind one via create_project / PATCH /projects/:id with brandKitId; without one the output is unbranded). Then call wait_job(kind=\"render\", id=renderId, projectId=...) to block until the file is ready and get the download URL, or register a webhook (create_webhook on render.completed \u2014 status rides the payload).",
351
+ description: "Queue an MP4 render of a project's composition. Returns { id (renderId), status, warnings? } \u2014 `warnings[]` carries non-fatal advisories (omitted when none). The render themes from the project's brand kit (bind one via create_project / update_project with brandKitId \u2014 or PATCH /projects/:id over REST; without one the output is unbranded). Then call wait_job(kind=\"render\", id=renderId, projectId=...) to block until the file is ready and get the download URL, or register a webhook (create_webhook on render.completed \u2014 status rides the payload).",
352
352
  okFormat: (j, a) => `Render queued.
353
353
 
354
354
  renderId: ${j.id}
@@ -552,7 +552,7 @@ Poll get_media_facts(mediaItemId="${a.mediaItemId}", kind="${a.body?.kind}", sta
552
552
  {
553
553
  name: "create_project",
554
554
  operationId: "createProject",
555
- description: "Create a new project \u2014 the unit you compose and render into. compose / apply_composition / create_render / the preview family all require a projectId; this mints one. Pass name (required) plus optionally a format (aspectRatio/fps/resolution) and brandKitId. brandKitId binds a brand kit to the PROJECT (pass the kitId from create_brand_kit): colors/fonts/motion theme every render of this project automatically (omit it and the output is unbranded). Bind or change it later via PATCH /projects/:id. Returns the ProjectResponse (id + metadata)."
555
+ description: "Create a new project \u2014 the unit you compose and render into. compose / apply_composition / create_render / the preview family all require a projectId; this mints one. Pass name (required) plus optionally a format (aspectRatio/fps/resolution) and brandKitId. brandKitId binds a brand kit to the PROJECT (pass the kitId from create_brand_kit): colors/fonts/motion theme every render of this project automatically (omit it and the output is unbranded). Bind or change it later via update_project (PATCH /projects/:id over REST). Returns the ProjectResponse (id + metadata)."
556
556
  },
557
557
  {
558
558
  name: "new_composition",
@@ -639,10 +639,16 @@ Render it with create_render(projectId="${a.projectId}", body={ compositionId: "
639
639
  },
640
640
  annotations: { readOnlyHint: true }
641
641
  },
642
+ {
643
+ name: "list_render_fonts",
644
+ operationId: "listRenderFonts",
645
+ description: "The fonts the RENDERER can actually draw \u2014 read this BEFORE authoring type, not after a refusal. Per family: the exact family name authoring accepts, the weight RANGES a shipped file declares (a static face has min===max; a variable face gives its axis range), the caption default weights, and whether the bytes are bundled or an aliased metric-compatible stand-in. Anything listed here passes validation by construction: it is derived from the same table the font gate refuses by. Two facts worth reading off it \u2014 every family's `styles` is [\"normal\"], because NO bundled family ships an italic FILE (a real italic comes only from a brand-kit font asset), and a weight outside every range is REFUSED, never synthesised. Contrast search_fonts, which searches the GOOGLE catalog and will happily return families the renderer cannot draw. `manifestVersion` identifies this exact face table; record it beside a composition to state what a font choice was validated against. Covers the bundled set only \u2014 a brand kit's sealed faces are per-org and per-render. No args, read-only, free.",
646
+ annotations: { readOnlyHint: true }
647
+ },
642
648
  {
643
649
  name: "search_fonts",
644
650
  operationId: "searchFonts",
645
- description: "Search web font families by name/style \u2014 returns family names to use in composition/component params. Pass query (+ optional perPage \u226450). Read-only + free; surfaces the Google Fonts catalog (family + category + variants + css2 stylesheet URL). IMPORTANT: this searches the GOOGLE catalog, not what the render can actually draw. Only the faces vendored into the render page are guaranteed to rasterize; naming any other family gets you the generic fallback (Liberation Sans) with no error. create_render returns a `font_not_available` warning naming the guaranteed set \u2014 treat that set, not this catalog, as the list you may choose from. An empty result set here means no match, or the upstream catalog was unavailable.",
651
+ description: "Search web font families by name/style \u2014 returns family names to use in composition/component params. Pass query (+ optional perPage \u226450). Read-only + free; surfaces the Google Fonts catalog (family + category + variants + css2 stylesheet URL). IMPORTANT: this searches the GOOGLE catalog, not what the render can actually draw. Only the faces vendored into the render page are guaranteed to rasterize; naming any other family gets you the generic fallback (Liberation Sans) with no error. Call list_render_fonts for the set you may actually choose from, WITH the admitted weights per family \u2014 treat that, not this catalog, as the list. An empty result set here means no match, or the upstream catalog was unavailable.",
646
652
  okFormat: (j) => `${(j.results || []).length} fonts: ${(j.results || []).map((r) => r.family).slice(0, 10).join(", ")}`,
647
653
  annotations: { readOnlyHint: true }
648
654
  },
@@ -800,7 +806,7 @@ Render it with create_render(projectId="${a.projectId}", body={ compositionId: "
800
806
  {
801
807
  name: "create_brand_kit",
802
808
  operationId: "createBrandKit",
803
- description: "Create or UPSERT a brand kit (re-POSTing the same kitId updates it in place \u2014 this is also the brand-kit UPDATE path). Sets fonts/colors/logo. This is brand step 0 of the workflow: author the kit, then bind it to a PROJECT so colors/fonts/motion theme the output AUTOMATICALLY \u2014 pass its kitId as brandKitId to create_project, or attach it to an existing project via PATCH /projects/:id. Without a bound kit, create_render produces UNBRANDED output. Tenant-scoped (no project arg)."
809
+ description: "Create or UPSERT a brand kit (re-POSTing the same kitId updates it in place \u2014 this is also the brand-kit UPDATE path). Sets fonts/colors/logo. This is brand step 0 of the workflow: author the kit, then bind it to a PROJECT so colors/fonts/motion theme the output AUTOMATICALLY \u2014 pass its kitId as brandKitId to create_project, or attach it to an existing project via update_project (PATCH /projects/:id over REST). Without a bound kit, create_render produces UNBRANDED output. Tenant-scoped (no project arg)."
804
810
  },
805
811
  {
806
812
  name: "extract_brand_kit",
@@ -1172,10 +1172,14 @@ function sceneShotSurfaceCount(spec2) {
1172
1172
  });
1173
1173
  return count;
1174
1174
  }
1175
- var sceneShotJsonSchema = z.toJSONSchema(SceneShotSpecV2Schema, {
1176
- target: "draft-2020-12",
1177
- io: "input"
1178
- });
1175
+ var SCENE_SHOT_SPEC_V2_DESCRIPTION = "A version-2 scene shot: a self-contained 3D world-object shot that scene.add / scene.update materializes into an ordinary component clip. The shot owns its layers, camera, lighting, backdrop and normalized local animation; the composition owns start, duration, ordering, cuts and transitions. Coordinates are REFERENCE PIXELS: origin at frame centre, +X right, +Y down, +Z toward the viewer. referenceSize must have the SAME aspect ratio as the composition format; mismatch fails instead of cropping. At equal aspect ratio the shot scales uniformly by outputWidth/referenceWidth. A segment's easing belongs to the keyframe it ARRIVES at; the first keyframe has no easing. Authoring limits: 32 layers, 4 devices, 16 distinct image slots, 256 keyframes per channel, 2048 keyframes per shot. Version 2 supports nested groups, procedural slab/page/phone/laptop objects, screen- and world-space text, admitted image/component/video surfaces, fixed photographic and generated studio environments, transparent/solid/linear/radial backdrops, constraints, focus, grain and vignette. Raw HTML, custom shader props, imported GLB models, arbitrary external HDR environments, skeletal animation and physics are refused with an exact field path.";
1176
+ var sceneShotJsonSchema = {
1177
+ ...z.toJSONSchema(SceneShotSpecV2Schema, {
1178
+ target: "draft-2020-12",
1179
+ io: "input"
1180
+ }),
1181
+ description: SCENE_SHOT_SPEC_V2_DESCRIPTION
1182
+ };
1179
1183
  function sceneShotJsonSchemaText() {
1180
1184
  return `${JSON.stringify(sceneShotJsonSchema, null, 2)}
1181
1185
  `;
@@ -3437,6 +3441,7 @@ export {
3437
3441
  sceneShotImageSlots,
3438
3442
  sceneShotVideoSlots,
3439
3443
  sceneShotSurfaceCount,
3444
+ SCENE_SHOT_SPEC_V2_DESCRIPTION,
3440
3445
  sceneShotJsonSchema,
3441
3446
  sceneShotJsonSchemaText,
3442
3447
  contentFrame,
@@ -1,9 +1,9 @@
1
- import {
2
- EASING_BY_INTENT
3
- } from "./chunk-MFHXCHRI.js";
4
1
  import {
5
2
  FitText
6
3
  } from "./chunk-XHGZ2E77.js";
4
+ import {
5
+ EASING_BY_INTENT
6
+ } from "./chunk-MFHXCHRI.js";
7
7
  import {
8
8
  ACCENT,
9
9
  ACCENT_STRONG,
@@ -26,7 +26,7 @@ import {
26
26
  perspectiveFor,
27
27
  resolveCamera,
28
28
  useStage
29
- } from "./chunk-XUU5PK6J.js";
29
+ } from "./chunk-DEDZKZ6G.js";
30
30
 
31
31
  // ../execution/primitives/src/effects/blur/index.tsx
32
32
  import React2 from "react";
@@ -15,7 +15,7 @@ import {
15
15
  componentBrowserBackend,
16
16
  componentBrowserOptions,
17
17
  readGpuAttestation
18
- } from "./chunk-BWLYZQ7I.js";
18
+ } from "./chunk-VDSO2KZY.js";
19
19
  import {
20
20
  ComponentCapturePageRasterAttestationV1,
21
21
  ComponentGraphicsApiV2,
@@ -28,7 +28,7 @@ import {
28
28
  } from "./chunk-ZVG446DJ.js";
29
29
  import {
30
30
  parseSceneShotSpecV2
31
- } from "./chunk-IRVRWQWD.js";
31
+ } from "./chunk-7YL7NJJF.js";
32
32
  import {
33
33
  BUNDLED_FONT_FACES
34
34
  } from "./chunk-AVTEPAWI.js";
@@ -19,7 +19,7 @@ import {
19
19
  slabTriangleCount,
20
20
  takeSceneEnvironment,
21
21
  useSceneActualResourceRegistrarV1
22
- } from "./chunk-OAVJUZIC.js";
22
+ } from "./chunk-TZ7DKL2G.js";
23
23
  import {
24
24
  PHOTOGRAPHIC_STUDIO_RIG_ID,
25
25
  SCENE_SLAB_CONTENT_OFFSET,
@@ -31,7 +31,7 @@ import {
31
31
  sceneTextureBytes,
32
32
  sceneVideoMidpointAddressV1,
33
33
  selectSceneBakeScale
34
- } from "./chunk-IRVRWQWD.js";
34
+ } from "./chunk-7YL7NJJF.js";
35
35
  import {
36
36
  resolveCaptionFaces
37
37
  } from "./chunk-AVTEPAWI.js";
@@ -8,7 +8,7 @@ import {
8
8
  sceneShotImageSlots,
9
9
  sceneShotVideoSlots,
10
10
  sceneSpecIssues
11
- } from "./chunk-IRVRWQWD.js";
11
+ } from "./chunk-7YL7NJJF.js";
12
12
 
13
13
  // ../authoring/src/scene/validate.ts
14
14
  var SceneAuthoringError = class extends Error {
@@ -5,7 +5,7 @@ import {
5
5
  isOk,
6
6
  opById,
7
7
  safeParse
8
- } from "./chunk-STTZC7NN.js";
8
+ } from "./chunk-RGKDDR7H.js";
9
9
 
10
10
  // ../mcp/src/wait.ts
11
11
  var defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
@@ -2,7 +2,10 @@ import {
2
2
  querySchemaShape,
3
3
  serializeQuery,
4
4
  waitForJob
5
- } from "./chunk-OTZDVUAM.js";
5
+ } from "./chunk-EDR75OU7.js";
6
+ import {
7
+ CURATED_TOOLS
8
+ } from "./chunk-3OOMVQ6I.js";
6
9
  import {
7
10
  GENERATED_OPERATIONS,
8
11
  apiErrorFrom,
@@ -18,11 +21,9 @@ import {
18
21
  safeParse,
19
22
  sniffImageMediaType,
20
23
  text,
24
+ textWithData,
21
25
  withMedia
22
- } from "./chunk-STTZC7NN.js";
23
- import {
24
- CURATED_TOOLS
25
- } from "./chunk-DFAESPHN.js";
26
+ } from "./chunk-RGKDDR7H.js";
26
27
 
27
28
  // ../mcp/src/prompts.ts
28
29
  var skillListCache = null;
@@ -2948,7 +2949,8 @@ var SCENE_SHOT_SCHEMA = deepFreeze({
2948
2949
  }
2949
2950
  ]
2950
2951
  }
2951
- }
2952
+ },
2953
+ "description": "A version-2 scene shot: a self-contained 3D world-object shot that scene.add / scene.update materializes into an ordinary component clip. The shot owns its layers, camera, lighting, backdrop and normalized local animation; the composition owns start, duration, ordering, cuts and transitions. Coordinates are REFERENCE PIXELS: origin at frame centre, +X right, +Y down, +Z toward the viewer. referenceSize must have the SAME aspect ratio as the composition format; mismatch fails instead of cropping. At equal aspect ratio the shot scales uniformly by outputWidth/referenceWidth. A segment's easing belongs to the keyframe it ARRIVES at; the first keyframe has no easing. Authoring limits: 32 layers, 4 devices, 16 distinct image slots, 256 keyframes per channel, 2048 keyframes per shot. Version 2 supports nested groups, procedural slab/page/phone/laptop objects, screen- and world-space text, admitted image/component/video surfaces, fixed photographic and generated studio environments, transparent/solid/linear/radial backdrops, constraints, focus, grain and vignette. Raw HTML, custom shader props, imported GLB models, arbitrary external HDR environments, skeletal animation and physics are refused with an exact field path."
2952
2954
  });
2953
2955
  var SCENE_SHOT_SCHEMA_DESCRIPTION = "A version-2 scene shot: a self-contained 3D world-object shot that scene.add / scene.update materializes into an ordinary component clip. The shot owns its layers, camera, lighting, backdrop and normalized local animation; the composition owns start, duration, ordering, cuts and transitions. Coordinates are REFERENCE PIXELS: origin at frame centre, +X right, +Y down, +Z toward the viewer. referenceSize must have the SAME aspect ratio as the composition format; mismatch fails instead of cropping. At equal aspect ratio the shot scales uniformly by outputWidth/referenceWidth. A segment's easing belongs to the keyframe it ARRIVES at; the first keyframe has no easing. Authoring limits: 32 layers, 4 devices, 16 distinct image slots, 256 keyframes per channel, 2048 keyframes per shot. Version 2 supports nested groups, procedural slab/page/phone/laptop objects, screen- and world-space text, admitted image/component/video surfaces, fixed photographic and generated studio environments, transparent/solid/linear/radial backdrops, constraints, focus, grain and vignette. Raw HTML, custom shader props, imported GLB models, arbitrary external HDR environments, skeletal animation and physics are refused with an exact field path.";
2954
2956
  var SCENE_SHOT_EXAMPLE_SHOTS = deepFreeze([
@@ -3615,7 +3617,7 @@ function registerResources(server, ex) {
3615
3617
  }),
3616
3618
  {
3617
3619
  title: "Component catalog",
3618
- description: "The component catalog: the FULL built-in primitive catalog (96 primitives + 7 scenes \u2014 lower-third, cinematic-title, color-grade, the scenes \u2026) PLUS your org-installed custom components. This is 'discover what to build with'. resources/list enumerates EVERY entry with its discovery facets (source/category/kind/tier/useCase) and a placement hint; read one for its full prop schema. NOT only your authored components. URI: cueframe://component/{componentId}.",
3620
+ description: "The component catalog: the FULL built-in primitive catalog (lower-third, cinematic-title, color-grade, the `scenes`-category templates \u2026) PLUS your org-installed custom components. This is 'discover what to build with'. resources/list enumerates EVERY entry with its discovery facets (source/category/kind/tier/useCase) and a placement hint; read one for its full prop schema. NOT only your authored components. NOTE the word 'scene' means two different things: the `scenes` CATEGORY here is composed built-in templates you place by primitiveId, whereas a SCENE SHOT (the scene.add op, cueframe://scene-shot) is a 3D spec you author and has no catalog entry at all. URI: cueframe://component/{componentId}.",
3619
3621
  mimeType: "application/json"
3620
3622
  },
3621
3623
  async (uri, { componentId }) => jsonResource(uri, await read(ex, "getComponent", () => String(componentId)))
@@ -3759,9 +3761,9 @@ function registerCuratedTools(server, ex, opts) {
3759
3761
  const urls = spec.preview.urls(json).filter(Boolean);
3760
3762
  const data = await fetchPreviews(urls, spec.preview.cap ?? 12);
3761
3763
  report({ preview: { urls: urls.length, fetched: data.length } });
3762
- if (data.length) return withMedia(payload, data.map((d) => ({ data: d, kind })));
3764
+ if (data.length) return withMedia(payload, data.map((d) => ({ data: d, kind })), json);
3763
3765
  }
3764
- return text(payload);
3766
+ return textWithData(payload, json);
3765
3767
  }, query);
3766
3768
  } catch (err) {
3767
3769
  return errText(`${spec.name} failed: ${fmtErr(err)}`);
@@ -7,10 +7,6 @@ import {
7
7
  flattenCompoundClips,
8
8
  hasCompoundClips
9
9
  } from "./chunk-QISFYLBB.js";
10
- import {
11
- compositionHasVo,
12
- roleDefaultGainDb
13
- } from "./chunk-VZ7TYX6Z.js";
14
10
  import {
15
11
  DOMINANCE_WEIGHTS,
16
12
  ENTER_SEC,
@@ -29,6 +25,10 @@ import {
29
25
  segmentShots,
30
26
  stabilizeSelectionHysteresis
31
27
  } from "./chunk-K4VE64CR.js";
28
+ import {
29
+ compositionHasVo,
30
+ roleDefaultGainDb
31
+ } from "./chunk-VZ7TYX6Z.js";
32
32
  import {
33
33
  SHOT_SCALE_TARGET,
34
34
  shotScaleZoom
@@ -51,7 +51,7 @@ import {
51
51
  sceneFullMipLevels,
52
52
  sceneTextureBytes,
53
53
  selectSceneBakeScale
54
- } from "./chunk-IRVRWQWD.js";
54
+ } from "./chunk-7YL7NJJF.js";
55
55
  import {
56
56
  SCENE_CONTEXT_GL_BUDGET_BYTES,
57
57
  SCENE_MAX_TRIANGLES,
@@ -1,3 +1,7 @@
1
+ import {
2
+ frostedGlassWipe,
3
+ spatialPush
4
+ } from "./chunk-QGAWDLYX.js";
1
5
  import {
2
6
  DashboardPopulate
3
7
  } from "./chunk-S5H6GH6M.js";
@@ -7,10 +11,6 @@ import {
7
11
  import {
8
12
  EASING_BY_INTENT
9
13
  } from "./chunk-MFHXCHRI.js";
10
- import {
11
- frostedGlassWipe,
12
- spatialPush
13
- } from "./chunk-QGAWDLYX.js";
14
14
  import {
15
15
  ACCENT,
16
16
  ACCENT_SOFT,
@@ -43,14 +43,14 @@ import {
43
43
  makeDefaultScreenTexture,
44
44
  resolveCamera,
45
45
  useImageTexture
46
- } from "./chunk-XUU5PK6J.js";
46
+ } from "./chunk-DEDZKZ6G.js";
47
47
  import {
48
48
  DEVICE_GLASS_OPACITY_ENCODED,
49
49
  DeviceMesh,
50
50
  StudioRig,
51
51
  deviceDimensions,
52
52
  laptopLayout
53
- } from "./chunk-OAVJUZIC.js";
53
+ } from "./chunk-TZ7DKL2G.js";
54
54
 
55
55
  // ../execution/primitives/src/scenes/changelog-bite/index.tsx
56
56
  import {