@workflow/web 5.0.0-beta.7 → 5.0.0-beta.9

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 (21) hide show
  1. package/build/client/assets/{highlighted-body-B3W2YXNL-Cq4feDhL.js → highlighted-body-B3W2YXNL-ijzNrESJ.js} +1 -1
  2. package/build/client/assets/{home-B-DWbULo.js → home-MRChHR_P.js} +8 -16
  3. package/build/client/assets/{manifest-21016363.js → manifest-b100514d.js} +1 -1
  4. package/build/client/assets/{mermaid-3ZIDBTTL-PK-k2mDG.js → mermaid-3ZIDBTTL-3cOa-aZ5.js} +305 -123
  5. package/build/client/assets/{root-DDT0W3fG.js → root-3uuTxUQN.js} +1 -1
  6. package/build/client/assets/root-BYtlAgHl.css +1 -0
  7. package/build/client/assets/{run-detail-COyTZwjr.js → run-detail-8qGjUNCj.js} +969 -886
  8. package/build/client/assets/server-build-ByHD2s6b.css +1 -0
  9. package/build/client/assets/{workflow-graph-viewer-CVUKAMV1.js → workflow-graph-viewer-DaYMiBT9.js} +50 -41
  10. package/build/server/assets/{app-CASBD2Jz.js → app-BEgkHdDF.js} +1 -1
  11. package/build/server/assets/{highlighted-body-B3W2YXNL-DtYGrm0G.js → highlighted-body-B3W2YXNL-B4fAdNsB.js} +2 -2
  12. package/build/server/assets/index-DltGJ3CV.js +89 -0
  13. package/build/server/assets/{mermaid-3ZIDBTTL-D37Y2lwn.js → mermaid-3ZIDBTTL-C6M7jb0V.js} +2 -2
  14. package/build/server/assets/{server-build-BZS28Q46.js → server-build-Ctg6FoI8.js} +2017 -1544
  15. package/build/server/assets/{token-98GkKm4t.js → token-BNjLoJXz.js} +2 -2
  16. package/build/server/assets/{token-util-CHxt50WW.js → token-util-DwTdh-aG.js} +2 -2
  17. package/build/server/index.js +1 -1
  18. package/package.json +7 -7
  19. package/build/client/assets/root-B527kgKt.css +0 -1
  20. package/build/client/assets/server-build-BUmla00D.css +0 -1
  21. package/build/server/assets/index-B_Gtun0B.js +0 -80
@@ -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, _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, 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-CASBD2Jz.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-BEgkHdDF.js";
18
18
  import require$$0$3, { PassThrough } from "node:stream";
19
19
  import require$$0 from "util";
20
20
  import require$$1 from "crypto";
@@ -48563,6 +48563,91 @@ const z$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty(
48563
48563
  xid,
48564
48564
  xor: xor$1
48565
48565
  }, Symbol.toStringTag, { value: "Module" }));
48566
+ const RESERVED_ATTRIBUTE_KEY_PREFIX = "$";
48567
+ const ATTRIBUTE_KEY_MAX_LENGTH = 256;
48568
+ const ATTRIBUTE_VALUE_MAX_BYTES = 256;
48569
+ const ATTRIBUTE_MAX_PER_RUN = 64;
48570
+ object$1({
48571
+ key: string$3(),
48572
+ value: union([string$3(), _null()])
48573
+ });
48574
+ class AttributeValidationError extends Error {
48575
+ constructor(message2) {
48576
+ super(message2);
48577
+ this.name = "AttributeValidationError";
48578
+ }
48579
+ }
48580
+ const valueByteLength = (value) => new TextEncoder().encode(value).length;
48581
+ function validateAttributeKey(key, options = {}) {
48582
+ if (typeof key !== "string") {
48583
+ return new AttributeValidationError(`Attribute key must be a string, got ${typeof key}`);
48584
+ }
48585
+ if (key.length === 0) {
48586
+ return new AttributeValidationError("Attribute key must not be empty");
48587
+ }
48588
+ if (key.length > ATTRIBUTE_KEY_MAX_LENGTH) {
48589
+ return new AttributeValidationError(`Attribute key length ${key.length} exceeds limit ${ATTRIBUTE_KEY_MAX_LENGTH}: ${JSON.stringify(key.slice(0, 32))}…`);
48590
+ }
48591
+ if (!options.allowReservedAttributes && key.startsWith(RESERVED_ATTRIBUTE_KEY_PREFIX)) {
48592
+ return new AttributeValidationError(`Attribute key ${JSON.stringify(key)} starts with reserved prefix "${RESERVED_ATTRIBUTE_KEY_PREFIX}" — that namespace is reserved for framework/library code. Set { allowReservedAttributes: true } only if your caller is framework-level.`);
48593
+ }
48594
+ return null;
48595
+ }
48596
+ function validateAttributeValue(value) {
48597
+ if (value === null)
48598
+ return null;
48599
+ if (typeof value !== "string") {
48600
+ return new AttributeValidationError(`Attribute value must be a string or null, got ${typeof value}`);
48601
+ }
48602
+ const bytes = valueByteLength(value);
48603
+ if (bytes > ATTRIBUTE_VALUE_MAX_BYTES) {
48604
+ return new AttributeValidationError(`Attribute value byte length ${bytes} exceeds limit ${ATTRIBUTE_VALUE_MAX_BYTES}`);
48605
+ }
48606
+ return null;
48607
+ }
48608
+ function validateAttributeChanges(changes, context = {}) {
48609
+ const seenKeys = /* @__PURE__ */ new Set();
48610
+ const existingKeys = context.existingKeys === void 0 ? void 0 : context.existingKeys instanceof Set ? context.existingKeys : new Set(context.existingKeys);
48611
+ let netAdds = 0;
48612
+ let netDeletes = 0;
48613
+ for (const change of changes) {
48614
+ const keyError = validateAttributeKey(change.key, {
48615
+ allowReservedAttributes: context.allowReservedAttributes
48616
+ });
48617
+ if (keyError)
48618
+ throw keyError;
48619
+ const valueError = validateAttributeValue(change.value);
48620
+ if (valueError)
48621
+ throw valueError;
48622
+ if (seenKeys.has(change.key)) {
48623
+ throw new AttributeValidationError(`Attribute key ${JSON.stringify(change.key)} appears more than once in the same batch`);
48624
+ }
48625
+ seenKeys.add(change.key);
48626
+ if (change.value !== null) {
48627
+ if (existingKeys === void 0 || !existingKeys.has(change.key)) {
48628
+ netAdds += 1;
48629
+ }
48630
+ } else if (existingKeys === void 0 || existingKeys.has(change.key)) {
48631
+ netDeletes += 1;
48632
+ }
48633
+ }
48634
+ const existing = existingKeys === void 0 ? 0 : existingKeys.size;
48635
+ const postMerge = existing + netAdds - netDeletes;
48636
+ if (postMerge > ATTRIBUTE_MAX_PER_RUN) {
48637
+ throw new AttributeValidationError(`Run attribute count would exceed limit ${ATTRIBUTE_MAX_PER_RUN} (post-merge ${postMerge})`);
48638
+ }
48639
+ }
48640
+ function applyAttributeChanges(existing, changes) {
48641
+ const next2 = { ...existing ?? {} };
48642
+ for (const { key, value } of changes) {
48643
+ if (value === null) {
48644
+ delete next2[key];
48645
+ } else {
48646
+ next2[key] = value;
48647
+ }
48648
+ }
48649
+ return next2;
48650
+ }
48566
48651
  const BinarySerializedDataSchema = _instanceof(Uint8Array);
48567
48652
  const LegacySerializedDataSchemaV1 = any();
