@workflow/web 5.0.0-beta.43 → 5.0.0-beta.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/build/client/assets/{arrow-up-right-D39pnGsD.js → arrow-up-right-UOc2WcaC.js} +1 -1
  2. package/build/client/assets/{highlighted-body-B3W2YXNL-Dc1dLaUr.js → highlighted-body-B3W2YXNL-D78gcP7S.js} +1 -1
  3. package/build/client/assets/{home-C6CuMqQu.js → home-DYB1uz9w.js} +3 -3
  4. package/build/client/assets/{loader-circle-BOxaTUjK.js → loader-circle-oscnpy3L.js} +1 -1
  5. package/build/client/assets/{manifest-157e28f1.js → manifest-a701502a.js} +1 -1
  6. package/build/client/assets/{mermaid-3ZIDBTTL-gEw-Ch1C.js → mermaid-3ZIDBTTL-BKGEyEYb.js} +463 -334
  7. package/build/client/assets/{root-BfhMCbkz.js → root-Zvnb602n.js} +3 -3
  8. package/build/client/assets/{run-detail-BG_1K2Hq.js → run-detail-CedyZW9h.js} +54 -31
  9. package/build/client/assets/{workflow-graph-viewer-CxrWityD.js → workflow-graph-viewer-Du0ztkb8.js} +1 -1
  10. package/build/client/assets/{zstd-browser-decoder-CAEVa0bm.js → zstd-browser-decoder-DafWVuEG.js} +1 -1
  11. package/build/server/assets/{app-_xgEuKqE.js → app-BpmEMaiu.js} +1162 -852
  12. package/build/server/assets/{highlighted-body-B3W2YXNL-B1Smd86a.js → highlighted-body-B3W2YXNL-C6ES2Pzm.js} +1 -1
  13. package/build/server/assets/{index-CSsrecUx.js → index-BtQfiVUN.js} +75 -73
  14. package/build/server/assets/{index-Ck5CB_wQ.js → index-QOlZC9D-.js} +1 -1
  15. package/build/server/assets/{mermaid-3ZIDBTTL-CwYR558N.js → mermaid-3ZIDBTTL-X6IEJ8gj.js} +1 -1
  16. package/build/server/assets/{token-COK7oHMh.js → token-CrxXUTBD.js} +1 -1
  17. package/build/server/assets/{token-util-BhmVdeCX.js → token-util-DuToe55u.js} +1 -1
  18. package/build/server/assets/{websocket-server-ByjlHAhQ.js → websocket-server-CTnzV_B7.js} +1 -1
  19. package/build/server/assets/{wrapper-DWeVTope.js → wrapper-Bjff6YRz.js} +3 -3
  20. package/build/server/assets/{ws-transport-BCfcEhAO.js → ws-transport-ByYax88V.js} +40 -22
  21. package/build/server/assets/{zstd-browser-decoder-D8JD_nwS.js → zstd-browser-decoder-Bfk1d5vU.js} +1 -1
  22. package/build/server/index.js +3 -3
  23. package/package.json +8 -8
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/zstd-browser-decoder-CAEVa0bm.js","assets/index-PFjW8YjQ.js","assets/highlighted-body-B3W2YXNL-Dc1dLaUr.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/zstd-browser-decoder-DafWVuEG.js","assets/index-PFjW8YjQ.js","assets/highlighted-body-B3W2YXNL-D78gcP7S.js"])))=>i.map(i=>d[i]);
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -14826,11 +14826,98 @@ function date(params) {
14826
14826
  return /* @__PURE__ */ _coercedDate(ZodDate, params);
14827
14827
  }
14828
14828
  const RESERVED_ATTRIBUTE_KEY_PREFIX = "$";
14829
+ const ATTRIBUTE_KEY_MAX_LENGTH = 256;
14830
+ const ATTRIBUTE_VALUE_MAX_BYTES = 256;
14831
+ const ATTRIBUTE_MAX_PER_RUN = 64;
14832
+ new TextEncoder();
14833
+ class AttributeValidationError extends Error {
14834
+ constructor(message) {
14835
+ super(message);
14836
+ this.name = "AttributeValidationError";
14837
+ }
14838
+ }
14839
+ function attributeCountDelta(key, value, existingKeys) {
14840
+ if (value === null)
14841
+ return (existingKeys == null ? void 0 : existingKeys.has(key)) ? -1 : 0;
14842
+ return existingKeys === void 0 || !existingKeys.has(key) ? 1 : 0;
14843
+ }
14844
+ function validateAttributeBatchConstraints(changes, context = {}) {
14845
+ const seenKeys = /* @__PURE__ */ new Set();
14846
+ const existingKeys = context.existingKeys === void 0 ? void 0 : context.existingKeys instanceof Set ? context.existingKeys : new Set(context.existingKeys);
14847
+ let postMergeCount = (existingKeys == null ? void 0 : existingKeys.size) ?? 0;
14848
+ for (const { key, value } of changes) {
14849
+ if (seenKeys.has(key)) {
14850
+ throw new AttributeValidationError(`Attribute key ${JSON.stringify(key)} appears more than once in the same batch`);
14851
+ }
14852
+ seenKeys.add(key);
14853
+ postMergeCount += attributeCountDelta(key, value, existingKeys);
14854
+ }
14855
+ if (postMergeCount > ATTRIBUTE_MAX_PER_RUN) {
14856
+ throw new AttributeValidationError(`Run attribute count would exceed limit ${ATTRIBUTE_MAX_PER_RUN} (post-merge ${postMergeCount})`);
14857
+ }
14858
+ }
14859
+ const textEncoder$1 = new TextEncoder();
14860
+ const AttributeKeySchema = string$2().min(1, { error: "Attribute key must not be empty" }).max(ATTRIBUTE_KEY_MAX_LENGTH, {
14861
+ error: `Attribute key exceeds limit ${ATTRIBUTE_KEY_MAX_LENGTH}`
14862
+ });
14863
+ const AttributeValueSchema = string$2().refine((value) => textEncoder$1.encode(value).length <= ATTRIBUTE_VALUE_MAX_BYTES, {
14864
+ error: `Attribute value exceeds limit ${ATTRIBUTE_VALUE_MAX_BYTES} UTF-8 bytes`
14865
+ }).nullable();
14829
14866
  const AttributeChangeSchema = object({
14830
- key: string$2(),
14831
- value: union([string$2(), _null()])
14867
+ key: AttributeKeySchema,
14868
+ value: AttributeValueSchema
14832
14869
  });
14833
- const AttributeChangesSchema = array(AttributeChangeSchema);
14870
+ const AttributeChangesSchema = array(AttributeChangeSchema).superRefine((changes, context) => {
14871
+ try {
14872
+ validateAttributeBatchConstraints(changes);
14873
+ } catch (error) {
14874
+ if (!(error instanceof AttributeValidationError))
14875
+ throw error;
14876
+ context.addIssue({
14877
+ code: "custom",
14878
+ message: error.message,
14879
+ input: changes
14880
+ });
14881
+ }
14882
+ });
14883
+ function getOwnProperty$1(object2, key) {
14884
+ return Object.hasOwn(object2, key) ? object2[key] : void 0;
14885
+ }
14886
+ function isSealedNoopEvent(event) {
14887
+ return event.eventType === "noop";
14888
+ }
14889
+ const ENTITY_EVENT_CLASS_BY_TYPE = {
14890
+ step_created: "step_created",
14891
+ step_started: "step_started",
14892
+ step_retrying: "step_retrying",
14893
+ step_completed: "step_terminal",
14894
+ step_failed: "step_terminal",
14895
+ wait_created: "wait_created",
14896
+ wait_completed: "wait_completed",
14897
+ hook_created: "hook_created",
14898
+ hook_disposed: "hook_disposed",
14899
+ run_started: "run_started"
14900
+ };
14901
+ function entityEventClass(eventType) {
14902
+ return getOwnProperty$1(ENTITY_EVENT_CLASS_BY_TYPE, eventType);
14903
+ }
14904
+ const EVENT_DATA_REF_FIELDS_BY_EVENT_TYPE = {
14905
+ run_created: ["input"],
14906
+ run_started: ["input"],
14907
+ run_completed: ["output"],
14908
+ run_failed: ["error"],
14909
+ step_created: ["input"],
14910
+ step_started: ["input"],
14911
+ step_completed: ["result"],
14912
+ step_failed: ["error"],
14913
+ step_retrying: ["error"],
14914
+ hook_created: ["metadata"],
14915
+ hook_received: ["payload"]
14916
+ };
14917
+ const NO_EVENT_DATA_REF_FIELDS = [];
14918
+ function getEventDataRefFields(eventType) {
14919
+ return getOwnProperty$1(EVENT_DATA_REF_FIELDS_BY_EVENT_TYPE, eventType) ?? NO_EVENT_DATA_REF_FIELDS;
14920
+ }
14834
14921
  const BinarySerializedDataSchema = _instanceof(Uint8Array);
