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

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-WHMd9MPa.js} +1 -1
  2. package/build/client/assets/{home-B-DWbULo.js → home-Cai0GqMt.js} +8 -16
  3. package/build/client/assets/{manifest-21016363.js → manifest-127f70fe.js} +1 -1
  4. package/build/client/assets/{mermaid-3ZIDBTTL-PK-k2mDG.js → mermaid-3ZIDBTTL-TNUP6Q3m.js} +170 -119
  5. package/build/client/assets/root-COvK3yNk.css +1 -0
  6. package/build/client/assets/{root-DDT0W3fG.js → root-ORTTXEp6.js} +1 -1
  7. package/build/client/assets/{run-detail-COyTZwjr.js → run-detail-DNZJxxPM.js} +952 -896
  8. package/build/client/assets/server-build-DzzvWTSG.css +1 -0
  9. package/build/client/assets/{workflow-graph-viewer-CVUKAMV1.js → workflow-graph-viewer-DKqOOMnz.js} +50 -41
  10. package/build/server/assets/{app-CASBD2Jz.js → app-BxqFvIap.js} +1 -1
  11. package/build/server/assets/{highlighted-body-B3W2YXNL-DtYGrm0G.js → highlighted-body-B3W2YXNL-BuIiME1D.js} +2 -2
  12. package/build/server/assets/index-CdMzuwNr.js +89 -0
  13. package/build/server/assets/{mermaid-3ZIDBTTL-D37Y2lwn.js → mermaid-3ZIDBTTL-TSh7T1Pv.js} +2 -2
  14. package/build/server/assets/{server-build-BZS28Q46.js → server-build-fc5Vuxba.js} +1776 -1494
  15. package/build/server/assets/{token-98GkKm4t.js → token--89oCxEK.js} +2 -2
  16. package/build/server/assets/{token-util-CHxt50WW.js → token-util-N0DDbkKZ.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-BxqFvIap.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,80 @@ 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
+ "hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))] dark-theme:hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))]",
50646
+ // disabled styles
50647
+ "disabled:cursor-not-allowed aria-disabled:cursor-not-allowed",
50648
+ "disabled:bg-gray-100 disabled:!text-gray-700 disabled:hover:bg-gray-100",
50649
+ "aria-disabled:bg-gray-100 aria-disabled:text-gray-700 aria-disabled:hover:bg-gray-100"
50650
+ ], {
50651
+ variants: {
50652
+ variant: {
50653
+ default: "",
50654
+ 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)]",
50655
+ ghost: "[--themed-bg:_transparent] [--themed-fg:_var(--ds-gray-1000)] [--themed-hover-bg:_var(--ds-gray-alpha-100)]"
50656
+ },
50657
+ size: {
50658
+ default: "h-10 px-4 text-[14px]",
50659
+ sm: "h-8 px-3 text-[14px]",
50660
+ xs: "h-6 px-1.5 py-0.5 text-button-12",
50661
+ icon: "h-8 w-8"
50662
+ }
50663
+ },
50664
+ defaultVariants: {
50665
+ variant: "default",
50666
+ size: "default"
50667
+ }
50668
+ });
50669
+ function Button$1({ className, variant, size: size2, type = "button", ...props }) {
50670
+ return jsxRuntimeExports.jsx("button", { type, className: cn$4(buttonVariants$1({ variant, size: size2, className })), ...props });
50671
+ }
50495
50672
  const STREAM_REF_TYPE = "__workflow_stream_ref__";
50496
50673
  const CLASS_INSTANCE_REF_TYPE = "__workflow_class_instance_ref__";
50497
50674
  const RUN_REF_TYPE = "__workflow_run_ref__";
@@ -50541,16 +50718,10 @@ const RunClickContext = reactExports.createContext(void 0);
50541
50718
  function EncryptedInlineLabel() {
50542
50719
  const ctx = reactExports.useContext(DecryptClickContext);
50543
50720
  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) => {
50721
+ return jsxRuntimeExports.jsxs(Button$1, { size: "xs", className: "align-baseline gap-x-1", disabled: ctx.isDecrypting, onClick: (e) => {
50551
50722
  e.stopPropagation();
50552
50723
  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" })] });
50724
+ }, children: [ctx.isDecrypting ? jsxRuntimeExports.jsx(Spinner, { size: 10 }) : jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { children: "Decrypt" })] });
50554
50725
  }
