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
@@ -608,10 +608,10 @@ var SDK_RELEASE = {
608
608
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
609
609
  // fields shipped in 0.1.153.
610
610
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
611
- version: "0.1.198",
611
+ version: "0.1.200",
612
612
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
613
613
  supportPolicy: {
614
- latest: "0.1.198",
614
+ latest: "0.1.200",
615
615
  minimumSupported: "0.1.53",
616
616
  deprecatedBelow: "0.1.53",
617
617
  commandMinimumSupported: [
@@ -1052,7 +1052,10 @@ var HttpClient = class {
1052
1052
  * @param path - API path (e.g. `"/api/v2/tools"`)
1053
1053
  */
1054
1054
  async get(path) {
1055
- return this.request(path, { method: "GET" });
1055
+ return this.request(path, {
1056
+ method: "GET",
1057
+ retryApiErrors: true
1058
+ });
1056
1059
  }
1057
1060
  async *streamSse(path, options) {
1058
1061
  const url = `${this.config.baseUrl}${path}`;
@@ -1326,7 +1329,6 @@ function resolveTimingWindow(input2) {
1326
1329
  // ../shared_libs/play-runtime/run-terminal-source.ts
1327
1330
  var PLAY_RUN_LEDGER_EVENT_SOURCES = [
1328
1331
  "worker",
1329
- "temporal",
1330
1332
  "convex",
1331
1333
  "coordinator",
1332
1334
  "system"
@@ -7033,7 +7035,7 @@ function isRecord4(value) {
7033
7035
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
7034
7036
  }
7035
7037
  function isSerializedDataset(value) {
7036
- return isRecord4(value) && value.kind === "dataset" && typeof value.count === "number" && Array.isArray(value.preview);
7038
+ return isRecord4(value) && value.kind === "dataset" && typeof value.count === "number" && (Array.isArray(value.preview) || typeof value.tableNamespace === "string");
7037
7039
  }
7038
7040
  function isPackagedDatasetOutput(value) {
7039
7041
  return isRecord4(value) && value.kind === "dataset" && isRecord4(value.preview) && Array.isArray(value.preview.rows);
@@ -7094,7 +7096,7 @@ function columnsFromDatasetSummary(summary) {
7094
7096
  function canonicalRowsInfoFromCandidate(input2) {
7095
7097
  const candidate = input2;
7096
7098
  if (isSerializedDataset(candidate.value)) {
7097
- const rawRows = rowArray(candidate.value.preview) ?? [];
7099
+ const rawRows = Array.isArray(candidate.value.preview) ? rowArray(candidate.value.preview) ?? [] : [];
7098
7100
  const totalRows2 = readNumber(candidate.value.count) ?? rawRows.length;
7099
7101
  const hasExplicitColumns = Array.isArray(candidate.value.columns) && candidate.value.columns.every((column) => typeof column === "string");
7100
7102
  const rawColumns = hasExplicitColumns ? candidate.value.columns : inferColumns(rawRows);
@@ -7322,6 +7324,13 @@ function collectSerializedDatasetRowsInfos(statusOrResult) {
7322
7324
  path: "result",
7323
7325
  output: candidates
7324
7326
  });
7327
+ if (isRecord4(result.output)) {
7328
+ collectDatasetCandidates({
7329
+ value: result.output,
7330
+ path: "result",
7331
+ output: candidates
7332
+ });
7333
+ }
7325
7334
  }
7326
7335
  candidates.push(...collectPackagedStepDatasetCandidates(statusOrResult));
7327
7336
  const seen = /* @__PURE__ */ new Set();
@@ -10440,22 +10449,22 @@ var PLAY_DEDUP_BACKENDS = {
10440
10449
 
10441
10450
  // ../shared_libs/play-runtime/scheduler-backend.ts
10442
10451
  var PLAY_SCHEDULER_BACKENDS = {
10443
- temporal: "temporal",
10444
10452
  cfWorkflows: "cf-workflows",
10453
+ /** Private legacy id retained only so old persisted rows can be interpreted. */
10454
+ postgres: "postgres",
10445
10455
  /**
10446
- * Private legacy id retained only so old persisted rows can be interpreted.
10447
- * It is not a selectable scheduler backend after the Hatchet hard cutover.
10456
+ * Postgres-native durable-execution scheduler (vendored Absurd engine). Runs
10457
+ * on the battle-tested run-state store without an external workflow engine.
10458
+ * Selected explicitly by the `absurd` profile.
10448
10459
  */
10449
- postgres: "postgres",
10450
- hatchet: "hatchet",
10460
+ absurd: "absurd",
10451
10461
  inProcess: "in-process"
10452
10462
  };
10453
10463
 
10454
10464
  // ../shared_libs/play-runtime/providers.ts
10455
10465
  var PLAY_RUNTIME_PROVIDER_IDS = {
10456
10466
  workersEdge: "workers_edge",
10457
- hatchet: "hatchet",
10458
- local: "local"
10467
+ absurd: "absurd"
10459
10468
  };
10460
10469
  var PLAY_RUNTIME_PROVIDERS = {
10461
10470
  workers_edge: {
@@ -10466,21 +10475,16 @@ var PLAY_RUNTIME_PROVIDERS = {
10466
10475
  artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
10467
10476
  label: "Cloudflare Dynamic Workflows + Dynamic Workers + DO dedup"
10468
10477
  },
10469
- hatchet: {
10470
- id: PLAY_RUNTIME_PROVIDER_IDS.hatchet,
10471
- scheduler: PLAY_SCHEDULER_BACKENDS.hatchet,
10478
+ absurd: {
10479
+ id: PLAY_RUNTIME_PROVIDER_IDS.absurd,
10480
+ scheduler: PLAY_SCHEDULER_BACKENDS.absurd,
10481
+ // Server runs execute on Daytona; the local-dev/test shape swaps the runner
10482
+ // axis to local_process (same as the local profile) via an explicit
10483
+ // runtimeBackend override at submit while tests drive local_process.
10472
10484
  runner: PLAY_RUNTIME_BACKENDS.daytona,
10473
10485
  dedup: PLAY_DEDUP_BACKENDS.inMemory,
10474
10486
  artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
10475
- label: "Hatchet scheduler + one-shot Daytona runner + receipt-backed in-process dedup"
10476
- },
10477
- local: {
10478
- id: PLAY_RUNTIME_PROVIDER_IDS.local,
10479
- scheduler: PLAY_SCHEDULER_BACKENDS.temporal,
10480
- runner: PLAY_RUNTIME_BACKENDS.localProcess,
10481
- dedup: PLAY_DEDUP_BACKENDS.inMemory,
10482
- artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
10483
- label: "Local Temporal scheduler + local subprocess runner (tests)"
10487
+ label: "Absurd (Postgres-native durable) scheduler + one-shot Daytona runner + receipt-backed in-process dedup"
10484
10488
  }
10485
10489
  };
10486
10490
  function defaultPlayRuntimeProvider() {
@@ -10493,7 +10497,7 @@ function resolvePlayRuntimeProvider(override) {
10493
10497
  return PLAY_RUNTIME_PROVIDERS[id];
10494
10498
  }
10495
10499
  throw new Error(
10496
- `Unknown play runtime provider "${id}". Expected one of: ${Object.keys(
10500
+ `Unsupported play runtime provider "${id}". Expected one of: ${Object.keys(
10497
10501
  PLAY_RUNTIME_PROVIDERS
10498
10502
  ).join(", ")}.`
10499
10503
  );
@@ -10745,14 +10749,219 @@ function parseReferencedPlayTarget2(target) {
10745
10749
  function isPrebuiltReferenceTarget(target) {
10746
10750
  return target.trim().toLowerCase().startsWith("prebuilt/");
10747
10751
  }
10752
+ function buildBarePrebuiltReferenceMessage(input2) {
10753
+ 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.`;
10754
+ }
10748
10755
  function buildBarePrebuiltReferenceError(input2) {
10749
- return new Error(
10750
- `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.`
10756
+ return new Error(buildBarePrebuiltReferenceMessage(input2));
10757
+ }
10758
+ function isPlayNotFoundError(error) {
10759
+ return error instanceof DeeplineError && (error.statusCode === 404 || error.code === "PLAY_NOT_FOUND" || error.code === "NOT_FOUND");
10760
+ }
10761
+ function isExplicitMissingPlayReferenceError(error) {
10762
+ if (!(error instanceof DeeplineError)) {
10763
+ return false;
10764
+ }
10765
+ if (error.statusCode !== 404 && error.code !== "PLAY_NOT_FOUND") {
10766
+ return false;
10767
+ }
10768
+ return /^play not found\b/i.test(error.message.trim());
10769
+ }
10770
+ function normalizePlayReferenceForMatch(value) {
10771
+ return value.trim().toLowerCase().replace(/^prebuilt\//, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
10772
+ }
10773
+ function playReferenceMatchTokens(value) {
10774
+ return normalizePlayReferenceForMatch(value).split("-").filter((token) => token.length > 1 && token !== "to" && token !== "and");
10775
+ }
10776
+ function playSuggestionReference(play) {
10777
+ if (play.reference?.trim()) {
10778
+ return play.reference.trim();
10779
+ }
10780
+ const ownerSlug = play.ownerSlug?.trim();
10781
+ return ownerSlug ? `${ownerSlug}/${play.name}` : play.name;
10782
+ }
10783
+ function scorePlayReferenceSuggestion(requested, play) {
10784
+ const parsed = parseReferencedPlayTarget2(requested);
10785
+ const requestedTrimmed = requested.trim();
10786
+ const requestedRef = requestedTrimmed.toLowerCase();
10787
+ const requestedName = parsed.unqualifiedPlayName;
10788
+ const requestedNorm = normalizePlayReferenceForMatch(requestedTrimmed);
10789
+ const requestedNameNorm = normalizePlayReferenceForMatch(requestedName);
10790
+ if (!requestedNorm && !requestedNameNorm) {
10791
+ return null;
10792
+ }
10793
+ const reference = playSuggestionReference(play);
10794
+ const referenceNorm = normalizePlayReferenceForMatch(reference);
10795
+ const nameNorm = normalizePlayReferenceForMatch(play.name);
10796
+ const candidateNamespace = reference.includes("/") ? reference.split("/")[0]?.toLowerCase() : null;
10797
+ const requestedNamespace = parsed.ownerSlug?.toLowerCase() ?? null;
10798
+ const aliases = (play.aliases ?? []).map(normalizePlayReferenceForMatch);
10799
+ const searchable = [referenceNorm, nameNorm, ...aliases].filter(Boolean);
10800
+ const requestedTokens = playReferenceMatchTokens(requestedName);
10801
+ const candidateTokens = [
10802
+ ...new Set(
10803
+ [reference, play.name, ...play.aliases ?? []].flatMap(
10804
+ playReferenceMatchTokens
10805
+ )
10806
+ )
10807
+ ];
10808
+ const hasTokenContainment = requestedTokens.length > 0 && requestedTokens.every((token) => candidateTokens.includes(token));
10809
+ let score = 0;
10810
+ if (reference.toLowerCase() === requestedRef) {
10811
+ score = 120;
10812
+ } else if (requestedNamespace && candidateNamespace === requestedNamespace && nameNorm === requestedNameNorm) {
10813
+ score = 110;
10814
+ } else if (nameNorm === requestedNameNorm || aliases.includes(requestedNameNorm)) {
10815
+ score = play.origin === "prebuilt" ? 100 : 95;
10816
+ } else if (requestedNamespace && candidateNamespace === requestedNamespace && searchable.some(
10817
+ (value) => value.includes(requestedNameNorm) || requestedNameNorm.includes(value)
10818
+ )) {
10819
+ score = 85;
10820
+ } else if (searchable.some(
10821
+ (value) => value.includes(requestedNorm) || requestedNorm.includes(value)
10822
+ )) {
10823
+ score = 70;
10824
+ } else if (requestedNameNorm && searchable.some(
10825
+ (value) => value.includes(requestedNameNorm) || requestedNameNorm.includes(value)
10826
+ )) {
10827
+ score = 60;
10828
+ } else if (hasTokenContainment) {
10829
+ score = requestedNamespace && candidateNamespace === requestedNamespace ? 58 : 50;
10830
+ }
10831
+ if (score <= 0) {
10832
+ return null;
10833
+ }
10834
+ if (play.origin === "prebuilt") {
10835
+ score += 3;
10836
+ }
10837
+ return {
10838
+ reference,
10839
+ name: play.name,
10840
+ origin: play.origin ?? null,
10841
+ score
10842
+ };
10843
+ }
10844
+ function rankPlayReferenceSuggestions(input2) {
10845
+ const byReference = /* @__PURE__ */ new Map();
10846
+ for (const play of input2.plays) {
10847
+ const suggestion = scorePlayReferenceSuggestion(input2.requested, play);
10848
+ if (!suggestion) continue;
10849
+ const existing = byReference.get(suggestion.reference);
10850
+ if (!existing || suggestion.score > existing.score) {
10851
+ byReference.set(suggestion.reference, suggestion);
10852
+ }
10853
+ }
10854
+ return [...byReference.values()].sort((left, right) => {
10855
+ if (right.score !== left.score) return right.score - left.score;
10856
+ if (left.origin === "prebuilt" && right.origin !== "prebuilt") return -1;
10857
+ if (right.origin === "prebuilt" && left.origin !== "prebuilt") return 1;
10858
+ return left.reference.localeCompare(right.reference);
10859
+ }).slice(0, input2.limit ?? 5);
10860
+ }
10861
+ function searchQueryForMissingPlayReference(target) {
10862
+ return parseReferencedPlayTarget2(target).unqualifiedPlayName.replace(/[-_./]+/g, " ").replace(/\s+/g, " ").trim();
10863
+ }
10864
+ function shellQuote2(value) {
10865
+ return `'${value.replace(/'/g, `'\\''`)}'`;
10866
+ }
10867
+ function buildPlayReferenceNotFoundMessage(input2) {
10868
+ const lines = [`Play not found: ${input2.requested}`];
10869
+ if (input2.suggestions.length > 0) {
10870
+ lines.push("", "Did you mean one of these?");
10871
+ for (const suggestion of input2.suggestions) {
10872
+ lines.push("", ` ${suggestion.reference}`);
10873
+ if (input2.command === "run") {
10874
+ lines.push(
10875
+ ` deepline plays run ${suggestion.reference} --input '{...}' --watch`
10876
+ );
10877
+ } else if (input2.command === "get") {
10878
+ lines.push(` deepline plays get ${suggestion.reference} --json`);
10879
+ } else if (input2.command === "check") {
10880
+ lines.push(` deepline plays check ${suggestion.reference} --json`);
10881
+ } else if (input2.command === "versions") {
10882
+ lines.push(
10883
+ ` deepline plays versions --name ${suggestion.reference} --json`
10884
+ );
10885
+ } else {
10886
+ lines.push(
10887
+ ` deepline plays describe ${suggestion.reference} --json`
10888
+ );
10889
+ }
10890
+ }
10891
+ }
10892
+ const searchQuery = searchQueryForMissingPlayReference(input2.requested);
10893
+ if (searchQuery) {
10894
+ lines.push(
10895
+ "",
10896
+ "Search visible plays:",
10897
+ ` deepline plays search ${shellQuote2(searchQuery)} --all --json`
10898
+ );
10899
+ }
10900
+ return lines.join("\n");
10901
+ }
10902
+ async function buildPlayReferenceNotFoundError(input2) {
10903
+ let suggestions = [];
10904
+ try {
10905
+ const searchQuery = searchQueryForMissingPlayReference(input2.target);
10906
+ const searchMatches = searchQuery ? await input2.client.searchPlays({
10907
+ query: searchQuery,
10908
+ scope: "all",
10909
+ compact: true
10910
+ }) : [];
10911
+ const plays = searchMatches.length > 0 ? searchMatches : await input2.client.listPlays();
10912
+ suggestions = rankPlayReferenceSuggestions({
10913
+ requested: input2.target,
10914
+ plays,
10915
+ limit: 5
10916
+ });
10917
+ } catch {
10918
+ suggestions = [];
10919
+ }
10920
+ const sourceError = input2.sourceError instanceof DeeplineError ? input2.sourceError : null;
10921
+ const code = sourceError?.code && sourceError.code !== "API_ERROR" ? sourceError.code : "PLAY_NOT_FOUND";
10922
+ return new DeeplineError(
10923
+ buildPlayReferenceNotFoundMessage({
10924
+ requested: input2.target,
10925
+ command: input2.command,
10926
+ suggestions
10927
+ }),
10928
+ sourceError?.statusCode ?? 404,
10929
+ code,
10930
+ sourceError?.details
10751
10931
  );
10752
10932
  }
10753
- async function assertCanonicalNamedPlayReference(client2, target) {
10933
+ async function isMissingRunPlayReferenceError(input2) {
10934
+ if (isExplicitMissingPlayReferenceError(input2.error)) {
10935
+ return true;
10936
+ }
10937
+ if (!(input2.error instanceof DeeplineError) || input2.error.statusCode !== 404 || !/^no artifact-backed revision found for play:/i.test(
10938
+ input2.error.message.trim()
10939
+ )) {
10940
+ return false;
10941
+ }
10942
+ try {
10943
+ await input2.client.getPlay(parseReferencedPlayTarget2(input2.playName).playName);
10944
+ return false;
10945
+ } catch (lookupError) {
10946
+ return isPlayNotFoundError(lookupError);
10947
+ }
10948
+ }
10949
+ async function assertCanonicalNamedPlayReference(client2, target, options = {}) {
10754
10950
  const parsed = parseReferencedPlayTarget2(target);
10755
- const detail = await client2.getPlay(parsed.playName);
10951
+ let detail;
10952
+ try {
10953
+ detail = await client2.getPlay(parsed.playName);
10954
+ } catch (error) {
10955
+ if (isPlayNotFoundError(error)) {
10956
+ throw await buildPlayReferenceNotFoundError({
10957
+ client: client2,
10958
+ target,
10959
+ command: options.command ?? "describe",
10960
+ sourceError: error
10961
+ });
10962
+ }
10963
+ throw error;
10964
+ }
10756
10965
  if (detail.play.ownerType === "deepline" && !isPrebuiltReferenceTarget(target)) {
10757
10966
  throw buildBarePrebuiltReferenceError({
10758
10967
  requested: target,
@@ -13488,10 +13697,7 @@ async function exportPlayStatusRows(client2, status, outPath, options = {}) {
13488
13697
  availableRows,
13489
13698
  datasetPath: options.datasetPath
13490
13699
  });
13491
- return {
13492
- path: writeCanonicalRowsCsv(guarded2, outPath),
13493
- rowsInfo: guarded2
13494
- };
13700
+ return { path: writeCanonicalRowsCsv(guarded2, outPath), rowsInfo: guarded2 };
13495
13701
  }
13496
13702
  if (rowsInfo.complete) {
13497
13703
  const guarded2 = assertDatasetHasExportableRows({
@@ -13500,7 +13706,10 @@ async function exportPlayStatusRows(client2, status, outPath, options = {}) {
13500
13706
  availableRows,
13501
13707
  datasetPath: options.datasetPath
13502
13708
  });
13503
- return { path: writeCanonicalRowsCsv(guarded2, outPath), rowsInfo: guarded2 };
13709
+ return {
13710
+ path: writeCanonicalRowsCsv(guarded2, outPath),
13711
+ rowsInfo: guarded2
13712
+ };
13504
13713
  }
13505
13714
  if (attempt < attempts && retryDelayMs > 0) {
13506
13715
  await sleep5(retryDelayMs);
@@ -13634,17 +13843,25 @@ function normalizePlayValidationError(error) {
13634
13843
  error instanceof DeeplineError ? error.details : void 0
13635
13844
  );
13636
13845
  }
13637
- function normalizePlayStartError(error, playName) {
13846
+ async function normalizePlayStartError(client2, error, playName, options = {}) {
13638
13847
  const activeRuns = extractActiveRunsFromError(error);
13639
- if (activeRuns.length === 0) {
13640
- return normalizePlayValidationError(error);
13848
+ if (activeRuns.length > 0) {
13849
+ return new DeeplineError(
13850
+ formatActiveRunConflictError({ playName, activeRuns }),
13851
+ error instanceof DeeplineError ? error.statusCode : 409,
13852
+ "ACTIVE_RUN_EXISTS",
13853
+ error instanceof DeeplineError ? error.details : void 0
13854
+ );
13641
13855
  }
13642
- return new DeeplineError(
13643
- formatActiveRunConflictError({ playName, activeRuns }),
13644
- error instanceof DeeplineError ? error.statusCode : 409,
13645
- "ACTIVE_RUN_EXISTS",
13646
- error instanceof DeeplineError ? error.details : void 0
13647
- );
13856
+ if (options.suggestMissingPlay && await isMissingRunPlayReferenceError({ client: client2, error, playName })) {
13857
+ return buildPlayReferenceNotFoundError({
13858
+ client: client2,
13859
+ target: playName,
13860
+ command: "run",
13861
+ sourceError: error
13862
+ });
13863
+ }
13864
+ return normalizePlayValidationError(error);
13648
13865
  }
13649
13866
  function renderServerResultView(value) {
13650
13867
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -13804,7 +14021,7 @@ function writeStartedPlayRun(input2) {
13804
14021
  );
13805
14022
  }
13806
14023
  function parsePlayRunOptions(args) {
13807
- 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.";
14024
+ 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.";
13808
14025
  let filePath = null;
13809
14026
  let playName = null;
13810
14027
  let input2 = null;
@@ -14157,7 +14374,9 @@ async function handlePlayCheck(args) {
14157
14374
  if (!isFileTarget(options.target)) {
14158
14375
  const client3 = new DeeplineClient();
14159
14376
  try {
14160
- await assertCanonicalNamedPlayReference(client3, options.target);
14377
+ await assertCanonicalNamedPlayReference(client3, options.target, {
14378
+ command: "check"
14379
+ });
14161
14380
  const play = await client3.describePlay(
14162
14381
  parseReferencedPlayTarget2(options.target).playName,
14163
14382
  { compact: true }
@@ -14427,8 +14646,8 @@ async function handleFileBackedRun(options) {
14427
14646
  waitTimeoutMs: options.waitTimeoutMs,
14428
14647
  noOpen: options.noOpen,
14429
14648
  progress
14430
- }).catch((error) => {
14431
- throw normalizePlayStartError(error, playName);
14649
+ }).catch(async (error) => {
14650
+ throw await normalizePlayStartError(client2, error, playName);
14432
14651
  })
14433
14652
  );
14434
14653
  if (finalStatus.status === "completed") {
@@ -14458,8 +14677,8 @@ async function handleFileBackedRun(options) {
14458
14677
  const started = await traceCliSpan(
14459
14678
  "cli.play_start_unwatched",
14460
14679
  { targetKind: "file", playName },
14461
- () => client2.startPlayRun(startRequest).catch((error) => {
14462
- throw normalizePlayStartError(error, playName);
14680
+ () => client2.startPlayRun(startRequest).catch(async (error) => {
14681
+ throw await normalizePlayStartError(client2, error, playName);
14463
14682
  })
14464
14683
  );
14465
14684
  const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
@@ -14517,7 +14736,9 @@ async function handleNamedRun(options) {
14517
14736
  return traceCliSpan(
14518
14737
  "cli.play_load_definition",
14519
14738
  { targetKind: "name", playName, skipped: false },
14520
- () => assertCanonicalNamedPlayReference(client2, playName)
14739
+ () => assertCanonicalNamedPlayReference(client2, playName, {
14740
+ command: "run"
14741
+ })
14521
14742
  );
14522
14743
  })() : (recordCliTrace({
14523
14744
  phase: "cli.play_load_definition",
@@ -14586,8 +14807,10 @@ async function handleNamedRun(options) {
14586
14807
  waitTimeoutMs: options.waitTimeoutMs,
14587
14808
  noOpen: options.noOpen,
14588
14809
  progress
14589
- }).catch((error) => {
14590
- throw normalizePlayStartError(error, playName);
14810
+ }).catch(async (error) => {
14811
+ throw await normalizePlayStartError(client2, error, playName, {
14812
+ suggestMissingPlay: true
14813
+ });
14591
14814
  })
14592
14815
  );
14593
14816
  if (finalStatus.status === "completed") {
@@ -14617,8 +14840,10 @@ async function handleNamedRun(options) {
14617
14840
  const started = await traceCliSpan(
14618
14841
  "cli.play_start_unwatched",
14619
14842
  { targetKind: "name", playName },
14620
- () => client2.startPlayRun(startRequest).catch((error) => {
14621
- throw normalizePlayStartError(error, playName);
14843
+ () => client2.startPlayRun(startRequest).catch(async (error) => {
14844
+ throw await normalizePlayStartError(client2, error, playName, {
14845
+ suggestMissingPlay: true
14846
+ });
14622
14847
  })
14623
14848
  );
14624
14849
  const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
@@ -15057,7 +15282,9 @@ async function handlePlayGet(args) {
15057
15282
  }
15058
15283
  }
15059
15284
  const playName = isFileTarget(target) ? extractPlayName(readFileSync7(resolve8(target), "utf-8"), resolve8(target)) : parseReferencedPlayTarget2(target).playName;
15060
- const detail = isFileTarget(target) ? await client2.getPlay(playName) : await assertCanonicalNamedPlayReference(client2, target);
15285
+ const detail = isFileTarget(target) ? await client2.getPlay(playName) : await assertCanonicalNamedPlayReference(client2, target, {
15286
+ command: "get"
15287
+ });
15061
15288
  const resolvedSource = detail.play.workingRevision?.sourceCode ?? detail.play.liveRevision?.sourceCode ?? detail.play.currentRevision?.sourceCode ?? detail.play.sourceCode ?? "";
15062
15289
  const materializedFile = outPath ? materializeRemotePlaySource({
15063
15290
  target,
@@ -15139,7 +15366,9 @@ async function handlePlayVersions(args) {
15139
15366
  }
15140
15367
  const client2 = new DeeplineClient();
15141
15368
  const jsonOutput = argsWantJson(args);
15142
- await assertCanonicalNamedPlayReference(client2, playName);
15369
+ await assertCanonicalNamedPlayReference(client2, playName, {
15370
+ command: "versions"
15371
+ });
15143
15372
  const versions = await client2.listPlayVersions(
15144
15373
  parseReferencedPlayTarget2(playName).playName
15145
15374
  );
@@ -15535,7 +15764,9 @@ async function handlePlayDescribe(args) {
15535
15764
  return 2;
15536
15765
  }
15537
15766
  const client2 = new DeeplineClient();
15538
- await assertCanonicalNamedPlayReference(client2, playName);
15767
+ await assertCanonicalNamedPlayReference(client2, playName, {
15768
+ command: "describe"
15769
+ });
15539
15770
  const play = await client2.describePlay(
15540
15771
  parseReferencedPlayTarget2(playName).playName,
15541
15772
  {
@@ -18736,7 +18967,8 @@ async function writeOutputCsv(outputPath, status, options) {
18736
18967
  }
18737
18968
  const selectedSourceRows = selectedSourceCsvRowCount(options);
18738
18969
  const shouldFetchBackingRows = options?.client && shouldFetchBackingRowsForEnrichExport(rowsInfo, status, {
18739
- selectedSourceRows
18970
+ selectedSourceRows,
18971
+ expectedAliases: options?.config ? collectConfigScalarAliasOrder(options.config) : []
18740
18972
  });
18741
18973
  if (options?.client && shouldFetchBackingRows) {
18742
18974
  let fetchedRowsInfo = null;
@@ -18773,6 +19005,7 @@ async function writeOutputCsv(outputPath, status, options) {
18773
19005
  const columns = orderEnrichCsvColumns(
18774
19006
  dataExportColumns(merged.rows, [
18775
19007
  ...merged.preferredColumns,
19008
+ ...options?.config ? collectConfigScalarAliasOrder(options.config) : [],
18776
19009
  ...rowsInfo.columns
18777
19010
  ]),
18778
19011
  options?.config
@@ -19430,26 +19663,39 @@ function shouldFetchBackingRowsForEnrichExport(rowsInfo, status, options = {}) {
19430
19663
  rowsInfo,
19431
19664
  status
19432
19665
  );
19666
+ const isGeneratedEnrichRows = tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE;
19433
19667
  if (terminalStatus === "failed" || terminalStatus === "cancelled") {
19434
- if (tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE && rowsInfo.source !== null && typeof options.selectedSourceRows === "number" && rowsInfo.rows.length < options.selectedSourceRows) {
19668
+ if (isGeneratedEnrichRows && rowsInfo.source !== null && typeof options.selectedSourceRows === "number" && rowsInfo.rows.length < options.selectedSourceRows) {
19435
19669
  return true;
19436
19670
  }
19437
- return tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE && (rowsInfo.recovered === true || hasPartialRunOutputWarning(status));
19671
+ return isGeneratedEnrichRows && (rowsInfo.recovered === true || hasPartialRunOutputWarning(status));
19438
19672
  }
19439
- if (tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE && typeof options.selectedSourceRows === "number" && rowsInfo.rows.length < options.selectedSourceRows) {
19673
+ if (isGeneratedEnrichRows && typeof options.selectedSourceRows === "number" && rowsInfo.rows.length < options.selectedSourceRows) {
19440
19674
  return true;
19441
19675
  }
19442
- if (tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE && typeof options.selectedSourceRows === "number" && options.selectedSourceRows > 0) {
19676
+ if (isGeneratedEnrichRows && (typeof options.selectedSourceRows === "number" && options.selectedSourceRows > 0 || rowsMissingExpectedAlias(rowsInfo.rows, options.expectedAliases))) {
19443
19677
  return true;
19444
19678
  }
19445
- if (tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE && hasFailedRowSignal(status)) {
19679
+ if (isGeneratedEnrichRows && hasFailedRowSignal(status)) {
19446
19680
  return true;
19447
19681
  }
19448
19682
  if (!rowsInfo.complete) {
19449
- return tableNamespace === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE;
19683
+ return isGeneratedEnrichRows;
19450
19684
  }
19451
19685
  return rowsInfo.rows.some((row) => hasLossyPreviewPlaceholder(row));
19452
19686
  }
19687
+ function rowsMissingExpectedAlias(rows, expectedAliases) {
19688
+ if (rows.length === 0 || !expectedAliases?.length) {
19689
+ return false;
19690
+ }
19691
+ const rowAliases = /* @__PURE__ */ new Set();
19692
+ for (const row of rows) {
19693
+ for (const key of Object.keys(row)) {
19694
+ rowAliases.add(normalizeAlias2(key));
19695
+ }
19696
+ }
19697
+ return expectedAliases.map((alias) => normalizeAlias2(alias)).filter(Boolean).some((alias) => !rowAliases.has(alias));
19698
+ }
19453
19699
  function hasPartialRunOutputWarning(status) {
19454
19700
  const warningLists = [
19455
19701
  recordField(status, "warnings"),
@@ -20015,6 +20261,18 @@ function collectEmptyWaterfallIssues(input2) {
20015
20261
  if (executionSignal === "all_condition_skipped" || executionSignal === "unknown" && waterfallChildrenAreStaticallySkipped(spec)) {
20016
20262
  return;
20017
20263
  }
20264
+ const statsEvidence = emptyWaterfallStatsEvidence(input2.status, spec);
20265
+ if (statsEvidence && input2.rowSetComplete && input2.outputPath) {
20266
+ issues.push(
20267
+ emptyWaterfallIssue({
20268
+ spec,
20269
+ selectedRows: statsEvidence.selectedRows,
20270
+ runId,
20271
+ followUpCommands
20272
+ })
20273
+ );
20274
+ return;
20275
+ }
20018
20276
  const logicalRows = /* @__PURE__ */ new Map();
20019
20277
  input2.rows.forEach((row, rowIndex) => {
20020
20278
  const sourceRowId = sourceRowIndexFromEnrichRow(
@@ -20036,24 +20294,34 @@ function collectEmptyWaterfallIssues(input2) {
20036
20294
  return;
20037
20295
  }
20038
20296
  const selectedRows = logicalRows.size;
20039
- const message = `Waterfall ${spec.alias} produced 0 values for ${selectedRows} selected row(s).`;
20040
- issues.push({
20041
- issue_id: `${spec.alias}-empty-waterfall`,
20042
- kind: "empty_waterfall",
20043
- severity: "needs_attention",
20044
- column: spec.alias,
20045
- selected_rows: selectedRows,
20046
- rows_with_value: 0,
20047
- rows_without_value: selectedRows,
20048
- message,
20049
- next_steps: enrichIssueNextSteps({ runId }),
20050
- follow_up_commands: followUpCommands,
20051
- ...spec.operation ? { operation: spec.operation } : {},
20052
- ...runId ? { run_id: runId } : {}
20053
- });
20297
+ issues.push(
20298
+ emptyWaterfallIssue({
20299
+ spec,
20300
+ selectedRows,
20301
+ runId,
20302
+ followUpCommands
20303
+ })
20304
+ );
20054
20305
  });
20055
20306
  return issues;
20056
20307
  }
20308
+ function emptyWaterfallIssue(input2) {
20309
+ const message = `Waterfall ${input2.spec.alias} produced 0 values for ${input2.selectedRows} selected row(s).`;
20310
+ return {
20311
+ issue_id: `${input2.spec.alias}-empty-waterfall`,
20312
+ kind: "empty_waterfall",
20313
+ severity: "needs_attention",
20314
+ column: input2.spec.alias,
20315
+ selected_rows: input2.selectedRows,
20316
+ rows_with_value: 0,
20317
+ rows_without_value: input2.selectedRows,
20318
+ message,
20319
+ next_steps: enrichIssueNextSteps({ runId: input2.runId }),
20320
+ follow_up_commands: input2.followUpCommands,
20321
+ ...input2.spec.operation ? { operation: input2.spec.operation } : {},
20322
+ ...input2.runId ? { run_id: input2.runId } : {}
20323
+ };
20324
+ }
20057
20325
  function waterfallChildrenAreStaticallySkipped(spec) {
20058
20326
  const childAliases = spec.childAliases ?? [];
20059
20327
  if (childAliases.length === 0 || !spec.childRunIfJsByAlias) {
@@ -20087,14 +20355,18 @@ function waterfallExecutionSignal(status, spec) {
20087
20355
  const executedSummary = parseExecutionSummary(
20088
20356
  execution?.["completed:executed"]
20089
20357
  );
20358
+ const reusedSummary = parseExecutionSummary(
20359
+ execution?.["completed:reused"]
20360
+ );
20090
20361
  const skippedConditionSummary = parseExecutionSummary(
20091
20362
  execution?.["skipped:condition"]
20092
20363
  );
20093
20364
  const executedCount = executedSummary?.count ?? 0;
20365
+ const reusedCount = reusedSummary?.count ?? 0;
20094
20366
  const skippedConditionCount = skippedConditionSummary?.count ?? 0;
20095
- const totalCount = executedSummary?.total ?? skippedConditionSummary?.total;
20096
- const onlyConditionSkips = totalCount !== void 0 && skippedConditionCount >= totalCount && executedCount <= skippedConditionCount;
20097
- if (executedCount > 0 && !onlyConditionSkips || numericFailedRowSignal(execution?.failed) > 0 || numericFailedRowSignal(stat2.failed) > 0 || numericFailedRowSignal(stat2.failedRows) > 0) {
20367
+ const totalCount = executedSummary?.total ?? reusedSummary?.total ?? skippedConditionSummary?.total;
20368
+ const onlyConditionSkips = totalCount !== void 0 && skippedConditionCount >= totalCount && executedCount + reusedCount <= skippedConditionCount;
20369
+ if (executedCount + reusedCount > 0 && !onlyConditionSkips || numericFailedRowSignal(execution?.failed) > 0 || numericFailedRowSignal(stat2.failed) > 0 || numericFailedRowSignal(stat2.failedRows) > 0) {
20098
20370
  return "executed";
20099
20371
  }
20100
20372
  if (!onlyConditionSkips) {
@@ -20107,6 +20379,48 @@ function waterfallExecutionSignal(status, spec) {
20107
20379
  }
20108
20380
  return "unknown";
20109
20381
  }
20382
+ function emptyWaterfallStatsEvidence(status, spec) {
20383
+ const summaries = collectColumnStats(status);
20384
+ const parentStats = summaries.map((summary) => summary[spec.alias]).filter(isRecord7);
20385
+ for (const stat2 of parentStats) {
20386
+ const nonEmpty = parseExecutionSummary(stat2.non_empty);
20387
+ if (nonEmpty?.total && nonEmpty.count === 0) {
20388
+ return { selectedRows: nonEmpty.total };
20389
+ }
20390
+ }
20391
+ const childAliases = spec.childAliases ?? [];
20392
+ if (childAliases.length === 0) {
20393
+ return null;
20394
+ }
20395
+ let selectedRows = 0;
20396
+ let sawStatsForEveryChild = true;
20397
+ for (const childAlias of childAliases) {
20398
+ const stat2 = summaries.map((summary) => summary[childAlias]).find(isRecord7);
20399
+ if (!stat2) {
20400
+ sawStatsForEveryChild = false;
20401
+ break;
20402
+ }
20403
+ const nonEmpty = parseExecutionSummary(stat2.non_empty);
20404
+ if ((nonEmpty?.count ?? 0) > 0) {
20405
+ return null;
20406
+ }
20407
+ const execution = isRecord7(stat2.execution) ? stat2.execution : null;
20408
+ const executed = parseExecutionSummary(execution?.["completed:executed"]);
20409
+ const reused = parseExecutionSummary(execution?.["completed:reused"]);
20410
+ const skipped = parseExecutionSummary(execution?.["skipped:condition"]);
20411
+ selectedRows = Math.max(
20412
+ selectedRows,
20413
+ nonEmpty?.total ?? 0,
20414
+ executed?.total ?? 0,
20415
+ reused?.total ?? 0,
20416
+ skipped?.total ?? 0
20417
+ );
20418
+ }
20419
+ if (!sawStatsForEveryChild || selectedRows <= 0 || waterfallExecutionSignal(status, spec) === "all_condition_skipped") {
20420
+ return null;
20421
+ }
20422
+ return { selectedRows };
20423
+ }
20110
20424
  function mergeEnrichFailureJobs(...jobGroups) {
20111
20425
  const merged = [];
20112
20426
  const seen = /* @__PURE__ */ new Set();
@@ -20926,12 +21240,34 @@ var ENRICH_FLATTENED_CONTROL_FIELDS = /* @__PURE__ */ new Set([
20926
21240
  "provider",
20927
21241
  "status"
20928
21242
  ]);
21243
+ var ENRICH_ALIAS_METADATA_FIELDS = /* @__PURE__ */ new Set([
21244
+ "_metadata",
21245
+ "metadata",
21246
+ "metadata.columns",
21247
+ "metadata__columns"
21248
+ ]);
21249
+ function isEnrichAliasPayloadField(field) {
21250
+ return !field.startsWith("_") && !ENRICH_FLATTENED_CONTROL_FIELDS.has(field) && !ENRICH_ALIAS_METADATA_FIELDS.has(field);
21251
+ }
20929
21252
  function materializeCsvCellValue(value) {
20930
21253
  if (value && typeof value === "object") {
20931
21254
  return csvSafeJsonString(value);
20932
21255
  }
20933
21256
  return value;
20934
21257
  }
21258
+ function compactArrayEnvelopeCompleteValue(value) {
21259
+ if (!isRecord7(value) || value.kind !== "array") {
21260
+ return null;
21261
+ }
21262
+ if (!Array.isArray(value.preview)) {
21263
+ return null;
21264
+ }
21265
+ const length = typeof value.length === "number" && Number.isFinite(value.length) ? Math.max(0, Math.trunc(value.length)) : null;
21266
+ if (length === null || length > value.preview.length) {
21267
+ return null;
21268
+ }
21269
+ return value.preview.slice(0, length);
21270
+ }
20935
21271
  function disambiguateCompactAiInferencePayload(value) {
20936
21272
  const parsed = parseMaybeJsonObject(value);
20937
21273
  if (!isRecord7(parsed) || !cellFailureError(parsed)) {
@@ -20968,6 +21304,10 @@ function compactAiInferenceCellForCsv(value) {
20968
21304
  function materializeEnrichAliasCellForCsv(row, alias, options) {
20969
21305
  const direct = row[alias];
20970
21306
  if (isRecord7(direct)) {
21307
+ const completeArray = compactArrayEnvelopeCompleteValue(direct);
21308
+ if (completeArray) {
21309
+ return materializeCsvCellValue(completeArray);
21310
+ }
20971
21311
  if (options?.compactAiCell && direct.status === "completed" && (isRecord7(direct.result) || Object.prototype.hasOwnProperty.call(direct, "extracted_json") || typeof direct.output === "string")) {
20972
21312
  return materializeCsvCellValue(compactAiInferenceCellForCsv(direct));
20973
21313
  }
@@ -20976,7 +21316,7 @@ function materializeEnrichAliasCellForCsv(row, alias, options) {
20976
21316
  }
20977
21317
  const directCells = [];
20978
21318
  for (const [field, value] of Object.entries(direct)) {
20979
- if (ENRICH_FLATTENED_CONTROL_FIELDS.has(field)) {
21319
+ if (!isEnrichAliasPayloadField(field)) {
20980
21320
  continue;
20981
21321
  }
20982
21322
  if (isNonEmptyCsvCell(value)) {
@@ -21006,7 +21346,7 @@ function materializeEnrichAliasCellForCsv(row, alias, options) {
21006
21346
  }
21007
21347
  }
21008
21348
  const cells = aliasFlattenedCells(row, alias).filter(({ field, value }) => {
21009
- if (ENRICH_FLATTENED_CONTROL_FIELDS.has(field)) {
21349
+ if (!isEnrichAliasPayloadField(field)) {
21010
21350
  return false;
21011
21351
  }
21012
21352
  return isNonEmptyCsvCell(value);
@@ -24050,7 +24390,7 @@ var EXIT_AUTH2 = 1;
24050
24390
  var EXIT_SERVER3 = 2;
24051
24391
  var MAX_PROMPT_LENGTH = 8e3;
24052
24392
  var MAX_BODY_BYTES = 64 * 1024;
24053
- function shellQuote2(arg) {
24393
+ function shellQuote3(arg) {
24054
24394
  return `'${arg.replace(/'/g, `'\\''`)}'`;
24055
24395
  }
24056
24396
  function hasClaudeBinary() {
@@ -24223,7 +24563,7 @@ async function handleQuickstart(options) {
24223
24563
  }
24224
24564
  progress.complete();
24225
24565
  const { prompt, workflowId } = outcome;
24226
- const claudeCommand = `claude ${shellQuote2(prompt)}`;
24566
+ const claudeCommand = `claude ${shellQuote3(prompt)}`;
24227
24567
  const claudeAvailable = hasClaudeBinary();
24228
24568
  const willLaunch = options.launch !== false && !jsonOutput && interactive && claudeAvailable;
24229
24569
  printCommandEnvelope(
@@ -26157,7 +26497,7 @@ function parseExecuteOptions(args) {
26157
26497
  function safeFileStem(value) {
26158
26498
  return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "tool";
26159
26499
  }
26160
- function shellQuote3(value) {
26500
+ function shellQuote4(value) {
26161
26501
  return `'${value.replace(/'/g, `'\\''`)}'`;
26162
26502
  }
26163
26503
  function powerShellQuote(value) {
@@ -26227,7 +26567,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
26227
26567
  path: scriptPath,
26228
26568
  sourceCode: script,
26229
26569
  projectDir,
26230
- macCopyCommand: `mkdir -p ${shellQuote3(projectDir)} && cp ${shellQuote3(scriptPath)} ${shellQuote3(`${projectDir}/${fileName}`)}`,
26570
+ macCopyCommand: `mkdir -p ${shellQuote4(projectDir)} && cp ${shellQuote4(scriptPath)} ${shellQuote4(`${projectDir}/${fileName}`)}`,
26231
26571
  windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
26232
26572
  };
26233
26573
  }
@@ -26250,7 +26590,7 @@ function buildToolExecuteBaseEnvelope(input2) {
26250
26590
  envelope,
26251
26591
  "output"
26252
26592
  );
26253
- const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote3(JSON.stringify(input2.params))} --json`;
26593
+ const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote4(JSON.stringify(input2.params))} --json`;
26254
26594
  const actions = input2.listConversion ? [
26255
26595
  {
26256
26596
  label: "next",
@@ -27328,7 +27668,7 @@ function hasCommand(command) {
27328
27668
  });
27329
27669
  return result.status === 0;
27330
27670
  }
27331
- function shellQuote4(arg) {
27671
+ function shellQuote5(arg) {
27332
27672
  return `'${arg.replace(/'/g, `'\\''`)}'`;
27333
27673
  }
27334
27674
  function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES) {
@@ -27336,7 +27676,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
27336
27676
  const npxInstall = {
27337
27677
  command: "npx",
27338
27678
  args: npxArgs,
27339
- manualCommand: `npx ${npxArgs.map(shellQuote4).join(" ")}`
27679
+ manualCommand: `npx ${npxArgs.map(shellQuote5).join(" ")}`
27340
27680
  };
27341
27681
  if (hasCommand("bunx")) {
27342
27682
  const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames);
@@ -27344,7 +27684,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
27344
27684
  {
27345
27685
  command: "bunx",
27346
27686
  args: bunxArgs,
27347
- manualCommand: `bunx ${bunxArgs.map(shellQuote4).join(" ")}`
27687
+ manualCommand: `bunx ${bunxArgs.map(shellQuote5).join(" ")}`
27348
27688
  },
27349
27689
  npxInstall
27350
27690
  ];
@@ -27511,14 +27851,14 @@ function posixShellQuote(value) {
27511
27851
  function windowsCmdQuote(value) {
27512
27852
  return `"${value.replace(/"/g, '""')}"`;
27513
27853
  }
27514
- function shellQuote5(value) {
27854
+ function shellQuote6(value) {
27515
27855
  if (process.platform === "win32") {
27516
27856
  return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : windowsCmdQuote(value);
27517
27857
  }
27518
27858
  return posixShellQuote(value);
27519
27859
  }
27520
27860
  function buildSourceUpdateCommand(sourceRoot) {
27521
- const quotedRoot = shellQuote5(sourceRoot);
27861
+ const quotedRoot = shellQuote6(sourceRoot);
27522
27862
  const cdCommand = process.platform === "win32" ? `cd /d ${quotedRoot}` : `cd ${quotedRoot}`;
27523
27863
  return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
27524
27864
  }
@@ -27530,7 +27870,7 @@ function buildSidecarProjectConfigCommand(versionDir, nodeBin) {
27530
27870
  "fs.mkdirSync(dir,{recursive:true});",
27531
27871
  `fs.writeFileSync(path.join(dir,'package.json'),${JSON.stringify(NPM_SDK_SIDECAR_PACKAGE_JSON)});`
27532
27872
  ].join("");
27533
- return `${shellQuote5(nodeBin)} -e ${shellQuote5(script)} ${shellQuote5(versionDir)}`;
27873
+ return `${shellQuote6(nodeBin)} -e ${shellQuote6(script)} ${shellQuote6(versionDir)}`;
27534
27874
  }
27535
27875
  function sidecarStateDir(input2) {
27536
27876
  const scope = input2.env.DEEPLINE_CONFIG_SCOPE?.trim();
@@ -27569,7 +27909,7 @@ function resolvePythonSidecarUpdatePlan(options) {
27569
27909
  const packageSpec = options.packageSpec || "deepline@latest";
27570
27910
  const npmCommand = "npm";
27571
27911
  const versionDir = join14(stateDir, "versions", "<version>");
27572
- const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote5(versionDir)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote5).join(" ")} ${shellQuote5(packageSpec)}`;
27912
+ const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote6(versionDir)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote6).join(" ")} ${shellQuote6(packageSpec)}`;
27573
27913
  return {
27574
27914
  kind: "python-sidecar",
27575
27915
  stateDir,
@@ -27649,7 +27989,7 @@ function resolveUpdatePlan(options = {}) {
27649
27989
  command,
27650
27990
  args,
27651
27991
  ...installPrefix ? { installPrefix } : {},
27652
- manualCommand: `${command} ${args.map(shellQuote5).join(" ")}`
27992
+ manualCommand: `${command} ${args.map(shellQuote6).join(" ")}`
27653
27993
  };
27654
27994
  }
27655
27995
  var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
@@ -27810,9 +28150,9 @@ function writeSidecarLauncher(input2) {
27810
28150
  input2.path,
27811
28151
  [
27812
28152
  "#!/usr/bin/env sh",
27813
- `export DEEPLINE_HOST_URL=${shellQuote5(input2.hostUrl)}`,
27814
- `export DEEPLINE_CONFIG_SCOPE=${shellQuote5(input2.scope)}`,
27815
- `exec ${shellQuote5(input2.nodeBin)} ${shellQuote5(input2.entryPath)} "$@"`,
28153
+ `export DEEPLINE_HOST_URL=${shellQuote6(input2.hostUrl)}`,
28154
+ `export DEEPLINE_CONFIG_SCOPE=${shellQuote6(input2.scope)}`,
28155
+ `exec ${shellQuote6(input2.nodeBin)} ${shellQuote6(input2.entryPath)} "$@"`,
27816
28156
  ""
27817
28157
  ].join("\n"),
27818
28158
  { encoding: "utf8", mode: 493 }