48568
48653
  const SerializedDataSchema = union([
@@ -48937,7 +49022,7 @@ const WorkflowRunBaseSchema = object$1({
48937
49022
  // Optional in database for backwards compatibility, defaults to 1 (legacy) when reading
48938
49023
  specVersion: number$3().optional(),
48939
49024
  executionContext: record(string$3(), any()).optional(),
48940
- input: SerializedDataSchema,
49025
+ input: SerializedDataSchema.optional(),
48941
49026
  output: SerializedDataSchema.optional(),
48942
49027
  /**
48943
49028
  * The thrown value from a run_failed event, serialized via the workflow
@@ -48953,6 +49038,24 @@ const WorkflowRunBaseSchema = object$1({
48953
49038
  * without needing to decrypt the full error payload.
48954
49039
  */
48955
49040
  errorCode: string$3().optional(),
49041
+ /**
49042
+ * Plaintext string-string metadata attached to the run via
49043
+ * `experimental_setAttributes()` (or, in the future, materialized
49044
+ * from `attr_set` events). Stored unencrypted alongside other
49045
+ * plaintext fields so observability surfaces can read it without
49046
+ * going through the decryption pipeline.
49047
+ *
49048
+ * Defaults to `{}` after schema parsing so consumers always receive
49049
+ * a record regardless of world. World adapters need not initialize
49050
+ * the field on disk — `world-local` JSON files written before this
49051
+ * field existed, and rows from any other adapter that omits the
49052
+ * column, both read as `{}` after Zod parses them.
49053
+ *
49054
+ * EXPERIMENTAL (MVP): the full Workflow Attributes feature replaces
49055
+ * the direct-mutation MVP path with an event-sourced model — see
49056
+ * the attributes-mvp changelog entry.
49057
+ */
49058
+ attributes: record(string$3(), string$3()).default({}),
48956
49059
  expiredAt: date$2().optional(),
48957
49060
  startedAt: date$2().optional(),
48958
49061
  completedAt: date$2().optional(),
@@ -49054,7 +49157,7 @@ const StepSchema = object$1({
49054
49157
  */
49055
49158
  stepName: string$3(),
49056
49159
  status: StepStatusSchema,
49057
- input: SerializedDataSchema,
49160
+ input: SerializedDataSchema.optional(),
49058
49161
  output: SerializedDataSchema.optional(),
49059
49162
  /**
49060
49163
  * The thrown value from a step_retrying or step_failed event, serialized
@@ -50492,6 +50595,87 @@ const geistTheme = {
50492
50595
  };
50493
50596
  const inspectorThemeLight = geistTheme;
50494
50597
  const inspectorThemeDark = geistTheme;
50598
+ const falsyToString = (value) => typeof value === "boolean" ? `${value}` : value === 0 ? "0" : value;
50599
+ const cx = clsx;
50600
+ const cva = (base, config2) => (props) => {
50601
+ var _config_compoundVariants;
50602
+ if ((config2 === null || config2 === void 0 ? void 0 : config2.variants) == null) return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
50603
+ const { variants, defaultVariants } = config2;
50604
+ const getVariantClassNames = Object.keys(variants).map((variant) => {
50605
+ const variantProp = props === null || props === void 0 ? void 0 : props[variant];
50606
+ const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];
50607
+ if (variantProp === null) return null;
50608
+ const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);
50609
+ return variants[variant][variantKey];
50610
+ });
50611
+ const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param) => {
50612
+ let [key, value] = param;
50613
+ if (value === void 0) {
50614
+ return acc;
50615
+ }
50616
+ acc[key] = value;
50617
+ return acc;
50618
+ }, {});
50619
+ const getCompoundVariantClassNames = config2 === null || config2 === void 0 ? void 0 : (_config_compoundVariants = config2.compoundVariants) === null || _config_compoundVariants === void 0 ? void 0 : _config_compoundVariants.reduce((acc, param) => {
50620
+ let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param;
50621
+ return Object.entries(compoundVariantOptions).every((param2) => {
50622
+ let [key, value] = param2;
50623
+ return Array.isArray(value) ? value.includes({
50624
+ ...defaultVariants,
50625
+ ...propsWithoutUndefined
50626
+ }[key]) : {
50627
+ ...defaultVariants,
50628
+ ...propsWithoutUndefined
50629
+ }[key] === value;
50630
+ }) ? [
50631
+ ...acc,
50632
+ cvClass,
50633
+ cvClassName
50634
+ ] : acc;
50635
+ }, []);
50636
+ return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
50637
+ };
50638
+ const buttonVariants$1 = cva([
50639
+ "outline-none m-0 border-0 align-baseline no-underline group/trigger",
50640
+ "relative cursor-pointer select-none transform translate-z-0",
50641
+ "inline-flex max-w-full items-center justify-center gap-x-1 whitespace-nowrap rounded-md font-medium",
50642
+ "!text-gray-100",
50643
+ "bg-gray-1000",
50644
+ "transition-[border-color,background,color,transform,box-shadow] duration-150 ease-in-out",
50645
+ // Geist invert hover: literal fallbacks (no token dep, so it resolves in any
50646
+ // consuming app), darkened via ancestor theme class without a registered variant.
50647
+ "hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))]",
50648
+ "[.dark-theme_&]:hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))]",
50649
+ "[[data-theme=dark]_&]:hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))]",
50650
+ // Geist focus ring as arbitrary properties (no bare `outline`/ambiguous
50651
+ // arbitrary-color utilities, which differ between Tailwind v3 and v4).
50652
+ "focus-visible:[outline:2px_solid_var(--ds-focus-color)] focus-visible:[outline-offset:2px]",
50653
+ // disabled styles
50654
+ "disabled:cursor-not-allowed aria-disabled:cursor-not-allowed",
50655
+ "disabled:bg-gray-100 disabled:!text-gray-700 disabled:hover:bg-gray-100",
50656
+ "aria-disabled:bg-gray-100 aria-disabled:text-gray-700 aria-disabled:hover:bg-gray-100"
50657
+ ], {
50658
+ variants: {
50659
+ variant: {
50660
+ default: "",
50661
+ secondary: "border border-gray-alpha-400 [--themed-bg:_var(--ds-background-100)] [--themed-fg:_var(--ds-gray-1000)] [--themed-hover-bg:_var(--ds-gray-alpha-200)]",
50662
+ ghost: "[--themed-bg:_transparent] [--themed-fg:_var(--ds-gray-1000)] [--themed-hover-bg:_var(--ds-gray-alpha-100)]"
50663
+ },
50664
+ size: {
50665
+ default: "h-10 px-4 text-[14px]",
50666
+ sm: "h-8 px-3 text-[14px]",
50667
+ xs: "h-6 px-1.5 py-0.5 text-button-12 rounded-[4px]",
50668
+ icon: "h-8 w-8"
50669
+ }
50670
+ },
50671
+ defaultVariants: {
50672
+ variant: "default",
50673
+ size: "default"
50674
+ }
50675
+ });
50676
+ function Button$1({ className, variant, size: size2, type = "button", ...props }) {
50677
+ return jsxRuntimeExports.jsx("button", { type, className: cn$4(buttonVariants$1({ variant, size: size2, className })), ...props });
50678
+ }
50495
50679
  const STREAM_REF_TYPE = "__workflow_stream_ref__";
50496
50680
  const CLASS_INSTANCE_REF_TYPE = "__workflow_class_instance_ref__";
50497
50681
  const RUN_REF_TYPE = "__workflow_run_ref__";
@@ -50541,16 +50725,10 @@ const RunClickContext = reactExports.createContext(void 0);
50541
50725
  function EncryptedInlineLabel() {
50542
50726
  const ctx = reactExports.useContext(DecryptClickContext);
50543
50727
  if (ctx) {
50544
- return jsxRuntimeExports.jsxs("button", { type: "button", className: "inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] cursor-pointer", style: {
50545
- backgroundColor: "var(--ds-gray-100)",
50546
- color: "var(--ds-gray-700)",
50547
- border: "1px solid var(--ds-gray-400)",
50548
- fontStyle: "italic",
50549
- opacity: ctx.isDecrypting ? 0.6 : 1
50550
- }, disabled: ctx.isDecrypting, onClick: (e) => {
50728
+ return jsxRuntimeExports.jsxs(Button$1, { size: "xs", className: "align-baseline gap-x-1", disabled: ctx.isDecrypting, onClick: (e) => {
50551
50729
  e.stopPropagation();
50552
50730
  ctx.onDecrypt();
50553
- }, title: "Click to decrypt", children: [ctx.isDecrypting ? jsxRuntimeExports.jsx(Spinner, { size: 12 }) : jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3", style: { display: "inline", flexShrink: 0 } }), jsxRuntimeExports.jsx("span", { children: ctx.isDecrypting ? "Decrypting…" : "Decrypt" })] });
50731
+ }, children: [ctx.isDecrypting ? jsxRuntimeExports.jsx(Spinner, { size: 10 }) : jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { children: "Decrypt" })] });
50554
50732
  }
50555
50733
  return jsxRuntimeExports.jsxs("span", { style: { color: "var(--ds-gray-600)", fontStyle: "italic" }, children: [jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3", style: {
50556
50734
  display: "inline",
@@ -50796,6 +50974,944 @@ function isDeepEqual(a2, b2, seen = /* @__PURE__ */ new WeakMap()) {
50796
50974
  }
50797
50975
  return true;
50798
50976
  }
50977
+ function CopyButton({ copyText, ariaLabel, className }) {
50978
+ const [copied, setCopied] = reactExports.useState(false);
50979
+ const timeoutRef = reactExports.useRef(null);
50980
+ reactExports.useEffect(() => {
50981
+ return () => {
50982
+ if (timeoutRef.current) {
50983
+ clearTimeout(timeoutRef.current);
50984
+ }
50985
+ };
50986
+ }, []);
50987
+ return jsxRuntimeExports.jsx("button", { type: "button", "aria-label": ariaLabel, className: cn$4("cursor-pointer text-gray-800 hover:text-gray-1000 bg-transparent border-0 p-1 m-0", className), onClick: (e) => {
50988
+ e.stopPropagation();
50989
+ if (timeoutRef.current) {
50990
+ clearTimeout(timeoutRef.current);
50991
+ }
50992
+ void navigator.clipboard.writeText(copyText).then(() => {
50993
+ setCopied(true);
50994
+ timeoutRef.current = setTimeout(() => setCopied(false), 1e3);
50995
+ });
50996
+ }, children: jsxRuntimeExports.jsxs("div", { className: "relative w-3 h-3", children: [jsxRuntimeExports.jsx("div", { className: cn$4("absolute inset-0 flex items-center justify-center transition-all duration-150 ease-out", copied ? "scale-100 opacity-100" : "scale-0 opacity-0"), children: jsxRuntimeExports.jsx(Check, { className: "w-3 h-3" }) }), jsxRuntimeExports.jsx("div", { className: cn$4("absolute inset-0 flex items-center justify-center transition-all duration-150 ease-out", copied ? "scale-0 opacity-0" : "scale-100 opacity-100"), children: jsxRuntimeExports.jsx(Copy, { className: "w-3 h-3" }) })] }) });
50997
+ }
50998
+ function isStructuredErrorWithStack(value) {
50999
+ return value != null && typeof value === "object" && "stack" in value && typeof value.stack === "string";
51000
+ }
51001
+ function deriveTitle(message2) {
51002
+ const firstLine = message2.split("\n").find((line) => line.trim().length > 0) ?? message2;
51003
+ return firstLine.trim();
51004
+ }
51005
+ function ErrorStackBlock({ value }) {
51006
+ const stack = value.stack;
51007
+ const message2 = typeof value.message === "string" ? value.message : void 0;
51008
+ const title = message2 ? deriveTitle(message2) : void 0;
51009
+ const copyText = message2 ? `${message2}
51010
+
51011
+ ${stack}` : stack;
51012
+ return jsxRuntimeExports.jsxs("div", { className: "relative overflow-hidden rounded-md border", style: {
51013
+ borderColor: "var(--ds-red-400)",
51014
+ background: "var(--ds-red-100)"
51015
+ }, children: [jsxRuntimeExports.jsx(CopyButton, { copyText, ariaLabel: "Copy error", className: "absolute right-2 top-2 flex h-6 w-6 items-center justify-center rounded-md border border-red-400 bg-red-100 p-0 text-red-900 transition-transform transition-colors duration-100 hover:bg-red-200 active:scale-95" }), title && jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-3 py-2.5 pr-10", style: {
51016
+ color: "var(--ds-red-900)",
51017
+ borderBottom: "1px solid var(--ds-red-400)"
51018
+ }, children: [jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4 shrink-0" }), jsxRuntimeExports.jsx("p", {
51019
+ className: "text-xs font-semibold m-0 truncate",
51020
+ // The full multi-line message is in the stack body below; the
51021
+ // header just shows the first line, single-line, with overflow
51022
+ // ellipsised so a long title doesn't push the copy button or
51023
+ // wrap into the framed hint/docs lines.
51024
+ title: message2,
51025
+ children: title
51026
+ })] }), jsxRuntimeExports.jsx("pre", { className: "px-3 py-2.5 text-xs font-mono whitespace-pre-wrap break-words overflow-auto m-0", style: {
51027
+ color: "var(--ds-red-900)",
51028
+ background: "var(--ds-red-200)"
51029
+ }, children: stack })] });
51030
+ }
51031
+ const STYLES$1 = `.wf-load-more{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;border-radius:6px;font-size:13px;font-weight:500;line-height:20px;color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400);cursor:pointer;white-space:nowrap;gap:6px;transition:background 150ms}.wf-load-more:hover{background:var(--ds-gray-alpha-200)}.wf-load-more:disabled{opacity:.6;cursor:default}.wf-load-more:disabled:hover{background:var(--ds-background-100)}`;
51032
+ function LoadMoreButton({ loading = false, onClick, label = "Load more", loadingLabel = "Loading..." }) {
51033
+ return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { dangerouslySetInnerHTML: { __html: STYLES$1 } }), jsxRuntimeExports.jsxs("button", { type: "button", onClick, disabled: loading, className: "wf-load-more", children: [loading && jsxRuntimeExports.jsx(Spinner, { size: 14 }), loading ? loadingLabel : label] })] });
51034
+ }
51035
+ const STYLES = `.wf-menu-btn{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:40px;padding:0 12px;border-radius:6px;font-size:14px;font-weight:500;line-height:20px;color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400);cursor:pointer;white-space:nowrap;transition:background 150ms}.wf-menu-btn:hover{background:var(--ds-gray-alpha-200)}.wf-menu-item{appearance:none;-webkit-appearance:none;border:none;display:flex;align-items:center;width:100%;height:40px;padding:0 8px;border-radius:6px;font-size:14px;color:var(--ds-gray-1000);background:transparent;cursor:pointer;transition:background 150ms}.wf-menu-item:hover{background:var(--ds-gray-alpha-100)}`;
51036
+ function MenuDropdown({ options, value, onChange }) {
51037
+ var _a3, _b2;
51038
+ const [open, setOpen] = reactExports.useState(false);
51039
+ const ref = reactExports.useRef(null);
51040
+ const label = ((_a3 = options.find((o) => o.value === value)) == null ? void 0 : _a3.label) ?? ((_b2 = options[0]) == null ? void 0 : _b2.label) ?? "";
51041
+ reactExports.useEffect(() => {
51042
+ if (!open)
51043
+ return;
51044
+ function handleClickOutside(e) {
51045
+ if (ref.current && !ref.current.contains(e.target)) {
51046
+ setOpen(false);
51047
+ }
51048
+ }
51049
+ document.addEventListener("mousedown", handleClickOutside);
51050
+ return () => document.removeEventListener("mousedown", handleClickOutside);
51051
+ }, [open]);
51052
+ return jsxRuntimeExports.jsxs("div", { ref, style: { position: "relative", flexShrink: 0 }, children: [jsxRuntimeExports.jsx("style", { dangerouslySetInnerHTML: { __html: STYLES } }), jsxRuntimeExports.jsxs("button", { type: "button", className: "wf-menu-btn", onClick: () => setOpen(!open), children: [jsxRuntimeExports.jsx("span", { children: label }), jsxRuntimeExports.jsx("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", style: {
51053
+ marginLeft: 16,
51054
+ marginRight: -4,
51055
+ color: "var(--ds-gray-900)"
51056
+ }, children: jsxRuntimeExports.jsx("path", { d: "M4.5 6L8 9.5L11.5 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })] }), open && jsxRuntimeExports.jsx("div", { style: {
51057
+ position: "absolute",
51058
+ right: 0,
51059
+ top: "100%",
51060
+ marginTop: 4,
51061
+ minWidth: 140,
51062
+ padding: 4,
51063
+ borderRadius: 12,
51064
+ background: "var(--ds-background-100)",
51065
+ boxShadow: "var(--ds-shadow-menu, var(--ds-shadow-medium))",
51066
+ zIndex: 2001
51067
+ }, role: "menu", children: options.map((option) => jsxRuntimeExports.jsx("button", { type: "button", role: "menuitem", className: "wf-menu-item", style: {
51068
+ fontWeight: option.value === value ? 500 : 400
51069
+ }, onClick: () => {
51070
+ onChange(option.value);
51071
+ setOpen(false);
51072
+ }, children: option.label }, option.value)) })] });
51073
+ }
51074
+ function Skeleton$2({ className, style: style2, ...props }) {
51075
+ return jsxRuntimeExports.jsx("div", { ...props, className: cn$4("rounded-md", className), style: { backgroundColor: "var(--ds-gray-200)", ...style2 } });
51076
+ }
51077
+ const TIME_UNITS = [
51078
+ { unit: "year", ms: 31536e6 },
51079
+ { unit: "month", ms: 2628e6 },
51080
+ { unit: "day", ms: 864e5 },
51081
+ { unit: "hour", ms: 36e5 },
51082
+ { unit: "minute", ms: 6e4 },
51083
+ { unit: "second", ms: 1e3 }
51084
+ ];
51085
+ function formatTimeDifference(diff) {
51086
+ let remaining = Math.abs(diff);
51087
+ const result = [];
51088
+ for (const { unit, ms: ms2 } of TIME_UNITS) {
51089
+ const value = Math.floor(remaining / ms2);
51090
+ if (value > 0 || result.length > 0) {
51091
+ result.push(`${value} ${unit}${value !== 1 ? "s" : ""}`);
51092
+ remaining %= ms2;
51093
+ }
51094
+ if (result.length === 3)
51095
+ break;
51096
+ }
51097
+ return result.join(", ");
51098
+ }
51099
+ function useTimeAgo(date2) {
51100
+ const [timeAgo, setTimeAgo] = reactExports.useState("");
51101
+ reactExports.useEffect(() => {
51102
+ const update = () => {
51103
+ const diff = Date.now() - date2;
51104
+ const formatted = formatTimeDifference(diff);
51105
+ setTimeAgo(formatted ? `${formatted} ago` : "Just now");
51106
+ };
51107
+ update();
51108
+ const timer2 = setInterval(update, 1e3);
51109
+ return () => clearInterval(timer2);
51110
+ }, [date2]);
51111
+ return timeAgo;
51112
+ }
51113
+ function ZoneDateTimeRow({ date: date2, zone }) {
51114
+ var _a3;
51115
+ const dateObj = new Date(date2);
51116
+ const formattedZone = ((_a3 = new Intl.DateTimeFormat("en-US", {
51117
+ timeZone: zone,
51118
+ timeZoneName: "short"
51119
+ }).formatToParts(dateObj).find((part) => part.type === "timeZoneName")) == null ? void 0 : _a3.value) || zone;
51120
+ const formattedDate = dateObj.toLocaleString("en-US", {
51121
+ timeZone: zone,
51122
+ year: "numeric",
51123
+ month: "long",
51124
+ day: "numeric"
51125
+ });
51126
+ const formattedTime = dateObj.toLocaleTimeString("en-US", {
51127
+ timeZone: zone,
51128
+ hour: "2-digit",
51129
+ minute: "2-digit",
51130
+ second: "2-digit"
51131
+ });
51132
+ return jsxRuntimeExports.jsxs("div", { style: {
51133
+ display: "flex",
51134
+ alignItems: "center",
51135
+ justifyContent: "space-between",
51136
+ gap: 12
51137
+ }, children: [jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [jsxRuntimeExports.jsx("div", { style: {
51138
+ display: "inline-flex",
51139
+ alignItems: "center",
51140
+ justifyContent: "center",
51141
+ height: 16,
51142
+ padding: "0 6px",
51143
+ backgroundColor: "var(--ds-gray-200)",
51144
+ borderRadius: 3,
51145
+ fontSize: 11,
51146
+ fontFamily: "var(--font-mono, monospace)",
51147
+ fontWeight: 500,
51148
+ color: "var(--ds-gray-900)",
51149
+ whiteSpace: "nowrap"
51150
+ }, children: formattedZone }), jsxRuntimeExports.jsx("span", { style: {
51151
+ fontSize: 13,
51152
+ color: "var(--ds-gray-1000)",
51153
+ whiteSpace: "nowrap"
51154
+ }, children: formattedDate })] }), jsxRuntimeExports.jsx("span", { style: {
51155
+ fontSize: 11,
51156
+ fontFamily: "var(--font-mono, monospace)",
51157
+ fontVariantNumeric: "tabular-nums",
51158
+ color: "var(--ds-gray-900)",
51159
+ whiteSpace: "nowrap"
51160
+ }, children: formattedTime })] });
51161
+ }
51162
+ function TimestampTooltipContent({ date: date2 }) {
51163
+ const localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
51164
+ const timeAgo = useTimeAgo(date2);
51165
+ return jsxRuntimeExports.jsxs("div", { style: {
51166
+ display: "flex",
51167
+ flexDirection: "column",
51168
+ gap: 12,
51169
+ minWidth: 300,
51170
+ padding: "12px 14px"
51171
+ }, children: [jsxRuntimeExports.jsx("span", { style: {
51172
+ fontSize: 13,
51173
+ fontVariantNumeric: "tabular-nums",
51174
+ color: "var(--ds-gray-900)"
51175
+ }, children: timeAgo }), jsxRuntimeExports.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [jsxRuntimeExports.jsx(ZoneDateTimeRow, { date: date2, zone: "UTC" }), jsxRuntimeExports.jsx(ZoneDateTimeRow, { date: date2, zone: localTimezone })] })] });
51176
+ }
51177
+ const TOOLTIP_WIDTH = 330;
51178
+ const VIEWPORT_PAD = 8;
51179
+ function TooltipPortal({ triggerRect, onMouseEnter, onMouseLeave, date: date2 }) {
51180
+ const tooltipRef = reactExports.useRef(null);
51181
+ const [style2, setStyle] = reactExports.useState({
51182
+ position: "fixed",
51183
+ zIndex: 9999,
51184
+ visibility: "hidden"
51185
+ });
51186
+ reactExports.useEffect(() => {
51187
+ const placement = triggerRect.top > 240 ? "above" : "below";
51188
+ const centerX = triggerRect.left + triggerRect.width / 2;
51189
+ const el = tooltipRef.current;
51190
+ const w2 = el ? el.offsetWidth : TOOLTIP_WIDTH;
51191
+ const h2 = el ? el.offsetHeight : 100;
51192
+ let left = centerX - w2 / 2;
51193
+ left = Math.max(VIEWPORT_PAD, Math.min(left, window.innerWidth - w2 - VIEWPORT_PAD));
51194
+ let top;
51195
+ if (placement === "above") {
51196
+ top = triggerRect.top - h2 - 6;
51197
+ if (top < VIEWPORT_PAD) {
51198
+ top = triggerRect.bottom + 6;
51199
+ }
51200
+ } else {
51201
+ top = triggerRect.bottom + 6;
51202
+ if (top + h2 > window.innerHeight - VIEWPORT_PAD) {
51203
+ top = triggerRect.top - h2 - 6;
51204
+ }
51205
+ }
51206
+ setStyle({
51207
+ position: "fixed",
51208
+ left,
51209
+ top,
51210
+ zIndex: 9999,
51211
+ borderRadius: 10,
51212
+ border: "1px solid var(--ds-gray-alpha-200)",
51213
+ backgroundColor: "var(--ds-background-100)",
51214
+ boxShadow: "0 4px 12px rgba(0,0,0,0.08), 0 1px 3px rgba(0,0,0,0.06)",
51215
+ visibility: "visible"
51216
+ });
51217
+ }, [triggerRect]);
51218
+ return reactDomExports.createPortal(
51219
+ // biome-ignore lint/a11y/noStaticElementInteractions: tooltip hover zone
51220
+ jsxRuntimeExports.jsx("div", { ref: tooltipRef, onMouseEnter, onMouseLeave, style: style2, children: jsxRuntimeExports.jsx(TimestampTooltipContent, { date: date2 }) }),
51221
+ document.body
51222
+ );
51223
+ }
51224
+ function TimestampTooltip({ date: date2, children: children2 }) {
51225
+ const [open, setOpen] = reactExports.useState(false);
51226
+ const [triggerRect, setTriggerRect] = reactExports.useState(null);
51227
+ const triggerRef = reactExports.useRef(null);
51228
+ const closeTimer = reactExports.useRef(null);
51229
+ reactExports.useEffect(() => {
51230
+ return () => {
51231
+ if (closeTimer.current)
51232
+ clearTimeout(closeTimer.current);
51233
+ };
51234
+ }, []);
51235
+ const ts = date2 == null ? null : typeof date2 === "number" ? date2 : new Date(date2).getTime();
51236
+ if (ts == null || Number.isNaN(ts))
51237
+ return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: children2 });
51238
+ const cancelClose = () => {
51239
+ if (closeTimer.current) {
51240
+ clearTimeout(closeTimer.current);
51241
+ closeTimer.current = null;
51242
+ }
51243
+ };
51244
+ const scheduleClose = () => {
51245
+ cancelClose();
51246
+ closeTimer.current = setTimeout(() => setOpen(false), 120);
51247
+ };
51248
+ const handleOpen = () => {
51249
+ cancelClose();
51250
+ if (triggerRef.current) {
51251
+ setTriggerRect(triggerRef.current.getBoundingClientRect());
51252
+ }
51253
+ setOpen(true);
51254
+ };
51255
+ return (
51256
+ // biome-ignore lint/a11y/noStaticElementInteractions: tooltip trigger
51257
+ jsxRuntimeExports.jsxs("span", { ref: triggerRef, onMouseEnter: handleOpen, onMouseLeave: scheduleClose, style: { display: "inline-flex" }, children: [children2, open && triggerRect && jsxRuntimeExports.jsx(TooltipPortal, { triggerRect, onMouseEnter: cancelClose, onMouseLeave: scheduleClose, date: ts })] })
51258
+ );
51259
+ }
51260
+ const ERROR_EVENT_TYPES$1 = /* @__PURE__ */ new Set([
51261
+ "step_failed",
51262
+ "step_retrying",
51263
+ "run_failed",
51264
+ "workflow_failed"
51265
+ ]);
51266
+ const BUTTON_RESET_STYLE = {
51267
+ appearance: "none",
51268
+ WebkitAppearance: "none",
51269
+ border: "none",
51270
+ background: "transparent"
51271
+ };
51272
+ const DOT_PULSE_ANIMATION = "workflow-dot-pulse 1.25s cubic-bezier(0, 0, 0.2, 1) infinite";
51273
+ function formatEventTime(date2) {
51274
+ return date2.toLocaleTimeString("en-US", {
51275
+ hour: "2-digit",
51276
+ minute: "2-digit",
51277
+ second: "2-digit",
51278
+ hour12: false
51279
+ }) + "." + date2.getMilliseconds().toString().padStart(3, "0");
51280
+ }
51281
+ function formatEventType(eventType) {
51282
+ return eventType.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
51283
+ }
51284
+ function getStatusDotColor(eventType) {
51285
+ if (eventType === "step_failed" || eventType === "run_failed" || eventType === "workflow_failed") {
51286
+ return "var(--ds-red-700)";
51287
+ }
51288
+ if (eventType === "run_cancelled") {
51289
+ return "var(--ds-amber-700)";
51290
+ }
51291
+ if (eventType === "step_retrying") {
51292
+ return "var(--ds-amber-700)";
51293
+ }
51294
+ if (eventType === "step_completed" || eventType === "run_completed" || eventType === "workflow_completed" || eventType === "hook_disposed" || eventType === "wait_completed") {
51295
+ return "var(--ds-green-700)";
51296
+ }
51297
+ if (eventType === "step_started" || eventType === "run_started" || eventType === "workflow_started" || eventType === "hook_received") {
51298
+ return "var(--ds-blue-700)";
51299
+ }
51300
+ return "var(--ds-gray-600)";
51301
+ }
51302
+ function buildNameMaps(events2, run) {
51303
+ var _a3, _b2;
51304
+ const correlationNameMap = /* @__PURE__ */ new Map();
51305
+ if (events2) {
51306
+ for (const event of events2) {
51307
+ if (event.eventType === "step_created" && event.correlationId) {
51308
+ const stepName = ((_a3 = event.eventData) == null ? void 0 : _a3.stepName) ?? "";
51309
+ const parsed = parseStepName(String(stepName));
51310
+ correlationNameMap.set(event.correlationId, (parsed == null ? void 0 : parsed.shortName) ?? stepName);
51311
+ }
51312
+ }
51313
+ }
51314
+ const workflowName = (run == null ? void 0 : run.workflowName) ? ((_b2 = parseWorkflowName(run.workflowName)) == null ? void 0 : _b2.shortName) ?? run.workflowName : null;
51315
+ return { correlationNameMap, workflowName };
51316
+ }
51317
+ function buildDurationMap(events2) {
51318
+ const chronological = [...events2].sort((a2, b2) => new Date(a2.createdAt).getTime() - new Date(b2.createdAt).getTime());
51319
+ const createdTimes = /* @__PURE__ */ new Map();
51320
+ const firstStartedTimes = /* @__PURE__ */ new Map();
51321
+ const startedTimes = /* @__PURE__ */ new Map();
51322
+ const durations = /* @__PURE__ */ new Map();
51323
+ for (const event of chronological) {
51324
+ const ts = new Date(event.createdAt).getTime();
51325
+ const key = event.correlationId ?? "__run__";
51326
+ const type = event.eventType;
51327
+ if (type === "step_created" || type === "run_created") {
51328
+ if (!createdTimes.has(key)) {
51329
+ createdTimes.set(key, ts);
51330
+ }
51331
+ }
51332
+ if (type === "step_started" || type === "run_started" || type === "workflow_started") {
51333
+ startedTimes.set(key, ts);
51334
+ if (!firstStartedTimes.has(key)) {
51335
+ firstStartedTimes.set(key, ts);
51336
+ if (!createdTimes.has(key)) {
51337
+ createdTimes.set(key, ts);
51338
+ }
51339
+ const createdAt = createdTimes.get(key);
51340
+ const info = durations.get(key) ?? {};
51341
+ if (createdAt !== void 0) {
51342
+ info.queued = ts - createdAt;
51343
+ }
51344
+ durations.set(key, info);
51345
+ }
51346
+ }
51347
+ if (type === "step_completed" || type === "step_failed" || type === "run_completed" || type === "run_failed" || type === "run_cancelled" || type === "workflow_completed" || type === "workflow_failed" || type === "wait_completed" || type === "hook_disposed") {
51348
+ const startedAt = startedTimes.get(key);
51349
+ const info = durations.get(key) ?? {};
51350
+ if (startedAt !== void 0) {
51351
+ info.ran = ts - startedAt;
51352
+ }
51353
+ durations.set(key, info);
51354
+ }
51355
+ }
51356
+ return durations;
51357
+ }
51358
+ function hasEncryptedValues(data) {
51359
+ if (!data || typeof data !== "object")
51360
+ return false;
51361
+ for (const val of Object.values(data)) {
51362
+ if (isEncryptedMarker(val))
51363
+ return true;
51364
+ }
51365
+ return false;
51366
+ }
51367
+ function isRunLevel(eventType) {
51368
+ return eventType === "run_created" || eventType === "run_started" || eventType === "run_completed" || eventType === "run_failed" || eventType === "run_cancelled" || eventType === "workflow_started" || eventType === "workflow_completed" || eventType === "workflow_failed";
51369
+ }
51370
+ const GUTTER_WIDTH = 36;
51371
+ const LANE_X = 20;
51372
+ const ROOT_LINE_COLOR = "var(--ds-gray-500)";
51373
+ function TreeGutter({ isFirst, isLast, isRunLevel: isRun, statusDotColor, pulse = false, hasSelection, showBranch, showLaneLine, isLaneStart, isLaneEnd, continuationOnly = false }) {
51374
+ const dotSize = isRun ? 8 : 6;
51375
+ const dotLeft = isRun ? 5 : 6;
51376
+ const dotOpacity = hasSelection && !showBranch && !isRun ? 0.3 : 1;
51377
+ return jsxRuntimeExports.jsxs("div", { className: "relative flex-shrink-0 self-stretch", style: {
51378
+ width: GUTTER_WIDTH,
51379
+ minHeight: continuationOnly ? 0 : void 0
51380
+ }, children: [jsxRuntimeExports.jsx("div", { style: {
51381
+ position: "absolute",
51382
+ left: 8,
51383
+ top: continuationOnly ? 0 : isFirst ? "50%" : 0,
51384
+ bottom: continuationOnly ? 0 : isLast ? "50%" : 0,
51385
+ width: 2,
51386
+ backgroundColor: ROOT_LINE_COLOR,
51387
+ zIndex: 0
51388
+ } }), !continuationOnly && jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("div", { style: {
51389
+ position: "absolute",
51390
+ left: dotLeft,
51391
+ top: "50%",
51392
+ transform: "translateY(-50%)",
51393
+ width: dotSize,
51394
+ height: dotSize,
51395
+ zIndex: 2
51396
+ }, children: [jsxRuntimeExports.jsx("div", { style: {
51397
+ position: "absolute",
51398
+ inset: 0,
51399
+ borderRadius: "50%",
51400
+ backgroundColor: "var(--ds-background-100)",
51401
+ zIndex: 0
51402
+ } }), pulse && jsxRuntimeExports.jsx("div", { style: {
51403
+ position: "absolute",
51404
+ inset: 0,
51405
+ borderRadius: "50%",
51406
+ backgroundColor: statusDotColor,
51407
+ opacity: 0.75 * dotOpacity,
51408
+ animation: DOT_PULSE_ANIMATION,
51409
+ zIndex: 1
51410
+ } }), jsxRuntimeExports.jsx("div", { style: {
51411
+ position: "relative",
51412
+ width: "100%",
51413
+ height: "100%",
51414
+ borderRadius: "50%",
51415
+ backgroundColor: statusDotColor,
51416
+ opacity: dotOpacity,
51417
+ transition: "opacity 150ms",
51418
+ zIndex: 2
51419
+ } })] }), showBranch && jsxRuntimeExports.jsx("div", { style: {
51420
+ position: "absolute",
51421
+ left: 9,
51422
+ top: "50%",
51423
+ width: GUTTER_WIDTH - 9,
51424
+ height: 2,
51425
+ backgroundColor: ROOT_LINE_COLOR,
51426
+ zIndex: 0
51427
+ } })] }), showLaneLine && jsxRuntimeExports.jsx("div", { style: {
51428
+ position: "absolute",
51429
+ left: LANE_X,
51430
+ top: continuationOnly ? 0 : isLaneStart ? "50%" : 0,
51431
+ bottom: continuationOnly ? 0 : isLaneEnd ? "50%" : 0,
51432
+ width: 2,
51433
+ backgroundColor: ROOT_LINE_COLOR,
51434
+ zIndex: 0
51435
+ } })] });
51436
+ }
51437
+ function CopyableCell({ value, className, style: styleProp }) {
51438
+ const [copied, setCopied] = reactExports.useState(false);
51439
+ const resetCopiedTimeoutRef = reactExports.useRef(null);
51440
+ reactExports.useEffect(() => {
51441
+ return () => {
51442
+ if (resetCopiedTimeoutRef.current !== null) {
51443
+ window.clearTimeout(resetCopiedTimeoutRef.current);
51444
+ }
51445
+ };
51446
+ }, []);
51447
+ const handleCopy = reactExports.useCallback((e) => {
51448
+ e.stopPropagation();
51449
+ navigator.clipboard.writeText(value).then(() => {
51450
+ setCopied(true);
51451
+ if (resetCopiedTimeoutRef.current !== null) {
51452
+ window.clearTimeout(resetCopiedTimeoutRef.current);
51453
+ }
51454
+ resetCopiedTimeoutRef.current = window.setTimeout(() => {
51455
+ setCopied(false);
51456
+ resetCopiedTimeoutRef.current = null;
51457
+ }, 1500);
51458
+ });
51459
+ }, [value]);
51460
+ return jsxRuntimeExports.jsxs("div", { className: `group/copy flex items-center gap-1 min-w-0 px-4 ${className ?? ""}`, style: styleProp, children: [jsxRuntimeExports.jsx("span", { className: "overflow-hidden text-ellipsis whitespace-nowrap", children: value || "-" }), value ? jsxRuntimeExports.jsx("button", { type: "button", onClick: handleCopy, className: "flex-shrink-0 opacity-0 group-hover/copy:opacity-100 transition-opacity p-0.5 rounded hover:bg-[var(--ds-gray-alpha-200)]", style: BUTTON_RESET_STYLE, "aria-label": `Copy ${value}`, children: copied ? jsxRuntimeExports.jsx(Check, { className: "h-3 w-3", style: { color: "var(--ds-green-700)" } }) : jsxRuntimeExports.jsx(Copy, { className: "h-3 w-3", style: { color: "var(--ds-gray-700)" } }) }) : null] });
51461
+ }
51462
+ function deepParseJson(value) {
51463
+ if (typeof value === "string") {
51464
+ const trimmed = value.trim();
51465
+ if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]") || trimmed.startsWith('"') && trimmed.endsWith('"')) {
51466
+ try {
51467
+ return deepParseJson(JSON.parse(trimmed));
51468
+ } catch {
51469
+ return value;
51470
+ }
51471
+ }
51472
+ return value;
51473
+ }
51474
+ if (Array.isArray(value)) {
51475
+ return value.map(deepParseJson);
51476
+ }
51477
+ if (value !== null && typeof value === "object") {
51478
+ if (value.constructor !== Object) {
51479
+ return value;
51480
+ }
51481
+ const result = {};
51482
+ for (const [k2, v2] of Object.entries(value)) {
51483
+ result[k2] = deepParseJson(v2);
51484
+ }
51485
+ return result;
51486
+ }
51487
+ return value;
51488
+ }
51489
+ function extractStructuredError(data, eventType) {
51490
+ if (!eventType || !ERROR_EVENT_TYPES$1.has(eventType))
51491
+ return null;
51492
+ if (data == null || typeof data !== "object")
51493
+ return null;
51494
+ const record2 = data;
51495
+ if (isStructuredErrorWithStack(record2.error))
51496
+ return record2.error;
51497
+ if (isStructuredErrorWithStack(record2))
51498
+ return record2;
51499
+ return null;
51500
+ }
51501
+ function PayloadBlock({ data, eventType }) {
51502
+ const structuredError = reactExports.useMemo(() => extractStructuredError(data, eventType), [data, eventType]);
51503
+ const [copied, setCopied] = reactExports.useState(false);
51504
+ const resetCopiedTimeoutRef = reactExports.useRef(null);
51505
+ const cleaned = reactExports.useMemo(() => deepParseJson(data), [data]);
51506
+ reactExports.useEffect(() => {
51507
+ return () => {
51508
+ if (resetCopiedTimeoutRef.current !== null) {
51509
+ window.clearTimeout(resetCopiedTimeoutRef.current);
51510
+ }
51511
+ };
51512
+ }, []);
51513
+ const formatted = reactExports.useMemo(() => {
51514
+ try {
51515
+ return JSON.stringify(cleaned, null, 2);
51516
+ } catch {
51517
+ return String(cleaned);
51518
+ }
51519
+ }, [cleaned]);
51520
+ const handleCopy = reactExports.useCallback((e) => {
51521
+ e.stopPropagation();
51522
+ navigator.clipboard.writeText(formatted).then(() => {
51523
+ setCopied(true);
51524
+ if (resetCopiedTimeoutRef.current !== null) {
51525
+ window.clearTimeout(resetCopiedTimeoutRef.current);
51526
+ }
51527
+ resetCopiedTimeoutRef.current = window.setTimeout(() => {
51528
+ setCopied(false);
51529
+ resetCopiedTimeoutRef.current = null;
51530
+ }, 1500);
51531
+ });
51532
+ }, [formatted]);
51533
+ if (structuredError) {
51534
+ return jsxRuntimeExports.jsx("div", { className: "p-2", children: jsxRuntimeExports.jsx(ErrorStackBlock, { value: structuredError }) });
51535
+ }
51536
+ return jsxRuntimeExports.jsxs("div", { className: "relative group/payload", children: [jsxRuntimeExports.jsx("div", { className: "overflow-x-auto p-2 text-[11px]", style: { color: "var(--ds-gray-1000)" }, children: jsxRuntimeExports.jsx(DataInspector, { data: cleaned, expandLevel: 2 }) }), jsxRuntimeExports.jsx("button", { type: "button", onClick: handleCopy, className: "absolute bottom-2 right-2 opacity-0 group-hover/payload:opacity-100 transition-opacity flex items-center gap-1 px-2 py-1 rounded-md text-xs hover:bg-[var(--ds-gray-alpha-200)]", style: { ...BUTTON_RESET_STYLE, color: "var(--ds-gray-700)" }, "aria-label": "Copy payload", children: copied ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Check, { className: "h-3 w-3", style: { color: "var(--ds-green-700)" } }), jsxRuntimeExports.jsx("span", { style: { color: "var(--ds-green-700)" }, children: "Copied" })] }) : jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Copy, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { children: "Copy" })] }) })] });
51537
+ }
51538
+ const SORT_OPTIONS = [
51539
+ { value: "desc", label: "Newest" },
51540
+ { value: "asc", label: "Oldest" }
51541
+ ];
51542
+ function RowsSkeleton() {
51543
+ return jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-hidden", children: Array.from({ length: 16 }, (_2, i) => jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0", style: { height: 40 }, children: [jsxRuntimeExports.jsxs("div", { className: "relative flex-shrink-0 self-stretch flex items-center", style: { width: GUTTER_WIDTH }, children: [jsxRuntimeExports.jsx("div", { style: {
51544
+ position: "absolute",
51545
+ left: 8,
51546
+ top: i === 0 ? "50%" : 0,
51547
+ bottom: 0,
51548
+ width: 2
51549
+ }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "w-full h-full", style: { borderRadius: 1 } }) }), jsxRuntimeExports.jsx(Skeleton$2, { className: "flex-shrink-0", style: {
51550
+ width: i % 4 === 0 ? 8 : 6,
51551
+ height: i % 4 === 0 ? 8 : 6,
51552
+ borderRadius: "50%",
51553
+ marginLeft: i % 4 === 0 ? 5 : 6
51554
+ } })] }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0 flex items-center justify-center", children: jsxRuntimeExports.jsx(Skeleton$2, { className: "w-5 h-5", style: { borderRadius: 4 } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "70%" } }) }), jsxRuntimeExports.jsxs("div", { className: "min-w-0 px-4 flex items-center gap-1.5", style: { flex: "2 1 0%" }, children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "flex-shrink-0", style: { width: 6, height: 6, borderRadius: "50%" } }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "60%" } })] }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "50%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "75%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "75%" } }) })] }, i)) });
51555
+ }
51556
+ function EventRow$1({ event, index: index2, isFirst, isLast, isExpanded, onToggleExpand, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData, onCacheEventData, encryptionKey, onEncryptedDataDetected }) {
51557
+ const [isLoading, setIsLoading] = reactExports.useState(false);
51558
+ const [loadedEventData, setLoadedEventData] = reactExports.useState(cachedEventData);
51559
+ const [loadError, setLoadError] = reactExports.useState(null);
51560
+ const [hasAttemptedLoad, setHasAttemptedLoad] = reactExports.useState(cachedEventData !== null);
51561
+ reactExports.useEffect(() => {
51562
+ if (cachedEventData !== null && !encryptionKey && hasEncryptedValues(cachedEventData)) {
51563
+ onEncryptedDataDetected == null ? void 0 : onEncryptedDataDetected();
51564
+ }
51565
+ }, []);
51566
+ const rowGroupKey = isRunLevel(event.eventType) ? "__run__" : event.correlationId ?? void 0;
51567
+ const statusDotColor = getStatusDotColor(event.eventType);
51568
+ const createdAt = new Date(event.createdAt);
51569
+ const hasExistingEventData = "eventData" in event && event.eventData != null;
51570
+ const isRun = isRunLevel(event.eventType);
51571
+ const eventName2 = isRun ? workflowName ?? "-" : event.correlationId ? correlationNameMap.get(event.correlationId) ?? "-" : "-";
51572
+ const durationKey = event.correlationId ?? (isRun ? "__run__" : "");
51573
+ const durationInfo = durationKey ? durationMap.get(durationKey) : void 0;
51574
+ const hasActive = activeGroupKey !== void 0;
51575
+ const isRelated = rowGroupKey !== void 0 && rowGroupKey === activeGroupKey;
51576
+ const isDimmed = hasActive && !isRelated;
51577
+ const isPulsing = hasActive && isRelated;
51578
+ const showBranch = hasActive && isRelated && !isRun;
51579
+ const showLaneLine = selectedGroupRange !== null && index2 >= selectedGroupRange.first && index2 <= selectedGroupRange.last;
51580
+ const isLaneStart = selectedGroupRange !== null && index2 === selectedGroupRange.first;
51581
+ const isLaneEnd = selectedGroupRange !== null && index2 === selectedGroupRange.last;
51582
+ const loadEventDetails = reactExports.useCallback(async () => {
51583
+ if (loadedEventData !== null) {
51584
+ return;
51585
+ }
51586
+ if (cachedEventData !== null) {
51587
+ setLoadedEventData(cachedEventData);
51588
+ setHasAttemptedLoad(true);
51589
+ return;
51590
+ }
51591
+ if (isLoading) {
51592
+ return;
51593
+ }
51594
+ setIsLoading(true);
51595
+ setLoadError(null);
51596
+ try {
51597
+ if (!onLoadEventData) {
51598
+ setLoadError("Event details unavailable");
51599
+ return;
51600
+ }
51601
+ const data = await onLoadEventData(event);
51602
+ if (data !== null && data !== void 0) {
51603
+ setLoadedEventData(data);
51604
+ onCacheEventData(event.eventId, data);
51605
+ if (!encryptionKey && hasEncryptedValues(data)) {
51606
+ onEncryptedDataDetected == null ? void 0 : onEncryptedDataDetected();
51607
+ }
51608
+ }
51609
+ } catch (err) {
51610
+ setLoadError(err instanceof Error ? err.message : "Failed to load event details");
51611
+ } finally {
51612
+ setIsLoading(false);
51613
+ setHasAttemptedLoad(true);
51614
+ }
51615
+ }, [
51616
+ event,
51617
+ loadedEventData,
51618
+ isLoading,
51619
+ onLoadEventData,
51620
+ onCacheEventData,
51621
+ encryptionKey,
51622
+ onEncryptedDataDetected,
51623
+ cachedEventData
51624
+ ]);
51625
+ reactExports.useEffect(() => {
51626
+ if (!isExpanded || isLoading) {
51627
+ return;
51628
+ }
51629
+ void loadEventDetails();
51630
+ }, []);
51631
+ reactExports.useEffect(() => {
51632
+ if (encryptionKey && hasAttemptedLoad && onLoadEventData) {
51633
+ setLoadedEventData(null);
51634
+ setHasAttemptedLoad(false);
51635
+ onLoadEventData(event).then((data) => {
51636
+ if (data !== null && data !== void 0) {
51637
+ setLoadedEventData(data);
51638
+ onCacheEventData(event.eventId, data);
51639
+ }
51640
+ setHasAttemptedLoad(true);
51641
+ }).catch(() => {
51642
+ setHasAttemptedLoad(true);
51643
+ });
51644
+ }
51645
+ }, [encryptionKey]);
51646
+ const handleRowClick = reactExports.useCallback(() => {
51647
+ onSelectGroup(rowGroupKey === selectedGroupKey ? void 0 : rowGroupKey);
51648
+ onToggleExpand(event.eventId);
51649
+ if (!isExpanded) {
51650
+ void loadEventDetails();
51651
+ }
51652
+ }, [
51653
+ selectedGroupKey,
51654
+ rowGroupKey,
51655
+ onSelectGroup,
51656
+ onToggleExpand,
51657
+ event.eventId,
51658
+ isExpanded,
51659
+ loadEventDetails
51660
+ ]);
51661
+ const mergedEventData = loadedEventData ?? (hasExistingEventData ? event.eventData : null);
51662
+ const displayPayload = isLoading ? loadedEventData : mergedEventData;
51663
+ const contentOpacity = isDimmed ? 0.3 : 1;
51664
+ return jsxRuntimeExports.jsxs("div", { "data-event-id": event.eventId, onMouseEnter: () => onHoverGroup(rowGroupKey), onMouseLeave: () => onHoverGroup(void 0), children: [jsxRuntimeExports.jsxs("div", { role: "button", tabIndex: 0, onClick: handleRowClick, onKeyDown: (e) => {
51665
+ if (e.key === "Enter" || e.key === " ")
51666
+ handleRowClick();
51667
+ }, className: "w-full text-left flex items-center gap-0 text-[13px] hover:bg-[var(--ds-gray-alpha-100)] transition-colors cursor-pointer", style: { minHeight: 40 }, children: [jsxRuntimeExports.jsx(TreeGutter, { isFirst, isLast: isLast && !isExpanded, isRunLevel: isRun, statusDotColor, pulse: isPulsing, hasSelection: hasActive, showBranch, showLaneLine, isLaneStart, isLaneEnd }), jsxRuntimeExports.jsxs("div", { className: "flex items-center flex-1 min-w-0", style: { opacity: contentOpacity, transition: "opacity 150ms" }, children: [jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center w-5 h-5 flex-shrink-0 rounded", style: {
51668
+ border: "1px solid var(--ds-gray-400)"
51669
+ }, children: jsxRuntimeExports.jsx(ChevronRight, { className: "h-3 w-3 transition-transform", style: {
51670
+ color: "var(--ds-gray-900)",
51671
+ transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)"
51672
+ } }) }), jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(TimestampTooltip, { date: createdAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(createdAt) }) }) }), jsxRuntimeExports.jsx("div", { className: "font-medium min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5", style: { color: "var(--ds-gray-900)" }, children: [jsxRuntimeExports.jsxs("span", { style: {
51673
+ position: "relative",
51674
+ display: "inline-flex",
51675
+ width: 6,
51676
+ height: 6,
51677
+ flexShrink: 0
51678
+ }, children: [isPulsing && jsxRuntimeExports.jsx("span", { style: {
51679
+ position: "absolute",
51680
+ inset: 0,
51681
+ borderRadius: "50%",
51682
+ backgroundColor: statusDotColor,
51683
+ opacity: 0.75,
51684
+ animation: DOT_PULSE_ANIMATION
51685
+ } }), jsxRuntimeExports.jsx("span", { style: {
51686
+ position: "relative",
51687
+ width: 6,
51688
+ height: 6,
51689
+ borderRadius: "50%",
51690
+ backgroundColor: statusDotColor
51691
+ } })] }), formatEventType(event.eventType)] }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4 overflow-hidden text-ellipsis whitespace-nowrap", style: { flex: "2 1 0%" }, title: eventName2 !== "-" ? eventName2 : void 0, children: eventName2 }), jsxRuntimeExports.jsx(CopyableCell, { value: event.correlationId || "", className: "font-mono", style: { flex: "3 1 0%" } }), jsxRuntimeExports.jsx(CopyableCell, { value: event.eventId, className: "font-mono", style: { flex: "3 1 0%" } })] })] }), isExpanded && jsxRuntimeExports.jsxs("div", { className: "flex", children: [jsxRuntimeExports.jsx(TreeGutter, { isFirst: false, isLast, isRunLevel: isRun, hasSelection: hasActive, showBranch: false, showLaneLine: showLaneLine && !isLaneEnd, isLaneStart: false, isLaneEnd: false, continuationOnly: true }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0" }), jsxRuntimeExports.jsxs("div", { className: "flex-1 my-1.5 mr-3 ml-2 py-2 rounded-md border overflow-hidden", style: {
51692
+ borderColor: "var(--ds-gray-alpha-200)",
51693
+ opacity: contentOpacity,
51694
+ transition: "opacity 150ms"
51695
+ }, children: [((durationInfo == null ? void 0 : durationInfo.queued) !== void 0 || (durationInfo == null ? void 0 : durationInfo.ran) !== void 0) && jsxRuntimeExports.jsxs("div", { className: "px-2 pb-1.5 text-xs flex gap-3", style: { color: "var(--ds-gray-900)" }, children: [durationInfo.queued !== void 0 && durationInfo.queued > 0 && jsxRuntimeExports.jsxs("span", { children: ["Queued for", " ", jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatDuration(durationInfo.queued) })] }), durationInfo.ran !== void 0 && jsxRuntimeExports.jsxs("span", { children: ["Ran for", " ", jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatDuration(durationInfo.ran) })] })] }), displayPayload != null ? jsxRuntimeExports.jsx(PayloadBlock, { data: displayPayload, eventType: event.eventType }) : loadError ? jsxRuntimeExports.jsx("div", { className: "rounded-md border p-3 text-xs", style: {
51696
+ borderColor: "var(--ds-red-400)",
51697
+ backgroundColor: "var(--ds-red-100)",
51698
+ color: "var(--ds-red-900)"
51699
+ }, children: loadError }) : isLoading || loadedEventData === null && !hasAttemptedLoad && event.correlationId ? jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 p-3", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "75%" } }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "50%" } }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "60%" } })] }) : jsxRuntimeExports.jsx("div", { className: "p-2 text-xs", style: { color: "var(--ds-gray-900)" }, children: "No data" })] })] })] });
51700
+ }
51701
+ function EventListView({ events: events2, run, onLoadEventData, hasMoreEvents = false, isLoadingMoreEvents = false, onLoadMoreEvents, encryptionKey, isLoading = false, sortOrder: sortOrderProp, onSortOrderChange, onDecrypt, isDecrypting = false, hasEncryptedData: hasEncryptedDataProp = false }) {
51702
+ const [internalSortOrder, setInternalSortOrder] = reactExports.useState("asc");
51703
+ const effectiveSortOrder = sortOrderProp ?? internalSortOrder;
51704
+ const handleSortOrderChange = reactExports.useCallback((order2) => {
51705
+ if (onSortOrderChange) {
51706
+ onSortOrderChange(order2);
51707
+ } else {
51708
+ setInternalSortOrder(order2);
51709
+ }
51710
+ }, [onSortOrderChange]);
51711
+ const sortedEvents2 = reactExports.useMemo(() => {
51712
+ if (!events2 || events2.length === 0)
51713
+ return [];
51714
+ const dir = effectiveSortOrder === "desc" ? -1 : 1;
51715
+ return [...events2].sort((a2, b2) => dir * (new Date(a2.createdAt).getTime() - new Date(b2.createdAt).getTime()));
51716
+ }, [events2, effectiveSortOrder]);
51717
+ const hasEncryptedInlineData = reactExports.useMemo(() => {
51718
+ if (!events2)
51719
+ return false;
51720
+ for (const event of events2) {
51721
+ const ed = event.eventData;
51722
+ if (hasEncryptedValues(ed))
51723
+ return true;
51724
+ }
51725
+ return false;
51726
+ }, [events2]);
51727
+ const [foundEncryptedInLazyData, setFoundEncryptedInLazyData] = reactExports.useState(false);
51728
+ const handleEncryptedDataDetected = reactExports.useCallback(() => {
51729
+ setFoundEncryptedInLazyData(true);
51730
+ }, []);
51731
+ const hasEncryptedData = hasEncryptedDataProp || hasEncryptedInlineData || foundEncryptedInLazyData;
51732
+ const { correlationNameMap, workflowName } = reactExports.useMemo(() => buildNameMaps(events2 ?? null, run ?? null), [events2, run]);
51733
+ const durationMap = reactExports.useMemo(() => buildDurationMap(sortedEvents2), [sortedEvents2]);
51734
+ const [selectedGroupKey, setSelectedGroupKey] = reactExports.useState(void 0);
51735
+ const [hoveredGroupKey, setHoveredGroupKey] = reactExports.useState(void 0);
51736
+ const onSelectGroup = reactExports.useCallback((groupKey) => {
51737
+ setSelectedGroupKey(groupKey);
51738
+ }, []);
51739
+ const onHoverGroup = reactExports.useCallback((groupKey) => {
51740
+ setHoveredGroupKey(groupKey);
51741
+ }, []);
51742
+ const activeGroupKey = selectedGroupKey ?? hoveredGroupKey;
51743
+ const [expandedEventIds, setExpandedEventIds] = reactExports.useState(() => /* @__PURE__ */ new Set());
51744
+ const toggleEventExpanded = reactExports.useCallback((eventId) => {
51745
+ setExpandedEventIds((prev) => {
51746
+ const next2 = new Set(prev);
51747
+ if (next2.has(eventId)) {
51748
+ next2.delete(eventId);
51749
+ } else {
51750
+ next2.add(eventId);
51751
+ }
51752
+ return next2;
51753
+ });
51754
+ }, []);
51755
+ const eventDataCacheRef = reactExports.useRef(/* @__PURE__ */ new Map());
51756
+ const cacheEventData = reactExports.useCallback((eventId, data) => {
51757
+ eventDataCacheRef.current.set(eventId, data);
51758
+ }, []);
51759
+ const eventGroupKeyMap = reactExports.useMemo(() => {
51760
+ const map2 = /* @__PURE__ */ new Map();
51761
+ for (const ev of sortedEvents2) {
51762
+ const gk = isRunLevel(ev.eventType) ? "__run__" : ev.correlationId ?? "";
51763
+ if (gk)
51764
+ map2.set(ev.eventId, gk);
51765
+ }
51766
+ return map2;
51767
+ }, [sortedEvents2]);
51768
+ reactExports.useEffect(() => {
51769
+ if (selectedGroupKey === void 0)
51770
+ return;
51771
+ setExpandedEventIds((prev) => {
51772
+ if (prev.size === 0)
51773
+ return prev;
51774
+ let changed = false;
51775
+ const next2 = /* @__PURE__ */ new Set();
51776
+ for (const eventId of prev) {
51777
+ if (eventGroupKeyMap.get(eventId) === selectedGroupKey) {
51778
+ next2.add(eventId);
51779
+ } else {
51780
+ changed = true;
51781
+ }
51782
+ }
51783
+ return changed ? next2 : prev;
51784
+ });
51785
+ }, [selectedGroupKey, eventGroupKeyMap]);
51786
+ const selectedGroupRange = reactExports.useMemo(() => {
51787
+ if (!activeGroupKey || activeGroupKey === "__run__")
51788
+ return null;
51789
+ let first = -1;
51790
+ let last = -1;
51791
+ for (let i = 0; i < sortedEvents2.length; i++) {
51792
+ if (sortedEvents2[i].correlationId === activeGroupKey) {
51793
+ if (first === -1)
51794
+ first = i;
51795
+ last = i;
51796
+ }
51797
+ }
51798
+ return first >= 0 ? { first, last } : null;
51799
+ }, [activeGroupKey, sortedEvents2]);
51800
+ const [searchQuery, setSearchQuery] = reactExports.useState("");
51801
+ const virtuosoRef = reactExports.useRef(null);
51802
+ const searchIndex = reactExports.useMemo(() => {
51803
+ const entries = [];
51804
+ for (let i = 0; i < sortedEvents2.length; i++) {
51805
+ const ev = sortedEvents2[i];
51806
+ const isRun = isRunLevel(ev.eventType);
51807
+ const name2 = isRun ? workflowName ?? "" : ev.correlationId ? correlationNameMap.get(ev.correlationId) ?? "" : "";
51808
+ entries.push({
51809
+ fields: [
51810
+ ev.eventId,
51811
+ ev.correlationId ?? "",
51812
+ ev.eventType,
51813
+ formatEventType(ev.eventType),
51814
+ name2
51815
+ ].map((f2) => f2.toLowerCase()),
51816
+ groupKey: ev.correlationId ?? (isRun ? "__run__" : void 0),
51817
+ eventId: ev.eventId,
51818
+ index: i
51819
+ });
51820
+ }
51821
+ return entries;
51822
+ }, [sortedEvents2, correlationNameMap, workflowName]);
51823
+ reactExports.useEffect(() => {
51824
+ var _a3;
51825
+ const q2 = searchQuery.trim().toLowerCase();
51826
+ if (!q2) {
51827
+ setSelectedGroupKey(void 0);
51828
+ return;
51829
+ }
51830
+ let bestMatch = null;
51831
+ let bestScore = 0;
51832
+ for (const entry2 of searchIndex) {
51833
+ for (const field of entry2.fields) {
51834
+ if (field && field.includes(q2)) {
51835
+ const score = q2.length / field.length;
51836
+ if (score > bestScore) {
51837
+ bestScore = score;
51838
+ bestMatch = entry2;
51839
+ }
51840
+ }
51841
+ }
51842
+ }
51843
+ if (bestMatch) {
51844
+ setSelectedGroupKey(bestMatch.groupKey);
51845
+ (_a3 = virtuosoRef.current) == null ? void 0 : _a3.scrollToIndex({
51846
+ index: bestMatch.index,
51847
+ align: "center",
51848
+ behavior: "smooth"
51849
+ });
51850
+ }
51851
+ }, [searchQuery, searchIndex]);
51852
+ const hasHadEventsRef = reactExports.useRef(false);
51853
+ if (sortedEvents2.length > 0) {
51854
+ hasHadEventsRef.current = true;
51855
+ }
51856
+ const isInitialLoad = isLoading && !hasHadEventsRef.current;
51857
+ const isRefetching = isLoading && hasHadEventsRef.current && sortedEvents2.length === 0;
51858
+ if (isInitialLoad) {
51859
+ return jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col overflow-hidden", children: [jsxRuntimeExports.jsx("div", { style: { padding: 6 }, children: jsxRuntimeExports.jsx(Skeleton$2, { style: { height: 40, borderRadius: 6 } }) }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0 h-10 border-b flex-shrink-0", style: { borderColor: "var(--ds-gray-alpha-200)" }, children: [jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", style: { width: GUTTER_WIDTH } }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: 40 } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: 72 } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: 44 } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: 92 } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: 60 } }) })] }), jsxRuntimeExports.jsx(RowsSkeleton, {})] });
51860
+ }
51861
+ if (!isLoading && (!events2 || events2.length === 0)) {
51862
+ return jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full text-sm", style: { color: "var(--ds-gray-700)" }, children: "No events found" });
51863
+ }
51864
+ return jsxRuntimeExports.jsx(DecryptClickContext.Provider, { value: onDecrypt ? { onDecrypt, isDecrypting } : void 0, children: jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col overflow-hidden", children: [jsxRuntimeExports.jsx("style", { children: `@keyframes workflow-dot-pulse{0%{transform:scale(1);opacity:.7}70%,100%{transform:scale(2.2);opacity:0}}` }), jsxRuntimeExports.jsxs("div", { style: {
51865
+ padding: 6,
51866
+ backgroundColor: "var(--ds-background-100)",
51867
+ display: "flex",
51868
+ gap: 6
51869
+ }, children: [jsxRuntimeExports.jsxs("label", { style: {
51870
+ display: "flex",
51871
+ alignItems: "center",
51872
+ justifyContent: "center",
51873
+ borderRadius: 6,
51874
+ boxShadow: "0 0 0 1px var(--ds-gray-alpha-400)",
51875
+ background: "var(--ds-background-100)",
51876
+ height: 40,
51877
+ flex: 1,
51878
+ minWidth: 0
51879
+ }, children: [jsxRuntimeExports.jsx("div", { style: {
51880
+ width: 40,
51881
+ height: 40,
51882
+ display: "flex",
51883
+ alignItems: "center",
51884
+ justifyContent: "center",
51885
+ color: "var(--ds-gray-800)",
51886
+ flexShrink: 0
51887
+ }, children: jsxRuntimeExports.jsxs("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", focusable: "false", children: [jsxRuntimeExports.jsx("circle", { cx: "7", cy: "7", r: "4.5", stroke: "currentColor", strokeWidth: "1.5" }), jsxRuntimeExports.jsx("path", { d: "M11.5 11.5L14 14", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })] }) }), jsxRuntimeExports.jsx("input", { type: "search", placeholder: "Search by name, event type, or ID…", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), style: {
51888
+ marginLeft: -16,
51889
+ paddingInline: 12,
51890
+ fontFamily: "inherit",
51891
+ fontSize: 14,
51892
+ background: "transparent",
51893
+ border: "none",
51894
+ outline: "none",
51895
+ height: 40,
51896
+ width: "100%"
51897
+ } })] }), jsxRuntimeExports.jsx(MenuDropdown, { options: SORT_OPTIONS, value: effectiveSortOrder, onChange: handleSortOrderChange }), (hasEncryptedData || encryptionKey) && onDecrypt && jsxRuntimeExports.jsx(DecryptButton, { decrypted: !!encryptionKey, loading: isDecrypting, onClick: onDecrypt })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0 text-[13px] font-medium h-10 border-b flex-shrink-0", style: {
51898
+ borderColor: "var(--ds-gray-alpha-200)",
51899
+ color: "var(--ds-gray-900)",
51900
+ backgroundColor: "var(--ds-background-100)"
51901
+ }, children: [jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", style: { width: GUTTER_WIDTH } }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Time" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Event Type" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Name" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: "Correlation ID" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: "Event ID" })] }), isRefetching ? jsxRuntimeExports.jsx(RowsSkeleton, {}) : jsxRuntimeExports.jsx(Yr, { ref: virtuosoRef, totalCount: sortedEvents2.length, overscan: 20, defaultItemHeight: 40, endReached: () => {
51902
+ if (!hasMoreEvents || isLoadingMoreEvents) {
51903
+ return;
51904
+ }
51905
+ void (onLoadMoreEvents == null ? void 0 : onLoadMoreEvents());
51906
+ }, itemContent: (index2) => {
51907
+ const ev = sortedEvents2[index2];
51908
+ return jsxRuntimeExports.jsx(EventRow$1, { event: ev, index: index2, isFirst: index2 === 0, isLast: index2 === sortedEvents2.length - 1, isExpanded: expandedEventIds.has(ev.eventId), onToggleExpand: toggleEventExpanded, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData: eventDataCacheRef.current.get(ev.eventId) ?? null, onCacheEventData: cacheEventData, encryptionKey, onEncryptedDataDetected: handleEncryptedDataDetected });
51909
+ }, style: { flex: 1, minHeight: 0 } }), jsxRuntimeExports.jsxs("div", { className: "relative flex-shrink-0 flex items-center h-10 border-t px-4 text-xs", style: {
51910
+ borderColor: "var(--ds-gray-alpha-200)",
51911
+ color: "var(--ds-gray-900)",
51912
+ backgroundColor: "var(--ds-background-100)"
51913
+ }, children: [jsxRuntimeExports.jsxs("span", { children: [sortedEvents2.length, " event", sortedEvents2.length !== 1 ? "s" : "", " loaded"] }), hasMoreEvents && jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: jsxRuntimeExports.jsx("div", { className: "pointer-events-auto", children: jsxRuntimeExports.jsx(LoadMoreButton, { loading: isLoadingMoreEvents, onClick: () => void (onLoadMoreEvents == null ? void 0 : onLoadMoreEvents()) }) }) })] })] }) });
51914
+ }
50799
51915
  function __insertCSS(code2) {
50800
51916
  if (typeof document == "undefined") return;
50801
51917
  let head = document.head || document.getElementsByTagName("head")[0];
@@ -51885,927 +53001,6 @@ const ToastContext = reactExports.createContext(defaultAdapter);
51885
53001
  function useToast() {
51886
53002
  return reactExports.useContext(ToastContext);
51887
53003
  }
51888
- function isStructuredErrorWithStack(value) {
51889
- return value != null && typeof value === "object" && "stack" in value && typeof value.stack === "string";
51890
- }
51891
- function deriveTitle(message2) {
51892
- const firstLine = message2.split("\n").find((line) => line.trim().length > 0) ?? message2;
51893
- return firstLine.trim();
51894
- }
51895
- function ErrorStackBlock({ value }) {
51896
- const toast2 = useToast();
51897
- const stack = value.stack;
51898
- const message2 = typeof value.message === "string" ? value.message : void 0;
51899
- const title = message2 ? deriveTitle(message2) : void 0;
51900
- const copyText = message2 ? `${message2}
51901
-
51902
- ${stack}` : stack;
51903
- return jsxRuntimeExports.jsxs("div", { className: "relative overflow-hidden rounded-md border", style: {
51904
- borderColor: "var(--ds-red-400)",
51905
- background: "var(--ds-red-100)"
51906
- }, children: [jsxRuntimeExports.jsx("button", { type: "button", "aria-label": "Copy error", title: "Copy", className: "!absolute !right-2 !top-2 !flex !h-6 !w-6 !items-center !justify-center !rounded-md !border transition-transform transition-colors duration-100 hover:!bg-[var(--ds-red-200)] active:!scale-95", style: {
51907
- borderColor: "var(--ds-red-400)",
51908
- background: "var(--ds-red-100)",
51909
- color: "var(--ds-red-900)"
51910
- }, onClick: () => {
51911
- navigator.clipboard.writeText(copyText).then(() => {
51912
- toast2.success("Copied to clipboard");
51913
- }).catch(() => {
51914
- toast2.error("Failed to copy");
51915
- });
51916
- }, children: jsxRuntimeExports.jsx(Copy, { size: 12 }) }), title && jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-3 py-2.5 pr-10", style: {
51917
- color: "var(--ds-red-900)",
51918
- borderBottom: "1px solid var(--ds-red-400)"
51919
- }, children: [jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4 shrink-0" }), jsxRuntimeExports.jsx("p", {
51920
- className: "text-xs font-semibold m-0 truncate",
51921
- // The full multi-line message is in the stack body below; the
51922
- // header just shows the first line, single-line, with overflow
51923
- // ellipsised so a long title doesn't push the copy button or
51924
- // wrap into the framed hint/docs lines.
51925
- title: message2,
51926
- children: title
51927
- })] }), jsxRuntimeExports.jsx("pre", { className: "px-3 py-2.5 text-xs font-mono whitespace-pre-wrap break-words overflow-auto m-0", style: {
51928
- color: "var(--ds-red-900)",
51929
- background: "var(--ds-red-200)"
51930
- }, children: stack })] });
51931
- }
51932
- const STYLES$1 = `.wf-load-more{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;border-radius:6px;font-size:13px;font-weight:500;line-height:20px;color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400);cursor:pointer;white-space:nowrap;gap:6px;transition:background 150ms}.wf-load-more:hover{background:var(--ds-gray-alpha-200)}.wf-load-more:disabled{opacity:.6;cursor:default}.wf-load-more:disabled:hover{background:var(--ds-background-100)}`;
51933
- function LoadMoreButton({ loading = false, onClick, label = "Load more", loadingLabel = "Loading..." }) {
51934
- return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { dangerouslySetInnerHTML: { __html: STYLES$1 } }), jsxRuntimeExports.jsxs("button", { type: "button", onClick, disabled: loading, className: "wf-load-more", children: [loading && jsxRuntimeExports.jsx(Spinner, { size: 14 }), loading ? loadingLabel : label] })] });
51935
- }
51936
- const STYLES = `.wf-menu-btn{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:40px;padding:0 12px;border-radius:6px;font-size:14px;font-weight:500;line-height:20px;color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400);cursor:pointer;white-space:nowrap;transition:background 150ms}.wf-menu-btn:hover{background:var(--ds-gray-alpha-200)}.wf-menu-item{appearance:none;-webkit-appearance:none;border:none;display:flex;align-items:center;width:100%;height:40px;padding:0 8px;border-radius:6px;font-size:14px;color:var(--ds-gray-1000);background:transparent;cursor:pointer;transition:background 150ms}.wf-menu-item:hover{background:var(--ds-gray-alpha-100)}`;
51937
- function MenuDropdown({ options, value, onChange }) {
51938
- var _a3, _b2;
51939
- const [open, setOpen] = reactExports.useState(false);
51940
- const ref = reactExports.useRef(null);
51941
- const label = ((_a3 = options.find((o) => o.value === value)) == null ? void 0 : _a3.label) ?? ((_b2 = options[0]) == null ? void 0 : _b2.label) ?? "";
51942
- reactExports.useEffect(() => {
51943
- if (!open)
51944
- return;
51945
- function handleClickOutside(e) {
51946
- if (ref.current && !ref.current.contains(e.target)) {
51947
- setOpen(false);
51948
- }
51949
- }
51950
- document.addEventListener("mousedown", handleClickOutside);
51951
- return () => document.removeEventListener("mousedown", handleClickOutside);
51952
- }, [open]);
51953
- return jsxRuntimeExports.jsxs("div", { ref, style: { position: "relative", flexShrink: 0 }, children: [jsxRuntimeExports.jsx("style", { dangerouslySetInnerHTML: { __html: STYLES } }), jsxRuntimeExports.jsxs("button", { type: "button", className: "wf-menu-btn", onClick: () => setOpen(!open), children: [jsxRuntimeExports.jsx("span", { children: label }), jsxRuntimeExports.jsx("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", style: {
51954
- marginLeft: 16,
51955
- marginRight: -4,
51956
- color: "var(--ds-gray-900)"
51957
- }, children: jsxRuntimeExports.jsx("path", { d: "M4.5 6L8 9.5L11.5 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })] }), open && jsxRuntimeExports.jsx("div", { style: {
51958
- position: "absolute",
51959
- right: 0,
51960
- top: "100%",
51961
- marginTop: 4,
51962
- minWidth: 140,
51963
- padding: 4,
51964
- borderRadius: 12,
51965
- background: "var(--ds-background-100)",
51966
- boxShadow: "var(--ds-shadow-menu, var(--ds-shadow-medium))",
51967
- zIndex: 2001
51968
- }, role: "menu", children: options.map((option) => jsxRuntimeExports.jsx("button", { type: "button", role: "menuitem", className: "wf-menu-item", style: {
51969
- fontWeight: option.value === value ? 500 : 400
51970
- }, onClick: () => {
51971
- onChange(option.value);
51972
- setOpen(false);
51973
- }, children: option.label }, option.value)) })] });
51974
- }
51975
- function Skeleton$2({ className, style: style2, ...props }) {
51976
- return jsxRuntimeExports.jsx("div", { ...props, className: cn$4("rounded-md", className), style: { backgroundColor: "var(--ds-gray-200)", ...style2 } });
51977
- }
51978
- const TIME_UNITS = [
51979
- { unit: "year", ms: 31536e6 },
51980
- { unit: "month", ms: 2628e6 },
51981
- { unit: "day", ms: 864e5 },
51982
- { unit: "hour", ms: 36e5 },
51983
- { unit: "minute", ms: 6e4 },
51984
- { unit: "second", ms: 1e3 }
51985
- ];
51986
- function formatTimeDifference(diff) {
51987
- let remaining = Math.abs(diff);
51988
- const result = [];
51989
- for (const { unit, ms: ms2 } of TIME_UNITS) {
51990
- const value = Math.floor(remaining / ms2);
51991
- if (value > 0 || result.length > 0) {
51992
- result.push(`${value} ${unit}${value !== 1 ? "s" : ""}`);
51993
- remaining %= ms2;
51994
- }
51995
- if (result.length === 3)
51996
- break;
51997
- }
51998
- return result.join(", ");
51999
- }
52000
- function useTimeAgo(date2) {
52001
- const [timeAgo, setTimeAgo] = reactExports.useState("");
52002
- reactExports.useEffect(() => {
52003
- const update = () => {
52004
- const diff = Date.now() - date2;
52005
- const formatted = formatTimeDifference(diff);
52006
- setTimeAgo(formatted ? `${formatted} ago` : "Just now");
52007
- };
52008
- update();
52009
- const timer2 = setInterval(update, 1e3);
52010
- return () => clearInterval(timer2);
52011
- }, [date2]);
52012
- return timeAgo;
52013
- }
52014
- function ZoneDateTimeRow({ date: date2, zone }) {
52015
- var _a3;
52016
- const dateObj = new Date(date2);
52017
- const formattedZone = ((_a3 = new Intl.DateTimeFormat("en-US", {
52018
- timeZone: zone,
52019
- timeZoneName: "short"
52020
- }).formatToParts(dateObj).find((part) => part.type === "timeZoneName")) == null ? void 0 : _a3.value) || zone;
52021
- const formattedDate = dateObj.toLocaleString("en-US", {
52022
- timeZone: zone,
52023
- year: "numeric",
52024
- month: "long",
52025
- day: "numeric"
52026
- });
52027
- const formattedTime = dateObj.toLocaleTimeString("en-US", {
52028
- timeZone: zone,
52029
- hour: "2-digit",
52030
- minute: "2-digit",
52031
- second: "2-digit"
52032
- });
52033
- return jsxRuntimeExports.jsxs("div", { style: {
52034
- display: "flex",
52035
- alignItems: "center",
52036
- justifyContent: "space-between",
52037
- gap: 12
52038
- }, children: [jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [jsxRuntimeExports.jsx("div", { style: {
52039
- display: "inline-flex",
52040
- alignItems: "center",
52041
- justifyContent: "center",
52042
- height: 16,
52043
- padding: "0 6px",
52044
- backgroundColor: "var(--ds-gray-200)",
52045
- borderRadius: 3,
52046
- fontSize: 11,
52047
- fontFamily: "var(--font-mono, monospace)",
52048
- fontWeight: 500,
52049
- color: "var(--ds-gray-900)",
52050
- whiteSpace: "nowrap"
52051
- }, children: formattedZone }), jsxRuntimeExports.jsx("span", { style: {
52052
- fontSize: 13,
52053
- color: "var(--ds-gray-1000)",
52054
- whiteSpace: "nowrap"
52055
- }, children: formattedDate })] }), jsxRuntimeExports.jsx("span", { style: {
52056
- fontSize: 11,
52057
- fontFamily: "var(--font-mono, monospace)",
52058
- fontVariantNumeric: "tabular-nums",
52059
- color: "var(--ds-gray-900)",
52060
- whiteSpace: "nowrap"
52061
- }, children: formattedTime })] });
52062
- }
52063
- function TimestampTooltipContent({ date: date2 }) {
52064
- const localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
52065
- const timeAgo = useTimeAgo(date2);
52066
- return jsxRuntimeExports.jsxs("div", { style: {
52067
- display: "flex",
52068
- flexDirection: "column",
52069
- gap: 12,
52070
- minWidth: 300,
52071
- padding: "12px 14px"
52072
- }, children: [jsxRuntimeExports.jsx("span", { style: {
52073
- fontSize: 13,
52074
- fontVariantNumeric: "tabular-nums",
52075
- color: "var(--ds-gray-900)"
52076
- }, children: timeAgo }), jsxRuntimeExports.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [jsxRuntimeExports.jsx(ZoneDateTimeRow, { date: date2, zone: "UTC" }), jsxRuntimeExports.jsx(ZoneDateTimeRow, { date: date2, zone: localTimezone })] })] });
52077
- }
52078
- const TOOLTIP_WIDTH = 330;
52079
- const VIEWPORT_PAD = 8;
52080
- function TooltipPortal({ triggerRect, onMouseEnter, onMouseLeave, date: date2 }) {
52081
- const tooltipRef = reactExports.useRef(null);
52082
- const [style2, setStyle] = reactExports.useState({
52083
- position: "fixed",
52084
- zIndex: 9999,
52085
- visibility: "hidden"
52086
- });
52087
- reactExports.useEffect(() => {
52088
- const placement = triggerRect.top > 240 ? "above" : "below";
52089
- const centerX = triggerRect.left + triggerRect.width / 2;
52090
- const el = tooltipRef.current;
52091
- const w2 = el ? el.offsetWidth : TOOLTIP_WIDTH;
52092
- const h2 = el ? el.offsetHeight : 100;
52093
- let left = centerX - w2 / 2;
52094
- left = Math.max(VIEWPORT_PAD, Math.min(left, window.innerWidth - w2 - VIEWPORT_PAD));
52095
- let top;
52096
- if (placement === "above") {
52097
- top = triggerRect.top - h2 - 6;
52098
- if (top < VIEWPORT_PAD) {
52099
- top = triggerRect.bottom + 6;
52100
- }
52101
- } else {
52102
- top = triggerRect.bottom + 6;
52103
- if (top + h2 > window.innerHeight - VIEWPORT_PAD) {
52104
- top = triggerRect.top - h2 - 6;
52105
- }
52106
- }
52107
- setStyle({
52108
- position: "fixed",
52109
- left,
52110
- top,
52111
- zIndex: 9999,
52112
- borderRadius: 10,
52113
- border: "1px solid var(--ds-gray-alpha-200)",
52114
- backgroundColor: "var(--ds-background-100)",
52115
- boxShadow: "0 4px 12px rgba(0,0,0,0.08), 0 1px 3px rgba(0,0,0,0.06)",
52116
- visibility: "visible"
52117
- });
52118
- }, [triggerRect]);
52119
- return reactDomExports.createPortal(
52120
- // biome-ignore lint/a11y/noStaticElementInteractions: tooltip hover zone
52121
- jsxRuntimeExports.jsx("div", { ref: tooltipRef, onMouseEnter, onMouseLeave, style: style2, children: jsxRuntimeExports.jsx(TimestampTooltipContent, { date: date2 }) }),
52122
- document.body
52123
- );
52124
- }
52125
- function TimestampTooltip({ date: date2, children: children2 }) {
52126
- const [open, setOpen] = reactExports.useState(false);
52127
- const [triggerRect, setTriggerRect] = reactExports.useState(null);
52128
- const triggerRef = reactExports.useRef(null);
52129
- const closeTimer = reactExports.useRef(null);
52130
- reactExports.useEffect(() => {
52131
- return () => {
52132
- if (closeTimer.current)
52133
- clearTimeout(closeTimer.current);
52134
- };
52135
- }, []);
52136
- const ts = date2 == null ? null : typeof date2 === "number" ? date2 : new Date(date2).getTime();
52137
- if (ts == null || Number.isNaN(ts))
52138
- return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: children2 });
52139
- const cancelClose = () => {
52140
- if (closeTimer.current) {
52141
- clearTimeout(closeTimer.current);
52142
- closeTimer.current = null;
52143
- }
52144
- };
52145
- const scheduleClose = () => {
52146
- cancelClose();
52147
- closeTimer.current = setTimeout(() => setOpen(false), 120);
52148
- };
52149
- const handleOpen = () => {
52150
- cancelClose();
52151
- if (triggerRef.current) {
52152
- setTriggerRect(triggerRef.current.getBoundingClientRect());
52153
- }
52154
- setOpen(true);
52155
- };
52156
- return (
52157
- // biome-ignore lint/a11y/noStaticElementInteractions: tooltip trigger
52158
- jsxRuntimeExports.jsxs("span", { ref: triggerRef, onMouseEnter: handleOpen, onMouseLeave: scheduleClose, style: { display: "inline-flex" }, children: [children2, open && triggerRect && jsxRuntimeExports.jsx(TooltipPortal, { triggerRect, onMouseEnter: cancelClose, onMouseLeave: scheduleClose, date: ts })] })
52159
- );
52160
- }
52161
- const ERROR_EVENT_TYPES$1 = /* @__PURE__ */ new Set([
52162
- "step_failed",
52163
- "step_retrying",
52164
- "run_failed",
52165
- "workflow_failed"
52166
- ]);
52167
- const BUTTON_RESET_STYLE = {
52168
- appearance: "none",
52169
- WebkitAppearance: "none",
52170
- border: "none",
52171
- background: "transparent"
52172
- };
52173
- const DOT_PULSE_ANIMATION = "workflow-dot-pulse 1.25s cubic-bezier(0, 0, 0.2, 1) infinite";
52174
- function formatEventTime(date2) {
52175
- return date2.toLocaleTimeString("en-US", {
52176
- hour: "2-digit",
52177
- minute: "2-digit",
52178
- second: "2-digit",
52179
- hour12: false
52180
- }) + "." + date2.getMilliseconds().toString().padStart(3, "0");
52181
- }
52182
- function formatEventType(eventType) {
52183
- return eventType.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
52184
- }
52185
- function getStatusDotColor(eventType) {
52186
- if (eventType === "step_failed" || eventType === "run_failed" || eventType === "workflow_failed") {
52187
- return "var(--ds-red-700)";
52188
- }
52189
- if (eventType === "run_cancelled") {
52190
- return "var(--ds-amber-700)";
52191
- }
52192
- if (eventType === "step_retrying") {
52193
- return "var(--ds-amber-700)";
52194
- }
52195
- if (eventType === "step_completed" || eventType === "run_completed" || eventType === "workflow_completed" || eventType === "hook_disposed" || eventType === "wait_completed") {
52196
- return "var(--ds-green-700)";
52197
- }
52198
- if (eventType === "step_started" || eventType === "run_started" || eventType === "workflow_started" || eventType === "hook_received") {
52199
- return "var(--ds-blue-700)";
52200
- }
52201
- return "var(--ds-gray-600)";
52202
- }
52203
- function buildNameMaps(events2, run) {
52204
- var _a3, _b2;
52205
- const correlationNameMap = /* @__PURE__ */ new Map();
52206
- if (events2) {
52207
- for (const event of events2) {
52208
- if (event.eventType === "step_created" && event.correlationId) {
52209
- const stepName = ((_a3 = event.eventData) == null ? void 0 : _a3.stepName) ?? "";
52210
- const parsed = parseStepName(String(stepName));
52211
- correlationNameMap.set(event.correlationId, (parsed == null ? void 0 : parsed.shortName) ?? stepName);
52212
- }
52213
- }
52214
- }
52215
- const workflowName = (run == null ? void 0 : run.workflowName) ? ((_b2 = parseWorkflowName(run.workflowName)) == null ? void 0 : _b2.shortName) ?? run.workflowName : null;
52216
- return { correlationNameMap, workflowName };
52217
- }
52218
- function buildDurationMap(events2) {
52219
- const createdTimes = /* @__PURE__ */ new Map();
52220
- const startedTimes = /* @__PURE__ */ new Map();
52221
- const durations = /* @__PURE__ */ new Map();
52222
- for (const event of events2) {
52223
- const ts = new Date(event.createdAt).getTime();
52224
- const key = event.correlationId ?? "__run__";
52225
- const type = event.eventType;
52226
- if (type === "step_created" || type === "run_created") {
52227
- createdTimes.set(key, ts);
52228
- }
52229
- if (type === "step_started" || type === "run_started" || type === "workflow_started") {
52230
- startedTimes.set(key, ts);
52231
- if (!createdTimes.has(key)) {
52232
- createdTimes.set(key, ts);
52233
- }
52234
- const createdAt = createdTimes.get(key);
52235
- const info = durations.get(key) ?? {};
52236
- if (createdAt !== void 0) {
52237
- info.queued = ts - createdAt;
52238
- }
52239
- durations.set(key, info);
52240
- }
52241
- if (type === "step_completed" || type === "step_failed" || type === "run_completed" || type === "run_failed" || type === "run_cancelled" || type === "workflow_completed" || type === "workflow_failed" || type === "wait_completed" || type === "hook_disposed") {
52242
- const startedAt = startedTimes.get(key);
52243
- const info = durations.get(key) ?? {};
52244
- if (startedAt !== void 0) {
52245
- info.ran = ts - startedAt;
52246
- }
52247
- durations.set(key, info);
52248
- }
52249
- }
52250
- return durations;
52251
- }
52252
- function hasEncryptedValues(data) {
52253
- if (!data || typeof data !== "object")
52254
- return false;
52255
- for (const val of Object.values(data)) {
52256
- if (isEncryptedMarker(val))
52257
- return true;
52258
- }
52259
- return false;
52260
- }
52261
- function isRunLevel(eventType) {
52262
- return eventType === "run_created" || eventType === "run_started" || eventType === "run_completed" || eventType === "run_failed" || eventType === "run_cancelled" || eventType === "workflow_started" || eventType === "workflow_completed" || eventType === "workflow_failed";
52263
- }
52264
- const GUTTER_WIDTH = 36;
52265
- const LANE_X = 20;
52266
- const ROOT_LINE_COLOR = "var(--ds-gray-500)";
52267
- function TreeGutter({ isFirst, isLast, isRunLevel: isRun, statusDotColor, pulse = false, hasSelection, showBranch, showLaneLine, isLaneStart, isLaneEnd, continuationOnly = false }) {
52268
- const dotSize = isRun ? 8 : 6;
52269
- const dotLeft = isRun ? 5 : 6;
52270
- const dotOpacity = hasSelection && !showBranch && !isRun ? 0.3 : 1;
52271
- return jsxRuntimeExports.jsxs("div", { className: "relative flex-shrink-0 self-stretch", style: {
52272
- width: GUTTER_WIDTH,
52273
- minHeight: continuationOnly ? 0 : void 0
52274
- }, children: [jsxRuntimeExports.jsx("div", { style: {
52275
- position: "absolute",
52276
- left: 8,
52277
- top: continuationOnly ? 0 : isFirst ? "50%" : 0,
52278
- bottom: continuationOnly ? 0 : isLast ? "50%" : 0,
52279
- width: 2,
52280
- backgroundColor: ROOT_LINE_COLOR,
52281
- zIndex: 0
52282
- } }), !continuationOnly && jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("div", { style: {
52283
- position: "absolute",
52284
- left: dotLeft,
52285
- top: "50%",
52286
- transform: "translateY(-50%)",
52287
- width: dotSize,
52288
- height: dotSize,
52289
- zIndex: 2
52290
- }, children: [jsxRuntimeExports.jsx("div", { style: {
52291
- position: "absolute",
52292
- inset: 0,
52293
- borderRadius: "50%",
52294
- backgroundColor: "var(--ds-background-100)",
52295
- zIndex: 0
52296
- } }), pulse && jsxRuntimeExports.jsx("div", { style: {
52297
- position: "absolute",
52298
- inset: 0,
52299
- borderRadius: "50%",
52300
- backgroundColor: statusDotColor,
52301
- opacity: 0.75 * dotOpacity,
52302
- animation: DOT_PULSE_ANIMATION,
52303
- zIndex: 1
52304
- } }), jsxRuntimeExports.jsx("div", { style: {
52305
- position: "relative",
52306
- width: "100%",
52307
- height: "100%",
52308
- borderRadius: "50%",
52309
- backgroundColor: statusDotColor,
52310
- opacity: dotOpacity,
52311
- transition: "opacity 150ms",
52312
- zIndex: 2
52313
- } })] }), showBranch && jsxRuntimeExports.jsx("div", { style: {
52314
- position: "absolute",
52315
- left: 9,
52316
- top: "50%",
52317
- width: GUTTER_WIDTH - 9,
52318
- height: 2,
52319
- backgroundColor: ROOT_LINE_COLOR,
52320
- zIndex: 0
52321
- } })] }), showLaneLine && jsxRuntimeExports.jsx("div", { style: {
52322
- position: "absolute",
52323
- left: LANE_X,
52324
- top: continuationOnly ? 0 : isLaneStart ? "50%" : 0,
52325
- bottom: continuationOnly ? 0 : isLaneEnd ? "50%" : 0,
52326
- width: 2,
52327
- backgroundColor: ROOT_LINE_COLOR,
52328
- zIndex: 0
52329
- } })] });
52330
- }
52331
- function CopyableCell({ value, className, style: styleProp }) {
52332
- const [copied, setCopied] = reactExports.useState(false);
52333
- const resetCopiedTimeoutRef = reactExports.useRef(null);
52334
- reactExports.useEffect(() => {
52335
- return () => {
52336
- if (resetCopiedTimeoutRef.current !== null) {
52337
- window.clearTimeout(resetCopiedTimeoutRef.current);
52338
- }
52339
- };
52340
- }, []);
52341
- const handleCopy = reactExports.useCallback((e) => {
52342
- e.stopPropagation();
52343
- navigator.clipboard.writeText(value).then(() => {
52344
- setCopied(true);
52345
- if (resetCopiedTimeoutRef.current !== null) {
52346
- window.clearTimeout(resetCopiedTimeoutRef.current);
52347
- }
52348
- resetCopiedTimeoutRef.current = window.setTimeout(() => {
52349
- setCopied(false);
52350
- resetCopiedTimeoutRef.current = null;
52351
- }, 1500);
52352
- });
52353
- }, [value]);
52354
- return jsxRuntimeExports.jsxs("div", { className: `group/copy flex items-center gap-1 min-w-0 px-4 ${className ?? ""}`, style: styleProp, children: [jsxRuntimeExports.jsx("span", { className: "overflow-hidden text-ellipsis whitespace-nowrap", children: value || "-" }), value ? jsxRuntimeExports.jsx("button", { type: "button", onClick: handleCopy, className: "flex-shrink-0 opacity-0 group-hover/copy:opacity-100 transition-opacity p-0.5 rounded hover:bg-[var(--ds-gray-alpha-200)]", style: BUTTON_RESET_STYLE, "aria-label": `Copy ${value}`, children: copied ? jsxRuntimeExports.jsx(Check, { className: "h-3 w-3", style: { color: "var(--ds-green-700)" } }) : jsxRuntimeExports.jsx(Copy, { className: "h-3 w-3", style: { color: "var(--ds-gray-700)" } }) }) : null] });
52355
- }
52356
- function deepParseJson(value) {
52357
- if (typeof value === "string") {
52358
- const trimmed = value.trim();
52359
- if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]") || trimmed.startsWith('"') && trimmed.endsWith('"')) {
52360
- try {
52361
- return deepParseJson(JSON.parse(trimmed));
52362
- } catch {
52363
- return value;
52364
- }
52365
- }
52366
- return value;
52367
- }
52368
- if (Array.isArray(value)) {
52369
- return value.map(deepParseJson);
52370
- }
52371
- if (value !== null && typeof value === "object") {
52372
- if (value.constructor !== Object) {
52373
- return value;
52374
- }
52375
- const result = {};
52376
- for (const [k2, v2] of Object.entries(value)) {
52377
- result[k2] = deepParseJson(v2);
52378
- }
52379
- return result;
52380
- }
52381
- return value;
52382
- }
52383
- function extractStructuredError(data, eventType) {
52384
- if (!eventType || !ERROR_EVENT_TYPES$1.has(eventType))
52385
- return null;
52386
- if (data == null || typeof data !== "object")
52387
- return null;
52388
- const record2 = data;
52389
- if (isStructuredErrorWithStack(record2.error))
52390
- return record2.error;
52391
- if (isStructuredErrorWithStack(record2))
52392
- return record2;
52393
- return null;
52394
- }
52395
- function PayloadBlock({ data, eventType }) {
52396
- const structuredError = reactExports.useMemo(() => extractStructuredError(data, eventType), [data, eventType]);
52397
- const [copied, setCopied] = reactExports.useState(false);
52398
- const resetCopiedTimeoutRef = reactExports.useRef(null);
52399
- const cleaned = reactExports.useMemo(() => deepParseJson(data), [data]);
52400
- reactExports.useEffect(() => {
52401
- return () => {
52402
- if (resetCopiedTimeoutRef.current !== null) {
52403
- window.clearTimeout(resetCopiedTimeoutRef.current);
52404
- }
52405
- };
52406
- }, []);
52407
- const formatted = reactExports.useMemo(() => {
52408
- try {
52409
- return JSON.stringify(cleaned, null, 2);
52410
- } catch {
52411
- return String(cleaned);
52412
- }
52413
- }, [cleaned]);
52414
- const handleCopy = reactExports.useCallback((e) => {
52415
- e.stopPropagation();
52416
- navigator.clipboard.writeText(formatted).then(() => {
52417
- setCopied(true);
52418
- if (resetCopiedTimeoutRef.current !== null) {
52419
- window.clearTimeout(resetCopiedTimeoutRef.current);
52420
- }
52421
- resetCopiedTimeoutRef.current = window.setTimeout(() => {
52422
- setCopied(false);
52423
- resetCopiedTimeoutRef.current = null;
52424
- }, 1500);
52425
- });
52426
- }, [formatted]);
52427
- if (structuredError) {
52428
- return jsxRuntimeExports.jsx("div", { className: "p-2", children: jsxRuntimeExports.jsx(ErrorStackBlock, { value: structuredError }) });
52429
- }
52430
- return jsxRuntimeExports.jsxs("div", { className: "relative group/payload", children: [jsxRuntimeExports.jsx("div", { className: "overflow-x-auto p-2 text-[11px]", style: { color: "var(--ds-gray-1000)" }, children: jsxRuntimeExports.jsx(DataInspector, { data: cleaned, expandLevel: 2 }) }), jsxRuntimeExports.jsx("button", { type: "button", onClick: handleCopy, className: "absolute bottom-2 right-2 opacity-0 group-hover/payload:opacity-100 transition-opacity flex items-center gap-1 px-2 py-1 rounded-md text-xs hover:bg-[var(--ds-gray-alpha-200)]", style: { ...BUTTON_RESET_STYLE, color: "var(--ds-gray-700)" }, "aria-label": "Copy payload", children: copied ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Check, { className: "h-3 w-3", style: { color: "var(--ds-green-700)" } }), jsxRuntimeExports.jsx("span", { style: { color: "var(--ds-green-700)" }, children: "Copied" })] }) : jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Copy, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { children: "Copy" })] }) })] });
52431
- }
52432
- const SORT_OPTIONS = [
52433
- { value: "desc", label: "Newest" },
52434
- { value: "asc", label: "Oldest" }
52435
- ];
52436
- function RowsSkeleton() {
52437
- return jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-hidden", children: Array.from({ length: 16 }, (_2, i) => jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0", style: { height: 40 }, children: [jsxRuntimeExports.jsxs("div", { className: "relative flex-shrink-0 self-stretch flex items-center", style: { width: GUTTER_WIDTH }, children: [jsxRuntimeExports.jsx("div", { style: {
52438
- position: "absolute",
52439
- left: 8,
52440
- top: i === 0 ? "50%" : 0,
52441
- bottom: 0,
52442
- width: 2
52443
- }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "w-full h-full", style: { borderRadius: 1 } }) }), jsxRuntimeExports.jsx(Skeleton$2, { className: "flex-shrink-0", style: {
52444
- width: i % 4 === 0 ? 8 : 6,
52445
- height: i % 4 === 0 ? 8 : 6,
52446
- borderRadius: "50%",
52447
- marginLeft: i % 4 === 0 ? 5 : 6
52448
- } })] }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0 flex items-center justify-center", children: jsxRuntimeExports.jsx(Skeleton$2, { className: "w-5 h-5", style: { borderRadius: 4 } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "70%" } }) }), jsxRuntimeExports.jsxs("div", { className: "min-w-0 px-4 flex items-center gap-1.5", style: { flex: "2 1 0%" }, children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "flex-shrink-0", style: { width: 6, height: 6, borderRadius: "50%" } }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "60%" } })] }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "50%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "75%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "75%" } }) })] }, i)) });
52449
- }
52450
- function EventRow$1({ event, index: index2, isFirst, isLast, isExpanded, onToggleExpand, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData, onCacheEventData, encryptionKey, onEncryptedDataDetected }) {
52451
- const [isLoading, setIsLoading] = reactExports.useState(false);
52452
- const [loadedEventData, setLoadedEventData] = reactExports.useState(cachedEventData);
52453
- const [loadError, setLoadError] = reactExports.useState(null);
52454
- const [hasAttemptedLoad, setHasAttemptedLoad] = reactExports.useState(cachedEventData !== null);
52455
- reactExports.useEffect(() => {
52456
- if (cachedEventData !== null && !encryptionKey && hasEncryptedValues(cachedEventData)) {
52457
- onEncryptedDataDetected == null ? void 0 : onEncryptedDataDetected();
52458
- }
52459
- }, []);
52460
- const rowGroupKey = isRunLevel(event.eventType) ? "__run__" : event.correlationId ?? void 0;
52461
- const statusDotColor = getStatusDotColor(event.eventType);
52462
- const createdAt = new Date(event.createdAt);
52463
- const hasExistingEventData = "eventData" in event && event.eventData != null;
52464
- const isRun = isRunLevel(event.eventType);
52465
- const eventName2 = isRun ? workflowName ?? "-" : event.correlationId ? correlationNameMap.get(event.correlationId) ?? "-" : "-";
52466
- const durationKey = event.correlationId ?? (isRun ? "__run__" : "");
52467
- const durationInfo = durationKey ? durationMap.get(durationKey) : void 0;
52468
- const hasActive = activeGroupKey !== void 0;
52469
- const isRelated = rowGroupKey !== void 0 && rowGroupKey === activeGroupKey;
52470
- const isDimmed = hasActive && !isRelated;
52471
- const isPulsing = hasActive && isRelated;
52472
- const showBranch = hasActive && isRelated && !isRun;
52473
- const showLaneLine = selectedGroupRange !== null && index2 >= selectedGroupRange.first && index2 <= selectedGroupRange.last;
52474
- const isLaneStart = selectedGroupRange !== null && index2 === selectedGroupRange.first;
52475
- const isLaneEnd = selectedGroupRange !== null && index2 === selectedGroupRange.last;
52476
- const loadEventDetails = reactExports.useCallback(async () => {
52477
- if (loadedEventData !== null) {
52478
- return;
52479
- }
52480
- if (cachedEventData !== null) {
52481
- setLoadedEventData(cachedEventData);
52482
- setHasAttemptedLoad(true);
52483
- return;
52484
- }
52485
- if (isLoading) {
52486
- return;
52487
- }
52488
- setIsLoading(true);
52489
- setLoadError(null);
52490
- try {
52491
- if (!onLoadEventData) {
52492
- setLoadError("Event details unavailable");
52493
- return;
52494
- }
52495
- const data = await onLoadEventData(event);
52496
- if (data !== null && data !== void 0) {
52497
- setLoadedEventData(data);
52498
- onCacheEventData(event.eventId, data);
52499
- if (!encryptionKey && hasEncryptedValues(data)) {
52500
- onEncryptedDataDetected == null ? void 0 : onEncryptedDataDetected();
52501
- }
52502
- }
52503
- } catch (err) {
52504
- setLoadError(err instanceof Error ? err.message : "Failed to load event details");
52505
- } finally {
52506
- setIsLoading(false);
52507
- setHasAttemptedLoad(true);
52508
- }
52509
- }, [
52510
- event,
52511
- loadedEventData,
52512
- isLoading,
52513
- onLoadEventData,
52514
- onCacheEventData,
52515
- encryptionKey,
52516
- onEncryptedDataDetected,
52517
- cachedEventData
52518
- ]);
52519
- reactExports.useEffect(() => {
52520
- if (!isExpanded || isLoading) {
52521
- return;
52522
- }
52523
- void loadEventDetails();
52524
- }, []);
52525
- reactExports.useEffect(() => {
52526
- if (encryptionKey && hasAttemptedLoad && onLoadEventData) {
52527
- setLoadedEventData(null);
52528
- setHasAttemptedLoad(false);
52529
- onLoadEventData(event).then((data) => {
52530
- if (data !== null && data !== void 0) {
52531
- setLoadedEventData(data);
52532
- onCacheEventData(event.eventId, data);
52533
- }
52534
- setHasAttemptedLoad(true);
52535
- }).catch(() => {
52536
- setHasAttemptedLoad(true);
52537
- });
52538
- }
52539
- }, [encryptionKey]);
52540
- const handleRowClick = reactExports.useCallback(() => {
52541
- onSelectGroup(rowGroupKey === selectedGroupKey ? void 0 : rowGroupKey);
52542
- onToggleExpand(event.eventId);
52543
- if (!isExpanded) {
52544
- void loadEventDetails();
52545
- }
52546
- }, [
52547
- selectedGroupKey,
52548
- rowGroupKey,
52549
- onSelectGroup,
52550
- onToggleExpand,
52551
- event.eventId,
52552
- isExpanded,
52553
- loadEventDetails
52554
- ]);
52555
- const mergedEventData = loadedEventData ?? (hasExistingEventData ? event.eventData : null);
52556
- const displayPayload = isLoading ? loadedEventData : mergedEventData;
52557
- const contentOpacity = isDimmed ? 0.3 : 1;
52558
- return jsxRuntimeExports.jsxs("div", { "data-event-id": event.eventId, onMouseEnter: () => onHoverGroup(rowGroupKey), onMouseLeave: () => onHoverGroup(void 0), children: [jsxRuntimeExports.jsxs("div", { role: "button", tabIndex: 0, onClick: handleRowClick, onKeyDown: (e) => {
52559
- if (e.key === "Enter" || e.key === " ")
52560
- handleRowClick();
52561
- }, className: "w-full text-left flex items-center gap-0 text-[13px] hover:bg-[var(--ds-gray-alpha-100)] transition-colors cursor-pointer", style: { minHeight: 40 }, children: [jsxRuntimeExports.jsx(TreeGutter, { isFirst, isLast: isLast && !isExpanded, isRunLevel: isRun, statusDotColor, pulse: isPulsing, hasSelection: hasActive, showBranch, showLaneLine, isLaneStart, isLaneEnd }), jsxRuntimeExports.jsxs("div", { className: "flex items-center flex-1 min-w-0", style: { opacity: contentOpacity, transition: "opacity 150ms" }, children: [jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center w-5 h-5 flex-shrink-0 rounded", style: {
52562
- border: "1px solid var(--ds-gray-400)"
52563
- }, children: jsxRuntimeExports.jsx(ChevronRight, { className: "h-3 w-3 transition-transform", style: {
52564
- color: "var(--ds-gray-900)",
52565
- transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)"
52566
- } }) }), jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(TimestampTooltip, { date: createdAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(createdAt) }) }) }), jsxRuntimeExports.jsx("div", { className: "font-medium min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5", style: { color: "var(--ds-gray-900)" }, children: [jsxRuntimeExports.jsxs("span", { style: {
52567
- position: "relative",
52568
- display: "inline-flex",
52569
- width: 6,
52570
- height: 6,
52571
- flexShrink: 0
52572
- }, children: [isPulsing && jsxRuntimeExports.jsx("span", { style: {
52573
- position: "absolute",
52574
- inset: 0,
52575
- borderRadius: "50%",
52576
- backgroundColor: statusDotColor,
52577
- opacity: 0.75,
52578
- animation: DOT_PULSE_ANIMATION
52579
- } }), jsxRuntimeExports.jsx("span", { style: {
52580
- position: "relative",
52581
- width: 6,
52582
- height: 6,
52583
- borderRadius: "50%",
52584
- backgroundColor: statusDotColor
52585
- } })] }), formatEventType(event.eventType)] }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4 overflow-hidden text-ellipsis whitespace-nowrap", style: { flex: "2 1 0%" }, title: eventName2 !== "-" ? eventName2 : void 0, children: eventName2 }), jsxRuntimeExports.jsx(CopyableCell, { value: event.correlationId || "", className: "font-mono", style: { flex: "3 1 0%" } }), jsxRuntimeExports.jsx(CopyableCell, { value: event.eventId, className: "font-mono", style: { flex: "3 1 0%" } })] })] }), isExpanded && jsxRuntimeExports.jsxs("div", { className: "flex", children: [jsxRuntimeExports.jsx(TreeGutter, { isFirst: false, isLast, isRunLevel: isRun, hasSelection: hasActive, showBranch: false, showLaneLine: showLaneLine && !isLaneEnd, isLaneStart: false, isLaneEnd: false, continuationOnly: true }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0" }), jsxRuntimeExports.jsxs("div", { className: "flex-1 my-1.5 mr-3 ml-2 py-2 rounded-md border overflow-hidden", style: {
52586
- borderColor: "var(--ds-gray-alpha-200)",
52587
- opacity: contentOpacity,
52588
- transition: "opacity 150ms"
52589
- }, children: [((durationInfo == null ? void 0 : durationInfo.queued) !== void 0 || (durationInfo == null ? void 0 : durationInfo.ran) !== void 0) && jsxRuntimeExports.jsxs("div", { className: "px-2 pb-1.5 text-xs flex gap-3", style: { color: "var(--ds-gray-900)" }, children: [durationInfo.queued !== void 0 && durationInfo.queued > 0 && jsxRuntimeExports.jsxs("span", { children: ["Queued for", " ", jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatDuration(durationInfo.queued) })] }), durationInfo.ran !== void 0 && jsxRuntimeExports.jsxs("span", { children: ["Ran for", " ", jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatDuration(durationInfo.ran) })] })] }), displayPayload != null ? jsxRuntimeExports.jsx(PayloadBlock, { data: displayPayload, eventType: event.eventType }) : loadError ? jsxRuntimeExports.jsx("div", { className: "rounded-md border p-3 text-xs", style: {
52590
- borderColor: "var(--ds-red-400)",
52591
- backgroundColor: "var(--ds-red-100)",
52592
- color: "var(--ds-red-900)"
52593
- }, children: loadError }) : isLoading || loadedEventData === null && !hasAttemptedLoad && event.correlationId ? jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 p-3", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "75%" } }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "50%" } }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "60%" } })] }) : jsxRuntimeExports.jsx("div", { className: "p-2 text-xs", style: { color: "var(--ds-gray-900)" }, children: "No data" })] })] })] });
52594
- }
52595
- function EventListView({ events: events2, run, onLoadEventData, hasMoreEvents = false, isLoadingMoreEvents = false, onLoadMoreEvents, encryptionKey, isLoading = false, sortOrder: sortOrderProp, onSortOrderChange, onDecrypt, isDecrypting = false, hasEncryptedData: hasEncryptedDataProp = false }) {
52596
- const [internalSortOrder, setInternalSortOrder] = reactExports.useState("asc");
52597
- const effectiveSortOrder = sortOrderProp ?? internalSortOrder;
52598
- const handleSortOrderChange = reactExports.useCallback((order2) => {
52599
- if (onSortOrderChange) {
52600
- onSortOrderChange(order2);
52601
- } else {
52602
- setInternalSortOrder(order2);
52603
- }
52604
- }, [onSortOrderChange]);
52605
- const sortedEvents2 = reactExports.useMemo(() => {
52606
- if (!events2 || events2.length === 0)
52607
- return [];
52608
- const dir = effectiveSortOrder === "desc" ? -1 : 1;
52609
- return [...events2].sort((a2, b2) => dir * (new Date(a2.createdAt).getTime() - new Date(b2.createdAt).getTime()));
52610
- }, [events2, effectiveSortOrder]);
52611
- const hasEncryptedInlineData = reactExports.useMemo(() => {
52612
- if (!events2)
52613
- return false;
52614
- for (const event of events2) {
52615
- const ed = event.eventData;
52616
- if (hasEncryptedValues(ed))
52617
- return true;
52618
- }
52619
- return false;
52620
- }, [events2]);
52621
- const [foundEncryptedInLazyData, setFoundEncryptedInLazyData] = reactExports.useState(false);
52622
- const handleEncryptedDataDetected = reactExports.useCallback(() => {
52623
- setFoundEncryptedInLazyData(true);
52624
- }, []);
52625
- const hasEncryptedData = hasEncryptedDataProp || hasEncryptedInlineData || foundEncryptedInLazyData;
52626
- const { correlationNameMap, workflowName } = reactExports.useMemo(() => buildNameMaps(events2 ?? null, run ?? null), [events2, run]);
52627
- const durationMap = reactExports.useMemo(() => buildDurationMap(sortedEvents2), [sortedEvents2]);
52628
- const [selectedGroupKey, setSelectedGroupKey] = reactExports.useState(void 0);
52629
- const [hoveredGroupKey, setHoveredGroupKey] = reactExports.useState(void 0);
52630
- const onSelectGroup = reactExports.useCallback((groupKey) => {
52631
- setSelectedGroupKey(groupKey);
52632
- }, []);
52633
- const onHoverGroup = reactExports.useCallback((groupKey) => {
52634
- setHoveredGroupKey(groupKey);
52635
- }, []);
52636
- const activeGroupKey = selectedGroupKey ?? hoveredGroupKey;
52637
- const [expandedEventIds, setExpandedEventIds] = reactExports.useState(() => /* @__PURE__ */ new Set());
52638
- const toggleEventExpanded = reactExports.useCallback((eventId) => {
52639
- setExpandedEventIds((prev) => {
52640
- const next2 = new Set(prev);
52641
- if (next2.has(eventId)) {
52642
- next2.delete(eventId);
52643
- } else {
52644
- next2.add(eventId);
52645
- }
52646
- return next2;
52647
- });
52648
- }, []);
52649
- const eventDataCacheRef = reactExports.useRef(/* @__PURE__ */ new Map());
52650
- const cacheEventData = reactExports.useCallback((eventId, data) => {
52651
- eventDataCacheRef.current.set(eventId, data);
52652
- }, []);
52653
- const eventGroupKeyMap = reactExports.useMemo(() => {
52654
- const map2 = /* @__PURE__ */ new Map();
52655
- for (const ev of sortedEvents2) {
52656
- const gk = isRunLevel(ev.eventType) ? "__run__" : ev.correlationId ?? "";
52657
- if (gk)
52658
- map2.set(ev.eventId, gk);
52659
- }
52660
- return map2;
52661
- }, [sortedEvents2]);
52662
- reactExports.useEffect(() => {
52663
- if (selectedGroupKey === void 0)
52664
- return;
52665
- setExpandedEventIds((prev) => {
52666
- if (prev.size === 0)
52667
- return prev;
52668
- let changed = false;
52669
- const next2 = /* @__PURE__ */ new Set();
52670
- for (const eventId of prev) {
52671
- if (eventGroupKeyMap.get(eventId) === selectedGroupKey) {
52672
- next2.add(eventId);
52673
- } else {
52674
- changed = true;
52675
- }
52676
- }
52677
- return changed ? next2 : prev;
52678
- });
52679
- }, [selectedGroupKey, eventGroupKeyMap]);
52680
- const selectedGroupRange = reactExports.useMemo(() => {
52681
- if (!activeGroupKey || activeGroupKey === "__run__")
52682
- return null;
52683
- let first = -1;
52684
- let last = -1;
52685
- for (let i = 0; i < sortedEvents2.length; i++) {
52686
- if (sortedEvents2[i].correlationId === activeGroupKey) {
52687
- if (first === -1)
52688
- first = i;
52689
- last = i;
52690
- }
52691
- }
52692
- return first >= 0 ? { first, last } : null;
52693
- }, [activeGroupKey, sortedEvents2]);
52694
- const [searchQuery, setSearchQuery] = reactExports.useState("");
52695
- const virtuosoRef = reactExports.useRef(null);
52696
- const searchIndex = reactExports.useMemo(() => {
52697
- const entries = [];
52698
- for (let i = 0; i < sortedEvents2.length; i++) {
52699
- const ev = sortedEvents2[i];
52700
- const isRun = isRunLevel(ev.eventType);
52701
- const name2 = isRun ? workflowName ?? "" : ev.correlationId ? correlationNameMap.get(ev.correlationId) ?? "" : "";
52702
- entries.push({
52703
- fields: [
52704
- ev.eventId,
52705
- ev.correlationId ?? "",
52706
- ev.eventType,
52707
- formatEventType(ev.eventType),
52708
- name2
52709
- ].map((f2) => f2.toLowerCase()),
52710
- groupKey: ev.correlationId ?? (isRun ? "__run__" : void 0),
52711
- eventId: ev.eventId,
52712
- index: i
52713
- });
52714
- }
52715
- return entries;
52716
- }, [sortedEvents2, correlationNameMap, workflowName]);
52717
- reactExports.useEffect(() => {
52718
- var _a3;
52719
- const q2 = searchQuery.trim().toLowerCase();
52720
- if (!q2) {
52721
- setSelectedGroupKey(void 0);
52722
- return;
52723
- }
52724
- let bestMatch = null;
52725
- let bestScore = 0;
52726
- for (const entry2 of searchIndex) {
52727
- for (const field of entry2.fields) {
52728
- if (field && field.includes(q2)) {
52729
- const score = q2.length / field.length;
52730
- if (score > bestScore) {
52731
- bestScore = score;
52732
- bestMatch = entry2;
52733
- }
52734
- }
52735
- }
52736
- }
52737
- if (bestMatch) {
52738
- setSelectedGroupKey(bestMatch.groupKey);
52739
- (_a3 = virtuosoRef.current) == null ? void 0 : _a3.scrollToIndex({
52740
- index: bestMatch.index,
52741
- align: "center",
52742
- behavior: "smooth"
52743
- });
52744
- }
52745
- }, [searchQuery, searchIndex]);
52746
- const hasHadEventsRef = reactExports.useRef(false);
52747
- if (sortedEvents2.length > 0) {
52748
- hasHadEventsRef.current = true;
52749
- }
52750
- const isInitialLoad = isLoading && !hasHadEventsRef.current;
52751
- const isRefetching = isLoading && hasHadEventsRef.current && sortedEvents2.length === 0;
52752
- if (isInitialLoad) {
52753
- return jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col overflow-hidden", children: [jsxRuntimeExports.jsx("div", { style: { padding: 6 }, children: jsxRuntimeExports.jsx(Skeleton$2, { style: { height: 40, borderRadius: 6 } }) }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0 h-10 border-b flex-shrink-0", style: { borderColor: "var(--ds-gray-alpha-200)" }, children: [jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", style: { width: GUTTER_WIDTH } }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: 40 } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: 72 } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: 44 } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: 92 } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: 60 } }) })] }), jsxRuntimeExports.jsx(RowsSkeleton, {})] });
52754
- }
52755
- if (!isLoading && (!events2 || events2.length === 0)) {
52756
- return jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full text-sm", style: { color: "var(--ds-gray-700)" }, children: "No events found" });
52757
- }
52758
- return jsxRuntimeExports.jsx(DecryptClickContext.Provider, { value: onDecrypt ? { onDecrypt, isDecrypting } : void 0, children: jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col overflow-hidden", children: [jsxRuntimeExports.jsx("style", { children: `@keyframes workflow-dot-pulse{0%{transform:scale(1);opacity:.7}70%,100%{transform:scale(2.2);opacity:0}}` }), jsxRuntimeExports.jsxs("div", { style: {
52759
- padding: 6,
52760
- backgroundColor: "var(--ds-background-100)",
52761
- display: "flex",
52762
- gap: 6
52763
- }, children: [jsxRuntimeExports.jsxs("label", { style: {
52764
- display: "flex",
52765
- alignItems: "center",
52766
- justifyContent: "center",
52767
- borderRadius: 6,
52768
- boxShadow: "0 0 0 1px var(--ds-gray-alpha-400)",
52769
- background: "var(--ds-background-100)",
52770
- height: 40,
52771
- flex: 1,
52772
- minWidth: 0
52773
- }, children: [jsxRuntimeExports.jsx("div", { style: {
52774
- width: 40,
52775
- height: 40,
52776
- display: "flex",
52777
- alignItems: "center",
52778
- justifyContent: "center",
52779
- color: "var(--ds-gray-800)",
52780
- flexShrink: 0
52781
- }, children: jsxRuntimeExports.jsxs("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", focusable: "false", children: [jsxRuntimeExports.jsx("circle", { cx: "7", cy: "7", r: "4.5", stroke: "currentColor", strokeWidth: "1.5" }), jsxRuntimeExports.jsx("path", { d: "M11.5 11.5L14 14", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })] }) }), jsxRuntimeExports.jsx("input", { type: "search", placeholder: "Search by name, event type, or ID…", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), style: {
52782
- marginLeft: -16,
52783
- paddingInline: 12,
52784
- fontFamily: "inherit",
52785
- fontSize: 14,
52786
- background: "transparent",
52787
- border: "none",
52788
- outline: "none",
52789
- height: 40,
52790
- width: "100%"
52791
- } })] }), jsxRuntimeExports.jsx(MenuDropdown, { options: SORT_OPTIONS, value: effectiveSortOrder, onChange: handleSortOrderChange }), (hasEncryptedData || encryptionKey) && onDecrypt && jsxRuntimeExports.jsx(DecryptButton, { decrypted: !!encryptionKey, loading: isDecrypting, onClick: onDecrypt })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0 text-[13px] font-medium h-10 border-b flex-shrink-0", style: {
52792
- borderColor: "var(--ds-gray-alpha-200)",
52793
- color: "var(--ds-gray-900)",
52794
- backgroundColor: "var(--ds-background-100)"
52795
- }, children: [jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", style: { width: GUTTER_WIDTH } }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Time" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Event Type" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Name" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: "Correlation ID" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: "Event ID" })] }), isRefetching ? jsxRuntimeExports.jsx(RowsSkeleton, {}) : jsxRuntimeExports.jsx(Yr, { ref: virtuosoRef, totalCount: sortedEvents2.length, overscan: 20, defaultItemHeight: 40, endReached: () => {
52796
- if (!hasMoreEvents || isLoadingMoreEvents) {
52797
- return;
52798
- }
52799
- void (onLoadMoreEvents == null ? void 0 : onLoadMoreEvents());
52800
- }, itemContent: (index2) => {
52801
- const ev = sortedEvents2[index2];
52802
- return jsxRuntimeExports.jsx(EventRow$1, { event: ev, index: index2, isFirst: index2 === 0, isLast: index2 === sortedEvents2.length - 1, isExpanded: expandedEventIds.has(ev.eventId), onToggleExpand: toggleEventExpanded, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData: eventDataCacheRef.current.get(ev.eventId) ?? null, onCacheEventData: cacheEventData, encryptionKey, onEncryptedDataDetected: handleEncryptedDataDetected });
52803
- }, style: { flex: 1, minHeight: 0 } }), jsxRuntimeExports.jsxs("div", { className: "relative flex-shrink-0 flex items-center h-10 border-t px-4 text-xs", style: {
52804
- borderColor: "var(--ds-gray-alpha-200)",
52805
- color: "var(--ds-gray-900)",
52806
- backgroundColor: "var(--ds-background-100)"
52807
- }, children: [jsxRuntimeExports.jsxs("span", { children: [sortedEvents2.length, " event", sortedEvents2.length !== 1 ? "s" : "", " loaded"] }), hasMoreEvents && jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: jsxRuntimeExports.jsx("div", { className: "pointer-events-auto", children: jsxRuntimeExports.jsx(LoadMoreButton, { loading: isLoadingMoreEvents, onClick: () => void (onLoadMoreEvents == null ? void 0 : onLoadMoreEvents()) }) }) })] })] }) });
52808
- }
52809
53004
  function ResolveHookModal({ isOpen, onClose, onSubmit, isSubmitting = false }) {
52810
53005
  var _a3;
52811
53006
  const [jsonInput, setJsonInput] = reactExports.useState("");
@@ -53439,6 +53634,286 @@ function buildTrace(run, events2, now2) {
53439
53634
  knownDurationMs: Math.max(0, knownDurationMs)
53440
53635
  };
53441
53636
  }
