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

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-AtCpRI70.js} +1 -1
  2. package/build/client/assets/{highlighted-body-B3W2YXNL-Dc1dLaUr.js → highlighted-body-B3W2YXNL-BPRwlr7r.js} +1 -1
  3. package/build/client/assets/{home-C6CuMqQu.js → home-BMHSjdeg.js} +3 -3
  4. package/build/client/assets/{loader-circle-BOxaTUjK.js → loader-circle-abAcDEYl.js} +1 -1
  5. package/build/client/assets/{manifest-157e28f1.js → manifest-a9a8ec99.js} +1 -1
  6. package/build/client/assets/{mermaid-3ZIDBTTL-gEw-Ch1C.js → mermaid-3ZIDBTTL-CrfHaTou.js} +368 -294
  7. package/build/client/assets/{root-BfhMCbkz.js → root-e8qlLJiK.js} +3 -3
  8. package/build/client/assets/{run-detail-BG_1K2Hq.js → run-detail-CrWq-9Tk.js} +54 -31
  9. package/build/client/assets/{workflow-graph-viewer-CxrWityD.js → workflow-graph-viewer-CFAXloBw.js} +1 -1
  10. package/build/client/assets/{zstd-browser-decoder-CAEVa0bm.js → zstd-browser-decoder-B9DmHkyE.js} +1 -1
  11. package/build/server/assets/{app-_xgEuKqE.js → app-wed_Qw3X.js} +986 -672
  12. package/build/server/assets/{highlighted-body-B3W2YXNL-B1Smd86a.js → highlighted-body-B3W2YXNL-imLU-Cvz.js} +1 -1
  13. package/build/server/assets/{index-Ck5CB_wQ.js → index-Dsr6TVhD.js} +1 -1
  14. package/build/server/assets/{index-CSsrecUx.js → index-DxLR22JW.js} +68 -64
  15. package/build/server/assets/{mermaid-3ZIDBTTL-CwYR558N.js → mermaid-3ZIDBTTL-CgaDjNgb.js} +1 -1
  16. package/build/server/assets/{token-COK7oHMh.js → token-CA6-cBL4.js} +1 -1
  17. package/build/server/assets/{token-util-BhmVdeCX.js → token-util-BNjC27Tj.js} +1 -1
  18. package/build/server/assets/{websocket-server-ByjlHAhQ.js → websocket-server-S8DMC969.js} +1 -1
  19. package/build/server/assets/{wrapper-DWeVTope.js → wrapper-DeK0m2tW.js} +3 -3
  20. package/build/server/assets/{ws-transport-BCfcEhAO.js → ws-transport-DdxSF5J6.js} +40 -22
  21. package/build/server/assets/{zstd-browser-decoder-D8JD_nwS.js → zstd-browser-decoder-Cd_DTxZV.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-B9DmHkyE.js","assets/index-PFjW8YjQ.js","assets/highlighted-body-B3W2YXNL-BPRwlr7r.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);
@@ -14860,7 +14860,11 @@ const EventTypeSchema = _enum([
14860
14860
  // Created by world when hook token already exists
14861
14861
  // Wait lifecycle events
14862
14862
  "wait_created",
14863
- "wait_completed"
14863
+ "wait_completed",
14864
+ // Sealed-log filler (specVersion >= 7): written ONLY by the World's backend
14865
+ // to occupy a slot whose writer allocated it and died. Carries no workflow
14866
+ // meaning; replay skips it (see EventsConsumer). Never user-creatable.
14867
+ "noop"
14864
14868
  ]);
