@aicopycoders/exodus 2026.9.2000-beta.8 → 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 +265 -51
- 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/exodus-workflow/SKILL.md +1 -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 +156 -5
- package/dist/commands/video.js +945 -63
- 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,8 +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";
|
|
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];
|
|
4
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";
|
|
5
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";
|
|
6
15
|
export interface ClipWord {
|
|
7
16
|
w: string;
|
|
8
17
|
s: number;
|
|
@@ -27,6 +36,7 @@ export interface ClipQcTake {
|
|
|
27
36
|
code: string;
|
|
28
37
|
wording: string;
|
|
29
38
|
}[];
|
|
39
|
+
heardText?: string;
|
|
30
40
|
}
|
|
31
41
|
export interface ClipQc {
|
|
32
42
|
verdict: "pass" | "fail";
|
|
@@ -59,6 +69,9 @@ export type ArtifactSubset = {
|
|
|
59
69
|
type: "image";
|
|
60
70
|
imageUrl?: string;
|
|
61
71
|
storageId?: string;
|
|
72
|
+
anchor?: "set-plate" | "product-sheet" | "filled-plate";
|
|
73
|
+
holds?: string[];
|
|
74
|
+
lid?: "closed";
|
|
62
75
|
} | {
|
|
63
76
|
type: "video";
|
|
64
77
|
sceneIndex?: number;
|
|
@@ -71,6 +84,10 @@ export type ArtifactSubset = {
|
|
|
71
84
|
speechTrimmed?: boolean;
|
|
72
85
|
tailTrimmed?: boolean;
|
|
73
86
|
rawStorageId?: string;
|
|
87
|
+
voiceMode?: "voice-first";
|
|
88
|
+
voiceFirstBlockedBy?: string[];
|
|
89
|
+
voicePitchHz?: number;
|
|
90
|
+
voicePitchMethod?: string;
|
|
74
91
|
} | {
|
|
75
92
|
type: "audio";
|
|
76
93
|
sceneIndex?: number;
|
|
@@ -111,6 +128,17 @@ export interface VideoRunNode {
|
|
|
111
128
|
planFailure?: PlanFailureRecord;
|
|
112
129
|
hasRejectedDraft?: boolean;
|
|
113
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;
|
|
114
142
|
}
|
|
115
143
|
export type BuilderPauseReason = "taste" | "repair" | "slots" | "call" | "checkpoint";
|
|
116
144
|
export interface PullCastLockMember {
|
|
@@ -138,8 +166,31 @@ export interface VideoRun {
|
|
|
138
166
|
pauseAhead?: WorkflowRun["pauseAhead"];
|
|
139
167
|
castLock?: PullCastLock | null;
|
|
140
168
|
provenance?: RunProvenance;
|
|
169
|
+
musicBed?: boolean;
|
|
170
|
+
videoChoice?: RunVideoChoice;
|
|
171
|
+
storyboardAutoApproval?: {
|
|
172
|
+
outcome: "approved" | "held";
|
|
173
|
+
at: number;
|
|
174
|
+
reason?: string;
|
|
175
|
+
};
|
|
141
176
|
workflowId?: string;
|
|
142
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
|
+
}[];
|
|
143
194
|
}
|
|
144
195
|
export declare function asVideoRun(data: unknown): VideoRun;
|
|
145
196
|
export interface NodeItem {
|
|
@@ -156,6 +207,7 @@ export interface NodeItem {
|
|
|
156
207
|
take: number;
|
|
157
208
|
outcome: string;
|
|
158
209
|
label: string;
|
|
210
|
+
reason?: string;
|
|
159
211
|
displacedHistory?: {
|
|
160
212
|
title: string;
|
|
161
213
|
lines: string[];
|
|
@@ -208,13 +260,18 @@ export declare function videoApiError(res: ApiResponse<unknown>): string;
|
|
|
208
260
|
export type RunStop = {
|
|
209
261
|
at: "running";
|
|
210
262
|
stage: string;
|
|
263
|
+
autoRedoScenes?: number[];
|
|
264
|
+
autoRedoReasons?: AutoRedoReason[];
|
|
211
265
|
} | {
|
|
212
266
|
at: "storyboard-gate";
|
|
213
267
|
nodeId?: string;
|
|
214
268
|
framesNodeId?: string;
|
|
215
269
|
showAd?: true;
|
|
270
|
+
heldReason?: string;
|
|
216
271
|
} | {
|
|
217
272
|
at: "final-watch";
|
|
273
|
+
missingScenes?: MissingScene[];
|
|
274
|
+
framesNodeId?: string;
|
|
218
275
|
} | {
|
|
219
276
|
at: "paused";
|
|
220
277
|
nodeId?: string;
|
|
@@ -231,18 +288,20 @@ export type RunStop = {
|
|
|
231
288
|
};
|
|
232
289
|
export type ResolvedStop = Exclude<RunStop, {
|
|
233
290
|
at: "final-watch";
|
|
234
|
-
}> | {
|
|
291
|
+
}> | (Extract<RunStop, {
|
|
235
292
|
at: "final-watch";
|
|
293
|
+
}> & {
|
|
236
294
|
cutAttached: boolean | null;
|
|
237
|
-
};
|
|
295
|
+
});
|
|
238
296
|
export declare function classifyRun(run: VideoRun): RunStop;
|
|
239
297
|
export declare function hasAttachedCut(items: NodeItem[]): boolean;
|
|
298
|
+
export declare function scenesBeingRedone(run: VideoRun, items: NodeItem[]): number[];
|
|
240
299
|
export declare function resolveStop(stop: RunStop, cutAttached: boolean | null): ResolvedStop;
|
|
241
300
|
export declare function resolveStopAtPark(stop: RunStop, runId: string, deps: Pick<VideoDeps, "get">): Promise<ResolvedStop>;
|
|
242
301
|
export declare function stageWord(stage: string): string;
|
|
243
302
|
export declare function stepName(kind: string | undefined): string;
|
|
244
303
|
export declare function isShowAd(run: Pick<VideoRun, "moduleOwned">): boolean;
|
|
245
|
-
export declare function reviewUrl(dashboardUrl: string, run: Pick<VideoRun, "_id" | "workflowId"
|
|
304
|
+
export declare function reviewUrl(dashboardUrl: string, run: Pick<VideoRun, "_id" | "workflowId">): string;
|
|
246
305
|
export declare function stopLines(stop: ResolvedStop, runId: string, runUrl: string): string[];
|
|
247
306
|
export declare function failedStoryboardNode(run: VideoRun): VideoRunNode | undefined;
|
|
248
307
|
export declare function errorEchoesReasons(error: string | undefined, record: PlanFailureRecord | undefined): boolean;
|
|
@@ -268,6 +327,10 @@ export interface ManifestScene {
|
|
|
268
327
|
revoiced: boolean | null;
|
|
269
328
|
speechTrimmed: boolean | null;
|
|
270
329
|
rawStorageId: string | null;
|
|
330
|
+
voiceMode: "voice-first" | null;
|
|
331
|
+
voiceFirstBlockedBy: string[] | null;
|
|
332
|
+
voicePitchHz: number | null;
|
|
333
|
+
voicePitchMethod: string | null;
|
|
271
334
|
clipStatus: string;
|
|
272
335
|
error: string | null;
|
|
273
336
|
flagged: boolean;
|
|
@@ -289,13 +352,32 @@ export interface ManifestCastRef {
|
|
|
289
352
|
voiceLabel: string | null;
|
|
290
353
|
voiceDescription: string | null;
|
|
291
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
|
+
}
|
|
292
368
|
export interface VideoManifest {
|
|
293
369
|
runId: string;
|
|
294
370
|
pulledAt: string;
|
|
295
371
|
dashboardUrl: string;
|
|
296
372
|
storyboard: string | null;
|
|
297
373
|
reference: string | null;
|
|
374
|
+
productSheet: string | null;
|
|
375
|
+
setPlate: string | null;
|
|
376
|
+
filledPlates: ManifestFilledPlate[];
|
|
298
377
|
music: string | null;
|
|
378
|
+
musicBed: MusicBedState;
|
|
379
|
+
musicHeardScenes: number[];
|
|
380
|
+
pendingRedo: number[];
|
|
299
381
|
cast: ManifestCastRef[];
|
|
300
382
|
narration: {
|
|
301
383
|
file: string;
|
|
@@ -304,8 +386,13 @@ export interface VideoManifest {
|
|
|
304
386
|
scenes: ManifestScene[];
|
|
305
387
|
failed: PullFailure[];
|
|
306
388
|
provenance?: RunProvenance;
|
|
389
|
+
videoChoice?: {
|
|
390
|
+
videoModel: string;
|
|
391
|
+
voiceMode: string;
|
|
392
|
+
};
|
|
307
393
|
}
|
|
308
394
|
export declare const CAST_LEDGER_BASE: number;
|
|
395
|
+
export declare function musicBedState(run: VideoRun): MusicBedState;
|
|
309
396
|
export interface PullPlan {
|
|
310
397
|
downloads: PullDownload[];
|
|
311
398
|
texts: PullTextFile[];
|
|
@@ -328,7 +415,41 @@ export interface StartOptions {
|
|
|
328
415
|
wait: boolean;
|
|
329
416
|
json: boolean;
|
|
330
417
|
}
|
|
418
|
+
export interface ScriptStartOptions {
|
|
419
|
+
scriptFile: string;
|
|
420
|
+
conceit: (typeof CONCEIT_KEYS)[number];
|
|
421
|
+
style: string;
|
|
422
|
+
direction?: string;
|
|
423
|
+
voicePath?: string;
|
|
424
|
+
videoModel?: string;
|
|
425
|
+
voiceMode?: VoiceMode;
|
|
426
|
+
music?: boolean;
|
|
427
|
+
reviewStoryboard?: true;
|
|
428
|
+
director?: true;
|
|
429
|
+
wait: boolean;
|
|
430
|
+
json: boolean;
|
|
431
|
+
}
|
|
432
|
+
export type VideoStartPlan = {
|
|
433
|
+
kind: "usage";
|
|
434
|
+
line: string;
|
|
435
|
+
} | {
|
|
436
|
+
kind: "show";
|
|
437
|
+
opts: StartOptions;
|
|
438
|
+
} | {
|
|
439
|
+
kind: "script";
|
|
440
|
+
opts: ScriptStartOptions;
|
|
441
|
+
};
|
|
331
442
|
export declare function startFlow(opts: StartOptions, deps: VideoDeps): Promise<FlowResult>;
|
|
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;
|
|
452
|
+
export declare function startScriptFlow(opts: ScriptStartOptions, deps: VideoDeps): Promise<FlowResult>;
|
|
332
453
|
export declare function waitFlow(runId: string, opts: {
|
|
333
454
|
json: boolean;
|
|
334
455
|
url?: string;
|
|
@@ -336,6 +457,12 @@ export declare function waitFlow(runId: string, opts: {
|
|
|
336
457
|
maxPolls?: number;
|
|
337
458
|
}, deps: VideoDeps): Promise<FlowResult>;
|
|
338
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>;
|
|
339
466
|
export declare function rejectedDraftFlow(runId: string, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
340
467
|
export declare function storyboardFlow(runId: string, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
341
468
|
export declare function approveFlow(runId: string, opts: {
|
|
@@ -343,7 +470,7 @@ export declare function approveFlow(runId: string, opts: {
|
|
|
343
470
|
approveStaleCut: boolean;
|
|
344
471
|
}, deps: VideoDeps): Promise<FlowResult>;
|
|
345
472
|
export declare function flagFlow(runId: string, note: string, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
346
|
-
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>;
|
|
347
474
|
export type ClipRedoPlan = {
|
|
348
475
|
ok: true;
|
|
349
476
|
nodeId: string;
|
|
@@ -359,7 +486,11 @@ export interface ClipRedoTarget {
|
|
|
359
486
|
nodeId?: string;
|
|
360
487
|
}
|
|
361
488
|
export declare function planClipRedo(run: VideoRun, items: NodeItem[], target: ClipRedoTarget): ClipRedoPlan;
|
|
362
|
-
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>;
|
|
363
494
|
export declare const VOICE_PATHS_NEVER_HEARD: Set<string>;
|
|
364
495
|
export declare function planClipRevoice(run: VideoRun, items: NodeItem[], target: ClipRedoTarget): ClipRedoPlan;
|
|
365
496
|
export type RevoiceTarget = ClipRedoTarget | {
|
|
@@ -420,6 +551,25 @@ export type VoiceMap = Record<string, string | {
|
|
|
420
551
|
export declare function parseVoiceFlags(occurrences: FlagOccurrence[], readFile: (path: string) => string): VoiceMap | null;
|
|
421
552
|
export declare function voicesFlow(runId: string, voices: VoiceMap | null, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
422
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
|
+
};
|
|
423
573
|
export declare function pullFlow(runId: string, dir: string, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
424
574
|
export declare function parseMvhdDurationSec(bytes: Uint8Array): number | null;
|
|
425
575
|
export declare const NO_DURATION_MESSAGE: string;
|
|
@@ -427,3 +577,4 @@ export declare function describeFetchFailure(err: unknown): string;
|
|
|
427
577
|
export declare function uploadFlow(runId: string, filePath: string, durationFlag: string | undefined, json: boolean, deps: VideoDeps): Promise<FlowResult>;
|
|
428
578
|
export declare function parsePositional(args?: string[]): string[];
|
|
429
579
|
export declare function run(flags: Record<string, string | boolean>, occurrences: FlagOccurrence[]): Promise<void>;
|
|
580
|
+
export {};
|