deepline 0.1.198 → 0.1.200

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.
Files changed (72) hide show
  1. package/dist/bundling-sources/apps/play-runner-workers/src/coordinator-entry.ts +5 -1
  2. package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +51 -17
  3. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/README.md +1 -1
  4. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/harness-receipt-store.ts +16 -0
  5. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/receipts.ts +40 -9
  6. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-dispatch.ts +108 -39
  7. package/dist/bundling-sources/sdk/src/http.ts +5 -2
  8. package/dist/bundling-sources/sdk/src/play.ts +1 -1
  9. package/dist/bundling-sources/sdk/src/plays/harness-stub.ts +7 -0
  10. package/dist/bundling-sources/sdk/src/release.ts +2 -2
  11. package/dist/bundling-sources/sdk/src/worker-play-entry.ts +11 -55
  12. package/dist/bundling-sources/shared_libs/play-runtime/adaptive-tool-dispatcher.ts +355 -0
  13. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +172 -73
  14. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +1794 -377
  15. package/dist/bundling-sources/shared_libs/play-runtime/ctx-contract.ts +3 -0
  16. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +67 -4
  17. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +161 -39
  18. package/dist/bundling-sources/shared_libs/play-runtime/governor/adaptive-admission.ts +218 -0
  19. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +1 -1
  20. package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +115 -25
  21. package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +17 -17
  22. package/dist/bundling-sources/shared_libs/play-runtime/lease-policy.ts +22 -0
  23. package/dist/bundling-sources/shared_libs/play-runtime/ledger-safe-payload.ts +2 -1
  24. package/dist/bundling-sources/shared_libs/play-runtime/live-events.ts +0 -1
  25. package/dist/bundling-sources/shared_libs/play-runtime/map-memory-limits.ts +265 -0
  26. package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +135 -0
  27. package/dist/bundling-sources/shared_libs/play-runtime/play-input.ts +17 -0
  28. package/dist/bundling-sources/shared_libs/play-runtime/play-latency-trace.ts +0 -3
  29. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +10 -1
  30. package/dist/bundling-sources/shared_libs/play-runtime/providers.ts +9 -15
  31. package/dist/bundling-sources/shared_libs/play-runtime/receipt-completion-sink.ts +262 -0
  32. package/dist/bundling-sources/shared_libs/play-runtime/receipt-heartbeat-supervisor.ts +64 -0
  33. package/dist/bundling-sources/shared_libs/play-runtime/receipt-sql.ts +76 -8
  34. package/dist/bundling-sources/shared_libs/play-runtime/receipt-state-sink.ts +59 -0
  35. package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +3 -2
  36. package/dist/bundling-sources/shared_libs/play-runtime/resource-governor.ts +269 -0
  37. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +2 -3
  38. package/dist/bundling-sources/shared_libs/play-runtime/run-terminal-source.ts +0 -1
  39. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +433 -0
  40. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +227 -0
  41. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +882 -0
  42. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/local-process.ts +573 -0
  43. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/bundle.ts +264 -0
  44. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/index.ts +33 -0
  45. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runner-events.ts +35 -0
  46. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +53 -0
  47. package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +0 -1
  48. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +459 -103
  49. package/dist/bundling-sources/shared_libs/play-runtime/runtime-constants.ts +12 -0
  50. package/dist/bundling-sources/shared_libs/play-runtime/runtime-infra-mode.ts +23 -0
  51. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-attempt-state-machine.ts +23 -2
  52. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +16 -24
  53. package/dist/bundling-sources/shared_libs/play-runtime/serial-task-queue.ts +26 -0
  54. package/dist/bundling-sources/shared_libs/play-runtime/submit-limits.ts +1 -1
  55. package/dist/bundling-sources/shared_libs/play-runtime/vercel-protection.ts +81 -0
  56. package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-state-machine.ts +54 -9
  57. package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +17 -3
  58. package/dist/bundling-sources/shared_libs/play-runtime/worker-api-types.ts +0 -20
  59. package/dist/bundling-sources/shared_libs/plays/dataset.ts +105 -4
  60. package/dist/bundling-sources/shared_libs/plays/row-identity.ts +4 -11
  61. package/dist/cli/index.js +441 -101
  62. package/dist/cli/index.mjs +441 -101
  63. package/dist/index.d.mts +1 -1
  64. package/dist/index.d.ts +1 -1
  65. package/dist/index.js +8 -8
  66. package/dist/index.mjs +8 -8
  67. package/dist/plays/bundle-play-file.mjs +15 -20
  68. package/package.json +1 -1
  69. package/dist/bundling-sources/shared_libs/play-runtime/hatchet-cold-execution-diagnosis.ts +0 -321
  70. package/dist/bundling-sources/shared_libs/play-runtime/hatchet-cold-execution-target.ts +0 -158
  71. package/dist/bundling-sources/shared_libs/temporal/constants.ts +0 -39
  72. package/dist/bundling-sources/shared_libs/temporal/preview-config.ts +0 -150
