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

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 (28) hide show
  1. package/build/client/assets/app-9JVnf-IU.css +1 -0
  2. package/build/client/assets/{arrow-up-right-jWH-UQH9.js → arrow-up-right-D39pnGsD.js} +1 -1
  3. package/build/client/assets/{highlighted-body-B3W2YXNL-DmmWu7VM.js → highlighted-body-B3W2YXNL-Dc1dLaUr.js} +1 -1
  4. package/build/client/assets/{home-BwYHJJJr.js → home-C6CuMqQu.js} +3 -3
  5. package/build/client/assets/{loader-circle-fFQM94Ej.js → loader-circle-BOxaTUjK.js} +1 -1
  6. package/build/client/assets/{manifest-f6a9dca2.js → manifest-157e28f1.js} +1 -1
  7. package/build/client/assets/{mermaid-3ZIDBTTL-DchhEfRL.js → mermaid-3ZIDBTTL-gEw-Ch1C.js} +308 -284
  8. package/build/client/assets/{root-D6p4Hb4F.js → root-BfhMCbkz.js} +3 -3
  9. package/build/client/assets/root-Bl5xphvU.css +1 -0
  10. package/build/client/assets/{run-detail-vPCbZIXx.js → run-detail-BG_1K2Hq.js} +339 -130
  11. package/build/client/assets/{workflow-graph-viewer-t_fSwuwz.js → workflow-graph-viewer-CxrWityD.js} +3 -145
  12. package/build/client/assets/{zstd-browser-decoder-BTw1glGN.js → zstd-browser-decoder-CAEVa0bm.js} +1 -1
  13. package/build/server/assets/{app-D8GiFFR6.js → app-_xgEuKqE.js} +1533 -799
  14. package/build/server/assets/{highlighted-body-B3W2YXNL-BZVc2guG.js → highlighted-body-B3W2YXNL-B1Smd86a.js} +5 -4
  15. package/build/server/assets/index-CSsrecUx.js +161 -0
  16. package/build/server/assets/{index-DTci39F3.js → index-Ck5CB_wQ.js} +1 -1
  17. package/build/server/assets/{mermaid-3ZIDBTTL-DOefrphg.js → mermaid-3ZIDBTTL-CwYR558N.js} +5 -4
  18. package/build/server/assets/{token-c3byIJRC.js → token-COK7oHMh.js} +1 -1
  19. package/build/server/assets/{token-util-C2yENsqE.js → token-util-BhmVdeCX.js} +1 -1
  20. package/build/server/assets/{websocket-server-DagS_hnJ.js → websocket-server-ByjlHAhQ.js} +1 -1
  21. package/build/server/assets/{wrapper-Cnumc4u1.js → wrapper-DWeVTope.js} +7 -6
  22. package/build/server/assets/{ws-transport-2gJL6hC2.js → ws-transport-BCfcEhAO.js} +45 -6
  23. package/build/server/assets/{zstd-browser-decoder-BCVvr1WT.js → zstd-browser-decoder-D8JD_nwS.js} +5 -4
  24. package/build/server/index.js +7 -6
  25. package/package.json +7 -7
  26. package/build/client/assets/app-BkGXg64e.css +0 -1
  27. package/build/client/assets/root-ZRjqDhEN.css +0 -1
  28. package/build/server/assets/index-BByEr1g6.js +0 -154
@@ -1,7 +1,7 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports, o as reactDomExports, D as ReactDOM, d as useNavigate, e as useSearchParams, c as Link, w as withComponentProps, G as useParams } from "./index-PFjW8YjQ.js";
2
- import { C as CircleAlert, O as parseStepName, B as parseWorkflowName, Q as ErrorCard, U as format, Z as Zap, S as Send, R as ResolveHookModal, q as ChevronUp, X, N as ErrorBoundary, V as Circle, u as unwrapOrThrow, W as WorkflowWebAPIError, I as unwrapServerActionResult, Y as useEscapeKeydown, t as composeEventHandlers, _ as useCallbackRef, $ as useLayoutEffect2, s as useControllableState, a0 as useId, a1 as createContext2, v as Presence, x as createContextScope, n as hideOthers, o as ReactRemoveScroll, a2 as useFocusGuards, a3 as LAYOUT, a4 as wakeUpRun, l as resumeHook, A as Alert, c as AlertTitle, g as getErrorTitle, d as AlertDescription, e as getErrorMessage, a as Skeleton$1, a5 as RunActionsButtons, F as StatusBadge, h as CopyableText, b as RelativeTime, T as Tabs, K as TabsList, L as TabsTrigger, M as TabsContent, a6 as cancelRun, a7 as recreateRun } from "./workflow-graph-viewer-t_fSwuwz.js";
3
- import { c as createLucideIcon, Y as cn, Z as CopyableDataBlock, $ as CollapsibleRoot, a0 as CollapsibleTrigger, a1 as CollapsibleContent, a2 as CopyButton, O as cva, a3 as RESERVED_ATTRIBUTE_KEY_PREFIX, a4 as Spinner, a5 as ContextCardProvider, h as useToast, a6 as Skeleton, a7 as DecryptClickContext, a8 as Yr, a9 as isEncryptedMarker, m as ChevronRight, aa as TimestampTooltip, ab as formatDuration, C as Check, l as Copy, ac as DataInspector, ad as _r, ae as isHookLifecycleEventType, af as isTerminalStepEventType, ag as isWaitEventType, ah as isStepEventType, ai as RunClickContext, aj as StreamClickContext, ak as Collapsible, al as isExpiredMarker, am as isDoStreamStep, an as extractConversation, ao as EncryptedDataBlock, ap as getEventDataRefFields, aq as hasEncryptedFields, ar as useSidebarDataOptional, as as isTerminalWorkflowRunStatus, at as clsx, au as useActiveSpan, av as useSidebarData, aw as Tooltip, ax as TooltipTrigger, ay as IconButton, az as TooltipContent, J as ChevronDown, aA as useRowWindow, aB as isSpanDimmedBySearch, aC as ROW_HEIGHT_PX, aD as getSpanDurationMs, aE as isSpanErrored, aF as formatDurationPrecise, aG as TooltipProvider, aH as ActiveSpanProvider, aI as useReducedMotion, aJ as searchSpans, aK as computeRootBounds, aL as computeTimeMarkers, aM as clampViewportToRoot, aN as getHighResInMs, aO as scrollRowIntoView, aP as TIMELINE_PADDING_PX, aQ as Minimap, aR as Timeline, aS as TimelineHeader, aT as wheelZoomScaleFactor, aU as wheelDeltaToPixels, aV as SidebarDataProvider, aW as fetchHook, n as fetchEvents, aX as hydrateResourceIOAsync, N as fetchRun, aY as fetchStep, aZ as hydrateResourceIO, a_ as fetchStreams, a$ as apiBase, b0 as Slot, L as useComposedRefs, b1 as Slottable, e as cn$1, b2 as buttonVariants, b3 as fetchEvent, b4 as fetchEventsByCorrelationId, b5 as isEncryptedData, b6 as hydrateData, b7 as decrypt, b8 as deriveRunPayloadKeys, b9 as getWebRevivers, T as Tooltip$1, a as TooltipTrigger$1, b as TooltipContent$1, ba as LIVE_UPDATE_INTERVAL_MS$1, u as useServerConfig, bb as getEncryptionKeyForRun, t as toast, bc as StreamViewerSkeleton, bd as Lock, be as StreamViewer } from "./mermaid-3ZIDBTTL-DchhEfRL.js";
4
- import { A as ArrowUpRight } from "./arrow-up-right-jWH-UQH9.js";
2
+ import { C as CircleAlert, O as parseStepName, B as parseWorkflowName, Q as ErrorCard, U as format, Z as Zap, S as Send, R as ResolveHookModal, q as ChevronUp, X, N as ErrorBoundary, V as Circle, u as unwrapOrThrow, W as WorkflowWebAPIError, I as unwrapServerActionResult, Y as useEscapeKeydown, t as composeEventHandlers, _ as useCallbackRef, $ as useLayoutEffect2, s as useControllableState, a0 as useId, a1 as createContext2, v as Presence, x as createContextScope, n as hideOthers, o as ReactRemoveScroll, a2 as useFocusGuards, a3 as LAYOUT, a4 as wakeUpRun, l as resumeHook, A as Alert, c as AlertTitle, g as getErrorTitle, d as AlertDescription, e as getErrorMessage, a as Skeleton$1, a5 as RunActionsButtons, F as StatusBadge, h as CopyableText, b as RelativeTime, T as Tabs, K as TabsList, L as TabsTrigger, M as TabsContent, a6 as cancelRun, a7 as recreateRun } from "./workflow-graph-viewer-CxrWityD.js";
3
+ import { c as createLucideIcon, Y as entityEventClass, Z as cn, $ as CopyableDataBlock, a0 as CollapsibleRoot, a1 as CollapsibleTrigger, a2 as CollapsibleContent, a3 as CopyButton, O as cva, a4 as RESERVED_ATTRIBUTE_KEY_PREFIX, a5 as Spinner, a6 as TooltipProvider, a7 as Tooltip, a8 as TooltipTrigger, a9 as TooltipContent, aa as ContextCardProvider, h as useToast, ab as Skeleton, ac as DecryptClickContext, ad as Yr, ae as isEncryptedMarker, m as ChevronRight, af as TimestampTooltip, ag as formatDuration, C as Check, l as Copy, ah as DataInspector, ai as _r, aj as isHookLifecycleEventType, ak as isTerminalStepEventType, al as isWaitEventType, am as isStepEventType, an as RunClickContext, ao as StreamClickContext, ap as Collapsible, aq as isExpiredMarker, ar as isDoStreamStep, as as extractConversation, at as EncryptedDataBlock, au as getEventDataRefFields, av as hasEncryptedFields, aw as useSidebarDataOptional, ax as isTerminalWorkflowRunStatus, ay as clsx, az as useActiveSpan, aA as useSidebarData, aB as IconButton, J as ChevronDown, aC as useRowWindow, aD as isSpanDimmedBySearch, aE as ROW_HEIGHT_PX, aF as getSpanDurationMs, aG as isSpanErrored, aH as formatDurationPrecise, aI as ActiveSpanProvider, aJ as useReducedMotion, aK as searchSpans, aL as computeRootBounds, aM as computeTimeMarkers, aN as clampViewportToRoot, aO as getHighResInMs, aP as scrollRowIntoView, aQ as TIMELINE_PADDING_PX, aR as Minimap, aS as Timeline, aT as TimelineHeader, aU as wheelZoomScaleFactor, aV as wheelDeltaToPixels, aW as SidebarDataProvider, aX as fetchHook, n as fetchEvents, aY as hydrateResourceIOAsync, N as fetchRun, aZ as fetchStep, a_ as hydrateResourceIO, a$ as fetchStreams, b0 as apiBase, b1 as Slot, L as useComposedRefs, b2 as Slottable, e as cn$1, b3 as buttonVariants, b4 as fetchEvent, b5 as fetchEventsByCorrelationId, b6 as isEncryptedData, b7 as hydrateData, b8 as decrypt, b9 as deriveRunPayloadKeys, ba as getWebRevivers, T as Tooltip$1, a as TooltipTrigger$1, b as TooltipContent$1, bb as LIVE_UPDATE_INTERVAL_MS$1, u as useServerConfig, bc as getEncryptionKeyForRun, t as toast, bd as StreamViewerSkeleton, be as Lock, bf as StreamViewer } from "./mermaid-3ZIDBTTL-gEw-Ch1C.js";
4
+ import { A as ArrowUpRight } from "./arrow-up-right-D39pnGsD.js";
5
5
  /**
6
6
  * @license lucide-react v0.575.0 - ISC
7
7
  *
@@ -76,6 +76,97 @@ const __iconNode = [
76
76
  ["line", { x1: "8", x2: "14", y1: "11", y2: "11", key: "durymu" }]
77
77
  ];
78
78
  const ZoomOut = createLucideIcon("zoom-out", __iconNode);
79
+ const EVENT_ID_BODY_LENGTH = 26;
80
+ const SLOT_LEADING_ZEROS = 10;
81
+ function isSlotBody(body) {
82
+ if (body.length !== EVENT_ID_BODY_LENGTH)
83
+ return false;
84
+ for (let i = 0; i < SLOT_LEADING_ZEROS; i++) {
85
+ if (body[i] !== "0")
86
+ return false;
87
+ }
88
+ for (let i = SLOT_LEADING_ZEROS; i < EVENT_ID_BODY_LENGTH; i++) {
89
+ const code = body.charCodeAt(i);
90
+ if (code < 48 || code > 57)
91
+ return false;
92
+ }
93
+ return true;
94
+ }
95
+ function stripEventIdPrefix(eventId) {
96
+ const underscore = eventId.indexOf("_");
97
+ return underscore === -1 ? eventId : eventId.slice(underscore + 1);
98
+ }
99
+ function isSlotEventId(eventId) {
100
+ return isSlotBody(stripEventIdPrefix(eventId));
101
+ }
102
+ const TERMINAL_EVENT_CLASSES = /* @__PURE__ */ new Set([
103
+ "step_terminal",
104
+ "wait_completed",
105
+ "hook_disposed"
106
+ ]);
107
+ const SINGLETON_EVENT_CLASSES = /* @__PURE__ */ new Set([
108
+ "run_started"
109
+ ]);
110
+ const RUN_ENTITY_KEY = "";
111
+ const DUPLICATE_EVENT_MESSAGE = "Written by a concurrent replay after an event of the same kind was already recorded and acted on. The run follows the earlier one.";
112
+ function compareEventId(a, b) {
113
+ if (a.eventId.length !== b.eventId.length) {
114
+ return a.eventId.length - b.eventId.length;
115
+ }
116
+ return a.eventId < b.eventId ? -1 : a.eventId > b.eventId ? 1 : 0;
117
+ }
118
+ function createdAtMs(event) {
119
+ const createdAt = event.createdAt;
120
+ return createdAt instanceof Date ? createdAt.getTime() : new Date(createdAt).getTime();
121
+ }
122
+ function hasKnowableLogOrder(orderedById) {
123
+ if (orderedById.every((event) => isSlotEventId(event.eventId)))
124
+ return true;
125
+ for (let index = 1; index < orderedById.length; index++) {
126
+ const previous = createdAtMs(orderedById[index - 1]);
127
+ const current = createdAtMs(orderedById[index]);
128
+ if (Number.isNaN(previous) || Number.isNaN(current))
129
+ return false;
130
+ if (current < previous)
131
+ return false;
132
+ }
133
+ return true;
134
+ }
135
+ function foldDuplicates(ordered) {
136
+ const duplicates = /* @__PURE__ */ new Set();
137
+ const seenClasses = /* @__PURE__ */ new Set();
138
+ const closedEntities = /* @__PURE__ */ new Set();
139
+ for (const event of ordered) {
140
+ const eventClass = entityEventClass(event.eventType);
141
+ if (eventClass === void 0)
142
+ continue;
143
+ const entity = event.correlationId ?? RUN_ENTITY_KEY;
144
+ const classKey = `${eventClass}:${entity}`;
145
+ const repeatsClass = seenClasses.has(classKey);
146
+ const entityWasClosed = closedEntities.has(entity);
147
+ if (TERMINAL_EVENT_CLASSES.has(eventClass)) {
148
+ closedEntities.add(entity);
149
+ }
150
+ if (!repeatsClass) {
151
+ if (entityWasClosed)
152
+ break;
153
+ seenClasses.add(classKey);
154
+ continue;
155
+ }
156
+ if (entityWasClosed || SINGLETON_EVENT_CLASSES.has(eventClass)) {
157
+ duplicates.add(event.eventId);
158
+ }
159
+ }
160
+ return duplicates;
161
+ }
162
+ function findDuplicateEventIds(events, { isCompleteHistory }) {
163
+ if (!isCompleteHistory || events.length < 2)
164
+ return /* @__PURE__ */ new Set();
165
+ const ordered = events.filter((event) => Boolean(event.eventId)).sort(compareEventId);
166
+ if (!hasKnowableLogOrder(ordered))
167
+ return /* @__PURE__ */ new Set();
168
+ return foldDuplicates(ordered);
169
+ }
79
170
  const WORKFLOW_ULID_BODY = "[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}";