14865
14869
  const RunEventTypeSchema = EventTypeSchema.extract([
14866
14870
  "run_created",
@@ -14932,6 +14936,9 @@ const WAIT_EVENT_TYPES = WaitEventTypeSchema.options;
14932
14936
  function isWaitEventType(eventType) {
14933
14937
  return WAIT_EVENT_TYPES.includes(eventType);
14934
14938
  }
14939
+ function isSealedNoopEvent(event) {
14940
+ return event.eventType === "noop";
14941
+ }
14935
14942
  const ChildEntityCreationEventTypeSchema = EventTypeSchema.extract([
14936
14943
  "step_created",
14937
14944
  "hook_created",
@@ -14982,7 +14989,7 @@ const stepLatencyTelemetryFields = {
14982
14989
  rsfs: number$3().optional(),
14983
14990
  // Synchronous workflow-function replay duration of only the FINAL replay
14984
14991
  // pass within the rsfs window (the pass that scheduled the first step),
14985
- // excluding awaited network I/O not accumulated across earlier
14992
+ // excluding awaited network I/O. Not accumulated across earlier
14986
14993
  // pre-first-step passes, so it is not "the replay portion of rsfs". Only
14987
14994
  // present alongside rsfs, and only for the run's first step.
14988
14995
  finalSchedulingReplay: number$3().optional(),
@@ -15042,7 +15049,7 @@ const StepStartedEventSchema = BaseEventSchema.extend({
15042
15049
  // handler is executing this step's body inline. Stamped on the lazy
15043
15050
  // step_started (and re-stamped on an owner-recovery bare start) so
15044
15051
  // 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
15052
+ // invocation" apart from "this attempt died with its process": the
15046
15053
  // owner's queue message doubles as the liveness lease (a crash means
15047
15054
  // the queue redelivers that same messageId, which is allowed to
15048
15055
  // re-execute). Ownership derives from the step's LATEST step_started:
@@ -15098,6 +15105,12 @@ const HookConflictEventSchema = BaseEventSchema.extend({
15098
15105
  conflictingRunId: string$2().optional()
15099
15106
  })
15100
15107
  });
15108
+ const NoopEventSchema = BaseEventSchema.extend({
15109
+ eventType: literal("noop"),
15110
+ eventData: object({
15111
+ sealed: boolean$2().optional()
15112
+ }).passthrough().optional()
15113
+ });
15101
15114
  const WaitCreatedEventSchema = BaseEventSchema.extend({
15102
15115
  eventType: literal("wait_created"),
15103
15116
  correlationId: string$2(),
@@ -15144,7 +15157,7 @@ const RunCreatedEventSchema = BaseEventSchema.extend({
15144
15157
  * The run's X25519 public key (base64), stamped by SDKs that support
15145
15158
  * sealed (`encp`) envelopes. Persisted onto the run entity so that
15146
15159
  * cross-run writers can seal payloads to this run without holding its
15147
- * symmetric key. Not secret see `WorkflowRunBaseSchema`.
15160
+ * symmetric key. Not secret. See `WorkflowRunBaseSchema`.
15148
15161
  */
15149
15162
  encryptionPublicKey: string$2().optional()
15150
15163
  })
@@ -15239,7 +15252,9 @@ const AllEventsSchema = discriminatedUnion("eventType", [
15239
15252
  // World-only: created when hook token conflicts
15240
15253
  // Wait lifecycle events
15241
15254
  WaitCreatedEventSchema,
15242
- WaitCompletedEventSchema
15255
+ WaitCompletedEventSchema,
15256
+ NoopEventSchema
15257
+ // World-only: sealed-log filler for an abandoned slot
15243
15258
  ]);
15244
15259
  AllEventsSchema.and(object({
15245
15260
  runId: string$2(),
@@ -15297,7 +15312,7 @@ const WorkflowRunBaseSchema = object({
15297
15312
  * ```
15298
15313
  */
15299
15314
  workflowName: string$2(),
15300
- // Optional in database for backwards compatibility, defaults to 1 (legacy) when reading
15315
+ // Optional in database for backward compatibility, defaults to 1 (legacy) when reading
15301
15316
  specVersion: number$3().optional(),
15302
15317
  executionContext: record(string$2(), any()).optional(),
15303
15318
  input: SerializedDataSchema.optional(),
@@ -15325,12 +15340,12 @@ const WorkflowRunBaseSchema = object({
15325
15340
  *
15326
15341
  * Defaults to `{}` after schema parsing so consumers always receive
15327
15342
  * a record regardless of world. World adapters need not initialize
15328
- * the field on disk `world-local` JSON files written before this
15343
+ * the field on disk: `world-local` JSON files written before this
15329
15344
  * field existed, and rows from any other adapter that omits the
15330
15345
  * column, both read as `{}` after Zod parses them.
15331
15346
  *
15332
15347
  * EXPERIMENTAL (MVP): the full Workflow Attributes feature replaces
15333
- * the direct-mutation MVP path with an event-sourced model — see
15348
+ * the direct-mutation MVP path with an event-sourced model. See
15334
15349
  * the attributes-mvp changelog entry.
15335
15350
  */
15336
15351
  attributes: record(string$2(), string$2()).default({}),
@@ -15338,12 +15353,12 @@ const WorkflowRunBaseSchema = object({
15338
15353
  * The run's X25519 public key, base64-encoded (~44 chars).
15339
15354
  *
15340
15355
  * 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.
15356
+ * being able to read the run's data. This is used for cross-run writes
15357
+ * such as a hook resumption from another deployment, or a child workflow
15358
+ * writing into a forwarded stream. The matching private scalar is never
15359
+ * stored: it is re-derived on demand from the deployment's own key
15360
+ * material, so this field is not secret and its presence does not weaken
15361
+ * the run's confidentiality.
15347
15362
  *
15348
15363
  * Stamped at run creation by SDKs that support sealed (`encp`) envelopes.
15349
15364
  * **Presence is the writer-side gate**: a run only carries a public key if
@@ -15596,6 +15611,9 @@ object({
15596
15611
  firstSeenAt: date(),
15597
15612
  lastSeenAt: date()
15598
15613
  });
15614
+ const WarnedEnvValuesKey = Symbol.for("@workflow/world//warnedEnvValues/v1");
15615
+ const globalStore = globalThis;
15616
+ globalStore[WarnedEnvValuesKey] ?? (globalStore[WarnedEnvValuesKey] = /* @__PURE__ */ new Set());
15599
15617
  string$2().regex(/^__(?:[a-z][a-z0-9]*_)?wkf_workflow_$/, "Must match __wkf_workflow_ or __{namespace}_wkf_workflow_");
15600
15618
  string$2().regex(/^__(?:[a-z][a-z0-9]*_)?wkf_workflow_.+$/, "Must be a valid queue name with a recognized prefix");
15601
15619
  string$2().regex(/^[a-z][a-z0-9]*$/, "Must be lowercase alphanumeric, starting with a letter");
@@ -15626,12 +15644,12 @@ const RunInputSchema = object({
15626
15644
  * two can disagree: if the message is consumed by a deployment in a
15627
15645
  * DIFFERENT environment, that consumer's `run_started` re-creates the run
15628
15646
  * under ITS tenant, so the same client-minted `wrun_` id ends up existing
15629
- * in two environments one stuck pending forever, the other executing.
15647
+ * in two environments: one stuck pending forever, the other executing.
15630
15648
  * Carrying the creator's environment lets the consumer compare it against
15631
15649
  * its own and refuse the delivery instead of forking the run.
15632
15650
  *
15633
15651
  * Absent for worlds with no environment dimension (local, Postgres), and
15634
- * for older SDKs consumers must treat it as advisory and skip the check
15652
+ * for older SDKs. Consumers must treat it as advisory and skip the check
15635
15653
  * when it is missing.
15636
15654
  */
15637
15655
  environment: string$2().optional()
@@ -15656,8 +15674,8 @@ const HookResumeInputSchema = object({
15656
15674
  hookId: string$2(),
15657
15675
  /**
15658
15676
  * 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.
15677
+ * the consumer's re-ensured event carries the same token the producer
15678
+ * would. Replay validates `eventData.token` against the `createHook` token.
15661
15679
  */
15662
15680
  token: string$2(),
15663
15681
  /** The serialized resume payload, reused verbatim from the direct write. */
@@ -15667,7 +15685,7 @@ const HookResumeInputSchema = object({
15667
15685
  * serialized bytes and forwarded verbatim on both the direct `events.create`
15668
15686
  * and this queue message. The consumer forwards it back to the server so both
15669
15687
  * writers of the same `resumeId` record an identical digest on the
15670
- * `(runId, resumeId)` constraint required because the v4 payload ref is not
15688
+ * `(runId, resumeId)` constraint, required because the v4 payload ref is not
15671
15689
  * content-stable server-side.
15672
15690
  */
15673
15691
  payloadDigest: string$2(),
@@ -15675,15 +15693,15 @@ const HookResumeInputSchema = object({
15675
15693
  * The deployment the run is pinned to, from the producer's resume context.
15676
15694
  * Lets the consumer detect a misrouted delivery with a cheap ambient
15677
15695
  * deployment-id comparison BEFORE its hoisted `hook_received` replay-preload
15678
- * write only a detected mismatch pays for the authoritative run fetch and
15696
+ * write: only a detected mismatch pays for the authoritative run fetch and
15679
15697
  * the deployment-affinity guard. Optional for queued-message compatibility:
15680
- * messages from older producers omit it and simply skip the pre-write
15698
+ * messages from older producers omit it and skip the pre-write
15681
15699
  * check (the authoritative guard before replay still protects them).
15682
15700
  */
15683
15701
  deploymentId: string$2().optional()
15684
15702
  });
15685
15703
  const HookResumeTimingSchema = object({
15686
- /** Epoch ms at entry into `resumeHook()` the start of the TTR window. */
15704
+ /** Epoch ms at entry into `resumeHook()`: the start of the TTR window. */
15687
15705
  resumeRequestedAtMs: number$3(),
15688
15706
  /** Epoch ms immediately before the queue publish was requested. */
15689
15707
  queuePublishRequestedAtMs: number$3(),
@@ -15719,10 +15737,41 @@ const WorkflowInvokePayloadSchema = object({
15719
15737
  serverErrorRetryCount: number$3().int().optional(),
15720
15738
  /** Number of times this message has been re-routed after a deployment mismatch */
15721
15739
  deploymentMismatchRetryCount: number$3().int().nonnegative().optional(),
15740
+ /**
15741
+ * The wait this message is the delayed continuation for, and which attempt
15742
+ * in that wait's chain it is.
15743
+ *
15744
+ * Present only on wait-continuation messages. It exists so the invocation a
15745
+ * continuation wakes can recognize itself as that continuation: if the wait
15746
+ * is STILL pending when it replays — the continuation arrived before its
15747
+ * deadline — then its own idempotency key is already spent, and re-enqueueing
15748
+ * under the same key is silently dropped by the world's dedupe window. The
15749
+ * attempt number is what makes the next key fresh, so an early delivery
15750
+ * costs one extra hop instead of losing the wait's timer permanently.
15751
+ *
15752
+ * Counted on the message for the same reason as
15753
+ * {@link WorkflowInvokePayloadSchema.shape.preconditionReinvocations}: the
15754
+ * budget has to survive across invocations, and a fresh enqueue resets
15755
+ * anything the queue tracks itself. Absent on the first continuation, so a
15756
+ * producer that predates this field is indistinguishable from attempt 0 and
15757
+ * a consumer that predates it simply ignores the field.
15758
+ */
15759
+ /**
15760
+ * `.catch(undefined)` for the reason `hookResumeTiming` has it: this field
15761
+ * must never be able to fail the parse of the invocation payload. A
15762
+ * malformed value would otherwise throw on every delivery of the message
15763
+ * and burn the run's delivery budget. Degrading to `undefined` reads as
15764
+ * "not a continuation", which costs at worst the pre-attempt behavior for
15765
+ * that one wait rather than killing the run.
15766
+ */
15767
+ waitContinuation: object({
15768
+ correlationId: string$2(),
15769
+ attempt: number$3().int().nonnegative()
15770
+ }).optional().catch(void 0),
15722
15771
  /** Step ID for inline step execution in combined handler. If provided, the flow execution
15723
15772
  * will jump directly to execute the step with the given ID before doing an event replay. */
15724
15773
  stepId: string$2().optional(),
15725
- /** Step name, sent alongside stepId to avoid loading the event log just to resolve the name. */
15774
+ /** Step name, sent alongside stepId to avoid loading the event log to resolve the name. */
15726
15775
  stepName: string$2().optional(),
15727
15776
  /** Run creation data, only present on the first queue delivery from start() */
15728
15777
  runInput: RunInputSchema.optional(),
@@ -15743,8 +15792,8 @@ const WorkflowInvokePayloadSchema = object({
15743
15792
  * Hook-resume TTR timing. Present on both `resumeHook()` dispatch paths
15744
15793
  * (unlike `hookInput`, which only rides the parallel fast path), and
15745
15794
  * 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}.
15795
+ * hands the next durable step to another invocation. Purely observational.
15796
+ * See {@link HookResumeTimingSchema}.
15748
15797
  *
15749
15798
  * `.catch(undefined)` because this field must never be able to fail the
15750
15799
  * parse of the invocation payload: a malformed value (a NaN boundary, a
@@ -15791,7 +15840,7 @@ const HookResumeContextSchema = object({
15791
15840
  // `@workflow/core` re-ensures the `hook_received` event from the queue
15792
15841
  // message's `hookInput` on replay, so `resumeHook()`'s parallel fast path is
15793
15842
  // 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
15843
+ // marker is a reliable per-run attestation, unlike inferring support from a
15795
15844
  // version compare against a predicted release cutoff. Absent on runs created
15796
15845
  // before the marker existed (fall back to the sequential path).
15797
15846
  hookResumeInputVersion: number$3().optional()
@@ -15812,7 +15861,7 @@ object({
15812
15861
  environment: string$2(),
15813
15862
  metadata: SerializedDataSchema.optional(),
15814
15863
  createdAt: date(),
15815
- // Optional in database for backwards compatibility, defaults to 1 (legacy) when reading
15864
+ // Optional in database for backward compatibility, defaults to 1 (legacy) when reading
15816
15865
  specVersion: number$3().optional(),
15817
15866
  isWebhook: boolean$2().optional(),
15818
15867
  isSystem: boolean$2().optional(),
@@ -15824,9 +15873,9 @@ object({
15824
15873
  // falls back to `runs.get`.
15825
15874
  resumeContext: HookResumeContextSchema.optional(),
15826
15875
  // Backend dedup capability, computed FRESH by the server on every by-token
15827
- // lookup RESPONSE-ONLY and TRANSIENT. Never persisted on the hook entity
15876
+ // lookup: RESPONSE-ONLY and TRANSIENT. Never persisted on the hook entity
15828
15877
  // 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).
15878
+ // takes effect on the next lookup (the field stops appearing).
15830
15879
  // `resumeHook()` gates its parallel fast path on this being present and
15831
15880
  // current. Absent against an older/rolled-back server or when the kill switch
15832
15881
  // is active.
@@ -15931,6 +15980,154 @@ const __vitePreload = function preload(baseModule, deps, importerUrl) {
15931
15980
  return baseModule().catch(handlePreloadError);
15932
15981
  });
15933
15982
  };
15983
+ function globalSingleton(name2, shapeVersion, create2) {
15984
+ const key = Symbol.for(`${name2}/v${shapeVersion}`);
15985
+ const store = globalThis;
15986
+ const existing = store[key];
15987
+ if (existing !== void 0) {
15988
+ return existing;
15989
+ }
15990
+ const created = create2();
15991
+ store[key] = created;
15992
+ return created;
15993
+ }
15994
+ var ms$1;
15995
+ var hasRequiredMs;
15996
+ function requireMs() {
15997
+ if (hasRequiredMs) return ms$1;
15998
+ hasRequiredMs = 1;
15999
+ var s2 = 1e3;
16000
+ var m2 = s2 * 60;
16001
+ var h2 = m2 * 60;
16002
+ var d2 = h2 * 24;
16003
+ var w2 = d2 * 7;
16004
+ var y2 = d2 * 365.25;
16005
+ ms$1 = function(val, options) {
16006
+ options = options || {};
16007
+ var type = typeof val;
16008
+ if (type === "string" && val.length > 0) {
16009
+ return parse2(val);
16010
+ } else if (type === "number" && isFinite(val)) {
16011
+ return options.long ? fmtLong(val) : fmtShort(val);
16012
+ }
16013
+ throw new Error(
16014
+ "val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
16015
+ );
16016
+ };
16017
+ function parse2(str) {
16018
+ str = String(str);
16019
+ if (str.length > 100) {
16020
+ return;
16021
+ }
16022
+ 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(
16023
+ str
16024
+ );
16025
+ if (!match) {
16026
+ return;
16027
+ }
16028
+ var n = parseFloat(match[1]);
16029
+ var type = (match[2] || "ms").toLowerCase();
16030
+ switch (type) {
16031
+ case "years":
16032
+ case "year":
16033
+ case "yrs":
16034
+ case "yr":
16035
+ case "y":
16036
+ return n * y2;
16037
+ case "weeks":
16038
+ case "week":
16039
+ case "w":
16040
+ return n * w2;
16041
+ case "days":
16042
+ case "day":
16043
+ case "d":
16044
+ return n * d2;
16045
+ case "hours":
16046
+ case "hour":
16047
+ case "hrs":
16048
+ case "hr":
16049
+ case "h":
16050
+ return n * h2;
16051
+ case "minutes":
16052
+ case "minute":
16053
+ case "mins":
16054
+ case "min":
16055
+ case "m":
16056
+ return n * m2;
16057
+ case "seconds":
16058
+ case "second":
16059
+ case "secs":
16060
+ case "sec":
16061
+ case "s":
16062
+ return n * s2;
16063
+ case "milliseconds":
16064
+ case "millisecond":
16065
+ case "msecs":
16066
+ case "msec":
16067
+ case "ms":
16068
+ return n;
16069
+ default:
16070
+ return void 0;
16071
+ }
16072
+ }
16073
+ function fmtShort(ms2) {
16074
+ var msAbs = Math.abs(ms2);
16075
+ if (msAbs >= d2) {
16076
+ return Math.round(ms2 / d2) + "d";
16077
+ }
16078
+ if (msAbs >= h2) {
16079
+ return Math.round(ms2 / h2) + "h";
16080
+ }
16081
+ if (msAbs >= m2) {
16082
+ return Math.round(ms2 / m2) + "m";
16083
+ }
16084
+ if (msAbs >= s2) {
16085
+ return Math.round(ms2 / s2) + "s";
16086
+ }
16087
+ return ms2 + "ms";
16088
+ }
16089
+ function fmtLong(ms2) {
16090
+ var msAbs = Math.abs(ms2);
16091
+ if (msAbs >= d2) {
16092
+ return plural(ms2, msAbs, d2, "day");
16093
+ }
16094
+ if (msAbs >= h2) {
16095
+ return plural(ms2, msAbs, h2, "hour");
16096
+ }
16097
+ if (msAbs >= m2) {
16098
+ return plural(ms2, msAbs, m2, "minute");
16099
+ }
16100
+ if (msAbs >= s2) {
16101
+ return plural(ms2, msAbs, s2, "second");
16102
+ }
16103
+ return ms2 + " ms";
16104
+ }
16105
+ function plural(ms2, msAbs, n, name2) {
16106
+ var isPlural = msAbs >= n * 1.5;
16107
+ return Math.round(ms2 / n) + " " + name2 + (isPlural ? "s" : "");
16108
+ }
16109
+ return ms$1;
16110
+ }
16111
+ var msExports = requireMs();
16112
+ const ms = /* @__PURE__ */ getDefaultExportFromCjs(msExports);
16113
+ function parseDurationToDate(param) {
16114
+ if (typeof param === "string") {
16115
+ const durationMs = ms(param);
16116
+ if (typeof durationMs !== "number" || durationMs < 0) {
16117
+ throw new Error(`Invalid duration: "${param}". Expected a valid duration string like "1s", "1m", "1h", etc.`);
16118
+ }
16119
+ return new Date(Date.now() + durationMs);
16120
+ } else if (typeof param === "number") {
16121
+ if (param < 0 || !Number.isFinite(param)) {
16122
+ throw new Error(`Invalid duration: ${param}. Expected a non-negative finite number of milliseconds.`);
16123
+ }
16124
+ return new Date(Date.now() + param);
16125
+ } else if (param instanceof Date || param && typeof param === "object" && typeof param.getTime === "function") {
16126
+ return param instanceof Date ? param : new Date(param.getTime());
16127
+ } else {
16128
+ throw new Error(`Invalid duration parameter. Expected a duration string, number (milliseconds), or Date object.`);
16129
+ }
16130
+ }
15934
16131
  const UNDEFINED = -1;
15935
16132
  const HOLE = -2;
15936
16133
  const NAN = -3;
@@ -16186,143 +16383,6 @@ function unflatten(parsed, revivers, options) {
16186
16383
  }
16187
16384
  return hydrate(0);
16188
16385
  }
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
16386
  const BASE_URL = "https://workflow-sdk.dev/err";
16327
16387
  function isError(value) {
16328
16388
  return typeof value === "object" && value !== null && "name" in value && "message" in value;
@@ -16606,7 +16666,7 @@ function importPublicKey(publicKey) {
16606
16666
  { name: "X25519" },
16607
16667
  /* extractable */
16608
16668
  true,
16609
- // Public keys carry no usages for X25519 the private key does the
16669
+ // Public keys carry no usages for X25519: the private key does the
16610
16670
  // deriving; the public key is only ever an argument to it.
16611
16671
  []
16612
16672
  );
@@ -16701,7 +16761,7 @@ const SerializationFormat$1 = {
16701
16761
  /** Encrypted payload (inner payload has its own format prefix) */
16702
16762
  ENCRYPTED: "encr",
16703
16763
  /**
16704
- * Sealed payload asymmetrically encrypted to a run's X25519 public key
16764
+ * Sealed payload: asymmetrically encrypted to a run's X25519 public key
16705
16765
  * (inner payload has its own format prefix).
16706
16766
  *
16707
16767
  * Used for *cross-run* writes (hook payloads, forwarded stream frames),
@@ -16831,7 +16891,7 @@ const SerializationFormat = {
16831
16891
  /** Encrypted payload (inner payload has its own format prefix after decryption) */
16832
16892
  ENCRYPTED: "encr",
16833
16893
  /**
16834
- * Sealed payload asymmetrically encrypted to a run's X25519 public key
16894
+ * Sealed payload: asymmetrically encrypted to a run's X25519 public key
16835
16895
  * (inner payload has its own format prefix after opening).
16836
16896
  *
16837
16897
  * Written by cross-run writers that hold only the recipient run's public
@@ -16925,17 +16985,19 @@ function decompressSyncIfAvailable(format, payload) {
16925
16985
  }
16926
16986
  return void 0;
16927
16987
  }
16928
- let zstdBrowserDecoder;
16988
+ const zstd = globalSingleton("@workflow/core//zstd.decoder", 1, () => ({
16989
+ decoder: void 0
16990
+ }));
16929
16991
  function registerZstdDecoder(decoder2) {
16930
- zstdBrowserDecoder = decoder2;
16992
+ zstd.decoder = decoder2;
16931
16993
  }
16932
16994
  async function decompressAsync(format, payload) {
16933
16995
  if (format === SerializationFormat.ZSTD) {
16934
16996
  const sync = decompressSyncIfAvailable(format, payload);
16935
16997
  if (sync)
16936
16998
  return sync;
16937
- if (zstdBrowserDecoder)
16938
- return zstdBrowserDecoder(payload);
16999
+ if (zstd.decoder)
17000
+ return zstd.decoder(payload);
16939
17001
  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
17002
  }
16941
17003
  const transform2 = new DecompressionStream("gzip");
@@ -17082,7 +17144,7 @@ const observabilityRevivers = {
17082
17144
  // throws on the `["DOMException", ...]` tag and `hydrateStepIO`'s
17083
17145
  // try/catch leaves the raw flat-encoded string in the UI. AbortController
17084
17146
  // 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
17147
+ // is called with no arg, so any abort that round-trips through a step
17086
17148
  // boundary surfaces here. Reconstruct as a real DOMException when the
17087
17149
  // global is available (modern browsers + Node 18+), else fall back to
17088
17150
  // an Error preserving name/message/stack/cause for display.
@@ -17289,8 +17351,8 @@ function getWebRevivers() {
17289
17351
  // entry for each built-in Error subclass plus the workflow-specific
17290
17352
  // `FatalError` / `RetryableError` / `HookConflictError` /
17291
17353
  // `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
17354
+ // matching revivers here, `devalue.unflatten` throws "Unknown type X",
17355
+ // which surfaces in the web o11y UI as "Failed to load resource
17294
17356
  // details: Unknown type FatalError".
17295
17357
  Error: (value) => {
17296
17358
  const opts = "cause" in value ? { cause: value.cause } : void 0;
@@ -17320,7 +17382,7 @@ function getWebRevivers() {
17320
17382
  // `FatalError` and `RetryableError` are not built-in browser globals,
17321
17383
  // so we can't resolve a constructor from globalThis. The web o11y UI
17322
17384
  // doesn't need `instanceof FatalError` to pass (no user code runs
17323
- // here) it just needs `name`, `message`, `stack`, and any extra
17385
+ // here). The web o11y UI needs `name`, `message`, `stack`, and any extra
17324
17386
  // enumerable fields to render. Construct a plain `Error` with `name`
17325
17387
  // set; ObjectInspector reads `constructor.name` for the displayed
17326
17388
  // class label, but we don't have the real class, so we emit a tagged
@@ -17522,7 +17584,7 @@ async function hydrateResourceIOAsync(resource, key) {
17522
17584
  return { hydrateDataWithKey: hydrateDataWithKey3, deriveRunPayloadKeys: deriveRunPayloadKeys3 };
17523
17585
  }, true ? void 0 : void 0);
17524
17586
  const { ensureZstdDecoderRegistered } = await __vitePreload(async () => {
17525
- const { ensureZstdDecoderRegistered: ensureZstdDecoderRegistered2 } = await import("./zstd-browser-decoder-CAEVa0bm.js");
17587
+ const { ensureZstdDecoderRegistered: ensureZstdDecoderRegistered2 } = await import("./zstd-browser-decoder-B9DmHkyE.js");
17526
17588
  return { ensureZstdDecoderRegistered: ensureZstdDecoderRegistered2 };
17527
17589
  }, true ? __vite__mapDeps([0,1]) : void 0);
17528
17590
  ensureZstdDecoderRegistered();
@@ -19109,7 +19171,7 @@ const RunClickContext = reactExports.createContext(void 0);
19109
19171
  function EncryptedInlineLabel() {
19110
19172
  const ctx = reactExports.useContext(DecryptClickContext);
19111
19173
  if (ctx) {
19112
- return jsxRuntimeExports.jsxs(Button$1, { size: "xs", className: "align-baseline gap-x-1", disabled: ctx.isDecrypting, onClick: (e) => {
19174
+ 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
19175
  e.stopPropagation();
19114
19176
  ctx.onDecrypt();
19115
19177
  }, children: [ctx.isDecrypting ? jsxRuntimeExports.jsx(Spinner, { size: 10 }) : jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { children: "Decrypt" })] });
@@ -19382,7 +19444,7 @@ function collapseRefs(data) {
19382
19444
  }
19383
19445
  return result;
19384
19446
  }
19385
- function DataInspector({ data, expandLevel = 2, name: name2, onStreamClick, onRunClick, onDecrypt, isDecrypting = false }) {
19447
+ function DataInspector({ data, expandLevel = 2, name: name2, onStreamClick, onRunClick, onDecrypt, isDecrypting = false, isDecryptDisabled = false, decryptDisabledReason }) {
19386
19448
  const collapsedData = reactExports.useMemo(() => collapseRefs(data), [data]);
19387
19449
  const stableData = useStableInspectorData(collapsedData);
19388
19450
  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 +19455,12 @@ function DataInspector({ data, expandLevel = 2, name: name2, onStreamClick, onRu
19393
19455
  content2 = jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: content2 });
19394
19456
  }
19395
19457
  if (onDecrypt) {
19396
- content2 = jsxRuntimeExports.jsx(DecryptClickContext.Provider, { value: { onDecrypt, isDecrypting }, children: content2 });
19458
+ content2 = jsxRuntimeExports.jsx(DecryptClickContext.Provider, { value: {
19459
+ onDecrypt,
19460
+ isDecrypting,
19461
+ isDecryptDisabled,
19462
+ decryptDisabledReason
19463
+ }, children: content2 });
19397
19464
  }
19398
19465
  return content2;
19399
19466
  }
@@ -19478,7 +19545,7 @@ const encryptedPlaceholderPreview = `{
19478
19545
  }`;
19479
19546
  function EncryptedDataBlock() {
19480
19547
  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"] }) })] });
19548
+ 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
19549
  }
19483
19550
  const serializeForClipboard = (value) => {
19484
19551
  if (typeof value === "string")
@@ -20305,27 +20372,27 @@ function ZoneDateTimeRow({ date: date2, zone }) {
20305
20372
  });
20306
20373
  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
20374
  }
20308
- function RelativeTimeContextCardContent({ date: date2 }) {
20375
+ function RelativeTimeContextCardContent({ date: date2, prefix }) {
20309
20376
  const localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
20310
20377
  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 })] })] });
20378
+ 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
20379
  }
20313
20380
  function DefaultTimeText({ date: date2 }) {
20314
20381
  const shortTimeAgo = useShortTimeAgo(date2);
20315
20382
  return jsxRuntimeExports.jsx("span", { className: "text-label-14 text-gray-900", children: shortTimeAgo });
20316
20383
  }
20317
- function RelativeTimeCard({ date: date2, children: _children, ...props }) {
20384
+ function RelativeTimeCard({ date: date2, children: _children, prefix, ...props }) {
20318
20385
  const children2 = _children === void 0 ? jsxRuntimeExports.jsx(DefaultTimeText, { date: date2 }) : _children;
20319
20386
  if (!date2)
20320
20387
  return children2;
20321
- return jsxRuntimeExports.jsx(ContextCardTrigger, { content: jsxRuntimeExports.jsx(RelativeTimeContextCardContent, { date: date2 }), ...props, children: children2 });
20388
+ return jsxRuntimeExports.jsx(ContextCardTrigger, { content: jsxRuntimeExports.jsx(RelativeTimeContextCardContent, { date: date2, prefix }), ...props, children: children2 });
20322
20389
  }
20323
- function TimestampTooltip({ date: date2, children: children2, side = "top" }) {
20390
+ function TimestampTooltip({ date: date2, children: children2, side = "top", prefix }) {
20324
20391
  const hasProvider = useHasContextCardProvider();
20325
20392
  const ts = date2 == null ? null : typeof date2 === "number" ? date2 : new Date(date2).getTime();
20326
20393
  if (ts == null || Number.isNaN(ts))
20327
20394
  return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: children2 });
20328
- const card = jsxRuntimeExports.jsx(RelativeTimeCard, { date: ts, side, asChild: true, children: children2 });
20395
+ const card = jsxRuntimeExports.jsx(RelativeTimeCard, { date: ts, side, prefix, asChild: true, children: children2 });
20329
20396
  return hasProvider ? card : jsxRuntimeExports.jsx(ContextCardProvider, { children: card });
20330
20397
  }
20331
20398
  const convert = (
@@ -45113,7 +45180,7 @@ var tn = f("block", "before:content-[counter(line)]", "before:inline-block", "be
45113
45180
  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
45181
  var Se = reactExports.createContext({ code: "" }), de = () => reactExports.useContext(Se);
45115
45182
  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 }) => {
45183
+ var cn$1 = /\n+$/, dn = reactExports.lazy(() => __vitePreload(() => import("./highlighted-body-B3W2YXNL-BPRwlr7r.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
45184
  let i = reactExports.useMemo(() => e.replace(cn$1, ""), [e]), c = reactExports.useMemo(() => ({ bg: "transparent", fg: "inherit", tokens: i.split(`
45118
45185
  `).map((a2) => [{ content: a2, color: "inherit", bgColor: "transparent", htmlStyle: {}, offset: 0 }]) }), [i]);
45119
45186
  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 +46341,7 @@ const RESOURCE_CLASS_NAMES = {
46274
46341
  className: "border-green-500 bg-green-200",
46275
46342
  errorClassName: "border-red-500 bg-red-200"
46276
46343
  },
46277
- // Passive spans (hooks) stay gray matches event-list icons and the minimap.
46344
+ // Passive spans (hooks) stay gray; matches event-list icons and the minimap.
46278
46345
  hook: {
46279
46346
  className: "border-gray-500 bg-gray-200",
46280
46347
  errorClassName: "border-red-500 bg-red-200"
@@ -46472,7 +46539,8 @@ function computeSpanSegments(span) {
46472
46539
  const MARKER_EVENT_NAMES = ["hook_received", "attr_set"];
46473
46540
  function computeSpanMarkers(span) {
46474
46541
  return sortedEventMarks(span.events, MARKER_EVENT_NAMES).map((mark2) => ({
46475
- timeMs: mark2.time
46542
+ timeMs: mark2.time,
46543
+ kind: mark2.type
46476
46544
  }));
46477
46545
  }
46478
46546
  function computeOffscreenMarkers(markers, visibleStartMs, visibleEndMs) {
@@ -46568,6 +46636,10 @@ function scrollRowIntoView(listEl, index2, rowHeight, opts) {
46568
46636
  behavior: opts == null ? void 0 : opts.behavior
46569
46637
  });
46570
46638
  }
46639
+ const MARKER_KIND_PREFIX = {
46640
+ hook_received: "Hook received",
46641
+ attr_set: "Attribute set"
46642
+ };
46571
46643
  function projectMarkers(markers, visibleStartMs, visibleEndMs) {
46572
46644
  const visibleDurationMs = visibleEndMs - visibleStartMs;
46573
46645
  if (visibleDurationMs <= 0)
@@ -46579,7 +46651,8 @@ function projectMarkers(markers, visibleStartMs, visibleEndMs) {
46579
46651
  return [
46580
46652
  {
46581
46653
  leftPct: (m2.timeMs - visibleStartMs) / visibleDurationMs * 100,
46582
- timeMs: m2.timeMs
46654
+ timeMs: m2.timeMs,
46655
+ kind: m2.kind
46583
46656
  }
46584
46657
  ];
46585
46658
  });
@@ -46601,7 +46674,7 @@ function MarkerTick({ className }) {
46601
46674
  return jsxRuntimeExports.jsx("span", { className: cn$4("block w-[3px] rounded-full bg-gray-1000", className) });
46602
46675
  }
46603
46676
  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)) });
46677
+ 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
46678
  }
46606
46679
  function OffscreenMarkerIndicator({ direction, count: count2, targetMs, onReveal }) {
46607
46680
  const Chevron = direction === "right" ? ArrowRight : ArrowLeft;
@@ -49524,7 +49597,7 @@ const mermaid3ZIDBTTL = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
49524
49597
  Mermaid: Nt
49525
49598
  }, Symbol.toStringTag, { value: "Module" }));
49526
49599
  export {
49527
- CopyableDataBlock as $,
49600
+ cn$4 as $,
49528
49601
  Anchor as A,
49529
49602
  Button as B,
49530
49603
  Check as C,
@@ -49550,108 +49623,109 @@ export {
49550
49623
  createContext2 as W,
49551
49624
  fetchWorkflowsManifest as X,
49552
49625
  entityEventClass as Y,
49553
- cn$4 as Z,
49626
+ isSealedNoopEvent as Z,
49554
49627
  __vitePreload as _,
49555
49628
  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,
49629
+ hydrateResourceIO as a$,
49630
+ CopyableDataBlock as a0,
49631
+ CollapsibleRoot as a1,
49632
+ CollapsibleTrigger as a2,
49633
+ CollapsibleContent as a3,
49634
+ CopyButton as a4,
49635
+ RESERVED_ATTRIBUTE_KEY_PREFIX as a5,
49636
+ Spinner as a6,
49637
+ TooltipProvider as a7,
49638
+ Tooltip$1 as a8,
49639
+ TooltipTrigger$1 as a9,
49640
+ useActiveSpan as aA,
49641
+ useSidebarData as aB,
49642
+ IconButton as aC,
49643
+ useRowWindow as aD,
49644
+ isSpanDimmedBySearch as aE,
49645
+ ROW_HEIGHT_PX as aF,
49646
+ getSpanDurationMs as aG,
49647
+ isSpanErrored as aH,
49648
+ formatDurationPrecise as aI,
49649
+ ActiveSpanProvider as aJ,
49650
+ useReducedMotion as aK,
49651
+ searchSpans as aL,
49652
+ computeRootBounds as aM,
49653
+ computeTimeMarkers as aN,
49654
+ clampViewportToRoot as aO,
49655
+ getHighResInMs as aP,
49656
+ scrollRowIntoView as aQ,
49657
+ TIMELINE_PADDING_PX as aR,
49658
+ Minimap as aS,
49659
+ Timeline as aT,
49660
+ TimelineHeader as aU,
49661
+ wheelZoomScaleFactor as aV,
49662
+ wheelDeltaToPixels as aW,
49663
+ SidebarDataProvider as aX,
49664
+ fetchHook as aY,
49665
+ hydrateResourceIOAsync as aZ,
49666
+ fetchStep as a_,
49667
+ TooltipContent$1 as aa,
49668
+ ContextCardProvider as ab,
49669
+ Skeleton as ac,
49670
+ DecryptClickContext as ad,
49671
+ Yr as ae,
49672
+ isEncryptedMarker$1 as af,
49673
+ TimestampTooltip as ag,
49674
+ formatDuration as ah,
49675
+ DataInspector as ai,
49676
+ _r as aj,
49677
+ isHookLifecycleEventType as ak,
49678
+ isTerminalStepEventType as al,
49679
+ isWaitEventType as am,
49680
+ isStepEventType as an,
49681
+ RunClickContext as ao,
49682
+ StreamClickContext as ap,
49683
+ Collapsible as aq,
49684
+ isExpiredMarker as ar,
49685
+ isDoStreamStep as as,
49686
+ extractConversation as at,
49687
+ EncryptedDataBlock as au,
49688
+ getEventDataRefFields as av,
49689
+ hasEncryptedFields as aw,
49690
+ useSidebarDataOptional as ax,
49691
+ isTerminalWorkflowRunStatus as ay,
49692
+ clsx as az,
49620
49693
  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,
49694
+ fetchStreams as b0,
49695
+ apiBase as b1,
49696
+ Slot as b2,
49697
+ Slottable as b3,
49698
+ buttonVariants as b4,
49699
+ fetchEvent as b5,
49700
+ fetchEventsByCorrelationId as b6,
49701
+ isEncryptedData as b7,
49702
+ hydrateData as b8,
49703
+ decrypt as b9,
49704
+ deriveRunPayloadKeys as ba,
49705
+ getWebRevivers as bb,
49706
+ LIVE_UPDATE_INTERVAL_MS as bc,
49707
+ getEncryptionKeyForRun as bd,
49708
+ StreamViewerSkeleton as be,
49709
+ Lock as bf,
49710
+ StreamViewer as bg,
49711
+ composeRefs as bh,
49712
+ useFloating as bi,
49713
+ offset as bj,
49714
+ shift as bk,
49715
+ limitShift as bl,
49716
+ flip as bm,
49717
+ size as bn,
49718
+ arrow as bo,
49719
+ hide as bp,
49720
+ autoUpdate as bq,
49721
+ VERCEL_403_ERROR_MESSAGE as br,
49722
+ bulkCancelRuns as bs,
49723
+ reenqueueRun as bt,
49724
+ wakeUpRun as bu,
49725
+ resumeHook as bv,
49726
+ fetchHookToken as bw,
49727
+ cancelRun as bx,
49728
+ recreateRun as by,
49655
49729
  createLucideIcon as c,
49656
49730
  runHealthCheck as d,
49657
49731
  cn as e,