@mengine/medeo-client 2.1.0 → 2.1.1-dsl.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2077 +0,0 @@
1
- import { InferInputType } from "loro-mirror";
2
- import { z } from "zod";
3
- import { LoroDoc, PeerID } from "loro-crdt";
4
-
5
- //#region src/document/generated/video-draft-idl.d.ts
6
- /**
7
- * @generated by @mengine/idl-codegen — DO NOT EDIT MANUALLY.
8
- *
9
- * VideoDraft read-view types extracted from the Smithy IDL
10
- * (medeo-v2-design-materials). Re-run `vp run @mengine/idl-codegen#sync`.
11
- * Source IDL commit: 902e82e3fec1e94b36e14ef671de91abd210dc86
12
- *
13
- * WHY EVERY FIELD IS `T | undefined`:
14
- * AWS `smithy-typescript-codegen` widens every structure member to
15
- * `T | undefined` regardless of the Smithy `@required` trait — it favours
16
- * deserialization robustness (a peer may omit a field on the wire) over
17
- * encoding requiredness in the static type. So these generated types are NOT
18
- * the source of truth for which fields are required: the Smithy `.smithy`
19
- * model is. Many fields here (e.g. `VideoClipPart.play_in` / `play_out` /
20
- * `volume` / `origin_media_id`) are `@required` in the contract.
21
- *
22
- * Requiredness is restored at the write-time gate, not here: see the part
23
- * schemas in `../zod-schema.ts`, which re-mark the `@required` fields as
24
- * mandatory before a VideoDocument is committed to Loro. Do not assume a
25
- * field is optional just because its type is `| undefined`.
26
- */
27
- /**
28
- * @public
29
- * @enum
30
- */
31
- declare const PartKind$1: {
32
- readonly BGM: 'bgm';
33
- readonly CAPTION: 'caption';
34
- readonly SPEECH: 'speech';
35
- readonly VIDEO_CLIP: 'video_clip';
36
- };
37
- /**
38
- * @public
39
- */
40
- type PartKind$1 = (typeof PartKind$1)[keyof typeof PartKind$1];
41
- /**
42
- * @public
43
- */
44
- interface VoiceSummary {
45
- name: string | undefined;
46
- id: string | undefined;
47
- }
48
- /**
49
- * @public
50
- */
51
- interface SpeechPart$1 {
52
- id: string | undefined;
53
- duration_ms: number | undefined;
54
- /**
55
- * Types of parts that can be contained in tracks
56
- * @public
57
- */
58
- kind: PartKind$1 | undefined;
59
- audio_script: string | undefined;
60
- volume: number | undefined;
61
- audio_storage_key: string | undefined;
62
- origin_speech_id: string | undefined;
63
- voice: VoiceSummary | undefined;
64
- caption_ids: string[] | undefined;
65
- }
66
- /**
67
- * Caption visual style configuration
68
- * @public
69
- */
70
- interface CaptionStyle {
71
- /**
72
- * Font ID referencing a font from the font library. Defaults to system font if not provided
73
- * @public
74
- */
75
- font_id?: string | undefined;
76
- /**
77
- * Font size in points
78
- * @public
79
- */
80
- font_size?: number | undefined;
81
- /**
82
- * Font color as hex string (e.g. "#FFFFFF")
83
- * @public
84
- */
85
- font_color?: string | undefined;
86
- /**
87
- * Numeric font weight, e.g. 400 for regular or 700 for bold
88
- * @public
89
- */
90
- font_weight?: number | undefined;
91
- /**
92
- * Caption entrance animation preset ID, e.g. "fade", "slideUp", or "none"
93
- * @public
94
- */
95
- entrance_animation?: string | undefined;
96
- /**
97
- * Caption entrance animation duration in milliseconds
98
- * @public
99
- */
100
- entrance_animation_duration_ms?: number | undefined;
101
- /**
102
- * Caption outline/stroke color as hex string (e.g. "#000000")
103
- * @public
104
- */
105
- stroke_color?: string | undefined;
106
- /**
107
- * Caption outline/stroke width in pixels
108
- * @public
109
- */
110
- stroke_width?: number | undefined;
111
- /**
112
- * Caption center X position as a percentage (0.0 to 1.0)
113
- * @public
114
- */
115
- position_x?: number | undefined;
116
- /**
117
- * Caption center Y position as a percentage (0.0 to 1.0)
118
- * @public
119
- */
120
- position_y?: number | undefined;
121
- }
122
- /**
123
- * @public
124
- */
125
- interface CaptionPart$1 {
126
- id: string | undefined;
127
- duration_ms: number | undefined;
128
- /**
129
- * Types of parts that can be contained in tracks
130
- * @public
131
- */
132
- kind: PartKind$1 | undefined;
133
- speech_part_id: string | undefined;
134
- text: string | undefined;
135
- start_ms: number | undefined;
136
- /**
137
- * Caption visual style (font, size, color, weight, animation, outline). Uses default style if not provided
138
- * @public
139
- */
140
- style?: CaptionStyle | undefined;
141
- }
142
- /**
143
- * @public
144
- * @enum
145
- */
146
- declare const AspectRatio: {
147
- readonly RATIO_16_9: '16:9';
148
- readonly RATIO_9_16: '9:16';
149
- };
150
- /**
151
- * @public
152
- */
153
- type AspectRatio = (typeof AspectRatio)[keyof typeof AspectRatio];
154
- /**
155
- * @public
156
- * @enum
157
- */
158
- declare const AssetSource: {
159
- readonly AI_IMAGES: 'ai_images';
160
- readonly AI_VIDEOS: 'ai_videos';
161
- readonly MY_UPLOADED_ASSETS: 'my_uploaded_assets';
162
- readonly STOCK_VIDEOS: 'stock_videos';
163
- };
164
- /**
165
- * @public
166
- */
167
- type AssetSource = (typeof AssetSource)[keyof typeof AssetSource];
168
- /**
169
- * An extra aspect ratio variant with independent storage keys for thumbnail,
170
- * preview video, and highlight video. Stored inside video_settings JSONB.
171
- * @public
172
- */
173
- interface RatioVariant {
174
- aspect_ratio: string | undefined;
175
- thumb_storage_key: string | undefined;
176
- video_storage_key: string | undefined;
177
- highlight_video_storage_key?: string | undefined;
178
- }
179
- /**
180
- * @public
181
- */
182
- interface VideoCreationSettings$1 {
183
- voice_id?: string | undefined;
184
- duration_ms?: number | undefined;
185
- aspect_ratio?: AspectRatio | undefined;
186
- video_style_id?: string | undefined;
187
- asset_sources?: AssetSource[] | undefined;
188
- recipe_id?: string | undefined;
189
- enable_high_cost_confirm?: boolean | undefined;
190
- user_confirm_cost_threshold?: number | undefined;
191
- /**
192
- * Extra aspect ratio variants with independent storage keys.
193
- * Each variant carries its own thumbnail, preview video, and optional highlight video.
194
- * Used when a recipe supports multiple aspect ratios (e.g. both 16:9 and 9:16).
195
- * @public
196
- */
197
- extra_ratios?: RatioVariant[] | undefined;
198
- }
199
- /**
200
- * @public
201
- */
202
- interface TrackItem$1 {
203
- abs_time_position: number | undefined;
204
- part_id: string | undefined;
205
- }
206
- /**
207
- * @public
208
- */
209
- interface Track$1 {
210
- id: string | undefined;
211
- /**
212
- * Types of parts that can be contained in tracks
213
- * @public
214
- */
215
- parts_kind: PartKind$1 | undefined;
216
- is_hidden: boolean | undefined;
217
- items: TrackItem$1[] | undefined;
218
- }
219
- /**
220
- * @public
221
- */
222
- interface Attachment {
223
- part_id: string | undefined;
224
- relative_time_position: number | undefined;
225
- }
226
- /**
227
- * @public
228
- */
229
- interface PartAggregation {
230
- body_part_id: string | undefined;
231
- attachments: Attachment[] | undefined;
232
- }
233
- /**
234
- * @public
235
- */
236
- interface BgmPart$1 {
237
- id: string | undefined;
238
- duration_ms: number | undefined;
239
- /**
240
- * Types of parts that can be contained in tracks
241
- * @public
242
- */
243
- kind: PartKind$1 | undefined;
244
- audio_storage_key: string | undefined;
245
- volume: number | undefined;
246
- origin_media_id: string | undefined;
247
- }
248
- /**
249
- * @public
250
- * @enum
251
- */
252
- declare const SpeedShiftCategory: {
253
- /**
254
- * Variable speed controlled by Bezier keyframes
255
- */
256
- readonly CURVE: 'curve';
257
- /**
258
- * Constant speed multiplier across the entire clip
259
- */
260
- readonly LINEAR: 'linear';
261
- };
262
- /**
263
- * @public
264
- */
265
- type SpeedShiftCategory = (typeof SpeedShiftCategory)[keyof typeof SpeedShiftCategory];
266
- /**
267
- * @public
268
- */
269
- interface TangentHandle {
270
- x: number | undefined;
271
- y: number | undefined;
272
- }
273
- /**
274
- * @public
275
- */
276
- interface SpeedKeyframe {
277
- position: number | undefined;
278
- rate: number | undefined;
279
- in_tangent?: TangentHandle | undefined;
280
- out_tangent?: TangentHandle | undefined;
281
- }
282
- /**
283
- * @public
284
- */
285
- interface CurveConfig {
286
- keyframes: SpeedKeyframe[] | undefined;
287
- }
288
- /**
289
- * @public
290
- */
291
- interface LinearConfig {
292
- speed: number | undefined;
293
- }
294
- /**
295
- * @public
296
- */
297
- type SpeedShiftConfigUnion = SpeedShiftConfigUnion.CurveMember | SpeedShiftConfigUnion.LinearMember | SpeedShiftConfigUnion.$UnknownMember;
298
- /**
299
- * @public
300
- */
301
- declare namespace SpeedShiftConfigUnion {
302
- interface LinearMember {
303
- linear: LinearConfig;
304
- curve?: never;
305
- $unknown?: never;
306
- }
307
- interface CurveMember {
308
- linear?: never;
309
- curve: CurveConfig;
310
- $unknown?: never;
311
- }
312
- /**
313
- * @public
314
- */
315
- interface $UnknownMember {
316
- linear?: never;
317
- curve?: never;
318
- $unknown: [string, any];
319
- }
320
- interface Visitor<T> {
321
- linear: (value: LinearConfig) => T;
322
- curve: (value: CurveConfig) => T;
323
- _: (name: string, value: any) => T;
324
- }
325
- const visit: <T>(value: SpeedShiftConfigUnion, visitor: Visitor<T>) => T;
326
- }
327
- /**
328
- * @public
329
- */
330
- interface SpeedShift {
331
- category: SpeedShiftCategory | undefined;
332
- mode: string | undefined;
333
- config: SpeedShiftConfigUnion | undefined;
334
- }
335
- /**
336
- * @public
337
- */
338
- interface VideoClipPart$1 {
339
- id: string | undefined;
340
- duration_ms: number | undefined;
341
- /**
342
- * Types of parts that can be contained in tracks
343
- * @public
344
- */
345
- kind: PartKind$1 | undefined;
346
- play_in: number | undefined;
347
- play_out: number | undefined;
348
- volume: number | undefined;
349
- origin_media_id: string | undefined;
350
- speed_shift?: SpeedShift | undefined;
351
- }
352
- /**
353
- * @public
354
- */
355
- type PartUnion$1 = PartUnion$1.BgmMember | PartUnion$1.CaptionMember | PartUnion$1.SpeechMember | PartUnion$1.Video_clipMember | PartUnion$1.$UnknownMember;
356
- /**
357
- * @public
358
- */
359
- declare namespace PartUnion$1 {
360
- interface Video_clipMember {
361
- video_clip: VideoClipPart$1;
362
- bgm?: never;
363
- speech?: never;
364
- caption?: never;
365
- $unknown?: never;
366
- }
367
- interface BgmMember {
368
- video_clip?: never;
369
- bgm: BgmPart$1;
370
- speech?: never;
371
- caption?: never;
372
- $unknown?: never;
373
- }
374
- interface SpeechMember {
375
- video_clip?: never;
376
- bgm?: never;
377
- speech: SpeechPart$1;
378
- caption?: never;
379
- $unknown?: never;
380
- }
381
- interface CaptionMember {
382
- video_clip?: never;
383
- bgm?: never;
384
- speech?: never;
385
- caption: CaptionPart$1;
386
- $unknown?: never;
387
- }
388
- /**
389
- * @public
390
- */
391
- interface $UnknownMember {
392
- video_clip?: never;
393
- bgm?: never;
394
- speech?: never;
395
- caption?: never;
396
- $unknown: [string, any];
397
- }
398
- interface Visitor<T> {
399
- video_clip: (value: VideoClipPart$1) => T;
400
- bgm: (value: BgmPart$1) => T;
401
- speech: (value: SpeechPart$1) => T;
402
- caption: (value: CaptionPart$1) => T;
403
- _: (name: string, value: any) => T;
404
- }
405
- const visit: <T>(value: PartUnion$1, visitor: Visitor<T>) => T;
406
- }
407
- /**
408
- * Timeline configuration for video editing
409
- * @public
410
- */
411
- interface Timeline$1 {
412
- duration_ms: number | undefined;
413
- unit_time_ms: number | undefined;
414
- }
415
- /**
416
- * Complete video draft information with timeline and tracks
417
- * @public
418
- */
419
- interface VideoDraft$1 {
420
- id?: string | undefined;
421
- project_id: string | undefined;
422
- owner_id: string | undefined;
423
- /**
424
- * for-code-gen: property value may be empty string ("")
425
- * @public
426
- */
427
- thumbnail_storage_key: string | undefined;
428
- /**
429
- * Timeline configuration for video editing
430
- * @public
431
- */
432
- timeline?: Timeline$1 | undefined;
433
- video_creation_settings?: VideoCreationSettings$1 | undefined;
434
- chat_session_id: string | undefined;
435
- main_track?: Track$1 | undefined;
436
- above_main_tracks: Track$1[] | undefined;
437
- below_main_tracks: Track$1[] | undefined;
438
- part_aggregations: PartAggregation[] | undefined;
439
- part_library: Record<string, PartUnion$1> | undefined;
440
- version: number | undefined;
441
- }
442
- //#endregion
443
- //#region src/document/types.d.ts
444
- type PartKind = 'video_clip' | 'speech' | 'caption' | 'bgm';
445
- /**
446
- * Project-level creation settings. Mirrors the IDL, but keeps the two fields the
447
- * upstream (Director / FE) sends as an explicit `null` nullable — the IDL models
448
- * "absent" only as `undefined`, whereas these arrive as `null` to mean
449
- * "explicitly cleared". Relaxing the type here avoids forcing every caller to
450
- * map `null` → `undefined`.
451
- */
452
- type VideoCreationSettings = Omit<VideoCreationSettings$1, 'video_style_id' | 'duration_ms'> & {
453
- video_style_id?: string | null | undefined;
454
- duration_ms?: number | null | undefined;
455
- };
456
- /**
457
- * Video clip part. `duration_ms` is dropped from the authoritative type
458
- * (reference/17 §5): it is the derived effective length and is re-derived into
459
- * the read-view by the projection. `play_in` / `play_out` are required (smithy
460
- * `@required`), so the timeline length is always the trim window over the speed
461
- * multiplier — no need to store the media's intrinsic length either. `speed_shift`
462
- * is the IDL type. See `effectiveVideoClipDurationMs`.
463
- */
464
- type VideoClipPart = Omit<VideoClipPart$1, 'duration_ms'>;
465
- /**
466
- * Speech part. `duration_ms` is dropped from the authoritative type
467
- * (reference/17 §5) in favour of the engine-only `media_duration_ms`: a speech
468
- * cannot be trimmed or speed-shifted, so its effective timeline duration equals
469
- * the TTS audio's intrinsic length. The read-view `duration_ms` is re-derived
470
- * from it by the projection.
471
- */
472
- type SpeechPart = Omit<SpeechPart$1, 'duration_ms'> & {
473
- media_duration_ms?: number | undefined;
474
- };
475
- /**
476
- * Authoritative caption part. The IDL `CaptionPart` carries `duration_ms` (the
477
- * effective display length, a derived read-view value); the authoritative store
478
- * instead keeps `initial_duration_ms` — the caption's length at generation time,
479
- * parsed from the voiceover, a resource-intrinsic fact that does not change
480
- * (reference/17 §5; onscreen-caption plan). The effective `duration_ms` is
481
- * re-derived into the `VideoDraft` read-view by the projection.
482
- *
483
- * `speech_part_id` / `start_ms` are kept as resource-intrinsic facts (which
484
- * speech it was split from, and its offset in that source) — reference/17
485
- * principle 4.
486
- */
487
- type CaptionPart = Omit<CaptionPart$1, 'duration_ms'> & {
488
- initial_duration_ms?: number | undefined;
489
- };
490
- /**
491
- * Background music. The IDL marks `duration_ms` required (via its part mixin),
492
- * but a bgm has no authoritative duration — its effective length is always the
493
- * whole timeline, derived on read (RFC 02 §0b). The engine therefore keeps it
494
- * optional rather than carrying the IDL's required field into storage.
495
- */
496
- type BgmPart = Omit<BgmPart$1, 'duration_ms'> & {
497
- duration_ms?: number | undefined;
498
- };
499
- /**
500
- * How a `TrackItem`'s start is determined — the authoritative positioning fact
501
- * (RFC 02 §4, reference/17 §3). The absolute time is never stored; it is solved
502
- * by the cascade at projection time. The three modes express "where the start
503
- * comes from": `sequential` follows the track's flow order, `anchored` hangs off
504
- * another part plus an offset, `absolute` pins to the timeline origin.
505
- * `anchorPartId` points at another item's `part_id` (a part is placed at most
506
- * once per lane, so `part_id` is the placement identity).
507
- *
508
- * `time_position` carries only the real editing intent (mode + anchor + offset),
509
- * so it is a single last-writer-wins unit safe to overwrite wholesale. The
510
- * derived fallback snapshot lives outside it on `TrackItem.fallback_abs_ms`.
511
- */
512
- type TrackItemTimePosition = {
513
- mode: 'sequential';
514
- } | {
515
- mode: 'anchored';
516
- anchorPartId: string;
517
- offsetMs: number;
518
- } | {
519
- mode: 'absolute';
520
- offsetMs: number;
521
- };
522
- /**
523
- * Authoritative track item: only facts. Absolute time is derived, not stored.
524
- *
525
- * `fallback_abs_ms` is the one deliberately-retained derived snapshot in
526
- * authoritative state: the `relative` item's absolute landing, so that when its
527
- * anchor is concurrently deleted (orphan, RFC 02 §11.1), the item can be put
528
- * back on the timeline and re-parented to the nearest video — orphan handling
529
- * needs an absolute anchor and cannot guess one.
530
- *
531
- * It is written by the write-side ops that create or move a `relative` item:
532
- * each resolves the item's absolute landing from its anchor once (add/change
533
- * speech from the host clip's start + offset; `moveSpeeches` from the requested
534
- * start; §9.1 reparent from the preserved abs) and stamps it here. The read-side
535
- * projection never writes it back — the authoritative model stays write-derived,
536
- * not read-derived. It is a field of its own (not inside `time_position`) so the
537
- * two are separate LWW units: a fallback refresh can never clobber a concurrent
538
- * `offsetMs` edit, since they carry unequal business value. When the anchor's
539
- * absolute position cannot be resolved at write time it is left undefined. Only
540
- * meaningful for `anchored` items.
541
- */
542
- interface TrackItem {
543
- part_id: string;
544
- time_position: TrackItemTimePosition;
545
- fallback_abs_ms?: number | undefined;
546
- }
547
- interface Track {
548
- id: string | undefined;
549
- parts_kind: PartKind | undefined;
550
- is_hidden: boolean | undefined;
551
- items: TrackItem[] | undefined;
552
- }
553
- /**
554
- * Authoritative part union: a flat discriminated union over the four part kinds.
555
- * Deliberately *not* the IDL's namespace union (no `$unknown` / `visit`): engine
556
- * storage rejects unknown kinds, and projection / validation read parts by plain
557
- * `part.video_clip` / `part.speech` property access, which this shape supports.
558
- */
559
- type PartUnion = {
560
- video_clip: VideoClipPart;
561
- speech?: never;
562
- caption?: never;
563
- bgm?: never;
564
- } | {
565
- video_clip?: never;
566
- speech: SpeechPart;
567
- caption?: never;
568
- bgm?: never;
569
- } | {
570
- video_clip?: never;
571
- speech?: never;
572
- caption: CaptionPart;
573
- bgm?: never;
574
- } | {
575
- video_clip?: never;
576
- speech?: never;
577
- caption?: never;
578
- bgm: BgmPart;
579
- };
580
- /**
581
- * Read-view part union for the derived `VideoDraft` (reference/17 §5/§7). The
582
- * authoritative parts drop their derived durations; the projection re-injects an
583
- * effective `duration_ms` for downstream compatibility — for a video clip it is
584
- * `(play_out - play_in) / speed`, for a speech it is `media_duration_ms`, for a
585
- * caption it is `initial_duration_ms`, for a bgm it is the timeline total. Each
586
- * read-view part is therefore the authoritative part plus a derived `duration_ms`.
587
- */
588
- type VideoDraftPartUnion = {
589
- video_clip: VideoClipPart & {
590
- duration_ms?: number;
591
- };
592
- speech?: never;
593
- caption?: never;
594
- bgm?: never;
595
- } | {
596
- video_clip?: never;
597
- speech: SpeechPart & {
598
- duration_ms?: number;
599
- };
600
- caption?: never;
601
- bgm?: never;
602
- } | {
603
- video_clip?: never;
604
- speech?: never;
605
- caption: CaptionPart & {
606
- duration_ms?: number;
607
- };
608
- bgm?: never;
609
- } | {
610
- video_clip?: never;
611
- speech?: never;
612
- caption?: never;
613
- bgm: BgmPart & {
614
- duration_ms?: number;
615
- };
616
- };
617
- /**
618
- * Legacy Draft import shape. It allows omitted durations and engine extensions
619
- * so existing fixtures and migrations can state only the facts they have.
620
- * Projection returns the narrower `VideoDraftContent` contract instead.
621
- */
622
- type VideoDraft = Omit<VideoDraft$1, 'part_library' | 'video_creation_settings'> & {
623
- part_library: Record<string, VideoDraftPartUnion> | undefined;
624
- video_creation_settings?: VideoCreationSettings | undefined;
625
- };
626
- /**
627
- * The complete content read model produced by the shared projection. Business
628
- * identity, settings, thumbnail and revision counters are assembled by Director;
629
- * keeping an explicit field list prevents new business DTO fields entering here.
630
- */
631
- type VideoDraftContent = Pick<VideoDraft, 'timeline' | 'main_track' | 'above_main_tracks' | 'below_main_tracks' | 'part_aggregations'> & {
632
- part_library: Record<string, VideoDraftContentPartUnion> | undefined;
633
- };
634
- /** Projection always states the duration field; legacy imports may omit it. */
635
- type VideoDraftContentPartUnion = {
636
- video_clip: VideoClipPart & {
637
- duration_ms: number | undefined;
638
- };
639
- speech?: never;
640
- caption?: never;
641
- bgm?: never;
642
- } | {
643
- video_clip?: never;
644
- speech: SpeechPart & {
645
- duration_ms: number | undefined;
646
- };
647
- caption?: never;
648
- bgm?: never;
649
- } | {
650
- video_clip?: never;
651
- speech?: never;
652
- caption: CaptionPart & {
653
- duration_ms: number | undefined;
654
- };
655
- bgm?: never;
656
- } | {
657
- video_clip?: never;
658
- speech?: never;
659
- caption?: never;
660
- bgm: BgmPart & {
661
- duration_ms: number | undefined;
662
- };
663
- };
664
- /** Authoritative timeline: `duration_ms` is derived (= longest track), not stored. */
665
- interface Timeline {
666
- unit_time_ms: number | undefined;
667
- }
668
- /**
669
- * The `timeline.unit_time_ms` the read-view states when the document states none.
670
- *
671
- * One frame at 30fps. A document legitimately has no such fact (display
672
- * granularity is the editor's, not the timeline's), but the read-view IDL marks
673
- * the field `@required`, so the projection has to name a value. This one is a
674
- * usable granularity; `0` — which a downstream consumer had been defaulting to —
675
- * is not, and passes any `>= 0` guard on its way to an editor that cannot use it.
676
- */
677
- declare const DEFAULT_UNIT_TIME_MS = 33.333;
678
- /**
679
- * Authoritative collaborative document: only facts. Positioning lives on each
680
- * `TrackItem.time_position`; absolute time, `part_aggregations`, and total
681
- * duration are derived in the `VideoDraft` projection, not stored here (RFC 02 §6).
682
- *
683
- * The content mirrors Loro storage: timeline, part library, and a single
684
- * ordered `tracks` list (reference/17 §4). Business metadata stays in Director. A
685
- * track's lane is expressed by its `parts_kind`, not by which container it lives
686
- * in — the `main` / `above` / `below` three-pane view is reconstructed at
687
- * projection time. Order is the list order itself, so there is no `lane` /
688
- * `lane_order` field to diverge under concurrent edits.
689
- */
690
- interface VideoDocument {
691
- timeline: Timeline | undefined;
692
- tracks: Track[] | undefined;
693
- part_library: Record<string, PartUnion> | undefined;
694
- }
695
- type VideoDocumentValidationIssueCode = 'invalid_schema' | 'duplicate_track_item_identity' | 'duplicate_lane_track' | 'unknown_part_kind' | 'part_kind_mismatch' | 'missing_part_reference' | 'track_kind_mismatch' | 'main_track_non_video_clip' | 'invalid_part_value' | 'invalid_speech_caption_reference' | 'invalid_position_anchor';
696
- /**
697
- * Issue severity (RFC 02 §11.1). `error` is a hard reject — the document is not
698
- * a legal `VideoDocument` and must not be projected. `recoverable` marks a
699
- * business inconsistency the projection is designed to heal on read (currently
700
- * only a dangling `anchorPartId`: the orphan condition, recovered via the item's
701
- * `fallback_abs_ms` snapshot + cascade reassign), so it is surfaced for
702
- * observability but does NOT block projection. Absent `severity` means `error`.
703
- */
704
- type VideoDocumentValidationIssueSeverity = 'error' | 'recoverable';
705
- interface VideoDocumentValidationIssue {
706
- code: VideoDocumentValidationIssueCode;
707
- path: string;
708
- message: string;
709
- severity?: VideoDocumentValidationIssueSeverity;
710
- }
711
- //#endregion
712
- //#region src/document/projection.d.ts
713
- /**
714
- * Projection between authoritative `VideoDocument` and compatible content
715
- * layouts (RFC 02 §5/§7). Both directions live here:
716
- *
717
- * - `toVideoDocument` ingests a `VideoDraft`, deriving each item's `position`
718
- * from the legacy absolute layout + aggregations; derived values (abs time,
719
- * `part_aggregations`, total duration) are dropped.
720
- * - `fromVideoDocument` solves a `VideoDocument` into `VideoDraftContent` via the
721
- * timeline-core cascade, re-deriving exactly those values.
722
- *
723
- * Business validation lives in `validation.ts`; `fromVideoDocument` asserts a
724
- * valid document before solving.
725
- */
726
- /**
727
- * Ingest the legacy `VideoDraft` into the authoritative `VideoDocument`,
728
- * deriving each item's `time_position` from the legacy absolute layout +
729
- * aggregations (RFC 02 §4/§5). Absolute time, `part_aggregations`, and total
730
- * duration are dropped — they are re-derived by the projection.
731
- */
732
- declare function toVideoDocument(draft: Pick<VideoDraft, keyof VideoDraftContent>): VideoDocument;
733
- /** speech/attachment part_id → its host video part_id + relative offset. */
734
- type SpeechHostMap = Map<string, {
735
- hostPartId: string;
736
- offsetMs: number;
737
- }>;
738
- /**
739
- * Build a speech-host map from a part_aggregations list. Used by
740
- * `toVideoDocument` (legacy VideoDraft → VideoDocument) to recover each speech's
741
- * host video clip and relative offset. Aggregation items with null ids are
742
- * skipped (malformed input tolerance).
743
- */
744
- declare function buildSpeechHostMap(aggregations: Array<{
745
- body_part_id?: string | null;
746
- attachments?: Array<{
747
- part_id?: string | null;
748
- relative_time_position?: number | null;
749
- }> | null;
750
- }> | null | undefined): SpeechHostMap;
751
- /** The derived time position + orphan-recovery snapshot for one item. */
752
- interface DerivedItemPosition {
753
- timePosition: TrackItemTimePosition;
754
- /** Present only for `anchored` items (RFC 02 §11.1). */
755
- fallbackAbsMs?: number;
756
- }
757
- /**
758
- * Derive `time_position` (and `fallbackAbsMs` for anchored items) from a legacy
759
- * absolute time + pre-built speech-host map + part library. The three-branch
760
- * rule (RFC 02 §4/§5, reference/17 §3):
761
- *
762
- * 1. main-track → `sequential`
763
- * 2. speech/attachment (part_id in speechHost) → `anchored(host, offsetMs)`
764
- * 3. caption (part has `speech_part_id`) → `anchored(speech, start_ms)`
765
- * 4. everything else → `absolute(abs)`
766
- *
767
- * `partLibrary` values may be `PartUnion | string | undefined` (draft raw
768
- * form); only object-typed entries are inspected for `caption`.
769
- */
770
- declare function derivePositionFromAbs(partId: string, abs: number, isMain: boolean, speechHost: SpeechHostMap, partLibrary: Record<string, PartUnion | string | undefined>): DerivedItemPosition;
771
- /**
772
- * Project `VideoDocument` into `VideoDraftContent`, solving each item's
773
- * absolute position, the `part_aggregations`, and
774
- * the total duration via the timeline-core cascade.
775
- *
776
- * The read-view is a compatibility contract, and the IDL declares
777
- * `Timeline.unit_time_ms` and `Track.is_hidden` `@required`
778
- * (`video_draft_comp.smithy`) — so a projection that omitted them handed every
779
- * consumer a payload that violated the shape it claims to satisfy, leaving each
780
- * one to invent its own default. Two already had, and they disagreed: the agent
781
- * harness used `unit_time_ms: 0`, director used a frame at 30fps. Defaulting here
782
- * makes the contract true at the one place that produces it.
783
- *
784
- * These two are defaultable because the projection knows their values on its own:
785
- * absent `unit_time_ms` means "no display granularity was ever stated" and absent
786
- * `is_hidden` means "this track was never hidden". `version` is NOT defaultable
787
- * here — it belongs to Director assembly using the server envelope update_seq.
788
- * Neither business metadata nor a revision counter belongs in content projection.
789
- */
790
- declare function fromVideoDocument(document: VideoDocument): VideoDraftContent;
791
- //#endregion
792
- //#region src/document/initial-document.d.ts
793
- /**
794
- * Build the `VideoDocument` a newly created project starts from: the caller's
795
- * no parts and one empty track per lane. Business facts remain in Director.
796
- *
797
- * The empty lane tracks are the reason this function exists rather than callers
798
- * assembling a document inline. Lane tracks are otherwise minted lazily by the
799
- * first op that needs one (`ensureLaneTrack`), which is find-then-mint over a
800
- * CRDT list — so if the Agent's first generation and a user edit race on an
801
- * empty document, each mints its own copy of the same lane and the merge keeps
802
- * both. Two video_clip tracks violate the at-most-one-main-track rule, and the
803
- * merged document becomes unprojectable for *every* reader (editor, render,
804
- * share) with no winning replica to fall back on. Seeding all four lanes up
805
- * front means `ensureLaneTrack` only ever finds, never mints, so the race cannot
806
- * happen on a document created here.
807
- *
808
- * All four, not just the main lane: the secondary lanes fail less loudly (a
809
- * duplicate pane rather than an unreadable document), but they fail by the same
810
- * mechanism, and covering only the fatal one would leave three live races.
811
- *
812
- * `timeline` is left absent: `unit_time_ms` is a display concern the editor
813
- * supplies, and total duration is derived on read (RFC 02 §6), so a new document
814
- * has no timeline fact to state.
815
- */
816
- declare function buildInitialVideoDocument(): VideoDocument;
817
- //#endregion
818
- //#region src/document/validation.d.ts
819
- /**
820
- * Business-level schema guard for `VideoDocument` (RFC 03 §9). It is the gate
821
- * that decides whether an arbitrary value is a *legal* `VideoDocument` before it
822
- * is written into Loro — distinct from two neighbours:
823
- *
824
- * - `zod-schema.ts` (`videoDocumentSchema`) checks structure/shape only; this
825
- * file layers the business rules on top (part-kind match, reference integrity,
826
- * `position.anchorPartId` targets, value ranges, identity uniqueness).
827
- * - loro-mirror's own `validateSchema` (run on every `setState`) only checks the
828
- * storage structure, never these business invariants.
829
- *
830
- * Projection (`projection.ts`) calls `assertValidVideoDocument` before solving a
831
- * document into the legacy `VideoDraft`.
832
- */
833
- declare class VideoDocumentValidationError extends Error {
834
- readonly issues: VideoDocumentValidationIssue[];
835
- constructor(issues: VideoDocumentValidationIssue[]);
836
- }
837
- /**
838
- * Assert the document is legal enough to project. Only `error`-severity issues
839
- * hard-reject; `recoverable` ones (dangling anchor / orphan, RFC 02 §11.1) are
840
- * left for the projection to heal on read and do NOT throw. Use
841
- * `validateVideoDocument` directly to inspect recoverable issues too.
842
- */
843
- declare function assertValidVideoDocument(document: unknown): asserts document is VideoDocument;
844
- declare function validateVideoDocument(document: unknown): VideoDocumentValidationIssue[];
845
- //#endregion
846
- //#region src/document/mirror-schema.d.ts
847
- declare const videoDocumentMirrorSchema: import("loro-mirror").RootSchemaType<{
848
- timeline: import("loro-mirror").LoroMapSchema<{
849
- unit_time_ms: /*elided*/any;
850
- }> & {
851
- options: {};
852
- } & {
853
- catchall: <C extends import("loro-mirror").SchemaType>(catchallSchema: C) => import("loro-mirror").LoroMapSchemaWithCatchall<{
854
- unit_time_ms: /*elided*/any;
855
- }, C>;
856
- };
857
- tracks: import("loro-mirror").LoroMovableListSchema<import("loro-mirror").LoroMapSchema<{
858
- id: /*elided*/any;
859
- parts_kind: /*elided*/any;
860
- is_hidden: /*elided*/any;
861
- items: /*elided*/any;
862
- }> & {
863
- options: {};
864
- } & {
865
- catchall: <C extends import("loro-mirror").SchemaType>(catchallSchema: C) => import("loro-mirror").LoroMapSchemaWithCatchall<{
866
- id: /*elided*/any;
867
- parts_kind: /*elided*/any;
868
- is_hidden: /*elided*/any;
869
- items: /*elided*/any;
870
- }, C>;
871
- }> & {
872
- options: {};
873
- };
874
- part_library: import("loro-mirror").LoroMapSchemaWithCatchall<{}, import("loro-mirror").LoroMapSchema<{
875
- video_clip: /*elided*/any;
876
- speech: /*elided*/any;
877
- caption: /*elided*/any;
878
- bgm: /*elided*/any;
879
- }> & {
880
- options: {};
881
- } & {
882
- catchall: <C extends import("loro-mirror").SchemaType>(catchallSchema: C) => import("loro-mirror").LoroMapSchemaWithCatchall<{
883
- video_clip: /*elided*/any;
884
- speech: /*elided*/any;
885
- caption: /*elided*/any;
886
- bgm: /*elided*/any;
887
- }, C>;
888
- }> & {
889
- options: {};
890
- };
891
- }> & {
892
- options: {};
893
- };
894
- type VideoDocumentMirrorSchema = typeof videoDocumentMirrorSchema;
895
- /**
896
- * The mutable draft an op's `transact` callback edits, inferred from the schema.
897
- *
898
- * `InferInputType` is the schema's *input* shape: the declared business fields
899
- * with the `$cid` container ids (which mirror injects into its output
900
- * `InferType`) made optional, so ops assign plain objects without supplying
901
- * `$cid`. Deriving it from the schema keeps draft and storage in lockstep — a
902
- * schema change is a compile error at every edit site, not a silent drift.
903
- * Reorders within `items` still diff to real Loro `move` ops because the schema
904
- * keys items by `part_id`.
905
- */
906
- type VideoDocumentDraft = InferInputType<VideoDocumentMirrorSchema>;
907
- /** Track value as it appears in a draft. Derived from the single `tracks` movable list. */
908
- type TrackDraft = NonNullable<NonNullable<VideoDocumentDraft['tracks']>[number]>;
909
- /** A single track item in a draft. */
910
- type TrackItemDraft = NonNullable<NonNullable<TrackDraft['items']>[number]>;
911
- //#endregion
912
- //#region src/editor/schemas/add-speeches.d.ts
913
- /**
914
- * Add speeches (and their captions). TTS runs upstream; the stable speech /
915
- * caption parts arrive materialized (see `speech-assets.ts`). The op writes the
916
- * parts and each speech's `{ mode:'anchored', anchorPartId, offsetMs }` fact
917
- * verbatim — no write-time host-picking, no cascade (RFC 02 §4). The projection
918
- * derives absolute positions on read.
919
- */
920
- declare const addSpeechesInputSchema: z.ZodObject<{
921
- speeches: z.ZodArray<z.ZodObject<{
922
- speech_id: z.ZodString;
923
- anchor_part_id: z.ZodString;
924
- offset_ms: z.ZodNumber;
925
- audio_storage_key: z.ZodString;
926
- duration_ms: z.ZodNumber;
927
- audio_script: z.ZodString;
928
- volume: z.ZodNumber;
929
- voice: z.ZodObject<{
930
- id: z.ZodString;
931
- name: z.ZodString;
932
- }, z.core.$strip>;
933
- origin_speech_id: z.ZodString;
934
- caption_ids: z.ZodArray<z.ZodString>;
935
- }, z.core.$strip>>;
936
- captions: z.ZodArray<z.ZodObject<{
937
- caption_id: z.ZodString;
938
- speech_part_id: z.ZodString;
939
- text: z.ZodString;
940
- start_ms: z.ZodNumber;
941
- duration_ms: z.ZodNumber;
942
- }, z.core.$strip>>;
943
- }, z.core.$strip>;
944
- type AddSpeechesInput = z.infer<typeof addSpeechesInputSchema>;
945
- //#endregion
946
- //#region src/editor/schemas/add-video-clips.d.ts
947
- /**
948
- * Add video clips to a track. Each clip's duration facts are separated so a
949
- * single number is never overloaded (RFC 02 / `reference/16` §0b):
950
- *
951
- * - `media_duration_ms` is the source media's intrinsic full length (a resource
952
- * fact, written to the part);
953
- * - `play_in` / `play_out` are the optional trim window into that media; when
954
- * omitted the whole media is used (`play_in=0`, `play_out=media_duration_ms`).
955
- *
956
- * The clip's effective timeline duration is derived by the projection from the
957
- * trim window and `speed_shift` — it is never an input here.
958
- */
959
- declare const addVideoClipsInputSchema: z.ZodObject<{
960
- clips: z.ZodArray<z.ZodObject<{
961
- media_id: z.ZodString;
962
- start_ms: z.ZodOptional<z.ZodNumber>;
963
- media_duration_ms: z.ZodNumber;
964
- play_in: z.ZodOptional<z.ZodNumber>;
965
- play_out: z.ZodOptional<z.ZodNumber>;
966
- track_id: z.ZodOptional<z.ZodString>;
967
- }, z.core.$strip>>;
968
- before_clip_id: z.ZodOptional<z.ZodString>;
969
- after_clip_id: z.ZodOptional<z.ZodString>;
970
- }, z.core.$strip>;
971
- type AddVideoClipsInput = z.infer<typeof addVideoClipsInputSchema>;
972
- //#endregion
973
- //#region src/editor/schemas/adjust-bgm-volume.d.ts
974
- declare const adjustBgmVolumeInputSchema: z.ZodObject<{
975
- bgm: z.ZodArray<z.ZodObject<{
976
- bgm_id: z.ZodString;
977
- volume: z.ZodNumber;
978
- }, z.core.$strip>>;
979
- }, z.core.$strip>;
980
- type AdjustBgmVolumeInput = z.infer<typeof adjustBgmVolumeInputSchema>;
981
- //#endregion
982
- //#region src/editor/schemas/adjust-speech-volume.d.ts
983
- declare const adjustSpeechVolumeInputSchema: z.ZodObject<{
984
- speeches: z.ZodArray<z.ZodObject<{
985
- speech_id: z.ZodString;
986
- volume: z.ZodNumber;
987
- }, z.core.$strip>>;
988
- }, z.core.$strip>;
989
- type AdjustSpeechVolumeInput = z.infer<typeof adjustSpeechVolumeInputSchema>;
990
- //#endregion
991
- //#region src/editor/schemas/adjust-video-clip-duration.d.ts
992
- /**
993
- * Re-trim existing video clips (the user-facing "adjust duration" gesture is a
994
- * trim of the source window). The new `play_in` / `play_out` are the facts; the
995
- * effective timeline duration is derived from them and the clip's `speed_shift`,
996
- * and the change reflows downstream clips, speeches, and the timeline inside the
997
- * op's transaction (no caller-materialized cascade).
998
- */
999
- declare const adjustVideoClipDurationInputSchema: z.ZodObject<{
1000
- clips: z.ZodArray<z.ZodObject<{
1001
- clip_id: z.ZodString;
1002
- play_in: z.ZodNumber;
1003
- play_out: z.ZodNumber;
1004
- }, z.core.$strip>>;
1005
- }, z.core.$strip>;
1006
- type AdjustVideoClipDurationInput = z.infer<typeof adjustVideoClipDurationInputSchema>;
1007
- //#endregion
1008
- //#region src/editor/schemas/adjust-video-clip-volume.d.ts
1009
- declare const adjustVideoClipVolumeInputSchema: z.ZodObject<{
1010
- clips: z.ZodArray<z.ZodObject<{
1011
- clip_id: z.ZodString;
1012
- volume: z.ZodNumber;
1013
- }, z.core.$strip>>;
1014
- }, z.core.$strip>;
1015
- type AdjustVideoClipVolumeInput = z.infer<typeof adjustVideoClipVolumeInputSchema>;
1016
- //#endregion
1017
- //#region src/editor/schemas/change-speech.d.ts
1018
- /**
1019
- * Change a speech's script or voice. Both re-run TTS upstream and return the
1020
- * regenerated speech / caption parts in the same materialized shape as
1021
- * `AddSpeeches` (`speech-assets.ts`); the op upserts them by id (the speech part
1022
- * id is preserved across a re-TTS), re-seats at `start_ms`, and reflows. Old
1023
- * caption parts no longer owned by the speech are removed via `caption_ids`.
1024
- */
1025
- declare const changeSpeechScriptInputSchema: z.ZodObject<{
1026
- speeches: z.ZodArray<z.ZodObject<{
1027
- speech_id: z.ZodString;
1028
- anchor_part_id: z.ZodString;
1029
- offset_ms: z.ZodNumber;
1030
- audio_storage_key: z.ZodString;
1031
- duration_ms: z.ZodNumber;
1032
- audio_script: z.ZodString;
1033
- volume: z.ZodNumber;
1034
- voice: z.ZodObject<{
1035
- id: z.ZodString;
1036
- name: z.ZodString;
1037
- }, z.core.$strip>;
1038
- origin_speech_id: z.ZodString;
1039
- caption_ids: z.ZodArray<z.ZodString>;
1040
- }, z.core.$strip>>;
1041
- captions: z.ZodArray<z.ZodObject<{
1042
- caption_id: z.ZodString;
1043
- speech_part_id: z.ZodString;
1044
- text: z.ZodString;
1045
- start_ms: z.ZodNumber;
1046
- duration_ms: z.ZodNumber;
1047
- }, z.core.$strip>>;
1048
- }, z.core.$strip>;
1049
- declare const changeSpeechVoiceInputSchema: z.ZodObject<{
1050
- speeches: z.ZodArray<z.ZodObject<{
1051
- speech_id: z.ZodString;
1052
- anchor_part_id: z.ZodString;
1053
- offset_ms: z.ZodNumber;
1054
- audio_storage_key: z.ZodString;
1055
- duration_ms: z.ZodNumber;
1056
- audio_script: z.ZodString;
1057
- volume: z.ZodNumber;
1058
- voice: z.ZodObject<{
1059
- id: z.ZodString;
1060
- name: z.ZodString;
1061
- }, z.core.$strip>;
1062
- origin_speech_id: z.ZodString;
1063
- caption_ids: z.ZodArray<z.ZodString>;
1064
- }, z.core.$strip>>;
1065
- captions: z.ZodArray<z.ZodObject<{
1066
- caption_id: z.ZodString;
1067
- speech_part_id: z.ZodString;
1068
- text: z.ZodString;
1069
- start_ms: z.ZodNumber;
1070
- duration_ms: z.ZodNumber;
1071
- }, z.core.$strip>>;
1072
- }, z.core.$strip>;
1073
- type ChangeSpeechScriptInput = z.infer<typeof changeSpeechScriptInputSchema>;
1074
- type ChangeSpeechVoiceInput = z.infer<typeof changeSpeechVoiceInputSchema>;
1075
- //#endregion
1076
- //#region src/editor/schemas/delete-bgm.d.ts
1077
- /**
1078
- * Remove the document BGM. Pure document edit: clears the bgm lane and removes
1079
- * the bgm part. Takes no input (a document holds at most one bgm); an empty
1080
- * object keeps the op signature uniform with the rest.
1081
- */
1082
- declare const deleteBgmInputSchema: z.ZodObject<{}, z.core.$strip>;
1083
- type DeleteBgmInput = z.infer<typeof deleteBgmInputSchema>;
1084
- //#endregion
1085
- //#region src/editor/schemas/delete-speeches.d.ts
1086
- /**
1087
- * Delete speeches with their captions. Pure document edit (no side effect): the
1088
- * op removes each speech part, cascade-deletes the captions it owns (via
1089
- * `caption_ids` / `speech_part_id`), drops their track items, and reflows.
1090
- */
1091
- declare const deleteSpeechesInputSchema: z.ZodObject<{
1092
- speech_ids: z.ZodArray<z.ZodString>;
1093
- }, z.core.$strip>;
1094
- type DeleteSpeechesInput = z.infer<typeof deleteSpeechesInputSchema>;
1095
- //#endregion
1096
- //#region src/editor/schemas/delete-video-clips.d.ts
1097
- /**
1098
- * How a delete handles the anchored subtree (speeches anchored to a deleted clip,
1099
- * and their captions) — a delete-op policy, not a data-model field (reference/17
1100
- * §6). `cascade` (default) removes the subtree; `detach` keeps the direct
1101
- * anchored children, re-pinning them to `absolute` so they stay on the timeline.
1102
- */
1103
- declare const anchoredDeletePolicySchema: z.ZodEnum<{
1104
- cascade: "cascade";
1105
- detach: "detach";
1106
- }>;
1107
- type AnchoredDeletePolicy = z.infer<typeof anchoredDeletePolicySchema>;
1108
- declare const deleteVideoClipsInputSchema: z.ZodObject<{
1109
- clip_ids: z.ZodArray<z.ZodString>;
1110
- on_anchored: z.ZodOptional<z.ZodEnum<{
1111
- cascade: "cascade";
1112
- detach: "detach";
1113
- }>>;
1114
- }, z.core.$strip>;
1115
- type DeleteVideoClipsInput = z.infer<typeof deleteVideoClipsInputSchema>;
1116
- //#endregion
1117
- //#region src/editor/schemas/move-speeches.d.ts
1118
- /**
1119
- * Move speeches in time. Pure document edit: the op re-seats each speech at its
1120
- * new absolute `start_ms`; the cascade reassigns it to the host video clip,
1121
- * resolves overlaps, and reflows. Captions follow their speech.
1122
- */
1123
- declare const moveSpeechesInputSchema: z.ZodObject<{
1124
- speeches: z.ZodArray<z.ZodObject<{
1125
- speech_id: z.ZodString;
1126
- new_start_ms: z.ZodNumber;
1127
- }, z.core.$strip>>;
1128
- }, z.core.$strip>;
1129
- type MoveSpeechesInput = z.infer<typeof moveSpeechesInputSchema>;
1130
- //#endregion
1131
- //#region src/editor/schemas/move-video-clips-by-anchor.d.ts
1132
- /**
1133
- * Where the moved block lands on the main track.
1134
- *
1135
- * A discriminated union rather than two optional `before_clip_id` /
1136
- * `after_clip_id` fields (the shape `addVideoClips` had to use, because there the
1137
- * two modes share a whole clip description): here the alternatives carry nothing
1138
- * in common, so making them mutually exclusive *by type* removes three runtime
1139
- * `superRefine` checks that would otherwise have to be written and tested.
1140
- *
1141
- * `track_start` is an explicit member, not the absence of an anchor. The
1142
- * agent-harness mutation this maps from treats "neither anchor given" as
1143
- * "move to the front" (`applyBatchMoveVideoClips` falls back to `insertIndex = 0`),
1144
- * which is a default buried in a tool description. Requiring the caller to name
1145
- * that intent keeps a forgotten field from silently reordering the timeline.
1146
- */
1147
- declare const moveAnchorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1148
- position: z.ZodLiteral<"before">;
1149
- clip_id: z.ZodString;
1150
- }, z.core.$strip>, z.ZodObject<{
1151
- position: z.ZodLiteral<"after">;
1152
- clip_id: z.ZodString;
1153
- }, z.core.$strip>, z.ZodObject<{
1154
- position: z.ZodLiteral<"track_start">;
1155
- }, z.core.$strip>], "position">;
1156
- /**
1157
- * What happens to the speeches anchored to the clips being moved.
1158
- *
1159
- * - `follow` keeps each speech anchored where it is, so it travels with its clip
1160
- * to the new position. In the anchored model this is the *no-op* branch: a
1161
- * speech's authoritative fact is `{ anchorPartId, offsetMs }` and its absolute
1162
- * time is derived on read from the host's position, so moving the host moves
1163
- * the speech with no write to the speech at all.
1164
- * - `keep_absolute` preserves each speech's current absolute landing instead, then
1165
- * re-anchors it to whichever clip now covers that time (RFC 02 §9.1/§11.1). This
1166
- * is the branch that costs an extra pass, and the one the FE timeline uses.
1167
- *
1168
- * **Required, with no default**, matching `deleteVideoClips` and
1169
- * `replaceVideoClipSequence`. The two branches decide which picture the user's
1170
- * narration ends up over, which is too consequential to infer from a missing
1171
- * field — and neither branch is "safe enough" to be the implicit one.
1172
- */
1173
- declare const movedClipAnchoredPolicySchema: z.ZodEnum<{
1174
- follow: "follow";
1175
- keep_absolute: "keep_absolute";
1176
- }>;
1177
- /**
1178
- * Reorder a set of main-track clips relative to a reference clip.
1179
- *
1180
- * Distinct from `moveVideoClips`, which positions clips by absolute time
1181
- * (`new_start_ms`) and is what the FE timeline dispatches after a drag. Main-track
1182
- * clips are `sequential`-positioned, so absolute time is not authoritative state
1183
- * there (RFC 02 §4/§7): `moveVideoClips` has to *guess* an index back out of the
1184
- * time it was handed, whereas an anchor already is the ordinal fact being changed.
1185
- * Keeping them separate also isolates blast radius — this method can diverge on
1186
- * speech policy without touching the FE path.
1187
- *
1188
- * `clip_ids` need not be contiguous. They move as one block, keeping their
1189
- * relative order, which is the agent-harness `batch_move_video_clips` contract.
1190
- */
1191
- declare const moveVideoClipsByAnchorInputSchema: z.ZodObject<{
1192
- clip_ids: z.ZodArray<z.ZodString>;
1193
- anchor: z.ZodDiscriminatedUnion<[z.ZodObject<{
1194
- position: z.ZodLiteral<"before">;
1195
- clip_id: z.ZodString;
1196
- }, z.core.$strip>, z.ZodObject<{
1197
- position: z.ZodLiteral<"after">;
1198
- clip_id: z.ZodString;
1199
- }, z.core.$strip>, z.ZodObject<{
1200
- position: z.ZodLiteral<"track_start">;
1201
- }, z.core.$strip>], "position">;
1202
- on_anchored: z.ZodEnum<{
1203
- follow: "follow";
1204
- keep_absolute: "keep_absolute";
1205
- }>;
1206
- }, z.core.$strip>;
1207
- type MoveAnchor = z.infer<typeof moveAnchorSchema>;
1208
- type MovedClipAnchoredPolicy = z.infer<typeof movedClipAnchoredPolicySchema>;
1209
- type MoveVideoClipsByAnchorInput = z.infer<typeof moveVideoClipsByAnchorInputSchema>;
1210
- //#endregion
1211
- //#region src/editor/schemas/move-video-clips.d.ts
1212
- declare const moveVideoClipsInputSchema: z.ZodObject<{
1213
- clips: z.ZodArray<z.ZodObject<{
1214
- clip_id: z.ZodString;
1215
- new_start_ms: z.ZodNumber;
1216
- new_track_id: z.ZodOptional<z.ZodString>;
1217
- }, z.core.$strip>>;
1218
- }, z.core.$strip>;
1219
- type MoveVideoClipsInput = z.infer<typeof moveVideoClipsInputSchema>;
1220
- //#endregion
1221
- //#region src/editor/schemas/replace-video-clip-content.d.ts
1222
- /**
1223
- * Replace the media backing existing video clips. The media import runs upstream
1224
- * (Director); its stable result — the new media id, intrinsic length, and the
1225
- * reset trim window — arrives materialized (see
1226
- * `results/phase-4-side-effect-payload-contract.md` §4). Director resets
1227
- * `play_in=0` / `play_out=media_duration_ms` and clears `speed_shift` on
1228
- * replacement. The clip `part_id`s (hence their track items) are unchanged; the
1229
- * editor reflows the main track from the new effective durations.
1230
- */
1231
- declare const replaceVideoClipContentInputSchema: z.ZodObject<{
1232
- clips: z.ZodArray<z.ZodObject<{
1233
- clip_id: z.ZodString;
1234
- origin_media_id: z.ZodString;
1235
- media_duration_ms: z.ZodNumber;
1236
- play_in: z.ZodNumber;
1237
- play_out: z.ZodNumber;
1238
- volume: z.ZodNumber;
1239
- }, z.core.$strip>>;
1240
- }, z.core.$strip>;
1241
- type ReplaceVideoClipContentInput = z.infer<typeof replaceVideoClipContentInputSchema>;
1242
- //#endregion
1243
- //#region src/editor/schemas/replace-video-clip-sequence.d.ts
1244
- /**
1245
- * What happens to the speeches anchored to the clips being replaced.
1246
- *
1247
- * - `remap` re-anchors each surviving speech to the new clip in the SAME POSITION
1248
- * of the sequence, keeping its offset — old[i]'s children become new[i]'s
1249
- * children. An old clip with no counterpart (fewer new clips than old) has its
1250
- * subtree deleted, because there is nothing left to anchor to.
1251
- * - `cascade` deletes every anchored speech (and its captions) outright, like
1252
- * `deleteVideoClips`.
1253
- *
1254
- * **Required, with no default.** The two branches differ in whether the user's
1255
- * narration survives, and the agent tool that drives this op makes its
1256
- * `preserve_speeches` flag required for that reason. A default here would let a
1257
- * caller that forgot the field silently delete speech.
1258
- */
1259
- declare const anchoredReplacePolicySchema: z.ZodEnum<{
1260
- cascade: "cascade";
1261
- remap: "remap";
1262
- }>;
1263
- type AnchoredReplacePolicy = z.infer<typeof anchoredReplacePolicySchema>;
1264
- /**
1265
- * Replace a contiguous run of main-track clips with a new run.
1266
- *
1267
- * A composite of delete + insert that cannot be expressed as the two ops in
1268
- * sequence, because the anchored speeches have to survive *across* the swap: with
1269
- * `remap` they are re-anchored positionally, which needs both the old and the new
1270
- * ids in the same transaction (ADR 0009 — the cascade stays in the editor, callers
1271
- * never re-wire anchors themselves).
1272
- *
1273
- * Duration facts follow `addVideoClips`: `media_duration_ms` is the source's
1274
- * intrinsic length and the trim window defaults to the whole media. The effective
1275
- * timeline duration is derived by the projection, never an input.
1276
- *
1277
- * `media_id` is optional: omitting it creates a **deliberate empty placeholder
1278
- * clip** (`origin_media_id: ''`) — structure with no picture. This is the only op
1279
- * that can produce one, and it is authoritative state, unlike the gap fillers the
1280
- * read-side solve mints (which never enter the document).
1281
- */
1282
- declare const replaceVideoClipSequenceInputSchema: z.ZodObject<{
1283
- old_clip_ids: z.ZodArray<z.ZodString>;
1284
- new_clips: z.ZodArray<z.ZodObject<{
1285
- media_id: z.ZodOptional<z.ZodString>;
1286
- media_duration_ms: z.ZodNumber;
1287
- play_in: z.ZodOptional<z.ZodNumber>;
1288
- play_out: z.ZodOptional<z.ZodNumber>;
1289
- }, z.core.$strip>>;
1290
- on_anchored: z.ZodEnum<{
1291
- cascade: "cascade";
1292
- remap: "remap";
1293
- }>;
1294
- }, z.core.$strip>;
1295
- type ReplaceVideoClipSequenceInput = z.infer<typeof replaceVideoClipSequenceInputSchema>;
1296
- //#endregion
1297
- //#region src/editor/schemas/set-bgm.d.ts
1298
- /**
1299
- * Set the document BGM. The media's stable result (storage key) arrives
1300
- * materialized from upstream (see
1301
- * `results/phase-4-side-effect-payload-contract.md` §3). The op upserts the bgm
1302
- * part and seats it on the bgm lane; its effective length is always the whole
1303
- * timeline, derived by the projection on read — so there is no `duration_ms`
1304
- * input or fact (RFC 02 / `reference/16` §0b). A `bgm_id` lets the op replace an
1305
- * existing bgm part by id.
1306
- */
1307
- declare const setBgmInputSchema: z.ZodObject<{
1308
- bgm_id: z.ZodString;
1309
- audio_storage_key: z.ZodString;
1310
- origin_media_id: z.ZodString;
1311
- volume: z.ZodNumber;
1312
- }, z.core.$strip>;
1313
- type SetBgmInput = z.infer<typeof setBgmInputSchema>;
1314
- //#endregion
1315
- //#region src/editor/schemas/set-caption-style.d.ts
1316
- /**
1317
- * Set the caption visual style. GLOBAL by design: the style applies to every
1318
- * caption part in the document — it carries NO `caption_id`. This mirrors the FE,
1319
- * whose caption-style store (`caption-style.ts:persistCaptionStylePatch`) iterates
1320
- * ALL captions and writes the same normalized style to each; the product has a
1321
- * single document-wide caption style, not per-caption styling.
1322
- *
1323
- * Every field is optional and maps to a `CaptionStyle` attribute (snake_case
1324
- * IDL). A field present in the input is written to every caption; a field ABSENT
1325
- * from the input is left untouched on each caption (the editor merges the patch
1326
- * onto each caption's existing style — this is a value edit, not a full-style
1327
- * replace, so a partial patch such as "recolor only" does not wipe font size).
1328
- *
1329
- * Pure document edit, no cascade — captions keep their positions; only the style
1330
- * sub-map of each caption part changes.
1331
- */
1332
- declare const setCaptionStyleInputSchema: z.ZodObject<{
1333
- font_id: z.ZodOptional<z.ZodString>;
1334
- font_size: z.ZodOptional<z.ZodNumber>;
1335
- font_color: z.ZodOptional<z.ZodString>;
1336
- font_weight: z.ZodOptional<z.ZodNumber>;
1337
- entrance_animation: z.ZodOptional<z.ZodString>;
1338
- entrance_animation_duration_ms: z.ZodOptional<z.ZodNumber>;
1339
- stroke_color: z.ZodOptional<z.ZodString>;
1340
- stroke_width: z.ZodOptional<z.ZodNumber>;
1341
- position_x: z.ZodOptional<z.ZodNumber>;
1342
- position_y: z.ZodOptional<z.ZodNumber>;
1343
- }, z.core.$strip>;
1344
- type SetCaptionStyleInput = z.infer<typeof setCaptionStyleInputSchema>;
1345
- //#endregion
1346
- //#region src/editor/schemas/set-caption-visibility.d.ts
1347
- /**
1348
- * Toggle caption visibility (the caption track's `is_hidden` flag). Pure
1349
- * document edit, no cascade — captions keep their positions; only the lane's
1350
- * hidden flag changes.
1351
- */
1352
- declare const setCaptionVisibilityInputSchema: z.ZodObject<{
1353
- is_hidden: z.ZodBoolean;
1354
- }, z.core.$strip>;
1355
- type SetCaptionVisibilityInput = z.infer<typeof setCaptionVisibilityInputSchema>;
1356
- //#endregion
1357
- //#region src/editor/schemas/set-video-clip-speed-shift.d.ts
1358
- /**
1359
- * Set the playback speed of existing video clips. Per the speed-shift decision
1360
- * (`reference/16` §0): the op writes only the `speed_shift` fact — it does NOT
1361
- * store an effective `duration_ms` (projection derives it from the trim window /
1362
- * speed) and does NOT scale anchored speeches' relative offsets (offsets stay
1363
- * put; the cascade reflows absolute positions). A `null` speed_shift clears the
1364
- * speed back to original (1×).
1365
- */
1366
- declare const setVideoClipSpeedShiftInputSchema: z.ZodObject<{
1367
- clips: z.ZodArray<z.ZodObject<{
1368
- clip_id: z.ZodString;
1369
- speed_shift: z.ZodNullable<z.ZodObject<{
1370
- category: z.ZodEnum<{
1371
- curve: "curve";
1372
- linear: "linear";
1373
- }>;
1374
- mode: z.ZodString;
1375
- config: z.ZodUnion<readonly [z.ZodObject<{
1376
- linear: z.ZodObject<{
1377
- speed: z.ZodNumber;
1378
- }, z.core.$strip>;
1379
- }, z.core.$strip>, z.ZodObject<{
1380
- curve: z.ZodObject<{
1381
- keyframes: z.ZodArray<z.ZodObject<{
1382
- position: z.ZodNumber;
1383
- rate: z.ZodNumber;
1384
- in_tangent: z.ZodOptional<z.ZodObject<{
1385
- x: z.ZodNumber;
1386
- y: z.ZodNumber;
1387
- }, z.core.$strip>>;
1388
- out_tangent: z.ZodOptional<z.ZodObject<{
1389
- x: z.ZodNumber;
1390
- y: z.ZodNumber;
1391
- }, z.core.$strip>>;
1392
- }, z.core.$strip>>;
1393
- }, z.core.$strip>;
1394
- }, z.core.$strip>]>;
1395
- }, z.core.$strip>>;
1396
- }, z.core.$strip>>;
1397
- }, z.core.$strip>;
1398
- type SetVideoClipSpeedShiftInput = z.infer<typeof setVideoClipSpeedShiftInputSchema>;
1399
- //#endregion
1400
- //#region src/editor/schemas/shared.d.ts
1401
- declare const clipIdSchema: z.ZodString;
1402
- declare const clipIdsSchema: z.ZodArray<z.ZodString>;
1403
- declare const mediaIdSchema: z.ZodString;
1404
- declare const speechIdSchema: z.ZodString;
1405
- declare const timelineMsSchema: z.ZodNumber;
1406
- declare const positiveMsSchema: z.ZodNumber;
1407
- declare const volumeSchema: z.ZodNumber;
1408
- declare const speechIdsSchema: z.ZodArray<z.ZodString>;
1409
- /**
1410
- * A clip's playback-speed fact, the only thing `SetVideoClipSpeedShift` writes.
1411
- * Mirrors the IDL `SpeedShift`: `category` is `linear` | `curve`, and `config`
1412
- * is a discriminated union — `{ linear: { speed } }` for a constant multiplier
1413
- * (the multiplier projection reads at `config.linear.speed`) or `{ curve: {
1414
- * keyframes } }` for a Bezier-controlled variable speed (RFC 02 / `reference/16`
1415
- * §0). Exactly one of `linear` / `curve` is present.
1416
- */
1417
- declare const speedShiftSchema: z.ZodObject<{
1418
- category: z.ZodEnum<{
1419
- curve: "curve";
1420
- linear: "linear";
1421
- }>;
1422
- mode: z.ZodString;
1423
- config: z.ZodUnion<readonly [z.ZodObject<{
1424
- linear: z.ZodObject<{
1425
- speed: z.ZodNumber;
1426
- }, z.core.$strip>;
1427
- }, z.core.$strip>, z.ZodObject<{
1428
- curve: z.ZodObject<{
1429
- keyframes: z.ZodArray<z.ZodObject<{
1430
- position: z.ZodNumber;
1431
- rate: z.ZodNumber;
1432
- in_tangent: z.ZodOptional<z.ZodObject<{
1433
- x: z.ZodNumber;
1434
- y: z.ZodNumber;
1435
- }, z.core.$strip>>;
1436
- out_tangent: z.ZodOptional<z.ZodObject<{
1437
- x: z.ZodNumber;
1438
- y: z.ZodNumber;
1439
- }, z.core.$strip>>;
1440
- }, z.core.$strip>>;
1441
- }, z.core.$strip>;
1442
- }, z.core.$strip>]>;
1443
- }, z.core.$strip>;
1444
- declare const voiceSchema: z.ZodObject<{
1445
- id: z.ZodString;
1446
- name: z.ZodString;
1447
- }, z.core.$strip>;
1448
- //#endregion
1449
- //#region src/editor/schemas/speech-assets.d.ts
1450
- /**
1451
- * The materialized TTS result shared by `AddSpeeches` / `ChangeSpeechScript` /
1452
- * `ChangeSpeechVoice` (see `results/phase-4-side-effect-payload-contract.md`
1453
- * §1/§2). The side effect (TTS/ASR + billing) runs upstream; the op receives the
1454
- * stable speech + caption parts and writes them as authoritative facts. No
1455
- * cascade runs on write — the projection derives absolute positions on read.
1456
- *
1457
- * Each speech carries the anchoring fact directly (RFC 02 §4): the host video
1458
- * clip `anchor_part_id` and the `offset_ms` within it. The upstream caller
1459
- * already knows which clip a speech attaches to, so the op writes
1460
- * `{ mode:'anchored', anchorPartId, offsetMs }` verbatim — no write-time
1461
- * host-picking. Captions anchor to their speech via the caption part's
1462
- * `start_ms` (offset within the speech).
1463
- */
1464
- declare const speechAssetSchema: z.ZodObject<{
1465
- speech_id: z.ZodString;
1466
- anchor_part_id: z.ZodString;
1467
- offset_ms: z.ZodNumber;
1468
- audio_storage_key: z.ZodString;
1469
- duration_ms: z.ZodNumber;
1470
- audio_script: z.ZodString;
1471
- volume: z.ZodNumber;
1472
- voice: z.ZodObject<{
1473
- id: z.ZodString;
1474
- name: z.ZodString;
1475
- }, z.core.$strip>;
1476
- origin_speech_id: z.ZodString;
1477
- caption_ids: z.ZodArray<z.ZodString>;
1478
- }, z.core.$strip>;
1479
- declare const captionAssetSchema: z.ZodObject<{
1480
- caption_id: z.ZodString;
1481
- speech_part_id: z.ZodString;
1482
- text: z.ZodString;
1483
- start_ms: z.ZodNumber;
1484
- duration_ms: z.ZodNumber;
1485
- }, z.core.$strip>;
1486
- /** A materialized speech-subtree write (speeches + their captions). */
1487
- declare const speechAssetsSchema: z.ZodObject<{
1488
- speeches: z.ZodArray<z.ZodObject<{
1489
- speech_id: z.ZodString;
1490
- anchor_part_id: z.ZodString;
1491
- offset_ms: z.ZodNumber;
1492
- audio_storage_key: z.ZodString;
1493
- duration_ms: z.ZodNumber;
1494
- audio_script: z.ZodString;
1495
- volume: z.ZodNumber;
1496
- voice: z.ZodObject<{
1497
- id: z.ZodString;
1498
- name: z.ZodString;
1499
- }, z.core.$strip>;
1500
- origin_speech_id: z.ZodString;
1501
- caption_ids: z.ZodArray<z.ZodString>;
1502
- }, z.core.$strip>>;
1503
- captions: z.ZodArray<z.ZodObject<{
1504
- caption_id: z.ZodString;
1505
- speech_part_id: z.ZodString;
1506
- text: z.ZodString;
1507
- start_ms: z.ZodNumber;
1508
- duration_ms: z.ZodNumber;
1509
- }, z.core.$strip>>;
1510
- }, z.core.$strip>;
1511
- type SpeechAsset = z.infer<typeof speechAssetSchema>;
1512
- type CaptionAsset = z.infer<typeof captionAssetSchema>;
1513
- type SpeechAssets = z.infer<typeof speechAssetsSchema>;
1514
- declare namespace index_d_exports {
1515
- export { AddSpeechesInput, AddVideoClipsInput, AdjustBgmVolumeInput, AdjustSpeechVolumeInput, AdjustVideoClipDurationInput, AdjustVideoClipVolumeInput, AnchoredDeletePolicy, AnchoredReplacePolicy, CaptionAsset, ChangeSpeechScriptInput, ChangeSpeechVoiceInput, DeleteBgmInput, DeleteSpeechesInput, DeleteVideoClipsInput, MoveAnchor, MoveSpeechesInput, MoveVideoClipsByAnchorInput, MoveVideoClipsInput, MovedClipAnchoredPolicy, ReplaceVideoClipContentInput, ReplaceVideoClipSequenceInput, SetBgmInput, SetCaptionStyleInput, SetCaptionVisibilityInput, SetVideoClipSpeedShiftInput, SpeechAsset, SpeechAssets, addSpeechesInputSchema, addVideoClipsInputSchema, adjustBgmVolumeInputSchema, adjustSpeechVolumeInputSchema, adjustVideoClipDurationInputSchema, adjustVideoClipVolumeInputSchema, anchoredDeletePolicySchema, anchoredReplacePolicySchema, changeSpeechScriptInputSchema, changeSpeechVoiceInputSchema, clipIdSchema, clipIdsSchema, deleteBgmInputSchema, deleteSpeechesInputSchema, deleteVideoClipsInputSchema, mediaIdSchema, moveAnchorSchema, moveSpeechesInputSchema, moveVideoClipsByAnchorInputSchema, moveVideoClipsInputSchema, movedClipAnchoredPolicySchema, positiveMsSchema, replaceVideoClipContentInputSchema, replaceVideoClipSequenceInputSchema, setBgmInputSchema, setCaptionStyleInputSchema, setCaptionVisibilityInputSchema, setVideoClipSpeedShiftInputSchema, speechAssetsSchema, speechIdSchema, speechIdsSchema, speedShiftSchema, timelineMsSchema, voiceSchema, volumeSchema };
1516
- }
1517
- //#endregion
1518
- //#region src/editor/schema-validator.d.ts
1519
- interface SnapshotReadable {
1520
- snapshot(): VideoDocument;
1521
- }
1522
- declare class ValidationError extends Error {
1523
- readonly code: string;
1524
- readonly context?: Record<string, unknown>;
1525
- constructor(code: string, message: string, context?: Record<string, unknown>);
1526
- }
1527
- declare class SchemaValidator {
1528
- validateMoveVideoClips(input: MoveVideoClipsInput, doc: SnapshotReadable): void;
1529
- /**
1530
- * The anchor must not be one of the clips being moved. Unlike the schema's
1531
- * mutual exclusions this needs the input read as a whole, so it stays here.
1532
- *
1533
- * Rejected rather than normalized: "put this block before itself" has no
1534
- * defensible outcome — treating it as a no-op hides a caller bug behind a
1535
- * success, and picking any surviving neighbour invents an intent. The legacy
1536
- * `applyBatchMoveVideoClips` omits this check (a self-anchor there silently
1537
- * lands the block at its own pre-move index); director's original move tool
1538
- * did enforce it (`_validate_position`: "不是被移动的clips"), and that is the
1539
- * behaviour worth keeping.
1540
- */
1541
- validateMoveVideoClipsByAnchor(input: MoveVideoClipsByAnchorInput, doc: SnapshotReadable): void;
1542
- validateDeleteVideoClips(input: DeleteVideoClipsInput, doc: SnapshotReadable): void;
1543
- validateAddVideoClips(input: AddVideoClipsInput, doc: SnapshotReadable): void;
1544
- validateAdjustVideoClipVolume(input: AdjustVideoClipVolumeInput, doc: SnapshotReadable): void;
1545
- validateSetVideoClipSpeedShift(input: SetVideoClipSpeedShiftInput, doc: SnapshotReadable): void;
1546
- validateReplaceVideoClipContent(input: ReplaceVideoClipContentInput, doc: SnapshotReadable): void;
1547
- /**
1548
- * `old_clip_ids` must name a **contiguous run of the main track, in track
1549
- * order**. A sparse or reordered selection is rejected rather than normalized:
1550
- * a sparse selection has no single stretch to swap, so the insert index, the
1551
- * positional speech remap, and the resulting order would each need a different
1552
- * arbitrary choice. Mirrors the agent tool's own contract ("must be a
1553
- * contiguous main-track sequence listed in timeline order").
1554
- */
1555
- validateReplaceVideoClipSequence(input: ReplaceVideoClipSequenceInput, doc: SnapshotReadable): void;
1556
- validateAdjustVideoClipDuration(input: AdjustVideoClipDurationInput, doc: SnapshotReadable): void;
1557
- validateAdjustSpeechVolume(input: AdjustSpeechVolumeInput, doc: SnapshotReadable): void;
1558
- validateAdjustBgmVolume(input: AdjustBgmVolumeInput, doc: SnapshotReadable): void;
1559
- validateAddSpeeches(input: AddSpeechesInput, doc: SnapshotReadable): void;
1560
- validateChangeSpeechScript(input: ChangeSpeechScriptInput, doc: SnapshotReadable): void;
1561
- validateChangeSpeechVoice(input: ChangeSpeechVoiceInput, doc: SnapshotReadable): void;
1562
- validateDeleteSpeeches(input: DeleteSpeechesInput, doc: SnapshotReadable): void;
1563
- validateMoveSpeeches(input: MoveSpeechesInput, doc: SnapshotReadable): void;
1564
- validateSetBgm(input: SetBgmInput, _doc: SnapshotReadable): void;
1565
- validateDeleteBgm(input: DeleteBgmInput, _doc: SnapshotReadable): void;
1566
- validateSetCaptionVisibility(input: SetCaptionVisibilityInput, _doc: SnapshotReadable): void;
1567
- validateSetCaptionStyle(input: SetCaptionStyleInput, _doc: SnapshotReadable): void;
1568
- private parse;
1569
- private mainTrackIds;
1570
- /** Every caption a speech declares in `caption_ids` must be supplied in `captions`. */
1571
- private assertCaptionsOwned;
1572
- /** Each regenerated speech (re-TTS) must already exist in the document. */
1573
- private assertSpeechesExist;
1574
- /**
1575
- * Each speech's `anchor_part_id` must point at a video clip that already
1576
- * exists. A relative speech anchored to a missing clip cannot be positioned
1577
- * by the projection and has no host to recover to (RFC 02 §4/§11.1), so the
1578
- * write must be rejected rather than landing a dangling reference. (Restores
1579
- * the dangling-reference guard the old `validateMaterializedPatch` carried;
1580
- * ADR 0009.)
1581
- */
1582
- private assertAnchorsExist;
1583
- private assertPartKind;
1584
- }
1585
- //#endregion
1586
- //#region src/editor/types.d.ts
1587
- /**
1588
- * `SemanticOp` contract surface — the frozen catalogue of business write
1589
- * operations the collaborative editor recognises.
1590
- *
1591
- * This is the single source of truth; `SemanticEditor` derives its method set
1592
- * (`SemanticOpName`) from `ImplementedSemanticOpKind`, so adding a method
1593
- * without listing it here (or vice versa) is a type error.
1594
- *
1595
- * Mapping of each kind to UI Operation / agent tool / side-effect routing is
1596
- * maintained in
1597
- * `docs/projects/medeo-integration/reference/operation-semantic-matrix.md`; the
1598
- * frozen contract narrative lives in
1599
- * `docs/projects/medeo-integration/results/phase-4-semantic-op-contract.md`.
1600
- */
1601
- /**
1602
- * Operations implemented by `SemanticEditor`. FROZEN: each entry has a
1603
- * `SemanticEditor` method, a narrow zod input schema (business intent +
1604
- * materialized side-effect assets, never a document slice), and validation. The
1605
- * editor runs the timeline-core cascade in-transaction to derive every position
1606
- * (ADR 0009 — no caller-materialized layout).
1607
- *
1608
- * Effectful ops (TTS for `AddSpeeches` / `ChangeSpeechScript` /
1609
- * `ChangeSpeechVoice`, media import for `ReplaceVideoClipContent`, BGM for
1610
- * `SetBgm`) receive their stable side-effect result already materialized — the
1611
- * editor only writes the document; it never performs the side effect. See the
1612
- * side-effect payload contract in
1613
- * `docs/projects/medeo-integration/results/phase-4-side-effect-payload-contract.md`.
1614
- */
1615
- type ImplementedSemanticOpKind = 'MoveVideoClips' | 'MoveVideoClipsByAnchor' | 'DeleteVideoClips' | 'AddVideoClips' | 'AdjustVideoClipVolume' | 'SetVideoClipSpeedShift' | 'ReplaceVideoClipContent' | 'ReplaceVideoClipSequence' | 'AdjustVideoClipDuration' | 'AddSpeeches' | 'DeleteSpeeches' | 'MoveSpeeches' | 'ChangeSpeechScript' | 'ChangeSpeechVoice' | 'AdjustSpeechVolume' | 'SetCaptionVisibility' | 'SetCaptionStyle' | 'SetBgm' | 'DeleteBgm' | 'AdjustBgmVolume';
1616
- /**
1617
- * Operations on the roadmap but NOT yet implemented by `SemanticEditor`. Empty:
1618
- * Phase 4 covers every op with a real entry point. Kept as a named type so the
1619
- * contract surface stays explicit and re-expanding the roadmap is a typed edit.
1620
- * To re-add planned kinds, list them here and add them back to the
1621
- * `SemanticOpKind` union below.
1622
- */
1623
- type PlannedSemanticOpKind = never;
1624
- /**
1625
- * Every SemanticOp kind. Currently equals `ImplementedSemanticOpKind` because
1626
- * `PlannedSemanticOpKind` is empty; re-add `| PlannedSemanticOpKind` when the
1627
- * roadmap is re-expanded.
1628
- */
1629
- type SemanticOpKind = ImplementedSemanticOpKind;
1630
- /** Runtime list of the frozen, implemented kinds (for guards / introspection). */
1631
- declare const IMPLEMENTED_SEMANTIC_OP_KINDS: readonly ImplementedSemanticOpKind[];
1632
- declare function isImplementedSemanticOpKind(kind: string): kind is ImplementedSemanticOpKind;
1633
- //#endregion
1634
- //#region src/editor/semantic-editor.d.ts
1635
- /**
1636
- * Who authored an op, recorded in the commit message alongside `semantic_op`.
1637
- *
1638
- * Rides the Loro commit message rather than a wire field or a storage column,
1639
- * for the same reason the semantic metadata does (`rfc/05 §5`): the message
1640
- * travels inside the update bytes, so attribution cannot disagree with the ops
1641
- * it describes, and it survives log truncation — a normal snapshot carries the
1642
- * full history, so folding and deleting update rows keeps every Change's message
1643
- * readable. A per-row column would lose the attribution at the first re-snapshot
1644
- * and could only record one author per push, while one push may carry several
1645
- * Changes.
1646
- *
1647
- * `role` deliberately mirrors the legacy `video_draft_op_records.operator_role`
1648
- * enum (`'user' | 'agent'`) so the two engines answer "was this a person or the
1649
- * agent" with the same vocabulary. It is declared rather than inferred from the
1650
- * Loro peer id: peer ranges separate the writers today, but that is an audit aid
1651
- * by convention, not an enforced fact, and peer ids are deliberately NOT derived
1652
- * from identity (`PeerId != userid`, adr/0012).
1653
- *
1654
- * A deliberately narrow shape: no client/platform field. That is telemetry, and
1655
- * document history is permanent and undeletable — the wrong place for it. Adding
1656
- * one later costs nothing (the message is JSON; older Changes simply lack the
1657
- * key), so the omission does not close the door.
1658
- *
1659
- * **Self-reported.** The client writes this and no server verifies it. The
1660
- * authorization principal is the `medeo-user-id` header, which mengine-server
1661
- * owner-checks; this field is the author, which it does not. The two hold the
1662
- * same value today but answer different questions — see the harness's mengine
1663
- * repository for why they are passed separately.
1664
- */
1665
- interface OpActor {
1666
- user_id: string;
1667
- role: 'user' | 'agent';
1668
- }
1669
- interface CommitOptions {
1670
- intent?: {
1671
- kind: string;
1672
- payload: unknown;
1673
- };
1674
- /** Author of this op; omitted for writes with no acting user (bootstrap, repair). */
1675
- actor?: OpActor;
1676
- }
1677
- type SemanticOpInput = MoveVideoClipsInput | MoveVideoClipsByAnchorInput | DeleteVideoClipsInput | AddVideoClipsInput | AdjustVideoClipVolumeInput | AdjustSpeechVolumeInput | AdjustBgmVolumeInput | SetVideoClipSpeedShiftInput | ReplaceVideoClipContentInput | ReplaceVideoClipSequenceInput | AdjustVideoClipDurationInput | AddSpeechesInput | DeleteSpeechesInput | MoveSpeechesInput | SetCaptionVisibilityInput | SetCaptionStyleInput | SetBgmInput | DeleteBgmInput;
1678
- type SemanticOpName = ImplementedSemanticOpKind;
1679
- /** Audit metadata committed alongside an op's writes. */
1680
- interface TransactAudit {
1681
- kind: SemanticOpName;
1682
- payload: unknown;
1683
- intent?: unknown;
1684
- actor?: OpActor;
1685
- }
1686
- /**
1687
- * Narrow write surface the `SemanticEditor` drives (ADR 0008 / 0009). It stays
1688
- * off raw Loro: every op runs its document mutations inside a single `transact`
1689
- * callback, which the storage adapter applies as one CRDT transaction + commit
1690
- * carrying the audit message.
1691
- *
1692
- * The callback edits a `VideoDocumentDraft` — an immer draft of the whole
1693
- * document state. A throw inside it discards the draft and never touches Loro,
1694
- * so partial writes roll back naturally (no `commit`/`rollback` machinery). The
1695
- * adapter's declarative diff turns the edited draft into minimal CRDT ops,
1696
- * including real `move`s for reordered track items (keyed by `part_id`), so
1697
- * per-item identity survives on every lane.
1698
- *
1699
- * Each op takes a narrow business input (intent + materialized side-effect
1700
- * assets, never a document slice); the editor applies the authoritative facts
1701
- * and runs the timeline-core cascade inside the callback to derive every
1702
- * position. The caller never materializes a layout (ADR 0009).
1703
- */
1704
- interface SemanticDocumentAdapter extends SnapshotReadable {
1705
- /**
1706
- * Apply one op's domain mutation in a single synchronous transaction. `edit`
1707
- * must finish before returning; async callbacks/await are unsupported. The
1708
- * adapter diffs the resulting draft and commits once with `audit`.
1709
- * A throw in `edit` rolls back (the draft is discarded, Loro untouched). An
1710
- * edit that changes nothing produces no domain commit (no phantom undo step).
1711
- */
1712
- transact(edit: (draft: VideoDocumentDraft) => void, audit: TransactAudit): void;
1713
- }
1714
- declare class SemanticEditor {
1715
- private readonly doc;
1716
- private readonly validator;
1717
- constructor(doc: SemanticDocumentAdapter, validator?: SchemaValidator);
1718
- moveVideoClips(input: MoveVideoClipsInput, options?: CommitOptions): Promise<void>;
1719
- /**
1720
- * Reorder main-track clips relative to an anchor clip, moving them as one block.
1721
- *
1722
- * The ordinal sibling of `moveVideoClips`: main-track clips are
1723
- * `sequential`-positioned, so their order is the authoritative fact and absolute
1724
- * time is derived on read (RFC 02 §4/§7). A caller that already knows "put these
1725
- * after that one" should say so, instead of computing a timeline offset that this
1726
- * editor would only have to resolve back into an index.
1727
- *
1728
- * `on_anchored` decides the speech treatment and is required. Note the asymmetry
1729
- * in cost: `follow` writes nothing to the speeches (their `{ anchorPartId,
1730
- * offsetMs }` facts stay valid and the derived absolute time moves with the host),
1731
- * while `keep_absolute` runs the extra re-parent pass that preserves each
1732
- * speech's absolute landing. `moveVideoClips` is permanently `keep_absolute`,
1733
- * matching the FE timeline it serves.
1734
- */
1735
- moveVideoClipsByAnchor(input: MoveVideoClipsByAnchorInput, options?: CommitOptions): Promise<void>;
1736
- deleteVideoClips(input: DeleteVideoClipsInput, options?: CommitOptions): Promise<void>;
1737
- addVideoClips(input: AddVideoClipsInput, options?: CommitOptions): Promise<void>;
1738
- /**
1739
- * Swap a contiguous run of main-track clips for a new run, in one transaction.
1740
- *
1741
- * Composite by necessity, not convenience: with `on_anchored: 'remap'` each
1742
- * surviving speech is re-anchored to the new clip in the **same position of the
1743
- * sequence** (old[i] → new[i]), which needs both id sets live at once. Splitting
1744
- * it into `deleteVideoClips` + `addVideoClips` would leave the caller holding the
1745
- * anchor re-wiring — the cascade-in-the-caller mistake ADR 0009 retires.
1746
- *
1747
- * Positional pairing, not by count: when there are fewer new clips than old, the
1748
- * unmatched old clips have no counterpart, so their anchored subtrees are deleted
1749
- * (there is nothing to anchor to). When there are more new clips than old, the
1750
- * extra ones simply arrive with no children.
1751
- *
1752
- * The new clips are inserted where the run started, so surrounding order is
1753
- * preserved. Every position is derived on read (RFC 02 §7) — this writes only the
1754
- * facts: track order, the trim windows, and the surviving anchors.
1755
- */
1756
- replaceVideoClipSequence(input: ReplaceVideoClipSequenceInput, options?: CommitOptions): Promise<void>;
1757
- adjustVideoClipVolume(input: AdjustVideoClipVolumeInput, options?: CommitOptions): Promise<void>;
1758
- setVideoClipSpeedShift(input: SetVideoClipSpeedShiftInput, options?: CommitOptions): Promise<void>;
1759
- adjustSpeechVolume(input: AdjustSpeechVolumeInput, options?: CommitOptions): Promise<void>;
1760
- adjustBgmVolume(input: AdjustBgmVolumeInput, options?: CommitOptions): Promise<void>;
1761
- /**
1762
- * Replace the media backing existing video clips. The new media's stable
1763
- * result (new media id, intrinsic length, reset trim window) is materialized
1764
- * upstream; the clip ids and their track items are unchanged. Only the part
1765
- * facts change — effective duration and downstream positions are derived by
1766
- * the projection on read.
1767
- */
1768
- replaceVideoClipContent(input: ReplaceVideoClipContentInput, options?: CommitOptions): Promise<void>;
1769
- /**
1770
- * Re-trim clips. Only the `play_in` / `play_out` facts change; the new
1771
- * effective duration and the resulting downstream reflow are derived by the
1772
- * projection on read (anchored speeches follow their host clip automatically).
1773
- */
1774
- adjustVideoClipDuration(input: AdjustVideoClipDurationInput, options?: CommitOptions): Promise<void>;
1775
- /**
1776
- * Add speeches (and their captions). TTS runs upstream; the materialized
1777
- * speech / caption parts arrive in `input`, each carrying its host clip
1778
- * `anchor_part_id` + `offset_ms`. The editor writes the parts and their
1779
- * `anchored` `time_position` facts verbatim — no write-time host-picking, no
1780
- * cascade. The projection derives absolute positions on read.
1781
- */
1782
- addSpeeches(input: AddSpeechesInput, options?: CommitOptions): Promise<void>;
1783
- /** Delete speeches with their captions; the subtree is removed (§9.2). Surviving lanes keep their facts. */
1784
- deleteSpeeches(input: DeleteSpeechesInput, options?: CommitOptions): Promise<void>;
1785
- /**
1786
- * Move speeches in time (§9.1). One forward positioning pass: anchor each
1787
- * speech to the main-track clip its new absolute start lands in and write the
1788
- * resulting `anchored` `time_position` fact. No cascade — the projection
1789
- * derives absolute positions on read.
1790
- */
1791
- moveSpeeches(input: MoveSpeechesInput, options?: CommitOptions): Promise<void>;
1792
- /** Change a speech's script. Re-TTS runs upstream; the regenerated parts arrive materialized (no cascade). */
1793
- changeSpeechScript(input: ChangeSpeechScriptInput, options?: CommitOptions): Promise<void>;
1794
- /** Change a speech's voice. Re-TTS runs upstream; the regenerated parts arrive materialized (no cascade). */
1795
- changeSpeechVoice(input: ChangeSpeechVoiceInput, options?: CommitOptions): Promise<void>;
1796
- /**
1797
- * Set the document BGM. The media's stable result arrives materialized.
1798
- *
1799
- * KNOWN GAP (non-blocking, FE callers only): a public-library BGM also needs
1800
- * project-level media ownership registered, or it plays but never appears in
1801
- * the project's media library. This editor deliberately does not do it — the
1802
- * document edit is complete and correct, and ownership is a side effect owned
1803
- * by whoever holds the authoritative media data (memota), not by a CRDT write.
1804
- *
1805
- * Who is affected, as of 2026-08-13: the agent harness registers it on BOTH
1806
- * its legacy and mengine paths (shared `resolveMutation` calls memota
1807
- * `attachMedia` directly), and FE's legacy REST path gets it from Director.
1808
- * Only FE's mengine path is missing it. FE cannot call memota directly:
1809
- * `attachMedia` is exposed on memota's internal contract only, so the fix is a
1810
- * Director proxy route — NOT a new Director business endpoint, since Director
1811
- * stopped owning media ownership entirely (`a2951355`, 2026-08-05).
1812
- *
1813
- * Tracked as a Phase 7 gate (it must land before "new documents default to
1814
- * mengine" makes public-library BGM a routine operation). See
1815
- * `docs/projects/medeo-integration/results/phase-6-m4-legacy-refresh-isolation.md`.
1816
- */
1817
- setBgm(input: SetBgmInput, options?: CommitOptions): Promise<void>;
1818
- /** Remove the document BGM; clears the bgm lane and removes the part. */
1819
- deleteBgm(input: DeleteBgmInput, options?: CommitOptions): Promise<void>;
1820
- /** Toggle caption visibility (caption track `is_hidden`). */
1821
- setCaptionVisibility(input: SetCaptionVisibilityInput, options?: CommitOptions): Promise<void>;
1822
- /**
1823
- * Set the document-wide caption style. GLOBAL (no `caption_id`): the patch is
1824
- * merged onto EVERY caption part's `style`, mirroring the FE, which applies a
1825
- * single style to all captions (`caption-style.ts:persistCaptionStylePatch`).
1826
- *
1827
- * Merge, not replace: only the fields present in the input overwrite the
1828
- * caption's existing style; absent fields are carried forward. So a partial
1829
- * patch ("recolor only") keeps the caption's font size. Pure document edit, no
1830
- * cascade — positions are untouched.
1831
- */
1832
- setCaptionStyle(input: SetCaptionStyleInput, options?: CommitOptions): Promise<void>;
1833
- /**
1834
- * Resolve the main-track sequential layout from `source`. Callers inside a
1835
- * `transact` MUST pass the live `draft` so item order reflects in-progress
1836
- * mutations; the default `this.doc.snapshot()` is only committed state and is
1837
- * correct for read-only callers outside a transaction. `readMainTrackItems` /
1838
- * `readPartDurationMs` accept both an immer draft and a raw snapshot.
1839
- */
1840
- private computeMainTrackLayout;
1841
- private indexForStartMs;
1842
- private computeAddInsertIndex;
1843
- }
1844
- //#endregion
1845
- //#region src/document/document-mutation-guard.d.ts
1846
- /**
1847
- * @internal
1848
- * Shared by synchronous mutation entry points for one document. The session
1849
- * closes it before teardown callbacks can attempt another write.
1850
- */
1851
- declare class DocumentMutationGuard {
1852
- private running;
1853
- private closed;
1854
- run<T>(mutation: () => T): T;
1855
- close(): void;
1856
- }
1857
- //#endregion
1858
- //#region src/document/mirror-adapter.d.ts
1859
- interface MirrorVideoDocumentOptions {
1860
- peerId?: PeerID;
1861
- origin?: string;
1862
- }
1863
- /**
1864
- * Storage-layer adapter that backs a `VideoDocument` with `loro-mirror` (ADR
1865
- * 0008). The mirror holds an in-memory immutable state synced to the `LoroDoc`
1866
- * by declarative diff, replacing the hand-rolled `@mengine/schema` adapter:
1867
- *
1868
- * - `snapshot()` projects the mirror's in-memory state to the read model — no
1869
- * per-call `toJSON()` FFI rebuild.
1870
- * - `transact(edit, audit)` runs the whole op in one `mirror.setState` callback:
1871
- * one diff, one `doc.commit` carrying the audit message. The callback edits an
1872
- * immer draft, so a throw inside it discards the draft and never touches Loro
1873
- * (natural rollback) without a document checkout or compensating commit.
1874
- * - mirror's `idSelector` (track items keyed by `part_id`) diffs reorders to
1875
- * real Loro `move` ops on every lane, so per-item CRDT identity survives on
1876
- * main and secondary tracks alike.
1877
- */
1878
- declare class MirrorVideoDocumentAdapter implements SemanticDocumentAdapter {
1879
- readonly doc: LoroDoc;
1880
- private readonly mutationGuard;
1881
- private readonly mirror;
1882
- private disposed;
1883
- constructor(doc: LoroDoc, mutationGuard?: DocumentMutationGuard);
1884
- snapshot(): VideoDocument;
1885
- /**
1886
- * Release mirror subscriptions; do not reuse this adapter afterwards.
1887
- * The caller still owns the borrowed LoroDoc.
1888
- */
1889
- dispose(): void;
1890
- /**
1891
- * Apply one op as a single transaction. `edit` mutates the immer draft; mirror
1892
- * diffs the result and commits once with the audit `message`. A throw in `edit`
1893
- * discards the draft (Loro untouched). When `edit` produces no change, mirror
1894
- * skips the commit — matching the prior "empty op leaves no audit" behavior.
1895
- */
1896
- transact(edit: (draft: VideoDocumentDraft) => void, audit: TransactAudit): void;
1897
- private assertActive;
1898
- }
1899
- /** Build a fresh Loro doc seeded with `document` through the mirror. */
1900
- declare function createMirrorVideoDocument(document: VideoDocument, options?: MirrorVideoDocumentOptions): LoroDoc;
1901
- /** Build a `MirrorVideoDocumentAdapter` over a fresh doc seeded with `document`. */
1902
- declare function createMirrorVideoDocumentAdapter(document: VideoDocument, options?: MirrorVideoDocumentOptions): MirrorVideoDocumentAdapter;
1903
- //#endregion
1904
- //#region src/document/mirror-read.d.ts
1905
- /**
1906
- * Project the mirror state (`VideoDocumentDraft`) into the authoritative
1907
- * `VideoDocument`. The storage shape is isomorphic to the domain shape (RFC 03
1908
- * §4, reference/17 §4: timeline + a single `tracks` list + part_library), so this
1909
- * is a near-identity — it reads `time_position` / `fallback_abs_ms` JSON blobs
1910
- * back into structured values and selects content fields. Legacy meta is ignored.
1911
- *
1912
- * It maps only authoritative facts (RFC 02 §6): `part_id` + `time_position`. The
1913
- * projection-derived `VideoDraft` read-view (absolute time, `part_aggregations`,
1914
- * total duration) is solved separately by the cascade, not here.
1915
- *
1916
- * It reads in-memory mirror state (O(n) over the document), not a Loro
1917
- * `toJSON()` FFI rebuild — the cost the prior schema adapter paid on every
1918
- * `snapshot()`.
1919
- */
1920
- declare function readVideoDocumentFromDraft(draft: VideoDocumentDraft): VideoDocument;
1921
- //#endregion
1922
- //#region src/document/zod-schema.d.ts
1923
- declare const partUnionSchema: z.ZodUnion<readonly [z.ZodObject<{
1924
- video_clip: z.ZodObject<{
1925
- id: z.ZodOptional<z.ZodString>;
1926
- kind: z.ZodLiteral<"video_clip">;
1927
- duration_ms: z.ZodOptional<z.ZodNumber>;
1928
- play_in: z.ZodNumber;
1929
- play_out: z.ZodNumber;
1930
- volume: z.ZodNumber;
1931
- origin_media_id: z.ZodString;
1932
- speed_shift: z.ZodOptional<z.ZodObject<{
1933
- category: z.ZodOptional<z.ZodString>;
1934
- mode: z.ZodOptional<z.ZodString>;
1935
- config: z.ZodOptional<z.ZodObject<{
1936
- linear: z.ZodOptional<z.ZodObject<{
1937
- speed: z.ZodOptional<z.ZodNumber>;
1938
- }, z.core.$loose>>;
1939
- }, z.core.$loose>>;
1940
- }, z.core.$loose>>;
1941
- }, z.core.$loose>;
1942
- }, z.core.$loose>, z.ZodObject<{
1943
- speech: z.ZodObject<{
1944
- id: z.ZodOptional<z.ZodString>;
1945
- kind: z.ZodLiteral<"speech">;
1946
- media_duration_ms: z.ZodNumber;
1947
- duration_ms: z.ZodOptional<z.ZodNumber>;
1948
- audio_script: z.ZodString;
1949
- volume: z.ZodNumber;
1950
- audio_storage_key: z.ZodString;
1951
- origin_speech_id: z.ZodString;
1952
- voice: z.ZodUnknown;
1953
- caption_ids: z.ZodArray<z.ZodString>;
1954
- }, z.core.$loose>;
1955
- }, z.core.$loose>, z.ZodObject<{
1956
- caption: z.ZodObject<{
1957
- id: z.ZodOptional<z.ZodString>;
1958
- kind: z.ZodLiteral<"caption">;
1959
- initial_duration_ms: z.ZodNumber;
1960
- speech_part_id: z.ZodString;
1961
- text: z.ZodString;
1962
- start_ms: z.ZodNumber;
1963
- style: z.ZodOptional<z.ZodObject<{
1964
- font_id: z.ZodOptional<z.ZodString>;
1965
- font_size: z.ZodOptional<z.ZodNumber>;
1966
- font_color: z.ZodOptional<z.ZodString>;
1967
- font_weight: z.ZodOptional<z.ZodNumber>;
1968
- entrance_animation: z.ZodOptional<z.ZodString>;
1969
- entrance_animation_duration_ms: z.ZodOptional<z.ZodNumber>;
1970
- stroke_color: z.ZodOptional<z.ZodString>;
1971
- stroke_width: z.ZodOptional<z.ZodNumber>;
1972
- position_x: z.ZodOptional<z.ZodNumber>;
1973
- position_y: z.ZodOptional<z.ZodNumber>;
1974
- }, z.core.$loose>>;
1975
- }, z.core.$loose>;
1976
- }, z.core.$loose>, z.ZodObject<{
1977
- bgm: z.ZodObject<{
1978
- id: z.ZodOptional<z.ZodString>;
1979
- kind: z.ZodLiteral<"bgm">;
1980
- audio_storage_key: z.ZodString;
1981
- volume: z.ZodNumber;
1982
- origin_media_id: z.ZodString;
1983
- }, z.core.$loose>;
1984
- }, z.core.$loose>]>;
1985
- declare const videoDocumentSchema: z.ZodObject<{
1986
- timeline: z.ZodOptional<z.ZodObject<{
1987
- unit_time_ms: z.ZodOptional<z.ZodNumber>;
1988
- }, z.core.$loose>>;
1989
- tracks: z.ZodOptional<z.ZodArray<z.ZodObject<{
1990
- id: z.ZodOptional<z.ZodString>;
1991
- parts_kind: z.ZodOptional<z.ZodEnum<{
1992
- bgm: "bgm";
1993
- caption: "caption";
1994
- speech: "speech";
1995
- video_clip: "video_clip";
1996
- }>>;
1997
- is_hidden: z.ZodOptional<z.ZodBoolean>;
1998
- items: z.ZodOptional<z.ZodArray<z.ZodObject<{
1999
- part_id: z.ZodString;
2000
- time_position: z.ZodDiscriminatedUnion<[z.ZodObject<{
2001
- mode: z.ZodLiteral<"sequential">;
2002
- }, z.core.$loose>, z.ZodObject<{
2003
- mode: z.ZodLiteral<"anchored">;
2004
- anchorPartId: z.ZodString;
2005
- offsetMs: z.ZodNumber;
2006
- }, z.core.$loose>, z.ZodObject<{
2007
- mode: z.ZodLiteral<"absolute">;
2008
- offsetMs: z.ZodNumber;
2009
- }, z.core.$loose>], "mode">;
2010
- fallback_abs_ms: z.ZodOptional<z.ZodNumber>;
2011
- }, z.core.$loose>>>;
2012
- }, z.core.$loose>>>;
2013
- part_library: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
2014
- video_clip: z.ZodObject<{
2015
- id: z.ZodOptional<z.ZodString>;
2016
- kind: z.ZodLiteral<"video_clip">;
2017
- duration_ms: z.ZodOptional<z.ZodNumber>;
2018
- play_in: z.ZodNumber;
2019
- play_out: z.ZodNumber;
2020
- volume: z.ZodNumber;
2021
- origin_media_id: z.ZodString;
2022
- speed_shift: z.ZodOptional<z.ZodObject<{
2023
- category: z.ZodOptional<z.ZodString>;
2024
- mode: z.ZodOptional<z.ZodString>;
2025
- config: z.ZodOptional<z.ZodObject<{
2026
- linear: z.ZodOptional<z.ZodObject<{
2027
- speed: z.ZodOptional<z.ZodNumber>;
2028
- }, z.core.$loose>>;
2029
- }, z.core.$loose>>;
2030
- }, z.core.$loose>>;
2031
- }, z.core.$loose>;
2032
- }, z.core.$loose>, z.ZodObject<{
2033
- speech: z.ZodObject<{
2034
- id: z.ZodOptional<z.ZodString>;
2035
- kind: z.ZodLiteral<"speech">;
2036
- media_duration_ms: z.ZodNumber;
2037
- duration_ms: z.ZodOptional<z.ZodNumber>;
2038
- audio_script: z.ZodString;
2039
- volume: z.ZodNumber;
2040
- audio_storage_key: z.ZodString;
2041
- origin_speech_id: z.ZodString;
2042
- voice: z.ZodUnknown;
2043
- caption_ids: z.ZodArray<z.ZodString>;
2044
- }, z.core.$loose>;
2045
- }, z.core.$loose>, z.ZodObject<{
2046
- caption: z.ZodObject<{
2047
- id: z.ZodOptional<z.ZodString>;
2048
- kind: z.ZodLiteral<"caption">;
2049
- initial_duration_ms: z.ZodNumber;
2050
- speech_part_id: z.ZodString;
2051
- text: z.ZodString;
2052
- start_ms: z.ZodNumber;
2053
- style: z.ZodOptional<z.ZodObject<{
2054
- font_id: z.ZodOptional<z.ZodString>;
2055
- font_size: z.ZodOptional<z.ZodNumber>;
2056
- font_color: z.ZodOptional<z.ZodString>;
2057
- font_weight: z.ZodOptional<z.ZodNumber>;
2058
- entrance_animation: z.ZodOptional<z.ZodString>;
2059
- entrance_animation_duration_ms: z.ZodOptional<z.ZodNumber>;
2060
- stroke_color: z.ZodOptional<z.ZodString>;
2061
- stroke_width: z.ZodOptional<z.ZodNumber>;
2062
- position_x: z.ZodOptional<z.ZodNumber>;
2063
- position_y: z.ZodOptional<z.ZodNumber>;
2064
- }, z.core.$loose>>;
2065
- }, z.core.$loose>;
2066
- }, z.core.$loose>, z.ZodObject<{
2067
- bgm: z.ZodObject<{
2068
- id: z.ZodOptional<z.ZodString>;
2069
- kind: z.ZodLiteral<"bgm">;
2070
- audio_storage_key: z.ZodString;
2071
- volume: z.ZodNumber;
2072
- origin_media_id: z.ZodString;
2073
- }, z.core.$loose>;
2074
- }, z.core.$loose>]>>>;
2075
- }, z.core.$loose>;
2076
- //#endregion
2077
- export { VideoDraft as $, assertValidVideoDocument as A, CaptionPart as B, index_d_exports as C, VideoDocumentMirrorSchema as D, VideoDocumentDraft as E, buildSpeechHostMap as F, Timeline as G, PartKind as H, derivePositionFromAbs as I, TrackItemTimePosition as J, Track as K, fromVideoDocument as L, buildInitialVideoDocument as M, DerivedItemPosition as N, videoDocumentMirrorSchema as O, SpeechHostMap as P, VideoDocumentValidationIssueCode as Q, toVideoDocument as R, ValidationError as S, TrackItemDraft as T, PartUnion as U, DEFAULT_UNIT_TIME_MS as V, SpeechPart as W, VideoDocument as X, VideoClipPart as Y, VideoDocumentValidationIssue as Z, PlannedSemanticOpKind as _, MirrorVideoDocumentOptions as a, PartAggregation as at, SchemaValidator as b, CommitOptions as c, Track$1 as ct, SemanticEditor as d, VideoDraftContent as et, SemanticOpInput as f, ImplementedSemanticOpKind as g, IMPLEMENTED_SEMANTIC_OP_KINDS as h, MirrorVideoDocumentAdapter as i, CaptionStyle as it, validateVideoDocument as j, VideoDocumentValidationError as k, OpActor as l, TrackItem$1 as lt, TransactAudit as m, videoDocumentSchema as n, Attachment as nt, createMirrorVideoDocument as o, SpeedShift as ot, SemanticOpName as p, TrackItem as q, readVideoDocumentFromDraft as r, CaptionPart$1 as rt, createMirrorVideoDocumentAdapter as s, Timeline$1 as st, partUnionSchema as t, VideoDraftPartUnion as tt, SemanticDocumentAdapter as u, SemanticOpKind as v, TrackDraft as w, SnapshotReadable as x, isImplementedSemanticOpKind as y, BgmPart as z };