@workflow/world-testing 5.0.0-beta.36 → 5.0.0-beta.38

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.
@@ -396,7 +396,7 @@ function buildFramedDetails(hint2, slug) {
396
396
  });
397
397
  return out;
398
398
  }
399
- var BASE_URL, ERROR_SLUGS, WorkflowError, WorkflowWorldError, WorkflowRunFailedError, WorkflowRunNotCompletedError, WorkflowRuntimeError, RuntimeDecryptionError, SerializationError, StepNotRegisteredError, WorkflowNotRegisteredError, WorkflowRunNotFoundError, HookConflictError, HookNotFoundError, EntityConflictError, ThrottleError, WorkflowRunCancelledError, FatalError, RetryableError, FATAL_ERROR_KEY, RETRYABLE_ERROR_KEY, HOOK_CONFLICT_ERROR_KEY, RUNTIME_DECRYPTION_ERROR_KEY;
399
+ var BASE_URL, ERROR_SLUGS, WorkflowError, WorkflowWorldError, WorkflowRunFailedError, WorkflowRunNotCompletedError, WorkflowRuntimeError, RuntimeDecryptionError, SerializationError, StepNotRegisteredError, WorkflowNotRegisteredError, WorkflowRunNotFoundError, HookConflictError, HookNotFoundError, EntityConflictError, RunExpiredError, ThrottleError, WorkflowRunCancelledError, FatalError, RetryableError, FATAL_ERROR_KEY, RETRYABLE_ERROR_KEY, HOOK_CONFLICT_ERROR_KEY, RUNTIME_DECRYPTION_ERROR_KEY;
400
400
  var init_dist2 = __esm({
401
401
  "../errors/dist/index.js"() {
402
402
  "use strict";
@@ -659,6 +659,18 @@ Caused by: ${options.cause.stack}`;
659
659
  return isError(value) && value.name === "EntityConflictError";
660
660
  }
661
661
  };
662
+ RunExpiredError = class extends WorkflowWorldError {
663
+ static {
664
+ __name(this, "RunExpiredError");
665
+ }
666
+ constructor(message) {
667
+ super(message);
668
+ this.name = "RunExpiredError";
669
+ }
670
+ static is(value) {
671
+ return isError(value) && value.name === "RunExpiredError";
672
+ }
673
+ };
662
674
  ThrottleError = class extends WorkflowWorldError {
663
675
  static {
664
676
  __name(this, "ThrottleError");
@@ -16787,7 +16799,14 @@ var init_events = __esm({
16787
16799
  input: SerializedDataSchema,
16788
16800
  executionContext: external_exports.record(external_exports.string(), external_exports.any()).optional(),
16789
16801
  attributes: external_exports.record(external_exports.string(), external_exports.string()).optional(),
16790
- allowReservedAttributes: external_exports.literal(true).optional()
16802
+ allowReservedAttributes: external_exports.literal(true).optional(),
16803
+ /**
16804
+ * The run's X25519 public key (base64), stamped by SDKs that support
16805
+ * sealed (`encp`) envelopes. Persisted onto the run entity so that
16806
+ * cross-run writers can seal payloads to this run without holding its
16807
+ * symmetric key. Not secret — see `WorkflowRunBaseSchema`.
16808
+ */
16809
+ encryptionPublicKey: external_exports.string().optional()
16791
16810
  })
16792
16811
  });
16793
16812
  RunStartedEventSchema = BaseEventSchema.extend({
@@ -16798,7 +16817,14 @@ var init_events = __esm({
16798
16817
  workflowName: external_exports.string().optional(),
16799
16818
  executionContext: external_exports.record(external_exports.string(), external_exports.any()).optional(),
16800
16819
  attributes: external_exports.record(external_exports.string(), external_exports.string()).optional(),
16801
- allowReservedAttributes: external_exports.literal(true).optional()
16820
+ allowReservedAttributes: external_exports.literal(true).optional(),
16821
+ /**
16822
+ * Mirrors `run_created.eventData.encryptionPublicKey`. Carried here for
16823
+ * the resilient-start path: when the `run_created` write failed, the
16824
+ * server creates the run from this event instead, and without the key
16825
+ * the run would silently lose its ability to receive sealed writes.
16826
+ */
16827
+ encryptionPublicKey: external_exports.string().optional()
16802
16828
  }).optional()
16803
16829
  });
16804
16830
  RunCompletedEventSchema = BaseEventSchema.extend({
@@ -16970,6 +16996,26 @@ var init_runs = __esm({
16970
16996
  * the attributes-mvp changelog entry.
16971
16997
  */
16972
16998
  attributes: external_exports.record(external_exports.string(), external_exports.string()).default({}),
16999
+ /**
17000
+ * The run's X25519 public key, base64-encoded (~44 chars).
17001
+ *
17002
+ * Lets any party that can read this run seal a payload *to* it without
17003
+ * being able to read the run's data — used for cross-run writes such as a
17004
+ * hook resumption from another deployment, or a child workflow writing into
17005
+ * a forwarded stream. The matching private scalar is never stored: it is
17006
+ * re-derived on demand from the deployment's own key material, so this
17007
+ * field is not secret and its presence does not weaken the run's
17008
+ * confidentiality.
17009
+ *
17010
+ * Stamped at run creation by SDKs that support sealed (`encp`) envelopes.
17011
+ * **Presence is the writer-side gate**: a run only carries a public key if
17012
+ * the runtime that created it could also open sealed payloads, and runs are
17013
+ * pinned to their creating deployment. Writers therefore seal iff this
17014
+ * field is set, and otherwise fall back to fetching the symmetric per-run
17015
+ * key. Absent on runs created by older SDKs, and on worlds that do not
17016
+ * implement `getEncryptionKeyForRun` (encryption disabled).
17017
+ */
17018
+ encryptionPublicKey: external_exports.string().optional(),
16973
17019
  expiredAt: external_exports.coerce.date().optional(),
16974
17020
  startedAt: external_exports.coerce.date().optional(),
16975
17021
  completedAt: external_exports.coerce.date().optional(),
@@ -17255,30 +17301,6 @@ var init_env_config = __esm({
17255
17301
  }
17256
17302
  });
17257
17303
 
17258
- // ../world/dist/hooks.js
17259
- var HookSchema;
17260
- var init_hooks = __esm({
17261
- "../world/dist/hooks.js"() {
17262
- "use strict";
17263
- init_zod();
17264
- init_serialization();
17265
- HookSchema = external_exports.object({
17266
- runId: external_exports.string(),
17267
- hookId: external_exports.string(),
17268
- token: external_exports.string(),
17269
- ownerId: external_exports.string(),
17270
- projectId: external_exports.string(),
17271
- environment: external_exports.string(),
17272
- metadata: SerializedDataSchema.optional(),
17273
- createdAt: external_exports.coerce.date(),
17274
- // Optional in database for backwards compatibility, defaults to 1 (legacy) when reading
17275
- specVersion: external_exports.number().optional(),
17276
- isWebhook: external_exports.boolean().optional(),
17277
- isSystem: external_exports.boolean().optional()
17278
- });
17279
- }
17280
- });
17281
-
17282
17304
  // ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/index.js
17283
17305
  var init_classic = __esm({
17284
17306
  "../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/index.js"() {
@@ -17302,19 +17324,22 @@ function resolveQueueNamespace(namespace) {
17302
17324
  return namespace ?? process.env.WORKFLOW_QUEUE_NAMESPACE ?? void 0;
17303
17325
  }
17304
17326
  function getQueueTopicPrefix(kind, namespace) {
17327
+ if (kind !== "workflow") {
17328
+ throw new Error(`Unsupported queue kind: ${kind}`);
17329
+ }
17305
17330
  if (namespace !== void 0) {
17306
17331
  QueueNamespace.parse(namespace);
17307
- return `__${namespace}_wkf_${kind}_`;
17332
+ return `__${namespace}_wkf_workflow_`;
17308
17333
  }
17309
- return `__wkf_${kind}_`;
17334
+ return "__wkf_workflow_";
17310
17335
  }
17311
- var QueuePrefix, ValidQueueName, QueueNamespace, MessageId, TraceCarrierSchema, RunInputSchema, WorkflowInvokePayloadSchema, StepInvokePayloadSchema, HealthCheckPayloadSchema, QueuePayloadSchema;
17336
+ var QueuePrefix, ValidQueueName, QueueNamespace, MessageId, TraceCarrierSchema, RunInputSchema, WorkflowInvokePayloadSchema, HealthCheckPayloadSchema, QueuePayloadSchema;
17312
17337
  var init_queue = __esm({
17313
17338
  "../world/dist/queue.js"() {
17314
17339
  "use strict";
17315
17340
  init_v4();
17316
- QueuePrefix = external_exports.string().regex(/^__(?:[a-z][a-z0-9]*_)?wkf_(?:workflow|step)_$/, "Must match __wkf_{workflow|step}_ or __{namespace}_wkf_{workflow|step}_");
17317
- ValidQueueName = external_exports.string().regex(/^__(?:[a-z][a-z0-9]*_)?wkf_(?:workflow|step)_.+$/, "Must be a valid queue name with a recognized prefix");
17341
+ QueuePrefix = external_exports.string().regex(/^__(?:[a-z][a-z0-9]*_)?wkf_workflow_$/, "Must match __wkf_workflow_ or __{namespace}_wkf_workflow_");
17342
+ ValidQueueName = external_exports.string().regex(/^__(?:[a-z][a-z0-9]*_)?wkf_workflow_.+$/, "Must be a valid queue name with a recognized prefix");
17318
17343
  QueueNamespace = external_exports.string().regex(/^[a-z][a-z0-9]*$/, "Must be lowercase alphanumeric, starting with a letter");
17319
17344
  __name(resolveQueueNamespace, "resolveQueueNamespace");
17320
17345
  __name(getQueueTopicPrefix, "getQueueTopicPrefix");
@@ -17354,26 +17379,71 @@ var init_queue = __esm({
17354
17379
  /** Run creation data, only present on the first queue delivery from start() */
17355
17380
  runInput: RunInputSchema.optional()
17356
17381
  });
17357
- StepInvokePayloadSchema = external_exports.object({
17358
- workflowName: external_exports.string(),
17359
- workflowRunId: external_exports.string(),
17360
- workflowStartedAt: external_exports.number(),
17361
- stepId: external_exports.string(),
17362
- traceCarrier: TraceCarrierSchema.optional(),
17363
- requestedAt: external_exports.coerce.date().optional()
17364
- });
17365
17382
  HealthCheckPayloadSchema = external_exports.object({
17366
17383
  __healthCheck: external_exports.literal(true),
17367
- correlationId: external_exports.string()
17384
+ correlationId: external_exports.string(),
17385
+ /**
17386
+ * The run id the caller is about to create, when the probe is being used to
17387
+ * prepare a cross-deployment `start()`.
17388
+ *
17389
+ * The responder runs inside the target deployment, so it can derive that
17390
+ * run's public key locally from its own key material and return it in the
17391
+ * probe response. That lets the caller seal the workflow arguments without
17392
+ * a separate key lookup. Absent for probes issued for other reasons (CLI
17393
+ * health command, dashboard), in which case no key is returned.
17394
+ */
17395
+ runId: external_exports.string().optional()
17368
17396
  });
17369
17397
  QueuePayloadSchema = external_exports.union([
17370
- WorkflowInvokePayloadSchema,
17371
- StepInvokePayloadSchema,
17372
- HealthCheckPayloadSchema
17398
+ HealthCheckPayloadSchema,
17399
+ WorkflowInvokePayloadSchema
17373
17400
  ]);
17374
17401
  }
17375
17402
  });
17376
17403
 
17404
+ // ../world/dist/hooks.js
17405
+ var HookResumeContextSchema, HookSchema;
17406
+ var init_hooks = __esm({
17407
+ "../world/dist/hooks.js"() {
17408
+ "use strict";
17409
+ init_zod();
17410
+ init_queue();
17411
+ init_serialization();
17412
+ HookResumeContextSchema = external_exports.object({
17413
+ deploymentId: external_exports.string(),
17414
+ workflowName: external_exports.string(),
17415
+ // Named `runSpecVersion` to distinguish it from the hook's own `specVersion`.
17416
+ runSpecVersion: external_exports.number().optional(),
17417
+ workflowCoreVersion: external_exports.string().optional(),
17418
+ traceCarrier: TraceCarrierSchema.optional(),
17419
+ // The run's published X25519 public key (base64), mirrored from the run
17420
+ // entity. Lets a resume seal (`encp`) its payload to the run without reading
17421
+ // the run or fetching its symmetric key. Absent on runs created before
17422
+ // sealed envelopes and on projects with encryption disabled, where the
17423
+ // resume falls back to the symmetric per-run key.
17424
+ encryptionPublicKey: external_exports.string().optional()
17425
+ });
17426
+ HookSchema = external_exports.object({
17427
+ runId: external_exports.string(),
17428
+ hookId: external_exports.string(),
17429
+ token: external_exports.string(),
17430
+ ownerId: external_exports.string(),
17431
+ projectId: external_exports.string(),
17432
+ environment: external_exports.string(),
17433
+ metadata: SerializedDataSchema.optional(),
17434
+ createdAt: external_exports.coerce.date(),
17435
+ // Optional in database for backwards compatibility, defaults to 1 (legacy) when reading
17436
+ specVersion: external_exports.number().optional(),
17437
+ isWebhook: external_exports.boolean().optional(),
17438
+ isSystem: external_exports.boolean().optional(),
17439
+ // Present when the server stored it (new hooks) or synthesized it from the
17440
+ // run (old hooks). Absent only against an old server, where the resume path
17441
+ // falls back to `runs.get`.
17442
+ resumeContext: HookResumeContextSchema.optional()
17443
+ });
17444
+ }
17445
+ });
17446
+
17377
17447
  // ../world/dist/recovery.js
17378
17448
  var init_recovery = __esm({
17379
17449
  "../world/dist/recovery.js"() {
@@ -17632,14 +17702,17 @@ async function importKey(raw, usages = [
17632
17702
  usages
17633
17703
  );
17634
17704
  }
17635
- async function encrypt(key, data) {
17705
+ async function encrypt(key, data, aad) {
17636
17706
  const nonce = globalThis.crypto.getRandomValues(new Uint8Array(NONCE_LENGTH));
17637
17707
  let ciphertext;
17638
17708
  try {
17639
17709
  ciphertext = await globalThis.crypto.subtle.encrypt({
17640
17710
  name: "AES-GCM",
17641
17711
  iv: nonce,
17642
- tagLength: TAG_LENGTH
17712
+ tagLength: TAG_LENGTH,
17713
+ ...aad ? {
17714
+ additionalData: aad
17715
+ } : {}
17643
17716
  }, key, data);
17644
17717
  } catch (cause) {
17645
17718
  throw new RuntimeDecryptionError(`AES-256-GCM encryption failed: ${cause instanceof Error ? cause.message : String(cause)}`, {
@@ -17655,7 +17728,7 @@ async function encrypt(key, data) {
17655
17728
  result.set(new Uint8Array(ciphertext), NONCE_LENGTH);
17656
17729
  return result;
17657
17730
  }
17658
- async function decrypt(key, data) {
17731
+ async function decrypt(key, data, aad) {
17659
17732
  const minLength = NONCE_LENGTH + TAG_LENGTH / 8;
17660
17733
  if (data.byteLength < minLength) {
17661
17734
  throw new RuntimeDecryptionError(`Encrypted data too short: expected at least ${minLength} bytes, got ${data.byteLength}`, {
@@ -17672,7 +17745,10 @@ async function decrypt(key, data) {
17672
17745
  plaintext = await globalThis.crypto.subtle.decrypt({
17673
17746
  name: "AES-GCM",
17674
17747
  iv: nonce,
17675
- tagLength: TAG_LENGTH
17748
+ tagLength: TAG_LENGTH,
17749
+ ...aad ? {
17750
+ additionalData: aad
17751
+ } : {}
17676
17752
  }, key, ciphertext);
17677
17753
  } catch (cause) {
17678
17754
  const causeMsg = cause instanceof Error ? cause.message : String(cause);
@@ -17686,13 +17762,14 @@ async function decrypt(key, data) {
17686
17762
  }
17687
17763
  return new Uint8Array(plaintext);
17688
17764
  }
17689
- var NONCE_LENGTH, TAG_LENGTH, KEY_LENGTH;
17765
+ var NONCE_LENGTH, TAG_LENGTH, TAG_BYTES, KEY_LENGTH;
17690
17766
  var init_encryption = __esm({
17691
17767
  "../core/dist/encryption.js"() {
17692
17768
  "use strict";
17693
17769
  init_dist2();
17694
17770
  NONCE_LENGTH = 12;
17695
17771
  TAG_LENGTH = 128;
17772
+ TAG_BYTES = TAG_LENGTH / 8;
17696
17773
  KEY_LENGTH = 32;
17697
17774
  __name(importKey, "importKey");
17698
17775
  __name(encrypt, "encrypt");
@@ -17700,140 +17777,708 @@ var init_encryption = __esm({
17700
17777
  }
17701
17778
  });
17702
17779
 
17703
- // ../../node_modules/.pnpm/devalue@5.8.1/node_modules/devalue/src/constants.js
17704
- var UNDEFINED, HOLE, NAN, POSITIVE_INFINITY, NEGATIVE_INFINITY, NEGATIVE_ZERO, SPARSE, MAX_ARRAY_LEN, MAX_ARRAY_INDEX;
17705
- var init_constants = __esm({
17706
- "../../node_modules/.pnpm/devalue@5.8.1/node_modules/devalue/src/constants.js"() {
17707
- "use strict";
17708
- UNDEFINED = -1;
17709
- HOLE = -2;
17710
- NAN = -3;
17711
- POSITIVE_INFINITY = -4;
17712
- NEGATIVE_INFINITY = -5;
17713
- NEGATIVE_ZERO = -6;
17714
- SPARSE = -7;
17715
- MAX_ARRAY_LEN = 2 ** 32 - 1;
17716
- MAX_ARRAY_INDEX = MAX_ARRAY_LEN - 1;
17780
+ // ../core/dist/sealed-box.js
17781
+ function assertKeyMaterialLength(runKeyMaterial) {
17782
+ if (runKeyMaterial.byteLength !== CONTENT_KEY_LENGTH) {
17783
+ throw new WorkflowRuntimeError(`Run key material must be exactly ${CONTENT_KEY_LENGTH} bytes, got ${runKeyMaterial.byteLength}`);
17717
17784
  }
17718
- });
17719
-
17720
- // ../../node_modules/.pnpm/devalue@5.8.1/node_modules/devalue/src/utils.js
17721
- function is_primitive(thing) {
17722
- return thing === null || typeof thing !== "object" && typeof thing !== "function";
17723
17785
  }
17724
- function is_plain_object(thing) {
17725
- const proto = Object.getPrototypeOf(thing);
17726
- return proto === Object.prototype || proto === null || Object.getPrototypeOf(proto) === null || Object.getOwnPropertyNames(proto).sort().join("\0") === object_proto_names;
17786
+ function assertPublicKeyLength(publicKey, label) {
17787
+ if (publicKey.byteLength !== X25519_KEY_LENGTH) {
17788
+ throw new WorkflowRuntimeError(`${label} must be exactly ${X25519_KEY_LENGTH} bytes, got ${publicKey.byteLength}`);
17789
+ }
17727
17790
  }
17728
- function get_type(thing) {
17729
- return Object.prototype.toString.call(thing).slice(8, -1);
17791
+ async function deriveRunKeyPair(runKeyMaterial) {
17792
+ assertKeyMaterialLength(runKeyMaterial);
17793
+ const hkdfKey = await globalThis.crypto.subtle.importKey("raw", runKeyMaterial, "HKDF", false, [
17794
+ "deriveBits"
17795
+ ]);
17796
+ const scalarBits = await globalThis.crypto.subtle.deriveBits({
17797
+ name: "HKDF",
17798
+ hash: "SHA-256",
17799
+ salt: new Uint8Array(32),
17800
+ info: infoEncoder.encode(SCALAR_INFO)
17801
+ }, hkdfKey, X25519_KEY_LENGTH * 8);
17802
+ const scalar = new Uint8Array(scalarBits);
17803
+ const publicKey = await derivePublicKeyFromScalar(scalar);
17804
+ return {
17805
+ scalar,
17806
+ publicKey
17807
+ };
17730
17808
  }
17731
- function get_escaped_char(char) {
17732
- switch (char) {
17733
- case '"':
17734
- return '\\"';
17735
- case "<":
17736
- return "\\u003C";
17737
- case "\\":
17738
- return "\\\\";
17739
- case "\n":
17740
- return "\\n";
17741
- case "\r":
17742
- return "\\r";
17743
- case " ":
17744
- return "\\t";
17745
- case "\b":
17746
- return "\\b";
17747
- case "\f":
17748
- return "\\f";
17749
- case "\u2028":
17750
- return "\\u2028";
17751
- case "\u2029":
17752
- return "\\u2029";
17753
- default:
17754
- return char < " " ? `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}` : "";
17809
+ async function derivePublicKeyFromScalar(scalar) {
17810
+ const privateKey = await importScalar(
17811
+ scalar,
17812
+ /* extractable */
17813
+ true
17814
+ );
17815
+ const jwk = await globalThis.crypto.subtle.exportKey("jwk", privateKey);
17816
+ if (!jwk.x) {
17817
+ throw new WorkflowRuntimeError('X25519 JWK export did not include a public key component ("x")');
17818
+ }
17819
+ const publicKey = base64UrlToBytes(jwk.x);
17820
+ if (publicKey.byteLength !== X25519_KEY_LENGTH) {
17821
+ throw new WorkflowRuntimeError(`X25519 JWK export produced a ${publicKey.byteLength}-byte public key, expected ${X25519_KEY_LENGTH}`);
17822
+ }
17823
+ return publicKey;
17824
+ }
17825
+ async function importScalar(scalar, extractable) {
17826
+ const pkcs8 = new Uint8Array(PKCS8_X25519_PREFIX.length + scalar.byteLength);
17827
+ pkcs8.set(PKCS8_X25519_PREFIX, 0);
17828
+ pkcs8.set(scalar, PKCS8_X25519_PREFIX.length);
17829
+ return globalThis.crypto.subtle.importKey("pkcs8", pkcs8, {
17830
+ name: "X25519"
17831
+ }, extractable, [
17832
+ "deriveBits"
17833
+ ]);
17834
+ }
17835
+ function importPublicKey(publicKey) {
17836
+ return globalThis.crypto.subtle.importKey(
17837
+ "raw",
17838
+ publicKey,
17839
+ {
17840
+ name: "X25519"
17841
+ },
17842
+ /* extractable */
17843
+ true,
17844
+ // Public keys carry no usages for X25519 — the private key does the
17845
+ // deriving; the public key is only ever an argument to it.
17846
+ []
17847
+ );
17848
+ }
17849
+ function bytesToBase64(bytes) {
17850
+ let out = "";
17851
+ for (let i = 0; i < bytes.length; i += 3) {
17852
+ const b0 = bytes[i];
17853
+ const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;
17854
+ const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;
17855
+ out += BASE64_CHARS[b0 >> 2 & 63];
17856
+ out += BASE64_CHARS[(b0 & 3) << 4 | b1 >> 4 & 15];
17857
+ out += i + 1 < bytes.length ? BASE64_CHARS[(b1 & 15) << 2 | b2 >> 6 & 3] : "=";
17858
+ out += i + 2 < bytes.length ? BASE64_CHARS[b2 & 63] : "=";
17755
17859
  }
17860
+ return out;
17756
17861
  }
17757
- function stringify_string(str) {
17758
- let result = "";
17759
- let last_pos = 0;
17760
- const len = str.length;
17761
- for (let i = 0; i < len; i += 1) {
17762
- const char = str[i];
17763
- const replacement = get_escaped_char(char);
17764
- if (replacement) {
17765
- result += str.slice(last_pos, i) + replacement;
17766
- last_pos = i + 1;
17862
+ function base64ToBytes(value) {
17863
+ let end = value.length;
17864
+ while (end > 0 && value[end - 1] === "=") end--;
17865
+ const body = value.slice(0, end);
17866
+ if (body.includes("=")) return void 0;
17867
+ if (body.length % 4 === 1) return void 0;
17868
+ if (end !== value.length && value.length % 4 !== 0) return void 0;
17869
+ let accumulator = 0;
17870
+ let bitCount = 0;
17871
+ const bytes = [];
17872
+ for (let i = 0; i < body.length; i++) {
17873
+ const index = BASE64_CHARS.indexOf(body[i]);
17874
+ if (index === -1) return void 0;
17875
+ accumulator = accumulator << 6 | index;
17876
+ bitCount += 6;
17877
+ if (bitCount >= 8) {
17878
+ bitCount -= 8;
17879
+ bytes.push(accumulator >> bitCount & 255);
17767
17880
  }
17768
17881
  }
17769
- return `"${last_pos === 0 ? str : result + str.slice(last_pos)}"`;
17882
+ if (bitCount > 0 && (accumulator & (1 << bitCount) - 1) !== 0) {
17883
+ return void 0;
17884
+ }
17885
+ return new Uint8Array(bytes);
17886
+ }
17887
+ function base64UrlToBytes(value) {
17888
+ let accumulator = 0;
17889
+ let bitCount = 0;
17890
+ const bytes = [];
17891
+ for (let i = 0; i < value.length; i++) {
17892
+ const char = value[i];
17893
+ if (char === "=") break;
17894
+ const index = BASE64URL_CHARS.indexOf(char);
17895
+ if (index === -1) {
17896
+ throw new WorkflowRuntimeError(`Invalid base64url character "${char}" in X25519 JWK key component`);
17897
+ }
17898
+ accumulator = accumulator << 6 | index;
17899
+ bitCount += 6;
17900
+ if (bitCount >= 8) {
17901
+ bitCount -= 8;
17902
+ bytes.push(accumulator >> bitCount & 255);
17903
+ }
17904
+ }
17905
+ return new Uint8Array(bytes);
17770
17906
  }
17771
- function enumerable_symbols(object2) {
17772
- return Object.getOwnPropertySymbols(object2).filter((symbol2) => Object.getOwnPropertyDescriptor(object2, symbol2).enumerable);
17907
+ async function deriveContentKey(sharedSecret, ephemeralPublicKey, recipientPublicKey, usages) {
17908
+ const label = infoEncoder.encode(CONTENT_KEY_INFO);
17909
+ const info = new Uint8Array(label.length + ephemeralPublicKey.length + recipientPublicKey.length);
17910
+ info.set(label, 0);
17911
+ info.set(ephemeralPublicKey, label.length);
17912
+ info.set(recipientPublicKey, label.length + ephemeralPublicKey.length);
17913
+ const hkdfKey = await globalThis.crypto.subtle.importKey("raw", sharedSecret, "HKDF", false, [
17914
+ "deriveBits"
17915
+ ]);
17916
+ const contentKeyBits = await globalThis.crypto.subtle.deriveBits({
17917
+ name: "HKDF",
17918
+ hash: "SHA-256",
17919
+ salt: new Uint8Array(32),
17920
+ info
17921
+ }, hkdfKey, CONTENT_KEY_LENGTH * 8);
17922
+ return globalThis.crypto.subtle.importKey(
17923
+ "raw",
17924
+ new Uint8Array(contentKeyBits),
17925
+ "AES-GCM",
17926
+ false,
17927
+ // `KeyUsage` is a DOM-lib type that is not in scope under `es2022`; the
17928
+ // parameter type is a strict subset of it, so this cast is sound.
17929
+ usages
17930
+ );
17773
17931
  }
17774
- function stringify_key(key) {
17775
- return is_identifier.test(key) ? "." + key : "[" + JSON.stringify(key) + "]";
17932
+ async function encapsulate(recipientPublicKey) {
17933
+ assertPublicKeyLength(recipientPublicKey, "Recipient public key");
17934
+ let recipientKey;
17935
+ try {
17936
+ recipientKey = await importPublicKey(recipientPublicKey);
17937
+ } catch (cause) {
17938
+ throw new WorkflowRuntimeError(`Invalid X25519 recipient public key: ${cause instanceof Error ? cause.message : String(cause)}`, {
17939
+ cause
17940
+ });
17941
+ }
17942
+ const ephemeral = await globalThis.crypto.subtle.generateKey(
17943
+ {
17944
+ name: "X25519"
17945
+ },
17946
+ /* extractable */
17947
+ true,
17948
+ [
17949
+ "deriveBits"
17950
+ ]
17951
+ );
17952
+ const ephemeralPublicKey = new Uint8Array(await globalThis.crypto.subtle.exportKey("raw", ephemeral.publicKey));
17953
+ let sharedSecretBits;
17954
+ try {
17955
+ sharedSecretBits = await globalThis.crypto.subtle.deriveBits({
17956
+ name: "X25519",
17957
+ public: recipientKey
17958
+ }, ephemeral.privateKey, X25519_KEY_LENGTH * 8);
17959
+ } catch (cause) {
17960
+ throw new WorkflowRuntimeError("X25519 key agreement failed: the recipient public key is not a valid curve point (low-order point or corrupted key material)", {
17961
+ cause
17962
+ });
17963
+ }
17964
+ const contentKey = await deriveContentKey(new Uint8Array(sharedSecretBits), ephemeralPublicKey, recipientPublicKey, [
17965
+ "encrypt"
17966
+ ]);
17967
+ return {
17968
+ ephemeralPublicKey,
17969
+ contentKey
17970
+ };
17776
17971
  }
17777
- function is_valid_array_index(n) {
17778
- if (!Number.isInteger(n)) return false;
17779
- if (n < 0) return false;
17780
- if (n > MAX_ARRAY_INDEX) return false;
17781
- return true;
17972
+ async function decapsulate(keyPair, ephemeralPublicKey) {
17973
+ if (ephemeralPublicKey.byteLength !== X25519_KEY_LENGTH) {
17974
+ throw new RuntimeDecryptionError(`Sealed payload has a malformed ephemeral public key: expected ${X25519_KEY_LENGTH} bytes, got ${ephemeralPublicKey.byteLength}`, {
17975
+ context: {
17976
+ operation: "decrypt",
17977
+ byteLength: ephemeralPublicKey.byteLength
17978
+ }
17979
+ });
17980
+ }
17981
+ let sharedSecretBits;
17982
+ try {
17983
+ const [privateKey, senderKey] = await Promise.all([
17984
+ importScalar(
17985
+ keyPair.scalar,
17986
+ /* extractable */
17987
+ false
17988
+ ),
17989
+ importPublicKey(ephemeralPublicKey)
17990
+ ]);
17991
+ sharedSecretBits = await globalThis.crypto.subtle.deriveBits({
17992
+ name: "X25519",
17993
+ public: senderKey
17994
+ }, privateKey, X25519_KEY_LENGTH * 8);
17995
+ } catch (cause) {
17996
+ throw new RuntimeDecryptionError(`X25519 key agreement failed while opening a sealed payload: ${cause instanceof Error ? cause.message : String(cause)}`, {
17997
+ cause,
17998
+ context: {
17999
+ operation: "decrypt",
18000
+ byteLength: ephemeralPublicKey.byteLength
18001
+ }
18002
+ });
18003
+ }
18004
+ return deriveContentKey(new Uint8Array(sharedSecretBits), ephemeralPublicKey, keyPair.publicKey, [
18005
+ "decrypt"
18006
+ ]);
17782
18007
  }
17783
- function is_valid_array_len(n) {
17784
- if (!Number.isInteger(n)) return false;
17785
- if (n < 0) return false;
17786
- if (n > MAX_ARRAY_LEN) return false;
17787
- return true;
18008
+ async function seal(recipientPublicKey, data, aad) {
18009
+ const { ephemeralPublicKey, contentKey } = await encapsulate(recipientPublicKey);
18010
+ const encrypted = await encrypt(contentKey, data, aad);
18011
+ const result = new Uint8Array(ephemeralPublicKey.byteLength + encrypted.byteLength);
18012
+ result.set(ephemeralPublicKey, 0);
18013
+ result.set(encrypted, ephemeralPublicKey.byteLength);
18014
+ return result;
17788
18015
  }
17789
- function is_valid_array_index_string(s) {
17790
- if (s.length === 0) return false;
17791
- if (s.length > 1 && s.charCodeAt(0) === 48) return false;
17792
- for (let i = 0; i < s.length; i++) {
17793
- const c = s.charCodeAt(i);
17794
- if (c < 48 || c > 57) return false;
18016
+ async function open(keyPair, sealed, aad) {
18017
+ const minLength = X25519_KEY_LENGTH + NONCE_LENGTH + TAG_BYTES;
18018
+ if (sealed.byteLength < minLength) {
18019
+ throw new RuntimeDecryptionError(`Sealed payload too short: expected at least ${minLength} bytes, got ${sealed.byteLength}`, {
18020
+ context: {
18021
+ operation: "decrypt",
18022
+ byteLength: sealed.byteLength
18023
+ }
18024
+ });
17795
18025
  }
17796
- return is_valid_array_index(+s);
18026
+ const ephemeralPublicKey = sealed.subarray(0, X25519_KEY_LENGTH);
18027
+ const encrypted = sealed.subarray(X25519_KEY_LENGTH);
18028
+ const contentKey = await decapsulate(keyPair, ephemeralPublicKey);
18029
+ return decrypt(contentKey, encrypted, aad);
17797
18030
  }
17798
- function valid_array_indices(array2) {
17799
- const keys = Object.keys(array2);
17800
- for (var i = keys.length - 1; i >= 0; i--) {
17801
- if (is_valid_array_index_string(keys[i])) {
17802
- break;
18031
+ function createSealSession(recipientPublicKey, aad) {
18032
+ let encapsulation;
18033
+ return {
18034
+ async seal(data) {
18035
+ encapsulation ??= encapsulate(recipientPublicKey);
18036
+ const { ephemeralPublicKey, contentKey } = await encapsulation;
18037
+ const encrypted = await encrypt(contentKey, data, aad);
18038
+ const result = new Uint8Array(ephemeralPublicKey.byteLength + encrypted.byteLength);
18039
+ result.set(ephemeralPublicKey, 0);
18040
+ result.set(encrypted, ephemeralPublicKey.byteLength);
18041
+ return result;
17803
18042
  }
17804
- }
17805
- keys.length = i + 1;
17806
- return keys;
18043
+ };
17807
18044
  }
17808
- var DevalueError, object_proto_names, is_identifier;
17809
- var init_utils = __esm({
17810
- "../../node_modules/.pnpm/devalue@5.8.1/node_modules/devalue/src/utils.js"() {
17811
- "use strict";
17812
- init_constants();
17813
- DevalueError = class extends Error {
17814
- static {
17815
- __name(this, "DevalueError");
18045
+ function createOpenSession(keyPair, aad) {
18046
+ let cachedSender;
18047
+ let cachedKey;
18048
+ return {
18049
+ async open(sealed) {
18050
+ const minLength = X25519_KEY_LENGTH + NONCE_LENGTH + TAG_BYTES;
18051
+ if (sealed.byteLength < minLength) {
18052
+ throw new RuntimeDecryptionError(`Sealed payload too short: expected at least ${minLength} bytes, got ${sealed.byteLength}`, {
18053
+ context: {
18054
+ operation: "decrypt",
18055
+ byteLength: sealed.byteLength
18056
+ }
18057
+ });
17816
18058
  }
17817
- /**
17818
- * @param {string} message
17819
- * @param {string[]} keys
17820
- * @param {any} [value] - The value that failed to be serialized
17821
- * @param {any} [root] - The root value being serialized
17822
- */
17823
- constructor(message, keys, value, root) {
17824
- super(message);
17825
- this.name = "DevalueError";
17826
- this.path = keys.join("");
17827
- this.value = value;
17828
- this.root = root;
18059
+ const ephemeralPublicKey = sealed.subarray(0, X25519_KEY_LENGTH);
18060
+ const encrypted = sealed.subarray(X25519_KEY_LENGTH);
18061
+ const sender = keyCacheId(ephemeralPublicKey);
18062
+ if (sender !== cachedSender || !cachedKey) {
18063
+ cachedSender = sender;
18064
+ cachedKey = decapsulate(keyPair, ephemeralPublicKey);
17829
18065
  }
17830
- };
17831
- __name(is_primitive, "is_primitive");
17832
- object_proto_names = /* @__PURE__ */ Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
17833
- __name(is_plain_object, "is_plain_object");
17834
- __name(get_type, "get_type");
17835
- __name(get_escaped_char, "get_escaped_char");
17836
- __name(stringify_string, "stringify_string");
18066
+ let contentKey;
18067
+ try {
18068
+ contentKey = await cachedKey;
18069
+ } catch (error48) {
18070
+ cachedSender = void 0;
18071
+ cachedKey = void 0;
18072
+ throw error48;
18073
+ }
18074
+ return decrypt(contentKey, encrypted, aad);
18075
+ }
18076
+ };
18077
+ }
18078
+ function keyCacheId(publicKey) {
18079
+ let id = "";
18080
+ for (let i = 0; i < publicKey.length; i++) {
18081
+ id += publicKey[i].toString(16).padStart(2, "0");
18082
+ }
18083
+ return id;
18084
+ }
18085
+ function decodeRunPublicKey(value) {
18086
+ if (!value) return void 0;
18087
+ const bytes = base64ToBytes(value);
18088
+ if (!bytes || bytes.byteLength !== X25519_KEY_LENGTH) return void 0;
18089
+ return bytes;
18090
+ }
18091
+ var X25519_KEY_LENGTH, CONTENT_KEY_LENGTH, SCALAR_INFO, CONTENT_KEY_INFO, PKCS8_X25519_PREFIX, infoEncoder, BASE64_CHARS, BASE64URL_CHARS;
18092
+ var init_sealed_box = __esm({
18093
+ "../core/dist/sealed-box.js"() {
18094
+ "use strict";
18095
+ init_dist2();
18096
+ init_encryption();
18097
+ X25519_KEY_LENGTH = 32;
18098
+ CONTENT_KEY_LENGTH = 32;
18099
+ SCALAR_INFO = "workflow/encp/x25519/v1";
18100
+ CONTENT_KEY_INFO = "workflow/encp/aes256gcm/v1";
18101
+ PKCS8_X25519_PREFIX = new Uint8Array([
18102
+ 48,
18103
+ 46,
18104
+ 2,
18105
+ 1,
18106
+ 0,
18107
+ 48,
18108
+ 5,
18109
+ 6,
18110
+ 3,
18111
+ 43,
18112
+ 101,
18113
+ 110,
18114
+ 4,
18115
+ 34,
18116
+ 4,
18117
+ 32
18118
+ ]);
18119
+ infoEncoder = new TextEncoder();
18120
+ __name(assertKeyMaterialLength, "assertKeyMaterialLength");
18121
+ __name(assertPublicKeyLength, "assertPublicKeyLength");
18122
+ __name(deriveRunKeyPair, "deriveRunKeyPair");
18123
+ __name(derivePublicKeyFromScalar, "derivePublicKeyFromScalar");
18124
+ __name(importScalar, "importScalar");
18125
+ __name(importPublicKey, "importPublicKey");
18126
+ BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
18127
+ BASE64URL_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
18128
+ __name(bytesToBase64, "bytesToBase64");
18129
+ __name(base64ToBytes, "base64ToBytes");
18130
+ __name(base64UrlToBytes, "base64UrlToBytes");
18131
+ __name(deriveContentKey, "deriveContentKey");
18132
+ __name(encapsulate, "encapsulate");
18133
+ __name(decapsulate, "decapsulate");
18134
+ __name(seal, "seal");
18135
+ __name(open, "open");
18136
+ __name(createSealSession, "createSealSession");
18137
+ __name(createOpenSession, "createOpenSession");
18138
+ __name(keyCacheId, "keyCacheId");
18139
+ __name(decodeRunPublicKey, "decodeRunPublicKey");
18140
+ }
18141
+ });
18142
+
18143
+ // ../core/dist/serialization/types.js
18144
+ function isFormatPrefix(value) {
18145
+ return value.length === 4 && /^[a-z0-9]{4}$/.test(value);
18146
+ }
18147
+ var SerializationFormat;
18148
+ var init_types = __esm({
18149
+ "../core/dist/serialization/types.js"() {
18150
+ "use strict";
18151
+ __name(isFormatPrefix, "isFormatPrefix");
18152
+ SerializationFormat = {
18153
+ /** devalue stringify/parse with TextEncoder/TextDecoder */
18154
+ DEVALUE_V1: "devl",
18155
+ /** Encrypted payload (inner payload has its own format prefix) */
18156
+ ENCRYPTED: "encr",
18157
+ /**
18158
+ * Sealed payload — asymmetrically encrypted to a run's X25519 public key
18159
+ * (inner payload has its own format prefix).
18160
+ *
18161
+ * Used for *cross-run* writes (hook payloads, forwarded stream frames),
18162
+ * where the writer holds only the recipient run's public key and therefore
18163
+ * cannot decrypt. A run's own payloads continue to use {@link ENCRYPTED}.
18164
+ * See `sealed-box.ts` for the construction.
18165
+ */
18166
+ SEALED: "encp",
18167
+ /** Gzip-compressed payload (inner payload has its own format prefix) */
18168
+ GZIP: "gzip",
18169
+ /** Zstandard-compressed payload (inner payload has its own format prefix) */
18170
+ ZSTD: "zstd"
18171
+ };
18172
+ }
18173
+ });
18174
+
18175
+ // ../core/dist/serialization/format.js
18176
+ function encodeWithFormatPrefix(format, payload) {
18177
+ if (!(payload instanceof Uint8Array)) {
18178
+ return payload;
18179
+ }
18180
+ const prefixBytes = formatEncoder.encode(format);
18181
+ const result = new Uint8Array(FORMAT_PREFIX_LENGTH + payload.length);
18182
+ result.set(prefixBytes, 0);
18183
+ result.set(payload, FORMAT_PREFIX_LENGTH);
18184
+ return result;
18185
+ }
18186
+ function peekFormatPrefix(data) {
18187
+ if (!(data instanceof Uint8Array) || data.length < FORMAT_PREFIX_LENGTH) {
18188
+ return null;
18189
+ }
18190
+ const prefixBytes = data.subarray(0, FORMAT_PREFIX_LENGTH);
18191
+ const str = formatDecoder.decode(prefixBytes);
18192
+ return isFormatPrefix(str) ? str : null;
18193
+ }
18194
+ function decodeFormatPrefix(data) {
18195
+ if (!(data instanceof Uint8Array)) {
18196
+ return {
18197
+ format: SerializationFormat.DEVALUE_V1,
18198
+ payload: new TextEncoder().encode(JSON.stringify(data))
18199
+ };
18200
+ }
18201
+ if (data.length < FORMAT_PREFIX_LENGTH) {
18202
+ throw new Error(`Data too short to contain format prefix: expected at least ${FORMAT_PREFIX_LENGTH} bytes, got ${data.length}`);
18203
+ }
18204
+ const prefixBytes = data.subarray(0, FORMAT_PREFIX_LENGTH);
18205
+ const str = formatDecoder.decode(prefixBytes);
18206
+ if (!isFormatPrefix(str)) {
18207
+ throw new Error(`Invalid format prefix: "${str}". Must be 4 characters of [a-z0-9].`);
18208
+ }
18209
+ const payload = data.subarray(FORMAT_PREFIX_LENGTH);
18210
+ return {
18211
+ format: str,
18212
+ payload
18213
+ };
18214
+ }
18215
+ var FORMAT_PREFIX_LENGTH, formatEncoder, formatDecoder;
18216
+ var init_format = __esm({
18217
+ "../core/dist/serialization/format.js"() {
18218
+ "use strict";
18219
+ init_types();
18220
+ FORMAT_PREFIX_LENGTH = 4;
18221
+ formatEncoder = new TextEncoder();
18222
+ formatDecoder = new TextDecoder();
18223
+ __name(encodeWithFormatPrefix, "encodeWithFormatPrefix");
18224
+ __name(peekFormatPrefix, "peekFormatPrefix");
18225
+ __name(decodeFormatPrefix, "decodeFormatPrefix");
18226
+ }
18227
+ });
18228
+
18229
+ // ../core/dist/serialization/encryption.js
18230
+ function sealTo(recipientPublicKey, aad) {
18231
+ return {
18232
+ [SEAL_TARGET_BRAND]: true,
18233
+ recipientPublicKey,
18234
+ aad
18235
+ };
18236
+ }
18237
+ function runPayloadKeys(aes, keyPair, aad) {
18238
+ return {
18239
+ [RUN_KEYS_BRAND]: true,
18240
+ aes,
18241
+ keyPair,
18242
+ aad
18243
+ };
18244
+ }
18245
+ async function deriveRunPayloadKeys(runKeyMaterial) {
18246
+ const [aes, keyPair] = await Promise.all([
18247
+ importKey(runKeyMaterial),
18248
+ deriveRunKeyPair(runKeyMaterial)
18249
+ ]);
18250
+ return runPayloadKeys(aes, keyPair);
18251
+ }
18252
+ function isSealTarget(value) {
18253
+ return typeof value === "object" && value !== null && value[SEAL_TARGET_BRAND] === true;
18254
+ }
18255
+ function isRunPayloadKeys(value) {
18256
+ return typeof value === "object" && value !== null && value[RUN_KEYS_BRAND] === true;
18257
+ }
18258
+ function aesKeyOf(key) {
18259
+ if (!key) return void 0;
18260
+ if (isRunPayloadKeys(key)) return key.aes;
18261
+ if (isSealTarget(key)) return void 0;
18262
+ return key;
18263
+ }
18264
+ async function resolveEncryptionKey(key) {
18265
+ return typeof key === "function" ? key() : key;
18266
+ }
18267
+ async function encrypt2(data, key) {
18268
+ if (!key || !(data instanceof Uint8Array)) return data;
18269
+ if (isSealTarget(key)) {
18270
+ const sealed = await seal(key.recipientPublicKey, data, key.aad);
18271
+ return encodeWithFormatPrefix(SerializationFormat.SEALED, sealed);
18272
+ }
18273
+ const aesKey = isRunPayloadKeys(key) ? key.aes : key;
18274
+ const encrypted = await encrypt(aesKey, data);
18275
+ return encodeWithFormatPrefix(SerializationFormat.ENCRYPTED, encrypted);
18276
+ }
18277
+ async function openSealedEnvelope(data, key) {
18278
+ if (!isRunPayloadKeys(key)) {
18279
+ throw new RuntimeDecryptionError("Sealed data encountered but no run keypair is available. Opening a sealed payload requires the run's own encryption key material; a symmetric key or a seal-only target cannot decrypt it.", {
18280
+ context: {
18281
+ operation: "decrypt",
18282
+ byteLength: data.byteLength,
18283
+ formatPrefix: "encp"
18284
+ }
18285
+ });
18286
+ }
18287
+ const { payload } = decodeFormatPrefix(data);
18288
+ try {
18289
+ return await open(key.keyPair, payload, key.aad);
18290
+ } catch (error48) {
18291
+ if (RuntimeDecryptionError.is(error48) && error48.context) {
18292
+ error48.context.formatPrefix = SerializationFormat.SEALED;
18293
+ }
18294
+ throw error48;
18295
+ }
18296
+ }
18297
+ async function decrypt2(data, key) {
18298
+ if (!(data instanceof Uint8Array)) return data;
18299
+ const format = peekFormatPrefix(data);
18300
+ if (format === SerializationFormat.SEALED) {
18301
+ return openSealedEnvelope(data, key);
18302
+ }
18303
+ if (format !== SerializationFormat.ENCRYPTED) return data;
18304
+ const aesKey = aesKeyOf(key);
18305
+ if (!aesKey) {
18306
+ throw new RuntimeDecryptionError("Encrypted data encountered but no encryption key is available. Encryption is not configured or no key was provided for this run.", {
18307
+ context: {
18308
+ operation: "decrypt",
18309
+ byteLength: data.byteLength,
18310
+ formatPrefix: "encr"
18311
+ }
18312
+ });
18313
+ }
18314
+ const { payload } = decodeFormatPrefix(data);
18315
+ try {
18316
+ return await decrypt(aesKey, payload);
18317
+ } catch (error48) {
18318
+ if (RuntimeDecryptionError.is(error48) && error48.context) {
18319
+ error48.context.formatPrefix = format;
18320
+ }
18321
+ throw error48;
18322
+ }
18323
+ }
18324
+ var SEAL_TARGET_BRAND, RUN_KEYS_BRAND;
18325
+ var init_encryption2 = __esm({
18326
+ "../core/dist/serialization/encryption.js"() {
18327
+ "use strict";
18328
+ init_dist2();
18329
+ init_encryption();
18330
+ init_sealed_box();
18331
+ init_format();
18332
+ init_types();
18333
+ SEAL_TARGET_BRAND = /* @__PURE__ */ Symbol.for("workflow.serialization.sealTarget");
18334
+ RUN_KEYS_BRAND = /* @__PURE__ */ Symbol.for("workflow.serialization.runKeys");
18335
+ __name(sealTo, "sealTo");
18336
+ __name(runPayloadKeys, "runPayloadKeys");
18337
+ __name(deriveRunPayloadKeys, "deriveRunPayloadKeys");
18338
+ __name(isSealTarget, "isSealTarget");
18339
+ __name(isRunPayloadKeys, "isRunPayloadKeys");
18340
+ __name(aesKeyOf, "aesKeyOf");
18341
+ __name(resolveEncryptionKey, "resolveEncryptionKey");
18342
+ __name(encrypt2, "encrypt");
18343
+ __name(openSealedEnvelope, "openSealedEnvelope");
18344
+ __name(decrypt2, "decrypt");
18345
+ }
18346
+ });
18347
+
18348
+ // ../../node_modules/.pnpm/devalue@5.8.1/node_modules/devalue/src/constants.js
18349
+ var UNDEFINED, HOLE, NAN, POSITIVE_INFINITY, NEGATIVE_INFINITY, NEGATIVE_ZERO, SPARSE, MAX_ARRAY_LEN, MAX_ARRAY_INDEX;
18350
+ var init_constants = __esm({
18351
+ "../../node_modules/.pnpm/devalue@5.8.1/node_modules/devalue/src/constants.js"() {
18352
+ "use strict";
18353
+ UNDEFINED = -1;
18354
+ HOLE = -2;
18355
+ NAN = -3;
18356
+ POSITIVE_INFINITY = -4;
18357
+ NEGATIVE_INFINITY = -5;
18358
+ NEGATIVE_ZERO = -6;
18359
+ SPARSE = -7;
18360
+ MAX_ARRAY_LEN = 2 ** 32 - 1;
18361
+ MAX_ARRAY_INDEX = MAX_ARRAY_LEN - 1;
18362
+ }
18363
+ });
18364
+
18365
+ // ../../node_modules/.pnpm/devalue@5.8.1/node_modules/devalue/src/utils.js
18366
+ function is_primitive(thing) {
18367
+ return thing === null || typeof thing !== "object" && typeof thing !== "function";
18368
+ }
18369
+ function is_plain_object(thing) {
18370
+ const proto = Object.getPrototypeOf(thing);
18371
+ return proto === Object.prototype || proto === null || Object.getPrototypeOf(proto) === null || Object.getOwnPropertyNames(proto).sort().join("\0") === object_proto_names;
18372
+ }
18373
+ function get_type(thing) {
18374
+ return Object.prototype.toString.call(thing).slice(8, -1);
18375
+ }
18376
+ function get_escaped_char(char) {
18377
+ switch (char) {
18378
+ case '"':
18379
+ return '\\"';
18380
+ case "<":
18381
+ return "\\u003C";
18382
+ case "\\":
18383
+ return "\\\\";
18384
+ case "\n":
18385
+ return "\\n";
18386
+ case "\r":
18387
+ return "\\r";
18388
+ case " ":
18389
+ return "\\t";
18390
+ case "\b":
18391
+ return "\\b";
18392
+ case "\f":
18393
+ return "\\f";
18394
+ case "\u2028":
18395
+ return "\\u2028";
18396
+ case "\u2029":
18397
+ return "\\u2029";
18398
+ default:
18399
+ return char < " " ? `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}` : "";
18400
+ }
18401
+ }
18402
+ function stringify_string(str) {
18403
+ let result = "";
18404
+ let last_pos = 0;
18405
+ const len = str.length;
18406
+ for (let i = 0; i < len; i += 1) {
18407
+ const char = str[i];
18408
+ const replacement = get_escaped_char(char);
18409
+ if (replacement) {
18410
+ result += str.slice(last_pos, i) + replacement;
18411
+ last_pos = i + 1;
18412
+ }
18413
+ }
18414
+ return `"${last_pos === 0 ? str : result + str.slice(last_pos)}"`;
18415
+ }
18416
+ function enumerable_symbols(object2) {
18417
+ return Object.getOwnPropertySymbols(object2).filter((symbol2) => Object.getOwnPropertyDescriptor(object2, symbol2).enumerable);
18418
+ }
18419
+ function stringify_key(key) {
18420
+ return is_identifier.test(key) ? "." + key : "[" + JSON.stringify(key) + "]";
18421
+ }
18422
+ function is_valid_array_index(n) {
18423
+ if (!Number.isInteger(n)) return false;
18424
+ if (n < 0) return false;
18425
+ if (n > MAX_ARRAY_INDEX) return false;
18426
+ return true;
18427
+ }
18428
+ function is_valid_array_len(n) {
18429
+ if (!Number.isInteger(n)) return false;
18430
+ if (n < 0) return false;
18431
+ if (n > MAX_ARRAY_LEN) return false;
18432
+ return true;
18433
+ }
18434
+ function is_valid_array_index_string(s) {
18435
+ if (s.length === 0) return false;
18436
+ if (s.length > 1 && s.charCodeAt(0) === 48) return false;
18437
+ for (let i = 0; i < s.length; i++) {
18438
+ const c = s.charCodeAt(i);
18439
+ if (c < 48 || c > 57) return false;
18440
+ }
18441
+ return is_valid_array_index(+s);
18442
+ }
18443
+ function valid_array_indices(array2) {
18444
+ const keys = Object.keys(array2);
18445
+ for (var i = keys.length - 1; i >= 0; i--) {
18446
+ if (is_valid_array_index_string(keys[i])) {
18447
+ break;
18448
+ }
18449
+ }
18450
+ keys.length = i + 1;
18451
+ return keys;
18452
+ }
18453
+ var DevalueError, object_proto_names, is_identifier;
18454
+ var init_utils = __esm({
18455
+ "../../node_modules/.pnpm/devalue@5.8.1/node_modules/devalue/src/utils.js"() {
18456
+ "use strict";
18457
+ init_constants();
18458
+ DevalueError = class extends Error {
18459
+ static {
18460
+ __name(this, "DevalueError");
18461
+ }
18462
+ /**
18463
+ * @param {string} message
18464
+ * @param {string[]} keys
18465
+ * @param {any} [value] - The value that failed to be serialized
18466
+ * @param {any} [root] - The root value being serialized
18467
+ */
18468
+ constructor(message, keys, value, root) {
18469
+ super(message);
18470
+ this.name = "DevalueError";
18471
+ this.path = keys.join("");
18472
+ this.value = value;
18473
+ this.root = root;
18474
+ }
18475
+ };
18476
+ __name(is_primitive, "is_primitive");
18477
+ object_proto_names = /* @__PURE__ */ Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
18478
+ __name(is_plain_object, "is_plain_object");
18479
+ __name(get_type, "get_type");
18480
+ __name(get_escaped_char, "get_escaped_char");
18481
+ __name(stringify_string, "stringify_string");
17837
18482
  __name(enumerable_symbols, "enumerable_symbols");
17838
18483
  is_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
17839
18484
  __name(stringify_key, "stringify_key");
@@ -18331,7 +18976,7 @@ var init_devalue = __esm({
18331
18976
  });
18332
18977
 
18333
18978
  // ../core/dist/symbols.js
18334
- var STABLE_ULID, STREAM_NAME_SYMBOL, STREAM_TYPE_SYMBOL, STREAM_FRAMING_SYMBOL, STREAM_SERVER_RUN_ID_SYMBOL, STREAM_SERVER_DEPLOYMENT_ID_SYMBOL, STREAM_WRITE_BATCH_SYMBOL, BODY_INIT_SYMBOL, WEBHOOK_RESPONSE_WRITABLE, WORKFLOW_CLASS_REGISTRY, ABORT_STREAM_NAME, ABORT_HOOK_TOKEN, ABORT_LISTENER_ATTACHED, ABORT_READER_CANCEL;
18979
+ var STABLE_ULID, STREAM_NAME_SYMBOL, STREAM_TYPE_SYMBOL, STREAM_FRAMING_SYMBOL, STREAM_SERVER_RUN_ID_SYMBOL, STREAM_SERVER_DEPLOYMENT_ID_SYMBOL, STREAM_SERVER_PUBLIC_KEY_SYMBOL, STREAM_DRAIN_SYMBOL, BODY_INIT_SYMBOL, WEBHOOK_RESPONSE_WRITABLE, WORKFLOW_CLASS_REGISTRY, ABORT_STREAM_NAME, ABORT_HOOK_TOKEN, ABORT_LISTENER_ATTACHED, ABORT_READER_CANCEL;
18335
18980
  var init_symbols = __esm({
18336
18981
  "../core/dist/symbols.js"() {
18337
18982
  "use strict";
@@ -18341,7 +18986,8 @@ var init_symbols = __esm({
18341
18986
  STREAM_FRAMING_SYMBOL = /* @__PURE__ */ Symbol.for("WORKFLOW_STREAM_FRAMING");
18342
18987
  STREAM_SERVER_RUN_ID_SYMBOL = /* @__PURE__ */ Symbol.for("WORKFLOW_STREAM_SERVER_RUN_ID");
18343
18988
  STREAM_SERVER_DEPLOYMENT_ID_SYMBOL = /* @__PURE__ */ Symbol.for("WORKFLOW_STREAM_SERVER_DEPLOYMENT_ID");
18344
- STREAM_WRITE_BATCH_SYMBOL = /* @__PURE__ */ Symbol.for("WORKFLOW_STREAM_WRITE_BATCH");
18989
+ STREAM_SERVER_PUBLIC_KEY_SYMBOL = /* @__PURE__ */ Symbol.for("WORKFLOW_STREAM_SERVER_PUBLIC_KEY");
18990
+ STREAM_DRAIN_SYMBOL = /* @__PURE__ */ Symbol.for("WORKFLOW_STREAM_DRAIN");
18345
18991
  BODY_INIT_SYMBOL = /* @__PURE__ */ Symbol.for("BODY_INIT");
18346
18992
  WEBHOOK_RESPONSE_WRITABLE = /* @__PURE__ */ Symbol.for("WEBHOOK_RESPONSE_WRITABLE");
18347
18993
  WORKFLOW_CLASS_REGISTRY = /* @__PURE__ */ Symbol.for("workflow-class-registry");
@@ -18394,6 +19040,14 @@ function isReadableUnlockedNotClosed(readable) {
18394
19040
  }
18395
19041
  return true;
18396
19042
  }
19043
+ function resolveAfterDrain(state) {
19044
+ const barrier = state.drainBarrier;
19045
+ if (!barrier) {
19046
+ state.resolve();
19047
+ return;
19048
+ }
19049
+ barrier().then(() => state.resolve(), (err) => state.reject(err));
19050
+ }
18397
19051
  function pollWritableLock(writable, state) {
18398
19052
  if (state.writablePollingInterval !== void 0) {
18399
19053
  return;
@@ -18406,9 +19060,9 @@ function pollWritableLock(writable, state) {
18406
19060
  }
18407
19061
  if (isWritableUnlockedNotClosed(writable) && state.pendingOps === 0) {
18408
19062
  state.doneResolved = true;
18409
- state.resolve();
18410
19063
  clearInterval(intervalId);
18411
19064
  state.writablePollingInterval = void 0;
19065
+ resolveAfterDrain(state);
18412
19066
  }
18413
19067
  }, getLockPollIntervalMs());
18414
19068
  state.writablePollingInterval = intervalId;
@@ -18425,147 +19079,39 @@ function pollReadableLock(readable, state) {
18425
19079
  }
18426
19080
  if (isReadableUnlockedNotClosed(readable) && state.pendingOps === 0) {
18427
19081
  state.doneResolved = true;
18428
- state.resolve();
18429
19082
  clearInterval(intervalId);
18430
19083
  state.readablePollingInterval = void 0;
19084
+ resolveAfterDrain(state);
18431
19085
  }
18432
19086
  }, getLockPollIntervalMs());
18433
19087
  state.readablePollingInterval = intervalId;
18434
19088
  }
18435
- function flushablePipe(source, sink, state) {
18436
- const batchWrite = sink[STREAM_WRITE_BATCH_SYMBOL];
18437
- return typeof batchWrite === "function" ? flushablePipeCoalescing(source, sink, state, batchWrite) : flushablePipePerChunk(source, sink, state);
18438
- }
18439
- async function flushablePipePerChunk(source, sink, state) {
18440
- const reader = source.getReader();
18441
- const writer = sink.getWriter();
18442
- let cancelReason;
18443
- try {
18444
- while (true) {
18445
- if (state.streamEnded) {
18446
- return;
18447
- }
18448
- const readResult = await Promise.race([
18449
- reader.read(),
18450
- writer.closed.then(() => {
18451
- throw new WorkflowRuntimeError("Writable stream closed prematurely");
18452
- })
18453
- ]);
18454
- if (state.streamEnded) {
18455
- return;
18456
- }
18457
- if (readResult.done) {
18458
- state.streamEnded = true;
18459
- await writer.close();
18460
- if (!state.doneResolved) {
18461
- state.doneResolved = true;
18462
- state.resolve();
18463
- }
18464
- return;
18465
- }
18466
- state.pendingOps++;
18467
- try {
18468
- await writer.write(readResult.value);
18469
- } finally {
18470
- state.pendingOps--;
18471
- }
18472
- }
18473
- } catch (err) {
18474
- state.streamEnded = true;
18475
- cancelReason = err;
18476
- if (!state.doneResolved) {
18477
- state.doneResolved = true;
18478
- state.reject(err);
18479
- }
18480
- throw err;
18481
- } finally {
18482
- reader.cancel(cancelReason).catch(() => {
18483
- });
18484
- reader.releaseLock();
18485
- writer.releaseLock();
18486
- }
18487
- }
18488
- function wake(ctx, which) {
18489
- const resolve = ctx[which];
18490
- if (resolve) {
18491
- ctx[which] = null;
18492
- resolve();
18493
- }
18494
- }
18495
- function nextBatchSize(ctx) {
18496
- let count2 = 0;
18497
- let bytes = 0;
18498
- for (const chunk of ctx.queue) {
18499
- if (count2 >= ctx.maxChunksPerBatch) break;
18500
- if (count2 > 0 && bytes + chunk.byteLength > ctx.maxBytesPerBatch) break;
18501
- count2++;
18502
- bytes += chunk.byteLength;
18503
- }
18504
- return count2;
18505
- }
18506
- async function drainBatches(ctx) {
18507
- while (true) {
18508
- if (ctx.queue.length === 0) {
18509
- if (ctx.sourceDone) return;
18510
- await new Promise((resolve) => {
18511
- ctx.wakeConsumer = resolve;
18512
- });
18513
- continue;
18514
- }
18515
- const count2 = nextBatchSize(ctx);
18516
- const batch = ctx.queue.slice(0, count2);
18517
- ctx.queue = ctx.queue.slice(count2);
18518
- await ctx.batchWrite(batch);
18519
- ctx.state.pendingOps -= batch.length;
18520
- wake(ctx, "wakeProducer");
18521
- }
18522
- }
18523
- function readNextChunk(reader, writer, consumer) {
18524
- return Promise.race([
18525
- reader.read(),
18526
- writer.closed.then(() => {
18527
- throw new WorkflowRuntimeError("Writable stream closed prematurely");
18528
- }),
18529
- consumer.then(() => {
18530
- throw new WorkflowRuntimeError("Stream consumer ended prematurely");
18531
- }, (err) => {
18532
- throw err;
18533
- })
18534
- ]);
18535
- }
18536
- async function awaitBackpressureRelief(ctx, consumer, maxInflight) {
18537
- if (ctx.state.pendingOps < maxInflight) return;
18538
- await Promise.race([
18539
- new Promise((resolve) => {
18540
- ctx.wakeProducer = resolve;
18541
- }),
18542
- consumer.then(() => void 0, () => void 0)
18543
- ]);
19089
+ function flushablePipe(source, sink, state) {
19090
+ const drain = sink[STREAM_DRAIN_SYMBOL];
19091
+ if (typeof drain === "function") {
19092
+ state.drainBarrier = drain;
19093
+ }
19094
+ return flushablePipePerChunk(source, sink, state);
18544
19095
  }
18545
- async function flushablePipeCoalescing(source, sink, state, batchWrite) {
19096
+ async function flushablePipePerChunk(source, sink, state) {
18546
19097
  const reader = source.getReader();
18547
19098
  const writer = sink.getWriter();
18548
- const maxInflight = getMaxInflightChunks();
18549
19099
  let cancelReason;
18550
- const ctx = {
18551
- state,
18552
- batchWrite,
18553
- queue: [],
18554
- sourceDone: false,
18555
- wakeConsumer: null,
18556
- wakeProducer: null,
18557
- maxChunksPerBatch: getMaxChunksPerBatch(),
18558
- maxBytesPerBatch: getMaxBytesPerBatch()
18559
- };
18560
- const consumer = drainBatches(ctx);
18561
19100
  try {
18562
- while (!state.streamEnded) {
18563
- const readResult = await readNextChunk(reader, writer, consumer);
18564
- if (state.streamEnded) return;
19101
+ while (true) {
19102
+ if (state.streamEnded) {
19103
+ return;
19104
+ }
19105
+ const readResult = await Promise.race([
19106
+ reader.read(),
19107
+ writer.closed.then(() => {
19108
+ throw new WorkflowRuntimeError("Writable stream closed prematurely");
19109
+ })
19110
+ ]);
19111
+ if (state.streamEnded) {
19112
+ return;
19113
+ }
18565
19114
  if (readResult.done) {
18566
- ctx.sourceDone = true;
18567
- wake(ctx, "wakeConsumer");
18568
- await consumer;
18569
19115
  state.streamEnded = true;
18570
19116
  await writer.close();
18571
19117
  if (!state.doneResolved) {
@@ -18574,18 +19120,20 @@ async function flushablePipeCoalescing(source, sink, state, batchWrite) {
18574
19120
  }
18575
19121
  return;
18576
19122
  }
18577
- ctx.queue.push(readResult.value);
18578
19123
  state.pendingOps++;
18579
- wake(ctx, "wakeConsumer");
18580
- await awaitBackpressureRelief(ctx, consumer, maxInflight);
19124
+ try {
19125
+ await writer.write(readResult.value);
19126
+ } finally {
19127
+ state.pendingOps--;
19128
+ }
18581
19129
  }
18582
19130
  } catch (err) {
18583
19131
  state.streamEnded = true;
18584
19132
  cancelReason = err;
18585
- ctx.sourceDone = true;
18586
- wake(ctx, "wakeConsumer");
18587
- await consumer.catch(() => {
18588
- });
19133
+ if (state.drainBarrier) {
19134
+ await state.drainBarrier().catch(() => {
19135
+ });
19136
+ }
18589
19137
  if (!state.doneResolved) {
18590
19138
  state.doneResolved = true;
18591
19139
  state.reject(err);
@@ -18598,7 +19146,7 @@ async function flushablePipeCoalescing(source, sink, state, batchWrite) {
18598
19146
  writer.releaseLock();
18599
19147
  }
18600
19148
  }
18601
- var MAX_INFLIGHT_CHUNKS, getMaxInflightChunks, MAX_CHUNKS_PER_BATCH, getMaxChunksPerBatch, MAX_BYTES_PER_BATCH, getMaxBytesPerBatch, LOCK_POLL_INTERVAL_MS, getLockPollIntervalMs;
19149
+ var MAX_INFLIGHT_CHUNKS, getMaxInflightChunks, MAX_CHUNKS_PER_BATCH, getMaxChunksPerBatch, MAX_BYTES_PER_BATCH, getMaxBytesPerBatch, MAX_BUFFERED_BYTES, getMaxBufferedBytes, LOCK_POLL_INTERVAL_MS, getLockPollIntervalMs;
18602
19150
  var init_flushable_stream = __esm({
18603
19151
  "../core/dist/flushable-stream.js"() {
18604
19152
  "use strict";
@@ -18621,6 +19169,11 @@ var init_flushable_stream = __esm({
18621
19169
  integer: true,
18622
19170
  min: 1
18623
19171
  }), "getMaxBytesPerBatch");
19172
+ MAX_BUFFERED_BYTES = 8 * 1024 * 1024;
19173
+ getMaxBufferedBytes = /* @__PURE__ */ __name(() => envNumber("WORKFLOW_STREAM_MAX_BUFFERED_BYTES", MAX_BUFFERED_BYTES, {
19174
+ integer: true,
19175
+ min: 1
19176
+ }), "getMaxBufferedBytes");
18624
19177
  LOCK_POLL_INTERVAL_MS = 10;
18625
19178
  getLockPollIntervalMs = /* @__PURE__ */ __name(() => envNumber("WORKFLOW_LOCK_POLL_INTERVAL_MS", LOCK_POLL_INTERVAL_MS, {
18626
19179
  integer: true,
@@ -18629,16 +19182,11 @@ var init_flushable_stream = __esm({
18629
19182
  __name(createFlushableState, "createFlushableState");
18630
19183
  __name(isWritableUnlockedNotClosed, "isWritableUnlockedNotClosed");
18631
19184
  __name(isReadableUnlockedNotClosed, "isReadableUnlockedNotClosed");
19185
+ __name(resolveAfterDrain, "resolveAfterDrain");
18632
19186
  __name(pollWritableLock, "pollWritableLock");
18633
19187
  __name(pollReadableLock, "pollReadableLock");
18634
19188
  __name(flushablePipe, "flushablePipe");
18635
19189
  __name(flushablePipePerChunk, "flushablePipePerChunk");
18636
- __name(wake, "wake");
18637
- __name(nextBatchSize, "nextBatchSize");
18638
- __name(drainBatches, "drainBatches");
18639
- __name(readNextChunk, "readNextChunk");
18640
- __name(awaitBackpressureRelief, "awaitBackpressureRelief");
18641
- __name(flushablePipeCoalescing, "flushablePipeCoalescing");
18642
19190
  }
18643
19191
  });
18644
19192
 
@@ -19234,28 +19782,6 @@ var init_step_function = __esm({
19234
19782
  }
19235
19783
  });
19236
19784
 
19237
- // ../core/dist/serialization/types.js
19238
- function isFormatPrefix(value) {
19239
- return value.length === 4 && /^[a-z0-9]{4}$/.test(value);
19240
- }
19241
- var SerializationFormat;
19242
- var init_types = __esm({
19243
- "../core/dist/serialization/types.js"() {
19244
- "use strict";
19245
- __name(isFormatPrefix, "isFormatPrefix");
19246
- SerializationFormat = {
19247
- /** devalue stringify/parse with TextEncoder/TextDecoder */
19248
- DEVALUE_V1: "devl",
19249
- /** Encrypted payload (inner payload has its own format prefix) */
19250
- ENCRYPTED: "encr",
19251
- /** Gzip-compressed payload (inner payload has its own format prefix) */
19252
- GZIP: "gzip",
19253
- /** Zstandard-compressed payload (inner payload has its own format prefix) */
19254
- ZSTD: "zstd"
19255
- };
19256
- }
19257
- });
19258
-
19259
19785
  // ../core/dist/serialization/codec-devalue.js
19260
19786
  function getReducersForMode(mode, global2 = globalThis, extraReducers) {
19261
19787
  let base;
@@ -19355,60 +19881,6 @@ var init_codec_devalue = __esm({
19355
19881
  }
19356
19882
  });
19357
19883
 
19358
- // ../core/dist/serialization/format.js
19359
- function encodeWithFormatPrefix(format, payload) {
19360
- if (!(payload instanceof Uint8Array)) {
19361
- return payload;
19362
- }
19363
- const prefixBytes = formatEncoder.encode(format);
19364
- const result = new Uint8Array(FORMAT_PREFIX_LENGTH + payload.length);
19365
- result.set(prefixBytes, 0);
19366
- result.set(payload, FORMAT_PREFIX_LENGTH);
19367
- return result;
19368
- }
19369
- function peekFormatPrefix(data) {
19370
- if (!(data instanceof Uint8Array) || data.length < FORMAT_PREFIX_LENGTH) {
19371
- return null;
19372
- }
19373
- const prefixBytes = data.subarray(0, FORMAT_PREFIX_LENGTH);
19374
- const str = formatDecoder.decode(prefixBytes);
19375
- return isFormatPrefix(str) ? str : null;
19376
- }
19377
- function decodeFormatPrefix(data) {
19378
- if (!(data instanceof Uint8Array)) {
19379
- return {
19380
- format: SerializationFormat.DEVALUE_V1,
19381
- payload: new TextEncoder().encode(JSON.stringify(data))
19382
- };
19383
- }
19384
- if (data.length < FORMAT_PREFIX_LENGTH) {
19385
- throw new Error(`Data too short to contain format prefix: expected at least ${FORMAT_PREFIX_LENGTH} bytes, got ${data.length}`);
19386
- }
19387
- const prefixBytes = data.subarray(0, FORMAT_PREFIX_LENGTH);
19388
- const str = formatDecoder.decode(prefixBytes);
19389
- if (!isFormatPrefix(str)) {
19390
- throw new Error(`Invalid format prefix: "${str}". Must be 4 characters of [a-z0-9].`);
19391
- }
19392
- const payload = data.subarray(FORMAT_PREFIX_LENGTH);
19393
- return {
19394
- format: str,
19395
- payload
19396
- };
19397
- }
19398
- var FORMAT_PREFIX_LENGTH, formatEncoder, formatDecoder;
19399
- var init_format = __esm({
19400
- "../core/dist/serialization/format.js"() {
19401
- "use strict";
19402
- init_types();
19403
- FORMAT_PREFIX_LENGTH = 4;
19404
- formatEncoder = new TextEncoder();
19405
- formatDecoder = new TextDecoder();
19406
- __name(encodeWithFormatPrefix, "encodeWithFormatPrefix");
19407
- __name(peekFormatPrefix, "peekFormatPrefix");
19408
- __name(decodeFormatPrefix, "decodeFormatPrefix");
19409
- }
19410
- });
19411
-
19412
19884
  // ../core/dist/serialization/compression.js
19413
19885
  function isCompressionDisabledByEnv() {
19414
19886
  try {
@@ -19568,51 +20040,6 @@ var init_compression = __esm({
19568
20040
  }
19569
20041
  });
19570
20042
 
19571
- // ../core/dist/serialization/encryption.js
19572
- async function resolveEncryptionKey(key) {
19573
- return typeof key === "function" ? key() : key;
19574
- }
19575
- async function encrypt2(data, key) {
19576
- if (!key || !(data instanceof Uint8Array)) return data;
19577
- const encrypted = await encrypt(key, data);
19578
- return encodeWithFormatPrefix(SerializationFormat.ENCRYPTED, encrypted);
19579
- }
19580
- async function decrypt2(data, key) {
19581
- if (!(data instanceof Uint8Array)) return data;
19582
- const format = peekFormatPrefix(data);
19583
- if (format === SerializationFormat.ENCRYPTED && !key) {
19584
- throw new RuntimeDecryptionError("Encrypted data encountered but no encryption key is available. Encryption is not configured or no key was provided for this run.", {
19585
- context: {
19586
- operation: "decrypt",
19587
- byteLength: data.byteLength,
19588
- formatPrefix: "encr"
19589
- }
19590
- });
19591
- }
19592
- if (format !== SerializationFormat.ENCRYPTED) return data;
19593
- const { payload } = decodeFormatPrefix(data);
19594
- try {
19595
- return await decrypt(key, payload);
19596
- } catch (error48) {
19597
- if (RuntimeDecryptionError.is(error48) && error48.context) {
19598
- error48.context.formatPrefix = format;
19599
- }
19600
- throw error48;
19601
- }
19602
- }
19603
- var init_encryption2 = __esm({
19604
- "../core/dist/serialization/encryption.js"() {
19605
- "use strict";
19606
- init_dist2();
19607
- init_encryption();
19608
- init_format();
19609
- init_types();
19610
- __name(resolveEncryptionKey, "resolveEncryptionKey");
19611
- __name(encrypt2, "encrypt");
19612
- __name(decrypt2, "decrypt");
19613
- }
19614
- });
19615
-
19616
20043
  // ../errors/dist/internal-chalk.js
19617
20044
  var colorEnabled, sgr, chalk, internal_chalk_default;
19618
20045
  var init_internal_chalk = __esm({
@@ -19625,7 +20052,7 @@ var init_internal_chalk = __esm({
19625
20052
  if (p.env.NO_COLOR) return false;
19626
20053
  return Boolean(p.stdout?.isTTY);
19627
20054
  })();
19628
- sgr = /* @__PURE__ */ __name((open, close) => (s) => colorEnabled ? `\x1B[${open}m${s}\x1B[${close}m` : s, "sgr");
20055
+ sgr = /* @__PURE__ */ __name((open2, close) => (s) => colorEnabled ? `\x1B[${open2}m${s}\x1B[${close}m` : s, "sgr");
19629
20056
  chalk = {
19630
20057
  bold: sgr(1, 22),
19631
20058
  dim: sgr(2, 22),
@@ -22540,6 +22967,7 @@ var init_abort_controller = __esm({
22540
22967
  "use strict";
22541
22968
  init_dist2();
22542
22969
  init_events_consumer();
22970
+ init_private();
22543
22971
  init_serialization2();
22544
22972
  init_symbols();
22545
22973
  init_util2();
@@ -24620,6 +25048,15 @@ var init_capabilities = __esm({
24620
25048
  {
24621
25049
  format: SerializationFormat.ZSTD,
24622
25050
  minVersion: "5.0.0-beta.18"
25051
+ },
25052
+ // TODO(release): verify this matches the actual version that ships sealed-box
25053
+ // encryption. If a "Version Packages (beta)" PR merges before this change,
25054
+ // bump to the next beta. Unlike the entries above, a wrong cutoff here is
25055
+ // not a correctness hazard: producers gate `encp` on the target run carrying
25056
+ // an `encryptionPublicKey`, not on this table (see History above).
25057
+ {
25058
+ format: SerializationFormat.SEALED,
25059
+ minVersion: "5.0.0-beta.37"
24623
25060
  }
24624
25061
  ];
24625
25062
  CAPABILITY_VERSION_TABLE = [
@@ -24640,7 +25077,7 @@ var version2;
24640
25077
  var init_version = __esm({
24641
25078
  "../core/dist/version.js"() {
24642
25079
  "use strict";
24643
- version2 = "5.0.0-beta.36";
25080
+ version2 = "5.0.0-beta.38";
24644
25081
  }
24645
25082
  });
24646
25083
 
@@ -24726,18 +25163,24 @@ function parseHealthCheckResponse(chunks) {
24726
25163
  if (typeof r.workflowCoreVersion === "string") {
24727
25164
  parsed.workflowCoreVersion = r.workflowCoreVersion;
24728
25165
  }
25166
+ if (typeof r.encryptionPublicKey === "string") {
25167
+ parsed.encryptionPublicKey = r.encryptionPublicKey;
25168
+ }
24729
25169
  return parsed;
24730
25170
  }
24731
- async function healthCheck(world, endpoint, options) {
25171
+ async function healthCheck(world, options) {
24732
25172
  const timeout = options?.timeout ?? DEFAULT_HEALTH_CHECK_TIMEOUT;
24733
25173
  const correlationId = world.createRunId?.() ?? generateId();
24734
25174
  const streamName = getHealthCheckStreamName(correlationId);
24735
- const queueName = `${getQueueTopicPrefix(endpoint, resolveQueueNamespace(options?.namespace))}health_check`;
25175
+ const queueName = `${getQueueTopicPrefix("workflow", resolveQueueNamespace(options?.namespace))}health_check`;
24736
25176
  const startTime = Date.now();
24737
25177
  try {
24738
25178
  await world.queue(queueName, {
24739
25179
  __healthCheck: true,
24740
- correlationId
25180
+ correlationId,
25181
+ ...options?.runId ? {
25182
+ runId: options.runId
25183
+ } : {}
24741
25184
  }, {
24742
25185
  // Use JSON transport so the health check works against both
24743
25186
  // old (JSON-only) and new (dual) deployments.
@@ -24788,8 +25231,9 @@ var init_helpers = __esm({
24788
25231
  init_dist2();
24789
25232
  init_dist4();
24790
25233
  init_node();
24791
- init_encryption();
24792
25234
  init_logger();
25235
+ init_sealed_box();
25236
+ init_encryption2();
24793
25237
  init_semantic_conventions();
24794
25238
  init_telemetry();
24795
25239
  init_version();
@@ -25981,20 +26425,49 @@ __export(resume_hook_exports, {
25981
26425
  resumeHook: () => resumeHook,
25982
26426
  resumeWebhook: () => resumeWebhook
25983
26427
  });
25984
- async function getHookAndRun(token) {
25985
- const world = await getWorldLazy();
25986
- const hook = await world.hooks.getByToken(token);
25987
- const run2 = await world.runs.get(hook.runId);
26428
+ function resumeContextFromRun(run2) {
26429
+ const coreVersion = run2.executionContext?.workflowCoreVersion;
26430
+ const traceCarrier = run2.executionContext?.traceCarrier;
25988
26431
  return {
25989
- hook,
26432
+ deploymentId: run2.deploymentId,
26433
+ workflowName: run2.workflowName,
26434
+ runSpecVersion: run2.specVersion,
26435
+ workflowCoreVersion: typeof coreVersion === "string" ? coreVersion : void 0,
26436
+ traceCarrier: traceCarrier && typeof traceCarrier === "object" ? traceCarrier : void 0,
26437
+ encryptionPublicKey: run2.encryptionPublicKey
26438
+ };
26439
+ }
26440
+ async function resolveHookResumeInfo(hook) {
26441
+ if (hook.resumeContext) {
26442
+ return {
26443
+ resumeContext: hook.resumeContext,
26444
+ source: "hook"
26445
+ };
26446
+ }
26447
+ const run2 = await (await getWorldLazy()).runs.get(hook.runId);
26448
+ return {
26449
+ resumeContext: resumeContextFromRun(run2),
26450
+ source: "run_fallback",
25990
26451
  run: run2
25991
26452
  };
25992
26453
  }
26454
+ async function resolveHookEncryptionKey(hook, info) {
26455
+ const world = await getWorldLazy();
26456
+ const rawKey = info.run ? await world.getEncryptionKeyForRun?.(info.run) : await world.getEncryptionKeyForRun?.(hook.runId, {
26457
+ deploymentId: info.resumeContext.deploymentId
26458
+ });
26459
+ return rawKey ? await importKey(rawKey) : void 0;
26460
+ }
25993
26461
  async function getHookByTokenWithKey(token) {
25994
- const { hook, run: run2 } = await getHookAndRun(token);
25995
- const rawKey = await (await getWorldLazy()).getEncryptionKeyForRun?.(run2);
25996
- const encryptionKey = rawKey ? await importKey(rawKey) : void 0;
26462
+ const world = await getWorldLazy();
26463
+ const hook = await world.hooks.getByToken(token);
26464
+ let encryptionKey;
25997
26465
  if (typeof hook.metadata !== "undefined") {
26466
+ const info = await resolveHookResumeInfo(hook);
26467
+ const rawKey = info.run ? await world.getEncryptionKeyForRun?.(info.run) : await world.getEncryptionKeyForRun?.(hook.runId, {
26468
+ deploymentId: info.resumeContext.deploymentId
26469
+ });
26470
+ encryptionKey = rawKey ? await deriveRunPayloadKeys(rawKey) : void 0;
25998
26471
  hook.metadata = await hydrateStepArguments(hook.metadata, hook.runId, encryptionKey);
25999
26472
  }
26000
26473
  return {
@@ -26011,38 +26484,38 @@ async function resumeHook(tokenOrHook, payload, encryptionKeyOverride) {
26011
26484
  return trace("hook.resume", async (span) => {
26012
26485
  const world = await getWorldLazy();
26013
26486
  try {
26014
- let hook;
26015
- let workflowRun;
26016
- if (typeof tokenOrHook === "string") {
26017
- const result = await getHookAndRun(tokenOrHook);
26018
- hook = result.hook;
26019
- workflowRun = result.run;
26020
- } else {
26021
- hook = tokenOrHook;
26022
- workflowRun = await world.runs.get(hook.runId);
26023
- }
26487
+ const hook = typeof tokenOrHook === "string" ? await world.hooks.getByToken(tokenOrHook) : tokenOrHook;
26488
+ const info = await resolveHookResumeInfo(hook);
26489
+ const { resumeContext } = info;
26024
26490
  span?.setAttributes({
26025
26491
  ...HookToken(hook.token),
26026
26492
  ...HookId(hook.hookId),
26027
- ...WorkflowRunId(hook.runId)
26493
+ ...WorkflowRunId(hook.runId),
26494
+ "workflow.hook.resume_context_source": info.source
26028
26495
  });
26029
- if (isTerminalWorkflowRunStatus(workflowRun.status)) {
26496
+ if (info.run && isTerminalWorkflowRunStatus(info.run.status)) {
26030
26497
  throw new HookNotFoundError(hook.token);
26031
26498
  }
26032
- let encryptionKey = encryptionKeyOverride;
26033
- if (!encryptionKey) {
26034
- const rawKey = await world.getEncryptionKeyForRun?.(workflowRun);
26035
- encryptionKey = rawKey ? await importKey(rawKey) : void 0;
26036
- }
26037
- const rawVersion = workflowRun.executionContext?.workflowCoreVersion;
26038
- const capabilities = getRunCapabilities(typeof rawVersion === "string" ? rawVersion : void 0);
26039
- if (!capabilities.supportedFormats.has(SerializationFormat.ENCRYPTED)) {
26040
- encryptionKey = void 0;
26499
+ const capabilities = getRunCapabilities(resumeContext.workflowCoreVersion);
26500
+ let payloadKey;
26501
+ const runPublicKey = encryptionKeyOverride ? (
26502
+ // hydrate hook metadata), so sealing would add an ECDH for no
26503
+ // saved round trip. Reuse what it resolved.
26504
+ void 0
26505
+ ) : decodeRunPublicKey(resumeContext.encryptionPublicKey);
26506
+ if (runPublicKey) {
26507
+ payloadKey = sealTo(runPublicKey);
26508
+ } else {
26509
+ let encryptionKey = encryptionKeyOverride ?? await resolveHookEncryptionKey(hook, info);
26510
+ if (!capabilities.supportedFormats.has(SerializationFormat.ENCRYPTED)) {
26511
+ encryptionKey = void 0;
26512
+ }
26513
+ payloadKey = encryptionKey;
26041
26514
  }
26042
- const compression = (workflowRun.specVersion ?? 0) >= SPEC_VERSION_SUPPORTS_COMPRESSION && capabilities.supportedFormats.has(SerializationFormat.GZIP);
26515
+ const compression = (resumeContext.runSpecVersion ?? 0) >= SPEC_VERSION_SUPPORTS_COMPRESSION && capabilities.supportedFormats.has(SerializationFormat.GZIP);
26043
26516
  const ops = [];
26044
26517
  const v1Compat = isLegacySpecVersion(hook.specVersion);
26045
- const dehydratedPayload = await dehydrateStepReturnValue(payload, hook.runId, encryptionKey, ops, globalThis, v1Compat, capabilities.framedByteStreams, compression);
26518
+ const dehydratedPayload = await dehydrateStepReturnValue(payload, hook.runId, payloadKey, ops, globalThis, v1Compat, capabilities.framedByteStreams, compression);
26046
26519
  safeWaitUntil(Promise.all(ops), (err) => {
26047
26520
  if (err === void 0) return;
26048
26521
  runtimeLogger.warn("Background flush of hook payload ops failed", {
@@ -26051,33 +26524,40 @@ async function resumeHook(tokenOrHook, payload, encryptionKeyOverride) {
26051
26524
  error: err instanceof Error ? err.message : String(err)
26052
26525
  });
26053
26526
  });
26054
- await world.events.create(hook.runId, {
26055
- eventType: "hook_received",
26056
- specVersion: SPEC_VERSION_CURRENT,
26057
- correlationId: hook.hookId,
26058
- eventData: {
26059
- ...v1Compat ? {} : {
26060
- token: hook.token
26061
- },
26062
- payload: dehydratedPayload
26527
+ try {
26528
+ await world.events.create(hook.runId, {
26529
+ eventType: "hook_received",
26530
+ specVersion: SPEC_VERSION_CURRENT,
26531
+ correlationId: hook.hookId,
26532
+ eventData: {
26533
+ ...v1Compat ? {} : {
26534
+ token: hook.token
26535
+ },
26536
+ payload: dehydratedPayload
26537
+ }
26538
+ }, {
26539
+ v1Compat
26540
+ });
26541
+ } catch (err) {
26542
+ if (HookNotFoundError.is(err) || EntityConflictError.is(err) || RunExpiredError.is(err)) {
26543
+ throw new HookNotFoundError(hook.token);
26063
26544
  }
26064
- }, {
26065
- v1Compat
26066
- });
26545
+ throw err;
26546
+ }
26067
26547
  span?.setAttributes({
26068
- ...WorkflowName(workflowRun.workflowName)
26548
+ ...WorkflowName(resumeContext.workflowName)
26069
26549
  });
26070
- const originLink = await linkToTraceCarrier(workflowRun.executionContext?.traceCarrier);
26550
+ const originLink = await linkToTraceCarrier(resumeContext.traceCarrier);
26071
26551
  if (originLink) {
26072
26552
  span?.addLink?.(originLink);
26073
26553
  }
26074
- await world.queue(getWorkflowQueueName(workflowRun.workflowName), {
26554
+ await world.queue(getWorkflowQueueName(resumeContext.workflowName), {
26075
26555
  runId: hook.runId,
26076
- // attach the trace carrier from the workflow run
26077
- traceCarrier: workflowRun.executionContext?.traceCarrier ?? void 0
26556
+ // attach the trace carrier from the run's resume context
26557
+ traceCarrier: resumeContext.traceCarrier ?? void 0
26078
26558
  }, {
26079
- deploymentId: workflowRun.deploymentId,
26080
- specVersion: workflowRun.specVersion ?? SPEC_VERSION_LEGACY
26559
+ deploymentId: resumeContext.deploymentId,
26560
+ specVersion: resumeContext.runSpecVersion ?? SPEC_VERSION_LEGACY
26081
26561
  });
26082
26562
  return hook;
26083
26563
  } catch (err) {
@@ -26138,6 +26618,8 @@ var init_resume_hook = __esm({
26138
26618
  init_capabilities();
26139
26619
  init_encryption();
26140
26620
  init_logger();
26621
+ init_sealed_box();
26622
+ init_encryption2();
26141
26623
  init_serialization2();
26142
26624
  init_symbols();
26143
26625
  init_semantic_conventions();
@@ -26145,7 +26627,9 @@ var init_resume_hook = __esm({
26145
26627
  init_get_world_lazy();
26146
26628
  init_helpers();
26147
26629
  init_wait_until();
26148
- __name(getHookAndRun, "getHookAndRun");
26630
+ __name(resumeContextFromRun, "resumeContextFromRun");
26631
+ __name(resolveHookResumeInfo, "resolveHookResumeInfo");
26632
+ __name(resolveHookEncryptionKey, "resolveHookEncryptionKey");
26149
26633
  __name(getHookByTokenWithKey, "getHookByTokenWithKey");
26150
26634
  __name(getHookByToken, "getHookByToken");
26151
26635
  __name(resumeHook, "resumeHook");
@@ -26198,19 +26682,24 @@ function getSerializeStream(reducers, cryptoKey) {
26198
26682
  resolved: false,
26199
26683
  key: void 0
26200
26684
  };
26685
+ let sealSession;
26201
26686
  const stream = new TransformStream({
26202
26687
  async transform(chunk, controller) {
26203
26688
  try {
26204
26689
  if (!keyState.resolved) {
26205
26690
  keyState.key = await resolveEncryptionKey(cryptoKey);
26206
26691
  keyState.resolved = true;
26692
+ if (isSealTarget(keyState.key)) {
26693
+ sealSession = createSealSession(keyState.key.recipientPublicKey, keyState.key.aad);
26694
+ }
26207
26695
  }
26208
26696
  const serialized = stringify(chunk, reducers);
26209
26697
  const payload = encoder2.encode(serialized);
26210
26698
  let prefixed = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
26211
- if (keyState.key) {
26212
- const encrypted = await encrypt(keyState.key, prefixed);
26213
- prefixed = encodeWithFormatPrefix(SerializationFormat.ENCRYPTED, encrypted);
26699
+ if (sealSession) {
26700
+ prefixed = encodeWithFormatPrefix(SerializationFormat.SEALED, await sealSession.seal(prefixed));
26701
+ } else if (keyState.key) {
26702
+ prefixed = await encrypt2(prefixed, keyState.key);
26214
26703
  }
26215
26704
  const frame2 = new Uint8Array(FRAME_HEADER_SIZE + prefixed.length);
26216
26705
  new DataView(frame2.buffer).setUint32(0, prefixed.length, false);
@@ -26238,6 +26727,7 @@ function getDeserializeStream(revivers, cryptoKey) {
26238
26727
  resolved: false,
26239
26728
  key: void 0
26240
26729
  };
26730
+ let openSession;
26241
26731
  function appendToBuffer(data) {
26242
26732
  const newBuffer = new Uint8Array(buffer2.length + data.length);
26243
26733
  newBuffer.set(buffer2, 0);
@@ -26249,6 +26739,9 @@ function getDeserializeStream(revivers, cryptoKey) {
26249
26739
  if (!keyState.resolved) {
26250
26740
  keyState.key = await resolveEncryptionKey(cryptoKey);
26251
26741
  keyState.resolved = true;
26742
+ if (isRunPayloadKeys(keyState.key)) {
26743
+ openSession = createOpenSession(keyState.key.keyPair, keyState.key.aad);
26744
+ }
26252
26745
  }
26253
26746
  while (buffer2.length >= FRAME_HEADER_SIZE) {
26254
26747
  const frameLength = new DataView(buffer2.buffer, buffer2.byteOffset, buffer2.byteLength).getUint32(0, false);
@@ -26258,20 +26751,22 @@ function getDeserializeStream(revivers, cryptoKey) {
26258
26751
  const frameData = buffer2.slice(FRAME_HEADER_SIZE, FRAME_HEADER_SIZE + frameLength);
26259
26752
  buffer2 = buffer2.slice(FRAME_HEADER_SIZE + frameLength);
26260
26753
  let { format, payload } = decodeFormatPrefix(frameData);
26261
- if (format === SerializationFormat.ENCRYPTED) {
26262
- if (!keyState.key) {
26263
- controller.error(new RuntimeDecryptionError("Encrypted stream data encountered but no encryption key is available. Encryption is not configured or no key was provided for this run.", {
26754
+ if (format === SerializationFormat.ENCRYPTED || format === SerializationFormat.SEALED) {
26755
+ const sealed = format === SerializationFormat.SEALED;
26756
+ const usable = sealed ? isRunPayloadKeys(keyState.key) : aesKeyOf(keyState.key) !== void 0;
26757
+ if (!usable) {
26758
+ controller.error(new RuntimeDecryptionError(sealed ? "Sealed stream data encountered but no run keypair is available. Opening a sealed frame requires the run's own encryption key material." : "Encrypted stream data encountered but no encryption key is available. Encryption is not configured or no key was provided for this run.", {
26264
26759
  context: {
26265
26760
  operation: "decrypt",
26266
26761
  byteLength: payload.byteLength,
26267
- formatPrefix: "encr"
26762
+ formatPrefix: sealed ? "encp" : "encr"
26268
26763
  }
26269
26764
  }));
26270
26765
  return;
26271
26766
  }
26272
26767
  let decrypted;
26273
26768
  try {
26274
- decrypted = await decrypt(keyState.key, payload);
26769
+ decrypted = sealed ? await openSession.open(decodeFormatPrefix(frameData).payload) : await decrypt2(frameData, keyState.key);
26275
26770
  } catch (error48) {
26276
26771
  if (RuntimeDecryptionError.is(error48) && error48.context) {
26277
26772
  error48.context.formatPrefix = format;
@@ -26699,6 +27194,10 @@ function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framed
26699
27194
  name: existingName,
26700
27195
  runId: existingRunId
26701
27196
  };
27197
+ const existingPublicKey = value[STREAM_SERVER_PUBLIC_KEY_SYMBOL];
27198
+ if (typeof existingPublicKey === "string") {
27199
+ descriptor.encryptionPublicKey = existingPublicKey;
27200
+ }
26702
27201
  const existingDeploymentId = value[STREAM_SERVER_DEPLOYMENT_ID_SYMBOL];
26703
27202
  if (typeof existingDeploymentId === "string") {
26704
27203
  descriptor.deploymentId = existingDeploymentId;
@@ -26764,6 +27263,10 @@ function getWorkflowReducers(global2 = globalThis) {
26764
27263
  if (typeof foreignDeploymentId === "string") {
26765
27264
  s.deploymentId = foreignDeploymentId;
26766
27265
  }
27266
+ const foreignPublicKey = value[STREAM_SERVER_PUBLIC_KEY_SYMBOL];
27267
+ if (typeof foreignPublicKey === "string") {
27268
+ s.encryptionPublicKey = foreignPublicKey;
27269
+ }
26767
27270
  return s;
26768
27271
  }, "WritableStream"),
26769
27272
  // AbortController/AbortSignal in workflow context — just read symbols (handles).
@@ -26836,6 +27339,10 @@ function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByte
26836
27339
  name
26837
27340
  };
26838
27341
  if (typeof foreignRunId === "string") s.runId = foreignRunId;
27342
+ const foreignPublicKey = value[STREAM_SERVER_PUBLIC_KEY_SYMBOL];
27343
+ if (typeof foreignPublicKey === "string") {
27344
+ s.encryptionPublicKey = foreignPublicKey;
27345
+ }
26839
27346
  const foreignDeploymentId = value[STREAM_SERVER_DEPLOYMENT_ID_SYMBOL];
26840
27347
  if (typeof foreignDeploymentId === "string") {
26841
27348
  s.deploymentId = foreignDeploymentId;
@@ -26988,7 +27495,9 @@ function getCommonRevivers2(global2 = globalThis) {
26988
27495
  ...getCommonRevivers(global2)
26989
27496
  };
26990
27497
  }
26991
- async function getForwardedWritableEncryptionKey(runId, deploymentId) {
27498
+ async function getForwardedWritableEncryptionKey(runId, deploymentId, encryptionPublicKey) {
27499
+ const ownerPublicKey = decodeRunPublicKey(encryptionPublicKey);
27500
+ if (ownerPublicKey) return sealTo(ownerPublicKey);
26992
27501
  const world = await getWorldLazy();
26993
27502
  if (!world.getEncryptionKeyForRun) return void 0;
26994
27503
  const rawKey = deploymentId ? await world.getEncryptionKeyForRun(runId, {
@@ -27061,7 +27570,7 @@ function getExternalRevivers(global2 = globalThis, ops, runId, cryptoKey) {
27061
27570
  }, "ReadableStream"),
27062
27571
  WritableStream: /* @__PURE__ */ __name((value) => {
27063
27572
  const targetRunId = typeof value.runId === "string" ? value.runId : runId;
27064
- const targetKey = targetRunId === runId ? cryptoKey : getForwardedWritableEncryptionKey(targetRunId, value.deploymentId);
27573
+ const targetKey = targetRunId === runId ? cryptoKey : getForwardedWritableEncryptionKey(targetRunId, value.deploymentId, value.encryptionPublicKey);
27065
27574
  const serialize3 = getSerializeStream(getExternalReducers(global2, ops, targetRunId, targetKey), targetKey);
27066
27575
  const serverWritable = new WorkflowServerWritableStream(targetRunId, value.name);
27067
27576
  const state = createFlushableState();
@@ -27083,6 +27592,12 @@ function getExternalRevivers(global2 = globalThis, ops, runId, cryptoKey) {
27083
27592
  writable: false
27084
27593
  });
27085
27594
  }
27595
+ if (typeof value.encryptionPublicKey === "string") {
27596
+ Object.defineProperty(serialize3.writable, STREAM_SERVER_PUBLIC_KEY_SYMBOL, {
27597
+ value: value.encryptionPublicKey,
27598
+ writable: false
27599
+ });
27600
+ }
27086
27601
  return serialize3.writable;
27087
27602
  }, "WritableStream"),
27088
27603
  AbortController: /* @__PURE__ */ __name((value) => reviveAbortController(value, ops, runId), "AbortController"),
@@ -27220,7 +27735,7 @@ function getStepRevivers(global2 = globalThis, ops, runId, cryptoKey, deployment
27220
27735
  WritableStream: /* @__PURE__ */ __name((value) => {
27221
27736
  const targetRunId = typeof value.runId === "string" ? value.runId : runId;
27222
27737
  const targetDeploymentId = typeof value.deploymentId === "string" ? value.deploymentId : targetRunId === runId ? deploymentId : void 0;
27223
- const targetKey = targetRunId === runId ? cryptoKey : getForwardedWritableEncryptionKey(targetRunId, targetDeploymentId);
27738
+ const targetKey = targetRunId === runId ? cryptoKey : getForwardedWritableEncryptionKey(targetRunId, targetDeploymentId, value.encryptionPublicKey);
27224
27739
  const serialize3 = getSerializeStream(getStepReducers(global2, ops, targetRunId, targetKey), targetKey);
27225
27740
  const serverWritable = new WorkflowServerWritableStream(targetRunId, value.name);
27226
27741
  const state = createFlushableState();
@@ -27242,6 +27757,18 @@ function getStepRevivers(global2 = globalThis, ops, runId, cryptoKey, deployment
27242
27757
  writable: false
27243
27758
  });
27244
27759
  }
27760
+ if (typeof value.encryptionPublicKey !== "string" && targetRunId === runId && isRunPayloadKeys(cryptoKey)) {
27761
+ Object.defineProperty(serialize3.writable, STREAM_SERVER_PUBLIC_KEY_SYMBOL, {
27762
+ value: bytesToBase64(cryptoKey.keyPair.publicKey),
27763
+ writable: false
27764
+ });
27765
+ }
27766
+ if (typeof value.encryptionPublicKey === "string") {
27767
+ Object.defineProperty(serialize3.writable, STREAM_SERVER_PUBLIC_KEY_SYMBOL, {
27768
+ value: value.encryptionPublicKey,
27769
+ writable: false
27770
+ });
27771
+ }
27245
27772
  return serialize3.writable;
27246
27773
  }, "WritableStream"),
27247
27774
  AbortController: /* @__PURE__ */ __name((value) => reviveAbortController(value, ops, runId), "AbortController"),
@@ -27384,7 +27911,7 @@ function getStreamAndRequestRevivers(allRevivers) {
27384
27911
  }
27385
27912
  return extra;
27386
27913
  }
27387
- var defaultUlid, FRAME_HEADER_SIZE, MAX_FRAME_SIZE, WorkflowServerReadableStream, FRAMED_STREAM_MAX_RECONNECTS, getFramedStreamMaxReconnects, FRAMED_STREAM_MAX_TOTAL_RECONNECTS, getFramedStreamMaxTotalReconnects, STREAM_FLUSH_INTERVAL_MS, getStreamFlushIntervalMs, WorkflowServerWritableStream, STREAM_AND_REQUEST_KEYS;
27914
+ var defaultUlid, FRAME_HEADER_SIZE, MAX_FRAME_SIZE, WorkflowServerReadableStream, FRAMED_STREAM_MAX_RECONNECTS, getFramedStreamMaxReconnects, FRAMED_STREAM_MAX_TOTAL_RECONNECTS, getFramedStreamMaxTotalReconnects, STREAM_FLUSH_INTERVAL_MS, getEnvStreamFlushIntervalMs, WorkflowServerWritableStream, STREAM_AND_REQUEST_KEYS;
27388
27915
  var init_serialization2 = __esm({
27389
27916
  "../core/dist/serialization.js"() {
27390
27917
  "use strict";
@@ -27392,10 +27919,12 @@ var init_serialization2 = __esm({
27392
27919
  init_dist4();
27393
27920
  init_devalue();
27394
27921
  init_node();
27922
+ init_sealed_box();
27395
27923
  init_encryption();
27396
27924
  init_flushable_stream();
27397
27925
  init_private();
27398
27926
  init_get_world_lazy();
27927
+ init_sealed_box();
27399
27928
  init_client();
27400
27929
  init_compression();
27401
27930
  init_encryption2();
@@ -27494,10 +28023,13 @@ var init_serialization2 = __esm({
27494
28023
  min: 1
27495
28024
  }), "getFramedStreamMaxTotalReconnects");
27496
28025
  __name(createReconnectingFramedStream, "createReconnectingFramedStream");
27497
- STREAM_FLUSH_INTERVAL_MS = 10;
27498
- getStreamFlushIntervalMs = /* @__PURE__ */ __name(() => envNumber("WORKFLOW_STREAM_FLUSH_INTERVAL_MS", STREAM_FLUSH_INTERVAL_MS, {
27499
- integer: true
27500
- }), "getStreamFlushIntervalMs");
28026
+ STREAM_FLUSH_INTERVAL_MS = 0;
28027
+ getEnvStreamFlushIntervalMs = /* @__PURE__ */ __name(() => {
28028
+ const value = envNumber("WORKFLOW_STREAM_FLUSH_INTERVAL_MS", Number.NaN, {
28029
+ integer: true
28030
+ });
28031
+ return Number.isNaN(value) ? void 0 : value;
28032
+ }, "getEnvStreamFlushIntervalMs");
27501
28033
  __name(recordStreamWriteFlush, "recordStreamWriteFlush");
27502
28034
  __name(recordStreamClose, "recordStreamClose");
27503
28035
  WorkflowServerWritableStream = class extends WritableStream {
@@ -27532,106 +28064,189 @@ var init_serialization2 = __esm({
27532
28064
  }
27533
28065
  }, "ensureRunReady");
27534
28066
  let buffer2 = [];
28067
+ let bufferBytes = 0;
28068
+ let inFlightChunks = 0;
28069
+ let inFlightBytes = 0;
27535
28070
  let flushTimer = null;
27536
- let flushPromise = null;
27537
- let resolvedFlushIntervalMs;
27538
- let batchStartAt;
27539
- const flush = /* @__PURE__ */ __name(async () => {
27540
- if (flushTimer) {
27541
- clearTimeout(flushTimer);
27542
- flushTimer = null;
27543
- }
27544
- if (buffer2.length === 0) return;
28071
+ let inFlight = null;
28072
+ let sinkError;
28073
+ let resolvedFlushIntervalMs = getEnvStreamFlushIntervalMs();
28074
+ let flushIntervalResolution = null;
28075
+ const maxChunksPerRequest = getMaxChunksPerBatch();
28076
+ const maxBytesPerRequest = getMaxBytesPerBatch();
28077
+ const maxBufferedChunks = getMaxInflightChunks();
28078
+ const maxBufferedBytes = getMaxBufferedBytes();
28079
+ let bufferT0;
28080
+ let capacityWaiters = [];
28081
+ let drainWaiters = [];
28082
+ const rejectWaiters = /* @__PURE__ */ __name((err) => {
28083
+ const all = [
28084
+ ...capacityWaiters,
28085
+ ...drainWaiters
28086
+ ];
28087
+ capacityWaiters = [];
28088
+ drainWaiters = [];
28089
+ for (const w of all) w.reject(err);
28090
+ }, "rejectWaiters");
28091
+ const takeGroup = /* @__PURE__ */ __name(() => {
28092
+ let count2 = 0;
28093
+ let bytes = 0;
28094
+ for (const chunk of buffer2) {
28095
+ if (count2 >= maxChunksPerRequest) break;
28096
+ if (count2 > 0 && bytes + chunk.byteLength > maxBytesPerRequest) break;
28097
+ count2++;
28098
+ bytes += chunk.byteLength;
28099
+ }
28100
+ const group = buffer2.slice(0, count2);
28101
+ buffer2 = buffer2.slice(count2);
28102
+ bufferBytes -= bytes;
28103
+ return {
28104
+ group,
28105
+ bytes
28106
+ };
28107
+ }, "takeGroup");
28108
+ const sendGroup = /* @__PURE__ */ __name(async (group, bytes, groupT0) => {
27545
28109
  await ensureRunReady();
27546
- const chunksToFlush = buffer2.slice();
27547
- const batchStart = batchStartAt;
27548
- batchStartAt = void 0;
27549
- const dispatchAt = Date.now();
27550
28110
  const world = await worldPromise;
27551
- if (resolvedFlushIntervalMs === void 0) {
27552
- resolvedFlushIntervalMs = world.streamFlushIntervalMs ?? getStreamFlushIntervalMs();
28111
+ const dispatchAt = Date.now();
28112
+ if (typeof world.streams.writeMulti === "function" && group.length > 1) {
28113
+ await world.streams.writeMulti(runId, name, group);
28114
+ } else {
28115
+ for (const chunk of group) {
28116
+ await world.streams.write(runId, name, chunk);
28117
+ }
27553
28118
  }
27554
- const rpcStartAt = Date.now();
27555
- try {
27556
- if (typeof world.streams.writeMulti === "function" && chunksToFlush.length > 1) {
27557
- await world.streams.writeMulti(runId, name, chunksToFlush);
27558
- } else {
27559
- for (const chunk of chunksToFlush) {
27560
- await world.streams.write(runId, name, chunk);
27561
- }
28119
+ if (groupT0 !== void 0) {
28120
+ recordStreamWriteFlush(groupT0, dispatchAt, runId, name, group.length, bytes, Date.now() - dispatchAt);
28121
+ }
28122
+ }, "sendGroup");
28123
+ const dispatchLoop = /* @__PURE__ */ __name(async () => {
28124
+ while (buffer2.length > 0) {
28125
+ if (flushTimer) {
28126
+ clearTimeout(flushTimer);
28127
+ flushTimer = null;
27562
28128
  }
27563
- } catch (error48) {
27564
- if (batchStart !== void 0) {
27565
- batchStartAt = batchStartAt === void 0 ? batchStart : Math.min(batchStartAt, batchStart);
28129
+ const groupT0 = bufferT0;
28130
+ const groupTakenAt = Date.now();
28131
+ const { group, bytes } = takeGroup();
28132
+ inFlightChunks = group.length;
28133
+ inFlightBytes = bytes;
28134
+ bufferT0 = buffer2.length > 0 ? groupTakenAt : void 0;
28135
+ try {
28136
+ await sendGroup(group, bytes, groupT0);
28137
+ inFlightChunks = 0;
28138
+ inFlightBytes = 0;
28139
+ } catch (error48) {
28140
+ buffer2 = group.concat(buffer2);
28141
+ bufferBytes += bytes;
28142
+ inFlightChunks = 0;
28143
+ inFlightBytes = 0;
28144
+ bufferT0 = groupT0 !== void 0 && bufferT0 !== void 0 ? Math.min(groupT0, bufferT0) : groupT0 ?? bufferT0;
28145
+ throw error48;
28146
+ }
28147
+ const relieved = capacityWaiters;
28148
+ capacityWaiters = [];
28149
+ for (const w of relieved) w.resolve();
28150
+ }
28151
+ }, "dispatchLoop");
28152
+ const startDispatch = /* @__PURE__ */ __name(() => {
28153
+ if (inFlight || sinkError !== void 0 || buffer2.length === 0) return;
28154
+ inFlight = dispatchLoop().then(() => {
28155
+ inFlight = null;
28156
+ if (buffer2.length > 0) {
28157
+ startDispatch();
28158
+ return;
27566
28159
  }
27567
- throw error48;
28160
+ const settled = drainWaiters;
28161
+ drainWaiters = [];
28162
+ for (const w of settled) w.resolve();
28163
+ }, (error48) => {
28164
+ inFlight = null;
28165
+ sinkError ??= error48;
28166
+ rejectWaiters(sinkError);
28167
+ });
28168
+ }, "startDispatch");
28169
+ const scheduleGroupCommit = /* @__PURE__ */ __name(() => {
28170
+ if (flushTimer || inFlight) return;
28171
+ if (resolvedFlushIntervalMs === void 0) {
28172
+ flushIntervalResolution ??= Promise.resolve(worldPromise).then((world) => {
28173
+ resolvedFlushIntervalMs = world.streamFlushIntervalMs ?? STREAM_FLUSH_INTERVAL_MS;
28174
+ }, () => {
28175
+ resolvedFlushIntervalMs = STREAM_FLUSH_INTERVAL_MS;
28176
+ }).then(() => {
28177
+ if (buffer2.length > 0) scheduleGroupCommit();
28178
+ });
28179
+ return;
27568
28180
  }
27569
- if (batchStart !== void 0) {
27570
- recordStreamWriteFlush(batchStart, dispatchAt, runId, name, chunksToFlush.length, chunksToFlush.reduce((sum, c) => sum + c.byteLength, 0), Date.now() - rpcStartAt);
28181
+ if (resolvedFlushIntervalMs <= 0) {
28182
+ startDispatch();
28183
+ return;
27571
28184
  }
27572
- buffer2 = [];
27573
- }, "flush");
27574
- let flushWaiters = [];
27575
- const scheduleFlush = /* @__PURE__ */ __name(() => {
27576
- if (flushTimer) return;
27577
28185
  flushTimer = setTimeout(() => {
27578
28186
  flushTimer = null;
27579
- const currentWaiters = flushWaiters;
27580
- flushWaiters = [];
27581
- flushPromise = flush().then(() => {
27582
- for (const w of currentWaiters) w.resolve();
27583
- }, (err) => {
27584
- for (const w of currentWaiters) w.reject(err);
27585
- });
27586
- }, resolvedFlushIntervalMs ?? getStreamFlushIntervalMs());
27587
- }, "scheduleFlush");
27588
- super({
27589
- async write(chunk) {
27590
- if (batchStartAt === void 0) batchStartAt = Date.now();
27591
- if (flushPromise) {
27592
- await flushPromise;
27593
- flushPromise = null;
27594
- }
27595
- buffer2.push(chunk);
27596
- scheduleFlush();
28187
+ startDispatch();
28188
+ }, resolvedFlushIntervalMs);
28189
+ }, "scheduleGroupCommit");
28190
+ const drain = /* @__PURE__ */ __name(async () => {
28191
+ while (true) {
28192
+ if (sinkError !== void 0) throw sinkError;
28193
+ if (buffer2.length === 0 && !inFlight) return;
28194
+ startDispatch();
27597
28195
  await new Promise((resolve, reject) => {
27598
- flushWaiters.push({
28196
+ drainWaiters.push({
27599
28197
  resolve,
27600
28198
  reject
27601
28199
  });
27602
28200
  });
28201
+ }
28202
+ }, "drain");
28203
+ super({
28204
+ async write(chunk) {
28205
+ if (sinkError !== void 0) throw sinkError;
28206
+ if (bufferT0 === void 0) bufferT0 = Date.now();
28207
+ buffer2.push(chunk);
28208
+ bufferBytes += chunk.byteLength;
28209
+ if (buffer2.length >= maxChunksPerRequest || bufferBytes >= maxBytesPerRequest) {
28210
+ startDispatch();
28211
+ } else {
28212
+ scheduleGroupCommit();
28213
+ }
28214
+ while (sinkError === void 0 && (buffer2.length + inFlightChunks >= maxBufferedChunks || bufferBytes + inFlightBytes >= maxBufferedBytes)) {
28215
+ startDispatch();
28216
+ await new Promise((resolve, reject) => {
28217
+ capacityWaiters.push({
28218
+ resolve,
28219
+ reject
28220
+ });
28221
+ });
28222
+ }
28223
+ if (sinkError !== void 0) throw sinkError;
27603
28224
  },
27604
28225
  async close() {
27605
- if (flushPromise) {
27606
- await flushPromise;
27607
- flushPromise = null;
27608
- }
27609
- await flush();
28226
+ await drain();
27610
28227
  await ensureRunReady();
27611
28228
  const world = await worldPromise;
27612
28229
  const closeStart = Date.now();
27613
28230
  await world.streams.close(runId, name);
27614
28231
  recordStreamClose(closeStart, runId, name);
27615
28232
  },
27616
- abort(reason) {
28233
+ async abort(reason) {
28234
+ try {
28235
+ await drain();
28236
+ } catch {
28237
+ }
27617
28238
  if (flushTimer) {
27618
28239
  clearTimeout(flushTimer);
27619
28240
  flushTimer = null;
27620
28241
  }
27621
28242
  buffer2 = [];
27622
- const waiters = flushWaiters;
27623
- flushWaiters = [];
27624
- const abortError = reason ?? new Error("Stream aborted");
27625
- for (const w of waiters) w.reject(abortError);
28243
+ bufferBytes = 0;
28244
+ sinkError ??= reason ?? new Error("Stream aborted");
28245
+ rejectWaiters(sinkError);
27626
28246
  }
27627
28247
  });
27628
- Object.defineProperty(this, STREAM_WRITE_BATCH_SYMBOL, {
27629
- value: /* @__PURE__ */ __name(async (chunks) => {
27630
- if (chunks.length === 0) return;
27631
- if (batchStartAt === void 0) batchStartAt = Date.now();
27632
- for (const chunk of chunks) buffer2.push(chunk);
27633
- await flush();
27634
- }, "value"),
28248
+ Object.defineProperty(this, STREAM_DRAIN_SYMBOL, {
28249
+ value: drain,
27635
28250
  enumerable: false,
27636
28251
  writable: false
27637
28252
  });
@@ -27770,7 +28385,7 @@ __builtin_set_attributes.maxRetries = INTERNAL_ATTRIBUTES_MAX_ATTEMPTS - 1;
27770
28385
  init_dist2();
27771
28386
  init_dist3();
27772
28387
  init_dist4();
27773
- init_encryption();
28388
+ init_encryption2();
27774
28389
  init_serialization2();
27775
28390
  init_util2();
27776
28391
  init_get_world_lazy();
@@ -27778,7 +28393,7 @@ init_get_world_lazy();
27778
28393
  // ../core/dist/runtime/runs.js
27779
28394
  init_dist2();
27780
28395
  init_dist4();
27781
- init_encryption();
28396
+ init_encryption2();
27782
28397
  init_serialization2();
27783
28398
  init_helpers();
27784
28399
 
@@ -27856,6 +28471,7 @@ __name(isRetryableWorldError, "isRetryableWorldError");
27856
28471
  // ../core/dist/runtime/start.js
27857
28472
  init_encryption();
27858
28473
  init_logger();
28474
+ init_sealed_box();
27859
28475
  init_serialization2();
27860
28476
  init_context_storage();
27861
28477
  init_semantic_conventions();
@@ -27919,8 +28535,10 @@ async function start(workflow, argsOrOptions, options) {
27919
28535
  deploymentId = currentDeploymentId;
27920
28536
  }
27921
28537
  }
28538
+ const runId = `wrun_${world.createRunId ? world.createRunId(opts) : ulid3()}`;
27922
28539
  let framedByteStreams;
27923
28540
  let targetSupportsCompression;
28541
+ let probedRunPublicKey;
27924
28542
  if (deploymentId === currentDeploymentId) {
27925
28543
  framedByteStreams = true;
27926
28544
  targetSupportsCompression = true;
@@ -27928,17 +28546,18 @@ async function start(workflow, argsOrOptions, options) {
27928
28546
  framedByteStreams = false;
27929
28547
  targetSupportsCompression = false;
27930
28548
  } else {
27931
- const probe = await healthCheck(world, "workflow", {
28549
+ const probe = await healthCheck(world, {
27932
28550
  deploymentId,
28551
+ runId,
27933
28552
  timeout: CROSS_DEPLOYMENT_CAPABILITY_PROBE_TIMEOUT_MS,
27934
28553
  namespace: opts.namespace
27935
28554
  }).catch(() => void 0);
28555
+ probedRunPublicKey = probe?.encryptionPublicKey;
27936
28556
  const capabilities = getRunCapabilities(probe?.workflowCoreVersion);
27937
28557
  framedByteStreams = capabilities.framedByteStreams;
27938
28558
  targetSupportsCompression = capabilities.supportedFormats.has(SerializationFormat.GZIP);
27939
28559
  }
27940
28560
  const ops = [];
27941
- const runId = `wrun_${world.createRunId ? world.createRunId(opts) : ulid3()}`;
27942
28561
  const traceCarrier = await serializeTraceCarrier();
27943
28562
  const specVersion = opts.specVersion ?? world.specVersion;
27944
28563
  const v1Compat = isLegacySpecVersion(specVersion);
@@ -27975,11 +28594,20 @@ async function start(workflow, argsOrOptions, options) {
27975
28594
  if (opts.replayedFromRunId !== void 0 && !workflowRunIdSchema.safeParse(opts.replayedFromRunId).success) {
27976
28595
  throw new WorkflowRuntimeError(`replayedFromRunId must be a run ID (wrun_<ulid>); received ${JSON.stringify(String(opts.replayedFromRunId).slice(0, 64))}.`);
27977
28596
  }
27978
- const rawKey = await world.getEncryptionKeyForRun?.(runId, {
27979
- ...opts,
27980
- deploymentId
27981
- });
27982
- const encryptionKey = rawKey ? await importKey(rawKey) : void 0;
28597
+ const probedPublicKey = decodeRunPublicKey(probedRunPublicKey);
28598
+ let encryptionKey;
28599
+ let encryptionPublicKey;
28600
+ if (probedPublicKey) {
28601
+ encryptionKey = sealTo(probedPublicKey);
28602
+ encryptionPublicKey = probedRunPublicKey;
28603
+ } else {
28604
+ const rawKey = await world.getEncryptionKeyForRun?.(runId, {
28605
+ ...opts,
28606
+ deploymentId
28607
+ });
28608
+ encryptionKey = rawKey ? await importKey(rawKey) : void 0;
28609
+ encryptionPublicKey = rawKey ? bytesToBase64((await deriveRunKeyPair(rawKey)).publicKey) : void 0;
28610
+ }
27983
28611
  const compression = targetSupportsCompression && specVersion >= SPEC_VERSION_SUPPORTS_COMPRESSION;
27984
28612
  const workflowArguments = await dehydrateWorkflowArguments(args, runId, encryptionKey, ops, globalThis, v1Compat, framedByteStreams, compression);
27985
28613
  const executionContext = {
@@ -28001,6 +28629,9 @@ async function start(workflow, argsOrOptions, options) {
28001
28629
  workflowName,
28002
28630
  input: workflowArguments,
28003
28631
  executionContext,
28632
+ ...encryptionPublicKey ? {
28633
+ encryptionPublicKey
28634
+ } : {},
28004
28635
  ...attributeSeed
28005
28636
  }
28006
28637
  }, {
@@ -28016,6 +28647,9 @@ async function start(workflow, argsOrOptions, options) {
28016
28647
  workflowName,
28017
28648
  specVersion,
28018
28649
  executionContext,
28650
+ ...encryptionPublicKey ? {
28651
+ encryptionPublicKey
28652
+ } : {},
28019
28653
  ...attributeSeed
28020
28654
  }
28021
28655
  } : {}
@@ -28082,7 +28716,7 @@ __name(start, "start");
28082
28716
  value: "start",
28083
28717
  configurable: true
28084
28718
  });
28085
- })(start, "step//@workflow/core/runtime/start@5.0.0-beta.36//start");
28719
+ })(start, "step//@workflow/core/runtime/start@5.0.0-beta.38//start");
28086
28720
 
28087
28721
  // ../core/dist/runtime/runs.js
28088
28722
  async function wakeUpRun(world, runId, options) {
@@ -28226,7 +28860,7 @@ var Run = class _Run {
28226
28860
  const world = await this.#lazyWorldPromise;
28227
28861
  const run2 = await world.runs.get(this.runId);
28228
28862
  const rawKey = await world.getEncryptionKeyForRun?.(run2);
28229
- return rawKey ? await importKey(rawKey) : void 0;
28863
+ return rawKey ? await deriveRunPayloadKeys(rawKey) : void 0;
28230
28864
  })();
28231
28865
  }
28232
28866
  return this.#encryptionKeyPromise;
@@ -28418,7 +29052,7 @@ var Run = class _Run {
28418
29052
  value: "wakeUp",
28419
29053
  configurable: true
28420
29054
  });
28421
- })(Run.prototype["wakeUp"], "step//@workflow/core/runtime/run@5.0.0-beta.36//Run#wakeUp");
29055
+ })(Run.prototype["wakeUp"], "step//@workflow/core/runtime/run@5.0.0-beta.38//Run#wakeUp");
28422
29056
  (function(__wf_fn, __wf_id) {
28423
29057
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
28424
29058
  __wf_reg.set(__wf_id, __wf_fn);
@@ -28427,7 +29061,7 @@ var Run = class _Run {
28427
29061
  value: "cancel",
28428
29062
  configurable: true
28429
29063
  });
28430
- })(Run.prototype["cancel"], "step//@workflow/core/runtime/run@5.0.0-beta.36//Run#cancel");
29064
+ })(Run.prototype["cancel"], "step//@workflow/core/runtime/run@5.0.0-beta.38//Run#cancel");
28431
29065
  (function(__wf_fn, __wf_id) {
28432
29066
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
28433
29067
  __wf_reg.set(__wf_id, __wf_fn);
@@ -28436,7 +29070,7 @@ var Run = class _Run {
28436
29070
  value: "getReadable",
28437
29071
  configurable: true
28438
29072
  });
28439
- })(Run.prototype["getReadable"], "step//@workflow/core/runtime/run@5.0.0-beta.36//Run#getReadable");
29073
+ })(Run.prototype["getReadable"], "step//@workflow/core/runtime/run@5.0.0-beta.38//Run#getReadable");
28440
29074
  (function(__wf_fn, __wf_id) {
28441
29075
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
28442
29076
  __wf_reg.set(__wf_id, __wf_fn);
@@ -28445,7 +29079,7 @@ var Run = class _Run {
28445
29079
  value: "exists",
28446
29080
  configurable: true
28447
29081
  });
28448
- })(Object.getOwnPropertyDescriptor(Run.prototype, "exists").get, "step//@workflow/core/runtime/run@5.0.0-beta.36//Run#exists");
29082
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "exists").get, "step//@workflow/core/runtime/run@5.0.0-beta.38//Run#exists");
28449
29083
  (function(__wf_fn, __wf_id) {
28450
29084
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
28451
29085
  __wf_reg.set(__wf_id, __wf_fn);
@@ -28454,7 +29088,7 @@ var Run = class _Run {
28454
29088
  value: "status",
28455
29089
  configurable: true
28456
29090
  });
28457
- })(Object.getOwnPropertyDescriptor(Run.prototype, "status").get, "step//@workflow/core/runtime/run@5.0.0-beta.36//Run#status");
29091
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "status").get, "step//@workflow/core/runtime/run@5.0.0-beta.38//Run#status");
28458
29092
  (function(__wf_fn, __wf_id) {
28459
29093
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
28460
29094
  __wf_reg.set(__wf_id, __wf_fn);
@@ -28463,7 +29097,7 @@ var Run = class _Run {
28463
29097
  value: "returnValue",
28464
29098
  configurable: true
28465
29099
  });
28466
- })(Object.getOwnPropertyDescriptor(Run.prototype, "returnValue").get, "step//@workflow/core/runtime/run@5.0.0-beta.36//Run#returnValue");
29100
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "returnValue").get, "step//@workflow/core/runtime/run@5.0.0-beta.38//Run#returnValue");
28467
29101
  (function(__wf_fn, __wf_id) {
28468
29102
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
28469
29103
  __wf_reg.set(__wf_id, __wf_fn);
@@ -28472,7 +29106,7 @@ var Run = class _Run {
28472
29106
  value: "workflowName",
28473
29107
  configurable: true
28474
29108
  });
28475
- })(Object.getOwnPropertyDescriptor(Run.prototype, "workflowName").get, "step//@workflow/core/runtime/run@5.0.0-beta.36//Run#workflowName");
29109
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "workflowName").get, "step//@workflow/core/runtime/run@5.0.0-beta.38//Run#workflowName");
28476
29110
  (function(__wf_fn, __wf_id) {
28477
29111
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
28478
29112
  __wf_reg.set(__wf_id, __wf_fn);
@@ -28481,7 +29115,7 @@ var Run = class _Run {
28481
29115
  value: "createdAt",
28482
29116
  configurable: true
28483
29117
  });
28484
- })(Object.getOwnPropertyDescriptor(Run.prototype, "createdAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.36//Run#createdAt");
29118
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "createdAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.38//Run#createdAt");
28485
29119
  (function(__wf_fn, __wf_id) {
28486
29120
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
28487
29121
  __wf_reg.set(__wf_id, __wf_fn);
@@ -28490,7 +29124,7 @@ var Run = class _Run {
28490
29124
  value: "startedAt",
28491
29125
  configurable: true
28492
29126
  });
28493
- })(Object.getOwnPropertyDescriptor(Run.prototype, "startedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.36//Run#startedAt");
29127
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "startedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.38//Run#startedAt");
28494
29128
  (function(__wf_fn, __wf_id) {
28495
29129
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
28496
29130
  __wf_reg.set(__wf_id, __wf_fn);
@@ -28499,7 +29133,7 @@ var Run = class _Run {
28499
29133
  value: "completedAt",
28500
29134
  configurable: true
28501
29135
  });
28502
- })(Object.getOwnPropertyDescriptor(Run.prototype, "completedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.36//Run#completedAt");
29136
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "completedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.38//Run#completedAt");
28503
29137
  (function(__wf_cls, __wf_id) {
28504
29138
  var __wf_sym = /* @__PURE__ */ Symbol.for("workflow-class-registry"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
28505
29139
  __wf_reg.set(__wf_id, __wf_cls);
@@ -28509,7 +29143,7 @@ var Run = class _Run {
28509
29143
  enumerable: false,
28510
29144
  configurable: false
28511
29145
  });
28512
- })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.36//Run");
29146
+ })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.38//Run");
28513
29147
 
28514
29148
  // ../workflow/dist/stdlib.js
28515
29149
  async function fetch2(...args) {
@@ -28773,6 +29407,7 @@ init_context_storage();
28773
29407
 
28774
29408
  // ../core/dist/step/writable-stream.js
28775
29409
  init_flushable_stream();
29410
+ init_sealed_box();
28776
29411
  init_serialization2();
28777
29412
  init_symbols();
28778
29413
  init_util2();