80
171
  const STEP_ID_PATTERN = new RegExp(`^step_(${WORKFLOW_ULID_BODY})$`, "i");
81
172
  const WAIT_ID_PATTERN = new RegExp(`^wait_(${WORKFLOW_ULID_BODY})$`, "i");
@@ -233,6 +324,33 @@ function getMiddleTruncateCopyTextFromSelectionText({ prefixText, selectionText,
233
324
  });
234
325
  return mappedText === null ? null : leading + mappedText + trailing;
235
326
  }
327
+ const pendingMeasurements = /* @__PURE__ */ new Map();
328
+ let measurementFrame = 0;
329
+ function flushMeasurements() {
330
+ measurementFrame = 0;
331
+ const reads = [...pendingMeasurements.values()];
332
+ pendingMeasurements.clear();
333
+ const measures = reads.map((read) => read());
334
+ for (const measure of measures) {
335
+ measure == null ? void 0 : measure();
336
+ }
337
+ }
338
+ function scheduleMeasurement(key, { read, measure }) {
339
+ pendingMeasurements.set(key, () => {
340
+ const measurement = read();
341
+ return measurement === null ? null : () => measure(measurement);
342
+ });
343
+ if (measurementFrame === 0) {
344
+ measurementFrame = requestAnimationFrame(flushMeasurements);
345
+ }
346
+ }
347
+ function cancelMeasurement(key) {
348
+ pendingMeasurements.delete(key);
349
+ if (pendingMeasurements.size === 0 && measurementFrame !== 0) {
350
+ cancelAnimationFrame(measurementFrame);
351
+ measurementFrame = 0;
352
+ }
353
+ }
236
354
  const useIsomorphicLayoutEffect = typeof window === "undefined" ? reactExports.useEffect : reactExports.useLayoutEffect;