53637
+ const ELLIPSIS = "...";
53638
+ const MIN_START = 3;
53639
+ const MIN_END = 3;
53640
+ const MIN_KEPT = MIN_START + MIN_END;
53641
+ const graphemeSegmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
53642
+ function toGraphemes(text2) {
53643
+ if (graphemeSegmenter) {
53644
+ return [...graphemeSegmenter.segment(text2)].map((s2) => s2.segment);
53645
+ }
53646
+ return Array.from(text2);
53647
+ }
53648
+ function buildCandidate(graphemes, kept) {
53649
+ if (kept <= 0) {
53650
+ return {
53651
+ prefixText: "",
53652
+ prefixGraphemeCount: 0,
53653
+ suffixText: "",
53654
+ suffixGraphemeCount: 0,
53655
+ text: ELLIPSIS,
53656
+ truncated: true
53657
+ };
53658
+ }
53659
+ const suffixGraphemeCount = kept >= MIN_KEPT ? Math.max(MIN_END, Math.floor(kept / 2)) : Math.floor(kept / 2);
53660
+ const prefixGraphemeCount = kept - suffixGraphemeCount;
53661
+ const prefixText = graphemes.slice(0, prefixGraphemeCount).join("");
53662
+ const suffixText = suffixGraphemeCount > 0 ? graphemes.slice(-suffixGraphemeCount).join("") : "";
53663
+ return {
53664
+ prefixText,
53665
+ prefixGraphemeCount,
53666
+ suffixText,
53667
+ suffixGraphemeCount,
53668
+ text: prefixText + ELLIPSIS + suffixText,
53669
+ truncated: true
53670
+ };
53671
+ }
53672
+ function middleTruncate(graphemes, availableWidth, measure, fullWidth) {
53673
+ const fullText = graphemes.join("");
53674
+ const resolvedFullWidth = fullWidth ?? measure(fullText);
53675
+ if (availableWidth <= 0 || graphemes.length === 0) {
53676
+ return {
53677
+ prefixText: fullText,
53678
+ prefixGraphemeCount: graphemes.length,
53679
+ suffixText: "",
53680
+ suffixGraphemeCount: 0,
53681
+ text: fullText,
53682
+ truncated: false
53683
+ };
53684
+ }
53685
+ if (resolvedFullWidth <= availableWidth) {
53686
+ return {
53687
+ prefixText: fullText,
53688
+ prefixGraphemeCount: graphemes.length,
53689
+ suffixText: "",
53690
+ suffixGraphemeCount: 0,
53691
+ text: fullText,
53692
+ truncated: false
53693
+ };
53694
+ }
53695
+ let lo2 = 0;
53696
+ let hi = graphemes.length - 1;
53697
+ let best = -1;
53698
+ while (lo2 <= hi) {
53699
+ const mid = lo2 + hi >>> 1;
53700
+ const candidate = buildCandidate(graphemes, mid);
53701
+ if (measure(candidate.text) <= availableWidth) {
53702
+ best = mid;
53703
+ lo2 = mid + 1;
53704
+ } else {
53705
+ hi = mid - 1;
53706
+ }
53707
+ }
53708
+ if (best === -1) {
53709
+ return {
53710
+ prefixText: "",
53711
+ prefixGraphemeCount: 0,
53712
+ suffixText: "",
53713
+ suffixGraphemeCount: 0,
53714
+ text: "",
53715
+ truncated: true
53716
+ };
53717
+ }
53718
+ return buildCandidate(graphemes, best);
53719
+ }
53720
+ function getMiddleTruncateCopyText({ prefixText, selectionEnd, selectionStart, suffixText, value }) {
53721
+ const visibleText = prefixText + ELLIPSIS + suffixText;
53722
+ if (selectionStart < 0 || selectionEnd > visibleText.length || selectionStart >= selectionEnd) {
53723
+ return null;
53724
+ }
53725
+ if (selectionStart === 0 && selectionEnd === visibleText.length) {
53726
+ return value;
53727
+ }
53728
+ const ellipsisStart = prefixText.length;
53729
+ const ellipsisEnd = ellipsisStart + ELLIPSIS.length;
53730
+ if (selectionStart > ellipsisStart || selectionEnd < ellipsisEnd) {
53731
+ return null;
53732
+ }
53733
+ const originalGraphemes = toGraphemes(value);
53734
+ const selectedPrefixGraphemeCount = toGraphemes(visibleText.slice(0, selectionStart)).length;
53735
+ const selectedSuffixGraphemeCount = toGraphemes(visibleText.slice(ellipsisEnd, selectionEnd)).length;
53736
+ const suffixStart = originalGraphemes.length - toGraphemes(suffixText).length;
53737
+ return originalGraphemes.slice(selectedPrefixGraphemeCount, suffixStart + selectedSuffixGraphemeCount).join("");
53738
+ }
53739
+ function getMiddleTruncateCopyTextFromSelectionText({ prefixText, selectionText, suffixText, value }) {
53740
+ const visibleText = prefixText + ELLIPSIS + suffixText;
53741
+ const trimmedSelectionText = selectionText.trim();
53742
+ if (!trimmedSelectionText) {
53743
+ return null;
53744
+ }
53745
+ const leading = selectionText.slice(0, selectionText.length - selectionText.trimStart().length);
53746
+ const trailing = selectionText.slice(selectionText.trimEnd().length);
53747
+ if (trimmedSelectionText === visibleText) {
53748
+ return leading + value + trailing;
53749
+ }
53750
+ if (!trimmedSelectionText.includes(ELLIPSIS)) {
53751
+ return null;
53752
+ }
53753
+ const selectionStart = visibleText.indexOf(trimmedSelectionText);
53754
+ if (selectionStart === -1) {
53755
+ return null;
53756
+ }
53757
+ const selectionEnd = selectionStart + trimmedSelectionText.length;
53758
+ const mappedText = getMiddleTruncateCopyText({
53759
+ prefixText,
53760
+ selectionEnd,
53761
+ selectionStart,
53762
+ suffixText,
53763
+ value
53764
+ });
53765
+ return mappedText === null ? null : leading + mappedText + trailing;
53766
+ }
53767
+ const useIsomorphicLayoutEffect$2 = typeof window === "undefined" ? reactExports.useEffect : reactExports.useLayoutEffect;
53768
+ function createFullState(value, graphemes) {
53769
+ return {
53770
+ displayText: value,
53771
+ isTruncated: false,
53772
+ prefixGraphemeCount: graphemes.length,
53773
+ prefixText: value,
53774
+ suffixGraphemeCount: 0,
53775
+ suffixText: ""
53776
+ };
53777
+ }
53778
+ function useMiddleTruncate(value) {
53779
+ const graphemes = reactExports.useMemo(() => toGraphemes(value), [value]);
53780
+ const fullState = reactExports.useMemo(() => createFullState(value, graphemes), [graphemes, value]);
53781
+ const ref = reactExports.useRef(null);
53782
+ const measureRef = reactExports.useRef(null);
53783
+ const [state, setState] = reactExports.useState(() => fullState);
53784
+ const rafRef = reactExports.useRef(0);
53785
+ const updateState = reactExports.useCallback((nextState) => {
53786
+ setState((currentState) => {
53787
+ if (currentState.displayText === nextState.displayText && currentState.isTruncated === nextState.isTruncated && currentState.prefixText === nextState.prefixText && currentState.prefixGraphemeCount === nextState.prefixGraphemeCount && currentState.suffixText === nextState.suffixText && currentState.suffixGraphemeCount === nextState.suffixGraphemeCount) {
53788
+ return currentState;
53789
+ }
53790
+ return nextState;
53791
+ });
53792
+ }, []);
53793
+ const recalculate = reactExports.useCallback(() => {
53794
+ const el = ref.current;
53795
+ const measureEl = measureRef.current;
53796
+ if (!el || !measureEl)
53797
+ return;
53798
+ const available = el.clientWidth;
53799
+ if (available <= 0) {
53800
+ updateState(fullState);
53801
+ return;
53802
+ }
53803
+ const measure = (text2) => {
53804
+ measureEl.textContent = text2;
53805
+ return measureEl.scrollWidth;
53806
+ };
53807
+ const fullWidth = measure(value);
53808
+ if (fullWidth <= available) {
53809
+ updateState(fullState);
53810
+ return;
53811
+ }
53812
+ const result = middleTruncate(graphemes, available, measure, fullWidth);
53813
+ updateState({
53814
+ displayText: result.text,
53815
+ isTruncated: result.truncated,
53816
+ prefixGraphemeCount: result.prefixGraphemeCount,
53817
+ prefixText: result.prefixText,
53818
+ suffixGraphemeCount: result.suffixGraphemeCount,
53819
+ suffixText: result.suffixText
53820
+ });
53821
+ }, [fullState, graphemes, updateState, value]);
53822
+ useIsomorphicLayoutEffect$2(() => {
53823
+ recalculate();
53824
+ }, [recalculate]);
53825
+ reactExports.useEffect(() => {
53826
+ var _a3;
53827
+ const el = ref.current;
53828
+ if (!el)
53829
+ return;
53830
+ const debouncedRecalc = () => {
53831
+ cancelAnimationFrame(rafRef.current);
53832
+ rafRef.current = requestAnimationFrame(recalculate);
53833
+ };
53834
+ const ro2 = typeof ResizeObserver !== "undefined" ? new ResizeObserver(debouncedRecalc) : null;
53835
+ ro2 == null ? void 0 : ro2.observe(el);
53836
+ window.addEventListener("resize", debouncedRecalc);
53837
+ const onFontsLoaded = () => {
53838
+ debouncedRecalc();
53839
+ };
53840
+ const fontSet = "fonts" in document ? document.fonts : null;
53841
+ (_a3 = fontSet == null ? void 0 : fontSet.addEventListener) == null ? void 0 : _a3.call(fontSet, "loadingdone", onFontsLoaded);
53842
+ return () => {
53843
+ var _a4;
53844
+ ro2 == null ? void 0 : ro2.disconnect();
53845
+ window.removeEventListener("resize", debouncedRecalc);
53846
+ cancelAnimationFrame(rafRef.current);
53847
+ (_a4 = fontSet == null ? void 0 : fontSet.removeEventListener) == null ? void 0 : _a4.call(fontSet, "loadingdone", onFontsLoaded);
53848
+ };
53849
+ }, [recalculate]);
53850
+ return {
53851
+ ref,
53852
+ measureRef,
53853
+ displayText: state.displayText,
53854
+ isTruncated: state.isTruncated,
53855
+ prefixGraphemeCount: state.prefixGraphemeCount,
53856
+ prefixText: state.prefixText,
53857
+ suffixGraphemeCount: state.suffixGraphemeCount,
53858
+ suffixText: state.suffixText
53859
+ };
53860
+ }
53861
+ function getRangeOffsets(container, range2) {
53862
+ if (!container.contains(range2.startContainer) || !container.contains(range2.endContainer)) {
53863
+ return null;
53864
+ }
53865
+ const startRange = document.createRange();
53866
+ startRange.selectNodeContents(container);
53867
+ startRange.setEnd(range2.startContainer, range2.startOffset);
53868
+ const endRange = document.createRange();
53869
+ endRange.selectNodeContents(container);
53870
+ endRange.setEnd(range2.endContainer, range2.endOffset);
53871
+ return {
53872
+ end: endRange.toString().length,
53873
+ start: startRange.toString().length
53874
+ };
53875
+ }
53876
+ function MiddleTruncate({ value, className, onCopy: onCopyProp, ...props }) {
53877
+ const { ref, measureRef, displayText, isTruncated, prefixText, suffixText } = useMiddleTruncate(value);
53878
+ const visibleRef = reactExports.useRef(null);
53879
+ const handleCopy = reactExports.useCallback((e) => {
53880
+ onCopyProp == null ? void 0 : onCopyProp(e);
53881
+ if (e.defaultPrevented || !isTruncated)
53882
+ return;
53883
+ const selection2 = window.getSelection();
53884
+ if (!selection2 || selection2.rangeCount === 0)
53885
+ return;
53886
+ const selectionText = selection2.toString();
53887
+ if (!selectionText)
53888
+ return;
53889
+ const range2 = selection2.getRangeAt(0);
53890
+ const visibleEl = visibleRef.current;
53891
+ let copyText = null;
53892
+ if (e.currentTarget.contains(range2.startContainer) && e.currentTarget.contains(range2.endContainer) && visibleEl) {
53893
+ const offsets = getRangeOffsets(visibleEl, range2);
53894
+ if (offsets) {
53895
+ copyText = getMiddleTruncateCopyText({
53896
+ prefixText,
53897
+ selectionEnd: offsets.end,
53898
+ selectionStart: offsets.start,
53899
+ suffixText,
53900
+ value
53901
+ });
53902
+ }
53903
+ }
53904
+ copyText ?? (copyText = getMiddleTruncateCopyTextFromSelectionText({
53905
+ prefixText,
53906
+ selectionText,
53907
+ suffixText,
53908
+ value
53909
+ }));
53910
+ if (copyText === null)
53911
+ return;
53912
+ e.preventDefault();
53913
+ e.clipboardData.setData("text/plain", copyText);
53914
+ }, [onCopyProp, isTruncated, prefixText, suffixText, value]);
53915
+ return jsxRuntimeExports.jsxs("span", { title: isTruncated ? value : void 0, ...props, ref, className: cn$4("relative inline-grid min-w-0 max-w-full overflow-hidden whitespace-nowrap", className), onCopy: handleCopy, children: [isTruncated && jsxRuntimeExports.jsx("span", { className: "sr-only select-none", children: value }), jsxRuntimeExports.jsx("span", { "aria-hidden": "true", className: "pointer-events-none col-start-1 row-start-1 invisible select-none whitespace-nowrap", children: value }), jsxRuntimeExports.jsx("span", { "aria-hidden": isTruncated || void 0, className: "col-start-1 row-start-1 min-w-0 overflow-hidden", ref: visibleRef, children: isTruncated ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { children: prefixText }), jsxRuntimeExports.jsx("span", { children: ELLIPSIS }), jsxRuntimeExports.jsx("span", { children: suffixText })] }) : displayText }), jsxRuntimeExports.jsx("span", { "aria-hidden": "true", className: "pointer-events-none absolute left-0 top-0 inline-block invisible select-none whitespace-nowrap", ref: measureRef })] });
53916
+ }
53442
53917
  const convert = (
53443
53918
  // Note: overloads in JSDoc can’t yet use different `@template`s.
53444
53919
  /**
@@ -80062,7 +80537,7 @@ var tn = f("block", "before:content-[counter(line)]", "before:inline-block", "be
80062
80537
  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 });
80063
80538
  var Se = reactExports.createContext({ code: "" }), de = () => reactExports.useContext(Se);
80064
80539
  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 }) });
80065
- var cn$1 = /\n+$/, dn = reactExports.lazy(() => import("./highlighted-body-B3W2YXNL-DtYGrm0G.js").then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
80540
+ var cn$1 = /\n+$/, dn = reactExports.lazy(() => import("./highlighted-body-B3W2YXNL-B4fAdNsB.js").then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
80066
80541
  let i = reactExports.useMemo(() => e.replace(cn$1, ""), [e]), c = reactExports.useMemo(() => ({ bg: "transparent", fg: "inherit", tokens: i.split(`
80067
80542
  `).map((a2) => [{ content: a2, color: "inherit", bgColor: "transparent", htmlStyle: {}, offset: 0 }]) }), [i]);
80068
80543
  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 }) })] }) });
@@ -80384,7 +80859,7 @@ var Dt = ({ children: e, className: t, onDownload: o, onError: n }) => {
80384
80859
  }, []), 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] });
80385
80860
  };
80386
80861
  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 }) })] });
80387
- var Jn = reactExports.lazy(() => import("./mermaid-3ZIDBTTL-D37Y2lwn.js").then((e) => ({ default: e.Mermaid }))), Kn = /language-([^\s]+)/;
80862
+ var Jn = reactExports.lazy(() => import("./mermaid-3ZIDBTTL-C6M7jb0V.js").then((e) => ({ default: e.Mermaid }))), Kn = /language-([^\s]+)/;
80388
80863
  function ke(e, t) {
80389
80864
  if (!(e != null && e.position || t != null && t.position)) return true;
80390
80865
  if (!(e != null && e.position && (t != null && t.position))) return false;
@@ -80932,6 +81407,14 @@ function parseContent(content2) {
80932
81407
  }
80933
81408
  return [];
80934
81409
  }
81410
+ const encryptedPlaceholderPreview = `{
81411
+ "input": "[encrypted]",
81412
+ "result": "[encrypted]"
81413
+ }`;
81414
+ function EncryptedDataBlock() {
81415
+ const ctx = reactExports.useContext(DecryptClickContext);
81416
+ return jsxRuntimeExports.jsxs("div", { className: "relative min-h-20 overflow-hidden rounded-md border border-gray-alpha-400 bg-background-100", children: [jsxRuntimeExports.jsx("pre", { "aria-hidden": "true", className: "pointer-events-none m-0 select-none p-3 font-mono text-label-12 text-gray-900 blur-[4px]", children: encryptedPlaceholderPreview }), jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: ctx ? jsxRuntimeExports.jsxs(Button$1, { onClick: ctx.onDecrypt, disabled: ctx.isDecrypting, size: "xs", children: [ctx.isDecrypting ? jsxRuntimeExports.jsx(Spinner, { size: 10 }) : jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { children: "Decrypt" })] }) : jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 rounded border border-gray-alpha-400 bg-gray-100 px-1.5 py-0.5 text-button-12 font-medium text-gray-700", children: [jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), "Encrypted"] }) })] });
81417
+ }
80935
81418
  const serializeForClipboard = (value) => {
80936
81419
  if (typeof value === "string")
80937
81420
  return value;
@@ -80945,31 +81428,31 @@ const serializeForClipboard = (value) => {
80945
81428
  }
80946
81429
  };
80947
81430
  function CopyableDataBlock({ data }) {
80948
- const toast2 = useToast();
80949
- return jsxRuntimeExports.jsxs("div", { className: "relative overflow-x-auto rounded-md border p-3", style: { borderColor: "var(--ds-gray-300)" }, children: [jsxRuntimeExports.jsx("button", { type: "button", "aria-label": "Copy data", title: "Copy", className: "!absolute !right-2 !top-2 !flex !h-6 !w-6 !items-center !justify-center !rounded-md !border !bg-[var(--ds-background-100)] !text-[var(--ds-gray-800)] transition-transform transition-colors duration-100 hover:!bg-[var(--ds-gray-alpha-200)] active:!scale-95 active:!bg-[var(--ds-gray-alpha-300)]", style: { borderColor: "var(--ds-gray-300)" }, onClick: () => {
80950
- navigator.clipboard.writeText(serializeForClipboard(data)).then(() => {
80951
- toast2.success("Copied to clipboard");
80952
- }).catch(() => {
80953
- toast2.error("Failed to copy");
80954
- });
80955
- }, children: jsxRuntimeExports.jsx(Copy, { size: 12 }) }), jsxRuntimeExports.jsx(DataInspector, { data })] });
81431
+ return jsxRuntimeExports.jsxs("div", { className: "relative overflow-x-auto rounded-md border border-gray-alpha-400 p-3", children: [jsxRuntimeExports.jsx(CopyButton, { copyText: serializeForClipboard(data), ariaLabel: "Copy data", className: "absolute right-2 top-2 z-10 flex h-6 w-6 items-center justify-center rounded-md border border-gray-alpha-400 !bg-background-100 p-0 text-gray-900 transition-transform transition-colors duration-100 hover:bg-gray-200 active:scale-95 active:bg-gray-300" }), jsxRuntimeExports.jsx(DataInspector, { data })] });
80956
81432
  }
80957
- function DetailCard({ summary, children: children2, onToggle, disabled = false, summaryClassName, contentClassName }) {
81433
+ function DetailCard({ summary, children: children2, onToggle, disabled = false, defaultOpen = false, variant = "section", trailing, summaryClassName, contentClassName }) {
81434
+ const [open, setOpen] = reactExports.useState(defaultOpen);
81435
+ const handleToggle = (e) => {
81436
+ if (e.target !== e.currentTarget)
81437
+ return;
81438
+ const next2 = e.currentTarget.open;
81439
+ setOpen(next2);
81440
+ onToggle == null ? void 0 : onToggle(next2);
81441
+ };
81442
+ if (variant === "card") {
81443
+ if (disabled) {
81444
+ return jsxRuntimeExports.jsx("div", { className: cn$4("list-none px-3 py-4 bg-background-200 [&::-webkit-details-marker]:hidden", summaryClassName), style: { cursor: "not-allowed", opacity: 0.8 }, children: summary });
81445
+ }
81446
+ return jsxRuntimeExports.jsxs("details", { className: "group/card last:border-b border-gray-alpha-400", open, onToggle: handleToggle, children: [jsxRuntimeExports.jsx("summary", { className: cn$4("list-none cursor-pointer px-3 py-4 border-t border-gray-alpha-400 bg-background-200 hover:bg-gray-100 [&::-webkit-details-marker]:hidden", summaryClassName), children: jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1.5", children: [jsxRuntimeExports.jsx(ChevronRight, { size: 14, className: cn$4("shrink-0 text-gray-700 group-hover/card:text-gray-1000", open && "rotate-90") }), summary] }) }), jsxRuntimeExports.jsx("div", { className: contentClassName, children: children2 })] });
81447
+ }
81448
+ const rowClasses = "flex h-9 items-center gap-2 px-2 -mx-2 text-heading-14 font-medium my-2";
81449
+ if (trailing) {
81450
+ return jsxRuntimeExports.jsx("section", { className: "-mx-4 border-t px-4 border-gray-alpha-400", children: jsxRuntimeExports.jsxs("div", { className: cn$4(rowClasses, summaryClassName), children: [jsxRuntimeExports.jsx("div", { className: "isolate relative shrink-0 w-3.5 h-3.5 text-gray-700", children: jsxRuntimeExports.jsx(ChevronRight, { size: 14, className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" }) }), jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1", children: summary }), jsxRuntimeExports.jsx("div", { className: "shrink-0 pr-1", children: trailing })] }) });
81451
+ }
80958
81452
  if (disabled) {
80959
- return jsxRuntimeExports.jsx("div", { className: `rounded-md border px-2.5 py-1.5 text-xs ${summaryClassName ?? ""}`, style: {
80960
- borderColor: "var(--ds-gray-300)",
80961
- backgroundColor: "var(--ds-gray-100)",
80962
- color: "var(--ds-gray-700)",
80963
- cursor: "not-allowed",
80964
- opacity: 0.8
80965
- }, children: summary });
81453
+ return jsxRuntimeExports.jsx("section", { className: "-mx-4 border-t px-4 border-gray-alpha-400", children: jsxRuntimeExports.jsx("div", { className: cn$4(rowClasses, summaryClassName), style: { color: "var(--ds-gray-700)", cursor: "not-allowed" }, children: jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1", children: summary }) }) });
80966
81454
  }
80967
- return jsxRuntimeExports.jsxs("details", { className: "group", onToggle: (e) => onToggle == null ? void 0 : onToggle(e.target.open), children: [jsxRuntimeExports.jsx("summary", { className: `cursor-pointer rounded-md border px-2.5 py-1.5 text-xs hover:brightness-95 [&::-webkit-details-marker]:hidden ${summaryClassName ?? ""}`, style: {
80968
- borderColor: "var(--ds-gray-300)",
80969
- backgroundColor: "var(--ds-gray-100)",
80970
- color: "var(--ds-gray-900)",
80971
- listStyle: "none"
80972
- }, children: jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1.5", children: [jsxRuntimeExports.jsx(ChevronRight, { size: 14, className: "shrink-0 transition-transform group-open:rotate-90" }), summary] }) }), jsxRuntimeExports.jsx("div", { className: `mt-2 ${contentClassName ?? ""}`, children: children2 })] });
81455
+ return jsxRuntimeExports.jsx("section", { className: "-mx-4 border-t px-4 border-gray-alpha-400", children: jsxRuntimeExports.jsxs("details", { className: "group", open, onToggle: handleToggle, children: [jsxRuntimeExports.jsxs("summary", { className: cn$4("group/trigger list-none cursor-pointer rounded hover:bg-gray-alpha-100 [&::-webkit-details-marker]:hidden", rowClasses, summaryClassName), children: [jsxRuntimeExports.jsxs("div", { className: "isolate relative shrink-0 text-gray-700 group-hover/trigger:text-gray-1000 w-3.5 h-3.5", children: [jsxRuntimeExports.jsx(ChevronRight, { size: 14, className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 opacity-100 group-open:opacity-0" }), jsxRuntimeExports.jsx(ChevronDown, { size: 14, className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 opacity-0 group-open:opacity-100" })] }), jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1", children: summary })] }), jsxRuntimeExports.jsx("div", { className: cn$4("mb-3", contentClassName), children: children2 })] }) });
80973
81456
  }
80974
81457
  function TabButton({ active, onClick, children: children2 }) {
80975
81458
  return jsxRuntimeExports.jsx("button", { type: "button", role: "tab", "aria-selected": active, tabIndex: active ? 0 : -1, onClick, className: "px-3 py-1.5 text-[11px] font-medium transition-colors -mb-px", style: {
@@ -81010,23 +81493,10 @@ const conversationTabs = [
81010
81493
  ];
81011
81494
  function ConversationWithTabs({ conversation, args }) {
81012
81495
  const [activeTab, setActiveTab] = reactExports.useState("conversation");
81013
- return jsxRuntimeExports.jsx(DetailCard, { summary: `Input (${conversation.length} messages)`, children: jsxRuntimeExports.jsx(TabbedContainer, { tabs: conversationTabs, activeTab, onTabChange: setActiveTab, ariaLabel: "Conversation view", children: activeTab === "conversation" ? jsxRuntimeExports.jsx(ConversationView, { messages: conversation }) : jsxRuntimeExports.jsx("div", { className: "p-3", children: Array.isArray(args) ? args.map((v2, i) => jsxRuntimeExports.jsx("div", { className: "mt-2 first:mt-0", children: JsonBlock(v2) }, i)) : JsonBlock(args) }) }) });
81496
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Input", children: jsxRuntimeExports.jsx(TabbedContainer, { tabs: conversationTabs, activeTab, onTabChange: setActiveTab, ariaLabel: "Conversation view", children: activeTab === "conversation" ? jsxRuntimeExports.jsx(ConversationView, { messages: conversation }) : jsxRuntimeExports.jsx("div", { className: "p-3", children: Array.isArray(args) ? args.map((v2, i) => jsxRuntimeExports.jsx("div", { className: "mt-2 first:mt-0", children: JsonBlock(v2) }, i)) : JsonBlock(args) }) }) });
81014
81497
  }
81015
81498
  function EncryptedFieldBlock() {
81016
- const ctx = reactExports.useContext(DecryptClickContext);
81017
- if (ctx) {
81018
- return jsxRuntimeExports.jsxs("button", { type: "button", onClick: ctx.onDecrypt, disabled: ctx.isDecrypting, className: "flex w-full items-center justify-center gap-1.5 rounded-md border px-3 py-2 text-xs cursor-pointer transition-colors", style: {
81019
- borderColor: "var(--ds-gray-400)",
81020
- backgroundColor: "var(--ds-gray-100)",
81021
- color: "var(--ds-gray-700)",
81022
- opacity: ctx.isDecrypting ? 0.6 : 1
81023
- }, title: "Click to decrypt", children: [ctx.isDecrypting ? jsxRuntimeExports.jsx(Spinner, { size: 12 }) : jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { className: "font-medium", children: ctx.isDecrypting ? "Decrypting…" : "Decrypt" })] });
81024
- }
81025
- return jsxRuntimeExports.jsxs("div", { className: "flex w-full items-center justify-center gap-1.5 rounded-md border px-3 py-2 text-xs", style: {
81026
- borderColor: "var(--ds-gray-300)",
81027
- backgroundColor: "var(--ds-gray-100)",
81028
- color: "var(--ds-gray-700)"
81029
- }, children: [jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Encrypted" })] });
81499
+ return jsxRuntimeExports.jsx(EncryptedDataBlock, {});
81030
81500
  }
81031
81501
  function ExpiredFieldBlock() {
81032
81502
  return jsxRuntimeExports.jsx("div", { className: "flex items-center gap-1.5 rounded-md border px-3 py-2 text-xs", style: {
@@ -81099,6 +81569,7 @@ const attributeDisplayNames = {
81099
81569
  attempt: "Attempts",
81100
81570
  eventId: "Event ID",
81101
81571
  runId: "Run ID",
81572
+ token: "Token",
81102
81573
  eventType: "Event Type",
81103
81574
  correlationId: "Correlation ID",
81104
81575
  deploymentId: "Deployment ID",
@@ -81152,13 +81623,6 @@ const formatLocalMillisecondTime = (date2) => date2.toLocaleString(void 0, {
81152
81623
  second: "numeric",
81153
81624
  fractionalSecondDigits: 3
81154
81625
  });
81155
- const localMillisecondTime = (value) => {
81156
- const date2 = parseDateValue(value);
81157
- if (!date2) {
81158
- return "-";
81159
- }
81160
- return formatLocalMillisecondTime(date2);
81161
- };
81162
81626
  const localMillisecondTimeOrNull = (value) => {
81163
81627
  const date2 = parseDateValue(value);
81164
81628
  if (!date2) {
@@ -81179,7 +81643,7 @@ const attributeToDisplayFn = {
81179
81643
  stepName: (_value) => null,
81180
81644
  // IDs
81181
81645
  runId: (_value) => null,
81182
- stepId: (_value) => null,
81646
+ stepId: (value) => String(value),
81183
81647
  hookId: (value) => String(value),
81184
81648
  eventId: (value) => String(value),
81185
81649
  // Run/step details
@@ -81204,6 +81668,14 @@ const attributeToDisplayFn = {
81204
81668
  projectId: (_value) => null,
81205
81669
  environment: (_value) => null,
81206
81670
  executionContext: (_value) => null,
81671
+ // Attributes MVP — string-string metadata attached to the run.
81672
+ // Rendered as a JSON block; if empty/missing, hidden by the
81673
+ // hasDisplayContent gate above.
81674
+ attributes: (value) => {
81675
+ if (!hasDisplayContent(value))
81676
+ return null;
81677
+ return JsonBlock(value);
81678
+ },
81207
81679
  // Dates — wrapped with TimestampTooltip showing UTC/local + relative time
81208
81680
  createdAt: timestampWithTooltipOrNull,
81209
81681
  startedAt: timestampWithTooltipOrNull,
@@ -81217,20 +81689,19 @@ const attributeToDisplayFn = {
81217
81689
  if (!hasDisplayContent(value))
81218
81690
  return null;
81219
81691
  if (isEncryptedMarker(value))
81220
- return jsxRuntimeExports.jsx(EncryptedFieldBlock, {});
81692
+ return jsxRuntimeExports.jsx(EncryptedDataBlock, {});
81221
81693
  if (isExpiredMarker(value))
81222
81694
  return jsxRuntimeExports.jsx(ExpiredFieldBlock, {});
81223
81695
  return JsonBlock(value);
81224
81696
  },
81225
81697
  input: (value, context) => {
81226
- if (isEncryptedMarker(value))
81227
- return jsxRuntimeExports.jsx(EncryptedFieldBlock, {});
81698
+ if (isEncryptedMarker(value)) {
81699
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Input", children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
81700
+ }
81228
81701
  if (isExpiredMarker(value))
81229
81702
  return jsxRuntimeExports.jsx(ExpiredFieldBlock, {});
81230
81703
  if (value && typeof value === "object" && "args" in value) {
81231
81704
  const { args, closureVars, thisVal } = value;
81232
- const argCount2 = Array.isArray(args) ? args.length : 0;
81233
- const argLabel2 = argCount2 === 1 ? "argument" : "arguments";
81234
81705
  const hasClosureVars = hasDisplayContent(closureVars);
81235
81706
  const hasThisVal = hasDisplayContent(thisVal);
81236
81707
  const hasArgs = hasDisplayContent(args);
@@ -81241,46 +81712,47 @@ const attributeToDisplayFn = {
81241
81712
  }
81242
81713
  }
81243
81714
  if (!hasArgs && !hasClosureVars && !hasThisVal) {
81244
- return jsxRuntimeExports.jsx(DetailCard, { summary: "Input (no data)", disabled: true, summaryClassName: "text-label-14 font-medium py-2" });
81715
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Input (no data)", disabled: true });
81245
81716
  }
81246
- return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(DetailCard, { summary: `Input (${argCount2} ${argLabel2})`, summaryClassName: "text-label-14 font-medium py-2", contentClassName: "mt-0", children: Array.isArray(args) ? args.map((v2, i) => jsxRuntimeExports.jsx("div", { className: "mt-2 first:mt-0", children: JsonBlock(v2) }, i)) : JsonBlock(args) }), hasClosureVars && jsxRuntimeExports.jsx(DetailCard, { summary: "Closure Variables", children: JsonBlock(closureVars) }), hasThisVal && jsxRuntimeExports.jsx(DetailCard, { summary: "this", children: JsonBlock(thisVal) })] });
81717
+ return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(DetailCard, { summary: "Input", children: Array.isArray(args) ? args.map((v2, i) => jsxRuntimeExports.jsx("div", { className: "mt-2 first:mt-0", children: JsonBlock(v2) }, i)) : JsonBlock(args) }), hasClosureVars && jsxRuntimeExports.jsx(DetailCard, { summary: "Closure Variables", children: JsonBlock(closureVars) }), hasThisVal && jsxRuntimeExports.jsx(DetailCard, { summary: "Context", children: JsonBlock(thisVal) })] });
81247
81718
  }
81248
- const argCount = Array.isArray(value) ? value.length : 0;
81249
- const argLabel = argCount === 1 ? "argument" : "arguments";
81250
81719
  if (!hasDisplayContent(value)) {
81251
- return jsxRuntimeExports.jsx(DetailCard, { summary: "Input (no data)", disabled: true, summaryClassName: "text-label-14 font-medium py-2" });
81720
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Input (no data)", disabled: true });
81252
81721
  }
81253
- return jsxRuntimeExports.jsx(DetailCard, { summary: `Input (${argCount} ${argLabel})`, summaryClassName: "text-label-14 font-medium py-2", contentClassName: "mt-0", children: Array.isArray(value) ? value.map((v2, i) => jsxRuntimeExports.jsx("div", { className: "mt-2 first:mt-0", children: JsonBlock(v2) }, i)) : JsonBlock(value) });
81722
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Input", children: Array.isArray(value) ? value.map((v2, i) => jsxRuntimeExports.jsx("div", { className: "mt-2 first:mt-0", children: JsonBlock(v2) }, i)) : JsonBlock(value) });
81254
81723
  },
81255
81724
  output: (value) => {
81725
+ if (isEncryptedMarker(value)) {
81726
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Output", children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
81727
+ }
81256
81728
  if (!hasDisplayContent(value))
81257
81729
  return null;
81258
- if (isEncryptedMarker(value))
81259
- return jsxRuntimeExports.jsx(EncryptedFieldBlock, {});
81260
81730
  if (isExpiredMarker(value))
81261
81731
  return jsxRuntimeExports.jsx(ExpiredFieldBlock, {});
81262
- return jsxRuntimeExports.jsx(DetailCard, { summary: "Output", summaryClassName: "text-label-14 font-medium py-2", contentClassName: "mt-0", children: JsonBlock(value) });
81732
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Output", children: JsonBlock(value) });
81263
81733
  },
81264
81734
  error: (value) => {
81265
- if (isEncryptedMarker(value))
81266
- return jsxRuntimeExports.jsx(EncryptedFieldBlock, {});
81735
+ if (isEncryptedMarker(value)) {
81736
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Error", defaultOpen: true, children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
81737
+ }
81267
81738
  if (isExpiredMarker(value))
81268
81739
  return jsxRuntimeExports.jsx(ExpiredFieldBlock, {});
81269
81740
  if (!hasDisplayContent(value))
81270
81741
  return null;
81271
81742
  if (isStructuredErrorWithStack(value)) {
81272
- return jsxRuntimeExports.jsx(DetailCard, { summary: "Error", summaryClassName: "text-label-14 font-medium py-2", contentClassName: "mt-0", children: jsxRuntimeExports.jsx(ErrorStackBlock, { value }) });
81743
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Error", defaultOpen: true, children: jsxRuntimeExports.jsx(ErrorStackBlock, { value }) });
81273
81744
  }
81274
- return jsxRuntimeExports.jsx(DetailCard, { summary: "Error", summaryClassName: "text-label-14 font-medium py-2", contentClassName: "mt-0", children: JsonBlock(value) });
81745
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Error", defaultOpen: true, children: JsonBlock(value) });
81275
81746
  },
81276
81747
  eventData: (value) => {
81277
- if (isEncryptedMarker(value))
81278
- return jsxRuntimeExports.jsx(EncryptedFieldBlock, {});
81748
+ if (isEncryptedMarker(value)) {
81749
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Event Data", defaultOpen: true, children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
81750
+ }
81279
81751
  if (isExpiredMarker(value))
81280
81752
  return jsxRuntimeExports.jsx(ExpiredFieldBlock, {});
81281
81753
  if (!hasDisplayContent(value))
81282
81754
  return null;
81283
- return jsxRuntimeExports.jsx(DetailCard, { summary: "Event Data", children: JsonBlock(value) });
81755
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Event Data", defaultOpen: true, children: JsonBlock(value) });
81284
81756
  },
81285
81757
  errorCode: (value) => {
81286
81758
  if (typeof value !== "string" || value.length === 0)
@@ -81295,15 +81767,32 @@ const resolvableAttributes = [
81295
81767
  "metadata",
81296
81768
  "eventData"
81297
81769
  ];
81770
+ const selfHeaderedAttributes = /* @__PURE__ */ new Set([
81771
+ "input",
81772
+ "output",
81773
+ "error",
81774
+ "eventData"
81775
+ ]);
81298
81776
  const ExpiredDataMessage = () => jsxRuntimeExports.jsx("div", { className: "text-copy-12 rounded-md border p-4 my-2", style: {
81299
81777
  borderColor: "var(--ds-gray-300)",
81300
81778
  backgroundColor: "var(--ds-gray-100)",
81301
81779
  color: "var(--ds-gray-700)"
81302
81780
  }, children: jsxRuntimeExports.jsx("span", { children: "The data for this run has expired and is no longer available." }) });
81781
+ const copyableBasicAttributes = /* @__PURE__ */ new Set([
81782
+ "stepId",
81783
+ "hookId",
81784
+ "eventId",
81785
+ "deploymentId"
81786
+ ]);
81303
81787
  const AttributeBlock = ({ attribute, value, isLoading, inline = false, context }) => {
81304
- const isExpandableLoadingTarget = attribute === "input" || attribute === "eventData";
81788
+ const decryptCtx = reactExports.useContext(DecryptClickContext);
81789
+ const isExpandableLoadingTarget = attribute === "input" || attribute === "output" || attribute === "eventData";
81305
81790
  if (isLoading && isExpandableLoadingTarget && !hasDisplayContent(value)) {
81306
- return jsxRuntimeExports.jsxs("div", { className: `my-2 flex flex-col ${attribute === "input" ? "gap-2 my-3.5" : "gap-0"}`, children: [jsxRuntimeExports.jsx("span", { className: "text-label-14 text-gray-1000 font-medium first-letter:uppercase", children: attribute }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-9 w-full rounded-md" })] });
81791
+ const label = attribute === "eventData" ? "Event Data" : attribute === "output" ? "Output" : "Input";
81792
+ if (decryptCtx == null ? void 0 : decryptCtx.hasEncryptedData) {
81793
+ return jsxRuntimeExports.jsx(DetailCard, { summary: label, defaultOpen: attribute === "eventData", children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
81794
+ }
81795
+ return jsxRuntimeExports.jsx(DetailCard, { summary: label });
81307
81796
  }
81308
81797
  const displayFn = attributeToDisplayFn[attribute];
81309
81798
  if (!displayFn) {
@@ -81316,7 +81805,10 @@ const AttributeBlock = ({ attribute, value, isLoading, inline = false, context }
81316
81805
  if (inline) {
81317
81806
  return jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [jsxRuntimeExports.jsx("span", { className: "text-[11px] font-medium", style: { color: "var(--ds-gray-700)" }, children: attribute }), jsxRuntimeExports.jsx("span", { className: "text-[11px]", style: { color: "var(--ds-gray-1000)" }, children: displayValue })] });
81318
81807
  }
81319
- return jsxRuntimeExports.jsxs("div", { className: "relative", children: [typeof isLoading === "boolean" && isLoading && jsxRuntimeExports.jsx("div", { className: "absolute top-9 right-4", children: jsxRuntimeExports.jsx("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2", style: { borderColor: "var(--ds-gray-900)" } }) }), jsxRuntimeExports.jsxs("div", { className: `my-2 flex flex-col ${attribute === "input" || attribute === "output" || attribute === "error" ? "gap-2 my-3.5" : "gap-0"}`, children: [jsxRuntimeExports.jsx("span", { className: "text-label-14 text-gray-1000 font-medium first-letter:uppercase", children: attribute }), jsxRuntimeExports.jsx("span", { className: "text-xs", style: { color: "var(--ds-gray-1000)" }, children: displayValue })] }, attribute)] });
81808
+ if (selfHeaderedAttributes.has(attribute)) {
81809
+ return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: displayValue });
81810
+ }
81811
+ return jsxRuntimeExports.jsxs("div", { className: "relative", children: [typeof isLoading === "boolean" && isLoading && jsxRuntimeExports.jsx("div", { className: "absolute top-9 right-4", children: jsxRuntimeExports.jsx("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2", style: { borderColor: "var(--ds-gray-900)" } }) }), jsxRuntimeExports.jsxs("div", { className: "my-2 flex flex-col gap-0", children: [jsxRuntimeExports.jsx("span", { className: "text-label-14 text-gray-1000 font-medium first-letter:uppercase", children: attribute }), jsxRuntimeExports.jsx("span", { className: "text-xs", style: { color: "var(--ds-gray-1000)" }, children: displayValue })] }, attribute)] });
81320
81812
  };
81321
81813
  const AttributePanel = ({ data, moduleSpecifier, isLoading, error: error2, expiredAt, onStreamClick, onRunClick, onDecrypt, isDecrypting = false, resource }) => {
81322
81814
  const toast2 = useToast();
@@ -81341,14 +81833,16 @@ const AttributePanel = ({ data, moduleSpecifier, isLoading, error: error2, expir
81341
81833
  const present = Object.keys(displayData).filter((key) => resolvableAttributes.includes(key)).sort(sortByAttributeOrder);
81342
81834
  if (!isLoading)
81343
81835
  return present;
81344
- const loadingDefaults = ["input"];
81836
+ if (resource === "sleep")
81837
+ return present;
81838
+ const loadingDefaults = ["input", "output"];
81345
81839
  for (const key of loadingDefaults) {
81346
81840
  if (!present.includes(key)) {
81347
81841
  present.push(key);
81348
81842
  }
81349
81843
  }
81350
81844
  return present.sort(sortByAttributeOrder);
81351
- }, [displayData, isLoading]);
81845
+ }, [displayData, isLoading, resource]);
81352
81846
  const visibleBasicAttributes = basicAttributes.filter((attribute) => {
81353
81847
  const displayFn = attributeToDisplayFn[attribute];
81354
81848
  if (!displayFn)
@@ -81386,23 +81880,27 @@ const AttributePanel = ({ data, moduleSpecifier, isLoading, error: error2, expir
81386
81880
  toast2.error("Failed to copy moduleSpecifier");
81387
81881
  });
81388
81882
  }, []);
81389
- return jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsx(DecryptClickContext.Provider, { value: onDecrypt ? { onDecrypt, isDecrypting } : void 0, children: jsxRuntimeExports.jsxs("div", { children: [visibleBasicAttributes.length > 0 && jsxRuntimeExports.jsxs("div", { className: "mb-3 flex flex-col overflow-hidden rounded-md border", style: {
81390
- borderColor: "var(--ds-gray-300)"
81391
- }, children: [orderedBasicAttributes.map((attribute, index2) => {
81883
+ const outerDecryptCtx = reactExports.useContext(DecryptClickContext);
81884
+ const decryptValue = onDecrypt ? {
81885
+ onDecrypt,
81886
+ isDecrypting,
81887
+ hasEncryptedData: outerDecryptCtx == null ? void 0 : outerDecryptCtx.hasEncryptedData
81888
+ } : outerDecryptCtx;
81889
+ return jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsxs(DecryptClickContext.Provider, { value: decryptValue, children: [visibleBasicAttributes.length > 0 && jsxRuntimeExports.jsxs("div", { className: "flex flex-col overflow-hidden divide-y divide-gray-alpha-400 mb-3", children: [orderedBasicAttributes.map((attribute) => {
81392
81890
  var _a3;
81393
81891
  const displayValue = (_a3 = attributeToDisplayFn[attribute]) == null ? void 0 : _a3.call(attributeToDisplayFn, displayData[attribute]);
81394
81892
  const isModuleSpecifier = attribute === "moduleSpecifier";
81893
+ const isCopyableBasicAttribute = copyableBasicAttributes.has(attribute) && typeof displayValue === "string";
81395
81894
  const moduleSpecifierValue = typeof displayValue === "string" ? displayValue : String(displayValue ?? displayData.moduleSpecifier ?? "");
81396
- const shouldCapitalizeLabel = attribute !== "workflowCoreVersion";
81397
- const showResumeAtSkeleton = isLoading && resource === "sleep" && !displayData.resumeAt;
81398
- const showDivider = index2 < orderedBasicAttributes.length - 1 || showResumeAtSkeleton;
81399
- return jsxRuntimeExports.jsxs("div", { className: "py-1", children: [jsxRuntimeExports.jsxs("div", { className: "flex min-h-[32px] items-center justify-between gap-4 rounded-sm px-2.5 py-1", children: [jsxRuntimeExports.jsx("span", { className: shouldCapitalizeLabel ? "text-[14px] first-letter:uppercase" : "text-[14px]", style: { color: "var(--ds-gray-700)" }, children: getAttributeDisplayName(attribute) }), isModuleSpecifier ? jsxRuntimeExports.jsx("button", { type: "button", className: "min-w-0 max-w-[70%] truncate text-right text-[13px] font-mono", style: {
81895
+ return jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between py-2", children: [jsxRuntimeExports.jsx("span", { className: "text-label-14 text-gray-900", children: getAttributeDisplayName(attribute) }), isModuleSpecifier ? jsxRuntimeExports.jsx("button", { type: "button", className: "min-w-0 max-w-[70%] truncate text-right text-label-13 font-mono", style: {
81400
81896
  color: "var(--ds-gray-1000)",
81401
81897
  background: "transparent",
81402
81898
  border: "none",
81403
81899
  padding: 0
81404
- }, title: moduleSpecifierValue, onClick: () => handleCopyModuleSpecifier(moduleSpecifierValue), children: moduleSpecifierValue }) : jsxRuntimeExports.jsx("span", { className: "min-w-0 max-w-[70%] truncate text-right text-[13px] font-mono", style: { color: "var(--ds-gray-1000)" }, children: displayValue })] }), showDivider ? jsxRuntimeExports.jsx("div", { className: "mx-2.5 border-b", style: { borderColor: "var(--ds-gray-300)" } }) : null] }, attribute);
81405
- }), isLoading && resource === "sleep" && !displayData.resumeAt && jsxRuntimeExports.jsx("div", { className: "py-1", children: jsxRuntimeExports.jsxs("div", { className: "flex min-h-[32px] items-center justify-between gap-4 rounded-sm px-2.5 py-1", children: [jsxRuntimeExports.jsx("span", { className: "text-[14px] first-letter:uppercase", style: { color: "var(--ds-gray-700)" }, children: "resumeAt" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-4 w-[55%]" })] }) })] }), error2 ? jsxRuntimeExports.jsx(ErrorCard, { title: "Failed to load resource details", details: error2.message, className: "my-4" }) : hasExpired ? jsxRuntimeExports.jsx(ExpiredDataMessage, {}) : jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: resolvedAttributes.map((attribute) => jsxRuntimeExports.jsx(AttributeBlock, { isLoading, attribute, value: displayData[attribute], context: displayContext }, attribute)) })] }) }) }) });
81900
+ }, title: moduleSpecifierValue, onClick: () => handleCopyModuleSpecifier(moduleSpecifierValue), children: moduleSpecifierValue }) : isCopyableBasicAttribute ? jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 max-w-[70%] items-center justify-end gap-1 text-right text-[13px] font-mono", style: {
81901
+ color: "var(--ds-gray-1000)"
81902
+ }, title: displayValue, children: [jsxRuntimeExports.jsx(MiddleTruncate, { value: displayValue, className: "flex-1" }), jsxRuntimeExports.jsx(CopyButton, { copyText: displayValue, ariaLabel: `Copy ${getAttributeDisplayName(attribute)}`, className: "shrink-0 -mr-1" })] }) : jsxRuntimeExports.jsx("span", { className: "text-right text-label-13 font-mono", children: displayValue })] }, attribute);
81903
+ }), isLoading && resource === "sleep" && !displayData.resumeAt && jsxRuntimeExports.jsx("div", { className: "py-1", children: jsxRuntimeExports.jsxs("div", { className: "flex min-h-[32px] items-center justify-between gap-4 rounded-sm px-2.5 py-1", children: [jsxRuntimeExports.jsx("span", { className: "text-[14px] first-letter:uppercase", style: { color: "var(--ds-gray-700)" }, children: "resumeAt" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-4 w-[55%]" })] }) })] }), error2 ? jsxRuntimeExports.jsx(ErrorCard, { title: "Failed to load resource details", details: error2.message, className: "my-4" }) : hasExpired ? jsxRuntimeExports.jsx(ExpiredDataMessage, {}) : resolvedAttributes.length > 0 ? jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: resolvedAttributes.map((attribute) => jsxRuntimeExports.jsx(AttributeBlock, { isLoading, attribute, value: displayData[attribute], context: displayContext }, attribute)) }) : null] }) }) });
81406
81904
  };
81407
81905
  const ERROR_EVENT_TYPES = /* @__PURE__ */ new Set(["step_failed", "step_retrying"]);
81408
81906
  const DATA_EVENT_TYPES = /* @__PURE__ */ new Set([
@@ -81451,7 +81949,7 @@ function EventItem({ event, onLoadEventData, encryptionKey }) {
81451
81949
  wasExpandedRef.current = true;
81452
81950
  await loadEventData();
81453
81951
  }, [isLoading, loadEventData]);
81454
- reactExports.useEffect(() => {
81952
+ reactExports.useLayoutEffect(() => {
81455
81953
  if (!encryptionKey || !wasExpandedRef.current)
81456
81954
  return;
81457
81955
  loadedDataRef.current = null;
@@ -81459,16 +81957,16 @@ function EventItem({ event, onLoadEventData, encryptionKey }) {
81459
81957
  void loadEventData({ force: true });
81460
81958
  }, [encryptionKey, loadEventData]);
81461
81959
  const createdAt = new Date(event.createdAt);
81960
+ const createdAtTime = createdAt.toLocaleTimeString(void 0, {
81961
+ hour: "numeric",
81962
+ minute: "numeric",
81963
+ second: "numeric"
81964
+ });
81462
81965
  const displayPayload = isLoading ? loadedData : mergedDisplay;
81463
- return jsxRuntimeExports.jsxs(DetailCard, { summaryClassName: "text-base py-2", summary: jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { className: "font-medium", style: { color: "var(--ds-gray-1000)" }, children: event.eventType }), " ", "-", " ", jsxRuntimeExports.jsx("span", { style: { color: "var(--ds-gray-700)" }, children: localMillisecondTime(createdAt.getTime()) })] }), onToggle: canHaveData ? (open) => {
81966
+ return jsxRuntimeExports.jsxs(DetailCard, { variant: "card", summaryClassName: "px-3 py-2", summary: jsxRuntimeExports.jsxs("div", { className: "flex w-full items-center justify-between gap-3", children: [jsxRuntimeExports.jsx("span", { className: "text-gray-1000 text-label-12 font-mono", children: event.eventType }), jsxRuntimeExports.jsx("span", { className: "shrink-0 text-label-13 text-gray-900", children: createdAtTime })] }), onToggle: canHaveData ? (open) => {
81464
81967
  if (open)
81465
81968
  handleExpand();
81466
- } : void 0, children: [jsxRuntimeExports.jsxs("div", { className: "flex flex-col divide-y rounded-md border overflow-hidden", style: {
81467
- borderColor: "var(--ds-gray-300)",
81468
- backgroundColor: "var(--ds-gray-100)"
81469
- }, children: [jsxRuntimeExports.jsxs("div", { className: "flex min-h-[32px] items-center justify-between gap-4 px-2.5 py-1.5", style: { borderColor: "var(--ds-gray-300)" }, children: [jsxRuntimeExports.jsx("span", { className: "text-[13px] font-medium", style: { color: "var(--ds-gray-700)" }, children: "Event ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-[13px] font-mono", style: { color: "var(--ds-gray-1000)" }, title: event.eventId, children: event.eventId })] }), event.correlationId && jsxRuntimeExports.jsxs("div", { className: "flex min-h-[32px] items-center justify-between gap-4 px-2.5 py-1.5", style: { borderColor: "var(--ds-gray-300)" }, children: [jsxRuntimeExports.jsx("span", { className: "text-[13px] font-medium", style: { color: "var(--ds-gray-700)" }, children: "Correlation ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-[13px] font-mono", style: { color: "var(--ds-gray-1000)" }, title: event.correlationId, children: event.correlationId })] })] }), isLoading && jsxRuntimeExports.jsxs("div", { className: "mt-2 rounded-md border p-3", style: {
81470
- borderColor: "var(--ds-gray-300)"
81471
- }, children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "h-4 w-[35%]" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "mt-2 h-4 w-[90%]" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "mt-2 h-4 w-[75%]" })] }), loadError && jsxRuntimeExports.jsx(ErrorCard, { title: "Failed to load event data", details: loadError, className: "mt-2" }), displayPayload != null && jsxRuntimeExports.jsx("div", { className: "mt-2", children: jsxRuntimeExports.jsx(EventDataBlock, { eventType: event.eventType, data: displayPayload }) })] });
81969
+ } : void 0, children: [jsxRuntimeExports.jsxs("div", { className: "flex flex-col bg-background-200 [&:has(+_*)]:border-b [&:has(+_*)]:border-gray-alpha-400", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Event ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.eventId })] }), event.correlationId && jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Correlation ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.correlationId })] })] }), isLoading && jsxRuntimeExports.jsxs("div", { className: "p-3", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "h-4 w-[35%]" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "mt-2 h-4 w-[90%]" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "mt-2 h-4 w-[75%]" })] }), loadError && jsxRuntimeExports.jsx(ErrorCard, { title: "Failed to load event data", details: loadError, className: "mt-2" }), displayPayload != null && jsxRuntimeExports.jsx("div", { className: "[&>div]:border-none [&>div]:rounded-none", children: jsxRuntimeExports.jsx(EventDataBlock, { eventType: event.eventType, data: displayPayload }) })] });
81472
81970
  }
81473
81971
  function hasOnlyExpiredFields(data, eventType) {
81474
81972
  if (data === null || typeof data !== "object" || Array.isArray(data)) {
@@ -81487,6 +81985,9 @@ function EventDataBlock({ eventType, data }) {
81487
81985
  color: "var(--ds-gray-700)"
81488
81986
  }, children: jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Data expired" }) });
81489
81987
  }
81988
+ if (hasEncryptedFields({ eventType, eventData: data })) {
81989
+ return jsxRuntimeExports.jsx(EncryptedDataBlock, {});
81990
+ }
81490
81991
  if (ERROR_EVENT_TYPES.has(eventType) && data != null && typeof data === "object") {
81491
81992
  const record2 = data;
81492
81993
  if (isStructuredErrorWithStack(record2.error)) {
@@ -81500,7 +82001,19 @@ function EventDataBlock({ eventType, data }) {
81500
82001
  }
81501
82002
  function EventsList({ events: events2, isLoading = false, error: error2, onLoadEventData, encryptionKey }) {
81502
82003
  const sortedEvents2 = reactExports.useMemo(() => [...events2].sort((a2, b2) => new Date(a2.createdAt).getTime() - new Date(b2.createdAt).getTime()), [events2]);
81503
- return jsxRuntimeExports.jsxs("div", { className: "mt-2", style: { color: "var(--ds-gray-1000)" }, children: [jsxRuntimeExports.jsx("h3", { className: "text-label-14 font-medium mt-4 mb-2", style: { color: "var(--ds-gray-1000)" }, children: "Events" }), isLoading ? jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-4", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "h-9 w-full rounded-md" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-9 w-full rounded-md" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-9 w-full rounded-md" })] }) : null, !isLoading && !error2 && sortedEvents2.length === 0 && jsxRuntimeExports.jsx("div", { className: "text-sm", children: "No events found" }), sortedEvents2.length > 0 && !error2 ? jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-4", children: sortedEvents2.map((event) => jsxRuntimeExports.jsx(EventItem, { event, onLoadEventData, encryptionKey }, event.eventId)) }) : null] });
82004
+ const hasEvents = sortedEvents2.length > 0 && !error2;
82005
+ if (!hasEvents && !isLoading) {
82006
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Events", disabled: true });
82007
+ }
82008
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Events", contentClassName: "mb-0", defaultOpen: true, children: isLoading ? jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: [0, 1, 2].map((i) => jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-3 bg-background-200 px-4 py-2", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "h-4 w-32 rounded" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3 w-16 rounded" })] }, i)) }) : jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: sortedEvents2.map((event) => jsxRuntimeExports.jsx(EventItem, { event, onLoadEventData, encryptionKey }, event.eventId)) }) });
82009
+ }
82010
+ const SidebarDataContext = reactExports.createContext(null);
82011
+ SidebarDataContext.displayName = "SidebarDataContext";
82012
+ function SidebarDataProvider({ value, children: children2 }) {
82013
+ return jsxRuntimeExports.jsx(SidebarDataContext.Provider, { value, children: children2 });
82014
+ }
82015
+ function useSidebarDataOptional() {
82016
+ return reactExports.useContext(SidebarDataContext);
81504
82017
  }
81505
82018
  function isStep(data) {
81506
82019
  return data !== null && typeof data === "object" && "stepId" in data;
@@ -81517,6 +82030,8 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
81517
82030
  const [showResolveHookModal, setShowResolveHookModal] = reactExports.useState(false);
81518
82031
  const [resolvingHook, setResolvingHook] = reactExports.useState(false);
81519
82032
  const [resolvedHookIds, setResolvedHookIds] = reactExports.useState(/* @__PURE__ */ new Set());
82033
+ const sidebar = useSidebarDataOptional();
82034
+ const hasEncryptedData = Boolean((sidebar == null ? void 0 : sidebar.hasEncryptedData) && !encryptionKey);
81520
82035
  const data = selectedSpan == null ? void 0 : selectedSpan.data;
81521
82036
  const rawEvents = selectedSpan == null ? void 0 : selectedSpan.rawEvents;
81522
82037
  const rawEventsLength = (rawEvents == null ? void 0 : rawEvents.length) ?? 0;
@@ -81693,7 +82208,7 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
81693
82208
  return null;
81694
82209
  }
81695
82210
  const hasPendingActions = resource === "sleep" && canWakeUp || resource === "hook" && canResolveHook;
81696
- return jsxRuntimeExports.jsxs("div", { className: "flex h-full flex-col", children: [jsxRuntimeExports.jsx(DecryptClickContext.Provider, { value: onDecrypt ? { onDecrypt, isDecrypting } : void 0, children: jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto px-3 pt-3 pb-8", children: [hasPendingActions && jsxRuntimeExports.jsxs("div", { className: "mb-4 rounded-lg border p-2", style: {
82211
+ return jsxRuntimeExports.jsxs("div", { className: "flex h-full flex-col", children: [jsxRuntimeExports.jsx(DecryptClickContext.Provider, { value: onDecrypt ? { onDecrypt, isDecrypting, hasEncryptedData } : void 0, children: jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto px-4 pb-8", children: [hasPendingActions && jsxRuntimeExports.jsxs("div", { className: "mb-4 rounded-lg border p-2", style: {
81697
82212
  borderColor: "var(--ds-gray-300)",
81698
82213
  backgroundColor: "var(--ds-gray-100)"
81699
82214
  }, children: [jsxRuntimeExports.jsx("p", { className: "mb-2 px-1 text-[13px] font-medium uppercase tracking-wide", style: { color: "var(--ds-gray-700)" }, children: "Actions" }), jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2", children: [resource === "sleep" && canWakeUp && jsxRuntimeExports.jsxs("button", { type: "button", onClick: handleWakeUp, disabled: stoppingSleep, className: clsx("flex items-center justify-center gap-2 rounded-md px-3 py-2 text-sm font-medium", "disabled:opacity-50 disabled:cursor-not-allowed transition-colors", stoppingSleep ? "opacity-50 cursor-not-allowed" : "cursor-pointer"), style: {
@@ -81702,7 +82217,7 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
81702
82217
  }, children: [jsxRuntimeExports.jsx(Zap, { className: "h-4 w-4" }), stoppingSleep ? "Waking up..." : "Wake Up Sleep"] }), resource === "hook" && canResolveHook && jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => setShowResolveHookModal(true), disabled: resolvingHook, className: clsx("flex items-center justify-center gap-2 rounded-md px-3 py-2 text-sm font-medium", "disabled:opacity-50 disabled:cursor-not-allowed transition-colors", resolvingHook ? "opacity-50 cursor-not-allowed" : "cursor-pointer"), style: {
81703
82218
  background: "var(--ds-gray-1000)",
81704
82219
  color: "var(--ds-background-100)"
81705
- }, children: [jsxRuntimeExports.jsx(Send, { className: "h-4 w-4" }), "Resolve Hook"] })] })] }), jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [jsxRuntimeExports.jsx("section", { children: jsxRuntimeExports.jsx(AttributePanel, { data: displayData, moduleSpecifier, expiredAt: run.expiredAt, isLoading: loading, error: error2 ?? void 0, onStreamClick, onRunClick, onDecrypt, isDecrypting, resource }) }), resource !== "run" && rawEvents && jsxRuntimeExports.jsx("section", { children: jsxRuntimeExports.jsx(EventsList, { events: rawEvents, onLoadEventData, encryptionKey }) })] })] }) }), jsxRuntimeExports.jsx(ResolveHookModal, { isOpen: showResolveHookModal, onClose: () => setShowResolveHookModal(false), onSubmit: handleResolveHook, isSubmitting: resolvingHook })] });
82220
+ }, children: [jsxRuntimeExports.jsx(Send, { className: "h-4 w-4" }), "Resolve Hook"] })] })] }), jsxRuntimeExports.jsx(AttributePanel, { data: displayData, moduleSpecifier, expiredAt: run.expiredAt, isLoading: loading, error: error2 ?? void 0, onStreamClick, onRunClick, onDecrypt, isDecrypting, resource }), resource !== "run" && rawEvents && jsxRuntimeExports.jsx(EventsList, { events: rawEvents, onLoadEventData, encryptionKey })] }) }), jsxRuntimeExports.jsx(ResolveHookModal, { isOpen: showResolveHookModal, onClose: () => setShowResolveHookModal(false), onSubmit: handleResolveHook, isSubmitting: resolvingHook })] });
81706
82221
  }
