@aicopycoders/exodus 2026.7.200-beta.13 → 2026.7.200-beta.14

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,5 +1,5 @@
1
1
  import { apiGet, apiPost, apiPostDashboard, getDashboardUrl } from "../lib/client.js";
2
- import { formatError } from "../lib/format.js";
2
+ import { displayRunStatus, formatError } from "../lib/format.js";
3
3
  import { AD_TYPES, AD_TYPE_NAMES, REPTILE_TRIGGERS, } from "../lib/template-constants.js";
4
4
  export const helpText = `
5
5
  exodus template — Fernando's Template pipeline (${AD_TYPES.length} AD_TYPES, resume)
@@ -225,7 +225,7 @@ async function runStatus(flags) {
225
225
  console.log(`runId: ${d._id ?? runId}`);
226
226
  if (d.name)
227
227
  console.log(`name: ${d.name}`);
228
- console.log(`status: ${d.status ?? "—"}`);
228
+ console.log(`status: ${displayRunStatus(d.status, "—")}`);
229
229
  if (d.completedImageCount !== undefined || d.requestedImageCount !== undefined) {
230
230
  console.log(`progress: ${d.completedImageCount ?? 0} / ${d.requestedImageCount ?? "?"} completed${d.failedImageCount ? `, ${d.failedImageCount} failed` : ""}`);
231
231
  }
@@ -1,7 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { apiGet, apiPost } from "../lib/client.js";
4
- import { formatError } from "../lib/format.js";
4
+ import { displayRunStatus, formatError, tickerRunStatus } from "../lib/format.js";
5
5
  import { pollUntilDone } from "../lib/poll.js";
6
6
  export const helpText = `
7
7
  exodus winners — Import your own brand's winning ads as generative fuel
@@ -290,7 +290,7 @@ async function runImport(positional, flags) {
290
290
  const status = typeof data.status === "string" ? data.status : "";
291
291
  if (!json && status && status !== lastStatus) {
292
292
  lastStatus = status;
293
- console.log(` status: ${status}`);
293
+ console.log(` status: ${tickerRunStatus(status)}`);
294
294
  }
295
295
  },
296
296
  });
@@ -343,7 +343,7 @@ async function uploadAsset(absPath, json) {
343
343
  }