237
355
  function createFullState(value, graphemes) {
238
356
  return {
@@ -250,7 +368,13 @@ function useMiddleTruncate(value) {
250
368
  const ref = reactExports.useRef(null);
251
369
  const measureRef = reactExports.useRef(null);
252
370
  const [state, setState] = reactExports.useState(() => fullState);
253
- const rafRef = reactExports.useRef(0);
371
+ const measurementKeyRef = reactExports.useRef({});
372
+ const textMeasurementCacheRef = reactExports.useRef({
373
+ typography: "",
374
+ value,
375
+ widths: /* @__PURE__ */ new Map()
376
+ });
377
+ const lastMeasurementRef = reactExports.useRef(null);
254
378
  const updateState = reactExports.useCallback((nextState) => {
255
379
  setState((currentState) => {
256
380
  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) {
@@ -259,26 +383,68 @@ function useMiddleTruncate(value) {
259
383
  return nextState;
260
384
  });
261
385
  }, []);
262
- const recalculate = reactExports.useCallback(() => {
386
+ const readMeasurement = reactExports.useCallback(() => {
263
387
  const el = ref.current;
264
388
  const measureEl = measureRef.current;
265
389
  if (!el || !measureEl)
390
+ return null;
391
+ const availableWidth = el.clientWidth;
392
+ const style = getComputedStyle(measureEl);
393
+ return {
394
+ availableWidth,
395
+ typography: [
396
+ style.fontFamily,
397
+ style.fontFeatureSettings,
398
+ style.fontKerning,
399
+ style.fontSize,
400
+ style.fontStretch,
401
+ style.fontStyle,
402
+ style.fontVariationSettings,
403
+ style.fontWeight,
404
+ style.letterSpacing,
405
+ style.textTransform
406
+ ].join("\0")
407
+ };
408
+ }, []);
409
+ const recalculate = reactExports.useCallback(({ availableWidth, typography }) => {
410
+ const measureEl = measureRef.current;
411
+ if (!measureEl)
412
+ return;
413
+ const lastMeasurement = lastMeasurementRef.current;
414
+ if ((lastMeasurement == null ? void 0 : lastMeasurement.availableWidth) === availableWidth && lastMeasurement.typography === typography && lastMeasurement.value === value) {
266
415
  return;
267
- const available = el.clientWidth;
268
- if (available <= 0) {
416
+ }
417
+ lastMeasurementRef.current = {
418
+ availableWidth,
419
+ typography,
420
+ value
421
+ };
422
+ if (availableWidth <= 0) {
269
423
  updateState(fullState);
270
424
  return;
271
425
  }
426
+ const textMeasurementCache = textMeasurementCacheRef.current;
427
+ if (textMeasurementCache.typography !== typography || textMeasurementCache.value !== value) {
428
+ textMeasurementCache.typography = typography;
429
+ textMeasurementCache.value = value;
430
+ textMeasurementCache.widths.clear();
431
+ }
272
432
  const measure = (text) => {
433
+ const cachedWidth = textMeasurementCache.widths.get(text);
434
+ if (cachedWidth !== void 0) {
435
+ return cachedWidth;
436
+ }
273
437
  measureEl.textContent = text;
274
- return measureEl.scrollWidth;
438
+ const width = measureEl.scrollWidth;
439
+ textMeasurementCache.widths.set(text, width);
440
+ return width;
275
441
  };
276
442
  const fullWidth = measure(value);
277
- if (fullWidth <= available) {
443
+ if (fullWidth <= availableWidth) {
278
444
  updateState(fullState);
279
445
  return;
280
446
  }
281
- const result = middleTruncate(graphemes, available, measure, fullWidth);
447
+ const result = middleTruncate(graphemes, availableWidth, measure, fullWidth);
282
448
  updateState({
283
449
  displayText: result.text,
284
450
  isTruncated: result.truncated,
@@ -289,33 +455,45 @@ function useMiddleTruncate(value) {
289
455
  });
290
456
  }, [fullState, graphemes, updateState, value]);
291
457
  useIsomorphicLayoutEffect(() => {
292
- recalculate();
293
- }, [recalculate]);
458
+ const measurement = readMeasurement();
459
+ if (measurement) {
460
+ recalculate(measurement);
461
+ }
462
+ }, [readMeasurement, recalculate]);
294
463
  reactExports.useEffect(() => {
295
464
  var _a;
296
465
  const el = ref.current;
297
466
  if (!el)
298
467
  return;
299
- const debouncedRecalc = () => {
300
- cancelAnimationFrame(rafRef.current);
301
- rafRef.current = requestAnimationFrame(recalculate);
468
+ const measurementKey = measurementKeyRef.current;
469
+ const scheduleRecalculation = () => {
470
+ scheduleMeasurement(measurementKey, {
471
+ read: readMeasurement,
472
+ measure: recalculate
473
+ });
302
474
  };
303
- const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(debouncedRecalc) : null;
475
+ const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(scheduleRecalculation) : null;
304
476
  ro == null ? void 0 : ro.observe(el);
305
- window.addEventListener("resize", debouncedRecalc);
477
+ if (!ro) {
478
+ window.addEventListener("resize", scheduleRecalculation);
479
+ }
306
480
  const onFontsLoaded = () => {
307
- debouncedRecalc();
481
+ textMeasurementCacheRef.current.widths.clear();
482
+ lastMeasurementRef.current = null;
483
+ scheduleRecalculation();
308
484
  };
309
485
  const fontSet = "fonts" in document ? document.fonts : null;
310
486
  (_a = fontSet == null ? void 0 : fontSet.addEventListener) == null ? void 0 : _a.call(fontSet, "loadingdone", onFontsLoaded);
311
487
  return () => {
312
488
  var _a2;
313
489
  ro == null ? void 0 : ro.disconnect();
314
- window.removeEventListener("resize", debouncedRecalc);
315
- cancelAnimationFrame(rafRef.current);
490
+ if (!ro) {
491
+ window.removeEventListener("resize", scheduleRecalculation);
492
+ }
493
+ cancelMeasurement(measurementKey);
316
494
  (_a2 = fontSet == null ? void 0 : fontSet.removeEventListener) == null ? void 0 : _a2.call(fontSet, "loadingdone", onFontsLoaded);
317
495
  };
318
- }, [recalculate]);
496
+ }, [readMeasurement, recalculate]);
319
497
  return {
320
498
  ref,
321
499
  measureRef,
@@ -331,12 +509,18 @@ function getRangeOffsets(container, range) {
331
509
  if (!container.contains(range.startContainer) || !container.contains(range.endContainer)) {
332
510
  return null;
333
511
  }
334
- const startRange = document.createRange();
335
- startRange.selectNodeContents(container);
336
- startRange.setEnd(range.startContainer, range.startOffset);
337
- const endRange = document.createRange();
338
- endRange.selectNodeContents(container);
339
- endRange.setEnd(range.endContainer, range.endOffset);
512
+ let startRange;
513
+ let endRange;
514
+ try {
515
+ startRange = document.createRange();
516
+ startRange.selectNodeContents(container);
517
+ startRange.setEnd(range.startContainer, range.startOffset);
518
+ endRange = document.createRange();
519
+ endRange.selectNodeContents(container);
520
+ endRange.setEnd(range.endContainer, range.endOffset);
521
+ } catch {
522
+ return null;
523
+ }
340
524
  return {
341
525
  end: endRange.toString().length,
342
526
  start: startRange.toString().length
@@ -358,7 +542,7 @@ function MiddleTruncate({ value, className, onCopy: onCopyProp, ...props }) {
358
542
  const range = selection.getRangeAt(0);
359
543
  const visibleEl = visibleRef.current;
360
544
  let copyText = null;
361
- if (e.currentTarget.contains(range.startContainer) && e.currentTarget.contains(range.endContainer) && visibleEl) {
545
+ if (selectionText.includes(ELLIPSIS) && e.currentTarget.contains(range.startContainer) && e.currentTarget.contains(range.endContainer) && visibleEl) {
362
546
  const offsets = getRangeOffsets(visibleEl, range);
363
547
  if (offsets) {
364
548
  copyText = getMiddleTruncateCopyText({
@@ -410,7 +594,7 @@ const rowCopyValueVariants = cva("flex min-w-0 flex-1 items-center justify-end g
410
594
  });
411
595
  function DetailKeyValueRowBase({ label, value, copyText, href, removed = false, variant }) {
412
596
  const stringValue = typeof value === "string" ? value : void 0;
413
- return jsxRuntimeExports.jsxs("div", { className: "px-1.5 hover:bg-gray-100 flex justify-between gap-3 -mx-1.5 py-0.5 rounded items-center", children: [jsxRuntimeExports.jsx("span", { className: "flex min-w-0 items-center gap-1.5 truncate text-label-13 text-gray-900", children: label }), removed ? jsxRuntimeExports.jsx("span", { className: "shrink-0 text-copy-13 italic text-gray-700", children: "removed" }) : copyText ? jsxRuntimeExports.jsxs("div", { className: cn(rowCopyValueVariants({ variant })), title: copyText, children: [href ? jsxRuntimeExports.jsxs("a", { href, target: "_blank", rel: "noreferrer", className: cn(rowValueVariants({ variant }), "flex min-w-0 items-center gap-0.5 hover:underline"), children: [jsxRuntimeExports.jsx(MiddleTruncate, { value: copyText, className: "min-w-0 text-right", style: { gridTemplateColumns: "minmax(0, 1fr)" } }), jsxRuntimeExports.jsx(ArrowUpRight, { "aria-hidden": true, className: "h-3 w-3 shrink-0" })] }) : jsxRuntimeExports.jsx(MiddleTruncate, { value: copyText, className: cn(rowValueVariants({ variant, className: "text-right" })), style: { gridTemplateColumns: "minmax(0, 1fr)" } }), jsxRuntimeExports.jsx(CopyButton, { copyText, ariaLabel: `Copy ${label}`, className: "shrink-0 -mr-1" })] }) : jsxRuntimeExports.jsx("span", { className: cn(rowValueVariants({ variant })), title: stringValue, children: href ? jsxRuntimeExports.jsx("a", { href, target: "_blank", rel: "noreferrer", className: "hover:underline", children: value }) : value })] });
597
+ return jsxRuntimeExports.jsxs("div", { className: "px-1.5 hover:bg-gray-100 flex justify-between gap-3 -mx-1.5 py-0.5 rounded items-center", children: [jsxRuntimeExports.jsx("span", { className: "flex min-w-0 items-center gap-1.5 truncate text-label-13 text-gray-900", children: label }), removed ? jsxRuntimeExports.jsx("span", { className: "shrink-0 text-copy-13 italic text-gray-700", children: "removed" }) : copyText ? jsxRuntimeExports.jsxs("div", { className: cn(rowCopyValueVariants({ variant })), title: copyText, children: [href ? jsxRuntimeExports.jsxs("a", { href, target: "_blank", rel: "noreferrer", className: cn(rowValueVariants({ variant }), "flex min-w-0 items-center gap-0.5 hover:underline"), children: [jsxRuntimeExports.jsx(MiddleTruncate, { value: copyText, className: "min-w-0 grid-cols-[minmax(0,1fr)] text-right" }), jsxRuntimeExports.jsx(ArrowUpRight, { "aria-hidden": true, className: "h-3 w-3 shrink-0" })] }) : jsxRuntimeExports.jsx(MiddleTruncate, { value: copyText, className: cn(rowValueVariants({ variant, className: "text-right" }), "grid-cols-[minmax(0,1fr)]") }), jsxRuntimeExports.jsx(CopyButton, { copyText, ariaLabel: `Copy ${label}`, className: "shrink-0 -mr-1" })] }) : jsxRuntimeExports.jsx("span", { className: cn(rowValueVariants({ variant })), title: stringValue, children: href ? jsxRuntimeExports.jsx("a", { href, target: "_blank", rel: "noreferrer", className: "hover:underline", children: value }) : value })] });
414
598
  }
415
599
  function DetailKeyValueRow(props) {
416
600
  return jsxRuntimeExports.jsx(DetailKeyValueRowBase, { ...props });
@@ -485,15 +669,17 @@ function AttrSetEventBlock({ data }) {
485
669
  return jsxRuntimeExports.jsx(CopyableDataBlock, { data });
486
670
  }
487
671
  const writerLabel = describeWriter(data.writer);
488
- return jsxRuntimeExports.jsxs("div", { className: "flex flex-col px-3 py-1", children: [jsxRuntimeExports.jsx("div", { className: "flex flex-col", children: data.changes.map((change, index) => jsxRuntimeExports.jsx(AttributeRow, { attributeKey: change.key, removed: change.value === null, value: change.value ?? void 0 }, `${change.key}:${index}`)) }), writerLabel && jsxRuntimeExports.jsx("div", { className: "border-t py-1.5 text-label-12", style: {
489
- borderColor: "var(--ds-gray-alpha-400)",
490
- color: "var(--ds-gray-700)"
491
- }, children: writerLabel })] });
672
+ return jsxRuntimeExports.jsxs("div", { className: "flex flex-col px-3 py-1", children: [jsxRuntimeExports.jsx("div", { className: "flex flex-col", children: data.changes.map((change, index) => jsxRuntimeExports.jsx(AttributeRow, { attributeKey: change.key, removed: change.value === null, value: change.value ?? void 0 }, `${change.key}:${index}`)) }), writerLabel && jsxRuntimeExports.jsx("div", { className: "border-gray-alpha-400 border-t py-1.5 text-gray-700 text-label-12", children: writerLabel })] });
492
673
  }
493
674
  const STYLES$2 = `.wf-decrypt-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;cursor:pointer;white-space:nowrap;gap:6px;transition:background 150ms}.wf-decrypt-idle{color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400)}.wf-decrypt-idle:hover{background:var(--ds-gray-alpha-200)}.wf-decrypt-done{color:var(--ds-green-900);background:var(--ds-green-100);box-shadow:0 0 0 1px var(--ds-green-400);cursor:default}`;
494
675
  function DecryptButton({ decrypted = false, loading = false, onClick }) {
495
676
  return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { dangerouslySetInnerHTML: { __html: STYLES$2 } }), jsxRuntimeExports.jsxs("button", { type: "button", onClick: decrypted ? void 0 : onClick, disabled: decrypted || loading, className: `wf-decrypt-btn ${decrypted ? "wf-decrypt-done" : "wf-decrypt-idle"}`, children: [loading ? jsxRuntimeExports.jsx(Spinner, { size: 14 }) : decrypted ? jsxRuntimeExports.jsxs("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), jsxRuntimeExports.jsx("path", { d: "M7 11V7a5 5 0 0 1 9.9-1" })] }) : jsxRuntimeExports.jsxs("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), jsxRuntimeExports.jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })] }), loading ? "Decrypting…" : decrypted ? "Decrypted" : "Decrypt"] })] });
496
677
  }
678
+ function DuplicateEventTooltip({ isDuplicate = false, children }) {
679
+ if (!isDuplicate)
680
+ return children;
681
+ return jsxRuntimeExports.jsx(TooltipProvider, { delayDuration: 300, children: jsxRuntimeExports.jsxs(Tooltip, { children: [jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children }), jsxRuntimeExports.jsx(TooltipContent, { className: "max-w-[264px] leading-snug", collisionPadding: 8, side: "top", children: DUPLICATE_EVENT_MESSAGE })] }) });
682
+ }
497
683
  function isStructuredError(value) {
498
684
  return value != null && typeof value === "object" && (typeof value.message === "string" || typeof value.stack === "string");
499
685
  }
@@ -549,24 +735,7 @@ function MenuDropdown({ options, value, onChange }) {
549
735
  document.addEventListener("mousedown", handleClickOutside);
550
736
  return () => document.removeEventListener("mousedown", handleClickOutside);
551
737
  }, [open]);
552
- 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: {
553
- marginLeft: 16,
554
- marginRight: -4,
555
- color: "var(--ds-gray-900)"
556
- }, 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: {
557
- position: "absolute",
558
- right: 0,
559
- top: "100%",
560
- marginTop: 4,
561
- minWidth: 140,
562
- padding: 4,
563
- borderRadius: 12,
564
- background: "var(--ds-background-100)",
565
- boxShadow: "var(--ds-shadow-menu, var(--ds-shadow-medium))",
566
- zIndex: 2001
567
- }, role: "menu", children: options.map((option) => jsxRuntimeExports.jsx("button", { type: "button", role: "menuitem", className: "wf-menu-item", style: {
568
- fontWeight: option.value === value ? 500 : 400
569
- }, onClick: () => {
738
+ return jsxRuntimeExports.jsxs("div", { ref, className: "relative shrink-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", className: "-mr-1 ml-4 text-gray-900", 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", { className: "absolute top-full right-0 z-[2001] mt-1 min-w-[140px] bg-background-100 p-1 material-menu", role: "menu", children: options.map((option) => jsxRuntimeExports.jsx("button", { type: "button", role: "menuitem", className: cn("wf-menu-item", option.value === value ? "font-medium" : "font-normal"), onClick: () => {
570
739
  onChange(option.value);
571
740
  setOpen(false);
572
741
  }, children: option.label }, option.value)) })] });
