@cueframe/kernel 0.1.2 → 0.1.4

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 (126) hide show
  1. package/dist/_members/authoring/agent/errors.d.ts +8 -0
  2. package/dist/_members/authoring/index.d.ts +1 -1
  3. package/dist/_members/authoring/motion/materializeMotionPresetOps.d.ts +4 -0
  4. package/dist/_members/authoring/prompts/index.d.ts +0 -1
  5. package/dist/_members/authoring/types.d.ts +1 -1
  6. package/dist/_members/cloud-import/CloudImportService.d.ts +3 -4
  7. package/dist/_members/cloud-import/ImportProvider.d.ts +3 -7
  8. package/dist/_members/cloud-import/cloudConfig.d.ts +0 -6
  9. package/dist/_members/cloud-import/index.d.ts +2 -4
  10. package/dist/_members/composition/graphics-plan/schemas.d.ts +20 -20
  11. package/dist/_members/composition/primitive-catalog/projection.d.ts +2 -1
  12. package/dist/_members/composition/projection/behind-readiness.d.ts +4 -2
  13. package/dist/_members/composition/validators/brandKit.d.ts +54 -94
  14. package/dist/_members/composition/validators/composePlan.d.ts +52 -52
  15. package/dist/_members/composition/validators/composition.d.ts +213 -253
  16. package/dist/_members/composition/validators/font.d.ts +2 -2
  17. package/dist/_members/composition/validators/index.d.ts +1 -0
  18. package/dist/_members/composition/validators/opaqueId.d.ts +13 -0
  19. package/dist/_members/composition/validators/project.d.ts +11 -15
  20. package/dist/_members/composition/validators/render.d.ts +372 -534
  21. package/dist/_members/composition/validators/session.d.ts +19 -39
  22. package/dist/_members/composition/validators/webhook.d.ts +8 -16
  23. package/dist/_members/composition-ops/index.d.ts +192 -228
  24. package/dist/_members/director/ai-sdk/messages.d.ts +2 -2
  25. package/dist/_members/director/domain/chat.d.ts +4 -4
  26. package/dist/_members/director/testing/contract.d.ts +1 -1
  27. package/dist/_members/errors/registry.d.ts +115 -1
  28. package/dist/_members/mcp/adapter.d.ts +19 -0
  29. package/dist/_members/mcp/core.d.ts +1 -1
  30. package/dist/_members/mcp/curation.d.ts +4 -0
  31. package/dist/_members/mcp/generated/harness.d.ts +1 -1
  32. package/dist/_members/mcp/generated/operations.d.ts +12 -0
  33. package/dist/_members/mcp/wait.d.ts +1 -1
  34. package/dist/_members/media-model/api.d.ts +53 -109
  35. package/dist/_members/media-model/generation.d.ts +2 -2
  36. package/dist/_members/media-model/index.d.ts +1 -0
  37. package/dist/_members/media-model/opaqueId.d.ts +10 -0
  38. package/dist/_members/render-harness/localRender.d.ts +3 -0
  39. package/dist/_members/render-harness/localRender.d.ts.map +1 -1
  40. package/dist/_members/render-harness/remotion-runtime.d.ts +53 -0
  41. package/dist/authoring/build-tools.js +6 -6
  42. package/dist/authoring/context.js +4 -4
  43. package/dist/authoring/prompts.js +1 -5
  44. package/dist/authoring/tools.js +5 -5
  45. package/dist/authoring.js +40 -27
  46. package/dist/chunk-2SNY75AR.js +498 -0
  47. package/dist/{chunk-XQ72DZKJ.js → chunk-7TQCR7AB.js} +1 -1
  48. package/dist/{chunk-QETYXKQQ.js → chunk-7V3F5HO4.js} +97 -14
  49. package/dist/{chunk-BZZTVOGG.js → chunk-D2EGO543.js} +5 -5
  50. package/dist/{chunk-ZPLJ24OV.js → chunk-D6S3ZKIY.js} +1 -1
  51. package/dist/{chunk-K2IUBCND.js → chunk-HFC3MKXA.js} +0 -51
  52. package/dist/{chunk-ICSZF37W.js → chunk-JRIPQ7DN.js} +1 -1
  53. package/dist/{chunk-TFGKUWHY.js → chunk-JTVFIN6H.js} +15 -19
  54. package/dist/{chunk-DCVJWGIA.js → chunk-JY26PIRP.js} +2 -2
  55. package/dist/{chunk-DWLNPNC4.js → chunk-LSP4HN5N.js} +1 -1
  56. package/dist/{chunk-AO744WIK.js → chunk-PJ4R4N4Q.js} +123 -38
  57. package/dist/{chunk-VFMW3JUY.js → chunk-QSDFTYKV.js} +1 -1
  58. package/dist/{chunk-LLUW26BS.js → chunk-R5BMJ2NX.js} +38 -2
  59. package/dist/{chunk-W3SIWT7J.js → chunk-RQ2G4DXI.js} +406 -174
  60. package/dist/{chunk-VHF66LCQ.js → chunk-RXCEPCAQ.js} +102 -41
  61. package/dist/{chunk-LJ5W4ZBU.js → chunk-TLVPDT4R.js} +1 -1
  62. package/dist/{chunk-PIURX6IZ.js → chunk-WTT3GGCA.js} +9 -4
  63. package/dist/{chunk-CAJQ7H5A.js → chunk-YE3F4LNJ.js} +17 -17
  64. package/dist/{chunk-TD347SSX.js → chunk-YXEZ75MB.js} +31 -20
  65. package/dist/{chunk-TPA6PYN2.js → chunk-ZBRPF6GV.js} +25 -10
  66. package/dist/cloud-import.js +20 -116
  67. package/dist/compose/renderer.js +17 -17
  68. package/dist/compose.js +18 -18
  69. package/dist/composition/graphics-plan.js +1 -1
  70. package/dist/composition/ops.js +3 -3
  71. package/dist/composition/primitive-catalog.js +1 -1
  72. package/dist/composition/projection.js +2 -2
  73. package/dist/composition/validators.js +4 -2
  74. package/dist/composition-ops.js +6 -6
  75. package/dist/composition.js +6 -4
  76. package/dist/{context-JLLU3MYD.js → context-XWNT6QZH.js} +4 -4
  77. package/dist/core/render.js +3 -3
  78. package/dist/core/select.js +2 -2
  79. package/dist/core.js +3 -3
  80. package/dist/director/ai-sdk.js +3 -3
  81. package/dist/director/domain.js +2 -2
  82. package/dist/director.js +3 -3
  83. package/dist/errors.js +1 -1
  84. package/dist/mcp/adapter.js +59 -22
  85. package/dist/mcp/core.js +1 -1
  86. package/dist/mcp/curation.js +5 -1
  87. package/dist/mcp/server.js +4 -4
  88. package/dist/mcp.js +4 -4
  89. package/dist/media-model/media-kind.js +98 -9
  90. package/dist/media-model/testing.js +6 -6
  91. package/dist/media-model.js +83 -77
  92. package/dist/nle-export.js +18 -18
  93. package/dist/primitives/backgrounds.js +2 -2
  94. package/dist/primitives/captions.js +3 -3
  95. package/dist/primitives/effects.js +2 -2
  96. package/dist/primitives/hero-text.js +2 -2
  97. package/dist/primitives/layouts.js +2 -2
  98. package/dist/primitives/lib/index.js +12 -12
  99. package/dist/primitives/lib.js +12 -12
  100. package/dist/primitives/scenes.js +2 -2
  101. package/dist/primitives/text.js +2 -2
  102. package/dist/primitives/ui-blocks.js +2 -2
  103. package/dist/primitives.js +19 -19
  104. package/dist/render-harness.js +4 -2
  105. package/package.json +13 -37
  106. package/dist/_members/authoring/prompts/designReviewerPrompt.d.ts +0 -2
  107. package/dist/_members/cloud-import/MediaItemPreprocessor.d.ts +0 -18
  108. package/dist/_members/cloud-import/multipartUpload.d.ts +0 -12
  109. package/dist/_members/convex-api/api.d.ts +0 -2
  110. package/dist/_members/convex-api/dataModel.d.ts +0 -4
  111. package/dist/chunk-6IU2UQI5.js +0 -107
  112. package/dist/chunk-EP2Y6M2J.js +0 -64
  113. package/dist/chunk-WZH57M53.js +0 -494
  114. package/dist/cloud-import/multipart.d.ts +0 -1
  115. package/dist/cloud-import/multipart.js +0 -8
  116. package/dist/convex-api/dataModel.d.ts +0 -1
  117. package/dist/convex-api/dataModel.js +0 -0
  118. package/dist/convex-api.d.ts +0 -1
  119. package/dist/convex-api.js +0 -8
  120. package/dist/{chunk-RP4SXXLJ.js → chunk-3PM6VICZ.js} +3 -3
  121. package/dist/{chunk-UQSOS726.js → chunk-6ABIXGLO.js} +4 -4
  122. package/dist/{chunk-SAMQUUO5.js → chunk-BIBYZJL3.js} +3 -3
  123. package/dist/{chunk-GMD33ZD7.js → chunk-O7GNE4BQ.js} +3 -3
  124. package/dist/{chunk-BKHGL4MB.js → chunk-THJAY7QS.js} +4 -4
  125. package/dist/{chunk-DYZE7JZA.js → chunk-TMIBBD5E.js} +3 -3
  126. package/dist/{chunk-G5BFI32U.js → chunk-XATRRDVG.js} +3 -3