50555
50726
  return jsxRuntimeExports.jsxs("span", { style: { color: "var(--ds-gray-600)", fontStyle: "italic" }, children: [jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3", style: {
50556
50727
  display: "inline",
@@ -50796,6 +50967,944 @@ function isDeepEqual(a2, b2, seen = /* @__PURE__ */ new WeakMap()) {
50796
50967
  }
50797
50968
  return true;
50798
50969
  }
50970
+ function CopyButton({ copyText, ariaLabel, className }) {
50971
+ const [copied, setCopied] = reactExports.useState(false);
50972
+ const timeoutRef = reactExports.useRef(null);
50973
+ reactExports.useEffect(() => {
50974
+ return () => {
50975
+ if (timeoutRef.current) {
50976
+ clearTimeout(timeoutRef.current);
50977
+ }
50978
+ };
50979
+ }, []);
50980
+ 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) => {
50981
+ e.stopPropagation();
50982
+ if (timeoutRef.current) {
50983
+ clearTimeout(timeoutRef.current);
50984
+ }
50985
+ void navigator.clipboard.writeText(copyText).then(() => {
50986
+ setCopied(true);
50987
+ timeoutRef.current = setTimeout(() => setCopied(false), 1e3);
50988
+ });
50989
+ }, 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" }) })] }) });
50990
+ }
50991
+ function isStructuredErrorWithStack(value) {
50992
+ return value != null && typeof value === "object" && "stack" in value && typeof value.stack === "string";
50993
+ }
50994
+ function deriveTitle(message2) {
50995
+ const firstLine = message2.split("\n").find((line) => line.trim().length > 0) ?? message2;
50996
+ return firstLine.trim();
50997
+ }
50998
+ function ErrorStackBlock({ value }) {
50999
+ const stack = value.stack;
51000
+ const message2 = typeof value.message === "string" ? value.message : void 0;
51001
+ const title = message2 ? deriveTitle(message2) : void 0;
51002
+ const copyText = message2 ? `${message2}
51003
+
51004
+ ${stack}` : stack;
51005
+ return jsxRuntimeExports.jsxs("div", { className: "relative overflow-hidden rounded-md border", style: {
51006
+ borderColor: "var(--ds-red-400)",
51007
+ background: "var(--ds-red-100)"
51008
+ }, 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: {
51009
+ color: "var(--ds-red-900)",
51010
+ borderBottom: "1px solid var(--ds-red-400)"
51011
+ }, children: [jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4 shrink-0" }), jsxRuntimeExports.jsx("p", {
51012
+ className: "text-xs font-semibold m-0 truncate",
51013
+ // The full multi-line message is in the stack body below; the
51014
+ // header just shows the first line, single-line, with overflow
51015
+ // ellipsised so a long title doesn't push the copy button or
51016
+ // wrap into the framed hint/docs lines.
51017
+ title: message2,
51018
+ children: title
51019
+ })] }), jsxRuntimeExports.jsx("pre", { className: "px-3 py-2.5 text-xs font-mono whitespace-pre-wrap break-words overflow-auto m-0", style: {
51020
+ color: "var(--ds-red-900)",
51021
+ background: "var(--ds-red-200)"
51022
+ }, children: stack })] });
51023
+ }
51024
+ 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)}`;
51025
+ function LoadMoreButton({ loading = false, onClick, label = "Load more", loadingLabel = "Loading..." }) {
51026
+ 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] })] });
51027
+ }
51028
+ 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)}`;
51029
+ function MenuDropdown({ options, value, onChange }) {
51030
+ var _a3, _b2;
51031
+ const [open, setOpen] = reactExports.useState(false);
51032
+ const ref = reactExports.useRef(null);
51033
+ const label = ((_a3 = options.find((o) => o.value === value)) == null ? void 0 : _a3.label) ?? ((_b2 = options[0]) == null ? void 0 : _b2.label) ?? "";
51034
+ reactExports.useEffect(() => {
51035
+ if (!open)
51036
+ return;
51037
+ function handleClickOutside(e) {
51038
+ if (ref.current && !ref.current.contains(e.target)) {
51039
+ setOpen(false);
51040
+ }
51041
+ }
51042
+ document.addEventListener("mousedown", handleClickOutside);
51043
+ return () => document.removeEventListener("mousedown", handleClickOutside);
51044
+ }, [open]);
51045
+ 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: {
51046
+ marginLeft: 16,
51047
+ marginRight: -4,
51048
+ color: "var(--ds-gray-900)"
51049
+ }, 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: {
51050
+ position: "absolute",
51051
+ right: 0,
51052
+ top: "100%",
51053
+ marginTop: 4,
51054
+ minWidth: 140,
51055
+ padding: 4,
51056
+ borderRadius: 12,
51057
+ background: "var(--ds-background-100)",
51058
+ boxShadow: "var(--ds-shadow-menu, var(--ds-shadow-medium))",
51059
+ zIndex: 2001
51060
+ }, role: "menu", children: options.map((option) => jsxRuntimeExports.jsx("button", { type: "button", role: "menuitem", className: "wf-menu-item", style: {
51061
+ fontWeight: option.value === value ? 500 : 400
51062
+ }, onClick: () => {
51063
+ onChange(option.value);
51064
+ setOpen(false);
51065
+ }, children: option.label }, option.value)) })] });
51066
+ }
51067
+ function Skeleton$2({ className, style: style2, ...props }) {
51068
+ return jsxRuntimeExports.jsx("div", { ...props, className: cn$4("rounded-md", className), style: { backgroundColor: "var(--ds-gray-200)", ...style2 } });
51069
+ }
51070
+ const TIME_UNITS = [
51071
+ { unit: "year", ms: 31536e6 },
51072
+ { unit: "month", ms: 2628e6 },
51073
+ { unit: "day", ms: 864e5 },
51074
+ { unit: "hour", ms: 36e5 },
51075
+ { unit: "minute", ms: 6e4 },
51076
+ { unit: "second", ms: 1e3 }
51077
+ ];
51078
+ function formatTimeDifference(diff) {
51079
+ let remaining = Math.abs(diff);
51080
+ const result = [];
51081
+ for (const { unit, ms: ms2 } of TIME_UNITS) {
51082
+ const value = Math.floor(remaining / ms2);
51083
+ if (value > 0 || result.length > 0) {
51084
+ result.push(`${value} ${unit}${value !== 1 ? "s" : ""}`);
51085
+ remaining %= ms2;
51086
+ }
51087
+ if (result.length === 3)
51088
+ break;
51089
+ }
51090
+ return result.join(", ");
51091
+ }
51092
+ function useTimeAgo(date2) {
51093
+ const [timeAgo, setTimeAgo] = reactExports.useState("");
51094
+ reactExports.useEffect(() => {
51095
+ const update = () => {
51096
+ const diff = Date.now() - date2;
51097
+ const formatted = formatTimeDifference(diff);
51098
+ setTimeAgo(formatted ? `${formatted} ago` : "Just now");
51099
+ };
51100
+ update();
51101
+ const timer2 = setInterval(update, 1e3);
51102
+ return () => clearInterval(timer2);
51103
+ }, [date2]);
51104
+ return timeAgo;
51105
+ }
51106
+ function ZoneDateTimeRow({ date: date2, zone }) {
51107
+ var _a3;
51108
+ const dateObj = new Date(date2);
51109
+ const formattedZone = ((_a3 = new Intl.DateTimeFormat("en-US", {
51110
+ timeZone: zone,
51111
+ timeZoneName: "short"
51112
+ }).formatToParts(dateObj).find((part) => part.type === "timeZoneName")) == null ? void 0 : _a3.value) || zone;
51113
+ const formattedDate = dateObj.toLocaleString("en-US", {
51114
+ timeZone: zone,
51115
+ year: "numeric",
51116
+ month: "long",
51117
+ day: "numeric"
51118
+ });
51119
+ const formattedTime = dateObj.toLocaleTimeString("en-US", {
51120
+ timeZone: zone,
51121
+ hour: "2-digit",
51122
+ minute: "2-digit",
51123
+ second: "2-digit"
51124
+ });
51125
+ return jsxRuntimeExports.jsxs("div", { style: {
51126
+ display: "flex",
51127
+ alignItems: "center",
51128
+ justifyContent: "space-between",
51129
+ gap: 12
51130
+ }, children: [jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [jsxRuntimeExports.jsx("div", { style: {
51131
+ display: "inline-flex",
51132
+ alignItems: "center",
51133
+ justifyContent: "center",
51134
+ height: 16,
51135
+ padding: "0 6px",
51136
+ backgroundColor: "var(--ds-gray-200)",
51137
+ borderRadius: 3,
51138
+ fontSize: 11,
51139
+ fontFamily: "var(--font-mono, monospace)",
51140
+ fontWeight: 500,
51141
+ color: "var(--ds-gray-900)",
51142
+ whiteSpace: "nowrap"
51143
+ }, children: formattedZone }), jsxRuntimeExports.jsx("span", { style: {
51144
+ fontSize: 13,
51145
+ color: "var(--ds-gray-1000)",
51146
+ whiteSpace: "nowrap"
51147
+ }, children: formattedDate })] }), jsxRuntimeExports.jsx("span", { style: {
51148
+ fontSize: 11,
51149
+ fontFamily: "var(--font-mono, monospace)",
51150
+ fontVariantNumeric: "tabular-nums",
51151
+ color: "var(--ds-gray-900)",
51152
+ whiteSpace: "nowrap"
51153
+ }, children: formattedTime })] });
51154
+ }
51155
+ function TimestampTooltipContent({ date: date2 }) {
51156
+ const localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
51157
+ const timeAgo = useTimeAgo(date2);
51158
+ return jsxRuntimeExports.jsxs("div", { style: {
51159
+ display: "flex",
51160
+ flexDirection: "column",
51161
+ gap: 12,
51162
+ minWidth: 300,
51163
+ padding: "12px 14px"
51164
+ }, children: [jsxRuntimeExports.jsx("span", { style: {
51165
+ fontSize: 13,
51166
+ fontVariantNumeric: "tabular-nums",
51167
+ color: "var(--ds-gray-900)"
51168
+ }, 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 })] })] });
51169
+ }
51170
+ const TOOLTIP_WIDTH = 330;
51171
+ const VIEWPORT_PAD = 8;
51172
+ function TooltipPortal({ triggerRect, onMouseEnter, onMouseLeave, date: date2 }) {
51173
+ const tooltipRef = reactExports.useRef(null);
51174
+ const [style2, setStyle] = reactExports.useState({
51175
+ position: "fixed",
51176
+ zIndex: 9999,
51177
+ visibility: "hidden"
51178
+ });
51179
+ reactExports.useEffect(() => {
51180
+ const placement = triggerRect.top > 240 ? "above" : "below";
51181
+ const centerX = triggerRect.left + triggerRect.width / 2;
51182
+ const el = tooltipRef.current;
51183
+ const w2 = el ? el.offsetWidth : TOOLTIP_WIDTH;
51184
+ const h2 = el ? el.offsetHeight : 100;
51185
+ let left = centerX - w2 / 2;
51186
+ left = Math.max(VIEWPORT_PAD, Math.min(left, window.innerWidth - w2 - VIEWPORT_PAD));
51187
+ let top;
51188
+ if (placement === "above") {
51189
+ top = triggerRect.top - h2 - 6;
51190
+ if (top < VIEWPORT_PAD) {
51191
+ top = triggerRect.bottom + 6;
51192
+ }
51193
+ } else {
51194
+ top = triggerRect.bottom + 6;
51195
+ if (top + h2 > window.innerHeight - VIEWPORT_PAD) {
51196
+ top = triggerRect.top - h2 - 6;
51197
+ }
51198
+ }
51199
+ setStyle({
51200
+ position: "fixed",
51201
+ left,
51202
+ top,
51203
+ zIndex: 9999,
51204
+ borderRadius: 10,
51205
+ border: "1px solid var(--ds-gray-alpha-200)",
51206
+ backgroundColor: "var(--ds-background-100)",
51207
+ boxShadow: "0 4px 12px rgba(0,0,0,0.08), 0 1px 3px rgba(0,0,0,0.06)",
51208
+ visibility: "visible"
51209
+ });
51210
+ }, [triggerRect]);
51211
+ return reactDomExports.createPortal(
51212
+ // biome-ignore lint/a11y/noStaticElementInteractions: tooltip hover zone
51213
+ jsxRuntimeExports.jsx("div", { ref: tooltipRef, onMouseEnter, onMouseLeave, style: style2, children: jsxRuntimeExports.jsx(TimestampTooltipContent, { date: date2 }) }),
51214
+ document.body
51215
+ );
51216
+ }
51217
+ function TimestampTooltip({ date: date2, children: children2 }) {
51218
+ const [open, setOpen] = reactExports.useState(false);
51219
+ const [triggerRect, setTriggerRect] = reactExports.useState(null);
51220
+ const triggerRef = reactExports.useRef(null);
51221
+ const closeTimer = reactExports.useRef(null);
51222
+ reactExports.useEffect(() => {
51223
+ return () => {
51224
+ if (closeTimer.current)
51225
+ clearTimeout(closeTimer.current);
51226
+ };
51227
+ }, []);
51228
+ const ts = date2 == null ? null : typeof date2 === "number" ? date2 : new Date(date2).getTime();
51229
+ if (ts == null || Number.isNaN(ts))
51230
+ return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: children2 });
51231
+ const cancelClose = () => {
51232
+ if (closeTimer.current) {
51233
+ clearTimeout(closeTimer.current);
51234
+ closeTimer.current = null;
51235
+ }
51236
+ };
51237
+ const scheduleClose = () => {
51238
+ cancelClose();
51239
+ closeTimer.current = setTimeout(() => setOpen(false), 120);
51240
+ };
51241
+ const handleOpen = () => {
51242
+ cancelClose();
51243
+ if (triggerRef.current) {
51244
+ setTriggerRect(triggerRef.current.getBoundingClientRect());
51245
+ }
51246
+ setOpen(true);
51247
+ };
51248
+ return (
51249
+ // biome-ignore lint/a11y/noStaticElementInteractions: tooltip trigger
51250
+ 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 })] })
51251
+ );
51252
+ }
51253
+ const ERROR_EVENT_TYPES$1 = /* @__PURE__ */ new Set([
51254
+ "step_failed",
51255
+ "step_retrying",
51256
+ "run_failed",
51257
+ "workflow_failed"
51258
+ ]);
51259
+ const BUTTON_RESET_STYLE = {
51260
+ appearance: "none",
51261
+ WebkitAppearance: "none",
51262
+ border: "none",
51263
+ background: "transparent"
51264
+ };
51265
+ const DOT_PULSE_ANIMATION = "workflow-dot-pulse 1.25s cubic-bezier(0, 0, 0.2, 1) infinite";
51266
+ function formatEventTime(date2) {
51267
+ return date2.toLocaleTimeString("en-US", {
51268
+ hour: "2-digit",
51269
+ minute: "2-digit",
51270
+ second: "2-digit",
51271
+ hour12: false
51272
+ }) + "." + date2.getMilliseconds().toString().padStart(3, "0");
51273
+ }
51274
+ function formatEventType(eventType) {
51275
+ return eventType.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
51276
+ }
51277
+ function getStatusDotColor(eventType) {
51278
+ if (eventType === "step_failed" || eventType === "run_failed" || eventType === "workflow_failed") {
51279
+ return "var(--ds-red-700)";
51280
+ }
51281
+ if (eventType === "run_cancelled") {
51282
+ return "var(--ds-amber-700)";
51283
+ }
51284
+ if (eventType === "step_retrying") {
51285
+ return "var(--ds-amber-700)";
51286
+ }
51287
+ if (eventType === "step_completed" || eventType === "run_completed" || eventType === "workflow_completed" || eventType === "hook_disposed" || eventType === "wait_completed") {
51288
+ return "var(--ds-green-700)";
51289
+ }
51290
+ if (eventType === "step_started" || eventType === "run_started" || eventType === "workflow_started" || eventType === "hook_received") {
51291
+ return "var(--ds-blue-700)";
51292
+ }
51293
+ return "var(--ds-gray-600)";
51294
+ }
51295
+ function buildNameMaps(events2, run) {
51296
+ var _a3, _b2;
51297
+ const correlationNameMap = /* @__PURE__ */ new Map();
51298
+ if (events2) {
51299
+ for (const event of events2) {
51300
+ if (event.eventType === "step_created" && event.correlationId) {
51301
+ const stepName = ((_a3 = event.eventData) == null ? void 0 : _a3.stepName) ?? "";
51302
+ const parsed = parseStepName(String(stepName));
51303
+ correlationNameMap.set(event.correlationId, (parsed == null ? void 0 : parsed.shortName) ?? stepName);
51304
+ }
51305
+ }
51306
+ }
51307
+ const workflowName = (run == null ? void 0 : run.workflowName) ? ((_b2 = parseWorkflowName(run.workflowName)) == null ? void 0 : _b2.shortName) ?? run.workflowName : null;
51308
+ return { correlationNameMap, workflowName };
51309
+ }
51310
+ function buildDurationMap(events2) {
51311
+ const chronological = [...events2].sort((a2, b2) => new Date(a2.createdAt).getTime() - new Date(b2.createdAt).getTime());
51312
+ const createdTimes = /* @__PURE__ */ new Map();
51313
+ const firstStartedTimes = /* @__PURE__ */ new Map();
51314
+ const startedTimes = /* @__PURE__ */ new Map();
51315
+ const durations = /* @__PURE__ */ new Map();
51316
+ for (const event of chronological) {
51317
+ const ts = new Date(event.createdAt).getTime();
51318
+ const key = event.correlationId ?? "__run__";
51319
+ const type = event.eventType;
51320
+ if (type === "step_created" || type === "run_created") {
51321
+ if (!createdTimes.has(key)) {
51322
+ createdTimes.set(key, ts);
51323
+ }
51324
+ }
51325
+ if (type === "step_started" || type === "run_started" || type === "workflow_started") {
51326
+ startedTimes.set(key, ts);
51327
+ if (!firstStartedTimes.has(key)) {
51328
+ firstStartedTimes.set(key, ts);
51329
+ if (!createdTimes.has(key)) {
51330
+ createdTimes.set(key, ts);
51331
+ }
51332
+ const createdAt = createdTimes.get(key);
51333
+ const info = durations.get(key) ?? {};
51334
+ if (createdAt !== void 0) {
51335
+ info.queued = ts - createdAt;
51336
+ }
51337
+ durations.set(key, info);
51338
+ }
51339
+ }
51340
+ 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") {
51341
+ const startedAt = startedTimes.get(key);
51342
+ const info = durations.get(key) ?? {};
51343
+ if (startedAt !== void 0) {
51344
+ info.ran = ts - startedAt;
51345
+ }
51346
+ durations.set(key, info);
51347
+ }
51348
+ }
51349
+ return durations;
51350
+ }
51351
+ function hasEncryptedValues(data) {
51352
+ if (!data || typeof data !== "object")
51353
+ return false;
51354
+ for (const val of Object.values(data)) {
51355
+ if (isEncryptedMarker(val))
51356
+ return true;
51357
+ }
51358
+ return false;
51359
+ }
51360
+ function isRunLevel(eventType) {
51361
+ 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";
51362
+ }
51363
+ const GUTTER_WIDTH = 36;
51364
+ const LANE_X = 20;
51365
+ const ROOT_LINE_COLOR = "var(--ds-gray-500)";
51366
+ function TreeGutter({ isFirst, isLast, isRunLevel: isRun, statusDotColor, pulse = false, hasSelection, showBranch, showLaneLine, isLaneStart, isLaneEnd, continuationOnly = false }) {
51367
+ const dotSize = isRun ? 8 : 6;
51368
+ const dotLeft = isRun ? 5 : 6;
51369
+ const dotOpacity = hasSelection && !showBranch && !isRun ? 0.3 : 1;
51370
+ return jsxRuntimeExports.jsxs("div", { className: "relative flex-shrink-0 self-stretch", style: {
51371
+ width: GUTTER_WIDTH,
51372
+ minHeight: continuationOnly ? 0 : void 0
51373
+ }, children: [jsxRuntimeExports.jsx("div", { style: {
51374
+ position: "absolute",
51375
+ left: 8,
51376
+ top: continuationOnly ? 0 : isFirst ? "50%" : 0,
51377
+ bottom: continuationOnly ? 0 : isLast ? "50%" : 0,
51378
+ width: 2,
51379
+ backgroundColor: ROOT_LINE_COLOR,
51380
+ zIndex: 0
51381
+ } }), !continuationOnly && jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("div", { style: {
51382
+ position: "absolute",
51383
+ left: dotLeft,
51384
+ top: "50%",
51385
+ transform: "translateY(-50%)",
51386
+ width: dotSize,
51387
+ height: dotSize,
51388
+ zIndex: 2
51389
+ }, children: [jsxRuntimeExports.jsx("div", { style: {
51390
+ position: "absolute",
51391
+ inset: 0,
51392
+ borderRadius: "50%",
51393
+ backgroundColor: "var(--ds-background-100)",
51394
+ zIndex: 0
51395
+ } }), pulse && jsxRuntimeExports.jsx("div", { style: {
51396
+ position: "absolute",
51397
+ inset: 0,
51398
+ borderRadius: "50%",
51399
+ backgroundColor: statusDotColor,
51400
+ opacity: 0.75 * dotOpacity,
51401
+ animation: DOT_PULSE_ANIMATION,
51402
+ zIndex: 1
51403
+ } }), jsxRuntimeExports.jsx("div", { style: {
51404
+ position: "relative",
51405
+ width: "100%",
51406
+ height: "100%",
51407
+ borderRadius: "50%",
51408
+ backgroundColor: statusDotColor,
51409
+ opacity: dotOpacity,
51410
+ transition: "opacity 150ms",
51411
+ zIndex: 2
51412
+ } })] }), showBranch && jsxRuntimeExports.jsx("div", { style: {
51413
+ position: "absolute",
51414
+ left: 9,
51415
+ top: "50%",
51416
+ width: GUTTER_WIDTH - 9,
51417
+ height: 2,
51418
+ backgroundColor: ROOT_LINE_COLOR,
51419
+ zIndex: 0
51420
+ } })] }), showLaneLine && jsxRuntimeExports.jsx("div", { style: {
51421
+ position: "absolute",
51422
+ left: LANE_X,
51423
+ top: continuationOnly ? 0 : isLaneStart ? "50%" : 0,
51424
+ bottom: continuationOnly ? 0 : isLaneEnd ? "50%" : 0,
51425
+ width: 2,
51426
+ backgroundColor: ROOT_LINE_COLOR,
51427
+ zIndex: 0
51428
+ } })] });
51429
+ }
51430
+ function CopyableCell({ value, className, style: styleProp }) {
51431
+ const [copied, setCopied] = reactExports.useState(false);
51432
+ const resetCopiedTimeoutRef = reactExports.useRef(null);
51433
+ reactExports.useEffect(() => {
51434
+ return () => {
51435
+ if (resetCopiedTimeoutRef.current !== null) {
51436
+ window.clearTimeout(resetCopiedTimeoutRef.current);
51437
+ }
51438
+ };
51439
+ }, []);
51440
+ const handleCopy = reactExports.useCallback((e) => {
51441
+ e.stopPropagation();
51442
+ navigator.clipboard.writeText(value).then(() => {
51443
+ setCopied(true);
51444
+ if (resetCopiedTimeoutRef.current !== null) {
51445
+ window.clearTimeout(resetCopiedTimeoutRef.current);
51446
+ }
51447
+ resetCopiedTimeoutRef.current = window.setTimeout(() => {
51448
+ setCopied(false);
51449
+ resetCopiedTimeoutRef.current = null;
51450
+ }, 1500);
51451
+ });
51452
+ }, [value]);
51453
+ 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] });
51454
+ }
51455
+ function deepParseJson(value) {
51456
+ if (typeof value === "string") {
51457
+ const trimmed = value.trim();
51458
+ if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]") || trimmed.startsWith('"') && trimmed.endsWith('"')) {
51459
+ try {
51460
+ return deepParseJson(JSON.parse(trimmed));
51461
+ } catch {
51462
+ return value;
51463
+ }
51464
+ }
51465
+ return value;
51466
+ }
51467
+ if (Array.isArray(value)) {
51468
+ return value.map(deepParseJson);
51469
+ }
51470
+ if (value !== null && typeof value === "object") {
51471
+ if (value.constructor !== Object) {
51472
+ return value;
51473
+ }
51474
+ const result = {};
51475
+ for (const [k2, v2] of Object.entries(value)) {
51476
+ result[k2] = deepParseJson(v2);
51477
+ }
51478
+ return result;
51479
+ }
51480
+ return value;
51481
+ }
51482
+ function extractStructuredError(data, eventType) {
51483
+ if (!eventType || !ERROR_EVENT_TYPES$1.has(eventType))
51484
+ return null;
51485
+ if (data == null || typeof data !== "object")
51486
+ return null;
51487
+ const record2 = data;
51488
+ if (isStructuredErrorWithStack(record2.error))
51489
+ return record2.error;
51490
+ if (isStructuredErrorWithStack(record2))
51491
+ return record2;
51492
+ return null;
51493
+ }
51494
+ function PayloadBlock({ data, eventType }) {
51495
+ const structuredError = reactExports.useMemo(() => extractStructuredError(data, eventType), [data, eventType]);
51496
+ const [copied, setCopied] = reactExports.useState(false);
51497
+ const resetCopiedTimeoutRef = reactExports.useRef(null);
51498
+ const cleaned = reactExports.useMemo(() => deepParseJson(data), [data]);
51499
+ reactExports.useEffect(() => {
51500
+ return () => {
51501
+ if (resetCopiedTimeoutRef.current !== null) {
51502
+ window.clearTimeout(resetCopiedTimeoutRef.current);
51503
+ }
51504
+ };
51505
+ }, []);
51506
+ const formatted = reactExports.useMemo(() => {
51507
+ try {
51508
+ return JSON.stringify(cleaned, null, 2);
51509
+ } catch {
51510
+ return String(cleaned);
51511
+ }
51512
+ }, [cleaned]);
51513
+ const handleCopy = reactExports.useCallback((e) => {
51514
+ e.stopPropagation();
51515
+ navigator.clipboard.writeText(formatted).then(() => {
51516
+ setCopied(true);
51517
+ if (resetCopiedTimeoutRef.current !== null) {
51518
+ window.clearTimeout(resetCopiedTimeoutRef.current);
51519
+ }
51520
+ resetCopiedTimeoutRef.current = window.setTimeout(() => {
51521
+ setCopied(false);
51522
+ resetCopiedTimeoutRef.current = null;
51523
+ }, 1500);
51524
+ });
51525
+ }, [formatted]);
51526
+ if (structuredError) {
51527
+ return jsxRuntimeExports.jsx("div", { className: "p-2", children: jsxRuntimeExports.jsx(ErrorStackBlock, { value: structuredError }) });
51528
+ }
51529
+ 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" })] }) })] });
51530
+ }
51531
+ const SORT_OPTIONS = [
51532
+ { value: "desc", label: "Newest" },
51533
+ { value: "asc", label: "Oldest" }
51534
+ ];
51535
+ function RowsSkeleton() {
51536
+ 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: {
51537
+ position: "absolute",
51538
+ left: 8,
51539
+ top: i === 0 ? "50%" : 0,
51540
+ bottom: 0,
51541
+ width: 2
51542
+ }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "w-full h-full", style: { borderRadius: 1 } }) }), jsxRuntimeExports.jsx(Skeleton$2, { className: "flex-shrink-0", style: {
51543
+ width: i % 4 === 0 ? 8 : 6,
51544
+ height: i % 4 === 0 ? 8 : 6,
51545
+ borderRadius: "50%",
51546
+ marginLeft: i % 4 === 0 ? 5 : 6
51547
+ } })] }), 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)) });
51548
+ }
51549
+ function EventRow$1({ event, index: index2, isFirst, isLast, isExpanded, onToggleExpand, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData, onCacheEventData, encryptionKey, onEncryptedDataDetected }) {
51550
+ const [isLoading, setIsLoading] = reactExports.useState(false);
51551
+ const [loadedEventData, setLoadedEventData] = reactExports.useState(cachedEventData);
51552
+ const [loadError, setLoadError] = reactExports.useState(null);
51553
+ const [hasAttemptedLoad, setHasAttemptedLoad] = reactExports.useState(cachedEventData !== null);
51554
+ reactExports.useEffect(() => {
51555
+ if (cachedEventData !== null && !encryptionKey && hasEncryptedValues(cachedEventData)) {
51556
+ onEncryptedDataDetected == null ? void 0 : onEncryptedDataDetected();
51557
+ }
51558
+ }, []);
51559
+ const rowGroupKey = isRunLevel(event.eventType) ? "__run__" : event.correlationId ?? void 0;
51560
+ const statusDotColor = getStatusDotColor(event.eventType);
51561
+ const createdAt = new Date(event.createdAt);
51562
+ const hasExistingEventData = "eventData" in event && event.eventData != null;
51563
+ const isRun = isRunLevel(event.eventType);
51564
+ const eventName2 = isRun ? workflowName ?? "-" : event.correlationId ? correlationNameMap.get(event.correlationId) ?? "-" : "-";
51565
+ const durationKey = event.correlationId ?? (isRun ? "__run__" : "");
51566
+ const durationInfo = durationKey ? durationMap.get(durationKey) : void 0;
51567
+ const hasActive = activeGroupKey !== void 0;
51568
+ const isRelated = rowGroupKey !== void 0 && rowGroupKey === activeGroupKey;
51569
+ const isDimmed = hasActive && !isRelated;
51570
+ const isPulsing = hasActive && isRelated;
51571
+ const showBranch = hasActive && isRelated && !isRun;
51572
+ const showLaneLine = selectedGroupRange !== null && index2 >= selectedGroupRange.first && index2 <= selectedGroupRange.last;
51573
+ const isLaneStart = selectedGroupRange !== null && index2 === selectedGroupRange.first;
51574
+ const isLaneEnd = selectedGroupRange !== null && index2 === selectedGroupRange.last;
51575
+ const loadEventDetails = reactExports.useCallback(async () => {
51576
+ if (loadedEventData !== null) {
51577
+ return;
51578
+ }
51579
+ if (cachedEventData !== null) {
51580
+ setLoadedEventData(cachedEventData);
51581
+ setHasAttemptedLoad(true);
51582
+ return;
51583
+ }
51584
+ if (isLoading) {
51585
+ return;
51586
+ }
51587
+ setIsLoading(true);
51588
+ setLoadError(null);
51589
+ try {
51590
+ if (!onLoadEventData) {
51591
+ setLoadError("Event details unavailable");
51592
+ return;
51593
+ }
51594
+ const data = await onLoadEventData(event);
51595
+ if (data !== null && data !== void 0) {
51596
+ setLoadedEventData(data);
51597
+ onCacheEventData(event.eventId, data);
51598
+ if (!encryptionKey && hasEncryptedValues(data)) {
51599
+ onEncryptedDataDetected == null ? void 0 : onEncryptedDataDetected();
51600
+ }
51601
+ }
51602
+ } catch (err) {
51603
+ setLoadError(err instanceof Error ? err.message : "Failed to load event details");
51604
+ } finally {
51605
+ setIsLoading(false);
51606
+ setHasAttemptedLoad(true);
51607
+ }
51608
+ }, [
51609
+ event,
51610
+ loadedEventData,
51611
+ isLoading,
51612
+ onLoadEventData,
51613
+ onCacheEventData,
51614
+ encryptionKey,
51615
+ onEncryptedDataDetected,
51616
+ cachedEventData
51617
+ ]);
51618
+ reactExports.useEffect(() => {
51619
+ if (!isExpanded || isLoading) {
51620
+ return;
51621
+ }
51622
+ void loadEventDetails();
51623
+ }, []);
51624
+ reactExports.useEffect(() => {
51625
+ if (encryptionKey && hasAttemptedLoad && onLoadEventData) {
51626
+ setLoadedEventData(null);
51627
+ setHasAttemptedLoad(false);
51628
+ onLoadEventData(event).then((data) => {
51629
+ if (data !== null && data !== void 0) {
51630
+ setLoadedEventData(data);
51631
+ onCacheEventData(event.eventId, data);
51632
+ }
51633
+ setHasAttemptedLoad(true);
51634
+ }).catch(() => {
51635
+ setHasAttemptedLoad(true);
51636
+ });
51637
+ }
51638
+ }, [encryptionKey]);
51639
+ const handleRowClick = reactExports.useCallback(() => {
51640
+ onSelectGroup(rowGroupKey === selectedGroupKey ? void 0 : rowGroupKey);
51641
+ onToggleExpand(event.eventId);
51642
+ if (!isExpanded) {
51643
+ void loadEventDetails();
51644
+ }
51645
+ }, [
51646
+ selectedGroupKey,
51647
+ rowGroupKey,
51648
+ onSelectGroup,
51649
+ onToggleExpand,
51650
+ event.eventId,
51651
+ isExpanded,
51652
+ loadEventDetails
51653
+ ]);
51654
+ const mergedEventData = loadedEventData ?? (hasExistingEventData ? event.eventData : null);
51655
+ const displayPayload = isLoading ? loadedEventData : mergedEventData;
51656
+ const contentOpacity = isDimmed ? 0.3 : 1;
51657
+ 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) => {
51658
+ if (e.key === "Enter" || e.key === " ")
51659
+ handleRowClick();
51660
+ }, 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: {
51661
+ border: "1px solid var(--ds-gray-400)"
51662
+ }, children: jsxRuntimeExports.jsx(ChevronRight, { className: "h-3 w-3 transition-transform", style: {
51663
+ color: "var(--ds-gray-900)",
51664
+ transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)"
51665
+ } }) }), 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: {
51666
+ position: "relative",
51667
+ display: "inline-flex",
51668
+ width: 6,
51669
+ height: 6,
51670
+ flexShrink: 0
51671
+ }, children: [isPulsing && jsxRuntimeExports.jsx("span", { style: {
51672
+ position: "absolute",
51673
+ inset: 0,
51674
+ borderRadius: "50%",
51675
+ backgroundColor: statusDotColor,
51676
+ opacity: 0.75,
51677
+ animation: DOT_PULSE_ANIMATION
51678
+ } }), jsxRuntimeExports.jsx("span", { style: {
51679
+ position: "relative",
51680
+ width: 6,
51681
+ height: 6,
51682
+ borderRadius: "50%",
51683
+ backgroundColor: statusDotColor
51684
+ } })] }), 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: {
51685
+ borderColor: "var(--ds-gray-alpha-200)",
51686
+ opacity: contentOpacity,
51687
+ transition: "opacity 150ms"
51688
+ }, 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: {
51689
+ borderColor: "var(--ds-red-400)",
51690
+ backgroundColor: "var(--ds-red-100)",
51691
+ color: "var(--ds-red-900)"
51692
+ }, 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" })] })] })] });
51693
+ }
51694
+ function EventListView({ events: events2, run, onLoadEventData, hasMoreEvents = false, isLoadingMoreEvents = false, onLoadMoreEvents, encryptionKey, isLoading = false, sortOrder: sortOrderProp, onSortOrderChange, onDecrypt, isDecrypting = false, hasEncryptedData: hasEncryptedDataProp = false }) {
51695
+ const [internalSortOrder, setInternalSortOrder] = reactExports.useState("asc");
51696
+ const effectiveSortOrder = sortOrderProp ?? internalSortOrder;
51697
+ const handleSortOrderChange = reactExports.useCallback((order2) => {
51698
+ if (onSortOrderChange) {
51699
+ onSortOrderChange(order2);
51700
+ } else {
51701
+ setInternalSortOrder(order2);
51702
+ }
51703
+ }, [onSortOrderChange]);
51704
+ const sortedEvents2 = reactExports.useMemo(() => {
51705
+ if (!events2 || events2.length === 0)
51706
+ return [];
51707
+ const dir = effectiveSortOrder === "desc" ? -1 : 1;
51708
+ return [...events2].sort((a2, b2) => dir * (new Date(a2.createdAt).getTime() - new Date(b2.createdAt).getTime()));
51709
+ }, [events2, effectiveSortOrder]);
51710
+ const hasEncryptedInlineData = reactExports.useMemo(() => {
51711
+ if (!events2)
51712
+ return false;
51713
+ for (const event of events2) {
51714
+ const ed = event.eventData;
51715
+ if (hasEncryptedValues(ed))
51716
+ return true;
51717
+ }
51718
+ return false;
51719
+ }, [events2]);
51720
+ const [foundEncryptedInLazyData, setFoundEncryptedInLazyData] = reactExports.useState(false);
51721
+ const handleEncryptedDataDetected = reactExports.useCallback(() => {
51722
+ setFoundEncryptedInLazyData(true);
51723
+ }, []);
51724
+ const hasEncryptedData = hasEncryptedDataProp || hasEncryptedInlineData || foundEncryptedInLazyData;
51725
+ const { correlationNameMap, workflowName } = reactExports.useMemo(() => buildNameMaps(events2 ?? null, run ?? null), [events2, run]);
51726
+ const durationMap = reactExports.useMemo(() => buildDurationMap(sortedEvents2), [sortedEvents2]);
51727
+ const [selectedGroupKey, setSelectedGroupKey] = reactExports.useState(void 0);
51728
+ const [hoveredGroupKey, setHoveredGroupKey] = reactExports.useState(void 0);
51729
+ const onSelectGroup = reactExports.useCallback((groupKey) => {
51730
+ setSelectedGroupKey(groupKey);
51731
+ }, []);
51732
+ const onHoverGroup = reactExports.useCallback((groupKey) => {
51733
+ setHoveredGroupKey(groupKey);
51734
+ }, []);
51735
+ const activeGroupKey = selectedGroupKey ?? hoveredGroupKey;
51736
+ const [expandedEventIds, setExpandedEventIds] = reactExports.useState(() => /* @__PURE__ */ new Set());
51737
+ const toggleEventExpanded = reactExports.useCallback((eventId) => {
51738
+ setExpandedEventIds((prev) => {
51739
+ const next2 = new Set(prev);
51740
+ if (next2.has(eventId)) {
51741
+ next2.delete(eventId);
51742
+ } else {
51743
+ next2.add(eventId);
51744
+ }
51745
+ return next2;
51746
+ });
51747
+ }, []);
51748
+ const eventDataCacheRef = reactExports.useRef(/* @__PURE__ */ new Map());
51749
+ const cacheEventData = reactExports.useCallback((eventId, data) => {
51750
+ eventDataCacheRef.current.set(eventId, data);
51751
+ }, []);
51752
+ const eventGroupKeyMap = reactExports.useMemo(() => {
51753
+ const map2 = /* @__PURE__ */ new Map();
51754
+ for (const ev of sortedEvents2) {
51755
+ const gk = isRunLevel(ev.eventType) ? "__run__" : ev.correlationId ?? "";
51756
+ if (gk)
51757
+ map2.set(ev.eventId, gk);
51758
+ }
51759
+ return map2;
51760
+ }, [sortedEvents2]);
51761
+ reactExports.useEffect(() => {
51762
+ if (selectedGroupKey === void 0)
51763
+ return;
51764
+ setExpandedEventIds((prev) => {
51765
+ if (prev.size === 0)
51766
+ return prev;
51767
+ let changed = false;
51768
+ const next2 = /* @__PURE__ */ new Set();
51769
+ for (const eventId of prev) {
51770
+ if (eventGroupKeyMap.get(eventId) === selectedGroupKey) {
51771
+ next2.add(eventId);
51772
+ } else {
51773
+ changed = true;
51774
+ }
51775
+ }
51776
+ return changed ? next2 : prev;
51777
+ });
51778
+ }, [selectedGroupKey, eventGroupKeyMap]);
51779
+ const selectedGroupRange = reactExports.useMemo(() => {
51780
+ if (!activeGroupKey || activeGroupKey === "__run__")
51781
+ return null;
51782
+ let first = -1;
51783
+ let last = -1;
51784
+ for (let i = 0; i < sortedEvents2.length; i++) {
51785
+ if (sortedEvents2[i].correlationId === activeGroupKey) {
51786
+ if (first === -1)
51787
+ first = i;
51788
+ last = i;
51789
+ }
51790
+ }
51791
+ return first >= 0 ? { first, last } : null;
51792
+ }, [activeGroupKey, sortedEvents2]);
51793
+ const [searchQuery, setSearchQuery] = reactExports.useState("");
51794
+ const virtuosoRef = reactExports.useRef(null);
51795
+ const searchIndex = reactExports.useMemo(() => {
51796
+ const entries = [];
51797
+ for (let i = 0; i < sortedEvents2.length; i++) {
51798
+ const ev = sortedEvents2[i];
51799
+ const isRun = isRunLevel(ev.eventType);
51800
+ const name2 = isRun ? workflowName ?? "" : ev.correlationId ? correlationNameMap.get(ev.correlationId) ?? "" : "";
51801
+ entries.push({
51802
+ fields: [
51803
+ ev.eventId,
51804
+ ev.correlationId ?? "",
51805
+ ev.eventType,
51806
+ formatEventType(ev.eventType),
51807
+ name2
51808
+ ].map((f2) => f2.toLowerCase()),
51809
+ groupKey: ev.correlationId ?? (isRun ? "__run__" : void 0),
51810
+ eventId: ev.eventId,
51811
+ index: i
51812
+ });
51813
+ }
51814
+ return entries;
51815
+ }, [sortedEvents2, correlationNameMap, workflowName]);
51816
+ reactExports.useEffect(() => {
51817
+ var _a3;
51818
+ const q2 = searchQuery.trim().toLowerCase();
51819
+ if (!q2) {
51820
+ setSelectedGroupKey(void 0);
51821
+ return;
51822
+ }
51823
+ let bestMatch = null;
51824
+ let bestScore = 0;
51825
+ for (const entry2 of searchIndex) {
51826
+ for (const field of entry2.fields) {
51827
+ if (field && field.includes(q2)) {
51828
+ const score = q2.length / field.length;
51829
+ if (score > bestScore) {
51830
+ bestScore = score;
51831
+ bestMatch = entry2;
51832
+ }
51833
+ }
51834
+ }
51835
+ }
51836
+ if (bestMatch) {
51837
+ setSelectedGroupKey(bestMatch.groupKey);
51838
+ (_a3 = virtuosoRef.current) == null ? void 0 : _a3.scrollToIndex({
51839
+ index: bestMatch.index,
51840
+ align: "center",
51841
+ behavior: "smooth"
51842
+ });
51843
+ }
51844
+ }, [searchQuery, searchIndex]);
51845
+ const hasHadEventsRef = reactExports.useRef(false);
51846
+ if (sortedEvents2.length > 0) {
51847
+ hasHadEventsRef.current = true;
51848
+ }
51849
+ const isInitialLoad = isLoading && !hasHadEventsRef.current;
51850
+ const isRefetching = isLoading && hasHadEventsRef.current && sortedEvents2.length === 0;
51851
+ if (isInitialLoad) {
51852
+ 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, {})] });
51853
+ }
51854
+ if (!isLoading && (!events2 || events2.length === 0)) {
51855
+ return jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full text-sm", style: { color: "var(--ds-gray-700)" }, children: "No events found" });
51856
+ }
51857
+ 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: {
51858
+ padding: 6,
51859
+ backgroundColor: "var(--ds-background-100)",
51860
+ display: "flex",
51861
+ gap: 6
51862
+ }, children: [jsxRuntimeExports.jsxs("label", { style: {
51863
+ display: "flex",
51864
+ alignItems: "center",
51865
+ justifyContent: "center",
51866
+ borderRadius: 6,
51867
+ boxShadow: "0 0 0 1px var(--ds-gray-alpha-400)",
51868
+ background: "var(--ds-background-100)",
51869
+ height: 40,
51870
+ flex: 1,
51871
+ minWidth: 0
51872
+ }, children: [jsxRuntimeExports.jsx("div", { style: {
51873
+ width: 40,
51874
+ height: 40,
51875
+ display: "flex",
51876
+ alignItems: "center",
51877
+ justifyContent: "center",
51878
+ color: "var(--ds-gray-800)",
51879
+ flexShrink: 0
51880
+ }, 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: {
51881
+ marginLeft: -16,
51882
+ paddingInline: 12,
51883
+ fontFamily: "inherit",
51884
+ fontSize: 14,
51885
+ background: "transparent",
51886
+ border: "none",
51887
+ outline: "none",
51888
+ height: 40,
51889
+ width: "100%"
51890
+ } })] }), 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: {
51891
+ borderColor: "var(--ds-gray-alpha-200)",
51892
+ color: "var(--ds-gray-900)",
51893
+ backgroundColor: "var(--ds-background-100)"
51894
+ }, 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: () => {
51895
+ if (!hasMoreEvents || isLoadingMoreEvents) {
51896
+ return;
51897
+ }
51898
+ void (onLoadMoreEvents == null ? void 0 : onLoadMoreEvents());
51899
+ }, itemContent: (index2) => {
51900
+ const ev = sortedEvents2[index2];
51901
+ 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 });
51902
+ }, 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: {
51903
+ borderColor: "var(--ds-gray-alpha-200)",
51904
+ color: "var(--ds-gray-900)",
51905
+ backgroundColor: "var(--ds-background-100)"
51906
+ }, 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()) }) }) })] })] }) });
51907
+ }
50799
51908
  function __insertCSS(code2) {
50800
51909
  if (typeof document == "undefined") return;
50801
51910
  let head = document.head || document.getElementsByTagName("head")[0];
@@ -51885,927 +52994,6 @@ const ToastContext = reactExports.createContext(defaultAdapter);
51885
52994
  function useToast() {
51886
52995
  return reactExports.useContext(ToastContext);
51887
52996
  }
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
52997
  function ResolveHookModal({ isOpen, onClose, onSubmit, isSubmitting = false }) {
52810
52998
  var _a3;
52811
52999
  const [jsonInput, setJsonInput] = reactExports.useState("");
@@ -53439,6 +53627,286 @@ function buildTrace(run, events2, now2) {
53439
53627
  knownDurationMs: Math.max(0, knownDurationMs)
53440
53628
  };
53441
53629
  }
53630
+ const ELLIPSIS = "...";
53631
+ const MIN_START = 3;
53632
+ const MIN_END = 3;
53633
+ const MIN_KEPT = MIN_START + MIN_END;
53634
+ const graphemeSegmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
53635
+ function toGraphemes(text2) {
53636
+ if (graphemeSegmenter) {
53637
+ return [...graphemeSegmenter.segment(text2)].map((s2) => s2.segment);
53638
+ }
53639
+ return Array.from(text2);
53640
+ }
53641
+ function buildCandidate(graphemes, kept) {
53642
+ if (kept <= 0) {
53643
+ return {
53644
+ prefixText: "",
53645
+ prefixGraphemeCount: 0,
53646
+ suffixText: "",
53647
+ suffixGraphemeCount: 0,
53648
+ text: ELLIPSIS,
53649
+ truncated: true
53650
+ };
53651
+ }
53652
+ const suffixGraphemeCount = kept >= MIN_KEPT ? Math.max(MIN_END, Math.floor(kept / 2)) : Math.floor(kept / 2);
53653
+ const prefixGraphemeCount = kept - suffixGraphemeCount;
53654
+ const prefixText = graphemes.slice(0, prefixGraphemeCount).join("");
53655
+ const suffixText = suffixGraphemeCount > 0 ? graphemes.slice(-suffixGraphemeCount).join("") : "";
53656
+ return {
53657
+ prefixText,
53658
+ prefixGraphemeCount,
53659
+ suffixText,
53660
+ suffixGraphemeCount,
53661
+ text: prefixText + ELLIPSIS + suffixText,
53662
+ truncated: true
53663
+ };
53664
+ }
53665
+ function middleTruncate(graphemes, availableWidth, measure, fullWidth) {
53666
+ const fullText = graphemes.join("");
53667
+ const resolvedFullWidth = fullWidth ?? measure(fullText);
53668
+ if (availableWidth <= 0 || graphemes.length === 0) {
53669
+ return {
53670
+ prefixText: fullText,
53671
+ prefixGraphemeCount: graphemes.length,
53672
+ suffixText: "",
53673
+ suffixGraphemeCount: 0,
53674
+ text: fullText,
53675
+ truncated: false
53676
+ };
53677
+ }
53678
+ if (resolvedFullWidth <= availableWidth) {
53679
+ return {
53680
+ prefixText: fullText,
53681
+ prefixGraphemeCount: graphemes.length,
53682
+ suffixText: "",
53683
+ suffixGraphemeCount: 0,
53684
+ text: fullText,
53685
+ truncated: false
53686
+ };
53687
+ }
53688
+ let lo2 = 0;
53689
+ let hi = graphemes.length - 1;
53690
+ let best = -1;
53691
+ while (lo2 <= hi) {
53692
+ const mid = lo2 + hi >>> 1;
53693
+ const candidate = buildCandidate(graphemes, mid);
53694
+ if (measure(candidate.text) <= availableWidth) {
53695
+ best = mid;
53696
+ lo2 = mid + 1;
53697
+ } else {
53698
+ hi = mid - 1;
53699
+ }
53700
+ }
53701
+ if (best === -1) {
53702
+ return {
53703
+ prefixText: "",
53704
+ prefixGraphemeCount: 0,
53705
+ suffixText: "",
53706
+ suffixGraphemeCount: 0,
53707
+ text: "",
53708
+ truncated: true
53709
+ };
53710
+ }
53711
+ return buildCandidate(graphemes, best);
53712
+ }
53713
+ function getMiddleTruncateCopyText({ prefixText, selectionEnd, selectionStart, suffixText, value }) {
53714
+ const visibleText = prefixText + ELLIPSIS + suffixText;
53715
+ if (selectionStart < 0 || selectionEnd > visibleText.length || selectionStart >= selectionEnd) {
53716
+ return null;
53717
+ }
53718
+ if (selectionStart === 0 && selectionEnd === visibleText.length) {
53719
+ return value;
53720
+ }
53721
+ const ellipsisStart = prefixText.length;
53722
+ const ellipsisEnd = ellipsisStart + ELLIPSIS.length;
53723
+ if (selectionStart > ellipsisStart || selectionEnd < ellipsisEnd) {
53724
+ return null;
53725
+ }
53726
+ const originalGraphemes = toGraphemes(value);
53727
+ const selectedPrefixGraphemeCount = toGraphemes(visibleText.slice(0, selectionStart)).length;
53728
+ const selectedSuffixGraphemeCount = toGraphemes(visibleText.slice(ellipsisEnd, selectionEnd)).length;
53729
+ const suffixStart = originalGraphemes.length - toGraphemes(suffixText).length;
53730
+ return originalGraphemes.slice(selectedPrefixGraphemeCount, suffixStart + selectedSuffixGraphemeCount).join("");
53731
+ }
53732
+ function getMiddleTruncateCopyTextFromSelectionText({ prefixText, selectionText, suffixText, value }) {
53733
+ const visibleText = prefixText + ELLIPSIS + suffixText;
53734
+ const trimmedSelectionText = selectionText.trim();
53735
+ if (!trimmedSelectionText) {
53736
+ return null;
53737
+ }
53738
+ const leading = selectionText.slice(0, selectionText.length - selectionText.trimStart().length);
53739
+ const trailing = selectionText.slice(selectionText.trimEnd().length);
53740
+ if (trimmedSelectionText === visibleText) {
53741
+ return leading + value + trailing;
53742
+ }
53743
+ if (!trimmedSelectionText.includes(ELLIPSIS)) {
53744
+ return null;
53745
+ }
53746
+ const selectionStart = visibleText.indexOf(trimmedSelectionText);
53747
+ if (selectionStart === -1) {
53748
+ return null;
53749
+ }
53750
+ const selectionEnd = selectionStart + trimmedSelectionText.length;
53751
+ const mappedText = getMiddleTruncateCopyText({
53752
+ prefixText,
53753
+ selectionEnd,
53754
+ selectionStart,
53755
+ suffixText,
53756
+ value
53757
+ });
53758
+ return mappedText === null ? null : leading + mappedText + trailing;
53759
+ }
53760
+ const useIsomorphicLayoutEffect$2 = typeof window === "undefined" ? reactExports.useEffect : reactExports.useLayoutEffect;
53761
+ function createFullState(value, graphemes) {
53762
+ return {
53763
+ displayText: value,
53764
+ isTruncated: false,
53765
+ prefixGraphemeCount: graphemes.length,
53766
+ prefixText: value,
53767
+ suffixGraphemeCount: 0,
53768
+ suffixText: ""
53769
+ };
53770
+ }
53771
+ function useMiddleTruncate(value) {
53772
+ const graphemes = reactExports.useMemo(() => toGraphemes(value), [value]);
53773
+ const fullState = reactExports.useMemo(() => createFullState(value, graphemes), [graphemes, value]);
53774
+ const ref = reactExports.useRef(null);
53775
+ const measureRef = reactExports.useRef(null);
53776
+ const [state, setState] = reactExports.useState(() => fullState);
53777
+ const rafRef = reactExports.useRef(0);
53778
+ const updateState = reactExports.useCallback((nextState) => {
53779
+ setState((currentState) => {
53780
+ 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) {
53781
+ return currentState;
53782
+ }
53783
+ return nextState;
53784
+ });
53785
+ }, []);
53786
+ const recalculate = reactExports.useCallback(() => {
53787
+ const el = ref.current;
53788
+ const measureEl = measureRef.current;
53789
+ if (!el || !measureEl)
53790
+ return;
53791
+ const available = el.clientWidth;
53792
+ if (available <= 0) {
53793
+ updateState(fullState);
53794
+ return;
53795
+ }
53796
+ const measure = (text2) => {
53797
+ measureEl.textContent = text2;
53798
+ return measureEl.scrollWidth;
53799
+ };
53800
+ const fullWidth = measure(value);
53801
+ if (fullWidth <= available) {
53802
+ updateState(fullState);
53803
+ return;
53804
+ }
53805
+ const result = middleTruncate(graphemes, available, measure, fullWidth);
53806
+ updateState({
53807
+ displayText: result.text,
53808
+ isTruncated: result.truncated,
53809
+ prefixGraphemeCount: result.prefixGraphemeCount,
53810
+ prefixText: result.prefixText,
53811
+ suffixGraphemeCount: result.suffixGraphemeCount,
53812
+ suffixText: result.suffixText
53813
+ });
53814
+ }, [fullState, graphemes, updateState, value]);
53815
+ useIsomorphicLayoutEffect$2(() => {
53816
+ recalculate();
53817
+ }, [recalculate]);
53818
+ reactExports.useEffect(() => {
53819
+ var _a3;
53820
+ const el = ref.current;
53821
+ if (!el)
53822
+ return;
53823
+ const debouncedRecalc = () => {
53824
+ cancelAnimationFrame(rafRef.current);
53825
+ rafRef.current = requestAnimationFrame(recalculate);
53826
+ };
53827
+ const ro2 = typeof ResizeObserver !== "undefined" ? new ResizeObserver(debouncedRecalc) : null;
53828
+ ro2 == null ? void 0 : ro2.observe(el);
53829
+ window.addEventListener("resize", debouncedRecalc);
53830
+ const onFontsLoaded = () => {
53831
+ debouncedRecalc();
53832
+ };
53833
+ const fontSet = "fonts" in document ? document.fonts : null;
53834
+ (_a3 = fontSet == null ? void 0 : fontSet.addEventListener) == null ? void 0 : _a3.call(fontSet, "loadingdone", onFontsLoaded);
53835
+ return () => {
53836
+ var _a4;
53837
+ ro2 == null ? void 0 : ro2.disconnect();
53838
+ window.removeEventListener("resize", debouncedRecalc);
53839
+ cancelAnimationFrame(rafRef.current);
53840
+ (_a4 = fontSet == null ? void 0 : fontSet.removeEventListener) == null ? void 0 : _a4.call(fontSet, "loadingdone", onFontsLoaded);
53841
+ };
53842
+ }, [recalculate]);
53843
+ return {
53844
+ ref,
53845
+ measureRef,
53846
+ displayText: state.displayText,
53847
+ isTruncated: state.isTruncated,
53848
+ prefixGraphemeCount: state.prefixGraphemeCount,
53849
+ prefixText: state.prefixText,
53850
+ suffixGraphemeCount: state.suffixGraphemeCount,
53851
+ suffixText: state.suffixText
53852
+ };
53853
+ }
53854
+ function getRangeOffsets(container, range2) {
53855
+ if (!container.contains(range2.startContainer) || !container.contains(range2.endContainer)) {
53856
+ return null;
53857
+ }
53858
+ const startRange = document.createRange();
53859
+ startRange.selectNodeContents(container);
53860
+ startRange.setEnd(range2.startContainer, range2.startOffset);
53861
+ const endRange = document.createRange();
53862
+ endRange.selectNodeContents(container);
53863
+ endRange.setEnd(range2.endContainer, range2.endOffset);
53864
+ return {
53865
+ end: endRange.toString().length,
53866
+ start: startRange.toString().length
53867
+ };
53868
+ }
53869
+ function MiddleTruncate({ value, className, onCopy: onCopyProp, ...props }) {
53870
+ const { ref, measureRef, displayText, isTruncated, prefixText, suffixText } = useMiddleTruncate(value);
53871
+ const visibleRef = reactExports.useRef(null);
53872
+ const handleCopy = reactExports.useCallback((e) => {
53873
+ onCopyProp == null ? void 0 : onCopyProp(e);
53874
+ if (e.defaultPrevented || !isTruncated)
53875
+ return;
53876
+ const selection2 = window.getSelection();
53877
+ if (!selection2 || selection2.rangeCount === 0)
53878
+ return;
53879
+ const selectionText = selection2.toString();
53880
+ if (!selectionText)
53881
+ return;
53882
+ const range2 = selection2.getRangeAt(0);
53883
+ const visibleEl = visibleRef.current;
53884
+ let copyText = null;
53885
+ if (e.currentTarget.contains(range2.startContainer) && e.currentTarget.contains(range2.endContainer) && visibleEl) {
53886
+ const offsets = getRangeOffsets(visibleEl, range2);
53887
+ if (offsets) {
53888
+ copyText = getMiddleTruncateCopyText({
53889
+ prefixText,
53890
+ selectionEnd: offsets.end,
53891
+ selectionStart: offsets.start,
53892
+ suffixText,
53893
+ value
53894
+ });
53895
+ }
53896
+ }
53897
+ copyText ?? (copyText = getMiddleTruncateCopyTextFromSelectionText({
53898
+ prefixText,
53899
+ selectionText,
53900
+ suffixText,
53901
+ value
53902
+ }));
53903
+ if (copyText === null)
53904
+ return;
53905
+ e.preventDefault();
53906
+ e.clipboardData.setData("text/plain", copyText);
53907
+ }, [onCopyProp, isTruncated, prefixText, suffixText, value]);
53908
+ 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 })] });
53909
+ }
53442
53910
  const convert = (
53443
53911
  // Note: overloads in JSDoc can’t yet use different `@template`s.
53444
53912
  /**
@@ -80062,7 +80530,7 @@ var tn = f("block", "before:content-[counter(line)]", "before:inline-block", "be
80062
80530
  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
80531
  var Se = reactExports.createContext({ code: "" }), de = () => reactExports.useContext(Se);
80064
80532
  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 }) => {
80533
+ var cn$1 = /\n+$/, dn = reactExports.lazy(() => import("./highlighted-body-B3W2YXNL-BuIiME1D.js").then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
80066
80534
  let i = reactExports.useMemo(() => e.replace(cn$1, ""), [e]), c = reactExports.useMemo(() => ({ bg: "transparent", fg: "inherit", tokens: i.split(`
80067
80535
  `).map((a2) => [{ content: a2, color: "inherit", bgColor: "transparent", htmlStyle: {}, offset: 0 }]) }), [i]);
80068
80536
  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 +80852,7 @@ var Dt = ({ children: e, className: t, onDownload: o, onError: n }) => {
80384
80852
  }, []), 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
80853
  };
80386
80854
  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]+)/;
80855
+ var Jn = reactExports.lazy(() => import("./mermaid-3ZIDBTTL-TSh7T1Pv.js").then((e) => ({ default: e.Mermaid }))), Kn = /language-([^\s]+)/;
80388
80856
  function ke(e, t) {
80389
80857
  if (!(e != null && e.position || t != null && t.position)) return true;
80390
80858
  if (!(e != null && e.position && (t != null && t.position))) return false;
@@ -80932,6 +81400,14 @@ function parseContent(content2) {
80932
81400
  }
80933
81401
  return [];
80934
81402
  }
81403
+ const encryptedPlaceholderPreview = `{
81404
+ "input": "[encrypted]",
81405
+ "result": "[encrypted]"
81406
+ }`;
81407
+ function EncryptedDataBlock() {
81408
+ const ctx = reactExports.useContext(DecryptClickContext);
81409
+ 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"] }) })] });
81410
+ }
80935
81411
  const serializeForClipboard = (value) => {
80936
81412
  if (typeof value === "string")
80937
81413
  return value;
@@ -80945,31 +81421,31 @@ const serializeForClipboard = (value) => {
80945
81421
  }
80946
81422
  };
80947
81423
  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 })] });
81424
+ 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
81425
  }
80957
- function DetailCard({ summary, children: children2, onToggle, disabled = false, summaryClassName, contentClassName }) {
81426
+ function DetailCard({ summary, children: children2, onToggle, disabled = false, defaultOpen = false, variant = "section", trailing, summaryClassName, contentClassName }) {
81427
+ const [open, setOpen] = reactExports.useState(defaultOpen);
81428
+ const handleToggle = (e) => {
81429
+ if (e.target !== e.currentTarget)
81430
+ return;
81431
+ const next2 = e.currentTarget.open;
81432
+ setOpen(next2);
81433
+ onToggle == null ? void 0 : onToggle(next2);
81434
+ };
81435
+ if (variant === "card") {
81436
+ if (disabled) {
81437
+ 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 });
81438
+ }
81439
+ 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 })] });
81440
+ }
81441
+ const rowClasses = "flex h-9 items-center gap-2 px-2 -mx-2 text-heading-14 font-medium my-2";
81442
+ if (trailing) {
81443
+ 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 })] }) });
81444
+ }
80958
81445
  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 });
81446
+ 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
81447
  }
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 })] });
81448
+ 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
81449
  }
80974
81450
  function TabButton({ active, onClick, children: children2 }) {
80975
81451
  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 +81486,10 @@ const conversationTabs = [
81010
81486
  ];
81011
81487
  function ConversationWithTabs({ conversation, args }) {
81012
81488
  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) }) }) });
81489
+ 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
81490
  }
81015
81491
  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" })] });
81492
+ return jsxRuntimeExports.jsx(EncryptedDataBlock, {});
81030
81493
  }
81031
81494
  function ExpiredFieldBlock() {
81032
81495
  return jsxRuntimeExports.jsx("div", { className: "flex items-center gap-1.5 rounded-md border px-3 py-2 text-xs", style: {
@@ -81099,6 +81562,7 @@ const attributeDisplayNames = {
81099
81562
  attempt: "Attempts",
81100
81563
  eventId: "Event ID",
81101
81564
  runId: "Run ID",
81565
+ token: "Token",
81102
81566
  eventType: "Event Type",
81103
81567
  correlationId: "Correlation ID",
81104
81568
  deploymentId: "Deployment ID",
@@ -81152,13 +81616,6 @@ const formatLocalMillisecondTime = (date2) => date2.toLocaleString(void 0, {
81152
81616
  second: "numeric",
81153
81617
  fractionalSecondDigits: 3
81154
81618
  });
81155
- const localMillisecondTime = (value) => {
81156
- const date2 = parseDateValue(value);
81157
- if (!date2) {
81158
- return "-";
81159
- }
81160
- return formatLocalMillisecondTime(date2);
81161
- };
81162
81619
  const localMillisecondTimeOrNull = (value) => {
81163
81620
  const date2 = parseDateValue(value);
81164
81621
  if (!date2) {
@@ -81179,7 +81636,7 @@ const attributeToDisplayFn = {
81179
81636
  stepName: (_value) => null,
81180
81637
  // IDs
81181
81638
  runId: (_value) => null,
81182
- stepId: (_value) => null,
81639
+ stepId: (value) => String(value),
81183
81640
  hookId: (value) => String(value),
81184
81641
  eventId: (value) => String(value),
81185
81642
  // Run/step details
@@ -81204,6 +81661,14 @@ const attributeToDisplayFn = {
81204
81661
  projectId: (_value) => null,
81205
81662
  environment: (_value) => null,
81206
81663
  executionContext: (_value) => null,
81664
+ // Attributes MVP — string-string metadata attached to the run.
81665
+ // Rendered as a JSON block; if empty/missing, hidden by the
81666
+ // hasDisplayContent gate above.
81667
+ attributes: (value) => {
81668
+ if (!hasDisplayContent(value))
81669
+ return null;
81670
+ return JsonBlock(value);
81671
+ },
81207
81672
  // Dates — wrapped with TimestampTooltip showing UTC/local + relative time
81208
81673
  createdAt: timestampWithTooltipOrNull,
81209
81674
  startedAt: timestampWithTooltipOrNull,
@@ -81217,20 +81682,19 @@ const attributeToDisplayFn = {
81217
81682
  if (!hasDisplayContent(value))
81218
81683
  return null;
81219
81684
  if (isEncryptedMarker(value))
81220
- return jsxRuntimeExports.jsx(EncryptedFieldBlock, {});
81685
+ return jsxRuntimeExports.jsx(EncryptedDataBlock, {});
81221
81686
  if (isExpiredMarker(value))
81222
81687
  return jsxRuntimeExports.jsx(ExpiredFieldBlock, {});
81223
81688
  return JsonBlock(value);
81224
81689
  },
81225
81690
  input: (value, context) => {
81226
- if (isEncryptedMarker(value))
81227
- return jsxRuntimeExports.jsx(EncryptedFieldBlock, {});
81691
+ if (isEncryptedMarker(value)) {
81692
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Input", children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
81693
+ }
81228
81694
  if (isExpiredMarker(value))
81229
81695
  return jsxRuntimeExports.jsx(ExpiredFieldBlock, {});
81230
81696
  if (value && typeof value === "object" && "args" in value) {
81231
81697
  const { args, closureVars, thisVal } = value;
81232
- const argCount2 = Array.isArray(args) ? args.length : 0;
81233
- const argLabel2 = argCount2 === 1 ? "argument" : "arguments";
81234
81698
  const hasClosureVars = hasDisplayContent(closureVars);
81235
81699
  const hasThisVal = hasDisplayContent(thisVal);
81236
81700
  const hasArgs = hasDisplayContent(args);
@@ -81241,46 +81705,47 @@ const attributeToDisplayFn = {
81241
81705
  }
81242
81706
  }
81243
81707
  if (!hasArgs && !hasClosureVars && !hasThisVal) {
81244
- return jsxRuntimeExports.jsx(DetailCard, { summary: "Input (no data)", disabled: true, summaryClassName: "text-label-14 font-medium py-2" });
81708
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Input (no data)", disabled: true });
81245
81709
  }
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) })] });
81710
+ 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
81711
  }
81248
- const argCount = Array.isArray(value) ? value.length : 0;
81249
- const argLabel = argCount === 1 ? "argument" : "arguments";
81250
81712
  if (!hasDisplayContent(value)) {
81251
- return jsxRuntimeExports.jsx(DetailCard, { summary: "Input (no data)", disabled: true, summaryClassName: "text-label-14 font-medium py-2" });
81713
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Input (no data)", disabled: true });
81252
81714
  }
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) });
81715
+ 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
81716
  },
81255
81717
  output: (value) => {
81718
+ if (isEncryptedMarker(value)) {
81719
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Output", children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
81720
+ }
81256
81721
  if (!hasDisplayContent(value))
81257
81722
  return null;
81258
- if (isEncryptedMarker(value))
81259
- return jsxRuntimeExports.jsx(EncryptedFieldBlock, {});
81260
81723
  if (isExpiredMarker(value))
81261
81724
  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) });
81725
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Output", children: JsonBlock(value) });
81263
81726
  },
81264
81727
  error: (value) => {
81265
- if (isEncryptedMarker(value))
81266
- return jsxRuntimeExports.jsx(EncryptedFieldBlock, {});
81728
+ if (isEncryptedMarker(value)) {
81729
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Error", defaultOpen: true, children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
81730
+ }
81267
81731
  if (isExpiredMarker(value))
81268
81732
  return jsxRuntimeExports.jsx(ExpiredFieldBlock, {});
81269
81733
  if (!hasDisplayContent(value))
81270
81734
  return null;
81271
81735
  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 }) });
81736
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Error", defaultOpen: true, children: jsxRuntimeExports.jsx(ErrorStackBlock, { value }) });
81273
81737
  }
81274
- return jsxRuntimeExports.jsx(DetailCard, { summary: "Error", summaryClassName: "text-label-14 font-medium py-2", contentClassName: "mt-0", children: JsonBlock(value) });
81738
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Error", defaultOpen: true, children: JsonBlock(value) });
81275
81739
  },
81276
81740
  eventData: (value) => {
81277
- if (isEncryptedMarker(value))
81278
- return jsxRuntimeExports.jsx(EncryptedFieldBlock, {});
81741
+ if (isEncryptedMarker(value)) {
81742
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Event Data", defaultOpen: true, children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
81743
+ }
81279
81744
  if (isExpiredMarker(value))
81280
81745
  return jsxRuntimeExports.jsx(ExpiredFieldBlock, {});
81281
81746
  if (!hasDisplayContent(value))
81282
81747
  return null;
81283
- return jsxRuntimeExports.jsx(DetailCard, { summary: "Event Data", children: JsonBlock(value) });
81748
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Event Data", defaultOpen: true, children: JsonBlock(value) });
81284
81749
  },
81285
81750
  errorCode: (value) => {
81286
81751
  if (typeof value !== "string" || value.length === 0)
@@ -81295,15 +81760,32 @@ const resolvableAttributes = [
81295
81760
  "metadata",
81296
81761
  "eventData"
81297
81762
  ];
81763
+ const selfHeaderedAttributes = /* @__PURE__ */ new Set([
81764
+ "input",
81765
+ "output",
81766
+ "error",
81767
+ "eventData"
81768
+ ]);
81298
81769
  const ExpiredDataMessage = () => jsxRuntimeExports.jsx("div", { className: "text-copy-12 rounded-md border p-4 my-2", style: {
81299
81770
  borderColor: "var(--ds-gray-300)",
81300
81771
  backgroundColor: "var(--ds-gray-100)",
81301
81772
  color: "var(--ds-gray-700)"
81302
81773
  }, children: jsxRuntimeExports.jsx("span", { children: "The data for this run has expired and is no longer available." }) });
81774
+ const copyableBasicAttributes = /* @__PURE__ */ new Set([
81775
+ "stepId",
81776
+ "hookId",
81777
+ "eventId",
81778
+ "deploymentId"
81779
+ ]);
81303
81780
  const AttributeBlock = ({ attribute, value, isLoading, inline = false, context }) => {
81304
- const isExpandableLoadingTarget = attribute === "input" || attribute === "eventData";
81781
+ const decryptCtx = reactExports.useContext(DecryptClickContext);
81782
+ const isExpandableLoadingTarget = attribute === "input" || attribute === "output" || attribute === "eventData";
81305
81783
  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" })] });
81784
+ const label = attribute === "eventData" ? "Event Data" : attribute === "output" ? "Output" : "Input";
81785
+ if (decryptCtx == null ? void 0 : decryptCtx.hasEncryptedData) {
81786
+ return jsxRuntimeExports.jsx(DetailCard, { summary: label, defaultOpen: attribute === "eventData", children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
81787
+ }
81788
+ return jsxRuntimeExports.jsx(DetailCard, { summary: label });
81307
81789
  }
81308
81790
  const displayFn = attributeToDisplayFn[attribute];
81309
81791
  if (!displayFn) {
@@ -81316,7 +81798,10 @@ const AttributeBlock = ({ attribute, value, isLoading, inline = false, context }
81316
81798
  if (inline) {
81317
81799
  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
81800
  }
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)] });
81801
+ if (selfHeaderedAttributes.has(attribute)) {
81802
+ return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: displayValue });
81803
+ }
81804
+ 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
81805
  };
