@cueframe/kernel 0.2.50 → 0.2.52

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 (51) hide show
  1. package/dist/_members/composition/validators/composition.d.ts +20 -0
  2. package/dist/_members/composition/validators/render.d.ts +2 -0
  3. package/dist/_members/composition-ops/index.d.ts +12 -0
  4. package/dist/_members/core/render/compositionAudioAndDepth.d.ts +8 -2
  5. package/dist/_members/core/render/compositionRender.d.ts +14 -0
  6. package/dist/_members/core/render/index.d.ts +1 -1
  7. package/dist/_members/core/render/types.d.ts +1 -0
  8. package/dist/authoring/build-tools.js +5 -5
  9. package/dist/authoring/context.js +4 -4
  10. package/dist/authoring/tools.js +4 -4
  11. package/dist/authoring.js +12 -12
  12. package/dist/{chunk-AOIY7NGF.js → chunk-2M65KQNG.js} +63 -0
  13. package/dist/{chunk-INYP56TC.js → chunk-3I43W7DP.js} +145 -9
  14. package/dist/{chunk-FYS2XUKJ.js → chunk-3OG2674K.js} +1 -1
  15. package/dist/{chunk-NLXQ7WTH.js → chunk-5JCLZPMV.js} +1 -1
  16. package/dist/{chunk-LZEX2GAY.js → chunk-CV3QQUMK.js} +27 -1
  17. package/dist/{chunk-OVV35ZS2.js → chunk-FSEB4LSU.js} +1 -1
  18. package/dist/{chunk-WIPIYUY2.js → chunk-IHXMBXXL.js} +11 -5
  19. package/dist/{chunk-XSBVOXSB.js → chunk-JWW54N24.js} +1 -1
  20. package/dist/{chunk-KY3QBG7O.js → chunk-KMDZDH5E.js} +4 -4
  21. package/dist/{chunk-LO3DH776.js → chunk-MBSQKRDF.js} +1 -1
  22. package/dist/{chunk-IHWC75AN.js → chunk-QVBUYWW6.js} +1 -1
  23. package/dist/{chunk-XVJU63TF.js → chunk-WZ22ZYXD.js} +4 -4
  24. package/dist/compose.js +23 -23
  25. package/dist/composition/graphics-plan.js +7 -7
  26. package/dist/composition/ops.js +3 -3
  27. package/dist/composition/projection.js +1 -1
  28. package/dist/composition/validators.js +6 -2
  29. package/dist/composition-ops.js +9 -5
  30. package/dist/composition.js +82 -78
  31. package/dist/{context-AIUJG7R4.js → context-2MBCDTCZ.js} +4 -4
  32. package/dist/core/render.js +7 -1
  33. package/dist/core.js +5 -1
  34. package/dist/mcp/adapter.js +2 -2
  35. package/dist/mcp/core.js +1 -1
  36. package/dist/mcp/scene-shot.js +2 -2
  37. package/dist/mcp/server.js +13 -9
  38. package/dist/mcp.js +13 -9
  39. package/dist/primitives/effects.js +2 -2
  40. package/dist/primitives/hero-text.js +2 -2
  41. package/dist/primitives/scenes.js +2 -2
  42. package/dist/primitives/text.js +2 -2
  43. package/dist/primitives/ui-blocks.js +4 -4
  44. package/dist/primitives.js +20 -20
  45. package/dist/render-harness.js +5 -1
  46. package/package.json +10 -10
  47. package/dist/{chunk-O3SJTX6S.js → chunk-4B4V3HYW.js} +4 -4
  48. package/dist/{chunk-7SXY6NFW.js → chunk-5ZQLMPDY.js} +3 -3
  49. package/dist/{chunk-RL5SO653.js → chunk-7SQOXIWR.js} +3 -3
  50. package/dist/{chunk-B3GSTQLR.js → chunk-VLJOIUHL.js} +6 -6
  51. package/dist/{chunk-RBWS5XHE.js → chunk-X34KW2SL.js} +4 -4
@@ -29,6 +29,9 @@ import {
29
29
  compositionHasVo,
30
30
  roleDefaultGainDb
31
31
  } from "./chunk-VZ7TYX6Z.js";
