@workflow/web 5.0.0-beta.14 → 5.0.0-beta.15

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 (20) hide show
  1. package/build/client/assets/{highlighted-body-B3W2YXNL-BEqiCpJd.js → highlighted-body-B3W2YXNL-BQ1pmB9V.js} +1 -1
  2. package/build/client/assets/{home-D9oyGYfj.js → home-DmsdVk2U.js} +2 -2
  3. package/build/client/assets/{manifest-6fc92124.js → manifest-67209c1f.js} +1 -1
  4. package/build/client/assets/{mermaid-3ZIDBTTL-C02sm-ZS.js → mermaid-3ZIDBTTL-BMWEihLr.js} +89 -34
  5. package/build/client/assets/{mermaid-3ZIDBTTL-DKxHcEOp.css → mermaid-3ZIDBTTL-CVTQRy2j.css} +1 -1
  6. package/build/client/assets/{root-Dduz44vX.js → root-BABNjrUh.js} +1 -1
  7. package/build/client/assets/{run-detail-uOQTua8_.js → run-detail-9xQOGhVk.js} +2 -2
  8. package/build/client/assets/server-build-Ik-p0gUh.css +1 -0
  9. package/build/client/assets/{workflow-graph-viewer-CU0UU458.js → workflow-graph-viewer-fgQ2XQ5R.js} +1 -1
  10. package/build/server/assets/{app-BKJ-G0q_.js → app-DM9e_6xn.js} +1 -1
  11. package/build/server/assets/{highlighted-body-B3W2YXNL-Frh10t8y.js → highlighted-body-B3W2YXNL-tYGHwGrY.js} +2 -2
  12. package/build/server/assets/index-8Fb8OEQ2.js +95 -0
  13. package/build/server/assets/{mermaid-3ZIDBTTL-BtSvadnb.js → mermaid-3ZIDBTTL-EN1JYLRP.js} +2 -2
  14. package/build/server/assets/{server-build-B9XdaVeE.js → server-build-CZXlov2m.js} +574 -165
  15. package/build/server/assets/{token-CpI-8AoV.js → token-CDoC3gHn.js} +2 -2
  16. package/build/server/assets/{token-util-FXtXbDcd.js → token-util-C02bLOPS.js} +2 -2
  17. package/build/server/index.js +1 -1
  18. package/package.json +5 -5
  19. package/build/client/assets/server-build-CNnlgxpd.css +0 -1
  20. package/build/server/assets/index-GhULR6rc.js +0 -92
@@ -14,7 +14,7 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
14
14
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
15
15
  var __superGet = (cls, obj, key) => __reflectGet(__getProtoOf(cls), key, obj);
16
16
  var _a2, _b, _c, _d, _listeners, _onabort, _reader, _root, _hasMagic, _uflag, _parts, _parent, _parentIndex, _negs, _filledNegs, _options, _toString, _emptyExt, _AST_instances, fillNegs_fn, _AST_static, parseAST_fn, canAdoptWithSpace_fn, canAdopt_fn, canAdoptType_fn, adoptWithSpace_fn, adopt_fn, canUsurpType_fn, canUsurp_fn, usurp_fn, flatten_fn, partsToRegExp_fn, parseGlob_fn, _Minimatch_instances, matchGlobstar_fn, matchGlobStarBodySections_fn, matchOne_fn, _worldPromise, _Run_instances, lazyWorldPromise_get, _encryptionKeyPromise, _resilientStart, getEncryptionKey_fn, getEncryptionKeyLazily_fn, pollReturnValue_fn;
17
- import { a as requireReact, S as ServerRouter, c as createReadableStreamFromReadable, r as reactExports, g as getDefaultExportFromCjs, R as React, b as ReactExports, w as withComponentProps, d as withErrorBoundaryProps, M as Meta, L as Links, e as ScrollRestoration, f as Scripts, O as Outlet, u as useNavigate, h as useSearchParams, i as Link$1, j as useRouteError, k as isRouteErrorResponse, l as useLocation, m as useParams } from "./app-BKJ-G0q_.js";
17
+ import { a as requireReact, S as ServerRouter, c as createReadableStreamFromReadable, r as reactExports, g as getDefaultExportFromCjs, R as React, b as ReactExports, w as withComponentProps, d as withErrorBoundaryProps, M as Meta, L as Links, e as ScrollRestoration, f as Scripts, O as Outlet, u as useNavigate, h as useSearchParams, i as Link$1, j as useRouteError, k as isRouteErrorResponse, l as useLocation, m as useParams } from "./app-DM9e_6xn.js";
18
18
  import require$$0$4, { PassThrough } from "node:stream";
19
19
  import require$$0 from "util";
20
20
  import require$$1 from "crypto";
@@ -48632,10 +48632,11 @@ const RESERVED_ATTRIBUTE_KEY_PREFIX = "$";
48632
48632
  const ATTRIBUTE_KEY_MAX_LENGTH = 256;
48633
48633
  const ATTRIBUTE_VALUE_MAX_BYTES = 256;
48634
48634
  const ATTRIBUTE_MAX_PER_RUN = 64;
48635
- object$1({
48635
+ const AttributeChangeSchema = object$1({
48636
48636
  key: string$3(),
48637
48637
  value: union([string$3(), _null()])
48638
48638
  });
48639
+ const AttributeChangesSchema = array$1(AttributeChangeSchema);
48639
48640
  class AttributeValidationError extends Error {
48640
48641
  constructor(message2) {
48641
48642
  super(message2);
@@ -48760,6 +48761,8 @@ const EventTypeSchema = _enum([
48760
48761
  "run_completed",
48761
48762
  "run_failed",
48762
48763
  "run_cancelled",
48764
+ // Run attribute events
48765
+ "attr_set",
48763
48766
  // Step lifecycle events
48764
48767
  "step_created",
48765
48768
  "step_completed",
@@ -48875,13 +48878,34 @@ const WaitCompletedEventSchema = BaseEventSchema.extend({
48875
48878
  resumeAt: date$2().optional()
48876
48879
  }).optional()
48877
48880
  });
48881
+ const AttributeWriterSchema = discriminatedUnion("type", [
48882
+ object$1({
48883
+ type: literal("workflow")
48884
+ }),
48885
+ object$1({
48886
+ type: literal("step"),
48887
+ stepId: string$3(),
48888
+ attempt: number$3()
48889
+ })
48890
+ ]);
48891
+ const AttrSetEventSchema = BaseEventSchema.extend({
48892
+ eventType: literal("attr_set"),
48893
+ correlationId: string$3().optional(),
48894
+ eventData: object$1({
48895
+ changes: AttributeChangesSchema,
48896
+ writer: AttributeWriterSchema,
48897
+ allowReservedAttributes: literal(true).optional()
48898
+ })
48899
+ });
48878
48900
  const RunCreatedEventSchema = BaseEventSchema.extend({
48879
48901
  eventType: literal("run_created"),
48880
48902
  eventData: object$1({
48881
48903
  deploymentId: string$3(),
48882
48904
  workflowName: string$3(),
48883
48905
  input: SerializedDataSchema,
48884
- executionContext: record(string$3(), any()).optional()
48906
+ executionContext: record(string$3(), any()).optional(),
48907
+ attributes: record(string$3(), string$3()).optional(),
48908
+ allowReservedAttributes: literal(true).optional()
48885
48909
  })
48886
48910
  });
48887
48911
  const RunStartedEventSchema = BaseEventSchema.extend({
@@ -48890,7 +48914,9 @@ const RunStartedEventSchema = BaseEventSchema.extend({
48890
48914
  input: SerializedDataSchema.optional(),
48891
48915
  deploymentId: string$3().optional(),
48892
48916
  workflowName: string$3().optional(),
48893
- executionContext: record(string$3(), any()).optional()
48917
+ executionContext: record(string$3(), any()).optional(),
48918
+ attributes: record(string$3(), string$3()).optional(),
48919
+ allowReservedAttributes: literal(true).optional()
48894
48920
  }).optional()
48895
48921
  });
48896
48922
  const RunCompletedEventSchema = BaseEventSchema.extend({
@@ -48922,6 +48948,7 @@ discriminatedUnion("eventType", [
48922
48948
  RunCompletedEventSchema,
48923
48949
  RunFailedEventSchema,
48924
48950
  RunCancelledEventSchema,
48951
+ AttrSetEventSchema,
48925
48952
  // Step lifecycle events
48926
48953
  StepCreatedEventSchema,
48927
48954
  StepCompletedEventSchema,
@@ -48943,6 +48970,7 @@ const AllEventsSchema = discriminatedUnion("eventType", [
48943
48970
  RunCompletedEventSchema,
48944
48971
  RunFailedEventSchema,
48945
48972
  RunCancelledEventSchema,
48973
+ AttrSetEventSchema,
48946
48974
  // Step lifecycle events
48947
48975
  StepCreatedEventSchema,
48948
48976
  StepCompletedEventSchema,
@@ -49010,7 +49038,9 @@ const RunInputSchema = object$1({
49010
49038
  deploymentId: string$3(),
49011
49039
  workflowName: string$3(),
49012
49040
  specVersion: number$3(),
49013
- executionContext: record(string$3(), any()).optional()
49041
+ executionContext: record(string$3(), any()).optional(),
49042
+ /** Initial plaintext run attributes, for resilient run creation. */
49043
+ attributes: record(string$3(), string$3()).optional()
49014
49044
  });
49015
49045
  const WorkflowInvokePayloadSchema = object$1({
49016
49046
  runId: string$3(),
@@ -49205,7 +49235,8 @@ object$1({
49205
49235
  const SPEC_VERSION_LEGACY = 1;
49206
49236
  const SPEC_VERSION_SUPPORTS_EVENT_SOURCING = 2;
49207
49237
  const SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT = 3;
49208
- const SPEC_VERSION_CURRENT = SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT;
49238
+ const SPEC_VERSION_SUPPORTS_ATTRIBUTES = 4;
49239
+ const SPEC_VERSION_CURRENT = SPEC_VERSION_SUPPORTS_ATTRIBUTES;
49209
49240
  function isLegacySpecVersion(v2) {
49210
49241
  return v2 === void 0 || v2 === null || v2 <= SPEC_VERSION_LEGACY;
49211
49242
  }
@@ -80705,7 +80736,7 @@ var tn = f("block", "before:content-[counter(line)]", "before:inline-block", "be
80705
80736
  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 });
80706
80737
  var Se = reactExports.createContext({ code: "" }), de = () => reactExports.useContext(Se);
80707
80738
  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 }) });
80708
- var cn$1 = /\n+$/, dn = reactExports.lazy(() => import("./highlighted-body-B3W2YXNL-Frh10t8y.js").then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
80739
+ var cn$1 = /\n+$/, dn = reactExports.lazy(() => import("./highlighted-body-B3W2YXNL-tYGHwGrY.js").then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
80709
80740
  let i = reactExports.useMemo(() => e.replace(cn$1, ""), [e]), c = reactExports.useMemo(() => ({ bg: "transparent", fg: "inherit", tokens: i.split(`
80710
80741
  `).map((a2) => [{ content: a2, color: "inherit", bgColor: "transparent", htmlStyle: {}, offset: 0 }]) }), [i]);
80711
80742
  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 }) })] }) });
@@ -81027,7 +81058,7 @@ var Dt = ({ children: e, className: t, onDownload: o, onError: n }) => {
81027
81058
  }, []), jsxRuntimeExports.jsxs("div", { className: "relative", ref: i, children: [jsxRuntimeExports.jsx("button", { className: f("cursor-pointer p-1 text-muted-foreground transition-all hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50", t), disabled: c, onClick: () => r2(!s2), title: "Download table", type: "button", children: e != null ? e : jsxRuntimeExports.jsx(Z, { size: 14 }) }), s2 ? jsxRuntimeExports.jsxs("div", { className: "absolute top-full right-0 z-10 mt-1 min-w-[120px] overflow-hidden rounded-md border border-border bg-background shadow-lg", children: [jsxRuntimeExports.jsx("button", { className: "w-full px-3 py-2 text-left text-sm transition-colors hover:bg-muted/40", onClick: () => a2("csv"), title: "Download table as CSV", type: "button", children: "CSV" }), jsxRuntimeExports.jsx("button", { className: "w-full px-3 py-2 text-left text-sm transition-colors hover:bg-muted/40", onClick: () => a2("markdown"), title: "Download table as Markdown", type: "button", children: "Markdown" })] }) : null] });
81028
81059
  };