@@ -643,8 +812,8 @@ function buildNameMaps(events, run) {
643
812
  const workflowName = (run == null ? void 0 : run.workflowName) ? ((_b = parseWorkflowName(run.workflowName)) == null ? void 0 : _b.shortName) ?? run.workflowName : null;
644
813
  return { correlationNameMap, workflowName };
645
814
  }
646
- function buildDurationMap(events) {
647
- const chronological = [...events].sort((a, b) => getEffectiveEventTime(a) - getEffectiveEventTime(b));
815
+ function buildDurationMap(events, duplicateEventIds = /* @__PURE__ */ new Set()) {
816
+ const chronological = [...events].filter((event) => !duplicateEventIds.has(event.eventId)).sort((a, b) => getEffectiveEventTime(a) - getEffectiveEventTime(b));
648
817
  const createdTimes = /* @__PURE__ */ new Map();
649
818
  const firstStartedTimes = /* @__PURE__ */ new Map();
650
819
  const startedTimes = /* @__PURE__ */ new Map();
@@ -893,7 +1062,7 @@ function RowsSkeleton({ showSeparateEventOccurrenceTimestamps = false }) {
893
1062
  marginLeft: i % 4 === 0 ? 5 : 6
894
1063
  } })] }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0 flex items-center justify-center", children: jsxRuntimeExports.jsx(Skeleton, { className: "w-5 h-5", style: { borderRadius: 4 } }) }), showSeparateEventOccurrenceTimestamps && jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "70%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { 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, { className: "flex-shrink-0", style: { width: 6, height: 6, borderRadius: "50%" } }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "60%" } })] }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "50%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "75%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "75%" } }) })] }, i)) });
895
1064
  }
896
- function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData, onCacheEventData, encryptionKey, onEncryptedDataDetected, suppressGroupDimming = false, showSeparateEventOccurrenceTimestamps = false }) {
1065
+ function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData, onCacheEventData, encryptionKey, onEncryptedDataDetected, suppressGroupDimming = false, showSeparateEventOccurrenceTimestamps = false, isDuplicate = false }) {
897
1066
  const [isLoading, setIsLoading] = reactExports.useState(false);
898
1067
  const [loadedEventData, setLoadedEventData] = reactExports.useState(cachedEventData);
899
1068
  const [loadError, setLoadError] = reactExports.useState(null);
@@ -1011,7 +1180,9 @@ function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand,
1011
1180
  }, children: jsxRuntimeExports.jsx(ChevronRight, { className: "h-3 w-3 transition-transform", style: {
1012
1181
  color: "var(--ds-gray-900)",
1013
1182
  transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)"
1014
- } }) }), showSeparateEventOccurrenceTimestamps && jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: occurredAt ? jsxRuntimeExports.jsx(TimestampTooltip, { date: occurredAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(occurredAt) }) }) : "-" }), 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: displayedCreatedAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(displayedCreatedAt) }) }) }), 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: {
1183
+ } }) }), showSeparateEventOccurrenceTimestamps && jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: occurredAt ? jsxRuntimeExports.jsx(TimestampTooltip, { date: occurredAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(occurredAt) }) }) : "-" }), 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: displayedCreatedAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(displayedCreatedAt) }) }) }), jsxRuntimeExports.jsx("div", { className: "font-medium min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(DuplicateEventTooltip, { isDuplicate, children: jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5", style: {
1184
+ color: isDuplicate ? "var(--ds-gray-700)" : "var(--ds-gray-900)"
1185
+ }, children: [jsxRuntimeExports.jsxs("span", { style: {
1015
1186
  position: "relative",
1016
1187
  display: "inline-flex",
1017
1188
  width: 6,
@@ -1030,7 +1201,7 @@ function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand,
1030
1201
  height: 6,
1031
1202
  borderRadius: "50%",
1032
1203
  backgroundColor: statusDotColor
1033
- } })] }), formatEventType(event.eventType)] }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4 overflow-hidden text-ellipsis whitespace-nowrap", style: { flex: "2 1 0%" }, title: eventName !== "-" ? eventName : void 0, children: eventName }), 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: {
1204
+ } })] }), formatEventType(event.eventType)] }) }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4 overflow-hidden text-ellipsis whitespace-nowrap", style: { flex: "2 1 0%" }, title: eventName !== "-" ? eventName : void 0, children: eventName }), 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: {
1034
1205
  borderColor: "var(--ds-gray-alpha-200)",
1035
1206
  opacity: contentOpacity,
1036
1207
  transition: "opacity 150ms"
@@ -1068,6 +1239,9 @@ function EventListViewInner({ events, run, onLoadEventData, hasMoreEvents = fals
1068
1239
  const dir = effectiveSortOrder === "desc" ? -1 : 1;
1069
1240
  return [...sourceEvents].sort((a, b) => dir * (getEffectiveEventTime(a) - getEffectiveEventTime(b)));
1070
1241
  }, [events, effectiveSortOrder, isExactSearchActive, searchResults]);