32
+ import {
33
+ resolveBrandRef
34
+ } from "./chunk-Z6NY6MCL.js";
32
35
  import {
33
36
  SHOT_SCALE_TARGET,
34
37
  shotScaleZoom
@@ -1229,6 +1232,7 @@ function assertBehindSubjectCaptionCoverage(captionSegments, clips, fps, output,
1229
1232
  const startFrame = Math.round(word.startMs / 1e3 * fps);
1230
1233
  const endFrame = Math.max(startFrame + 1, Math.round(word.endMs / 1e3 * fps));
1231
1234
  for (const window of visiblePackedHostWindows(clips, startFrame, endFrame, output, effects)) {
1235
+ if (!window.captionVisible) continue;
1232
1236
  if (window.hostClipId) continue;
1233
1237
  const code = window.candidateClipIds.length > 1 ? "behind_subject_caption_host_ambiguous" : "behind_subject_caption_host_missing";
1234
1238
  throw renderInputError(
@@ -1242,10 +1246,10 @@ function assertBehindSubjectCaptionCoverage(captionSegments, clips, fps, output,
1242
1246
  }
1243
1247
  var FULL_RECT = { left: 0, top: 0, right: 1, bottom: 1 };
1244
1248
  function hasClipEffect(clip, effects) {
1245
- return effects.some((effect) => effect.target.kind === "clip" && effect.trackId === clip.trackId && effect.contentIndex === clip.contentIndex);
1249
+ return clip.hasClipEffects === true || effects.some((effect) => effect.target.kind === "clip" && effect.trackId === clip.trackId && effect.contentIndex === clip.contentIndex);
1246
1250
  }
1247
1251
  function pictureRect(clip, output, effects) {
1248
- if (clip.cropTrajectory || clip.cropTrajectoryUrl || hasClipEffect(clip, effects)) return void 0;
1252
+ if (clip.cropTrajectory || clip.cropTrajectoryUrl || clip.hasCropIntent || hasClipEffect(clip, effects)) return void 0;
1249
1253
  if (clip.fit !== "contain") return FULL_RECT;
1250
1254
  const sourceWidth = clip.sourceWidth;
1251
1255
  const sourceHeight = clip.sourceHeight;
@@ -1268,7 +1272,7 @@ function coversLowerPictures(upper, lower, output, effects) {
1268
1272
  return upperRect.left <= rect.left + epsilon && upperRect.top <= rect.top + epsilon && upperRect.right + epsilon >= rect.right && upperRect.bottom + epsilon >= rect.bottom;
1269
1273
  });
1270
1274
  }
1271
- function visiblePackedHostWindows(clips, startFrame, endFrame, output, effects = []) {
1275
+ function visiblePackedHostWindows(clips, startFrame, endFrame, output, effects = [], hostMode = "packed-only") {
1272
1276
  if (endFrame <= startFrame) return [];
1273
1277
  const boundaries = /* @__PURE__ */ new Set([startFrame, endFrame]);
1274
1278
  for (const clip of clips) {
@@ -1277,6 +1281,13 @@ function visiblePackedHostWindows(clips, startFrame, endFrame, output, effects =
1277
1281
  if (start > startFrame && start < endFrame) boundaries.add(start);
1278
1282
  if (end > startFrame && end < endFrame) boundaries.add(end);
1279
1283
  }
1284
+ for (const effect of effects) {
1285
+ if (effect.target.kind !== "global") continue;
1286
+ const start = effect.startFrame ?? startFrame;
1287
+ const end = start + (effect.durationInFrames ?? endFrame - start);
1288
+ if (start > startFrame && start < endFrame) boundaries.add(start);
1289
+ if (end > startFrame && end < endFrame) boundaries.add(end);
1290
+ }
1280
1291
  const points = [...boundaries].sort((a, b) => a - b);
1281
1292
  const windows = [];
1282
1293
  for (let i = 0; i < points.length - 1; i++) {
@@ -1287,6 +1298,7 @@ function visiblePackedHostWindows(clips, startFrame, endFrame, output, effects =
1287
1298
  );
1288
1299
  const topLayer = Math.max(...active.map((clip) => clip.layerIndex));
1289
1300
  const top = active.filter((clip) => clip.layerIndex === topLayer);
1301
+ const globalEffectActive = effects.some((effect) => effect.target.kind === "global" && (effect.startFrame ?? startFrame) <= start && (effect.startFrame ?? startFrame) + (effect.durationInFrames ?? endFrame - startFrame) >= end);
1290
1302
  const fullFrame = top[0]?.region === void 0 || top[0].region.x === 0 && top[0].region.y === 0 && top[0].region.w === 1 && top[0].region.h === 1;
1291
1303
  const provesOcclusion = top.length === 1 && fullFrame && (active.length === 1 || coversLowerPictures(
1292
1304
  top[0],
@@ -1294,18 +1306,22 @@ function visiblePackedHostWindows(clips, startFrame, endFrame, output, effects =
1294
1306
  output,
1295
1307
  effects
1296
1308
  ));
1297
- const host = provesOcclusion && top[0].packedUrl ? top[0] : void 0;
1298
- const unresolvedOverlap = top.length > 1 || top.length === 1 && !!top[0].packedUrl && active.length > 1 && !provesOcclusion;
1299
- const candidates = unresolvedOverlap ? active.filter((clip) => clip.packedUrl).map((clip) => clip.id) : top.map((clip) => clip.id);
1309
+ const suppressesCaption = provesOcclusion && !globalEffectActive && pictureRect(top[0], output, effects) !== void 0;
1310
+ const captionVisible = !(suppressesCaption && top[0].captionVisibility === "hidden");
1311
+ const candidateHost = (clip) => hostMode === "all-video-candidates" ? clip.mediaType !== "image" : !!clip.packedUrl;
1312
+ const host = provesOcclusion && candidateHost(top[0]) ? top[0] : void 0;
1313
+ const unresolvedOverlap = top.length > 1 || top.length === 1 && active.length > 1 && !provesOcclusion;
1314
+ const candidates = unresolvedOverlap ? active.filter(candidateHost).map((clip) => clip.id) : top.map((clip) => clip.id);
1300
1315
  const previous = windows[windows.length - 1];
1301
- if (previous && previous.endFrame === start && previous.hostClipId === host?.id && previous.candidateClipIds.join("\0") === candidates.join("\0")) {
1316
+ if (previous && previous.endFrame === start && previous.hostClipId === host?.id && previous.captionVisible === captionVisible && previous.candidateClipIds.join("\0") === candidates.join("\0")) {
1302
1317
  previous.endFrame = end;
1303
1318
  } else {
1304
1319
  windows.push({
1305
1320
  startFrame: start,
1306
1321
  endFrame: end,
1307
1322
  ...host ? { hostClipId: host.id } : {},
1308
- candidateClipIds: candidates
1323
+ candidateClipIds: candidates,
1324
+ captionVisible
1309
1325
  });
1310
1326
  }
1311
1327
  }
@@ -1452,6 +1468,13 @@ function projectMediaTrack(track, trackIndex, trackCount, fps, srcUrls, trajecto
1452
1468
  );
1453
1469
  }
1454
1470
  if (rendersNoFrames(c)) continue;
1471
+ if (c.captionVisibility !== void 0 && track.kind !== "video") {
1472
+ throw renderInputError(
1473
+ "invalid_composition",
1474
+ `Clip ${c.id}: captionVisibility is supported only on video media clips.`,
1475
+ { trackId: track.id, clipId: c.id, compositionPath: `composition.tracks[${track.id}].contents[${i}].captionVisibility` }
1476
+ );
1477
+ }
1455
1478
  const src = resolveSrcUrl(c.source.mediaId, srcUrls, {
1456
1479
  trackId: track.id,
1457
1480
  clipId: c.id,
@@ -1543,6 +1566,7 @@ function projectMediaTrack(track, trackIndex, trackCount, fps, srcUrls, trajecto
1543
1566
  ...c.animate !== void 0 ? { animate: c.animate } : {},
1544
1567
  ...c.region !== void 0 ? { region: c.region } : {},
1545
1568
  ...c.fit !== void 0 ? { fit: c.fit } : {},
1569
+ ...c.captionVisibility !== void 0 ? { captionVisibility: c.captionVisibility } : {},
1546
1570
  ...s === 0 && c.transitionIn ? {
1547
1571
  transitionIn: mapTransitionType(c.transitionIn.type),
1548
1572
  transitionDurationFrames: Math.max(1, Math.round(c.transitionIn.duration * fps))
@@ -1810,6 +1834,104 @@ function projectEffectTrack(track, trackIndex, trackCount, fps) {
1810
1834
  }
1811
1835
 
1812
1836
  // ../execution/core/src/render/compositionRender.ts
1837
+ function captionVisibilityWindowsForComposition(composition, sourceDimensions) {
1838
+ const { fps, width, height } = compositionFormatDimensions(composition.format);
1839
+ const clips = [];
1840
+ const mediaIdByProjectedClipId = {};
1841
+ let endFrame = 0;
1842
+ const trackCount = composition.tracks.length;
1843
+ const effects = composition.tracks.flatMap(
1844
+ (track, index) => track.enabled !== false && track.kind === "effect" ? projectEffectTrack(track, index, trackCount, fps) : []
1845
+ );
1846
+ for (const [trackIndex, track] of composition.tracks.entries()) {
1847
+ if (track.enabled === false || track.kind !== "video" && track.kind !== "image") continue;
1848
+ for (const [contentIndex, item] of track.contents.entries()) {
1849
+ if (!("source" in item)) continue;
1850
+ if (item.source.kind !== "media") {
1851
+ throw renderInputError(
1852
+ "clip_source_track_mismatch",
1853
+ `Clip ${item.id} on video track ${track.id} must use a media source.`,
1854
+ { trackId: track.id, clipId: item.id }
1855
+ );
1856
+ }
1857
+ const spans = projectMediaPlaybackSpans(track.kind === "video" ? {
1858
+ startTime: item.startTime,
1859
+ duration: item.duration,
1860
+ trim: item.source.trim,
1861
+ excludedRanges: item.source.excludedRanges,
1862
+ playbackRate: item.source.playbackRate,
1863
+ fps
1864
+ } : { startTime: item.startTime, duration: item.duration, fps });
1865
+ const dimensions = sourceDimensions[item.source.mediaId];
1866
+ const validDimensions = track.kind === "video" && dimensions && Number.isFinite(dimensions.width) && dimensions.width > 0 && Number.isFinite(dimensions.height) && dimensions.height > 0;
1867
+ for (const [spanIndex, span] of spans.entries()) {
1868
+ if (span.durationInFrames === 0) continue;
1869
+ const id = spans.length === 1 ? item.id : `${item.id}#${spanIndex}`;
1870
+ clips.push({
1871
+ id,
1872
+ trackId: track.id,
1873
+ layerIndex: trackCount - trackIndex,
1874
+ contentIndex,
1875
+ timelineStartFrames: span.timelineStartFrames,
1876
+ durationInFrames: span.durationInFrames,
1877
+ ...track.kind === "image" ? { mediaType: "image" } : {},
1878
+ ...validDimensions ? { sourceWidth: dimensions.width, sourceHeight: dimensions.height } : {},
1879
+ ...item.region ? { region: item.region } : {},
1880
+ ...item.fit ? { fit: item.fit } : {},
1881
+ ...track.kind === "video" && item.captionVisibility ? { captionVisibility: item.captionVisibility } : {},
1882
+ ...item.source.reframe?.segments.length ? { hasCropIntent: true } : {},
1883
+ ...item.effects?.length ? { hasClipEffects: true } : {}
1884
+ });
1885
+ if (track.kind === "video") mediaIdByProjectedClipId[id] = item.source.mediaId;
1886
+ endFrame = Math.max(endFrame, span.timelineStartFrames + span.durationInFrames);
1887
+ }
1888
+ }
1889
+ }
1890
+ for (const segment of composition.captions?.segments ?? []) {
1891
+ for (const word of segment.words) {
1892
+ const startFrame = Math.round(word.startMs / 1e3 * fps);
1893
+ endFrame = Math.max(endFrame, Math.max(startFrame + 1, Math.round(word.endMs / 1e3 * fps)));
1894
+ }
1895
+ }
1896
+ return {
1897
+ fps,
1898
+ windows: visiblePackedHostWindows(clips, 0, endFrame, { width, height }, effects, "all-video-candidates"),
1899
+ mediaIdByProjectedClipId
1900
+ };
1901
+ }
1902
+ var CAPTION_COLOR_FIELDS = [
1903
+ "color",
1904
+ "highlightColor",
1905
+ "backgroundColor",
1906
+ "emphasisColor",
1907
+ "emphasisPlateColor",
1908
+ "emphasisPlateTextColor",
1909
+ "emphasisPlateAltColor",
1910
+ "emphasisPlateAltTextColor",
1911
+ "annotationColor"
1912
+ ];
1913
+ function resolveCaptionColorRefs(style, brandKit) {
1914
+ const resolvedStyle = { ...style };
1915
+ for (const field of CAPTION_COLOR_FIELDS) {
1916
+ const authored = resolvedStyle[field];
1917
+ if (typeof authored !== "string") continue;
1918
+ if (authored.startsWith("\\$brand:")) {
1919
+ resolvedStyle[field] = authored.slice(1);
1920
+ continue;
1921
+ }
1922
+ if (!authored.startsWith("$brand:")) continue;
1923
+ const resolved = authored.startsWith("$brand:colors.") && brandKit ? resolveBrandRef(authored, brandKit) : null;
1924
+ if (typeof resolved !== "string" || !resolved) {
1925
+ throw renderInputError(
1926
+ "brand_kit_unresolved",
1927
+ `Caption color ${field} references ${authored}, but the bound brand kit has no matching color. Use $brand:colors.<name> or a literal color.`,
1928
+ { compositionPath: `captions.style.${field}`, brandRef: authored }
1929
+ );
1930
+ }
1931
+ resolvedStyle[field] = resolved;
1932
+ }
1933
+ return resolvedStyle;
1934
+ }
1813
1935
  function compositionFormatDimensions(format) {
1814
1936
  const fps = format.fps ?? 30;
1815
1937
  const resolution = format.resolution ?? "fhd";
@@ -1867,6 +1989,18 @@ function assertMergedCaptionFacesDrawable(composition) {
1867
1989
  function compositionToRenderInput(composition, srcUrls, trajectoryUrls, coViewUrls, alphaUrls, subCompositions, trajectories, options) {
1868
1990
  const flattened = hasCompoundClips(composition) ? flattenCompoundClips(composition, (id) => subCompositions?.[id]) : composition;
1869
1991
  composition = flattened;
1992
+ for (const track of composition.tracks) {
1993
+ for (const content of track.contents) {
1994
+ if (!("source" in content) || content.captionVisibility === void 0) continue;
1995
+ if (track.kind !== "video" || content.source.kind !== "media") {
1996
+ throw renderInputError(
1997
+ "invalid_composition",
1998
+ `Clip ${content.id}: captionVisibility is supported only on video media clips.`,
1999
+ { trackId: track.id, clipId: content.id, compositionPath: `composition.tracks[${track.id}].contents[${content.id}].captionVisibility` }
2000
+ );
2001
+ }
2002
+ }
2003
+ }
1870
2004
  assertMergedCaptionFacesDrawable(composition);
1871
2005
  const { width, height, fps } = compositionFormatDimensions(composition.format);
1872
2006
  const clips = [];
@@ -1992,6 +2126,7 @@ function compositionToRenderInput(composition, srcUrls, trajectoryUrls, coViewUr
1992
2126
  ...cap?.entranceStaggerMs != null ? { entranceStaggerMs: cap.entranceStaggerMs } : {},
1993
2127
  ...cap?.exitMs != null ? { exitMs: cap.exitMs } : {}
1994
2128
  } : void 0;
2129
+ const resolvedCaptionStyle = captionStyle ? resolveCaptionColorRefs(captionStyle, brandKit) : void 0;
1995
2130
  return {
1996
2131
  clips,
1997
2132
  overlays,
@@ -2004,7 +2139,7 @@ function compositionToRenderInput(composition, srcUrls, trajectoryUrls, coViewUr
2004
2139
  ...effects.length > 0 ? { effects } : {},
2005
2140
  ...hasCaptions ? { captionSegments } : {},
2006
2141
  ...hasCaptions && composition.captions?.zPlane === "behind-subject" ? { captionsBehind: true } : {},
2007
- ...captionStyle ? { captionStyle } : {},
2142
+ ...resolvedCaptionStyle ? { captionStyle: resolvedCaptionStyle } : {},
2008
2143
  ...brandKit ? { brandKit } : {}
2009
2144
  };
2010
2145
  }
@@ -3049,6 +3184,7 @@ export {
3049
3184
  visiblePackedHostWindows,
3050
3185
  playableSpans,
3051
3186
  projectMediaPlaybackSpans,
3187
+ captionVisibilityWindowsForComposition,
3052
3188
  compositionFormatDimensions,
3053
3189
  referencedMediaIds,
3054
3190
  compositionToRenderInput,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  bodySchemaFor,
3
3
  opById
4
- } from "./chunk-AOIY7NGF.js";
4
+ } from "./chunk-2M65KQNG.js";
5
5
 
6
6
  // ../mcp/src/generated/sceneContract.ts
7
7
  function deepFreeze(value) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Composition
3
- } from "./chunk-LZEX2GAY.js";
3
+ } from "./chunk-CV3QQUMK.js";
4
4
  import {
5
5
  expandToLinkGroup
6
6
  } from "./chunk-KYRDKK2D.js";
@@ -124,6 +124,7 @@ var CaptionRegion = Region.refine(
124
124
  "captions style.region must fit within the normalized frame"
125
125
  );
126
126
  var ClipFit = z2.enum(["cover", "contain"]);
127
+ var CaptionVisibility = z2.enum(["visible", "hidden"]);
127
128
  var PerClipEffect = z2.object({
128
129
  primitiveId: z2.string().min(1),
129
130
  params: z2.record(z2.string(), z2.unknown()).optional()
@@ -166,6 +167,9 @@ var TimelineClip = z2.object({
166
167
  position: Position.optional(),
167
168
  region: Region.optional(),
168
169
  fit: ClipFit.optional(),
170
+ captionVisibility: CaptionVisibility.optional().describe(
171
+ "Video media clip only. Hide native captions while this clip is the visible full-frame picture; caption words and timings remain stored and resume when another visible clip takes over."
172
+ ),
169
173
  effects: z2.array(PerClipEffect).optional(),
170
174
  transitionIn: Transition.optional(),
171
175
  linkGroupId: z2.string().min(1).optional(),
@@ -314,6 +318,18 @@ function captionsAreBehindSubject(captions) {
314
318
  function captionWords(c) {
315
319
  return c.segments.flatMap((s) => s.words);
316
320
  }
321
+ function captionVisibilityIssues(composition) {
322
+ const issues = [];
323
+ composition.tracks.forEach((track, trackIndex) => {
324
+ track.contents.forEach((item, contentIndex) => {
325
+ if (!("source" in item) || item.captionVisibility === void 0) return;
326
+ if (track.kind !== "video" || item.source.kind !== "media") {
327
+ issues.push({ trackIndex, contentIndex });
328
+ }
329
+ });
330
+ });
331
+ return issues;
332
+ }
317
333
  var Composition = z2.object({
318
334
  v: z2.literal(1, {
319
335
  error: (issue) => issue.input === void 0 ? 'Missing version envelope: add top-level "v": 1 to the composition.' : `Invalid version envelope: top-level "v" must be the literal 1 (got ${JSON.stringify(issue.input)}).`
@@ -332,7 +348,15 @@ var Composition = z2.object({
332
348
  accessibility: CompositionAccessibility.optional(),
333
349
  ownerOrgId: z2.string().optional(),
334
350
  acl: AccessControl.optional()
335
- }).strict();
351
+ }).strict().superRefine((composition, ctx) => {
352
+ for (const issue of captionVisibilityIssues(composition)) {
353
+ ctx.addIssue({
354
+ code: "custom",
355
+ path: ["tracks", issue.trackIndex, "contents", issue.contentIndex, "captionVisibility"],
356
+ message: "captionVisibility is supported only on video media clips"
357
+ });
358
+ }
359
+ });
336
360
  var CompositionAuthorKind = z2.enum(["user", "agent", "import"]);
337
361
  var CompositionVersion = z2.object({
338
362
  id: z2.string().min(1),
@@ -502,6 +526,7 @@ export {
502
526
  Region,
503
527
  CaptionRegion,
504
528
  ClipFit,
529
+ CaptionVisibility,
505
530
  PerClipEffect,
506
531
  KeyframeEasing,
507
532
  Keyframe,
@@ -519,6 +544,7 @@ export {
519
544
  CompositionCaptions,
520
545
  captionsAreBehindSubject,
521
546
  captionWords,
547
+ captionVisibilityIssues,
522
548
  Composition,
523
549
  CompositionAuthorKind,
524
550
  CompositionVersion,
@@ -2,7 +2,7 @@ import {
2
2
  selectAllClips,
3
3
  selectAllOverlays,
4
4
  selectSceneMarkers
5
- } from "./chunk-NLXQ7WTH.js";
5
+ } from "./chunk-5JCLZPMV.js";
6
6
 
7
7
  // ../authoring/src/context/transcript.ts
8
8
  var MAX_TRANSCRIPT_CHARS = 6e4;
@@ -3,13 +3,13 @@ import {
3
3
  projectMediaPlaybackSpans,
4
4
  sliceTranscriptWords,
5
5
  splitIntoSentences
6
- } from "./chunk-INYP56TC.js";
6
+ } from "./chunk-3I43W7DP.js";
7
7
  import {
8
8
  createHeadlessStore,
9
9
  findClipById,
10
10
  findMarkerById,
11
11
  findTrackContainingClipId
12
- } from "./chunk-NLXQ7WTH.js";
12
+ } from "./chunk-5JCLZPMV.js";
13
13
  import {
14
14
  CaptionSegment,
15
15
  CaptionStyle,
@@ -19,8 +19,9 @@ import {
19
19
  PerClipEffect,
20
20
  TimelineClip,
21
21
  Track,
22
- Transition
23
- } from "./chunk-LZEX2GAY.js";
22
+ Transition,
23
+ captionVisibilityIssues
24
+ } from "./chunk-CV3QQUMK.js";
24
25
  import {
25
26
  ReframeSegment
26
27
  } from "./chunk-B7J5UUUV.js";
@@ -588,7 +589,12 @@ function applyCaptionOpToStore(store, op) {
588
589
  function applyOp(composition, op) {
589
590
  const store = createHeadlessStore(composition);
590
591
  applyOpToStore(store, op);
591
- return store.getState().composition;
592
+ const next = store.getState().composition;
593
+ const issue = captionVisibilityIssues(next)[0];
594
+ if (issue) {
595
+ throw new Error(`tracks[${issue.trackIndex}].contents[${issue.contentIndex}].captionVisibility: captionVisibility is supported only on video media clips`);
596
+ }
597
+ return next;
592
598
  }
593
599
  function applyOpToStore(store, op) {
594
600
  const composition = store.getState().composition;
@@ -5,7 +5,7 @@ import {
5
5
  isOk,
6
6
  opById,
7
7
  safeParse
8
- } from "./chunk-AOIY7NGF.js";
8
+ } from "./chunk-2M65KQNG.js";
9
9
 
10
10
  // ../mcp/src/wait.ts
11
11
  var defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
@@ -7,13 +7,13 @@ import {
7
7
  } from "./chunk-7AZLFN26.js";
8
8
  import {
9
9
  selectAllOverlays
10
- } from "./chunk-NLXQ7WTH.js";
10
+ } from "./chunk-5JCLZPMV.js";
11
11
  import {
12
12
  ComposePlan
13
- } from "./chunk-LO3DH776.js";
13
+ } from "./chunk-MBSQKRDF.js";
14
14
  import {
15
15
  OverlayClipSource
16
- } from "./chunk-LZEX2GAY.js";
16
+ } from "./chunk-CV3QQUMK.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-AIUJG7R4.js");
66
+ const { buildDirectorContext } = await import("./context-2MBCDTCZ.js");
67
67
  return buildDirectorContext(capabilities);
68
68
  }
69
69
  },
@@ -4,7 +4,7 @@ import {
4
4
  Format,
5
5
  GraphicRole,
6
6
  OpaqueId
7
- } from "./chunk-LZEX2GAY.js";
7
+ } from "./chunk-CV3QQUMK.js";
8
8
  import {
9
9
  brandKitCaptionFaceIssues
10
10
  } from "./chunk-AVTEPAWI.js";
@@ -2,7 +2,7 @@ import {
2
2
  COMPOSE_PLANNER_TOOLS,
3
3
  COMPOSE_ROLE_TOOLS,
4
4
  dispatchComposeRoleTool
5
- } from "./chunk-KY3QBG7O.js";
5
+ } from "./chunk-KMDZDH5E.js";
6
6
 
7
7
  // ../authoring/src/agent/buildTools.ts
8
8
  import { tool } from "ai";
@@ -2,12 +2,12 @@ import {
2
2
  SCENE_SHOT_RESOURCE_DESCRIPTION,
3
3
  SCENE_SHOT_RESOURCE_URI,
4
4
  sceneShotContract
5
- } from "./chunk-FYS2XUKJ.js";
5
+ } from "./chunk-3OG2674K.js";
6
6
  import {
7
7
  querySchemaShape,
8
8
  serializeQuery,
9
9
  waitForJob
10
- } from "./chunk-XSBVOXSB.js";
10
+ } from "./chunk-JWW54N24.js";
11
11
  import {
12
12
  CURATED_TOOLS
13
13
  } from "./chunk-4WBSXHQA.js";
@@ -28,10 +28,10 @@ import {
28
28
  text,
29
29
  textWithData,
30
30
  withMedia
31
- } from "./chunk-AOIY7NGF.js";
31
+ } from "./chunk-2M65KQNG.js";
32
32
  import {
33
33
  CompositionOp
34
- } from "./chunk-WIPIYUY2.js";
34
+ } from "./chunk-IHXMBXXL.js";
35
35
 
36
36
  // ../mcp/src/prompts.ts
37
37
  var skillListCache = null;
package/dist/compose.js CHANGED
@@ -5,40 +5,40 @@ import "./chunk-GULDS3VE.js";
5
5
  import {
6
6
  isContrastCritical
7
7
  } from "./chunk-QDBVYZSF.js";
8
- import {
9
- catalog
10
- } from "./chunk-RBWS5XHE.js";
11
- import "./chunk-DLF4WVSE.js";
12
- import "./chunk-U4V4FZGE.js";
13
- import {
14
- catalog as catalog3
15
- } from "./chunk-FVDFPJHT.js";
16
8
  import {
17
9
  catalog as catalog6
18
- } from "./chunk-B3GSTQLR.js";
19
- import {
20
- catalog as catalog5
21
- } from "./chunk-RAXHCRVV.js";
10
+ } from "./chunk-VLJOIUHL.js";
22
11
  import {
23
12
  catalog as catalog2
24
- } from "./chunk-7SXY6NFW.js";
13
+ } from "./chunk-5ZQLMPDY.js";
25
14
  import {
26
15
  catalog as catalog8
27
- } from "./chunk-RL5SO653.js";
28
- import "./chunk-LT4PWSR2.js";
29
- import "./chunk-FWSJLHSV.js";
30
- import "./chunk-ZFEXATWN.js";
16
+ } from "./chunk-7SQOXIWR.js";
31
17
  import {
32
18
  catalog as catalog4
33
19
  } from "./chunk-CZOVEX2D.js";
34
- import "./chunk-XHGZ2E77.js";
35
20
  import {
36
21
  catalog as catalog7
37
- } from "./chunk-O3SJTX6S.js";
38
- import "./chunk-QGAWDLYX.js";
22
+ } from "./chunk-4B4V3HYW.js";
39
23
  import "./chunk-S5H6GH6M.js";
40
24
  import "./chunk-QAGGJHAF.js";
41
25
  import "./chunk-MFHXCHRI.js";
26
+ import {
27
+ catalog
28
+ } from "./chunk-X34KW2SL.js";
29
+ import "./chunk-DLF4WVSE.js";
30
+ import "./chunk-U4V4FZGE.js";
31
+ import "./chunk-LT4PWSR2.js";
32
+ import "./chunk-FWSJLHSV.js";
33
+ import {
34
+ catalog as catalog3
35
+ } from "./chunk-FVDFPJHT.js";
36
+ import "./chunk-QGAWDLYX.js";
37
+ import {
38
+ catalog as catalog5
39
+ } from "./chunk-RAXHCRVV.js";
40
+ import "./chunk-XHGZ2E77.js";
41
+ import "./chunk-ZFEXATWN.js";
42
42
  import "./chunk-W2245F6G.js";
43
43
  import "./chunk-2PU2TSUG.js";
44
44
  import "./chunk-XV2K3AQT.js";
@@ -48,14 +48,14 @@ import {
48
48
  getPrimitiveTextParam,
49
49
  listPrimitivesByCategory
50
50
  } from "./chunk-7AZLFN26.js";
51
- import {
52
- NEUTRAL_RAMP
53
- } from "./chunk-VG2ND6PX.js";
54
51
  import {
55
52
  CueframeError,
56
53
  encodeError
57
54
  } from "./chunk-E63UEO5C.js";
58
55
  import "./chunk-7PA7FGLD.js";
56
+ import {
57
+ NEUTRAL_RAMP
58
+ } from "./chunk-VG2ND6PX.js";
59
59
  import "./chunk-CL5Y6V6K.js";
60
60
  import "./chunk-2L7PYYJK.js";
61
61
  import "./chunk-AVTEPAWI.js";
@@ -1,9 +1,3 @@
1
- import {
2
- placeInLegalArea,
3
- resolveBrandRefsDeep
4
- } from "../chunk-Z6NY6MCL.js";
5
- import "../chunk-ILO4NEZ3.js";
6
- import "../chunk-VG2ND6PX.js";
7
1
  import {
8
2
  ContentBeat,
9
3
  ContentPlan,
@@ -26,10 +20,16 @@ import {
26
20
  PlanRect,
27
21
  StyleRole,
28
22
  ZPlane
29
- } from "../chunk-LZEX2GAY.js";
23
+ } from "../chunk-CV3QQUMK.js";
30
24
  import "../chunk-WPZKOVYF.js";
31
25
  import "../chunk-B7J5UUUV.js";
26
+ import {
27
+ placeInLegalArea,
28
+ resolveBrandRefsDeep
29
+ } from "../chunk-Z6NY6MCL.js";
32
30
  import "../chunk-WREYUH2E.js";
31
+ import "../chunk-ILO4NEZ3.js";
32
+ import "../chunk-VG2ND6PX.js";
33
33
  import "../chunk-AVTEPAWI.js";
34
34
  import "../chunk-2ESYSVXG.js";
35
35
 
@@ -20,9 +20,9 @@ import {
20
20
  selectMediaClipAt,
21
21
  selectSceneMarkers,
22
22
  selectTracksByKind
23
- } from "../chunk-NLXQ7WTH.js";
24
- import "../chunk-LO3DH776.js";
25
- import "../chunk-LZEX2GAY.js";
23
+ } from "../chunk-5JCLZPMV.js";
24
+ import "../chunk-MBSQKRDF.js";
25
+ import "../chunk-CV3QQUMK.js";
26
26
  import "../chunk-WPZKOVYF.js";
27
27
  import "../chunk-B7J5UUUV.js";
28
28
  import "../chunk-KYRDKK2D.js";
@@ -73,8 +73,8 @@ import {
73
73
  import {
74
74
  contrastRatio
75
75
  } from "../chunk-ILO4NEZ3.js";
76
- import "../chunk-VG2ND6PX.js";
77
76
  import "../chunk-E63UEO5C.js";
77
+ import "../chunk-VG2ND6PX.js";
78
78
  import "../chunk-AVTEPAWI.js";
79
79
  import "../chunk-2ESYSVXG.js";
80
80
  export {
@@ -48,7 +48,7 @@ import {
48
48
  WebhookDeliveryStatus,
49
49
  WebhookDestination,
50
50
  YoutubeDestination
51
- } from "../chunk-LO3DH776.js";
51
+ } from "../chunk-MBSQKRDF.js";
52
52
  import {
53
53
  ANIMATABLE_PARAMS,
54
54
  ANIMATABLE_VALUE,
@@ -56,6 +56,7 @@ import {
56
56
  CaptionRegion,
57
57
  CaptionSegment,
58
58
  CaptionStyle,
59
+ CaptionVisibility,
59
60
  CaptionWord,
60
61
  CardClipSource,
61
62
  ClipFit,
@@ -84,9 +85,10 @@ import {
84
85
  Track,
85
86
  TrackContent,
86
87
  Transition,
88
+ captionVisibilityIssues,
87
89
  captionWords,
88
90
  captionsAreBehindSubject
89
- } from "../chunk-LZEX2GAY.js";
91
+ } from "../chunk-CV3QQUMK.js";
90
92
  import {
91
93
  AUTHORED_GRAPHIC_KINDS
92
94
  } from "../chunk-WPZKOVYF.js";
@@ -109,6 +111,7 @@ export {
109
111
  CaptionRegion,
110
112
  CaptionSegment,
111
113
  CaptionStyle,
114
+ CaptionVisibility,
112
115
  CaptionWord,
113
116
  CardClipSource,
114
117
  ClipFit,
@@ -188,6 +191,7 @@ export {
188
191
  WebhookDeliveryStatus,
189
192
  WebhookDestination,
190
193
  YoutubeDestination,
194
+ captionVisibilityIssues,
191
195
  captionWords,
192
196
  captionsAreBehindSubject
193
197
  };