package/dist/cli/index.js CHANGED
@@ -623,10 +623,10 @@ var SDK_RELEASE = {
623
623
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
624
624
  // fields shipped in 0.1.153.
625
625
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
626
- version: "0.1.198",
626
+ version: "0.1.200",
627
627
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
628
628
  supportPolicy: {
629
- latest: "0.1.198",
629
+ latest: "0.1.200",
630
630
  minimumSupported: "0.1.53",
631
631
  deprecatedBelow: "0.1.53",
632
632
  commandMinimumSupported: [
@@ -1067,7 +1067,10 @@ var HttpClient = class {
1067
1067
  * @param path - API path (e.g. `"/api/v2/tools"`)
1068
1068
  */
1069
1069
  async get(path) {
1070
- return this.request(path, { method: "GET" });
1070
+ return this.request(path, {
1071
+ method: "GET",
1072
+ retryApiErrors: true
1073
+ });
1071
1074
  }
1072
1075
  async *streamSse(path, options) {
1073
1076
  const url = `${this.config.baseUrl}${path}`;
@@ -1341,7 +1344,6 @@ function resolveTimingWindow(input2) {
1341
1344
  // ../shared_libs/play-runtime/run-terminal-source.ts
1342
1345
  var PLAY_RUN_LEDGER_EVENT_SOURCES = [
1343
1346
  "worker",
1344
- "temporal",
1345
1347
  "convex",
1346
1348
  "coordinator",
1347
1349
  "system"
@@ -7028,7 +7030,7 @@ function isRecord4(value) {
7028
7030
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
7029
7031
  }
7030
7032
  function isSerializedDataset(value) {
7031
- return isRecord4(value) && value.kind === "dataset" && typeof value.count === "number" && Array.isArray(value.preview);
7033
+ return isRecord4(value) && value.kind === "dataset" && typeof value.count === "number" && (Array.isArray(value.preview) || typeof value.tableNamespace === "string");
7032
7034
  }
7033
7035
  function isPackagedDatasetOutput(value) {
7034
7036
  return isRecord4(value) && value.kind === "dataset" && isRecord4(value.preview) && Array.isArray(value.preview.rows);
@@ -7089,7 +7091,7 @@ function columnsFromDatasetSummary(summary) {
7089
7091
  function canonicalRowsInfoFromCandidate(input2) {
7090
7092
  const candidate = input2;
7091
7093
  if (isSerializedDataset(candidate.value)) {
7092
- const rawRows = rowArray(candidate.value.preview) ?? [];
7094
+ const rawRows = Array.isArray(candidate.value.preview) ? rowArray(candidate.value.preview) ?? [] : [];
7093
7095
  const totalRows2 = readNumber(candidate.value.count) ?? rawRows.length;
7094
7096
  const hasExplicitColumns = Array.isArray(candidate.value.columns) && candidate.value.columns.every((column) => typeof column === "string");
7095
7097
  const rawColumns = hasExplicitColumns ? candidate.value.columns : inferColumns(rawRows);
@@ -7317,6 +7319,13 @@ function collectSerializedDatasetRowsInfos(statusOrResult) {
7317
7319
  path: "result",
7318
7320
  output: candidates
7319
7321
  });
7322
+ if (isRecord4(result.output)) {
7323
+ collectDatasetCandidates({
7324
+ value: result.output,
7325
+ path: "result",
7326
+ output: candidates
7327
+ });
7328
+ }
7320
7329
  }
7321
7330
  candidates.push(...collectPackagedStepDatasetCandidates(statusOrResult));
7322
7331
  const seen = /* @__PURE__ */ new Set();
@@ -10411,22 +10420,22 @@ var PLAY_DEDUP_BACKENDS = {
10411
10420
 
10412
10421
  // ../shared_libs/play-runtime/scheduler-backend.ts
10413
10422
  var PLAY_SCHEDULER_BACKENDS = {
10414
- temporal: "temporal",
10415
10423
  cfWorkflows: "cf-workflows",
10424
+ /** Private legacy id retained only so old persisted rows can be interpreted. */
10425
+ postgres: "postgres",
10416
10426
  /**
10417
- * Private legacy id retained only so old persisted rows can be interpreted.
10418
- * It is not a selectable scheduler backend after the Hatchet hard cutover.
10427
+ * Postgres-native durable-execution scheduler (vendored Absurd engine). Runs
10428
+ * on the battle-tested run-state store without an external workflow engine.
10429
+ * Selected explicitly by the `absurd` profile.
10419
10430
  */
10420
- postgres: "postgres",
10421
- hatchet: "hatchet",
10431
+ absurd: "absurd",
10422
10432
  inProcess: "in-process"
10423
10433
  };
10424
10434
 
10425
10435
  // ../shared_libs/play-runtime/providers.ts
10426
10436
  var PLAY_RUNTIME_PROVIDER_IDS = {
10427
10437
  workersEdge: "workers_edge",
10428
- hatchet: "hatchet",
10429
- local: "local"
10438
+ absurd: "absurd"
10430
10439
  };
10431
10440
  var PLAY_RUNTIME_PROVIDERS = {
10432
10441
  workers_edge: {
@@ -10437,21 +10446,16 @@ var PLAY_RUNTIME_PROVIDERS = {
10437
10446
  artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
10438
10447
  label: "Cloudflare Dynamic Workflows + Dynamic Workers + DO dedup"
10439
10448
  },
10440
- hatchet: {
10441
- id: PLAY_RUNTIME_PROVIDER_IDS.hatchet,
10442
- scheduler: PLAY_SCHEDULER_BACKENDS.hatchet,
10449
+ absurd: {
10450
+ id: PLAY_RUNTIME_PROVIDER_IDS.absurd,
10451
+ scheduler: PLAY_SCHEDULER_BACKENDS.absurd,
10452
+ // Server runs execute on Daytona; the local-dev/test shape swaps the runner
10453
+ // axis to local_process (same as the local profile) via an explicit
10454
+ // runtimeBackend override at submit while tests drive local_process.
10443
10455
  runner: PLAY_RUNTIME_BACKENDS.daytona,
10444
10456
  dedup: PLAY_DEDUP_BACKENDS.inMemory,
10445
10457
  artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
10446
- label: "Hatchet scheduler + one-shot Daytona runner + receipt-backed in-process dedup"
10447
- },
10448
- local: {
10449
- id: PLAY_RUNTIME_PROVIDER_IDS.local,
10450
- scheduler: PLAY_SCHEDULER_BACKENDS.temporal,
10451
- runner: PLAY_RUNTIME_BACKENDS.localProcess,
10452
- dedup: PLAY_DEDUP_BACKENDS.inMemory,
10453
- artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
10454
- label: "Local Temporal scheduler + local subprocess runner (tests)"
10458
+ label: "Absurd (Postgres-native durable) scheduler + one-shot Daytona runner + receipt-backed in-process dedup"
10455
10459
  }
10456
10460
  };
10457
10461
  function defaultPlayRuntimeProvider() {
@@ -10464,7 +10468,7 @@ function resolvePlayRuntimeProvider(override) {
10464
10468
  return PLAY_RUNTIME_PROVIDERS[id];
10465
10469
  }
10466
10470
  throw new Error(
10467
- `Unknown play runtime provider "${id}". Expected one of: ${Object.keys(
10471
+ `Unsupported play runtime provider "${id}". Expected one of: ${Object.keys(
10468
10472
  PLAY_RUNTIME_PROVIDERS
10469
10473
  ).join(", ")}.`
10470
10474
  );
@@ -10716,14 +10720,219 @@ function parseReferencedPlayTarget2(target) {
10716
10720
  function isPrebuiltReferenceTarget(target) {
10717
10721
  return target.trim().toLowerCase().startsWith("prebuilt/");
10718
10722
  }
10723
+ function buildBarePrebuiltReferenceMessage(input2) {
10724
+ return `Prebuilt play "${input2.requested}" must be referenced as "${input2.reference}". Use the prebuilt/ namespace anywhere you run, describe, get, or link to Deepline-managed plays.`;
10725
+ }
10719
10726
  function buildBarePrebuiltReferenceError(input2) {
10720
- return new Error(
10721
- `Prebuilt play "${input2.requested}" must be referenced as "${input2.reference}". Use the prebuilt/ namespace anywhere you run, describe, get, or link to Deepline-managed plays.`
10727
+ return new Error(buildBarePrebuiltReferenceMessage(input2));
10728
+ }
10729
+ function isPlayNotFoundError(error) {
10730
+ return error instanceof DeeplineError && (error.statusCode === 404 || error.code === "PLAY_NOT_FOUND" || error.code === "NOT_FOUND");
10731
+ }
10732
+ function isExplicitMissingPlayReferenceError(error) {
10733
+ if (!(error instanceof DeeplineError)) {
10734
+ return false;
10735
+ }
10736
+ if (error.statusCode !== 404 && error.code !== "PLAY_NOT_FOUND") {
10737
+ return false;
10738
+ }
10739
+ return /^play not found\b/i.test(error.message.trim());
10740
+ }
10741
+ function normalizePlayReferenceForMatch(value) {
10742
+ return value.trim().toLowerCase().replace(/^prebuilt\//, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
10743
+ }
10744
+ function playReferenceMatchTokens(value) {
10745
+ return normalizePlayReferenceForMatch(value).split("-").filter((token) => token.length > 1 && token !== "to" && token !== "and");
10746
+ }
10747
+ function playSuggestionReference(play) {
10748
+ if (play.reference?.trim()) {
10749
+ return play.reference.trim();
10750
+ }
10751
+ const ownerSlug = play.ownerSlug?.trim();
10752
+ return ownerSlug ? `${ownerSlug}/${play.name}` : play.name;
10753
+ }
10754
+ function scorePlayReferenceSuggestion(requested, play) {
10755
+ const parsed = parseReferencedPlayTarget2(requested);
10756
+ const requestedTrimmed = requested.trim();
10757
+ const requestedRef = requestedTrimmed.toLowerCase();
10758
+ const requestedName = parsed.unqualifiedPlayName;
10759
+ const requestedNorm = normalizePlayReferenceForMatch(requestedTrimmed);
10760
+ const requestedNameNorm = normalizePlayReferenceForMatch(requestedName);
10761
+ if (!requestedNorm && !requestedNameNorm) {
10762
+ return null;
10763
+ }
10764
+ const reference = playSuggestionReference(play);
10765
+ const referenceNorm = normalizePlayReferenceForMatch(reference);
10766
+ const nameNorm = normalizePlayReferenceForMatch(play.name);
10767
+ const candidateNamespace = reference.includes("/") ? reference.split("/")[0]?.toLowerCase() : null;
10768
+ const requestedNamespace = parsed.ownerSlug?.toLowerCase() ?? null;
10769
+ const aliases = (play.aliases ?? []).map(normalizePlayReferenceForMatch);
10770
+ const searchable = [referenceNorm, nameNorm, ...aliases].filter(Boolean);
10771
+ const requestedTokens = playReferenceMatchTokens(requestedName);
10772
+ const candidateTokens = [
10773
+ ...new Set(
10774
+ [reference, play.name, ...play.aliases ?? []].flatMap(
10775
+ playReferenceMatchTokens
10776
+ )
10777
+ )
10778
+ ];
10779
+ const hasTokenContainment = requestedTokens.length > 0 && requestedTokens.every((token) => candidateTokens.includes(token));
10780
+ let score = 0;
10781
+ if (reference.toLowerCase() === requestedRef) {
10782
+ score = 120;
10783
+ } else if (requestedNamespace && candidateNamespace === requestedNamespace && nameNorm === requestedNameNorm) {
10784
+ score = 110;
10785
+ } else if (nameNorm === requestedNameNorm || aliases.includes(requestedNameNorm)) {
10786
+ score = play.origin === "prebuilt" ? 100 : 95;
10787
+ } else if (requestedNamespace && candidateNamespace === requestedNamespace && searchable.some(
10788
+ (value) => value.includes(requestedNameNorm) || requestedNameNorm.includes(value)
10789
+ )) {
10790
+ score = 85;
10791
+ } else if (searchable.some(
10792
+ (value) => value.includes(requestedNorm) || requestedNorm.includes(value)
10793
+ )) {
10794
+ score = 70;
10795
+ } else if (requestedNameNorm && searchable.some(
10796
+ (value) => value.includes(requestedNameNorm) || requestedNameNorm.includes(value)
10797
+ )) {
10798
+ score = 60;
10799
+ } else if (hasTokenContainment) {
10800
+ score = requestedNamespace && candidateNamespace === requestedNamespace ? 58 : 50;
10801
+ }
10802
+ if (score <= 0) {
10803
+ return null;
10804
+ }
10805
+ if (play.origin === "prebuilt") {
10806
+ score += 3;
10807
+ }
10808
+ return {
10809
+ reference,
10810
+ name: play.name,
10811
+ origin: play.origin ?? null,
10812
+ score
10813
+ };
10814
+ }
10815
+ function rankPlayReferenceSuggestions(input2) {
10816
+ const byReference = /* @__PURE__ */ new Map();
10817
+ for (const play of input2.plays) {
10818
+ const suggestion = scorePlayReferenceSuggestion(input2.requested, play);
10819
+ if (!suggestion) continue;
10820
+ const existing = byReference.get(suggestion.reference);
10821
+ if (!existing || suggestion.score > existing.score) {
10822
+ byReference.set(suggestion.reference, suggestion);
10823
+ }
10824
+ }
10825
+ return [...byReference.values()].sort((left, right) => {
10826
+ if (right.score !== left.score) return right.score - left.score;
10827
+ if (left.origin === "prebuilt" && right.origin !== "prebuilt") return -1;
10828
+ if (right.origin === "prebuilt" && left.origin !== "prebuilt") return 1;
10829
+ return left.reference.localeCompare(right.reference);
10830
+ }).slice(0, input2.limit ?? 5);
10831
+ }
10832
+ function searchQueryForMissingPlayReference(target) {
10833
+ return parseReferencedPlayTarget2(target).unqualifiedPlayName.replace(/[-_./]+/g, " ").replace(/\s+/g, " ").trim();
10834
+ }
10835
+ function shellQuote2(value) {
10836
+ return `'${value.replace(/'/g, `'\\''`)}'`;
10837
+ }
10838
+ function buildPlayReferenceNotFoundMessage(input2) {
10839
+ const lines = [`Play not found: ${input2.requested}`];
10840
+ if (input2.suggestions.length > 0) {
10841
+ lines.push("", "Did you mean one of these?");
10842
+ for (const suggestion of input2.suggestions) {
10843
+ lines.push("", ` ${suggestion.reference}`);
10844
+ if (input2.command === "run") {
10845
+ lines.push(
10846
+ ` deepline plays run ${suggestion.reference} --input '{...}' --watch`
10847
+ );
10848
+ } else if (input2.command === "get") {
10849
+ lines.push(` deepline plays get ${suggestion.reference} --json`);
10850
+ } else if (input2.command === "check") {
10851
+ lines.push(` deepline plays check ${suggestion.reference} --json`);
10852
+ } else if (input2.command === "versions") {
10853
+ lines.push(
10854
+ ` deepline plays versions --name ${suggestion.reference} --json`
10855
+ );
10856
+ } else {
10857
+ lines.push(
10858
+ ` deepline plays describe ${suggestion.reference} --json`
10859
+ );
10860
+ }
10861
+ }
10862
+ }
10863
+ const searchQuery = searchQueryForMissingPlayReference(input2.requested);
10864
+ if (searchQuery) {
10865
+ lines.push(
10866
+ "",
10867
+ "Search visible plays:",
10868
+ ` deepline plays search ${shellQuote2(searchQuery)} --all --json`
10869
+ );
10870
+ }
10871
+ return lines.join("\n");
10872
+ }
10873
+ async function buildPlayReferenceNotFoundError(input2) {
10874
+ let suggestions = [];
10875
+ try {
10876
+ const searchQuery = searchQueryForMissingPlayReference(input2.target);
10877
+ const searchMatches = searchQuery ? await input2.client.searchPlays({
10878
+ query: searchQuery,
10879
+ scope: "all",
10880
+ compact: true
10881
+ }) : [];
10882
+ const plays = searchMatches.length > 0 ? searchMatches : await input2.client.listPlays();
10883
+ suggestions = rankPlayReferenceSuggestions({
10884
+ requested: input2.target,
10885
+ plays,
10886
+ limit: 5
10887
+ });
10888
+ } catch {
10889
+ suggestions = [];
10890
+ }
10891
+ const sourceError = input2.sourceError instanceof DeeplineError ? input2.sourceError : null;
10892
+ const code = sourceError?.code && sourceError.code !== "API_ERROR" ? sourceError.code : "PLAY_NOT_FOUND";
10893
+ return new DeeplineError(
10894
+ buildPlayReferenceNotFoundMessage({
10895
+ requested: input2.target,
10896
+ command: input2.command,
10897
+ suggestions
10898
+ }),
10899
+ sourceError?.statusCode ?? 404,
10900
+ code,
10901
+ sourceError?.details
10722
10902
  );
10723
10903
  }
10724
- async function assertCanonicalNamedPlayReference(client2, target) {
10904
+ async function isMissingRunPlayReferenceError(input2) {
10905
+ if (isExplicitMissingPlayReferenceError(input2.error)) {
10906
+ return true;
10907
+ }
10908
+ if (!(input2.error instanceof DeeplineError) || input2.error.statusCode !== 404 || !/^no artifact-backed revision found for play:/i.test(
10909
+ input2.error.message.trim()
10910
+ )) {
10911
+ return false;
10912
+ }
10913
+ try {
10914
+ await input2.client.getPlay(parseReferencedPlayTarget2(input2.playName).playName);
10915
+ return false;
10916
+ } catch (lookupError) {
10917
+ return isPlayNotFoundError(lookupError);
10918
+ }
10919
+ }
10920
+ async function assertCanonicalNamedPlayReference(client2, target, options = {}) {
10725
10921
  const parsed = parseReferencedPlayTarget2(target);
10726
- const detail = await client2.getPlay(parsed.playName);
10922
+ let detail;
10923
+ try {
10924
+ detail = await client2.getPlay(parsed.playName);
10925
+ } catch (error) {
10926
+ if (isPlayNotFoundError(error)) {
10927
+ throw await buildPlayReferenceNotFoundError({
10928
+ client: client2,
10929
+ target,
10930
+ command: options.command ?? "describe",
10931
+ sourceError: error
10932
+ });
10933
+ }
10934
+ throw error;
10935
+ }
10727
10936
  if (detail.play.ownerType === "deepline" && !isPrebuiltReferenceTarget(target)) {
10728
10937
  throw buildBarePrebuiltReferenceError({
10729
10938
  requested: target,
@@ -13459,10 +13668,7 @@ async function exportPlayStatusRows(client2, status, outPath, options = {}) {
13459
13668
  availableRows,
13460
13669
  datasetPath: options.datasetPath
13461
13670
  });
13462
- return {
13463
- path: writeCanonicalRowsCsv(guarded2, outPath),
13464
- rowsInfo: guarded2
13465
- };
13671
+ return { path: writeCanonicalRowsCsv(guarded2, outPath), rowsInfo: guarded2 };
13466
13672
  }
13467
13673
  if (rowsInfo.complete) {
13468
13674
  const guarded2 = assertDatasetHasExportableRows({
@@ -13471,7 +13677,10 @@ async function exportPlayStatusRows(client2, status, outPath, options = {}) {
13471
13677
  availableRows,
13472
13678
  datasetPath: options.datasetPath
13473
13679
  });
13474
- return { path: writeCanonicalRowsCsv(guarded2, outPath), rowsInfo: guarded2 };
13680
+ return {
13681
+ path: writeCanonicalRowsCsv(guarded2, outPath),
13682
+ rowsInfo: guarded2
13683
+ };
13475
13684
  }
13476
13685
  if (attempt < attempts && retryDelayMs > 0) {
13477
13686
  await sleep5(retryDelayMs);
@@ -13605,17 +13814,25 @@ function normalizePlayValidationError(error) {
13605
13814
  error instanceof DeeplineError ? error.details : void 0
13606
13815
  );
13607
13816
  }
13608
- function normalizePlayStartError(error, playName) {
13817
+ async function normalizePlayStartError(client2, error, playName, options = {}) {
13609
13818
  const activeRuns = extractActiveRunsFromError(error);
13610
- if (activeRuns.length === 0) {
13611
- return normalizePlayValidationError(error);
13819
+ if (activeRuns.length > 0) {
13820
+ return new DeeplineError(
13821
+ formatActiveRunConflictError({ playName, activeRuns }),
13822
+ error instanceof DeeplineError ? error.statusCode : 409,
13823
+ "ACTIVE_RUN_EXISTS",
13824
+ error instanceof DeeplineError ? error.details : void 0
13825
+ );
13612
13826
  }
13613
- return new DeeplineError(
13614
- formatActiveRunConflictError({ playName, activeRuns }),
13615
- error instanceof DeeplineError ? error.statusCode : 409,
13616
- "ACTIVE_RUN_EXISTS",
13617
- error instanceof DeeplineError ? error.details : void 0
13618
- );
13827
+ if (options.suggestMissingPlay && await isMissingRunPlayReferenceError({ client: client2, error, playName })) {
13828
+ return buildPlayReferenceNotFoundError({
13829
+ client: client2,
13830
+ target: playName,
13831
+ command: "run",
13832
+ sourceError: error
13833
+ });
13834
+ }
13835
+ return normalizePlayValidationError(error);
13619
13836
  }
13620
13837
  function renderServerResultView(value) {
13621
13838
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -13775,7 +13992,7 @@ function writeStartedPlayRun(input2) {
13775
13992
  );
13776
13993
  }
13777
13994
  function parsePlayRunOptions(args) {
13778
- const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--profile <id>] [--live|--latest|--revision-id <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--no-open] [--json] [--full] [--<input> value]\n --profile defaults to workers_edge; pass hatchet explicitly for Hatchet runtime comparison.\n Unknown --<input> value flags, such as --limit 5, are passed into play input.\nRun `deepline plays run --help` for idempotent call caching and ctx.dataset guidance.";
13995
+ const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--profile <id>] [--live|--latest|--revision-id <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--no-open] [--json] [--full] [--<input> value]\n --profile defaults to workers_edge, unless your local dev server exports a dev default such as absurd.\n Unknown --<input> value flags, such as --limit 5, are passed into play input.\nRun `deepline plays run --help` for idempotent call caching and ctx.dataset guidance.";
13779
13996
  let filePath = null;
13780
13997
  let playName = null;
13781
13998
  let input2 = null;
@@ -14128,7 +14345,9 @@ async function handlePlayCheck(args) {
14128
14345
  if (!isFileTarget(options.target)) {
14129
14346
  const client3 = new DeeplineClient();
14130
14347
  try {
14131
- await assertCanonicalNamedPlayReference(client3, options.target);
14348
+ await assertCanonicalNamedPlayReference(client3, options.target, {
14349
+ command: "check"
14350
+ });
14132
14351
  const play = await client3.describePlay(
14133
14352
  parseReferencedPlayTarget2(options.target).playName,
14134
14353
  { compact: true }
@@ -14398,8 +14617,8 @@ async function handleFileBackedRun(options) {
14398
14617
  waitTimeoutMs: options.waitTimeoutMs,
14399
14618
  noOpen: options.noOpen,
14400
14619
  progress
14401
- }).catch((error) => {
14402
- throw normalizePlayStartError(error, playName);
14620
+ }).catch(async (error) => {
14621
+ throw await normalizePlayStartError(client2, error, playName);
14403
14622
  })
14404
14623
  );
14405
14624
  if (finalStatus.status === "completed") {
@@ -14429,8 +14648,8 @@ async function handleFileBackedRun(options) {
14429
14648
  const started = await traceCliSpan(
14430
14649
  "cli.play_start_unwatched",
14431
14650
  { targetKind: "file", playName },
14432
- () => client2.startPlayRun(startRequest).catch((error) => {
14433
- throw normalizePlayStartError(error, playName);
14651
+ () => client2.startPlayRun(startRequest).catch(async (error) => {
14652
+ throw await normalizePlayStartError(client2, error, playName);
14434
14653
  })
14435
14654
  );
14436
14655
  const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
@@ -14488,7 +14707,9 @@ async function handleNamedRun(options) {
14488
14707
  return traceCliSpan(
14489
14708
  "cli.play_load_definition",
14490
14709
  { targetKind: "name", playName, skipped: false },
14491
- () => assertCanonicalNamedPlayReference(client2, playName)
14710
+ () => assertCanonicalNamedPlayReference(client2, playName, {
14711
+ command: "run"
14712
+ })
14492
14713
  );
14493
14714
  })() : (recordCliTrace({
14494
14715
  phase: "cli.play_load_definition",
@@ -14557,8 +14778,10 @@ async function handleNamedRun(options) {
14557
14778
  waitTimeoutMs: options.waitTimeoutMs,
14558
14779
  noOpen: options.noOpen,
14559
14780
  progress
14560
- }).catch((error) => {
14561
- throw normalizePlayStartError(error, playName);
14781
+ }).catch(async (error) => {
14782
+ throw await normalizePlayStartError(client2, error, playName, {
14783
+ suggestMissingPlay: true
14784
+ });
14562
14785
  })
14563
14786
  );
14564
14787
  if (finalStatus.status === "completed") {
@@ -14588,8 +14811,10 @@ async function handleNamedRun(options) {
14588
14811
  const started = await traceCliSpan(
14589
14812
  "cli.play_start_unwatched",
14590
14813
  { targetKind: "name", playName },
14591
- () => client2.startPlayRun(startRequest).catch((error) => {
14592
- throw normalizePlayStartError(error, playName);
14814
+ () => client2.startPlayRun(startRequest).catch(async (error) => {
14815
+ throw await normalizePlayStartError(client2, error, playName, {
14816
+ suggestMissingPlay: true
14817
+ });
14593
14818
  })
14594
14819
  );
14595
14820
  const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
@@ -15028,7 +15253,9 @@ async function handlePlayGet(args) {
15028
15253
  }
15029
15254
  }
15030
15255
  const playName = isFileTarget(target) ? extractPlayName((0, import_node_fs10.readFileSync)((0, import_node_path11.resolve)(target), "utf-8"), (0, import_node_path11.resolve)(target)) : parseReferencedPlayTarget2(target).playName;
15031
- const detail = isFileTarget(target) ? await client2.getPlay(playName) : await assertCanonicalNamedPlayReference(client2, target);
15256
+ const detail = isFileTarget(target) ? await client2.getPlay(playName) : await assertCanonicalNamedPlayReference(client2, target, {
15257
+ command: "get"
15258
+ });
15032
15259
  const resolvedSource = detail.play.workingRevision?.sourceCode ?? detail.play.liveRevision?.sourceCode ?? detail.play.currentRevision?.sourceCode ?? detail.play.sourceCode ?? "";
15033
15260
  const materializedFile = outPath ? materializeRemotePlaySource({
15034
15261
  target,
@@ -15110,7 +15337,9 @@ async function handlePlayVersions(args) {
15110
15337
  }
15111
15338
  const client2 = new DeeplineClient();
15112
15339
  const jsonOutput = argsWantJson(args);
15113
- await assertCanonicalNamedPlayReference(client2, playName);
15340
+ await assertCanonicalNamedPlayReference(client2, playName, {
15341
+ command: "versions"
15342
+ });
15114
15343
  const versions = await client2.listPlayVersions(
15115
15344
  parseReferencedPlayTarget2(playName).playName
15116
15345
  );
@@ -15506,7 +15735,9 @@ async function handlePlayDescribe(args) {
15506
15735
  return 2;
15507
15736
  }
15508
15737
  const client2 = new DeeplineClient();
15509
- await assertCanonicalNamedPlayReference(client2, playName);
15738
+ await assertCanonicalNamedPlayReference(client2, playName, {
15739
+ command: "describe"
15740
+ });
15510
15741
  const play = await client2.describePlay(
15511
15742
  parseReferencedPlayTarget2(playName).playName,
15512
15743
  {
@@ -18707,7 +18938,8 @@ async function writeOutputCsv(outputPath, status, options) {
18707
18938
  }
18708
18939
  const selectedSourceRows = selectedSourceCsvRowCount(options);
18709
18940
  const shouldFetchBackingRows = options?.client && shouldFetchBackingRowsForEnrichExport(rowsInfo, status, {
18710
- selectedSourceRows
18941
+ selectedSourceRows,
18942
+ expectedAliases: options?.config ? collectConfigScalarAliasOrder(options.config) : []
18711
18943
  });
18712
18944
  if (options?.client && shouldFetchBackingRows) {
18713
18945
  let fetchedRowsInfo = null;
@@ -18744,6 +18976,7 @@ async function writeOutputCsv(outputPath, status, options) {
18744
18976
  const columns = orderEnrichCsvColumns(
18745
18977
  dataExportColumns(merged.rows, [
18746
18978
  ...merged.preferredColumns,
18979
+ ...options?.config ? collectConfigScalarAliasOrder(options.config) : [],
18747
18980
  ...rowsInfo.columns
18748
18981
  ]),
18749
18982
  options?.config
@@ -19401,26 +19634,39 @@ function shouldFetchBackingRowsForEnrichExport(rowsInfo, status, options = {}) {
19401
19634
  rowsInfo,
19402
19635
  status
19403
19636
  );
19637
+ const isGeneratedEnrichRows = tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE;
19404
19638
  if (terminalStatus === "failed" || terminalStatus === "cancelled") {
19405
- if (tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE && rowsInfo.source !== null && typeof options.selectedSourceRows === "number" && rowsInfo.rows.length < options.selectedSourceRows) {
19639
+ if (isGeneratedEnrichRows && rowsInfo.source !== null && typeof options.selectedSourceRows === "number" && rowsInfo.rows.length < options.selectedSourceRows) {
19406
19640
  return true;
19407
19641
  }
19408
- return tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE && (rowsInfo.recovered === true || hasPartialRunOutputWarning(status));
19642
+ return isGeneratedEnrichRows && (rowsInfo.recovered === true || hasPartialRunOutputWarning(status));
19409
19643
  }
19410
- if (tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE && typeof options.selectedSourceRows === "number" && rowsInfo.rows.length < options.selectedSourceRows) {
19644
+ if (isGeneratedEnrichRows && typeof options.selectedSourceRows === "number" && rowsInfo.rows.length < options.selectedSourceRows) {
19411
19645
  return true;
19412
19646
  }
19413
- if (tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE && typeof options.selectedSourceRows === "number" && options.selectedSourceRows > 0) {
19647
+ if (isGeneratedEnrichRows && (typeof options.selectedSourceRows === "number" && options.selectedSourceRows > 0 || rowsMissingExpectedAlias(rowsInfo.rows, options.expectedAliases))) {
19414
19648
  return true;
19415
19649
  }
19416
- if (tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE && hasFailedRowSignal(status)) {
19650
+ if (isGeneratedEnrichRows && hasFailedRowSignal(status)) {
19417
19651
  return true;
19418
19652
  }
19419
19653
  if (!rowsInfo.complete) {
19420
- return tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE;
19654
+ return isGeneratedEnrichRows;
19421
19655
  }
19422
19656
  return rowsInfo.rows.some((row) => hasLossyPreviewPlaceholder(row));
19423
19657
  }
19658
+ function rowsMissingExpectedAlias(rows, expectedAliases) {
19659
+ if (rows.length === 0 || !expectedAliases?.length) {
19660
+ return false;
19661
+ }
19662
+ const rowAliases = /* @__PURE__ */ new Set();
19663
+ for (const row of rows) {
19664
+ for (const key of Object.keys(row)) {
19665
+ rowAliases.add(normalizeAlias2(key));
19666
+ }
19667
+ }
19668
+ return expectedAliases.map((alias) => normalizeAlias2(alias)).filter(Boolean).some((alias) => !rowAliases.has(alias));
19669
+ }
19424
19670
  function hasPartialRunOutputWarning(status) {
19425
19671
  const warningLists = [
19426
19672
  recordField(status, "warnings"),
@@ -19986,6 +20232,18 @@ function collectEmptyWaterfallIssues(input2) {
19986
20232
  if (executionSignal === "all_condition_skipped" || executionSignal === "unknown" && waterfallChildrenAreStaticallySkipped(spec)) {
19987
20233
  return;
19988
20234
  }
20235
+ const statsEvidence = emptyWaterfallStatsEvidence(input2.status, spec);
20236
+ if (statsEvidence && input2.rowSetComplete && input2.outputPath) {
20237
+ issues.push(
20238
+ emptyWaterfallIssue({
20239
+ spec,
20240
+ selectedRows: statsEvidence.selectedRows,
20241
+ runId,
20242
+ followUpCommands
20243
+ })
20244
+ );
20245
+ return;
20246
+ }
19989
20247
  const logicalRows = /* @__PURE__ */ new Map();
19990
20248
  input2.rows.forEach((row, rowIndex) => {
19991
20249
  const sourceRowId = sourceRowIndexFromEnrichRow(
@@ -20007,24 +20265,34 @@ function collectEmptyWaterfallIssues(input2) {
20007
20265
  return;
20008
20266
  }
20009
20267
  const selectedRows = logicalRows.size;
20010
- const message = `Waterfall ${spec.alias} produced 0 values for ${selectedRows} selected row(s).`;
20011
- issues.push({
20012
- issue_id: `${spec.alias}-empty-waterfall`,
20013
- kind: "empty_waterfall",
20014
- severity: "needs_attention",
20015
- column: spec.alias,
20016
- selected_rows: selectedRows,
20017
- rows_with_value: 0,
20018
- rows_without_value: selectedRows,
20019
- message,
20020
- next_steps: enrichIssueNextSteps({ runId }),
20021
- follow_up_commands: followUpCommands,
20022
- ...spec.operation ? { operation: spec.operation } : {},
20023
- ...runId ? { run_id: runId } : {}
20024
- });
20268
+ issues.push(
20269
+ emptyWaterfallIssue({
20270
+ spec,
20271
+ selectedRows,
20272
+ runId,
20273
+ followUpCommands
20274
+ })
20275
+ );
20025
20276
  });
20026
20277
  return issues;
20027
20278
  }
20279
+ function emptyWaterfallIssue(input2) {
20280
+ const message = `Waterfall ${input2.spec.alias} produced 0 values for ${input2.selectedRows} selected row(s).`;
20281
+ return {
20282
+ issue_id: `${input2.spec.alias}-empty-waterfall`,
20283
+ kind: "empty_waterfall",
20284
+ severity: "needs_attention",
20285
+ column: input2.spec.alias,
20286
+ selected_rows: input2.selectedRows,
20287
+ rows_with_value: 0,
20288
+ rows_without_value: input2.selectedRows,
20289
+ message,
20290
+ next_steps: enrichIssueNextSteps({ runId: input2.runId }),
20291
+ follow_up_commands: input2.followUpCommands,
20292
+ ...input2.spec.operation ? { operation: input2.spec.operation } : {},
20293
+ ...input2.runId ? { run_id: input2.runId } : {}
20294
+ };
20295
+ }
20028
20296
  function waterfallChildrenAreStaticallySkipped(spec) {
20029
20297
  const childAliases = spec.childAliases ?? [];
20030
20298
  if (childAliases.length === 0 || !spec.childRunIfJsByAlias) {
@@ -20058,14 +20326,18 @@ function waterfallExecutionSignal(status, spec) {
20058
20326
  const executedSummary = parseExecutionSummary(
20059
20327
  execution?.["completed:executed"]
20060
20328
  );
20329
+ const reusedSummary = parseExecutionSummary(
20330
+ execution?.["completed:reused"]
20331
+ );
20061
20332
  const skippedConditionSummary = parseExecutionSummary(
20062
20333
  execution?.["skipped:condition"]
20063
20334
  );
20064
20335
  const executedCount = executedSummary?.count ?? 0;
20336
+ const reusedCount = reusedSummary?.count ?? 0;
20065
20337
  const skippedConditionCount = skippedConditionSummary?.count ?? 0;
20066
- const totalCount = executedSummary?.total ?? skippedConditionSummary?.total;
20067
- const onlyConditionSkips = totalCount !== void 0 && skippedConditionCount >= totalCount && executedCount <= skippedConditionCount;
20068
- if (executedCount > 0 && !onlyConditionSkips || numericFailedRowSignal(execution?.failed) > 0 || numericFailedRowSignal(stat2.failed) > 0 || numericFailedRowSignal(stat2.failedRows) > 0) {
20338
+ const totalCount = executedSummary?.total ?? reusedSummary?.total ?? skippedConditionSummary?.total;
20339
+ const onlyConditionSkips = totalCount !== void 0 && skippedConditionCount >= totalCount && executedCount + reusedCount <= skippedConditionCount;
20340
+ if (executedCount + reusedCount > 0 && !onlyConditionSkips || numericFailedRowSignal(execution?.failed) > 0 || numericFailedRowSignal(stat2.failed) > 0 || numericFailedRowSignal(stat2.failedRows) > 0) {
20069
20341
  return "executed";
20070
20342
  }
20071
20343
  if (!onlyConditionSkips) {
@@ -20078,6 +20350,48 @@ function waterfallExecutionSignal(status, spec) {
20078
20350
  }
20079
20351
  return "unknown";
20080
20352
  }
20353
+ function emptyWaterfallStatsEvidence(status, spec) {
20354
+ const summaries = collectColumnStats(status);
20355
+ const parentStats = summaries.map((summary) => summary[spec.alias]).filter(isRecord7);
20356
+ for (const stat2 of parentStats) {
20357
+ const nonEmpty = parseExecutionSummary(stat2.non_empty);
20358
+ if (nonEmpty?.total && nonEmpty.count === 0) {
20359
+ return { selectedRows: nonEmpty.total };
20360
+ }
20361
+ }
20362
+ const childAliases = spec.childAliases ?? [];
20363
+ if (childAliases.length === 0) {
20364
+ return null;
20365
+ }
20366
+ let selectedRows = 0;
20367
+ let sawStatsForEveryChild = true;
20368
+ for (const childAlias of childAliases) {
20369
+ const stat2 = summaries.map((summary) => summary[childAlias]).find(isRecord7);
20370
+ if (!stat2) {
20371
+ sawStatsForEveryChild = false;
20372
+ break;
20373
+ }
20374
+ const nonEmpty = parseExecutionSummary(stat2.non_empty);
20375
+ if ((nonEmpty?.count ?? 0) > 0) {
20376
+ return null;
20377
+ }
20378
+ const execution = isRecord7(stat2.execution) ? stat2.execution : null;
20379
+ const executed = parseExecutionSummary(execution?.["completed:executed"]);
20380
+ const reused = parseExecutionSummary(execution?.["completed:reused"]);
20381
+ const skipped = parseExecutionSummary(execution?.["skipped:condition"]);
20382
+ selectedRows = Math.max(
20383
+ selectedRows,
20384
+ nonEmpty?.total ?? 0,
20385
+ executed?.total ?? 0,
20386
+ reused?.total ?? 0,
20387
+ skipped?.total ?? 0
20388
+ );
20389
+ }
20390
+ if (!sawStatsForEveryChild || selectedRows <= 0 || waterfallExecutionSignal(status, spec) === "all_condition_skipped") {
20391
+ return null;
20392
+ }
20393
+ return { selectedRows };
20394
+ }
20081
20395
  function mergeEnrichFailureJobs(...jobGroups) {
20082
20396
  const merged = [];
20083
20397
  const seen = /* @__PURE__ */ new Set();
@@ -20897,12 +21211,34 @@ var ENRICH_FLATTENED_CONTROL_FIELDS = /* @__PURE__ */ new Set([
20897
21211
  "provider",
20898
21212
  "status"
20899
21213
  ]);
21214
+ var ENRICH_ALIAS_METADATA_FIELDS = /* @__PURE__ */ new Set([
21215
+ "_metadata",
21216
+ "metadata",
21217
+ "metadata.columns",
21218
+ "metadata__columns"
21219
+ ]);
21220
+ function isEnrichAliasPayloadField(field) {
21221
+ return !field.startsWith("_") && !ENRICH_FLATTENED_CONTROL_FIELDS.has(field) && !ENRICH_ALIAS_METADATA_FIELDS.has(field);
21222
+ }
20900
21223
  function materializeCsvCellValue(value) {
20901
21224
  if (value && typeof value === "object") {
20902
21225
  return csvSafeJsonString(value);
20903
21226
  }
20904
21227
  return value;
20905
21228
  }
21229
+ function compactArrayEnvelopeCompleteValue(value) {
21230
+ if (!isRecord7(value) || value.kind !== "array") {
21231
+ return null;
21232
+ }
21233
+ if (!Array.isArray(value.preview)) {
21234
+ return null;
21235
+ }
21236
+ const length = typeof value.length === "number" && Number.isFinite(value.length) ? Math.max(0, Math.trunc(value.length)) : null;
21237
+ if (length === null || length > value.preview.length) {
21238
+ return null;
21239
+ }
21240
+ return value.preview.slice(0, length);
21241
+ }
20906
21242
  function disambiguateCompactAiInferencePayload(value) {
20907
21243
  const parsed = parseMaybeJsonObject(value);
20908
21244
  if (!isRecord7(parsed) || !cellFailureError(parsed)) {
@@ -20939,6 +21275,10 @@ function compactAiInferenceCellForCsv(value) {
20939
21275
  function materializeEnrichAliasCellForCsv(row, alias, options) {
20940
21276
  const direct = row[alias];
20941
21277
  if (isRecord7(direct)) {
21278
+ const completeArray = compactArrayEnvelopeCompleteValue(direct);
21279
+ if (completeArray) {
21280
+ return materializeCsvCellValue(completeArray);
21281
+ }
20942
21282
  if (options?.compactAiCell && direct.status === "completed" && (isRecord7(direct.result) || Object.prototype.hasOwnProperty.call(direct, "extracted_json") || typeof direct.output === "string")) {
20943
21283
  return materializeCsvCellValue(compactAiInferenceCellForCsv(direct));
20944
21284
  }
@@ -20947,7 +21287,7 @@ function materializeEnrichAliasCellForCsv(row, alias, options) {
20947
21287
  }
20948
21288
  const directCells = [];
20949
21289
  for (const [field, value] of Object.entries(direct)) {
20950
- if (ENRICH_FLATTENED_CONTROL_FIELDS.has(field)) {
21290
+ if (!isEnrichAliasPayloadField(field)) {
20951
21291
  continue;
20952
21292
  }
20953
21293
  if (isNonEmptyCsvCell(value)) {
@@ -20977,7 +21317,7 @@ function materializeEnrichAliasCellForCsv(row, alias, options) {
20977
21317
  }
20978
21318
  }
20979
21319
  const cells = aliasFlattenedCells(row, alias).filter(({ field, value }) => {
20980
- if (ENRICH_FLATTENED_CONTROL_FIELDS.has(field)) {
21320
+ if (!isEnrichAliasPayloadField(field)) {
20981
21321
  return false;
20982
21322
  }
20983
21323
  return isNonEmptyCsvCell(value);
@@ -24014,7 +24354,7 @@ var EXIT_AUTH2 = 1;
24014
24354
  var EXIT_SERVER3 = 2;
24015
24355
  var MAX_PROMPT_LENGTH = 8e3;
24016
24356
  var MAX_BODY_BYTES = 64 * 1024;
24017
- function shellQuote2(arg) {
24357
+ function shellQuote3(arg) {
24018
24358
  return `'${arg.replace(/'/g, `'\\''`)}'`;
24019
24359
  }
24020
24360
  function hasClaudeBinary() {
@@ -24187,7 +24527,7 @@ async function handleQuickstart(options) {
24187
24527
  }
24188
24528
  progress.complete();
24189
24529
  const { prompt, workflowId } = outcome;
24190
- const claudeCommand = `claude ${shellQuote2(prompt)}`;
24530
+ const claudeCommand = `claude ${shellQuote3(prompt)}`;
24191
24531
  const claudeAvailable = hasClaudeBinary();
24192
24532
  const willLaunch = options.launch !== false && !jsonOutput && interactive && claudeAvailable;
24193
24533
  printCommandEnvelope(
@@ -26109,7 +26449,7 @@ function parseExecuteOptions(args) {
26109
26449
  function safeFileStem(value) {
26110
26450
  return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "tool";
26111
26451
  }
26112
- function shellQuote3(value) {
26452
+ function shellQuote4(value) {
26113
26453
  return `'${value.replace(/'/g, `'\\''`)}'`;
26114
26454
  }
26115
26455
  function powerShellQuote(value) {
@@ -26179,7 +26519,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
26179
26519
  path: scriptPath,
26180
26520
  sourceCode: script,
26181
26521
  projectDir,
26182
- macCopyCommand: `mkdir -p ${shellQuote3(projectDir)} && cp ${shellQuote3(scriptPath)} ${shellQuote3(`${projectDir}/${fileName}`)}`,
26522
+ macCopyCommand: `mkdir -p ${shellQuote4(projectDir)} && cp ${shellQuote4(scriptPath)} ${shellQuote4(`${projectDir}/${fileName}`)}`,
26183
26523
  windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
26184
26524
  };
26185
26525
  }
@@ -26202,7 +26542,7 @@ function buildToolExecuteBaseEnvelope(input2) {
26202
26542
  envelope,
26203
26543
  "output"
26204
26544
  );
26205
- const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote3(JSON.stringify(input2.params))} --json`;
26545
+ const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote4(JSON.stringify(input2.params))} --json`;
26206
26546
  const actions = input2.listConversion ? [
26207
26547
  {
26208
26548
  label: "next",
@@ -27271,7 +27611,7 @@ function hasCommand(command) {
27271
27611
  });
27272
27612
  return result.status === 0;
27273
27613
  }
27274
- function shellQuote4(arg) {
27614
+ function shellQuote5(arg) {
27275
27615
  return `'${arg.replace(/'/g, `'\\''`)}'`;
27276
27616
  }
27277
27617
  function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES) {
@@ -27279,7 +27619,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
27279
27619
  const npxInstall = {
27280
27620
  command: "npx",
27281
27621
  args: npxArgs,
27282
- manualCommand: `npx ${npxArgs.map(shellQuote4).join(" ")}`
27622
+ manualCommand: `npx ${npxArgs.map(shellQuote5).join(" ")}`
27283
27623
  };
27284
27624
  if (hasCommand("bunx")) {
27285
27625
  const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames);
@@ -27287,7 +27627,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
27287
27627
  {
27288
27628
  command: "bunx",
27289
27629
  args: bunxArgs,
27290
- manualCommand: `bunx ${bunxArgs.map(shellQuote4).join(" ")}`
27630
+ manualCommand: `bunx ${bunxArgs.map(shellQuote5).join(" ")}`
27291
27631
  },
27292
27632
  npxInstall
27293
27633
  ];
@@ -27454,14 +27794,14 @@ function posixShellQuote(value) {
27454
27794
  function windowsCmdQuote(value) {
27455
27795
  return `"${value.replace(/"/g, '""')}"`;
27456
27796
  }
27457
- function shellQuote5(value) {
27797
+ function shellQuote6(value) {
27458
27798
  if (process.platform === "win32") {
27459
27799
  return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : windowsCmdQuote(value);
27460
27800
  }
27461
27801
  return posixShellQuote(value);
27462
27802
  }
27463
27803
  function buildSourceUpdateCommand(sourceRoot) {
27464
- const quotedRoot = shellQuote5(sourceRoot);
27804
+ const quotedRoot = shellQuote6(sourceRoot);
27465
27805
  const cdCommand = process.platform === "win32" ? `cd /d ${quotedRoot}` : `cd ${quotedRoot}`;
27466
27806
  return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
27467
27807
  }
@@ -27473,7 +27813,7 @@ function buildSidecarProjectConfigCommand(versionDir, nodeBin) {
27473
27813
  "fs.mkdirSync(dir,{recursive:true});",
27474
27814
  `fs.writeFileSync(path.join(dir,'package.json'),${JSON.stringify(NPM_SDK_SIDECAR_PACKAGE_JSON)});`
27475
27815
  ].join("");
27476
- return `${shellQuote5(nodeBin)} -e ${shellQuote5(script)} ${shellQuote5(versionDir)}`;
27816
+ return `${shellQuote6(nodeBin)} -e ${shellQuote6(script)} ${shellQuote6(versionDir)}`;
27477
27817
  }
27478
27818
  function sidecarStateDir(input2) {
27479
27819
  const scope = input2.env.DEEPLINE_CONFIG_SCOPE?.trim();
@@ -27512,7 +27852,7 @@ function resolvePythonSidecarUpdatePlan(options) {
27512
27852
  const packageSpec = options.packageSpec || "deepline@latest";
27513
27853
  const npmCommand = "npm";
27514
27854
  const versionDir = (0, import_node_path19.join)(stateDir, "versions", "<version>");
27515
- const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote5(versionDir)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote5).join(" ")} ${shellQuote5(packageSpec)}`;
27855
+ const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote6(versionDir)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote6).join(" ")} ${shellQuote6(packageSpec)}`;
27516
27856
  return {
27517
27857
  kind: "python-sidecar",
27518
27858
  stateDir,
@@ -27592,7 +27932,7 @@ function resolveUpdatePlan(options = {}) {
27592
27932
  command,
27593
27933
  args,
27594
27934
  ...installPrefix ? { installPrefix } : {},
27595
- manualCommand: `${command} ${args.map(shellQuote5).join(" ")}`
27935
+ manualCommand: `${command} ${args.map(shellQuote6).join(" ")}`
27596
27936
  };
27597
27937
  }
27598
27938
  var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
@@ -27753,9 +28093,9 @@ function writeSidecarLauncher(input2) {
27753
28093
  input2.path,
27754
28094
  [
27755
28095
  "#!/usr/bin/env sh",
27756
- `export DEEPLINE_HOST_URL=${shellQuote5(input2.hostUrl)}`,
27757
- `export DEEPLINE_CONFIG_SCOPE=${shellQuote5(input2.scope)}`,
27758
- `exec ${shellQuote5(input2.nodeBin)} ${shellQuote5(input2.entryPath)} "$@"`,
28096
+ `export DEEPLINE_HOST_URL=${shellQuote6(input2.hostUrl)}`,
28097
+ `export DEEPLINE_CONFIG_SCOPE=${shellQuote6(input2.scope)}`,
28098
+ `exec ${shellQuote6(input2.nodeBin)} ${shellQuote6(input2.entryPath)} "$@"`,
27759
28099
  ""
27760
28100
  ].join("\n"),
27761
28101
  { encoding: "utf8", mode: 493 }