81321
81806
  const AttributePanel = ({ data, moduleSpecifier, isLoading, error: error2, expiredAt, onStreamClick, onRunClick, onDecrypt, isDecrypting = false, resource }) => {
81322
81807
  const toast2 = useToast();
@@ -81341,14 +81826,16 @@ const AttributePanel = ({ data, moduleSpecifier, isLoading, error: error2, expir
81341
81826
  const present = Object.keys(displayData).filter((key) => resolvableAttributes.includes(key)).sort(sortByAttributeOrder);
81342
81827
  if (!isLoading)
81343
81828
  return present;
81344
- const loadingDefaults = ["input"];
81829
+ if (resource === "sleep")
81830
+ return present;
81831
+ const loadingDefaults = ["input", "output"];
81345
81832
  for (const key of loadingDefaults) {
81346
81833
  if (!present.includes(key)) {
81347
81834
  present.push(key);
81348
81835
  }
81349
81836
  }
81350
81837
  return present.sort(sortByAttributeOrder);
81351
- }, [displayData, isLoading]);
81838
+ }, [displayData, isLoading, resource]);
81352
81839
  const visibleBasicAttributes = basicAttributes.filter((attribute) => {
81353
81840
  const displayFn = attributeToDisplayFn[attribute];
81354
81841
  if (!displayFn)
@@ -81386,23 +81873,27 @@ const AttributePanel = ({ data, moduleSpecifier, isLoading, error: error2, expir
81386
81873
  toast2.error("Failed to copy moduleSpecifier");
81387
81874
  });
81388
81875
  }, []);
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) => {
81876
+ const outerDecryptCtx = reactExports.useContext(DecryptClickContext);
81877
+ const decryptValue = onDecrypt ? {
81878
+ onDecrypt,
81879
+ isDecrypting,
81880
+ hasEncryptedData: outerDecryptCtx == null ? void 0 : outerDecryptCtx.hasEncryptedData
81881
+ } : outerDecryptCtx;
81882
+ 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
81883
  var _a3;
81393
81884
  const displayValue = (_a3 = attributeToDisplayFn[attribute]) == null ? void 0 : _a3.call(attributeToDisplayFn, displayData[attribute]);
81394
81885
  const isModuleSpecifier = attribute === "moduleSpecifier";
81886
+ const isCopyableBasicAttribute = copyableBasicAttributes.has(attribute) && typeof displayValue === "string";
81395
81887
  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: {
81888
+ 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
81889
  color: "var(--ds-gray-1000)",
81401
81890
  background: "transparent",
81402
81891
  border: "none",
81403
81892
  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)) })] }) }) }) });