81707
82222
  const MAP_HEIGHT = 56;
81708
82223
  const TIMELINE_PADDING = 8;
@@ -82933,14 +83448,6 @@ reactExports.memo(function MiniMap({ timelineRef, rows, scale }) {
82933
83448
  height: MAP_HEIGHT - 4
82934
83449
  } })] });
82935
83450
  });
82936
- const SidebarDataContext = reactExports.createContext(null);
82937
- SidebarDataContext.displayName = "SidebarDataContext";
82938
- function SidebarDataProvider({ value, children: children2 }) {
82939
- return jsxRuntimeExports.jsx(SidebarDataContext.Provider, { value, children: children2 });
82940
- }
82941
- function useSidebarDataOptional() {
82942
- return reactExports.useContext(SidebarDataContext);
82943
- }
82944
83451
  const ChunkRow = ReactExports.memo(function ChunkRow2({ chunk, index: index2 }) {
82945
83452
  return jsxRuntimeExports.jsx("div", { className: "text-[11px] rounded-md border p-3", style: {
82946
83453
  borderColor: "var(--ds-gray-300)",
@@ -82976,6 +83483,30 @@ function StreamViewer({ streamId: _streamId, chunks, isLive, error: error2, isLo
82976
83483
  color: "var(--ds-gray-600)"
82977
83484
  }, children: isLive ? "Waiting for stream data..." : "Stream is empty" }) : jsxRuntimeExports.jsx(Yr, { ref: virtuosoRef, totalCount: chunks.length, overscan: 10, endReached: () => onScrollEnd == null ? void 0 : onScrollEnd(), itemContent: (index2) => jsxRuntimeExports.jsx("div", { style: { paddingBottom: 8 }, children: jsxRuntimeExports.jsx(ChunkRow, { chunk: chunks[index2], index: index2 }) }), style: { flex: 1, minHeight: 0 } }) })] });