@@ -5,7 +5,7 @@ import {
5
5
  isOk,
6
6
  opById,
7
7
  safeParse
8
- } from "./chunk-W3SIWT7J.js";
8
+ } from "./chunk-RQ2G4DXI.js";
9
9
 
10
10
  // ../mcp/src/wait.ts
11
11
  var defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
@@ -14,7 +14,47 @@ var DEFAULT_POLL_MS = 3e3;
14
14
  function fmtTime(sec) {
15
15
  return `${Math.floor(sec / 60)}:${String(Math.floor(sec % 60)).padStart(2, "0")}`;
16
16
  }
17
+ function describeProgress(json, nowMs) {
18
+ const status = json?.processingStatus?.phase ?? json?.status;
19
+ const phase = json?.progress?.phase;
20
+ const percent = json?.processingStatus?.percent ?? json?.progress?.percent;
21
+ const updatedAt = json?.updatedAt ?? json?.progress?.updatedAt;
22
+ const parts = [];
23
+ if (typeof status === "string" && status) parts.push(`Last status: ${status}`);
24
+ if (typeof phase === "string" && phase && phase !== status) parts.push(`phase: ${phase}`);
25
+ if (typeof percent === "number" && Number.isFinite(percent)) parts.push(`progress: ${percent}%`);
26
+ if (typeof updatedAt === "string" && updatedAt) {
27
+ parts.push(`updatedAt: ${updatedAt}`);
28
+ const parsed = Date.parse(updatedAt);
29
+ if (Number.isFinite(parsed) && nowMs >= parsed) {
30
+ const staleSec = Math.floor((nowMs - parsed) / 1e3);
31
+ if (staleSec >= 60) parts.push(`unchanged for ~${fmtTime(staleSec)}`);
32
+ }
33
+ }
34
+ return parts.join("; ");
35
+ }
17
36
  var KINDS = {
37
+ media: {
38
+ operationId: "getMedia",
39
+ mapArg: (_p, id) => id,
40
+ terminal: (j) => {
41
+ const phase = String(j?.processingStatus?.phase ?? j?.status ?? "");
42
+ if (phase === "complete" || phase === "completed" || phase === "ready") {
43
+ const lines = ["Media ready."];
44
+ if (j?.id) lines.push(`Media ID: ${j.id}`);
45
+ if (j?.name) lines.push(`Name: ${j.name}`);
46
+ if (typeof j?.duration === "number") lines.push(`Duration: ${j.duration.toFixed(2)}s`);
47
+ if (j?.mimeType) lines.push(`Type: ${j.mimeType}`);
48
+ lines.push("\nUse this media ID with get_media_context, suggest_briefs, or as a composition source.");
49
+ return { ok: true, text: lines.join("\n") };
50
+ }
51
+ if (phase === "error" || phase === "failed" || phase === "cancelled") {
52
+ const cause = j?.processingStatus?.error ?? j?.processingStatus?.message ?? j?.error ?? "";
53
+ return { ok: false, text: `Media ${phase}${cause ? `: ${typeof cause === "string" ? cause : JSON.stringify(cause)}` : ""}.` };
54
+ }
55
+ return null;
56
+ }
57
+ },
18
58
  render: {
19
59
  operationId: "getRender",
20
60
  mapArg: (p, id, projectId) => p === "renderId" ? id : projectId,
@@ -33,9 +73,15 @@ Download URL: ${url}`);
33
73
  const lines = [`Render ${s}${cause ? `: ${cause}` : ""}.`];
34
74
  if (j?.errorCode) lines.push(`Code: ${j.errorCode}${j?.category ? ` (${j.category})` : ""}`);
35
75
  if (typeof j?.retryable === "boolean") {
36
- lines.push(
37
- j.retryable ? "retryable: true \u2014 transient pipeline failure; call retry_render to re-attempt." : `retryable: false \u2014 deterministic defect${j?.category ? ` (category ${j.category})` : ""}; fix the composition before re-rendering \u2014 retry_render alone will not help.`
38
- );
76
+ if (j?.category === "internal") {
77
+ lines.push(
78
+ `retryable: ${j.retryable} \u2014 Cueframe reported an INTERNAL pipeline defect. The composition has not been proven invalid; do not mutate it to work around this failure. Correlate the renderId/requestId in Axiom or Sentry and fix the failing pipeline stage.`
79
+ );
80
+ } else {
81
+ lines.push(
82
+ j.retryable ? "retryable: true \u2014 transient pipeline failure; call retry_render to re-attempt." : `retryable: false \u2014 deterministic defect${j?.category ? ` (category ${j.category})` : ""}; fix the composition before re-rendering \u2014 retry_render alone will not help.`
83
+ );
84
+ }
39
85
  }
40
86
  return { ok: false, text: lines.join("\n") };
41
87
  }
@@ -219,7 +265,35 @@ Worst-first critique: ${r.critique}`);
219
265
  lines.push("\nFix the lowest criterion via apply_composition, then re-verify.");
220
266
  return { ok: true, text: lines.join("\n") };
221
267
  }