1242
+ const duplicateEventIds = reactExports.useMemo(() => findDuplicateEventIds(events ?? [], {
1243
+ isCompleteHistory: !hasMoreEvents && !isExactSearchActive
1244
+ }), [events, hasMoreEvents, isExactSearchActive]);
1071
1245
  const hasEncryptedInlineData = reactExports.useMemo(() => {
1072
1246
  const sourceEvents = isExactSearchActive ? searchResults : events;
1073
1247
  if (!sourceEvents)
@@ -1085,7 +1259,7 @@ function EventListViewInner({ events, run, onLoadEventData, hasMoreEvents = fals
1085
1259
  }, []);
1086
1260
  const hasEncryptedData = hasEncryptedDataProp || hasEncryptedInlineData || foundEncryptedInLazyData;
1087
1261
  const { correlationNameMap, workflowName } = reactExports.useMemo(() => buildNameMaps(isExactSearchActive ? searchResults : events ?? null, run ?? null), [events, isExactSearchActive, run, searchResults]);
1088
- const durationMap = reactExports.useMemo(() => buildDurationMap(sortedEvents), [sortedEvents]);
1262
+ const durationMap = reactExports.useMemo(() => buildDurationMap(sortedEvents, duplicateEventIds), [sortedEvents, duplicateEventIds]);
1089
1263
  const [selectedGroupKey, setSelectedGroupKey] = reactExports.useState(void 0);
1090
1264
  const [hoveredGroupKey, setHoveredGroupKey] = reactExports.useState(void 0);
1091
1265
  const onSelectGroup = reactExports.useCallback((groupKey) => {
@@ -1301,7 +1475,7 @@ function EventListViewInner({ events, run, onLoadEventData, hasMoreEvents = fals
1301
1475
  void (onLoadMoreEvents == null ? void 0 : onLoadMoreEvents());
1302
1476
  }, itemContent: (index) => {
1303
1477
  const ev = sortedEvents[index];
1304
- return jsxRuntimeExports.jsx(EventRow$1, { event: ev, index, isFirst: index === 0, isLast: index === sortedEvents.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, suppressGroupDimming: isExactSearchActive, showSeparateEventOccurrenceTimestamps });
1478
+ return jsxRuntimeExports.jsx(EventRow$1, { event: ev, index, isFirst: index === 0, isLast: index === sortedEvents.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, suppressGroupDimming: isExactSearchActive, isDuplicate: duplicateEventIds.has(ev.eventId), showSeparateEventOccurrenceTimestamps });
1305
1479
  }, style: { flex: 1, minHeight: 0 } }), jsxRuntimeExports.jsxs("div", { className: "relative flex-shrink-0 flex items-center h-10 border-t px-4 text-label-12", style: {
1306
1480
  borderColor: "var(--ds-gray-alpha-200)",
1307
1481
  color: "var(--ds-gray-900)",
@@ -1313,76 +1487,59 @@ function EventListView(props) {
1313
1487
  }
1314
1488
  function ConversationView({ messages }) {
1315
1489
  if (messages.length === 0) {
1316
- return jsxRuntimeExports.jsx("div", { className: "text-center py-8 text-[11px]", style: { color: "var(--ds-gray-600)" }, children: "No messages" });
1490
+ return jsxRuntimeExports.jsx("div", { className: "py-8 text-center text-[11px] text-gray-600", children: "No messages" });
1317
1491
  }
1318
1492
  return jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-3 p-3", children: messages.map((message, index) => jsxRuntimeExports.jsx(MessageBubble, { message }, index)) });
1319
1493
  }
1320
1494
  function MessageBubble({ message }) {
1321
1495
  const role = message.role;
1322
1496
  const parts = parseContent(message.content);
1323
- const style = getRoleStyle(role);
1324
- return jsxRuntimeExports.jsxs("div", { className: "rounded-md border text-[11px]", style: {
1325
- backgroundColor: style.bg,
1326
- borderColor: style.border
1327
- }, children: [jsxRuntimeExports.jsx("div", { className: "px-2.5 py-1 border-b text-[10px] font-medium uppercase tracking-wide", style: {
1328
- borderColor: style.border,
1329
- color: style.label
1330
- }, children: role }), jsxRuntimeExports.jsx("div", { className: "px-2.5 py-2 space-y-2", children: parts.map((part, i) => jsxRuntimeExports.jsx(ContentPart, { part, role }, i)) })] });
1497
+ const roleClasses = getRoleClasses(role);
1498
+ return jsxRuntimeExports.jsxs("div", { className: `rounded-md border text-[11px] ${roleClasses.bubble}`, children: [jsxRuntimeExports.jsx("div", { className: `border-b px-2.5 py-1 font-medium text-[10px] uppercase tracking-wide ${roleClasses.label}`, children: role }), jsxRuntimeExports.jsx("div", { className: "px-2.5 py-2 space-y-2", children: parts.map((part, i) => jsxRuntimeExports.jsx(ContentPart, { part, role }, i)) })] });
1331
1499
  }
1332
1500
  function ContentPart({ part, role }) {
1333
1501
  if (part.type === "text") {
1334
1502
  if (!part.text)
1335
1503
  return null;
1336
1504
  if (role === "assistant") {
1337
- return jsxRuntimeExports.jsx("div", { className: "prose prose-sm max-w-none text-[11px] [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", style: { color: "var(--ds-gray-1000)" }, children: jsxRuntimeExports.jsx(_r, { children: part.text }) });
1505
+ return jsxRuntimeExports.jsx("div", { className: "prose prose-sm max-w-none text-[11px] text-gray-1000 [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", children: jsxRuntimeExports.jsx(_r, { children: part.text }) });
1338
1506
  }
1339
- return jsxRuntimeExports.jsx("div", { className: "whitespace-pre-wrap break-words", style: { color: "var(--ds-gray-1000)" }, children: part.text });
1507
+ return jsxRuntimeExports.jsx("div", { className: "whitespace-pre-wrap break-words text-gray-1000", children: part.text });
1340
1508
  }
1341
1509
  if (part.type === "tool-call") {
1342
- return jsxRuntimeExports.jsxs("div", { className: "rounded border px-2 py-1.5", style: {
1343
- backgroundColor: "var(--ds-purple-100)",
1344
- borderColor: "var(--ds-purple-300)"
1345
- }, children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-medium", children: [jsxRuntimeExports.jsx("span", { children: "🔧" }), jsxRuntimeExports.jsx("span", { style: { color: "var(--ds-purple-900)" }, children: part.toolName })] }), part.input != null && jsxRuntimeExports.jsx("div", { className: "mt-1.5 overflow-x-auto p-1.5 rounded", style: { backgroundColor: "var(--ds-gray-100)" }, children: typeof part.input === "string" ? jsxRuntimeExports.jsx("pre", { className: "text-[10px]", style: { color: "var(--ds-gray-800)" }, children: part.input }) : jsxRuntimeExports.jsx(DataInspector, { data: part.input }) })] });
1510
+ return jsxRuntimeExports.jsxs("div", { className: "rounded border border-purple-300 bg-purple-100 px-2 py-1.5", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-medium", children: [jsxRuntimeExports.jsx("span", { children: "🔧" }), jsxRuntimeExports.jsx("span", { className: "text-purple-900", children: part.toolName })] }), part.input != null && jsxRuntimeExports.jsx("div", { className: "mt-1.5 overflow-x-auto rounded bg-gray-100 p-1.5", children: typeof part.input === "string" ? jsxRuntimeExports.jsx("pre", { className: "text-[10px] text-gray-800", children: part.input }) : jsxRuntimeExports.jsx(DataInspector, { data: part.input }) })] });
1346
1511
  }
1347
1512
  if (part.type === "tool-result") {
1348
- return jsxRuntimeExports.jsxs("div", { className: "rounded border px-2 py-1.5", style: {
1349
- backgroundColor: "var(--ds-green-100)",
1350
- borderColor: "var(--ds-green-300)"
1351
- }, children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-medium", children: [jsxRuntimeExports.jsx("span", { children: "✓" }), jsxRuntimeExports.jsxs("span", { style: { color: "var(--ds-green-900)" }, children: [part.toolName, " result"] })] }), part.output != null && jsxRuntimeExports.jsx("div", { className: "mt-1.5 overflow-x-auto max-h-[200px] overflow-y-auto p-1.5 rounded", style: { backgroundColor: "var(--ds-gray-100)" }, children: typeof part.output === "string" ? jsxRuntimeExports.jsx("pre", { className: "text-[10px]", style: { color: "var(--ds-gray-800)" }, children: part.output }) : jsxRuntimeExports.jsx(DataInspector, { data: part.output, expandLevel: 1 }) })] });
1513
+ return jsxRuntimeExports.jsxs("div", { className: "rounded border border-green-300 bg-green-100 px-2 py-1.5", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-medium", children: [jsxRuntimeExports.jsx("span", { children: "✓" }), jsxRuntimeExports.jsxs("span", { className: "text-green-900", children: [part.toolName, " result"] })] }), part.output != null && jsxRuntimeExports.jsx("div", { className: "mt-1.5 max-h-[200px] overflow-x-auto overflow-y-auto rounded bg-gray-100 p-1.5", children: typeof part.output === "string" ? jsxRuntimeExports.jsx("pre", { className: "text-[10px] text-gray-800", children: part.output }) : jsxRuntimeExports.jsx(DataInspector, { data: part.output, expandLevel: 1 }) })] });
1352
1514
  }
1353
1515
  return null;
1354
1516
  }
1355
- function getRoleStyle(role) {
1517
+ function getRoleClasses(role) {
1356
1518
  switch (role) {
1357
1519
  case "user":
1358
1520
  return {
1359
- bg: "var(--ds-blue-100)",
1360
- border: "var(--ds-blue-300)",
1361
- label: "var(--ds-blue-700)"
1521
+ bubble: "border-blue-300 bg-blue-100",
1522
+ label: "border-blue-300 text-blue-700"
1362
1523
  };
1363
1524
  case "assistant":
1364
1525
  return {
1365
- bg: "var(--ds-gray-100)",
1366
- border: "var(--ds-gray-300)",
1367
- label: "var(--ds-gray-700)"
1526
+ bubble: "border-gray-300 bg-gray-100",
1527
+ label: "border-gray-300 text-gray-700"
1368
1528
  };
1369
1529
  case "system":
1370
1530
  return {
1371
- bg: "var(--ds-amber-100)",
1372
- border: "var(--ds-amber-300)",
1373
- label: "var(--ds-amber-700)"
1531
+ bubble: "border-amber-300 bg-amber-100",
1532
+ label: "border-amber-300 text-amber-700"
1374
1533
  };
1375
1534
  case "tool":
1376
1535
  return {
1377
- bg: "var(--ds-green-50)",
1378
- border: "var(--ds-green-300)",
1379
- label: "var(--ds-green-700)"
1536
+ bubble: "border-green-300 bg-green-100",
1537
+ label: "border-green-300 text-green-700"
1380
1538
  };
1381
1539
  default:
1382
1540
  return {
1383
- bg: "var(--ds-gray-100)",
1384
- border: "var(--ds-gray-300)",
1385
- label: "var(--ds-gray-700)"
1541
+ bubble: "border-gray-300 bg-gray-100",
1542
+ label: "border-gray-300 text-gray-700"
1386
1543
  };
1387
1544
  }
1388
1545
  }
@@ -1808,9 +1965,13 @@ function cascadeSpans(runSpan, spans) {
1808
1965
  };
1809
1966
  });
1810
1967
  }
1811
- function buildTrace(run, events, now) {
1812
- const groupedEvents = groupEventsByCorrelation(events);
1813
- const latestKnownTime = computeLatestKnownTime(events, run);
1968
+ function buildTrace(run, events, now, { isCompleteHistory = false } = {}) {
1969
+ const duplicateEventIds = findDuplicateEventIds(events, {
1970
+ isCompleteHistory
1971
+ });
1972
+ const actedOnEvents = duplicateEventIds.size === 0 ? events : events.filter((event) => !duplicateEventIds.has(event.eventId));
1973
+ const groupedEvents = groupEventsByCorrelation(actedOnEvents);
1974
+ const latestKnownTime = computeLatestKnownTime(actedOnEvents, run);
1814
1975
  const { runSpan, spans } = buildSpans(run, groupedEvents, now, latestKnownTime);
1815
1976
  const sortedCascadingSpans = cascadeSpans(runSpan, spans);
1816
1977
  const traceStartMs = otelTimeToMs(runSpan.startTime);
@@ -1827,34 +1988,72 @@ function buildTrace(run, events, now) {
1827
1988
  }
1828
1989
  }
1829
1990
  ],
1830
- knownDurationMs: Math.max(0, knownDurationMs)
1991
+ knownDurationMs: Math.max(0, knownDurationMs),
1992
+ duplicateEventIds
1831
1993
  };
1832
1994
  }
1833
- const GUTTER_PX = 1;
1834
- const MIN_PX = 50;
1835
- const DEFAULT_START_PX = 340;
1836
- function paneColTemplate(startPx) {
1837
- return `${startPx}px ${GUTTER_PX}px minmax(${MIN_PX}px, 1fr)`;
1838
- }
1839
- const COL_TEMPLATE = paneColTemplate(DEFAULT_START_PX);
1840
1995
  const ROWS = [
1841
- { id: "r0", name: 62, off: 0, bar: 72 },
1842
- { id: "r1", name: 78, off: 6, bar: 48 },
1843
- { id: "r2", name: 50, off: 10, bar: 55 },
1844
- { id: "r3", name: 84, off: 18, bar: 30 },
1845
- { id: "r4", name: 45, off: 18, bar: 42 },
1846
- { id: "r5", name: 66, off: 34, bar: 38 },
1847
- { id: "r6", name: 55, off: 41, bar: 25 },
1848
- { id: "r7", name: 40, off: 50, bar: 30 }
1996
+ {
1997
+ id: "r0",
1998
+ nameClassName: "w-[62%]",
1999
+ offsetClassName: "left-0",
2000
+ barClassName: "w-[72%]",
2001
+ topClassName: "top-0"
2002
+ },
2003
+ {
2004
+ id: "r1",
2005
+ nameClassName: "w-[78%]",
2006
+ offsetClassName: "left-[6%]",
2007
+ barClassName: "w-[48%]",
2008
+ topClassName: "top-[3.5px]"
2009
+ },
2010
+ {
2011
+ id: "r2",
2012
+ nameClassName: "w-1/2",
2013
+ offsetClassName: "left-[10%]",
2014
+ barClassName: "w-[55%]",
2015
+ topClassName: "top-[7px]"
2016
+ },
2017
+ {
2018
+ id: "r3",
2019
+ nameClassName: "w-[84%]",
2020
+ offsetClassName: "left-[18%]",
2021
+ barClassName: "w-[30%]",
2022
+ topClassName: "top-[10.5px]"
2023
+ },
2024
+ {
2025
+ id: "r4",
2026
+ nameClassName: "w-[45%]",
2027
+ offsetClassName: "left-[18%]",
2028
+ barClassName: "w-[42%]",
2029
+ topClassName: "top-[14px]"
2030
+ },
2031
+ {
2032
+ id: "r5",
2033
+ nameClassName: "w-[66%]",
2034
+ offsetClassName: "left-[34%]",
2035
+ barClassName: "w-[38%]",
2036
+ topClassName: "top-[17.5px]"
2037
+ },
2038
+ {
2039
+ id: "r6",
2040
+ nameClassName: "w-[55%]",
2041
+ offsetClassName: "left-[41%]",
2042
+ barClassName: "w-1/4",
2043
+ topClassName: "top-[21px]"
2044
+ },
2045
+ {
2046
+ id: "r7",
2047
+ nameClassName: "w-2/5",
2048
+ offsetClassName: "left-1/2",
2049
+ barClassName: "w-[30%]",
2050
+ topClassName: "top-[24.5px]"
2051
+ }
1849
2052
  ];
1850
2053
  const HEADER_MARKERS = ["m0", "m1", "m2", "m3"];
1851
2054
  const HeaderDivider = () => jsxRuntimeExports.jsx("div", { className: "flex justify-center", children: jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }) });
1852
2055
  function TraceViewerSkeleton() {
1853
- return jsxRuntimeExports.jsxs("output", { "aria-busy": "true", "aria-label": "Loading trace", className: "flex flex-col w-full h-full min-h-0 bg-background-100", children: [jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Loading trace…" }), jsxRuntimeExports.jsx("div", { className: "relative h-10 min-h-10 shrink-0 border-b border-gray-alpha-400", children: jsxRuntimeExports.jsx("div", { className: "absolute inset-x-4 top-[6px]", children: ROWS.map((row, index) => jsxRuntimeExports.jsx(Skeleton, { className: "absolute h-[3px] rounded-full", style: {
1854
- left: `${row.off}%`,
1855
- width: `${row.bar}%`,
1856
- top: index * 3.5
1857
- } }, row.id)) }) }), jsxRuntimeExports.jsxs("div", { className: "shrink-0 grid", style: { gridTemplateColumns: COL_TEMPLATE }, children: [jsxRuntimeExports.jsxs("div", { className: "h-10 min-h-10 flex items-center border-b border-gray-alpha-400 pl-4 pr-2 gap-1.5", children: [jsxRuntimeExports.jsx(Skeleton, { className: "w-3.5 h-3.5 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5 w-40" })] }), jsxRuntimeExports.jsx(HeaderDivider, {}), jsxRuntimeExports.jsx("div", { className: "h-10 min-h-10 flex items-end border-b border-gray-alpha-400 px-4 pb-1 gap-2", children: jsxRuntimeExports.jsx("div", { className: "relative flex-1 flex items-end justify-between", children: HEADER_MARKERS.map((id) => jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5 w-9" }, id)) }) })] }), jsxRuntimeExports.jsxs("div", { className: "grid flex-1 min-h-0 overflow-hidden", style: { gridTemplateColumns: COL_TEMPLATE }, children: [jsxRuntimeExports.jsx("div", { className: "block overflow-visible", children: jsxRuntimeExports.jsx("ul", { className: "block divide-y divide-gray-alpha-400 border-b border-gray-alpha-400", children: ROWS.map((row) => jsxRuntimeExports.jsxs("li", { className: "h-10 flex items-center pl-4 pr-2", children: [jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [jsxRuntimeExports.jsx(Skeleton, { className: "w-4 h-4 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5", style: { width: `${row.name}%` } })] }), jsxRuntimeExports.jsx(Skeleton, { className: "ml-2 h-3.5 w-10 shrink-0" })] }, row.id)) }) }), jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }), jsxRuntimeExports.jsx("div", { className: "relative min-h-0", children: ROWS.map((row) => jsxRuntimeExports.jsx("div", { className: "relative h-10", children: jsxRuntimeExports.jsx("div", { className: "absolute inset-x-4 inset-y-0", children: jsxRuntimeExports.jsx(Skeleton, { className: "absolute top-1/2 -translate-y-1/2 h-6 rounded-[0.25rem]", style: { left: `${row.off}%`, width: `${row.bar}%` } }) }) }, row.id)) })] })] });
2056
+ return jsxRuntimeExports.jsxs("output", { "aria-busy": "true", "aria-label": "Loading trace", className: "flex flex-col w-full h-full min-h-0 bg-background-100", children: [jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Loading trace…" }), jsxRuntimeExports.jsx("div", { className: "relative h-10 min-h-10 shrink-0 border-b border-gray-alpha-400", children: jsxRuntimeExports.jsx("div", { className: "absolute inset-x-4 top-[6px]", children: ROWS.map((row) => jsxRuntimeExports.jsx(Skeleton, { className: `absolute h-[3px] rounded-full ${row.offsetClassName} ${row.barClassName} ${row.topClassName}` }, row.id)) }) }), jsxRuntimeExports.jsxs("div", { className: "grid shrink-0 grid-cols-[340px_1px_minmax(50px,1fr)]", children: [jsxRuntimeExports.jsxs("div", { className: "h-10 min-h-10 flex items-center border-b border-gray-alpha-400 pl-4 pr-2 gap-1.5", children: [jsxRuntimeExports.jsx(Skeleton, { className: "w-3.5 h-3.5 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5 w-40" })] }), jsxRuntimeExports.jsx(HeaderDivider, {}), jsxRuntimeExports.jsx("div", { className: "h-10 min-h-10 flex items-end border-b border-gray-alpha-400 px-4 pb-1 gap-2", children: jsxRuntimeExports.jsx("div", { className: "relative flex-1 flex items-end justify-between", children: HEADER_MARKERS.map((id) => jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5 w-9" }, id)) }) })] }), jsxRuntimeExports.jsxs("div", { className: "grid min-h-0 flex-1 grid-cols-[340px_1px_minmax(50px,1fr)] overflow-hidden", children: [jsxRuntimeExports.jsx("div", { className: "block overflow-visible", children: jsxRuntimeExports.jsx("ul", { className: "block divide-y divide-gray-alpha-400 border-b border-gray-alpha-400", children: ROWS.map((row) => jsxRuntimeExports.jsxs("li", { className: "h-10 flex items-center pl-4 pr-2", children: [jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [jsxRuntimeExports.jsx(Skeleton, { className: "w-4 h-4 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton, { className: `h-3.5 ${row.nameClassName}` })] }), jsxRuntimeExports.jsx(Skeleton, { className: "ml-2 h-3.5 w-10 shrink-0" })] }, row.id)) }) }), jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }), jsxRuntimeExports.jsx("div", { className: "relative min-h-0", children: ROWS.map((row) => jsxRuntimeExports.jsx("div", { className: "relative h-10", children: jsxRuntimeExports.jsx("div", { className: "absolute inset-x-4 inset-y-0", children: jsxRuntimeExports.jsx(Skeleton, { className: `absolute top-1/2 h-6 -translate-y-1/2 rounded-[0.25rem] ${row.offsetClassName} ${row.barClassName}` }) }) }, row.id)) })] })] });
1858
2057
  }
1859
2058
  function useIntersectionObserver(elementRef, { threshold = 0, rootRef, rootMargin = "0%", freezeOnceVisible = false } = {}) {
1860
2059
  const [entry, setEntry] = reactExports.useState();
@@ -2398,7 +2597,7 @@ const formatEventTimestamp = (date) => date.toLocaleString(void 0, {
2398
2597
  fractionalSecondDigits: 3,
2399
2598
  timeZoneName: "short"
2400
2599
  });
2401
- function EventItem({ event, onLoadEventData, encryptionKey, showSeparateEventOccurrenceTimestamps = false }) {
2600
+ function EventItem({ event, onLoadEventData, encryptionKey, showSeparateEventOccurrenceTimestamps = false, isDuplicate = false }) {
2402
2601
  const [loadedData, setLoadedData] = reactExports.useState(null);
2403
2602
  const [isLoading, setIsLoading] = reactExports.useState(false);
2404
2603
  const [loadError, setLoadError] = reactExports.useState(null);
@@ -2450,7 +2649,7 @@ function EventItem({ event, onLoadEventData, encryptionKey, showSeparateEventOcc
2450
2649
  return jsxRuntimeExports.jsxs(CollapsibleRoot, { variant: "card", onOpenChange: canHaveData ? (open) => {
2451
2650
  if (open)
2452
2651
  handleExpand();
2453
- } : void 0, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { className: "px-3 py-2", children: 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: displayedCreatedAtTime })] }) }), jsxRuntimeExports.jsxs(CollapsibleContent, { children: [jsxRuntimeExports.jsxs("div", { className: "flex flex-col bg-background-200 [&:has(+_*)]:border-b [&:has(+_*)]:border-gray-alpha-400", children: [showSeparateEventOccurrenceTimestamps && occurredAt && 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: "Occurred" }), jsxRuntimeExports.jsx(TimestampTooltip, { date: occurredAt, children: jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: formatEventTimestamp(occurredAt) }) })] }), 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, { className: "h-4 w-[35%]" }), jsxRuntimeExports.jsx(Skeleton, { className: "mt-2 h-4 w-[90%]" }), jsxRuntimeExports.jsx(Skeleton, { 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 }) })] })] });
2652
+ } : void 0, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { className: "px-3 py-2", children: jsxRuntimeExports.jsxs("div", { className: "flex w-full items-center justify-between gap-3", children: [jsxRuntimeExports.jsx(DuplicateEventTooltip, { isDuplicate, children: jsxRuntimeExports.jsx("span", { className: `text-label-12 font-mono ${isDuplicate ? "text-gray-700" : "text-gray-1000"}`, children: event.eventType }) }), jsxRuntimeExports.jsx("span", { className: "shrink-0 text-label-13 text-gray-900", children: displayedCreatedAtTime })] }) }), jsxRuntimeExports.jsxs(CollapsibleContent, { children: [jsxRuntimeExports.jsxs("div", { className: "flex flex-col bg-background-200 [&:has(+_*)]:border-b [&:has(+_*)]:border-gray-alpha-400", children: [showSeparateEventOccurrenceTimestamps && occurredAt && 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: "Occurred" }), jsxRuntimeExports.jsx(TimestampTooltip, { date: occurredAt, children: jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: formatEventTimestamp(occurredAt) }) })] }), 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, { className: "h-4 w-[35%]" }), jsxRuntimeExports.jsx(Skeleton, { className: "mt-2 h-4 w-[90%]" }), jsxRuntimeExports.jsx(Skeleton, { 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 }) })] })] });
2454
2653
  }
