@eigenpal/cli 0.6.17 → 0.7.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/dist/cli.js CHANGED
@@ -17155,6 +17155,7 @@ var init_common = __esm(() => {
17155
17155
  AGENT_EXPERIMENT: "aexp",
17156
17156
  AGENT_EMAIL_ALIAS: "aea",
17157
17157
  AGENT_EMAIL_INVOCATION: "aei",
17158
+ AUTOMATION_TRIGGER: "atr",
17158
17159
  SANDBOX_WS_TOKEN: "sws"
17159
17160
  };
17160
17161
  TimestampSchema = exports_external.union([exports_external.date(), exports_external.string().datetime()]).transform((val) => {
@@ -19807,6 +19808,63 @@ var init_execution_row = __esm(() => {
19807
19808
  ];
19808
19809
  });
19809
19810
 
19811
+ // ../types/src/run-expand.ts
19812
+ function isRunExpandSection(token) {
19813
+ return RUN_EXPAND_SECTION_SET.has(token);
19814
+ }
19815
+ function parseRunExpand(raw) {
19816
+ const sections = new Set;
19817
+ const invalid = [];
19818
+ for (const part of (raw ?? "").split(",")) {
19819
+ const token = part.trim();
19820
+ if (!token)
19821
+ continue;
19822
+ if (isRunExpandSection(token)) {
19823
+ sections.add(token);
19824
+ } else {
19825
+ invalid.push(token);
19826
+ }
19827
+ }
19828
+ return { sections, invalid };
19829
+ }
19830
+ function runIncludeErrorMessage(include) {
19831
+ const hint = LEGACY_RUN_INCLUDE_MIGRATION[include];
19832
+ return hint ? `Legacy \`include=${include}\` is removed: ${hint}.` : null;
19833
+ }
19834
+ function runExpandErrorMessage(invalid) {
19835
+ const hints = invalid.map((token) => {
19836
+ const hint = LEGACY_RUN_EXPAND_MIGRATION[token];
19837
+ return hint ? `\`${token}\`: ${hint}` : null;
19838
+ }).filter((line) => line !== null);
19839
+ const base = `Unknown expand section(s): ${invalid.join(", ")}. Supported: ${RUN_EXPAND_SECTIONS.join(", ")}.`;
19840
+ return hints.length > 0 ? `${base} ${hints.join("; ")}.` : base;
19841
+ }
19842
+ var RUN_EXPAND_SECTIONS, RUN_EXPAND_SECTION_SET, RUN_DETAIL_EXPAND_PRESET, LEGACY_RUN_EXPAND_MIGRATION, LEGACY_RUN_INCLUDE_MIGRATION;
19843
+ var init_run_expand = __esm(() => {
19844
+ RUN_EXPAND_SECTIONS = ["input", "usage", "execution", "debug"];
19845
+ RUN_EXPAND_SECTION_SET = new Set(RUN_EXPAND_SECTIONS);
19846
+ RUN_DETAIL_EXPAND_PRESET = RUN_EXPAND_SECTIONS.join(",");
19847
+ LEGACY_RUN_EXPAND_MIGRATION = {
19848
+ output: "`output` is not expandable; completed detail responses include top-level `output`",
19849
+ lineage: "use `expand=execution` — batch, retry, and annotation live on `execution`",
19850
+ cost: "use `expand=usage`",
19851
+ input: "still `expand=input` — args now live at `input.args`",
19852
+ metadata: "use `expand=input` — metadata now lives at `input.metadata`",
19853
+ observability: "use `expand=debug`",
19854
+ feedback: "use `expand=execution` — feedback lives at `execution.feedback` (agent runs)",
19855
+ steps: "use `expand=execution` — steps live at `execution.steps` (workflow runs)",
19856
+ definition: "use `GET /api/v1/runs/{id}/definition`",
19857
+ files: "downloadable output refs live at top-level `files` on completed detail responses; `expand=execution` adds `execution.files.output` metadata for agent runs",
19858
+ expected: "use `expand=execution` — expected output lives at `execution.expected`",
19859
+ trace: "trace id: `expand=debug` (`debug.traceId`); trace files: `GET /api/v1/runs/{id}/artifacts`",
19860
+ issues: "use `GET /api/v1/runs/{id}/artifacts` and look for `issues.md`",
19861
+ lockfile: "use `GET /api/v1/runs/{id}/artifacts` and look for `eigenpal.lock`"
19862
+ };
19863
+ LEGACY_RUN_INCLUDE_MIGRATION = {
19864
+ detail: "the grouped run detail is returned by default; use `expand=input,usage,execution,debug` for optional sections"
19865
+ };
19866
+ });
19867
+
19810
19868
  // ../types/src/llm-determinism.ts
19811
19869
  var DETERMINISTIC_TEMPERATURE = 0;
19812
19870
 
@@ -65480,7 +65538,7 @@ function compareOutput(expectedData, actualData, fileFields, resultFileNames, ex
65480
65538
  mismatches.push({
65481
65539
  path: `output/${g}`,
65482
65540
  expected: "(golden file)",
65483
- actual: "(no matching file in result/)"
65541
+ actual: "(no matching file in output/)"
65484
65542
  });
65485
65543
  }
65486
65544
  }
@@ -65990,7 +66048,7 @@ function formatRunTarget(target) {
65990
66048
  return version2 ? `${pathTarget}@${version2}` : pathTarget;
65991
66049
  }
65992
66050
  function runTargetToPathParts(target) {
65993
- const normalized = parseRunTarget(target);
66051
+ const normalized = isNormalizedRunTarget(target) ? target : parseRunTarget(target);
65994
66052
  if (normalized.type === "agent") {
65995
66053
  return {
65996
66054
  pathTarget: normalized.packageName,
@@ -66003,9 +66061,21 @@ function runTargetToPathParts(target) {
66003
66061
  };
66004
66062
  }
66005
66063
  function runTargetApiPath(target) {
66006
- const { pathTarget, version: version2 } = runTargetToPathParts(target);
66064
+ const { version: version2 } = runTargetToPathParts(target);
66007
66065
  const query = version2 ? `?${new URLSearchParams({ version: version2 }).toString()}` : "";
66008
- return `/api/v1/run/${encodeURIComponent(pathTarget)}${query}`;
66066
+ return `/api/v1/runs${query}`;
66067
+ }
66068
+ function runStartJsonBody(target, input = {}) {
66069
+ const normalized = typeof target === "string" ? parseRunTarget(target) : isNormalizedRunTarget(target) ? target : parseRunTarget(target);
66070
+ const { pathTarget } = runTargetToPathParts(normalized);
66071
+ return { target: pathTarget, input };
66072
+ }
66073
+ function runStartMultipartTarget(target) {
66074
+ const normalized = typeof target === "string" ? parseRunTarget(target) : isNormalizedRunTarget(target) ? target : parseRunTarget(target);
66075
+ return runTargetToPathParts(normalized).pathTarget;
66076
+ }
66077
+ function isNormalizedRunTarget(target) {
66078
+ return typeof target === "object" && target !== null && "type" in target && (("idOrSlug" in target) || ("packageName" in target));
66009
66079
  }
66010
66080
  function pathToDottedPackageName(path) {
66011
66081
  const parsed = SourcePackagePathSchema.parse(path);
@@ -66214,6 +66284,54 @@ var init_grammar = __esm(() => {
66214
66284
  RunTargetSchema = exports_external.union([RunTargetStringSchema, RunTargetObjectSchema]);
66215
66285
  });
66216
66286
 
66287
+ // ../types/src/git-source/rerun-version.ts
66288
+ function parseWorkflowRerunVersion(raw) {
66289
+ const value = raw?.trim() || "latest";
66290
+ if (value === "latest")
66291
+ return { ok: true, parsed: { kind: "latest" } };
66292
+ if (value === RERUN_ORIGINAL_VERSION)
66293
+ return { ok: true, parsed: { kind: "original" } };
66294
+ const result = WorkflowRunVersionRefSchema.safeParse(value);
66295
+ if (!result.success) {
66296
+ return {
66297
+ ok: false,
66298
+ message: "Use latest, original, an exact X.Y.Z version, or a workflow version/history id (wfv_*, version_*, wfh_*)."
66299
+ };
66300
+ }
66301
+ return { ok: true, parsed: { kind: "explicit", value: result.data } };
66302
+ }
66303
+ function parseAgentRerunVersion(raw) {
66304
+ const value = raw?.trim() || "latest";
66305
+ if (value === "latest")
66306
+ return { ok: true, parsed: { kind: "latest" } };
66307
+ if (value === RERUN_ORIGINAL_VERSION)
66308
+ return { ok: true, parsed: { kind: "original" } };
66309
+ const result = SourceVersionRefSchema.safeParse(value);
66310
+ if (!result.success) {
66311
+ return {
66312
+ ok: false,
66313
+ message: "Use latest, original, main, X.Y.Z, X.Y.x, X.x, or a 40-character commit SHA."
66314
+ };
66315
+ }
66316
+ return { ok: true, parsed: { kind: "explicit", value: result.data } };
66317
+ }
66318
+ function resolveAgentOriginalSourceRef(provenance) {
66319
+ if (provenance.resolvedCommitSha && SOURCE_COMMIT_SHA_PATTERN.test(provenance.resolvedCommitSha)) {
66320
+ return provenance.resolvedCommitSha;
66321
+ }
66322
+ const candidate = provenance.resolvedGitRef ?? provenance.requestedSourceRef;
66323
+ if (candidate) {
66324
+ const parsed = SourceVersionRefSchema.safeParse(candidate);
66325
+ if (parsed.success)
66326
+ return parsed.data;
66327
+ }
66328
+ return "latest";
66329
+ }
66330
+ var RERUN_ORIGINAL_VERSION = "original";
66331
+ var init_rerun_version = __esm(() => {
66332
+ init_grammar();
66333
+ });
66334
+
66217
66335
  // ../types/src/git-source/lockfile.ts
66218
66336
  import { createHash } from "node:crypto";
66219
66337
  function parseSourcePackageRef(input) {
@@ -66578,11 +66696,86 @@ var init_secrets = __esm(() => {
66578
66696
  // ../types/src/git-source/index.ts
66579
66697
  var init_git_source = __esm(() => {
66580
66698
  init_grammar();
66699
+ init_rerun_version();
66581
66700
  init_lockfile();
66582
66701
  init_manifests();
66583
66702
  init_secrets();
66584
66703
  });
66585
66704
 
66705
+ // ../types/src/automation/triggers.ts
66706
+ function workflowMethodEnabled(methods, type) {
66707
+ return methods.some((method) => method.type === type);
66708
+ }
66709
+ function triggersFromWorkflowDefinition(definition) {
66710
+ if (definition.kind === "block")
66711
+ return [];
66712
+ const methods = getTriggerMethods(definition);
66713
+ return [
66714
+ { type: "api", enabled: workflowMethodEnabled(methods, "api") },
66715
+ { type: "manual", enabled: workflowMethodEnabled(methods, "manual") },
66716
+ { type: "email", enabled: workflowMethodEnabled(methods, "email") },
66717
+ { type: "cron", enabled: false }
66718
+ ];
66719
+ }
66720
+ function triggersFromGitManifest(triggers) {
66721
+ const emailEnabled = triggers?.email?.enabled ?? (triggers?.email?.aliases?.length ?? 0) > 0;
66722
+ return [
66723
+ { type: "api", enabled: triggers?.api ?? true },
66724
+ { type: "email", enabled: emailEnabled },
66725
+ { type: "manual", enabled: true },
66726
+ { type: "cron", enabled: false }
66727
+ ];
66728
+ }
66729
+ function isAgentEmailExplicitlyDisabled(config2) {
66730
+ if (!config2 || typeof config2 !== "object" || Array.isArray(config2))
66731
+ return false;
66732
+ const triggers = config2.triggers;
66733
+ if (!triggers || typeof triggers !== "object" || Array.isArray(triggers))
66734
+ return false;
66735
+ const email3 = triggers.email;
66736
+ if (!email3 || typeof email3 !== "object" || Array.isArray(email3))
66737
+ return false;
66738
+ if (!("enabled" in email3))
66739
+ return false;
66740
+ return email3.enabled === false;
66741
+ }
66742
+ function triggersFromAgentConfig(input) {
66743
+ const triggers = workflowTriggerConfigSchema.parse(input.config && typeof input.config === "object" && !Array.isArray(input.config) ? input.config.triggers : undefined);
66744
+ const emailEnabled = input.hasActiveEmailAliases && !isAgentEmailExplicitlyDisabled(input.config);
66745
+ return [
66746
+ { type: "api", enabled: triggers.api.enabled },
66747
+ {
66748
+ type: "email",
66749
+ enabled: emailEnabled
66750
+ },
66751
+ { type: "manual", enabled: true },
66752
+ { type: "cron", enabled: false }
66753
+ ];
66754
+ }
66755
+ function isAutomationTriggerEnabled(rows, type) {
66756
+ return rows.find((row) => row.type === type)?.enabled ?? false;
66757
+ }
66758
+ var AUTOMATION_TRIGGER_TYPES;
66759
+ var init_triggers = __esm(() => {
66760
+ init_email_trigger();
66761
+ init_workflow();
66762
+ AUTOMATION_TRIGGER_TYPES = ["api", "email", "manual", "cron"];
66763
+ });
66764
+
66765
+ // ../types/src/api/display-path.ts
66766
+ function displayApiPath(path) {
66767
+ return path.replace(/\{([^{}/]+)\}/g, ":$1");
66768
+ }
66769
+ function displayApiPathsInText(text) {
66770
+ let result = text;
66771
+ let prev;
66772
+ do {
66773
+ prev = result;
66774
+ result = result.replace(/(\/api\/v1\/[^\s`'"({]*)\{([^{}/]+)\}/g, "$1:$2");
66775
+ } while (result !== prev);
66776
+ return result;
66777
+ }
66778
+
66586
66779
  // ../types/src/storage/paths.ts
66587
66780
  function seg(name, value) {
66588
66781
  if (!value || !SEGMENT_RX.test(value)) {
@@ -66880,6 +67073,9 @@ __export(exports_src, {
66880
67073
  validateOutput: () => validateOutput,
66881
67074
  validateInput: () => validateInput,
66882
67075
  validateConfig: () => validateConfig,
67076
+ triggersFromWorkflowDefinition: () => triggersFromWorkflowDefinition,
67077
+ triggersFromGitManifest: () => triggersFromGitManifest,
67078
+ triggersFromAgentConfig: () => triggersFromAgentConfig,
66883
67079
  toJsonSchema: () => toJsonSchema,
66884
67080
  suppressRequiredMissingErrorsForSchemaFileFields: () => suppressRequiredMissingErrorsForSchemaFileFields,
66885
67081
  suggestWorkflowName: () => suggestWorkflowName,
@@ -66889,22 +67085,30 @@ __export(exports_src, {
66889
67085
  schemaFileUploadMatchesField: () => schemaFileUploadMatchesField,
66890
67086
  runTargetToPathParts: () => runTargetToPathParts,
66891
67087
  runTargetApiPath: () => runTargetApiPath,
67088
+ runStartMultipartTarget: () => runStartMultipartTarget,
67089
+ runStartJsonBody: () => runStartJsonBody,
66892
67090
  runOutputKey: () => runOutputKey,
66893
67091
  runInputKey: () => runInputKey,
67092
+ runIncludeErrorMessage: () => runIncludeErrorMessage,
67093
+ runExpandErrorMessage: () => runExpandErrorMessage,
66894
67094
  rootS3Path: () => rootS3Path,
66895
67095
  resolveEffectiveMimeType: () => resolveEffectiveMimeType,
67096
+ resolveAgentOriginalSourceRef: () => resolveAgentOriginalSourceRef,
66896
67097
  requiresSpecializedParser: () => requiresSpecializedParser,
66897
67098
  publicExecutionFailure: () => publicExecutionFailure,
66898
67099
  projectAgentInputFiles: () => projectAgentInputFiles,
66899
67100
  pathToDottedPackageName: () => pathToDottedPackageName,
67101
+ parseWorkflowRerunVersion: () => parseWorkflowRerunVersion,
66900
67102
  parseStepType: () => parseStepType,
66901
67103
  parseSourcePackageRef: () => parseSourcePackageRef,
66902
67104
  parseRunTarget: () => parseRunTarget,
67105
+ parseRunExpand: () => parseRunExpand,
66903
67106
  parseReleaseTag: () => parseReleaseTag,
66904
67107
  parseInputSchemaJson: () => parseInputSchemaJson,
66905
67108
  parseFileKey: () => parseFileKey,
66906
67109
  parseFailureEnvelope: () => parseFailureEnvelope,
66907
67110
  parseAutomationTarget: () => parseAutomationTarget,
67111
+ parseAgentRerunVersion: () => parseAgentRerunVersion,
66908
67112
  noopTracingContext: () => noopTracingContext,
66909
67113
  mapOCRAttributes: () => mapOCRAttributes,
66910
67114
  mapLLMAttributes: () => mapLLMAttributes,
@@ -66917,11 +67121,14 @@ __export(exports_src, {
66917
67121
  isTerminalExecutionStatus: () => isTerminalExecutionStatus,
66918
67122
  isStepCategory: () => isStepCategory,
66919
67123
  isSchemaFile: () => isSchemaFile,
67124
+ isRunExpandSection: () => isRunExpandSection,
66920
67125
  isOutputSchemaUnknown: () => isOutputSchemaUnknown,
66921
67126
  isNonSuccessTerminalExecutionStatus: () => isNonSuccessTerminalExecutionStatus,
66922
67127
  isLocalAgentResourcePath: () => isLocalAgentResourcePath,
66923
67128
  isFilePathDescriptor: () => isFilePathDescriptor,
66924
67129
  isFileOutput: () => isFileOutput,
67130
+ isAutomationTriggerEnabled: () => isAutomationTriggerEnabled,
67131
+ isAgentEmailExplicitlyDisabled: () => isAgentEmailExplicitlyDisabled,
66925
67132
  hasTriggerMethod: () => hasTriggerMethod,
66926
67133
  goldenFileSatisfiedInResult: () => goldenFileSatisfiedInResult,
66927
67134
  getTriggerMethods: () => getTriggerMethods,
@@ -66956,6 +67163,8 @@ __export(exports_src, {
66956
67163
  errorHintFor: () => errorHintFor,
66957
67164
  eigenpalAjv: () => eigenpalAjv,
66958
67165
  dottedPackageNameToPath: () => dottedPackageNameToPath,
67166
+ displayApiPathsInText: () => displayApiPathsInText,
67167
+ displayApiPath: () => displayApiPath,
66959
67168
  defaultScriptFunction: () => defaultScriptFunction,
66960
67169
  defaultScoreFunction: () => defaultScoreFunction,
66961
67170
  convertTsTypeToJsonSchema: () => convertTsTypeToJsonSchema,
@@ -67074,7 +67283,10 @@ __export(exports_src, {
67074
67283
  RootSourceManifestSchema: () => RootSourceManifestSchema,
67075
67284
  ReleaseTagSchema: () => ReleaseTagSchema,
67076
67285
  RUN_TARGET_SEGMENT_PATTERN: () => RUN_TARGET_SEGMENT_PATTERN,
67286
+ RUN_EXPAND_SECTIONS: () => RUN_EXPAND_SECTIONS,
67287
+ RUN_DETAIL_EXPAND_PRESET: () => RUN_DETAIL_EXPAND_PRESET,
67077
67288
  RUNS_TRIGGERED_BY_SYSTEM: () => RUNS_TRIGGERED_BY_SYSTEM,
67289
+ RERUN_ORIGINAL_VERSION: () => RERUN_ORIGINAL_VERSION,
67078
67290
  ProcessorPortSchema: () => ProcessorPortSchema,
67079
67291
  ProcessorExecutionContextSchema: () => ProcessorExecutionContextSchema,
67080
67292
  ProcessorDefinitionSchema: () => ProcessorDefinitionSchema,
@@ -67114,6 +67326,7 @@ __export(exports_src, {
67114
67326
  LayoutElementTypeSchema: () => LayoutElementTypeSchema,
67115
67327
  LayoutElementSchema: () => LayoutElementSchema,
67116
67328
  LLM_JUDGE_PROMPT_MIN_LENGTH: () => LLM_JUDGE_PROMPT_MIN_LENGTH,
67329
+ LEGACY_RUN_EXPAND_MIGRATION: () => LEGACY_RUN_EXPAND_MIGRATION,
67117
67330
  JudgeModeSchema: () => JudgeModeSchema,
67118
67331
  JsonSchemaSchema: () => JsonSchemaSchema,
67119
67332
  IfStepSchema: () => IfStepSchema,
@@ -67231,6 +67444,7 @@ __export(exports_src, {
67231
67444
  ActionInvokeWorkflowConfigSchema: () => ActionInvokeWorkflowConfigSchema,
67232
67445
  ActionHttpOutputSchema: () => ActionHttpOutputSchema,
67233
67446
  ActionHttpConfigSchema: () => ActionHttpConfigSchema,
67447
+ AUTOMATION_TRIGGER_TYPES: () => AUTOMATION_TRIGGER_TYPES,
67234
67448
  AIStepSchema: () => AIStepSchema,
67235
67449
  ACTION_TYPES: () => ACTION_TYPES
67236
67450
  });
@@ -67240,12 +67454,14 @@ var init_src = __esm(() => {
67240
67454
  init_parser2();
67241
67455
  init_otel();
67242
67456
  init_execution_row();
67457
+ init_run_expand();
67243
67458
  init_paths();
67244
67459
  init_s3_path_grammar();
67245
67460
  init_validation();
67246
67461
  init_workflow2();
67247
67462
  init_eval();
67248
67463
  init_git_source();
67464
+ init_triggers();
67249
67465
  init_typed_script();
67250
67466
  });
67251
67467
 
@@ -188883,7 +189099,7 @@ import { fileURLToPath as fileURLToPath8 } from "url";
188883
189099
  // package.json
188884
189100
  var package_default = {
188885
189101
  name: "@eigenpal/cli",
188886
- version: "0.6.17",
189102
+ version: "0.7.1",
188887
189103
  description: "Eigenpal CLI — author and run document workflows from your terminal. Agent-ready.",
188888
189104
  keywords: [
188889
189105
  "eigenpal",
@@ -191439,6 +191655,7 @@ function registerGitCommands(program2) {
191439
191655
  import path8 from "node:path";
191440
191656
 
191441
191657
  // src/commands/agents/shared.ts
191658
+ init_src();
191442
191659
  import { existsSync as existsSync6, promises as fs } from "node:fs";
191443
191660
  import path6 from "node:path";
191444
191661
  import { createInterface as createInterface2 } from "node:readline/promises";
@@ -191488,10 +191705,13 @@ async function writeBase64File(file2, contentBase64) {
191488
191705
  }
191489
191706
  async function pollRun(client, executionId, interval, maxWait) {
191490
191707
  const started = Date.now();
191708
+ const base = `/api/v1/runs/${encodeURIComponent(executionId)}`;
191491
191709
  for (;; ) {
191492
- const payload = await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}?include=detail`);
191493
- if (isTerminal(payload.run?.status))
191494
- return payload;
191710
+ const payload = await client.get(base);
191711
+ const status = payload.execution?.status;
191712
+ if (payload.finished || isTerminalExecutionStatus(status)) {
191713
+ return await client.get(`${base}?expand=usage,execution`);
191714
+ }
191495
191715
  if (Date.now() - started > maxWait * 1000) {
191496
191716
  process.stderr.write(`Timed out waiting for run ${executionId}
191497
191717
  `);
@@ -191517,14 +191737,16 @@ async function pollExperiment(client, agentId, batchId, interval, maxWait) {
191517
191737
  function renderRunPayload(payload, opts) {
191518
191738
  if (opts.json)
191519
191739
  return printJson(payload);
191520
- const run = payload.run;
191521
- if (!run)
191740
+ const run = payload;
191741
+ if (!run || run.id === undefined)
191522
191742
  return printJson(payload);
191523
- success2(`Run ${run.id} is ${run.status}`);
191743
+ const status = run.execution?.status ?? (run.finished === true ? "completed" : "running");
191744
+ success2(`Run ${run.id} is ${status}`);
191524
191745
  }
191525
191746
  function setExitCodeForFailedTerminalRun(payload) {
191526
- const status = payload.run?.status;
191527
- if (status === "failed" || status === "cancelled") {
191747
+ const run = payload;
191748
+ const status = run?.execution?.status;
191749
+ if (status === "failed" || status === "cancelled" || run?.finished === true && run?.error) {
191528
191750
  process.exitCode = 1;
191529
191751
  }
191530
191752
  }
@@ -191555,9 +191777,6 @@ function parseResultsFormat(value) {
191555
191777
  return value;
191556
191778
  throw new InvalidArgumentError("format must be csv or json");
191557
191779
  }
191558
- function isTerminal(status) {
191559
- return status === "completed" || status === "failed" || status === "cancelled";
191560
- }
191561
191780
  async function confirmTyped(id, actionName) {
191562
191781
  if (!process.stdin.isTTY || !process.stderr.isTTY)
191563
191782
  return false;
@@ -192305,6 +192524,7 @@ async function stopSession(sessionId, opts) {
192305
192524
  }
192306
192525
 
192307
192526
  // src/commands/runs.ts
192527
+ init_src();
192308
192528
  import { spawnSync as spawnSync4 } from "node:child_process";
192309
192529
  import { createHash as createHash3 } from "node:crypto";
192310
192530
  import { promises as fs6, readFileSync as readFileSync8 } from "node:fs";
@@ -192385,7 +192605,7 @@ async function resolveWorkflowId(client, idOrSlug) {
192385
192605
  }
192386
192606
 
192387
192607
  // src/lib/watch.ts
192388
- var TERMINAL_STATUSES = new Set(["completed", "failed", "cancelled", "rejected"]);
192608
+ init_src();
192389
192609
  var STATUS_BADGES = {
192390
192610
  pending: "[ ]",
192391
192611
  running: "[..]",
@@ -192491,7 +192711,7 @@ async function watchExecution(opts) {
192491
192711
  }
192492
192712
  lastFetched = current;
192493
192713
  render(renderFrame(current));
192494
- if (TERMINAL_STATUSES.has(current.status)) {
192714
+ if (isTerminalExecutionStatus(current.status)) {
192495
192715
  return { final: current, detached: false };
192496
192716
  }
192497
192717
  if (now() - start >= maxMs) {
@@ -192511,15 +192731,15 @@ function registerRunsCommands(program2) {
192511
192731
  });
192512
192732
  const listRunsCmd = addJsonFlag(withPagination(withBaseUrl(runs.command("list [source]")), 50)).alias("ls").description("List runs across workflows and agents, optionally scoped to one source.").option("--type <type>", "Filter by run type: workflow|agent").option("--status <status>", "Filter by run status").option("--source-ref <ref>", "Filter agent runs by source ref").option("--batch-id <id>", "Filter eval/experiment runs by batch id").option("--example-id <id>", "Filter eval runs by example id").option("--example-id-contains <text>", "Filter eval runs by example id substring").option("--from <date>", "Created at or after this ISO timestamp or relative date").option("--to <date>", "Created before this ISO timestamp or relative date").option("--created-after <date>", "Alias for --from").option("--created-before <date>", "Alias for --to").option("--completed-after <date>", "Completed at or after this ISO timestamp or relative date").option("--completed-before <date>", "Completed before this ISO timestamp or relative date").option("--compact", "Render compact run rows").option("--sort <field>", "Sort field; only createdAt is supported").option("--order <asc|desc>", "Sort order; only desc is supported");
192513
192733
  listRunsCmd.action(action(listRuns));
192514
- addJsonFlag(withBaseUrl(runs.command("get <run-id>"))).description("Get one run.").option("--step <name>", "For workflow runs, show only this step (or comma-separated list)").option("--include <parts>", "Comma-separated extra parts or workflow step fields: feedback,expected,files,trace,issues,input,output,error,duration,inputRef", "feedback").action(action(getRun));
192734
+ addJsonFlag(withBaseUrl(runs.command("get <run-id>"))).description("Get one run.").option("--step <name>", "For workflow runs, show only this step (or comma-separated list)").option("--expand <sections>", "Comma-separated server expand sections for GET /api/v1/runs/:id: input, usage, execution, debug. Use execution for status/schemaValid; completed runs include top-level output/files/error.").option("--include <parts>", "Comma-separated local workflow step projection fields (error, duration, inputRef, …). Legacy expand names are mapped when possible; use --expand for server sections.", "feedback").action(action(getRun));
192515
192735
  addJsonFlag(withBaseUrl(runs.command("compare <reference-run-id> <run-id>"))).description("Compare one run against another run. PDF/DOCX text comparison uses pdftotext/python3 and reports byte fallbacks.").option("--baseline", "Compare actual outputs from both runs instead of expected artifacts").option("--step <name>", "For workflow runs, restrict comparison to one step").option("--out <dir>", "Write comparison artifacts to this directory").option("--normalize-dates", "Normalize YYYYMMDD and YYYY-MM-DD tokens in filenames/text").option("--fail-on-diff", "Exit 1 when comparison status is fail").action(action(compareRun));
192516
- addJsonFlag(withBaseUrl(runs.command("rerun <run-id>"))).description("Create a new run from a previous run's stored input snapshot.").option("--source-ref <ref>", "Source ref for the new run: latest (default) or original. Workflow runs support only latest/original.").option("--wait", "Poll until the rerun reaches a terminal status").option("--interval <seconds>", "Polling interval in seconds", intArg, 2).option("--max-wait <seconds>", "Maximum wait before exiting 2", intArg, 1800).action(action(rerunRun));
192517
- const artifacts = runs.command("artifacts").description("Inspect agent run artifacts.").action(() => {
192736
+ addJsonFlag(withBaseUrl(runs.command("rerun <run-id>"))).description("Create a new run from a previous run's stored input snapshot.").option("--version <version>", "Version/source ref for the new run: latest (default), original, or an explicit ref (same grammar as eigenpal run)").option("--source-ref <ref>", "Alias for --version").option("--wait", "Poll until the rerun reaches a terminal status").option("--interval <seconds>", "Polling interval in seconds", intArg, 2).option("--max-wait <seconds>", "Maximum wait before exiting 2", intArg, 1800).action(action(rerunRun));
192737
+ const artifacts = runs.command("artifacts").description("Inspect workflow and agent run artifacts.").action(() => {
192518
192738
  process.stderr.write("`eigenpal runs artifacts` requires a subcommand. Run `eigenpal runs artifacts --help`.\n");
192519
192739
  process.exit(2);
192520
192740
  });
192521
- addJsonFlag(withBaseUrl(artifacts.command("list <run-id>"))).description("List available agent run artifacts without downloading them.").action(action(listRunArtifacts));
192522
- withBaseUrl(artifacts.command("fetch <run-id>")).description("Download agent run artifacts by canonical artifact path.").option("--out <dir>", "Output directory").option("--include <parts>", "Comma-separated parts: output,input,metadata,issues,trace,lockfile,expected,all", "all").option("--path <path>", "Fetch one exact artifact path from `artifacts list`; repeatable", collectRepeated, []).option("--json", "Output a JSON summary of written artifacts").action(action(fetchRunArtifacts));
192741
+ addJsonFlag(withBaseUrl(artifacts.command("list <run-id>"))).description("List available run artifacts without downloading them.").action(action(listRunArtifacts));
192742
+ withBaseUrl(artifacts.command("fetch <run-id>")).description("Download run artifacts by canonical artifact path.").option("--out <dir>", "Output directory").option("--include <parts>", "Comma-separated parts: output,input,metadata,issues,trace,lockfile,expected,all", "all").option("--path <path>", "Fetch one exact artifact path from `artifacts list`; repeatable", collectRepeated, []).option("--json", "Output a JSON summary of written artifacts").action(action(fetchRunArtifacts));
192523
192743
  withBaseUrl(runs.command("trace <run-id>")).description("Print raw trace.jsonl for a run, or write it with --out.").option("--out <file>", "Output file path").action(action(traceRun));
192524
192744
  registerRunFeedbackCommands(runs);
192525
192745
  registerRunExpectedCommands(runs);
@@ -192553,7 +192773,7 @@ async function runExample(agentId, opts) {
192553
192773
  exampleId: opts.example,
192554
192774
  ...opts.sourceRef ? { sourceRef: opts.sourceRef } : {}
192555
192775
  });
192556
- const runId = started.runs?.[0]?.runId;
192776
+ const runId = started.runs?.[0]?.id;
192557
192777
  if (opts.wait && runId) {
192558
192778
  const payload2 = await pollRun(client, runId, opts.interval, opts.maxWait);
192559
192779
  renderRunPayload(payload2, opts);
@@ -192561,7 +192781,7 @@ async function runExample(agentId, opts) {
192561
192781
  return;
192562
192782
  }
192563
192783
  const payload = {
192564
- runId,
192784
+ id: runId,
192565
192785
  exampleId: opts.example,
192566
192786
  batchId: started.batchId,
192567
192787
  status: "pending"
@@ -192570,39 +192790,96 @@ async function runExample(agentId, opts) {
192570
192790
  return printJson(payload);
192571
192791
  success2(`Run ${runId ?? ""} queued for example ${opts.example}`);
192572
192792
  }
192793
+ var SERVER_EXPAND_SECTIONS = new Set(RUN_EXPAND_SECTIONS);
192794
+ var LEGACY_INCLUDE_EXPAND_MAP = {
192795
+ output: null,
192796
+ cost: "usage",
192797
+ steps: "execution",
192798
+ files: "execution",
192799
+ feedback: "execution",
192800
+ expected: "execution",
192801
+ input: "input",
192802
+ metadata: "input",
192803
+ observability: "debug",
192804
+ trace: "debug",
192805
+ issues: null,
192806
+ lockfile: null
192807
+ };
192808
+ function splitCsv(raw) {
192809
+ if (!raw)
192810
+ return [];
192811
+ return raw.split(",").map((part) => part.trim()).filter(Boolean);
192812
+ }
192813
+ function collectExactServerExpandTokens(raw) {
192814
+ const valid = [];
192815
+ const invalid = [];
192816
+ for (const token of splitCsv(raw)) {
192817
+ if (SERVER_EXPAND_SECTIONS.has(token)) {
192818
+ valid.push(token);
192819
+ } else {
192820
+ invalid.push(token);
192821
+ }
192822
+ }
192823
+ if (invalid.length > 0) {
192824
+ throw new Error(runExpandErrorMessage(invalid));
192825
+ }
192826
+ return valid;
192827
+ }
192828
+ function collectIncludeExpandTokens(raw) {
192829
+ const sections = new Set;
192830
+ for (const token of splitCsv(raw)) {
192831
+ if (SERVER_EXPAND_SECTIONS.has(token))
192832
+ sections.add(token);
192833
+ else if (token in LEGACY_INCLUDE_EXPAND_MAP) {
192834
+ const mapped = LEGACY_INCLUDE_EXPAND_MAP[token];
192835
+ if (mapped)
192836
+ sections.add(mapped);
192837
+ }
192838
+ }
192839
+ return [...sections];
192840
+ }
192841
+ function serverExpandParam(args) {
192842
+ if (args.expand !== undefined) {
192843
+ const sections2 = new Set(collectExactServerExpandTokens(args.expand));
192844
+ for (const part of collectIncludeExpandTokens(args.include))
192845
+ sections2.add(part);
192846
+ return [...sections2].join(",");
192847
+ }
192848
+ const sections = new Set(["usage", "execution"]);
192849
+ for (const part of collectIncludeExpandTokens(args.include ?? "feedback"))
192850
+ sections.add(part);
192851
+ return [...sections].join(",");
192852
+ }
192853
+ function projectionIncludeSource(opts) {
192854
+ const parts = [opts.include, opts.expand].filter(Boolean);
192855
+ return parts.length > 0 ? parts.join(",") : undefined;
192856
+ }
192573
192857
  async function getRun(executionId, opts) {
192574
192858
  const client = buildClient(opts);
192575
- const include = opts.include ? `detail,${opts.include}` : "detail";
192576
- const payload = await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}`, {
192577
- include
192578
- });
192579
- const run = payload.run;
192580
- if (!run)
192581
- return renderRunPayload(payload, opts);
192859
+ const run = toLegacyRunView(await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}`, {
192860
+ expand: serverExpandParam({ expand: opts.expand, include: opts.include })
192861
+ }));
192582
192862
  if (opts.step && !isWorkflowRun(run)) {
192583
192863
  throw new Error("Agent runs do not have workflow steps. Use `eigenpal runs get <run-id> --json` to inspect the agent run payload.");
192584
192864
  }
192585
192865
  if (isWorkflowRun(run)) {
192586
192866
  const steps = filterWorkflowSteps(run.stepExecutions, opts.step);
192587
- const projectionIncludes = workflowStepProjectionIncludes(opts.include);
192867
+ const projectionIncludes = workflowStepProjectionIncludes(projectionIncludeSource(opts));
192588
192868
  if (opts.step) {
192589
- return printJson({
192590
- ...payload,
192591
- run: { ...run, stepExecutions: projectWorkflowSteps(steps, projectionIncludes) }
192592
- });
192869
+ return printJson({ ...run, stepExecutions: projectWorkflowSteps(steps, projectionIncludes) });
192593
192870
  }
192594
192871
  if (opts.json) {
192595
- return printJson(payload);
192872
+ return printJson(run);
192596
192873
  }
192597
192874
  console.log(renderFrame(toExecutionSnapshot(run, executionId)));
192598
192875
  process.stderr.write(`${ui.dim(`use --json for the full payload, then pipe to jq for field projection`)}
192599
192876
  `);
192600
192877
  return;
192601
192878
  }
192602
- renderRunPayload(payload, opts);
192879
+ renderRunPayload(run, opts);
192603
192880
  }
192604
192881
  function isWorkflowRun(run) {
192605
- return Array.isArray(run.stepExecutions);
192882
+ return run.type === "workflow";
192606
192883
  }
192607
192884
  function isAgentRun(run) {
192608
192885
  return run.type === "agent";
@@ -192610,15 +192887,100 @@ function isAgentRun(run) {
192610
192887
  function ensureAgentRun(run, feature) {
192611
192888
  if (isAgentRun(run))
192612
192889
  return;
192613
- throw new Error(`${feature} is only available for agent runs. Workflow runs do not have agent artifacts, feedback, or expected files.`);
192890
+ throw new Error(`${feature} is only available for agent runs. Workflow runs do not have agent feedback or expected files.`);
192891
+ }
192892
+ function objectOrNull(value) {
192893
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
192894
+ }
192895
+ function toLegacyRunView(run) {
192896
+ const timing = objectOrNull(run.timing);
192897
+ const source = objectOrNull(run.source);
192898
+ const sourceGit = objectOrNull(source?.git);
192899
+ const trigger = objectOrNull(run.trigger);
192900
+ const lineage = objectOrNull(run.lineage);
192901
+ const execution = objectOrNull(run.execution);
192902
+ const legacyRetry = objectOrNull(lineage?.retry);
192903
+ const retry = objectOrNull(execution?.retry) ?? legacyRetry;
192904
+ const nextRun = objectOrNull(retry?.nextRun);
192905
+ const evalInfo = objectOrNull(run.eval);
192906
+ const result = objectOrNull(run.result);
192907
+ const input = objectOrNull(run.input);
192908
+ const usage = objectOrNull(run.usage);
192909
+ const tokens = objectOrNull(usage?.tokens);
192910
+ const executionFiles = objectOrNull(execution?.files);
192911
+ const executionExpected = objectOrNull(execution?.expected);
192912
+ const debug = objectOrNull(run.debug);
192913
+ const hasGroupedShape = timing != null || source != null || result != null || run.output !== undefined;
192914
+ if (!hasGroupedShape)
192915
+ return run;
192916
+ const terminalOutput = run.output !== undefined ? run.output : result?.output;
192917
+ const terminalFiles = run.files !== undefined ? run.files : result?.files ?? executionFiles?.output;
192918
+ const terminalError = run.error !== undefined ? run.error : result?.error;
192919
+ const terminalSchemaValid = execution?.schemaValid !== undefined ? execution.schemaValid : result?.schemaValid;
192920
+ return {
192921
+ ...run,
192922
+ createdAt: timing?.createdAt,
192923
+ startedAt: timing?.startedAt,
192924
+ completedAt: timing?.completedAt,
192925
+ durationMs: timing?.durationMs,
192926
+ cancelRequestedAt: timing?.cancelRequestedAt,
192927
+ sourceId: source?.id,
192928
+ sourceName: source?.name,
192929
+ version: source?.version,
192930
+ versionId: source?.versionId,
192931
+ agentSlug: source?.slug,
192932
+ model: source?.model,
192933
+ requestedSourceRef: sourceGit?.requestedRef,
192934
+ resolvedGitRef: sourceGit?.resolvedRef,
192935
+ resolvedGitTag: sourceGit?.resolvedTag,
192936
+ resolvedCommitSha: sourceGit?.commitSha,
192937
+ triggerType: trigger?.type,
192938
+ triggeredBy: trigger?.by,
192939
+ emailTrigger: trigger?.email,
192940
+ batchId: execution?.batchId ?? lineage?.batchId,
192941
+ retryNumber: retry?.number,
192942
+ previousExecutionId: retry?.previousRunId,
192943
+ annotation: execution?.annotation ?? lineage?.annotation,
192944
+ exampleId: evalInfo?.exampleId ?? evalInfo?.example,
192945
+ exampleName: evalInfo?.example,
192946
+ status: execution?.status ?? run.status,
192947
+ finished: run.finished,
192948
+ evalScore: evalInfo?.score,
192949
+ evalPassed: evalInfo?.passed,
192950
+ output: terminalOutput,
192951
+ resultFiles: terminalFiles,
192952
+ schemaValid: terminalSchemaValid,
192953
+ error: terminalError,
192954
+ input: input?.args,
192955
+ inputFiles: input?.files,
192956
+ metadata: input?.metadata,
192957
+ cost: usage ? {
192958
+ totalInputTokens: tokens?.input ?? null,
192959
+ totalOutputTokens: tokens?.output ?? null,
192960
+ totalCacheReadTokens: tokens?.cacheRead ?? null,
192961
+ totalCacheWriteTokens: tokens?.cacheWrite ?? null,
192962
+ llmCallCount: usage.llmCallCount,
192963
+ ocrPagesProcessed: usage.ocrPagesProcessed,
192964
+ agentTurns: usage.agentTurns,
192965
+ creditsCharged: usage.creditsCharged,
192966
+ durationMs: usage.durationMs
192967
+ } : undefined,
192968
+ stepExecutions: execution?.steps,
192969
+ nextRetryId: nextRun?.id ?? objectOrNull(execution?.nextRetry)?.id,
192970
+ nextRetryStatus: nextRun?.status ?? objectOrNull(execution?.nextRetry)?.status,
192971
+ feedback: execution?.feedback,
192972
+ expected: executionExpected?.output,
192973
+ expectedFiles: executionExpected?.files,
192974
+ observability: debug?.observability,
192975
+ traceId: debug?.traceId
192976
+ };
192614
192977
  }
192615
192978
  async function getRunForCompatibilityCheck(client, executionId) {
192616
- const payload = await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}`, {
192617
- include: "detail"
192618
- });
192619
- if (!payload.run)
192979
+ const raw = await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}`);
192980
+ const run = raw ? toLegacyRunView(raw) : null;
192981
+ if (!run || run.id === undefined)
192620
192982
  throw new Error(`Run ${executionId} not found`);
192621
- return payload.run;
192983
+ return run;
192622
192984
  }
192623
192985
  async function ensureAgentRunById(client, executionId, feature) {
192624
192986
  ensureAgentRun(await getRunForCompatibilityCheck(client, executionId), feature);
@@ -192674,9 +193036,10 @@ function projectWorkflowStep(step, includes) {
192674
193036
  return out;
192675
193037
  }
192676
193038
  function toExecutionSnapshot(run, fallbackId) {
193039
+ const execution = objectOrNull(run.execution);
192677
193040
  return {
192678
193041
  id: String(run.id ?? run.executionId ?? fallbackId),
192679
- status: String(run.status ?? "unknown"),
193042
+ status: String(run.status ?? execution?.status ?? "unknown"),
192680
193043
  startedAt: typeof run.startedAt === "string" ? run.startedAt : null,
192681
193044
  completedAt: typeof run.completedAt === "string" ? run.completedAt : null,
192682
193045
  durationMs: typeof run.durationMs === "number" ? run.durationMs : null,
@@ -192712,9 +193075,15 @@ function previewOutput(value) {
192712
193075
  }
192713
193076
  async function rerunRun(executionId, opts) {
192714
193077
  const client = buildClient(opts);
192715
- const sourceRef = await resolveRerunSourceRef(client, executionId, opts.sourceRef);
192716
- let payload = await client.post(`/api/v1/runs/${encodeURIComponent(executionId)}/rerun`, sourceRef ? { sourceRef } : {});
192717
- const rerunId = String(payload.runId ?? payload.executionId ?? "");
193078
+ const params = new URLSearchParams;
193079
+ const version2 = (opts.sourceRef ?? opts.version)?.trim();
193080
+ if (version2 && version2 !== "latest") {
193081
+ params.set("version", version2);
193082
+ }
193083
+ const query = params.toString();
193084
+ const path12 = `/api/v1/runs/${encodeURIComponent(executionId)}/rerun${query ? `?${query}` : ""}`;
193085
+ let payload = await client.post(path12);
193086
+ const rerunId = String(payload.id ?? "");
192718
193087
  if (opts.wait && rerunId) {
192719
193088
  payload = await pollRun(client, rerunId, opts.interval, opts.maxWait);
192720
193089
  renderRunPayload(payload, opts);
@@ -192725,41 +193094,12 @@ async function rerunRun(executionId, opts) {
192725
193094
  return printJson(payload);
192726
193095
  success2(`Started rerun ${ui.bold(rerunId)} from ${executionId}`);
192727
193096
  }
192728
- async function resolveRerunSourceRef(client, executionId, requested) {
192729
- if (!requested)
192730
- return;
192731
- if (requested !== "original")
192732
- return requested;
192733
- const summary = await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}`);
192734
- const run = summary.run;
192735
- if (!run)
192736
- throw new Error(`Run ${executionId} not found`);
192737
- if (run.type === "workflow") {
192738
- return "original";
192739
- }
192740
- const detail = await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}`, {
192741
- include: "detail"
192742
- });
192743
- const agentRun = detail.run;
192744
- if (!agentRun)
192745
- throw new Error(`Run ${executionId} not found`);
192746
- const resolved = stringOrNull(agentRun.resolvedGitRef);
192747
- const requestedSource = stringOrNull(agentRun.requestedSourceRef);
192748
- const original = resolved ?? requestedSource;
192749
- if (!original) {
192750
- throw new Error(`Run ${executionId} does not have an original source ref to reuse`);
192751
- }
192752
- return original;
192753
- }
192754
193097
  async function fetchRunArtifacts(executionId, opts) {
192755
193098
  const client = buildClient(opts);
192756
- const payload = await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}`, {
192757
- include: "detail,expected,files,input,output,issues,trace,lockfile,metadata"
192758
- });
192759
- const run = payload.run;
192760
- if (!run)
192761
- throw new Error(`Run ${executionId} not found`);
192762
- ensureAgentRun(run, "Artifact download");
193099
+ const baseRun = toLegacyRunView(await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}`, {
193100
+ expand: "input,execution"
193101
+ }));
193102
+ const run = await attachListedArtifacts(client, executionId, baseRun);
192763
193103
  const out = path11.resolve(opts.out ?? path11.join(".eigenpal", "artifacts", "runs", executionId));
192764
193104
  await fs6.mkdir(out, { recursive: true });
192765
193105
  const written = [];
@@ -192794,14 +193134,7 @@ async function fetchRunArtifacts(executionId, opts) {
192794
193134
  }
192795
193135
  async function listRunArtifacts(executionId, opts) {
192796
193136
  const client = buildClient(opts);
192797
- const payload = await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}`, {
192798
- include: "detail,expected,files,input,output,issues,trace,lockfile,metadata"
192799
- });
192800
- const run = payload.run;
192801
- if (!run)
192802
- throw new Error(`Run ${executionId} not found`);
192803
- ensureAgentRun(run, "Artifact inventory");
192804
- const artifacts = runArtifactInventory(run);
193137
+ const artifacts = await listCanonicalRunArtifacts(client, executionId);
192805
193138
  if (opts.json)
192806
193139
  return printJson({ runId: executionId, artifacts });
192807
193140
  console.log(table(artifacts, [
@@ -192811,6 +193144,53 @@ async function listRunArtifacts(executionId, opts) {
192811
193144
  { key: "present", header: "PRESENT" }
192812
193145
  ]));
192813
193146
  }
193147
+ async function listCanonicalRunArtifacts(client, executionId) {
193148
+ const payload = await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}/artifacts`);
193149
+ return (payload.artifacts ?? []).map((artifact) => {
193150
+ const name = String(artifact.name ?? "");
193151
+ const artifactPath = stringOrNull(artifact.path);
193152
+ const kind = inferArtifactKind(artifactPath, name);
193153
+ return {
193154
+ kind,
193155
+ name,
193156
+ path: artifactPath ?? artifactPathForKind(kind, name),
193157
+ present: "yes"
193158
+ };
193159
+ });
193160
+ }
193161
+ async function attachListedArtifacts(client, executionId, run) {
193162
+ const artifacts = await listCanonicalRunArtifacts(client, executionId);
193163
+ return {
193164
+ ...run,
193165
+ resultFiles: [
193166
+ ...artifactEntries(run.resultFiles),
193167
+ ...artifacts.filter((a) => a.kind === "output").map(({ name, path: path12 }) => ({ name, path: path12 }))
193168
+ ],
193169
+ issueFiles: artifacts.filter((a) => a.kind === "issue").map(({ name }) => ({ name })),
193170
+ traceFiles: artifacts.filter((a) => a.kind === "trace").map(({ name }) => ({ name })),
193171
+ lockfileFiles: artifacts.filter((a) => a.kind === "lockfile").map(({ name }) => ({ name }))
193172
+ };
193173
+ }
193174
+ function artifactPathForKind(kind, name) {
193175
+ if (kind === "output")
193176
+ return `output/${name}`;
193177
+ return name;
193178
+ }
193179
+ function inferArtifactKind(artifactPath, name) {
193180
+ if (artifactPath?.startsWith("output/"))
193181
+ return "output";
193182
+ if (artifactPath?.startsWith("input/"))
193183
+ return "input";
193184
+ if (artifactPath === "issues.md" || name === "issues.md")
193185
+ return "issue";
193186
+ if (artifactPath === "trace.jsonl" || name === "trace.jsonl")
193187
+ return "trace";
193188
+ if (artifactPath === "eigenpal.lock" || name === "eigenpal.lock")
193189
+ return "lockfile";
193190
+ if (name)
193191
+ return "output";
193192
+ return "";
193193
+ }
192814
193194
  function artifactIncluded(artifact, include) {
192815
193195
  const parts = new Set(include.split(",").map((part) => part.trim()).filter(Boolean));
192816
193196
  if (parts.has("all"))
@@ -192836,7 +193216,7 @@ async function writeJsonRunArtifact(out, artifactPath, value) {
192836
193216
  }
192837
193217
  async function writeDownloadedRunArtifact(client, executionId, out, artifactPath, routePrefix) {
192838
193218
  const routePath = routePrefix === "files" ? artifactPath : artifactPath.slice("expected/".length);
192839
- const routeBase = routePrefix === "files" ? "artifact" : "expected";
193219
+ const routeBase = routePrefix === "files" ? "artifacts" : "expected";
192840
193220
  const response = await client.getStream(`/api/v1/runs/${encodeURIComponent(executionId)}/${routeBase}/${encodeRunArtifactPath(routePath)}`);
192841
193221
  const outPath = path11.join(out, artifactPath);
192842
193222
  await fs6.mkdir(path11.dirname(outPath), { recursive: true });
@@ -192848,9 +193228,9 @@ async function writeRunArtifact(client, executionId, out, artifactPath, run) {
192848
193228
  return artifactPath;
192849
193229
  }
192850
193230
  if (artifactPath === "input.json") {
192851
- if (run.inputJson == null)
193231
+ if (run.input == null)
192852
193232
  return null;
192853
- await writeJsonRunArtifact(out, artifactPath, run.inputJson);
193233
+ await writeJsonRunArtifact(out, artifactPath, run.input);
192854
193234
  return artifactPath;
192855
193235
  }
192856
193236
  if (artifactPath === "metadata.json") {
@@ -192887,18 +193267,13 @@ async function traceRun(executionId, opts) {
192887
193267
  }
192888
193268
  async function compareRun(referenceId, executionId, opts) {
192889
193269
  const client = buildClient(opts);
192890
- const targetPayload = await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}`, {
192891
- include: "detail,files,output"
192892
- });
192893
- const target = targetPayload.run;
192894
- if (!target)
192895
- throw new Error(`Run ${executionId} not found`);
193270
+ const target = toLegacyRunView(await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}`, {
193271
+ expand: "execution"
193272
+ }));
192896
193273
  const mode = opts.baseline ? "baseline" : "expected";
192897
- const reference = (await client.get(`/api/v1/runs/${encodeURIComponent(referenceId)}`, {
192898
- include: mode === "baseline" ? "detail,files,output" : "detail,expected"
192899
- })).run;
192900
- if (!reference)
192901
- throw new Error(`Reference run ${referenceId} not found`);
193274
+ const reference = toLegacyRunView(await client.get(`/api/v1/runs/${encodeURIComponent(referenceId)}`, {
193275
+ expand: "execution"
193276
+ }));
192902
193277
  if (isWorkflowRun(reference) && isWorkflowRun(target)) {
192903
193278
  const report2 = compareWorkflowRuns(referenceId, reference, executionId, target, opts.step);
192904
193279
  if (opts.json) {
@@ -193042,7 +193417,8 @@ async function listRuns(source, opts) {
193042
193417
  ...parsedAgentTarget?.sourceRef ? { sourceRef: parsedAgentTarget.sourceRef } : {}
193043
193418
  };
193044
193419
  const payload = await client.get("/api/v1/runs", params);
193045
- const rows = opts.compact ? payload.runs.map(compactRunRow) : payload.runs;
193420
+ const viewRuns = payload.runs.map(toLegacyRunView);
193421
+ const rows = opts.compact ? viewRuns.map(compactRunRow) : viewRuns;
193046
193422
  if (opts.json)
193047
193423
  return printJson({ ...payload, runs: rows });
193048
193424
  if (payload.scanLimited) {
@@ -193221,9 +193597,9 @@ async function watchRunCommand(executionId, opts) {
193221
193597
  const result = await watchExecution({
193222
193598
  fetch: async () => {
193223
193599
  const payload = await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}`, {
193224
- include: "detail"
193600
+ expand: "execution"
193225
193601
  });
193226
- return toExecutionSnapshot(payload.run ?? {}, executionId);
193602
+ return toExecutionSnapshot(toLegacyRunView(payload), executionId);
193227
193603
  },
193228
193604
  maxMs: opts.maxWait * 1000,
193229
193605
  transitionIntervalMs: opts.interval * 1000,
@@ -193247,7 +193623,7 @@ async function cancelRun(executionId, opts) {
193247
193623
  renderRunPayload(payload, opts);
193248
193624
  }
193249
193625
  async function downloadTraceText(client, executionId) {
193250
- const response = await client.getStream(`/api/v1/runs/${encodeURIComponent(executionId)}/artifact/trace.jsonl`);
193626
+ const response = await client.getStream(`/api/v1/runs/${encodeURIComponent(executionId)}/artifacts/trace.jsonl`);
193251
193627
  return Buffer.from(await response.arrayBuffer()).toString("utf-8");
193252
193628
  }
193253
193629
  function diffJson(expected, actual, basePath = "$") {
@@ -193292,6 +193668,19 @@ function diffJson(expected, actual, basePath = "$") {
193292
193668
  function fileNames(files) {
193293
193669
  return (Array.isArray(files) ? files : []).map((file2) => String(file2.name ?? "")).filter(Boolean).sort();
193294
193670
  }
193671
+ function artifactEntries(files) {
193672
+ return (Array.isArray(files) ? files : []).map((file2) => {
193673
+ const record2 = file2;
193674
+ const name = String(record2.name ?? "");
193675
+ if (!name)
193676
+ return null;
193677
+ const artifactPath = stringOrNull(record2.path);
193678
+ return {
193679
+ name,
193680
+ ...artifactPath ? { path: artifactPath } : {}
193681
+ };
193682
+ }).filter((entry) => entry !== null).sort((a, b2) => a.name.localeCompare(b2.name));
193683
+ }
193295
193684
  function stringOrNull(value) {
193296
193685
  return typeof value === "string" && value.length > 0 ? value : null;
193297
193686
  }
@@ -193299,7 +193688,7 @@ function runArtifactInventory(run) {
193299
193688
  const rows = [
193300
193689
  { kind: "metadata", name: "run.json", path: "run.json", present: "yes" }
193301
193690
  ];
193302
- if (run.inputJson != null) {
193691
+ if (run.input != null) {
193303
193692
  rows.push({ kind: "input", name: "input.json", path: "input.json", present: "yes" });
193304
193693
  }
193305
193694
  if (run.metadata != null) {
@@ -193311,8 +193700,13 @@ function runArtifactInventory(run) {
193311
193700
  for (const name of fileNames(run.inputFiles)) {
193312
193701
  rows.push({ kind: "input", name, path: `input/${name}`, present: "yes" });
193313
193702
  }
193314
- for (const name of fileNames(run.resultFiles).filter((name2) => name2 !== "issues.md" && name2 !== "trace.jsonl")) {
193315
- rows.push({ kind: "output", name, path: `output/${name}`, present: "yes" });
193703
+ for (const artifact of artifactEntries(run.resultFiles).filter((file2) => file2.name !== "issues.md" && file2.name !== "trace.jsonl")) {
193704
+ rows.push({
193705
+ kind: "output",
193706
+ name: artifact.name,
193707
+ path: artifact.path ?? `output/${artifact.name}`,
193708
+ present: "yes"
193709
+ });
193316
193710
  }
193317
193711
  for (const name of fileNames(run.expectedFiles)) {
193318
193712
  rows.push({ kind: "expected", name, path: `expected/${name}`, present: "yes" });
@@ -193326,7 +193720,10 @@ function runArtifactInventory(run) {
193326
193720
  for (const name of fileNames(run.lockfileFiles)) {
193327
193721
  rows.push({ kind: "lockfile", name, path: name, present: "yes" });
193328
193722
  }
193329
- return rows.sort((a, b2) => a.path.localeCompare(b2.path));
193723
+ const byPath = new Map;
193724
+ for (const row of rows)
193725
+ byPath.set(row.path, row);
193726
+ return [...byPath.values()].sort((a, b2) => a.path.localeCompare(b2.path));
193330
193727
  }
193331
193728
  function normalizeGeneratedTokens(value) {
193332
193729
  return value.replace(/\d{4}-\d{2}-\d{2}/g, "<date>").replace(/\d{8}/g, "<date>");
@@ -193390,7 +193787,7 @@ async function compareMatchedFileText(client, left, right, out, matched, normali
193390
193787
  function runFileUrl(side, name) {
193391
193788
  const runId = encodeURIComponent(side.runId);
193392
193789
  const filename = encodeURIComponent(name);
193393
- return side.kind === "expected" ? `/api/v1/runs/${runId}/expected/${filename}` : `/api/v1/runs/${runId}/artifact/output/${filename}`;
193790
+ return side.kind === "expected" ? `/api/v1/runs/${runId}/expected/${filename}` : `/api/v1/runs/${runId}/artifacts/${encodeRunArtifactPath(`output/${name}`)}`;
193394
193791
  }
193395
193792
  function encodeRunArtifactPath(artifactPath) {
193396
193793
  return artifactPath.split("/").map(encodeURIComponent).join("/");
@@ -194137,17 +194534,45 @@ function guessMimeType(filename) {
194137
194534
  }
194138
194535
 
194139
194536
  // src/commands/run-form-data.ts
194537
+ var RESERVED_FIELD_NAMES = new Set([
194538
+ "_json",
194539
+ "_metadata",
194540
+ "_overrides",
194541
+ "input",
194542
+ "target",
194543
+ "overrides",
194544
+ "metadata"
194545
+ ]);
194140
194546
  async function buildRunFormData(input) {
194141
194547
  const form = new FormData;
194142
- for (const spec of parseInputFileSpecs(input.inputFile)) {
194548
+ form.append("target", input.target);
194549
+ const inputObj = input.input ?? (input.inputJson ? JSON.parse(input.inputJson) : {});
194550
+ form.append("input", JSON.stringify(inputObj));
194551
+ if (input.overrides) {
194552
+ form.append("overrides", JSON.stringify(input.overrides));
194553
+ }
194554
+ if (input.metadata) {
194555
+ form.append("metadata", JSON.stringify(input.metadata));
194556
+ }
194557
+ for (const spec of parseInputFileSpecs(input.inputFile ?? [])) {
194143
194558
  const data = await fs7.readFile(spec.filePath);
194144
- const filename = path13.basename(spec.filePath);
194145
- const mimeType = guessMimeType(filename) || "application/octet-stream";
194146
- form.append(spec.fieldName, new Blob([data], { type: mimeType }), filename);
194559
+ appendFilePart(form, spec.fieldName, data, path13.basename(spec.filePath));
194560
+ }
194561
+ for (const file2 of input.files ?? []) {
194562
+ appendFilePart(form, file2.fieldName, file2.content, file2.filename, file2.mimeType);
194147
194563
  }
194148
- form.append("_json", JSON.stringify(input.inputJson ? JSON.parse(input.inputJson) : {}));
194149
194564
  return form;
194150
194565
  }
194566
+ function appendFilePart(form, fieldName, content, filename, mimeType) {
194567
+ assertValidFileFieldName(fieldName);
194568
+ const type = mimeType ?? guessMimeType(filename) ?? "application/octet-stream";
194569
+ form.append(`files.${fieldName}`, new Blob([content], { type }), filename);
194570
+ }
194571
+ function assertValidFileFieldName(fieldName) {
194572
+ if (RESERVED_FIELD_NAMES.has(fieldName) || fieldName.startsWith("files.")) {
194573
+ throw new Error(`file field "${fieldName}" is reserved`);
194574
+ }
194575
+ }
194151
194576
  function parseInputFileSpecs(inputFile) {
194152
194577
  const values = Array.isArray(inputFile) ? inputFile : [inputFile];
194153
194578
  return values.map((value) => {
@@ -194160,9 +194585,7 @@ function parseInputFileSpecs(inputFile) {
194160
194585
  if (!fieldName || !filePath) {
194161
194586
  throw new Error("--input-file must be <field=path> or a bare path");
194162
194587
  }
194163
- if (fieldName === "_json" || fieldName === "_metadata" || fieldName === "input") {
194164
- throw new Error(`--input-file field "${fieldName}" is reserved`);
194165
- }
194588
+ assertValidFileFieldName(fieldName);
194166
194589
  return { fieldName, filePath };
194167
194590
  });
194168
194591
  }
@@ -194247,6 +194670,18 @@ async function formatFileIfAvailable(filepath) {
194247
194670
  function isWorkflowResult2(value) {
194248
194671
  return value != null && typeof value === "object" && "files" in value && Array.isArray(value.files);
194249
194672
  }
194673
+ async function listResultArtifacts(client, executionId) {
194674
+ try {
194675
+ const payload = await client.get(`/api/v1/runs/${encodeURIComponent(executionId)}/artifacts`);
194676
+ return (payload.artifacts ?? []).filter((artifact) => typeof artifact.path === "string" && artifact.path.startsWith("output/") && typeof artifact.name === "string");
194677
+ } catch {
194678
+ return [];
194679
+ }
194680
+ }
194681
+ async function downloadRunArtifact(client, executionId, artifactPath) {
194682
+ const encodedPath = artifactPath.split("/").map(encodeURIComponent).join("/");
194683
+ return client.getStream(`/api/v1/runs/${encodeURIComponent(executionId)}/artifacts/${encodedPath}`);
194684
+ }
194250
194685
  function filenameFromContentDisposition(header) {
194251
194686
  if (!header)
194252
194687
  return null;
@@ -194270,8 +194705,34 @@ async function writeExecutionArtifacts(client, exampleDir, payload) {
194270
194705
  const filesDir = join7(executionsDir, "files");
194271
194706
  mkdirSync5(filesDir, { recursive: true });
194272
194707
  const generatedFiles = [];
194708
+ const resultArtifacts = await listResultArtifacts(client, payload.executionId);
194709
+ if (resultArtifacts.length > 0) {
194710
+ for (let i = 0;i < resultArtifacts.length; i++) {
194711
+ const artifact = resultArtifacts[i];
194712
+ const artifactPath = artifact.path;
194713
+ if (typeof artifactPath !== "string")
194714
+ continue;
194715
+ const name = typeof artifact.name === "string" ? artifact.name : `file-${i}.bin`;
194716
+ try {
194717
+ const res = await downloadRunArtifact(client, payload.executionId, artifactPath);
194718
+ const disposition = res.headers.get("Content-Disposition");
194719
+ const filename = filenameFromContentDisposition(disposition) ?? name;
194720
+ const safe = safeFilename(filename, `file-${i}${filename.includes(".") ? "" : ".bin"}`);
194721
+ const destPath = join7(filesDir, safe);
194722
+ const buf = Buffer.from(await res.arrayBuffer());
194723
+ writeFileSync7(destPath, buf);
194724
+ generatedFiles.push({
194725
+ fileId: artifact.fileId ?? artifactPath,
194726
+ stepName: artifact.stepName ?? "",
194727
+ filename: safe
194728
+ });
194729
+ } catch (err) {
194730
+ console.warn(` Warning: could not download artifact ${artifactPath}:`, err);
194731
+ }
194732
+ }
194733
+ }
194273
194734
  const result = payload.output;
194274
- if (isWorkflowResult2(result) && result.files.length > 0) {
194735
+ if (generatedFiles.length === 0 && isWorkflowResult2(result) && result.files.length > 0) {
194275
194736
  for (let i = 0;i < result.files.length; i++) {
194276
194737
  const entry = result.files[i];
194277
194738
  const fileId = entry?.fileId;
@@ -194461,17 +194922,42 @@ function createProgressLines(options8) {
194461
194922
  var POLL_INTERVAL_MS = 2000;
194462
194923
  var MAX_POLL_MS = 5 * 60 * 1000;
194463
194924
  var DEFAULT_CONCURRENCY = 3;
194925
+ function runTerminalOutput(run) {
194926
+ return run.output !== undefined ? run.output : run.result?.output;
194927
+ }
194928
+ function runTerminalError(run) {
194929
+ const error52 = run.error !== undefined ? run.error : run.result?.error;
194930
+ return error52 ?? undefined;
194931
+ }
194464
194932
  async function pollExecution(client, executionId) {
194465
194933
  const start = Date.now();
194466
194934
  while (Date.now() - start < MAX_POLL_MS) {
194467
- const payload = await client.get(`/api/v1/runs/${executionId}?include=detail`);
194468
- const res = "run" in payload && payload.run ? payload.run : payload;
194469
- if (["completed", "failed", "cancelled", "rejected"].includes(res.status))
194470
- return res;
194935
+ const run = await client.get(`/api/v1/runs/${executionId}`);
194936
+ const status = run.execution?.status ?? run.status;
194937
+ if (run.finished || isTerminalExecutionStatus(status)) {
194938
+ return {
194939
+ executionId: run.id,
194940
+ status: status ?? (run.error ? "failed" : "completed"),
194941
+ output: runTerminalOutput(run),
194942
+ error: runTerminalError(run)
194943
+ };
194944
+ }
194471
194945
  await new Promise((r5) => setTimeout(r5, POLL_INTERVAL_MS));
194472
194946
  }
194473
194947
  return { executionId, status: "timeout", error: "Execution timed out" };
194474
194948
  }
194949
+ function toExecutionArtifactPayload(run) {
194950
+ const status = run.execution?.status ?? run.status ?? "unknown";
194951
+ return {
194952
+ executionId: run.id,
194953
+ status,
194954
+ createdAt: run.timing?.createdAt ?? new Date().toISOString(),
194955
+ completedAt: run.timing?.completedAt ?? null,
194956
+ error: run.error !== undefined ? run.error : run.result?.error ?? null,
194957
+ output: runTerminalOutput(run),
194958
+ stepExecutions: run.execution?.steps ?? []
194959
+ };
194960
+ }
194475
194961
  async function runExec(client, dir, workflowIdOrSlug, exampleNames, options8 = {}) {
194476
194962
  const workflowId = await resolveWorkflowId(client, workflowIdOrSlug);
194477
194963
  const names = getExampleNames(dir, exampleNames.length ? exampleNames : undefined);
@@ -194517,21 +195003,26 @@ async function runExec(client, dir, workflowIdOrSlug, exampleNames, options8 = {
194517
195003
  progress.setRunning(index);
194518
195004
  else
194519
195005
  console.log(`${ui.dim("→")} ${name}`);
194520
- const form = new FormData;
194521
- form.append("_json", JSON.stringify(example.scalars));
194522
- if (example.overrides) {
194523
- form.append("_overrides", JSON.stringify(example.overrides));
194524
- }
194525
- for (const file2 of example.files) {
194526
- form.append(file2.argument, new Blob([file2.content], {
194527
- type: file2.mimeType ?? "application/octet-stream"
194528
- }), file2.filename);
194529
- }
195006
+ const form = await buildRunFormData({
195007
+ target: runStartMultipartTarget({
195008
+ type: "workflow",
195009
+ id: workflowId,
195010
+ version: options8.version
195011
+ }),
195012
+ input: example.scalars,
195013
+ overrides: example.overrides,
195014
+ files: example.files.map((file2) => ({
195015
+ fieldName: file2.argument,
195016
+ content: file2.content,
195017
+ filename: file2.filename,
195018
+ mimeType: file2.mimeType
195019
+ }))
195020
+ });
194530
195021
  const res = await client.postFormData(runTargetApiPath({ type: "workflow", id: workflowId, version: options8.version }), form);
194531
- if (typeof res?.runId !== "string") {
194532
- throw new Error("Run API did not return runId");
195022
+ if (typeof res?.id !== "string") {
195023
+ throw new Error("Run API did not return a run id");
194533
195024
  }
194534
- const executionId = res.runId;
195025
+ const executionId = res.id;
194535
195026
  process.stderr.write(` ${ui.dim(`→ ${name}: ${executionId}`)}
194536
195027
  `);
194537
195028
  const result = await pollExecution(client, executionId);
@@ -194541,9 +195032,8 @@ async function runExec(client, dir, workflowIdOrSlug, exampleNames, options8 = {
194541
195032
  else
194542
195033
  failed++;
194543
195034
  try {
194544
- const artifactPayload = await client.get(`/api/v1/runs/${executionId}?include=detail`);
194545
- const artifact = "run" in artifactPayload && artifactPayload.run ? artifactPayload.run : artifactPayload;
194546
- const artifactDir = await writeExecutionArtifacts(client, exampleDir, artifact);
195035
+ const run = await client.get(`/api/v1/runs/${executionId}?expand=execution`);
195036
+ const artifactDir = await writeExecutionArtifacts(client, exampleDir, toExecutionArtifactPayload(run));
194547
195037
  if (!interactive)
194548
195038
  console.log(ui.dim(` Artifacts: ${artifactDir}`));
194549
195039
  } catch (artErr) {
@@ -194617,12 +195107,18 @@ async function runTarget(target, opts) {
194617
195107
  const client = buildClient(opts);
194618
195108
  let payload;
194619
195109
  const runPath = runTargetApiPath(target);
195110
+ const pathTarget = runStartMultipartTarget(target);
194620
195111
  if (opts.inputFile && opts.inputFile.length > 0) {
194621
- payload = await client.postFormData(runPath, await buildRunFormData({ inputFile: opts.inputFile, inputJson: opts.inputJson }));
195112
+ const form = await buildRunFormData({
195113
+ target: pathTarget,
195114
+ inputFile: opts.inputFile,
195115
+ inputJson: opts.inputJson
195116
+ });
195117
+ payload = await client.postFormData(runPath, form);
194622
195118
  } else {
194623
- payload = await client.post(runPath, opts.inputJson ? JSON.parse(opts.inputJson) : {});
195119
+ payload = await client.post(runPath, runStartJsonBody(target, opts.inputJson ? JSON.parse(opts.inputJson) : {}));
194624
195120
  }
194625
- const runId = String(payload.runId ?? "");
195121
+ const runId = String(payload.id ?? "");
194626
195122
  let waitedForTerminalRun = false;
194627
195123
  if (opts.wait && runId) {
194628
195124
  payload = await pollRun(client, runId, opts.interval, opts.maxWait);
@@ -194633,8 +195129,7 @@ async function runTarget(target, opts) {
194633
195129
  setExitCodeForFailedTerminalRun(payload);
194634
195130
  }
194635
195131
  async function rerunTarget(runId, opts) {
194636
- const sourceRef = opts.version === "latest" ? undefined : opts.version;
194637
- await rerunRun(runId, { ...opts, sourceRef });
195132
+ await rerunRun(runId, { ...opts, version: opts.version });
194638
195133
  }
194639
195134
 
194640
195135
  // src/commands/skill/index.ts
@@ -198136,14 +198631,13 @@ ${ui.info("ℹ")} step-level errors live on \`stepExecutions[].error\` — see $
198136
198631
 
198137
198632
  `);
198138
198633
  }
198139
- var TERMINAL_EXEC_STATES = new Set(["completed", "failed", "cancelled", "rejected"]);
198140
198634
  function summarizeExperimentExecutions(execs) {
198141
198635
  const counts = {};
198142
198636
  for (const e8 of execs) {
198143
198637
  const s5 = e8.status ?? "unknown";
198144
198638
  counts[s5] = (counts[s5] ?? 0) + 1;
198145
198639
  }
198146
- const terminal = execs.filter((e8) => TERMINAL_EXEC_STATES.has(e8.status ?? "")).length;
198640
+ const terminal = execs.filter((e8) => isTerminalExecutionStatus(e8.status)).length;
198147
198641
  return {
198148
198642
  total: execs.length,
198149
198643
  terminal,