222
- if (s === "failed") return jobFailedResult("Verify", "score_composition", j);
268
+ if (s === "failed" || s === "cancelled") return jobFailedResult("Verify", "score_composition", j);
269
+ return null;
270
+ }
271
+ },
272
+ preview_frame: {
273
+ operationId: "getJob",
274
+ mapArg: (_p, id) => id,
275
+ terminal: (j) => {
276
+ const status = String(j?.status ?? "");
277
+ if (status === "succeeded") {
278
+ const result = j?.result ?? {};
279
+ const artifacts = Array.isArray(result.artifacts) ? result.artifacts : [];
280
+ const urls = artifacts.map((artifact) => artifact.url).filter((url) => typeof url === "string" && url.length > 0);
281
+ const lines = [`Preview-frame complete: ${artifacts.length} artifact(s).`];
282
+ for (const artifact of artifacts) {
283
+ lines.push(
284
+ `- ${typeof artifact.beatSec === "number" ? `${artifact.beatSec.toFixed(2)}s` : artifact.id ?? "frame"}${artifact.url ? ` \u2014 ${artifact.url}` : " \u2014 missing presigned URL"}`
285
+ );
286
+ }
287
+ lines.push(`
288
+ Snapshot provenance: ${JSON.stringify(result.previewed ?? {})}`);
289
+ lines.push(`Geometry: ${JSON.stringify(result.geometry ?? {})}`);
290
+ if (result.warnings?.length) lines.push(`Warnings: ${JSON.stringify(result.warnings)}`);
291
+ lines.push("\nThe images ride with this result; judge the pixels and use layers/geometry as evidence.");
292
+ return { ok: urls.length === artifacts.length && artifacts.length > 0, text: lines.join("\n"), mediaUrls: urls };
293
+ }
294
+ if (status === "failed" || status === "cancelled") {
295
+ return jobFailedResult("Preview-frame", "preview_frame", j);
296
+ }
223
297
  return null;
224
298
  }
225
299
  },
