deepline 0.1.182 → 0.1.184

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 (69) hide show
  1. package/dist/bundling-sources/apps/play-runner-workers/src/child-play-await.ts +203 -6
  2. package/dist/bundling-sources/apps/play-runner-workers/src/child-play-submit.ts +8 -1
  3. package/dist/bundling-sources/apps/play-runner-workers/src/coordinator-entry.ts +639 -109
  4. package/dist/bundling-sources/apps/play-runner-workers/src/dedup-do.ts +3 -2
  5. package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +1752 -1899
  6. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/harness-receipt-store.ts +116 -0
  7. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/map-chunk-plan.ts +542 -78
  8. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/receipts.ts +292 -11
  9. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/run-work-dispatcher.ts +519 -0
  10. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-dispatch.ts +2381 -0
  11. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-receipts.ts +18 -5
  12. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/work-budget.ts +130 -0
  13. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/worker-platform-budget.ts +39 -0
  14. package/dist/bundling-sources/apps/play-runner-workers/src/workflow-retry-state.ts +2 -0
  15. package/dist/bundling-sources/sdk/src/client.ts +41 -0
  16. package/dist/bundling-sources/sdk/src/http.ts +23 -8
  17. package/dist/bundling-sources/sdk/src/plays/harness-stub.ts +56 -3
  18. package/dist/bundling-sources/sdk/src/release.ts +2 -2
  19. package/dist/bundling-sources/sdk/src/types.ts +2 -0
  20. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +133 -10
  21. package/dist/bundling-sources/shared_libs/play-runtime/auth-scope-resolver.ts +92 -0
  22. package/dist/bundling-sources/shared_libs/play-runtime/batch-runtime.ts +4 -4
  23. package/dist/bundling-sources/shared_libs/play-runtime/batching-types.ts +8 -0
  24. package/dist/bundling-sources/shared_libs/play-runtime/child-run-id.ts +101 -0
  25. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +1612 -287
  26. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +105 -6
  27. package/dist/bundling-sources/shared_libs/play-runtime/dedup-backend.ts +0 -0
  28. package/dist/bundling-sources/shared_libs/play-runtime/default-batch-strategies.ts +1 -0
  29. package/dist/bundling-sources/shared_libs/play-runtime/durability-store.ts +4 -0
  30. package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +116 -16
  31. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +186 -20
  32. package/dist/bundling-sources/shared_libs/play-runtime/dynamic-worker-version.ts +2 -0
  33. package/dist/bundling-sources/shared_libs/play-runtime/execution-ledger-store.ts +133 -0
  34. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +245 -0
  35. package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +5 -5
  36. package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +14 -0
  37. package/dist/bundling-sources/shared_libs/play-runtime/lease-policy.ts +52 -0
  38. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +41 -0
  39. package/dist/bundling-sources/shared_libs/play-runtime/providers.ts +3 -2
  40. package/dist/bundling-sources/shared_libs/play-runtime/receipt-sql.ts +124 -0
  41. package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +6 -2
  42. package/dist/bundling-sources/shared_libs/play-runtime/row-isolation.ts +48 -2
  43. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +158 -15
  44. package/dist/bundling-sources/shared_libs/play-runtime/run-terminal-source.ts +45 -0
  45. package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +9 -0
  46. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api-paths.ts +21 -0
  47. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +2038 -262
  48. package/dist/bundling-sources/shared_libs/play-runtime/runtime-contract.ts +42 -0
  49. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-attempt-state-machine.ts +183 -0
  50. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-errors.ts +88 -0
  51. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +8 -1
  52. package/dist/bundling-sources/shared_libs/play-runtime/sheet-attempt-sql.ts +103 -0
  53. package/dist/bundling-sources/shared_libs/play-runtime/suspension.ts +19 -1
  54. package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +343 -0
  55. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +43 -0
  56. package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +11 -0
  57. package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-state-machine.ts +437 -0
  58. package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +83 -6
  59. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +28 -11
  60. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +38 -6
  61. package/dist/bundling-sources/shared_libs/security/safe-outbound-fetch.ts +24 -17
  62. package/dist/cli/index.js +76 -17
  63. package/dist/cli/index.mjs +76 -17
  64. package/dist/index.d.mts +2 -0
  65. package/dist/index.d.ts +2 -0
  66. package/dist/index.js +63 -9
  67. package/dist/index.mjs +63 -9
  68. package/dist/plays/bundle-play-file.mjs +20 -6
  69. package/package.json +1 -1