81893
+ }, 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: {
81894
+ color: "var(--ds-gray-1000)"
81895
+ }, 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);
81896
+ }), 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
81897
  };
81407
81898
  const ERROR_EVENT_TYPES = /* @__PURE__ */ new Set(["step_failed", "step_retrying"]);
81408
81899
  const DATA_EVENT_TYPES = /* @__PURE__ */ new Set([
@@ -81451,7 +81942,7 @@ function EventItem({ event, onLoadEventData, encryptionKey }) {
81451
81942
  wasExpandedRef.current = true;
81452
81943
  await loadEventData();
81453
81944
  }, [isLoading, loadEventData]);
81454
- reactExports.useEffect(() => {
81945
+ reactExports.useLayoutEffect(() => {
81455
81946
  if (!encryptionKey || !wasExpandedRef.current)
81456
81947
  return;
81457
81948
  loadedDataRef.current = null;
@@ -81459,16 +81950,16 @@ function EventItem({ event, onLoadEventData, encryptionKey }) {
81459
81950
  void loadEventData({ force: true });
81460
81951
  }, [encryptionKey, loadEventData]);
81461
81952
  const createdAt = new Date(event.createdAt);
81953
+ const createdAtTime = createdAt.toLocaleTimeString(void 0, {
81954
+ hour: "numeric",
81955
+ minute: "numeric",
81956
+ second: "numeric"
81957
+ });
81462
81958
  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) => {
81959
+ 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
81960
  if (open)
81465
81961
  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 }) })] });