82978
83485
  }
83486
+ const iconButtonVariants = cva([
83487
+ "m-0 inline-flex shrink-0 appearance-none items-center justify-center border-0 bg-transparent p-0 align-baseline font-inherit no-underline [background:none] [-webkit-appearance:none] [-webkit-tap-highlight-color:transparent]",
83488
+ "transition-colors duration-150 ease-in-out",
83489
+ "enabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-40",
83490
+ "focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--ds-focus-color)] focus-visible:outline-offset-2"
83491
+ ], {
83492
+ variants: {
83493
+ variant: {
83494
+ tertiary: "text-gray-900 enabled:hover:bg-gray-alpha-200 enabled:hover:text-gray-1000 enabled:active:bg-gray-alpha-200 focus-visible:text-gray-1000",
83495
+ muted: "text-gray-900 enabled:hover:bg-gray-alpha-200 enabled:hover:text-gray-1000 enabled:active:bg-gray-alpha-200 focus-visible:text-gray-1000"
83496
+ },
83497
+ size: {
83498
+ tiny: "h-6 w-6 rounded-[4px] [&_svg]:h-4 [&_svg]:w-4",
83499
+ small: "h-8 w-8 rounded-md [&_svg]:h-4 [&_svg]:w-4"
83500
+ }
83501
+ },
83502
+ defaultVariants: {
83503
+ variant: "tertiary",
83504
+ size: "tiny"
83505
+ }
83506
+ });
83507
+ function IconButton({ className, variant, size: size2, type = "button", ...props }) {
83508
+ return jsxRuntimeExports.jsx("button", { type, className: cn$4(iconButtonVariants({ variant, size: size2, className })), ...props });
83509
+ }
82979
83510
  const QUERY = "(prefers-reduced-motion: reduce)";