2455
2654
  function hasOnlyExpiredFields(data, eventType) {
2456
2655
  if (data === null || typeof data !== "object" || Array.isArray(data)) {
@@ -2486,13 +2685,13 @@ function EventDataBlock({ eventType, data }) {
2486
2685
  }
2487
2686
  return jsxRuntimeExports.jsx(CopyableDataBlock, { data });
2488
2687
  }
2489
- function EventsList({ events, isLoading = false, error, onLoadEventData, onStreamClick, onRunClick, encryptionKey, showSeparateEventOccurrenceTimestamps = false }) {
2688
+ function EventsList({ events, isLoading = false, error, onLoadEventData, onStreamClick, onRunClick, encryptionKey, showSeparateEventOccurrenceTimestamps = false, duplicateEventIds }) {
2490
2689
  const sortedEvents = reactExports.useMemo(() => [...events].sort((a, b) => getEffectiveEventDate(a).getTime() - getEffectiveEventDate(b).getTime()), [events]);
2491
2690
  const hasEvents = sortedEvents.length > 0 && !error;
2492
2691
  if (!hasEvents && !isLoading) {
2493
2692
  return jsxRuntimeExports.jsx(Collapsible, { label: "Events", disabled: true });
2494
2693
  }
2495
- return jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsxs(CollapsibleRoot, { defaultOpen: true, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { children: "Events" }), jsxRuntimeExports.jsx(CollapsibleContent, { className: "mb-0", 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, { className: "h-4 w-32 rounded" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3 w-16 rounded" })] }, i)) }) : jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: sortedEvents.map((event) => jsxRuntimeExports.jsx(EventItem, { event, onLoadEventData, encryptionKey, showSeparateEventOccurrenceTimestamps }, event.eventId)) }) })] }) }) });
2694
+ return jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsxs(CollapsibleRoot, { defaultOpen: true, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { children: "Events" }), jsxRuntimeExports.jsx(CollapsibleContent, { className: "mb-0", 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, { className: "h-4 w-32 rounded" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3 w-16 rounded" })] }, i)) }) : jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: sortedEvents.map((event) => jsxRuntimeExports.jsx(EventItem, { event, onLoadEventData, encryptionKey, showSeparateEventOccurrenceTimestamps, isDuplicate: duplicateEventIds == null ? void 0 : duplicateEventIds.has(event.eventId) }, event.eventId)) }) })] }) }) });
2496
2695
  }
2497
2696
  const hasField = (value, key) => key in value;
2498
2697
  const RESOURCES_WITH_FETCHED_DETAIL = /* @__PURE__ */ new Set(["run", "step", "sleep"]);
@@ -2812,7 +3011,7 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, fetchSpanDetail, on
2812
3011
  }, 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-button-14", "disabled:opacity-50 disabled:cursor-not-allowed transition-colors", resolvingHook ? "opacity-50 cursor-not-allowed" : "cursor-pointer"), style: {
2813
3012
  background: "var(--ds-gray-1000)",
2814
3013
  color: "var(--ds-background-100)"
2815
- }, children: [jsxRuntimeExports.jsx(Send, { className: "h-4 w-4" }), "Resolve Hook"] })] })] }), jsxRuntimeExports.jsx(AttributePanel, { data: displayData, moduleSpecifier, moduleSourceUrl, expiredAt: run.expiredAt, isLoading: loading, error: error ?? void 0, onStreamClick, onRunClick, onDecrypt, isDecrypting, resource }), rawEvents && jsxRuntimeExports.jsx(EventsList, { events: rawEvents, onLoadEventData, onStreamClick, onRunClick, encryptionKey, showSeparateEventOccurrenceTimestamps })] }) }), jsxRuntimeExports.jsx(ResolveHookModal, { isOpen: showResolveHookModal, onClose: () => setShowResolveHookModal(false), onSubmit: handleResolveHook, isSubmitting: resolvingHook })] });
3014
+ }, children: [jsxRuntimeExports.jsx(Send, { className: "h-4 w-4" }), "Resolve Hook"] })] })] }), jsxRuntimeExports.jsx(AttributePanel, { data: displayData, moduleSpecifier, moduleSourceUrl, expiredAt: run.expiredAt, isLoading: loading, error: error ?? void 0, onStreamClick, onRunClick, onDecrypt, isDecrypting, resource }), rawEvents && jsxRuntimeExports.jsx(EventsList, { events: rawEvents, onLoadEventData, onStreamClick, onRunClick, encryptionKey, showSeparateEventOccurrenceTimestamps, duplicateEventIds: selectedSpan == null ? void 0 : selectedSpan.duplicateEventIds })] }) }), jsxRuntimeExports.jsx(ResolveHookModal, { isOpen: showResolveHookModal, onClose: () => setShowResolveHookModal(false), onSubmit: handleResolveHook, isSubmitting: resolvingHook })] });
2816
3015
  }
