deepline 0.1.119 → 0.1.121

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 (148) hide show
  1. package/README.md +4 -0
  2. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/README.md +21 -0
  3. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/batching.ts +185 -0
  4. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-batch.ts +107 -0
  5. package/dist/{repo → bundling-sources}/sdk/src/client.ts +116 -12
  6. package/dist/bundling-sources/sdk/src/compat.ts +191 -0
  7. package/dist/bundling-sources/sdk/src/gtm.ts +146 -0
  8. package/dist/bundling-sources/sdk/src/helpers.ts +12 -0
  9. package/dist/{repo → bundling-sources}/sdk/src/index.ts +2 -1
  10. package/dist/{repo → bundling-sources}/sdk/src/play.ts +3 -1
  11. package/dist/{repo → bundling-sources}/sdk/src/plays/bundle-play-file.ts +17 -5
  12. package/dist/{repo → bundling-sources}/sdk/src/release.ts +2 -2
  13. package/dist/{repo → bundling-sources}/sdk/src/runs/observe-transport.ts +2 -3
  14. package/dist/bundling-sources/shared_libs/play-data-plane/index.ts +3 -0
  15. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +838 -0
  16. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +5510 -0
  17. package/dist/bundling-sources/shared_libs/play-runtime/ctx-contract.ts +261 -0
  18. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +828 -0
  19. package/dist/bundling-sources/shared_libs/play-runtime/dataset-id.ts +10 -0
  20. package/dist/bundling-sources/shared_libs/play-runtime/daytona-runtime-config.ts +50 -0
  21. package/dist/bundling-sources/shared_libs/play-runtime/durability-store.ts +20 -0
  22. package/dist/bundling-sources/shared_libs/play-runtime/event-wait-tools.ts +9 -0
  23. package/dist/bundling-sources/shared_libs/play-runtime/governor/in-memory-rate-state-backend.ts +171 -0
  24. package/dist/bundling-sources/shared_libs/play-runtime/hatchet-cold-execution-diagnosis.ts +321 -0
  25. package/dist/bundling-sources/shared_libs/play-runtime/hatchet-cold-execution-target.ts +158 -0
  26. package/dist/bundling-sources/shared_libs/play-runtime/internal-step-ids.ts +34 -0
  27. package/dist/bundling-sources/shared_libs/play-runtime/ledger-safe-payload.ts +34 -0
  28. package/dist/bundling-sources/shared_libs/play-runtime/live-state-contract.ts +50 -0
  29. package/dist/bundling-sources/shared_libs/play-runtime/map-execution-frame.ts +119 -0
  30. package/dist/{repo → bundling-sources}/shared_libs/play-runtime/map-row-identity.ts +1 -1
  31. package/dist/bundling-sources/shared_libs/play-runtime/play-latency-trace.ts +636 -0
  32. package/dist/bundling-sources/shared_libs/play-runtime/postgres-json.ts +9 -0
  33. package/dist/bundling-sources/shared_libs/play-runtime/progress-emitter.ts +197 -0
  34. package/dist/bundling-sources/shared_libs/play-runtime/projection.ts +262 -0
  35. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +143 -0
  36. package/dist/bundling-sources/shared_libs/play-runtime/public-play-contract.ts +42 -0
  37. package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +40 -0
  38. package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +178 -0
  39. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +4015 -0
  40. package/dist/bundling-sources/shared_libs/play-runtime/runtime-constraints.ts +2 -0
  41. package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-neon-serverless.ts +238 -0
  42. package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-pg.ts +53 -0
  43. package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver.ts +149 -0
  44. package/dist/bundling-sources/shared_libs/play-runtime/suspension.ts +68 -0
  45. package/dist/bundling-sources/shared_libs/play-runtime/tool-batch-executor.ts +149 -0
  46. package/dist/bundling-sources/shared_libs/play-runtime/tool-result-types.ts +159 -0
  47. package/dist/bundling-sources/shared_libs/play-runtime/tracing.ts +33 -0
  48. package/dist/bundling-sources/shared_libs/play-runtime/waterfall-replay.ts +79 -0
  49. package/dist/bundling-sources/shared_libs/play-runtime/worker-api-types.ts +139 -0
  50. package/dist/bundling-sources/shared_libs/plays/artifact-transport.ts +14 -0
  51. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +49 -0
  52. package/dist/bundling-sources/shared_libs/plays/compiler-manifest.ts +41 -0
  53. package/dist/bundling-sources/shared_libs/plays/dataset-summary.ts +163 -0
  54. package/dist/bundling-sources/shared_libs/plays/definition.ts +267 -0
  55. package/dist/bundling-sources/shared_libs/plays/file-refs.ts +11 -0
  56. package/dist/bundling-sources/shared_libs/plays/input-contract.ts +146 -0
  57. package/dist/bundling-sources/shared_libs/plays/resolve-static-pipeline.ts +190 -0
  58. package/dist/bundling-sources/shared_libs/plays/runtime-validation.ts +417 -0
  59. package/dist/bundling-sources/shared_libs/plays/tool-codegen.ts +142 -0
  60. package/dist/bundling-sources/shared_libs/security/safe-outbound-fetch.ts +274 -0
  61. package/dist/bundling-sources/shared_libs/temporal/preview-config.ts +150 -0
  62. package/dist/cli/index.js +811 -2207
  63. package/dist/cli/index.mjs +847 -2258
  64. package/dist/compiler-manifest-BjoRENv9.d.mts +227 -0
  65. package/dist/compiler-manifest-BjoRENv9.d.ts +227 -0
  66. package/dist/index.d.mts +8 -231
  67. package/dist/index.d.ts +8 -231
  68. package/dist/index.js +101 -15
  69. package/dist/index.mjs +101 -15
  70. package/dist/plays/bundle-play-file.d.mts +120 -0
  71. package/dist/plays/bundle-play-file.d.ts +120 -0
  72. package/dist/plays/bundle-play-file.mjs +1830 -0
  73. package/package.json +4 -9
  74. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/child-play-await.ts +0 -0
  75. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/child-play-submit.ts +0 -0
  76. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/coordinator-entry.ts +0 -0
  77. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/dedup-do.ts +0 -0
  78. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/entry.ts +0 -0
  79. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/csv-rows.ts +0 -0
  80. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/dataset-handles.ts +0 -0
  81. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/harness-receipt-store.ts +0 -0
  82. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/live-progress.ts +0 -0
  83. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/map-chunk-plan.ts +0 -0
  84. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/receipts.ts +0 -0
  85. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/row-isolation.ts +0 -0
  86. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/tool-http-errors.ts +0 -0
  87. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/workflow-instance-create.ts +0 -0
  88. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/workflow-retry-state.ts +0 -0
  89. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/workflow-retry.ts +0 -0
  90. /package/dist/{repo → bundling-sources}/sdk/src/agent-runtime.ts +0 -0
  91. /package/dist/{repo → bundling-sources}/sdk/src/config.ts +0 -0
  92. /package/dist/{repo → bundling-sources}/sdk/src/errors.ts +0 -0
  93. /package/dist/{repo → bundling-sources}/sdk/src/http.ts +0 -0
  94. /package/dist/{repo → bundling-sources}/sdk/src/plays/harness-stub.ts +0 -0
  95. /package/dist/{repo → bundling-sources}/sdk/src/plays/local-file-discovery.ts +0 -0
  96. /package/dist/{repo → bundling-sources}/sdk/src/stream-reconnect.ts +0 -0
  97. /package/dist/{repo → bundling-sources}/sdk/src/tool-output.ts +0 -0
  98. /package/dist/{repo → bundling-sources}/sdk/src/types.ts +0 -0
  99. /package/dist/{repo → bundling-sources}/sdk/src/version.ts +0 -0
  100. /package/dist/{repo → bundling-sources}/sdk/src/worker-play-entry.ts +0 -0
  101. /package/dist/{repo → bundling-sources}/shared_libs/play-data-plane/cell-policy.ts +0 -0
  102. /package/dist/{repo → bundling-sources}/shared_libs/play-data-plane/column-names.ts +0 -0
  103. /package/dist/{repo → bundling-sources}/shared_libs/play-data-plane/sheet-contract.ts +0 -0
  104. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/backend.ts +0 -0
  105. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/batch-runtime.ts +0 -0
  106. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/batching-types.ts +0 -0
  107. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/cell-staleness.ts +0 -0
  108. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/coordinator-headers.ts +0 -0
  109. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/csv-rename.ts +0 -0
  110. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/db-session-crypto.ts +0 -0
  111. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/db-session-plan.ts +0 -0
  112. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/db-session.ts +0 -0
  113. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/dedup-backend.ts +0 -0
  114. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/default-batch-strategies.ts +0 -0
  115. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/email-status.ts +0 -0
  116. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/execution-plan.ts +0 -0
  117. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/extractor-targets.ts +0 -0
  118. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/fullenrich-batching.ts +0 -0
  119. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/governor/coordinator-rate-state-backend.ts +0 -0
  120. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/governor/governor.ts +0 -0
  121. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/governor/policy.ts +0 -0
  122. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/governor/rate-state-backend.ts +0 -0
  123. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/live-events.ts +0 -0
  124. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/play-runtime-batching-registry.ts +0 -0
  125. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/profiles.ts +0 -0
  126. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/providers.ts +0 -0
  127. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/run-failure.ts +0 -0
  128. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/run-ledger.ts +0 -0
  129. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/run-snapshot-stream.ts +0 -0
  130. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/scheduler-backend.ts +0 -0
  131. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/secret-capability.ts +0 -0
  132. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/secret-redaction.ts +0 -0
  133. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/step-lifecycle-tracker.ts +0 -0
  134. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/step-program-dataset-builder.ts +0 -0
  135. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/submit-limits.ts +0 -0
  136. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/tool-result.ts +0 -0
  137. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/work-receipts.ts +0 -0
  138. /package/dist/{repo → bundling-sources}/shared_libs/plays/bootstrap-routes.ts +0 -0
  139. /package/dist/{repo → bundling-sources}/shared_libs/plays/bundling/index.ts +0 -0
  140. /package/dist/{repo → bundling-sources}/shared_libs/plays/bundling/limits.ts +0 -0
  141. /package/dist/{repo → bundling-sources}/shared_libs/plays/contracts.ts +0 -0
  142. /package/dist/{repo → bundling-sources}/shared_libs/plays/dataset.ts +0 -0
  143. /package/dist/{repo → bundling-sources}/shared_libs/plays/row-identity.ts +0 -0
  144. /package/dist/{repo → bundling-sources}/shared_libs/plays/secret-guardrails.ts +0 -0
  145. /package/dist/{repo → bundling-sources}/shared_libs/plays/static-pipeline.ts +0 -0
  146. /package/dist/{repo → bundling-sources}/shared_libs/security/outbound-url-policy.ts +0 -0
  147. /package/dist/{repo → bundling-sources}/shared_libs/security/safe-fetch.ts +0 -0
  148. /package/dist/{repo → bundling-sources}/shared_libs/temporal/constants.ts +0 -0