@@ -230,18 +304,23 @@ Worst-first critique: ${r.critique}`);
230
304
  const s = String(j?.status ?? "");
231
305
  if (s === "succeeded") {
232
306
  const r = j?.result ?? {};
307
+ const isImage = r.artifactKind === "image" || r.contentType?.startsWith("image/") === true || !r.artifactKind && !r.contentType && /\.(?:png|jpe?g|webp)(?:\?|$)/i.test(r.url ?? "");
308
+ const label = isImage ? "Image" : r.artifactKind === "motion" ? "Motion clip" : "Artifact";
233
309
  return {
234
310
  ok: true,
235
- mediaUrls: r.url ? [r.url] : void 0,
311
+ // MCP image blocks are image-only. Motion remains a truthful URL;
312
+ // attaching WebM bytes as an image corrupts the model-facing media type.
313
+ mediaUrls: r.url && isImage ? [r.url] : void 0,
236
314
  text: r.url ? `Preview ready.
237
315
 
238
- Clip: ${r.url}${r.urlExpiresAt ? `
316
+ ${label}: ${r.url}${r.contentType ? `
317
+ Content-Type: ${r.contentType}` : ""}${r.urlExpiresAt ? `
239
318
  (link valid until ${r.urlExpiresAt})` : ""}
240
319
 
241
320
  Inspect it, fix the component via create_component if needed, and re-preview.` : "Preview succeeded but returned no url \u2014 inspect GET /v1/jobs for the raw result."
242
321
  };
