deepline 0.2.55 → 0.2.57

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 (49) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +14 -0
  2. package/dist/bundling-sources/sdk/src/http.ts +19 -1
  3. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  4. package/dist/bundling-sources/sdk/src/stream-reconnect.ts +6 -0
  5. package/dist/bundling-sources/sdk/src/types.ts +7 -0
  6. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +146 -12
  7. package/dist/bundling-sources/shared_libs/play-runtime/batch-runtime.ts +6 -3
  8. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +1631 -748
  9. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +20 -0
  10. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +81 -52
  11. package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +146 -6
  12. package/dist/bundling-sources/shared_libs/play-runtime/gateway-auth-session.ts +56 -22
  13. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +14 -11
  14. package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +21 -2
  15. package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +81 -21
  16. package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +7 -0
  17. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +3 -0
  18. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +21 -0
  19. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +27 -2
  20. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-runtime-watchdog.ts +49 -10
  21. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +96 -3
  22. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +341 -67
  23. package/dist/bundling-sources/shared_libs/play-runtime/runtime-capacity-policy.ts +10 -0
  24. package/dist/bundling-sources/shared_libs/play-runtime/runtime-contract.ts +8 -1
  25. package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-pg.ts +17 -2
  26. package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver.ts +4 -1
  27. package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-store-adapter.ts +17 -1
  28. package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-writer.ts +16 -2
  29. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-row-writer.ts +25 -0
  30. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +3 -0
  31. package/dist/bundling-sources/shared_libs/play-runtime/suspension.ts +2 -0
  32. package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +80 -1
  33. package/dist/bundling-sources/shared_libs/plays/docflow.ts +113 -14
  34. package/dist/bundling-sources/shared_libs/plays/play-exports.ts +53 -4
  35. package/dist/bundling-sources/shared_libs/security/safe-fetch.ts +9 -0
  36. package/dist/bundling-sources/shared_libs/security/safe-outbound-fetch.ts +85 -48
  37. package/dist/cli/index.js +429 -54
  38. package/dist/cli/index.mjs +409 -28
  39. package/dist/{compiler-manifest-Bl8kmLx9.d.mts → compiler-manifest-TgaC4DeD.d.mts} +13 -0
  40. package/dist/{compiler-manifest-Bl8kmLx9.d.ts → compiler-manifest-TgaC4DeD.d.ts} +13 -0
  41. package/dist/index.d.mts +21 -3
  42. package/dist/index.d.ts +21 -3
  43. package/dist/index.js +29 -2
  44. package/dist/index.mjs +29 -2
  45. package/dist/install-integrity.json +2 -2
  46. package/dist/plays/bundle-play-file.d.mts +2 -2
  47. package/dist/plays/bundle-play-file.d.ts +2 -2
  48. package/dist/plays/bundle-play-file.mjs +78 -18
  49. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -185,7 +185,7 @@ function configureProxyFromEnv() {
185
185
  configureProxyFromEnv();
186
186
 
187
187
  // src/cli/index.ts
188
- var import_promises8 = require("fs/promises");
188
+ var import_promises9 = require("fs/promises");
189
189
  var import_node_path26 = require("path");
190
190
  var import_node_os19 = require("os");
191
191
  var import_commander4 = require("commander");
@@ -1044,7 +1044,7 @@ var SDK_RELEASE = {
1044
1044
  // 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
1045
1045
  // exposed storage-dependent synchronous access. This deliberate minor
1046
1046
  // release keeps lazy paging semantics independent of row residency.
1047
- version: "0.2.55",
1047
+ version: "0.2.57",
1048
1048
  contracts: {
1049
1049
  api: {
1050
1050
  name: "sdk-http-api",
@@ -1627,9 +1627,26 @@ var HttpClient = class {
1627
1627
  if (error instanceof AuthError || error instanceof DeeplineError) {
1628
1628
  throw error;
1629
1629
  }
1630
- lastError = error instanceof Error ? error : new Error(String(error));
1630
+ const normalized = error instanceof Error ? error : new Error(String(error));
1631
+ if (isAbortLikeError(normalized) && options?.signal?.aborted) {
1632
+ throw new DeeplineError(
1633
+ `Stream from ${this.config.baseUrl} was aborted by the caller.`,
1634
+ void 0,
1635
+ "ABORTED"
1636
+ );
1637
+ }
1638
+ lastError = normalized;
1631
1639
  }
1632
1640
  }
1641
+ if (lastError && isAbortLikeError(lastError)) {
1642
+ throw new DeeplineError(
1643
+ withCoworkNetworkHint(
1644
+ `Unable to stream from ${this.config.baseUrl}. The remote stream was interrupted.`
1645
+ ),
1646
+ void 0,
1647
+ "PLAY_STREAM_NETWORK_ABORTED"
1648
+ );
1649
+ }
1633
1650
  throw new DeeplineError(
1634
1651
  withCoworkNetworkHint(
1635
1652
  lastError?.message ? `Unable to stream from ${this.config.baseUrl}. ${lastError.message}` : `Unable to stream from ${this.config.baseUrl}.`
@@ -1892,6 +1909,9 @@ function streamReconnectDelayMs(attempt) {
1892
1909
  return Math.max(1, Math.floor(Math.random() * (cappedExponentialMs + 1)));
1893
1910
  }
1894
1911
  function isTransientPlayStreamError(error) {
1912
+ if (error instanceof DeeplineError && error.code === "PLAY_STREAM_NETWORK_ABORTED") {
1913
+ return true;
1914
+ }
1895
1915
  if (error instanceof DeeplineError && typeof error.statusCode === "number") {
1896
1916
  return error.statusCode >= 500 && error.statusCode < 600;
1897
1917
  }
@@ -2044,6 +2064,7 @@ var RUNTIME_RECEIPT_OUTPUT_MAX_BYTES = 10 * 1024 * 1024;
2044
2064
  var RUNTIME_RECEIPT_COMPLETION_BUFFER_MAX_BYTES = 32 * 1024 * 1024;
2045
2065
  var RUNNER_TERMINAL_PUSH_MAX_BODY_BYTES = 16 * 1024 * 1024;
2046
2066
  var RUNTIME_RECEIPT_GATEWAY_BATCH_MAX_BYTES = 12 * 1024 * 1024;
2067
+ var RUNTIME_RECEIPT_WRITER_TARGET_BATCH_BYTES = 4 * 1024 * 1024;
2047
2068
  var RUNNER_POST_TERMINAL_DIAGNOSTIC_MAX_BYTES = 64 * 1024;
2048
2069
 
2049
2070
  // ../shared_libs/play-runtime/ledger-safe-payload.ts
@@ -4626,6 +4647,10 @@ var DeeplineClient = class {
4626
4647
  ...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
4627
4648
  ...request.force ? { force: true } : {},
4628
4649
  ...forceToolRefresh ? { forceToolRefresh: true } : {},
4650
+ ...typeof request.maxConcurrentExternalCalls === "number" ? {
4651
+ maxConcurrentExternalCalls: request.maxConcurrentExternalCalls
4652
+ } : {},
4653
+ ...typeof request.maxConcurrentRows === "number" ? { maxConcurrentRows: request.maxConcurrentRows } : {},
4629
4654
  ...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
4630
4655
  // Profile selection is the API's job, not the CLI's. The server
4631
4656
  // defaults to absurd; callers normally omit this field.
@@ -4678,6 +4703,8 @@ var DeeplineClient = class {
4678
4703
  ...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
4679
4704
  ...request.force ? { force: true } : {},
4680
4705
  ...forceToolRefresh ? { forceToolRefresh: true } : {},
4706
+ ...typeof request.maxConcurrentExternalCalls === "number" ? { maxConcurrentExternalCalls: request.maxConcurrentExternalCalls } : {},
4707
+ ...typeof request.maxConcurrentRows === "number" ? { maxConcurrentRows: request.maxConcurrentRows } : {},
4681
4708
  ...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
4682
4709
  ...request.profile ? { profile: request.profile } : {},
4683
4710
  ...integrationMode ? { integrationMode } : {},
@@ -8758,14 +8785,14 @@ function invoiceDateText(createdAt) {
8758
8785
  }
8759
8786
  function invoiceLine(entry, compact) {
8760
8787
  const amount = invoiceAmountText(entry.amount_cents, entry.currency);
8761
- const link = entry.url ?? "(no link)";
8788
+ const link2 = entry.url ?? "(no link)";
8762
8789
  if (compact) {
8763
8790
  return [
8764
8791
  entry.id,
8765
8792
  invoiceDateText(entry.created_at),
8766
8793
  amount,
8767
8794
  entry.status,
8768
- link
8795
+ link2
8769
8796
  ].join(" | ");
8770
8797
  }
8771
8798
  return [
@@ -8773,7 +8800,7 @@ function invoiceLine(entry, compact) {
8773
8800
  entry.description,
8774
8801
  amount,
8775
8802
  entry.status,
8776
- link
8803
+ link2
8777
8804
  ].join(" | ");
8778
8805
  }
8779
8806
  async function handleInvoices(options) {
@@ -10917,7 +10944,7 @@ Examples:
10917
10944
  }
10918
10945
 
10919
10946
  // src/cli/commands/enrich.ts
10920
- var import_promises5 = require("fs/promises");
10947
+ var import_promises6 = require("fs/promises");
10921
10948
  var import_node_os10 = require("os");
10922
10949
  var import_node_path15 = require("path");
10923
10950
  var import_commander2 = require("commander");
@@ -10925,6 +10952,7 @@ var import_commander2 = require("commander");
10925
10952
  // src/cli/commands/play.ts
10926
10953
  var import_node_crypto6 = require("crypto");
10927
10954
  var import_node_fs12 = require("fs");
10955
+ var import_promises5 = require("fs/promises");
10928
10956
  var import_node_path14 = require("path");
10929
10957
  var import_sync5 = require("csv-parse/sync");
10930
10958
 
@@ -16617,6 +16645,12 @@ function isDefinePlayCall(node) {
16617
16645
  }
16618
16646
  return false;
16619
16647
  }
16648
+ function definePlayName(node) {
16649
+ const expression = unwrapStaticExpression(node);
16650
+ if (!expression || expression.type !== "CallExpression") return null;
16651
+ const first = astArray(expression.arguments)[0] ?? null;
16652
+ return first?.type === "Literal" && typeof first.value === "string" ? first.value : null;
16653
+ }
16620
16654
  function listPlayFileExports(sourceCode) {
16621
16655
  const ast = parsePlaySourceForAnalysis(sourceCode);
16622
16656
  if (!ast) return null;
@@ -16666,13 +16700,24 @@ function listPlayFileExports(sourceCode) {
16666
16700
  if (defaultIsPlay) {
16667
16701
  const aliases = defaultLocalName ? [...namedExports.entries()].filter(([, local]) => local === defaultLocalName).map(([exported]) => exported) : [];
16668
16702
  if (defaultLocalName) aliasedLocals.add(defaultLocalName);
16669
- exports2.push({ name: PLAY_DEFAULT_EXPORT, aliases });
16703
+ exports2.push({
16704
+ name: PLAY_DEFAULT_EXPORT,
16705
+ aliases,
16706
+ playName: definePlayName(
16707
+ defaultLocalName ? declarations.get(defaultLocalName) ?? null : defaultExpression
16708
+ )
16709
+ });
16670
16710
  }
16671
16711
  for (const [exportedName, localName] of namedExports) {
16672
16712
  if (exportedName === PLAY_DEFAULT_EXPORT) continue;
16673
16713
  if (aliasedLocals.has(localName)) continue;
16674
- if (!isDefinePlayCall(declarations.get(localName) ?? null)) continue;
16675
- exports2.push({ name: exportedName, aliases: [] });
16714
+ const declaration = declarations.get(localName) ?? null;
16715
+ if (!isDefinePlayCall(declaration)) continue;
16716
+ exports2.push({
16717
+ name: exportedName,
16718
+ aliases: [],
16719
+ playName: definePlayName(declaration)
16720
+ });
16676
16721
  }
16677
16722
  return exports2;
16678
16723
  }
@@ -17577,6 +17622,31 @@ ${hint}`;
17577
17622
  });
17578
17623
  }
17579
17624
 
17625
+ // ../shared_libs/play-runtime/governor/policy.ts
17626
+ var DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS = 64;
17627
+ var MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS = 256;
17628
+ var MAX_CONFIGURABLE_CONCURRENT_ROWS = 1e3;
17629
+ function resolveMaxConcurrentExternalCalls(requested) {
17630
+ if (requested === void 0 || requested === null) {
17631
+ return DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS;
17632
+ }
17633
+ if (!Number.isSafeInteger(requested) || requested < 1 || requested > MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS) {
17634
+ throw new Error(
17635
+ `maxConcurrentExternalCalls must be a whole number from 1 through ${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS}.`
17636
+ );
17637
+ }
17638
+ return requested;
17639
+ }
17640
+ function resolveMaxConcurrentRows(requested) {
17641
+ if (requested === void 0 || requested === null) return null;
17642
+ if (!Number.isSafeInteger(requested) || requested < 1 || requested > MAX_CONFIGURABLE_CONCURRENT_ROWS) {
17643
+ throw new Error(
17644
+ `maxConcurrentRows must be a whole number from 1 through ${MAX_CONFIGURABLE_CONCURRENT_ROWS}.`
17645
+ );
17646
+ }
17647
+ return requested;
17648
+ }
17649
+
17580
17650
  // ../shared_libs/play-runtime/sandbox-runtime-limits.ts
17581
17651
  var PLAY_SANDBOX_SIZE_LIMITS = {
17582
17652
  standard: {
@@ -17801,6 +17871,7 @@ function stripLeadingTimestamp(line) {
17801
17871
  // ../shared_libs/play-runtime/fixture-behavior.ts
17802
17872
  var FIXTURE_BEHAVIOR_VERSION = 1;
17803
17873
  var FIXTURE_BEHAVIOR_RESPONSE_VERSION = 2;
17874
+ var FIXTURE_BEHAVIOR_REPLAY_VERSION = 3;
17804
17875
  var MAX_FIXTURE_RESPONSE_DELAY_SAMPLES = 256;
17805
17876
  var MAX_FIXTURE_RESPONSE_DELAY_MS = 8 * 6e4;
17806
17877
  var MAX_FIXTURE_RESPONSE_ERROR_MESSAGE_LENGTH = 500;
@@ -17812,7 +17883,11 @@ function validateFixtureBehavior(value) {
17812
17883
  return { ok: false, error: "fixtureBehavior must be a JSON object." };
17813
17884
  }
17814
17885
  const record = value;
17815
- const supportedKeys = record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION ? /* @__PURE__ */ new Set(["version", "responseSamples"]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
17886
+ const supportedKeys = record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? /* @__PURE__ */ new Set([
17887
+ "version",
17888
+ "responseSamples",
17889
+ ...record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION ? ["replayBundle"] : []
17890
+ ]) : /* @__PURE__ */ new Set(["version", "responseDelaySamplesMs"]);
17816
17891
  const unknownKeys = Object.keys(record).filter(
17817
17892
  (key) => !supportedKeys.has(key)
17818
17893
  );
@@ -17822,13 +17897,13 @@ function validateFixtureBehavior(value) {
17822
17897
  error: `Unsupported fixtureBehavior field "${unknownKeys[0]}".`
17823
17898
  };
17824
17899
  }
17825
- if (record.version !== FIXTURE_BEHAVIOR_VERSION && record.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION) {
17900
+ if (record.version !== FIXTURE_BEHAVIOR_VERSION && record.version !== FIXTURE_BEHAVIOR_RESPONSE_VERSION && record.version !== FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17826
17901
  return {
17827
17902
  ok: false,
17828
- error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}.`
17903
+ error: `fixtureBehavior.version must be ${FIXTURE_BEHAVIOR_VERSION} or ${FIXTURE_BEHAVIOR_RESPONSE_VERSION}, or ${FIXTURE_BEHAVIOR_REPLAY_VERSION}.`
17829
17904
  };
17830
17905
  }
17831
- if (record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION) {
17906
+ if (record.version === FIXTURE_BEHAVIOR_RESPONSE_VERSION || record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
17832
17907
  if (!Array.isArray(record.responseSamples) || record.responseSamples.length === 0 || record.responseSamples.length > MAX_FIXTURE_RESPONSE_DELAY_SAMPLES) {
17833
17908
  return {
17834
17909
  ok: false,
@@ -17935,6 +18010,72 @@ function validateFixtureBehavior(value) {
17935
18010
  ...httpError ? { httpError } : {}
17936
18011
  });
17937
18012
  }
18013
+ let replayBundle;
18014
+ if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
18015
+ if (!record.replayBundle || typeof record.replayBundle !== "object" || Array.isArray(record.replayBundle)) {
18016
+ return {
18017
+ ok: false,
18018
+ error: "fixtureBehavior.replayBundle must be an object."
18019
+ };
18020
+ }
18021
+ const replay = record.replayBundle;
18022
+ const replayUnknownKeys = Object.keys(replay).filter(
18023
+ (key) => key !== "bundleId" && key !== "manifestSha256" && key !== "syntheticFallbackToolIds"
18024
+ );
18025
+ if (replayUnknownKeys.length > 0) {
18026
+ return {
18027
+ ok: false,
18028
+ error: `Unsupported fixtureBehavior.replayBundle field "${replayUnknownKeys[0]}".`
18029
+ };
18030
+ }
18031
+ const digestPattern = /^[a-f0-9]{64}$/;
18032
+ if (typeof replay.bundleId !== "string" || !digestPattern.test(replay.bundleId)) {
18033
+ return {
18034
+ ok: false,
18035
+ error: "fixtureBehavior.replayBundle.bundleId must be a lowercase SHA-256 digest."
18036
+ };
18037
+ }
18038
+ if (typeof replay.manifestSha256 !== "string" || !digestPattern.test(replay.manifestSha256)) {
18039
+ return {
18040
+ ok: false,
18041
+ error: "fixtureBehavior.replayBundle.manifestSha256 must be a lowercase SHA-256 digest."
18042
+ };
18043
+ }
18044
+ let syntheticFallbackToolIds;
18045
+ if (replay.syntheticFallbackToolIds !== void 0) {
18046
+ if (!Array.isArray(replay.syntheticFallbackToolIds) || replay.syntheticFallbackToolIds.length === 0 || replay.syntheticFallbackToolIds.length > 32) {
18047
+ return {
18048
+ ok: false,
18049
+ error: "fixtureBehavior.replayBundle.syntheticFallbackToolIds must contain 1-32 tool ids."
18050
+ };
18051
+ }
18052
+ syntheticFallbackToolIds = [];
18053
+ for (const rawToolId of replay.syntheticFallbackToolIds) {
18054
+ if (typeof rawToolId !== "string" || rawToolId !== rawToolId.trim().toLowerCase() || !/^[a-z0-9][a-z0-9_.-]*$/.test(rawToolId) || rawToolId.length > 250 || syntheticFallbackToolIds.includes(rawToolId)) {
18055
+ return {
18056
+ ok: false,
18057
+ error: "fixtureBehavior.replayBundle.syntheticFallbackToolIds contains an invalid tool id."
18058
+ };
18059
+ }
18060
+ syntheticFallbackToolIds.push(rawToolId);
18061
+ }
18062
+ }
18063
+ replayBundle = {
18064
+ bundleId: replay.bundleId,
18065
+ manifestSha256: replay.manifestSha256,
18066
+ ...syntheticFallbackToolIds ? { syntheticFallbackToolIds } : {}
18067
+ };
18068
+ }
18069
+ if (record.version === FIXTURE_BEHAVIOR_REPLAY_VERSION) {
18070
+ return {
18071
+ ok: true,
18072
+ behavior: {
18073
+ version: FIXTURE_BEHAVIOR_REPLAY_VERSION,
18074
+ responseSamples: samples2,
18075
+ replayBundle
18076
+ }
18077
+ };
18078
+ }
17938
18079
  return {
17939
18080
  ok: true,
17940
18081
  behavior: {
@@ -18027,6 +18168,114 @@ var PLAY_RUN_RESERVED_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
18027
18168
  "--debug-map-latency",
18028
18169
  "--debug-fixture-provider-pacing"
18029
18170
  ]);
18171
+ async function pathExistsIncludingSymlink(path) {
18172
+ try {
18173
+ await (0, import_promises5.lstat)(path);
18174
+ return true;
18175
+ } catch (error) {
18176
+ if (error.code === "ENOENT") {
18177
+ return false;
18178
+ }
18179
+ throw error;
18180
+ }
18181
+ }
18182
+ function runIdFileTempPath(destination) {
18183
+ return (0, import_node_path14.join)(
18184
+ (0, import_node_path14.dirname)(destination),
18185
+ `.${(0, import_node_path14.basename)(destination)}.${process.pid}.${(0, import_node_crypto6.randomUUID)()}.tmp`
18186
+ );
18187
+ }
18188
+ async function removeRunIdTempFile(path) {
18189
+ try {
18190
+ await (0, import_promises5.unlink)(path);
18191
+ } catch (error) {
18192
+ if (error.code !== "ENOENT") {
18193
+ throw error;
18194
+ }
18195
+ }
18196
+ }
18197
+ async function preflightRunIdFile(path) {
18198
+ const destination = (0, import_node_path14.resolve)(path);
18199
+ if (await pathExistsIncludingSymlink(destination)) {
18200
+ throw new Error(
18201
+ `--run-id-file destination already exists: ${destination}. Choose a new path so this run cannot overwrite another run identity.`
18202
+ );
18203
+ }
18204
+ const tempPath = runIdFileTempPath(destination);
18205
+ let handle = null;
18206
+ try {
18207
+ handle = await (0, import_promises5.open)(tempPath, "wx", 384);
18208
+ await handle.sync();
18209
+ } catch (error) {
18210
+ throw new Error(
18211
+ `Cannot write --run-id-file destination ${destination}: ${error instanceof Error ? error.message : String(error)}`
18212
+ );
18213
+ } finally {
18214
+ await handle?.close();
18215
+ await removeRunIdTempFile(tempPath);
18216
+ }
18217
+ return destination;
18218
+ }
18219
+ async function readRunIdFile(destination) {
18220
+ if (!await pathExistsIncludingSymlink(destination)) {
18221
+ return null;
18222
+ }
18223
+ let parsed;
18224
+ try {
18225
+ parsed = JSON.parse(await (0, import_promises5.readFile)(destination, "utf8"));
18226
+ } catch (error) {
18227
+ throw new Error(
18228
+ `--run-id-file destination contains invalid JSON: ${destination}. Refusing to overwrite it (${error instanceof Error ? error.message : String(error)}).`
18229
+ );
18230
+ }
18231
+ if (!parsed || typeof parsed !== "object" || parsed.version !== 1 || typeof parsed.runId !== "string" || !parsed.runId) {
18232
+ throw new Error(
18233
+ `--run-id-file destination has an unsupported identity record: ${destination}. Refusing to overwrite it.`
18234
+ );
18235
+ }
18236
+ return parsed;
18237
+ }
18238
+ async function writePlayRunIdFile(destination, runId) {
18239
+ const existing = await readRunIdFile(destination);
18240
+ if (existing) {
18241
+ if (existing.runId === runId) return;
18242
+ throw new Error(
18243
+ `--run-id-file destination already records run ${existing.runId}; refusing to replace it with ${runId}: ${destination}`
18244
+ );
18245
+ }
18246
+ const tempPath = runIdFileTempPath(destination);
18247
+ let handle = null;
18248
+ try {
18249
+ handle = await (0, import_promises5.open)(tempPath, "wx", 384);
18250
+ await handle.writeFile(
18251
+ `${JSON.stringify({ version: 1, runId })}
18252
+ `,
18253
+ "utf8"
18254
+ );
18255
+ await handle.sync();
18256
+ await handle.close();
18257
+ handle = null;
18258
+ try {
18259
+ await (0, import_promises5.link)(tempPath, destination);
18260
+ const directory = await (0, import_promises5.open)((0, import_node_path14.dirname)(destination), "r");
18261
+ try {
18262
+ await directory.sync();
18263
+ } finally {
18264
+ await directory.close();
18265
+ }
18266
+ } catch (error) {
18267
+ if (error.code !== "EEXIST") throw error;
18268
+ const raced = await readRunIdFile(destination);
18269
+ if (raced?.runId === runId) return;
18270
+ throw new Error(
18271
+ `--run-id-file destination already records run ${raced?.runId ?? "<invalid>"}; refusing to replace it with ${runId}: ${destination}`
18272
+ );
18273
+ }
18274
+ } finally {
18275
+ await handle?.close();
18276
+ await removeRunIdTempFile(tempPath);
18277
+ }
18278
+ }
18030
18279
  function traceCliSync(phase, fields, run) {
18031
18280
  const startedAt = Date.now();
18032
18281
  try {
@@ -19431,8 +19680,8 @@ function buildPlayDashboardUrl(baseUrl, playName) {
19431
19680
  const encodedPlayName = encodeURIComponent(playName);
19432
19681
  return `${trimmedBase}/dashboard/plays/${encodedPlayName}`;
19433
19682
  }
19434
- function openPlayDashboard(dashboardUrl, open) {
19435
- if (open && dashboardUrl) {
19683
+ function openPlayDashboard(dashboardUrl, open2) {
19684
+ if (open2 && dashboardUrl) {
19436
19685
  openInBrowser(dashboardUrl);
19437
19686
  }
19438
19687
  }
@@ -19468,9 +19717,11 @@ function assertPlayWaitNotTimedOut(input2) {
19468
19717
  );
19469
19718
  }
19470
19719
  }
19720
+ var PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS = 15e3;
19471
19721
  async function waitForPlayCompletionByStream(input2) {
19472
19722
  let lastPhase = null;
19473
19723
  let reconnectAttempt = 0;
19724
+ let nextDurableProbeAt = Date.now() + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
19474
19725
  const withDashboardUrl = (status) => input2.dashboardUrl ? { ...status, dashboardUrl: input2.dashboardUrl } : status;
19475
19726
  const remainingWaitMs = () => input2.waitTimeoutMs === null ? null : input2.waitTimeoutMs - (Date.now() - input2.startedAt);
19476
19727
  const fetchTerminalStatus = async () => {
@@ -19489,6 +19740,14 @@ async function waitForPlayCompletionByStream(input2) {
19489
19740
  };
19490
19741
  const handleLiveEvent = async (event) => {
19491
19742
  assertPlayWaitNotTimedOut({ ...input2, lastPhase });
19743
+ const now = Date.now();
19744
+ if (now >= nextDurableProbeAt) {
19745
+ nextDurableProbeAt = now + PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
19746
+ const durableTerminal = await fetchTerminalStatus();
19747
+ if (durableTerminal) {
19748
+ return durableTerminal;
19749
+ }
19750
+ }
19492
19751
  const phase = describeLiveEventPhase(event);
19493
19752
  if (phase) {
19494
19753
  lastPhase = phase;
@@ -19737,7 +19996,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
19737
19996
  lastKnownWorkflowId = eventRunId;
19738
19997
  firstRunIdMs ??= Date.now() - startedAt;
19739
19998
  if (runStartedNow) {
19740
- input2.onRunStarted?.(eventRunId);
19999
+ await input2.onRunStarted?.(eventRunId);
19741
20000
  }
19742
20001
  }
19743
20002
  if (eventConfirmsPlayRunLaunch(event) && eventRunId === lastKnownWorkflowId) {
@@ -21016,6 +21275,15 @@ function buildOrdinaryPlayRunCommand(options, resolvedRevisionId) {
21016
21275
  }
21017
21276
  if (options.profile)
21018
21277
  parts.push("--profile", shellSingleQuote(options.profile));
21278
+ if (options.maxConcurrentExternalCalls !== null) {
21279
+ parts.push(
21280
+ "--max-concurrent-external-calls",
21281
+ String(options.maxConcurrentExternalCalls)
21282
+ );
21283
+ }
21284
+ if (options.maxConcurrentRows !== null) {
21285
+ parts.push("--max-concurrent-rows", String(options.maxConcurrentRows));
21286
+ }
21019
21287
  const pinnedRevisionId = options.target.kind === "name" ? resolvedRevisionId ?? options.revisionId : null;
21020
21288
  if (pinnedRevisionId) {
21021
21289
  parts.push("--revision-id", shellSingleQuote(pinnedRevisionId));
@@ -21885,7 +22153,7 @@ function writeStartedPlayRun(input2) {
21885
22153
  );
21886
22154
  }
21887
22155
  function parsePlayRunOptions(args) {
21888
- const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--profile <id>] [--live|--latest|--revision-id <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--json] [--full] [--<input> value]\n Runs use the Absurd CJS runtime.\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.";
22156
+ const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--profile <id>] [--live|--latest|--revision-id <id>] [--run-id-file <path>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--open] [--json] [--full] [--<input> value]\n Runs use the Absurd CJS runtime.\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.";
21889
22157
  let filePath = null;
21890
22158
  let playName = null;
21891
22159
  let input2 = null;
@@ -21896,15 +22164,18 @@ function parsePlayRunOptions(args) {
21896
22164
  const fullJson = args.includes("--full");
21897
22165
  const emitLogs = !jsonOutput || args.includes("--logs");
21898
22166
  const force = args.includes("--force");
21899
- const open = args.includes("--open");
22167
+ const open2 = args.includes("--open");
21900
22168
  const debugMapLatency = args.includes("--debug-map-latency");
21901
22169
  const debugFixtureProviderPacing = args.includes(
21902
22170
  "--debug-fixture-provider-pacing"
21903
22171
  );
21904
22172
  const verboseLogs = args.includes("--logs") || debugMapLatency;
21905
22173
  let waitTimeoutMs = null;
22174
+ let maxConcurrentExternalCalls = null;
22175
+ let maxConcurrentRows = null;
21906
22176
  let profile = null;
21907
22177
  let fixtureBehavior = null;
22178
+ let runIdFile = null;
21908
22179
  for (let index = 0; index < args.length; index += 1) {
21909
22180
  const arg = args[index];
21910
22181
  if (arg === "--file" && args[index + 1]) {
@@ -21919,6 +22190,23 @@ function parsePlayRunOptions(args) {
21919
22190
  input2 = parseJsonInput(args[++index]);
21920
22191
  continue;
21921
22192
  }
22193
+ if (arg === "--run-id-file") {
22194
+ const value = args[index + 1];
22195
+ if (!value || value.startsWith("--")) {
22196
+ throw new Error("--run-id-file requires a destination path.");
22197
+ }
22198
+ runIdFile = value;
22199
+ index += 1;
22200
+ continue;
22201
+ }
22202
+ if (arg.startsWith("--run-id-file=")) {
22203
+ const value = arg.slice("--run-id-file=".length);
22204
+ if (!value) {
22205
+ throw new Error("--run-id-file requires a destination path.");
22206
+ }
22207
+ runIdFile = value;
22208
+ continue;
22209
+ }
21922
22210
  if (arg === "--revision-id" && args[index + 1]) {
21923
22211
  revisionId = args[++index];
21924
22212
  continue;
@@ -21933,6 +22221,41 @@ function parsePlayRunOptions(args) {
21933
22221
  index += 1;
21934
22222
  continue;
21935
22223
  }
22224
+ if (arg === "--max-concurrent-external-calls") {
22225
+ const value = args[index + 1];
22226
+ if (!value || value.startsWith("--")) {
22227
+ throw new Error(
22228
+ "--max-concurrent-external-calls requires a whole number."
22229
+ );
22230
+ }
22231
+ if (!/^[1-9]\d*$/.test(value)) {
22232
+ throw new Error(
22233
+ "--max-concurrent-external-calls requires a positive whole number."
22234
+ );
22235
+ }
22236
+ maxConcurrentExternalCalls = parsePositiveInteger3(
22237
+ value,
22238
+ "--max-concurrent-external-calls"
22239
+ );
22240
+ resolveMaxConcurrentExternalCalls(maxConcurrentExternalCalls);
22241
+ index += 1;
22242
+ continue;
22243
+ }
22244
+ if (arg === "--max-concurrent-rows") {
22245
+ const value = args[index + 1];
22246
+ if (!value || value.startsWith("--")) {
22247
+ throw new Error("--max-concurrent-rows requires a whole number.");
22248
+ }
22249
+ if (!/^[1-9]\d*$/.test(value)) {
22250
+ throw new Error(
22251
+ "--max-concurrent-rows requires a positive whole number."
22252
+ );
22253
+ }
22254
+ maxConcurrentRows = parsePositiveInteger3(value, "--max-concurrent-rows");
22255
+ resolveMaxConcurrentRows(maxConcurrentRows);
22256
+ index += 1;
22257
+ continue;
22258
+ }
21936
22259
  if (arg === "--fixture-behavior") {
21937
22260
  const value = args[index + 1];
21938
22261
  if (!value) {
@@ -22043,11 +22366,14 @@ function parsePlayRunOptions(args) {
22043
22366
  fullJson,
22044
22367
  waitTimeoutMs,
22045
22368
  force,
22046
- open,
22369
+ maxConcurrentExternalCalls,
22370
+ maxConcurrentRows,
22371
+ open: open2,
22047
22372
  profile,
22048
22373
  debugMapLatency,
22049
22374
  debugFixtureProviderPacing,
22050
- fixtureBehavior
22375
+ fixtureBehavior,
22376
+ runIdFile
22051
22377
  };
22052
22378
  }
22053
22379
  function parsePlayCheckOptions(args) {
@@ -22730,6 +23056,8 @@ async function handleFileBackedRun(options, hooks) {
22730
23056
  ...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
22731
23057
  ...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
22732
23058
  ...options.force ? { force: true } : {},
23059
+ ...options.maxConcurrentExternalCalls !== null ? { maxConcurrentExternalCalls: options.maxConcurrentExternalCalls } : {},
23060
+ ...options.maxConcurrentRows !== null ? { maxConcurrentRows: options.maxConcurrentRows } : {},
22733
23061
  ...options.profile ? { profile: options.profile } : {},
22734
23062
  ...Object.keys(testPolicyOverrides).length > 0 ? { testPolicyOverrides } : {},
22735
23063
  ...integrationMode ? { integrationMode } : {},
@@ -22790,6 +23118,7 @@ async function handleFileBackedRun(options, hooks) {
22790
23118
  throw await normalizePlayStartError(client2, error, playName);
22791
23119
  })
22792
23120
  );
23121
+ await hooks?.onRunStarted?.(started.workflowId);
22793
23122
  const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
22794
23123
  openPlayDashboard(resolvedDashboardUrl, options.open);
22795
23124
  progress.phase("started run");
@@ -22910,6 +23239,8 @@ async function handleNamedRun(options, hooks) {
22910
23239
  ...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
22911
23240
  ...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
22912
23241
  ...options.force ? { force: true } : {},
23242
+ ...options.maxConcurrentExternalCalls !== null ? { maxConcurrentExternalCalls: options.maxConcurrentExternalCalls } : {},
23243
+ ...options.maxConcurrentRows !== null ? { maxConcurrentRows: options.maxConcurrentRows } : {},
22913
23244
  ...options.profile ? { profile: options.profile } : {},
22914
23245
  ...Object.keys(testPolicyOverrides).length > 0 ? { testPolicyOverrides } : {},
22915
23246
  ...integrationMode ? { integrationMode } : {},
@@ -22975,6 +23306,7 @@ async function handleNamedRun(options, hooks) {
22975
23306
  });
22976
23307
  })
22977
23308
  );
23309
+ await hooks?.onRunStarted?.(started.workflowId);
22978
23310
  const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
22979
23311
  openPlayDashboard(resolvedDashboardUrl, options.open);
22980
23312
  progress.phase("started run");
@@ -22991,10 +23323,28 @@ async function handleNamedRun(options, hooks) {
22991
23323
  return 0;
22992
23324
  }
22993
23325
  async function handlePlayRun(args, hooks) {
22994
- const options = parsePlayRunOptions(args);
23326
+ const parsedOptions = parsePlayRunOptions(args);
23327
+ const options = parsedOptions.runIdFile ? {
23328
+ ...parsedOptions,
23329
+ runIdFile: await preflightRunIdFile(parsedOptions.runIdFile)
23330
+ } : parsedOptions;
23331
+ const runHooks = options.runIdFile ? {
23332
+ ...hooks,
23333
+ onRunStarted: async (runId) => {
23334
+ try {
23335
+ await writePlayRunIdFile(options.runIdFile, runId);
23336
+ } catch (error) {
23337
+ throw new Error(
23338
+ `Run ${runId} was accepted, but its identity could not be persisted to ${options.runIdFile}: ${error instanceof Error ? error.message : String(error)}. Inspect it with 'deepline runs get ${runId} --full --json'; do not submit a replacement run.`,
23339
+ { cause: error }
23340
+ );
23341
+ }
23342
+ await hooks?.onRunStarted?.(runId);
23343
+ }
23344
+ } : hooks;
22995
23345
  if (options.target.kind === "file") {
22996
23346
  if (isFileTarget(options.target.path)) {
22997
- return handleFileBackedRun(options, hooks);
23347
+ return handleFileBackedRun(options, runHooks);
22998
23348
  }
22999
23349
  const resolved = (0, import_node_path14.resolve)(options.target.path);
23000
23350
  console.error(`File not found: ${resolved}`);
@@ -23016,7 +23366,7 @@ async function handlePlayRun(args, hooks) {
23016
23366
  }
23017
23367
  return 1;
23018
23368
  }
23019
- return handleNamedRun(options, hooks);
23369
+ return handleNamedRun(options, runHooks);
23020
23370
  }
23021
23371
  function parseRunIdPositional(args, usage) {
23022
23372
  for (let index = 0; index < args.length; index += 1) {
@@ -24344,10 +24694,18 @@ Notes:
24344
24694
  next commands. --watch and --wait are accepted compatibility aliases for the
24345
24695
  default behavior. Use --no-wait only when you intentionally want
24346
24696
  a fire-and-forget run id.
24697
+ --run-id-file writes the durable run id to a versioned JSON file as soon as
24698
+ the server accepts the run. The destination must not already exist.
24347
24699
  The play page URL is printed when the run starts. Pass --open to open it in a browser.
24348
24700
  Concurrent runs for the same play are allowed.
24349
24701
  --force starts a fresh run graph without refreshing completed provider calls.
24350
24702
  It does not cancel active sibling runs.
24703
+ --max-concurrent-external-calls controls the per-run provider-tool/ctx.fetch
24704
+ resident-work ceiling. Default: ${DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS}; accepted range: 1-${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS}.
24705
+ Provider pacing and sandbox memory limits still apply.
24706
+ --max-concurrent-rows sets the run-wide default and ceiling for live map row
24707
+ resolvers. Accepted range: 1-${MAX_CONFIGURABLE_CONCURRENT_ROWS}. The runtime
24708
+ may lower it when source-row size exceeds the active-row memory budget.
24351
24709
  This command starts cloud work and may spend Deepline credits through tool calls.
24352
24710
 
24353
24711
  Idempotent execution:
@@ -24383,8 +24741,10 @@ Idempotent execution:
24383
24741
  Examples:
24384
24742
  deepline plays run prebuilt/person-linkedin-to-email --input '{"linkedin_url":"..."}'
24385
24743
  deepline plays run long-background-play --no-wait
24744
+ deepline plays run long-background-play --run-id-file ./run-id.json
24386
24745
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
24387
24746
  deepline plays run my.play.ts --profile absurd
24747
+ deepline plays run my.play.ts --max-concurrent-external-calls 20
24388
24748
  deepline plays run my.play.ts --input @input.json --json
24389
24749
  deepline plays run cto-search.play.ts --limit 5
24390
24750
  deepline runs export <run-id> --out output.csv
@@ -24400,9 +24760,18 @@ Examples:
24400
24760
  "--fixture-behavior <json>",
24401
24761
  "Internal/testing: fixture response behavior JSON object or @file path"
24402
24762
  ).option("--watch", "Compatibility alias; run waits by default").option("--wait", "Compatibility alias; run waits by default").option("--no-wait", "Start the run and return immediately").option(
24763
+ "--run-id-file <path>",
24764
+ "Atomically write the accepted run id to a new JSON file"
24765
+ ).option(
24403
24766
  "--logs",
24404
24767
  "When output is non-interactive, stream play logs to stderr while waiting"
24405
- ).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Start a fresh run graph").option("--open", "Open the play page in a browser after the run starts").option(
24768
+ ).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Start a fresh run graph").option(
24769
+ "--max-concurrent-external-calls <count>",
24770
+ `Concurrent provider-tool and ctx.fetch executions (${DEFAULT_MAX_CONCURRENT_EXTERNAL_CALLS} default, max ${MAX_CONFIGURABLE_CONCURRENT_EXTERNAL_CALLS})`
24771
+ ).option(
24772
+ "--max-concurrent-rows <count>",
24773
+ `Run-wide dataset map row resolver ceiling (max ${MAX_CONFIGURABLE_CONCURRENT_ROWS})`
24774
+ ).option("--open", "Open the play page in a browser after the run starts").option(
24406
24775
  "--debug-map-latency",
24407
24776
  "Internal diagnostics: emit one aggregate latency profile per dataset map"
24408
24777
  ).option(
@@ -24441,10 +24810,16 @@ Pass-through input flags:
24441
24810
  ...options.profile ? ["--profile", options.profile] : [],
24442
24811
  ...options.fixtureBehavior ? ["--fixture-behavior", options.fixtureBehavior] : [],
24443
24812
  ...options.wait === false ? ["--no-wait"] : [],
24813
+ ...options.runIdFile ? ["--run-id-file", options.runIdFile] : [],
24444
24814
  ...options.watch || options.wait ? ["--watch"] : [],
24445
24815
  ...options.logs ? ["--logs"] : [],
24446
24816
  ...options.tailTimeoutMs ? ["--tail-timeout-ms", options.tailTimeoutMs] : [],
24447
24817
  ...options.force ? ["--force"] : [],
24818
+ ...options.maxConcurrentExternalCalls ? [
24819
+ "--max-concurrent-external-calls",
24820
+ options.maxConcurrentExternalCalls
24821
+ ] : [],
24822
+ ...options.maxConcurrentRows ? ["--max-concurrent-rows", options.maxConcurrentRows] : [],
24448
24823
  ...options.open ? ["--open"] : [],
24449
24824
  ...options.debugMapLatency ? ["--debug-map-latency"] : [],
24450
24825
  ...options.debugFixtureProviderPacing ? ["--debug-fixture-provider-pacing"] : [],
@@ -26833,7 +27208,7 @@ async function readAtFileReference(value, argumentName, strip = true) {
26833
27208
  throw new Error(`Invalid ${argumentName} value: empty @file path.`);
26834
27209
  }
26835
27210
  try {
26836
- const text = await (0, import_promises5.readFile)(filePath, "utf8");
27211
+ const text = await (0, import_promises6.readFile)(filePath, "utf8");
26837
27212
  const normalized = text.replace(/^\uFEFF/, "");
26838
27213
  return strip ? normalized.trim() : normalized;
26839
27214
  } catch (error) {
@@ -27131,7 +27506,7 @@ async function buildPlanArgs(args) {
27131
27506
  async function assertInputCsvExists(inputCsv) {
27132
27507
  const path = (0, import_node_path15.resolve)(inputCsv);
27133
27508
  try {
27134
- const info = await (0, import_promises5.stat)(path);
27509
+ const info = await (0, import_promises6.stat)(path);
27135
27510
  if (info.isFile()) {
27136
27511
  return;
27137
27512
  }
@@ -27152,8 +27527,8 @@ async function assertSafeOutputPath(inputCsv, outputPath) {
27152
27527
  }
27153
27528
  try {
27154
27529
  const [inputInfo, outputInfo] = await Promise.all([
27155
- (0, import_promises5.stat)(input2),
27156
- (0, import_promises5.stat)(output2)
27530
+ (0, import_promises6.stat)(input2),
27531
+ (0, import_promises6.stat)(output2)
27157
27532
  ]);
27158
27533
  if (inputInfo.dev === outputInfo.dev && inputInfo.ino === outputInfo.ino) {
27159
27534
  throw new Error(
@@ -27173,7 +27548,7 @@ async function assertSafeOutputPath(inputCsv, outputPath) {
27173
27548
  }
27174
27549
  async function regularFileExists(path) {
27175
27550
  try {
27176
- const info = await (0, import_promises5.stat)((0, import_node_path15.resolve)(path));
27551
+ const info = await (0, import_promises6.stat)((0, import_node_path15.resolve)(path));
27177
27552
  return info.isFile();
27178
27553
  } catch (error) {
27179
27554
  const code = error && typeof error === "object" ? error.code : void 0;
@@ -27184,7 +27559,7 @@ async function regularFileExists(path) {
27184
27559
  }
27185
27560
  }
27186
27561
  async function readConfig(path) {
27187
- const source = await (0, import_promises5.readFile)((0, import_node_path15.resolve)(path), "utf8");
27562
+ const source = await (0, import_promises6.readFile)((0, import_node_path15.resolve)(path), "utf8");
27188
27563
  let parsed;
27189
27564
  try {
27190
27565
  parsed = JSON.parse(source);
@@ -27605,7 +27980,7 @@ async function writeOutputCsv(outputPath, status, options) {
27605
27980
  ]),
27606
27981
  options?.config
27607
27982
  );
27608
- await (0, import_promises5.writeFile)(
27983
+ await (0, import_promises6.writeFile)(
27609
27984
  (0, import_node_path15.resolve)(outputPath),
27610
27985
  csvStringFromRows(merged.rows, columns),
27611
27986
  "utf8"
@@ -29285,7 +29660,7 @@ async function persistEnrichFailureReport(input2) {
29285
29660
  }
29286
29661
  const stateDir = (0, import_node_path15.join)((0, import_node_os10.homedir)(), ".local", "deepline", "runtime", "state");
29287
29662
  const reportPrefix = input2.jobs.length > 0 ? "run-block-failures" : "enrich-issues";
29288
- await (0, import_promises5.mkdir)(stateDir, { recursive: true });
29663
+ await (0, import_promises6.mkdir)(stateDir, { recursive: true });
29289
29664
  const reportPath = (0, import_node_path15.join)(
29290
29665
  stateDir,
29291
29666
  `${reportPrefix}-${Math.floor(Date.now() / 1e3)}-${process.pid}.json`
@@ -29311,7 +29686,7 @@ async function persistEnrichFailureReport(input2) {
29311
29686
  if (input2.rows.rowStart !== null && input2.rows.rowEnd !== null) {
29312
29687
  report.rows = { start: input2.rows.rowStart, end: input2.rows.rowEnd };
29313
29688
  }
29314
- await (0, import_promises5.writeFile)(reportPath, `${JSON.stringify(report, null, 2)}
29689
+ await (0, import_promises6.writeFile)(reportPath, `${JSON.stringify(report, null, 2)}
29315
29690
  `, "utf8");
29316
29691
  return reportPath;
29317
29692
  }
@@ -30214,13 +30589,13 @@ function registerEnrichCommand(program) {
30214
30589
  sdkEnrichTelemetryCompleted = true;
30215
30590
  await completeSdkEnrichTelemetry(sdkEnrichTelemetry, input2);
30216
30591
  };
30217
- const tempDir = await (0, import_promises5.mkdtemp)((0, import_node_path15.join)((0, import_node_os10.tmpdir)(), "deepline-enrich-play-"));
30592
+ const tempDir = await (0, import_promises6.mkdtemp)((0, import_node_path15.join)((0, import_node_os10.tmpdir)(), "deepline-enrich-play-"));
30218
30593
  await emitSdkEnrichTelemetry(sdkEnrichTelemetry, "enrich_started");
30219
30594
  const tempPlay = (0, import_node_path15.join)(tempDir, "deepline-enrich.play.ts");
30220
30595
  let inPlaceTempDir = null;
30221
30596
  let inPlaceTempOutputPath = null;
30222
30597
  const inPlaceFinalOutputPath = options.inPlace ? (0, import_node_path15.resolve)(inputCsv) : null;
30223
- const inPlaceCommitOutputPath = options.inPlace ? (await (0, import_promises5.lstat)(inputCsv)).isSymbolicLink() ? await (0, import_promises5.realpath)(inputCsv) : inPlaceFinalOutputPath : null;
30598
+ const inPlaceCommitOutputPath = options.inPlace ? (await (0, import_promises6.lstat)(inputCsv)).isSymbolicLink() ? await (0, import_promises6.realpath)(inputCsv) : inPlaceFinalOutputPath : null;
30224
30599
  const failureReportOutputPath = options.inPlace ? inPlaceFinalOutputPath : null;
30225
30600
  const enrichIssueFollowUpOutputPath = options.inPlace && inPlaceFinalOutputPath ? sidecarEnrichRowsExportPath(inPlaceFinalOutputPath) : null;
30226
30601
  let activeRunId2 = null;
@@ -30241,16 +30616,16 @@ function registerEnrichCommand(program) {
30241
30616
  return;
30242
30617
  }
30243
30618
  if (inPlaceTempDir) {
30244
- await (0, import_promises5.rm)(inPlaceTempDir, { recursive: true, force: true });
30619
+ await (0, import_promises6.rm)(inPlaceTempDir, { recursive: true, force: true });
30245
30620
  }
30246
- inPlaceTempDir = await (0, import_promises5.mkdtemp)(
30621
+ inPlaceTempDir = await (0, import_promises6.mkdtemp)(
30247
30622
  (0, import_node_path15.join)(
30248
30623
  (0, import_node_path15.dirname)(inPlaceCommitOutputPath ?? (0, import_node_path15.resolve)(inputCsv)),
30249
30624
  ".deepline-enrich-in-place-"
30250
30625
  )
30251
30626
  );
30252
30627
  inPlaceTempOutputPath = (0, import_node_path15.join)(inPlaceTempDir, "output.csv");
30253
- await (0, import_promises5.copyFile)((0, import_node_path15.resolve)(inputCsv), inPlaceTempOutputPath);
30628
+ await (0, import_promises6.copyFile)((0, import_node_path15.resolve)(inputCsv), inPlaceTempOutputPath);
30254
30629
  outputPath = inPlaceTempOutputPath;
30255
30630
  };
30256
30631
  const commitInPlaceOutput = async (exportResult) => {
@@ -30258,12 +30633,12 @@ function registerEnrichCommand(program) {
30258
30633
  return exportResult;
30259
30634
  }
30260
30635
  const committedTempDir = inPlaceTempDir;
30261
- await (0, import_promises5.rename)(inPlaceTempOutputPath, inPlaceCommitOutputPath);
30636
+ await (0, import_promises6.rename)(inPlaceTempOutputPath, inPlaceCommitOutputPath);
30262
30637
  inPlaceTempDir = null;
30263
30638
  inPlaceTempOutputPath = null;
30264
30639
  outputPath = inPlaceFinalOutputPath;
30265
30640
  if (committedTempDir) {
30266
- await (0, import_promises5.rm)(committedTempDir, { recursive: true, force: true });
30641
+ await (0, import_promises6.rm)(committedTempDir, { recursive: true, force: true });
30267
30642
  }
30268
30643
  if (!exportResult) {
30269
30644
  return null;
@@ -30276,7 +30651,7 @@ function registerEnrichCommand(program) {
30276
30651
  try {
30277
30652
  process.once("SIGINT", onSigint);
30278
30653
  process.once("SIGTERM", onSigterm);
30279
- await (0, import_promises5.writeFile)(tempPlay, playSource, "utf8");
30654
+ await (0, import_promises6.writeFile)(tempPlay, playSource, "utf8");
30280
30655
  if (options.inPlace) {
30281
30656
  await prepareInPlaceOutput();
30282
30657
  }
@@ -30470,11 +30845,11 @@ function registerEnrichCommand(program) {
30470
30845
  process.removeListener("SIGINT", onSigint);
30471
30846
  process.removeListener("SIGTERM", onSigterm);
30472
30847
  if (inPlaceTempDir) {
30473
- await (0, import_promises5.rm)(inPlaceTempDir, { recursive: true, force: true });
30848
+ await (0, import_promises6.rm)(inPlaceTempDir, { recursive: true, force: true });
30474
30849
  } else if (inPlaceTempOutputPath) {
30475
- await (0, import_promises5.rm)(inPlaceTempOutputPath, { force: true });
30850
+ await (0, import_promises6.rm)(inPlaceTempOutputPath, { force: true });
30476
30851
  }
30477
- await (0, import_promises5.rm)(tempDir, { recursive: true, force: true });
30852
+ await (0, import_promises6.rm)(tempDir, { recursive: true, force: true });
30478
30853
  }
30479
30854
  });
30480
30855
  }
@@ -31366,7 +31741,7 @@ Examples:
31366
31741
 
31367
31742
  // src/cli/commands/monitors.ts
31368
31743
  var import_node_fs14 = require("fs");
31369
- var import_promises6 = require("readline/promises");
31744
+ var import_promises7 = require("readline/promises");
31370
31745
  var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
31371
31746
  function withJsonOption(command) {
31372
31747
  return command.option("--json", JSON_OPTION_DESCRIPTION);
@@ -32135,7 +32510,7 @@ async function handleMonitorsValidate(key, options) {
32135
32510
  if (result.valid === false) process.exitCode = 7;
32136
32511
  }
32137
32512
  async function confirmMonitorDelete(key, options) {
32138
- const rl = (0, import_promises6.createInterface)({
32513
+ const rl = (0, import_promises7.createInterface)({
32139
32514
  input: process.stdin,
32140
32515
  output: process.stderr
32141
32516
  });
@@ -36156,7 +36531,7 @@ Examples:
36156
36531
  }
36157
36532
 
36158
36533
  // src/cli/commands/workflow.ts
36159
- var import_promises7 = require("fs/promises");
36534
+ var import_promises8 = require("fs/promises");
36160
36535
  var import_node_path20 = require("path");
36161
36536
 
36162
36537
  // src/cli/workflow-to-play.ts
@@ -36366,7 +36741,7 @@ function readStatus(payload) {
36366
36741
  }
36367
36742
  async function readJsonOption(payload, file) {
36368
36743
  if (file) {
36369
- const raw = await (0, import_promises7.readFile)((0, import_node_path20.resolve)(file), "utf8");
36744
+ const raw = await (0, import_promises8.readFile)((0, import_node_path20.resolve)(file), "utf8");
36370
36745
  return JSON.parse(raw);
36371
36746
  }
36372
36747
  if (payload) {
@@ -36401,8 +36776,8 @@ async function transformOne(api, workflowId, outDir, publish) {
36401
36776
  { workflowName: workflow.name, version: revision.version }
36402
36777
  );
36403
36778
  const file = (0, import_node_path20.join)((0, import_node_path20.resolve)(outDir), `${compiled.playName}.play.ts`);
36404
- await (0, import_promises7.mkdir)((0, import_node_path20.dirname)(file), { recursive: true });
36405
- await (0, import_promises7.writeFile)(file, compiled.sourceCode, "utf8");
36779
+ await (0, import_promises8.mkdir)((0, import_node_path20.dirname)(file), { recursive: true });
36780
+ await (0, import_promises8.writeFile)(file, compiled.sourceCode, "utf8");
36406
36781
  let published = false;
36407
36782
  if (publish) {
36408
36783
  const code = await handlePlayPublish([file]);
@@ -40477,10 +40852,10 @@ function topLevelCommandKnown(program, commandName) {
40477
40852
  );
40478
40853
  }
40479
40854
  async function runPlayRunnerHealthCheck() {
40480
- const dir = await (0, import_promises8.mkdtemp)((0, import_node_path26.join)((0, import_node_os19.tmpdir)(), "deepline-health-play-"));
40855
+ const dir = await (0, import_promises9.mkdtemp)((0, import_node_path26.join)((0, import_node_os19.tmpdir)(), "deepline-health-play-"));
40481
40856
  const file = (0, import_node_path26.join)(dir, "health-check.play.ts");
40482
40857
  try {
40483
- await (0, import_promises8.writeFile)(
40858
+ await (0, import_promises9.writeFile)(
40484
40859
  file,
40485
40860
  [
40486
40861
  "import { definePlay } from 'deepline';",
@@ -40529,7 +40904,7 @@ async function runPlayRunnerHealthCheck() {
40529
40904
  }
40530
40905
  };
40531
40906
  } finally {
40532
- await (0, import_promises8.rm)(dir, { recursive: true, force: true });
40907
+ await (0, import_promises9.rm)(dir, { recursive: true, force: true });
40533
40908
  }
40534
40909
  }
40535
40910
  function pickString(value, ...keys) {