81962
+ } : 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
81963
  }
81473
81964
  function hasOnlyExpiredFields(data, eventType) {
81474
81965
  if (data === null || typeof data !== "object" || Array.isArray(data)) {
@@ -81487,6 +81978,9 @@ function EventDataBlock({ eventType, data }) {
81487
81978
  color: "var(--ds-gray-700)"
81488
81979
  }, children: jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Data expired" }) });
81489
81980
  }
81981
+ if (hasEncryptedFields({ eventType, eventData: data })) {
81982
+ return jsxRuntimeExports.jsx(EncryptedDataBlock, {});
81983
+ }
81490
81984
  if (ERROR_EVENT_TYPES.has(eventType) && data != null && typeof data === "object") {
81491
81985
  const record2 = data;
81492
81986
  if (isStructuredErrorWithStack(record2.error)) {
@@ -81500,7 +81994,19 @@ function EventDataBlock({ eventType, data }) {
81500
81994
  }
81501
81995
  function EventsList({ events: events2, isLoading = false, error: error2, onLoadEventData, encryptionKey }) {
81502
81996
  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] });
81997
+ const hasEvents = sortedEvents2.length > 0 && !error2;
81998
+ if (!hasEvents && !isLoading) {
81999
+ return jsxRuntimeExports.jsx(DetailCard, { summary: "Events", disabled: true });
82000
+ }
82001
+ 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)) }) });
82002
+ }
82003
+ const SidebarDataContext = reactExports.createContext(null);
82004
+ SidebarDataContext.displayName = "SidebarDataContext";
82005
+ function SidebarDataProvider({ value, children: children2 }) {
82006
+ return jsxRuntimeExports.jsx(SidebarDataContext.Provider, { value, children: children2 });
82007
+ }
82008
+ function useSidebarDataOptional() {
82009
+ return reactExports.useContext(SidebarDataContext);
81504
82010
  }
