@aicopycoders/exodus 2026.9.2000-beta.9 → 2026.9.2000
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 +168 -38
- package/assets/skills/exodus-video/scripts/first-cut.d.mts +27 -0
- package/assets/skills/exodus-video/scripts/first-cut.mjs +766 -59
- 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 +98 -0
- package/dist/commands/video-customer.js +147 -0
- package/dist/commands/video.d.ts +134 -7
- package/dist/commands/video.js +755 -66
- 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 +1 -1
package/dist/commands/video.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
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
|
+
import { type CustomerItem, type CustomerRun } from "./video-customer.js";
|
|
4
5
|
declare const CONCEIT_KEYS: readonly ["podcast", "ugc", "stage", "street", "personification"];
|
|
6
|
+
declare const VOICE_MODES: readonly ["native", "voice-first"];
|
|
7
|
+
type VoiceMode = (typeof VOICE_MODES)[number];
|
|
5
8
|
export declare const helpText: string;
|
|
9
|
+
export declare const RUN_PATH = "/api/v2/workflow";
|
|
10
|
+
export declare const ITEMS_PATH = "/api/v2/workflow/items";
|
|
11
|
+
export declare const FINAL_PATH = "/api/v2/video/final";
|
|
6
12
|
export declare const VOICES_PATH = "/api/v2/video/voices";
|
|
13
|
+
export declare const ASSET_UPLOAD_URL_PATH = "/api/v2/workflows/asset-upload-url";
|
|
14
|
+
export declare const ASSETS_PATH = "/api/v2/workflows/assets";
|
|
7
15
|
export interface ClipWord {
|
|
8
16
|
w: string;
|
|
9
17
|
s: number;
|
|
@@ -28,6 +36,7 @@ export interface ClipQcTake {
|
|
|
28
36
|
code: string;
|
|
29
37
|
wording: string;
|
|
30
38
|
}[];
|
|
39
|
+
heardText?: string;
|
|
31
40
|
}
|
|
32
41
|
export interface ClipQc {
|
|
33
42
|
verdict: "pass" | "fail";
|
|
@@ -60,6 +69,9 @@ export type ArtifactSubset = {
|
|
|
60
69
|
type: "image";
|
|
61
70
|
imageUrl?: string;
|
|
62
71
|
storageId?: string;
|
|
72
|
+
anchor?: "set-plate" | "product-sheet" | "filled-plate";
|
|
73
|
+
holds?: string[];
|
|
74
|
+
lid?: "closed";
|
|
63
75
|
} | {
|
|
64
76
|
type: "video";
|
|
65
77
|
sceneIndex?: number;
|
|
@@ -72,6 +84,10 @@ export type ArtifactSubset = {
|
|
|
72
84
|
speechTrimmed?: boolean;
|
|
73
85
|
tailTrimmed?: boolean;
|
|
74
86
|
rawStorageId?: string;
|
|
87
|
+
voiceMode?: "voice-first";
|
|
88
|
+
voiceFirstBlockedBy?: string[];
|
|
89
|
+
voicePitchHz?: number;
|
|
90
|
+
voicePitchMethod?: string;
|
|
75
91
|
} | {
|
|
76
92
|
type: "audio";
|
|
77
93
|
sceneIndex?: number;
|
|
@@ -112,6 +128,17 @@ export interface VideoRunNode {
|
|
|
112
128
|
planFailure?: PlanFailureRecord;
|
|
113
129
|
hasRejectedDraft?: boolean;
|
|
114
130
|
outputs?: ArtifactSubset[];
|
|
131
|
+
missingScenes?: MissingScene[];
|
|
132
|
+
autoRedoScenes?: number[];
|
|
133
|
+
autoRedoReasons?: AutoRedoReason[];
|
|
134
|
+
}
|
|
135
|
+
export interface AutoRedoReason {
|
|
136
|
+
sceneIndex: number;
|
|
137
|
+
reason: string;
|
|
138
|
+
}
|
|
139
|
+
export interface MissingScene {
|
|
140
|
+
sceneIndex: number;
|
|
141
|
+
pictureRefused: boolean;
|
|
115
142
|
}
|
|
116
143
|
export type BuilderPauseReason = "taste" | "repair" | "slots" | "call" | "checkpoint";
|
|
117
144
|
export interface PullCastLockMember {
|
|
@@ -139,8 +166,31 @@ export interface VideoRun {
|
|
|
139
166
|
pauseAhead?: WorkflowRun["pauseAhead"];
|
|
140
167
|
castLock?: PullCastLock | null;
|
|
141
168
|
provenance?: RunProvenance;
|
|
169
|
+
musicBed?: boolean;
|
|
170
|
+
videoChoice?: RunVideoChoice;
|
|
171
|
+
storyboardAutoApproval?: {
|
|
172
|
+
outcome: "approved" | "held";
|
|
173
|
+
at: number;
|
|
174
|
+
reason?: string;
|
|
175
|
+
};
|
|
142
176
|
workflowId?: string;
|
|
143
177
|
moduleOwned?: boolean;
|
|
178
|
+
director?: RunDirector;
|
|
179
|
+
}
|
|
180
|
+
export interface RunDirector {
|
|
181
|
+
on: boolean;
|
|
182
|
+
runSetting: boolean | null;
|
|
183
|
+
workspaceOn: boolean;
|
|
184
|
+
status: "reviewing" | "waiting" | "done" | "stopped" | null;
|
|
185
|
+
redosUsed: number;
|
|
186
|
+
redoCap: number;
|
|
187
|
+
spendUsd: number;
|
|
188
|
+
spendCapUsd: number;
|
|
189
|
+
log: {
|
|
190
|
+
at: number;
|
|
191
|
+
phase: "storyboard" | "final-watch";
|
|
192
|
+
text: string;
|
|
193
|
+
}[];
|
|
144
194
|
}
|
|
145
195
|
export declare function asVideoRun(data: unknown): VideoRun;
|
|
146
196
|
export interface NodeItem {
|
|
@@ -157,6 +207,7 @@ export interface NodeItem {
|
|
|
157
207
|
take: number;
|
|
158
208
|
outcome: string;
|
|
159
209
|
label: string;
|
|
210
|
+
reason?: string;
|
|
160
211
|
displacedHistory?: {
|
|
161
212
|
title: string;
|
|
162
213
|
lines: string[];
|
|
@@ -209,13 +260,18 @@ export declare function videoApiError(res: ApiResponse<unknown>): string;
|
|
|
209
260
|
export type RunStop = {
|
|
210
261
|
at: "running";
|
|
211
262
|
stage: string;
|
|
263
|
+
autoRedoScenes?: number[];
|
|
264
|
+
autoRedoReasons?: AutoRedoReason[];
|
|
212
265
|
} | {
|
|
213
266
|
at: "storyboard-gate";
|
|
214
267
|
nodeId?: string;
|
|
215
268
|
framesNodeId?: string;
|
|
216
269
|
showAd?: true;
|
|
270
|
+
heldReason?: string;
|
|
217
271
|
} | {
|
|
218
272
|
at: "final-watch";
|
|
273
|
+
missingScenes?: MissingScene[];
|
|
274
|
+
framesNodeId?: string;
|
|
219
275
|
} | {
|
|
220
276
|
at: "paused";
|
|
221
277
|
nodeId?: string;
|
|
@@ -232,18 +288,20 @@ export type RunStop = {
|
|
|
232
288
|
};
|
|
233
289
|
export type ResolvedStop = Exclude<RunStop, {
|
|
234
290
|
at: "final-watch";
|
|
235
|
-
}> | {
|
|
291
|
+
}> | (Extract<RunStop, {
|
|
236
292
|
at: "final-watch";
|
|
293
|
+
}> & {
|
|
237
294
|
cutAttached: boolean | null;
|
|
238
|
-
};
|
|
295
|
+
});
|
|
239
296
|
export declare function classifyRun(run: VideoRun): RunStop;
|
|
240
297
|
export declare function hasAttachedCut(items: NodeItem[]): boolean;
|
|
298
|
+
export declare function scenesBeingRedone(run: VideoRun, items: NodeItem[]): number[];
|
|
241
299
|
export declare function resolveStop(stop: RunStop, cutAttached: boolean | null): ResolvedStop;
|
|
242
300
|
export declare function resolveStopAtPark(stop: RunStop, runId: string, deps: Pick<VideoDeps, "get">): Promise<ResolvedStop>;
|
|
243
301
|
export declare function stageWord(stage: string): string;
|
|
244
302
|
export declare function stepName(kind: string | undefined): string;
|
|
245
303
|
export declare function isShowAd(run: Pick<VideoRun, "moduleOwned">): boolean;
|
|
246
|
-
export declare function reviewUrl(dashboardUrl: string, run: Pick<VideoRun, "_id" | "workflowId"
|
|
304
|
+
export declare function reviewUrl(dashboardUrl: string, run: Pick<VideoRun, "_id" | "workflowId">): string;
|
|
247
305
|
export declare function stopLines(stop: ResolvedStop, runId: string, runUrl: string): string[];
|
|
248
306
|
export declare function failedStoryboardNode(run: VideoRun): VideoRunNode | undefined;
|
|
249
307
|
export declare function errorEchoesReasons(error: string | undefined, record: PlanFailureRecord | undefined): boolean;
|
|
@@ -269,6 +327,10 @@ export interface ManifestScene {
|
|
|
269
327
|
revoiced: boolean | null;
|
|
270
328
|
speechTrimmed: boolean | null;
|
|
271
329
|
rawStorageId: string | null;
|
|
330
|
+
voiceMode: "voice-first" | null;
|
|
331
|
+
voiceFirstBlockedBy: string[] | null;
|
|
332
|
+
voicePitchHz: number | null;
|
|
333
|
+
voicePitchMethod: string | null;
|
|
272
334
|
clipStatus: string;
|
|
273
335
|
error: string | null;
|
|
274
336
|
flagged: boolean;
|
|
@@ -290,13 +352,32 @@ export interface ManifestCastRef {
|
|
|
290
352
|
voiceLabel: string | null;
|
|
291
353
|
voiceDescription: string | null;
|
|
292
354
|
}
|
|
355
|
+
export type MusicBedState = "on" | "off" | "unknown";
|
|
356
|
+
export interface RunVideoChoice {
|
|
357
|
+
videoModel: string;
|
|
358
|
+
videoModelLabel: string;
|
|
359
|
+
voiceMode: string;
|
|
360
|
+
voiceModeLabel: string;
|
|
361
|
+
}
|
|
362
|
+
export declare const MUSIC_HEARD_CODE = "music-heard";
|
|
363
|
+
export interface ManifestFilledPlate {
|
|
364
|
+
file: string | null;
|
|
365
|
+
holds: string[];
|
|
366
|
+
lid?: "closed";
|
|
367
|
+
}
|
|
293
368
|
export interface VideoManifest {
|
|
294
369
|
runId: string;
|
|
295
370
|
pulledAt: string;
|
|
296
371
|
dashboardUrl: string;
|
|
297
372
|
storyboard: string | null;
|
|
298
373
|
reference: string | null;
|
|
374
|
+
productSheet: string | null;
|
|
375
|
+
setPlate: string | null;
|
|
376
|
+
filledPlates: ManifestFilledPlate[];
|
|
299
377
|
music: string | null;
|
|
378
|
+
musicBed: MusicBedState;
|
|
379
|
+
musicHeardScenes: number[];
|
|
380
|
+
pendingRedo: number[];
|
|
300
381
|
cast: ManifestCastRef[];
|
|
301
382
|
narration: {
|
|
302
383
|
file: string;
|
|
@@ -305,8 +386,13 @@ export interface VideoManifest {
|
|
|
305
386
|
scenes: ManifestScene[];
|
|
306
387
|
failed: PullFailure[];
|
|
307
388
|
provenance?: RunProvenance;
|
|
389
|
+
videoChoice?: {
|
|
390
|
+
videoModel: string;
|
|
391
|
+
voiceMode: string;
|
|
392
|
+
};
|
|
308
393
|
}
|
|
309
394
|
export declare const CAST_LEDGER_BASE: number;
|
|
395
|
+
export declare function musicBedState(run: VideoRun): MusicBedState;
|
|
310
396
|
export interface PullPlan {
|
|
311
397
|
downloads: PullDownload[];
|
|
312
398
|
texts: PullTextFile[];
|
|
@@ -335,7 +421,11 @@ export interface ScriptStartOptions {
|
|
|
335
421
|
style: string;
|
|
336
422
|
direction?: string;
|
|
337
423
|
voicePath?: string;
|
|
338
|
-
|
|
424
|
+
videoModel?: string;
|
|
425
|
+
voiceMode?: VoiceMode;
|
|
426
|
+
music?: boolean;
|
|
427
|
+
reviewStoryboard?: true;
|
|
428
|
+
director?: true;
|
|
339
429
|
wait: boolean;
|
|
340
430
|
json: boolean;
|
|
341
431
|
}
|
|
@@ -350,7 +440,15 @@ export type VideoStartPlan = {
|
|
|
350
440
|
opts: ScriptStartOptions;
|
|
351
441
|
};
|
|
352
442
|
export declare function startFlow(opts: StartOptions, deps: VideoDeps): Promise<FlowResult>;
|
|
353
|
-
export
|
|
443
|
+
export type MusicChoice = {
|
|
444
|
+
ok: true;
|
|
445
|
+
music: boolean | undefined;
|
|
446
|
+
} | {
|
|
447
|
+
ok: false;
|
|
448
|
+
line: string;
|
|
449
|
+
};
|
|
450
|
+
export declare function planMusicChoice(occurrences: FlagOccurrence[]): MusicChoice;
|
|
451
|
+
export declare function planVideoStart(flags: Record<string, string | boolean>, occurrences: FlagOccurrence[]): VideoStartPlan;
|
|
354
452
|
export declare function startScriptFlow(opts: ScriptStartOptions, deps: VideoDeps): Promise<FlowResult>;
|
|
355
453
|
export declare function waitFlow(runId: string, opts: {
|
|
356
454
|
json: boolean;
|
|
@@ -359,6 +457,12 @@ export declare function waitFlow(runId: string, opts: {
|
|
|
359
457
|
maxPolls?: number;
|
|
360
458
|
}, deps: VideoDeps): Promise<FlowResult>;
|
|
361
459
|
export declare function statusFlow(runId: string, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
460
|
+
export declare function directorLines(director: RunDirector): string[];
|
|
461
|
+
export type DirectorSwitch = boolean | null;
|
|
462
|
+
export declare function parseDirectorSwitch(word: string | undefined): {
|
|
463
|
+
on: DirectorSwitch;
|
|
464
|
+
} | null;
|
|
465
|
+
export declare function directorFlow(runId: string, on: DirectorSwitch, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
362
466
|
export declare function rejectedDraftFlow(runId: string, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
363
467
|
export declare function storyboardFlow(runId: string, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
364
468
|
export declare function approveFlow(runId: string, opts: {
|
|
@@ -366,7 +470,7 @@ export declare function approveFlow(runId: string, opts: {
|
|
|
366
470
|
approveStaleCut: boolean;
|
|
367
471
|
}, deps: VideoDeps): Promise<FlowResult>;
|
|
368
472
|
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>;
|
|
473
|
+
export declare function retryFrameFlow(runId: string, nodeId: string | undefined, sceneIndex: number, note: string | undefined, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
370
474
|
export type ClipRedoPlan = {
|
|
371
475
|
ok: true;
|
|
372
476
|
nodeId: string;
|
|
@@ -382,7 +486,11 @@ export interface ClipRedoTarget {
|
|
|
382
486
|
nodeId?: string;
|
|
383
487
|
}
|
|
384
488
|
export declare function planClipRedo(run: VideoRun, items: NodeItem[], target: ClipRedoTarget): ClipRedoPlan;
|
|
385
|
-
export
|
|
489
|
+
export interface ClipRedoOptions {
|
|
490
|
+
note?: string;
|
|
491
|
+
voiceFirst?: boolean;
|
|
492
|
+
}
|
|
493
|
+
export declare function retryClipFlow(runId: string, target: ClipRedoTarget, { note, voiceFirst }: ClipRedoOptions, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
386
494
|
export declare const VOICE_PATHS_NEVER_HEARD: Set<string>;
|
|
387
495
|
export declare function planClipRevoice(run: VideoRun, items: NodeItem[], target: ClipRedoTarget): ClipRedoPlan;
|
|
388
496
|
export type RevoiceTarget = ClipRedoTarget | {
|
|
@@ -443,6 +551,25 @@ export type VoiceMap = Record<string, string | {
|
|
|
443
551
|
export declare function parseVoiceFlags(occurrences: FlagOccurrence[], readFile: (path: string) => string): VoiceMap | null;
|
|
444
552
|
export declare function voicesFlow(runId: string, voices: VoiceMap | null, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
445
553
|
export declare function voiceSheetLines(sheet: CastVoiceSheet): string[];
|
|
554
|
+
export interface CustomerManifest {
|
|
555
|
+
runId: string;
|
|
556
|
+
pulledAt: string;
|
|
557
|
+
dashboardUrl: string;
|
|
558
|
+
scenes: Array<{
|
|
559
|
+
index: number;
|
|
560
|
+
clip: string | null;
|
|
561
|
+
voice: string | null;
|
|
562
|
+
}>;
|
|
563
|
+
music: string | null;
|
|
564
|
+
video: string | null;
|
|
565
|
+
}
|
|
566
|
+
export declare function planCustomerPull(run: CustomerRun, items: CustomerItem[], meta: {
|
|
567
|
+
pulledAt: string;
|
|
568
|
+
dashboardUrl: string;
|
|
569
|
+
}): {
|
|
570
|
+
downloads: PullDownload[];
|
|
571
|
+
manifest: CustomerManifest;
|
|
572
|
+
};
|
|
446
573
|
export declare function pullFlow(runId: string, dir: string, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
447
574
|
export declare function parseMvhdDurationSec(bytes: Uint8Array): number | null;
|
|
448
575
|
export declare const NO_DURATION_MESSAGE: string;
|