14835
14922
  const LegacySerializedDataSchemaV1 = any();
14836
14923
  const SerializedDataSchema = union([
@@ -14860,7 +14947,11 @@ const EventTypeSchema = _enum([
14860
14947
  // Created by world when hook token already exists
14861
14948
  // Wait lifecycle events
14862
14949
  "wait_created",
14863
- "wait_completed"
14950
+ "wait_completed",
14951
+ // Sealed-log filler (specVersion >= 7): written ONLY by the World's backend
14952
+ // to occupy a slot whose writer allocated it and died. Carries no workflow
14953
+ // meaning; replay skips it (see EventsConsumer). Never user-creatable.
14954
+ "noop"
14864
14955
  ]);
14865
14956
  const RunEventTypeSchema = EventTypeSchema.extract([
14866
14957
  "run_created",
@@ -14895,21 +14986,6 @@ const TERMINAL_STEP_EVENT_TYPES = TerminalStepEventTypeSchema.options;
14895
14986
  function isTerminalStepEventType(eventType) {
14896
14987
  return TERMINAL_STEP_EVENT_TYPES.includes(eventType);
14897
14988
  }
14898
- const ENTITY_EVENT_CLASS_BY_TYPE = {
14899
- step_created: "step_created",
14900
- step_started: "step_started",
14901
- step_retrying: "step_retrying",
14902
- step_completed: "step_terminal",
14903
- step_failed: "step_terminal",
14904
- wait_created: "wait_created",
14905
- wait_completed: "wait_completed",
14906
- hook_created: "hook_created",
14907
- hook_disposed: "hook_disposed",
14908
- run_started: "run_started"
14909
- };
14910
- function entityEventClass(eventType) {
14911
- return ENTITY_EVENT_CLASS_BY_TYPE[eventType];
14912
- }
14913
14989
  const HookLifecycleEventTypeSchema = EventTypeSchema.extract([
14914
14990
  "hook_created",
14915
14991
  "hook_received",
@@ -14938,23 +15014,6 @@ const ChildEntityCreationEventTypeSchema = EventTypeSchema.extract([
14938
15014
  "wait_created"
14939
15015
  ]);
14940
15016
  ChildEntityCreationEventTypeSchema.options;
14941
- const EVENT_DATA_PAYLOAD_FIELD_BY_EVENT_TYPE = {
14942
- run_created: "input",
14943
- run_started: "input",
14944
- run_completed: "output",
14945
- run_failed: "error",
14946
- step_created: "input",
14947
- step_started: "input",
14948
- step_completed: "result",
14949
- step_failed: "error",
14950
- step_retrying: "error",
14951
- hook_created: "metadata",
14952
- hook_received: "payload"
14953
- };
14954
- const EVENT_DATA_REF_FIELDS = Object.fromEntries(Object.entries(EVENT_DATA_PAYLOAD_FIELD_BY_EVENT_TYPE).map(([eventType, field]) => [eventType, [field]]));
14955
- function getEventDataRefFields(eventType) {
14956
- return EVENT_DATA_REF_FIELDS[eventType] ?? [];
14957
- }
14958
15017
  const BaseEventSchema = object({
14959
15018
  eventType: EventTypeSchema,
14960
15019
  correlationId: string$2().optional(),
@@ -14982,7 +15041,7 @@ const stepLatencyTelemetryFields = {
14982
15041
  rsfs: number$3().optional(),
14983
15042
  // Synchronous workflow-function replay duration of only the FINAL replay
14984
15043
  // pass within the rsfs window (the pass that scheduled the first step),
14985
- // excluding awaited network I/O not accumulated across earlier
15044
+ // excluding awaited network I/O. Not accumulated across earlier
14986
15045
  // pre-first-step passes, so it is not "the replay portion of rsfs". Only
14987
15046
  // present alongside rsfs, and only for the run's first step.
14988
15047
  finalSchedulingReplay: number$3().optional(),
@@ -15042,7 +15101,7 @@ const StepStartedEventSchema = BaseEventSchema.extend({
15042
15101
  // handler is executing this step's body inline. Stamped on the lazy
15043
15102
  // step_started (and re-stamped on an owner-recovery bare start) so
15044
15103
  // that a wake replay can tell "this attempt is in flight in a live
15045
- // invocation" apart from "this attempt died with its process" the
15104
+ // invocation" apart from "this attempt died with its process": the
15046
15105
  // owner's queue message doubles as the liveness lease (a crash means
15047
15106
  // the queue redelivers that same messageId, which is allowed to
15048
15107
  // re-execute). Ownership derives from the step's LATEST step_started:
@@ -15098,6 +15157,12 @@ const HookConflictEventSchema = BaseEventSchema.extend({
15098
15157
  conflictingRunId: string$2().optional()
15099
15158
  })
15100
15159
  });
15160
+ const NoopEventSchema = BaseEventSchema.extend({
15161
+ eventType: literal("noop"),
15162
+ eventData: object({
15163
+ sealed: boolean$2().optional()
15164
+ }).passthrough().optional()
15165
+ });
15101
15166
  const WaitCreatedEventSchema = BaseEventSchema.extend({
15102
15167
  eventType: literal("wait_created"),
15103
15168
  correlationId: string$2(),
@@ -15144,7 +15209,7 @@ const RunCreatedEventSchema = BaseEventSchema.extend({
15144
15209
  * The run's X25519 public key (base64), stamped by SDKs that support
15145
15210
  * sealed (`encp`) envelopes. Persisted onto the run entity so that
15146
15211
  * cross-run writers can seal payloads to this run without holding its
15147
- * symmetric key. Not secret see `WorkflowRunBaseSchema`.
15212
+ * symmetric key. Not secret. See `WorkflowRunBaseSchema`.
15148
15213
  */
15149
15214
  encryptionPublicKey: string$2().optional()
15150
15215
  })
@@ -15239,7 +15304,9 @@ const AllEventsSchema = discriminatedUnion("eventType", [
15239
15304
  // World-only: created when hook token conflicts
15240
15305
  // Wait lifecycle events
15241
15306
  WaitCreatedEventSchema,
15242
- WaitCompletedEventSchema
15307
+ WaitCompletedEventSchema,
15308
+ NoopEventSchema
15309
+ // World-only: sealed-log filler for an abandoned slot
15243
15310
  ]);
15244
15311
  AllEventsSchema.and(object({
15245
15312
  runId: string$2(),
@@ -15297,7 +15364,7 @@ const WorkflowRunBaseSchema = object({
15297
15364
  * ```
15298
15365
  */
15299
15366
  workflowName: string$2(),
15300
- // Optional in database for backwards compatibility, defaults to 1 (legacy) when reading
15367
+ // Optional in database for backward compatibility, defaults to 1 (legacy) when reading
15301
15368
  specVersion: number$3().optional(),
15302
15369
  executionContext: record(string$2(), any()).optional(),
15303
15370
  input: SerializedDataSchema.optional(),
@@ -15325,12 +15392,12 @@ const WorkflowRunBaseSchema = object({
15325
15392
  *
15326
15393
  * Defaults to `{}` after schema parsing so consumers always receive
15327
15394
  * a record regardless of world. World adapters need not initialize
15328
- * the field on disk `world-local` JSON files written before this
15395
+ * the field on disk: `world-local` JSON files written before this
15329
15396
  * field existed, and rows from any other adapter that omits the
15330
15397
  * column, both read as `{}` after Zod parses them.
15331
15398
  *
15332
15399
  * EXPERIMENTAL (MVP): the full Workflow Attributes feature replaces
15333
- * the direct-mutation MVP path with an event-sourced model — see
15400
+ * the direct-mutation MVP path with an event-sourced model. See
15334
15401
  * the attributes-mvp changelog entry.
15335
15402
  */
15336
15403
  attributes: record(string$2(), string$2()).default({}),
@@ -15338,12 +15405,12 @@ const WorkflowRunBaseSchema = object({
15338
15405
  * The run's X25519 public key, base64-encoded (~44 chars).
15339
15406
  *
15340
15407
  * Lets any party that can read this run seal a payload *to* it without
15341
- * being able to read the run's data used for cross-run writes such as a
15342
- * hook resumption from another deployment, or a child workflow writing into
15343
- * a forwarded stream. The matching private scalar is never stored: it is
15344
- * re-derived on demand from the deployment's own key material, so this
15345
- * field is not secret and its presence does not weaken the run's
15346
- * confidentiality.
15408
+ * being able to read the run's data. This is used for cross-run writes
15409
+ * such as a hook resumption from another deployment, or a child workflow
15410
+ * writing into a forwarded stream. The matching private scalar is never
15411
+ * stored: it is re-derived on demand from the deployment's own key
15412
+ * material, so this field is not secret and its presence does not weaken
15413
+ * the run's confidentiality.
15347
15414
  *
15348
15415
  * Stamped at run creation by SDKs that support sealed (`encp`) envelopes.
15349
15416
  * **Presence is the writer-side gate**: a run only carries a public key if
@@ -15596,6 +15663,9 @@ object({
15596
15663
  firstSeenAt: date(),
15597
15664
  lastSeenAt: date()
15598
15665
  });
15666
+ const WarnedEnvValuesKey = Symbol.for("@workflow/world//warnedEnvValues/v1");
15667
+ const globalStore = globalThis;
15668
+ globalStore[WarnedEnvValuesKey] ?? (globalStore[WarnedEnvValuesKey] = /* @__PURE__ */ new Set());
15599
15669
  string$2().regex(/^__(?:[a-z][a-z0-9]*_)?wkf_workflow_$/, "Must match __wkf_workflow_ or __{namespace}_wkf_workflow_");
15600
15670
  string$2().regex(/^__(?:[a-z][a-z0-9]*_)?wkf_workflow_.+$/, "Must be a valid queue name with a recognized prefix");
15601
15671
  string$2().regex(/^[a-z][a-z0-9]*$/, "Must be lowercase alphanumeric, starting with a letter");
@@ -15626,12 +15696,12 @@ const RunInputSchema = object({
15626
15696
  * two can disagree: if the message is consumed by a deployment in a
15627
15697
  * DIFFERENT environment, that consumer's `run_started` re-creates the run
15628
15698
  * under ITS tenant, so the same client-minted `wrun_` id ends up existing
15629
- * in two environments one stuck pending forever, the other executing.
15699
+ * in two environments: one stuck pending forever, the other executing.
15630
15700
  * Carrying the creator's environment lets the consumer compare it against
15631
15701
  * its own and refuse the delivery instead of forking the run.
15632
15702
  *
15633
15703
  * Absent for worlds with no environment dimension (local, Postgres), and
15634
- * for older SDKs consumers must treat it as advisory and skip the check
15704
+ * for older SDKs. Consumers must treat it as advisory and skip the check
15635
15705
  * when it is missing.
15636
15706
  */
15637
15707
  environment: string$2().optional()
@@ -15656,8 +15726,8 @@ const HookResumeInputSchema = object({
15656
15726
  hookId: string$2(),
15657
15727
  /**
15658
15728
  * The hook's token, written into the `hook_received` event's `eventData` so
15659
- * the consumer's re-ensured event carries the same token the producer would
15660
- * replay validates `eventData.token` against the `createHook` token.
15729
+ * the consumer's re-ensured event carries the same token the producer
15730
+ * would. Replay validates `eventData.token` against the `createHook` token.
15661
15731
  */
15662
15732
  token: string$2(),
15663
15733
  /** The serialized resume payload, reused verbatim from the direct write. */
@@ -15667,7 +15737,7 @@ const HookResumeInputSchema = object({
15667
15737
  * serialized bytes and forwarded verbatim on both the direct `events.create`
15668
15738
  * and this queue message. The consumer forwards it back to the server so both
15669
15739
  * writers of the same `resumeId` record an identical digest on the
15670
- * `(runId, resumeId)` constraint required because the v4 payload ref is not
15740
+ * `(runId, resumeId)` constraint, required because the v4 payload ref is not
15671
15741
  * content-stable server-side.
15672
15742
  */
15673
15743
  payloadDigest: string$2(),
@@ -15675,19 +15745,22 @@ const HookResumeInputSchema = object({
15675
15745
  * The deployment the run is pinned to, from the producer's resume context.
15676
15746
  * Lets the consumer detect a misrouted delivery with a cheap ambient
15677
15747
  * deployment-id comparison BEFORE its hoisted `hook_received` replay-preload
15678
- * write only a detected mismatch pays for the authoritative run fetch and
15748
+ * write: only a detected mismatch pays for the authoritative run fetch and
15679
15749
  * the deployment-affinity guard. Optional for queued-message compatibility:
15680
- * messages from older producers omit it and simply skip the pre-write
15750
+ * messages from older producers omit it and skip the pre-write
15681
15751
  * check (the authoritative guard before replay still protects them).
15682
15752
  */
15683
15753
  deploymentId: string$2().optional()
15684
15754
  });
15685
15755
  const HookResumeTimingSchema = object({
15686
- /** Epoch ms at entry into `resumeHook()` the start of the TTR window. */
15756
+ /** Epoch ms at entry into `resumeHook()`: the start of the TTR window. */
15687
15757
  resumeRequestedAtMs: number$3(),
15688
15758
  /** Epoch ms immediately before the queue publish was requested. */
15689
15759
  queuePublishRequestedAtMs: number$3(),
15690
- /** Which `resumeHook()` dispatch path ran: `parallel` or `sequential`. */
15760
+ /**
15761
+ * Which `resumeHook()` dispatch path ran: `lazy` or `sequential` (`parallel`
15762
+ * from producers predating lazy-only resume).
15763
+ */
15691
15764
  strategy: string$2().optional(),
15692
15765
  /** Epoch ms the final consumer's queue handler was entered. */
15693
15766
  consumerStartedAtMs: number$3().optional(),
@@ -15719,10 +15792,41 @@ const WorkflowInvokePayloadSchema = object({
15719
15792
  serverErrorRetryCount: number$3().int().optional(),
15720
15793
  /** Number of times this message has been re-routed after a deployment mismatch */
15721
15794
  deploymentMismatchRetryCount: number$3().int().nonnegative().optional(),
15795
+ /**
15796
+ * The wait this message is the delayed continuation for, and which attempt
15797
+ * in that wait's chain it is.
15798
+ *
15799
+ * Present only on wait-continuation messages. It exists so the invocation a
15800
+ * continuation wakes can recognize itself as that continuation: if the wait
15801
+ * is STILL pending when it replays — the continuation arrived before its
15802
+ * deadline — then its own idempotency key is already spent, and re-enqueueing
15803
+ * under the same key is silently dropped by the world's dedupe window. The
15804
+ * attempt number is what makes the next key fresh, so an early delivery
15805
+ * costs one extra hop instead of losing the wait's timer permanently.
15806
+ *
15807
+ * Counted on the message for the same reason as
15808
+ * {@link WorkflowInvokePayloadSchema.shape.preconditionReinvocations}: the
15809
+ * budget has to survive across invocations, and a fresh enqueue resets
15810
+ * anything the queue tracks itself. Absent on the first continuation, so a
15811
+ * producer that predates this field is indistinguishable from attempt 0 and
15812
+ * a consumer that predates it simply ignores the field.
15813
+ */
15814
+ /**
15815
+ * `.catch(undefined)` for the reason `hookResumeTiming` has it: this field
15816
+ * must never be able to fail the parse of the invocation payload. A
15817
+ * malformed value would otherwise throw on every delivery of the message
15818
+ * and burn the run's delivery budget. Degrading to `undefined` reads as
15819
+ * "not a continuation", which costs at worst the pre-attempt behavior for
15820
+ * that one wait rather than killing the run.
15821
+ */
15822
+ waitContinuation: object({
15823
+ correlationId: string$2(),
15824
+ attempt: number$3().int().nonnegative()
15825
+ }).optional().catch(void 0),
15722
15826
  /** Step ID for inline step execution in combined handler. If provided, the flow execution
15723
15827
  * will jump directly to execute the step with the given ID before doing an event replay. */
15724
15828
  stepId: string$2().optional(),
15725
- /** Step name, sent alongside stepId to avoid loading the event log just to resolve the name. */
15829
+ /** Step name, sent alongside stepId to avoid loading the event log to resolve the name. */
15726
15830
  stepName: string$2().optional(),
15727
15831
  /** Run creation data, only present on the first queue delivery from start() */
15728
15832
  runInput: RunInputSchema.optional(),
@@ -15741,10 +15845,10 @@ const WorkflowInvokePayloadSchema = object({
15741
15845
  stepInput: StepDispatchInputSchema.optional(),
15742
15846
  /**
15743
15847
  * Hook-resume TTR timing. Present on both `resumeHook()` dispatch paths
15744
- * (unlike `hookInput`, which only rides the parallel fast path), and
15848
+ * (unlike `hookInput`, which only rides the lazy path), and
15745
15849
  * forwarded onto a dispatched step message when the resuming invocation
15746
- * hands the next durable step to another invocation. Purely observational
15747
- * see {@link HookResumeTimingSchema}.
15850
+ * hands the next durable step to another invocation. Purely observational.
15851
+ * See {@link HookResumeTimingSchema}.
15748
15852
  *
15749
15853
  * `.catch(undefined)` because this field must never be able to fail the
15750
15854
  * parse of the invocation payload: a malformed value (a NaN boundary, a
@@ -15789,9 +15893,9 @@ const HookResumeContextSchema = object({
15789
15893
  // Feature marker: the version of the lazy-hook-resume consumer protocol the
15790
15894
  // run's creating deployment supports. Present (>= 1) means that deployment's
15791
15895
  // `@workflow/core` re-ensures the `hook_received` event from the queue
15792
- // message's `hookInput` on replay, so `resumeHook()`'s parallel fast path is
15793
- // safe to use. Because a run is pinned to its creating deployment, this
15794
- // marker is a reliable per-run attestation unlike inferring support from a
15896
+ // message's `hookInput` on replay, so `resumeHook()`'s lazy path is safe to
15897
+ // use. Because a run is pinned to its creating deployment, this
15898
+ // marker is a reliable per-run attestation, unlike inferring support from a
15795
15899
  // version compare against a predicted release cutoff. Absent on runs created
15796
15900
  // before the marker existed (fall back to the sequential path).
15797
15901
  hookResumeInputVersion: number$3().optional()
@@ -15812,7 +15916,7 @@ object({
15812
15916
  environment: string$2(),
15813
15917
  metadata: SerializedDataSchema.optional(),
15814
15918
  createdAt: date(),
15815
- // Optional in database for backwards compatibility, defaults to 1 (legacy) when reading
15919
+ // Optional in database for backward compatibility, defaults to 1 (legacy) when reading
15816
15920
  specVersion: number$3().optional(),
15817
15921
  isWebhook: boolean$2().optional(),
15818
15922
  isSystem: boolean$2().optional(),
@@ -15824,10 +15928,10 @@ object({
15824
15928
  // falls back to `runs.get`.
15825
15929
  resumeContext: HookResumeContextSchema.optional(),
15826
15930
  // Backend dedup capability, computed FRESH by the server on every by-token
15827
- // lookup RESPONSE-ONLY and TRANSIENT. Never persisted on the hook entity
15931
+ // lookup: RESPONSE-ONLY and TRANSIENT. Never persisted on the hook entity
15828
15932
  // and never part of `resumeContext`, so a server rollback or kill switch
15829
- // takes effect on the very next lookup (the field simply stops appearing).
15830
- // `resumeHook()` gates its parallel fast path on this being present and
15933
+ // takes effect on the next lookup (the field stops appearing).
15934
+ // `resumeHook()` gates its lazy path on this being present and
15831
15935
  // current. Absent against an older/rolled-back server or when the kill switch
15832
15936
  // is active.
15833
15937
  resumeCapabilities: HookResumeCapabilitiesSchema.optional()
@@ -15931,6 +16035,154 @@ const __vitePreload = function preload(baseModule, deps, importerUrl) {
15931
16035
  return baseModule().catch(handlePreloadError);
15932
16036
  });
15933
16037
  };
16038
+ function globalSingleton(name2, shapeVersion, create2) {
16039
+ const key = Symbol.for(`${name2}/v${shapeVersion}`);
16040
+ const store = globalThis;
16041
+ const existing = store[key];
16042
+ if (existing !== void 0) {
16043
+ return existing;
16044
+ }
16045
+ const created = create2();
16046
+ store[key] = created;
16047
+ return created;
16048
+ }
16049
+ var ms$1;
16050
+ var hasRequiredMs;
16051
+ function requireMs() {
16052
+ if (hasRequiredMs) return ms$1;
16053
+ hasRequiredMs = 1;
16054
+ var s2 = 1e3;
16055
+ var m2 = s2 * 60;
16056
+ var h2 = m2 * 60;
16057
+ var d2 = h2 * 24;
16058
+ var w2 = d2 * 7;
16059
+ var y2 = d2 * 365.25;
16060
+ ms$1 = function(val, options) {
16061
+ options = options || {};
16062
+ var type = typeof val;
16063
+ if (type === "string" && val.length > 0) {
16064
+ return parse2(val);
16065
+ } else if (type === "number" && isFinite(val)) {
16066
+ return options.long ? fmtLong(val) : fmtShort(val);
16067
+ }
16068
+ throw new Error(
16069
+ "val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
16070
+ );
16071
+ };
16072
+ function parse2(str) {
16073
+ str = String(str);
16074
+ if (str.length > 100) {
16075
+ return;
16076
+ }
16077
+ var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
16078
+ str
16079
+ );
16080
+ if (!match) {
16081
+ return;
16082
+ }
16083
+ var n = parseFloat(match[1]);
16084
+ var type = (match[2] || "ms").toLowerCase();
16085
+ switch (type) {
16086
+ case "years":
16087
+ case "year":
16088
+ case "yrs":
16089
+ case "yr":
16090
+ case "y":
16091
+ return n * y2;
16092
+ case "weeks":
16093
+ case "week":
16094
+ case "w":
16095
+ return n * w2;
16096
+ case "days":
16097
+ case "day":
16098
+ case "d":
16099
+ return n * d2;
16100
+ case "hours":
16101
+ case "hour":
16102
+ case "hrs":
16103
+ case "hr":
16104
+ case "h":
16105
+ return n * h2;
16106
+ case "minutes":
16107
+ case "minute":
16108
+ case "mins":
16109
+ case "min":
16110
+ case "m":
16111
+ return n * m2;
16112
+ case "seconds":
16113
+ case "second":
16114
+ case "secs":
16115
+ case "sec":
16116
+ case "s":
16117
+ return n * s2;
16118
+ case "milliseconds":
16119
+ case "millisecond":
16120
+ case "msecs":
16121
+ case "msec":
16122
+ case "ms":
16123
+ return n;
16124
+ default:
16125
+ return void 0;
16126
+ }
16127
+ }
16128
+ function fmtShort(ms2) {
16129
+ var msAbs = Math.abs(ms2);
16130
+ if (msAbs >= d2) {
16131
+ return Math.round(ms2 / d2) + "d";
16132
+ }
16133
+ if (msAbs >= h2) {
16134
+ return Math.round(ms2 / h2) + "h";
16135
+ }
16136
+ if (msAbs >= m2) {
16137
+ return Math.round(ms2 / m2) + "m";
16138
+ }
16139
+ if (msAbs >= s2) {
16140
+ return Math.round(ms2 / s2) + "s";
16141
+ }
16142
+ return ms2 + "ms";
16143
+ }
16144
+ function fmtLong(ms2) {
16145
+ var msAbs = Math.abs(ms2);
16146
+ if (msAbs >= d2) {
16147
+ return plural(ms2, msAbs, d2, "day");
16148
+ }
16149
+ if (msAbs >= h2) {
16150
+ return plural(ms2, msAbs, h2, "hour");
16151
+ }
16152
+ if (msAbs >= m2) {
16153
+ return plural(ms2, msAbs, m2, "minute");
16154
+ }
16155
+ if (msAbs >= s2) {
16156
+ return plural(ms2, msAbs, s2, "second");
16157
+ }
16158
+ return ms2 + " ms";
16159
+ }
16160
+ function plural(ms2, msAbs, n, name2) {
16161
+ var isPlural = msAbs >= n * 1.5;
16162
+ return Math.round(ms2 / n) + " " + name2 + (isPlural ? "s" : "");
16163
+ }
16164
+ return ms$1;
16165
+ }
16166
+ var msExports = requireMs();
16167
+ const ms = /* @__PURE__ */ getDefaultExportFromCjs(msExports);
16168
+ function parseDurationToDate(param) {
16169
+ if (typeof param === "string") {
16170
+ const durationMs = ms(param);
16171
+ if (typeof durationMs !== "number" || durationMs < 0) {
16172
+ throw new Error(`Invalid duration: "${param}". Expected a valid duration string like "1s", "1m", "1h", etc.`);
16173
+ }
16174
+ return new Date(Date.now() + durationMs);
16175
+ } else if (typeof param === "number") {
16176
+ if (param < 0 || !Number.isFinite(param)) {
16177
+ throw new Error(`Invalid duration: ${param}. Expected a non-negative finite number of milliseconds.`);
16178
+ }
16179
+ return new Date(Date.now() + param);
16180
+ } else if (param instanceof Date || param && typeof param === "object" && typeof param.getTime === "function") {
16181
+ return param instanceof Date ? param : new Date(param.getTime());
16182
+ } else {
16183
+ throw new Error(`Invalid duration parameter. Expected a duration string, number (milliseconds), or Date object.`);
16184
+ }
16185
+ }
15934
16186
  const UNDEFINED = -1;
15935
16187
  const HOLE = -2;
15936
16188
  const NAN = -3;
@@ -16186,143 +16438,6 @@ function unflatten(parsed, revivers, options) {
16186
16438
  }
16187
16439
  return hydrate(0);
16188
16440
  }
16189
- var ms$1;
16190
- var hasRequiredMs;
16191
- function requireMs() {
16192
- if (hasRequiredMs) return ms$1;
16193
- hasRequiredMs = 1;
16194
- var s2 = 1e3;
16195
- var m2 = s2 * 60;
16196
- var h2 = m2 * 60;
16197
- var d2 = h2 * 24;
16198
- var w2 = d2 * 7;
16199
- var y2 = d2 * 365.25;
16200
- ms$1 = function(val, options) {
16201
- options = options || {};
16202
- var type = typeof val;
16203
- if (type === "string" && val.length > 0) {
16204
- return parse2(val);
16205
- } else if (type === "number" && isFinite(val)) {
16206
- return options.long ? fmtLong(val) : fmtShort(val);
16207
- }
16208
- throw new Error(
16209
- "val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
16210
- );
16211
- };
16212
- function parse2(str) {
16213
- str = String(str);
16214
- if (str.length > 100) {
16215
- return;
16216
- }
16217
- var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
16218
- str
16219
- );
16220
- if (!match) {
16221
- return;
16222
- }
16223
- var n = parseFloat(match[1]);
16224
- var type = (match[2] || "ms").toLowerCase();
16225
- switch (type) {
16226
- case "years":
16227
- case "year":
16228
- case "yrs":
16229
- case "yr":
16230
- case "y":
16231
- return n * y2;
16232
- case "weeks":
16233
- case "week":
16234
- case "w":
16235
- return n * w2;
16236
- case "days":
16237
- case "day":
16238
- case "d":
16239
- return n * d2;
16240
- case "hours":
16241
- case "hour":
16242
- case "hrs":
16243
- case "hr":
16244
- case "h":
16245
- return n * h2;
16246
- case "minutes":
16247
- case "minute":
16248
- case "mins":
16249
- case "min":
16250
- case "m":
16251
- return n * m2;
16252
- case "seconds":
16253
- case "second":
16254
- case "secs":
16255
- case "sec":
16256
- case "s":
16257
- return n * s2;
16258
- case "milliseconds":
16259
- case "millisecond":
16260
- case "msecs":
16261
- case "msec":
16262
- case "ms":
16263
- return n;
16264
- default:
16265
- return void 0;
16266
- }
16267
- }
16268
- function fmtShort(ms2) {
16269
- var msAbs = Math.abs(ms2);
16270
- if (msAbs >= d2) {
16271
- return Math.round(ms2 / d2) + "d";
16272
- }
16273
- if (msAbs >= h2) {
16274
- return Math.round(ms2 / h2) + "h";
16275
- }
16276
- if (msAbs >= m2) {
16277
- return Math.round(ms2 / m2) + "m";
16278
- }
16279
- if (msAbs >= s2) {
16280
- return Math.round(ms2 / s2) + "s";
16281
- }
16282
- return ms2 + "ms";
16283
- }
16284
- function fmtLong(ms2) {
16285
- var msAbs = Math.abs(ms2);
16286
- if (msAbs >= d2) {
16287
- return plural(ms2, msAbs, d2, "day");
16288
- }
16289
- if (msAbs >= h2) {
16290
- return plural(ms2, msAbs, h2, "hour");
16291
- }
16292
- if (msAbs >= m2) {
16293
- return plural(ms2, msAbs, m2, "minute");
16294
- }
16295
- if (msAbs >= s2) {
16296
- return plural(ms2, msAbs, s2, "second");
16297
- }
16298
- return ms2 + " ms";
16299
- }
16300
- function plural(ms2, msAbs, n, name2) {
16301
- var isPlural = msAbs >= n * 1.5;
16302
- return Math.round(ms2 / n) + " " + name2 + (isPlural ? "s" : "");
16303
- }
16304
- return ms$1;
16305
- }
16306
- var msExports = requireMs();
16307
- const ms = /* @__PURE__ */ getDefaultExportFromCjs(msExports);
16308
- function parseDurationToDate(param) {
16309
- if (typeof param === "string") {
16310
- const durationMs = ms(param);
16311
- if (typeof durationMs !== "number" || durationMs < 0) {
16312
- throw new Error(`Invalid duration: "${param}". Expected a valid duration string like "1s", "1m", "1h", etc.`);
16313
- }
16314
- return new Date(Date.now() + durationMs);
16315
- } else if (typeof param === "number") {
16316
- if (param < 0 || !Number.isFinite(param)) {
16317
- throw new Error(`Invalid duration: ${param}. Expected a non-negative finite number of milliseconds.`);
16318
- }
16319
- return new Date(Date.now() + param);
16320
- } else if (param instanceof Date || param && typeof param === "object" && typeof param.getTime === "function") {
16321
- return param instanceof Date ? param : new Date(param.getTime());
16322
- } else {
16323
- throw new Error(`Invalid duration parameter. Expected a duration string, number (milliseconds), or Date object.`);
16324
- }
16325
- }
16326
16441
  const BASE_URL = "https://workflow-sdk.dev/err";
16327
16442
  function isError(value) {
16328
16443
  return typeof value === "object" && value !== null && "name" in value && "message" in value;
@@ -16606,7 +16721,7 @@ function importPublicKey(publicKey) {
16606
16721
  { name: "X25519" },
16607
16722
  /* extractable */
16608
16723
  true,
16609
- // Public keys carry no usages for X25519 the private key does the
16724
+ // Public keys carry no usages for X25519: the private key does the
16610
16725
  // deriving; the public key is only ever an argument to it.
16611
16726
  []
16612
16727
  );
@@ -16701,7 +16816,7 @@ const SerializationFormat$1 = {
16701
16816
  /** Encrypted payload (inner payload has its own format prefix) */
16702
16817
  ENCRYPTED: "encr",
16703
16818
  /**
16704
- * Sealed payload asymmetrically encrypted to a run's X25519 public key
16819
+ * Sealed payload: asymmetrically encrypted to a run's X25519 public key
16705
16820
  * (inner payload has its own format prefix).
16706
16821
  *
16707
16822
  * Used for *cross-run* writes (hook payloads, forwarded stream frames),
@@ -16831,7 +16946,7 @@ const SerializationFormat = {
16831
16946
  /** Encrypted payload (inner payload has its own format prefix after decryption) */
16832
16947
  ENCRYPTED: "encr",
16833
16948
  /**
16834
- * Sealed payload asymmetrically encrypted to a run's X25519 public key
16949
+ * Sealed payload: asymmetrically encrypted to a run's X25519 public key
16835
16950
  * (inner payload has its own format prefix after opening).
16836
16951
  *
16837
16952
  * Written by cross-run writers that hold only the recipient run's public
@@ -16925,17 +17040,19 @@ function decompressSyncIfAvailable(format, payload) {
16925
17040
  }
16926
17041
  return void 0;
16927
17042
  }
16928
- let zstdBrowserDecoder;
17043
+ const zstd = globalSingleton("@workflow/core//zstd.decoder", 1, () => ({
17044
+ decoder: void 0
17045
+ }));
16929
17046
  function registerZstdDecoder(decoder2) {
16930
- zstdBrowserDecoder = decoder2;
17047
+ zstd.decoder = decoder2;
16931
17048
  }
16932
17049
  async function decompressAsync(format, payload) {
16933
17050
  if (format === SerializationFormat.ZSTD) {
16934
17051
  const sync = decompressSyncIfAvailable(format, payload);
16935
17052
  if (sync)
16936
17053
  return sync;
16937
- if (zstdBrowserDecoder)
16938
- return zstdBrowserDecoder(payload);
17054
+ if (zstd.decoder)
17055
+ return zstd.decoder(payload);
16939
17056
  throw new Error("zstd-compressed workflow data encountered but no zstd decoder is available. Node.js 22.15+ decodes natively; in the browser register one via registerZstdDecoder (the web o11y package does this).");
16940
17057
  }
16941
17058
  const transform2 = new DecompressionStream("gzip");
@@ -17082,7 +17199,7 @@ const observabilityRevivers = {
17082
17199
  // throws on the `["DOMException", ...]` tag and `hydrateStepIO`'s
17083
17200
  // try/catch leaves the raw flat-encoded string in the UI. AbortController
17084
17201
  // synthesizes a DOMException as the default `signal.reason` when abort()
17085
- // is called with no arg so any abort that round-trips through a step
17202
+ // is called with no arg, so any abort that round-trips through a step
17086
17203
  // boundary surfaces here. Reconstruct as a real DOMException when the
17087
17204
  // global is available (modern browsers + Node 18+), else fall back to
17088
17205
  // an Error preserving name/message/stack/cause for display.
@@ -17289,8 +17406,8 @@ function getWebRevivers() {
17289
17406
  // entry for each built-in Error subclass plus the workflow-specific
17290
17407
  // `FatalError` / `RetryableError` / `HookConflictError` /
17291
17408
  // `RuntimeDecryptionError` and `AggregateError`. Without
17292
- // matching revivers here, `devalue.unflatten` throws "Unknown type X"
17293
- // which surfaces in the web o11y UI as "Failed to load resource
17409
+ // matching revivers here, `devalue.unflatten` throws "Unknown type X",
17410
+ // which surfaces in the web o11y UI as "Failed to load resource
17294
17411
  // details: Unknown type FatalError".
17295
17412
  Error: (value) => {
17296
17413
  const opts = "cause" in value ? { cause: value.cause } : void 0;
@@ -17320,7 +17437,7 @@ function getWebRevivers() {
17320
17437
  // `FatalError` and `RetryableError` are not built-in browser globals,
17321
17438
  // so we can't resolve a constructor from globalThis. The web o11y UI
17322
17439
  // doesn't need `instanceof FatalError` to pass (no user code runs
17323
- // here) it just needs `name`, `message`, `stack`, and any extra
17440
+ // here). The web o11y UI needs `name`, `message`, `stack`, and any extra
17324
17441
  // enumerable fields to render. Construct a plain `Error` with `name`
17325
17442
  // set; ObjectInspector reads `constructor.name` for the displayed
17326
17443
  // class label, but we don't have the real class, so we emit a tagged
@@ -17522,7 +17639,7 @@ async function hydrateResourceIOAsync(resource, key) {
17522
17639
  return { hydrateDataWithKey: hydrateDataWithKey3, deriveRunPayloadKeys: deriveRunPayloadKeys3 };
17523
17640
  }, true ? void 0 : void 0);
17524
17641
  const { ensureZstdDecoderRegistered } = await __vitePreload(async () => {
17525
- const { ensureZstdDecoderRegistered: ensureZstdDecoderRegistered2 } = await import("./zstd-browser-decoder-CAEVa0bm.js");
17642
+ const { ensureZstdDecoderRegistered: ensureZstdDecoderRegistered2 } = await import("./zstd-browser-decoder-DafWVuEG.js");
17526
17643
  return { ensureZstdDecoderRegistered: ensureZstdDecoderRegistered2 };
17527
17644
  }, true ? __vite__mapDeps([0,1]) : void 0);
17528
17645
  ensureZstdDecoderRegistered();
@@ -19109,7 +19226,7 @@ const RunClickContext = reactExports.createContext(void 0);
19109
19226
  function EncryptedInlineLabel() {
19110
19227
  const ctx = reactExports.useContext(DecryptClickContext);
19111
19228
  if (ctx) {
19112
- return jsxRuntimeExports.jsxs(Button$1, { size: "xs", className: "align-baseline gap-x-1", disabled: ctx.isDecrypting, onClick: (e) => {
19229
+ return jsxRuntimeExports.jsxs(Button$1, { size: "xs", className: "align-baseline gap-x-1", disabled: ctx.isDecrypting || ctx.isDecryptDisabled, title: ctx.isDecryptDisabled ? ctx.decryptDisabledReason : void 0, onClick: (e) => {
19113
19230
  e.stopPropagation();
19114
19231
  ctx.onDecrypt();
19115
19232
  }, children: [ctx.isDecrypting ? jsxRuntimeExports.jsx(Spinner, { size: 10 }) : jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { children: "Decrypt" })] });
@@ -19382,7 +19499,7 @@ function collapseRefs(data) {
19382
19499
  }
19383
19500
  return result;
19384
19501
  }
19385
- function DataInspector({ data, expandLevel = 2, name: name2, onStreamClick, onRunClick, onDecrypt, isDecrypting = false }) {
19502
+ function DataInspector({ data, expandLevel = 2, name: name2, onStreamClick, onRunClick, onDecrypt, isDecrypting = false, isDecryptDisabled = false, decryptDisabledReason }) {
19386
19503
  const collapsedData = reactExports.useMemo(() => collapseRefs(data), [data]);
19387
19504
  const stableData = useStableInspectorData(collapsedData);
19388
19505
  let content2 = jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { href: "wf-json-view", precedence: "default", children: JSON_VIEW_STYLES }), jsxRuntimeExports.jsx(JsonTree, { data: stableData, name: name2, expandLevel })] });
@@ -19393,7 +19510,12 @@ function DataInspector({ data, expandLevel = 2, name: name2, onStreamClick, onRu
19393
19510
  content2 = jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: content2 });
19394
19511
  }
19395
19512
  if (onDecrypt) {
19396
- content2 = jsxRuntimeExports.jsx(DecryptClickContext.Provider, { value: { onDecrypt, isDecrypting }, children: content2 });
19513
+ content2 = jsxRuntimeExports.jsx(DecryptClickContext.Provider, { value: {
19514
+ onDecrypt,
19515
+ isDecrypting,
19516
+ isDecryptDisabled,
19517
+ decryptDisabledReason
19518
+ }, children: content2 });
19397
19519
  }
19398
19520
  return content2;
19399
19521
  }
@@ -19478,7 +19600,7 @@ const encryptedPlaceholderPreview = `{
19478
19600
  }`;
19479
19601
  function EncryptedDataBlock() {
19480
19602
  const ctx = reactExports.useContext(DecryptClickContext);
19481
- return jsxRuntimeExports.jsxs("div", { className: "relative min-h-20 overflow-hidden rounded-md border border-gray-alpha-400 bg-background-100", children: [jsxRuntimeExports.jsx("pre", { "aria-hidden": "true", className: "pointer-events-none m-0 select-none p-3 font-mono text-label-12 text-gray-900 blur-[4px]", children: encryptedPlaceholderPreview }), jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: ctx ? jsxRuntimeExports.jsxs(Button$1, { onClick: ctx.onDecrypt, disabled: ctx.isDecrypting, size: "xs", children: [ctx.isDecrypting ? jsxRuntimeExports.jsx(Spinner, { size: 10 }) : jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { children: "Decrypt" })] }) : jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 rounded border border-gray-alpha-400 bg-gray-100 px-1.5 py-0.5 text-button-12 font-medium text-gray-700", children: [jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), "Encrypted"] }) })] });
19603
+ return jsxRuntimeExports.jsxs("div", { className: "relative min-h-20 overflow-hidden rounded-md border border-gray-alpha-400 bg-background-100", children: [jsxRuntimeExports.jsx("pre", { "aria-hidden": "true", className: "pointer-events-none m-0 select-none p-3 font-mono text-label-12 text-gray-900 blur-[4px]", children: encryptedPlaceholderPreview }), jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: ctx ? jsxRuntimeExports.jsxs(Button$1, { onClick: ctx.onDecrypt, disabled: ctx.isDecrypting || ctx.isDecryptDisabled, title: ctx.isDecryptDisabled ? ctx.decryptDisabledReason : void 0, size: "xs", children: [ctx.isDecrypting ? jsxRuntimeExports.jsx(Spinner, { size: 10 }) : jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { children: "Decrypt" })] }) : jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 rounded border border-gray-alpha-400 bg-gray-100 px-1.5 py-0.5 text-button-12 font-medium text-gray-700", children: [jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), "Encrypted"] }) })] });
19482
19604
  }
19483
19605
  const serializeForClipboard = (value) => {
19484
19606
  if (typeof value === "string")
@@ -20305,27 +20427,27 @@ function ZoneDateTimeRow({ date: date2, zone }) {
20305
20427
  });
20306
20428
  return jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-4 px-1.5 bg-gray-200 rounded-xs", children: jsxRuntimeExports.jsx("span", { className: "text-label-12-mono text-gray-900", children: formattedZone }) }), jsxRuntimeExports.jsx("span", { className: "text-label-13 text-gray-1000", children: formattedDate })] }), jsxRuntimeExports.jsx("span", { className: "tabular-nums text-label-12-mono text-gray-900", children: formattedTime })] });
20307
20429
  }
20308
- function RelativeTimeContextCardContent({ date: date2 }) {
20430
+ function RelativeTimeContextCardContent({ date: date2, prefix }) {
20309
20431
  const localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
20310
20432
  const timeAgo = useTimeAgo(date2);
20311
- return jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3 min-w-[300px]", children: [jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-3", children: jsxRuntimeExports.jsx("span", { className: "tabular-nums text-label-13 text-gray-900", children: timeAgo }) }), jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntimeExports.jsx(ZoneDateTimeRow, { date: date2, zone: "UTC" }), jsxRuntimeExports.jsx(ZoneDateTimeRow, { date: date2, zone: localTimezone })] })] });
20433
+ return jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3 min-w-[300px]", children: [jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-3", children: jsxRuntimeExports.jsx("span", { className: "tabular-nums text-label-13 text-gray-900", children: prefix ? `${prefix} ${timeAgo}` : timeAgo }) }), jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntimeExports.jsx(ZoneDateTimeRow, { date: date2, zone: "UTC" }), jsxRuntimeExports.jsx(ZoneDateTimeRow, { date: date2, zone: localTimezone })] })] });
20312
20434
  }
20313
20435
  function DefaultTimeText({ date: date2 }) {
20314
20436
  const shortTimeAgo = useShortTimeAgo(date2);
20315
20437
  return jsxRuntimeExports.jsx("span", { className: "text-label-14 text-gray-900", children: shortTimeAgo });
20316
20438
  }
20317
- function RelativeTimeCard({ date: date2, children: _children, ...props }) {
20439
+ function RelativeTimeCard({ date: date2, children: _children, prefix, ...props }) {
20318
20440
  const children2 = _children === void 0 ? jsxRuntimeExports.jsx(DefaultTimeText, { date: date2 }) : _children;
20319
20441
  if (!date2)
20320
20442
  return children2;
20321
- return jsxRuntimeExports.jsx(ContextCardTrigger, { content: jsxRuntimeExports.jsx(RelativeTimeContextCardContent, { date: date2 }), ...props, children: children2 });
20443
+ return jsxRuntimeExports.jsx(ContextCardTrigger, { content: jsxRuntimeExports.jsx(RelativeTimeContextCardContent, { date: date2, prefix }), ...props, children: children2 });
20322
20444
  }
20323
- function TimestampTooltip({ date: date2, children: children2, side = "top" }) {
20445
+ function TimestampTooltip({ date: date2, children: children2, side = "top", prefix }) {
20324
20446
  const hasProvider = useHasContextCardProvider();
20325
20447
  const ts = date2 == null ? null : typeof date2 === "number" ? date2 : new Date(date2).getTime();
20326
20448
  if (ts == null || Number.isNaN(ts))
20327
20449
  return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: children2 });
20328
- const card = jsxRuntimeExports.jsx(RelativeTimeCard, { date: ts, side, asChild: true, children: children2 });
20450
+ const card = jsxRuntimeExports.jsx(RelativeTimeCard, { date: ts, side, prefix, asChild: true, children: children2 });
20329
20451
  return hasProvider ? card : jsxRuntimeExports.jsx(ContextCardProvider, { children: card });
20330
20452
  }
20331
20453
  const convert = (
@@ -45113,7 +45235,7 @@ var tn = f("block", "before:content-[counter(line)]", "before:inline-block", "be
45113
45235
  var et = ({ className: e, language: t, style: o, isIncomplete: n, ...s2 }) => jsxRuntimeExports.jsx("div", { className: f("my-4 flex w-full flex-col gap-2 rounded-xl border border-border bg-sidebar p-2", e), "data-incomplete": n || void 0, "data-language": t, "data-streamdown": "code-block", style: { contentVisibility: "auto", containIntrinsicSize: "auto 200px", ...o }, ...s2 });
45114
45236
  var Se = reactExports.createContext({ code: "" }), de = () => reactExports.useContext(Se);
45115
45237
  var ot = ({ language: e }) => jsxRuntimeExports.jsx("div", { className: "flex h-8 items-center text-muted-foreground text-xs", "data-language": e, "data-streamdown": "code-block-header", children: jsxRuntimeExports.jsx("span", { className: "ml-1 font-mono lowercase", children: e }) });
45116
- var cn$1 = /\n+$/, dn = reactExports.lazy(() => __vitePreload(() => import("./highlighted-body-B3W2YXNL-Dc1dLaUr.js"), true ? __vite__mapDeps([2,1]) : void 0).then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
45238
+ var cn$1 = /\n+$/, dn = reactExports.lazy(() => __vitePreload(() => import("./highlighted-body-B3W2YXNL-D78gcP7S.js"), true ? __vite__mapDeps([2,1]) : void 0).then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
45117
45239
  let i = reactExports.useMemo(() => e.replace(cn$1, ""), [e]), c = reactExports.useMemo(() => ({ bg: "transparent", fg: "inherit", tokens: i.split(`
45118
45240
  `).map((a2) => [{ content: a2, color: "inherit", bgColor: "transparent", htmlStyle: {}, offset: 0 }]) }), [i]);
45119
45241
  return jsxRuntimeExports.jsx(Se.Provider, { value: { code: e }, children: jsxRuntimeExports.jsxs(et, { isIncomplete: s2, language: t, children: [jsxRuntimeExports.jsx(ot, { language: t }), n ? jsxRuntimeExports.jsx("div", { className: "pointer-events-none sticky top-2 z-10 -mt-10 flex h-8 items-center justify-end", children: jsxRuntimeExports.jsx("div", { className: "pointer-events-auto flex shrink-0 items-center gap-2 rounded-md border border-sidebar bg-sidebar/80 px-1.5 py-1 supports-[backdrop-filter]:bg-sidebar/70 supports-[backdrop-filter]:backdrop-blur", "data-streamdown": "code-block-actions", children: n }) }) : null, jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: jsxRuntimeExports.jsx(Qe, { className: o, language: t, result: c, ...r2 }), children: jsxRuntimeExports.jsx(dn, { className: o, code: i, language: t, raw: c, ...r2 }) })] }) });
@@ -46274,7 +46396,7 @@ const RESOURCE_CLASS_NAMES = {
46274
46396
  className: "border-green-500 bg-green-200",
46275
46397
  errorClassName: "border-red-500 bg-red-200"
46276
46398
  },
46277
- // Passive spans (hooks) stay gray matches event-list icons and the minimap.
46399
+ // Passive spans (hooks) stay gray; matches event-list icons and the minimap.
46278
46400
  hook: {
46279
46401
  className: "border-gray-500 bg-gray-200",
46280
46402
  errorClassName: "border-red-500 bg-red-200"
@@ -46472,7 +46594,8 @@ function computeSpanSegments(span) {
46472
46594
  const MARKER_EVENT_NAMES = ["hook_received", "attr_set"];
46473
46595
  function computeSpanMarkers(span) {
46474
46596
  return sortedEventMarks(span.events, MARKER_EVENT_NAMES).map((mark2) => ({
46475
- timeMs: mark2.time
46597
+ timeMs: mark2.time,
46598
+ kind: mark2.type
46476
46599
  }));
46477
46600
  }
46478
46601
  function computeOffscreenMarkers(markers, visibleStartMs, visibleEndMs) {
@@ -46568,6 +46691,10 @@ function scrollRowIntoView(listEl, index2, rowHeight, opts) {
46568
46691
  behavior: opts == null ? void 0 : opts.behavior
46569
46692
  });
46570
46693
  }
46694
+ const MARKER_KIND_PREFIX = {
46695
+ hook_received: "Hook received",
46696
+ attr_set: "Attribute set"
46697
+ };
46571
46698
  function projectMarkers(markers, visibleStartMs, visibleEndMs) {
46572
46699
  const visibleDurationMs = visibleEndMs - visibleStartMs;
46573
46700
  if (visibleDurationMs <= 0)
@@ -46579,7 +46706,8 @@ function projectMarkers(markers, visibleStartMs, visibleEndMs) {
46579
46706
  return [
46580
46707
  {
46581
46708
  leftPct: (m2.timeMs - visibleStartMs) / visibleDurationMs * 100,
46582
- timeMs: m2.timeMs
46709
+ timeMs: m2.timeMs,
46710
+ kind: m2.kind
46583
46711
  }
46584
46712
  ];
46585
46713
  });
@@ -46601,7 +46729,7 @@ function MarkerTick({ className }) {
46601
46729
  return jsxRuntimeExports.jsx("span", { className: cn$4("block w-[3px] rounded-full bg-gray-1000", className) });
46602
46730
  }
46603
46731
  function MarkerLayer({ markers }) {
46604
- return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: markers.map((m2) => jsxRuntimeExports.jsx("span", { className: "pointer-events-auto absolute top-0 bottom-0 z-10 flex w-8 -translate-x-1/2 items-center justify-center", style: { left: `clamp(8px, ${m2.leftPct}%, calc(100% - 8px))` }, children: jsxRuntimeExports.jsx(TimestampTooltip, { date: m2.timeMs, children: jsxRuntimeExports.jsx("span", { className: "flex h-6 w-8 items-center justify-center", children: jsxRuntimeExports.jsx(MarkerTick, { className: "h-3" }) }) }) }, m2.timeMs)) });
46732
+ return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: markers.map((m2, index2) => jsxRuntimeExports.jsx("span", { className: "pointer-events-auto absolute top-0 bottom-0 z-10 flex w-8 -translate-x-1/2 items-center justify-center", style: { left: `clamp(8px, ${m2.leftPct}%, calc(100% - 8px))` }, children: jsxRuntimeExports.jsx(TimestampTooltip, { date: m2.timeMs, prefix: MARKER_KIND_PREFIX[m2.kind], children: jsxRuntimeExports.jsx("span", { className: "flex h-6 w-8 items-center justify-center", children: jsxRuntimeExports.jsx(MarkerTick, { className: "h-3" }) }) }) }, `${m2.timeMs}-${index2}`)) });
46605
46733
  }
46606
46734
  function OffscreenMarkerIndicator({ direction, count: count2, targetMs, onReveal }) {
46607
46735
  const Chevron = direction === "right" ? ArrowRight : ArrowLeft;
@@ -49524,7 +49652,7 @@ const mermaid3ZIDBTTL = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
49524
49652
  Mermaid: Nt
49525
49653
  }, Symbol.toStringTag, { value: "Module" }));
49526
49654
  export {
49527
- CopyableDataBlock as $,
49655
+ cn$4 as $,
49528
49656
  Anchor as A,
49529
49657
  Button as B,
49530
49658
  Check as C,
@@ -49550,108 +49678,109 @@ export {
49550
49678
  createContext2 as W,
49551
49679
  fetchWorkflowsManifest as X,
49552
49680
  entityEventClass as Y,
49553
- cn$4 as Z,
49681
+ isSealedNoopEvent as Z,
49554
49682
  __vitePreload as _,
49555
49683
  TooltipTrigger as a,
49556
- fetchStreams as a$,
49557
- CollapsibleRoot as a0,
49558
- CollapsibleTrigger as a1,
49559
- CollapsibleContent as a2,
49560
- CopyButton as a3,
49561
- RESERVED_ATTRIBUTE_KEY_PREFIX as a4,
49562
- Spinner as a5,
49563
- TooltipProvider as a6,
49564
- Tooltip$1 as a7,
49565
- TooltipTrigger$1 as a8,
49566
- TooltipContent$1 as a9,
49567
- useSidebarData as aA,
49568
- IconButton as aB,
49569
- useRowWindow as aC,
49570
- isSpanDimmedBySearch as aD,
49571
- ROW_HEIGHT_PX as aE,
49572
- getSpanDurationMs as aF,
49573
- isSpanErrored as aG,
49574
- formatDurationPrecise as aH,
49575
- ActiveSpanProvider as aI,
49576
- useReducedMotion as aJ,
49577
- searchSpans as aK,
49578
- computeRootBounds as aL,
49579
- computeTimeMarkers as aM,
49580
- clampViewportToRoot as aN,
49581
- getHighResInMs as aO,
49582
- scrollRowIntoView as aP,
49583
- TIMELINE_PADDING_PX as aQ,
49584
- Minimap as aR,
49585
- Timeline as aS,
49586
- TimelineHeader as aT,
49587
- wheelZoomScaleFactor as aU,
49588
- wheelDeltaToPixels as aV,
49589
- SidebarDataProvider as aW,
49590
- fetchHook as aX,
49591
- hydrateResourceIOAsync as aY,
49592
- fetchStep as aZ,
49593
- hydrateResourceIO as a_,
49594
- ContextCardProvider as aa,
49595
- Skeleton as ab,
49596
- DecryptClickContext as ac,
49597
- Yr as ad,
49598
- isEncryptedMarker$1 as ae,
49599
- TimestampTooltip as af,
49600
- formatDuration as ag,
49601
- DataInspector as ah,
49602
- _r as ai,
49603
- isHookLifecycleEventType as aj,
49604
- isTerminalStepEventType as ak,
49605
- isWaitEventType as al,
49606
- isStepEventType as am,
49607
- RunClickContext as an,
49608
- StreamClickContext as ao,
49609
- Collapsible as ap,
49610
- isExpiredMarker as aq,
49611
- isDoStreamStep as ar,
49612
- extractConversation as as,
49613
- EncryptedDataBlock as at,
49614
- getEventDataRefFields as au,
49615
- hasEncryptedFields as av,
49616
- useSidebarDataOptional as aw,
49617
- isTerminalWorkflowRunStatus as ax,
49618
- clsx as ay,
49619
- useActiveSpan as az,
49684
+ hydrateResourceIO as a$,
49685
+ CopyableDataBlock as a0,
49686
+ CollapsibleRoot as a1,
49687
+ CollapsibleTrigger as a2,
49688
+ CollapsibleContent as a3,
49689
+ CopyButton as a4,
49690
+ RESERVED_ATTRIBUTE_KEY_PREFIX as a5,
49691
+ Spinner as a6,
49692
+ TooltipProvider as a7,
49693
+ Tooltip$1 as a8,
49694
+ TooltipTrigger$1 as a9,
49695
+ useActiveSpan as aA,
49696
+ useSidebarData as aB,
49697
+ IconButton as aC,
49698
+ useRowWindow as aD,
49699
+ isSpanDimmedBySearch as aE,
49700
+ ROW_HEIGHT_PX as aF,
49701
+ getSpanDurationMs as aG,
49702
+ isSpanErrored as aH,
49703
+ formatDurationPrecise as aI,
49704
+ ActiveSpanProvider as aJ,
49705
+ useReducedMotion as aK,
49706
+ searchSpans as aL,
49707
+ computeRootBounds as aM,
49708
+ computeTimeMarkers as aN,
49709
+ clampViewportToRoot as aO,
49710
+ getHighResInMs as aP,
49711
+ scrollRowIntoView as aQ,
49712
+ TIMELINE_PADDING_PX as aR,
49713
+ Minimap as aS,
49714
+ Timeline as aT,
49715
+ TimelineHeader as aU,
49716
+ wheelZoomScaleFactor as aV,
49717
+ wheelDeltaToPixels as aW,
49718
+ SidebarDataProvider as aX,
49719
+ fetchHook as aY,
49720
+ hydrateResourceIOAsync as aZ,
49721
+ fetchStep as a_,
49722
+ TooltipContent$1 as aa,
49723
+ ContextCardProvider as ab,
49724
+ Skeleton as ac,
49725
+ DecryptClickContext as ad,
49726
+ Yr as ae,
49727
+ isEncryptedMarker$1 as af,
49728
+ TimestampTooltip as ag,
49729
+ formatDuration as ah,
49730
+ DataInspector as ai,
49731
+ _r as aj,
49732
+ isHookLifecycleEventType as ak,
49733
+ isTerminalStepEventType as al,
49734
+ isWaitEventType as am,
49735
+ isStepEventType as an,
49736
+ RunClickContext as ao,
49737
+ StreamClickContext as ap,
49738
+ Collapsible as aq,
49739
+ isExpiredMarker as ar,
49740
+ isDoStreamStep as as,
49741
+ extractConversation as at,
49742
+ EncryptedDataBlock as au,
49743
+ getEventDataRefFields as av,
49744
+ hasEncryptedFields as aw,
49745
+ useSidebarDataOptional as ax,
49746
+ isTerminalWorkflowRunStatus as ay,
49747
+ clsx as az,
49620
49748
  TooltipContent as b,
49621
- apiBase as b0,
49622
- Slot as b1,
49623
- Slottable as b2,
49624
- buttonVariants as b3,
49625
- fetchEvent as b4,
49626
- fetchEventsByCorrelationId as b5,
49627
- isEncryptedData as b6,
49628
- hydrateData as b7,
49629
- decrypt as b8,
49630
- deriveRunPayloadKeys as b9,
49631
- getWebRevivers as ba,
49632
- LIVE_UPDATE_INTERVAL_MS as bb,
49633
- getEncryptionKeyForRun as bc,
49634
- StreamViewerSkeleton as bd,
49635
- Lock as be,
49636
- StreamViewer as bf,
49637
- composeRefs as bg,
49638
- useFloating as bh,
49639
- offset as bi,
49640
- shift as bj,
49641
- limitShift as bk,
49642
- flip as bl,
49643
- size as bm,
49644
- arrow as bn,
49645
- hide as bo,
49646
- autoUpdate as bp,
49647
- VERCEL_403_ERROR_MESSAGE as bq,
49648
- bulkCancelRuns as br,
49649
- reenqueueRun as bs,
49650
- wakeUpRun as bt,
49651
- resumeHook as bu,
49652
- fetchHookToken as bv,
49653
- cancelRun as bw,
49654
- recreateRun as bx,
49749
+ fetchStreams as b0,
49750
+ apiBase as b1,
49751
+ Slot as b2,
49752
+ Slottable as b3,
49753
+ buttonVariants as b4,
49754
+ fetchEvent as b5,
49755
+ fetchEventsByCorrelationId as b6,
49756
+ isEncryptedData as b7,
49757
+ hydrateData as b8,
49758
+ decrypt as b9,
49759
+ deriveRunPayloadKeys as ba,
49760
+ getWebRevivers as bb,
49761
+ LIVE_UPDATE_INTERVAL_MS as bc,
49762
+ getEncryptionKeyForRun as bd,
49763
+ StreamViewerSkeleton as be,
49764
+ Lock as bf,
49765
+ StreamViewer as bg,
49766
+ composeRefs as bh,
49767
+ useFloating as bi,
49768
+ offset as bj,
49769
+ shift as bk,
49770
+ limitShift as bl,
49771
+ flip as bm,
49772
+ size as bn,
49773
+ arrow as bo,
49774
+ hide as bp,
49775
+ autoUpdate as bq,
49776
+ VERCEL_403_ERROR_MESSAGE as br,
49777
+ bulkCancelRuns as bs,
49778
+ reenqueueRun as bt,
49779
+ wakeUpRun as bu,
49780
+ resumeHook as bv,
49781
+ fetchHookToken as bw,
49782
+ cancelRun as bx,
49783
+ recreateRun as by,
49655
49784
  createLucideIcon as c,
49656
49785
  runHealthCheck as d,
49657
49786
  cn as e,