82980
83511
  const useReducedMotion = () => {
82981
83512
  const [reduced, setReduced] = reactExports.useState(() => {
@@ -82994,27 +83525,6 @@ const useReducedMotion = () => {
82994
83525
  }, []);
82995
83526
  return reduced;
82996
83527
  };
82997
- function CopyButton({ copyText, ariaLabel, className }) {
82998
- const [copied, setCopied] = reactExports.useState(false);
82999
- const timeoutRef = reactExports.useRef(null);
83000
- reactExports.useEffect(() => {
83001
- return () => {
83002
- if (timeoutRef.current) {
83003
- clearTimeout(timeoutRef.current);
83004
- }
83005
- };
83006
- }, []);
83007
- return jsxRuntimeExports.jsx("button", { type: "button", "aria-label": ariaLabel, className: cn$4("cursor-pointer text-gray-800 hover:text-gray-1000 bg-transparent border-none p-1 m-0", className), onClick: (e) => {
83008
- e.stopPropagation();
83009
- if (timeoutRef.current) {
83010
- clearTimeout(timeoutRef.current);
83011
- }
83012
- void navigator.clipboard.writeText(copyText).then(() => {
83013
- setCopied(true);
83014
- timeoutRef.current = setTimeout(() => setCopied(false), 1e3);
83015
- });
83016
- }, children: jsxRuntimeExports.jsxs("div", { className: "relative w-3 h-3", children: [jsxRuntimeExports.jsx("div", { className: cn$4("absolute inset-0 flex items-center justify-center transition-all duration-150 ease-out", copied ? "scale-100 opacity-100" : "scale-0 opacity-0"), children: jsxRuntimeExports.jsx(Check, { className: "w-3 h-3" }) }), jsxRuntimeExports.jsx("div", { className: cn$4("absolute inset-0 flex items-center justify-center transition-all duration-150 ease-out", copied ? "scale-0 opacity-0" : "scale-100 opacity-100"), children: jsxRuntimeExports.jsx(Copy, { className: "w-3 h-3" }) })] }) });
83017
- }
83018
83528
  const WorkflowIcon = () => {
83019
83529
  return jsxRuntimeExports.jsx("svg", { "data-testid": "geist-icon", height: "16", "stroke-linejoin": "round", style: { color: "currentColor" }, viewBox: "0 0 16 16", width: "16", children: jsxRuntimeExports.jsx("path", { d: "M5.75 7L6.4209 7.33594L4.85254 10.4717C5.38789 10.771 5.75 11.3431 5.75 12V14C5.75 14.9665 4.96648 15.75 4 15.75H2C1.03352 15.75 0.25 14.9665 0.25 14V12C0.25 11.0335 1.03352 10.25 2 10.25H3.28711L5.0791 6.66504L5.75 7ZM14 10.25C14.9665 10.25 15.75 11.0335 15.75 12V14C15.75 14.9665 14.9665 15.75 14 15.75H12C11.1185 15.75 10.3909 15.098 10.2695 14.25H7V12.75H10.25V12C10.25 11.0335 11.0335 10.25 12 10.25H14ZM2 11.75C1.86192 11.75 1.75 11.8619 1.75 12V14C1.75 14.1381 1.86192 14.25 2 14.25H4C4.13808 14.25 4.25 14.1381 4.25 14V12C4.25 11.8619 4.13808 11.75 4 11.75H2ZM12 11.75C11.8619 11.75 11.75 11.8619 11.75 12V14C11.75 14.1381 11.8619 14.25 12 14.25H14C14.1381 14.25 14.25 14.1381 14.25 14V12C14.25 11.8619 14.1381 11.75 14 11.75H12ZM9 0.25C9.96649 0.25 10.75 1.03351 10.75 2V4C10.75 4.44642 10.5808 4.85197 10.3057 5.16113L12.2041 8.6416L10.8877 9.36035L8.91895 5.75H7C6.03351 5.75 5.25 4.96649 5.25 4V2C5.25 1.03351 6.03351 0.25 7 0.25H9ZM7 1.75C6.86193 1.75 6.75 1.86193 6.75 2V4C6.75 4.13807 6.86193 4.25 7 4.25H9C9.13807 4.25 9.25 4.13807 9.25 4V2C9.25 1.86193 9.13807 1.75 9 1.75H7Z", fill: "currentColor" }) });
83020
83530
  };
@@ -83027,6 +83537,128 @@ const SleepIcon = () => {
83027
83537
  const StepForwardIcon = () => {
83028
83538
  return jsxRuntimeExports.jsx("svg", { "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", style: { color: "currentColor" }, children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.21969 12.5303L4.75002 13.0607L5.81068 12L5.28035 11.4697L1.81068 7.99999L5.28035 4.53032L5.81068 3.99999L4.75002 2.93933L4.21969 3.46966L0.39647 7.29289C0.00594562 7.68341 0.00594562 8.31658 0.39647 8.7071L4.21969 12.5303ZM11.7804 12.5303L11.25 13.0607L10.1894 12L10.7197 11.4697L14.1894 7.99999L10.7197 4.53032L10.1894 3.99999L11.25 2.93933L11.7804 3.46966L15.6036 7.29289C15.9941 7.68341 15.9941 8.31658 15.6036 8.7071L11.7804 12.5303Z", fill: "currentColor" }) });
83029
83539
  };
83540
+ const ATTR_FILTER_REGEX = /(?:^|\s)(?<pair>(?<key>[\w.]+):(?<value>\S*))/g;
83541
+ function parseSpanSearchQuery(rawQuery) {
83542
+ var _a3, _b2, _c2;
83543
+ const attributes = [];
83544
+ for (const match2 of rawQuery.matchAll(ATTR_FILTER_REGEX)) {
83545
+ const key = (_b2 = (_a3 = match2.groups) == null ? void 0 : _a3.key) == null ? void 0 : _b2.trim();
83546
+ if (!key)
83547
+ continue;
83548
+ attributes.push({
83549
+ key,
83550
+ value: (((_c2 = match2.groups) == null ? void 0 : _c2.value) ?? "").toLocaleLowerCase()
83551
+ });
83552
+ }
83553
+ const text2 = rawQuery.replace(ATTR_FILTER_REGEX, " ").replace(/\s{2,}/g, " ").trim().toLocaleLowerCase();
83554
+ return { text: text2, attributes };
83555
+ }
83556
+ function isSpanDimmedBySearch(spanId, result) {
83557
+ return result.isActive && !result.matchedSpanIds.has(spanId);
83558
+ }
83559
+ function searchSpans(spans, rawQuery) {
83560
+ const query = parseSpanSearchQuery(rawQuery);
83561
+ const isActive = Boolean(query.text || query.attributes.length);
83562
+ const matchingSpans = isActive ? spans.filter((span) => spanMatchesQuery(span, query)) : spans;
83563
+ return {
83564
+ isActive,
83565
+ matchedSpanIds: new Set(matchingSpans.map((span) => span.spanId)),
83566
+ matchingSpans,
83567
+ query
83568
+ };
83569
+ }
83570
+ function spanMatchesQuery(span, query) {
83571
+ if (query.text && !spanMatchesText(span, query.text)) {
83572
+ return false;
83573
+ }
83574
+ return query.attributes.every(({ key, value }) => spanMatchesAttribute(span, key, value));
83575
+ }
83576
+ function spanMatchesText(span, text2) {
83577
+ return [
83578
+ span.name,
83579
+ span.spanId,
83580
+ span.resource,
83581
+ span.library.name,
83582
+ span.library.version
83583
+ ].filter((value) => typeof value === "string").some((value) => value.toLocaleLowerCase().includes(text2));
83584
+ }
83585
+ function spanMatchesAttribute(span, key, expectedValue) {
83586
+ const candidates = getSearchValues(span, key);
83587
+ if (!candidates.length)
83588
+ return false;
83589
+ if (!expectedValue) {
83590
+ return candidates.some((value) => value != null);
83591
+ }
83592
+ return candidates.some((value) => valueToSearchString(value).toLocaleLowerCase().includes(expectedValue));
83593
+ }
83594
+ function getSearchValues(span, key) {
83595
+ const candidates = [];
83596
+ const normalizedKey = key.toLocaleLowerCase();
83597
+ switch (normalizedKey) {
83598
+ case "id":
83599
+ case "spanid":
83600
+ case "span.id":
83601
+ candidates.push(span.spanId);
83602
+ break;
83603
+ case "name":
83604
+ candidates.push(span.name);
83605
+ break;
83606
+ case "resource":
83607
+ candidates.push(span.resource);
83608
+ break;
83609
+ case "library":
83610
+ case "library.name":
83611
+ candidates.push(span.library.name);
83612
+ break;
83613
+ case "library.version":
83614
+ candidates.push(span.library.version);
83615
+ break;
83616
+ case "status":
83617
+ case "status.code":
83618
+ candidates.push(span.status.code);
83619
+ break;
83620
+ }
83621
+ candidates.push(getOwnProperty(span.attributes, key));
83622
+ candidates.push(getPathValue(span.attributes, key));
83623
+ if (!normalizedKey.startsWith("data.")) {
83624
+ candidates.push(getPathValue(span.attributes.data, key));
83625
+ }
83626
+ return candidates.filter((value) => value !== void 0);
83627
+ }
83628
+ function getOwnProperty(source, key) {
83629
+ if (!source || typeof source !== "object")
83630
+ return void 0;
83631
+ if (!Object.hasOwn(source, key))
83632
+ return void 0;
83633
+ return source[key];
83634
+ }
83635
+ function getPathValue(source, path2) {
83636
+ if (!source || typeof source !== "object")
83637
+ return void 0;
83638
+ let current = source;
83639
+ for (const segment2 of path2.split(".")) {
83640
+ if (!segment2)
83641
+ return void 0;
83642
+ current = getOwnProperty(current, segment2);
83643
+ if (current === void 0)
83644
+ return void 0;
83645
+ }
83646
+ return current;
83647
+ }
83648
+ function valueToSearchString(value) {
83649
+ if (value instanceof Date)
83650
+ return value.toISOString();
83651
+ if (typeof value === "string")
83652
+ return value;
83653
+ if (value == null || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
83654
+ return String(value);
83655
+ }
83656
+ try {
83657
+ return JSON.stringify(value);
83658
+ } catch {
83659
+ return String(value);
83660
+ }
83661
+ }
83030
83662
  function computeRootBounds(spans) {
83031
83663
  let minStart = Number.POSITIVE_INFINITY;
83032
83664
  let maxEnd = Number.NEGATIVE_INFINITY;
@@ -83350,286 +83982,6 @@ function computeSpanSegments(span) {
83350
83982
  return [];
83351
83983
  }
83352
83984
  }
83353
- const ELLIPSIS = "...";
83354
- const MIN_START = 3;
83355
- const MIN_END = 3;
83356
- const MIN_KEPT = MIN_START + MIN_END;
83357
- const graphemeSegmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
83358
- function toGraphemes(text2) {
83359
- if (graphemeSegmenter) {
83360
- return [...graphemeSegmenter.segment(text2)].map((s2) => s2.segment);
83361
- }
83362
- return Array.from(text2);
83363
- }
83364
- function buildCandidate(graphemes, kept) {
83365
- if (kept <= 0) {
83366
- return {
83367
- prefixText: "",
83368
- prefixGraphemeCount: 0,
83369
- suffixText: "",
83370
- suffixGraphemeCount: 0,
83371
- text: ELLIPSIS,
83372
- truncated: true
83373
- };
83374
- }
83375
- const suffixGraphemeCount = kept >= MIN_KEPT ? Math.max(MIN_END, Math.floor(kept / 2)) : Math.floor(kept / 2);
83376
- const prefixGraphemeCount = kept - suffixGraphemeCount;
83377
- const prefixText = graphemes.slice(0, prefixGraphemeCount).join("");
83378
- const suffixText = suffixGraphemeCount > 0 ? graphemes.slice(-suffixGraphemeCount).join("") : "";
83379
- return {
83380
- prefixText,
83381
- prefixGraphemeCount,
83382
- suffixText,
83383
- suffixGraphemeCount,
83384
- text: prefixText + ELLIPSIS + suffixText,
83385
- truncated: true
83386
- };
83387
- }
83388
- function middleTruncate(graphemes, availableWidth, measure, fullWidth) {
83389
- const fullText = graphemes.join("");
83390
- const resolvedFullWidth = fullWidth ?? measure(fullText);
83391
- if (availableWidth <= 0 || graphemes.length === 0) {
83392
- return {
83393
- prefixText: fullText,
83394
- prefixGraphemeCount: graphemes.length,
83395
- suffixText: "",
83396
- suffixGraphemeCount: 0,
83397
- text: fullText,
83398
- truncated: false
83399
- };
83400
- }
83401
- if (resolvedFullWidth <= availableWidth) {
83402
- return {
83403
- prefixText: fullText,
83404
- prefixGraphemeCount: graphemes.length,
83405
- suffixText: "",
83406
- suffixGraphemeCount: 0,
83407
- text: fullText,
83408
- truncated: false
83409
- };
83410
- }
83411
- let lo2 = 0;
83412
- let hi = graphemes.length - 1;
83413
- let best = -1;
83414
- while (lo2 <= hi) {
83415
- const mid = lo2 + hi >>> 1;
83416
- const candidate = buildCandidate(graphemes, mid);
83417
- if (measure(candidate.text) <= availableWidth) {
83418
- best = mid;
83419
- lo2 = mid + 1;
83420
- } else {
83421
- hi = mid - 1;
83422
- }
83423
- }
83424
- if (best === -1) {
83425
- return {
83426
- prefixText: "",
83427
- prefixGraphemeCount: 0,
83428
- suffixText: "",
83429
- suffixGraphemeCount: 0,
83430
- text: "",
83431
- truncated: true
83432
- };
83433
- }
83434
- return buildCandidate(graphemes, best);
83435
- }
83436
- function getMiddleTruncateCopyText({ prefixText, selectionEnd, selectionStart, suffixText, value }) {
83437
- const visibleText = prefixText + ELLIPSIS + suffixText;
83438
- if (selectionStart < 0 || selectionEnd > visibleText.length || selectionStart >= selectionEnd) {
83439
- return null;
83440
- }
83441
- if (selectionStart === 0 && selectionEnd === visibleText.length) {
83442
- return value;
83443
- }
83444
- const ellipsisStart = prefixText.length;
83445
- const ellipsisEnd = ellipsisStart + ELLIPSIS.length;
83446
- if (selectionStart > ellipsisStart || selectionEnd < ellipsisEnd) {
83447
- return null;
83448
- }
83449
- const originalGraphemes = toGraphemes(value);
83450
- const selectedPrefixGraphemeCount = toGraphemes(visibleText.slice(0, selectionStart)).length;
83451
- const selectedSuffixGraphemeCount = toGraphemes(visibleText.slice(ellipsisEnd, selectionEnd)).length;
83452
- const suffixStart = originalGraphemes.length - toGraphemes(suffixText).length;
83453
- return originalGraphemes.slice(selectedPrefixGraphemeCount, suffixStart + selectedSuffixGraphemeCount).join("");
83454
- }
83455
- function getMiddleTruncateCopyTextFromSelectionText({ prefixText, selectionText, suffixText, value }) {
83456
- const visibleText = prefixText + ELLIPSIS + suffixText;
83457
- const trimmedSelectionText = selectionText.trim();
83458
- if (!trimmedSelectionText) {
83459
- return null;
83460
- }
83461
- const leading = selectionText.slice(0, selectionText.length - selectionText.trimStart().length);
83462
- const trailing = selectionText.slice(selectionText.trimEnd().length);
83463
- if (trimmedSelectionText === visibleText) {
83464
- return leading + value + trailing;
83465
- }
83466
- if (!trimmedSelectionText.includes(ELLIPSIS)) {
83467
- return null;
83468
- }
83469
- const selectionStart = visibleText.indexOf(trimmedSelectionText);
83470
- if (selectionStart === -1) {
83471
- return null;
83472
- }
83473
- const selectionEnd = selectionStart + trimmedSelectionText.length;
83474
- const mappedText = getMiddleTruncateCopyText({
83475
- prefixText,
83476
- selectionEnd,
83477
- selectionStart,
83478
- suffixText,
83479
- value
83480
- });
83481
- return mappedText === null ? null : leading + mappedText + trailing;
83482
- }
83483
- const useIsomorphicLayoutEffect$2 = typeof window === "undefined" ? reactExports.useEffect : reactExports.useLayoutEffect;
83484
- function createFullState(value, graphemes) {
83485
- return {
83486
- displayText: value,
83487
- isTruncated: false,
83488
- prefixGraphemeCount: graphemes.length,
83489
- prefixText: value,
83490
- suffixGraphemeCount: 0,
83491
- suffixText: ""
83492
- };
83493
- }
83494
- function useMiddleTruncate(value) {
83495
- const graphemes = reactExports.useMemo(() => toGraphemes(value), [value]);
83496
- const fullState = reactExports.useMemo(() => createFullState(value, graphemes), [graphemes, value]);
83497
- const ref = reactExports.useRef(null);
83498
- const measureRef = reactExports.useRef(null);
83499
- const [state, setState] = reactExports.useState(() => fullState);
83500
- const rafRef = reactExports.useRef(0);
83501
- const updateState = reactExports.useCallback((nextState) => {
83502
- setState((currentState) => {
83503
- if (currentState.displayText === nextState.displayText && currentState.isTruncated === nextState.isTruncated && currentState.prefixText === nextState.prefixText && currentState.prefixGraphemeCount === nextState.prefixGraphemeCount && currentState.suffixText === nextState.suffixText && currentState.suffixGraphemeCount === nextState.suffixGraphemeCount) {
83504
- return currentState;
83505
- }
83506
- return nextState;
83507
- });
83508
- }, []);
83509
- const recalculate = reactExports.useCallback(() => {
83510
- const el = ref.current;
83511
- const measureEl = measureRef.current;
83512
- if (!el || !measureEl)
83513
- return;
83514
- const available = el.clientWidth;
83515
- if (available <= 0) {
83516
- updateState(fullState);
83517
- return;
83518
- }
83519
- const measure = (text2) => {
83520
- measureEl.textContent = text2;
83521
- return measureEl.scrollWidth;
83522
- };
83523
- const fullWidth = measure(value);
83524
- if (fullWidth <= available) {
83525
- updateState(fullState);
83526
- return;
83527
- }
83528
- const result = middleTruncate(graphemes, available, measure, fullWidth);
83529
- updateState({
83530
- displayText: result.text,
83531
- isTruncated: result.truncated,
83532
- prefixGraphemeCount: result.prefixGraphemeCount,
83533
- prefixText: result.prefixText,
83534
- suffixGraphemeCount: result.suffixGraphemeCount,
83535
- suffixText: result.suffixText
83536
- });
83537
- }, [fullState, graphemes, updateState, value]);
83538
- useIsomorphicLayoutEffect$2(() => {
83539
- recalculate();
83540
- }, [recalculate]);
83541
- reactExports.useEffect(() => {
83542
- var _a3;
83543
- const el = ref.current;
83544
- if (!el)
83545
- return;
83546
- const debouncedRecalc = () => {
83547
- cancelAnimationFrame(rafRef.current);
83548
- rafRef.current = requestAnimationFrame(recalculate);
83549
- };
83550
- const ro2 = typeof ResizeObserver !== "undefined" ? new ResizeObserver(debouncedRecalc) : null;
83551
- ro2 == null ? void 0 : ro2.observe(el);
83552
- window.addEventListener("resize", debouncedRecalc);
83553
- const onFontsLoaded = () => {
83554
- debouncedRecalc();
83555
- };
83556
- const fontSet = "fonts" in document ? document.fonts : null;
83557
- (_a3 = fontSet == null ? void 0 : fontSet.addEventListener) == null ? void 0 : _a3.call(fontSet, "loadingdone", onFontsLoaded);
83558
- return () => {
83559
- var _a4;
83560
- ro2 == null ? void 0 : ro2.disconnect();
83561
- window.removeEventListener("resize", debouncedRecalc);
83562
- cancelAnimationFrame(rafRef.current);
83563
- (_a4 = fontSet == null ? void 0 : fontSet.removeEventListener) == null ? void 0 : _a4.call(fontSet, "loadingdone", onFontsLoaded);
83564
- };
83565
- }, [recalculate]);
83566
- return {
83567
- ref,
83568
- measureRef,
83569
- displayText: state.displayText,
83570
- isTruncated: state.isTruncated,
83571
- prefixGraphemeCount: state.prefixGraphemeCount,
83572
- prefixText: state.prefixText,
83573
- suffixGraphemeCount: state.suffixGraphemeCount,
83574
- suffixText: state.suffixText
83575
- };
83576
- }
83577
- function getRangeOffsets(container, range2) {
83578
- if (!container.contains(range2.startContainer) || !container.contains(range2.endContainer)) {
83579
- return null;
83580
- }
83581
- const startRange = document.createRange();
83582
- startRange.selectNodeContents(container);
83583
- startRange.setEnd(range2.startContainer, range2.startOffset);
83584
- const endRange = document.createRange();
83585
- endRange.selectNodeContents(container);
83586
- endRange.setEnd(range2.endContainer, range2.endOffset);
83587
- return {
83588
- end: endRange.toString().length,
83589
- start: startRange.toString().length
83590
- };
83591
- }
83592
- function MiddleTruncate({ value, className, onCopy: onCopyProp, ...props }) {
83593
- const { ref, measureRef, displayText, isTruncated, prefixText, suffixText } = useMiddleTruncate(value);
83594
- const visibleRef = reactExports.useRef(null);
83595
- const handleCopy = reactExports.useCallback((e) => {
83596
- onCopyProp == null ? void 0 : onCopyProp(e);
83597
- if (e.defaultPrevented || !isTruncated)
83598
- return;
83599
- const selection2 = window.getSelection();
83600
- if (!selection2 || selection2.rangeCount === 0)
83601
- return;
83602
- const selectionText = selection2.toString();
83603
- if (!selectionText)
83604
- return;
83605
- const range2 = selection2.getRangeAt(0);
83606
- const visibleEl = visibleRef.current;
83607
- let copyText = null;
83608
- if (e.currentTarget.contains(range2.startContainer) && e.currentTarget.contains(range2.endContainer) && visibleEl) {
83609
- const offsets = getRangeOffsets(visibleEl, range2);
83610
- if (offsets) {
83611
- copyText = getMiddleTruncateCopyText({
83612
- prefixText,
83613
- selectionEnd: offsets.end,
83614
- selectionStart: offsets.start,
83615
- suffixText,
83616
- value
83617
- });
83618
- }
83619
- }
83620
- copyText ?? (copyText = getMiddleTruncateCopyTextFromSelectionText({
83621
- prefixText,
83622
- selectionText,
83623
- suffixText,
83624
- value
83625
- }));
83626
- if (copyText === null)
83627
- return;
83628
- e.preventDefault();
83629
- e.clipboardData.setData("text/plain", copyText);
83630
- }, [onCopyProp, isTruncated, prefixText, suffixText, value]);
83631
- return jsxRuntimeExports.jsxs("span", { title: isTruncated ? value : void 0, ...props, ref, className: cn$4("relative inline-grid min-w-0 max-w-full overflow-hidden whitespace-nowrap", className), onCopy: handleCopy, children: [isTruncated && jsxRuntimeExports.jsx("span", { className: "sr-only select-none", children: value }), jsxRuntimeExports.jsx("span", { "aria-hidden": "true", className: "pointer-events-none col-start-1 row-start-1 invisible select-none whitespace-nowrap", children: value }), jsxRuntimeExports.jsx("span", { "aria-hidden": isTruncated || void 0, className: "col-start-1 row-start-1 min-w-0 overflow-hidden", ref: visibleRef, children: isTruncated ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { children: prefixText }), jsxRuntimeExports.jsx("span", { children: ELLIPSIS }), jsxRuntimeExports.jsx("span", { children: suffixText })] }) : displayText }), jsxRuntimeExports.jsx("span", { "aria-hidden": "true", className: "pointer-events-none absolute left-0 top-0 inline-block invisible select-none whitespace-nowrap", ref: measureRef })] });
83632
- }
83633
83985
  const eventStyles = {
83634
83986
  run: { icon: WorkflowIcon, className: "text-blue-900" },
83635
83987
  step: { icon: StepForwardIcon, className: "text-green-900" },
@@ -83648,15 +84000,15 @@ function getEventStyle(resource, isErrored) {
83648
84000
  className: cn$4(isErrored ? "text-red-900" : style2.className)
83649
84001
  };
83650
84002
  }