2817
3016
  const PANEL_MIN_WIDTH = 280;
2818
3017
  const PANEL_HARD_MAX_WIDTH = 1300;
@@ -2990,7 +3189,8 @@ function useSelectedSpanInfo() {
2990
3189
  data: (_b = activeSpan.attributes) == null ? void 0 : _b.data,
2991
3190
  resource,
2992
3191
  spanId: activeSpan.spanId,
2993
- rawEvents
3192
+ rawEvents,
3193
+ duplicateEventIds: sidebar.duplicateEventIds
2994
3194
  };
2995
3195
  }, [activeSpan, sidebar]);
2996
3196
  }
@@ -3066,16 +3266,16 @@ function TraceDetailPanel({ containerRef, onNavigateToSpan, onClose }) {
3066
3266
  return jsxRuntimeExports.jsxs("aside", { ref: asideRef, id: DETAIL_PANEL_ID, className: "relative flex flex-col h-full max-h-full shrink-0 bg-background-100 border-l border-gray-alpha-400", style: { width: panelWidth }, children: [jsxRuntimeExports.jsx(DraggableBorder, { element: asideRef, position: "left", onWidthChange: handleResize, onReset: () => handleResize(PANEL_DEFAULT_WIDTH), "aria-label": "Resize span details panel", "aria-controls": DETAIL_PANEL_ID, "aria-valuemin": PANEL_MIN_WIDTH, "aria-valuemax": panelMaxWidth, "aria-valuenow": Math.min(Math.max(Math.round(panelWidth), PANEL_MIN_WIDTH), panelMaxWidth) }), jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 shrink-0 px-4 py-[7.5px]", 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.jsxs(Tooltip, { children: [jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: jsxRuntimeExports.jsx(IconButton, { "aria-label": "Navigate up", "aria-keyshortcuts": "K", onClick: handleSelectPrev, disabled: !prevSpanId, children: jsxRuntimeExports.jsx(ChevronUp, { className: "w-4 h-4" }) }) }), prevSpanId ? jsxRuntimeExports.jsxs(TooltipContent, { children: ["Navigate up", jsxRuntimeExports.jsx(Kbd, { children: "K" })] }) : null] }), jsxRuntimeExports.jsxs(Tooltip, { children: [jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: jsxRuntimeExports.jsx(IconButton, { "aria-label": "Navigate down", "aria-keyshortcuts": "J", onClick: handleSelectNext, disabled: !nextSpanId, children: jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4" }) }) }), nextSpanId ? jsxRuntimeExports.jsxs(TooltipContent, { children: ["Navigate down", jsxRuntimeExports.jsx(Kbd, { children: "J" })] }) : null] }), jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "w-px h-4 bg-gray-alpha-400 mx-1" }), jsxRuntimeExports.jsx(IconButton, { "aria-label": "Close span details", "aria-keyshortcuts": "Escape", onClick: onClose, children: jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) })] })] }), jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto", children: jsxRuntimeExports.jsx(ErrorBoundary, { children: jsxRuntimeExports.jsx(EntityDetailPanel, { run: sidebar.run, onStreamClick: sidebar.onStreamClick, onRunClick: sidebar.onRunClick, fetchSpanDetail: sidebar.fetchSpanDetail, onWakeUpSleep: sidebar.onWakeUpSleep, onLoadEventData: sidebar.onLoadEventData, onResolveHook: sidebar.onResolveHook, encryptionKey: sidebar.encryptionKey, onDecrypt: sidebar.onDecrypt, isDecrypting: sidebar.isDecrypting, selectedSpan, showSeparateEventOccurrenceTimestamps: sidebar.showSeparateEventOccurrenceTimestamps, getModuleSourceUrl: sidebar.getModuleSourceUrl }) }) })] });
3067
3267
  }