243
322
  }
244
- if (s === "failed") return jobFailedResult("Preview", "preview_component", j);
323
+ if (s === "failed" || s === "cancelled") return jobFailedResult("Preview", "preview_component", j);
245
324
  return null;
246
325
  }
247
326
  },
@@ -270,10 +349,14 @@ Review the tokens, then create_brand_kit to persist a kit. (0 tokens usually mea
270
349
  }
271
350
  };
272
351
  function jobFailedResult(label, reEnqueueTool, j) {
273
- const code = String(j?.error?.code ?? "unknown");
352
+ const cancelled = j?.status === "cancelled";
353
+ const code = String(j?.error?.code ?? (cancelled ? "cancelled" : "unknown"));
274
354
  const msg = typeof j?.error?.message === "string" ? j.error.message : "";
275
- const retryHint = code === "job_timeout" ? ` The executor died mid-run and the stall sweep reaped the job \u2014 re-enqueue ${reEnqueueTool} to retry.` : "";
276
- return { ok: false, text: `${label} failed (${code})${msg ? `: ${msg}` : ""}.${retryHint}` };
355
+ const retryHint = code === "job_timeout" ? ` The executor died mid-run and the stall sweep reaped the job \u2014 inspect this jobId in Axiom/Sentry before retrying; re-enqueue ${reEnqueueTool} only after the failing pipeline stage is healthy.` : "";
356
+ return {
357
+ ok: false,
358
+ text: `${label} ${cancelled ? "cancelled" : "failed"} (${code})${msg ? `: ${msg}` : ""}.${retryHint}`
359
+ };
277
360
  }
278
361
  async function waitForJob(ex, kind, id, projectId, deadline, deps = {}) {
279
362
  const sleep = deps.sleep ?? defaultSleep;
@@ -281,7 +364,7 @@ async function waitForJob(ex, kind, id, projectId, deadline, deps = {}) {
281
364
  const pollMs = deps.pollMs ?? DEFAULT_POLL_MS;
282
365
  const cfg = KINDS[kind];
283
366
  const op = opById(cfg.operationId);
284
- let lastStatus = "";
367
+ let lastProgress = "";
285
368
  const INVOKE_BUDGET_MS = deps.invokeBudgetMs ?? 2e3;
286
369
  let firstPoll = true;
287
370
  while (firstPoll || now() + INVOKE_BUDGET_MS < deadline) {
@@ -300,12 +383,12 @@ async function waitForJob(ex, kind, id, projectId, deadline, deps = {}) {
300
383
  const json = safeParse(res.text);
301
384
  const t = cfg.terminal(json);
302
385
  if (t) return t;
303
- if (json && typeof json.status === "string") lastStatus = json.status;
386
+ lastProgress = describeProgress(json, now());
304
387
  }
305
388
  if (now() + pollMs + INVOKE_BUDGET_MS >= deadline) break;
306
389
  await sleep(pollMs);
307
390
  }
308
- const tail = lastStatus ? ` Last status: ${lastStatus}.` : "";
391
+ const tail = lastProgress ? ` ${lastProgress}.` : "";
309
392
  return {
310
393
  ok: true,
311
394
  stillRunning: true,
@@ -4,16 +4,16 @@ import {
4
4
  import {
5
5
  getPrimitiveSubtextParam,
6
6
  getPrimitiveTextParam
7
- } from "./chunk-DCVJWGIA.js";
7
+ } from "./chunk-JY26PIRP.js";
8
8
  import {
9
9
  selectAllOverlays
10
- } from "./chunk-ICSZF37W.js";
10
+ } from "./chunk-JRIPQ7DN.js";
11
11
  import {
12
12
  ComposePlan
13
- } from "./chunk-TFGKUWHY.js";
13
+ } from "./chunk-JTVFIN6H.js";
14
14
  import {
15
15
  OverlayClipSource
16
- } from "./chunk-WZH57M53.js";
16
+ } from "./chunk-2SNY75AR.js";
17
17
 