83651
- const EventRow = ({ span, isSelected, onSelectSpan }) => {
84003
+ const EventRow = ({ span, isSelected, isDimmed, onSelectSpan }) => {
83652
84004
  const durationMs = getSpanDurationMs(span);
83653
84005
  const isErrored = span.attributes.data.status === "failed";
83654
84006
  const { icon: Icon2, className: tagClassName } = getEventStyle(span.resource, isErrored);
83655
- return jsxRuntimeExports.jsx("li", { className: cn$4("relative overflow-clip group after:absolute after:inset-x-0 after:bottom-0 after:h-px after:bg-gray-alpha-400", ROW_HEIGHT_CLASS), role: "treeitem", "aria-selected": isSelected, "aria-expanded": isSelected, "aria-level": 1, onClick: () => onSelectSpan(span.spanId), children: jsxRuntimeExports.jsx("div", { className: "h-full hover:bg-gray-100 group-aria-selected:bg-gray-100 group-aria-selected:hover:bg-gray-200", children: jsxRuntimeExports.jsxs("div", { className: "flex h-full min-w-0 items-center px-2", children: [jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [jsxRuntimeExports.jsx("span", { className: cn$4("shrink-0", tagClassName), children: jsxRuntimeExports.jsx(Icon2, { className: "w-4 h-4" }) }), jsxRuntimeExports.jsx("span", { className: "min-w-0 text-label-14", children: jsxRuntimeExports.jsx(MiddleTruncate, { value: span.name }) })] }), jsxRuntimeExports.jsx("div", { className: "ml-2 shrink-0", children: jsxRuntimeExports.jsx("span", { className: "text-label-14 text-gray-900 tabular-nums", children: formatDuration(durationMs) }) })] }) }) });
84007
+ return jsxRuntimeExports.jsx("li", { className: cn$4("relative overflow-clip group transition-opacity", ROW_HEIGHT_CLASS, isDimmed && "opacity-35"), role: "treeitem", "aria-selected": isSelected, "aria-expanded": isSelected, "aria-level": 1, onClick: () => onSelectSpan(span.spanId), children: jsxRuntimeExports.jsx("div", { className: "h-full hover:bg-gray-100 group-aria-selected:bg-gray-100 group-aria-selected:hover:bg-gray-200", children: jsxRuntimeExports.jsxs("div", { className: "flex h-full min-w-0 items-center pl-4 pr-2", children: [jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [jsxRuntimeExports.jsx("span", { className: cn$4("shrink-0", tagClassName), children: jsxRuntimeExports.jsx(Icon2, { className: "w-4 h-4" }) }), jsxRuntimeExports.jsx("span", { className: "min-w-0 text-label-14", children: jsxRuntimeExports.jsx(MiddleTruncate, { value: span.name }) })] }), jsxRuntimeExports.jsx("div", { className: "ml-2 shrink-0", children: jsxRuntimeExports.jsx("span", { className: "text-label-14 text-gray-900 tabular-nums", children: formatDuration(durationMs) }) })] }) }) });
83656
84008
  };
83657
- const EventList = ({ spans, activeSpanId, onSelectSpan }) => {
83658
- return jsxRuntimeExports.jsx("ul", { id: "event-list", role: "tree", className: "block min-h-0 overflow-visible", children: spans.map((span) => {
83659
- return jsxRuntimeExports.jsx(EventRow, { span, isSelected: span.spanId === activeSpanId, onSelectSpan }, span.spanId);
84009
+ const EventList = ({ spans, activeSpanId, searchResult, onSelectSpan }) => {
84010
+ return jsxRuntimeExports.jsx("ul", { id: "event-list", role: "tree", className: "block min-h-0 overflow-visible divide-y divide-gray-alpha-400 border-b border-gray-alpha-400", children: spans.map((span) => {
84011
+ return jsxRuntimeExports.jsx(EventRow, { span, isSelected: span.spanId === activeSpanId, isDimmed: isSpanDimmedBySearch(span.spanId, searchResult), onSelectSpan }, span.spanId);
83660
84012
  }) });
83661
84013
  };
83662
84014
  const GUTTER_PX = 1;
@@ -83856,7 +84208,7 @@ function SegmentBar({ segments }) {
83856
84208
  }, children: showLabel ? jsxRuntimeExports.jsx(DurationLabel, { label }) : null }, `${seg.status}-${i}`);
83857
84209
  }) });
83858
84210
  }
83859
- const TimelineBar = reactExports.memo(function TimelineBar2({ span, viewStart, viewDuration, containerWidth, isSelected, onSelect }) {
84211
+ const TimelineBar = reactExports.memo(function TimelineBar2({ span, viewStart, viewDuration, containerWidth, isSelected, isDimmed, onSelect }) {
83860
84212
  var _a3;
83861
84213
  const startMs = getHighResInMs(span.startTime);
83862
84214
  const endMs = getHighResInMs(span.endTime);
@@ -83874,7 +84226,7 @@ const TimelineBar = reactExports.memo(function TimelineBar2({ span, viewStart, v
83874
84226
  const handleClick = reactExports.useCallback(() => {
83875
84227
  onSelect(span.spanId);
83876
84228
  }, [onSelect, span.spanId]);
83877
- return jsxRuntimeExports.jsx("div", { role: "treeitem", "aria-selected": isSelected, "aria-expanded": isSelected, "aria-level": 1, className: "group/timeline-row h-10 relative flex items-center hover:bg-gray-100 aria-selected:bg-gray-100 aria-selected:hover:bg-gray-200", onClick: handleClick, children: jsxRuntimeExports.jsx("div", { className: "absolute inset-y-0", style: TIMELINE_INSET_STYLE, children: jsxRuntimeExports.jsx("div", { className: "absolute top-1/2 h-6 -translate-y-1/2", style: getBarPositionStyle(geometry), children: geometry.mode.kind === "arrow" ? jsxRuntimeExports.jsx(BoundaryArrow, { direction: geometry.mode.direction }) : geometry.mode.kind === "tiny" ? jsxRuntimeExports.jsx("div", { className: "h-6 rounded-[0.25rem] border", style: { background: fallbackBg, borderColor: fallbackBorder } }) : segments.length > 0 ? jsxRuntimeExports.jsx(SegmentBar, { segments }) : jsxRuntimeExports.jsx(PlainBar, { bg: fallbackBg, border: fallbackBorder, label: showTotalLabel ? totalLabel : null }) }) }) });
84229
+ return jsxRuntimeExports.jsx("div", { role: "treeitem", "aria-selected": isSelected, "aria-expanded": isSelected, "aria-level": 1, className: cn$4("group/timeline-row h-10 relative flex items-center hover:bg-gray-100 aria-selected:bg-gray-100 aria-selected:hover:bg-gray-200 transition-opacity", isDimmed && "opacity-35"), onClick: handleClick, children: jsxRuntimeExports.jsx("div", { className: "absolute inset-y-0", style: TIMELINE_INSET_STYLE, children: jsxRuntimeExports.jsx("div", { className: "absolute top-1/2 h-6 -translate-y-1/2 rounded-[0.25rem]", style: getBarPositionStyle(geometry), children: geometry.mode.kind === "arrow" ? jsxRuntimeExports.jsx(BoundaryArrow, { direction: geometry.mode.direction }) : geometry.mode.kind === "tiny" ? jsxRuntimeExports.jsx("div", { className: "h-6 rounded-[0.25rem] border", style: { background: fallbackBg, borderColor: fallbackBorder } }) : segments.length > 0 ? jsxRuntimeExports.jsx(SegmentBar, { segments }) : jsxRuntimeExports.jsx(PlainBar, { bg: fallbackBg, border: fallbackBorder, label: showTotalLabel ? totalLabel : null }) }) }) });
83878
84230
  });
83879
84231
  const DELTA_ROW_HEIGHT_PX = 40;
83880
84232
  const DELTA_CAP_HEIGHT_PX = 8;
@@ -83891,7 +84243,7 @@ const DeltaIndicator = reactExports.memo(function DeltaIndicator2({ leftFrac, ri
83891
84243
  function TimelineHeader({ markers: markers2, hoverInfo: hoverInfo2 }) {
83892
84244
  return jsxRuntimeExports.jsx("div", { className: "relative bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-end px-4 pb-1", children: jsxRuntimeExports.jsxs("div", { className: "relative h-full flex-1", children: [markers2.map((m2) => jsxRuntimeExports.jsx("span", { className: "absolute bottom-1 font-mono text-xs font-normal leading-4 text-gray-900 whitespace-nowrap", style: { left: `${m2.position * 100}%` }, children: m2.label }, `${m2.position}-${m2.label}`)), hoverInfo2 && jsxRuntimeExports.jsx("span", { className: "absolute top-1 pointer-events-none z-10 font-mono text-[11px] leading-4 text-gray-1000 whitespace-nowrap bg-background-100 border border-gray-alpha-400 rounded px-1 -translate-x-1/2", style: { left: `${hoverInfo2.fraction * 100}%` }, children: hoverInfo2.label })] }) });
83893
84245
  }
83894
- function Timeline({ spans, viewStart, viewEnd, markers: markers2, selectedId, onSelect, hoverFraction, altHeld = false }) {
84246
+ function Timeline({ spans, viewStart, viewEnd, markers: markers2, selectedId, searchResult, onSelect, hoverFraction, altHeld = false }) {
83895
84247
  const containerRef = reactExports.useRef(null);
83896
84248
  const [containerWidth, setContainerWidth] = reactExports.useState(0);
83897
84249
  const viewDuration = viewEnd - viewStart;
@@ -83910,7 +84262,7 @@ function Timeline({ spans, viewStart, viewEnd, markers: markers2, selectedId, on
83910
84262
  return jsxRuntimeExports.jsxs("div", { ref: containerRef, className: "relative h-full overflow-hidden", children: [jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "absolute inset-y-0 pointer-events-none", style: TIMELINE_INSET_STYLE, children: markers2.map((marker2) => (
83911
84263
  // Skip the "0s" origin marker since the left edge already implies it.
83912
84264
  Math.abs(marker2.value) > 1e-6 ? jsxRuntimeExports.jsx("div", { className: "absolute top-0 bottom-0 w-px bg-gray-alpha-300", style: { left: `${marker2.position * 100}%` } }, `${marker2.position}-${marker2.label}`) : null
83913
- )) }), hoverFraction != null && jsxRuntimeExports.jsx("div", { className: "absolute inset-y-0 pointer-events-none z-10", style: TIMELINE_INSET_STYLE, children: jsxRuntimeExports.jsx("div", { className: "absolute top-0 bottom-0 w-px bg-gray-alpha-500", style: { left: `${hoverFraction * 100}%` } }) }), spans.map((span) => jsxRuntimeExports.jsx(TimelineBar, { span, viewStart, viewDuration, containerWidth: timelineWidth, isSelected: selectedId === span.spanId, onSelect }, span.spanId)), altHeld && jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "absolute inset-y-0 pointer-events-none", style: TIMELINE_INSET_STYLE, children: gaps.map((gap) => jsxRuntimeExports.jsx(DeltaIndicator, { leftFrac: gap.leftFrac, rightFrac: gap.rightFrac, label: formatDuration(gap.gapMs, true), rowIndex: gap.rowIndex }, gap.rowIndex)) })] });
84265
+ )) }), hoverFraction != null && jsxRuntimeExports.jsx("div", { className: "absolute inset-y-0 pointer-events-none z-10", style: TIMELINE_INSET_STYLE, children: jsxRuntimeExports.jsx("div", { className: "absolute top-0 bottom-0 w-px bg-gray-alpha-500", style: { left: `${hoverFraction * 100}%` } }) }), spans.map((span) => jsxRuntimeExports.jsx(TimelineBar, { span, viewStart, viewDuration, containerWidth: timelineWidth, isSelected: selectedId === span.spanId, isDimmed: isSpanDimmedBySearch(span.spanId, searchResult), onSelect }, span.spanId)), altHeld && jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "absolute inset-y-0 pointer-events-none", style: TIMELINE_INSET_STYLE, children: gaps.map((gap) => jsxRuntimeExports.jsx(DeltaIndicator, { leftFrac: gap.leftFrac, rightFrac: gap.rightFrac, label: formatDuration(gap.gapMs, true), rowIndex: gap.rowIndex }, gap.rowIndex)) })] });
83914
84266
  }
83915
84267
  const ActiveSpanContext = reactExports.createContext(null);
83916
84268
  ActiveSpanContext.displayName = "ActiveSpanContext";
@@ -83960,7 +84312,7 @@ function DetailPanel({ span, rootStart, onClose }) {
83960
84312
  const startMs = getHighResInMs(span.startTime);
83961
84313
  const durationMs = getSpanDurationMs(span);
83962
84314
  const offsetMs = startMs - rootStart;
83963
- return jsxRuntimeExports.jsxs("aside", { className: "grid h-full max-h-full grid-rows-[2.5rem_1fr] bg-background-200", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-3 border-b border-gray-alpha-400", children: [jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-1000 truncate", children: span.name }), jsxRuntimeExports.jsx("button", { type: "button", className: "p-1 rounded-md text-gray-900 hover:text-gray-1000 hover:bg-gray-alpha-200 transition-colors", onClick: onClose, children: jsxRuntimeExports.jsx(X$3, { className: "w-4 h-4" }) })] }), jsxRuntimeExports.jsx("div", { className: "overflow-y-auto p-3 space-y-3", children: jsxRuntimeExports.jsxs("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1.5 text-sm", children: [jsxRuntimeExports.jsx("dt", { className: "text-gray-900", children: "Resource" }), jsxRuntimeExports.jsx("dd", { className: "text-gray-1000 font-mono", children: span.resource }), jsxRuntimeExports.jsx("dt", { className: "text-gray-900", children: "Duration" }), jsxRuntimeExports.jsx("dd", { className: "text-gray-1000 tabular-nums font-mono", children: formatDuration(durationMs) }), jsxRuntimeExports.jsx("dt", { className: "text-gray-900", children: "Offset" }), jsxRuntimeExports.jsxs("dd", { className: "text-gray-1000 tabular-nums font-mono", children: ["+", formatDuration(offsetMs)] }), jsxRuntimeExports.jsx("dt", { className: "text-gray-900", children: "Status" }), jsxRuntimeExports.jsx("dd", { className: "text-gray-1000 font-mono", children: span.status.code === 2 ? "Error" : "OK" })] }) })] });
84315
+ return jsxRuntimeExports.jsxs("aside", { className: "grid h-full max-h-full grid-rows-[2.5rem_1fr] bg-background-200", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-3 border-b border-gray-alpha-400", children: [jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-1000 truncate", children: span.name }), jsxRuntimeExports.jsx(IconButton, { "aria-label": "Close span details", onClick: onClose, children: jsxRuntimeExports.jsx(X$3, { className: "w-4 h-4" }) })] }), jsxRuntimeExports.jsx("div", { className: "overflow-y-auto p-3 space-y-3", children: jsxRuntimeExports.jsxs("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1.5 text-sm", children: [jsxRuntimeExports.jsx("dt", { className: "text-gray-900", children: "Resource" }), jsxRuntimeExports.jsx("dd", { className: "text-gray-1000 font-mono", children: span.resource }), jsxRuntimeExports.jsx("dt", { className: "text-gray-900", children: "Duration" }), jsxRuntimeExports.jsx("dd", { className: "text-gray-1000 tabular-nums font-mono", children: formatDuration(durationMs) }), jsxRuntimeExports.jsx("dt", { className: "text-gray-900", children: "Offset" }), jsxRuntimeExports.jsxs("dd", { className: "text-gray-1000 tabular-nums font-mono", children: ["+", formatDuration(offsetMs)] }), jsxRuntimeExports.jsx("dt", { className: "text-gray-900", children: "Status" }), jsxRuntimeExports.jsx("dd", { className: "text-gray-1000 font-mono", children: span.status.code === 2 ? "Error" : "OK" })] }) })] });
83964
84316
  }
83965
84317
  const MIN_VIEWPORT_MS = 1e-3;
83966
84318
  function useAnimatedViewport(initial) {
@@ -84030,7 +84382,7 @@ function useSelectedSpanInfo() {
84030
84382
  spanId: activeSpan.spanId,
84031
84383
  rawEvents
84032
84384
  };
84033
- }, [activeSpan, sidebar == null ? void 0 : sidebar.events]);
84385
+ }, [activeSpan, sidebar]);
84034
84386
  }
84035
84387
  function NewTraceViewer$1({ trace: trace2 }) {
84036
84388
  return jsxRuntimeExports.jsx(ActiveSpanProvider, { spans: trace2.spans, children: jsxRuntimeExports.jsx(NewTraceViewerContent, { trace: trace2 }) });
@@ -84040,12 +84392,8 @@ function NewTraceViewerContent({ trace: trace2 }) {
84040
84392
  const sidebar = useSidebarDataOptional();
84041
84393
  const selectedSpan = useSelectedSpanInfo();
84042
84394
  const [searchQuery, setSearchQuery] = reactExports.useState("");
84043
- const filteredSpans = reactExports.useMemo(() => {
84044
- const q2 = searchQuery.trim().toLowerCase();
84045
- if (!q2)
84046
- return trace2.spans;
84047
- return trace2.spans.filter((s2) => s2.name.toLowerCase().includes(q2) || s2.resource.toLowerCase().includes(q2));
84048
- }, [trace2.spans, searchQuery]);
84395
+ const deferredSearchQuery = reactExports.useDeferredValue(searchQuery);
84396
+ const searchResult = reactExports.useMemo(() => searchSpans(trace2.spans, deferredSearchQuery), [trace2.spans, deferredSearchQuery]);
84049
84397
  const root2 = reactExports.useMemo(() => computeRootBounds(trace2.spans), [trace2.spans]);
84050
84398
  const { viewport, setViewport, animateTo } = useAnimatedViewport({
84051
84399
  start: root2.startTime,
@@ -84067,7 +84415,7 @@ function NewTraceViewerContent({ trace: trace2 }) {
84067
84415
  return prev;
84068
84416
  });
84069
84417
  prevRootRef.current = { start: newStart, end: newEnd };
84070
- }, [root2.startTime, root2.duration]);
84418
+ }, [root2.startTime, root2.duration, setViewport]);
84071
84419
  const viewDuration = viewport.end - viewport.start;
84072
84420
  const timeMarkers = reactExports.useMemo(() => computeTimeMarkers(viewDuration, viewport.start - root2.startTime), [viewDuration, viewport.start, root2.startTime]);
84073
84421
  const resetZoom = reactExports.useCallback(() => {
@@ -84146,13 +84494,25 @@ function NewTraceViewerContent({ trace: trace2 }) {
84146
84494
  ]);
84147
84495
  const [altHeld, setAltHeld] = reactExports.useState(false);
84148
84496
  reactExports.useEffect(() => {
84497
+ const handleSidebarNavKey = (e) => {
84498
+ const target2 = e.target;
84499
+ if (target2 instanceof HTMLInputElement || target2 instanceof HTMLTextAreaElement || (target2 == null ? void 0 : target2.isContentEditable)) {
84500
+ return;
84501
+ }
84502
+ const targetId = e.key === "k" ? prevSpanIdRef.current : nextSpanIdRef.current;
84503
+ if (targetId) {
84504
+ e.preventDefault();
84505
+ handleSelectSpanRef.current(targetId);
84506
+ }
84507
+ };
84149
84508
  const onKeyDown = (e) => {
84150
84509
  if (e.key === "Escape") {
84151
84510
  clearActiveSpan();
84152
- }
84153
- if (e.key === "Alt") {
84511
+ } else if (e.key === "Alt") {
84154
84512
  e.preventDefault();
84155
84513
  setAltHeld(true);
84514
+ } else if (e.key === "j" || e.key === "k") {
84515
+ handleSidebarNavKey(e);
84156
84516
  }
84157
84517
  };
84158
84518
  const onKeyUp = (e) => {
@@ -84216,7 +84576,8 @@ function NewTraceViewerContent({ trace: trace2 }) {
84216
84576
  if (e.deltaMode === 1)
84217
84577
  dy *= 16;
84218
84578
  const cursorFraction = Math.max(0, Math.min(1, (e.clientX - rect.left - TIMELINE_PADDING_PX) / contentWidth));
84219
- const scaleFactor = Math.pow(2, dy / 200);
84579
+ const isMouseWheel = e.deltaMode === 1 || Math.abs(e.deltaY) >= 50;
84580
+ const scaleFactor = Math.pow(2, dy / (isMouseWheel ? 200 : 60));
84220
84581
  setViewport((prev) => {
84221
84582
  const prevDuration = prev.end - prev.start;
84222
84583
  const cursorTime = prev.start + cursorFraction * prevDuration;
@@ -84256,7 +84617,7 @@ function NewTraceViewerContent({ trace: trace2 }) {
84256
84617
  };
84257
84618
  el.addEventListener("wheel", onWheel, { passive: false });
84258
84619
  return () => el.removeEventListener("wheel", onWheel);
84259
- }, [root2.startTime, root2.duration]);
84620
+ }, [root2.startTime, root2.duration, setViewport]);
84260
84621
  const selectedSpanName = reactExports.useMemo(() => {
84261
84622
  var _a3, _b2;
84262
84623
  if (!(selectedSpan == null ? void 0 : selectedSpan.data))
@@ -84269,17 +84630,39 @@ function NewTraceViewerContent({ trace: trace2 }) {
84269
84630
  const workflowName = data.workflowName;
84270
84631
  return (stepName ? (_a3 = parseStepName(stepName)) == null ? void 0 : _a3.shortName : void 0) ?? (workflowName ? (_b2 = parseWorkflowName(workflowName)) == null ? void 0 : _b2.shortName : void 0) ?? stepName ?? workflowName ?? data.hookId ?? "Details";
84271
84632
  }, [selectedSpan == null ? void 0 : selectedSpan.data, selectedSpan == null ? void 0 : selectedSpan.resource]);
84272
- const selectedResource = selectedSpan == null ? void 0 : selectedSpan.resource;
84273
- const selectedResourceId = reactExports.useMemo(() => {
84274
- if (!(selectedSpan == null ? void 0 : selectedSpan.data))
84275
- return void 0;
84276
- const data = selectedSpan.data;
84277
- if (selectedSpan.resource === "hook") {
84278
- return data.hookId ?? selectedSpan.spanId;
84633
+ const { prevSpanId, nextSpanId } = reactExports.useMemo(() => {
84634
+ var _a3, _b2;
84635
+ if (!activeSpanId)
84636
+ return { prevSpanId: null, nextSpanId: null };
84637
+ const i = trace2.spans.findIndex((s2) => s2.spanId === activeSpanId);
84638
+ if (i === -1)
84639
+ return { prevSpanId: null, nextSpanId: null };
84640
+ return {
84641
+ prevSpanId: ((_a3 = trace2.spans[i - 1]) == null ? void 0 : _a3.spanId) ?? null,
84642
+ nextSpanId: ((_b2 = trace2.spans[i + 1]) == null ? void 0 : _b2.spanId) ?? null
84643
+ };
84644
+ }, [activeSpanId, trace2.spans]);
84645
+ const handleSelectPrevSpan = reactExports.useCallback(() => {
84646
+ if (prevSpanId)
84647
+ handleSelectSpan(prevSpanId);
84648
+ }, [prevSpanId, handleSelectSpan]);
84649
+ const handleSelectNextSpan = reactExports.useCallback(() => {
84650
+ if (nextSpanId)
84651
+ handleSelectSpan(nextSpanId);
84652
+ }, [nextSpanId, handleSelectSpan]);
84653
+ const prevSpanIdRef = reactExports.useRef(prevSpanId);
84654
+ const nextSpanIdRef = reactExports.useRef(nextSpanId);
84655
+ const handleSelectSpanRef = reactExports.useRef(handleSelectSpan);
84656
+ prevSpanIdRef.current = prevSpanId;
84657
+ nextSpanIdRef.current = nextSpanId;
84658
+ handleSelectSpanRef.current = handleSelectSpan;
84659
+ return jsxRuntimeExports.jsxs("div", { "data-pane": "pane-root", "data-has-detail": activeSpan ? "" : void 0, className: "grid w-full h-full max-h-full grid-cols-[minmax(100px,1fr)] data-[has-detail]:grid-cols-[minmax(100px,1fr)_clamp(280px,420px,100%)]", children: [jsxRuntimeExports.jsxs("div", { id: "trace-parent", className: "grid grid-rows-[1fr] h-full min-h-0 overflow-hidden relative bg-background-100", children: [jsxRuntimeExports.jsxs(SplitPane, { startHeader: jsxRuntimeExports.jsxs("div", { className: "bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-center pl-4 pr-2 gap-1.5", children: [jsxRuntimeExports.jsx(Search, { className: "w-3.5 h-3.5 shrink-0 text-gray-800" }), jsxRuntimeExports.jsx("input", { id: "trace-viewer-search", name: "trace-viewer-search", type: "text", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), onKeyDown: (e) => {
84660
+ if (e.key === "Escape" && searchQuery) {
84661
+ e.preventDefault();
84662
+ e.stopPropagation();
84663
+ setSearchQuery("");
84279
84664
  }
84280
- return data.stepId ?? data.runId ?? data.hookId ?? selectedSpan.spanId;
84281
- }, [selectedSpan == null ? void 0 : selectedSpan.data, selectedSpan == null ? void 0 : selectedSpan.resource, selectedSpan == null ? void 0 : selectedSpan.spanId]);
84282
- return jsxRuntimeExports.jsxs("div", { "data-pane": "pane-root", "data-has-detail": activeSpan ? "" : void 0, className: "grid w-full h-full max-h-full grid-cols-[minmax(100px,1fr)] data-[has-detail]:grid-cols-[minmax(100px,1fr)_clamp(280px,420px,100%)]", children: [jsxRuntimeExports.jsxs("div", { id: "trace-parent", className: "grid grid-rows-[1fr] h-full min-h-0 overflow-hidden relative bg-background-100", children: [jsxRuntimeExports.jsxs(SplitPane, { startHeader: jsxRuntimeExports.jsxs("div", { className: "bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-center px-2 gap-1.5", children: [jsxRuntimeExports.jsx(Search, { className: "w-3.5 h-3.5 shrink-0 text-gray-800" }), jsxRuntimeExports.jsx("input", { id: "trace-viewer-search", name: "trace-viewer-search", type: "text", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: "Search spans...", "aria-label": "Search spans", className: "flex-1 min-w-0 bg-transparent text-sm text-gray-1000 placeholder:text-gray-800 outline-none" }), searchQuery && jsxRuntimeExports.jsx("button", { type: "button", onClick: () => setSearchQuery(""), className: "shrink-0 p-0.5 rounded-sm text-gray-800 hover:text-gray-1000 hover:bg-gray-200 transition-colors", children: jsxRuntimeExports.jsx(X$3, { className: "w-3 h-3" }) })] }), endHeader: jsxRuntimeExports.jsx(TimelineHeader, { markers: timeMarkers, hoverInfo: hoverInfo2 }), children: [jsxRuntimeExports.jsx("div", { className: "block overflow-visible", children: jsxRuntimeExports.jsx(EventList, { spans: filteredSpans, activeSpanId, onSelectSpan: handleSelectSpan }) }), jsxRuntimeExports.jsx("div", { ref: timelineRef, className: "block min-h-0 overflow-visible relative", onDoubleClick: resetZoom, onMouseMove: handleTimelineMouseMove, onMouseLeave: handleTimelineMouseLeave, children: jsxRuntimeExports.jsx(Timeline, { spans: filteredSpans, viewStart: viewport.start, viewEnd: viewport.end, markers: timeMarkers, selectedId: activeSpanId, onSelect: handleSelectSpan, hoverFraction, altHeld }) })] }), jsxRuntimeExports.jsxs("div", { className: "absolute right-3 bottom-3 z-[5] flex items-center border border-gray-alpha-400 rounded-lg bg-background-100 shadow-sm overflow-hidden divide-x divide-gray-alpha-400", children: [jsxRuntimeExports.jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[time:120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100", onClick: zoomOut, "aria-label": "Zoom out", children: jsxRuntimeExports.jsx(ZoomOut, { className: "w-4 h-4" }) }), jsxRuntimeExports.jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[time:120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100", onClick: resetZoom, "aria-label": "Reset zoom", children: jsxRuntimeExports.jsx(RotateCcw, { className: "w-3.5 h-3.5" }) }), jsxRuntimeExports.jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[time:120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100", onClick: zoomIn, "aria-label": "Zoom in", children: jsxRuntimeExports.jsx(ZoomIn, { className: "w-4 h-4" }) })] })] }), activeSpan && sidebar ? jsxRuntimeExports.jsxs("aside", { className: "flex flex-col h-full max-h-full bg-background-100 border-l border-gray-alpha-400 overflow-auto", children: [jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 px-4 pt-4 pb-3", children: jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1", children: [jsxRuntimeExports.jsx("span", { className: "text-[15px] font-semibold text-gray-1000 truncate block", children: selectedSpanName }), selectedResourceId && jsxRuntimeExports.jsxs("div", { className: "mt-1 flex items-center gap-2", children: [selectedResource && jsxRuntimeExports.jsx("span", { className: `inline-flex items-center rounded-md px-1.5 py-0.5 text-[11px] font-medium leading-none shrink-0 ${selectedResource === "step" ? "bg-green-200 text-green-900" : selectedResource === "run" ? "bg-blue-200 text-blue-900" : "bg-gray-200 text-gray-900"}`, children: selectedResource.charAt(0).toUpperCase() + selectedResource.slice(1) }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-[13px] font-mono text-gray-700 min-w-0", title: selectedResourceId, children: [jsxRuntimeExports.jsx("span", { className: "truncate", children: selectedResourceId }), jsxRuntimeExports.jsx(CopyButton, { copyText: selectedResourceId, ariaLabel: "Copy ID", className: "shrink-0" })] })] })] }), jsxRuntimeExports.jsx("button", { type: "button", className: "p-1 rounded-md text-gray-900 hover:text-gray-1000 hover:bg-gray-alpha-200 transition-colors shrink-0", onClick: clearActiveSpan, children: jsxRuntimeExports.jsx(X$3, { className: "w-4 h-4" }) })] }) }), jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto", children: jsxRuntimeExports.jsx(ErrorBoundary$1, { children: jsxRuntimeExports.jsx(EntityDetailPanel, { run: sidebar.run, onStreamClick: sidebar.onStreamClick, onRunClick: sidebar.onRunClick, spanDetailData: sidebar.spanDetailData, spanDetailError: sidebar.spanDetailError, spanDetailLoading: sidebar.spanDetailLoading, onSpanSelect: sidebar.onSpanSelect, onWakeUpSleep: sidebar.onWakeUpSleep, onLoadEventData: sidebar.onLoadEventData, onResolveHook: sidebar.onResolveHook, encryptionKey: sidebar.encryptionKey, onDecrypt: sidebar.onDecrypt, isDecrypting: sidebar.isDecrypting, selectedSpan }) }) })] }) : activeSpan ? jsxRuntimeExports.jsx(DetailPanel, { span: activeSpan, rootStart: root2.startTime, onClose: clearActiveSpan }) : null] });
84665
+ }, placeholder: "Search spans...", "aria-label": "Search spans", className: "flex-1 min-w-0 bg-transparent text-sm text-gray-1000 placeholder:text-gray-800 outline-none" }), searchQuery && jsxRuntimeExports.jsx("button", { type: "button", "aria-label": "Clear search", onClick: () => setSearchQuery(""), className: "-mr-2 hidden h-full max-w-full shrink-0 cursor-pointer items-center rounded-r-md border-0 bg-transparent px-2.5 font-inherit text-base text-gray-900 no-underline transition-colors duration-150 ease-in hover:text-gray-1000 focus-visible:-outline-offset-1 focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--ds-focus-color)] min-[961px]:flex", children: jsxRuntimeExports.jsx("kbd", { className: "inline-flex h-5 min-h-5 min-w-5 items-center justify-center rounded border border-gray-alpha-400 bg-background-100 px-1 font-sans text-[13px] font-medium leading-[1.7em] text-gray-900", children: "Esc" }) })] }), endHeader: jsxRuntimeExports.jsx(TimelineHeader, { markers: timeMarkers, hoverInfo: hoverInfo2 }), children: [jsxRuntimeExports.jsx("div", { className: "block overflow-visible", children: jsxRuntimeExports.jsx(EventList, { spans: trace2.spans, activeSpanId, searchResult, onSelectSpan: handleSelectSpan }) }), jsxRuntimeExports.jsx("div", { ref: timelineRef, className: "block min-h-0 overflow-visible relative", onDoubleClick: resetZoom, onMouseMove: handleTimelineMouseMove, onMouseLeave: handleTimelineMouseLeave, children: jsxRuntimeExports.jsx(Timeline, { spans: trace2.spans, viewStart: viewport.start, viewEnd: viewport.end, markers: timeMarkers, selectedId: activeSpanId, searchResult, onSelect: handleSelectSpan, hoverFraction, altHeld }) })] }), jsxRuntimeExports.jsxs("div", { className: "absolute right-3 bottom-3 z-[5] flex items-center border border-gray-alpha-400 rounded-md bg-background-100 shadow-sm overflow-hidden divide-x divide-gray-alpha-400", children: [jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: zoomOut, "aria-label": "Zoom out", children: jsxRuntimeExports.jsx(ZoomOut, { className: "w-4 h-4" }) }), jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: resetZoom, "aria-label": "Reset zoom", children: jsxRuntimeExports.jsx(RotateCcw, { className: "w-3.5 h-3.5" }) }), jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: zoomIn, "aria-label": "Zoom in", children: jsxRuntimeExports.jsx(ZoomIn, { className: "w-4 h-4" }) })] })] }), activeSpan && sidebar ? jsxRuntimeExports.jsxs("aside", { className: "flex flex-col h-full max-h-full bg-background-100 border-l border-gray-alpha-400 overflow-auto", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 shrink-0 px-4 pt-3 pb-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-14 font-medium text-gray-1000 truncate block", children: selectedSpanName }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0.5 shrink-0", children: [jsxRuntimeExports.jsx(IconButton, { "aria-label": "Navigate to previous span", "aria-keyshortcuts": "K", onClick: handleSelectPrevSpan, disabled: !prevSpanId, children: jsxRuntimeExports.jsx(ChevronUp, { className: "w-4 h-4" }) }), jsxRuntimeExports.jsx(IconButton, { "aria-label": "Navigate to next span", "aria-keyshortcuts": "J", onClick: handleSelectNextSpan, disabled: !nextSpanId, children: jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4" }) }), jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "w-px h-4 bg-gray-alpha-400 mx-1" }), jsxRuntimeExports.jsx(IconButton, { "aria-label": "Close span details", "aria-keyshortcuts": "Escape", onClick: clearActiveSpan, children: jsxRuntimeExports.jsx(X$3, { className: "w-4 h-4" }) })] })] }), jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto", children: jsxRuntimeExports.jsx(ErrorBoundary$1, { children: jsxRuntimeExports.jsx(EntityDetailPanel, { run: sidebar.run, onStreamClick: sidebar.onStreamClick, onRunClick: sidebar.onRunClick, spanDetailData: sidebar.spanDetailData, spanDetailError: sidebar.spanDetailError, spanDetailLoading: sidebar.spanDetailLoading, onSpanSelect: sidebar.onSpanSelect, onWakeUpSleep: sidebar.onWakeUpSleep, onLoadEventData: sidebar.onLoadEventData, onResolveHook: sidebar.onResolveHook, encryptionKey: sidebar.encryptionKey, onDecrypt: sidebar.onDecrypt, isDecrypting: sidebar.isDecrypting, selectedSpan }) }) })] }) : activeSpan ? jsxRuntimeExports.jsx(DetailPanel, { span: activeSpan, rootStart: root2.startTime, onClose: clearActiveSpan }) : null] });
84283
84666
  }
84284
84667
  const NewTraceViewer = ({ run, events: events2, sidebarData }) => {
84285
84668
  const traceWithMeta = reactExports.useMemo(() => {
@@ -84613,46 +84996,6 @@ function getElementRef$2(element2) {
84613
84996
  }
84614
84997
  return element2.props.ref || element2.ref;
84615
84998
  }
84616
- const falsyToString = (value) => typeof value === "boolean" ? `${value}` : value === 0 ? "0" : value;
84617
- const cx = clsx;
84618
- const cva = (base, config2) => (props) => {
84619
- var _config_compoundVariants;
84620
- if ((config2 === null || config2 === void 0 ? void 0 : config2.variants) == null) return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
84621
- const { variants, defaultVariants } = config2;
84622
- const getVariantClassNames = Object.keys(variants).map((variant) => {
84623
- const variantProp = props === null || props === void 0 ? void 0 : props[variant];
84624
- const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];
84625
- if (variantProp === null) return null;
84626
- const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);
84627
- return variants[variant][variantKey];
84628
- });
84629
- const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param) => {
84630
- let [key, value] = param;
84631
- if (value === void 0) {
84632
- return acc;
84633
- }
84634
- acc[key] = value;
84635
- return acc;
84636
- }, {});
84637
- const getCompoundVariantClassNames = config2 === null || config2 === void 0 ? void 0 : (_config_compoundVariants = config2.compoundVariants) === null || _config_compoundVariants === void 0 ? void 0 : _config_compoundVariants.reduce((acc, param) => {
84638
- let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param;
84639
- return Object.entries(compoundVariantOptions).every((param2) => {
84640
- let [key, value] = param2;
84641
- return Array.isArray(value) ? value.includes({
84642
- ...defaultVariants,
84643
- ...propsWithoutUndefined
84644
- }[key]) : {
84645
- ...defaultVariants,
84646
- ...propsWithoutUndefined
84647
- }[key] === value;
84648
- }) ? [
84649
- ...acc,
84650
- cvClass,
84651
- cvClassName
84652
- ] : acc;
84653
- }, []);
84654
- return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
84655
- };
84656
84999
  const buttonVariants = cva(
84657
85000
  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
84658
85001
  {
@@ -88243,7 +88586,7 @@ const encryption = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
88243
88586
  encrypt: encrypt$1,
88244
88587
  importKey
88245
88588
  }, Symbol.toStringTag, { value: "Module" }));
88246
- const version$1 = "5.0.0-beta.7";
88589
+ const version$1 = "5.0.0-beta.9";
88247
88590
  const WorldCacheKey = Symbol.for("@workflow/world//cache");
88248
88591
  const WorldCachePromiseKey = Symbol.for("@workflow/world//cachePromise");
88249
88592
  const GetWorldFnKey$1 = Symbol.for("@workflow/world//getWorldFn");