81029
81060
  var Vt = ({ children: e, className: t, showControls: o, ...n }) => jsxRuntimeExports.jsxs("div", { className: "my-4 flex flex-col gap-2 rounded-lg border border-border bg-sidebar p-2", "data-streamdown": "table-wrapper", children: [o ? jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-1", children: [jsxRuntimeExports.jsx(Ht, {}), jsxRuntimeExports.jsx(Dt, {})] }) : null, jsxRuntimeExports.jsx("div", { className: "border-collapse overflow-x-auto overscroll-y-auto rounded-md border border-border bg-background", children: jsxRuntimeExports.jsx("table", { className: f("w-full divide-y divide-border", t), "data-streamdown": "table", ...n, children: e }) })] });
81030
- var Jn = reactExports.lazy(() => import("./mermaid-3ZIDBTTL-BtSvadnb.js").then((e) => ({ default: e.Mermaid }))), Kn = /language-([^\s]+)/;
81061
+ var Jn = reactExports.lazy(() => import("./mermaid-3ZIDBTTL-EN1JYLRP.js").then((e) => ({ default: e.Mermaid }))), Kn = /language-([^\s]+)/;
81031
81062
  function ke(e, t) {
81032
81063
  if (!(e != null && e.position || t != null && t.position)) return true;
81033
81064
  if (!(e != null && e.position && (t != null && t.position))) return false;
@@ -82595,7 +82626,7 @@ const eventFailed = "_eventFailed_1fmf2_1432";
82595
82626
  const eventRetrying = "_eventRetrying_1fmf2_1441";
82596
82627
  const eventHook = "_eventHook_1fmf2_1450";
82597
82628
  const eventDefault = "_eventDefault_1fmf2_1459";
82598
- const styles$1 = {
82629
+ const styles$2 = {
82599
82630
  traceNode,
82600
82631
  childRow,
82601
82632
  spanNode,
@@ -83065,15 +83096,15 @@ const SEGMENT_LABELS = {
83065
83096
  function SegmentLayer({ segments, spanDuration: spanDuration2 }) {
83066
83097
  if (segments.length === 0)
83067
83098
  return null;
83068
- return jsxRuntimeExports.jsx("div", { className: styles$1.segmentLayer, children: segments.map((seg, i) => {
83069
- const className = styles$1[SEGMENT_CLASS_MAP[seg.status]];
83099
+ return jsxRuntimeExports.jsx("div", { className: styles$2.segmentLayer, children: segments.map((seg, i) => {
83100
+ const className = styles$2[SEGMENT_CLASS_MAP[seg.status]];
83070
83101
  const segDuration = (seg.endFraction - seg.startFraction) * spanDuration2;
83071
83102
  const label = SEGMENT_LABELS[seg.status];
83072
83103
  const style2 = {
83073
83104
  left: `${seg.startFraction * 100}%`,
83074
83105
  width: `${(seg.endFraction - seg.startFraction) * 100}%`
83075
83106
  };
83076
- return jsxRuntimeExports.jsx("div", { className: `${styles$1.segment} ${String(className)}`, style: style2, title: label ? `${label} ${formatDuration(segDuration)}` : formatDuration(segDuration) }, `seg-${seg.status}-${String(i)}`);
83107
+ return jsxRuntimeExports.jsx("div", { className: `${styles$2.segment} ${String(className)}`, style: style2, title: label ? `${label} ${formatDuration(segDuration)}` : formatDuration(segDuration) }, `seg-${seg.status}-${String(i)}`);
83077
83108
  }) });
83078
83109
  }
83079
83110
  function getSegmentTags(segments, spanDuration2) {
@@ -83102,7 +83133,7 @@ function TextContent({ node: node2, layout, durationMs, segmentTags }) {
83102
83133
  return null;
83103
83134
  }
83104
83135
  const showTags = segmentTags && segmentTags.length > 0 && (layout.isHovered || layout.width > 200);
83105
- return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("span", { className: styles$1.spanName, children: [node2.label || node2.span.name, showTags ? segmentTags.map((tag, i) => jsxRuntimeExports.jsxs("span", { className: styles$1.segmentTag, children: [" · ", tag.label, " ", tag.duration] }, i)) : null] }), layout.isHuge ? jsxRuntimeExports.jsx("span", { className: styles$1.spanSpacer }) : null, layout.isHovered || layout.width > 128 ? jsxRuntimeExports.jsx("span", { className: styles$1.spanDuration, children: duration2 }) : null] });
83136
+ return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("span", { className: styles$2.spanName, children: [node2.label || node2.span.name, showTags ? segmentTags.map((tag, i) => jsxRuntimeExports.jsxs("span", { className: styles$2.segmentTag, children: [" · ", tag.label, " ", tag.duration] }, i)) : null] }), layout.isHuge ? jsxRuntimeExports.jsx("span", { className: styles$2.spanSpacer }) : null, layout.isHovered || layout.width > 128 ? jsxRuntimeExports.jsx("span", { className: styles$2.spanDuration, children: duration2 }) : null] });
83106
83137
  }
83107
83138
  function DefaultContent({ node: node2, layout }) {
83108
83139
  return jsxRuntimeExports.jsx(TextContent, { node: node2, layout });
@@ -83225,8 +83256,8 @@ function getSpanLayout(resourceType, node2, root2, scale, scrollSnapshotRef) {
83225
83256
  }
83226
83257
  const getSpanColorClassName = (node2) => {
83227
83258
  if (node2.isVercel)
83228
- return String(styles$1.colorVercel);
83229
- return String(styles$1[`color${node2.resourceIndex % 5}`]);
83259
+ return String(styles$2.colorVercel);
83260
+ return String(styles$2[`color${node2.resourceIndex % 5}`]);
83230
83261
  };
83231
83262
  function getTerminalTimestamp(resourceType, node2) {
83232
83263
  const events2 = node2.events;
@@ -83369,7 +83400,7 @@ const SpanComponent = reactExports.memo(function SpanComponent2({ node: node2, r
83369
83400
  return () => cancelAnimationFrame(rafId);
83370
83401
  }, [isLive, canonicalStartTime, scale]);
83371
83402
  const renderNode = segmentNode;
83372
- return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("button", { "aria-label": `${span.name} - ${duration2}`, className: clsx(styles$1.spanNode, layout.isHuge && styles$1.huge, layout.isSmall && styles$1.small, layout.isExpanded && styles$1.xHover, node2.isHighlighted ? styles$1.colorHighlight : getSpanColorClassName(node2), node2.isHighlighted === false && styles$1.unlit, customClassName, hasSegments2 && styles$1.hasSegments), "data-span-id": span.spanId, "data-start-time": segmentNode.startTime - root2.startTime, "data-right-side": layout.isNearRightSide, "data-selected": node2.isSelected ? "" : void 0, ref, style: getSpanStyle(layout, segmentNode, root2, scale), type: "button", children: jsxRuntimeExports.jsx(SpanContent, { durationMs, resourceType, node: renderNode, layout }) }), segmentNode.events && !layout.isSmall ? segmentNode.events.map((x2) => jsxRuntimeExports.jsx(SpanEventComponent, { customSpanEventClassNameFunc, event: x2, node: segmentNode, root: root2, scale, asBoundary: isWorkflowSpan }, x2.key)) : null] });
83403
+ return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("button", { "aria-label": `${span.name} - ${duration2}`, className: clsx(styles$2.spanNode, layout.isHuge && styles$2.huge, layout.isSmall && styles$2.small, layout.isExpanded && styles$2.xHover, node2.isHighlighted ? styles$2.colorHighlight : getSpanColorClassName(node2), node2.isHighlighted === false && styles$2.unlit, customClassName, hasSegments2 && styles$2.hasSegments), "data-span-id": span.spanId, "data-start-time": segmentNode.startTime - root2.startTime, "data-right-side": layout.isNearRightSide, "data-selected": node2.isSelected ? "" : void 0, ref, style: getSpanStyle(layout, segmentNode, root2, scale), type: "button", children: jsxRuntimeExports.jsx(SpanContent, { durationMs, resourceType, node: renderNode, layout }) }), segmentNode.events && !layout.isSmall ? segmentNode.events.map((x2) => jsxRuntimeExports.jsx(SpanEventComponent, { customSpanEventClassNameFunc, event: x2, node: segmentNode, root: root2, scale, asBoundary: isWorkflowSpan }, x2.key)) : null] });
83373
83404
  });