18
18
  // ../authoring/src/tools/toolSets.ts
19
19
  var COMPOSE_PLANNER_TOOLS = [
@@ -63,7 +63,7 @@ var COMPOSE_ROLE_TOOLS = Object.freeze({
63
63
  schema: z.object({}),
64
64
  metadata: { label: "Get Context" },
65
65
  handler: async (_args, capabilities) => {
66
- const { buildDirectorContext } = await import("./context-JLLU3MYD.js");
66
+ const { buildDirectorContext } = await import("./context-XWNT6QZH.js");
67
67
  return buildDirectorContext(capabilities);
68
68
  }
69
69
  },
@@ -9,7 +9,7 @@ import {
9
9
  import {
10
10
  decodeError,
11
11
  scrubSensitive
12
- } from "./chunk-LLUW26BS.js";
12
+ } from "./chunk-R5BMJ2NX.js";
13
13
 
14
14
  // ../director/src/domain/chat.ts
15
15
  import { z } from "zod";
@@ -127,55 +127,6 @@ Call submit_plan with type "plan" if:
127
127
  - Prefer moments where the speaker introduces a concept or transitions topics
128
128
  - At most 1 intro and 1 outro`;
129
129
 
130
- // ../authoring/src/prompts/designReviewerPrompt.ts
131
- var DESIGN_REVIEWER_PROMPT = `You are a design quality reviewer for motion graphics in CueFrame.
132
-
133
- ## Workflow
134
-
135
- 1. Call \`get_context\` to understand the current project state and brand kit.
136
- 2. Call \`get_composition\` to read the graphics themselves \u2014 a card clip carries its
137
- \`html\` and \`tokens\` verbatim; an overlay or component clip carries its params.
138
- For a component's animation code, call \`get_component_source\` with its componentId.
139
- 3. Call \`preview_frame\` with EVERY beat you need to see in ONE call \u2014 the rendered
140
- pixels, not your reading of the source.
141
- 4. Assess quality against the checklist below. If improvements are needed, send the
142
- fixes as ONE \`apply_composition\` batch \u2014 a \`clip.update\` op per graphic carrying
143
- only the fields that change \u2014 then re-preview the beats you touched to verify.
144
-
145
- ## Quality Checklist
146
-
147
- - **Visual hierarchy**: Title large/bold, subtext smaller/lighter, decorative elements subtle
148
- - **Animation choreography**: Elements arrive in sequence with staggered timing, not all at once
149
- - **Spring physics**: Use \`spring()\` for organic entrances instead of plain linear interpolation
150
- - **Color usage**: Read ALL colors from params (accentColor, textColor, backgroundColor) \u2014 never hardcode
151
- - **Entrance + exit**: Choreographed entrance sequence AND fade-out in final 15 frames
152
- - **Layered composition**: Multiple animated elements (text + accent line + shape + bg glow), not just a single element with opacity
153
- - **Typography**: Appropriate font from FONTS.*, proper letter-spacing, readable sizing
154
- - **Atmosphere**: Subtle glows, gradients, or accent color bleeds for depth
155
-
156
- ## Component Contract
157
-
158
- - Signature: \`export default function Name({ durationInFrames, params }) { ... }\`
159
- - ONLY \`useCurrentFrame()\` and \`useVideoConfig()\` hooks. NO useEffect/useState/useMemo/useCallback/useRef.
160
- - Inline styles only. No imports, no CSS files, no \`document\` access. Max 10000 chars.
161
- - All animation driven by frame number.
162
-
163
- ## Guidelines
164
-
165
- - Be specific in feedback: cite which element, which frame range, what to change.
166
- - Prefer refinement over complete rewrites \u2014 preserve the designer's intent.
167
- - A still cannot show motion. Judge timing and choreography from the source; judge
168
- layout, contrast and legibility from the frame.
169
- - After fixing, always re-preview to confirm the improvement visually.
170
- `;
171
- var DESIGN_REVIEWER_TOOLS = [
172
- "get_context",
173
- "get_composition",
174
- "get_component_source",
175
- "preview_frame",
176
- "apply_composition"
177
- ];
178
-
179
130
  // ../authoring/src/prompts/graphics.ts
180
131
  var CODE_GEN_FEW_SHOT_EXAMPLES = `
181
132
  ## Reference Examples (study these patterns, then write your component)
@@ -404,8 +355,6 @@ export {
404
355
  buildExecutionTask,
405
356
  buildPlannerUserMessage,
406
357
  PLANNING_INSTRUCTIONS,
407
- DESIGN_REVIEWER_PROMPT,
408
- DESIGN_REVIEWER_TOOLS,
409
358
  CODE_GEN_FEW_SHOT_EXAMPLES,
410
359
  COMPONENT_CONTRACT,
411
360
  TOOLKIT_REFERENCE,
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-KYRDKK2D.js";
4
4
  import {
5
5
  Composition
6
- } from "./chunk-WZH57M53.js";
6
+ } from "./chunk-2SNY75AR.js";
7
7
 
8
8
  // ../composition/src/ops/compositionOps.shared.ts
9
9
  function findOrCreateTrackByKind(composition, kind) {
@@ -2,8 +2,9 @@ import {
2
2
  Composition,
3
3
  Copy,
4
4
  Format,
5
- GraphicRole
6
- } from "./chunk-WZH57M53.js";
5
+ GraphicRole,
6
+ OpaqueId
7
+ } from "./chunk-2SNY75AR.js";
7
8
 
8
9
  // ../composition/src/validators/composePlan.ts
9
10
  import { z } from "zod";
@@ -77,7 +78,6 @@ var ComposePlan = z.object({
77
78
 
78
79
  // ../composition/src/validators/brandKit.ts
79
80
  import { z as z2 } from "zod";
80
- import { zid } from "convex-helpers/server/zod3";
81
81
  var EasingValue = z2.union([
82
82
  z2.enum(["linear", "ease", "ease-in", "ease-out", "ease-in-out"]),
83
83
  z2.object({
@@ -101,7 +101,7 @@ var FontRef = z2.union([
101
101
  }),
102
102
  z2.object({
103
103
  kind: z2.literal("uploaded"),
104
- fontId: zid("fonts"),
104
+ fontId: OpaqueId,
105
105
  family: z2.string().optional()
106
106
  })
107
107
  ]);
@@ -331,7 +331,6 @@ var Font = z3.object({
331
331
 
332
332
  // ../composition/src/validators/render.ts
333
333
  import { z as z4 } from "zod";
334
- import { zid as zid2 } from "convex-helpers/server/zod3";
335
334
  var RenderPriority = z4.enum(["interactive", "standard", "background"]);
336
335
  var RenderIntent = z4.enum(["preview", "final"]);
337
336
  var RenderMode = z4.enum(["offline", "live"]);
@@ -362,7 +361,7 @@ var RegistryPin = z4.object({
362
361
  version: z4.string().min(1)
363
362
  });
364
363
  var MediaSourceSnapshot = z4.object({
365
- mediaId: zid2("mediaItems"),
364
+ mediaId: OpaqueId,
366
365
  presignedUrl: z4.string().url(),
367
366
  expiresAt: z4.number().optional()
368
367
  });
@@ -425,9 +424,9 @@ var DestinationResult = z4.object({
425
424
  error: z4.string().optional()
426
425
  });
427
426
  var RenderJob = z4.object({
428
- id: zid2("renderJobs"),
429
- projectId: zid2("projects").optional(),
430
- compositionId: zid2("compositions"),
427
+ id: OpaqueId,
428
+ projectId: OpaqueId.optional(),
429
+ compositionId: OpaqueId,
431
430
  compositionVersionId: z4.string().min(1),
432
431
  status: RenderStatus,
433
432
  progress: RenderProgressPhase.optional(),
@@ -452,7 +451,7 @@ var RenderJob = z4.object({
452
451
  updatedAt: z4.number()
453
452
  });
454
453
  var RenderProgress = z4.object({
455
- jobId: zid2("renderJobs"),
454
+ jobId: OpaqueId,
456
455
  status: RenderStatus,
457
456
  percent: z4.number().min(0).max(100).optional(),
458
457
  framesRendered: z4.number().int().nonnegative().optional(),
@@ -504,13 +503,12 @@ var PrimitiveRegistryEntry = z5.object({
504
503
 
505
504
  // ../composition/src/validators/project.ts
506
505
  import { z as z6 } from "zod";
507
- import { zid as zid3 } from "convex-helpers/server/zod3";
508
506
  var Project = z6.object({
509
- id: zid3("projects"),
507
+ id: OpaqueId,
510
508
  name: z6.string().min(1),
511
509
  defaultFormat: Format.optional(),
512
510
  palConformDefault: z6.union([z6.literal(24), z6.literal(30)]).optional(),
513
- activeCompositionId: zid3("compositions").nullable().optional(),
511
+ activeCompositionId: OpaqueId.nullable().optional(),
514
512
  brandKitId: z6.string().optional(),
515
513
  ownerOrgId: z6.string().optional(),
516
514
  createdAt: z6.number(),
@@ -519,7 +517,6 @@ var Project = z6.object({
519
517
 
520
518
  // ../composition/src/validators/session.ts
521
519
  import { z as z7 } from "zod";
522
- import { zid as zid4 } from "convex-helpers/server/zod3";
523
520
  var SessionMediaRole = z7.enum([
524
521
  "main",
525
522
  "wide",
@@ -528,7 +525,7 @@ var SessionMediaRole = z7.enum([
528
525
  "audio"
529
526
  ]);
530
527
  var SessionMember = z7.object({
531
- mediaId: zid4("mediaItems"),
528
+ mediaId: OpaqueId,
532
529
  role: SessionMediaRole,
533
530
  label: z7.string().optional()
534
531
  // human-readable annotation, e.g., "host's camera"
@@ -538,7 +535,7 @@ var SessionMux = z7.object({
538
535
  audioRole: z7.literal("audio")
539
536
  });
540
537
  var Session = z7.object({
541
- id: zid4("sessions"),
538
+ id: OpaqueId,
542
539
  name: z7.string().min(1),
543
540
  members: z7.array(SessionMember).nonempty(),
544
541
  mux: z7.array(SessionMux).optional(),
@@ -549,7 +546,6 @@ var Session = z7.object({
549
546
 
550
547
  // ../composition/src/validators/webhook.ts
551
548
  import { z as z8 } from "zod";
552
- import { zid as zid5 } from "convex-helpers/server/zod3";
553
549
  var SubstrateWebhookEvent = z8.enum([
554
550
  "render.completed",
555
551
  "media.transcribed",
@@ -565,7 +561,7 @@ var WebhookDeliveryStatus = z8.enum([
565
561
  // retry budget burned through
566
562
  ]);
567
563
  var Webhook = z8.object({
568
- id: zid5("webhooks"),
564
+ id: OpaqueId,
569
565
  url: z8.string().url(),
570
566
  events: z8.array(z8.string().min(1)).nonempty(),
571
567
  signingKeyId: z8.string().optional(),
@@ -577,7 +573,7 @@ var Webhook = z8.object({
577
573
  });
578
574
  var WebhookDelivery = z8.object({
579
575
  id: z8.string().min(1),
580
- webhookId: zid5("webhooks"),
576
+ webhookId: OpaqueId,
581
577
  event: z8.string().min(1),
582
578
  payload: z8.record(z8.string(), z8.unknown()),
583
579
  status: WebhookDeliveryStatus,
@@ -15221,8 +15221,8 @@ function resolution(h) {
15221
15221
  }
15222
15222
  function sceneFps(fps) {
15223
15223
  if (fps === void 0) return void 0;
15224
- if (fps === 24 || fps === 30 || fps === 60) return fps;
15225
- throw new Error(`sceneFormat: unsupported scene fps ${fps} (expected 24|30|60)`);
15224
+ if (fps === 24 || fps === 25 || fps === 30 || fps === 60) return fps;
15225
+ throw new Error(`sceneFormat: unsupported scene fps ${fps} (expected 24|25|30|60)`);
15226
15226
  }
15227
15227
  function sceneFormat(m) {
15228
15228
  if (m.kind !== "scene") return void 0;
@@ -2,7 +2,7 @@ import {
2
2
  selectAllClips,
3
3
  selectAllOverlays,
4
4
  selectSceneMarkers
5
- } from "./chunk-ICSZF37W.js";
5
+ } from "./chunk-JRIPQ7DN.js";
6
6
 
7
7
  // ../authoring/src/context/transcript.ts
8
8
  var MAX_TRANSCRIPT_CHARS = 6e4;