package/dist/cli/index.js CHANGED
@@ -181,9 +181,9 @@ function configureProxyFromEnv() {
181
181
  configureProxyFromEnv();
182
182
 
183
183
  // src/cli/index.ts
184
- var import_promises7 = require("fs/promises");
185
- var import_node_path22 = require("path");
186
- var import_node_os17 = require("os");
184
+ var import_promises5 = require("fs/promises");
185
+ var import_node_path19 = require("path");
186
+ var import_node_os15 = require("os");
187
187
  var import_commander3 = require("commander");
188
188
 
189
189
  // src/config.ts
@@ -403,10 +403,10 @@ var SDK_RELEASE = {
403
403
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
404
404
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
405
405
  // the SDK enrich generator's one-second stale policy.
406
- version: "0.1.119",
406
+ version: "0.1.121",
407
407
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
408
408
  supportPolicy: {
409
- latest: "0.1.119",
409
+ latest: "0.1.121",
410
410
  minimumSupported: "0.1.53",
411
411
  deprecatedBelow: "0.1.53",
412
412
  commandMinimumSupported: [
@@ -919,7 +919,7 @@ function decodeSseFrame(frame) {
919
919
  return parsed;
920
920
  }
921
921
  function sleep(ms) {
922
- return new Promise((resolve16) => setTimeout(resolve16, ms));
922
+ return new Promise((resolve13) => setTimeout(resolve13, ms));
923
923
  }
924
924
  function withCoworkNetworkHint(message) {
925
925
  if (!isCoworkLikeSandbox() || message.includes(COWORK_NETWORK_HINT)) {
@@ -1676,14 +1676,14 @@ async function* observeRunEvents(options) {
1676
1676
  try {
1677
1677
  for (; ; ) {
1678
1678
  if (queue.length === 0) {
1679
- const waitForItem = new Promise((resolve16) => {
1680
- wake = resolve16;
1679
+ const waitForItem = new Promise((resolve13) => {
1680
+ wake = resolve13;
1681
1681
  });
1682
1682
  if (!sawFirstSnapshot) {
1683
1683
  const timedOut = await Promise.race([
1684
1684
  waitForItem.then(() => false),
1685
1685
  new Promise(
1686
- (resolve16) => setTimeout(() => resolve16(true), OBSERVE_BOOTSTRAP_TIMEOUT_MS)
1686
+ (resolve13) => setTimeout(() => resolve13(true), OBSERVE_BOOTSTRAP_TIMEOUT_MS)
1687
1687
  )
1688
1688
  ]);
1689
1689
  if (timedOut && queue.length === 0) {
@@ -1783,7 +1783,7 @@ var REGISTER_PLAY_ARTIFACTS_COMPILE_CONCURRENCY = 3;
1783
1783
  var REGISTER_PLAY_ARTIFACTS_MAX_BATCH_COUNT = 3;
1784
1784
  var REGISTER_PLAY_ARTIFACTS_MAX_BATCH_BYTES = 25e5;
1785
1785
  function sleep2(ms) {
1786
- return new Promise((resolve16) => setTimeout(resolve16, ms));
1786
+ return new Promise((resolve13) => setTimeout(resolve13, ms));
1787
1787
  }
1788
1788
  function isTransientCompileManifestError(error) {
1789
1789
  if (error instanceof DeeplineError && typeof error.statusCode === "number") {
@@ -2900,20 +2900,105 @@ var DeeplineClient = class {
2900
2900
  return response.runs ?? [];
2901
2901
  }
2902
2902
  /**
2903
- * Observe one run's live events through the Convex Run Snapshot
2904
- * subscription transport (ADR-0008). Yields the same `play.*` event
2905
- * envelopes as {@link streamPlayRunEvents} and ends after the terminal
2906
- * snapshot. Throws {@link RunObserveTransportUnavailableError} when this
2907
- * server cannot serve the transport (older server, unconfigured grants, or
2908
- * unreachable Convex) — callers fall back to the SSE stream with a notice.
2903
+ * Observe one run's live events. Uses the Convex Run Snapshot subscription
2904
+ * transport first (ADR-0008), then falls back to the canonical SSE stream
2905
+ * when the subscription transport or its optional client modules are not
2906
+ * available. Pass `fallback: 'none'` to receive
2907
+ * {@link RunObserveTransportUnavailableError} instead.
2909
2908
  */
2910
- observeRunEvents(runId, options) {
2911
- return observeRunEvents({
2912
- http: this.http,
2909
+ async *observeRunEvents(runId, options) {
2910
+ let yieldedObserveEvent = false;
2911
+ try {
2912
+ for await (const event of observeRunEvents({
2913
+ http: this.http,
2914
+ runId,
2915
+ signal: options?.signal,
2916
+ onNotice: options?.onNotice
2917
+ })) {
2918
+ yieldedObserveEvent = true;
2919
+ yield event;
2920
+ }
2921
+ } catch (error) {
2922
+ if (!(error instanceof RunObserveTransportUnavailableError) || yieldedObserveEvent || options?.fallback === "none") {
2923
+ throw error;
2924
+ }
2925
+ options?.onNotice?.(
2926
+ `[observe] live subscription unavailable (${error.reason}); falling back to SSE tail (support window, ADR-0008)`
2927
+ );
2928
+ yield* this.streamPlayRunEventsUntilTerminal(runId, options);
2929
+ }
2930
+ }
2931
+ async *streamPlayRunEventsUntilTerminal(runId, options) {
2932
+ const state = {
2913
2933
  runId,
2914
- signal: options?.signal,
2915
- onNotice: options?.onNotice
2916
- });
2934
+ status: "running",
2935
+ logs: [],
2936
+ lastLogSeq: 0,
2937
+ latest: null
2938
+ };
2939
+ let lastEventId;
2940
+ let reconnectAttempt = 0;
2941
+ for (; ; ) {
2942
+ if (options?.signal?.aborted) {
2943
+ return;
2944
+ }
2945
+ const connectedAt = Date.now();
2946
+ let sawEvent = false;
2947
+ let endedReason = "stream window ended before a terminal event";
2948
+ try {
2949
+ for await (const event of this.streamPlayRunEvents(runId, {
2950
+ mode: "cli",
2951
+ signal: options?.signal,
2952
+ ...lastEventId ? { lastEventId } : {}
2953
+ })) {
2954
+ sawEvent = true;
2955
+ if (event.cursor?.trim()) {
2956
+ lastEventId = event.cursor;
2957
+ }
2958
+ yield event;
2959
+ const status = updatePlayLiveStatusState(state, event);
2960
+ if (status && TERMINAL_PLAY_STATUSES.has(status.status)) {
2961
+ return;
2962
+ }
2963
+ }
2964
+ } catch (error) {
2965
+ if (options?.signal?.aborted) {
2966
+ return;
2967
+ }
2968
+ if (!isTransientPlayStreamError(error)) {
2969
+ throw error;
2970
+ }
2971
+ endedReason = error instanceof Error ? error.message : String(error);
2972
+ }
2973
+ let refreshed = null;
2974
+ try {
2975
+ refreshed = await this.getRunStatus(runId);
2976
+ } catch (error) {
2977
+ if (!isTransientPlayStreamError(error)) {
2978
+ throw error;
2979
+ }
2980
+ }
2981
+ if (refreshed && TERMINAL_PLAY_STATUSES.has(refreshed.status)) {
2982
+ yield {
2983
+ cursor: String(Date.now()),
2984
+ streamId: `sse-fallback:${runId}`,
2985
+ scope: "play",
2986
+ type: "play.run.status",
2987
+ at: (/* @__PURE__ */ new Date()).toISOString(),
2988
+ payload: refreshed
2989
+ };
2990
+ return;
2991
+ }
2992
+ if (sawEvent || Date.now() - connectedAt >= STREAM_HEALTHY_CONNECTION_MS) {
2993
+ reconnectAttempt = 0;
2994
+ }
2995
+ const delayMs = streamReconnectDelayMs(reconnectAttempt);
2996
+ reconnectAttempt += 1;
2997
+ options?.onNotice?.(
2998
+ `[observe] SSE tail window ended before terminal status (${endedReason}); reconnecting to run ${runId}`
2999
+ );
3000
+ await sleep2(delayMs);
3001
+ }
2917
3002
  }
2918
3003
  /**
2919
3004
  * Tail one run through the subscription transport until terminal, then
@@ -2929,7 +3014,8 @@ var DeeplineClient = class {
2929
3014
  };
2930
3015
  for await (const event of this.observeRunEvents(runId, {
2931
3016
  signal: options?.signal,
2932
- onNotice: options?.onNotice
3017
+ onNotice: options?.onNotice,
3018
+ fallback: "none"
2933
3019
  })) {
2934
3020
  const status = updatePlayLiveStatusState(state, event);
2935
3021
  if (!status || !TERMINAL_PLAY_STATUSES.has(status.status)) {
@@ -4221,7 +4307,7 @@ function buildCandidateUrls2(url) {
4221
4307
  }
4222
4308
  }
4223
4309
  function sleep4(ms) {
4224
- return new Promise((resolve16) => setTimeout(resolve16, ms));
4310
+ return new Promise((resolve13) => setTimeout(resolve13, ms));
4225
4311
  }
4226
4312
  function printDeeplineLogo() {
4227
4313
  if (process.stdout.isTTY && (process.stdout.columns ?? 80) >= 70) {
@@ -4256,10 +4342,8 @@ async function claimInstallBonus(baseUrl, apiKey) {
4256
4342
  apiKey,
4257
4343
  {}
4258
4344
  );
4259
- if (status !== 200) {
4260
- return;
4261
- }
4262
- const granted = Number(data.credits_granted ?? 0);
4345
+ if (status !== 200) return;
4346
+ const granted = typeof data.credits_granted === "number" ? data.credits_granted : 0;
4263
4347
  const alreadyGranted = data.already_granted === true;
4264
4348
  if (granted > 0) {
4265
4349
  console.log(`
@@ -6173,38 +6257,38 @@ function buildDatasetStats(rows, totalRows = rows.length, columns = inferColumns
6173
6257
  }
6174
6258
  }
6175
6259
  const denominator = nonEmpty + empty;
6176
- const stat4 = {
6260
+ const stat2 = {
6177
6261
  non_empty: percentText(nonEmpty, denominator),
6178
6262
  unique: valueCounts.size
6179
6263
  };
6180
6264
  const rawExecutionStats = executionStats?.columnStats[column];
6181
6265
  if (rawExecutionStats) {
6182
- stat4.execution = formatDatasetExecutionStats(
6266
+ stat2.execution = formatDatasetExecutionStats(
6183
6267
  rawExecutionStats,
6184
6268
  totalRows
6185
6269
  );
6186
6270
  }
6187
6271
  if (sampleValue !== void 0 && sampleValueType) {
6188
- stat4.sample_value = sampleValue;
6189
- stat4.sample_type = sampleValueType;
6272
+ stat2.sample_value = sampleValue;
6273
+ stat2.sample_type = sampleValueType;
6190
6274
  }
6191
6275
  if (valueCounts.size > 0 && valueCounts.size < nonEmpty) {
6192
6276
  const top = [...valueCounts.entries()].sort((left, right) => right[1] - left[1]).slice(0, 3);
6193
6277
  const topKeys = new Set(top.map(([key]) => key));
6194
6278
  const otherCount = [...valueCounts.entries()].filter(([key]) => !topKeys.has(key)).reduce((sum, [, count]) => sum + count, 0);
6195
- stat4.top_values = Object.fromEntries(
6279
+ stat2.top_values = Object.fromEntries(
6196
6280
  top.map(([key, count]) => [key, countPercentText(count, denominator)])
6197
6281
  );
6198
6282
  if (otherCount > 0) {
6199
- stat4.top_values["(other)"] = countPercentText(otherCount, denominator);
6283
+ stat2.top_values["(other)"] = countPercentText(otherCount, denominator);
6200
6284
  }
6201
6285
  if (empty > 0) {
6202
- stat4.top_values["(null)"] = countPercentText(empty, denominator);
6286
+ stat2.top_values["(null)"] = countPercentText(empty, denominator);
6203
6287
  }
6204
6288
  } else if (empty > 0 && nonEmpty > 0) {
6205
- stat4.top_values = { "(null)": countPercentText(empty, denominator) };
6289
+ stat2.top_values = { "(null)": countPercentText(empty, denominator) };
6206
6290
  }
6207
- columnStats[column] = stat4;
6291
+ columnStats[column] = stat2;
6208
6292
  }
6209
6293
  return {
6210
6294
  total_rows: totalRows,
@@ -6689,1898 +6773,98 @@ Examples:
6689
6773
  }
6690
6774
 
6691
6775
  // src/cli/commands/enrich.ts
6692
- var import_promises5 = require("fs/promises");
6693
- var import_node_os9 = require("os");
6694
- var import_node_path14 = require("path");
6776
+ var import_promises3 = require("fs/promises");
6777
+ var import_node_os7 = require("os");
6778
+ var import_node_path11 = require("path");
6695
6779
 
6696
6780
  // src/cli/commands/play.ts
6697
- var import_node_crypto3 = require("crypto");
6698
- var import_node_fs11 = require("fs");
6699
- var import_node_path13 = require("path");
6700
- var import_sync5 = require("csv-parse/sync");
6701
-
6702
- // src/plays/bundle-play-file.ts
6703
- var import_node_os8 = require("os");
6704
- var import_node_path11 = require("path");
6705
- var import_node_url = require("url");
6781
+ var import_node_crypto = require("crypto");
6706
6782
  var import_node_fs9 = require("fs");
6783
+ var import_node_path10 = require("path");
6784
+ var import_sync5 = require("csv-parse/sync");
6707
6785
 
6708
- // ../shared_libs/plays/bundling/index.ts
6709
- var import_node_crypto = require("crypto");
6786
+ // src/cli/commands/plays/bootstrap.ts
6710
6787
  var import_node_fs8 = require("fs");
6711
- var import_promises3 = require("fs/promises");
6712
- var import_node_os7 = require("os");
6713
6788
  var import_node_path9 = require("path");
6714
- var import_node_module = require("module");
6715
- var import_esbuild = require("esbuild");
6789
+ var import_sync4 = require("csv-parse/sync");
6716
6790
 
6717
- // ../shared_libs/play-runtime/backend.ts
6718
- var PLAY_RUNTIME_BACKENDS = {
6719
- localProcess: "local_process",
6720
- daytona: "daytona",
6721
- // Artifact/runtime contract for Cloudflare Dynamic Workers. This is no
6722
- // longer a standalone runner backend; use profile=workers_edge so the
6723
- // cf-workflows scheduler owns loading and execution.
6724
- cloudflareWorkers: "cloudflare_workers"
6725
- };
6726
- var PLAY_ARTIFACT_KINDS = {
6727
- cjsNode20: "cjs_node20",
6728
- esmWorkers: "esm_workers"
6791
+ // ../shared_libs/plays/bootstrap-routes.ts
6792
+ var PLAY_BOOTSTRAP_TEMPLATES = [
6793
+ "people-list",
6794
+ "company-list",
6795
+ "people-email",
6796
+ "people-phone",
6797
+ "company-people",
6798
+ "company-people-email",
6799
+ "company-people-phone"
6800
+ ];
6801
+ var PLAY_BOOTSTRAP_COMPANY_PROVIDER_CATEGORY = "company_search";
6802
+ var PLAY_BOOTSTRAP_PEOPLE_PROVIDER_CATEGORY = "people_search";
6803
+ var PLAY_BOOTSTRAP_PROVIDER_CATEGORY_BY_FINDER = {
6804
+ email_finder: "email_finder",
6805
+ phone_finder: "phone_finder"
6729
6806
  };
6730
- var PLAY_BACKEND_DESCRIPTORS = {
6731
- [PLAY_RUNTIME_BACKENDS.localProcess]: {
6732
- id: PLAY_RUNTIME_BACKENDS.localProcess,
6733
- artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
6734
- label: "Local node subprocess"
6735
- },
6736
- [PLAY_RUNTIME_BACKENDS.daytona]: {
6737
- id: PLAY_RUNTIME_BACKENDS.daytona,
6738
- artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
6739
- label: "Daytona sandbox"
6740
- },
6741
- [PLAY_RUNTIME_BACKENDS.cloudflareWorkers]: {
6742
- id: PLAY_RUNTIME_BACKENDS.cloudflareWorkers,
6743
- artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
6744
- label: "Cloudflare Dynamic Workers"
6745
- }
6807
+ var PLAY_BOOTSTRAP_OUTPUT_FIELD_BY_FINDER = {
6808
+ email_finder: "email",
6809
+ phone_finder: "phone"
6746
6810
  };
6747
-
6748
- // ../shared_libs/plays/contracts.ts
6749
- var PLAY_PUBLIC_API_VERSION = 1;
6750
- var PLAY_ARTIFACT_VERSION = 1;
6751
- var PLAY_MIN_RUNNER_VERSION = 1;
6752
- var PLAY_RUNTIME_FEATURES = [
6753
- "artifact_storage",
6754
- "checkpoint_resume",
6755
- "durable_sleep",
6756
- "packaged_files"
6757
- ];
6758
- function buildPlayContractCompatibility(input2) {
6759
- return {
6760
- apiVersion: PLAY_PUBLIC_API_VERSION,
6761
- artifactVersion: PLAY_ARTIFACT_VERSION,
6762
- minRunnerVersion: PLAY_MIN_RUNNER_VERSION,
6763
- runtimeFeatures: [...PLAY_RUNTIME_FEATURES],
6764
- runtimeBackend: input2?.runtimeBackend ?? null
6765
- };
6766
- }
6767
-
6768
- // ../shared_libs/plays/secret-guardrails.ts
6769
- var SECRET_ENV_PATTERN = /\bprocess(?:\.env|\[['"]env['"]\])(?:\.|\[['"])([A-Z0-9_]*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PRIVATE[_-]?KEY|ACCESS[_-]?KEY)[A-Z0-9_]*)(?:['"]\])?/g;
6770
- var PRIVATE_KEY_PATTERN = /-----BEGIN (?:RSA |EC |OPENSSH |PGP )?PRIVATE KEY-----/;
6771
- var BEARER_LITERAL_PATTERN = /\bBearer\s+[A-Za-z0-9._~+/=-]{16,}/i;
6772
- var ASSIGNMENT_SECRET_LITERAL_PATTERN = /\b(?:api[_-]?key|token|secret|password)\b\s*[:=]\s*['"][^'"]{12,}['"]/i;
6773
- var HIGH_ENTROPY_LITERAL_PATTERN = /['"]([A-Za-z0-9+/=_-]{32,})['"]/g;
6774
- function shannonEntropy(value) {
6775
- const counts = /* @__PURE__ */ new Map();
6776
- for (const char of value) counts.set(char, (counts.get(char) ?? 0) + 1);
6777
- return [...counts.values()].reduce((entropy, count) => {
6778
- const p = count / value.length;
6779
- return entropy - p * Math.log2(p);
6780
- }, 0);
6781
- }
6782
- function collectInlineSecretFindings(sourceCode) {
6783
- const findings = [];
6784
- for (const match of sourceCode.matchAll(SECRET_ENV_PATTERN)) {
6785
- findings.push(`process.env.${match[1]}`);
6786
- }
6787
- if (PRIVATE_KEY_PATTERN.test(sourceCode)) findings.push("private key block");
6788
- if (BEARER_LITERAL_PATTERN.test(sourceCode))
6789
- findings.push("bearer token literal");
6790
- if (ASSIGNMENT_SECRET_LITERAL_PATTERN.test(sourceCode)) {
6791
- findings.push("secret-looking assignment literal");
6792
- }
6793
- for (const match of sourceCode.matchAll(HIGH_ENTROPY_LITERAL_PATTERN)) {
6794
- const literal = match[1] ?? "";
6795
- if (literal.length >= 40 && shannonEntropy(literal) >= 4.2) {
6796
- findings.push("high-entropy string literal");
6797
- break;
6798
- }
6799
- }
6800
- return [...new Set(findings)];
6801
- }
6802
- function validatePlaySourceHasNoInlineSecrets(input2) {
6803
- const findings = collectInlineSecretFindings(input2.sourceCode);
6804
- if (!findings.length) return;
6805
- throw new Error(
6806
- [
6807
- `Play source ${input2.filePath} appears to contain inline secret material: ${[
6808
- ...new Set(findings)
6809
- ].join(", ")}.`,
6810
- 'Author secrets in the dashboard and use ctx.secrets.get("NAME") with an approved helper such as ctx.secrets.bearer(handle).'
6811
- ].join(" ")
6812
- );
6811
+ function isPlayBootstrapTemplate(value) {
6812
+ return PLAY_BOOTSTRAP_TEMPLATES.includes(value);
6813
6813
  }
6814
- function validatePlaySourceFilesHaveNoInlineSecrets(sourceFiles) {
6815
- for (const [filePath, sourceCode] of Object.entries(sourceFiles)) {
6816
- validatePlaySourceHasNoInlineSecrets({ filePath, sourceCode });
6817
- }
6814
+ function formatPlayBootstrapTemplates() {
6815
+ return PLAY_BOOTSTRAP_TEMPLATES.join("|");
6818
6816
  }
6819
6817
 
6820
- // ../shared_libs/plays/bundling/limits.ts
6821
- var MAX_PLAY_BUNDLE_BYTES = 30 * 1024 * 1024;
6822
- var MAX_ESM_WORKERS_BUNDLE_BYTES = 115e4;
6823
-
6824
- // ../shared_libs/plays/bundling/index.ts
6825
- var PLAY_BUNDLE_CACHE_VERSION = 24;
6826
- var PLAY_ARTIFACT_CACHE_DIR = (0, import_node_path9.join)(
6827
- (0, import_node_os7.tmpdir)(),
6828
- `deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION}`
6829
- );
6830
- var PLAY_PROXY_NAMESPACE = "deepline-play-runtime-ref";
6831
- var SOURCE_EXTENSIONS = [
6832
- ".ts",
6833
- ".tsx",
6834
- ".mts",
6835
- ".cts",
6836
- ".js",
6837
- ".jsx",
6838
- ".mjs",
6839
- ".cjs",
6840
- ".json"
6841
- ];
6842
- var WORKERS_PLAY_ENTRY_VIRTUAL = "deepline-play-entry";
6843
- var PLAY_SOURCE_FILE_PATTERN = /\.play\.(?:[cm]?[jt]sx?)$/i;
6844
- var NODE_BUILTIN_SET = new Set(
6845
- import_node_module.builtinModules.flatMap(
6846
- (name) => name.startsWith("node:") ? [name, name.slice(5)] : [name, `node:${name}`]
6847
- )
6848
- );
6849
- function assertValidExportName(exportName) {
6850
- if (exportName === "default") return;
6851
- if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(exportName)) {
6852
- throw new Error(
6853
- `Invalid play export name "${exportName}". Named prebuilt exports must be valid JavaScript identifiers.`
6854
- );
6855
- }
6856
- }
6857
- function sha256(value) {
6858
- return (0, import_node_crypto.createHash)("sha256").update(value).digest("hex");
6859
- }
6860
- function formatEsbuildMessage(message) {
6861
- const location = message.location ? `${message.location.file}:${message.location.line}:${message.location.column}` : null;
6862
- return location ? `${location} ${message.text}` : message.text;
6863
- }
6864
- function isLocalSpecifier(specifier) {
6865
- return specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:");
6866
- }
6867
- async function normalizeLocalPath(filePath) {
6868
- try {
6869
- return await (0, import_promises3.realpath)(filePath);
6870
- } catch {
6871
- return (0, import_node_path9.resolve)(filePath);
6818
+ // src/cli/commands/plays/bootstrap.ts
6819
+ function parseReferencedPlayTarget(target) {
6820
+ const trimmed = target.trim();
6821
+ const slashIndex = trimmed.indexOf("/");
6822
+ if (slashIndex <= 0 || slashIndex === trimmed.length - 1) {
6823
+ return { ownerSlug: null, playName: trimmed, unqualifiedPlayName: trimmed };
6872
6824
  }
6873
- }
6874
- function createPlayWorkspace(entryFile) {
6875
6825
  return {
6876
- entryFile,
6877
- rootDir: (0, import_node_path9.dirname)(entryFile)
6826
+ ownerSlug: trimmed.slice(0, slashIndex),
6827
+ playName: trimmed,
6828
+ unqualifiedPlayName: trimmed.slice(slashIndex + 1)
6878
6829
  };
6879
6830
  }
6880
- function isPathInsideDirectory(filePath, directory) {
6881
- return filePath === directory || filePath.startsWith(`${directory}/`);
6882
- }
6883
- function assertWithinPlayWorkspace(input2) {
6884
- if (isPathInsideDirectory(input2.resolvedPath, input2.workspace.rootDir)) {
6885
- return;
6831
+ function parsePositiveInteger2(value, flagName) {
6832
+ const parsed = Number.parseInt(value, 10);
6833
+ if (!Number.isFinite(parsed) || parsed <= 0) {
6834
+ throw new PlayBootstrapUsageError(
6835
+ `${flagName} must be a positive integer.`
6836
+ );
6886
6837
  }
6887
- throw new Error(
6888
- `${input2.importer}:${input2.line}:${input2.column} Local play imports must stay inside the play workspace (${input2.workspace.rootDir}). Import "${input2.specifier}" resolved to ${input2.resolvedPath}, which crosses into app/backend code. Use the public SDK/API surface or move shared helpers into the play workspace.`
6889
- );
6838
+ return parsed;
6890
6839
  }
6891
- function getPackageName(specifier) {
6892
- if (specifier.startsWith("@")) {
6893
- const [scope, name] = specifier.split("/");
6894
- return scope && name ? `${scope}/${name}` : specifier;
6895
- }
6896
- return specifier.split("/")[0] ?? specifier;
6840
+ function isRecord5(value) {
6841
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
6897
6842
  }
6898
- function isPlaySourceFile(filePath) {
6899
- return PLAY_SOURCE_FILE_PATTERN.test(filePath);
6843
+ function stringValue(value) {
6844
+ return typeof value === "string" ? value.trim() : "";
6900
6845
  }
6901
- function stripCommentsToSpaces(source) {
6902
- return source.replace(/\/\*[\s\S]*?\*\//g, (match) => match.replace(/[^\n]/g, " ")).replace(
6903
- /(^|[^:])\/\/.*$/gm,
6904
- (match, prefix) => prefix + " ".repeat(Math.max(0, match.length - prefix.length))
6846
+ function extractionEntries(value) {
6847
+ if (Array.isArray(value)) return value.filter(isRecord5);
6848
+ if (!isRecord5(value)) return [];
6849
+ return Object.entries(value).map(
6850
+ ([name, entry]) => isRecord5(entry) ? { name, ...entry } : { name }
6905
6851
  );
6906
6852
  }
6907
- function lineAndColumnAt(source, index) {
6908
- const prefix = source.slice(0, index);
6909
- const lines = prefix.split("\n");
6910
- return { line: lines.length, column: lines[lines.length - 1].length + 1 };
6911
- }
6912
- function findSourceImportReferences(sourceCode) {
6913
- const source = stripCommentsToSpaces(sourceCode);
6914
- const references = [];
6915
- const addReference = (specifier, specifierIndex, kind) => {
6916
- if (!specifier) return;
6917
- const position = lineAndColumnAt(sourceCode, specifierIndex);
6918
- references.push({
6919
- specifier,
6920
- line: position.line,
6921
- column: position.column,
6922
- kind
6923
- });
6924
- };
6925
- const staticImportPattern = /\b(?:import|export)\s+(?!type\b)(?:[\s\S]*?\s+from\s*)?(['"])([^'"\n]+)\1/g;
6926
- for (const match of source.matchAll(staticImportPattern)) {
6927
- addReference(
6928
- match[2],
6929
- match.index + match[0].lastIndexOf(match[1]),
6930
- "static"
6931
- );
6932
- }
6933
- const dynamicImportPattern = /\bimport\s*\(\s*(['"])([^'"\n]+)\1/g;
6934
- for (const match of source.matchAll(dynamicImportPattern)) {
6935
- addReference(
6936
- match[2],
6937
- match.index + match[0].lastIndexOf(match[1]),
6938
- "dynamic-import"
6939
- );
6940
- }
6941
- const requirePattern = /\brequire\s*\(\s*(['"])([^'"\n]+)\1/g;
6942
- for (const match of source.matchAll(requirePattern)) {
6943
- addReference(
6944
- match[2],
6945
- match.index + match[0].lastIndexOf(match[1]),
6946
- "require"
6947
- );
6853
+ var PlayBootstrapError = class extends Error {
6854
+ constructor(message, exitCode) {
6855
+ super(message);
6856
+ this.exitCode = exitCode;
6948
6857
  }
6949
- const literalDynamicImportIndexes = new Set(
6950
- [...source.matchAll(dynamicImportPattern)].map((match) => match.index)
6951
- );
6952
- for (const match of source.matchAll(/\bimport\s*\(/g)) {
6953
- if (literalDynamicImportIndexes.has(match.index)) continue;
6954
- const position = lineAndColumnAt(sourceCode, match.index);
6955
- throw new Error(
6956
- `:${position.line}:${position.column} Dynamic import() is not allowed in plays. Use static imports instead.`
6957
- );
6858
+ exitCode;
6859
+ };
6860
+ var PlayBootstrapUsageError = class extends PlayBootstrapError {
6861
+ constructor(message) {
6862
+ super(message, 2);
6958
6863
  }
6959
- const literalRequireIndexes = new Set(
6960
- [...source.matchAll(requirePattern)].map((match) => match.index)
6961
- );
6962
- for (const match of source.matchAll(/\brequire\s*\(/g)) {
6963
- if (literalRequireIndexes.has(match.index)) continue;
6964
- const position = lineAndColumnAt(sourceCode, match.index);
6965
- throw new Error(
6966
- `:${position.line}:${position.column} Dynamic require() is not allowed in plays. Use static imports or require("literal") only.`
6967
- );
6968
- }
6969
- return references.sort(
6970
- (left, right) => left.line === right.line ? left.column - right.column : left.line - right.line
6971
- );
6972
- }
6973
- function unquoteStringLiteral(literal) {
6974
- const trimmed = literal.trim();
6975
- const quote = trimmed[0];
6976
- if (quote !== '"' && quote !== "'" || trimmed[trimmed.length - 1] !== quote) {
6977
- return null;
6978
- }
6979
- try {
6980
- return JSON.parse(
6981
- quote === '"' ? trimmed : `"${trimmed.slice(1, -1).replace(/"/g, '\\"')}"`
6982
- );
6983
- } catch {
6984
- return trimmed.slice(1, -1);
6985
- }
6986
- }
6987
- function findMatchingBrace(source, openIndex) {
6988
- let depth = 0;
6989
- let quote = null;
6990
- let escaped = false;
6991
- for (let index = openIndex; index < source.length; index += 1) {
6992
- const char = source[index];
6993
- if (quote) {
6994
- if (escaped) {
6995
- escaped = false;
6996
- } else if (char === "\\") {
6997
- escaped = true;
6998
- } else if (char === quote) {
6999
- quote = null;
7000
- }
7001
- continue;
7002
- }
7003
- if (char === '"' || char === "'" || char === "`") {
7004
- quote = char;
7005
- continue;
7006
- }
7007
- if (char === "{") depth += 1;
7008
- if (char === "}") {
7009
- depth -= 1;
7010
- if (depth === 0) return index;
7011
- }
7012
- }
7013
- return -1;
7014
- }
7015
- function extractDefinedPlayName(sourceCode) {
7016
- const source = stripCommentsToSpaces(sourceCode);
7017
- const callPattern = /(?:\b[A-Za-z_$][\w$]*\s*\.\s*)?\b(?:definePlay|defineWorkflow)\s*\(/g;
7018
- for (const match of source.matchAll(callPattern)) {
7019
- const openParen = match.index + match[0].length - 1;
7020
- const firstArgStart = openParen + 1;
7021
- const firstNonSpace = source.slice(firstArgStart).search(/\S/);
7022
- if (firstNonSpace < 0) continue;
7023
- const argIndex = firstArgStart + firstNonSpace;
7024
- const quote = source[argIndex];
7025
- if (quote === '"' || quote === "'") {
7026
- const literalMatch = source.slice(argIndex).match(/^(['"])(?:\\.|(?!\1)[\s\S])*\1/);
7027
- const value = literalMatch ? unquoteStringLiteral(literalMatch[0]) : null;
7028
- if (value?.trim()) return value.trim();
7029
- }
7030
- if (quote === "{") {
7031
- const closeBrace = findMatchingBrace(source, argIndex);
7032
- if (closeBrace < 0) continue;
7033
- const objectSource = source.slice(argIndex + 1, closeBrace);
7034
- const idMatch = objectSource.match(
7035
- /(?:^|[,{\s])(?:id|['"]id['"])\s*:\s*(['"])([\s\S]*?)\1/
7036
- );
7037
- if (idMatch?.[2]?.trim()) {
7038
- return idMatch[2].trim();
7039
- }
7040
- }
7041
- }
7042
- return null;
7043
- }
7044
- function canonicalizeRootPlayNameForWorkersRuntimeHash(sourceCode) {
7045
- const source = stripCommentsToSpaces(sourceCode);
7046
- const callPattern = /(?:\b[A-Za-z_$][\w$]*\s*\.\s*)?\b(?:definePlay|defineWorkflow)\s*\(/g;
7047
- const match = callPattern.exec(source);
7048
- if (!match) return sourceCode;
7049
- const openParen = match.index + match[0].length - 1;
7050
- const firstArgStart = openParen + 1;
7051
- const firstNonSpace = source.slice(firstArgStart).search(/\S/);
7052
- if (firstNonSpace < 0) return sourceCode;
7053
- const argIndex = firstArgStart + firstNonSpace;
7054
- const quote = source[argIndex];
7055
- if (quote === '"' || quote === "'") {
7056
- const literalMatch = source.slice(argIndex).match(/^(['"])(?:\\.|(?!\1)[\s\S])*\1/);
7057
- if (!literalMatch) return sourceCode;
7058
- const replacement = `${quote}__deepline_runtime_play_name__${quote}`;
7059
- return `${sourceCode.slice(0, argIndex)}${replacement}${sourceCode.slice(argIndex + literalMatch[0].length)}`;
7060
- }
7061
- if (quote !== "{") return sourceCode;
7062
- const closeBrace = findMatchingBrace(source, argIndex);
7063
- if (closeBrace < 0) return sourceCode;
7064
- const objectSource = source.slice(argIndex + 1, closeBrace);
7065
- const idMatch = objectSource.match(
7066
- /(^|[,{\s])((?:id|['"]id['"])\s*:\s*)(['"])([\s\S]*?)\3/
7067
- );
7068
- if (!idMatch || idMatch.index === void 0) return sourceCode;
7069
- const idValueStart = argIndex + 1 + idMatch.index + idMatch[1].length + idMatch[2].length + idMatch[3].length;
7070
- return `${sourceCode.slice(0, idValueStart)}__deepline_runtime_play_name__${sourceCode.slice(idValueStart + idMatch[4].length)}`;
7071
- }
7072
- function workersRuntimeGraphFilePath(input2) {
7073
- if (input2.filePath === input2.entryFile) return "<entry>";
7074
- const entryRelative = (0, import_node_path9.relative)((0, import_node_path9.dirname)(input2.entryFile), input2.filePath);
7075
- if (entryRelative && !entryRelative.startsWith("..")) {
7076
- return entryRelative.replaceAll("\\", "/");
7077
- }
7078
- return `<project>/${(0, import_node_path9.relative)(input2.adapter.projectRoot, input2.filePath).replaceAll("\\", "/")}`;
7079
- }
7080
- function buildWorkersRuntimeGraphHash(input2) {
7081
- const sourceFiles = Object.entries(input2.analysis.sourceFiles).map(([filePath, contents]) => ({
7082
- filePath: workersRuntimeGraphFilePath({
7083
- entryFile: input2.entryFile,
7084
- filePath,
7085
- adapter: input2.adapter
7086
- }),
7087
- hash: sha256(
7088
- filePath === input2.entryFile ? canonicalizeRootPlayNameForWorkersRuntimeHash(contents) : contents
7089
- )
7090
- })).sort((left, right) => left.filePath.localeCompare(right.filePath));
7091
- return sha256(
7092
- JSON.stringify({
7093
- entryFile: "<entry>",
7094
- entryExport: input2.exportName,
7095
- localFiles: sourceFiles,
7096
- nodeBuiltins: [...input2.analysis.importPolicy.nodeBuiltins].sort(),
7097
- packages: input2.analysis.importPolicy.packages.map(({ name, version }) => ({ name, version })).sort((left, right) => left.name.localeCompare(right.name)),
7098
- importedPlayDependencies: input2.analysis.importedPlayDependencies.map((dependency) => ({
7099
- filePath: workersRuntimeGraphFilePath({
7100
- entryFile: input2.entryFile,
7101
- filePath: dependency.filePath,
7102
- adapter: input2.adapter
7103
- }),
7104
- playName: dependency.playName
7105
- })).sort((left, right) => left.filePath.localeCompare(right.filePath))
7106
- })
7107
- );
7108
- }
7109
- function readPackageVersionFromPackageJson(packageJsonPath, packageName) {
7110
- try {
7111
- const packageJson = JSON.parse((0, import_node_fs8.readFileSync)(packageJsonPath, "utf-8"));
7112
- if (packageJson.name === packageName && typeof packageJson.version === "string") {
7113
- return packageJson.version;
7114
- }
7115
- } catch {
7116
- return null;
7117
- }
7118
- return null;
7119
- }
7120
- function findPackageJsonPathFrom(startDir, packageName) {
7121
- if (!(0, import_node_path9.isAbsolute)(startDir)) {
7122
- throw new Error(
7123
- `Package resolution requires an absolute start directory, got ${startDir}`
7124
- );
7125
- }
7126
- let current = startDir;
7127
- while (true) {
7128
- const packageJsonPath = (0, import_node_path9.join)(
7129
- current,
7130
- "node_modules",
7131
- packageName,
7132
- "package.json"
7133
- );
7134
- if ((0, import_node_fs8.existsSync)(packageJsonPath)) {
7135
- return packageJsonPath;
7136
- }
7137
- const parent = (0, import_node_path9.dirname)(current);
7138
- if (parent === current) {
7139
- return null;
7140
- }
7141
- current = parent;
7142
- }
7143
- }
7144
- function findPackageJsonPath(packageName, fromFile, adapter) {
7145
- const startDirs = [
7146
- (0, import_node_path9.resolve)((0, import_node_path9.dirname)(fromFile)),
7147
- (0, import_node_path9.resolve)(adapter.projectRoot),
7148
- (0, import_node_path9.resolve)((0, import_node_path9.dirname)(adapter.sdkPackageJson))
7149
- ];
7150
- const seen = /* @__PURE__ */ new Set();
7151
- for (const startDir of startDirs) {
7152
- if (seen.has(startDir)) continue;
7153
- seen.add(startDir);
7154
- const packageJsonPath = findPackageJsonPathFrom(startDir, packageName);
7155
- if (packageJsonPath) return packageJsonPath;
7156
- }
7157
- const adapterNodeModulesPackageJson = (0, import_node_path9.join)(
7158
- adapter.nodeModulesDir,
7159
- packageName,
7160
- "package.json"
7161
- );
7162
- return (0, import_node_fs8.existsSync)(adapterNodeModulesPackageJson) ? adapterNodeModulesPackageJson : null;
7163
- }
7164
- function localSdkAliasPlugin(adapter, options) {
7165
- const entryFile = options?.workersRuntime ? adapter.sdkWorkersEntryFile : adapter.sdkEntryFile;
7166
- if (!(0, import_node_fs8.existsSync)(entryFile)) {
7167
- return null;
7168
- }
7169
- return {
7170
- name: "deepline-sdk-local-alias",
7171
- setup(buildContext) {
7172
- buildContext.onResolve({ filter: /^deepline$/ }, () => ({
7173
- path: entryFile
7174
- }));
7175
- buildContext.onResolve({ filter: /^deepline\/helpers$/ }, () => ({
7176
- path: (0, import_node_path9.join)(adapter.sdkSourceRoot, "helpers.ts")
7177
- }));
7178
- }
7179
- };
7180
- }
7181
- function workersPlayEntryAliasPlugin(playFilePath) {
7182
- return {
7183
- name: "deepline-workers-play-entry-alias",
7184
- setup(buildContext) {
7185
- buildContext.onResolve(
7186
- { filter: new RegExp(`^${WORKERS_PLAY_ENTRY_VIRTUAL}$`) },
7187
- () => ({ path: playFilePath })
7188
- );
7189
- }
7190
- };
7191
- }
7192
- function workersNamedPlayEntryAliasPlugin(playFilePath, exportName) {
7193
- return {
7194
- name: "deepline-workers-named-play-entry-alias",
7195
- setup(buildContext) {
7196
- buildContext.onResolve(
7197
- { filter: new RegExp(`^${WORKERS_PLAY_ENTRY_VIRTUAL}$`) },
7198
- () => ({
7199
- path: `${playFilePath}.${exportName}.entry.ts`,
7200
- namespace: "deepline-named-play-entry"
7201
- })
7202
- );
7203
- buildContext.onLoad(
7204
- { filter: /.*/, namespace: "deepline-named-play-entry" },
7205
- () => ({
7206
- contents: `export { ${exportName} as default } from ${JSON.stringify(playFilePath)};
7207
- `,
7208
- loader: "ts",
7209
- resolveDir: (0, import_node_path9.dirname)(playFilePath)
7210
- })
7211
- );
7212
- }
7213
- };
7214
- }
7215
- function workersNodeBuiltinStubPlugin() {
7216
- const UNSUPPORTED = /* @__PURE__ */ new Set([
7217
- "node:fs",
7218
- "node:fs/promises",
7219
- "node:os",
7220
- "node:child_process"
7221
- ]);
7222
- return {
7223
- name: "deepline-workers-node-builtin-stub",
7224
- setup(buildContext) {
7225
- buildContext.onResolve({ filter: /^node:/ }, (args) => {
7226
- if (!UNSUPPORTED.has(args.path)) return null;
7227
- return { path: args.path, namespace: "deepline-workers-node-stub" };
7228
- });
7229
- buildContext.onLoad(
7230
- { filter: /.*/, namespace: "deepline-workers-node-stub" },
7231
- (args) => {
7232
- const builtinName = args.path;
7233
- const stubSource = `
7234
- const message = ${JSON.stringify(
7235
- `Workers backend: ${builtinName} is not available in Cloudflare Workers (no filesystem / no OS). Run this play on Daytona or local-process backend if it needs node builtins.`
7236
- )};
7237
- function makeThrower(name) {
7238
- return new Proxy(function() { throw new Error(message + ' (called: ' + name + ')'); }, {
7239
- get(_t, prop) {
7240
- if (prop === '__esModule') return true;
7241
- if (typeof prop === 'symbol') return undefined;
7242
- return makeThrower(name + '.' + String(prop));
7243
- },
7244
- apply() { throw new Error(message + ' (called: ' + name + ')'); },
7245
- construct() { throw new Error(message + ' (constructed: ' + name + ')'); },
7246
- });
7247
- }
7248
- module.exports = makeThrower(${JSON.stringify(builtinName)});
7249
- `;
7250
- return { contents: stubSource, loader: "js" };
7251
- }
7252
- );
7253
- }
7254
- };
7255
- }
7256
- function zodNonEnglishLocaleStubPlugin() {
7257
- const LOCALE_PATH_FILTER = /[\\/]zod[\\/]v4[\\/]locales[\\/][^\\/]+\.(?:c?js|mjs)$/;
7258
- const NAMESPACE = "deepline-zod-locale-stub";
7259
- return {
7260
- name: "deepline-zod-non-english-locale-stub",
7261
- setup(buildContext) {
7262
- buildContext.onResolve({ filter: LOCALE_PATH_FILTER }, (args) => {
7263
- const norm = args.path.replace(/\\/g, "/");
7264
- const file = norm.slice(norm.lastIndexOf("/") + 1);
7265
- if (/^en(?:[-_][A-Za-z]+)?\.(?:c?js|mjs)$/.test(file)) {
7266
- return null;
7267
- }
7268
- return { path: args.path, namespace: NAMESPACE };
7269
- });
7270
- buildContext.onLoad({ filter: /.*/, namespace: NAMESPACE }, () => ({
7271
- // zod locales export a default object literal. Empty object is
7272
- // structurally compatible — accessing any locale key returns
7273
- // undefined and zod falls back to its built-in English.
7274
- contents: "export default {};",
7275
- loader: "js"
7276
- }));
7277
- }
7278
- };
7279
- }
7280
- var WORKERS_BANNED_NODE_MODULES = /* @__PURE__ */ new Set([
7281
- "node:fs",
7282
- "node:fs/promises",
7283
- "node:net",
7284
- "node:child_process",
7285
- "node:cluster",
7286
- "node:tls",
7287
- "node:dgram",
7288
- "node:dns",
7289
- "node:dns/promises",
7290
- "node:repl",
7291
- "node:vm",
7292
- "node:worker_threads"
7293
- ]);
7294
- function workersNodeImportBanlistPlugin(adapter) {
7295
- return {
7296
- name: "deepline-workers-node-import-banlist",
7297
- setup(buildContext) {
7298
- buildContext.onResolve({ filter: /^node:/ }, (args) => {
7299
- if (!WORKERS_BANNED_NODE_MODULES.has(args.path)) return null;
7300
- const importer = args.importer ?? "";
7301
- if (importer.startsWith(adapter.sdkSourceRoot)) {
7302
- return null;
7303
- }
7304
- return {
7305
- errors: [
7306
- {
7307
- text: `Module "${args.path}" is not allowed in workers_edge plays. See AGENTS.md for the V8 isolate boundary.`,
7308
- detail: { importer: args.importer, kind: args.kind }
7309
- }
7310
- ]
7311
- };
7312
- });
7313
- }
7314
- };
7315
- }
7316
- function buildImportedPlayProxyModule(playName) {
7317
- const serializedName = JSON.stringify(playName);
7318
- return `
7319
- const PLAY_METADATA_SYMBOL = Symbol.for('deepline.play.metadata');
7320
- const importedPlayRef = async function importedPlayRef(ctx, input) {
7321
- return ctx.runPlay(${JSON.stringify(`imported_${playName.replace(/[^A-Za-z0-9_]+/g, "_")}`)}, importedPlayRef, input, {
7322
- description: 'Run the imported Deepline play dependency.',
7323
- });
7324
- };
7325
- Object.defineProperty(importedPlayRef, 'playName', {
7326
- value: ${serializedName},
7327
- enumerable: true,
7328
- configurable: false,
7329
- writable: false,
7330
- });
7331
- Object.defineProperty(importedPlayRef, PLAY_METADATA_SYMBOL, {
7332
- value: { name: ${serializedName} },
7333
- enumerable: false,
7334
- configurable: false,
7335
- writable: false,
7336
- });
7337
- export const playName = ${serializedName};
7338
- export const name = ${serializedName};
7339
- export default importedPlayRef;
7340
- `;
7341
- }
7342
- function importedPlayProxyPlugin(importedPlayDependencies) {
7343
- if (importedPlayDependencies.length === 0) {
7344
- return null;
7345
- }
7346
- const dependenciesByPath = new Map(
7347
- importedPlayDependencies.map((dependency) => [
7348
- dependency.filePath,
7349
- dependency
7350
- ])
7351
- );
7352
- return {
7353
- name: "deepline-imported-play-proxy",
7354
- setup(buildContext) {
7355
- buildContext.onResolve({ filter: /.*/ }, async (args) => {
7356
- if (!args.importer || !isLocalSpecifier(args.path)) {
7357
- return null;
7358
- }
7359
- const resolvedPath = await resolveLocalImport(args.importer, args.path);
7360
- const dependency = dependenciesByPath.get(resolvedPath);
7361
- if (!dependency) {
7362
- return null;
7363
- }
7364
- return {
7365
- path: dependency.filePath,
7366
- namespace: PLAY_PROXY_NAMESPACE,
7367
- pluginData: dependency
7368
- };
7369
- });
7370
- buildContext.onLoad(
7371
- { filter: /.*/, namespace: PLAY_PROXY_NAMESPACE },
7372
- async (args) => {
7373
- const dependency = args.pluginData ?? dependenciesByPath.get(args.path);
7374
- if (!dependency) {
7375
- return null;
7376
- }
7377
- return {
7378
- contents: buildImportedPlayProxyModule(dependency.playName),
7379
- loader: "ts",
7380
- resolveDir: (0, import_node_path9.dirname)(args.path)
7381
- };
7382
- }
7383
- );
7384
- }
7385
- };
7386
- }
7387
- async function fileExists(filePath) {
7388
- try {
7389
- await (0, import_promises3.stat)(filePath);
7390
- return true;
7391
- } catch {
7392
- return false;
7393
- }
7394
- }
7395
- async function resolveLocalImport(fromFile, specifier) {
7396
- if (specifier.startsWith("file:")) {
7397
- return normalizeLocalPath(new URL(specifier).pathname);
7398
- }
7399
- const base = (0, import_node_path9.isAbsolute)(specifier) ? (0, import_node_path9.resolve)(specifier) : (0, import_node_path9.resolve)((0, import_node_path9.dirname)(fromFile), specifier);
7400
- const candidates = [base];
7401
- const explicitExtension = (0, import_node_path9.extname)(base).toLowerCase();
7402
- if (!explicitExtension) {
7403
- candidates.push(
7404
- ...SOURCE_EXTENSIONS.map((extension) => `${base}${extension}`)
7405
- );
7406
- candidates.push(
7407
- ...SOURCE_EXTENSIONS.map((extension) => (0, import_node_path9.join)(base, `index${extension}`))
7408
- );
7409
- } else if ([".js", ".jsx", ".mjs", ".cjs"].includes(explicitExtension)) {
7410
- const stem = base.slice(0, -explicitExtension.length);
7411
- candidates.push(
7412
- ...SOURCE_EXTENSIONS.map((extension) => `${stem}${extension}`)
7413
- );
7414
- }
7415
- for (const candidate of candidates) {
7416
- if (await fileExists(candidate)) {
7417
- return normalizeLocalPath(candidate);
7418
- }
7419
- }
7420
- throw new Error(
7421
- `Could not resolve local import "${specifier}" from ${fromFile}`
7422
- );
7423
- }
7424
- function resolvePackageImport(specifier, fromFile, adapter) {
7425
- const packageName = getPackageName(specifier);
7426
- if (packageName === "deepline" && (0, import_node_fs8.existsSync)(adapter.sdkPackageJson)) {
7427
- const packageJson = JSON.parse(
7428
- (0, import_node_fs8.readFileSync)(adapter.sdkPackageJson, "utf-8")
7429
- );
7430
- return {
7431
- name: "deepline",
7432
- version: packageJson.version ?? null
7433
- };
7434
- }
7435
- const packageJsonPath = findPackageJsonPath(packageName, fromFile, adapter);
7436
- if (!packageJsonPath) {
7437
- throw new Error(`Could not resolve "${specifier}" from ${fromFile}`);
7438
- }
7439
- return {
7440
- name: packageName,
7441
- version: readPackageVersionFromPackageJson(packageJsonPath, packageName)
7442
- };
7443
- }
7444
- async function analyzeSourceGraph(entryFile, adapter) {
7445
- const absoluteEntryFile = await normalizeLocalPath(entryFile);
7446
- const workspace = createPlayWorkspace(absoluteEntryFile);
7447
- const localFiles = /* @__PURE__ */ new Map();
7448
- const nodeBuiltins = /* @__PURE__ */ new Set();
7449
- const packages = /* @__PURE__ */ new Map();
7450
- const importedPlayDependencies = /* @__PURE__ */ new Map();
7451
- const visited = /* @__PURE__ */ new Set();
7452
- const visitFile = async (filePath) => {
7453
- const absolutePath = await normalizeLocalPath(filePath);
7454
- if (visited.has(absolutePath)) {
7455
- return;
7456
- }
7457
- visited.add(absolutePath);
7458
- const sourceCode2 = await (0, import_promises3.readFile)(absolutePath, "utf-8");
7459
- localFiles.set(absolutePath, sourceCode2);
7460
- if ((0, import_node_path9.extname)(absolutePath).toLowerCase() === ".json") {
7461
- return;
7462
- }
7463
- const handleSpecifier = async (specifier, line, column, kind) => {
7464
- if (kind === "dynamic-import") {
7465
- throw new Error(
7466
- `${absolutePath}:${line}:${column} Dynamic import() is not allowed in plays. Use static imports instead.`
7467
- );
7468
- }
7469
- if (NODE_BUILTIN_SET.has(specifier)) {
7470
- nodeBuiltins.add(
7471
- specifier.startsWith("node:") ? specifier : `node:${specifier}`
7472
- );
7473
- return;
7474
- }
7475
- if (isLocalSpecifier(specifier)) {
7476
- const resolved = await resolveLocalImport(absolutePath, specifier);
7477
- assertWithinPlayWorkspace({
7478
- importer: absolutePath,
7479
- specifier,
7480
- resolvedPath: resolved,
7481
- workspace,
7482
- line,
7483
- column
7484
- });
7485
- if (resolved !== absoluteEntryFile && isPlaySourceFile(resolved)) {
7486
- const importedSource = await (0, import_promises3.readFile)(resolved, "utf-8");
7487
- const importedPlayName = extractDefinedPlayName(importedSource);
7488
- if (!importedPlayName) {
7489
- throw new Error(
7490
- `${absolutePath}:${line}:${column} Imported play file "${specifier}" must export definePlay(...) so it can be runtime-composed.`
7491
- );
7492
- }
7493
- importedPlayDependencies.set(resolved, {
7494
- filePath: resolved,
7495
- playName: importedPlayName
7496
- });
7497
- return;
7498
- }
7499
- await visitFile(resolved);
7500
- return;
7501
- }
7502
- if (specifier.includes(":")) {
7503
- throw new Error(
7504
- `${absolutePath}:${line}:${column} Unsupported import specifier "${specifier}". Allowed imports are relative files, Node builtins, and installed packages.`
7505
- );
7506
- }
7507
- const packageImport = resolvePackageImport(
7508
- specifier,
7509
- absolutePath,
7510
- adapter
7511
- );
7512
- packages.set(packageImport.name, packageImport.version);
7513
- };
7514
- try {
7515
- for (const reference of findSourceImportReferences(sourceCode2)) {
7516
- await handleSpecifier(
7517
- reference.specifier,
7518
- reference.line,
7519
- reference.column,
7520
- reference.kind
7521
- );
7522
- }
7523
- } catch (error) {
7524
- if (error instanceof Error && error.message.startsWith(":")) {
7525
- throw new Error(`${absolutePath}${error.message}`);
7526
- }
7527
- throw error;
7528
- }
7529
- };
7530
- await visitFile(absoluteEntryFile);
7531
- const sourceCode = localFiles.get(absoluteEntryFile) ?? "";
7532
- const sourceHash = sha256(sourceCode);
7533
- const graphHash = sha256(
7534
- JSON.stringify({
7535
- entryFile: absoluteEntryFile,
7536
- localFiles: [...localFiles.entries()].map(([filePath, contents]) => ({ filePath, hash: sha256(contents) })).sort((left, right) => left.filePath.localeCompare(right.filePath)),
7537
- nodeBuiltins: [...nodeBuiltins].sort(),
7538
- packages: [...packages.entries()].map(([name, version]) => ({ name, version })).sort((left, right) => left.name.localeCompare(right.name)),
7539
- importedPlayDependencies: [...importedPlayDependencies.values()].map((dependency) => ({
7540
- filePath: dependency.filePath,
7541
- playName: dependency.playName
7542
- })).sort((left, right) => left.filePath.localeCompare(right.filePath))
7543
- })
7544
- );
7545
- const playName = extractDefinedPlayName(sourceCode);
7546
- return {
7547
- sourceCode,
7548
- sourceFiles: Object.fromEntries(
7549
- [...localFiles.entries()].sort(
7550
- (left, right) => left[0].localeCompare(right[0])
7551
- )
7552
- ),
7553
- sourceHash,
7554
- graphHash,
7555
- importPolicy: {
7556
- localFiles: [...localFiles.keys()].sort(),
7557
- nodeBuiltins: [...nodeBuiltins].sort(),
7558
- packages: [...packages.entries()].map(([name, version]) => ({ name, version })).sort((left, right) => left.name.localeCompare(right.name))
7559
- },
7560
- playName,
7561
- importedPlayDependencies: [...importedPlayDependencies.values()].sort(
7562
- (left, right) => left.filePath.localeCompare(right.filePath)
7563
- )
7564
- };
7565
- }
7566
- async function computeWorkersHarnessFingerprintWithAdapter(adapter) {
7567
- const { readdir } = await import("fs/promises");
7568
- const addFilePart = async (parts2, rootDir, filePath) => {
7569
- const contents = await (0, import_promises3.readFile)(filePath, "utf-8");
7570
- parts2.push({
7571
- name: `${(0, import_node_path9.basename)(rootDir)}:${filePath.slice(rootDir.length + 1)}`,
7572
- hash: sha256(contents)
7573
- });
7574
- };
7575
- const collectTopLevelTsFiles = async (rootDir, parts2) => {
7576
- if (!await fileExists(rootDir)) return;
7577
- const entries2 = await readdir(rootDir, { withFileTypes: true });
7578
- const tsFiles2 = entries2.filter((entry) => entry.isFile() && /\.[cm]?ts$/.test(entry.name)).map((entry) => entry.name).sort();
7579
- for (const name of tsFiles2) {
7580
- await addFilePart(parts2, rootDir, (0, import_node_path9.join)(rootDir, name));
7581
- }
7582
- };
7583
- const collectIntegrationBatchingFiles = async (rootDir, parts2) => {
7584
- if (!await fileExists(rootDir)) return;
7585
- const entries2 = await readdir(rootDir, { withFileTypes: true });
7586
- const filePaths = [];
7587
- for (const entry of entries2) {
7588
- if (entry.isFile() && (entry.name === "play-runtime-batching-registry.ts" || /^batching.*\.ts$/.test(entry.name))) {
7589
- filePaths.push((0, import_node_path9.join)(rootDir, entry.name));
7590
- }
7591
- if (entry.isDirectory()) {
7592
- const batchingFile = (0, import_node_path9.join)(rootDir, entry.name, "batching.ts");
7593
- if (await fileExists(batchingFile)) {
7594
- filePaths.push(batchingFile);
7595
- }
7596
- }
7597
- }
7598
- for (const filePath of filePaths.sort()) {
7599
- await addFilePart(parts2, rootDir, filePath);
7600
- }
7601
- };
7602
- const entries = await readdir(adapter.workersHarnessFilesDir, {
7603
- withFileTypes: true
7604
- });
7605
- const tsFiles = entries.filter((e) => e.isFile() && /\.[cm]?ts$/.test(e.name)).map((e) => e.name).sort();
7606
- const parts = [];
7607
- for (const name of tsFiles) {
7608
- await addFilePart(
7609
- parts,
7610
- adapter.workersHarnessFilesDir,
7611
- (0, import_node_path9.join)(adapter.workersHarnessFilesDir, name)
7612
- );
7613
- }
7614
- for (const dir of adapter.workersRuntimeFingerprintDirs ?? []) {
7615
- if ((0, import_node_path9.basename)(dir) === "integrations") {
7616
- await collectIntegrationBatchingFiles(dir, parts);
7617
- } else {
7618
- await collectTopLevelTsFiles(dir, parts);
7619
- }
7620
- }
7621
- return sha256(JSON.stringify(parts));
7622
- }
7623
- function artifactCachePath(graphHash, artifactKind, adapter) {
7624
- return (0, import_node_path9.join)(
7625
- adapter.cacheDir ?? PLAY_ARTIFACT_CACHE_DIR,
7626
- `${graphHash}.${artifactKind}.json`
7627
- );
7628
- }
7629
- async function readArtifactCache(graphHash, artifactKind, adapter) {
7630
- try {
7631
- const serialized = await (0, import_promises3.readFile)(
7632
- artifactCachePath(graphHash, artifactKind, adapter),
7633
- "utf-8"
7634
- );
7635
- return JSON.parse(serialized);
7636
- } catch {
7637
- return null;
7638
- }
7639
- }
7640
- async function writeArtifactCache(artifact, adapter) {
7641
- const cacheDir = adapter.cacheDir ?? PLAY_ARTIFACT_CACHE_DIR;
7642
- await (0, import_promises3.mkdir)(cacheDir, { recursive: true });
7643
- await (0, import_promises3.writeFile)(
7644
- artifactCachePath(
7645
- artifact.graphHash,
7646
- artifact.artifactKind ?? PLAY_ARTIFACT_KINDS.cjsNode20,
7647
- adapter
7648
- ),
7649
- JSON.stringify(artifact),
7650
- "utf-8"
7651
- );
7652
- }
7653
- function normalizeSourceMapForRuntime(sourceMapText, projectRoot) {
7654
- const parsed = JSON.parse(sourceMapText);
7655
- parsed.sources = (parsed.sources ?? []).map((sourcePath) => {
7656
- if (sourcePath.startsWith("data:") || sourcePath.startsWith("node:") || sourcePath.startsWith("/") || /^[a-zA-Z]+:\/\//.test(sourcePath)) {
7657
- return sourcePath;
7658
- }
7659
- return (0, import_node_path9.join)(projectRoot, sourcePath);
7660
- });
7661
- parsed.sourceRoot = void 0;
7662
- return JSON.stringify(parsed);
7663
- }
7664
- function getBundleSizeErrorForBytes(filePath, bundleBytes, artifactKind) {
7665
- if (bundleBytes > MAX_PLAY_BUNDLE_BYTES) {
7666
- return `${filePath} Play bundle exceeds the 30 MiB limit (${bundleBytes} bytes > ${MAX_PLAY_BUNDLE_BYTES} bytes).`;
7667
- }
7668
- if (artifactKind === PLAY_ARTIFACT_KINDS.esmWorkers && bundleBytes > MAX_ESM_WORKERS_BUNDLE_BYTES) {
7669
- const mib = (bundleBytes / 1024 / 1024).toFixed(2);
7670
- const limitMib = (MAX_ESM_WORKERS_BUNDLE_BYTES / 1024 / 1024).toFixed(2);
7671
- return `${filePath} Cloudflare Workers bundle is ${mib} MiB, above the workerd local-mode threshold of ${limitMib} MiB. Bundles past this size silently hang without executing the workflow body. Reduce dependencies (top offenders are usually date-fns, lodash, large schema libs) or split the play into smaller pieces with ctx.runPlay.`;
7672
- }
7673
- return null;
7674
- }
7675
- function getBundleSizeError(filePath, bundledCode, artifactKind) {
7676
- return getBundleSizeErrorForBytes(
7677
- filePath,
7678
- Buffer.byteLength(bundledCode, "utf8"),
7679
- artifactKind
7680
- );
7681
- }
7682
- async function runEsbuildForCjsNode(entryFile, importedPlayDependencies, adapter, exportName) {
7683
- const sdkAliasPlugin = localSdkAliasPlugin(adapter);
7684
- const playProxyPlugin = importedPlayProxyPlugin(importedPlayDependencies);
7685
- const namedExportShim = exportName === "default" ? null : `export { ${exportName} as default } from ${JSON.stringify(entryFile)};
7686
- `;
7687
- const result = await (0, import_esbuild.build)({
7688
- ...namedExportShim ? {
7689
- stdin: {
7690
- contents: namedExportShim,
7691
- resolveDir: (0, import_node_path9.dirname)(entryFile),
7692
- sourcefile: `${(0, import_node_path9.basename)(entryFile)}.${exportName}.entry.ts`,
7693
- loader: "ts"
7694
- }
7695
- } : { entryPoints: [entryFile] },
7696
- absWorkingDir: adapter.projectRoot,
7697
- bundle: true,
7698
- format: "cjs",
7699
- nodePaths: [adapter.nodeModulesDir],
7700
- platform: "node",
7701
- target: ["node20"],
7702
- outfile: "play-artifact.cjs",
7703
- write: false,
7704
- sourcemap: "external",
7705
- sourcesContent: false,
7706
- logLevel: "silent",
7707
- legalComments: "none",
7708
- plugins: [sdkAliasPlugin, playProxyPlugin].filter(
7709
- (plugin) => plugin != null
7710
- )
7711
- });
7712
- const codeFile = result.outputFiles?.find((f) => f.path.endsWith(".cjs"));
7713
- const mapFile = result.outputFiles?.find((f) => f.path.endsWith(".cjs.map"));
7714
- if (!codeFile?.text || !mapFile?.text) {
7715
- return ["Play bundling produced incomplete output."];
7716
- }
7717
- return {
7718
- bundledCode: codeFile.text,
7719
- sourceMapText: mapFile.text,
7720
- outputExtension: "cjs"
7721
- };
7722
- }
7723
- async function runEsbuildForEsmWorkers(playEntryFile, importedPlayDependencies, adapter, exportName) {
7724
- const sdkAliasPlugin = localSdkAliasPlugin(adapter, { workersRuntime: true });
7725
- const playProxyPlugin = importedPlayProxyPlugin(importedPlayDependencies);
7726
- const playEntryAlias = exportName === "default" ? workersPlayEntryAliasPlugin(playEntryFile) : workersNamedPlayEntryAliasPlugin(playEntryFile, exportName);
7727
- const result = await (0, import_esbuild.build)({
7728
- // Entry is the Workers harness; it imports the play via the virtual
7729
- // `deepline-play-entry` alias resolved by workersPlayEntryAliasPlugin.
7730
- entryPoints: [adapter.workersHarnessEntryFile],
7731
- absWorkingDir: adapter.projectRoot,
7732
- bundle: true,
7733
- format: "esm",
7734
- nodePaths: [adapter.nodeModulesDir],
7735
- // Browser platform with workerd + worker conditions matches Cloudflare's
7736
- // V8-isolate runtime. Avoids accidentally pulling node-only branches of
7737
- // dual-publish packages.
7738
- platform: "browser",
7739
- conditions: ["workerd", "worker", "browser", "import", "default"],
7740
- mainFields: ["module", "main"],
7741
- target: ["es2022"],
7742
- outfile: "play-worker.mjs",
7743
- write: false,
7744
- sourcemap: "external",
7745
- sourcesContent: false,
7746
- logLevel: "silent",
7747
- legalComments: "none",
7748
- // Aggressive minify + treeshake: a tiny play (<1KB source) was producing
7749
- // an ~870KB bundle, dominated by zod's locale files (~260KB unused) and
7750
- // dead-code branches across `shared_libs/play-runtime/*` and the SDK.
7751
- // Both DCE on with these flags. workerd compiles each unique-graphHash
7752
- // bundle on first dispatch, so bundle bytes translate ~linearly into
7753
- // per-play cold latency on workers_edge. External sourcemap remains
7754
- // unchanged (`sourcemap: 'external'`), so debugging is unaffected.
7755
- minify: true,
7756
- treeShaking: true,
7757
- // Most node:* builtins are provided by Cloudflare's `nodejs_compat` flag.
7758
- // The unsupported subset (fs, fs/promises, os, child_process) gets
7759
- // replaced with throwing stubs by workersNodeBuiltinStubPlugin so deploy
7760
- // validation passes; anything supported (path, crypto, buffer, etc.) is
7761
- // marked external and resolved at runtime by the Workers runtime.
7762
- external: ["node:*", "cloudflare:workers"],
7763
- plugins: [
7764
- // Banlist runs first so a forbidden import errors out before any other
7765
- // resolver (esp. the workersNodeBuiltinStubPlugin which would silently
7766
- // turn it into a throwing-stub).
7767
- workersNodeImportBanlistPlugin(adapter),
7768
- sdkAliasPlugin,
7769
- playProxyPlugin,
7770
- playEntryAlias,
7771
- workersNodeBuiltinStubPlugin(),
7772
- // Strip non-English zod locale data from the bundle. zod's locales
7773
- // are re-exported as a static namespace from `zod/v4/core`, so
7774
- // tree-shaking can't drop them; this plugin replaces each
7775
- // non-English locale module with an empty default export at bundle
7776
- // time. ~150–200 KB savings on every per-play bundle, with no
7777
- // behavior change (we only surface English messages anyway).
7778
- // If the bundle suddenly grows back, check whether a new dep added
7779
- // its own zod copy or whether zod's locale layout changed.
7780
- zodNonEnglishLocaleStubPlugin()
7781
- ].filter((plugin) => plugin != null)
7782
- });
7783
- const codeFile = result.outputFiles?.find((f) => f.path.endsWith(".mjs"));
7784
- const mapFile = result.outputFiles?.find((f) => f.path.endsWith(".mjs.map"));
7785
- if (!codeFile?.text || !mapFile?.text) {
7786
- return ["Workers play bundling produced incomplete output."];
7787
- }
7788
- return {
7789
- bundledCode: codeFile.text,
7790
- sourceMapText: mapFile.text,
7791
- outputExtension: "mjs"
7792
- };
7793
- }
7794
- var PLAY_ARTIFACT_TARGET_ADAPTERS = {
7795
- [PLAY_ARTIFACT_KINDS.cjsNode20]: {
7796
- artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
7797
- codeFormat: "cjs_module",
7798
- includeWorkersHarnessInGraphHash: false,
7799
- runEsbuild: ({
7800
- entryFile,
7801
- importedPlayDependencies,
7802
- adapter,
7803
- exportName
7804
- }) => runEsbuildForCjsNode(
7805
- entryFile,
7806
- importedPlayDependencies,
7807
- adapter,
7808
- exportName
7809
- )
7810
- },
7811
- [PLAY_ARTIFACT_KINDS.esmWorkers]: {
7812
- artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
7813
- codeFormat: "esm_module",
7814
- includeWorkersHarnessInGraphHash: true,
7815
- runEsbuild: ({
7816
- entryFile,
7817
- importedPlayDependencies,
7818
- adapter,
7819
- exportName
7820
- }) => runEsbuildForEsmWorkers(
7821
- entryFile,
7822
- importedPlayDependencies,
7823
- adapter,
7824
- exportName
7825
- )
7826
- }
7827
- };
7828
- function resolvePlayArtifactTargetAdapter(artifactKind) {
7829
- return PLAY_ARTIFACT_TARGET_ADAPTERS[artifactKind];
7830
- }
7831
- async function bundlePlayFile(filePath, options) {
7832
- const adapter = options.adapter;
7833
- const target = options.target ?? PLAY_ARTIFACT_KINDS.cjsNode20;
7834
- const targetAdapter = resolvePlayArtifactTargetAdapter(target);
7835
- const exportName = options.exportName?.trim() || "default";
7836
- assertValidExportName(exportName);
7837
- const absolutePath = await normalizeLocalPath(filePath);
7838
- adapter.warnAboutNonDevelopmentBundling?.(absolutePath);
7839
- try {
7840
- const analysis = await analyzeSourceGraph(absolutePath, adapter);
7841
- analysis.graphHash = target === PLAY_ARTIFACT_KINDS.esmWorkers ? buildWorkersRuntimeGraphHash({
7842
- analysis,
7843
- entryFile: absolutePath,
7844
- adapter,
7845
- exportName
7846
- }) : sha256(`${analysis.graphHash}
7847
- entry-export:${exportName}`);
7848
- if (targetAdapter.includeWorkersHarnessInGraphHash) {
7849
- const harnessFingerprint = await computeWorkersHarnessFingerprintWithAdapter(adapter);
7850
- analysis.graphHash = sha256(
7851
- `${analysis.graphHash}
7852
- workers-harness:${harnessFingerprint}`
7853
- );
7854
- }
7855
- try {
7856
- validatePlaySourceFilesHaveNoInlineSecrets(analysis.sourceFiles);
7857
- } catch (error) {
7858
- return {
7859
- success: false,
7860
- filePath: absolutePath,
7861
- errors: [error instanceof Error ? error.message : String(error)]
7862
- };
7863
- }
7864
- const typecheckErrors = [
7865
- ...await adapter.typecheckPlaySource?.({
7866
- sourceCode: analysis.sourceCode,
7867
- sourcePath: absolutePath,
7868
- importedFilePaths: [
7869
- ...analysis.importPolicy.localFiles,
7870
- ...analysis.importedPlayDependencies.map(
7871
- (dependency) => dependency.filePath
7872
- )
7873
- ]
7874
- }) ?? []
7875
- ];
7876
- if (typecheckErrors.length > 0) {
7877
- return {
7878
- success: false,
7879
- filePath: absolutePath,
7880
- errors: typecheckErrors
7881
- };
7882
- }
7883
- const canUseArtifactCache = target !== PLAY_ARTIFACT_KINDS.esmWorkers;
7884
- const cachedArtifact = canUseArtifactCache ? await readArtifactCache(analysis.graphHash, target, adapter) : null;
7885
- const discoveredFiles = await adapter.discoverPackagedLocalFiles(absolutePath);
7886
- if (cachedArtifact) {
7887
- const cachedArtifactSizeError = getBundleSizeError(
7888
- absolutePath,
7889
- cachedArtifact.bundledCode,
7890
- target
7891
- );
7892
- if (cachedArtifactSizeError) {
7893
- return {
7894
- success: false,
7895
- filePath: absolutePath,
7896
- errors: [cachedArtifactSizeError]
7897
- };
7898
- }
7899
- return {
7900
- success: true,
7901
- artifact: {
7902
- ...cachedArtifact,
7903
- entryFile: absolutePath,
7904
- sourceHash: analysis.sourceHash,
7905
- importPolicy: analysis.importPolicy,
7906
- cacheHit: true
7907
- },
7908
- sourceCode: analysis.sourceCode,
7909
- sourceFiles: analysis.sourceFiles,
7910
- filePath: absolutePath,
7911
- playName: analysis.playName,
7912
- packagedFiles: discoveredFiles.files,
7913
- unresolvedFileReferences: discoveredFiles.unresolved,
7914
- importedPlayDependencies: analysis.importedPlayDependencies
7915
- };
7916
- }
7917
- const buildOutcome = await targetAdapter.runEsbuild({
7918
- entryFile: absolutePath,
7919
- importedPlayDependencies: analysis.importedPlayDependencies,
7920
- adapter,
7921
- exportName
7922
- });
7923
- if (Array.isArray(buildOutcome)) {
7924
- return {
7925
- success: false,
7926
- filePath: absolutePath,
7927
- errors: buildOutcome
7928
- };
7929
- }
7930
- const { bundledCode, sourceMapText, outputExtension } = buildOutcome;
7931
- const normalizedSourceMap = normalizeSourceMapForRuntime(
7932
- sourceMapText,
7933
- (0, import_node_path9.resolve)(adapter.projectRoot)
7934
- );
7935
- const virtualBaseName = exportName === "default" ? (0, import_node_path9.basename)(absolutePath).replace(/\.[^.]+$/, "") : `${(0, import_node_path9.basename)(absolutePath).replace(/\.[^.]+$/, "")}.${exportName}`;
7936
- const virtualFilename = `/virtual/deepline-plays/${analysis.graphHash}/${virtualBaseName}.${outputExtension}`;
7937
- const executableCode = `${bundledCode}
7938
- //# sourceMappingURL=${(0, import_node_path9.basename)(virtualFilename)}.map
7939
- `;
7940
- const bundleSizeError = getBundleSizeError(
7941
- absolutePath,
7942
- executableCode,
7943
- target
7944
- );
7945
- if (bundleSizeError) {
7946
- return {
7947
- success: false,
7948
- filePath: absolutePath,
7949
- errors: [bundleSizeError]
7950
- };
7951
- }
7952
- const artifact = {
7953
- codeFormat: targetAdapter.codeFormat,
7954
- artifactKind: target,
7955
- entryFile: absolutePath,
7956
- virtualFilename,
7957
- sourceHash: analysis.sourceHash,
7958
- graphHash: analysis.graphHash,
7959
- artifactHash: sha256(executableCode),
7960
- sourceMapHash: sha256(normalizedSourceMap),
7961
- bundledCode: executableCode,
7962
- sourceMap: normalizedSourceMap,
7963
- importPolicy: analysis.importPolicy,
7964
- compatibility: buildPlayContractCompatibility(),
7965
- generatedAt: Date.now(),
7966
- cacheHit: false
7967
- };
7968
- if (canUseArtifactCache) {
7969
- await writeArtifactCache(artifact, adapter);
7970
- }
7971
- return {
7972
- success: true,
7973
- artifact,
7974
- sourceCode: analysis.sourceCode,
7975
- sourceFiles: analysis.sourceFiles,
7976
- filePath: absolutePath,
7977
- playName: analysis.playName,
7978
- packagedFiles: discoveredFiles.files,
7979
- unresolvedFileReferences: discoveredFiles.unresolved,
7980
- importedPlayDependencies: analysis.importedPlayDependencies
7981
- };
7982
- } catch (error) {
7983
- if (error && typeof error === "object" && "errors" in error) {
7984
- const errors = Array.isArray(error.errors) ? error.errors.map(formatEsbuildMessage) : ["Play bundling failed."];
7985
- return {
7986
- success: false,
7987
- filePath: absolutePath,
7988
- errors
7989
- };
7990
- }
7991
- return {
7992
- success: false,
7993
- filePath: absolutePath,
7994
- errors: [error instanceof Error ? error.message : String(error)]
7995
- };
7996
- }
7997
- }
7998
-
7999
- // ../shared_libs/play-runtime/dedup-backend.ts
8000
- var PLAY_DEDUP_BACKENDS = {
8001
- inMemory: "in_memory",
8002
- neonTable: "neon_table",
8003
- durableObject: "durable_object"
8004
- };
8005
-
8006
- // ../shared_libs/play-runtime/scheduler-backend.ts
8007
- var PLAY_SCHEDULER_BACKENDS = {
8008
- temporal: "temporal",
8009
- cfWorkflows: "cf-workflows",
8010
- /**
8011
- * Private legacy id retained only so old persisted rows can be interpreted.
8012
- * It is not a selectable scheduler backend after the Hatchet hard cutover.
8013
- */
8014
- postgres: "postgres",
8015
- hatchet: "hatchet",
8016
- inProcess: "in-process"
8017
- };
8018
-
8019
- // ../shared_libs/play-runtime/providers.ts
8020
- var PLAY_RUNTIME_PROVIDER_IDS = {
8021
- workersEdge: "workers_edge",
8022
- hatchet: "hatchet",
8023
- local: "local"
8024
- };
8025
- var PLAY_RUNTIME_PROVIDERS = {
8026
- workers_edge: {
8027
- id: PLAY_RUNTIME_PROVIDER_IDS.workersEdge,
8028
- scheduler: PLAY_SCHEDULER_BACKENDS.cfWorkflows,
8029
- runner: PLAY_RUNTIME_BACKENDS.cloudflareWorkers,
8030
- dedup: PLAY_DEDUP_BACKENDS.durableObject,
8031
- artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
8032
- label: "Cloudflare Dynamic Workflows + Dynamic Workers + DO dedup"
8033
- },
8034
- hatchet: {
8035
- id: PLAY_RUNTIME_PROVIDER_IDS.hatchet,
8036
- scheduler: PLAY_SCHEDULER_BACKENDS.hatchet,
8037
- runner: PLAY_RUNTIME_BACKENDS.daytona,
8038
- dedup: PLAY_DEDUP_BACKENDS.durableObject,
8039
- artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
8040
- label: "Hatchet scheduler + one-shot Daytona runner + DO dedup"
8041
- },
8042
- local: {
8043
- id: PLAY_RUNTIME_PROVIDER_IDS.local,
8044
- scheduler: PLAY_SCHEDULER_BACKENDS.temporal,
8045
- runner: PLAY_RUNTIME_BACKENDS.localProcess,
8046
- dedup: PLAY_DEDUP_BACKENDS.inMemory,
8047
- artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
8048
- label: "Local Temporal scheduler + local subprocess runner (tests)"
8049
- }
8050
- };
8051
- function defaultPlayRuntimeProvider() {
8052
- return PLAY_RUNTIME_PROVIDERS.workers_edge;
8053
- }
8054
- function resolvePlayRuntimeProvider(override) {
8055
- if (override?.trim()) {
8056
- const id = override.trim();
8057
- if (id in PLAY_RUNTIME_PROVIDERS) {
8058
- return PLAY_RUNTIME_PROVIDERS[id];
8059
- }
8060
- throw new Error(
8061
- `Unknown play runtime provider "${id}". Expected one of: ${Object.keys(
8062
- PLAY_RUNTIME_PROVIDERS
8063
- ).join(", ")}.`
8064
- );
8065
- }
8066
- return defaultPlayRuntimeProvider();
8067
- }
8068
-
8069
- // ../shared_libs/play-runtime/profiles.ts
8070
- var PLAY_EXECUTION_PROFILE_IDS = {
8071
- ...PLAY_RUNTIME_PROVIDER_IDS
8072
- };
8073
- var PLAY_EXECUTION_PROFILES = PLAY_RUNTIME_PROVIDERS;
8074
- function resolveExecutionProfile(override) {
8075
- try {
8076
- return resolvePlayRuntimeProvider(override);
8077
- } catch (error) {
8078
- if (override?.trim()) {
8079
- throw new Error(
8080
- `Unknown execution profile "${override.trim()}". Expected one of: ${Object.keys(
8081
- PLAY_EXECUTION_PROFILES
8082
- ).join(", ")}.`
8083
- );
8084
- }
8085
- throw error;
8086
- }
8087
- }
8088
-
8089
- // src/plays/local-file-discovery.ts
8090
- var import_node_crypto2 = require("crypto");
8091
- var import_promises4 = require("fs/promises");
8092
- var import_node_path10 = require("path");
8093
- var SOURCE_EXTENSIONS2 = [
8094
- ".ts",
8095
- ".tsx",
8096
- ".mts",
8097
- ".cts",
8098
- ".js",
8099
- ".jsx",
8100
- ".mjs",
8101
- ".cjs",
8102
- ".json"
8103
- ];
8104
- function sha2562(buffer) {
8105
- return (0, import_node_crypto2.createHash)("sha256").update(buffer).digest("hex");
8106
- }
8107
- function contentTypeForFile(filePath) {
8108
- const extension = (0, import_node_path10.extname)(filePath).toLowerCase();
8109
- if (extension === ".csv") return "text/csv";
8110
- if (extension === ".json") return "application/json";
8111
- if (extension === ".txt") return "text/plain";
8112
- return "application/octet-stream";
8113
- }
8114
- function stripCommentsToSpaces2(source) {
8115
- return source.replace(/\/\*[\s\S]*?\*\//g, (match) => match.replace(/[^\n]/g, " ")).replace(
8116
- /(^|[^:])\/\/.*$/gm,
8117
- (match, prefix) => prefix + " ".repeat(Math.max(0, match.length - prefix.length))
8118
- );
8119
- }
8120
- function unquoteStringLiteral2(literal) {
8121
- const trimmed = literal.trim();
8122
- const quote = trimmed[0];
8123
- if (quote !== '"' && quote !== "'" || trimmed[trimmed.length - 1] !== quote) {
8124
- return null;
8125
- }
8126
- try {
8127
- return JSON.parse(
8128
- quote === '"' ? trimmed : `"${trimmed.slice(1, -1).replace(/"/g, '\\"')}"`
8129
- );
8130
- } catch {
8131
- return trimmed.slice(1, -1);
8132
- }
8133
- }
8134
- function splitTopLevelPlus(expression) {
8135
- const parts = [];
8136
- let start = 0;
8137
- let depth = 0;
8138
- let quote = null;
8139
- let escaped = false;
8140
- for (let index = 0; index < expression.length; index += 1) {
8141
- const char = expression[index];
8142
- if (quote) {
8143
- if (escaped) {
8144
- escaped = false;
8145
- } else if (char === "\\") {
8146
- escaped = true;
8147
- } else if (char === quote) {
8148
- quote = null;
8149
- }
8150
- continue;
8151
- }
8152
- if (char === '"' || char === "'" || char === "`") {
8153
- quote = char;
8154
- continue;
8155
- }
8156
- if (char === "(" || char === "[" || char === "{") depth += 1;
8157
- if (char === ")" || char === "]" || char === "}") depth -= 1;
8158
- if (char === "+" && depth === 0) {
8159
- parts.push(expression.slice(start, index));
8160
- start = index + 1;
8161
- }
8162
- }
8163
- if (parts.length === 0) return null;
8164
- parts.push(expression.slice(start));
8165
- return parts;
8166
- }
8167
- function stripOuterParens(expression) {
8168
- let value = expression.trim();
8169
- while (value.startsWith("(") && value.endsWith(")")) {
8170
- value = value.slice(1, -1).trim();
8171
- }
8172
- return value;
8173
- }
8174
- function isRuntimeInputExpression(expression) {
8175
- return /(^|[^\w$])input([^\w$]|$)/.test(expression);
8176
- }
8177
- function resolveStringExpression(expression, constants) {
8178
- const value = stripOuterParens(expression);
8179
- if (/^(['"])(?:\\.|(?!\1)[\s\S])*\1$/.test(value)) {
8180
- return unquoteStringLiteral2(value);
8181
- }
8182
- if (/^`(?:\\.|[^`$]|\$(?!\{))*`$/.test(value)) {
8183
- return value.slice(1, -1);
8184
- }
8185
- if (/^[A-Za-z_$][\w$]*$/.test(value)) {
8186
- return constants.get(value) ?? null;
8187
- }
8188
- const parts = splitTopLevelPlus(value);
8189
- if (parts) {
8190
- const resolved = parts.map(
8191
- (part) => resolveStringExpression(part, constants)
8192
- );
8193
- return resolved.every((part) => part != null) ? resolved.join("") : null;
8194
- }
8195
- return null;
8196
- }
8197
- function collectTopLevelStringConstants(sourceCode) {
8198
- const constants = /* @__PURE__ */ new Map();
8199
- const source = stripCommentsToSpaces2(sourceCode);
8200
- for (const match of source.matchAll(
8201
- /(?:^|\n)\s*const\s+([A-Za-z_$][\w$]*)\s*=\s*([^;\n]+)/g
8202
- )) {
8203
- const resolved = resolveStringExpression(match[2], constants);
8204
- if (resolved != null) {
8205
- constants.set(match[1], resolved);
8206
- }
8207
- }
8208
- return constants;
8209
- }
8210
- function findMatchingGenericEnd(source, openIndex) {
8211
- let depth = 0;
8212
- let quote = null;
8213
- let escaped = false;
8214
- for (let index = openIndex; index < source.length; index += 1) {
8215
- const char = source[index];
8216
- if (quote) {
8217
- if (escaped) {
8218
- escaped = false;
8219
- } else if (char === "\\") {
8220
- escaped = true;
8221
- } else if (char === quote) {
8222
- quote = null;
8223
- }
8224
- continue;
8225
- }
8226
- if (char === '"' || char === "'" || char === "`") {
8227
- quote = char;
8228
- continue;
8229
- }
8230
- if (char === "<") depth += 1;
8231
- if (char === ">") {
8232
- depth -= 1;
8233
- if (depth === 0) return index;
8234
- }
8235
- }
8236
- return -1;
8237
- }
8238
- function findCallOpenParen(source, afterCsvIndex) {
8239
- let index = afterCsvIndex;
8240
- while (/\s/.test(source[index] ?? "")) index += 1;
8241
- if (source[index] === "<") {
8242
- const genericEnd = findMatchingGenericEnd(source, index);
8243
- if (genericEnd < 0) return -1;
8244
- index = genericEnd + 1;
8245
- while (/\s/.test(source[index] ?? "")) index += 1;
8246
- }
8247
- return source[index] === "(" ? index : -1;
8248
- }
8249
- function firstCallArgument(source, openParen) {
8250
- let depth = 0;
8251
- let quote = null;
8252
- let escaped = false;
8253
- const start = openParen + 1;
8254
- for (let index = start; index < source.length; index += 1) {
8255
- const char = source[index];
8256
- if (quote) {
8257
- if (escaped) {
8258
- escaped = false;
8259
- } else if (char === "\\") {
8260
- escaped = true;
8261
- } else if (char === quote) {
8262
- quote = null;
8263
- }
8264
- continue;
8265
- }
8266
- if (char === '"' || char === "'" || char === "`") {
8267
- quote = char;
8268
- continue;
8269
- }
8270
- if (char === "(" || char === "[" || char === "{") depth += 1;
8271
- if (char === ")" && depth === 0) {
8272
- const text = source.slice(start, index).trim();
8273
- return text ? { text, start, end: index } : null;
8274
- }
8275
- if (char === "," && depth === 0) {
8276
- const text = source.slice(start, index).trim();
8277
- return text ? { text, start, end: index } : null;
8278
- }
8279
- if (char === ")" || char === "]" || char === "}") depth -= 1;
8280
- }
8281
- return null;
8282
- }
8283
- function localImportSpecifiers(sourceCode) {
8284
- const source = stripCommentsToSpaces2(sourceCode);
8285
- const specifiers = [];
8286
- for (const match of source.matchAll(
8287
- /\b(?:import|export)\s+(?!type\b)(?:[\s\S]*?\s+from\s*)?['"]([^'"]+)['"]/g
8288
- )) {
8289
- if (match[1]?.startsWith(".")) specifiers.push(match[1]);
8290
- }
8291
- for (const match of source.matchAll(
8292
- /\brequire\s*\(\s*(['"])(\.[^'"]*)\1\s*\)/g
8293
- )) {
8294
- specifiers.push(match[2]);
8295
- }
8296
- return specifiers;
8297
- }
8298
- async function fileExists2(filePath) {
8299
- try {
8300
- await (0, import_promises4.stat)(filePath);
8301
- return true;
8302
- } catch {
8303
- return false;
8304
- }
8305
- }
8306
- function isPathInsideDirectory2(filePath, directory) {
8307
- const relativePath = (0, import_node_path10.relative)(directory, filePath);
8308
- return relativePath === "" || !relativePath.startsWith("..") && !(0, import_node_path10.isAbsolute)(relativePath);
8309
- }
8310
- async function resolveLocalImport2(fromFile, specifier) {
8311
- const base = (0, import_node_path10.isAbsolute)(specifier) ? (0, import_node_path10.resolve)(specifier) : (0, import_node_path10.resolve)((0, import_node_path10.dirname)(fromFile), specifier);
8312
- const candidates = [base];
8313
- const explicitExtension = (0, import_node_path10.extname)(base).toLowerCase();
8314
- if (!explicitExtension) {
8315
- candidates.push(
8316
- ...SOURCE_EXTENSIONS2.map((extension) => `${base}${extension}`)
8317
- );
8318
- candidates.push(
8319
- ...SOURCE_EXTENSIONS2.map((extension) => (0, import_node_path10.join)(base, `index${extension}`))
8320
- );
8321
- } else if ([".js", ".jsx", ".mjs", ".cjs"].includes(explicitExtension)) {
8322
- const stem = base.slice(0, -explicitExtension.length);
8323
- candidates.push(
8324
- ...SOURCE_EXTENSIONS2.map((extension) => `${stem}${extension}`)
8325
- );
8326
- }
8327
- for (const candidate of candidates) {
8328
- if (await fileExists2(candidate)) {
8329
- return candidate;
8330
- }
8331
- }
8332
- throw new Error(
8333
- `Could not resolve local import "${specifier}" from ${fromFile}`
8334
- );
8335
- }
8336
- async function discoverPackagedLocalFiles(entryFile) {
8337
- const absoluteEntryFile = (0, import_node_path10.resolve)(entryFile);
8338
- const packagingRoot = (0, import_node_path10.dirname)(absoluteEntryFile);
8339
- const files = /* @__PURE__ */ new Map();
8340
- const unresolved = [];
8341
- const visitedFiles = /* @__PURE__ */ new Set();
8342
- const visitSourceFile = async (filePath) => {
8343
- const absolutePath = (0, import_node_path10.resolve)(filePath);
8344
- if (visitedFiles.has(absolutePath)) {
8345
- return;
8346
- }
8347
- visitedFiles.add(absolutePath);
8348
- const sourceCode = await (0, import_promises4.readFile)(absolutePath, "utf-8");
8349
- const scanSource = stripCommentsToSpaces2(sourceCode);
8350
- const constants = collectTopLevelStringConstants(sourceCode);
8351
- const childVisits = [];
8352
- for (const match of scanSource.matchAll(
8353
- /\b([A-Za-z_$][\w$]*)\s*\.\s*csv\b/g
8354
- )) {
8355
- const target = match[1];
8356
- if (target !== "ctx" && !target.endsWith("Ctx")) {
8357
- continue;
8358
- }
8359
- const openParen = findCallOpenParen(
8360
- scanSource,
8361
- match.index + match[0].length
8362
- );
8363
- if (openParen < 0) {
8364
- continue;
8365
- }
8366
- const argument = firstCallArgument(scanSource, openParen);
8367
- if (!argument) {
8368
- unresolved.push({
8369
- sourceFragment: "ctx.csv()",
8370
- message: "ctx.csv() requires a file path string or input reference."
8371
- });
8372
- } else if (!isRuntimeInputExpression(argument.text)) {
8373
- const resolvedPath = resolveStringExpression(argument.text, constants);
8374
- if (resolvedPath == null) {
8375
- unresolved.push({
8376
- sourceFragment: sourceCode.slice(argument.start, argument.end).trim(),
8377
- message: "Could not resolve this ctx.csv(...) path at submit time. Use a string literal, a top-level const string, or pass a runtime input like input.file."
8378
- });
8379
- } else {
8380
- const absoluteCsvPath = (0, import_node_path10.resolve)((0, import_node_path10.dirname)(absolutePath), resolvedPath);
8381
- if ((0, import_node_path10.isAbsolute)(resolvedPath) || !isPathInsideDirectory2(absoluteCsvPath, packagingRoot)) {
8382
- unresolved.push({
8383
- sourceFragment: sourceCode.slice(argument.start, argument.end).trim(),
8384
- message: "ctx.csv(...) packaged file paths must be relative paths inside the play directory. Pass external files at runtime with input.file instead."
8385
- });
8386
- continue;
8387
- }
8388
- const buffer = await (0, import_promises4.readFile)(absoluteCsvPath);
8389
- const stats = await (0, import_promises4.stat)(absoluteCsvPath);
8390
- files.set(absoluteCsvPath, {
8391
- sourceFragment: sourceCode.slice(argument.start, argument.end).trim(),
8392
- logicalPath: resolvedPath,
8393
- absolutePath: absoluteCsvPath,
8394
- bytes: stats.size,
8395
- contentHash: sha2562(buffer),
8396
- contentType: contentTypeForFile(absoluteCsvPath)
8397
- });
8398
- }
8399
- }
8400
- }
8401
- for (const specifier of localImportSpecifiers(sourceCode)) {
8402
- childVisits.push(
8403
- resolveLocalImport2(absolutePath, specifier).then(
8404
- (resolvedImport) => visitSourceFile(resolvedImport)
8405
- )
8406
- );
8407
- }
8408
- await Promise.all(childVisits);
8409
- };
8410
- await visitSourceFile(absoluteEntryFile);
8411
- return {
8412
- files: [...files.values()],
8413
- unresolved
8414
- };
8415
- }
8416
-
8417
- // src/plays/bundle-play-file.ts
8418
- var import_meta = {};
8419
- var PLAY_BUNDLE_CACHE_VERSION2 = 30;
8420
- var MODULE_DIR = (0, import_node_path11.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
8421
- var SDK_PACKAGE_ROOT = (0, import_node_path11.resolve)(MODULE_DIR, "..", "..");
8422
- var SOURCE_REPO_ROOT = (0, import_node_path11.resolve)(SDK_PACKAGE_ROOT, "..");
8423
- var HAS_SOURCE_BUNDLING_SOURCES = (0, import_node_fs9.existsSync)(
8424
- (0, import_node_path11.resolve)(SOURCE_REPO_ROOT, "apps", "play-runner-workers", "src", "entry.ts")
8425
- );
8426
- var PACKAGED_REPO_ROOT = (0, import_node_path11.resolve)(SDK_PACKAGE_ROOT, "dist", "repo");
8427
- var HAS_PACKAGED_BUNDLING_SOURCES = (0, import_node_fs9.existsSync)(
8428
- (0, import_node_path11.resolve)(PACKAGED_REPO_ROOT, "apps", "play-runner-workers", "src", "entry.ts")
8429
- );
8430
- var PROJECT_ROOT = HAS_SOURCE_BUNDLING_SOURCES ? SOURCE_REPO_ROOT : HAS_PACKAGED_BUNDLING_SOURCES ? PACKAGED_REPO_ROOT : (0, import_node_path11.resolve)(SDK_PACKAGE_ROOT, "..");
8431
- var SDK_SOURCE_ROOT = HAS_SOURCE_BUNDLING_SOURCES ? (0, import_node_path11.resolve)(SOURCE_REPO_ROOT, "sdk", "src") : HAS_PACKAGED_BUNDLING_SOURCES ? (0, import_node_path11.resolve)(PACKAGED_REPO_ROOT, "sdk", "src") : (0, import_node_path11.resolve)(SDK_PACKAGE_ROOT, "src");
8432
- var SDK_PACKAGE_JSON = (0, import_node_path11.resolve)(SDK_PACKAGE_ROOT, "package.json");
8433
- var SDK_ENTRY_FILE = (0, import_node_path11.resolve)(SDK_SOURCE_ROOT, "index.ts");
8434
- var SDK_TYPES_ENTRY_FILE = HAS_SOURCE_BUNDLING_SOURCES ? SDK_ENTRY_FILE : (0, import_node_path11.resolve)(SDK_PACKAGE_ROOT, "dist", "index.d.ts");
8435
- var SDK_WORKERS_ENTRY_FILE = (0, import_node_path11.resolve)(SDK_SOURCE_ROOT, "worker-play-entry.ts");
8436
- var WORKERS_HARNESS_ENTRY_FILE = (0, import_node_path11.resolve)(
8437
- PROJECT_ROOT,
8438
- "apps",
8439
- "play-runner-workers",
8440
- "src",
8441
- "entry.ts"
8442
- );
8443
- var WORKERS_HARNESS_FILES_DIR = (0, import_node_path11.resolve)(
8444
- PROJECT_ROOT,
8445
- "apps",
8446
- "play-runner-workers",
8447
- "src"
8448
- );
8449
- var hasWarnedAboutNonDevelopmentBundling = false;
8450
- function warnAboutNonDevelopmentBundling(filePath) {
8451
- if (hasWarnedAboutNonDevelopmentBundling) {
8452
- return;
8453
- }
8454
- const nodeEnv = String(process.env.NODE_ENV ?? "").trim().toLowerCase();
8455
- if (!nodeEnv || nodeEnv === "development" || nodeEnv === "test") {
8456
- return;
8457
- }
8458
- hasWarnedAboutNonDevelopmentBundling = true;
8459
- console.warn(
8460
- `[deepline] Warning: live play bundling was invoked while NODE_ENV=${nodeEnv} for ${filePath}. This source-first SDK path is intended for local development. For preview/production, run a published or prebuilt play reference instead of bundling source at runtime.`
8461
- );
8462
- console.warn(
8463
- '[deepline] Preferred production call pattern: client.play("person-to-email").run(...) or run a previously registered/published org play.'
8464
- );
8465
- }
8466
- function defaultPlayBundleTarget() {
8467
- return resolveExecutionProfile(null).artifactKind;
8468
- }
8469
- function createSdkPlayBundlingAdapter() {
8470
- return {
8471
- projectRoot: PROJECT_ROOT,
8472
- nodeModulesDir: (0, import_node_path11.resolve)(PROJECT_ROOT, "node_modules"),
8473
- cacheDir: (0, import_node_path11.join)(
8474
- (0, import_node_os8.tmpdir)(),
8475
- `deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION2}`
8476
- ),
8477
- sdkSourceRoot: SDK_SOURCE_ROOT,
8478
- sdkPackageJson: SDK_PACKAGE_JSON,
8479
- sdkEntryFile: SDK_ENTRY_FILE,
8480
- sdkTypesEntryFile: HAS_SOURCE_BUNDLING_SOURCES || !(0, import_node_fs9.existsSync)(SDK_TYPES_ENTRY_FILE) ? SDK_ENTRY_FILE : SDK_TYPES_ENTRY_FILE,
8481
- sdkWorkersEntryFile: SDK_WORKERS_ENTRY_FILE,
8482
- workersHarnessEntryFile: WORKERS_HARNESS_ENTRY_FILE,
8483
- workersHarnessFilesDir: WORKERS_HARNESS_FILES_DIR,
8484
- workersRuntimeFingerprintDirs: [
8485
- (0, import_node_path11.resolve)(PROJECT_ROOT, "shared_libs", "play-runtime")
8486
- ],
8487
- discoverPackagedLocalFiles,
8488
- warnAboutNonDevelopmentBundling
8489
- };
8490
- }
8491
- async function bundlePlayFile2(filePath, options = {}) {
8492
- const result = await bundlePlayFile(filePath, {
8493
- target: options.target ?? defaultPlayBundleTarget(),
8494
- exportName: options.exportName,
8495
- adapter: createSdkPlayBundlingAdapter()
8496
- });
8497
- if (result.success)
8498
- validatePlaySourceFilesHaveNoInlineSecrets(result.sourceFiles);
8499
- return result;
8500
- }
8501
-
8502
- // src/cli/commands/plays/bootstrap.ts
8503
- var import_node_fs10 = require("fs");
8504
- var import_node_path12 = require("path");
8505
- var import_sync4 = require("csv-parse/sync");
8506
-
8507
- // ../shared_libs/plays/bootstrap-routes.ts
8508
- var PLAY_BOOTSTRAP_TEMPLATES = [
8509
- "people-list",
8510
- "company-list",
8511
- "people-email",
8512
- "people-phone",
8513
- "company-people",
8514
- "company-people-email",
8515
- "company-people-phone"
8516
- ];
8517
- var PLAY_BOOTSTRAP_COMPANY_PROVIDER_CATEGORY = "company_search";
8518
- var PLAY_BOOTSTRAP_PEOPLE_PROVIDER_CATEGORY = "people_search";
8519
- var PLAY_BOOTSTRAP_PROVIDER_CATEGORY_BY_FINDER = {
8520
- email_finder: "email_finder",
8521
- phone_finder: "phone_finder"
8522
- };
8523
- var PLAY_BOOTSTRAP_OUTPUT_FIELD_BY_FINDER = {
8524
- email_finder: "email",
8525
- phone_finder: "phone"
8526
- };
8527
- function isPlayBootstrapTemplate(value) {
8528
- return PLAY_BOOTSTRAP_TEMPLATES.includes(value);
8529
- }
8530
- function formatPlayBootstrapTemplates() {
8531
- return PLAY_BOOTSTRAP_TEMPLATES.join("|");
8532
- }
8533
-
8534
- // src/cli/commands/plays/bootstrap.ts
8535
- function parseReferencedPlayTarget(target) {
8536
- const trimmed = target.trim();
8537
- const slashIndex = trimmed.indexOf("/");
8538
- if (slashIndex <= 0 || slashIndex === trimmed.length - 1) {
8539
- return { ownerSlug: null, playName: trimmed, unqualifiedPlayName: trimmed };
8540
- }
8541
- return {
8542
- ownerSlug: trimmed.slice(0, slashIndex),
8543
- playName: trimmed,
8544
- unqualifiedPlayName: trimmed.slice(slashIndex + 1)
8545
- };
8546
- }
8547
- function parsePositiveInteger2(value, flagName) {
8548
- const parsed = Number.parseInt(value, 10);
8549
- if (!Number.isFinite(parsed) || parsed <= 0) {
8550
- throw new PlayBootstrapUsageError(
8551
- `${flagName} must be a positive integer.`
8552
- );
8553
- }
8554
- return parsed;
8555
- }
8556
- function isRecord5(value) {
8557
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
8558
- }
8559
- function stringValue(value) {
8560
- return typeof value === "string" ? value.trim() : "";
8561
- }
8562
- function extractionEntries(value) {
8563
- if (Array.isArray(value)) return value.filter(isRecord5);
8564
- if (!isRecord5(value)) return [];
8565
- return Object.entries(value).map(
8566
- ([name, entry]) => isRecord5(entry) ? { name, ...entry } : { name }
8567
- );
8568
- }
8569
- var PlayBootstrapError = class extends Error {
8570
- constructor(message, exitCode) {
8571
- super(message);
8572
- this.exitCode = exitCode;
8573
- }
8574
- exitCode;
8575
- };
8576
- var PlayBootstrapUsageError = class extends PlayBootstrapError {
8577
- constructor(message) {
8578
- super(message, 2);
8579
- }
8580
- };
8581
- var PlayBootstrapValidationError = class extends PlayBootstrapError {
8582
- constructor(message) {
8583
- super(message, 7);
6864
+ };
6865
+ var PlayBootstrapValidationError = class extends PlayBootstrapError {
6866
+ constructor(message) {
6867
+ super(message, 7);
8584
6868
  }
8585
6869
  };
8586
6870
  var CSV_HEADER_SAMPLE_BYTES = 64 * 1024;
@@ -8930,13 +7214,13 @@ function inferCsvColumnSpecs(headers, rows) {
8930
7214
  }));
8931
7215
  }
8932
7216
  function readCsvSample(csvPath) {
8933
- const resolvedPath = (0, import_node_path12.resolve)(csvPath);
8934
- const size = (0, import_node_fs10.statSync)(resolvedPath).size;
8935
- const fd = (0, import_node_fs10.openSync)(resolvedPath, "r");
7217
+ const resolvedPath = (0, import_node_path9.resolve)(csvPath);
7218
+ const size = (0, import_node_fs8.statSync)(resolvedPath).size;
7219
+ const fd = (0, import_node_fs8.openSync)(resolvedPath, "r");
8936
7220
  const byteLength = Math.min(size, CSV_HEADER_SAMPLE_BYTES);
8937
7221
  const buffer = Buffer.alloc(byteLength);
8938
- const bytesRead = (0, import_node_fs10.readSync)(fd, buffer, 0, byteLength, 0);
8939
- (0, import_node_fs10.closeSync)(fd);
7222
+ const bytesRead = (0, import_node_fs8.readSync)(fd, buffer, 0, byteLength, 0);
7223
+ (0, import_node_fs8.closeSync)(fd);
8940
7224
  if (bytesRead === 0) {
8941
7225
  throw new PlayBootstrapUsageError(`--from csv:${csvPath} is empty.`);
8942
7226
  }
@@ -9005,9 +7289,9 @@ ${properties}
9005
7289
  }
9006
7290
  function packagedCsvPathForPlay(csvPath) {
9007
7291
  const playDir = process.cwd();
9008
- const absoluteCsvPath = (0, import_node_path12.resolve)(csvPath);
9009
- const relativePath = (0, import_node_path12.relative)(playDir, absoluteCsvPath);
9010
- if (relativePath === "" || relativePath.startsWith("..") || (0, import_node_path12.isAbsolute)(relativePath)) {
7292
+ const absoluteCsvPath = (0, import_node_path9.resolve)(csvPath);
7293
+ const relativePath = (0, import_node_path9.relative)(playDir, absoluteCsvPath);
7294
+ if (relativePath === "" || relativePath.startsWith("..") || (0, import_node_path9.isAbsolute)(relativePath)) {
9011
7295
  throw new PlayBootstrapUsageError(
9012
7296
  `--from csv:${csvPath} must point to a file inside the directory where you run plays bootstrap. Run bootstrap from the intended play directory and write the play with --out there.`
9013
7297
  );
@@ -9926,8 +8210,8 @@ async function runPlayBootstrap(args) {
9926
8210
  ...csvContext
9927
8211
  });
9928
8212
  if (options.out) {
9929
- (0, import_node_fs10.writeFileSync)((0, import_node_path12.resolve)(options.out), source, "utf-8");
9930
- process.stdout.write(`Wrote ${(0, import_node_path12.resolve)(options.out)}
8213
+ (0, import_node_fs8.writeFileSync)((0, import_node_path9.resolve)(options.out), source, "utf-8");
8214
+ process.stdout.write(`Wrote ${(0, import_node_path9.resolve)(options.out)}
9931
8215
  `);
9932
8216
  return 0;
9933
8217
  }
@@ -10271,23 +8555,144 @@ function hintForError(error, sourceLine) {
10271
8555
  if (looksLikeRunPlaySignature(error, sourceLine)) {
10272
8556
  return RUN_PLAY_SIGNATURE_HINT;
10273
8557
  }
10274
- if (looksLikeRowPropertyMismatch(error, sourceLine)) {
10275
- return ROW_PROPERTY_HINT;
8558
+ if (looksLikeRowPropertyMismatch(error, sourceLine)) {
8559
+ return ROW_PROPERTY_HINT;
8560
+ }
8561
+ return null;
8562
+ }
8563
+ function addPlayCheckRepairHints(input2) {
8564
+ const addedHints = /* @__PURE__ */ new Set();
8565
+ return input2.errors.map((error) => {
8566
+ const line = sourceLineForError(input2.sourceCode, error);
8567
+ const hint = hintForError(error, line);
8568
+ if (!hint || addedHints.has(hint) || error.includes(hint)) {
8569
+ return error;
8570
+ }
8571
+ addedHints.add(hint);
8572
+ return `${error}
8573
+ ${hint}`;
8574
+ });
8575
+ }
8576
+
8577
+ // ../shared_libs/play-runtime/backend.ts
8578
+ var PLAY_RUNTIME_BACKENDS = {
8579
+ localProcess: "local_process",
8580
+ daytona: "daytona",
8581
+ // Artifact/runtime contract for Cloudflare Dynamic Workers. This is no
8582
+ // longer a standalone runner backend; use profile=workers_edge so the
8583
+ // cf-workflows scheduler owns loading and execution.
8584
+ cloudflareWorkers: "cloudflare_workers"
8585
+ };
8586
+ var PLAY_ARTIFACT_KINDS = {
8587
+ cjsNode20: "cjs_node20",
8588
+ esmWorkers: "esm_workers"
8589
+ };
8590
+ var PLAY_BACKEND_DESCRIPTORS = {
8591
+ [PLAY_RUNTIME_BACKENDS.localProcess]: {
8592
+ id: PLAY_RUNTIME_BACKENDS.localProcess,
8593
+ artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
8594
+ label: "Local node subprocess"
8595
+ },
8596
+ [PLAY_RUNTIME_BACKENDS.daytona]: {
8597
+ id: PLAY_RUNTIME_BACKENDS.daytona,
8598
+ artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
8599
+ label: "Daytona sandbox"
8600
+ },
8601
+ [PLAY_RUNTIME_BACKENDS.cloudflareWorkers]: {
8602
+ id: PLAY_RUNTIME_BACKENDS.cloudflareWorkers,
8603
+ artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
8604
+ label: "Cloudflare Dynamic Workers"
8605
+ }
8606
+ };
8607
+
8608
+ // ../shared_libs/play-runtime/dedup-backend.ts
8609
+ var PLAY_DEDUP_BACKENDS = {
8610
+ inMemory: "in_memory",
8611
+ neonTable: "neon_table",
8612
+ durableObject: "durable_object"
8613
+ };
8614
+
8615
+ // ../shared_libs/play-runtime/scheduler-backend.ts
8616
+ var PLAY_SCHEDULER_BACKENDS = {
8617
+ temporal: "temporal",
8618
+ cfWorkflows: "cf-workflows",
8619
+ /**
8620
+ * Private legacy id retained only so old persisted rows can be interpreted.
8621
+ * It is not a selectable scheduler backend after the Hatchet hard cutover.
8622
+ */
8623
+ postgres: "postgres",
8624
+ hatchet: "hatchet",
8625
+ inProcess: "in-process"
8626
+ };
8627
+
8628
+ // ../shared_libs/play-runtime/providers.ts
8629
+ var PLAY_RUNTIME_PROVIDER_IDS = {
8630
+ workersEdge: "workers_edge",
8631
+ hatchet: "hatchet",
8632
+ local: "local"
8633
+ };
8634
+ var PLAY_RUNTIME_PROVIDERS = {
8635
+ workers_edge: {
8636
+ id: PLAY_RUNTIME_PROVIDER_IDS.workersEdge,
8637
+ scheduler: PLAY_SCHEDULER_BACKENDS.cfWorkflows,
8638
+ runner: PLAY_RUNTIME_BACKENDS.cloudflareWorkers,
8639
+ dedup: PLAY_DEDUP_BACKENDS.durableObject,
8640
+ artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
8641
+ label: "Cloudflare Dynamic Workflows + Dynamic Workers + DO dedup"
8642
+ },
8643
+ hatchet: {
8644
+ id: PLAY_RUNTIME_PROVIDER_IDS.hatchet,
8645
+ scheduler: PLAY_SCHEDULER_BACKENDS.hatchet,
8646
+ runner: PLAY_RUNTIME_BACKENDS.daytona,
8647
+ dedup: PLAY_DEDUP_BACKENDS.durableObject,
8648
+ artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
8649
+ label: "Hatchet scheduler + one-shot Daytona runner + DO dedup"
8650
+ },
8651
+ local: {
8652
+ id: PLAY_RUNTIME_PROVIDER_IDS.local,
8653
+ scheduler: PLAY_SCHEDULER_BACKENDS.temporal,
8654
+ runner: PLAY_RUNTIME_BACKENDS.localProcess,
8655
+ dedup: PLAY_DEDUP_BACKENDS.inMemory,
8656
+ artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
8657
+ label: "Local Temporal scheduler + local subprocess runner (tests)"
8658
+ }
8659
+ };
8660
+ function defaultPlayRuntimeProvider() {
8661
+ return PLAY_RUNTIME_PROVIDERS.workers_edge;
8662
+ }
8663
+ function resolvePlayRuntimeProvider(override) {
8664
+ if (override?.trim()) {
8665
+ const id = override.trim();
8666
+ if (id in PLAY_RUNTIME_PROVIDERS) {
8667
+ return PLAY_RUNTIME_PROVIDERS[id];
8668
+ }
8669
+ throw new Error(
8670
+ `Unknown play runtime provider "${id}". Expected one of: ${Object.keys(
8671
+ PLAY_RUNTIME_PROVIDERS
8672
+ ).join(", ")}.`
8673
+ );
10276
8674
  }
10277
- return null;
8675
+ return defaultPlayRuntimeProvider();
10278
8676
  }
10279
- function addPlayCheckRepairHints(input2) {
10280
- const addedHints = /* @__PURE__ */ new Set();
10281
- return input2.errors.map((error) => {
10282
- const line = sourceLineForError(input2.sourceCode, error);
10283
- const hint = hintForError(error, line);
10284
- if (!hint || addedHints.has(hint) || error.includes(hint)) {
10285
- return error;
8677
+
8678
+ // ../shared_libs/play-runtime/profiles.ts
8679
+ var PLAY_EXECUTION_PROFILE_IDS = {
8680
+ ...PLAY_RUNTIME_PROVIDER_IDS
8681
+ };
8682
+ var PLAY_EXECUTION_PROFILES = PLAY_RUNTIME_PROVIDERS;
8683
+ function resolveExecutionProfile(override) {
8684
+ try {
8685
+ return resolvePlayRuntimeProvider(override);
8686
+ } catch (error) {
8687
+ if (override?.trim()) {
8688
+ throw new Error(
8689
+ `Unknown execution profile "${override.trim()}". Expected one of: ${Object.keys(
8690
+ PLAY_EXECUTION_PROFILES
8691
+ ).join(", ")}.`
8692
+ );
10286
8693
  }
10287
- addedHints.add(hint);
10288
- return `${error}
10289
- ${hint}`;
10290
- });
8694
+ throw error;
8695
+ }
10291
8696
  }
10292
8697
 
10293
8698
  // ../shared_libs/play-runtime/internal-step-ids.ts
@@ -10297,6 +8702,165 @@ function isInternalGlueStepId(stepId) {
10297
8702
  }
10298
8703
 
10299
8704
  // src/cli/commands/play.ts
8705
+ var PLAY_BUNDLER_MODULE_PATHS = [
8706
+ // Built CLI bundle: dist/cli/index.mjs -> dist/plays/bundle-play-file.mjs.
8707
+ ["..", "plays", "bundle-play-file.mjs"].join("/"),
8708
+ // Source CLI: src/cli/commands/play.ts -> src/plays/bundle-play-file.ts.
8709
+ ["..", "..", "plays", "bundle-play-file.js"].join("/")
8710
+ ];
8711
+ var playBundlerPromise = null;
8712
+ async function loadPlayBundler() {
8713
+ playBundlerPromise ??= (async () => {
8714
+ const errors = [];
8715
+ for (const modulePath of PLAY_BUNDLER_MODULE_PATHS) {
8716
+ try {
8717
+ return await import(modulePath);
8718
+ } catch (error) {
8719
+ errors.push(
8720
+ `${modulePath}: ${error instanceof Error ? error.message : String(error)}`
8721
+ );
8722
+ }
8723
+ }
8724
+ playBundlerPromise = null;
8725
+ throw new Error(
8726
+ `Local play-file bundling is unavailable in this Deepline SDK install. Reinstall the package, or run a saved/prebuilt play by name while you repair the install. Bundler load failed: ${errors.join("; ")}`
8727
+ );
8728
+ })();
8729
+ return playBundlerPromise;
8730
+ }
8731
+ function stripCommentsToSpaces(source) {
8732
+ let output2 = "";
8733
+ let quote = null;
8734
+ let escaped = false;
8735
+ let lineComment = false;
8736
+ let blockComment = false;
8737
+ for (let index = 0; index < source.length; index += 1) {
8738
+ const char = source[index];
8739
+ const next = source[index + 1];
8740
+ if (lineComment) {
8741
+ if (char === "\n" || char === "\r") {
8742
+ lineComment = false;
8743
+ output2 += char;
8744
+ } else {
8745
+ output2 += " ";
8746
+ }
8747
+ continue;
8748
+ }
8749
+ if (blockComment) {
8750
+ if (char === "*" && next === "/") {
8751
+ output2 += " ";
8752
+ index += 1;
8753
+ blockComment = false;
8754
+ } else {
8755
+ output2 += char === "\n" || char === "\r" ? char : " ";
8756
+ }
8757
+ continue;
8758
+ }
8759
+ if (quote) {
8760
+ output2 += char;
8761
+ if (escaped) {
8762
+ escaped = false;
8763
+ } else if (char === "\\") {
8764
+ escaped = true;
8765
+ } else if (char === quote) {
8766
+ quote = null;
8767
+ }
8768
+ continue;
8769
+ }
8770
+ if (char === '"' || char === "'" || char === "`") {
8771
+ quote = char;
8772
+ output2 += char;
8773
+ continue;
8774
+ }
8775
+ if (char === "/" && next === "/") {
8776
+ output2 += " ";
8777
+ index += 1;
8778
+ lineComment = true;
8779
+ continue;
8780
+ }
8781
+ if (char === "/" && next === "*") {
8782
+ output2 += " ";
8783
+ index += 1;
8784
+ blockComment = true;
8785
+ continue;
8786
+ }
8787
+ output2 += char;
8788
+ }
8789
+ return output2;
8790
+ }
8791
+ function unquotePlayNameLiteral(raw) {
8792
+ if (raw.length < 2) return null;
8793
+ const quote = raw[0];
8794
+ let value = "";
8795
+ for (let index = 1; index < raw.length - 1; index += 1) {
8796
+ const char = raw[index];
8797
+ if (char !== "\\") {
8798
+ value += char;
8799
+ continue;
8800
+ }
8801
+ index += 1;
8802
+ const escaped = raw[index];
8803
+ if (escaped === void 0) return null;
8804
+ value += escaped === "n" ? "\n" : escaped === "r" ? "\r" : escaped === "t" ? " " : escaped;
8805
+ }
8806
+ if (quote === "`" && value.includes("${")) return null;
8807
+ return value;
8808
+ }
8809
+ function findMatchingBrace(source, openIndex) {
8810
+ let depth = 0;
8811
+ let quote = null;
8812
+ let escaped = false;
8813
+ for (let index = openIndex; index < source.length; index += 1) {
8814
+ const char = source[index];
8815
+ if (quote) {
8816
+ if (escaped) {
8817
+ escaped = false;
8818
+ } else if (char === "\\") {
8819
+ escaped = true;
8820
+ } else if (char === quote) {
8821
+ quote = null;
8822
+ }
8823
+ continue;
8824
+ }
8825
+ if (char === '"' || char === "'" || char === "`") {
8826
+ quote = char;
8827
+ continue;
8828
+ }
8829
+ if (char === "{") depth += 1;
8830
+ if (char === "}") {
8831
+ depth -= 1;
8832
+ if (depth === 0) return index;
8833
+ }
8834
+ }
8835
+ return -1;
8836
+ }
8837
+ function extractDefinedPlayName(code) {
8838
+ const source = stripCommentsToSpaces(code);
8839
+ const callPattern = /(?:\b[A-Za-z_$][\w$]*\s*\.\s*)?\b(?:definePlay|defineWorkflow)\s*\(/g;
8840
+ for (const match of source.matchAll(callPattern)) {
8841
+ const openParen = match.index + match[0].length - 1;
8842
+ const firstArgStart = openParen + 1;
8843
+ const firstNonSpace = source.slice(firstArgStart).search(/\S/);
8844
+ if (firstNonSpace < 0) continue;
8845
+ const argIndex = firstArgStart + firstNonSpace;
8846
+ const quote = source[argIndex];
8847
+ if (quote === '"' || quote === "'" || quote === "`") {
8848
+ const literalMatch = source.slice(argIndex).match(/^(['"`])(?:\\.|(?!\1)[\s\S])*\1/);
8849
+ const value2 = literalMatch ? unquotePlayNameLiteral(literalMatch[0]) : null;
8850
+ if (value2?.trim()) return value2.trim();
8851
+ }
8852
+ if (quote !== "{") continue;
8853
+ const closeBrace = findMatchingBrace(source, argIndex);
8854
+ if (closeBrace < 0) continue;
8855
+ const objectSource = source.slice(argIndex + 1, closeBrace);
8856
+ const idMatch = objectSource.match(
8857
+ /(?:^|[,{\s])(?:id|name|['"](?:id|name)['"])\s*:\s*(['"`])((?:\\.|(?!\1)[\s\S])*)\1/
8858
+ );
8859
+ const value = idMatch ? unquotePlayNameLiteral(`${idMatch[1]}${idMatch[2]}${idMatch[1]}`) : null;
8860
+ if (value?.trim()) return value.trim();
8861
+ }
8862
+ return null;
8863
+ }
10300
8864
  var PLAY_RUN_RESERVED_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
10301
8865
  "--json",
10302
8866
  "--wait",
@@ -10331,7 +8895,7 @@ function traceCliSync(phase, fields, run) {
10331
8895
  }
10332
8896
  }
10333
8897
  function sleep5(ms) {
10334
- return new Promise((resolve16) => setTimeout(resolve16, ms));
8898
+ return new Promise((resolve13) => setTimeout(resolve13, ms));
10335
8899
  }
10336
8900
  function parseReferencedPlayTarget2(target) {
10337
8901
  const trimmed = target.trim();
@@ -10375,7 +8939,7 @@ function formatPlayListReference(play) {
10375
8939
  return play.reference || play.name;
10376
8940
  }
10377
8941
  function defaultMaterializedPlayPath(reference) {
10378
- return (0, import_node_path13.resolve)(defaultStarterPlayPath(reference));
8942
+ return (0, import_node_path10.resolve)(defaultStarterPlayPath(reference));
10379
8943
  }
10380
8944
  function defaultStarterPlayPath(reference) {
10381
8945
  const playName = parseReferencedPlayTarget2(reference).unqualifiedPlayName;
@@ -10401,15 +8965,15 @@ function materializeRemotePlaySource(input2) {
10401
8965
  return null;
10402
8966
  }
10403
8967
  const outputPath = input2.outPath ?? defaultMaterializedPlayPath(input2.playName);
10404
- if ((0, import_node_fs11.existsSync)(outputPath)) {
10405
- const existingSource = (0, import_node_fs11.readFileSync)(outputPath, "utf-8");
8968
+ if ((0, import_node_fs9.existsSync)(outputPath)) {
8969
+ const existingSource = (0, import_node_fs9.readFileSync)(outputPath, "utf-8");
10406
8970
  if (existingSource === input2.sourceCode) {
10407
8971
  return { path: outputPath, status: "unchanged", created: false };
10408
8972
  }
10409
- (0, import_node_fs11.writeFileSync)(outputPath, input2.sourceCode, "utf-8");
8973
+ (0, import_node_fs9.writeFileSync)(outputPath, input2.sourceCode, "utf-8");
10410
8974
  return { path: outputPath, status: "updated", created: false };
10411
8975
  }
10412
- (0, import_node_fs11.writeFileSync)(outputPath, input2.sourceCode, "utf-8");
8976
+ (0, import_node_fs9.writeFileSync)(outputPath, input2.sourceCode, "utf-8");
10413
8977
  return { path: outputPath, status: "created", created: true };
10414
8978
  }
10415
8979
  function formatLoadedPlayMessage(materializedFile) {
@@ -10454,7 +9018,7 @@ function extractPlayName(code, filePath) {
10454
9018
  throw buildMissingDefinePlayError(filePath);
10455
9019
  }
10456
9020
  function isFileTarget(target) {
10457
- return (0, import_node_fs11.existsSync)((0, import_node_path13.resolve)(target));
9021
+ return (0, import_node_fs9.existsSync)((0, import_node_path10.resolve)(target));
10458
9022
  }
10459
9023
  function looksLikeRunId(target) {
10460
9024
  return /^play\/[^/]+\/run\/[^/]+/.test(target.trim());
@@ -10483,7 +9047,7 @@ function parsePositiveInteger3(value, flagName) {
10483
9047
  return parsed;
10484
9048
  }
10485
9049
  function parseJsonInput(raw) {
10486
- const source = raw.startsWith("@") ? (0, import_node_fs11.readFileSync)((0, import_node_path13.resolve)(raw.slice(1)), "utf-8") : raw;
9050
+ const source = raw.startsWith("@") ? (0, import_node_fs9.readFileSync)((0, import_node_path10.resolve)(raw.slice(1)), "utf-8") : raw;
10487
9051
  const parsed = JSON.parse(source);
10488
9052
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
10489
9053
  throw new Error("--input must be a JSON object.");
@@ -10585,7 +9149,7 @@ function fileInputBindingsFromStaticPipeline(staticPipeline) {
10585
9149
  function isLocalFilePathValue(value) {
10586
9150
  if (typeof value !== "string" || !value.trim()) return false;
10587
9151
  if (/^[a-z][a-z0-9+.-]*:\/\//i.test(value.trim())) return false;
10588
- return (0, import_node_fs11.existsSync)((0, import_node_path13.resolve)(value));
9152
+ return (0, import_node_fs9.existsSync)((0, import_node_path10.resolve)(value));
10589
9153
  }
10590
9154
  function inputContainsLocalFilePath(value) {
10591
9155
  if (isLocalFilePathValue(value)) {
@@ -10632,7 +9196,7 @@ function collectLocalFileInputRefs(value, inputPath, key, out) {
10632
9196
  const looksLikeFile = /\.[a-z0-9]{1,8}$/i.test(trimmed);
10633
9197
  if (keyIsCsvData) {
10634
9198
  out.push({ inputPath, value: trimmed, isCsvData: true });
10635
- } else if (endsWithCsv || looksLikeFile && (0, import_node_fs11.existsSync)((0, import_node_path13.resolve)(trimmed))) {
9199
+ } else if (endsWithCsv || looksLikeFile && (0, import_node_fs9.existsSync)((0, import_node_path10.resolve)(trimmed))) {
10636
9200
  out.push({ inputPath, value: trimmed, isCsvData: false });
10637
9201
  }
10638
9202
  return;
@@ -10674,8 +9238,8 @@ function preflightLocalFileInputs(runtimeInput) {
10674
9238
  collectLocalFileInputRefs(value, key, key, refs);
10675
9239
  }
10676
9240
  for (const ref of refs) {
10677
- const absolutePath = (0, import_node_path13.resolve)(ref.value);
10678
- if (!(0, import_node_fs11.existsSync)(absolutePath)) {
9241
+ const absolutePath = (0, import_node_path10.resolve)(ref.value);
9242
+ if (!(0, import_node_fs9.existsSync)(absolutePath)) {
10679
9243
  throw new DeeplineError(
10680
9244
  `Input ${ref.inputPath} references a local file that does not exist: ${ref.value} (resolved to ${absolutePath}). No run was created.`,
10681
9245
  void 0,
@@ -10683,9 +9247,9 @@ function preflightLocalFileInputs(runtimeInput) {
10683
9247
  { inputPath: ref.inputPath, path: ref.value, resolved: absolutePath }
10684
9248
  );
10685
9249
  }
10686
- let stat4;
9250
+ let stat2;
10687
9251
  try {
10688
- stat4 = (0, import_node_fs11.statSync)(absolutePath);
9252
+ stat2 = (0, import_node_fs9.statSync)(absolutePath);
10689
9253
  } catch (error) {
10690
9254
  throw new DeeplineError(
10691
9255
  `Input ${ref.inputPath} references a local file that is not readable: ${ref.value} (${error instanceof Error ? error.message : String(error)}). No run was created.`,
@@ -10694,7 +9258,7 @@ function preflightLocalFileInputs(runtimeInput) {
10694
9258
  { inputPath: ref.inputPath, path: ref.value }
10695
9259
  );
10696
9260
  }
10697
- if (!stat4.isFile()) {
9261
+ if (!stat2.isFile()) {
10698
9262
  throw new DeeplineError(
10699
9263
  `Input ${ref.inputPath} references ${ref.value}, which is not a file. No run was created.`,
10700
9264
  void 0,
@@ -10711,7 +9275,7 @@ function preflightLocalFileInputs(runtimeInput) {
10711
9275
  function preflightCsvDataInput(ref, absolutePath) {
10712
9276
  let content;
10713
9277
  try {
10714
- content = (0, import_node_fs11.readFileSync)(absolutePath, "utf-8");
9278
+ content = (0, import_node_fs9.readFileSync)(absolutePath, "utf-8");
10715
9279
  } catch (error) {
10716
9280
  throw new DeeplineError(
10717
9281
  `Input ${ref.inputPath} CSV ${ref.value} is not readable: ${error instanceof Error ? error.message : String(error)}. No run was created.`,
@@ -10793,8 +9357,8 @@ async function stageFileInputArgs(input2) {
10793
9357
  const localFiles = uniqueBindings.flatMap((binding) => {
10794
9358
  const value = getDottedInputValue(input2.runtimeInput, binding.inputPath);
10795
9359
  if (!isLocalFilePathValue(value)) return [];
10796
- const absolutePath = (0, import_node_path13.resolve)(value);
10797
- return [{ binding, absolutePath, logicalPath: (0, import_node_path13.basename)(absolutePath) }];
9360
+ const absolutePath = (0, import_node_path10.resolve)(value);
9361
+ return [{ binding, absolutePath, logicalPath: (0, import_node_path10.basename)(absolutePath) }];
10798
9362
  });
10799
9363
  if (localFiles.length === 0) {
10800
9364
  return { inputFile: null, packagedFiles: [] };
@@ -10826,20 +9390,20 @@ async function stageFileInputArgs(input2) {
10826
9390
  };
10827
9391
  }
10828
9392
  function stageFile(logicalPath, absolutePath) {
10829
- const buffer = (0, import_node_fs11.readFileSync)(absolutePath);
9393
+ const buffer = (0, import_node_fs9.readFileSync)(absolutePath);
10830
9394
  return {
10831
9395
  logicalPath,
10832
9396
  contentBase64: buffer.toString("base64"),
10833
- contentHash: (0, import_node_crypto3.createHash)("sha256").update(buffer).digest("hex"),
9397
+ contentHash: (0, import_node_crypto.createHash)("sha256").update(buffer).digest("hex"),
10834
9398
  contentType: absolutePath.toLowerCase().endsWith(".csv") ? "text/csv" : absolutePath.toLowerCase().endsWith(".json") ? "application/json" : "application/octet-stream",
10835
9399
  bytes: buffer.byteLength
10836
9400
  };
10837
9401
  }
10838
9402
  function normalizePlayPath(filePath) {
10839
9403
  try {
10840
- return import_node_fs11.realpathSync.native((0, import_node_path13.resolve)(filePath));
9404
+ return import_node_fs9.realpathSync.native((0, import_node_path10.resolve)(filePath));
10841
9405
  } catch {
10842
- return (0, import_node_path13.resolve)(filePath);
9406
+ return (0, import_node_path10.resolve)(filePath);
10843
9407
  }
10844
9408
  }
10845
9409
  function formatBundlingErrors(filePath, errors) {
@@ -10850,6 +9414,7 @@ function formatUnresolvedPackagedFiles(filePath, unresolvedFileReferences) {
10850
9414
  return `Failed to package local ctx.csv(...) files in ${filePath}: ${details}`;
10851
9415
  }
10852
9416
  async function collectBundledPlayGraph(entryFile, profile = null) {
9417
+ const playBundler = await loadPlayBundler();
10853
9418
  const nodes = /* @__PURE__ */ new Map();
10854
9419
  const visiting = /* @__PURE__ */ new Set();
10855
9420
  const artifactKind = resolveExecutionProfile(profile).artifactKind;
@@ -10866,7 +9431,7 @@ async function collectBundledPlayGraph(entryFile, profile = null) {
10866
9431
  }
10867
9432
  visiting.add(absolutePath);
10868
9433
  try {
10869
- const bundleResult = await bundlePlayFile2(absolutePath, {
9434
+ const bundleResult = await playBundler.bundlePlayFile(absolutePath, {
10870
9435
  target: artifactKind
10871
9436
  });
10872
9437
  if (bundleResult.success === false) {
@@ -11490,6 +10055,7 @@ async function waitForPlayCompletionByStream(input2) {
11490
10055
  input2.workflowId,
11491
10056
  {
11492
10057
  signal: controller.signal,
10058
+ fallback: "none",
11493
10059
  onNotice: input2.jsonOutput ? void 0 : (message) => input2.progress.writeLine(message)
11494
10060
  }
11495
10061
  )) {
@@ -12503,15 +11069,15 @@ function formatDatasetStatsLines(datasetStats, indent2 = " ") {
12503
11069
  return [];
12504
11070
  }
12505
11071
  const lines = [`${indent2}summary:`];
12506
- for (const [column, stat4] of Object.entries(datasetStats.columnStats).slice(
11072
+ for (const [column, stat2] of Object.entries(datasetStats.columnStats).slice(
12507
11073
  0,
12508
11074
  12
12509
11075
  )) {
12510
- const topValues = stat4.top_values ? `, top_values=${Object.entries(stat4.top_values).slice(0, 3).map(([value, count]) => `${value}=${count}`).join(", ")}` : "";
12511
- const sample = stat4.sample_value !== void 0 ? `, sample_value=${JSON.stringify(stat4.sample_value)}` : "";
12512
- const execution = stat4.execution ? `, execution=${Object.entries(stat4.execution).map(([bucket, count]) => `${bucket}=${count}`).join(", ")}` : "";
11076
+ const topValues = stat2.top_values ? `, top_values=${Object.entries(stat2.top_values).slice(0, 3).map(([value, count]) => `${value}=${count}`).join(", ")}` : "";
11077
+ const sample = stat2.sample_value !== void 0 ? `, sample_value=${JSON.stringify(stat2.sample_value)}` : "";
11078
+ const execution = stat2.execution ? `, execution=${Object.entries(stat2.execution).map(([bucket, count]) => `${bucket}=${count}`).join(", ")}` : "";
12513
11079
  lines.push(
12514
- `${indent2} ${column}: non_empty=${stat4.non_empty}, unique=${stat4.unique}${topValues}${sample}${execution}`
11080
+ `${indent2} ${column}: non_empty=${stat2.non_empty}, unique=${stat2.unique}${topValues}${sample}${execution}`
12515
11081
  );
12516
11082
  }
12517
11083
  return lines;
@@ -12824,7 +11390,7 @@ function shellSingleQuote(value) {
12824
11390
  return `'${value.replace(/'/g, `'\\''`)}'`;
12825
11391
  }
12826
11392
  function runExportRetryCommand(runId, outPath, datasetPath) {
12827
- return `deepline runs export ${runId}${datasetPath ? ` --dataset ${shellSingleQuote(datasetPath)}` : ""} --out ${shellSingleQuote((0, import_node_path13.resolve)(outPath))}`;
11393
+ return `deepline runs export ${runId}${datasetPath ? ` --dataset ${shellSingleQuote(datasetPath)}` : ""} --out ${shellSingleQuote((0, import_node_path10.resolve)(outPath))}`;
12828
11394
  }
12829
11395
  function extractRunPlayName(status) {
12830
11396
  const run = status.run;
@@ -13628,7 +12194,7 @@ async function handlePlayCheck(args) {
13628
12194
  }
13629
12195
  return 0;
13630
12196
  } catch (error) {
13631
- const resolved = (0, import_node_path13.resolve)(options.target);
12197
+ const resolved = (0, import_node_path10.resolve)(options.target);
13632
12198
  const message = error instanceof Error && error.message ? error.message : `File not found: ${resolved}`;
13633
12199
  if (options.jsonOutput) {
13634
12200
  process.stdout.write(
@@ -13645,8 +12211,8 @@ async function handlePlayCheck(args) {
13645
12211
  return 1;
13646
12212
  }
13647
12213
  }
13648
- const absolutePlayPath = (0, import_node_path13.resolve)(options.target);
13649
- const sourceCode = (0, import_node_fs11.readFileSync)(absolutePlayPath, "utf-8");
12214
+ const absolutePlayPath = (0, import_node_path10.resolve)(options.target);
12215
+ const sourceCode = (0, import_node_fs9.readFileSync)(absolutePlayPath, "utf-8");
13650
12216
  let graph;
13651
12217
  try {
13652
12218
  graph = await collectBundledPlayGraph(absolutePlayPath);
@@ -13725,12 +12291,12 @@ async function handleFileBackedRun(options) {
13725
12291
  }
13726
12292
  const client2 = new DeeplineClient();
13727
12293
  const progress = getActiveCliProgress() ?? createCliProgress(!options.jsonOutput);
13728
- const absolutePlayPath = (0, import_node_path13.resolve)(options.target.path);
12294
+ const absolutePlayPath = (0, import_node_path10.resolve)(options.target.path);
13729
12295
  progress.phase("compiling play");
13730
12296
  const sourceCode = traceCliSync(
13731
12297
  "cli.play_file_read_source",
13732
12298
  { targetKind: "file" },
13733
- () => (0, import_node_fs11.readFileSync)(absolutePlayPath, "utf-8")
12299
+ () => (0, import_node_fs9.readFileSync)(absolutePlayPath, "utf-8")
13734
12300
  );
13735
12301
  const runtimeInput = options.input ? { ...options.input } : {};
13736
12302
  try {
@@ -14049,19 +12615,19 @@ async function handlePlayRun(args) {
14049
12615
  if (isFileTarget(options.target.path)) {
14050
12616
  return handleFileBackedRun(options);
14051
12617
  }
14052
- const resolved = (0, import_node_path13.resolve)(options.target.path);
12618
+ const resolved = (0, import_node_path10.resolve)(options.target.path);
14053
12619
  console.error(`File not found: ${resolved}`);
14054
- const dir = (0, import_node_path13.dirname)(resolved);
14055
- if ((0, import_node_fs11.existsSync)(dir)) {
14056
- const base = (0, import_node_path13.basename)(resolved);
12620
+ const dir = (0, import_node_path10.dirname)(resolved);
12621
+ if ((0, import_node_fs9.existsSync)(dir)) {
12622
+ const base = (0, import_node_path10.basename)(resolved);
14057
12623
  try {
14058
- const siblings = (0, import_node_fs11.readdirSync)(dir).filter(
12624
+ const siblings = (0, import_node_fs9.readdirSync)(dir).filter(
14059
12625
  (f) => f.includes(base.replace(/\.(play\.)?ts$/, "")) || f.endsWith(".play.ts")
14060
12626
  );
14061
12627
  if (siblings.length > 0) {
14062
12628
  console.error(`Did you mean one of these?`);
14063
12629
  for (const s of siblings.slice(0, 5)) {
14064
- console.error(` ${(0, import_node_path13.join)(dir, s)}`);
12630
+ console.error(` ${(0, import_node_path10.join)(dir, s)}`);
14065
12631
  }
14066
12632
  }
14067
12633
  } catch {
@@ -14216,14 +12782,14 @@ async function handleRunLogs(args) {
14216
12782
  continue;
14217
12783
  }
14218
12784
  if (arg === "--out" && args[index + 1]) {
14219
- outPath = (0, import_node_path13.resolve)(args[++index]);
12785
+ outPath = (0, import_node_path10.resolve)(args[++index]);
14220
12786
  }
14221
12787
  }
14222
12788
  const client2 = new DeeplineClient();
14223
12789
  if (outPath) {
14224
12790
  const result2 = await client2.runs.logs(runId, { all: true });
14225
12791
  const logs = result2.entries;
14226
- (0, import_node_fs11.writeFileSync)(outPath, `${logs.join("\n")}${logs.length > 0 ? "\n" : ""}`);
12792
+ (0, import_node_fs9.writeFileSync)(outPath, `${logs.join("\n")}${logs.length > 0 ? "\n" : ""}`);
14227
12793
  printCommandEnvelope(
14228
12794
  {
14229
12795
  runId: result2.runId,
@@ -14348,7 +12914,7 @@ async function handleRunExport(args) {
14348
12914
  for (let index = 0; index < args.length; index += 1) {
14349
12915
  const arg = args[index];
14350
12916
  if (arg === "--out" && args[index + 1]) {
14351
- outPath = (0, import_node_path13.resolve)(args[++index]);
12917
+ outPath = (0, import_node_path10.resolve)(args[++index]);
14352
12918
  continue;
14353
12919
  }
14354
12920
  if (arg === "--dataset" && args[index + 1]) {
@@ -14356,7 +12922,7 @@ async function handleRunExport(args) {
14356
12922
  continue;
14357
12923
  }
14358
12924
  if (arg === "--metadata-out" && args[index + 1]) {
14359
- metadataOutPath = (0, import_node_path13.resolve)(args[++index]);
12925
+ metadataOutPath = (0, import_node_path10.resolve)(args[++index]);
14360
12926
  }
14361
12927
  }
14362
12928
  if (!outPath) {
@@ -14396,7 +12962,7 @@ async function handleRunExport(args) {
14396
12962
  }
14397
12963
  };
14398
12964
  if (metadataOutPath) {
14399
- (0, import_node_fs11.writeFileSync)(
12965
+ (0, import_node_fs9.writeFileSync)(
14400
12966
  metadataOutPath,
14401
12967
  `${JSON.stringify(payload, null, 2)}
14402
12968
  `,
@@ -14428,10 +12994,10 @@ async function handlePlayGet(args) {
14428
12994
  for (let index = 1; index < args.length; index += 1) {
14429
12995
  const arg = args[index];
14430
12996
  if (arg === "--out" && args[index + 1]) {
14431
- outPath = (0, import_node_path13.resolve)(args[++index]);
12997
+ outPath = (0, import_node_path10.resolve)(args[++index]);
14432
12998
  }
14433
12999
  }
14434
- const playName = isFileTarget(target) ? extractPlayName((0, import_node_fs11.readFileSync)((0, import_node_path13.resolve)(target), "utf-8"), (0, import_node_path13.resolve)(target)) : parseReferencedPlayTarget2(target).playName;
13000
+ const playName = isFileTarget(target) ? extractPlayName((0, import_node_fs9.readFileSync)((0, import_node_path10.resolve)(target), "utf-8"), (0, import_node_path10.resolve)(target)) : parseReferencedPlayTarget2(target).playName;
14435
13001
  const detail = isFileTarget(target) ? await client2.getPlay(playName) : await assertCanonicalNamedPlayReference(client2, target);
14436
13002
  const resolvedSource = detail.play.workingRevision?.sourceCode ?? detail.play.liveRevision?.sourceCode ?? detail.play.currentRevision?.sourceCode ?? detail.play.sourceCode ?? "";
14437
13003
  const materializedFile = outPath ? materializeRemotePlaySource({
@@ -14874,7 +13440,7 @@ async function handlePlayDescribe(args) {
14874
13440
  const definedName = isFileTarget(playName) ? (() => {
14875
13441
  try {
14876
13442
  return extractPlayName(
14877
- (0, import_node_fs11.readFileSync)((0, import_node_path13.resolve)(playName), "utf-8"),
13443
+ (0, import_node_fs9.readFileSync)((0, import_node_path10.resolve)(playName), "utf-8"),
14878
13444
  playName
14879
13445
  );
14880
13446
  } catch {
@@ -14955,7 +13521,7 @@ async function handlePlayPublish(args) {
14955
13521
  graph = await traceCliSpan(
14956
13522
  "cli.play_publish_bundle_graph",
14957
13523
  { targetKind: "file" },
14958
- () => collectBundledPlayGraph((0, import_node_path13.resolve)(playName))
13524
+ () => collectBundledPlayGraph((0, import_node_path10.resolve)(playName))
14959
13525
  );
14960
13526
  await traceCliSpan(
14961
13527
  "cli.play_publish_compile_manifests",
@@ -15075,14 +13641,15 @@ Concepts:
15075
13641
  Stable ctx.tools.execute({ id, tool, input }) calls are replay-safe.
15076
13642
  ctx.dataset adds row keys and row progress.
15077
13643
  Named play runs use the live revision unless --latest or --revision-id is set.
15078
- Running a local file does not make it live; use set-live/publish explicitly.
13644
+ Installed npm and repo-local CLIs can run saved/prebuilt plays by name or
13645
+ bundle local .play.ts files for development workflows.
13646
+ Running a local file does not make it live; use publish or set-live for that.
15079
13647
 
15080
13648
  Common commands:
15081
13649
  deepline plays search email --json
15082
13650
  deepline plays describe prebuilt/person-linkedin-to-email --json
15083
- deepline plays check my.play.ts
15084
- deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
15085
- deepline plays set-live my.play.ts --json
13651
+ deepline plays check prebuilt/name-and-domain-to-email-waterfall-batch
13652
+ deepline plays run prebuilt/person-linkedin-to-email --input '{"linkedin_url":"..."}'
15086
13653
  deepline plays get prebuilt/person-linkedin-to-email --json
15087
13654
  `
15088
13655
  );
@@ -15090,14 +13657,14 @@ Common commands:
15090
13657
  "after",
15091
13658
  `
15092
13659
  Notes:
15093
- Validates a local play without storing it, promoting it, or starting a run.
15094
- This uses the authoritative cloud preflight path.
15095
13660
  For named or prebuilt plays, validates that the contract is discoverable
15096
13661
  without starting a run or spending Deepline credits.
13662
+ Local .play.ts checks bundle the play, validate its artifact, and stop before
13663
+ any cloud run is created.
15097
13664
 
15098
13665
  Examples:
15099
- deepline plays check my.play.ts
15100
13666
  deepline plays check prebuilt/name-and-domain-to-email-waterfall-batch
13667
+ deepline plays check my-play --json
15101
13668
  deepline plays check my.play.ts --json
15102
13669
  `
15103
13670
  ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
@@ -15106,11 +13673,10 @@ Examples:
15106
13673
  ...options.json ? ["--json"] : []
15107
13674
  ]);
15108
13675
  });
15109
- play.command("run [target]").description("Run a play file or named play.").allowUnknownOption(true).allowExcessArguments(true).addHelpText(
13676
+ play.command("run [target]").description("Run a named/prebuilt play or local play file.").allowUnknownOption(true).allowExcessArguments(true).addHelpText(
15110
13677
  "after",
15111
13678
  `
15112
13679
  Notes:
15113
- Local files are bundled, preflighted, then run in Deepline cloud.
15114
13680
  Named plays run the live saved revision.
15115
13681
  Unknown --foo value and --foo.bar value flags are passed into play input.
15116
13682
  Example: --limit 5 becomes input.limit = 5.
@@ -15150,11 +13716,11 @@ Idempotent execution:
15150
13716
  .run({ key: 'domain' })
15151
13717
 
15152
13718
  Examples:
13719
+ deepline plays run prebuilt/person-linkedin-to-email --input '{"linkedin_url":"..."}'
13720
+ deepline plays run long-background-play --no-wait
15153
13721
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
15154
13722
  deepline plays run my.play.ts --input @input.json --json
15155
- deepline plays run prebuilt/person-linkedin-to-email --input '{"linkedin_url":"..."}'
15156
13723
  deepline plays run cto-search.play.ts --limit 5
15157
- deepline plays run long-background-play --no-wait
15158
13724
  deepline runs export <run-id> --out output.csv
15159
13725
  deepline runs get <run-id>
15160
13726
  `
@@ -15347,20 +13913,21 @@ Examples:
15347
13913
  "after",
15348
13914
  `
15349
13915
  Notes:
15350
- Mutates cloud state. For a local file, this bundles, validates, saves a new
15351
- revision, and promotes that revision live. For a saved play, --latest or
15352
- --revision-id promotes an existing saved revision live.
13916
+ Mutates cloud state. For a saved play, --latest or --revision-id promotes an
13917
+ existing saved revision live.
13918
+ Local .play.ts publishing bundles the file, validates it, saves a revision,
13919
+ and promotes that revision live.
15353
13920
  Running a local file with plays run does not publish it.
15354
13921
 
15355
13922
  Examples:
15356
- deepline plays set-live my.play.ts --json
15357
13923
  deepline plays set-live my-play --latest --json
15358
13924
  deepline plays set-live my-play --revision-id <revision-id> --json
13925
+ deepline plays set-live my.play.ts --json
15359
13926
  deepline plays publish my.play.ts --json
15360
13927
  `
15361
13928
  );
15362
13929
  addPublishHelp(
15363
- play.command("publish <target>").description("Bundle, validate, save, and promote a play revision live.")
13930
+ play.command("publish <target>").description("Promote a saved play revision or publish a local play file.")
15364
13931
  ).option("--latest", "Promote the newest saved revision").option("--revision-id <id>", "Revision to promote").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
15365
13932
  process.exitCode = await handlePlayPublish([
15366
13933
  target,
@@ -15371,7 +13938,7 @@ Examples:
15371
13938
  });
15372
13939
  addPublishHelp(
15373
13940
  play.command("set-live <target>").description(
15374
- "Promote a local file or saved revision as the live play revision."
13941
+ "Promote a saved revision or publish a local play file."
15375
13942
  )
15376
13943
  ).option("--latest", "Promote the newest saved revision").option("--revision-id <id>", "Revision to promote").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
15377
13944
  process.exitCode = await handlePlayPublish([
@@ -17243,10 +15810,10 @@ function expandAtFilePath(rawPath) {
17243
15810
  (_match, bareName, bracedName) => process.env[bareName ?? bracedName ?? ""] ?? ""
17244
15811
  );
17245
15812
  if (expanded === "~") {
17246
- return (0, import_node_os9.homedir)();
15813
+ return (0, import_node_os7.homedir)();
17247
15814
  }
17248
15815
  if (expanded.startsWith("~/") || expanded.startsWith("~\\")) {
17249
- return (0, import_node_path14.join)((0, import_node_os9.homedir)(), expanded.slice(2));
15816
+ return (0, import_node_path11.join)((0, import_node_os7.homedir)(), expanded.slice(2));
17250
15817
  }
17251
15818
  return expanded;
17252
15819
  }
@@ -17259,7 +15826,7 @@ async function readAtFileReference(value, argumentName, strip = true) {
17259
15826
  throw new Error(`Invalid ${argumentName} value: empty @file path.`);
17260
15827
  }
17261
15828
  try {
17262
- const text = await (0, import_promises5.readFile)(filePath, "utf8");
15829
+ const text = await (0, import_promises3.readFile)(filePath, "utf8");
17263
15830
  const normalized = text.replace(/^\uFEFF/, "");
17264
15831
  return strip ? normalized.trim() : normalized;
17265
15832
  } catch (error) {
@@ -17430,9 +15997,9 @@ async function buildPlanArgs(args) {
17430
15997
  return planArgs;
17431
15998
  }
17432
15999
  async function assertInputCsvExists(inputCsv) {
17433
- const path = (0, import_node_path14.resolve)(inputCsv);
16000
+ const path = (0, import_node_path11.resolve)(inputCsv);
17434
16001
  try {
17435
- const info = await (0, import_promises5.stat)(path);
16002
+ const info = await (0, import_promises3.stat)(path);
17436
16003
  if (info.isFile()) {
17437
16004
  return;
17438
16005
  }
@@ -17444,8 +16011,8 @@ async function assertInputCsvExists(inputCsv) {
17444
16011
  }
17445
16012
  }
17446
16013
  async function assertSafeOutputPath(inputCsv, outputPath) {
17447
- const input2 = (0, import_node_path14.resolve)(inputCsv);
17448
- const output2 = (0, import_node_path14.resolve)(outputPath);
16014
+ const input2 = (0, import_node_path11.resolve)(inputCsv);
16015
+ const output2 = (0, import_node_path11.resolve)(outputPath);
17449
16016
  if (input2 === output2) {
17450
16017
  throw new Error(
17451
16018
  "--input and --output must be different files when not using --in-place."
@@ -17453,8 +16020,8 @@ async function assertSafeOutputPath(inputCsv, outputPath) {
17453
16020
  }
17454
16021
  try {
17455
16022
  const [inputInfo, outputInfo] = await Promise.all([
17456
- (0, import_promises5.stat)(input2),
17457
- (0, import_promises5.stat)(output2)
16023
+ (0, import_promises3.stat)(input2),
16024
+ (0, import_promises3.stat)(output2)
17458
16025
  ]);
17459
16026
  if (inputInfo.dev === outputInfo.dev && inputInfo.ino === outputInfo.ino) {
17460
16027
  throw new Error(
@@ -17474,7 +16041,7 @@ async function assertSafeOutputPath(inputCsv, outputPath) {
17474
16041
  }
17475
16042
  async function regularFileExists(path) {
17476
16043
  try {
17477
- const info = await (0, import_promises5.stat)((0, import_node_path14.resolve)(path));
16044
+ const info = await (0, import_promises3.stat)((0, import_node_path11.resolve)(path));
17478
16045
  return info.isFile();
17479
16046
  } catch (error) {
17480
16047
  const code = error && typeof error === "object" ? error.code : void 0;
@@ -17485,7 +16052,7 @@ async function regularFileExists(path) {
17485
16052
  }
17486
16053
  }
17487
16054
  async function readConfig(path) {
17488
- const source = await (0, import_promises5.readFile)((0, import_node_path14.resolve)(path), "utf8");
16055
+ const source = await (0, import_promises3.readFile)((0, import_node_path11.resolve)(path), "utf8");
17489
16056
  let parsed;
17490
16057
  try {
17491
16058
  parsed = JSON.parse(source);
@@ -17770,7 +16337,7 @@ async function runGeneratedEnrichPlay(runArgs, options = {}) {
17770
16337
  });
17771
16338
  } catch (error) {
17772
16339
  if (attempt === 0 && isPlayStartStreamEndedError(error)) {
17773
- await new Promise((resolve16) => setTimeout(resolve16, 250));
16340
+ await new Promise((resolve13) => setTimeout(resolve13, 250));
17774
16341
  continue;
17775
16342
  }
17776
16343
  throw error;
@@ -17801,8 +16368,8 @@ async function writeOutputCsv(outputPath, status, options) {
17801
16368
  ]),
17802
16369
  options?.config
17803
16370
  );
17804
- await (0, import_promises5.writeFile)(
17805
- (0, import_node_path14.resolve)(outputPath),
16371
+ await (0, import_promises3.writeFile)(
16372
+ (0, import_node_path11.resolve)(outputPath),
17806
16373
  csvStringFromRows(merged.rows, columns),
17807
16374
  "utf8"
17808
16375
  );
@@ -17812,7 +16379,7 @@ async function writeOutputCsv(outputPath, status, options) {
17812
16379
  selectedRows: rowsInfo.totalRows,
17813
16380
  enrichedRows: rowsInfo.rows.length,
17814
16381
  rows: merged.rows.length,
17815
- path: (0, import_node_path14.resolve)(outputPath),
16382
+ path: (0, import_node_path11.resolve)(outputPath),
17816
16383
  enrichedDataRows: rowsInfo.rows
17817
16384
  };
17818
16385
  }
@@ -18001,12 +16568,12 @@ function firstAliasExecutionCounts(input2) {
18001
16568
  const aliases = collectConfigScalarAliasOrder(input2.config);
18002
16569
  const summaries = collectColumnStats(input2.status);
18003
16570
  for (const alias of aliases) {
18004
- const stat4 = summaries.map((summary) => summary[alias]).find(isRecord7);
18005
- if (!stat4) continue;
16571
+ const stat2 = summaries.map((summary) => summary[alias]).find(isRecord7);
16572
+ if (!stat2) continue;
18006
16573
  if (input2.forceAliases.has(normalizeAlias2(alias))) {
18007
16574
  return { executed: input2.selectedRows, reused: 0 };
18008
16575
  }
18009
- const execution = isRecord7(stat4.execution) ? stat4.execution : null;
16576
+ const execution = isRecord7(stat2.execution) ? stat2.execution : null;
18010
16577
  if (!execution) continue;
18011
16578
  return {
18012
16579
  executed: parseExecutionCount(execution["completed:executed"]),
@@ -18066,11 +16633,11 @@ function rewriteEnrichJsonStatus(input2) {
18066
16633
  if (isRecord7(next.columnStats) && selectedRows > 0) {
18067
16634
  const columnStats = { ...next.columnStats };
18068
16635
  for (const alias of forcedAliases) {
18069
- const stat4 = isRecord7(columnStats[alias]) ? columnStats[alias] : null;
18070
- const execution = isRecord7(stat4?.execution) ? stat4.execution : null;
18071
- if (!stat4 || !execution) continue;
16636
+ const stat2 = isRecord7(columnStats[alias]) ? columnStats[alias] : null;
16637
+ const execution = isRecord7(stat2?.execution) ? stat2.execution : null;
16638
+ if (!stat2 || !execution) continue;
18072
16639
  columnStats[alias] = {
18073
- ...stat4,
16640
+ ...stat2,
18074
16641
  execution: {
18075
16642
  ...execution,
18076
16643
  "completed:executed": executionSummaryText(
@@ -18107,9 +16674,9 @@ async function persistEnrichFailureReport(input2) {
18107
16674
  if (input2.jobs.length === 0) {
18108
16675
  return null;
18109
16676
  }
18110
- const stateDir = (0, import_node_path14.join)((0, import_node_os9.homedir)(), ".local", "deepline", "runtime", "state");
18111
- await (0, import_promises5.mkdir)(stateDir, { recursive: true });
18112
- const reportPath = (0, import_node_path14.join)(
16677
+ const stateDir = (0, import_node_path11.join)((0, import_node_os7.homedir)(), ".local", "deepline", "runtime", "state");
16678
+ await (0, import_promises3.mkdir)(stateDir, { recursive: true });
16679
+ const reportPath = (0, import_node_path11.join)(
18113
16680
  stateDir,
18114
16681
  `run-block-failures-${Math.floor(Date.now() / 1e3)}-${process.pid}.json`
18115
16682
  );
@@ -18133,7 +16700,7 @@ async function persistEnrichFailureReport(input2) {
18133
16700
  if (input2.rows.rowStart !== null && input2.rows.rowEnd !== null) {
18134
16701
  report.rows = { start: input2.rows.rowStart, end: input2.rows.rowEnd };
18135
16702
  }
18136
- await (0, import_promises5.writeFile)(reportPath, `${JSON.stringify(report, null, 2)}
16703
+ await (0, import_promises3.writeFile)(reportPath, `${JSON.stringify(report, null, 2)}
18137
16704
  `, "utf8");
18138
16705
  return reportPath;
18139
16706
  }
@@ -18546,8 +17113,8 @@ function registerEnrichCommand(program) {
18546
17113
  if (options.json) {
18547
17114
  printJson({
18548
17115
  dryRun: true,
18549
- input: (0, import_node_path14.resolve)(inputCsv),
18550
- output: options.output ? (0, import_node_path14.resolve)(options.output) : null,
17116
+ input: (0, import_node_path11.resolve)(inputCsv),
17117
+ output: options.output ? (0, import_node_path11.resolve)(options.output) : null,
18551
17118
  plan: summary
18552
17119
  });
18553
17120
  return;
@@ -18571,12 +17138,12 @@ function registerEnrichCommand(program) {
18571
17138
  forceAliases,
18572
17139
  playName: options.name
18573
17140
  });
18574
- const tempDir = await (0, import_promises5.mkdtemp)((0, import_node_path14.join)((0, import_node_os9.tmpdir)(), "deepline-enrich-play-"));
18575
- const tempPlay = (0, import_node_path14.join)(tempDir, "deepline-enrich.play.ts");
17141
+ const tempDir = await (0, import_promises3.mkdtemp)((0, import_node_path11.join)((0, import_node_os7.tmpdir)(), "deepline-enrich-play-"));
17142
+ const tempPlay = (0, import_node_path11.join)(tempDir, "deepline-enrich.play.ts");
18576
17143
  try {
18577
- await (0, import_promises5.writeFile)(tempPlay, playSource, "utf8");
17144
+ await (0, import_promises3.writeFile)(tempPlay, playSource, "utf8");
18578
17145
  const runtimeInput = {
18579
- file: (0, import_node_path14.resolve)(sourceCsvPath),
17146
+ file: (0, import_node_path11.resolve)(sourceCsvPath),
18580
17147
  ...rows.rowStart !== null ? { rowStart: rows.rowStart } : {},
18581
17148
  ...rows.rowEnd !== null ? { rowEnd: rows.rowEnd } : {}
18582
17149
  };
@@ -18687,7 +17254,7 @@ function registerEnrichCommand(program) {
18687
17254
  process.exitCode = EXIT_SERVER2;
18688
17255
  }
18689
17256
  } finally {
18690
- await (0, import_promises5.rm)(tempDir, { recursive: true, force: true });
17257
+ await (0, import_promises3.rm)(tempDir, { recursive: true, force: true });
18691
17258
  }
18692
17259
  });
18693
17260
  }
@@ -18737,11 +17304,11 @@ Examples:
18737
17304
  }
18738
17305
 
18739
17306
  // src/cli/commands/sessions.ts
18740
- var import_node_fs12 = require("fs");
18741
- var import_node_os10 = require("os");
18742
- var import_node_path15 = require("path");
17307
+ var import_node_fs10 = require("fs");
17308
+ var import_node_os8 = require("os");
17309
+ var import_node_path12 = require("path");
18743
17310
  var import_node_zlib = require("zlib");
18744
- var import_node_crypto4 = require("crypto");
17311
+ var import_node_crypto2 = require("crypto");
18745
17312
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
18746
17313
  var UUID_IN_TEXT_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
18747
17314
  var MAX_SESSION_UPLOAD_BYTES = 35e5;
@@ -18753,41 +17320,41 @@ var MAX_EVENT_OBJECT_KEYS = 80;
18753
17320
  var TRUNCATION_MARKER = "...[truncated]";
18754
17321
  var NOISE_EVENT_TYPES = /* @__PURE__ */ new Set(["progress", "file-history-snapshot"]);
18755
17322
  function homeDir() {
18756
- return process.env.HOME?.trim() || (0, import_node_os10.homedir)();
17323
+ return process.env.HOME?.trim() || (0, import_node_os8.homedir)();
18757
17324
  }
18758
17325
  function detectShellContext() {
18759
17326
  const shellPath = process.env.SHELL?.trim() || process.env.ComSpec?.trim() || process.env.COMSPEC?.trim() || "";
18760
17327
  return {
18761
- shell: shellPath ? (0, import_node_path15.basename)(shellPath).replace(/\.exe$/i, "") : "unknown",
17328
+ shell: shellPath ? (0, import_node_path12.basename)(shellPath).replace(/\.exe$/i, "") : "unknown",
18762
17329
  shell_path: shellPath || null,
18763
- os: (0, import_node_os10.platform)(),
17330
+ os: (0, import_node_os8.platform)(),
18764
17331
  cwd: process.cwd()
18765
17332
  };
18766
17333
  }
18767
17334
  function claudeProjectsRoot() {
18768
- return (0, import_node_path15.join)(homeDir(), ".claude", "projects");
17335
+ return (0, import_node_path12.join)(homeDir(), ".claude", "projects");
18769
17336
  }
18770
17337
  function codexSessionsRoot() {
18771
- return (0, import_node_path15.join)(homeDir(), ".codex", "sessions");
17338
+ return (0, import_node_path12.join)(homeDir(), ".codex", "sessions");
18772
17339
  }
18773
17340
  function listClaudeSessionFiles() {
18774
17341
  const root = claudeProjectsRoot();
18775
- if (!(0, import_node_fs12.existsSync)(root)) return [];
17342
+ if (!(0, import_node_fs10.existsSync)(root)) return [];
18776
17343
  const projectDirs = readDirectoryNames(root);
18777
17344
  const files = [];
18778
17345
  for (const projectDir of projectDirs) {
18779
- const fullProjectDir = (0, import_node_path15.join)(root, projectDir);
17346
+ const fullProjectDir = (0, import_node_path12.join)(root, projectDir);
18780
17347
  for (const fileName of readDirectoryNames(fullProjectDir)) {
18781
17348
  if (fileName.endsWith(".jsonl")) {
18782
- const filePath = (0, import_node_path15.join)(fullProjectDir, fileName);
17349
+ const filePath = (0, import_node_path12.join)(fullProjectDir, fileName);
18783
17350
  const sessionId = sessionIdFromClaudeFilePath(filePath);
18784
- const stat4 = statIfReadable(filePath);
18785
- if (sessionId && stat4) {
17351
+ const stat2 = statIfReadable(filePath);
17352
+ if (sessionId && stat2) {
18786
17353
  files.push({
18787
17354
  agent: "claude",
18788
17355
  sessionId,
18789
17356
  filePath,
18790
- mtimeMs: stat4.mtimeMs
17357
+ mtimeMs: stat2.mtimeMs
18791
17358
  });
18792
17359
  }
18793
17360
  }
@@ -18797,14 +17364,14 @@ function listClaudeSessionFiles() {
18797
17364
  }
18798
17365
  function listCodexSessionFiles() {
18799
17366
  const root = codexSessionsRoot();
18800
- if (!(0, import_node_fs12.existsSync)(root)) return [];
17367
+ if (!(0, import_node_fs10.existsSync)(root)) return [];
18801
17368
  const files = [];
18802
17369
  for (const filePath of listJsonlFilesRecursive(root, 5)) {
18803
- const stat4 = statIfReadable(filePath);
18804
- if (!stat4) continue;
17370
+ const stat2 = statIfReadable(filePath);
17371
+ if (!stat2) continue;
18805
17372
  const sessionId = sessionIdFromCodexFilePath(filePath) ?? readCodexSessionId(filePath);
18806
17373
  if (!sessionId) continue;
18807
- files.push({ agent: "codex", sessionId, filePath, mtimeMs: stat4.mtimeMs });
17374
+ files.push({ agent: "codex", sessionId, filePath, mtimeMs: stat2.mtimeMs });
18808
17375
  }
18809
17376
  return files;
18810
17377
  }
@@ -18820,7 +17387,7 @@ function listSessionFiles(agent) {
18820
17387
  }
18821
17388
  function readDirectoryNames(dir) {
18822
17389
  try {
18823
- return (0, import_node_fs12.readdirSync)(dir);
17390
+ return (0, import_node_fs10.readdirSync)(dir);
18824
17391
  } catch {
18825
17392
  return [];
18826
17393
  }
@@ -18831,12 +17398,12 @@ function listJsonlFilesRecursive(root, maxDepth) {
18831
17398
  if (depth > maxDepth) return;
18832
17399
  let entries;
18833
17400
  try {
18834
- entries = (0, import_node_fs12.readdirSync)(dir, { withFileTypes: true });
17401
+ entries = (0, import_node_fs10.readdirSync)(dir, { withFileTypes: true });
18835
17402
  } catch {
18836
17403
  return;
18837
17404
  }
18838
17405
  for (const entry of entries) {
18839
- const fullPath = (0, import_node_path15.join)(dir, entry.name);
17406
+ const fullPath = (0, import_node_path12.join)(dir, entry.name);
18840
17407
  if (entry.isDirectory()) {
18841
17408
  visit(fullPath, depth + 1);
18842
17409
  } else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
@@ -18849,7 +17416,7 @@ function listJsonlFilesRecursive(root, maxDepth) {
18849
17416
  }
18850
17417
  function statIfReadable(filePath) {
18851
17418
  try {
18852
- return (0, import_node_fs12.statSync)(filePath);
17419
+ return (0, import_node_fs10.statSync)(filePath);
18853
17420
  } catch {
18854
17421
  return null;
18855
17422
  }
@@ -18864,15 +17431,15 @@ function newestSessionFile(agent) {
18864
17431
  return newest;
18865
17432
  }
18866
17433
  function sessionIdFromClaudeFilePath(filePath) {
18867
- return (0, import_node_path15.basename)(filePath, ".jsonl");
17434
+ return (0, import_node_path12.basename)(filePath, ".jsonl");
18868
17435
  }
18869
17436
  function sessionIdFromCodexFilePath(filePath) {
18870
- const match = (0, import_node_path15.basename)(filePath, ".jsonl").match(UUID_IN_TEXT_RE);
17437
+ const match = (0, import_node_path12.basename)(filePath, ".jsonl").match(UUID_IN_TEXT_RE);
18871
17438
  return match?.[0] ?? null;
18872
17439
  }
18873
17440
  function readCodexSessionId(filePath) {
18874
17441
  try {
18875
- for (const line of normalizedJsonLines((0, import_node_fs12.readFileSync)(filePath)).slice(
17442
+ for (const line of normalizedJsonLines((0, import_node_fs10.readFileSync)(filePath)).slice(
18876
17443
  0,
18877
17444
  20
18878
17445
  )) {
@@ -19103,7 +17670,7 @@ async function uploadPayload(path, payload) {
19103
17670
  return await http.post(path, payload);
19104
17671
  }
19105
17672
  async function uploadChunkedSessions(sessions, options) {
19106
- const uploadId = (0, import_node_crypto4.randomUUID)();
17673
+ const uploadId = (0, import_node_crypto2.randomUUID)();
19107
17674
  for (const session of sessions) {
19108
17675
  const bytes = Buffer.from(session.encodedContent, "base64");
19109
17676
  const chunks = [];
@@ -19149,25 +17716,25 @@ async function uploadChunkedSessions(sessions, options) {
19149
17716
  }
19150
17717
  async function handleSessionsSend(options) {
19151
17718
  if (options.file) {
19152
- const filePath = (0, import_node_path15.resolve)(options.file);
19153
- if (!(0, import_node_fs12.existsSync)(filePath)) {
17719
+ const filePath = (0, import_node_path12.resolve)(options.file);
17720
+ if (!(0, import_node_fs10.existsSync)(filePath)) {
19154
17721
  throw new Error(`File not found: ${options.file}`);
19155
17722
  }
19156
17723
  const response2 = await uploadPayload("/api/v2/cli/send-session", {
19157
- file: (0, import_node_fs12.readFileSync)(filePath).toString("base64"),
19158
- filename: (0, import_node_path15.basename)(filePath)
17724
+ file: (0, import_node_fs10.readFileSync)(filePath).toString("base64"),
17725
+ filename: (0, import_node_path12.basename)(filePath)
19159
17726
  });
19160
17727
  printCommandEnvelope(
19161
17728
  {
19162
17729
  ...response2,
19163
17730
  ok: true,
19164
- filename: (0, import_node_path15.basename)(filePath),
17731
+ filename: (0, import_node_path12.basename)(filePath),
19165
17732
  render: {
19166
17733
  sections: [
19167
17734
  {
19168
17735
  title: "sessions send",
19169
17736
  lines: [
19170
- `File '${(0, import_node_path15.basename)(filePath)}' uploaded to #internal-reports.`
17737
+ `File '${(0, import_node_path12.basename)(filePath)}' uploaded to #internal-reports.`
19171
17738
  ]
19172
17739
  }
19173
17740
  ]
@@ -19184,7 +17751,7 @@ async function handleSessionsSend(options) {
19184
17751
  agent: options.agent
19185
17752
  });
19186
17753
  const built = targets.map((target) => {
19187
- const upload = buildSessionUploadContent((0, import_node_fs12.readFileSync)(target.filePath));
17754
+ const upload = buildSessionUploadContent((0, import_node_fs10.readFileSync)(target.filePath));
19188
17755
  return { ...target, ...upload };
19189
17756
  });
19190
17757
  if (built.some((session) => session.needsChunking)) {
@@ -19248,28 +17815,28 @@ function fallbackViewerAssets() {
19248
17815
  };
19249
17816
  }
19250
17817
  function loadViewerAssets() {
19251
- const cliEntry = process.argv[1]?.trim() ? (0, import_node_path15.resolve)(process.argv[1]) : null;
17818
+ const cliEntry = process.argv[1]?.trim() ? (0, import_node_path12.resolve)(process.argv[1]) : null;
19252
17819
  const candidateRoots2 = [
19253
17820
  ...cliEntry ? [
19254
- (0, import_node_path15.join)((0, import_node_path15.dirname)((0, import_node_path15.dirname)(cliEntry)), "viewer"),
19255
- (0, import_node_path15.join)(
19256
- (0, import_node_path15.dirname)((0, import_node_path15.dirname)((0, import_node_path15.dirname)(cliEntry))),
17821
+ (0, import_node_path12.join)((0, import_node_path12.dirname)((0, import_node_path12.dirname)(cliEntry)), "viewer"),
17822
+ (0, import_node_path12.join)(
17823
+ (0, import_node_path12.dirname)((0, import_node_path12.dirname)((0, import_node_path12.dirname)(cliEntry))),
19257
17824
  "src",
19258
17825
  "lib",
19259
17826
  "cli",
19260
17827
  "viewer"
19261
17828
  )
19262
17829
  ] : [],
19263
- (0, import_node_path15.join)(process.cwd(), "src", "lib", "cli", "viewer")
17830
+ (0, import_node_path12.join)(process.cwd(), "src", "lib", "cli", "viewer")
19264
17831
  ];
19265
17832
  for (const root of candidateRoots2) {
19266
17833
  try {
19267
- const cssPath = (0, import_node_path15.join)(root, "viewer.css");
19268
- const jsPath = (0, import_node_path15.join)(root, "viewer.js");
19269
- if (!(0, import_node_fs12.existsSync)(cssPath) || !(0, import_node_fs12.existsSync)(jsPath)) continue;
17834
+ const cssPath = (0, import_node_path12.join)(root, "viewer.css");
17835
+ const jsPath = (0, import_node_path12.join)(root, "viewer.js");
17836
+ if (!(0, import_node_fs10.existsSync)(cssPath) || !(0, import_node_fs10.existsSync)(jsPath)) continue;
19270
17837
  return {
19271
- css: (0, import_node_fs12.readFileSync)(cssPath, "utf8"),
19272
- js: (0, import_node_fs12.readFileSync)(jsPath, "utf8")
17838
+ css: (0, import_node_fs10.readFileSync)(cssPath, "utf8"),
17839
+ js: (0, import_node_fs10.readFileSync)(jsPath, "utf8")
19273
17840
  };
19274
17841
  } catch {
19275
17842
  continue;
@@ -19293,21 +17860,21 @@ async function handleSessionsRender(options) {
19293
17860
  currentSession: options.currentSession,
19294
17861
  agent: options.agent
19295
17862
  });
19296
- let outputPath = options.output ? (0, import_node_path15.resolve)(options.output) : "";
17863
+ let outputPath = options.output ? (0, import_node_path12.resolve)(options.output) : "";
19297
17864
  if (!outputPath) {
19298
- const outputDir = (0, import_node_path15.join)(process.cwd(), "deepline", "data");
19299
- (0, import_node_fs12.mkdirSync)(outputDir, { recursive: true });
19300
- outputPath = (0, import_node_path15.join)(
17865
+ const outputDir = (0, import_node_path12.join)(process.cwd(), "deepline", "data");
17866
+ (0, import_node_fs10.mkdirSync)(outputDir, { recursive: true });
17867
+ outputPath = (0, import_node_path12.join)(
19301
17868
  outputDir,
19302
17869
  targets.length > 1 ? "session-viewer.html" : `session-${targets[0]?.sessionId}.html`
19303
17870
  );
19304
17871
  } else {
19305
- (0, import_node_fs12.mkdirSync)((0, import_node_path15.dirname)(outputPath), { recursive: true });
17872
+ (0, import_node_fs10.mkdirSync)((0, import_node_path12.dirname)(outputPath), { recursive: true });
19306
17873
  }
19307
17874
  const sessions = targets.map((target) => ({
19308
17875
  label: target.label,
19309
17876
  events: parsePreparedEvents(
19310
- prepareSessionBuffer((0, import_node_fs12.readFileSync)(target.filePath))
17877
+ prepareSessionBuffer((0, import_node_fs10.readFileSync)(target.filePath))
19311
17878
  )
19312
17879
  }));
19313
17880
  const { css, js } = loadViewerAssets();
@@ -19330,7 +17897,7 @@ ${refreshMeta}
19330
17897
  <script>${js}</script>
19331
17898
  </body>
19332
17899
  </html>`;
19333
- (0, import_node_fs12.writeFileSync)(outputPath, html, "utf8");
17900
+ (0, import_node_fs10.writeFileSync)(outputPath, html, "utf8");
19334
17901
  printCommandEnvelope(
19335
17902
  {
19336
17903
  ok: true,
@@ -19748,7 +18315,7 @@ Examples:
19748
18315
 
19749
18316
  // src/cli/commands/quickstart.ts
19750
18317
  var import_node_child_process = require("child_process");
19751
- var import_node_crypto5 = require("crypto");
18318
+ var import_node_crypto3 = require("crypto");
19752
18319
  var import_node_http = require("http");
19753
18320
  var EXIT_OK2 = 0;
19754
18321
  var EXIT_AUTH2 = 1;
@@ -19770,17 +18337,17 @@ function hasClaudeBinary() {
19770
18337
  }
19771
18338
  }
19772
18339
  function launchClaude(prompt) {
19773
- return new Promise((resolve16) => {
18340
+ return new Promise((resolve13) => {
19774
18341
  const child = (0, import_node_child_process.spawn)("claude", [prompt], {
19775
18342
  stdio: "inherit",
19776
18343
  shell: process.platform === "win32"
19777
18344
  });
19778
- child.on("error", () => resolve16(EXIT_SERVER3));
19779
- child.on("close", (status) => resolve16(status ?? EXIT_OK2));
18345
+ child.on("error", () => resolve13(EXIT_SERVER3));
18346
+ child.on("close", (status) => resolve13(status ?? EXIT_OK2));
19780
18347
  });
19781
18348
  }
19782
18349
  function readBody(req) {
19783
- return new Promise((resolve16, reject) => {
18350
+ return new Promise((resolve13, reject) => {
19784
18351
  let raw = "";
19785
18352
  req.setEncoding("utf8");
19786
18353
  req.on("data", (chunk) => {
@@ -19790,7 +18357,7 @@ function readBody(req) {
19790
18357
  req.destroy();
19791
18358
  }
19792
18359
  });
19793
- req.on("end", () => resolve16(raw));
18360
+ req.on("end", () => resolve13(raw));
19794
18361
  req.on("error", reject);
19795
18362
  });
19796
18363
  }
@@ -19845,7 +18412,7 @@ function startCallbackServer(input2) {
19845
18412
  writeJson(res, 400, { error: "Invalid request body." });
19846
18413
  });
19847
18414
  });
19848
- return new Promise((resolve16, reject) => {
18415
+ return new Promise((resolve13, reject) => {
19849
18416
  server.once("error", reject);
19850
18417
  server.listen(0, "127.0.0.1", () => {
19851
18418
  const address = server.address();
@@ -19853,7 +18420,7 @@ function startCallbackServer(input2) {
19853
18420
  reject(new Error("Failed to bind quickstart callback server."));
19854
18421
  return;
19855
18422
  }
19856
- resolve16({ server, port: address.port });
18423
+ resolve13({ server, port: address.port });
19857
18424
  });
19858
18425
  });
19859
18426
  }
@@ -19877,10 +18444,10 @@ async function handleQuickstart(options) {
19877
18444
  return EXIT_AUTH2;
19878
18445
  }
19879
18446
  }
19880
- const state = (0, import_node_crypto5.randomBytes)(32).toString("hex");
18447
+ const state = (0, import_node_crypto3.randomBytes)(32).toString("hex");
19881
18448
  let resolveSelection;
19882
- const selectionPromise = new Promise((resolve16) => {
19883
- resolveSelection = resolve16;
18449
+ const selectionPromise = new Promise((resolve13) => {
18450
+ resolveSelection = resolve13;
19884
18451
  });
19885
18452
  let callback;
19886
18453
  try {
@@ -20014,7 +18581,7 @@ async function readHiddenLine(prompt) {
20014
18581
  if (typeof import_node_process.stdin.setRawMode === "function") import_node_process.stdin.setRawMode(true);
20015
18582
  let value = "";
20016
18583
  import_node_process.stdin.resume();
20017
- return await new Promise((resolve16, reject) => {
18584
+ return await new Promise((resolve13, reject) => {
20018
18585
  let settled = false;
20019
18586
  const cleanup = () => {
20020
18587
  import_node_process.stdin.off("data", onData);
@@ -20029,7 +18596,7 @@ async function readHiddenLine(prompt) {
20029
18596
  settled = true;
20030
18597
  import_node_process.stdout.write("\n");
20031
18598
  cleanup();
20032
- resolve16(line);
18599
+ resolve13(line);
20033
18600
  };
20034
18601
  const fail = (error) => {
20035
18602
  if (settled) return;
@@ -20200,9 +18767,9 @@ Examples:
20200
18767
  }
20201
18768
 
20202
18769
  // src/cli/commands/switch.ts
20203
- var import_node_fs13 = require("fs");
20204
- var import_node_os11 = require("os");
20205
- var import_node_path16 = require("path");
18770
+ var import_node_fs11 = require("fs");
18771
+ var import_node_os9 = require("os");
18772
+ var import_node_path13 = require("path");
20206
18773
  function hostSlugFromBaseUrl(baseUrl) {
20207
18774
  try {
20208
18775
  const url = new URL(baseUrl);
@@ -20222,8 +18789,8 @@ function resolveConfigScope() {
20222
18789
  return hostSlugFromBaseUrl(autoDetectBaseUrl());
20223
18790
  }
20224
18791
  function activeFamilyPath() {
20225
- const home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os11.homedir)();
20226
- return (0, import_node_path16.join)(
18792
+ const home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os9.homedir)();
18793
+ return (0, import_node_path13.join)(
20227
18794
  home,
20228
18795
  ".local",
20229
18796
  "deepline",
@@ -20235,15 +18802,15 @@ function activeFamilyPath() {
20235
18802
  function readActiveFamily() {
20236
18803
  const path = activeFamilyPath();
20237
18804
  try {
20238
- return (0, import_node_fs13.readFileSync)(path, "utf-8").trim() || "sdk";
18805
+ return (0, import_node_fs11.readFileSync)(path, "utf-8").trim() || "sdk";
20239
18806
  } catch {
20240
18807
  return "sdk";
20241
18808
  }
20242
18809
  }
20243
18810
  function writeActiveFamily(family) {
20244
18811
  const path = activeFamilyPath();
20245
- (0, import_node_fs13.mkdirSync)((0, import_node_path16.dirname)(path), { recursive: true });
20246
- (0, import_node_fs13.writeFileSync)(path, `${family}
18812
+ (0, import_node_fs11.mkdirSync)((0, import_node_path13.dirname)(path), { recursive: true });
18813
+ (0, import_node_fs11.writeFileSync)(path, `${family}
20247
18814
  `, "utf-8");
20248
18815
  return path;
20249
18816
  }
@@ -20260,7 +18827,7 @@ function handleSwitch(action, options) {
20260
18827
  ok: true,
20261
18828
  active_family: activeFamily,
20262
18829
  active_family_path: path,
20263
- active_family_file_exists: (0, import_node_fs13.existsSync)(path),
18830
+ active_family_file_exists: (0, import_node_fs11.existsSync)(path),
20264
18831
  render: {
20265
18832
  sections: [
20266
18833
  {
@@ -20360,14 +18927,14 @@ Examples:
20360
18927
 
20361
18928
  // src/cli/commands/tools.ts
20362
18929
  var import_commander2 = require("commander");
20363
- var import_node_fs15 = require("fs");
20364
- var import_node_os13 = require("os");
20365
- var import_node_path18 = require("path");
18930
+ var import_node_fs13 = require("fs");
18931
+ var import_node_os11 = require("os");
18932
+ var import_node_path15 = require("path");
20366
18933
 
20367
18934
  // src/tool-output.ts
20368
- var import_node_fs14 = require("fs");
20369
- var import_node_os12 = require("os");
20370
- var import_node_path17 = require("path");
18935
+ var import_node_fs12 = require("fs");
18936
+ var import_node_os10 = require("os");
18937
+ var import_node_path14 = require("path");
20371
18938
  function isPlainObject(value) {
20372
18939
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
20373
18940
  }
@@ -20463,19 +19030,19 @@ function tryConvertToList(payload, options) {
20463
19030
  return null;
20464
19031
  }
20465
19032
  function ensureOutputDir() {
20466
- const outputDir = (0, import_node_path17.join)((0, import_node_os12.homedir)(), ".local", "share", "deepline", "data");
20467
- (0, import_node_fs14.mkdirSync)(outputDir, { recursive: true });
19033
+ const outputDir = (0, import_node_path14.join)((0, import_node_os10.homedir)(), ".local", "share", "deepline", "data");
19034
+ (0, import_node_fs12.mkdirSync)(outputDir, { recursive: true });
20468
19035
  return outputDir;
20469
19036
  }
20470
19037
  function writeJsonOutputFile(payload, stem) {
20471
19038
  const outputDir = ensureOutputDir();
20472
- const outputPath = (0, import_node_path17.join)(outputDir, `${stem}_${Date.now()}.json`);
20473
- (0, import_node_fs14.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
19039
+ const outputPath = (0, import_node_path14.join)(outputDir, `${stem}_${Date.now()}.json`);
19040
+ (0, import_node_fs12.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
20474
19041
  return outputPath;
20475
19042
  }
20476
19043
  function writeCsvOutputFile(rows, stem) {
20477
19044
  const outputDir = ensureOutputDir();
20478
- const outputPath = (0, import_node_path17.join)(outputDir, `${stem}_${Date.now()}.csv`);
19045
+ const outputPath = (0, import_node_path14.join)(outputDir, `${stem}_${Date.now()}.csv`);
20479
19046
  const seen = /* @__PURE__ */ new Set();
20480
19047
  const columns = [];
20481
19048
  for (const row of rows) {
@@ -20498,7 +19065,7 @@ function writeCsvOutputFile(rows, stem) {
20498
19065
  for (const row of rows) {
20499
19066
  lines.push(columns.map((column) => escapeCell(row[column])).join(","));
20500
19067
  }
20501
- (0, import_node_fs14.writeFileSync)(outputPath, `${lines.join("\n")}
19068
+ (0, import_node_fs12.writeFileSync)(outputPath, `${lines.join("\n")}
20502
19069
  `, "utf-8");
20503
19070
  const previewRows = rows.slice(0, 5);
20504
19071
  const previewColumns = columns.slice(0, 5);
@@ -21552,11 +20119,11 @@ function normalizeOutputFormat(raw) {
21552
20119
  }
21553
20120
  function resolveAtFilePath(rawPath) {
21554
20121
  const trimmed = rawPath.trim();
21555
- const resolved = (0, import_node_path18.resolve)(trimmed);
21556
- if ((0, import_node_fs15.existsSync)(resolved)) return resolved;
20122
+ const resolved = (0, import_node_path15.resolve)(trimmed);
20123
+ if ((0, import_node_fs13.existsSync)(resolved)) return resolved;
21557
20124
  if (process.platform !== "win32" && trimmed.includes("\\")) {
21558
- const normalized = (0, import_node_path18.resolve)(trimmed.replace(/\\/g, "/"));
21559
- if ((0, import_node_fs15.existsSync)(normalized)) return normalized;
20125
+ const normalized = (0, import_node_path15.resolve)(trimmed.replace(/\\/g, "/"));
20126
+ if ((0, import_node_fs13.existsSync)(normalized)) return normalized;
21560
20127
  }
21561
20128
  return resolved;
21562
20129
  }
@@ -21567,7 +20134,7 @@ function readJsonArgument(raw, flagName) {
21567
20134
  throw new Error(`Invalid ${flagName} value: empty @file path.`);
21568
20135
  }
21569
20136
  try {
21570
- return (0, import_node_fs15.readFileSync)(resolveAtFilePath(filePath), "utf8").replace(
20137
+ return (0, import_node_fs13.readFileSync)(resolveAtFilePath(filePath), "utf8").replace(
21571
20138
  /^\uFEFF/,
21572
20139
  ""
21573
20140
  );
@@ -21669,9 +20236,9 @@ function starterScriptJson(script) {
21669
20236
  function seedToolListScript(input2) {
21670
20237
  const stem = safeFileStem(input2.toolId);
21671
20238
  const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
21672
- const scriptDir = (0, import_node_fs15.mkdtempSync)((0, import_node_path18.join)((0, import_node_os13.tmpdir)(), "deepline-workflow-seed-"));
21673
- (0, import_node_fs15.chmodSync)(scriptDir, 448);
21674
- const scriptPath = (0, import_node_path18.join)(scriptDir, fileName);
20239
+ const scriptDir = (0, import_node_fs13.mkdtempSync)((0, import_node_path15.join)((0, import_node_os11.tmpdir)(), "deepline-workflow-seed-"));
20240
+ (0, import_node_fs13.chmodSync)(scriptDir, 448);
20241
+ const scriptPath = (0, import_node_path15.join)(scriptDir, fileName);
21675
20242
  const projectDir = `deepline/projects/${stem}-workflow`;
21676
20243
  const playName = `${stem}-workflow`;
21677
20244
  const sampleRows = input2.rows.length > 0 ? `${JSON.stringify(input2.rows.slice(0, 2)).replace(/\]$/, "")}, ...]` : "[]";
@@ -21707,7 +20274,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
21707
20274
  };
21708
20275
  });
21709
20276
  `;
21710
- (0, import_node_fs15.writeFileSync)(scriptPath, script, { encoding: "utf-8", mode: 384 });
20277
+ (0, import_node_fs13.writeFileSync)(scriptPath, script, { encoding: "utf-8", mode: 384 });
21711
20278
  return {
21712
20279
  path: scriptPath,
21713
20280
  sourceCode: script,
@@ -21971,11 +20538,48 @@ async function executeTool(args) {
21971
20538
  }
21972
20539
 
21973
20540
  // src/cli/commands/workflow.ts
21974
- var import_promises6 = require("fs/promises");
21975
- var import_node_path19 = require("path");
20541
+ var import_promises4 = require("fs/promises");
20542
+ var import_node_path16 = require("path");
20543
+
20544
+ // src/cli/workflow-to-play.ts
20545
+ var import_node_crypto4 = require("crypto");
20546
+
20547
+ // ../shared_libs/plays/secret-guardrails.ts
20548
+ var SECRET_ENV_PATTERN = /\bprocess(?:\.env|\[['"]env['"]\])(?:\.|\[['"])([A-Z0-9_]*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PRIVATE[_-]?KEY|ACCESS[_-]?KEY)[A-Z0-9_]*)(?:['"]\])?/g;
20549
+ var PRIVATE_KEY_PATTERN = /-----BEGIN (?:RSA |EC |OPENSSH |PGP )?PRIVATE KEY-----/;
20550
+ var BEARER_LITERAL_PATTERN = /\bBearer\s+[A-Za-z0-9._~+/=-]{16,}/i;
20551
+ var ASSIGNMENT_SECRET_LITERAL_PATTERN = /\b(?:api[_-]?key|token|secret|password)\b\s*[:=]\s*['"][^'"]{12,}['"]/i;
20552
+ var HIGH_ENTROPY_LITERAL_PATTERN = /['"]([A-Za-z0-9+/=_-]{32,})['"]/g;
20553
+ function shannonEntropy(value) {
20554
+ const counts = /* @__PURE__ */ new Map();
20555
+ for (const char of value) counts.set(char, (counts.get(char) ?? 0) + 1);
20556
+ return [...counts.values()].reduce((entropy, count) => {
20557
+ const p = count / value.length;
20558
+ return entropy - p * Math.log2(p);
20559
+ }, 0);
20560
+ }
20561
+ function collectInlineSecretFindings(sourceCode) {
20562
+ const findings = [];
20563
+ for (const match of sourceCode.matchAll(SECRET_ENV_PATTERN)) {
20564
+ findings.push(`process.env.${match[1]}`);
20565
+ }
20566
+ if (PRIVATE_KEY_PATTERN.test(sourceCode)) findings.push("private key block");
20567
+ if (BEARER_LITERAL_PATTERN.test(sourceCode))
20568
+ findings.push("bearer token literal");
20569
+ if (ASSIGNMENT_SECRET_LITERAL_PATTERN.test(sourceCode)) {
20570
+ findings.push("secret-looking assignment literal");
20571
+ }
20572
+ for (const match of sourceCode.matchAll(HIGH_ENTROPY_LITERAL_PATTERN)) {
20573
+ const literal = match[1] ?? "";
20574
+ if (literal.length >= 40 && shannonEntropy(literal) >= 4.2) {
20575
+ findings.push("high-entropy string literal");
20576
+ break;
20577
+ }
20578
+ }
20579
+ return [...new Set(findings)];
20580
+ }
21976
20581
 
21977
20582
  // src/cli/workflow-to-play.ts
21978
- var import_node_crypto6 = require("crypto");
21979
20583
  var HITL_WAIT_FOR_SIGNAL_TOOL = "deepline_workflow_wait_for_signal";
21980
20584
  var HITL_SLACK_TOOL = "slack_message_with_hitl";
21981
20585
  var SUB_WORKFLOW_TOOL_PREFIX = "deepline_workflow_";
@@ -22081,7 +20685,7 @@ function sanitizePlayNameSegment(value) {
22081
20685
  }
22082
20686
  function deriveWorkflowPlayName(workflowName) {
22083
20687
  const base = sanitizePlayNameSegment(workflowName) || "workflow";
22084
- const suffix = (0, import_node_crypto6.createHash)("sha256").update(workflowName).digest("hex").slice(0, 8);
20688
+ const suffix = (0, import_node_crypto4.createHash)("sha256").update(workflowName).digest("hex").slice(0, 8);
22085
20689
  const reserved = suffix.length + 1;
22086
20690
  const allowedBase = Math.max(1, MAX_PLAY_NAME_LENGTH - reserved);
22087
20691
  let name = `${base.slice(0, allowedBase)}_${suffix}`;
@@ -22179,7 +20783,7 @@ function readStatus(payload) {
22179
20783
  }
22180
20784
  async function readJsonOption(payload, file) {
22181
20785
  if (file) {
22182
- const raw = await (0, import_promises6.readFile)((0, import_node_path19.resolve)(file), "utf8");
20786
+ const raw = await (0, import_promises4.readFile)((0, import_node_path16.resolve)(file), "utf8");
22183
20787
  return JSON.parse(raw);
22184
20788
  }
22185
20789
  if (payload) {
@@ -22213,9 +20817,9 @@ async function transformOne(api, workflowId, outDir, publish) {
22213
20817
  revision.config,
22214
20818
  { workflowName: workflow.name, version: revision.version }
22215
20819
  );
22216
- const file = (0, import_node_path19.join)((0, import_node_path19.resolve)(outDir), `${compiled.playName}.play.ts`);
22217
- await (0, import_promises6.mkdir)((0, import_node_path19.dirname)(file), { recursive: true });
22218
- await (0, import_promises6.writeFile)(file, compiled.sourceCode, "utf8");
20820
+ const file = (0, import_node_path16.join)((0, import_node_path16.resolve)(outDir), `${compiled.playName}.play.ts`);
20821
+ await (0, import_promises4.mkdir)((0, import_node_path16.dirname)(file), { recursive: true });
20822
+ await (0, import_promises4.writeFile)(file, compiled.sourceCode, "utf8");
22219
20823
  let published = false;
22220
20824
  if (publish) {
22221
20825
  const code = await handlePlayPublish([file]);
@@ -22461,9 +21065,9 @@ Notes:
22461
21065
 
22462
21066
  // src/cli/commands/update.ts
22463
21067
  var import_node_child_process2 = require("child_process");
22464
- var import_node_fs16 = require("fs");
22465
- var import_node_os14 = require("os");
22466
- var import_node_path20 = require("path");
21068
+ var import_node_fs14 = require("fs");
21069
+ var import_node_os12 = require("os");
21070
+ var import_node_path17 = require("path");
22467
21071
  function posixShellQuote(value) {
22468
21072
  return `'${value.replace(/'/g, `'\\''`)}'`;
22469
21073
  }
@@ -22486,11 +21090,11 @@ function sidecarStateDir(input2) {
22486
21090
  if (!scope || scope.includes("/") || scope.includes("\\")) {
22487
21091
  return null;
22488
21092
  }
22489
- return (0, import_node_path20.join)(input2.homeDir, ".local", "deepline", scope, "sdk-cli");
21093
+ return (0, import_node_path17.join)(input2.homeDir, ".local", "deepline", scope, "sdk-cli");
22490
21094
  }
22491
21095
  function readOptionalText(path) {
22492
21096
  try {
22493
- return (0, import_node_fs16.readFileSync)(path, "utf8").trim();
21097
+ return (0, import_node_fs14.readFileSync)(path, "utf8").trim();
22494
21098
  } catch {
22495
21099
  return "";
22496
21100
  }
@@ -22498,26 +21102,26 @@ function readOptionalText(path) {
22498
21102
  function resolvePythonSidecarUpdatePlan(options) {
22499
21103
  const stateDir = sidecarStateDir(options);
22500
21104
  if (!stateDir) return null;
22501
- const relativeEntrypoint = (0, import_node_path20.relative)(
22502
- (0, import_node_path20.resolve)(stateDir),
22503
- (0, import_node_path20.resolve)(options.entrypoint)
21105
+ const relativeEntrypoint = (0, import_node_path17.relative)(
21106
+ (0, import_node_path17.resolve)(stateDir),
21107
+ (0, import_node_path17.resolve)(options.entrypoint)
22504
21108
  );
22505
- if (!relativeEntrypoint || relativeEntrypoint.startsWith("..") || (0, import_node_path20.isAbsolute)(relativeEntrypoint)) {
21109
+ if (!relativeEntrypoint || relativeEntrypoint.startsWith("..") || (0, import_node_path17.isAbsolute)(relativeEntrypoint)) {
22506
21110
  return null;
22507
21111
  }
22508
- const installMethod = readOptionalText((0, import_node_path20.join)(stateDir, ".install-method"));
21112
+ const installMethod = readOptionalText((0, import_node_path17.join)(stateDir, ".install-method"));
22509
21113
  if (installMethod !== "python-sidecar") return null;
22510
21114
  const scope = options.env.DEEPLINE_CONFIG_SCOPE?.trim() || "";
22511
21115
  const hostUrl = options.env.DEEPLINE_HOST_URL?.trim() || "";
22512
- const nodeBin = readOptionalText((0, import_node_path20.join)(stateDir, ".node-bin")) || process.execPath;
22513
- const sidecarPath = readOptionalText((0, import_node_path20.join)(stateDir, ".command-path")) || (0, import_node_path20.join)(
21116
+ const nodeBin = readOptionalText((0, import_node_path17.join)(stateDir, ".node-bin")) || process.execPath;
21117
+ const sidecarPath = readOptionalText((0, import_node_path17.join)(stateDir, ".command-path")) || (0, import_node_path17.join)(
22514
21118
  stateDir,
22515
21119
  "bin",
22516
21120
  process.platform === "win32" ? "deepline-sdk.cmd" : "deepline-sdk"
22517
21121
  );
22518
21122
  const packageSpec = options.packageSpec || "deepline@latest";
22519
21123
  const npmCommand = "npm";
22520
- const manualCommand = `${npmCommand} install --prefix ${shellQuote3((0, import_node_path20.join)(stateDir, "versions", "<version>"))} --no-audit --no-fund ${shellQuote3(packageSpec)}`;
21124
+ const manualCommand = `${npmCommand} install --prefix ${shellQuote3((0, import_node_path17.join)(stateDir, "versions", "<version>"))} --no-audit --no-fund ${shellQuote3(packageSpec)}`;
22521
21125
  return {
22522
21126
  kind: "python-sidecar",
22523
21127
  stateDir,
@@ -22531,21 +21135,21 @@ function resolvePythonSidecarUpdatePlan(options) {
22531
21135
  };
22532
21136
  }
22533
21137
  function findRepoBackedSdkRoot(startPath) {
22534
- let current = (0, import_node_path20.resolve)(startPath);
21138
+ let current = (0, import_node_path17.resolve)(startPath);
22535
21139
  while (true) {
22536
- if ((0, import_node_fs16.existsSync)((0, import_node_path20.join)(current, "sdk", "package.json")) && (0, import_node_fs16.existsSync)((0, import_node_path20.join)(current, "sdk", "bin", "deepline-dev.ts"))) {
21140
+ if ((0, import_node_fs14.existsSync)((0, import_node_path17.join)(current, "sdk", "package.json")) && (0, import_node_fs14.existsSync)((0, import_node_path17.join)(current, "sdk", "bin", "deepline-dev.ts"))) {
22537
21141
  return current;
22538
21142
  }
22539
- const parent = (0, import_node_path20.dirname)(current);
21143
+ const parent = (0, import_node_path17.dirname)(current);
22540
21144
  if (parent === current) return null;
22541
21145
  current = parent;
22542
21146
  }
22543
21147
  }
22544
21148
  function resolveUpdatePlan(options = {}) {
22545
21149
  const env = options.env ?? process.env;
22546
- const homeDir2 = options.homeDir ?? (0, import_node_os14.homedir)();
22547
- const entrypoint = options.entrypoint ?? (process.argv[1] ? (0, import_node_path20.resolve)(process.argv[1]) : "");
22548
- const sourceRoot = entrypoint ? findRepoBackedSdkRoot((0, import_node_path20.dirname)(entrypoint)) : null;
21150
+ const homeDir2 = options.homeDir ?? (0, import_node_os12.homedir)();
21151
+ const entrypoint = options.entrypoint ?? (process.argv[1] ? (0, import_node_path17.resolve)(process.argv[1]) : "");
21152
+ const sourceRoot = entrypoint ? findRepoBackedSdkRoot((0, import_node_path17.dirname)(entrypoint)) : null;
22549
21153
  if (sourceRoot) {
22550
21154
  return {
22551
21155
  kind: "source",
@@ -22575,7 +21179,7 @@ function safeVersionSegment(value) {
22575
21179
  return /^[0-9A-Za-z._-]+$/.test(normalized) ? normalized : "";
22576
21180
  }
22577
21181
  function entryPathInVersionDir(versionDir) {
22578
- return (0, import_node_path20.join)(
21182
+ return (0, import_node_path17.join)(
22579
21183
  versionDir,
22580
21184
  "node_modules",
22581
21185
  "deepline",
@@ -22585,14 +21189,14 @@ function entryPathInVersionDir(versionDir) {
22585
21189
  );
22586
21190
  }
22587
21191
  function installedPackageVersion(versionDir) {
22588
- const packageJsonPath = (0, import_node_path20.join)(
21192
+ const packageJsonPath = (0, import_node_path17.join)(
22589
21193
  versionDir,
22590
21194
  "node_modules",
22591
21195
  "deepline",
22592
21196
  "package.json"
22593
21197
  );
22594
21198
  try {
22595
- const parsed = JSON.parse((0, import_node_fs16.readFileSync)(packageJsonPath, "utf8"));
21199
+ const parsed = JSON.parse((0, import_node_fs14.readFileSync)(packageJsonPath, "utf8"));
22596
21200
  return typeof parsed.version === "string" ? safeVersionSegment(parsed.version) : "";
22597
21201
  } catch {
22598
21202
  return "";
@@ -22616,9 +21220,9 @@ function runCommand(command, args, env = process.env) {
22616
21220
  });
22617
21221
  }
22618
21222
  function writeSidecarLauncher(input2) {
22619
- (0, import_node_fs16.mkdirSync)((0, import_node_path20.dirname)(input2.path), { recursive: true });
21223
+ (0, import_node_fs14.mkdirSync)((0, import_node_path17.dirname)(input2.path), { recursive: true });
22620
21224
  if (process.platform === "win32") {
22621
- (0, import_node_fs16.writeFileSync)(
21225
+ (0, import_node_fs14.writeFileSync)(
22622
21226
  input2.path,
22623
21227
  [
22624
21228
  `@set DEEPLINE_HOST_URL=${input2.hostUrl.replace(/\r?\n/g, "")}`,
@@ -22630,7 +21234,7 @@ function writeSidecarLauncher(input2) {
22630
21234
  );
22631
21235
  return;
22632
21236
  }
22633
- (0, import_node_fs16.writeFileSync)(
21237
+ (0, import_node_fs14.writeFileSync)(
22634
21238
  input2.path,
22635
21239
  [
22636
21240
  "#!/usr/bin/env sh",
@@ -22643,17 +21247,17 @@ function writeSidecarLauncher(input2) {
22643
21247
  );
22644
21248
  }
22645
21249
  async function runPythonSidecarUpdatePlan(plan) {
22646
- const versionsDir = (0, import_node_path20.join)(plan.stateDir, "versions");
22647
- const tempDir = (0, import_node_path20.join)(
21250
+ const versionsDir = (0, import_node_path17.join)(plan.stateDir, "versions");
21251
+ const tempDir = (0, import_node_path17.join)(
22648
21252
  versionsDir,
22649
21253
  `.tmp-sdk-update-${process.pid}-${Date.now()}`
22650
21254
  );
22651
- (0, import_node_fs16.rmSync)(tempDir, { recursive: true, force: true });
22652
- (0, import_node_fs16.mkdirSync)(tempDir, { recursive: true });
22653
- (0, import_node_fs16.writeFileSync)((0, import_node_path20.join)(tempDir, "package.json"), '{"private":true}\n', "utf8");
21255
+ (0, import_node_fs14.rmSync)(tempDir, { recursive: true, force: true });
21256
+ (0, import_node_fs14.mkdirSync)(tempDir, { recursive: true });
21257
+ (0, import_node_fs14.writeFileSync)((0, import_node_path17.join)(tempDir, "package.json"), '{"private":true}\n', "utf8");
22654
21258
  const env = {
22655
21259
  ...process.env,
22656
- PATH: `${(0, import_node_path20.dirname)(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
21260
+ PATH: `${(0, import_node_path17.dirname)(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
22657
21261
  };
22658
21262
  const installExitCode = await runCommand(
22659
21263
  plan.npmCommand,
@@ -22668,7 +21272,7 @@ async function runPythonSidecarUpdatePlan(plan) {
22668
21272
  env
22669
21273
  );
22670
21274
  if (installExitCode !== 0) {
22671
- (0, import_node_fs16.rmSync)(tempDir, { recursive: true, force: true });
21275
+ (0, import_node_fs14.rmSync)(tempDir, { recursive: true, force: true });
22672
21276
  return installExitCode;
22673
21277
  }
22674
21278
  const installedVersion = installedPackageVersion(tempDir);
@@ -22676,19 +21280,19 @@ async function runPythonSidecarUpdatePlan(plan) {
22676
21280
  process.stderr.write(
22677
21281
  "Updated Deepline SDK package did not report a version.\n"
22678
21282
  );
22679
- (0, import_node_fs16.rmSync)(tempDir, { recursive: true, force: true });
21283
+ (0, import_node_fs14.rmSync)(tempDir, { recursive: true, force: true });
22680
21284
  return 1;
22681
21285
  }
22682
- const finalDir = (0, import_node_path20.join)(versionsDir, installedVersion);
21286
+ const finalDir = (0, import_node_path17.join)(versionsDir, installedVersion);
22683
21287
  const finalEntryPath = entryPathInVersionDir(finalDir);
22684
- if ((0, import_node_fs16.existsSync)(finalEntryPath)) {
22685
- (0, import_node_fs16.rmSync)(tempDir, { recursive: true, force: true });
21288
+ if ((0, import_node_fs14.existsSync)(finalEntryPath)) {
21289
+ (0, import_node_fs14.rmSync)(tempDir, { recursive: true, force: true });
22686
21290
  } else {
22687
- (0, import_node_fs16.rmSync)(finalDir, { recursive: true, force: true });
21291
+ (0, import_node_fs14.rmSync)(finalDir, { recursive: true, force: true });
22688
21292
  try {
22689
- (0, import_node_fs16.renameSync)(tempDir, finalDir);
21293
+ (0, import_node_fs14.renameSync)(tempDir, finalDir);
22690
21294
  } catch (error) {
22691
- (0, import_node_fs16.rmSync)(tempDir, { recursive: true, force: true });
21295
+ (0, import_node_fs14.rmSync)(tempDir, { recursive: true, force: true });
22692
21296
  process.stderr.write(
22693
21297
  `Failed to publish Deepline SDK sidecar update: ${error.message}
22694
21298
  `
@@ -22696,7 +21300,7 @@ async function runPythonSidecarUpdatePlan(plan) {
22696
21300
  return 1;
22697
21301
  }
22698
21302
  }
22699
- if (!(0, import_node_fs16.existsSync)(finalEntryPath)) {
21303
+ if (!(0, import_node_fs14.existsSync)(finalEntryPath)) {
22700
21304
  process.stderr.write(
22701
21305
  `Updated Deepline SDK CLI entrypoint missing: ${finalEntryPath}
22702
21306
  `
@@ -22710,28 +21314,28 @@ async function runPythonSidecarUpdatePlan(plan) {
22710
21314
  nodeBin: plan.nodeBin,
22711
21315
  entryPath: finalEntryPath
22712
21316
  });
22713
- (0, import_node_fs16.writeFileSync)(
22714
- (0, import_node_path20.join)(plan.stateDir, ".version"),
21317
+ (0, import_node_fs14.writeFileSync)(
21318
+ (0, import_node_path17.join)(plan.stateDir, ".version"),
22715
21319
  `${installedVersion}
22716
21320
  `,
22717
21321
  "utf8"
22718
21322
  );
22719
- (0, import_node_fs16.writeFileSync)(
22720
- (0, import_node_path20.join)(plan.stateDir, ".install-method"),
21323
+ (0, import_node_fs14.writeFileSync)(
21324
+ (0, import_node_path17.join)(plan.stateDir, ".install-method"),
22721
21325
  "python-sidecar\n",
22722
21326
  "utf8"
22723
21327
  );
22724
- (0, import_node_fs16.writeFileSync)(
22725
- (0, import_node_path20.join)(plan.stateDir, ".command-path"),
21328
+ (0, import_node_fs14.writeFileSync)(
21329
+ (0, import_node_path17.join)(plan.stateDir, ".command-path"),
22726
21330
  `${plan.sidecarPath}
22727
21331
  `,
22728
21332
  "utf8"
22729
21333
  );
22730
- (0, import_node_fs16.writeFileSync)((0, import_node_path20.join)(plan.stateDir, ".runner"), "node\n", "utf8");
22731
- (0, import_node_fs16.writeFileSync)((0, import_node_path20.join)(plan.stateDir, ".node-bin"), `${plan.nodeBin}
21334
+ (0, import_node_fs14.writeFileSync)((0, import_node_path17.join)(plan.stateDir, ".runner"), "node\n", "utf8");
21335
+ (0, import_node_fs14.writeFileSync)((0, import_node_path17.join)(plan.stateDir, ".node-bin"), `${plan.nodeBin}
22732
21336
  `, "utf8");
22733
- (0, import_node_fs16.writeFileSync)(
22734
- (0, import_node_path20.join)(plan.stateDir, ".entry-path"),
21337
+ (0, import_node_fs14.writeFileSync)(
21338
+ (0, import_node_path17.join)(plan.stateDir, ".entry-path"),
22735
21339
  `${finalEntryPath}
22736
21340
  `,
22737
21341
  "utf8"
@@ -23018,7 +21622,7 @@ function shouldSkipSelfUpdate() {
23018
21622
  return envTruthy("DEEPLINE_SKIP_SELF_UPDATE") || envTruthy("DEEPLINE_NO_AUTO_UPDATE") || envTruthy("DEEPLINE_SKIP_SDK_AUTO_UPDATE") || envTruthy("DEEPLINE_DISABLE_AUTO_UPDATE") || isCi();
23019
21623
  }
23020
21624
  function relaunchCurrentCommand(plan) {
23021
- return new Promise((resolve16) => {
21625
+ return new Promise((resolve13) => {
23022
21626
  const command = plan.kind === "python-sidecar" ? plan.sidecarPath : process.execPath;
23023
21627
  const args = plan.kind === "python-sidecar" ? process.argv.slice(2) : process.argv.slice(1);
23024
21628
  const child = (0, import_node_child_process3.spawn)(command, args, {
@@ -23034,9 +21638,9 @@ function relaunchCurrentCommand(plan) {
23034
21638
  `Deepline SDK/CLI updated, but relaunch failed: ${error.message}
23035
21639
  `
23036
21640
  );
23037
- resolve16(1);
21641
+ resolve13(1);
23038
21642
  });
23039
- child.on("close", (code) => resolve16(code ?? 1));
21643
+ child.on("close", (code) => resolve13(code ?? 1));
23040
21644
  });
23041
21645
  }
23042
21646
  async function maybeAutoUpdateAndRelaunch(response) {
@@ -23075,9 +21679,9 @@ async function maybeAutoUpdateAndRelaunch(response) {
23075
21679
 
23076
21680
  // src/cli/skills-sync.ts
23077
21681
  var import_node_child_process4 = require("child_process");
23078
- var import_node_fs17 = require("fs");
23079
- var import_node_os15 = require("os");
23080
- var import_node_path21 = require("path");
21682
+ var import_node_fs15 = require("fs");
21683
+ var import_node_os13 = require("os");
21684
+ var import_node_path18 = require("path");
23081
21685
  var CHECK_TIMEOUT_MS2 = 3e3;
23082
21686
  var SDK_PLAY_SKILL_NAME = "deepline-plays";
23083
21687
  var attemptedSync = false;
@@ -23091,20 +21695,20 @@ function activePluginSkillsDir() {
23091
21695
  return "";
23092
21696
  }
23093
21697
  const dir = process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim() ?? "";
23094
- return dir && (0, import_node_fs17.existsSync)(dir) ? dir : "";
21698
+ return dir && (0, import_node_fs15.existsSync)(dir) ? dir : "";
23095
21699
  }
23096
21700
  function readPluginSkillsVersion() {
23097
21701
  const dir = activePluginSkillsDir();
23098
21702
  if (!dir) return "";
23099
21703
  try {
23100
- return (0, import_node_fs17.readFileSync)((0, import_node_path21.join)(dir, ".version"), "utf-8").trim();
21704
+ return (0, import_node_fs15.readFileSync)((0, import_node_path18.join)(dir, ".version"), "utf-8").trim();
23101
21705
  } catch {
23102
21706
  return "";
23103
21707
  }
23104
21708
  }
23105
21709
  function sdkSkillsVersionPath(baseUrl) {
23106
- const home = process.env.HOME?.trim() || (0, import_node_os15.homedir)();
23107
- return (0, import_node_path21.join)(
21710
+ const home = process.env.HOME?.trim() || (0, import_node_os13.homedir)();
21711
+ return (0, import_node_path18.join)(
23108
21712
  home,
23109
21713
  ".local",
23110
21714
  "deepline",
@@ -23117,17 +21721,17 @@ function readLocalSkillsVersion(baseUrl) {
23117
21721
  const pluginVersion = readPluginSkillsVersion();
23118
21722
  if (pluginVersion) return pluginVersion;
23119
21723
  const path = sdkSkillsVersionPath(baseUrl);
23120
- if (!(0, import_node_fs17.existsSync)(path)) return "";
21724
+ if (!(0, import_node_fs15.existsSync)(path)) return "";
23121
21725
  try {
23122
- return (0, import_node_fs17.readFileSync)(path, "utf-8").trim();
21726
+ return (0, import_node_fs15.readFileSync)(path, "utf-8").trim();
23123
21727
  } catch {
23124
21728
  return "";
23125
21729
  }
23126
21730
  }
23127
21731
  function writeLocalSkillsVersion(baseUrl, version) {
23128
21732
  const path = sdkSkillsVersionPath(baseUrl);
23129
- (0, import_node_fs17.mkdirSync)((0, import_node_path21.dirname)(path), { recursive: true });
23130
- (0, import_node_fs17.writeFileSync)(path, `${version}
21733
+ (0, import_node_fs15.mkdirSync)((0, import_node_path18.dirname)(path), { recursive: true });
21734
+ (0, import_node_fs15.writeFileSync)(path, `${version}
23131
21735
  `, "utf-8");
23132
21736
  }
23133
21737
  function sortedUniqueSkillNames(names) {
@@ -23225,7 +21829,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
23225
21829
  return [npxInstall];
23226
21830
  }
23227
21831
  function runOneSkillsInstall(install) {
23228
- return new Promise((resolve16) => {
21832
+ return new Promise((resolve13) => {
23229
21833
  const child = (0, import_node_child_process4.spawn)(install.command, install.args, {
23230
21834
  stdio: ["ignore", "ignore", "pipe"],
23231
21835
  env: process.env
@@ -23235,7 +21839,7 @@ function runOneSkillsInstall(install) {
23235
21839
  stderr += chunk.toString("utf-8");
23236
21840
  });
23237
21841
  child.on("error", (error) => {
23238
- resolve16({
21842
+ resolve13({
23239
21843
  ok: false,
23240
21844
  detail: `failed to start ${install.command}: ${error.message}`,
23241
21845
  manualCommand: install.manualCommand
@@ -23243,11 +21847,11 @@ function runOneSkillsInstall(install) {
23243
21847
  });
23244
21848
  child.on("close", (code) => {
23245
21849
  if (code === 0) {
23246
- resolve16({ ok: true, detail: "", manualCommand: install.manualCommand });
21850
+ resolve13({ ok: true, detail: "", manualCommand: install.manualCommand });
23247
21851
  return;
23248
21852
  }
23249
21853
  const detail = stderr.trim();
23250
- resolve16({
21854
+ resolve13({
23251
21855
  ok: false,
23252
21856
  detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
23253
21857
  manualCommand: install.manualCommand
@@ -23306,7 +21910,7 @@ async function syncSdkSkillsIfNeeded(baseUrl) {
23306
21910
  }
23307
21911
 
23308
21912
  // src/cli/failure-reporting.ts
23309
- var import_node_os16 = require("os");
21913
+ var import_node_os14 = require("os");
23310
21914
  var FAILURE_REPORT_DISABLE_ENV = "DEEPLINE_DISABLE_FAILURE_REPORTING";
23311
21915
  var REPORT_FAILURE_TIMEOUT_MS = 1e4;
23312
21916
  var MAX_FAILURE_TEXT_CHARS = 4e3;
@@ -23408,12 +22012,12 @@ function isNetworkFailure(error) {
23408
22012
  }
23409
22013
  function buildEnvironmentContext() {
23410
22014
  const context = {
23411
- os: (0, import_node_os16.platform)(),
23412
- os_release: (0, import_node_os16.release)(),
23413
- platform: `${(0, import_node_os16.platform)()}-${(0, import_node_os16.release)()}-${process.arch}`,
22015
+ os: (0, import_node_os14.platform)(),
22016
+ os_release: (0, import_node_os14.release)(),
22017
+ platform: `${(0, import_node_os14.platform)()}-${(0, import_node_os14.release)()}-${process.arch}`,
23414
22018
  node_version: process.version,
23415
22019
  runtime: "Node.js",
23416
- hostname: (0, import_node_os16.hostname)(),
22020
+ hostname: (0, import_node_os14.hostname)(),
23417
22021
  agent_runtime: detectAgentRuntime()
23418
22022
  };
23419
22023
  for (const key of ["CLAUDE_CODE_REMOTE", "DEEPLINE_PLUGIN_MODE"]) {
@@ -23593,10 +22197,10 @@ function topLevelCommandKnown(program, commandName) {
23593
22197
  );
23594
22198
  }
23595
22199
  async function runPlayRunnerHealthCheck() {
23596
- const dir = await (0, import_promises7.mkdtemp)((0, import_node_path22.join)((0, import_node_os17.tmpdir)(), "deepline-health-play-"));
23597
- const file = (0, import_node_path22.join)(dir, "health-check.play.ts");
22200
+ const dir = await (0, import_promises5.mkdtemp)((0, import_node_path19.join)((0, import_node_os15.tmpdir)(), "deepline-health-play-"));
22201
+ const file = (0, import_node_path19.join)(dir, "health-check.play.ts");
23598
22202
  try {
23599
- await (0, import_promises7.writeFile)(
22203
+ await (0, import_promises5.writeFile)(
23600
22204
  file,
23601
22205
  [
23602
22206
  "import { definePlay } from 'deepline';",
@@ -23644,7 +22248,7 @@ async function runPlayRunnerHealthCheck() {
23644
22248
  }
23645
22249
  };
23646
22250
  } finally {
23647
- await (0, import_promises7.rm)(dir, { recursive: true, force: true });
22251
+ await (0, import_promises5.rm)(dir, { recursive: true, force: true });
23648
22252
  }
23649
22253
  }
23650
22254
  function pickString(value, ...keys) {