3068
3268
  const WorkflowIcon = () => {
3069
- return jsxRuntimeExports.jsx("svg", { "data-testid": "geist-icon", height: "16", strokeLinejoin: "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" }) });
3269
+ return jsxRuntimeExports.jsx("svg", { "aria-hidden": "true", "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", 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" }) });
3070
3270
  };
3071
3271
  const WebhookIcon = () => {
3072
- return jsxRuntimeExports.jsx("svg", { "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", style: { color: "currentColor" }, children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M5.8349 3.24994C5.14454 4.44567 5.55423 5.97464 6.74996 6.665L7.39465 7.03721L7.02726 7.68466L5.14599 11C5.21289 11.1531 5.25 11.3222 5.25 11.5C5.25 12.1904 4.69036 12.75 4 12.75C3.30964 12.75 2.75 12.1904 2.75 11.5C2.75 10.8634 3.22584 10.338 3.84123 10.26L5.38944 7.5316C3.95909 6.30274 3.55857 4.19264 4.53586 2.49994C5.64043 0.586765 8.08679 -0.0687357 9.99996 1.03583C11.836 2.09584 12.5137 4.39156 11.5892 6.26591L10.4949 4.33754C10.4418 3.53274 10.0009 2.76843 9.24996 2.33487C8.05423 1.64452 6.52525 2.0542 5.8349 3.24994ZM9.146 4.99996C9.21289 4.84686 9.25 4.67776 9.25 4.5C9.25 3.80964 8.69036 3.25 8 3.25C7.30964 3.25 6.75 3.80964 6.75 4.5C6.75 5.13659 7.22586 5.66203 7.84127 5.74002L9.72266 9.05556L10.0956 9.71274L10.75 9.33493C11.9457 8.64458 13.4747 9.05427 14.165 10.25C14.8554 11.4457 14.4457 12.9747 13.25 13.6651C12.5047 14.0953 11.63 14.0983 10.9096 13.75H8.69252C9.85895 15.4685 12.1727 16.0191 14 14.9641C15.9131 13.8595 16.5686 11.4132 15.4641 9.5C14.4886 7.81038 12.4665 7.10169 10.6895 7.71998L9.146 4.99996ZM13.25 11.5C13.25 12.1904 12.6904 12.75 12 12.75C11.591 12.75 11.228 12.5536 10.9999 12.25H7.9298C7.57875 14.1006 5.95279 15.5 4 15.5C1.79086 15.5 0 13.7091 0 11.5C0 9.40018 1.61801 7.67826 3.67529 7.51299L2.58098 9.44147C1.92792 9.89251 1.5 10.6463 1.5 11.5C1.5 12.8807 2.61929 14 4 14C5.38071 14 6.5 12.8807 6.5 11.5V10.75H7.25H10.9999C11.228 10.4464 11.591 10.25 12 10.25C12.6904 10.25 13.25 10.8096 13.25 11.5Z", fill: "currentColor" }) });
3272
+ return jsxRuntimeExports.jsx("svg", { "aria-hidden": "true", "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M5.8349 3.24994C5.14454 4.44567 5.55423 5.97464 6.74996 6.665L7.39465 7.03721L7.02726 7.68466L5.14599 11C5.21289 11.1531 5.25 11.3222 5.25 11.5C5.25 12.1904 4.69036 12.75 4 12.75C3.30964 12.75 2.75 12.1904 2.75 11.5C2.75 10.8634 3.22584 10.338 3.84123 10.26L5.38944 7.5316C3.95909 6.30274 3.55857 4.19264 4.53586 2.49994C5.64043 0.586765 8.08679 -0.0687357 9.99996 1.03583C11.836 2.09584 12.5137 4.39156 11.5892 6.26591L10.4949 4.33754C10.4418 3.53274 10.0009 2.76843 9.24996 2.33487C8.05423 1.64452 6.52525 2.0542 5.8349 3.24994ZM9.146 4.99996C9.21289 4.84686 9.25 4.67776 9.25 4.5C9.25 3.80964 8.69036 3.25 8 3.25C7.30964 3.25 6.75 3.80964 6.75 4.5C6.75 5.13659 7.22586 5.66203 7.84127 5.74002L9.72266 9.05556L10.0956 9.71274L10.75 9.33493C11.9457 8.64458 13.4747 9.05427 14.165 10.25C14.8554 11.4457 14.4457 12.9747 13.25 13.6651C12.5047 14.0953 11.63 14.0983 10.9096 13.75H8.69252C9.85895 15.4685 12.1727 16.0191 14 14.9641C15.9131 13.8595 16.5686 11.4132 15.4641 9.5C14.4886 7.81038 12.4665 7.10169 10.6895 7.71998L9.146 4.99996ZM13.25 11.5C13.25 12.1904 12.6904 12.75 12 12.75C11.591 12.75 11.228 12.5536 10.9999 12.25H7.9298C7.57875 14.1006 5.95279 15.5 4 15.5C1.79086 15.5 0 13.7091 0 11.5C0 9.40018 1.61801 7.67826 3.67529 7.51299L2.58098 9.44147C1.92792 9.89251 1.5 10.6463 1.5 11.5C1.5 12.8807 2.61929 14 4 14C5.38071 14 6.5 12.8807 6.5 11.5V10.75H7.25H10.9999C11.228 10.4464 11.591 10.25 12 10.25C12.6904 10.25 13.25 10.8096 13.25 11.5Z", fill: "currentColor" }) });
3073
3273
  };
3074
3274
  const SleepIcon = () => {
3075
- return jsxRuntimeExports.jsx("svg", { "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", style: { color: "currentColor" }, children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M7.25 1.25V2.03971C5.87928 2.18571 4.62678 2.72736 3.6089 3.54824L3.03033 2.96967L2.5 2.43934L1.43934 3.5L1.96967 4.03033L2.54824 4.6089C1.57979 5.80976 1 7.33717 1 9C1 12.866 4.13401 16 8 16C11.866 16 15 12.866 15 9C15 7.33717 14.4202 5.80976 13.4518 4.6089L14.0303 4.03033L14.5607 3.5L13.5 2.43934L12.9697 2.96967L12.3911 3.54824C11.3732 2.72736 10.1207 2.18571 8.75 2.03971V1.25H9.25H10V-0.25H9.25H8.75H7.25H6.75H6V1.25H6.75H7.25ZM2.5 9C2.5 5.96243 4.96243 3.5 8 3.5C11.0376 3.5 13.5 5.96243 13.5 9C13.5 12.0376 11.0376 14.5 8 14.5C4.96243 14.5 2.5 12.0376 2.5 9ZM8.75 6.75V6H7.25V6.75V9V9.75H8.75V9V6.75Z", fill: "currentColor" }) });
3275
+ return jsxRuntimeExports.jsx("svg", { "aria-hidden": "true", "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M7.25 1.25V2.03971C5.87928 2.18571 4.62678 2.72736 3.6089 3.54824L3.03033 2.96967L2.5 2.43934L1.43934 3.5L1.96967 4.03033L2.54824 4.6089C1.57979 5.80976 1 7.33717 1 9C1 12.866 4.13401 16 8 16C11.866 16 15 12.866 15 9C15 7.33717 14.4202 5.80976 13.4518 4.6089L14.0303 4.03033L14.5607 3.5L13.5 2.43934L12.9697 2.96967L12.3911 3.54824C11.3732 2.72736 10.1207 2.18571 8.75 2.03971V1.25H9.25H10V-0.25H9.25H8.75H7.25H6.75H6V1.25H6.75H7.25ZM2.5 9C2.5 5.96243 4.96243 3.5 8 3.5C11.0376 3.5 13.5 5.96243 13.5 9C13.5 12.0376 11.0376 14.5 8 14.5C4.96243 14.5 2.5 12.0376 2.5 9ZM8.75 6.75V6H7.25V6.75V9V9.75H8.75V9V6.75Z", fill: "currentColor" }) });
3076
3276
  };
3077
3277
  const StepForwardIcon = () => {
3078
- return jsxRuntimeExports.jsx("svg", { "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", style: { color: "currentColor" }, children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.21969 12.5303L4.75002 13.0607L5.81068 12L5.28035 11.4697L1.81068 7.99999L5.28035 4.53032L5.81068 3.99999L4.75002 2.93933L4.21969 3.46966L0.39647 7.29289C0.00594562 7.68341 0.00594562 8.31658 0.39647 8.7071L4.21969 12.5303ZM11.7804 12.5303L11.25 13.0607L10.1894 12L10.7197 11.4697L14.1894 7.99999L10.7197 4.53032L10.1894 3.99999L11.25 2.93933L11.7804 3.46966L15.6036 7.29289C15.9941 7.68341 15.9941 8.31658 15.6036 8.7071L11.7804 12.5303Z", fill: "currentColor" }) });
3278
+ return jsxRuntimeExports.jsx("svg", { "aria-hidden": "true", "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", viewBox: "0 0 16 16", width: "16", children: jsxRuntimeExports.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.21969 12.5303L4.75002 13.0607L5.81068 12L5.28035 11.4697L1.81068 7.99999L5.28035 4.53032L5.81068 3.99999L4.75002 2.93933L4.21969 3.46966L0.39647 7.29289C0.00594562 7.68341 0.00594562 8.31658 0.39647 8.7071L4.21969 12.5303ZM11.7804 12.5303L11.25 13.0607L10.1894 12L10.7197 11.4697L14.1894 7.99999L10.7197 4.53032L10.1894 3.99999L11.25 2.93933L11.7804 3.46966L15.6036 7.29289C15.9941 7.68341 15.9941 8.31658 15.6036 8.7071L11.7804 12.5303Z", fill: "currentColor" }) });
3079
3279
  };
3080
3280
  const eventStyles = {
3081
3281
  run: { icon: WorkflowIcon, className: "text-blue-900", label: "Workflow" },
@@ -3111,6 +3311,12 @@ const EventList = ({ spans, activeSpanId, searchResult, onSelectSpan }) => {
3111
3311
  paddingBottom: (spans.length - end) * ROW_HEIGHT_PX
3112
3312
  }, children: spans.slice(start, end).map((span) => jsxRuntimeExports.jsx(EventRow, { span, isSelected: span.spanId === activeSpanId, isDimmed: isSpanDimmedBySearch(span.spanId, searchResult), onSelectSpan }, span.spanId)) });
3113
3313
  };
3314
+ const GUTTER_PX = 1;
3315
+ const MIN_PX = 50;
3316
+ const DEFAULT_START_PX = 340;
3317
+ function paneColTemplate(startPx) {
3318
+ return `${startPx}px ${GUTTER_PX}px minmax(${MIN_PX}px, 1fr)`;
3319
+ }
3114
3320
  const SPLIT_PANE_START_ID = "trace-split-start";
3115
3321
  function SplitPane({ children, className, startHeader, endHeader, scrollContainerRef }) {
3116
3322
  const parts = reactExports.Children.toArray(children);
@@ -3494,12 +3700,15 @@ const TraceViewer = ({ run, events, sidebarData, onLoadMore, hasMore, isLoadingM
3494
3700
  if (!(run == null ? void 0 : run.runId)) {
3495
3701
  return void 0;
3496
3702
  }
3497
- return buildTrace(run, events, /* @__PURE__ */ new Date());
3498
- }, [run, events]);
3703
+ return buildTrace(run, events, /* @__PURE__ */ new Date(), {
3704
+ isCompleteHistory: !hasMore
3705
+ });
3706
+ }, [run, events, hasMore]);
3707
+ const sidebarValue = reactExports.useMemo(() => ({ ...sidebarData, duplicateEventIds: trace == null ? void 0 : trace.duplicateEventIds }), [sidebarData, trace]);
3499
3708
  if (!trace || loading && events.length === 0) {
3500
3709
  return jsxRuntimeExports.jsx(TraceViewerSkeleton, {});
3501
3710
  }
3502
- return jsxRuntimeExports.jsx(SidebarDataProvider, { value: sidebarData, children: jsxRuntimeExports.jsx("div", { className: "relative w-full h-full flex", children: jsxRuntimeExports.jsx(TraceViewer$1, { trace, onLoadMore, hasMore, isLoadingMore }) }) });
3711
+ return jsxRuntimeExports.jsx(SidebarDataProvider, { value: sidebarValue, children: jsxRuntimeExports.jsx("div", { className: "relative w-full h-full flex", children: jsxRuntimeExports.jsx(TraceViewer$1, { trace, onLoadMore, hasMore, isLoadingMore }) }) });
3503
3712
  };
3504
3713
  async function fetchResourceWithCorrelationId(env, resource, resourceId, options = {}) {
3505
3714
  const resolveData = options.resolveData ?? "all";