81505
82011
  function isStep(data) {
81506
82012
  return data !== null && typeof data === "object" && "stepId" in data;
@@ -81517,6 +82023,8 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
81517
82023
  const [showResolveHookModal, setShowResolveHookModal] = reactExports.useState(false);
81518
82024
  const [resolvingHook, setResolvingHook] = reactExports.useState(false);
81519
82025
  const [resolvedHookIds, setResolvedHookIds] = reactExports.useState(/* @__PURE__ */ new Set());
82026
+ const sidebar = useSidebarDataOptional();
82027
+ const hasEncryptedData = Boolean((sidebar == null ? void 0 : sidebar.hasEncryptedData) && !encryptionKey);
81520
82028
  const data = selectedSpan == null ? void 0 : selectedSpan.data;
81521
82029
  const rawEvents = selectedSpan == null ? void 0 : selectedSpan.rawEvents;
81522
82030
  const rawEventsLength = (rawEvents == null ? void 0 : rawEvents.length) ?? 0;
@@ -81693,7 +82201,7 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
81693
82201
  return null;
81694
82202
  }
81695
82203
  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: {
82204
+ 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
82205
  borderColor: "var(--ds-gray-300)",
81698
82206
  backgroundColor: "var(--ds-gray-100)"
81699
82207
  }, 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 +82210,7 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
81702
82210
  }, 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
82211
  background: "var(--ds-gray-1000)",
81704
82212
  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 })] });
82213
+ }, 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
82214
  }
81707
82215
  const MAP_HEIGHT = 56;
81708
82216
  const TIMELINE_PADDING = 8;
@@ -82933,14 +83441,6 @@ reactExports.memo(function MiniMap({ timelineRef, rows, scale }) {
82933
83441
  height: MAP_HEIGHT - 4
82934
83442
  } })] });