@@ -1022,8 +1022,13 @@ export function compileSheetContract(pipeline: PlayStaticPipeline): {
1022
1022
  contract: PlaySheetContract | null;
1023
1023
  errors: string[];
1024
1024
  } {
1025
- const errors = [...(pipeline.sheetContractErrors ?? [])];
1026
- const tableNamespace = pipeline.tableNamespace?.trim();
1025
+ const errors = Array.isArray(pipeline.sheetContractErrors)
1026
+ ? [...pipeline.sheetContractErrors]
1027
+ : [];
1028
+ const tableNamespace =
1029
+ typeof pipeline.tableNamespace === 'string'
1030
+ ? pipeline.tableNamespace.trim()
1031
+ : '';
1027
1032
  if (!tableNamespace) {
1028
1033
  return {
1029
1034
  contract: null,
@@ -1032,6 +1037,34 @@ export function compileSheetContract(pipeline: PlayStaticPipeline): {
1032
1037
  }
1033
1038
 
1034
1039
  const columns: PlaySheetColumnContract[] = [];
1040
+ const inputFields = Array.isArray(pipeline.inputFields)
1041
+ ? pipeline.inputFields.filter((field): field is string => {
1042
+ if (typeof field === 'string') return true;
1043
+ errors.push('Sheet contract ignored a non-string input field.');
1044
+ return false;
1045
+ })
1046
+ : [];
1047
+ const rowKeyFields = Array.isArray(pipeline.rowKeyFields)
1048
+ ? pipeline.rowKeyFields.filter((field): field is string => {
1049
+ if (typeof field === 'string') return true;
1050
+ errors.push('Sheet contract ignored a non-string row key field.');
1051
+ return false;
1052
+ })
1053
+ : [];
1054
+ const fields = Array.isArray(pipeline.fields)
1055
+ ? pipeline.fields.filter((field): field is string => {
1056
+ if (typeof field === 'string') return true;
1057
+ errors.push('Sheet contract ignored a non-string output field.');
1058
+ return false;
1059
+ })
1060
+ : [];
1061
+ const substeps = Array.isArray(pipeline.substeps) ? pipeline.substeps : [];
1062
+ if (!Array.isArray(pipeline.fields)) {
1063
+ errors.push('Sheet contract could not read static output fields.');
1064
+ }
1065
+ if (!Array.isArray(pipeline.substeps)) {
1066
+ errors.push('Sheet contract could not read static substeps.');
1067
+ }
1035
1068
 
1036
1069
  const addColumn = (column: Omit<PlaySheetColumnContract, 'sqlName'>) => {
1037
1070
  if (!column.id.trim()) {
@@ -1052,8 +1085,7 @@ export function compileSheetContract(pipeline: PlayStaticPipeline): {
1052
1085
  });
1053
1086
  };
1054
1087
 
1055
- const inputFields = pipeline.inputFields?.length ? pipeline.inputFields : [];
1056
- const rowKeyFieldSet = new Set(pipeline.rowKeyFields ?? []);
1088
+ const rowKeyFieldSet = new Set(rowKeyFields);
1057
1089
  for (const inputField of inputFields) {
1058
1090
  addColumn({
1059
1091
  id: inputField,
@@ -1063,7 +1095,7 @@ export function compileSheetContract(pipeline: PlayStaticPipeline): {
1063
1095
  });
1064
1096
  }
1065
1097
 
1066
- for (const field of pipeline.fields) {
1098
+ for (const field of fields) {
1067
1099
  addColumn({ id: field, source: 'datasetColumn', field });
1068
1100
  }
1069
1101
 
@@ -1186,7 +1218,7 @@ export function compileSheetContract(pipeline: PlayStaticPipeline): {
1186
1218
  }
1187
1219
  };
1188
1220
 
1189
- for (const substep of pipeline.substeps) {
1221
+ for (const substep of substeps) {
1190
1222
  processSubstep(substep);
1191
1223
  }
1192
1224
 
@@ -42,6 +42,12 @@ const TRANSPORT_OWNED_REQUEST_HEADERS = new Set([
42
42
  'x-forwarded-host',
43
43
  'x-forwarded-proto',
44
44
  ]);
45
+ const CROSS_ORIGIN_REDIRECT_SAFE_HEADERS = new Set([
46
+ 'accept',
47
+ 'accept-language',
48
+ 'content-language',
49
+ 'content-type',
50
+ ]);
45
51
 
46
52
  function cloneHeaders(headers: RequestInit['headers']): Headers {
47
53
  return new Headers(headers);
@@ -57,6 +63,18 @@ function removeTransportOwnedHeaders(headers: Headers): void {
57
63
  }
58
64
  }
59
65
 
66
+ function removeUnsafeCrossOriginRedirectHeaders(headers: Headers): void {
67
+ const namesToDelete: string[] = [];
68
+ for (const [name] of headers) {
69
+ if (!CROSS_ORIGIN_REDIRECT_SAFE_HEADERS.has(name.toLowerCase())) {
70
+ namesToDelete.push(name);
71
+ }
72
+ }
73
+ for (const name of namesToDelete) {
74
+ headers.delete(name);
75
+ }
76
+ }
77
+
60
78
  function withContentLength(
61
79
  body: Buffer | string | undefined,
62
80
  headers: Headers,
@@ -222,14 +240,11 @@ function createRequest(
222
240
  response.on('error', reject);
223
241
  response.on('end', () => {
224
242
  resolve(
225
- new Response(
226
- noBodyResponse ? null : Buffer.concat(chunks),
227
- {
228
- status,
229
- statusText: response.statusMessage,
230
- headers: response.headers as HeadersInit,
231
- },
232
- ),
243
+ new Response(noBodyResponse ? null : Buffer.concat(chunks), {
244
+ status,
245
+ statusText: response.statusMessage,
246
+ headers: response.headers as HeadersInit,
247
+ }),
233
248
  );
234
249
  });
235
250
  },
@@ -248,7 +263,6 @@ function initForRedirect(
248
263
  from: URL,
249
264
  to: URL,
250
265
  status: number,
251
- sensitiveHeaders: Iterable<string>,
252
266
  ): RequestInit {
253
267
  const headers = cloneHeaders(init.headers);
254
268
  let method = String(init.method ?? 'GET').toUpperCase();
@@ -265,12 +279,7 @@ function initForRedirect(
265
279
  }
266
280
 
267
281
  if (from.origin !== to.origin) {
268
- deleteHeader(headers, 'authorization');
269
- deleteHeader(headers, 'cookie');
270
- deleteHeader(headers, 'proxy-authorization');
271
- for (const header of sensitiveHeaders) {
272
- deleteHeader(headers, header);
273
- }
282
+ removeUnsafeCrossOriginRedirectHeaders(headers);
274
283
  }
275
284
 
276
285
  return {
@@ -290,7 +299,6 @@ export async function safeOutboundFetch(
290
299
  const redirectMode = init.redirect ?? 'follow';
291
300
  const maxRedirects = options.maxRedirects ?? 10;
292
301
  const maxResponseBytes = options.maxResponseBytes;
293
- const sensitiveHeaders = options.sensitiveHeaders ?? [];
294
302
  const validateUrl = options.validateUrl;
295
303
  let currentUrl = assertPublicHttpUrl(input);
296
304
  let currentInit: RequestInit = { ...init, redirect: 'manual' };
@@ -348,7 +356,6 @@ export async function safeOutboundFetch(
348
356
  currentUrl,
349
357
  nextUrl,
350
358
  response.status,
351
- sensitiveHeaders,
352
359
  );
353
360
  currentUrl = nextUrl;
354
361
  }
package/dist/cli/index.js CHANGED
@@ -623,10 +623,10 @@ var SDK_RELEASE = {
623
623
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
624
624
  // fields shipped in 0.1.153.
625
625
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
626
- version: "0.1.182",
626
+ version: "0.1.184",
627
627
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
628
628
  supportPolicy: {
629
- latest: "0.1.182",
629
+ latest: "0.1.184",
630
630
  minimumSupported: "0.1.53",
631
631
  deprecatedBelow: "0.1.53",
632
632
  commandMinimumSupported: [
@@ -784,6 +784,10 @@ var WORKER_CALLBACK_URL_OVERRIDE_HEADER = "x-deepline-worker-callback-url";
784
784
  var RUNTIME_SCHEDULER_SCHEMA_OVERRIDE_HEADER = "x-deepline-runtime-scheduler-schema";
785
785
  var SYNTHETIC_RUN_HEADER = "x-deepline-synthetic-run";
786
786
 
787
+ // ../shared_libs/play-runtime/test-runtime-seams.ts
788
+ var PLAY_RUNTIME_TEST_FAULT_HEADER = "x-deepline-test-fault";
789
+ var MAX_RUNTIME_TEST_POLICY_MS = 10 * 6e4;
790
+
787
791
  // src/http.ts
788
792
  var MAX_DIAGNOSTIC_HEADER_LENGTH = 120;
789
793
  var COWORK_NETWORK_HINT = "Claude Cowork appears to be running Deepline in a network-restricted sandbox. In Claude Desktop, open Settings > Capabilities, turn on Allow network egress, and set Domain allowlist to All domains for the Cowork session.";
@@ -898,12 +902,9 @@ var HttpClient = class {
898
902
  headers["x-deepline-play-artifact-r2-prefix"] = playArtifactR2Prefix;
899
903
  }
900
904
  const coordinatorUrl = typeof process !== "undefined" ? process.env?.DEEPLINE_COORDINATOR_URL : void 0;
905
+ const coordinatorInternalToken = typeof process !== "undefined" ? process.env?.DEEPLINE_INTERNAL_TOKEN : void 0;
901
906
  if (coordinatorUrl?.trim()) {
902
907
  headers[COORDINATOR_URL_OVERRIDE_HEADER] = coordinatorUrl.trim();
903
- const coordinatorInternalToken = typeof process !== "undefined" ? process.env?.DEEPLINE_INTERNAL_TOKEN : void 0;
904
- if (coordinatorInternalToken?.trim()) {
905
- headers[COORDINATOR_INTERNAL_TOKEN_HEADER] = coordinatorInternalToken.trim();
906
- }
907
908
  }
908
909
  const workerCallbackUrl = typeof process !== "undefined" ? process.env?.DEEPLINE_WORKER_CALLBACK_URL : void 0;
909
910
  if (workerCallbackUrl?.trim()) {
@@ -917,6 +918,13 @@ var HttpClient = class {
917
918
  if (syntheticRun && syntheticRun.trim() && syntheticRun.trim() !== "0") {
918
919
  headers[SYNTHETIC_RUN_HEADER] = "1";
919
920
  }
921
+ const runtimeTestFault = typeof process !== "undefined" ? process.env?.DEEPLINE_TEST_RUNTIME_FAULT : void 0;
922
+ if (runtimeTestFault?.trim()) {
923
+ headers[PLAY_RUNTIME_TEST_FAULT_HEADER] = runtimeTestFault.trim();
924
+ }
925
+ if (coordinatorInternalToken?.trim() && (coordinatorUrl?.trim() || workerCallbackUrl?.trim() || runtimeTestFault?.trim())) {
926
+ headers[COORDINATOR_INTERNAL_TOKEN_HEADER] = coordinatorInternalToken.trim();
927
+ }
920
928
  return headers;
921
929
  }
922
930
  /**
@@ -1330,6 +1338,20 @@ function resolveTimingWindow(input2) {
1330
1338
  };
1331
1339
  }
1332
1340
 
1341
+ // ../shared_libs/play-runtime/run-terminal-source.ts
1342
+ var PLAY_RUN_LEDGER_EVENT_SOURCES = [
1343
+ "worker",
1344
+ "temporal",
1345
+ "convex",
1346
+ "coordinator",
1347
+ "system"
1348
+ ];
1349
+ function normalizePlayRunLedgerTerminalSource(value) {
1350
+ return PLAY_RUN_LEDGER_EVENT_SOURCES.includes(
1351
+ value
1352
+ ) ? value : null;
1353
+ }
1354
+
1333
1355
  // ../shared_libs/play-runtime/run-ledger.ts
1334
1356
  var LOG_TAIL_LIMIT = 100;
1335
1357
  function isRecord(value) {
@@ -1466,7 +1488,8 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1466
1488
  ),
1467
1489
  resultTableNamespace: optionalNullableString(value.resultTableNamespace),
1468
1490
  resultSummary: value.resultSummary,
1469
- result: value.result
1491
+ result: value.result,
1492
+ terminalSource: normalizePlayRunLedgerTerminalSource(value.terminalSource)
1470
1493
  };
1471
1494
  }
1472
1495
  function normalizeStepStatus(value) {
@@ -2191,6 +2214,33 @@ function resolvePlayRunIntegrationMode(request) {
2191
2214
  request.integrationMode ?? process.env.DEEPLINE_EVAL_INTEGRATION_MODE
2192
2215
  );
2193
2216
  }
2217
+ function normalizeTestPolicyOverrides(value, source) {
2218
+ if (value && typeof value === "object" && !Array.isArray(value)) {
2219
+ return value;
2220
+ }
2221
+ throw new DeeplineError(
2222
+ `${source} must be a JSON object.`,
2223
+ void 0,
2224
+ "INVALID_TEST_POLICY_OVERRIDES"
2225
+ );
2226
+ }
2227
+ function parseEnvTestPolicyOverrides() {
2228
+ const raw = typeof process !== "undefined" ? process.env?.DEEPLINE_TEST_POLICY_OVERRIDES : void 0;
2229
+ const trimmed = raw?.trim();
2230
+ if (!trimmed) return void 0;
2231
+ let parsed;
2232
+ try {
2233
+ parsed = JSON.parse(trimmed);
2234
+ } catch (error) {
2235
+ const detail = error instanceof Error ? ` ${error.message}` : "";
2236
+ throw new DeeplineError(
2237
+ `DEEPLINE_TEST_POLICY_OVERRIDES must be valid JSON.${detail}`,
2238
+ void 0,
2239
+ "INVALID_TEST_POLICY_OVERRIDES"
2240
+ );
2241
+ }
2242
+ return normalizeTestPolicyOverrides(parsed, "DEEPLINE_TEST_POLICY_OVERRIDES");
2243
+ }
2194
2244
  function sleep2(ms) {
2195
2245
  return new Promise((resolve14) => setTimeout(resolve14, ms));
2196
2246
  }
@@ -2833,6 +2883,7 @@ var DeeplineClient = class {
2833
2883
  */
2834
2884
  async startPlayRun(request) {
2835
2885
  const integrationMode = resolvePlayRunIntegrationMode(request);
2886
+ const testPolicyOverrides = request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
2836
2887
  const forceToolRefresh = request.forceToolRefresh === true;
2837
2888
  const response = await this.http.post(
2838
2889
  "/api/v2/plays/run",
@@ -2860,7 +2911,8 @@ var DeeplineClient = class {
2860
2911
  // defaults to workers_edge; tests and runtime probes that want a
2861
2912
  // different profile pass `request.profile` explicitly.
2862
2913
  ...request.profile ? { profile: request.profile } : {},
2863
- ...integrationMode ? { integrationMode } : {}
2914
+ ...integrationMode ? { integrationMode } : {},
2915
+ ...testPolicyOverrides ? { testPolicyOverrides } : {}
2864
2916
  }
2865
2917
  );
2866
2918
  return normalizePlayRunStart(response);
@@ -2878,6 +2930,7 @@ var DeeplineClient = class {
2878
2930
  */
2879
2931
  async *startPlayRunStream(request, options) {
2880
2932
  const integrationMode = resolvePlayRunIntegrationMode(request);
2933
+ const testPolicyOverrides = request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
2881
2934
  const forceToolRefresh = request.forceToolRefresh === true;
2882
2935
  const body = {
2883
2936
  ...request.name ? { name: request.name } : {},
@@ -2900,7 +2953,8 @@ var DeeplineClient = class {
2900
2953
  ...forceToolRefresh ? { forceToolRefresh: true } : {},
2901
2954
  ...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
2902
2955
  ...request.profile ? { profile: request.profile } : {},
2903
- ...integrationMode ? { integrationMode } : {}
2956
+ ...integrationMode ? { integrationMode } : {},
2957
+ ...testPolicyOverrides ? { testPolicyOverrides } : {}
2904
2958
  };
2905
2959
  for await (const event of this.http.streamSse(
2906
2960
  "/api/v2/plays/run?stream=true",
@@ -9892,9 +9946,9 @@ var PLAY_RUNTIME_PROVIDERS = {
9892
9946
  id: PLAY_RUNTIME_PROVIDER_IDS.hatchet,
9893
9947
  scheduler: PLAY_SCHEDULER_BACKENDS.hatchet,
9894
9948
  runner: PLAY_RUNTIME_BACKENDS.daytona,
9895
- dedup: PLAY_DEDUP_BACKENDS.durableObject,
9949
+ dedup: PLAY_DEDUP_BACKENDS.inMemory,
9896
9950
  artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
9897
- label: "Hatchet scheduler + one-shot Daytona runner + DO dedup"
9951
+ label: "Hatchet scheduler + one-shot Daytona runner + receipt-backed in-process dedup"
9898
9952
  },
9899
9953
  local: {
9900
9954
  id: PLAY_RUNTIME_PROVIDER_IDS.local,
@@ -13719,7 +13773,7 @@ async function handleFileBackedRun(options) {
13719
13773
  ...Object.keys(runtimeInput).length > 0 ? { input: runtimeInput } : {},
13720
13774
  ...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
13721
13775
  ...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
13722
- ...options.force ? { force: true, forceToolRefresh: true } : {},
13776
+ ...options.force ? { force: true } : {},
13723
13777
  ...options.profile ? { profile: options.profile } : {},
13724
13778
  ...integrationMode ? { integrationMode } : {}
13725
13779
  };
@@ -13878,7 +13932,7 @@ async function handleNamedRun(options) {
13878
13932
  ...Object.keys(runtimeInput).length > 0 ? { input: runtimeInput } : {},
13879
13933
  ...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
13880
13934
  ...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
13881
- ...options.force ? { force: true, forceToolRefresh: true } : {},
13935
+ ...options.force ? { force: true } : {},
13882
13936
  ...options.profile ? { profile: options.profile } : {},
13883
13937
  ...integrationMode ? { integrationMode } : {}
13884
13938
  };
@@ -15065,7 +15119,7 @@ Notes:
15065
15119
  The play page opens in your browser as soon as the run starts; use --no-open
15066
15120
  to only print the URL.
15067
15121
  Concurrent runs for the same play are allowed.
15068
- --force bypasses durable dataset/tool cache reuse for this run.
15122
+ --force starts a fresh run graph without refreshing completed provider calls.
15069
15123
  It does not cancel active sibling runs.
15070
15124
  This command starts cloud work and may spend Deepline credits through tool calls.
15071
15125
 
@@ -15117,7 +15171,7 @@ Examples:
15117
15171
  ).option("--watch", "Compatibility alias; run waits by default").option("--wait", "Compatibility alias; run waits by default").option("--no-wait", "Start the run and return immediately").option(
15118
15172
  "--logs",
15119
15173
  "When output is non-interactive, stream play logs to stderr while waiting"
15120
- ).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Bypass durable dataset/tool cache reuse").option("--no-open", "Print the play page URL without opening a browser").option("--json", "Emit JSON output").option("--full", "Debug only: with --json, emit the raw status payload").addHelpText(
15174
+ ).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Start a fresh run graph").option("--no-open", "Print the play page URL without opening a browser").option("--json", "Emit JSON output").option("--full", "Debug only: with --json, emit the raw status payload").addHelpText(
15121
15175
  "afterAll",
15122
15176
  `
15123
15177
  Pass-through input flags:
@@ -22467,7 +22521,7 @@ async function readHiddenLine(prompt, streams = {}) {
22467
22521
  if (typeof inputStream.setRawMode === "function") {
22468
22522
  inputStream.setRawMode(previousRawMode);
22469
22523
  }
22470
- if (wasPaused) {
22524
+ if (wasPaused || inputStream === import_node_process.stdin) {
22471
22525
  inputStream.pause();
22472
22526
  }
22473
22527
  };
@@ -25600,10 +25654,15 @@ async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
25600
25654
  }
25601
25655
 
25602
25656
  // src/cli/commands/update.ts
25603
- var NPM_SDK_INSTALL_COMMON_FLAGS = ["--no-audit", "--no-fund"];
25657
+ var NPM_SDK_INSTALL_COMMON_FLAGS = [
25658
+ "--no-audit",
25659
+ "--no-fund",
25660
+ "--include=optional"
25661
+ ];
25604
25662
  var NPM_SDK_GLOBAL_INSTALL_FLAGS = [
25605
25663
  "--no-audit",
25606
25664
  "--no-fund",
25665
+ "--include=optional",
25607
25666
  "--allow-scripts=esbuild"
25608
25667
  ];
25609
25668
  var NPM_SDK_SIDECAR_PACKAGE_JSON = `${JSON.stringify(
@@ -608,10 +608,10 @@ var SDK_RELEASE = {
608
608
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
609
609
  // fields shipped in 0.1.153.
610
610
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
611
- version: "0.1.182",
611
+ version: "0.1.184",
612
612
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
613
613
  supportPolicy: {
614
- latest: "0.1.182",
614
+ latest: "0.1.184",
615
615
  minimumSupported: "0.1.53",
616
616
  deprecatedBelow: "0.1.53",
617
617
  commandMinimumSupported: [
@@ -769,6 +769,10 @@ var WORKER_CALLBACK_URL_OVERRIDE_HEADER = "x-deepline-worker-callback-url";
769
769
  var RUNTIME_SCHEDULER_SCHEMA_OVERRIDE_HEADER = "x-deepline-runtime-scheduler-schema";
770
770
  var SYNTHETIC_RUN_HEADER = "x-deepline-synthetic-run";
771
771
 
772
+ // ../shared_libs/play-runtime/test-runtime-seams.ts
773
+ var PLAY_RUNTIME_TEST_FAULT_HEADER = "x-deepline-test-fault";
774
+ var MAX_RUNTIME_TEST_POLICY_MS = 10 * 6e4;
775
+
772
776
  // src/http.ts
773
777
  var MAX_DIAGNOSTIC_HEADER_LENGTH = 120;
774
778
  var COWORK_NETWORK_HINT = "Claude Cowork appears to be running Deepline in a network-restricted sandbox. In Claude Desktop, open Settings > Capabilities, turn on Allow network egress, and set Domain allowlist to All domains for the Cowork session.";
@@ -883,12 +887,9 @@ var HttpClient = class {
883
887
  headers["x-deepline-play-artifact-r2-prefix"] = playArtifactR2Prefix;
884
888
  }
885
889
  const coordinatorUrl = typeof process !== "undefined" ? process.env?.DEEPLINE_COORDINATOR_URL : void 0;
890
+ const coordinatorInternalToken = typeof process !== "undefined" ? process.env?.DEEPLINE_INTERNAL_TOKEN : void 0;
886
891
  if (coordinatorUrl?.trim()) {
887
892
  headers[COORDINATOR_URL_OVERRIDE_HEADER] = coordinatorUrl.trim();
888
- const coordinatorInternalToken = typeof process !== "undefined" ? process.env?.DEEPLINE_INTERNAL_TOKEN : void 0;
889
- if (coordinatorInternalToken?.trim()) {
890
- headers[COORDINATOR_INTERNAL_TOKEN_HEADER] = coordinatorInternalToken.trim();
891
- }
892
893
  }
893
894
  const workerCallbackUrl = typeof process !== "undefined" ? process.env?.DEEPLINE_WORKER_CALLBACK_URL : void 0;
894
895
  if (workerCallbackUrl?.trim()) {
@@ -902,6 +903,13 @@ var HttpClient = class {
902
903
  if (syntheticRun && syntheticRun.trim() && syntheticRun.trim() !== "0") {
903
904
  headers[SYNTHETIC_RUN_HEADER] = "1";
904
905
  }
906
+ const runtimeTestFault = typeof process !== "undefined" ? process.env?.DEEPLINE_TEST_RUNTIME_FAULT : void 0;
907
+ if (runtimeTestFault?.trim()) {
908
+ headers[PLAY_RUNTIME_TEST_FAULT_HEADER] = runtimeTestFault.trim();
909
+ }
910
+ if (coordinatorInternalToken?.trim() && (coordinatorUrl?.trim() || workerCallbackUrl?.trim() || runtimeTestFault?.trim())) {
911
+ headers[COORDINATOR_INTERNAL_TOKEN_HEADER] = coordinatorInternalToken.trim();
912
+ }
905
913
  return headers;
906
914
  }
907
915
  /**
@@ -1315,6 +1323,20 @@ function resolveTimingWindow(input2) {
1315
1323
  };
1316
1324
  }
1317
1325
 
1326
+ // ../shared_libs/play-runtime/run-terminal-source.ts
1327
+ var PLAY_RUN_LEDGER_EVENT_SOURCES = [
1328
+ "worker",
1329
+ "temporal",
1330
+ "convex",
1331
+ "coordinator",
1332
+ "system"
1333
+ ];
1334
+ function normalizePlayRunLedgerTerminalSource(value) {
1335
+ return PLAY_RUN_LEDGER_EVENT_SOURCES.includes(
1336
+ value
1337
+ ) ? value : null;
1338
+ }
1339
+
1318
1340
  // ../shared_libs/play-runtime/run-ledger.ts
1319
1341
  var LOG_TAIL_LIMIT = 100;
1320
1342
  function isRecord(value) {
@@ -1451,7 +1473,8 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1451
1473
  ),
1452
1474
  resultTableNamespace: optionalNullableString(value.resultTableNamespace),
1453
1475
  resultSummary: value.resultSummary,
1454
- result: value.result
1476
+ result: value.result,
1477
+ terminalSource: normalizePlayRunLedgerTerminalSource(value.terminalSource)
1455
1478
  };
1456
1479
  }
1457
1480
  function normalizeStepStatus(value) {
@@ -2176,6 +2199,33 @@ function resolvePlayRunIntegrationMode(request) {
2176
2199
  request.integrationMode ?? process.env.DEEPLINE_EVAL_INTEGRATION_MODE
2177
2200
  );
2178
2201
  }
2202
+ function normalizeTestPolicyOverrides(value, source) {
2203
+ if (value && typeof value === "object" && !Array.isArray(value)) {
2204
+ return value;
2205
+ }
2206
+ throw new DeeplineError(
2207
+ `${source} must be a JSON object.`,
2208
+ void 0,
2209
+ "INVALID_TEST_POLICY_OVERRIDES"
2210
+ );
2211
+ }
2212
+ function parseEnvTestPolicyOverrides() {
2213
+ const raw = typeof process !== "undefined" ? process.env?.DEEPLINE_TEST_POLICY_OVERRIDES : void 0;
2214
+ const trimmed = raw?.trim();
2215
+ if (!trimmed) return void 0;
2216
+ let parsed;
2217
+ try {
2218
+ parsed = JSON.parse(trimmed);
2219
+ } catch (error) {
2220
+ const detail = error instanceof Error ? ` ${error.message}` : "";
2221
+ throw new DeeplineError(
2222
+ `DEEPLINE_TEST_POLICY_OVERRIDES must be valid JSON.${detail}`,
2223
+ void 0,
2224
+ "INVALID_TEST_POLICY_OVERRIDES"
2225
+ );
2226
+ }
2227
+ return normalizeTestPolicyOverrides(parsed, "DEEPLINE_TEST_POLICY_OVERRIDES");
2228
+ }
2179
2229
  function sleep2(ms) {
2180
2230
  return new Promise((resolve14) => setTimeout(resolve14, ms));
2181
2231
  }
@@ -2818,6 +2868,7 @@ var DeeplineClient = class {
2818
2868
  */
2819
2869
  async startPlayRun(request) {
2820
2870
  const integrationMode = resolvePlayRunIntegrationMode(request);
2871
+ const testPolicyOverrides = request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
2821
2872
  const forceToolRefresh = request.forceToolRefresh === true;
2822
2873
  const response = await this.http.post(
2823
2874
  "/api/v2/plays/run",
@@ -2845,7 +2896,8 @@ var DeeplineClient = class {
2845
2896
  // defaults to workers_edge; tests and runtime probes that want a
2846
2897
  // different profile pass `request.profile` explicitly.
2847
2898
  ...request.profile ? { profile: request.profile } : {},
2848
- ...integrationMode ? { integrationMode } : {}
2899
+ ...integrationMode ? { integrationMode } : {},
2900
+ ...testPolicyOverrides ? { testPolicyOverrides } : {}
2849
2901
  }
2850
2902
  );
2851
2903
  return normalizePlayRunStart(response);
@@ -2863,6 +2915,7 @@ var DeeplineClient = class {
2863
2915
  */
2864
2916
  async *startPlayRunStream(request, options) {
2865
2917
  const integrationMode = resolvePlayRunIntegrationMode(request);
2918
+ const testPolicyOverrides = request.testPolicyOverrides ?? parseEnvTestPolicyOverrides();
2866
2919
  const forceToolRefresh = request.forceToolRefresh === true;
2867
2920
  const body = {
2868
2921
  ...request.name ? { name: request.name } : {},
@@ -2885,7 +2938,8 @@ var DeeplineClient = class {
2885
2938
  ...forceToolRefresh ? { forceToolRefresh: true } : {},
2886
2939
  ...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
2887
2940
  ...request.profile ? { profile: request.profile } : {},
2888
- ...integrationMode ? { integrationMode } : {}
2941
+ ...integrationMode ? { integrationMode } : {},
2942
+ ...testPolicyOverrides ? { testPolicyOverrides } : {}
2889
2943
  };
2890
2944
  for await (const event of this.http.streamSse(
2891
2945
  "/api/v2/plays/run?stream=true",
@@ -9919,9 +9973,9 @@ var PLAY_RUNTIME_PROVIDERS = {
9919
9973
  id: PLAY_RUNTIME_PROVIDER_IDS.hatchet,
9920
9974
  scheduler: PLAY_SCHEDULER_BACKENDS.hatchet,
9921
9975
  runner: PLAY_RUNTIME_BACKENDS.daytona,
9922
- dedup: PLAY_DEDUP_BACKENDS.durableObject,
9976
+ dedup: PLAY_DEDUP_BACKENDS.inMemory,
9923
9977
  artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
9924
- label: "Hatchet scheduler + one-shot Daytona runner + DO dedup"
9978
+ label: "Hatchet scheduler + one-shot Daytona runner + receipt-backed in-process dedup"
9925
9979
  },
9926
9980
  local: {
9927
9981
  id: PLAY_RUNTIME_PROVIDER_IDS.local,
@@ -13746,7 +13800,7 @@ async function handleFileBackedRun(options) {
13746
13800
  ...Object.keys(runtimeInput).length > 0 ? { input: runtimeInput } : {},
13747
13801
  ...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
13748
13802
  ...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
13749
- ...options.force ? { force: true, forceToolRefresh: true } : {},
13803
+ ...options.force ? { force: true } : {},
13750
13804
  ...options.profile ? { profile: options.profile } : {},
13751
13805
  ...integrationMode ? { integrationMode } : {}
13752
13806
  };
@@ -13905,7 +13959,7 @@ async function handleNamedRun(options) {
13905
13959
  ...Object.keys(runtimeInput).length > 0 ? { input: runtimeInput } : {},
13906
13960
  ...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
13907
13961
  ...stagedFileInputs.packagedFiles.length ? { packagedFiles: stagedFileInputs.packagedFiles } : {},
13908
- ...options.force ? { force: true, forceToolRefresh: true } : {},
13962
+ ...options.force ? { force: true } : {},
13909
13963
  ...options.profile ? { profile: options.profile } : {},
13910
13964
  ...integrationMode ? { integrationMode } : {}
13911
13965
  };
@@ -15092,7 +15146,7 @@ Notes:
15092
15146
  The play page opens in your browser as soon as the run starts; use --no-open
15093
15147
  to only print the URL.
15094
15148
  Concurrent runs for the same play are allowed.
15095
- --force bypasses durable dataset/tool cache reuse for this run.
15149
+ --force starts a fresh run graph without refreshing completed provider calls.
15096
15150
  It does not cancel active sibling runs.
15097
15151
  This command starts cloud work and may spend Deepline credits through tool calls.
15098
15152
 
@@ -15144,7 +15198,7 @@ Examples:
15144
15198
  ).option("--watch", "Compatibility alias; run waits by default").option("--wait", "Compatibility alias; run waits by default").option("--no-wait", "Start the run and return immediately").option(
15145
15199
  "--logs",
15146
15200
  "When output is non-interactive, stream play logs to stderr while waiting"
15147
- ).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Bypass durable dataset/tool cache reuse").option("--no-open", "Print the play page URL without opening a browser").option("--json", "Emit JSON output").option("--full", "Debug only: with --json, emit the raw status payload").addHelpText(
15201
+ ).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Start a fresh run graph").option("--no-open", "Print the play page URL without opening a browser").option("--json", "Emit JSON output").option("--full", "Debug only: with --json, emit the raw status payload").addHelpText(
15148
15202
  "afterAll",
15149
15203
  `
15150
15204
  Pass-through input flags:
@@ -22501,7 +22555,7 @@ async function readHiddenLine(prompt, streams = {}) {
22501
22555
  if (typeof inputStream.setRawMode === "function") {
22502
22556
  inputStream.setRawMode(previousRawMode);
22503
22557
  }
22504
- if (wasPaused) {
22558
+ if (wasPaused || inputStream === input) {
22505
22559
  inputStream.pause();
22506
22560
  }
22507
22561
  };
@@ -25655,10 +25709,15 @@ async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
25655
25709
  }
25656
25710
 
25657
25711
  // src/cli/commands/update.ts
25658
- var NPM_SDK_INSTALL_COMMON_FLAGS = ["--no-audit", "--no-fund"];
25712
+ var NPM_SDK_INSTALL_COMMON_FLAGS = [
25713
+ "--no-audit",
25714
+ "--no-fund",
25715
+ "--include=optional"
25716
+ ];
25659
25717
  var NPM_SDK_GLOBAL_INSTALL_FLAGS = [
25660
25718
  "--no-audit",
25661
25719
  "--no-fund",
25720
+ "--include=optional",
25662
25721
  "--allow-scripts=esbuild"
25663
25722
  ];
25664
25723
  var NPM_SDK_SIDECAR_PACKAGE_JSON = `${JSON.stringify(
package/dist/index.d.mts CHANGED
@@ -952,6 +952,8 @@ interface StartPlayRunRequest {
952
952
  profile?: string;
953
953
  /** Optional per-run provider execution mode for eval/smoke runs. */
954
954
  integrationMode?: 'live' | 'eval_stub' | 'fixture';
955
+ /** Internal/dev-only runtime policy overrides for black-box durability tests. */
956
+ testPolicyOverrides?: Record<string, unknown>;
955
957
  }
956
958
  /**
957
959
  * Request body for making a play revision live.
package/dist/index.d.ts CHANGED
@@ -952,6 +952,8 @@ interface StartPlayRunRequest {
952
952
  profile?: string;
953
953
  /** Optional per-run provider execution mode for eval/smoke runs. */
954
954
  integrationMode?: 'live' | 'eval_stub' | 'fixture';
955
+ /** Internal/dev-only runtime policy overrides for black-box durability tests. */
956
+ testPolicyOverrides?: Record<string, unknown>;
955
957
  }
956
958
  /**
957
959
  * Request body for making a play revision live.