344
344
  function printOutcomeTable(data) {
345
345
  const winners = data.winners ?? [];
346
- console.log(`\nImport ${data.importId ?? "?"}: ${data.status ?? "?"}`);
346
+ console.log(`\nImport ${data.importId ?? "?"}: ${displayRunStatus(data.status, "?")}`);
347
347
  if (data.error)
348
348
  console.log(` error: ${data.error}`);
349
349
  const created = winners.filter((w) => w.created === true).length;
@@ -1,8 +1,9 @@
1
1
  import { type ApiResponse } from "../lib/client.js";
2
2
  import { type PollOptions, type PollResult } from "../lib/poll.js";
3
+ import { LEGACY_WORKFLOW_RUN_STATUS_VALUES, type RunStatus } from "../lib/runStatus.js";
3
4
  import { type Channel } from "../lib/channel.js";
4
5
  export declare const helpText: string;
5
- export type WorkflowNodeKind = "brief" | "bot" | "primer" | "image" | "rig" | "storyboard" | "reference" | "scene-frames" | "video" | "voiceover" | "output" | "push" | "gate" | "call" | "show-set" | "show-cast" | "show-voices" | "product-truth" | "transform";
6
+ export type WorkflowNodeKind = "brief" | "asset" | "bot" | "primer" | "image" | "image-rig" | "rig" | "storyboard" | "reference" | "scene-frames" | "video" | "voiceover" | "output" | "call" | "show-set" | "show-cast" | "show-voices" | "product-truth" | "transform" | "formatter" | "splitter" | "collector";
6
7
  export type WorkflowSlotState = "locked" | "auto" | "ask" | "inferred";
7
8
  export interface WorkflowSlot {
8
9
  id: string;
@@ -67,7 +68,7 @@ export interface WorkflowImportResult {
67
68
  unresolved: UnresolvedWorkflowRef[];
68
69
  warnings: string[];
69
70
  }
70
- export type GraphIssueCode = "bad-shape" | "unknown-kind" | "duplicate-node-id" | "dangling-edge" | "unknown-port" | "type-mismatch" | "duplicate-input" | "session-fan-out" | "cycle" | "missing-required-input" | "bad-config" | "bad-slot" | "bad-trigger";
71
+ export type GraphIssueCode = "bad-shape" | "unknown-kind" | "duplicate-node-id" | "dangling-edge" | "unknown-port" | "type-mismatch" | "duplicate-input" | "duplicate-input-key" | "cycle" | "missing-required-input" | "bad-config" | "bad-slot" | "bad-trigger" | "nested-split" | "fan-overlap" | "lane-ineligible" | "collector-unpaired";
71
72
  export interface GraphIssue {
72
73
  code: GraphIssueCode;
73
74
  message: string;
@@ -83,7 +84,7 @@ export interface WorkflowImportError {
83
84
  issues?: GraphIssue[];
84
85
  currentUpdatedAt?: string;
85
86
  }
86
- export type WorkflowPortType = "text" | "primer" | "image" | "rig" | "storyboard" | "frames" | "video" | "audio" | "show" | "session";
87
+ export type WorkflowPortType = "text" | "primer" | "image" | "rig" | "storyboard" | "frames" | "video" | "audio" | "document" | "show" | "session";
87
88
  export type WorkflowPrimerKind = "body" | "hook" | "headline" | "summary";
88
89
  export type WorkflowDurationSpec = {
89
90
  kind: "fixed";
@@ -163,20 +164,25 @@ export interface WorkflowCatalog {
163
164
  };
164
165
  }
165
166
  export type WorkflowBriefSource = "text" | "swipe-ad" | "swipe-bundle" | "organic-url" | "ad-url";
167
+ export type WorkflowMediaType = "image" | "video" | "audio" | "document";
168
+ export type WorkflowEntryFieldType = "text" | "select" | "number" | "toggle";
166
169
  export interface WorkflowInputDescriptor {
167
170
  fieldName: string;
168
171
  nodeId: string;
169
- source: WorkflowBriefSource;
172
+ source: WorkflowBriefSource | "asset";
170
173
  required: boolean;
171
174
  description?: string;
175
+ type?: WorkflowEntryFieldType;
176
+ options?: string[];
172
177
  bundleSize?: number;
178
+ assetType?: WorkflowMediaType;
173
179
  }
174
180
  export interface WorkflowPrerequisiteDescriptor {
175
181
  primerKind: WorkflowPrimerKind;
176
182
  nodeIds: string[];
177
183
  }
178
184
  export interface WorkflowOutputDescriptor {
179
- type: "text" | "image" | "video" | "audio" | "frames" | "storyboard";
185
+ type: "text" | "image" | "video" | "audio" | "document" | "frames" | "storyboard";
180
186
  label: string;
181
187
  nodeId: string;
182
188
  botSlug?: string;
@@ -225,32 +231,40 @@ export interface WorkflowVersion {
225
231
  export interface WorkflowVersionsResponse {
226
232
  versions: WorkflowVersion[];
227
233
  }
228
- export type WorkflowRunStatus = "queued" | "running" | "awaiting-review" | "completed" | "partial" | "failed" | "canceled";
234
+ export type WorkflowRunStatus = RunStatus | (typeof LEGACY_WORKFLOW_RUN_STATUS_VALUES)[number];
229
235
  export type WorkflowNodeRunStatus = "idle" | "running" | "done" | "failed" | "skipped";
236
+ export interface ArtifactItemIdentity {
237
+ index: number;
238
+ total: number;
239
+ }
230
240
  export type WorkflowArtifact = {
231
241
  type: "text";
232
242
  text: string;
233
243
  label?: string;
234
244
  port?: string;
235
245
  humanEdited?: boolean;
246
+ item?: ArtifactItemIdentity;
236
247
  } | {
237
248
  type: "primer";
238
249
  text: string;
239
250
  primerKind: string;
251
+ item?: ArtifactItemIdentity;
240
252
  } | {
241
253
  type: "image";
242
254
  storageId: string;
243
255
  imageUrl?: string;
256
+ item?: ArtifactItemIdentity;
244
257
  } | {
245
258
  type: "session";
246
259
  sessionId: string;
247
260
  label?: string;
248
261
  port?: string;
262
+ item?: ArtifactItemIdentity;
249
263
  };
250
264
  export interface WorkflowRunOutput {
251
265
  nodeId: string;
252
266
  botSlug?: string;
253
- type: "text" | "image" | "video" | "audio" | "frames" | "storyboard";
267
+ type: "text" | "image" | "video" | "audio" | "document" | "frames" | "storyboard";
254
268
  label: string;
255
269
  text?: string;
256
270
  imageUrl?: string;
@@ -265,10 +279,26 @@ export interface WorkflowRunOutput {
265
279
  imageUrl?: string;
266
280
  }>;
267
281
  storyboardJson?: string;
282
+ documentUrl?: string;
283
+ filename?: string;
284
+ mimeType?: string;
285
+ }
286
+ export type WorkflowOutputSlotType = "text" | "structured" | "asset" | "collection";
287
+ export interface WorkflowRunDelivery {
288
+ key: string;
289
+ label: string;
290
+ type: WorkflowOutputSlotType;
291
+ description?: string;
292
+ order: number;
293
+ nodeId: string;
294
+ status: "delivered" | "unfulfilled";
295
+ error?: string;
296
+ artifacts: WorkflowRunOutput[];
268
297
  }
269
298
  export interface WorkflowRunNode {
270
299
  nodeId: string;
271
300
  kind: string;
301
+ botSlug?: string;
272
302
  status: WorkflowNodeRunStatus;
273
303
  error?: string;
274
304
  startedAt?: number;
@@ -287,7 +317,7 @@ export interface WorkflowRunSession {
287
317
  title: string;
288
318
  botSlug: string;
289
319
  }
290
- export type WorkflowPauseReason = "taste" | "repair" | "slots" | "call";
320
+ export type WorkflowPauseReason = "taste" | "repair" | "slots" | "call" | "checkpoint";
291
321
  export interface WorkflowPendingSlot {
292
322
  id: string;
293
323
  label?: string;
@@ -312,6 +342,7 @@ export interface WorkflowRun {
312
342
  isTerminal: boolean;
313
343
  nodes: WorkflowRunNode[];
314
344
  outputs?: WorkflowRunOutput[];
345
+ deliveries?: WorkflowRunDelivery[];
315
346
  sessions?: WorkflowRunSession[];
316
347
  pauseReason?: WorkflowPauseReason;
317
348
  pausedNodeId?: string;
@@ -327,10 +358,22 @@ export interface WorkflowRunDeps {
327
358
  readFile: (path: string) => string;
328
359
  writeFile: (path: string, text: string) => void;
329
360
  poll: (opts: PollOptions) => Promise<PollResult>;
361
+ mkdirp?: (dir: string) => void;
362
+ downloadToFile?: (url: string, path: string) => Promise<void>;
330
363
  postDashboard?: (path: string, body: unknown, opts?: {
331
364
  timeoutMs?: number;
332
365
  }) => Promise<ApiResponse<unknown>>;
333
366
  dashboardUrl?: string;
367
+ statFile?: (filePath: string) => {
368
+ size: number;
369
+ } | null;
370
+ readFileBytes?: (filePath: string) => Uint8Array;
371
+ uploadBytes?: (uploadUrl: string, contentType: string, bytes: Uint8Array) => Promise<{
372
+ ok: boolean;
373
+ status: number;
374
+ storageId?: string;
375
+ body?: string;
376
+ }>;
334
377
  }
335
378
  export interface FlowResult {
336
379
  code: number;
@@ -339,13 +382,22 @@ export interface FlowResult {
339
382
  interface RunFlowOptions {
340
383
  inputs: Record<string, string>;
341
384
  terminalNodeIds?: string[];
385
+ fill?: string;
342
386
  wait: boolean;
343
387
  json: boolean;
388
+ out?: string;
344
389
  onProgressLine?: (line: string) => void;
345
390
  }
346
391
  export declare function formatPauseNotice(pauseReason: WorkflowPauseReason | undefined, runId: string, dashboardUrl: string): string[];
392
+ export declare function parseRawInputFlags(args: string[]): Record<string, string>;
347
393
  export declare function parseInputFlags(args: string[], readFile?: (path: string) => string): Record<string, string>;
394
+ export declare const ASSET_UPLOAD_POLICY: Record<WorkflowMediaType, {
395
+ mimeByExtension: Record<string, string>;
396
+ maxBytes: number;
397
+ accepts: string;
398
+ }>;
348
399
  export declare function parseTerminalFlags(args: string[]): string[];
400
+ export declare function parseFillFlag(args: string[]): string | undefined;
349
401
  export declare function formatWorkflowList(workflows: WorkflowListItem[]): string;
350
402
  export declare function formatRecentRuns(runs: WorkflowRunProjection[]): string;
351
403
  export declare function formatWorkflowVersions(versions: WorkflowVersion[]): string;
@@ -355,6 +407,12 @@ export declare function formatImportSummary(result: WorkflowImportResult, mode?:
355
407
  validate?: boolean;
356
408
  }): string;
357
409
  export declare function formatWorkflowRun(run: WorkflowRun): string;
410
+ export interface DeliverySaveResult {
411
+ lines: string[];
412
+ paths: string[];
413
+ }
414
+ export declare function workflowFilenameSlug(name: string): string;
415
+ export declare function saveDeliveries(run: WorkflowRun, dir: string, deps: WorkflowRunDeps): Promise<DeliverySaveResult>;
358
416
  export declare function formatDescribe(res: WorkflowDescribeResponse): string;
359
417
  export declare function formatBotsList(catalog: WorkflowCatalog, category?: string): string;
360
418
  export declare function formatBotDetail(bot: CatalogBot): string;
@@ -374,6 +432,7 @@ export declare function runFlow(workflowRef: string, opts: RunFlowOptions, deps:
374
432
  export declare function statusFlow(opts: {
375
433
  id?: string;
376
434
  json: boolean;
435
+ out?: string;
377
436
  }, deps: WorkflowRunDeps): Promise<FlowResult>;
378
437
  export declare function exportFlow(workflowRef: string, opts: {
379
438
  out?: string;
@@ -428,7 +487,7 @@ export interface WorkflowInboxRow {
428
487
  workflowName: string;
429
488
  pausedNodeId?: string;
430
489
  pausedNodeKind?: string;
431
- pauseReason?: "taste" | "repair" | "slots";
490
+ pauseReason?: "taste" | "repair" | "slots" | "checkpoint";
432
491
  counts?: WorkflowCounts;
433
492
  createdAt: number | string;
434
493
  queuedAt?: number | string;
@@ -448,28 +507,35 @@ export declare function parkBadge(pauseReason: string | undefined): string;
448
507
  export declare function invocationBadge(row: WorkflowInboxRow): string;
449
508
  export declare function formatInbox(rows: WorkflowInboxRow[], now?: number): string;
450
509
  export declare function inboxFlow(json: boolean, deps: WorkflowRunDeps): Promise<FlowResult>;
451
- export declare function gateShowFlow(runId: string, opts: {
510
+ export declare function checkpointShowFlow(runId: string, opts: {
452
511
  json: boolean;
453
512
  }, deps: WorkflowRunDeps): Promise<FlowResult>;
454
- export declare function gatePickFlow(runId: string, numbers: number[], opts: {
513
+ export declare function parseRejectItems(raw: string | undefined): {
514
+ ok: true;
515
+ items: number[];
516
+ } | {
517
+ ok: false;
518
+ message: string;
519
+ };
520
+ export declare function checkpointApproveFlow(runId: string, opts: {
521
+ wait: boolean;
455
522
  json: boolean;
523
+ onProgressLine?: (line: string) => void;
524
+ reject?: string;
456
525
  }, deps: WorkflowRunDeps): Promise<FlowResult>;
457
- export declare function gateEditFlow(runId: string, n: number, sources: {
526
+ export declare function checkpointEditFlow(runId: string, n: number, sources: {
458
527
  text?: string;
459
528
  file?: string;
460
529
  stdin?: string;
461
530
  }, opts: {
462
531
  json: boolean;
463
532
  }, deps: WorkflowRunDeps): Promise<FlowResult>;
464
- export declare function gatePushFlow(runId: string, message: string, opts: {
465
- json: boolean;
466
- }, deps: WorkflowRunDeps): Promise<FlowResult>;
467
- export declare function gateApproveFlow(runId: string, opts: {
533
+ export declare function checkpointRetryFlow(runId: string, opts: {
468
534
  wait: boolean;
469
535
  json: boolean;
470
536
  onProgressLine?: (line: string) => void;
471
537
  }, deps: WorkflowRunDeps): Promise<FlowResult>;
472
- export declare function gateRejectFlow(runId: string, opts: {
538
+ export declare function checkpointCancelFlow(runId: string, opts: {
473
539
  reason?: string;
474
540
  json: boolean;
475
541
  }, deps: WorkflowRunDeps): Promise<FlowResult>;