83374
83405
  const BOUNDARY_LABELS = {
83375
83406
  step_started: "Started",
@@ -83427,17 +83458,17 @@ const SpanEventComponent = reactExports.memo(function SpanEventComponent2({ even
83427
83458
  const isLeftAligned = node2.duration <= 0 || (event.timestamp - node2.startTime) / node2.duration < 0.5;
83428
83459
  const customClassName = customSpanEventClassNameFunc ? customSpanEventClassNameFunc(event) : "";
83429
83460
  return jsxRuntimeExports.jsxs("div", { title: phaseDuration ? `${displayLabel} ${timestamp}
83430
- ${phaseLabel} ${phaseDuration}` : `${displayLabel} ${timestamp}`, className: clsx(styles$1.spanNodeEvent, customClassName, asBoundary && styles$1.boundaryMarker, node2.isHighlighted ? styles$1.colorHighlight : getSpanColorClassName(node2), node2.isHighlighted === false && styles$1.unlit), "data-hovered": event.isHovered, ref, style: {
83461
+ ${phaseLabel} ${phaseDuration}` : `${displayLabel} ${timestamp}`, className: clsx(styles$2.spanNodeEvent, customClassName, asBoundary && styles$2.boundaryMarker, node2.isHighlighted ? styles$2.colorHighlight : getSpanColorClassName(node2), node2.isHighlighted === false && styles$2.unlit), "data-hovered": event.isHovered, ref, style: {
83431
83462
  left,
83432
83463
  top
83433
- }, children: [jsxRuntimeExports.jsx("div", { className: clsx(styles$1.hoverInfo, isLeftAligned ? styles$1.alignStart : styles$1.alignEnd), children: asBoundary ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { className: styles$1.eventName, children: displayLabel }), jsxRuntimeExports.jsx("span", { className: styles$1.eventTimestamp, children: timestamp }), phaseDuration ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { className: styles$1.eventName, children: phaseLabel }), jsxRuntimeExports.jsx("span", { className: styles$1.eventTimestamp, children: phaseDuration })] }) : null] }) : jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { className: styles$1.eventName, children: name2 }), jsxRuntimeExports.jsx("span", { className: styles$1.eventTimestamp, children: timestamp })] }) }), asBoundary ? jsxRuntimeExports.jsx("div", { className: styles$1.boundaryLine }) : jsxRuntimeExports.jsx("div", { className: styles$1.eventDiamond })] });
83464
+ }, children: [jsxRuntimeExports.jsx("div", { className: clsx(styles$2.hoverInfo, isLeftAligned ? styles$2.alignStart : styles$2.alignEnd), children: asBoundary ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { className: styles$2.eventName, children: displayLabel }), jsxRuntimeExports.jsx("span", { className: styles$2.eventTimestamp, children: timestamp }), phaseDuration ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { className: styles$2.eventName, children: phaseLabel }), jsxRuntimeExports.jsx("span", { className: styles$2.eventTimestamp, children: phaseDuration })] }) : null] }) : jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { className: styles$2.eventName, children: name2 }), jsxRuntimeExports.jsx("span", { className: styles$2.eventTimestamp, children: timestamp })] }) }), asBoundary ? jsxRuntimeExports.jsx("div", { className: styles$2.boundaryLine }) : jsxRuntimeExports.jsx("div", { className: styles$2.eventDiamond })] });
83434
83465
  });
83435
83466
  const colorTokenMap = {
83436
83467
  "gray-700": "var(--ds-gray-700)",
83437
83468
  "gray-900": "var(--ds-gray-900)"
83438
83469
  };
83439
83470
  function IconChevronDown({ size: size2 = 16 }) {
83440
- return jsxRuntimeExports.jsxs("svg", { width: size2, height: size2, viewBox: "0 0 24 24", fill: "none", "aria-hidden": true, className: styles$1.detailHeadingIcon, children: [jsxRuntimeExports.jsx("title", { children: "Chevron Down" }), jsxRuntimeExports.jsx("path", { d: "M6 9l6 6 6-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })] });
83471
+ return jsxRuntimeExports.jsxs("svg", { width: size2, height: size2, viewBox: "0 0 24 24", fill: "none", "aria-hidden": true, className: styles$2.detailHeadingIcon, children: [jsxRuntimeExports.jsx("title", { children: "Chevron Down" }), jsxRuntimeExports.jsx("path", { d: "M6 9l6 6 6-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })] });
83441
83472
  }
83442
83473
  function IconExternalSmall({ size: size2 = 16, color: color5 = "gray-900" }) {
83443
83474
  const style2 = { color: colorTokenMap[color5] || color5 };
@@ -83452,7 +83483,7 @@ function Link(props) {
83452
83483
  return jsxRuntimeExports.jsx("a", { className, href, ...rest, children: children2 });
83453
83484
  }
83454
83485
  function Skeleton$1({ width, height, rounded }) {
83455
- return jsxRuntimeExports.jsx("span", { className: clsx(styles$1.skeleton, rounded && styles$1.skeletonRounded), style: { width, height }, "aria-hidden": true });
83486
+ return jsxRuntimeExports.jsx("span", { className: clsx(styles$2.skeleton, rounded && styles$2.skeletonRounded), style: { width, height }, "aria-hidden": true });
83456
83487
  }
83457
83488
  const EXPANDED_STORAGE_KEY_PREFIX = "vc-trace-span-exp:";
83458
83489
  function DetailGroup({ name: name2, className = "", children: children2 }) {
@@ -83468,7 +83499,7 @@ function DetailGroup({ name: name2, className = "", children: children2 }) {
83468
83499
  return willBeExpanded;
83469
83500
  });
83470
83501
  }, [name2]);
83471
- return jsxRuntimeExports.jsxs("div", { className: clsx(styles$1.detailGroup, isExpanded ? styles$1.expanded : styles$1.collapsed, className), children: [jsxRuntimeExports.jsxs("button", { className: styles$1.detailHeading, onClick: toggleExpanded, type: "button", children: [jsxRuntimeExports.jsx("span", { children: name2 }), jsxRuntimeExports.jsx(IconChevronDown, {})] }), isExpanded ? children2 : null] });
83502
+ return jsxRuntimeExports.jsxs("div", { className: clsx(styles$2.detailGroup, isExpanded ? styles$2.expanded : styles$2.collapsed, className), children: [jsxRuntimeExports.jsxs("button", { className: styles$2.detailHeading, onClick: toggleExpanded, type: "button", children: [jsxRuntimeExports.jsx("span", { children: name2 }), jsxRuntimeExports.jsx(IconChevronDown, {})] }), isExpanded ? children2 : null] });
83472
83503
  }
83473
83504
  reactExports.memo(function EntrySpanLinks({ getQuickLinks, span }) {
83474
83505
  const links = getQuickLinks(span);
@@ -83492,7 +83523,7 @@ function usePromise(promise2) {
83492
83523
  }
83493
83524
  function EntrySpanLink({ name: name2, link: linkPromise }) {
83494
83525
  const link2 = usePromise(linkPromise);
83495
- return jsxRuntimeExports.jsxs(Link, { as: link2 ? void 0 : "span", className: clsx(styles$1.spanDetailPanelAttribute, styles$1.spanDetailPanelQuickLink), href: (link2 == null ? void 0 : link2.href) || "", children: [jsxRuntimeExports.jsx("span", { className: styles$1.spanDetailPanelAttributeKey, children: name2 }), jsxRuntimeExports.jsx("span", { className: clsx(styles$1.spanDetailPanelAttributeValue, styles$1.spanDetailPanelQuickLinkLabel), children: link2 ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [link2.label, link2.icon || jsxRuntimeExports.jsx(IconExternalSmall, { color: "gray-900" })] }) : jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Skeleton$1, { height: 18, width: 32 + name2.length * 8 }), jsxRuntimeExports.jsx(Skeleton$1, { height: 18, rounded: true, width: 18 })] }) })] });
83526
+ return jsxRuntimeExports.jsxs(Link, { as: link2 ? void 0 : "span", className: clsx(styles$2.spanDetailPanelAttribute, styles$2.spanDetailPanelQuickLink), href: (link2 == null ? void 0 : link2.href) || "", children: [jsxRuntimeExports.jsx("span", { className: styles$2.spanDetailPanelAttributeKey, children: name2 }), jsxRuntimeExports.jsx("span", { className: clsx(styles$2.spanDetailPanelAttributeValue, styles$2.spanDetailPanelQuickLinkLabel), children: link2 ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [link2.label, link2.icon || jsxRuntimeExports.jsx(IconExternalSmall, { color: "gray-900" })] }) : jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Skeleton$1, { height: 18, width: 32 + name2.length * 8 }), jsxRuntimeExports.jsx(Skeleton$1, { height: 18, rounded: true, width: 18 })] }) })] });
83496
83527
  }
83497
83528
  function useImmediateStyle(ref) {
83498
83529
  const styleRef = reactExports.useRef({});
@@ -83651,10 +83682,10 @@ reactExports.memo(function MiniMap({ timelineRef, rows, scale }) {
83651
83682
  $timeline.removeEventListener("scroll", onScroll);
83652
83683
  };
83653
83684
  }, [timelineRef, thumbRatio, setThumbStyle]);
83654
- return jsxRuntimeExports.jsxs("div", { className: styles$1.mapContainer, ref: containerRef, style: {
83685
+ return jsxRuntimeExports.jsxs("div", { className: styles$2.mapContainer, ref: containerRef, style: {
83655
83686
  width: thumbWidth > 0 ? mapWidth : "100%",
83656
83687
  height: MAP_HEIGHT
83657
- }, children: [jsxRuntimeExports.jsx("canvas", { className: styles$1.mapCanvas, height: MAP_HEIGHT * dpi, ref: canvasRef, style: { width: mapWidth, height: MAP_HEIGHT }, width: mapWidth * dpi }), jsxRuntimeExports.jsx("div", { className: styles$1.mapThumb, ref: thumbRef, style: {
83688
+ }, children: [jsxRuntimeExports.jsx("canvas", { className: styles$2.mapCanvas, height: MAP_HEIGHT * dpi, ref: canvasRef, style: { width: mapWidth, height: MAP_HEIGHT }, width: mapWidth * dpi }), jsxRuntimeExports.jsx("div", { className: styles$2.mapThumb, ref: thumbRef, style: {
83658
83689
  transform: thumbStyle.transform,
83659
83690
  width: thumbWidth > 0 ? thumbWidth : `calc(100% - ${TIMELINE_PADDING * 2}px)`,
83660
83691
  top: 2,
@@ -84179,15 +84210,22 @@ function computeSleepSegmentsFromSpan(_startMs, duration2, _events) {
84179
84210
  return [];
84180
84211
  return [{ startFraction: 0, endFraction: 1, status: "sleeping" }];
84181
84212
  }
84213
+ function runSegmentStatus(runStatus) {
84214
+ if (runStatus === "failed")
84215
+ return "failed";
84216
+ if (runStatus === "running" || runStatus === "pending")
84217
+ return "running";
84218
+ return "completed";
84219
+ }
84182
84220
  function computeRunSegmentsFromSpan(startMs, duration2, activeStartMs, events2, attributes) {
84183
84221
  const segments = [];
84184
84222
  if (duration2 <= 0)
84185
84223
  return segments;
84186
84224
  const sorted = [...events2].map((e) => ({ name: e.name, time: getHighResInMs(e.timestamp) })).sort((a2, b2) => a2.time - b2.time);
84225
+ const runData = attributes == null ? void 0 : attributes.data;
84226
+ const runStatus = runData == null ? void 0 : runData.status;
84187
84227
  const hasRunCreated = sorted.some((e) => e.name === "run_created");
84188
84228
  if (!hasRunCreated) {
84189
- const runData = attributes == null ? void 0 : attributes.data;
84190
- const runStatus = runData == null ? void 0 : runData.status;
84191
84229
  return computeV1RunSegments(startMs, duration2, activeStartMs, runStatus);
84192
84230
  }
84193
84231
  const failedEvent = sorted.find((e) => e.name === "run_failed");
@@ -84206,7 +84244,7 @@ function computeRunSegmentsFromSpan(startMs, duration2, activeStartMs, events2,
84206
84244
  segments.push({
84207
84245
  startFraction: cursor,
84208
84246
  endFraction: 1,
84209
- status: failedEvent ? "failed" : "running"
84247
+ status: failedEvent ? "failed" : runSegmentStatus(runStatus)
84210
84248
  });
84211
84249
  return segments;
84212
84250
  }
@@ -84227,7 +84265,7 @@ function computeV1RunSegments(startMs, duration2, activeStartMs, runStatus) {
84227
84265
  segments.push({
84228
84266
  startFraction: cursor,
84229
84267
  endFraction: 1,
84230
- status: runStatus === "failed" ? "failed" : "running"
84268
+ status: runSegmentStatus(runStatus)
84231
84269
  });
84232
84270
  return segments;
84233
84271
  }
@@ -84427,6 +84465,10 @@ function SplitPane({ children: children2, className, defaultStartWidth = DEFAULT
84427
84465
  }
84428
84466
  return jsxRuntimeExports.jsxs("div", { ref: setContainerRef, className: cn$4("grid h-full min-h-0 content-start overflow-x-hidden overflow-y-auto", isDragging && "select-none", className), style: { gridTemplateColumns: colTemplate, height: "100%" }, children: [start2, gutter, end] });
84429
84467
  }
84468
+ const runningStripes = "_runningStripes_62ud0_1";
84469
+ const styles$1 = {
84470
+ runningStripes
84471
+ };
84430
84472
  const TINY_BAR_BOX_SIZE_PX = 24;
84431
84473
  const TINY_BAR_WIDTH_PX = 4;
84432
84474
  const TIMELINE_PADDING_PX = 16;
@@ -84435,6 +84477,7 @@ const SEGMENT_CLASSES = {
84435
84477
  retrying: "bg-gray-400 border border-gray-500",
84436
84478
  waiting: "bg-gray-400 border border-gray-500",
84437
84479
  running: "bg-blue-200 border border-blue-500",
84480
+ completed: "bg-blue-200 border border-blue-500",
84438
84481
  failed: "bg-red-200 border border-red-500",
84439
84482
  succeeded: "bg-green-200 border border-green-500",
84440
84483
  sleeping: "bg-gray-400 border border-gray-500",
@@ -84444,6 +84487,13 @@ const TIMELINE_INSET_STYLE = {
84444
84487
  left: TIMELINE_PADDING_PX,
84445
84488
  right: TIMELINE_PADDING_PX
84446
84489
  };
84490
+ const ACTIVE_SEGMENT_STATUSES = /* @__PURE__ */ new Set([
84491
+ "running",
84492
+ "received"
84493
+ ]);
84494
+ function RunningStripes() {
84495
+ return jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: styles$1.runningStripes });
84496
+ }
84447
84497
  function computeBarGeometry(startMs, endMs, viewStart, viewEnd, containerWidth) {
84448
84498
  const viewDuration = viewEnd - viewStart;
84449
84499
  const visibleStartMs = Math.max(startMs, viewStart);
@@ -84516,21 +84566,27 @@ function BoundaryArrow({ direction }) {
84516
84566
  function PlainBar({ bg: bg2, border, label }) {
84517
84567
  return jsxRuntimeExports.jsx("div", { className: "relative h-6 w-full min-w-1 rounded-[0.25rem] border", style: { background: bg2, borderColor: border }, children: label ? jsxRuntimeExports.jsx(DurationLabel, { label }) : null });
84518
84568
  }
84569
+ function LeadInConnector({ leftPct, widthPct, label }) {
84570
+ return jsxRuntimeExports.jsxs("div", { className: "absolute top-1/2 h-6 -translate-y-1/2", style: {
84571
+ left: `calc(${leftPct}% + 0.5px)`,
84572
+ width: `calc(${widthPct}% - 1px)`
84573
+ }, children: [jsxRuntimeExports.jsx("div", { className: "absolute left-0 top-1/2 h-4 w-px -translate-y-1/2 bg-gray-500" }), jsxRuntimeExports.jsx("div", { className: "absolute inset-x-0 top-1/2 h-px -translate-y-1/2 bg-gray-500" }), label ? jsxRuntimeExports.jsx(DurationLabel, { label }) : null] });
84574
+ }
84519
84575
  function SegmentBar({ segments }) {
84520
84576
  return jsxRuntimeExports.jsx("div", { className: "relative h-6 w-full", children: segments.map((seg, i) => {
84577
+ if (seg.status === "queued") {
84578
+ const leadInLabel = formatDurationPrecise(seg.fullDurationMs);
84579
+ const showLeadInLabel = seg.pixelWidth >= Math.max(40, leadInLabel.length * 6 + 12);
84580
+ return jsxRuntimeExports.jsx(LeadInConnector, { leftPct: seg.leftPct, widthPct: seg.widthPct, label: showLeadInLabel ? leadInLabel : null }, i);
84581
+ }
84521
84582
  const label = formatDurationPrecise(seg.fullDurationMs);
84522
84583
  const showLabel = seg.pixelWidth >= Math.max(40, label.length * 6 + 12);
84523
- const isNarrowQueued = seg.status === "queued" && seg.pixelWidth < 20;
84524
- const overrideBg = isNarrowQueued ? "var(--ds-gray-400)" : void 0;
84525
- const overrideBorder = isNarrowQueued ? "var(--ds-gray-500)" : void 0;
84526
- return jsxRuntimeExports.jsx("div", { className: cn$4("absolute h-full rounded-[0.25rem]", SEGMENT_CLASSES[seg.status]), style: {
84584
+ return jsxRuntimeExports.jsxs("div", { className: cn$4("absolute h-full overflow-hidden rounded-[0.25rem]", SEGMENT_CLASSES[seg.status]), style: {
84527
84585
  // 1px gap between adjacent segments, distributed equally.
84528
84586
  left: `calc(${seg.leftPct}% + 0.5px)`,
84529
84587
  width: `calc(${seg.widthPct}% - 1px)`,
84530
- minWidth: 1,
84531
- background: overrideBg,
84532
- borderColor: overrideBorder
84533
- }, children: showLabel ? jsxRuntimeExports.jsx(DurationLabel, { label }) : null }, i);
84588
+ minWidth: 1
84589
+ }, children: [ACTIVE_SEGMENT_STATUSES.has(seg.status) ? jsxRuntimeExports.jsx(RunningStripes, {}) : null, showLabel ? jsxRuntimeExports.jsx(DurationLabel, { label }) : null] }, i);
84534
84590
  }) });
84535
84591
  }
84536
84592
  const TimelineBar = reactExports.memo(function TimelineBar2({ span, viewStart, viewDuration, containerWidth, isSelected, isDimmed, onSelect }) {
@@ -88526,6 +88582,7 @@ class WorkflowSuspension extends Error {
88526
88582
  let stepCount = 0;
88527
88583
  let hookCount = 0;
88528
88584
  let waitCount = 0;
88585
+ let attributeCount = 0;
88529
88586
  let hookDisposedCount = 0;
88530
88587
  let abortCount = 0;
88531
88588
  for (const item of steps) {
@@ -88540,6 +88597,8 @@ class WorkflowSuspension extends Error {
88540
88597
  hookCount++;
88541
88598
  } else if (item.type === "wait")
88542
88599
  waitCount++;
88600
+ else if (item.type === "attribute")
88601
+ attributeCount++;
88543
88602
  }
88544
88603
  const parts = [];
88545
88604
  if (stepCount > 0) {
@@ -88551,12 +88610,15 @@ class WorkflowSuspension extends Error {
88551
88610
  if (waitCount > 0) {
88552
88611
  parts.push(`${waitCount} ${pluralize("wait", "waits", waitCount)}`);
88553
88612
  }
88613
+ if (attributeCount > 0) {
88614
+ parts.push(`${attributeCount} ${pluralize("attribute write", "attribute writes", attributeCount)}`);
88615
+ }
88554
88616
  if (hookDisposedCount > 0) {
88555
88617
  parts.push(`${hookDisposedCount} hook ${pluralize("disposal", "disposals", hookDisposedCount)}`);
88556
88618
  }
88557
- const totalCount = stepCount + hookCount + waitCount + hookDisposedCount;
88619
+ const totalCount = stepCount + hookCount + waitCount + attributeCount + hookDisposedCount;
88558
88620
  const hasOrHave = pluralize("has", "have", totalCount);
88559
- const typeCount = (stepCount > 0 ? 1 : 0) + (hookCount > 0 ? 1 : 0) + (waitCount > 0 ? 1 : 0) + (hookDisposedCount > 0 ? 1 : 0);
88621
+ const typeCount = (stepCount > 0 ? 1 : 0) + (hookCount > 0 ? 1 : 0) + (waitCount > 0 ? 1 : 0) + (attributeCount > 0 ? 1 : 0) + (hookDisposedCount > 0 ? 1 : 0);
88560
88622
  let action2;
88561
88623
  if (typeCount > 1) {
88562
88624
  action2 = "processed";
@@ -88566,6 +88628,8 @@ class WorkflowSuspension extends Error {
88566
88628
  action2 = "created";
88567
88629
  } else if (waitCount > 0) {
88568
88630
  action2 = "created";
88631
+ } else if (attributeCount > 0) {
88632
+ action2 = "written";
88569
88633
  } else if (hookDisposedCount > 0) {
88570
88634
  action2 = "processed";
88571
88635
  } else {
@@ -88578,6 +88642,7 @@ class WorkflowSuspension extends Error {
88578
88642
  __publicField(this, "stepCount");
88579
88643
  __publicField(this, "hookCount");
88580
88644
  __publicField(this, "waitCount");
88645
+ __publicField(this, "attributeCount");
88581
88646
  __publicField(this, "hookDisposedCount");
88582
88647
  __publicField(this, "abortCount");
88583
88648
  this.name = "WorkflowSuspension";
@@ -88586,6 +88651,7 @@ class WorkflowSuspension extends Error {
88586
88651
  this.stepCount = stepCount;
88587
88652
  this.hookCount = hookCount;
88588
88653
  this.waitCount = waitCount;
88654
+ this.attributeCount = attributeCount;
88589
88655
  this.hookDisposedCount = hookDisposedCount;
88590
88656
  this.abortCount = abortCount;
88591
88657
  }
@@ -88979,7 +89045,7 @@ const encryption = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
88979
89045
  encrypt: encrypt$1,
88980
89046
  importKey
88981
89047
  }, Symbol.toStringTag, { value: "Module" }));
88982
- const version$1 = "5.0.0-beta.14";
89048
+ const version$1 = "5.0.0-beta.15";
88983
89049
  const WorldCacheKey = Symbol.for("@workflow/world//cache");
88984
89050
  const WorldCachePromiseKey = Symbol.for("@workflow/world//cachePromise");
88985
89051
  const GetWorldFnKey$1 = Symbol.for("@workflow/world//getWorldFn");
@@ -89317,6 +89383,7 @@ const WORKFLOW_DESERIALIZE = Symbol.for("workflow-deserialize");
89317
89383
  const STABLE_ULID = Symbol.for("WORKFLOW_STABLE_ULID");
89318
89384
  const STREAM_NAME_SYMBOL = Symbol.for("WORKFLOW_STREAM_NAME");
89319
89385
  const STREAM_TYPE_SYMBOL = Symbol.for("WORKFLOW_STREAM_TYPE");
89386
+ const STREAM_FRAMING_SYMBOL = Symbol.for("WORKFLOW_STREAM_FRAMING");
89320
89387
  const STREAM_SERVER_RUN_ID_SYMBOL = Symbol.for("WORKFLOW_STREAM_SERVER_RUN_ID");
89321
89388
  const STREAM_SERVER_DEPLOYMENT_ID_SYMBOL = Symbol.for("WORKFLOW_STREAM_SERVER_DEPLOYMENT_ID");
89322
89389
  const BODY_INIT_SYMBOL = Symbol.for("BODY_INIT");
@@ -90227,6 +90294,55 @@ function getDeserializeStream(revivers, cryptoKey) {
90227
90294
  });
90228
90295
  return stream;
90229
90296
  }
90297
+ const MAX_FRAME_SIZE = 1e8;
90298
+ function getByteFramingStream() {
90299
+ return new TransformStream({
90300
+ transform(chunk, controller) {
90301
+ if (chunk.length === 0)
90302
+ return;
90303
+ if (chunk.length > MAX_FRAME_SIZE) {
90304
+ controller.error(new WorkflowRuntimeError(`Byte-stream chunk of ${chunk.length} bytes exceeds the maximum framed chunk size (${MAX_FRAME_SIZE}). Split the data into smaller chunks before writing.`, { slug: "serialization-failed" }));
90305
+ return;
90306
+ }
90307
+ const frame2 = new Uint8Array(FRAME_HEADER_SIZE$1 + chunk.length);
90308
+ new DataView(frame2.buffer).setUint32(0, chunk.length, false);
90309
+ frame2.set(chunk, FRAME_HEADER_SIZE$1);
90310
+ controller.enqueue(frame2);
90311
+ }
90312
+ });
90313
+ }
90314
+ function getByteUnframingStream() {
90315
+ let buffer2 = new Uint8Array(0);
90316
+ function appendToBuffer(data) {
90317
+ const next2 = new Uint8Array(buffer2.length + data.length);
90318
+ next2.set(buffer2, 0);
90319
+ next2.set(data, buffer2.length);
90320
+ buffer2 = next2;
90321
+ }
90322
+ return new TransformStream({
90323
+ transform(chunk, controller) {
90324
+ if (chunk.length > 0)
90325
+ appendToBuffer(chunk);
90326
+ while (buffer2.length >= FRAME_HEADER_SIZE$1) {
90327
+ const frameLength = new DataView(buffer2.buffer, buffer2.byteOffset, buffer2.byteLength).getUint32(0, false);
90328
+ if (frameLength > MAX_FRAME_SIZE) {
90329
+ controller.error(new WorkflowRuntimeError(`Byte-stream frame length ${frameLength} exceeds maximum (${MAX_FRAME_SIZE}). This usually means a non-framed byte stream is being read as framed.`, { slug: "serialization-failed" }));
90330
+ return;
90331
+ }
90332
+ const total = FRAME_HEADER_SIZE$1 + frameLength;
90333
+ if (buffer2.length < total)
90334
+ break;
90335
+ controller.enqueue(buffer2.slice(FRAME_HEADER_SIZE$1, total));
90336
+ buffer2 = buffer2.slice(total);
90337
+ }
90338
+ },
90339
+ flush(controller) {
90340
+ if (buffer2.length > 0) {
90341
+ controller.error(new WorkflowRuntimeError(`Byte-stream ended with ${buffer2.length} bytes of incomplete frame data. The stream was truncated mid-frame.`, { slug: "serialization-failed" }));
90342
+ }
90343
+ }
90344
+ });
90345
+ }
90230
90346
  class WorkflowServerReadableStream extends ReadableStream {
90231
90347
  constructor(runId, name2, startIndex) {
90232
90348
  if (typeof name2 !== "string" || name2.length === 0) {
@@ -90552,7 +90668,7 @@ function attachAbortListenerOnce(signal, streamName, runId, cryptoKey, ops) {
90552
90668
  })());
90553
90669
  }, { once: true });
90554
90670
  }
90555
- function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey) {
90671
+ function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false) {
90556
90672
  return {
90557
90673
  ...getAllBaseReducers(global2),
90558
90674
  ReadableStream: (value) => {
@@ -90568,13 +90684,19 @@ function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey) {
90568
90684
  const type = getStreamType(value);
90569
90685
  const writable = new WorkflowServerWritableStream(runId, name2);
90570
90686
  if (type === "bytes") {
90571
- ops.push(value.pipeTo(writable));
90687
+ if (framedByteStreams) {
90688
+ ops.push(value.pipeThrough(getByteFramingStream()).pipeTo(writable));
90689
+ } else {
90690
+ ops.push(value.pipeTo(writable));
90691
+ }
90572
90692
  } else {
90573
- ops.push(value.pipeThrough(getSerializeStream(getExternalReducers(global2, ops, runId, cryptoKey), cryptoKey)).pipeTo(writable));
90693
+ ops.push(value.pipeThrough(getSerializeStream(getExternalReducers(global2, ops, runId, cryptoKey, framedByteStreams), cryptoKey)).pipeTo(writable));
90574
90694
  }
90575
90695
  const s2 = { name: name2 };
90576
90696
  if (type)
90577
90697
  s2.type = type;
90698
+ if (type === "bytes" && framedByteStreams)
90699
+ s2.framing = "framed-v1";
90578
90700
  return s2;
90579
90701
  },
90580
90702
  WritableStream: (value) => {
@@ -90631,6 +90753,9 @@ function getWorkflowReducers(global2 = globalThis) {
90631
90753
  const type = value[STREAM_TYPE_SYMBOL];
90632
90754
  if (type)
90633
90755
  s2.type = type;
90756
+ const framing = value[STREAM_FRAMING_SYMBOL];
90757
+ if (framing)
90758
+ s2.framing = framing;
90634
90759
  return s2;
90635
90760
  },
90636
90761
  WritableStream: (value) => {
@@ -90675,7 +90800,7 @@ function getWorkflowReducers(global2 = globalThis) {
90675
90800
  }
90676
90801
  };
90677
90802
  }
90678
- function getStepReducers(global2 = globalThis, ops, runId, cryptoKey) {
90803
+ function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false) {
90679
90804
  return {
90680
90805
  ...getAllBaseReducers(global2),
90681
90806
  ReadableStream: (value) => {
@@ -90688,20 +90813,28 @@ function getStepReducers(global2 = globalThis, ops, runId, cryptoKey) {
90688
90813
  }
90689
90814
  let name2 = value[STREAM_NAME_SYMBOL];
90690
90815
  let type = value[STREAM_TYPE_SYMBOL];
90816
+ let framing = value[STREAM_FRAMING_SYMBOL];
90691
90817
  if (!name2) {
90692
90818
  const streamId = (global2[STABLE_ULID] || defaultUlid)();
90693
90819
  name2 = `strm_${streamId}`;
90694
90820
  type = getStreamType(value);
90821
+ framing = type === "bytes" && framedByteStreams ? "framed-v1" : framing;
90695
90822
  const writable = new WorkflowServerWritableStream(runId, name2);
90696
90823
  if (type === "bytes") {
90697
- ops.push(value.pipeTo(writable));
90824
+ if (framing === "framed-v1") {
90825
+ ops.push(value.pipeThrough(getByteFramingStream()).pipeTo(writable));
90826
+ } else {
90827
+ ops.push(value.pipeTo(writable));
90828
+ }
90698
90829
  } else {
90699
- ops.push(value.pipeThrough(getSerializeStream(getStepReducers(global2, ops, runId, cryptoKey), cryptoKey)).pipeTo(writable));
90830
+ ops.push(value.pipeThrough(getSerializeStream(getStepReducers(global2, ops, runId, cryptoKey, framedByteStreams), cryptoKey)).pipeTo(writable));
90700
90831
  }
90701
90832
  }
90702
90833
  const s2 = { name: name2 };
90703
90834
  if (type)
90704
90835
  s2.type = type;
90836
+ if (framing)
90837
+ s2.framing = framing;
90705
90838
  return s2;
90706
90839
  },
90707
90840
  WritableStream: (value) => {
@@ -90906,7 +91039,7 @@ function getExternalRevivers(global2 = globalThis, ops, runId, cryptoKey) {
90906
91039
  const readable2 = new WorkflowServerReadableStream(runId, value.name, value.startIndex);
90907
91040
  const state = createFlushableState();
90908
91041
  ops.push(state.promise);
90909
- const { readable: userReadable, writable } = new global2.TransformStream();
91042
+ const { readable: userReadable, writable } = value.framing === "framed-v1" ? getByteUnframingStream() : new global2.TransformStream();
90910
91043
  flushablePipe(readable2, writable, state).catch(() => {
90911
91044
  });
90912
91045
  pollReadableLock(userReadable, state);
@@ -91000,6 +91133,15 @@ function getWorkflowRevivers(global2 = globalThis) {
91000
91133
  [STREAM_TYPE_SYMBOL]: {
91001
91134
  value: value.type,
91002
91135
  writable: false
91136
+ },
91137
+ // Carry the wire-framing decision through the workflow VM so
91138
+ // that when the handle is later passed to a step (which reads
91139
+ // the actual bytes from the server) we know whether to unframe.
91140
+ // Defaults to undefined for streams whose serialized ref didn't
91141
+ // carry the field — those are treated as legacy raw bytes.
91142
+ [STREAM_FRAMING_SYMBOL]: {
91143
+ value: value.framing,
91144
+ writable: false
91003
91145
  }
91004
91146
  });
91005
91147
  },
@@ -91161,7 +91303,7 @@ function getStepRevivers(global2 = globalThis, ops, runId, cryptoKey, deployment
91161
91303
  if (value.type === "bytes") {
91162
91304
  const state = createFlushableState();
91163
91305
  ops.push(state.promise);
91164
- const { readable: userReadable, writable } = new global2.TransformStream();
91306
+ const { readable: userReadable, writable } = value.framing === "framed-v1" ? getByteUnframingStream() : new global2.TransformStream();
91165
91307
  flushablePipe(readable2, writable, state).catch(() => {
91166
91308
  });
91167
91309
  pollReadableLock(userReadable, state);
@@ -91210,15 +91352,15 @@ function getStepRevivers(global2 = globalThis, ops, runId, cryptoKey, deployment
91210
91352
  async function maybeDecrypt(data, key) {
91211
91353
  return decrypt(data, key);
91212
91354
  }
91213
- async function dehydrateWorkflowArguments(value, runId, key, ops = [], global2 = globalThis, v1Compat = false) {
91355
+ async function dehydrateWorkflowArguments(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false) {
91214
91356
  if (v1Compat) {
91215
- const str = stringify$2(value, getExternalReducers(global2, ops, runId, key));
91357
+ const str = stringify$2(value, getExternalReducers(global2, ops, runId, key, framedByteStreams));
91216
91358
  return revive(str);
91217
91359
  }
91218
91360
  try {
91219
91361
  return await serialize$1(value, key, {
91220
91362
  global: global2,
91221
- extraReducers: getStreamAndRequestReducers(getExternalReducers(global2, ops, runId, key))
91363
+ extraReducers: getStreamAndRequestReducers(getExternalReducers(global2, ops, runId, key, framedByteStreams))
91222
91364
  });
91223
91365
  } catch (error2) {
91224
91366
  const cause = unwrapSerializationCause(error2);
@@ -91269,15 +91411,15 @@ async function hydrateStepArguments(value, runId, key, ops = [], global2 = globa
91269
91411
  }
91270
91412
  });
91271
91413
  }
91272
- async function dehydrateStepReturnValue(value, runId, key, ops = [], global2 = globalThis, v1Compat = false) {
91414
+ async function dehydrateStepReturnValue(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false) {
91273
91415
  if (v1Compat) {
91274
- const str = stringify$2(value, getStepReducers(global2, ops, runId, key));
91416
+ const str = stringify$2(value, getStepReducers(global2, ops, runId, key, framedByteStreams));
91275
91417
  return revive(str);
91276
91418
  }
91277
91419
  try {
91278
91420
  return await serialize(value, key, {
91279
91421
  global: global2,
91280
- extraReducers: getStreamAndRequestReducers(getStepReducers(global2, ops, runId, key))
91422
+ extraReducers: getStreamAndRequestReducers(getStepReducers(global2, ops, runId, key, framedByteStreams))
91281
91423
  });
91282
91424
  } catch (error2) {
91283
91425
  const cause = unwrapSerializationCause(error2);
@@ -117602,6 +117744,8 @@ function createQueue$2(config2) {
117602
117744
  const transport = new TypedJsonTransport();
117603
117745
  const generateId2 = monotonicFactory();
117604
117746
  const semaphore = new libExports.Sema(WORKFLOW_LOCAL_QUEUE_CONCURRENCY);
117747
+ const closeController = new AbortController();
117748
+ const closeSignal = closeController.signal;
117605
117749
  const inflightMessages = /* @__PURE__ */ new Map();
117606
117750
  const directHandlers = /* @__PURE__ */ new Map();
117607
117751
  const queue = async (queueName, message2, opts) => {
@@ -117626,6 +117770,10 @@ function createQueue$2(config2) {
117626
117770
  });
117627
117771
  }
117628
117772
  (async () => {
117773
+ if ((opts == null ? void 0 : opts.delaySeconds) && opts.delaySeconds > 0) {
117774
+ const delayMs = Math.min(opts.delaySeconds * 1e3, MAX_SAFE_TIMEOUT_MS);
117775
+ await setTimeout$1(delayMs, void 0, { signal: closeSignal });
117776
+ }
117629
117777
  const token = semaphore.tryAcquire();
117630
117778
  if (!token) {
117631
117779
  console.warn(`[world-local]: concurrency limit (${WORKFLOW_LOCAL_QUEUE_CONCURRENCY}) reached, waiting for queue to free up`);
@@ -117667,7 +117815,9 @@ function createQueue$2(config2) {
117667
117815
  if (Number.isFinite(timeoutSeconds) && timeoutSeconds >= 0) {
117668
117816
  if (timeoutSeconds > 0) {
117669
117817
  const timeoutMs = Math.min(timeoutSeconds * 1e3, MAX_SAFE_TIMEOUT_MS);
117670
- await setTimeout$1(timeoutMs);
117818
+ await setTimeout$1(timeoutMs, void 0, {
117819
+ signal: closeSignal
117820
+ });
117671
117821
  }
117672
117822
  continue;
117673
117823
  }
@@ -117682,7 +117832,7 @@ function createQueue$2(config2) {
117682
117832
  ...stepId && { stepId },
117683
117833
  handlerError: text2
117684
117834
  });
117685
- await setTimeout$1(5e3);
117835
+ await setTimeout$1(5e3, void 0, { signal: closeSignal });
117686
117836
  }
117687
117837
  console.error(`[world-local] Queue message exhausted safety limit (${MAX_LOCAL_SAFETY_LIMIT} attempts)`, {
117688
117838
  queueName,
@@ -117762,6 +117912,9 @@ function createQueue$2(config2) {
117762
117912
  directHandlers.set(prefix, handler);
117763
117913
  },
117764
117914
  async close() {
117915
+ if (closeSignal.aborted)
117916
+ return;
117917
+ closeController.abort();
117765
117918
  await httpAgent.close();
117766
117919
  }
117767
117920
  };
@@ -117769,6 +117922,10 @@ function createQueue$2(config2) {
117769
117922
  function hashToken(token) {
117770
117923
  return createHash("sha256").update(token).digest("hex");
117771
117924
  }
117925
+ function hookRecoveryMarkerPath(basedir, token, runId, hookId) {
117926
+ const key = createHash("sha256").update(`${token}\0${runId}\0${hookId}`).digest("hex");
117927
+ return path$3.join(basedir, "hooks", "tokens", `${key}.recovery.json`);
117928
+ }
117772
117929
  const monotonicUlid$1 = monotonicFactory(() => Math.random());
117773
117930
  const getObjectCreatedAt = (idPrefix) => (filename) => {
117774
117931
  const cleanName = stripTag(filename.replace(/\.json$/, "")) + ".json";
@@ -117880,6 +118037,7 @@ async function deleteAllHooksForRun(basedir, runId) {
117880
118037
  if (hook && hook.runId === runId) {
117881
118038
  const constraintPath = path$3.join(hooksDir, "tokens", `${hashToken(hook.token)}.json`);
117882
118039
  await deleteJSON(constraintPath);
118040
+ await deleteJSON(hookRecoveryMarkerPath(basedir, hook.token, hook.runId, hook.hookId));
117883
118041
  await deleteJSON(hookPath);
117884
118042
  }
117885
118043
  }
@@ -118031,9 +118189,27 @@ function createRunsStorage(basedir, tag) {
118031
118189
  }
118032
118190
  };
118033
118191
  }
118034
- const stepLocks = /* @__PURE__ */ new Map();
118035
118192
  const HookTokenClaimSchema = object$1({
118036
- runId: string$3()
118193
+ // The token-claim writer below has always persisted `hookId`, but
118194
+ // this read schema previously omitted it, which is the bug fixed
118195
+ // by https://github.com/vercel/workflow/issues/2283. `optional()`
118196
+ // is defensive: any claim file that somehow lacks the field still
118197
+ // parses (yielding `undefined`) and falls through to the cross-
118198
+ // hook conflict branch, matching pre-fix behavior.
118199
+ hookId: string$3().optional(),
118200
+ runId: string$3(),
118201
+ // `eventId` is the canonical hook_created event ID the claiming
118202
+ // worker committed to publishing. Persisting it here turns the
118203
+ // claim file into a durable convergence key for cross-worker /
118204
+ // cross-process retries (see comment on the hook_created branch).
118205
+ // `optional()` for backward compatibility: a legacy claim file
118206
+ // written before this field existed falls through to the recovery-
118207
+ // marker upgrade path, which atomically pins a canonical eventId
118208
+ // via a sidecar marker (also a `writeExclusive`).
118209
+ eventId: string$3().optional()
118210
+ });
118211
+ const HookRecoveryMarkerSchema = object$1({
118212
+ eventId: string$3()
118037
118213
  });
118038
118214
  async function readHookTokenClaim(constraintPath) {
118039
118215
  try {
@@ -118045,8 +118221,70 @@ async function readHookTokenClaim(constraintPath) {
118045
118221
  throw error2;
118046
118222
  }
118047
118223
  }
118048
- function withStepLock(key, fn2) {
118049
- const prev = stepLocks.get(key);
118224
+ async function readHookRecoveryMarker(markerPath) {
118225
+ try {
118226
+ return await readJSON(markerPath, HookRecoveryMarkerSchema);
118227
+ } catch (error2) {
118228
+ if (error2 instanceof SyntaxError || error2 instanceof ZodError) {
118229
+ return null;
118230
+ }
118231
+ throw error2;
118232
+ }
118233
+ }
118234
+ async function findExistingHookCreatedEventId(basedir, runId, correlationId) {
118235
+ var _a3;
118236
+ const result = await paginatedFileSystemQuery({
118237
+ directory: path$3.join(basedir, "events"),
118238
+ schema: EventSchema,
118239
+ filePrefix: `${runId}-`,
118240
+ filter: (event) => event.eventType === "hook_created" && event.correlationId === correlationId,
118241
+ limit: 1,
118242
+ getCreatedAt: getObjectCreatedAt("evnt"),
118243
+ getId: (event) => event.eventId
118244
+ });
118245
+ return ((_a3 = result.data[0]) == null ? void 0 : _a3.eventId) ?? null;
118246
+ }
118247
+ async function repairHookEntityFromPersistedEvent(basedir, runId, hookId, persistedEventId, tag) {
118248
+ const compositeKey = `${runId}-${persistedEventId}`;
118249
+ const persistedEvent = await readJSONWithFallback(basedir, "events", compositeKey, EventSchema, tag);
118250
+ if (!persistedEvent || persistedEvent.eventType !== "hook_created" || persistedEvent.correlationId !== hookId) {
118251
+ return;
118252
+ }
118253
+ const existingHook = await readJSONWithFallback(basedir, "hooks", hookId, HookSchema, tag);
118254
+ if (existingHook) {
118255
+ return;
118256
+ }
118257
+ const eventData = persistedEvent.eventData ?? {};
118258
+ if (typeof eventData.token !== "string") {
118259
+ return;
118260
+ }
118261
+ const hook = {
118262
+ runId,
118263
+ hookId,
118264
+ token: eventData.token,
118265
+ metadata: eventData.metadata,
118266
+ ownerId: "local-owner",
118267
+ projectId: "local-project",
118268
+ environment: "local",
118269
+ createdAt: persistedEvent.createdAt,
118270
+ specVersion: persistedEvent.specVersion,
118271
+ isWebhook: eventData.isWebhook ?? false,
118272
+ isSystem: eventData.isSystem ?? false
118273
+ };
118274
+ await writeExclusive(taggedPath(basedir, "hooks", hookId, tag), JSON.stringify(hook, jsonReplacer, 2));
118275
+ }
118276
+ async function pinCanonicalEventIdForLegacyClaim(basedir, token, runId, hookId, candidateEventId) {
118277
+ const markerPath = hookRecoveryMarkerPath(basedir, token, runId, hookId);
118278
+ const markerContent = JSON.stringify({ eventId: candidateEventId });
118279
+ const won = await writeExclusive(markerPath, markerContent);
118280
+ if (won) {
118281
+ return candidateEventId;
118282
+ }
118283
+ const existing = await readHookRecoveryMarker(markerPath);
118284
+ return (existing == null ? void 0 : existing.eventId) ?? null;
118285
+ }
118286
+ function withInProcessLock(locks, key, fn2) {
118287
+ const prev = locks.get(key);
118050
118288
  const taskBox = {};
118051
118289
  const task = (async () => {
118052
118290
  if (prev) {
@@ -118055,13 +118293,13 @@ function withStepLock(key, fn2) {
118055
118293
  try {
118056
118294
  return await fn2();
118057
118295
  } finally {
118058
- if (stepLocks.get(key) === taskBox.task) {
118059
- stepLocks.delete(key);
118296
+ if (locks.get(key) === taskBox.task) {
118297
+ locks.delete(key);
118060
118298
  }
118061
118299
  }
118062
118300
  })();
118063
118301
  taskBox.task = task;
118064
- stepLocks.set(key, task);
118302
+ locks.set(key, task);
118065
118303
  return task;
118066
118304
  }
118067
118305
  async function deleteAllWaitsForRun(basedir, runId) {
@@ -118088,6 +118326,8 @@ async function writeRunUnderLifecycleLock(basedir, runId, tag, proposed) {
118088
118326
  });
118089
118327
  }
118090
118328
  function createEventsStorage(basedir, tag) {
118329
+ const stepLocks = /* @__PURE__ */ new Map();
118330
+ const hookLocks = /* @__PURE__ */ new Map();
118091
118331
  return {
118092
118332
  async create(runId, data, params) {
118093
118333
  if (runId != null && runId !== "") {
@@ -118099,11 +118339,15 @@ function createEventsStorage(basedir, tag) {
118099
118339
  const isStepEvent2 = data.eventType === "step_created" || data.eventType === "step_started" || data.eventType === "step_completed" || data.eventType === "step_failed" || data.eventType === "step_retrying";
118100
118340
  if (isStepEvent2 && runId && data.correlationId) {
118101
118341
  const lockKey = tag ? `${runId}-${data.correlationId}.${tag}` : `${runId}-${data.correlationId}`;
118102
- return withStepLock(lockKey, () => createImpl());
118342
+ return withInProcessLock(stepLocks, lockKey, () => createImpl());
118343
+ }
118344
+ if (data.eventType === "hook_created" && runId && data.correlationId) {
118345
+ const lockKey = tag ? `${runId}-${data.correlationId}.hook.${tag}` : `${runId}-${data.correlationId}.hook`;
118346
+ return withInProcessLock(hookLocks, lockKey, () => createImpl());
118103
118347
  }
118104
118348
  return createImpl();
118105
118349
  async function createImpl() {
118106
- const eventId = `evnt_${monotonicUlid$1()}`;
118350
+ let eventId = `evnt_${monotonicUlid$1()}`;
118107
118351
  const now2 = /* @__PURE__ */ new Date();
118108
118352
  let effectiveRunId;
118109
118353
  if (data.eventType === "run_created" && (!runId || runId === "")) {
@@ -118129,6 +118373,9 @@ function createEventsStorage(basedir, tag) {
118129
118373
  if (data.eventType === "run_started" && !currentRun && "eventData" in data && data.eventData) {
118130
118374
  const runInputData = data.eventData;
118131
118375
  if (runInputData.deploymentId && runInputData.workflowName && runInputData.input !== void 0) {
118376
+ validateAttributeChanges(Object.entries(runInputData.attributes ?? {}).map(([key, value]) => ({ key, value })), {
118377
+ allowReservedAttributes: runInputData.allowReservedAttributes === true
118378
+ });
118132
118379
  const createdRun = {
118133
118380
  runId: effectiveRunId,
118134
118381
  deploymentId: runInputData.deploymentId,
@@ -118141,7 +118388,7 @@ function createEventsStorage(basedir, tag) {
118141
118388
  error: void 0,
118142
118389
  startedAt: void 0,
118143
118390
  completedAt: void 0,
118144
- attributes: {},
118391
+ attributes: runInputData.attributes ?? {},
118145
118392
  createdAt: now2,
118146
118393
  updatedAt: now2
118147
118394
  };
@@ -118159,7 +118406,9 @@ function createEventsStorage(basedir, tag) {
118159
118406
  deploymentId: runInputData.deploymentId,
118160
118407
  workflowName: runInputData.workflowName,
118161
118408
  input: runInputData.input,
118162
- executionContext: runInputData.executionContext
118409
+ executionContext: runInputData.executionContext,
118410
+ attributes: runInputData.attributes,
118411
+ allowReservedAttributes: runInputData.allowReservedAttributes
118163
118412
  }
118164
118413
  };
118165
118414
  const createdCompositeKey = `${effectiveRunId}-${runCreatedEventId}`;
@@ -118174,6 +118423,9 @@ function createEventsStorage(basedir, tag) {
118174
118423
  if (data.eventType === "run_failed" && !currentRun) {
118175
118424
  throw new WorkflowRunNotFoundError(effectiveRunId);
118176
118425
  }
118426
+ if (data.eventType === "attr_set" && !currentRun) {
118427
+ throw new WorkflowRunNotFoundError(effectiveRunId);
118428
+ }
118177
118429
  if (currentRun) {
118178
118430
  if (requiresNewerWorld(currentRun.specVersion)) {
118179
118431
  throw new RunNotSupportedError(currentRun.specVersion, SPEC_VERSION_CURRENT);
@@ -118213,6 +118465,9 @@ function createEventsStorage(basedir, tag) {
118213
118465
  if (data.eventType === "step_created" || data.eventType === "hook_created" || data.eventType === "wait_created") {
118214
118466
  throw new EntityConflictError(`Cannot create new entities on run in terminal state "${currentRun.status}"`);
118215
118467
  }
118468
+ if (data.eventType === "attr_set") {
118469
+ throw new EntityConflictError(`Cannot set attributes on run in terminal state "${currentRun.status}"`);
118470
+ }
118216
118471
  }
118217
118472
  let validatedStep = null;
118218
118473
  const stepEvents = [
@@ -118243,7 +118498,7 @@ function createEventsStorage(basedir, tag) {
118243
118498
  throw new HookNotFoundError(data.correlationId);
118244
118499
  }
118245
118500
  }
118246
- const event = {
118501
+ let event = {
118247
118502
  ...data,
118248
118503
  runId: effectiveRunId,
118249
118504
  eventId,
@@ -118257,8 +118512,15 @@ function createEventsStorage(basedir, tag) {
118257
118512
  let step;
118258
118513
  let hook;
118259
118514
  let wait;
118515
+ let hookEntityWriteOptions;
118260
118516
  if (data.eventType === "run_created" && "eventData" in data) {
118261
118517
  const runData = data.eventData;
118518
+ validateAttributeChanges(Object.entries(runData.attributes ?? {}).map(([key, value]) => ({
118519
+ key,
118520
+ value
118521
+ })), {
118522
+ allowReservedAttributes: runData.allowReservedAttributes === true
118523
+ });
118262
118524
  run2 = {
118263
118525
  runId: effectiveRunId,
118264
118526
  deploymentId: runData.deploymentId,
@@ -118272,7 +118534,7 @@ function createEventsStorage(basedir, tag) {
118272
118534
  error: void 0,
118273
118535
  startedAt: void 0,
118274
118536
  completedAt: void 0,
118275
- attributes: {},
118537
+ attributes: runData.attributes ?? {},
118276
118538
  createdAt: now2,
118277
118539
  updatedAt: now2
118278
118540
  };
@@ -118379,6 +118641,32 @@ function createEventsStorage(basedir, tag) {
118379
118641
  deleteAllWaitsForRun(basedir, effectiveRunId)
118380
118642
  ]);
118381
118643
  }
118644
+ } else if (data.eventType === "attr_set" && currentRun) {
118645
+ run2 = await withRunFileLock(effectiveRunId, async () => {
118646
+ const fresh = await readJSON(taggedPath(basedir, "runs", effectiveRunId, tag), WorkflowRunSchema);
118647
+ if (!fresh) {
118648
+ throw new WorkflowRunNotFoundError(effectiveRunId);
118649
+ }
118650
+ validateAttributeChanges(data.eventData.changes, {
118651
+ existingKeys: Object.keys(fresh.attributes),
118652
+ allowReservedAttributes: data.eventData.allowReservedAttributes === true
118653
+ });
118654
+ if (data.correlationId && data.eventData.writer.type === "workflow") {
118655
+ const attrLockName = tag ? `${effectiveRunId}-${data.correlationId}.created.${tag}` : `${effectiveRunId}-${data.correlationId}.created`;
118656
+ const attrLockPath = resolveWithinBase(basedir, ".locks", "attributes", attrLockName);
118657
+ const attrClaimed = await writeExclusive(attrLockPath, "");
118658
+ if (!attrClaimed) {
118659
+ throw new EntityConflictError(`Attribute event "${data.correlationId}" already exists`);
118660
+ }
118661
+ }
118662
+ const next2 = {
118663
+ ...fresh,
118664
+ attributes: applyAttributeChanges(fresh.attributes, data.eventData.changes),
118665
+ updatedAt: now2
118666
+ };
118667
+ await writeJSON(taggedPath(basedir, "runs", effectiveRunId, tag), next2, { overwrite: true });
118668
+ return next2;
118669
+ });
118382
118670
  } else if (
118383
118671
  // Step lifecycle events
118384
118672
  data.eventType === "step_created" && "eventData" in data
@@ -118493,32 +118781,62 @@ function createEventsStorage(basedir, tag) {
118493
118781
  const tokenClaimed = await writeExclusive(constraintPath, JSON.stringify({
118494
118782
  token: hookData.token,
118495
118783
  hookId: data.correlationId,
118496
- runId: effectiveRunId
118784
+ runId: effectiveRunId,
118785
+ eventId
118497
118786
  }));
118787
+ let writeHookEntityWithOverwrite = false;
118498
118788
  if (!tokenClaimed) {
118499
118789
  const existingClaim = await readHookTokenClaim(constraintPath);
118500
- const conflictEvent = {
118501
- eventType: "hook_conflict",
118502
- correlationId: data.correlationId,
118503
- eventData: {
118504
- token: hookData.token,
118505
- ...existingClaim ? { conflictingRunId: existingClaim.runId } : {}
118506
- },
118507
- runId: effectiveRunId,
118508
- eventId,
118509
- createdAt: now2,
118510
- specVersion: effectiveSpecVersion
118511
- };
118512
- const compositeKey2 = `${effectiveRunId}-${eventId}`;
118513
- await writeJSON(taggedPath(basedir, "events", compositeKey2, tag), conflictEvent);
118514
- const resolveData2 = (params == null ? void 0 : params.resolveData) ?? DEFAULT_RESOLVE_DATA_OPTION$1;
118515
- const filteredEvent2 = stripEventDataRefs(conflictEvent, resolveData2);
118516
- return {
118517
- event: filteredEvent2,
118518
- run: run2,
118519
- step,
118520
- hook: void 0
118521
- };
118790
+ if ((existingClaim == null ? void 0 : existingClaim.runId) === effectiveRunId && existingClaim.hookId === data.correlationId) {
118791
+ let canonicalEventId;
118792
+ if (existingClaim.eventId) {
118793
+ canonicalEventId = existingClaim.eventId;
118794
+ } else {
118795
+ const alreadyPublishedEventId = await findExistingHookCreatedEventId(basedir, effectiveRunId, data.correlationId);
118796
+ if (alreadyPublishedEventId !== null) {
118797
+ await repairHookEntityFromPersistedEvent(basedir, effectiveRunId, data.correlationId, alreadyPublishedEventId, tag);
118798
+ throw new EntityConflictError(`Hook "${data.correlationId}" already created`);
118799
+ }
118800
+ const pinned = await pinCanonicalEventIdForLegacyClaim(basedir, hookData.token, effectiveRunId, data.correlationId, eventId);
118801
+ if (pinned === null) {
118802
+ throw new EntityConflictError(`Hook "${data.correlationId}" already created`);
118803
+ }
118804
+ canonicalEventId = pinned;
118805
+ }
118806
+ eventId = canonicalEventId;
118807
+ const canonicalCreatedAt = ulidToDate(eventId.replace(/^evnt_/, "")) ?? now2;
118808
+ event = {
118809
+ ...data,
118810
+ runId: effectiveRunId,
118811
+ eventId,
118812
+ createdAt: canonicalCreatedAt,
118813
+ specVersion: effectiveSpecVersion
118814
+ };
118815
+ writeHookEntityWithOverwrite = true;
118816
+ } else {
118817
+ const conflictEvent = {
118818
+ eventType: "hook_conflict",
118819
+ correlationId: data.correlationId,
118820
+ eventData: {
118821
+ token: hookData.token,
118822
+ ...existingClaim ? { conflictingRunId: existingClaim.runId } : {}
118823
+ },
118824
+ runId: effectiveRunId,
118825
+ eventId,
118826
+ createdAt: now2,
118827
+ specVersion: effectiveSpecVersion
118828
+ };
118829
+ const compositeKey2 = `${effectiveRunId}-${eventId}`;
118830
+ await writeJSON(taggedPath(basedir, "events", compositeKey2, tag), conflictEvent);
118831
+ const resolveData2 = (params == null ? void 0 : params.resolveData) ?? DEFAULT_RESOLVE_DATA_OPTION$1;
118832
+ const filteredEvent2 = stripEventDataRefs(conflictEvent, resolveData2);
118833
+ return {
118834
+ event: filteredEvent2,
118835
+ run: run2,
118836
+ step,
118837
+ hook: void 0
118838
+ };
118839
+ }
118522
118840
  }
118523
118841
  hook = {
118524
118842
  runId: effectiveRunId,
@@ -118528,13 +118846,16 @@ function createEventsStorage(basedir, tag) {
118528
118846
  ownerId: "local-owner",
118529
118847
  projectId: "local-project",
118530
118848
  environment: "local",
118531
- createdAt: now2,
118849
+ // Use the (possibly canonical) event's createdAt so two
118850
+ // workers writing the same hook entity produce byte-
118851
+ // identical content during convergence.
118852
+ createdAt: event.createdAt,
118532
118853
  // Propagate specVersion from the event to the hook entity
118533
118854
  specVersion: effectiveSpecVersion,
118534
118855
  isWebhook: hookData.isWebhook ?? false,
118535
118856
  isSystem: hookData.isSystem ?? false
118536
118857
  };
118537
- await writeJSON(taggedPath(basedir, "hooks", data.correlationId, tag), hook);
118858
+ hookEntityWriteOptions = writeHookEntityWithOverwrite ? { overwrite: true } : void 0;
118538
118859
  } else if (data.eventType === "hook_disposed") {
118539
118860
  const hookLockName = tag ? `${data.correlationId}.disposed.${tag}` : `${data.correlationId}.disposed`;
118540
118861
  const lockPath = resolveWithinBase(basedir, ".locks", "hooks", hookLockName);
@@ -118547,6 +118868,7 @@ function createEventsStorage(basedir, tag) {
118547
118868
  if (existingHook) {
118548
118869
  const disposedConstraintPath = path$3.join(basedir, "hooks", "tokens", `${hashToken(existingHook.token)}.json`);
118549
118870
  await deleteJSON(disposedConstraintPath);
118871
+ await deleteJSON(hookRecoveryMarkerPath(basedir, existingHook.token, existingHook.runId, existingHook.hookId));
118550
118872
  }
118551
118873
  await deleteJSON(hookPath);
118552
118874
  } else if (data.eventType === "wait_created" && "eventData" in data) {
@@ -118592,7 +118914,16 @@ function createEventsStorage(basedir, tag) {
118592
118914
  await writeJSON(taggedPath(basedir, "waits", waitCompositeKey, tag), wait, { overwrite: true });
118593
118915
  }
118594
118916
  const compositeKey = `${effectiveRunId}-${eventId}`;
118595
- await writeJSON(taggedPath(basedir, "events", compositeKey, tag), event);
118917
+ const eventPublished = await writeExclusive(taggedPath(basedir, "events", compositeKey, tag), JSON.stringify(event, jsonReplacer, 2));
118918
+ if (!eventPublished) {
118919
+ if (data.eventType === "hook_created" && data.correlationId) {
118920
+ await repairHookEntityFromPersistedEvent(basedir, effectiveRunId, data.correlationId, eventId, tag);
118921
+ }
118922
+ throw new EntityConflictError(`Event "${eventId}" already exists for run "${effectiveRunId}"`);
118923
+ }
118924
+ if (hook && data.eventType === "hook_created") {
118925
+ await writeJSON(taggedPath(basedir, "hooks", hook.hookId, tag), hook, hookEntityWriteOptions);
118926
+ }
118596
118927
  const resolveData = (params == null ? void 0 : params.resolveData) ?? DEFAULT_RESOLVE_DATA_OPTION$1;
118597
118928
  const filteredEvent = stripEventDataRefs(event, resolveData);
118598
118929
  let events2;
@@ -119154,11 +119485,12 @@ function createLocalWorld(args) {
119154
119485
  const basedir = mergedConfig.dataDir;
119155
119486
  const hooksDir = path$3.join(basedir, "hooks");
119156
119487
  const taggedHookFiles = await listTaggedFiles(hooksDir, tag);
119157
- const { HookSchema: HookSchema2 } = await import("./index-GhULR6rc.js");
119488
+ const { HookSchema: HookSchema2 } = await import("./index-8Fb8OEQ2.js");
119158
119489
  await Promise.all(taggedHookFiles.map(async (hookFile) => {
119159
119490
  const hook = await readJSON(path$3.join(hooksDir, hookFile), HookSchema2);
119160
119491
  if (hook == null ? void 0 : hook.token) {
119161
119492
  await deleteJSON(path$3.join(hooksDir, "tokens", `${hashToken(hook.token)}.json`));
119493
+ await deleteJSON(hookRecoveryMarkerPath(basedir, hook.token, hook.runId, hook.hookId));
119162
119494
  }
119163
119495
  }));
119164
119496
  const entityDirs = [
@@ -119306,8 +119638,8 @@ function requireGetVercelOidcToken() {
119306
119638
  }
119307
119639
  try {
119308
119640
  const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([
119309
- await import("./token-util-FXtXbDcd.js").then((n) => n.t),
119310
- await import("./token-CpI-8AoV.js").then((n) => n.t)
119641
+ await import("./token-util-C02bLOPS.js").then((n) => n.t),
119642
+ await import("./token-CDoC3gHn.js").then((n) => n.t)
119311
119643
  ]);
119312
119644
  if (!token || isExpired(getTokenPayload(token), options == null ? void 0 : options.expirationBufferMs)) {
119313
119645
  await refreshToken(options);
@@ -120700,7 +121032,7 @@ function expand_(str, max2, isTop) {
120700
121032
  const x2 = numeric(n[0]);
120701
121033
  const y2 = numeric(n[1]);
120702
121034
  const width = Math.max(n[0].length, n[1].length);
120703
- let incr = n.length === 3 && n[2] !== void 0 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
121035
+ let incr = n.length === 3 && n[2] !== void 0 ? Math.abs(numeric(n[2])) : 1;
120704
121036
  let test = lte;
120705
121037
  const reverse = y2 < x2;
120706
121038
  if (reverse) {
@@ -120709,7 +121041,7 @@ function expand_(str, max2, isTop) {
120709
121041
  }
120710
121042
  const pad = n.some(isPadded);
120711
121043
  N2 = [];
120712
- for (let i = x2; test(i, y2) && N2.length < max2; i += incr) {
121044
+ for (let i = x2; test(i, y2); i += incr) {
120713
121045
  let c;
120714
121046
  if (isAlphaSequence) {
120715
121047
  c = String.fromCharCode(i);
@@ -120867,9 +121199,9 @@ const parseClass = (glob, position2) => {
120867
121199
  };
120868
121200
  const unescape$1 = (s2, { windowsPathsNoEscape = false, magicalBraces = true } = {}) => {
120869
121201
  if (magicalBraces) {
120870
- return windowsPathsNoEscape ? s2.replace(/\[([^/\\])\]/g, "$1") : s2.replace(/((?!\\).|^)\[([^/\\])\]/g, "$1$2").replace(/\\([^/])/g, "$1");
121202
+ return windowsPathsNoEscape ? s2.replace(/\[([^\/\\])\]/g, "$1") : s2.replace(/((?!\\).|^)\[([^\/\\])\]/g, "$1$2").replace(/\\([^\/])/g, "$1");
120871
121203
  }
120872
- return windowsPathsNoEscape ? s2.replace(/\[([^/\\{}])\]/g, "$1") : s2.replace(/((?!\\).|^)\[([^/\\{}])\]/g, "$1$2").replace(/\\([^/{}])/g, "$1");
121204
+ return windowsPathsNoEscape ? s2.replace(/\[([^\/\\{}])\]/g, "$1") : s2.replace(/((?!\\).|^)\[([^\/\\{}])\]/g, "$1$2").replace(/\\([^\/{}])/g, "$1");
120873
121205
  };
120874
121206
  var _a;
120875
121207
  const types = /* @__PURE__ */ new Set(["!", "?", "+", "*", "@"]);
@@ -120990,7 +121322,13 @@ class AST {
120990
121322
  }
120991
121323
  // reconstructs the pattern
120992
121324
  toString() {
120993
- return __privateGet(this, _toString) !== void 0 ? __privateGet(this, _toString) : !this.type ? __privateSet(this, _toString, __privateGet(this, _parts).map((p2) => String(p2)).join("")) : __privateSet(this, _toString, this.type + "(" + __privateGet(this, _parts).map((p2) => String(p2)).join("|") + ")");
121325
+ if (__privateGet(this, _toString) !== void 0)
121326
+ return __privateGet(this, _toString);
121327
+ if (!this.type) {
121328
+ return __privateSet(this, _toString, __privateGet(this, _parts).map((p2) => String(p2)).join(""));
121329
+ } else {
121330
+ return __privateSet(this, _toString, this.type + "(" + __privateGet(this, _parts).map((p2) => String(p2)).join("|") + ")");
121331
+ }
120994
121332
  }
120995
121333
  push(...parts) {
120996
121334
  for (const p2 of parts) {
@@ -121552,7 +121890,7 @@ const minimatch = (p2, pattern2, options = {}) => {
121552
121890
  }
121553
121891
  return new Minimatch(pattern2, options).match(p2);
121554
121892
  };
121555
- const starDotExtRE = /^\*+([^+@!?*[(]*)$/;
121893
+ const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/;
121556
121894
  const starDotExtTest = (ext2) => (f2) => !f2.startsWith(".") && f2.endsWith(ext2);
121557
121895
  const starDotExtTestDot = (ext2) => (f2) => f2.endsWith(ext2);
121558
121896
  const starDotExtTestNocase = (ext2) => {
@@ -121571,7 +121909,7 @@ const dotStarTest = (f2) => f2 !== "." && f2 !== ".." && f2.startsWith(".");
121571
121909
  const starRE = /^\*+$/;
121572
121910
  const starTest = (f2) => f2.length !== 0 && !f2.startsWith(".");
121573
121911
  const starTestDot = (f2) => f2.length !== 0 && f2 !== "." && f2 !== "..";
121574
- const qmarksRE = /^\?+([^+@!?*[(]*)?$/;
121912
+ const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/;
121575
121913
  const qmarksTestNocase = ([$0, ext2 = ""]) => {
121576
121914
  const noext = qmarksTestNoExt([$0]);
121577
121915
  if (!ext2)
@@ -121791,10 +122129,10 @@ class Minimatch {
121791
122129
  // of patterns that we have to process.
121792
122130
  preprocess(globParts) {
121793
122131
  if (this.options.noglobstar) {
121794
- for (const partset of globParts) {
121795
- for (let j2 = 0; j2 < partset.length; j2++) {
121796
- if (partset[j2] === "**") {
121797
- partset[j2] = "*";
122132
+ for (let i = 0; i < globParts.length; i++) {
122133
+ for (let j2 = 0; j2 < globParts[i].length; j2++) {
122134
+ if (globParts[i][j2] === "**") {
122135
+ globParts[i][j2] = "*";
121798
122136
  }
121799
122137
  }
121800
122138
  }
@@ -121872,7 +122210,7 @@ class Minimatch {
121872
122210
  let dd = 0;
121873
122211
  while (-1 !== (dd = parts.indexOf("..", dd + 1))) {
121874
122212
  const p2 = parts[dd - 1];
121875
- if (p2 && p2 !== "." && p2 !== ".." && p2 !== "**" && !(this.isWindows && /^[a-z]:$/i.test(p2))) {
122213
+ if (p2 && p2 !== "." && p2 !== ".." && p2 !== "**") {
121876
122214
  didSomething = true;
121877
122215
  parts.splice(dd - 1, 2);
121878
122216
  dd -= 2;
@@ -122153,7 +122491,7 @@ class Minimatch {
122153
122491
  re2 = "^(?!" + re2 + ").+$";
122154
122492
  try {
122155
122493
  this.regexp = new RegExp(re2, [...flags].join(""));
122156
- } catch {
122494
+ } catch (ex) {
122157
122495
  this.regexp = false;
122158
122496
  }
122159
122497
  return this.regexp;
@@ -122161,7 +122499,7 @@ class Minimatch {
122161
122499
  slashSplit(p2) {
122162
122500
  if (this.preserveMultipleSlashes) {
122163
122501
  return p2.split("/");
122164
- } else if (this.isWindows && /^\/\/[^/]+/.test(p2)) {
122502
+ } else if (this.isWindows && /^\/\/[^\/]+/.test(p2)) {
122165
122503
  return ["", ...p2.split(/\/+/)];
122166
122504
  } else {
122167
122505
  return p2.split(/\/+/);
@@ -122192,7 +122530,8 @@ class Minimatch {
122192
122530
  filename = ff[i];
122193
122531
  }
122194
122532
  }
122195
- for (const pattern2 of set2) {
122533
+ for (let i = 0; i < set2.length; i++) {
122534
+ const pattern2 = set2[i];
122196
122535
  let file2 = ff;
122197
122536
  if (options.matchBase && pattern2.length === 1) {
122198
122537
  file2 = [filename];
@@ -124497,7 +124836,7 @@ var QueueClient = class {
124497
124836
  setApi(this, new ApiClient({ ...options, region }));
124498
124837
  }
124499
124838
  };
124500
- const version = "5.0.0-beta.13";
124839
+ const version = "5.0.0-beta.14";
124501
124840
  const HTTP_DEBUG_ENABLED = typeof process !== "undefined" && typeof process.env.DEBUG === "string" && (process.env.DEBUG.includes("workflow:") || process.env.DEBUG === "*");
124502
124841
  function httpLog(method, endpoint, response2, ms2) {
124503
124842
  if (HTTP_DEBUG_ENABLED) {
@@ -125884,7 +126223,11 @@ function createVercelWorld(config2) {
125884
126223
  var _a3, _b2;
125885
126224
  const projectId = ((_a3 = config2 == null ? void 0 : config2.projectConfig) == null ? void 0 : _a3.projectId) || process.env.VERCEL_PROJECT_ID;
125886
126225
  return {
125887
- specVersion: SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT,
126226
+ // Spec v4: the workflow-server materializes native `attr_set` events
126227
+ // and accepts initial run attributes on creation. New runs are stamped
126228
+ // with this version; the server must be at least this version (it
126229
+ // rejects runs newer than its own SPEC_VERSION_CURRENT).
126230
+ specVersion: SPEC_VERSION_SUPPORTS_ATTRIBUTES,
125888
126231
  // On Vercel the platform fails the function invocation when the
125889
126232
  // process exits non-zero, and VQS redelivers the queue message via a
125890
126233
  // fresh invocation. The core runtime uses this to decide whether
@@ -128627,12 +128970,16 @@ const FORMAT_VERSION_TABLE = [
128627
128970
  // { format: SerializationFormat.CBOR, minVersion: '5.x.y' },
128628
128971
  // { format: SerializationFormat.ENCRYPTED_V2, minVersion: '5.x.y' },
128629
128972
  ];
128973
+ const CAPABILITY_VERSION_TABLE = [{ capability: "framedByteStreams", minVersion: "5.0.0-beta.15" }];
128630
128974
  const BASELINE_FORMATS = /* @__PURE__ */ new Set([
128631
128975
  SerializationFormat.DEVALUE_V1
128632
128976
  ]);
128633
128977
  function getRunCapabilities(workflowCoreVersion) {
128634
128978
  if (!workflowCoreVersion || !semver.valid(workflowCoreVersion)) {
128635
- return { supportedFormats: BASELINE_FORMATS };
128979
+ return {
128980
+ supportedFormats: BASELINE_FORMATS,
128981
+ framedByteStreams: false
128982
+ };
128636
128983
  }
128637
128984
  const formats = new Set(BASELINE_FORMATS);
128638
128985
  for (const { format: format2, minVersion } of FORMAT_VERSION_TABLE) {
@@ -128640,7 +128987,16 @@ function getRunCapabilities(workflowCoreVersion) {
128640
128987
  formats.add(format2);
128641
128988
  }
128642
128989
  }
128643
- return { supportedFormats: formats };
128990
+ const result = {
128991
+ supportedFormats: formats,
128992
+ framedByteStreams: false
128993
+ };
128994
+ for (const { capability, minVersion } of CAPABILITY_VERSION_TABLE) {
128995
+ if (semver.gte(workflowCoreVersion, minVersion)) {
128996
+ result[capability] = true;
128997
+ }
128998
+ }
128999
+ return result;
128644
129000
  }
128645
129001
  async function getHookByTokenWithKey(token) {
128646
129002
  var _a3;
@@ -128688,13 +129044,13 @@ async function resumeHook$2(tokenOrHook, payload, encryptionKeyOverride) {
128688
129044
  ...WorkflowRunId(hook.runId)
128689
129045
  });
128690
129046
  const rawVersion = (_b2 = workflowRun.executionContext) == null ? void 0 : _b2.workflowCoreVersion;
128691
- const { supportedFormats } = getRunCapabilities(typeof rawVersion === "string" ? rawVersion : void 0);
128692
- if (!supportedFormats.has(SerializationFormat.ENCRYPTED)) {
129047
+ const capabilities = getRunCapabilities(typeof rawVersion === "string" ? rawVersion : void 0);
129048
+ if (!capabilities.supportedFormats.has(SerializationFormat.ENCRYPTED)) {
128693
129049
  encryptionKey = void 0;
128694
129050
  }
128695
129051
  const ops = [];
128696
129052
  const v1Compat = isLegacySpecVersion(hook.specVersion);
128697
- const dehydratedPayload = await dehydrateStepReturnValue(payload, hook.runId, encryptionKey, ops, globalThis, v1Compat);
129053
+ const dehydratedPayload = await dehydrateStepReturnValue(payload, hook.runId, encryptionKey, ops, globalThis, v1Compat, capabilities.framedByteStreams);
128698
129054
  safeWaitUntil(Promise.all(ops), (err) => {
128699
129055
  if (err === void 0)
128700
129056
  return;
@@ -128784,6 +129140,28 @@ const resumeHook$3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.define
128784
129140
  resumeHook: resumeHook$2,
128785
129141
  resumeWebhook
128786
129142
  }, Symbol.toStringTag, { value: "Module" }));
129143
+ function normalizeAttributeChanges(attrs, options = {}) {
129144
+ if (attrs === null || typeof attrs !== "object" || Array.isArray(attrs)) {
129145
+ throw new FatalError(`experimental_setAttributes requires a plain object, got ${attrs === null ? "null" : Array.isArray(attrs) ? "array" : typeof attrs}`);
129146
+ }
129147
+ const changes = Object.entries(attrs).map(([key, value]) => ({
129148
+ key,
129149
+ value: value === void 0 ? null : value
129150
+ }));
129151
+ if (changes.length === 0)
129152
+ return changes;
129153
+ const allowReservedAttributes = options.allowReservedAttributes === true;
129154
+ try {
129155
+ validateAttributeChanges(changes, { allowReservedAttributes });
129156
+ } catch (err) {
129157
+ if (err instanceof AttributeValidationError) {
129158
+ throw new FatalError(err.message);
129159
+ }
129160
+ throw err;
129161
+ }
129162
+ return changes;
129163
+ }
129164
+ const CROSS_DEPLOYMENT_CAPABILITY_PROBE_TIMEOUT_MS = 2e3;
128787
129165
  const ulid = monotonicFactory();
128788
129166
  async function start$1(workflow, argsOrOptions, options) {
128789
129167
  "use step";
@@ -128793,7 +129171,7 @@ async function start$1(workflow, argsOrOptions, options) {
128793
129171
  throw new WorkflowRuntimeError(`'start' received an invalid workflow function. Ensure the Workflow SDK is configured correctly and the function includes a 'use workflow' directive.`, { slug: "start-invalid-workflow-function" });
128794
129172
  }
128795
129173
  return trace$2(`workflow.start ${workflowName}`, async (span) => {
128796
- var _a3;
129174
+ var _a3, _b2;
128797
129175
  span == null ? void 0 : span.setAttributes({
128798
129176
  ...WorkflowName(workflowName),
128799
129177
  ...WorkflowOperation("start")
@@ -128809,24 +129187,50 @@ async function start$1(workflow, argsOrOptions, options) {
128809
129187
  ...WorkflowArgumentsCount(args.length)
128810
129188
  });
128811
129189
  const world = (opts == null ? void 0 : opts.world) ?? await getWorldLazy();
128812
- let deploymentId = opts.deploymentId ?? await world.getDeploymentId();
129190
+ const currentDeploymentId = await world.getDeploymentId();
129191
+ let deploymentId = opts.deploymentId ?? currentDeploymentId;
128813
129192
  if (deploymentId === "latest") {
128814
129193
  if (!world.resolveLatestDeploymentId) {
128815
129194
  throw new WorkflowRuntimeError("deploymentId 'latest' requires a World that implements resolveLatestDeploymentId()");
128816
129195
  }
128817
129196
  deploymentId = await world.resolveLatestDeploymentId();
128818
129197
  }
129198
+ let framedByteStreams;
129199
+ if (deploymentId === currentDeploymentId) {
129200
+ framedByteStreams = true;
129201
+ } else if (typeof ((_a3 = world.streams) == null ? void 0 : _a3.get) !== "function") {
129202
+ framedByteStreams = false;
129203
+ } else {
129204
+ const probe = await healthCheck(world, "workflow", {
129205
+ deploymentId,
129206
+ timeout: CROSS_DEPLOYMENT_CAPABILITY_PROBE_TIMEOUT_MS
129207
+ }).catch(() => void 0);
129208
+ framedByteStreams = getRunCapabilities(probe == null ? void 0 : probe.workflowCoreVersion).framedByteStreams;
129209
+ }
128819
129210
  const ops = [];
128820
129211
  const runId = `wrun_${ulid()}`;
128821
129212
  const traceCarrier = await serializeTraceCarrier();
128822
129213
  const specVersion = opts.specVersion ?? world.specVersion ?? SPEC_VERSION_SUPPORTS_EVENT_SOURCING;
128823
129214
  const v1Compat = isLegacySpecVersion(specVersion);
128824
- const rawKey = await ((_a3 = world.getEncryptionKeyForRun) == null ? void 0 : _a3.call(world, runId, {
129215
+ let attributes;
129216
+ if (opts.attributes && Object.keys(opts.attributes).length > 0) {
129217
+ if (specVersion < SPEC_VERSION_SUPPORTS_ATTRIBUTES) {
129218
+ throw new WorkflowRuntimeError("Initial workflow attributes require a World that supports spec version 4 or later.");
129219
+ }
129220
+ for (const [key, value] of Object.entries(opts.attributes)) {
129221
+ if (typeof value !== "string") {
129222
+ throw new WorkflowRuntimeError(`Initial workflow attribute ${JSON.stringify(key)} must be a string value.`);
129223
+ }
129224
+ }
129225
+ const changes = normalizeAttributeChanges(opts.attributes);
129226
+ attributes = Object.fromEntries(changes.map(({ key, value }) => [key, value]));
129227
+ }
129228
+ const rawKey = await ((_b2 = world.getEncryptionKeyForRun) == null ? void 0 : _b2.call(world, runId, {
128825
129229
  ...opts,
128826
129230
  deploymentId
128827
129231
  }));
128828
129232
  const encryptionKey = rawKey ? await importKey(rawKey) : void 0;
128829
- const workflowArguments = await dehydrateWorkflowArguments(args, runId, encryptionKey, ops, globalThis, v1Compat);
129233
+ const workflowArguments = await dehydrateWorkflowArguments(args, runId, encryptionKey, ops, globalThis, v1Compat, framedByteStreams);
128830
129234
  const executionContext = {
128831
129235
  traceCarrier,
128832
129236
  workflowCoreVersion: version$1,
@@ -128840,7 +129244,8 @@ async function start$1(workflow, argsOrOptions, options) {
128840
129244
  deploymentId,
128841
129245
  workflowName,
128842
129246
  input: workflowArguments,
128843
- executionContext
129247
+ executionContext,
129248
+ ...attributes ? { attributes } : {}
128844
129249
  }
128845
129250
  }, { v1Compat }),
128846
129251
  world.queue(getWorkflowQueueName(workflowName), {
@@ -128852,7 +129257,8 @@ async function start$1(workflow, argsOrOptions, options) {
128852
129257
  deploymentId,
128853
129258
  workflowName,
128854
129259
  specVersion,
128855
- executionContext
129260
+ executionContext,
129261
+ ...attributes ? { attributes } : {}
128856
129262
  }
128857
129263
  } : {}
128858
129264
  }, {
@@ -152585,7 +152991,7 @@ const route4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
152585
152991
  __proto__: null,
152586
152992
  loader
152587
152993
  }, Symbol.toStringTag, { value: "Module" }));
152588
- const serverManifest = { "entry": { "module": "/assets/entry.client-DOJDY_4b.js", "imports": ["/assets/index-BXZSIDEp.js"], "css": [] }, "routes": { "root": { "id": "root", "parentId": void 0, "path": "", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/root-Dduz44vX.js", "imports": ["/assets/index-BXZSIDEp.js", "/assets/mermaid-3ZIDBTTL-C02sm-ZS.js"], "css": ["/assets/root-Bqr5evzw.css", "/assets/mermaid-3ZIDBTTL-DKxHcEOp.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/home": { "id": "routes/home", "parentId": "root", "path": void 0, "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": false, "module": "/assets/home-D9oyGYfj.js", "imports": ["/assets/index-BXZSIDEp.js", "/assets/workflow-graph-viewer-CU0UU458.js", "/assets/mermaid-3ZIDBTTL-C02sm-ZS.js", "/assets/index-B6-SzLmT.js"], "css": ["/assets/workflow-graph-viewer-DnlNuQQH.css", "/assets/mermaid-3ZIDBTTL-DKxHcEOp.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/run-detail": { "id": "routes/run-detail", "parentId": "root", "path": "run/:runId", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": false, "module": "/assets/run-detail-uOQTua8_.js", "imports": ["/assets/index-BXZSIDEp.js", "/assets/workflow-graph-viewer-CU0UU458.js", "/assets/mermaid-3ZIDBTTL-C02sm-ZS.js", "/assets/encryption-g14N5vQl.js", "/assets/index-B6-SzLmT.js"], "css": ["/assets/workflow-graph-viewer-DnlNuQQH.css", "/assets/mermaid-3ZIDBTTL-DKxHcEOp.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/api.rpc": { "id": "routes/api.rpc", "parentId": "root", "path": "api/rpc", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": false, "hasErrorBoundary": false, "module": "/assets/api.rpc-l0sNRNKZ.js", "imports": [], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/api.stream.$streamId": { "id": "routes/api.stream.$streamId", "parentId": "root", "path": "api/stream/:streamId", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": false, "hasErrorBoundary": false, "module": "/assets/api.stream._streamId-l0sNRNKZ.js", "imports": [], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 } }, "url": "/assets/manifest-6fc92124.js", "version": "6fc92124", "sri": void 0 };
152994
+ const serverManifest = { "entry": { "module": "/assets/entry.client-DOJDY_4b.js", "imports": ["/assets/index-BXZSIDEp.js"], "css": [] }, "routes": { "root": { "id": "root", "parentId": void 0, "path": "", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/root-BABNjrUh.js", "imports": ["/assets/index-BXZSIDEp.js", "/assets/mermaid-3ZIDBTTL-BMWEihLr.js"], "css": ["/assets/root-Bqr5evzw.css", "/assets/mermaid-3ZIDBTTL-CVTQRy2j.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/home": { "id": "routes/home", "parentId": "root", "path": void 0, "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": false, "module": "/assets/home-DmsdVk2U.js", "imports": ["/assets/index-BXZSIDEp.js", "/assets/workflow-graph-viewer-fgQ2XQ5R.js", "/assets/mermaid-3ZIDBTTL-BMWEihLr.js", "/assets/index-B6-SzLmT.js"], "css": ["/assets/workflow-graph-viewer-DnlNuQQH.css", "/assets/mermaid-3ZIDBTTL-CVTQRy2j.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/run-detail": { "id": "routes/run-detail", "parentId": "root", "path": "run/:runId", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": false, "module": "/assets/run-detail-9xQOGhVk.js", "imports": ["/assets/index-BXZSIDEp.js", "/assets/workflow-graph-viewer-fgQ2XQ5R.js", "/assets/mermaid-3ZIDBTTL-BMWEihLr.js", "/assets/encryption-g14N5vQl.js", "/assets/index-B6-SzLmT.js"], "css": ["/assets/workflow-graph-viewer-DnlNuQQH.css", "/assets/mermaid-3ZIDBTTL-CVTQRy2j.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/api.rpc": { "id": "routes/api.rpc", "parentId": "root", "path": "api/rpc", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": false, "hasErrorBoundary": false, "module": "/assets/api.rpc-l0sNRNKZ.js", "imports": [], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/api.stream.$streamId": { "id": "routes/api.stream.$streamId", "parentId": "root", "path": "api/stream/:streamId", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": false, "hasErrorBoundary": false, "module": "/assets/api.stream._streamId-l0sNRNKZ.js", "imports": [], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 } }, "url": "/assets/manifest-67209c1f.js", "version": "67209c1f", "sri": void 0 };
152589
152995
  const assetsBuildDirectory = "build/client";
152590
152996
  const basename = "/";
152591
152997
  const future = { "unstable_optimizeDeps": false, "unstable_subResourceIntegrity": false, "unstable_trailingSlashAwareDataRequests": false, "unstable_previewServerPrerendering": false, "v8_middleware": false, "v8_splitRouteModules": false, "v8_viteEnvironmentApi": false };
@@ -152654,59 +153060,62 @@ const serverBuild = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineP
152654
153060
  ssr
152655
153061
  }, Symbol.toStringTag, { value: "Module" }));
152656
153062
  export {
152657
- requireTokenError as $,
153063
+ jsxRuntimeExports as $,
152658
153064
  ATTRIBUTE_KEY_MAX_LENGTH as A,
152659
153065
  BaseEventSchema as B,
152660
- requiresNewerWorld as C,
153066
+ isLegacySpecVersion as C,
152661
153067
  DEFAULT_TIMESTAMP_THRESHOLD_FUTURE_MS as D,
152662
153068
  EVENT_DATA_REF_FIELDS as E,
152663
- resolveQueueNamespace as F,
152664
- stripEventDataRefs as G,
153069
+ parseQueueName as F,
153070
+ reenqueueActiveRuns as G,
152665
153071
  HookSchema as H,
152666
- ulidToDate as I,
152667
- validateAttributeChanges as J,
152668
- validateAttributeKey as K,
153072
+ requiresNewerWorld as I,
153073
+ resolveQueueNamespace as J,
153074
+ stripEventDataRefs as K,
152669
153075
  LegacySerializedDataSchemaV1 as L,
152670
153076
  MessageId as M,
152671
153077
  Nt as N,
152672
- validateAttributeValue as O,
153078
+ ulidToDate as O,
152673
153079
  PaginatedResponseSchema as P,
152674
153080
  QueuePayloadSchema as Q,
152675
153081
  RESERVED_ATTRIBUTE_KEY_PREFIX as R,
152676
153082
  SPEC_VERSION_CURRENT as S,
152677
- validateUlidTimestamp as T,
152678
- R as U,
153083
+ validateAttributeChanges as T,
153084
+ validateAttributeKey as U,
152679
153085
  ValidQueueName as V,
152680
153086
  WaitSchema as W,
152681
- Ks as X,
152682
- jsxRuntimeExports as Y,
152683
- Qe as Z,
152684
- requireTokenUtil as _,
153087
+ validateAttributeValue as X,
153088
+ validateUlidTimestamp as Y,
153089
+ R as Z,
153090
+ Ks as _,
152685
153091
  ATTRIBUTE_MAX_PER_RUN as a,
152686
- serverBuild as a0,
153092
+ Qe as a0,
153093
+ requireTokenUtil as a1,
153094
+ requireTokenError as a2,
153095
+ serverBuild as a3,
152687
153096
  ATTRIBUTE_VALUE_MAX_BYTES as b,
152688
- AttributeValidationError as c,
152689
- DEFAULT_TIMESTAMP_THRESHOLD_PAST_MS as d,
152690
- EventSchema as e,
152691
- EventTypeSchema as f,
152692
- HealthCheckPayloadSchema as g,
152693
- QueuePrefix as h,
152694
- RunInputSchema as i,
152695
- SPEC_VERSION_LEGACY as j,
152696
- SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT as k,
152697
- SPEC_VERSION_SUPPORTS_EVENT_SOURCING as l,
152698
- SerializedDataSchema as m,
152699
- StepInvokePayloadSchema as n,
152700
- StepSchema as o,
152701
- StepStatusSchema as p,
152702
- WaitStatusSchema as q,
152703
- WorkflowInvokePayloadSchema as r,
152704
- WorkflowRunBaseSchema as s,
152705
- WorkflowRunSchema as t,
152706
- WorkflowRunStatusSchema as u,
152707
- applyAttributeChanges as v,
152708
- getQueueTopicPrefix as w,
152709
- isLegacySpecVersion as x,
152710
- parseQueueName as y,
152711
- reenqueueActiveRuns as z
153097
+ AttributeChangeSchema as c,
153098
+ AttributeChangesSchema as d,
153099
+ AttributeValidationError as e,
153100
+ DEFAULT_TIMESTAMP_THRESHOLD_PAST_MS as f,
153101
+ EventSchema as g,
153102
+ EventTypeSchema as h,
153103
+ HealthCheckPayloadSchema as i,
153104
+ QueuePrefix as j,
153105
+ RunInputSchema as k,
153106
+ SPEC_VERSION_LEGACY as l,
153107
+ SPEC_VERSION_SUPPORTS_ATTRIBUTES as m,
153108
+ SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT as n,
153109
+ SPEC_VERSION_SUPPORTS_EVENT_SOURCING as o,
153110
+ SerializedDataSchema as p,
153111
+ StepInvokePayloadSchema as q,
153112
+ StepSchema as r,
153113
+ StepStatusSchema as s,
153114
+ WaitStatusSchema as t,
153115
+ WorkflowInvokePayloadSchema as u,
153116
+ WorkflowRunBaseSchema as v,
153117
+ WorkflowRunSchema as w,
153118
+ WorkflowRunStatusSchema as x,
153119
+ applyAttributeChanges as y,
153120
+ getQueueTopicPrefix as z
152712
153121
  };