@aicopycoders/exodus 2026.9.2000-beta.9 → 2026.10.1200-beta.1
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.
- package/assets/docs/CLAUDE.md +1 -0
- package/assets/skills/exodus-primer/SKILL.md +10 -5
- package/assets/skills/exodus-video/SKILL.md +203 -47
- package/assets/skills/exodus-video/scripts/first-cut.d.mts +44 -0
- package/assets/skills/exodus-video/scripts/first-cut.mjs +1140 -92
- package/assets/skills/exodus-winners/SKILL.md +13 -1
- package/assets/skills/swipe/SKILL.md +78 -0
- package/dist/commands/ads.js +1 -1
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/primer.js +84 -12
- package/dist/commands/video-customer.d.ts +101 -0
- package/dist/commands/video-customer.js +158 -0
- package/dist/commands/video.d.ts +169 -9
- package/dist/commands/video.js +877 -87
- package/dist/commands/whoami.js +2 -1
- package/dist/commands/workflow.d.ts +2 -1
- package/dist/commands/workflow.js +16 -2
- package/dist/lib/meta-ads.d.ts +1 -0
- package/package.json +3 -3
package/dist/commands/video.d.ts
CHANGED
|
@@ -1,9 +1,27 @@
|
|
|
1
1
|
import { type ApiResponse } from "../lib/client.js";
|
|
2
2
|
import type { FlagOccurrence } from "../lib/args.js";
|
|
3
3
|
import { type RunProvenance, type WorkflowRun } from "./workflow.js";
|
|
4
|
-
|
|
4
|
+
import { type CustomerItem, type CustomerRun } from "./video-customer.js";
|
|
5
|
+
declare const VOICE_MODES: readonly ["native", "voice-first"];
|
|
6
|
+
type VoiceMode = (typeof VOICE_MODES)[number];
|
|
7
|
+
export type ScriptRunOptions = {
|
|
8
|
+
conceits: {
|
|
9
|
+
key: string;
|
|
10
|
+
label: string;
|
|
11
|
+
}[];
|
|
12
|
+
styles: {
|
|
13
|
+
slug: string;
|
|
14
|
+
label: string;
|
|
15
|
+
}[];
|
|
16
|
+
};
|
|
17
|
+
export declare function scriptRunPickProblem(options: ScriptRunOptions, conceit: string, style: string): string | null;
|
|
5
18
|
export declare const helpText: string;
|
|
19
|
+
export declare const RUN_PATH = "/api/v2/workflow";
|
|
20
|
+
export declare const ITEMS_PATH = "/api/v2/workflow/items";
|
|
21
|
+
export declare const FINAL_PATH = "/api/v2/video/final";
|
|
6
22
|
export declare const VOICES_PATH = "/api/v2/video/voices";
|
|
23
|
+
export declare const ASSET_UPLOAD_URL_PATH = "/api/v2/workflows/asset-upload-url";
|
|
24
|
+
export declare const ASSETS_PATH = "/api/v2/workflows/assets";
|
|
7
25
|
export interface ClipWord {
|
|
8
26
|
w: string;
|
|
9
27
|
s: number;
|
|
@@ -28,6 +46,7 @@ export interface ClipQcTake {
|
|
|
28
46
|
code: string;
|
|
29
47
|
wording: string;
|
|
30
48
|
}[];
|
|
49
|
+
heardText?: string;
|
|
31
50
|
}
|
|
32
51
|
export interface ClipQc {
|
|
33
52
|
verdict: "pass" | "fail";
|
|
@@ -60,6 +79,9 @@ export type ArtifactSubset = {
|
|
|
60
79
|
type: "image";
|
|
61
80
|
imageUrl?: string;
|
|
62
81
|
storageId?: string;
|
|
82
|
+
anchor?: "set-plate" | "product-sheet" | "filled-plate";
|
|
83
|
+
holds?: string[];
|
|
84
|
+
lid?: "closed";
|
|
63
85
|
} | {
|
|
64
86
|
type: "video";
|
|
65
87
|
sceneIndex?: number;
|
|
@@ -72,6 +94,10 @@ export type ArtifactSubset = {
|
|
|
72
94
|
speechTrimmed?: boolean;
|
|
73
95
|
tailTrimmed?: boolean;
|
|
74
96
|
rawStorageId?: string;
|
|
97
|
+
voiceMode?: "voice-first";
|
|
98
|
+
voiceFirstBlockedBy?: string[];
|
|
99
|
+
voicePitchHz?: number;
|
|
100
|
+
voicePitchMethod?: string;
|
|
75
101
|
} | {
|
|
76
102
|
type: "audio";
|
|
77
103
|
sceneIndex?: number;
|
|
@@ -112,6 +138,17 @@ export interface VideoRunNode {
|
|
|
112
138
|
planFailure?: PlanFailureRecord;
|
|
113
139
|
hasRejectedDraft?: boolean;
|
|
114
140
|
outputs?: ArtifactSubset[];
|
|
141
|
+
missingScenes?: MissingScene[];
|
|
142
|
+
autoRedoScenes?: number[];
|
|
143
|
+
autoRedoReasons?: AutoRedoReason[];
|
|
144
|
+
}
|
|
145
|
+
export interface AutoRedoReason {
|
|
146
|
+
sceneIndex: number;
|
|
147
|
+
reason: string;
|
|
148
|
+
}
|
|
149
|
+
export interface MissingScene {
|
|
150
|
+
sceneIndex: number;
|
|
151
|
+
pictureRefused: boolean;
|
|
115
152
|
}
|
|
116
153
|
export type BuilderPauseReason = "taste" | "repair" | "slots" | "call" | "checkpoint";
|
|
117
154
|
export interface PullCastLockMember {
|
|
@@ -139,8 +176,32 @@ export interface VideoRun {
|
|
|
139
176
|
pauseAhead?: WorkflowRun["pauseAhead"];
|
|
140
177
|
castLock?: PullCastLock | null;
|
|
141
178
|
provenance?: RunProvenance;
|
|
179
|
+
musicBed?: boolean;
|
|
180
|
+
videoChoice?: RunVideoChoice;
|
|
181
|
+
shots?: RunShots;
|
|
182
|
+
storyboardAutoApproval?: {
|
|
183
|
+
outcome: "approved" | "held";
|
|
184
|
+
at: number;
|
|
185
|
+
reason?: string;
|
|
186
|
+
};
|
|
142
187
|
workflowId?: string;
|
|
143
188
|
moduleOwned?: boolean;
|
|
189
|
+
director?: RunDirector;
|
|
190
|
+
}
|
|
191
|
+
export interface RunDirector {
|
|
192
|
+
on: boolean;
|
|
193
|
+
runSetting: boolean | null;
|
|
194
|
+
workspaceOn: boolean;
|
|
195
|
+
status: "reviewing" | "waiting" | "done" | "stopped" | null;
|
|
196
|
+
redosUsed: number;
|
|
197
|
+
redoCap: number;
|
|
198
|
+
spendUsd: number;
|
|
199
|
+
spendCapUsd: number;
|
|
200
|
+
log: {
|
|
201
|
+
at: number;
|
|
202
|
+
phase: "storyboard" | "final-watch";
|
|
203
|
+
text: string;
|
|
204
|
+
}[];
|
|
144
205
|
}
|
|
145
206
|
export declare function asVideoRun(data: unknown): VideoRun;
|
|
146
207
|
export interface NodeItem {
|
|
@@ -157,6 +218,7 @@ export interface NodeItem {
|
|
|
157
218
|
take: number;
|
|
158
219
|
outcome: string;
|
|
159
220
|
label: string;
|
|
221
|
+
reason?: string;
|
|
160
222
|
displacedHistory?: {
|
|
161
223
|
title: string;
|
|
162
224
|
lines: string[];
|
|
@@ -180,6 +242,7 @@ export interface ShowRow {
|
|
|
180
242
|
export interface FlowResult {
|
|
181
243
|
code: number;
|
|
182
244
|
lines: string[];
|
|
245
|
+
usage?: true;
|
|
183
246
|
}
|
|
184
247
|
export interface VideoDeps {
|
|
185
248
|
get: (path: string) => Promise<ApiResponse<unknown>>;
|
|
@@ -209,13 +272,18 @@ export declare function videoApiError(res: ApiResponse<unknown>): string;
|
|
|
209
272
|
export type RunStop = {
|
|
210
273
|
at: "running";
|
|
211
274
|
stage: string;
|
|
275
|
+
autoRedoScenes?: number[];
|
|
276
|
+
autoRedoReasons?: AutoRedoReason[];
|
|
212
277
|
} | {
|
|
213
278
|
at: "storyboard-gate";
|
|
214
279
|
nodeId?: string;
|
|
215
280
|
framesNodeId?: string;
|
|
216
281
|
showAd?: true;
|
|
282
|
+
heldReason?: string;
|
|
217
283
|
} | {
|
|
218
284
|
at: "final-watch";
|
|
285
|
+
missingScenes?: MissingScene[];
|
|
286
|
+
framesNodeId?: string;
|
|
219
287
|
} | {
|
|
220
288
|
at: "paused";
|
|
221
289
|
nodeId?: string;
|
|
@@ -232,18 +300,20 @@ export type RunStop = {
|
|
|
232
300
|
};
|
|
233
301
|
export type ResolvedStop = Exclude<RunStop, {
|
|
234
302
|
at: "final-watch";
|
|
235
|
-
}> | {
|
|
303
|
+
}> | (Extract<RunStop, {
|
|
236
304
|
at: "final-watch";
|
|
305
|
+
}> & {
|
|
237
306
|
cutAttached: boolean | null;
|
|
238
|
-
};
|
|
307
|
+
});
|
|
239
308
|
export declare function classifyRun(run: VideoRun): RunStop;
|
|
240
309
|
export declare function hasAttachedCut(items: NodeItem[]): boolean;
|
|
310
|
+
export declare function scenesBeingRedone(run: VideoRun, items: NodeItem[]): number[];
|
|
241
311
|
export declare function resolveStop(stop: RunStop, cutAttached: boolean | null): ResolvedStop;
|
|
242
312
|
export declare function resolveStopAtPark(stop: RunStop, runId: string, deps: Pick<VideoDeps, "get">): Promise<ResolvedStop>;
|
|
243
313
|
export declare function stageWord(stage: string): string;
|
|
244
314
|
export declare function stepName(kind: string | undefined): string;
|
|
245
315
|
export declare function isShowAd(run: Pick<VideoRun, "moduleOwned">): boolean;
|
|
246
|
-
export declare function reviewUrl(dashboardUrl: string, run: Pick<VideoRun, "_id" | "workflowId"
|
|
316
|
+
export declare function reviewUrl(dashboardUrl: string, run: Pick<VideoRun, "_id" | "workflowId">): string;
|
|
247
317
|
export declare function stopLines(stop: ResolvedStop, runId: string, runUrl: string): string[];
|
|
248
318
|
export declare function failedStoryboardNode(run: VideoRun): VideoRunNode | undefined;
|
|
249
319
|
export declare function errorEchoesReasons(error: string | undefined, record: PlanFailureRecord | undefined): boolean;
|
|
@@ -269,6 +339,10 @@ export interface ManifestScene {
|
|
|
269
339
|
revoiced: boolean | null;
|
|
270
340
|
speechTrimmed: boolean | null;
|
|
271
341
|
rawStorageId: string | null;
|
|
342
|
+
voiceMode: "voice-first" | null;
|
|
343
|
+
voiceFirstBlockedBy: string[] | null;
|
|
344
|
+
voicePitchHz: number | null;
|
|
345
|
+
voicePitchMethod: string | null;
|
|
272
346
|
clipStatus: string;
|
|
273
347
|
error: string | null;
|
|
274
348
|
flagged: boolean;
|
|
@@ -290,13 +364,32 @@ export interface ManifestCastRef {
|
|
|
290
364
|
voiceLabel: string | null;
|
|
291
365
|
voiceDescription: string | null;
|
|
292
366
|
}
|
|
367
|
+
export type MusicBedState = "on" | "off" | "unknown";
|
|
368
|
+
export interface RunVideoChoice {
|
|
369
|
+
videoModel: string;
|
|
370
|
+
videoModelLabel: string;
|
|
371
|
+
voiceMode: string;
|
|
372
|
+
voiceModeLabel: string;
|
|
373
|
+
}
|
|
374
|
+
export declare const MUSIC_HEARD_CODE = "music-heard";
|
|
375
|
+
export interface ManifestFilledPlate {
|
|
376
|
+
file: string | null;
|
|
377
|
+
holds: string[];
|
|
378
|
+
lid?: "closed";
|
|
379
|
+
}
|
|
293
380
|
export interface VideoManifest {
|
|
294
381
|
runId: string;
|
|
295
382
|
pulledAt: string;
|
|
296
383
|
dashboardUrl: string;
|
|
297
384
|
storyboard: string | null;
|
|
298
385
|
reference: string | null;
|
|
386
|
+
productSheet: string | null;
|
|
387
|
+
setPlate: string | null;
|
|
388
|
+
filledPlates: ManifestFilledPlate[];
|
|
299
389
|
music: string | null;
|
|
390
|
+
musicBed: MusicBedState;
|
|
391
|
+
musicHeardScenes: number[];
|
|
392
|
+
pendingRedo: number[];
|
|
300
393
|
cast: ManifestCastRef[];
|
|
301
394
|
narration: {
|
|
302
395
|
file: string;
|
|
@@ -305,8 +398,18 @@ export interface VideoManifest {
|
|
|
305
398
|
scenes: ManifestScene[];
|
|
306
399
|
failed: PullFailure[];
|
|
307
400
|
provenance?: RunProvenance;
|
|
401
|
+
videoChoice?: {
|
|
402
|
+
videoModel: string;
|
|
403
|
+
voiceMode: string;
|
|
404
|
+
};
|
|
405
|
+
shots?: RunShots;
|
|
406
|
+
}
|
|
407
|
+
export interface RunShots {
|
|
408
|
+
frame?: string;
|
|
409
|
+
pacing?: string;
|
|
308
410
|
}
|
|
309
411
|
export declare const CAST_LEDGER_BASE: number;
|
|
412
|
+
export declare function musicBedState(run: VideoRun): MusicBedState;
|
|
310
413
|
export interface PullPlan {
|
|
311
414
|
downloads: PullDownload[];
|
|
312
415
|
texts: PullTextFile[];
|
|
@@ -331,11 +434,16 @@ export interface StartOptions {
|
|
|
331
434
|
}
|
|
332
435
|
export interface ScriptStartOptions {
|
|
333
436
|
scriptFile: string;
|
|
334
|
-
conceit:
|
|
437
|
+
conceit: string;
|
|
335
438
|
style: string;
|
|
336
439
|
direction?: string;
|
|
337
440
|
voicePath?: string;
|
|
338
|
-
|
|
441
|
+
videoModel?: string;
|
|
442
|
+
voiceMode?: VoiceMode;
|
|
443
|
+
music?: boolean;
|
|
444
|
+
reviewStoryboard?: true;
|
|
445
|
+
director?: true;
|
|
446
|
+
shots?: RunShots;
|
|
339
447
|
wait: boolean;
|
|
340
448
|
json: boolean;
|
|
341
449
|
}
|
|
@@ -350,7 +458,15 @@ export type VideoStartPlan = {
|
|
|
350
458
|
opts: ScriptStartOptions;
|
|
351
459
|
};
|
|
352
460
|
export declare function startFlow(opts: StartOptions, deps: VideoDeps): Promise<FlowResult>;
|
|
353
|
-
export
|
|
461
|
+
export type MusicChoice = {
|
|
462
|
+
ok: true;
|
|
463
|
+
music: boolean | undefined;
|
|
464
|
+
} | {
|
|
465
|
+
ok: false;
|
|
466
|
+
line: string;
|
|
467
|
+
};
|
|
468
|
+
export declare function planMusicChoice(occurrences: FlagOccurrence[]): MusicChoice;
|
|
469
|
+
export declare function planVideoStart(flags: Record<string, string | boolean>, occurrences: FlagOccurrence[]): VideoStartPlan;
|
|
354
470
|
export declare function startScriptFlow(opts: ScriptStartOptions, deps: VideoDeps): Promise<FlowResult>;
|
|
355
471
|
export declare function waitFlow(runId: string, opts: {
|
|
356
472
|
json: boolean;
|
|
@@ -359,6 +475,12 @@ export declare function waitFlow(runId: string, opts: {
|
|
|
359
475
|
maxPolls?: number;
|
|
360
476
|
}, deps: VideoDeps): Promise<FlowResult>;
|
|
361
477
|
export declare function statusFlow(runId: string, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
478
|
+
export declare function directorLines(director: RunDirector): string[];
|
|
479
|
+
export type DirectorSwitch = boolean | null;
|
|
480
|
+
export declare function parseDirectorSwitch(word: string | undefined): {
|
|
481
|
+
on: DirectorSwitch;
|
|
482
|
+
} | null;
|
|
483
|
+
export declare function directorFlow(runId: string, on: DirectorSwitch, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
362
484
|
export declare function rejectedDraftFlow(runId: string, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
363
485
|
export declare function storyboardFlow(runId: string, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
364
486
|
export declare function approveFlow(runId: string, opts: {
|
|
@@ -366,7 +488,7 @@ export declare function approveFlow(runId: string, opts: {
|
|
|
366
488
|
approveStaleCut: boolean;
|
|
367
489
|
}, deps: VideoDeps): Promise<FlowResult>;
|
|
368
490
|
export declare function flagFlow(runId: string, note: string, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
369
|
-
export declare function retryFrameFlow(runId: string, nodeId: string, sceneIndex: number, note: string | undefined, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
491
|
+
export declare function retryFrameFlow(runId: string, nodeId: string | undefined, sceneIndex: number, note: string | undefined, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
370
492
|
export type ClipRedoPlan = {
|
|
371
493
|
ok: true;
|
|
372
494
|
nodeId: string;
|
|
@@ -382,7 +504,11 @@ export interface ClipRedoTarget {
|
|
|
382
504
|
nodeId?: string;
|
|
383
505
|
}
|
|
384
506
|
export declare function planClipRedo(run: VideoRun, items: NodeItem[], target: ClipRedoTarget): ClipRedoPlan;
|
|
385
|
-
export
|
|
507
|
+
export interface ClipRedoOptions {
|
|
508
|
+
note?: string;
|
|
509
|
+
voiceFirst?: boolean;
|
|
510
|
+
}
|
|
511
|
+
export declare function retryClipFlow(runId: string, target: ClipRedoTarget, { note, voiceFirst }: ClipRedoOptions, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
386
512
|
export declare const VOICE_PATHS_NEVER_HEARD: Set<string>;
|
|
387
513
|
export declare function planClipRevoice(run: VideoRun, items: NodeItem[], target: ClipRedoTarget): ClipRedoPlan;
|
|
388
514
|
export type RevoiceTarget = ClipRedoTarget | {
|
|
@@ -443,10 +569,44 @@ export type VoiceMap = Record<string, string | {
|
|
|
443
569
|
export declare function parseVoiceFlags(occurrences: FlagOccurrence[], readFile: (path: string) => string): VoiceMap | null;
|
|
444
570
|
export declare function voicesFlow(runId: string, voices: VoiceMap | null, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
445
571
|
export declare function voiceSheetLines(sheet: CastVoiceSheet): string[];
|
|
572
|
+
export interface CustomerManifest {
|
|
573
|
+
runId: string;
|
|
574
|
+
pulledAt: string;
|
|
575
|
+
dashboardUrl: string;
|
|
576
|
+
scenes: Array<{
|
|
577
|
+
index: number;
|
|
578
|
+
clip: string | null;
|
|
579
|
+
voice: string | null;
|
|
580
|
+
}>;
|
|
581
|
+
music: string | null;
|
|
582
|
+
video: string | null;
|
|
583
|
+
}
|
|
584
|
+
export declare function planCustomerPull(run: CustomerRun, items: CustomerItem[], meta: {
|
|
585
|
+
pulledAt: string;
|
|
586
|
+
dashboardUrl: string;
|
|
587
|
+
}): {
|
|
588
|
+
downloads: PullDownload[];
|
|
589
|
+
manifest: CustomerManifest;
|
|
590
|
+
};
|
|
446
591
|
export declare function pullFlow(runId: string, dir: string, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
447
592
|
export declare function parseMvhdDurationSec(bytes: Uint8Array): number | null;
|
|
448
593
|
export declare const NO_DURATION_MESSAGE: string;
|
|
449
594
|
export declare function describeFetchFailure(err: unknown): string;
|
|
595
|
+
export interface CutScene {
|
|
596
|
+
scene: number;
|
|
597
|
+
startSec: number;
|
|
598
|
+
seconds: number;
|
|
599
|
+
}
|
|
600
|
+
export interface CutWord {
|
|
601
|
+
text: string;
|
|
602
|
+
start: number;
|
|
603
|
+
end: number;
|
|
604
|
+
scene: number;
|
|
605
|
+
}
|
|
606
|
+
export declare function cutSidecars(filePath: string, deps: VideoDeps): {
|
|
607
|
+
cutScenes?: CutScene[];
|
|
608
|
+
cutWords?: CutWord[];
|
|
609
|
+
};
|
|
450
610
|
export declare function uploadFlow(runId: string, filePath: string, durationFlag: string | undefined, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
451
611
|
export declare function parsePositional(args?: string[]): string[];
|
|
452
612
|
export declare function run(flags: Record<string, string | boolean>, occurrences: FlagOccurrence[]): Promise<void>;
|