@@ -88379,12 +88722,15 @@ async function healthCheck(world, endpoint, options) {
88379
88722
  }
88380
88723
  const LOCK_POLL_INTERVAL_MS = 10;
88381
88724
  function createFlushableState() {
88382
- return {
88725
+ const state = {
88383
88726
  ...withResolvers$1(),
88384
88727
  pendingOps: 0,
88385
88728
  doneResolved: false,
88386
88729
  streamEnded: false
88387
88730
  };
88731
+ state.promise.catch(() => {
88732
+ });
88733
+ return state;
88388
88734
  }
88389
88735
  function isWritableUnlockedNotClosed(writable) {
88390
88736
  if (writable.locked)
@@ -91730,7 +92076,7 @@ function truncateForError(value) {
91730
92076
  }
91731
92077
  class UnsafeEntityIdError extends WorkflowWorldError {
91732
92078
  constructor(kind, value) {
91733
- super(`Unsafe ${kind} "${truncateForError(value)}": must not be empty, start with ".", or contain path separators or null bytes`);
92079
+ super(`Unsafe ${kind} "${truncateForError(value)}": must not be empty, contain ".", "/", "\\", or null bytes`);
91734
92080
  this.name = "UnsafeEntityIdError";
91735
92081
  }
91736
92082
  static is(value) {
@@ -91738,7 +92084,7 @@ class UnsafeEntityIdError extends WorkflowWorldError {
91738
92084
  }
91739
92085
  }
91740
92086
  function assertSafeEntityId(kind, value) {
91741
- if (value.length === 0 || value.startsWith(".") || value.includes("/") || value.includes("\\") || value.includes("\0")) {
92087
+ if (value.length === 0 || value.startsWith(".") || value.includes("/") || value.includes("\\") || value.includes("\0") || value.includes(".")) {
91742
92088
  throw new UnsafeEntityIdError(kind, value);
91743
92089
  }
91744
92090
  }
@@ -91889,6 +92235,16 @@ async function readBuffer(filePath) {
91889
92235
  const content2 = await promises.readFile(filePath);
91890
92236
  return content2;
91891
92237
  }
92238
+ async function readFirstByte(filePath) {
92239
+ const file2 = await promises.open(filePath, "r");
92240
+ try {
92241
+ const byte = Buffer.allocUnsafe(1);
92242
+ const { bytesRead } = await file2.read(byte, 0, 1, 0);
92243
+ return bytesRead === 0 ? void 0 : byte[0];
92244
+ } finally {
92245
+ await file2.close();
92246
+ }
92247
+ }
91892
92248
  async function deleteJSON(filePath) {
91893
92249
  try {
91894
92250
  await promises.unlink(filePath);
@@ -116833,7 +117189,8 @@ async function handleLegacyEvent(basedir, runId, data, currentRun, params) {
116833
117189
  output: void 0,
116834
117190
  error: void 0,
116835
117191
  completedAt: now2,
116836
- updatedAt: now2
117192
+ updatedAt: now2,
117193
+ attributes: currentRun.attributes
116837
117194
  };
116838
117195
  const runPath = resolveWithinBase(basedir, "runs", `${runId}.json`);
116839
117196
  await writeJSON(runPath, run, { overwrite: true });
@@ -116863,6 +117220,102 @@ async function handleLegacyEvent(basedir, runId, data, currentRun, params) {
116863
117220
  throw new Error(`Event type '${data.eventType}' not supported for legacy runs (specVersion: ${currentRun.specVersion || "undefined"}). Please upgrade 'workflow' package.`);
116864
117221
  }
116865
117222
  }
117223
+ const runFileLocks = /* @__PURE__ */ new Map();
117224
+ function withRunFileLock(key, fn2) {
117225
+ const prev = runFileLocks.get(key);
117226
+ const taskBox = {};
117227
+ const task = (async () => {
117228
+ if (prev)
117229
+ await prev.catch(() => void 0);
117230
+ try {
117231
+ return await fn2();
117232
+ } finally {
117233
+ if (runFileLocks.get(key) === taskBox.task) {
117234
+ runFileLocks.delete(key);
117235
+ }
117236
+ }
117237
+ })();
117238
+ taskBox.task = task;
117239
+ runFileLocks.set(key, task);
117240
+ return task;
117241
+ }
117242
+ function createRunsStorage(basedir, tag) {
117243
+ return {
117244
+ get: (async (id2, params) => {
117245
+ assertSafeEntityId("runId", id2);
117246
+ const run = await readJSONWithFallback(basedir, "runs", id2, WorkflowRunSchema, tag);
117247
+ if (!run) {
117248
+ throw new WorkflowRunNotFoundError(id2);
117249
+ }
117250
+ const resolveData = (params == null ? void 0 : params.resolveData) ?? DEFAULT_RESOLVE_DATA_OPTION$1;
117251
+ return filterRunData$1(run, resolveData);
117252
+ }),
117253
+ list: (async (params) => {
117254
+ var _a3, _b2, _c2;
117255
+ const resolveData = (params == null ? void 0 : params.resolveData) ?? DEFAULT_RESOLVE_DATA_OPTION$1;
117256
+ const result = await paginatedFileSystemQuery({
117257
+ directory: path$3.join(basedir, "runs"),
117258
+ schema: WorkflowRunSchema,
117259
+ fileIdFilter: params == null ? void 0 : params.fileIdFilter,
117260
+ filter: (run) => {
117261
+ if ((params == null ? void 0 : params.workflowName) && run.workflowName !== params.workflowName) {
117262
+ return false;
117263
+ }
117264
+ if ((params == null ? void 0 : params.status) && run.status !== params.status) {
117265
+ return false;
117266
+ }
117267
+ return true;
117268
+ },
117269
+ sortOrder: ((_a3 = params == null ? void 0 : params.pagination) == null ? void 0 : _a3.sortOrder) ?? "desc",
117270
+ limit: (_b2 = params == null ? void 0 : params.pagination) == null ? void 0 : _b2.limit,
117271
+ cursor: (_c2 = params == null ? void 0 : params.pagination) == null ? void 0 : _c2.cursor,
117272
+ getCreatedAt: getObjectCreatedAt("wrun"),
117273
+ getId: (run) => run.runId
117274
+ });
117275
+ if (resolveData === "none") {
117276
+ return {
117277
+ ...result,
117278
+ data: result.data.map((run) => ({
117279
+ ...run,
117280
+ input: void 0,
117281
+ output: void 0
117282
+ }))
117283
+ };
117284
+ }
117285
+ return result;
117286
+ }),
117287
+ experimentalSetAttributes: async (runId, changes, options) => {
117288
+ assertSafeEntityId("runId", runId);
117289
+ return withRunFileLock(runId, async () => {
117290
+ const run = await readJSONWithFallback(basedir, "runs", runId, WorkflowRunSchema, tag);
117291
+ if (!run) {
117292
+ throw new WorkflowRunNotFoundError(runId);
117293
+ }
117294
+ try {
117295
+ validateAttributeChanges(changes, {
117296
+ existingKeys: Object.keys(run.attributes ?? {}),
117297
+ allowReservedAttributes: options == null ? void 0 : options.allowReservedAttributes
117298
+ });
117299
+ } catch (err) {
117300
+ if (err instanceof AttributeValidationError) {
117301
+ throw err;
117302
+ }
117303
+ throw err;
117304
+ }
117305
+ const nextAttributes = applyAttributeChanges(run.attributes, changes);
117306
+ const updatedRun = {
117307
+ ...run,
117308
+ attributes: nextAttributes,
117309
+ updatedAt: /* @__PURE__ */ new Date()
117310
+ };
117311
+ await writeJSON(taggedPath(basedir, "runs", runId, tag), updatedRun, {
117312
+ overwrite: true
117313
+ });
117314
+ return { attributes: nextAttributes };
117315
+ });
117316
+ }
117317
+ };
117318
+ }
116866
117319
  const stepLocks = /* @__PURE__ */ new Map();
116867
117320
  const HookTokenClaimSchema = object$1({
116868
117321
  runId: string$3()
@@ -116906,13 +117359,26 @@ async function deleteAllWaitsForRun(basedir, runId) {
116906
117359
  }
116907
117360
  }
116908
117361
  }
117362
+ async function writeRunUnderLifecycleLock(basedir, runId, tag, proposed) {
117363
+ return withRunFileLock(runId, async () => {
117364
+ const fresh = await readJSON(taggedPath(basedir, "runs", runId, tag), WorkflowRunSchema);
117365
+ const next2 = {
117366
+ ...proposed,
117367
+ attributes: (fresh == null ? void 0 : fresh.attributes) ?? proposed.attributes
117368
+ };
117369
+ await writeJSON(taggedPath(basedir, "runs", runId, tag), next2, {
117370
+ overwrite: true
117371
+ });
117372
+ return next2;
117373
+ });
117374
+ }
116909
117375
  function createEventsStorage(basedir, tag) {
116910
117376
  return {
116911
117377
  async create(runId, data, params) {
116912
117378
  if (runId != null && runId !== "") {
116913
117379
  assertSafeEntityId("runId", runId);
116914
117380
  }
116915
- if ("correlationId" in data && typeof data.correlationId === "string" && data.correlationId.length > 0) {
117381
+ if ("correlationId" in data && typeof data.correlationId === "string") {
116916
117382
  assertSafeEntityId("correlationId", data.correlationId);
116917
117383
  }
116918
117384
  const isStepEvent2 = data.eventType === "step_created" || data.eventType === "step_started" || data.eventType === "step_completed" || data.eventType === "step_failed" || data.eventType === "step_retrying";
@@ -116960,6 +117426,7 @@ function createEventsStorage(basedir, tag) {
116960
117426
  error: void 0,
116961
117427
  startedAt: void 0,
116962
117428
  completedAt: void 0,
117429
+ attributes: {},
116963
117430
  createdAt: now2,
116964
117431
  updatedAt: now2
116965
117432
  };
@@ -117090,6 +117557,7 @@ function createEventsStorage(basedir, tag) {
117090
117557
  error: void 0,
117091
117558
  startedAt: void 0,
117092
117559
  completedAt: void 0,
117560
+ attributes: {},
117093
117561
  createdAt: now2,
117094
117562
  updatedAt: now2
117095
117563
  };
@@ -117103,7 +117571,7 @@ function createEventsStorage(basedir, tag) {
117103
117571
  if (currentRun.status === "running") {
117104
117572
  return { run: currentRun };
117105
117573
  }
117106
- run = {
117574
+ run = await writeRunUnderLifecycleLock(basedir, effectiveRunId, tag, {
117107
117575
  runId: currentRun.runId,
117108
117576
  deploymentId: currentRun.deploymentId,
117109
117577
  workflowName: currentRun.workflowName,
@@ -117117,14 +117585,14 @@ function createEventsStorage(basedir, tag) {
117117
117585
  error: void 0,
117118
117586
  completedAt: void 0,
117119
117587
  startedAt: currentRun.startedAt ?? now2,
117120
- updatedAt: now2
117121
- };
117122
- await writeJSON(taggedPath(basedir, "runs", effectiveRunId, tag), run, { overwrite: true });
117588
+ updatedAt: now2,
117589
+ attributes: currentRun.attributes
117590
+ });
117123
117591
  }
117124
117592
  } else if (data.eventType === "run_completed" && "eventData" in data) {
117125
117593
  const completedData = data.eventData;
117126
117594
  if (currentRun) {
117127
- run = {
117595
+ run = await writeRunUnderLifecycleLock(basedir, effectiveRunId, tag, {
117128
117596
  runId: currentRun.runId,
117129
117597
  deploymentId: currentRun.deploymentId,
117130
117598
  workflowName: currentRun.workflowName,
@@ -117138,9 +117606,9 @@ function createEventsStorage(basedir, tag) {
117138
117606
  output: completedData.output,
117139
117607
  error: void 0,
117140
117608
  completedAt: now2,
117141
- updatedAt: now2
117142
- };
117143
- await writeJSON(taggedPath(basedir, "runs", effectiveRunId, tag), run, { overwrite: true });
117609
+ updatedAt: now2,
117610
+ attributes: currentRun.attributes
117611
+ });
117144
117612
  await Promise.all([
117145
117613
  deleteAllHooksForRun(basedir, effectiveRunId),
117146
117614
  deleteAllWaitsForRun(basedir, effectiveRunId)
@@ -117149,7 +117617,7 @@ function createEventsStorage(basedir, tag) {
117149
117617
  } else if (data.eventType === "run_failed" && "eventData" in data) {
117150
117618
  const failedData = data.eventData;
117151
117619
  if (currentRun) {
117152
- run = {
117620
+ run = await writeRunUnderLifecycleLock(basedir, effectiveRunId, tag, {
117153
117621
  runId: currentRun.runId,
117154
117622
  deploymentId: currentRun.deploymentId,
117155
117623
  workflowName: currentRun.workflowName,
@@ -117164,9 +117632,9 @@ function createEventsStorage(basedir, tag) {
117164
117632
  error: failedData.error,
117165
117633
  errorCode: failedData.errorCode,
117166
117634
  completedAt: now2,
117167
- updatedAt: now2
117168
- };
117169
- await writeJSON(taggedPath(basedir, "runs", effectiveRunId, tag), run, { overwrite: true });
117635
+ updatedAt: now2,
117636
+ attributes: currentRun.attributes
117637
+ });
117170
117638
  await Promise.all([
117171
117639
  deleteAllHooksForRun(basedir, effectiveRunId),
117172
117640
  deleteAllWaitsForRun(basedir, effectiveRunId)
@@ -117174,7 +117642,7 @@ function createEventsStorage(basedir, tag) {
117174
117642
  }
117175
117643
  } else if (data.eventType === "run_cancelled") {
117176
117644
  if (currentRun) {
117177
- run = {
117645
+ run = await writeRunUnderLifecycleLock(basedir, effectiveRunId, tag, {
117178
117646
  runId: currentRun.runId,
117179
117647
  deploymentId: currentRun.deploymentId,
117180
117648
  workflowName: currentRun.workflowName,
@@ -117188,9 +117656,9 @@ function createEventsStorage(basedir, tag) {
117188
117656
  output: void 0,
117189
117657
  error: void 0,
117190
117658
  completedAt: now2,
117191
- updatedAt: now2
117192
- };
117193
- await writeJSON(taggedPath(basedir, "runs", effectiveRunId, tag), run, { overwrite: true });
117659
+ updatedAt: now2,
117660
+ attributes: currentRun.attributes
117661
+ });
117194
117662
  await Promise.all([
117195
117663
  deleteAllHooksForRun(basedir, effectiveRunId),
117196
117664
  deleteAllWaitsForRun(basedir, effectiveRunId)
@@ -117505,53 +117973,6 @@ function createEventsStorage(basedir, tag) {
117505
117973
  }
117506
117974
  };
117507
117975
  }
117508
- function createRunsStorage(basedir, tag) {
117509
- return {
117510
- get: (async (id2, params) => {
117511
- assertSafeEntityId("runId", id2);
117512
- const run = await readJSONWithFallback(basedir, "runs", id2, WorkflowRunSchema, tag);
117513
- if (!run) {
117514
- throw new WorkflowRunNotFoundError(id2);
117515
- }
117516
- const resolveData = (params == null ? void 0 : params.resolveData) ?? DEFAULT_RESOLVE_DATA_OPTION$1;
117517
- return filterRunData$1(run, resolveData);
117518
- }),
117519
- list: (async (params) => {
117520
- var _a3, _b2, _c2;
117521
- const resolveData = (params == null ? void 0 : params.resolveData) ?? DEFAULT_RESOLVE_DATA_OPTION$1;
117522
- const result = await paginatedFileSystemQuery({
117523
- directory: path$3.join(basedir, "runs"),
117524
- schema: WorkflowRunSchema,
117525
- fileIdFilter: params == null ? void 0 : params.fileIdFilter,
117526
- filter: (run) => {
117527
- if ((params == null ? void 0 : params.workflowName) && run.workflowName !== params.workflowName) {
117528
- return false;
117529
- }
117530
- if ((params == null ? void 0 : params.status) && run.status !== params.status) {
117531
- return false;
117532
- }
117533
- return true;
117534
- },
117535
- sortOrder: ((_a3 = params == null ? void 0 : params.pagination) == null ? void 0 : _a3.sortOrder) ?? "desc",
117536
- limit: (_b2 = params == null ? void 0 : params.pagination) == null ? void 0 : _b2.limit,
117537
- cursor: (_c2 = params == null ? void 0 : params.pagination) == null ? void 0 : _c2.cursor,
117538
- getCreatedAt: getObjectCreatedAt("wrun"),
117539
- getId: (run) => run.runId
117540
- });
117541
- if (resolveData === "none") {
117542
- return {
117543
- ...result,
117544
- data: result.data.map((run) => ({
117545
- ...run,
117546
- input: void 0,
117547
- output: void 0
117548
- }))
117549
- };
117550
- }
117551
- return result;
117552
- })
117553
- };
117554
- }
117555
117976
  function createStepsStorage(basedir, tag) {
117556
117977
  return {
117557
117978
  get: (async (runId, stepId, params) => {
@@ -117609,40 +118030,50 @@ const monotonicUlid = monotonicFactory(() => Math.random());
117609
118030
  const RunStreamsSchema = object$1({
117610
118031
  streams: array$1(string$3())
117611
118032
  });
118033
+ const EOF_MARKER = 1;
118034
+ function isEofByte(byte) {
118035
+ return byte === EOF_MARKER;
118036
+ }
117612
118037
  function serializeChunk(chunk) {
117613
- const eofByte = Buffer.from([chunk.eof ? 1 : 0]);
118038
+ const eofByte = Buffer.from([chunk.eof ? EOF_MARKER : 0]);
117614
118039
  return Buffer.concat([eofByte, chunk.chunk]);
117615
118040
  }
117616
118041
  function isEofChunk(serialized) {
117617
- return serialized[0] === 1;
118042
+ return isEofByte(serialized[0]);
117618
118043
  }
117619
118044
  function deserializeChunk(serialized) {
117620
- const eof = serialized[0] === 1;
118045
+ const eof = isEofChunk(serialized);
117621
118046
  const chunk = Buffer.from(serialized.subarray(1));
117622
118047
  return { eof, chunk };
117623
118048
  }
118049
+ async function listChunkEntries(chunksDir) {
118050
+ try {
118051
+ return await fs$1.readdir(chunksDir);
118052
+ } catch (error2) {
118053
+ if (error2.code === "ENOENT")
118054
+ return [];
118055
+ throw error2;
118056
+ }
118057
+ }
118058
+ function addChunkFilesByExtension(extMap, entries, sourceExtension, fileExtension = sourceExtension, include = () => true) {
118059
+ for (const entry2 of entries) {
118060
+ if (!entry2.endsWith(sourceExtension))
118061
+ continue;
118062
+ const file2 = entry2.slice(0, -sourceExtension.length);
118063
+ if (include(file2))
118064
+ extMap.set(file2, fileExtension);
118065
+ }
118066
+ }
117624
118067
  async function listChunkFilesForStream(chunksDir, name2, tag) {
117625
118068
  assertSafeEntityId("streamName", name2);
117626
- const listPromises = [
117627
- listFilesByExtension(chunksDir, ".bin"),
117628
- listFilesByExtension(chunksDir, ".json")
117629
- ];
117630
- if (tag) {
117631
- listPromises.push(listFilesByExtension(chunksDir, `.${tag}.bin`));
117632
- }
117633
- const [binFiles, jsonFiles, ...taggedResults] = await Promise.all(listPromises);
117634
- const taggedBinFiles = taggedResults[0] ?? [];
118069
+ const entries = await listChunkEntries(chunksDir);
117635
118070
  const extMap = /* @__PURE__ */ new Map();
117636
- for (const f2 of jsonFiles)
117637
- extMap.set(f2, ".json");
117638
- const tagSfx = tag ? `.${tag}` : "";
117639
- for (const f2 of binFiles) {
117640
- if (tag && f2.endsWith(tagSfx))
117641
- continue;
117642
- extMap.set(f2, ".bin");
118071
+ addChunkFilesByExtension(extMap, entries, ".json");
118072
+ addChunkFilesByExtension(extMap, entries, ".bin", ".bin", tag ? (file2) => !file2.endsWith(`.${tag}`) : void 0);
118073
+ if (tag) {
118074
+ const taggedExtension = `.${tag}.bin`;
118075
+ addChunkFilesByExtension(extMap, entries, taggedExtension);
117643
118076
  }
117644
- for (const f2 of taggedBinFiles)
117645
- extMap.set(f2, `.${tag}.bin`);
117646
118077
  const files = [...extMap.keys()].filter((file2) => file2.startsWith(`${name2}-`)).sort();
117647
118078
  return { files, extMap };
117648
118079
  }
@@ -117757,7 +118188,7 @@ function createStreamer$1(basedir, tag) {
117757
118188
  const ext2 = fileExtMap.get(file2) ?? ".bin";
117758
118189
  const filePath = path$3.join(chunksDir, `${file2}${ext2}`);
117759
118190
  if (dataIndex < startIndex) {
117760
- if (isEofChunk(await readBuffer(filePath))) {
118191
+ if (isEofByte(await readFirstByte(filePath))) {
117761
118192
  streamDone = true;
117762
118193
  break;
117763
118194
  }
@@ -117765,7 +118196,7 @@ function createStreamer$1(basedir, tag) {
117765
118196
  continue;
117766
118197
  }
117767
118198
  if (resultChunks.length >= limit) {
117768
- if (isEofChunk(await readBuffer(filePath))) {
118199
+ if (isEofByte(await readFirstByte(filePath))) {
117769
118200
  streamDone = true;
117770
118201
  } else {
117771
118202
  dataIndex++;
@@ -117800,7 +118231,7 @@ function createStreamer$1(basedir, tag) {
117800
118231
  let dataCount = 0;
117801
118232
  for (const file2 of chunkFiles) {
117802
118233
  const ext2 = fileExtMap.get(file2) ?? ".bin";
117803
- if (isEofChunk(await readBuffer(path$3.join(chunksDir, `${file2}${ext2}`)))) {
118234
+ if (isEofByte(await readFirstByte(path$3.join(chunksDir, `${file2}${ext2}`)))) {
117804
118235
  streamDone = true;
117805
118236
  break;
117806
118237
  }
@@ -117861,8 +118292,7 @@ function createStreamer$1(basedir, tag) {
117861
118292
  if (typeof startIndex === "number" && startIndex < 0 && chunkFiles.length > 0) {
117862
118293
  const lastFile = chunkFiles[chunkFiles.length - 1];
117863
118294
  const lastExt = fileExtMap.get(lastFile) ?? ".bin";
117864
- const lastChunk = deserializeChunk(await readBuffer(path$3.join(chunksDir, `${lastFile}${lastExt}`)));
117865
- if ((lastChunk == null ? void 0 : lastChunk.eof) === true) {
118295
+ if (isEofByte(await readFirstByte(path$3.join(chunksDir, `${lastFile}${lastExt}`)))) {
117866
118296
  dataChunkCount--;
117867
118297
  }
117868
118298
  }
@@ -118009,7 +118439,7 @@ function createLocalWorld(args) {
118009
118439
  const basedir = mergedConfig.dataDir;
118010
118440
  const hooksDir = path$3.join(basedir, "hooks");
118011
118441
  const taggedHookFiles = await listTaggedFiles(hooksDir, tag);
118012
- const { HookSchema: HookSchema2 } = await import("./index-B_Gtun0B.js");
118442
+ const { HookSchema: HookSchema2 } = await import("./index-DltGJ3CV.js");
118013
118443
  await Promise.all(taggedHookFiles.map(async (hookFile) => {
118014
118444
  const hook = await readJSON(path$3.join(hooksDir, hookFile), HookSchema2);
118015
118445
  if (hook == null ? void 0 : hook.token) {
@@ -118161,8 +118591,8 @@ function requireGetVercelOidcToken() {
118161
118591
  }
118162
118592
  try {
118163
118593
  const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([
118164
- await import("./token-util-CHxt50WW.js").then((n) => n.t),
118165
- await import("./token-98GkKm4t.js").then((n) => n.t)
118594
+ await import("./token-util-DwTdh-aG.js").then((n) => n.t),
118595
+ await import("./token-BNjLoJXz.js").then((n) => n.t)
118166
118596
  ]);
118167
118597
  if (!token || isExpired(getTokenPayload(token), options == null ? void 0 : options.expirationBufferMs)) {
118168
118598
  await refreshToken(options);
@@ -123333,7 +123763,7 @@ var QueueClient = class {
123333
123763
  setApi(this, new ApiClient({ ...options, region }));
123334
123764
  }
123335
123765
  };
123336
- const version = "5.0.0-beta.6";
123766
+ const version = "5.0.0-beta.8";
123337
123767
  const HTTP_DEBUG_ENABLED = typeof process !== "undefined" && typeof process.env.DEBUG === "string" && (process.env.DEBUG.includes("workflow:") || process.env.DEBUG === "*");
123338
123768
  function httpLog(method, endpoint, status, ms2) {
123339
123769
  if (HTTP_DEBUG_ENABLED) {
@@ -124003,6 +124433,26 @@ async function cancelWorkflowRunV1(id2, params, config2) {
124003
124433
  throw error2;
124004
124434
  }
124005
124435
  }
124436
+ const ExperimentalSetAttributesResponseSchema = object$1({
124437
+ attributes: record(string$3(), string$3())
124438
+ });
124439
+ async function experimentalSetAttributes(runId, changes, options, config2) {
124440
+ try {
124441
+ const response2 = await makeRequest({
124442
+ endpoint: `/v2/runs/${encodeURIComponent(runId)}/attributes`,
124443
+ options: { method: "POST" },
124444
+ data: (options == null ? void 0 : options.allowReservedAttributes) ? { changes, allowReservedAttributes: true } : { changes },
124445
+ config: config2,
124446
+ schema: ExperimentalSetAttributesResponseSchema
124447
+ });
124448
+ return { attributes: response2.attributes };
124449
+ } catch (error2) {
124450
+ if (error2 instanceof WorkflowWorldError && error2.status === 404) {
124451
+ throw new WorkflowRunNotFoundError(runId);
124452
+ }
124453
+ throw error2;
124454
+ }
124455
+ }
124006
124456
  const StepWireSchema = StepSchema.omit({
124007
124457
  error: true
124008
124458
  }).extend({
@@ -124441,7 +124891,8 @@ function createStorage(config2) {
124441
124891
  // Storage interface with namespaced methods
124442
124892
  runs: {
124443
124893
  get: ((id2, params) => getWorkflowRun(id2, params, config2)),
124444
- list: ((params) => listWorkflowRuns(params, config2))
124894
+ list: ((params) => listWorkflowRuns(params, config2)),
124895
+ experimentalSetAttributes: (runId, changes, options) => experimentalSetAttributes(runId, changes, options, config2)
124445
124896
  },
124446
124897
  steps: {
124447
124898
  get: ((runId, stepId, params) => getStep(runId, stepId, params, config2)),
@@ -124470,6 +124921,16 @@ const MAX_CHUNKS_PER_REQUEST = 1e3;
124470
124921
  function getStreamUrl(name2, runId, httpConfig) {
124471
124922
  return new URL(`${httpConfig.baseUrl}/v2/runs/${encodeURIComponent(runId)}/stream/${encodeURIComponent(name2)}`);
124472
124923
  }
124924
+ function createStreamRequestError(operation, url2, response2, text2) {
124925
+ const context = [`PUT ${url2.origin}${url2.pathname}`];
124926
+ for (const header of ["x-vercel-id", "x-vercel-error"]) {
124927
+ const value = response2.headers.get(header);
124928
+ if (value) {
124929
+ context.push(`${header}=${value}`);
124930
+ }
124931
+ }
124932
+ return new Error(`Stream ${operation} failed: HTTP ${response2.status} (${context.join("; ")}): ${text2}`);
124933
+ }
124473
124934
  function encodeMultiChunks(chunks) {
124474
124935
  const encoder2 = new TextEncoder();
124475
124936
  const binaryChunks = [];
@@ -124509,14 +124970,15 @@ function createStreamer(config2) {
124509
124970
  async write(runId, name2, chunk) {
124510
124971
  const resolvedRunId = await runId;
124511
124972
  const httpConfig = await getHttpConfig(config2);
124512
- const response2 = await fetch(getStreamUrl(name2, resolvedRunId, httpConfig), {
124973
+ const url2 = getStreamUrl(name2, resolvedRunId, httpConfig);
124974
+ const response2 = await fetch(url2, {
124513
124975
  method: "PUT",
124514
124976
  body: chunk,
124515
124977
  headers: httpConfig.headers
124516
124978
  });
124517
124979
  const text2 = await response2.text();
124518
124980
  if (!response2.ok) {
124519
- throw new Error(`Stream write failed: HTTP ${response2.status}: ${text2}`);
124981
+ throw createStreamRequestError("write", url2, response2, text2);
124520
124982
  }
124521
124983
  },
124522
124984
  async writeMulti(runId, name2, chunks) {
@@ -124528,14 +124990,15 @@ function createStreamer(config2) {
124528
124990
  for (let i = 0; i < chunks.length; i += MAX_CHUNKS_PER_REQUEST) {
124529
124991
  const batch = chunks.slice(i, i + MAX_CHUNKS_PER_REQUEST);
124530
124992
  const body2 = encodeMultiChunks(batch);
124531
- const response2 = await fetch(getStreamUrl(name2, resolvedRunId, httpConfig), {
124993
+ const url2 = getStreamUrl(name2, resolvedRunId, httpConfig);
124994
+ const response2 = await fetch(url2, {
124532
124995
  method: "PUT",
124533
124996
  body: body2,
124534
124997
  headers: httpConfig.headers
124535
124998
  });
124536
124999
  const text2 = await response2.text();
124537
125000
  if (!response2.ok) {
124538
- throw new Error(`Stream write failed: HTTP ${response2.status}: ${text2}`);
125001
+ throw createStreamRequestError("write", url2, response2, text2);
124539
125002
  }
124540
125003
  }
124541
125004
  },
@@ -124543,13 +125006,14 @@ function createStreamer(config2) {
124543
125006
  const resolvedRunId = await runId;
124544
125007
  const httpConfig = await getHttpConfig(config2);
124545
125008
  httpConfig.headers.set("X-Stream-Done", "true");
124546
- const response2 = await fetch(getStreamUrl(name2, resolvedRunId, httpConfig), {
125009
+ const url2 = getStreamUrl(name2, resolvedRunId, httpConfig);
125010
+ const response2 = await fetch(url2, {
124547
125011
  method: "PUT",
124548
125012
  headers: httpConfig.headers
124549
125013
  });
124550
125014
  const text2 = await response2.text();
124551
125015
  if (!response2.ok) {
124552
- throw new Error(`Stream close failed: HTTP ${response2.status}: ${text2}`);
125016
+ throw createStreamRequestError("close", url2, response2, text2);
124553
125017
  }
124554
125018
  },
124555
125019
  async get(runId, name2, startIndex) {
@@ -151188,7 +151652,7 @@ const route4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
151188
151652
  __proto__: null,
151189
151653
  loader
151190
151654
  }, Symbol.toStringTag, { value: "Module" }));
151191
- const serverManifest = { "entry": { "module": "/assets/entry.client-DtOpLtMQ.js", "imports": ["/assets/index-BsV8i_Jn.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-DDT0W3fG.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/mermaid-3ZIDBTTL-PK-k2mDG.js"], "css": ["/assets/root-B527kgKt.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-B-DWbULo.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/workflow-graph-viewer-CVUKAMV1.js", "/assets/mermaid-3ZIDBTTL-PK-k2mDG.js", "/assets/index-Byi8AWfe.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-COyTZwjr.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/workflow-graph-viewer-CVUKAMV1.js", "/assets/mermaid-3ZIDBTTL-PK-k2mDG.js", "/assets/encryption-C69WMRfh.js", "/assets/index-Byi8AWfe.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-21016363.js", "version": "21016363", "sri": void 0 };
151655
+ const serverManifest = { "entry": { "module": "/assets/entry.client-DtOpLtMQ.js", "imports": ["/assets/index-BsV8i_Jn.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-3uuTxUQN.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/mermaid-3ZIDBTTL-3cOa-aZ5.js"], "css": ["/assets/root-BYtlAgHl.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-MRChHR_P.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/workflow-graph-viewer-DaYMiBT9.js", "/assets/mermaid-3ZIDBTTL-3cOa-aZ5.js", "/assets/index-Byi8AWfe.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-8qGjUNCj.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/workflow-graph-viewer-DaYMiBT9.js", "/assets/mermaid-3ZIDBTTL-3cOa-aZ5.js", "/assets/encryption-C69WMRfh.js", "/assets/index-Byi8AWfe.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-b100514d.js", "version": "b100514d", "sri": void 0 };
151192
151656
  const assetsBuildDirectory = "build/client";
151193
151657
  const basename = "/";
151194
151658
  const future = { "unstable_optimizeDeps": false, "unstable_subResourceIntegrity": false, "unstable_trailingSlashAwareDataRequests": false, "unstable_previewServerPrerendering": false, "v8_middleware": false, "v8_splitRouteModules": false, "v8_viteEnvironmentApi": false };
@@ -151257,47 +151721,56 @@ const serverBuild = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineP
151257
151721
  ssr
151258
151722
  }, Symbol.toStringTag, { value: "Module" }));
151259
151723
  export {
151260
- requireTokenUtil as A,
151724
+ ATTRIBUTE_KEY_MAX_LENGTH as A,
151261
151725
  BaseEventSchema as B,
151262
- requireTokenError as C,
151726
+ ulidToDate as C,
151263
151727
  DEFAULT_TIMESTAMP_THRESHOLD_FUTURE_MS as D,
151264
151728
  EVENT_DATA_REF_FIELDS as E,
151265
- serverBuild as F,
151729
+ validateAttributeChanges as F,
151730
+ validateAttributeKey as G,
151266
151731
  HookSchema as H,
151267
- Ks as K,
151732
+ validateAttributeValue as I,
151733
+ validateUlidTimestamp as J,
151734
+ R as K,
151268
151735
  LegacySerializedDataSchemaV1 as L,
151269
151736
  MessageId as M,
151270
151737
  Nt as N,
151738
+ Ks as O,
151271
151739
  PaginatedResponseSchema as P,
151272
151740
  QueuePayloadSchema as Q,
151273
- RunInputSchema as R,
151741
+ RESERVED_ATTRIBUTE_KEY_PREFIX as R,
151274
151742
  SPEC_VERSION_CURRENT as S,
151743
+ jsxRuntimeExports as T,
151744
+ Qe as U,
151275
151745
  ValidQueueName as V,
151276
151746
  WaitSchema as W,
151277
- DEFAULT_TIMESTAMP_THRESHOLD_PAST_MS as a,
151278
- EventSchema as b,
151279
- EventTypeSchema as c,
151280
- HealthCheckPayloadSchema as d,
151281
- QueuePrefix as e,
151282
- SPEC_VERSION_LEGACY as f,
151283
- SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT as g,
151284
- SPEC_VERSION_SUPPORTS_EVENT_SOURCING as h,
151285
- SerializedDataSchema as i,
151286
- StepInvokePayloadSchema as j,
151287
- StepSchema as k,
151288
- StepStatusSchema as l,
151289
- WaitStatusSchema as m,
151290
- WorkflowInvokePayloadSchema as n,
151291
- WorkflowRunBaseSchema as o,
151292
- WorkflowRunSchema as p,
151293
- WorkflowRunStatusSchema as q,
151294
- isLegacySpecVersion as r,
151295
- reenqueueActiveRuns as s,
151296
- requiresNewerWorld as t,
151297
- stripEventDataRefs as u,
151298
- ulidToDate as v,
151299
- validateUlidTimestamp as w,
151300
- R as x,
151301
- jsxRuntimeExports as y,
151302
- Qe as z
151747
+ requireTokenUtil as X,
151748
+ requireTokenError as Y,
151749
+ serverBuild as Z,
151750
+ ATTRIBUTE_MAX_PER_RUN as a,
151751
+ ATTRIBUTE_VALUE_MAX_BYTES as b,
151752
+ AttributeValidationError as c,
151753
+ DEFAULT_TIMESTAMP_THRESHOLD_PAST_MS as d,
151754
+ EventSchema as e,
151755
+ EventTypeSchema as f,
151756
+ HealthCheckPayloadSchema as g,
151757
+ QueuePrefix as h,
151758
+ RunInputSchema as i,
151759
+ SPEC_VERSION_LEGACY as j,
151760
+ SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT as k,
151761
+ SPEC_VERSION_SUPPORTS_EVENT_SOURCING as l,
151762
+ SerializedDataSchema as m,
151763
+ StepInvokePayloadSchema as n,
151764
+ StepSchema as o,
151765
+ StepStatusSchema as p,
151766
+ WaitStatusSchema as q,
151767
+ WorkflowInvokePayloadSchema as r,
151768
+ WorkflowRunBaseSchema as s,
151769
+ WorkflowRunSchema as t,
151770
+ WorkflowRunStatusSchema as u,
151771
+ applyAttributeChanges as v,
151772
+ isLegacySpecVersion as w,
151773
+ reenqueueActiveRuns as x,
151774
+ requiresNewerWorld as y,
151775
+ stripEventDataRefs as z
151303
151776
  };