82935
83443
  });
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
83444
  const ChunkRow = ReactExports.memo(function ChunkRow2({ chunk, index: index2 }) {
82945
83445
  return jsxRuntimeExports.jsx("div", { className: "text-[11px] rounded-md border p-3", style: {
82946
83446
  borderColor: "var(--ds-gray-300)",
@@ -82994,27 +83494,6 @@ const useReducedMotion = () => {
82994
83494
  }, []);
82995
83495
  return reduced;
82996
83496
  };
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
83497
  const WorkflowIcon = () => {
83019
83498
  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
83499
  };
@@ -83350,286 +83829,6 @@ function computeSpanSegments(span) {
83350
83829
  return [];
83351
83830
  }
83352
83831
  }
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
83832
  const eventStyles = {
83634
83833
  run: { icon: WorkflowIcon, className: "text-blue-900" },
83635
83834
  step: { icon: StepForwardIcon, className: "text-green-900" },
@@ -83652,7 +83851,7 @@ const EventRow = ({ span, isSelected, onSelectSpan }) => {
83652
83851
  const durationMs = getSpanDurationMs(span);
83653
83852
  const isErrored = span.attributes.data.status === "failed";
83654
83853
  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) }) })] }) }) });
83854
+ 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 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
83855
  };
83657
83856
  const EventList = ({ spans, activeSpanId, onSelectSpan }) => {
83658
83857
  return jsxRuntimeExports.jsx("ul", { id: "event-list", role: "tree", className: "block min-h-0 overflow-visible", children: spans.map((span) => {
@@ -83960,7 +84159,7 @@ function DetailPanel({ span, rootStart, onClose }) {
83960
84159
  const startMs = getHighResInMs(span.startTime);
83961
84160
  const durationMs = getSpanDurationMs(span);
83962
84161
  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" })] }) })] });
84162
+ 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-1000 hover:bg-gray-alpha-100 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" })] }) })] });
83964
84163
  }
83965
84164
  const MIN_VIEWPORT_MS = 1e-3;
83966
84165
  function useAnimatedViewport(initial) {
@@ -84146,13 +84345,25 @@ function NewTraceViewerContent({ trace: trace2 }) {
84146
84345
  ]);
84147
84346
  const [altHeld, setAltHeld] = reactExports.useState(false);
84148
84347
  reactExports.useEffect(() => {
84348
+ const handleSidebarNavKey = (e) => {
84349
+ const target2 = e.target;
84350
+ if (target2 instanceof HTMLInputElement || target2 instanceof HTMLTextAreaElement || (target2 == null ? void 0 : target2.isContentEditable)) {
84351
+ return;
84352
+ }
84353
+ const targetId = e.key === "k" ? prevSpanIdRef.current : nextSpanIdRef.current;
84354
+ if (targetId) {
84355
+ e.preventDefault();
84356
+ handleSelectSpanRef.current(targetId);
84357
+ }
84358
+ };
84149
84359
  const onKeyDown = (e) => {
84150
84360
  if (e.key === "Escape") {
84151
84361
  clearActiveSpan();
84152
- }
84153
- if (e.key === "Alt") {
84362
+ } else if (e.key === "Alt") {
84154
84363
  e.preventDefault();
84155
84364
  setAltHeld(true);
84365
+ } else if (e.key === "j" || e.key === "k") {
84366
+ handleSidebarNavKey(e);
84156
84367
  }
84157
84368
  };
84158
84369
  const onKeyUp = (e) => {
@@ -84269,17 +84480,33 @@ function NewTraceViewerContent({ trace: trace2 }) {
84269
84480
  const workflowName = data.workflowName;
84270
84481
  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
84482
  }, [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;
84279
- }
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] });
84483
+ const { prevSpanId, nextSpanId } = reactExports.useMemo(() => {
84484
+ var _a3, _b2;
84485
+ if (!activeSpanId)
84486
+ return { prevSpanId: null, nextSpanId: null };
84487
+ const i = filteredSpans.findIndex((s2) => s2.spanId === activeSpanId);
84488
+ if (i === -1)
84489
+ return { prevSpanId: null, nextSpanId: null };
84490
+ return {
84491
+ prevSpanId: ((_a3 = filteredSpans[i - 1]) == null ? void 0 : _a3.spanId) ?? null,
84492
+ nextSpanId: ((_b2 = filteredSpans[i + 1]) == null ? void 0 : _b2.spanId) ?? null
84493
+ };
84494
+ }, [activeSpanId, filteredSpans]);
84495
+ const handleSelectPrevSpan = reactExports.useCallback(() => {
84496
+ if (prevSpanId)
84497
+ handleSelectSpan(prevSpanId);
84498
+ }, [prevSpanId, handleSelectSpan]);
84499
+ const handleSelectNextSpan = reactExports.useCallback(() => {
84500
+ if (nextSpanId)
84501
+ handleSelectSpan(nextSpanId);
84502
+ }, [nextSpanId, handleSelectSpan]);
84503
+ const prevSpanIdRef = reactExports.useRef(prevSpanId);
84504
+ const nextSpanIdRef = reactExports.useRef(nextSpanId);
84505
+ const handleSelectSpanRef = reactExports.useRef(handleSelectSpan);
84506
+ prevSpanIdRef.current = prevSpanId;
84507
+ nextSpanIdRef.current = nextSpanId;
84508
+ handleSelectSpanRef.current = handleSelectSpan;
84509
+ 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), 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: "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.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("button", { type: "button", "aria-label": "Navigate to previous span", "aria-keyshortcuts": "K", onClick: handleSelectPrevSpan, disabled: !prevSpanId, className: "p-1 rounded text-gray-1000 transition-colors enabled:hover:bg-gray-alpha-100 disabled:opacity-40 disabled:cursor-not-allowed", children: jsxRuntimeExports.jsx(ChevronUp, { className: "w-4 h-4" }) }), jsxRuntimeExports.jsx("button", { type: "button", "aria-label": "Navigate to next span", "aria-keyshortcuts": "J", onClick: handleSelectNextSpan, disabled: !nextSpanId, className: "p-1 rounded text-gray-1000 transition-colors enabled:hover:bg-gray-alpha-100 disabled:opacity-40 disabled:cursor-not-allowed", 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("button", { type: "button", "aria-label": "Close span details", "aria-keyshortcuts": "Escape", className: "p-1 rounded text-gray-1000 hover:bg-gray-alpha-100 transition-colors", 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
84510
  }
84284
84511
  const NewTraceViewer = ({ run, events: events2, sidebarData }) => {
84285
84512
  const traceWithMeta = reactExports.useMemo(() => {
@@ -84613,46 +84840,6 @@ function getElementRef$2(element2) {
84613
84840
  }
84614
84841
  return element2.props.ref || element2.ref;
84615
84842
  }
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
84843
  const buttonVariants = cva(
84657
84844
  "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
84845
  {
@@ -88243,7 +88430,7 @@ const encryption = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
88243
88430
  encrypt: encrypt$1,
88244
88431
  importKey
88245
88432
  }, Symbol.toStringTag, { value: "Module" }));
88246
- const version$1 = "5.0.0-beta.7";
88433
+ const version$1 = "5.0.0-beta.8";
88247
88434
  const WorldCacheKey = Symbol.for("@workflow/world//cache");
88248
88435
  const WorldCachePromiseKey = Symbol.for("@workflow/world//cachePromise");
88249
88436
  const GetWorldFnKey$1 = Symbol.for("@workflow/world//getWorldFn");
@@ -91730,7 +91917,7 @@ function truncateForError(value) {
91730
91917
  }
91731
91918
  class UnsafeEntityIdError extends WorkflowWorldError {
91732
91919
  constructor(kind, value) {
91733
- super(`Unsafe ${kind} "${truncateForError(value)}": must not be empty, start with ".", or contain path separators or null bytes`);
91920
+ super(`Unsafe ${kind} "${truncateForError(value)}": must not be empty, contain ".", "/", "\\", or null bytes`);
91734
91921
  this.name = "UnsafeEntityIdError";
91735
91922
  }
91736
91923
  static is(value) {
@@ -91738,7 +91925,7 @@ class UnsafeEntityIdError extends WorkflowWorldError {
91738
91925
  }
91739
91926
  }
91740
91927
  function assertSafeEntityId(kind, value) {
91741
- if (value.length === 0 || value.startsWith(".") || value.includes("/") || value.includes("\\") || value.includes("\0")) {
91928
+ if (value.length === 0 || value.startsWith(".") || value.includes("/") || value.includes("\\") || value.includes("\0") || value.includes(".")) {
91742
91929
  throw new UnsafeEntityIdError(kind, value);
91743
91930
  }
91744
91931
  }
@@ -116833,7 +117020,8 @@ async function handleLegacyEvent(basedir, runId, data, currentRun, params) {
116833
117020
  output: void 0,
116834
117021
  error: void 0,
116835
117022
  completedAt: now2,
116836
- updatedAt: now2
117023
+ updatedAt: now2,
117024
+ attributes: currentRun.attributes
116837
117025
  };
116838
117026
  const runPath = resolveWithinBase(basedir, "runs", `${runId}.json`);
116839
117027
  await writeJSON(runPath, run, { overwrite: true });
@@ -116863,6 +117051,102 @@ async function handleLegacyEvent(basedir, runId, data, currentRun, params) {
116863
117051
  throw new Error(`Event type '${data.eventType}' not supported for legacy runs (specVersion: ${currentRun.specVersion || "undefined"}). Please upgrade 'workflow' package.`);
116864
117052
  }
116865
117053
  }
117054
+ const runFileLocks = /* @__PURE__ */ new Map();
117055
+ function withRunFileLock(key, fn2) {
117056
+ const prev = runFileLocks.get(key);
117057
+ const taskBox = {};
117058
+ const task = (async () => {
117059
+ if (prev)
117060
+ await prev.catch(() => void 0);
117061
+ try {
117062
+ return await fn2();
117063
+ } finally {
117064
+ if (runFileLocks.get(key) === taskBox.task) {
117065
+ runFileLocks.delete(key);
117066
+ }
117067
+ }
117068
+ })();
117069
+ taskBox.task = task;
117070
+ runFileLocks.set(key, task);
117071
+ return task;
117072
+ }
117073
+ function createRunsStorage(basedir, tag) {
117074
+ return {
117075
+ get: (async (id2, params) => {
117076
+ assertSafeEntityId("runId", id2);
117077
+ const run = await readJSONWithFallback(basedir, "runs", id2, WorkflowRunSchema, tag);
117078
+ if (!run) {
117079
+ throw new WorkflowRunNotFoundError(id2);
117080
+ }
117081
+ const resolveData = (params == null ? void 0 : params.resolveData) ?? DEFAULT_RESOLVE_DATA_OPTION$1;
117082
+ return filterRunData$1(run, resolveData);
117083
+ }),
117084
+ list: (async (params) => {
117085
+ var _a3, _b2, _c2;
117086
+ const resolveData = (params == null ? void 0 : params.resolveData) ?? DEFAULT_RESOLVE_DATA_OPTION$1;
117087
+ const result = await paginatedFileSystemQuery({
117088
+ directory: path$3.join(basedir, "runs"),
117089
+ schema: WorkflowRunSchema,
117090
+ fileIdFilter: params == null ? void 0 : params.fileIdFilter,
117091
+ filter: (run) => {
117092
+ if ((params == null ? void 0 : params.workflowName) && run.workflowName !== params.workflowName) {
117093
+ return false;
117094
+ }
117095
+ if ((params == null ? void 0 : params.status) && run.status !== params.status) {
117096
+ return false;
117097
+ }
117098
+ return true;
117099
+ },
117100
+ sortOrder: ((_a3 = params == null ? void 0 : params.pagination) == null ? void 0 : _a3.sortOrder) ?? "desc",
117101
+ limit: (_b2 = params == null ? void 0 : params.pagination) == null ? void 0 : _b2.limit,
117102
+ cursor: (_c2 = params == null ? void 0 : params.pagination) == null ? void 0 : _c2.cursor,
117103
+ getCreatedAt: getObjectCreatedAt("wrun"),
117104
+ getId: (run) => run.runId
117105
+ });
117106
+ if (resolveData === "none") {
117107
+ return {
117108
+ ...result,
117109
+ data: result.data.map((run) => ({
117110
+ ...run,
117111
+ input: void 0,
117112
+ output: void 0
117113
+ }))
117114
+ };
117115
+ }
117116
+ return result;
117117
+ }),
117118
+ experimentalSetAttributes: async (runId, changes, options) => {
117119
+ assertSafeEntityId("runId", runId);
117120
+ return withRunFileLock(runId, async () => {
117121
+ const run = await readJSONWithFallback(basedir, "runs", runId, WorkflowRunSchema, tag);
117122
+ if (!run) {
117123
+ throw new WorkflowRunNotFoundError(runId);
117124
+ }
117125
+ try {
117126
+ validateAttributeChanges(changes, {
117127
+ existingKeys: Object.keys(run.attributes ?? {}),
117128
+ allowReservedAttributes: options == null ? void 0 : options.allowReservedAttributes
117129
+ });
117130
+ } catch (err) {
117131
+ if (err instanceof AttributeValidationError) {
117132
+ throw err;
117133
+ }
117134
+ throw err;
117135
+ }
117136
+ const nextAttributes = applyAttributeChanges(run.attributes, changes);
117137
+ const updatedRun = {
117138
+ ...run,
117139
+ attributes: nextAttributes,
117140
+ updatedAt: /* @__PURE__ */ new Date()
117141
+ };
117142
+ await writeJSON(taggedPath(basedir, "runs", runId, tag), updatedRun, {
117143
+ overwrite: true
117144
+ });
117145
+ return { attributes: nextAttributes };
117146
+ });
117147
+ }
117148
+ };
117149
+ }
116866
117150
  const stepLocks = /* @__PURE__ */ new Map();
116867
117151
  const HookTokenClaimSchema = object$1({
116868
117152
  runId: string$3()
@@ -116906,13 +117190,26 @@ async function deleteAllWaitsForRun(basedir, runId) {
116906
117190
  }
116907
117191
  }
116908
117192
  }
117193
+ async function writeRunUnderLifecycleLock(basedir, runId, tag, proposed) {
117194
+ return withRunFileLock(runId, async () => {
117195
+ const fresh = await readJSON(taggedPath(basedir, "runs", runId, tag), WorkflowRunSchema);
117196
+ const next2 = {
117197
+ ...proposed,
117198
+ attributes: (fresh == null ? void 0 : fresh.attributes) ?? proposed.attributes
117199
+ };
117200
+ await writeJSON(taggedPath(basedir, "runs", runId, tag), next2, {
117201
+ overwrite: true
117202
+ });
117203
+ return next2;
117204
+ });
117205
+ }
116909
117206
  function createEventsStorage(basedir, tag) {
116910
117207
  return {
116911
117208
  async create(runId, data, params) {
116912
117209
  if (runId != null && runId !== "") {
116913
117210
  assertSafeEntityId("runId", runId);
116914
117211
  }
116915
- if ("correlationId" in data && typeof data.correlationId === "string" && data.correlationId.length > 0) {
117212
+ if ("correlationId" in data && typeof data.correlationId === "string") {
116916
117213
  assertSafeEntityId("correlationId", data.correlationId);
116917
117214
  }
116918
117215
  const isStepEvent2 = data.eventType === "step_created" || data.eventType === "step_started" || data.eventType === "step_completed" || data.eventType === "step_failed" || data.eventType === "step_retrying";
@@ -116960,6 +117257,7 @@ function createEventsStorage(basedir, tag) {
116960
117257
  error: void 0,
116961
117258
  startedAt: void 0,
116962
117259
  completedAt: void 0,
117260
+ attributes: {},
116963
117261
  createdAt: now2,
116964
117262
  updatedAt: now2
116965
117263
  };
@@ -117090,6 +117388,7 @@ function createEventsStorage(basedir, tag) {
117090
117388
  error: void 0,
117091
117389
  startedAt: void 0,
117092
117390
  completedAt: void 0,
117391
+ attributes: {},
117093
117392
  createdAt: now2,
117094
117393
  updatedAt: now2
117095
117394
  };
@@ -117103,7 +117402,7 @@ function createEventsStorage(basedir, tag) {
117103
117402
  if (currentRun.status === "running") {
117104
117403
  return { run: currentRun };
117105
117404
  }
117106
- run = {
117405
+ run = await writeRunUnderLifecycleLock(basedir, effectiveRunId, tag, {
117107
117406
  runId: currentRun.runId,
117108
117407
  deploymentId: currentRun.deploymentId,
117109
117408
  workflowName: currentRun.workflowName,
@@ -117117,14 +117416,14 @@ function createEventsStorage(basedir, tag) {
117117
117416
  error: void 0,
117118
117417
  completedAt: void 0,
117119
117418
  startedAt: currentRun.startedAt ?? now2,
117120
- updatedAt: now2
117121
- };
117122
- await writeJSON(taggedPath(basedir, "runs", effectiveRunId, tag), run, { overwrite: true });
117419
+ updatedAt: now2,
117420
+ attributes: currentRun.attributes
117421
+ });
117123
117422
  }
117124
117423
  } else if (data.eventType === "run_completed" && "eventData" in data) {
117125
117424
  const completedData = data.eventData;
117126
117425
  if (currentRun) {
117127
- run = {
117426
+ run = await writeRunUnderLifecycleLock(basedir, effectiveRunId, tag, {
117128
117427
  runId: currentRun.runId,
117129
117428
  deploymentId: currentRun.deploymentId,
117130
117429
  workflowName: currentRun.workflowName,
@@ -117138,9 +117437,9 @@ function createEventsStorage(basedir, tag) {
117138
117437
  output: completedData.output,
117139
117438
  error: void 0,
117140
117439
  completedAt: now2,
117141
- updatedAt: now2
117142
- };
117143
- await writeJSON(taggedPath(basedir, "runs", effectiveRunId, tag), run, { overwrite: true });
117440
+ updatedAt: now2,
117441
+ attributes: currentRun.attributes
117442
+ });
117144
117443
  await Promise.all([
117145
117444
  deleteAllHooksForRun(basedir, effectiveRunId),
117146
117445
  deleteAllWaitsForRun(basedir, effectiveRunId)
@@ -117149,7 +117448,7 @@ function createEventsStorage(basedir, tag) {
117149
117448
  } else if (data.eventType === "run_failed" && "eventData" in data) {
117150
117449
  const failedData = data.eventData;
117151
117450
  if (currentRun) {
117152
- run = {
117451
+ run = await writeRunUnderLifecycleLock(basedir, effectiveRunId, tag, {
117153
117452
  runId: currentRun.runId,
117154
117453
  deploymentId: currentRun.deploymentId,
117155
117454
  workflowName: currentRun.workflowName,
@@ -117164,9 +117463,9 @@ function createEventsStorage(basedir, tag) {
117164
117463
  error: failedData.error,
117165
117464
  errorCode: failedData.errorCode,
117166
117465
  completedAt: now2,
117167
- updatedAt: now2
117168
- };
117169
- await writeJSON(taggedPath(basedir, "runs", effectiveRunId, tag), run, { overwrite: true });
117466
+ updatedAt: now2,
117467
+ attributes: currentRun.attributes
117468
+ });
117170
117469
  await Promise.all([
117171
117470
  deleteAllHooksForRun(basedir, effectiveRunId),
117172
117471
  deleteAllWaitsForRun(basedir, effectiveRunId)
@@ -117174,7 +117473,7 @@ function createEventsStorage(basedir, tag) {
117174
117473
  }
117175
117474
  } else if (data.eventType === "run_cancelled") {
117176
117475
  if (currentRun) {
117177
- run = {
117476
+ run = await writeRunUnderLifecycleLock(basedir, effectiveRunId, tag, {
117178
117477
  runId: currentRun.runId,
117179
117478
  deploymentId: currentRun.deploymentId,
117180
117479
  workflowName: currentRun.workflowName,
@@ -117188,9 +117487,9 @@ function createEventsStorage(basedir, tag) {
117188
117487
  output: void 0,
117189
117488
  error: void 0,
117190
117489
  completedAt: now2,
117191
- updatedAt: now2
117192
- };
117193
- await writeJSON(taggedPath(basedir, "runs", effectiveRunId, tag), run, { overwrite: true });
117490
+ updatedAt: now2,
117491
+ attributes: currentRun.attributes
117492
+ });
117194
117493
  await Promise.all([
117195
117494
  deleteAllHooksForRun(basedir, effectiveRunId),
117196
117495
  deleteAllWaitsForRun(basedir, effectiveRunId)
@@ -117505,53 +117804,6 @@ function createEventsStorage(basedir, tag) {
117505
117804
  }
117506
117805
  };
117507
117806
  }
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
117807
  function createStepsStorage(basedir, tag) {
117556
117808
  return {
117557
117809
  get: (async (runId, stepId, params) => {
@@ -118009,7 +118261,7 @@ function createLocalWorld(args) {
118009
118261
  const basedir = mergedConfig.dataDir;
118010
118262
  const hooksDir = path$3.join(basedir, "hooks");
118011
118263
  const taggedHookFiles = await listTaggedFiles(hooksDir, tag);
118012
- const { HookSchema: HookSchema2 } = await import("./index-B_Gtun0B.js");
118264
+ const { HookSchema: HookSchema2 } = await import("./index-CdMzuwNr.js");
118013
118265
  await Promise.all(taggedHookFiles.map(async (hookFile) => {
118014
118266
  const hook = await readJSON(path$3.join(hooksDir, hookFile), HookSchema2);
118015
118267
  if (hook == null ? void 0 : hook.token) {
@@ -118161,8 +118413,8 @@ function requireGetVercelOidcToken() {
118161
118413
  }
118162
118414
  try {
118163
118415
  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)
118416
+ await import("./token-util-N0DDbkKZ.js").then((n) => n.t),
118417
+ await import("./token--89oCxEK.js").then((n) => n.t)
118166
118418
  ]);
118167
118419
  if (!token || isExpired(getTokenPayload(token), options == null ? void 0 : options.expirationBufferMs)) {
118168
118420
  await refreshToken(options);
@@ -123333,7 +123585,7 @@ var QueueClient = class {
123333
123585
  setApi(this, new ApiClient({ ...options, region }));
123334
123586
  }
123335
123587
  };
123336
- const version = "5.0.0-beta.6";
123588
+ const version = "5.0.0-beta.7";
123337
123589
  const HTTP_DEBUG_ENABLED = typeof process !== "undefined" && typeof process.env.DEBUG === "string" && (process.env.DEBUG.includes("workflow:") || process.env.DEBUG === "*");
123338
123590
  function httpLog(method, endpoint, status, ms2) {
123339
123591
  if (HTTP_DEBUG_ENABLED) {
@@ -124003,6 +124255,26 @@ async function cancelWorkflowRunV1(id2, params, config2) {
124003
124255
  throw error2;
124004
124256
  }
124005
124257
  }
124258
+ const ExperimentalSetAttributesResponseSchema = object$1({
124259
+ attributes: record(string$3(), string$3())
124260
+ });
124261
+ async function experimentalSetAttributes(runId, changes, options, config2) {
124262
+ try {
124263
+ const response2 = await makeRequest({
124264
+ endpoint: `/v2/runs/${encodeURIComponent(runId)}/attributes`,
124265
+ options: { method: "POST" },
124266
+ data: (options == null ? void 0 : options.allowReservedAttributes) ? { changes, allowReservedAttributes: true } : { changes },
124267
+ config: config2,
124268
+ schema: ExperimentalSetAttributesResponseSchema
124269
+ });
124270
+ return { attributes: response2.attributes };
124271
+ } catch (error2) {
124272
+ if (error2 instanceof WorkflowWorldError && error2.status === 404) {
124273
+ throw new WorkflowRunNotFoundError(runId);
124274
+ }
124275
+ throw error2;
124276
+ }
124277
+ }
124006
124278
  const StepWireSchema = StepSchema.omit({
124007
124279
  error: true
124008
124280
  }).extend({
@@ -124441,7 +124713,8 @@ function createStorage(config2) {
124441
124713
  // Storage interface with namespaced methods
124442
124714
  runs: {
124443
124715
  get: ((id2, params) => getWorkflowRun(id2, params, config2)),
124444
- list: ((params) => listWorkflowRuns(params, config2))
124716
+ list: ((params) => listWorkflowRuns(params, config2)),
124717
+ experimentalSetAttributes: (runId, changes, options) => experimentalSetAttributes(runId, changes, options, config2)
124445
124718
  },
124446
124719
  steps: {
124447
124720
  get: ((runId, stepId, params) => getStep(runId, stepId, params, config2)),
@@ -151188,7 +151461,7 @@ const route4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
151188
151461
  __proto__: null,
151189
151462
  loader
151190
151463
  }, 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 };
151464
+ 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-ORTTXEp6.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/mermaid-3ZIDBTTL-TNUP6Q3m.js"], "css": ["/assets/root-COvK3yNk.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-Cai0GqMt.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/workflow-graph-viewer-DKqOOMnz.js", "/assets/mermaid-3ZIDBTTL-TNUP6Q3m.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-DNZJxxPM.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/workflow-graph-viewer-DKqOOMnz.js", "/assets/mermaid-3ZIDBTTL-TNUP6Q3m.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-127f70fe.js", "version": "127f70fe", "sri": void 0 };
151192
151465
  const assetsBuildDirectory = "build/client";
151193
151466
  const basename = "/";
151194
151467
  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 +151530,56 @@ const serverBuild = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineP
151257
151530
  ssr
151258
151531
  }, Symbol.toStringTag, { value: "Module" }));
151259
151532
  export {
151260
- requireTokenUtil as A,
151533
+ ATTRIBUTE_KEY_MAX_LENGTH as A,
151261
151534
  BaseEventSchema as B,
151262
- requireTokenError as C,
151535
+ ulidToDate as C,
151263
151536
  DEFAULT_TIMESTAMP_THRESHOLD_FUTURE_MS as D,
151264
151537
  EVENT_DATA_REF_FIELDS as E,
151265
- serverBuild as F,
151538
+ validateAttributeChanges as F,
151539
+ validateAttributeKey as G,
151266
151540
  HookSchema as H,
151267
- Ks as K,
151541
+ validateAttributeValue as I,
151542
+ validateUlidTimestamp as J,
151543
+ R as K,
151268
151544
  LegacySerializedDataSchemaV1 as L,
151269
151545
  MessageId as M,
151270
151546
  Nt as N,
151547
+ Ks as O,
151271
151548
  PaginatedResponseSchema as P,
151272
151549
  QueuePayloadSchema as Q,
151273
- RunInputSchema as R,
151550
+ RESERVED_ATTRIBUTE_KEY_PREFIX as R,
151274
151551
  SPEC_VERSION_CURRENT as S,
151552
+ jsxRuntimeExports as T,
151553
+ Qe as U,
151275
151554
  ValidQueueName as V,
151276
151555
  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
151556
+ requireTokenUtil as X,
151557
+ requireTokenError as Y,
151558
+ serverBuild as Z,
151559
+ ATTRIBUTE_MAX_PER_RUN as a,
151560
+ ATTRIBUTE_VALUE_MAX_BYTES as b,
151561
+ AttributeValidationError as c,
151562
+ DEFAULT_TIMESTAMP_THRESHOLD_PAST_MS as d,
151563
+ EventSchema as e,
151564
+ EventTypeSchema as f,
151565
+ HealthCheckPayloadSchema as g,
151566
+ QueuePrefix as h,
151567
+ RunInputSchema as i,
151568
+ SPEC_VERSION_LEGACY as j,
151569
+ SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT as k,
151570
+ SPEC_VERSION_SUPPORTS_EVENT_SOURCING as l,
151571
+ SerializedDataSchema as m,
151572
+ StepInvokePayloadSchema as n,
151573
+ StepSchema as o,
151574
+ StepStatusSchema as p,
151575
+ WaitStatusSchema as q,
151576
+ WorkflowInvokePayloadSchema as r,
151577
+ WorkflowRunBaseSchema as s,
151578
+ WorkflowRunSchema as t,
151579
+ WorkflowRunStatusSchema as u,
151580
+ applyAttributeChanges as v,
151581
+ isLegacySpecVersion as w,
151582
+ reenqueueActiveRuns as x,
151583
+ requiresNewerWorld as y,
151584
+ stripEventDataRefs as z
151303
151585
  };