@workflow/web-shared 5.0.0-beta.1 → 5.0.0-beta.11

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 (298) hide show
  1. package/README.md +1 -1
  2. package/dist/components/error-boundary.js +1 -1
  3. package/dist/components/event-list-view.d.ts +18 -1
  4. package/dist/components/event-list-view.d.ts.map +1 -1
  5. package/dist/components/event-list-view.js +219 -125
  6. package/dist/components/hook-actions.js +1 -1
  7. package/dist/components/index.d.ts +5 -1
  8. package/dist/components/index.d.ts.map +1 -1
  9. package/dist/components/index.js +6 -2
  10. package/dist/components/new-trace-viewer/components/copy-button.d.ts +9 -0
  11. package/dist/components/new-trace-viewer/components/copy-button.d.ts.map +1 -0
  12. package/dist/components/new-trace-viewer/components/copy-button.js +27 -0
  13. package/dist/components/new-trace-viewer/components/event-list.d.ts +10 -0
  14. package/dist/components/new-trace-viewer/components/event-list.d.ts.map +1 -0
  15. package/dist/components/new-trace-viewer/components/event-list.js +44 -0
  16. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.d.ts +18 -0
  17. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.d.ts.map +1 -0
  18. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js +54 -0
  19. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.d.ts +20 -0
  20. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.d.ts.map +1 -0
  21. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js +81 -0
  22. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts +25 -0
  23. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts.map +1 -0
  24. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js +101 -0
  25. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.d.ts +20 -0
  26. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.d.ts.map +1 -0
  27. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js +114 -0
  28. package/dist/components/new-trace-viewer/components/split-pane.d.ts +15 -0
  29. package/dist/components/new-trace-viewer/components/split-pane.d.ts.map +1 -0
  30. package/dist/components/new-trace-viewer/components/split-pane.js +105 -0
  31. package/dist/components/new-trace-viewer/components/timeline.d.ts +34 -0
  32. package/dist/components/new-trace-viewer/components/timeline.d.ts.map +1 -0
  33. package/dist/components/new-trace-viewer/components/timeline.js +221 -0
  34. package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.d.ts +2 -0
  35. package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.d.ts.map +1 -0
  36. package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.js +19 -0
  37. package/dist/components/new-trace-viewer/components/use-row-window.d.ts +20 -0
  38. package/dist/components/new-trace-viewer/components/use-row-window.d.ts.map +1 -0
  39. package/dist/components/new-trace-viewer/components/use-row-window.js +69 -0
  40. package/dist/components/new-trace-viewer/context.d.ts +15 -0
  41. package/dist/components/new-trace-viewer/context.d.ts.map +1 -0
  42. package/dist/components/new-trace-viewer/context.js +47 -0
  43. package/dist/components/new-trace-viewer/detail-panel.d.ts +10 -0
  44. package/dist/components/new-trace-viewer/detail-panel.d.ts.map +1 -0
  45. package/dist/components/new-trace-viewer/detail-panel.js +13 -0
  46. package/dist/components/new-trace-viewer/icons.d.ts +6 -0
  47. package/dist/components/new-trace-viewer/icons.d.ts.map +1 -0
  48. package/dist/components/new-trace-viewer/icons.js +15 -0
  49. package/dist/components/new-trace-viewer/search.d.ts +19 -0
  50. package/dist/components/new-trace-viewer/search.d.ts.map +1 -0
  51. package/dist/components/new-trace-viewer/search.js +134 -0
  52. package/dist/components/new-trace-viewer/trace-viewer.d.ts +11 -0
  53. package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +1 -0
  54. package/dist/components/new-trace-viewer/trace-viewer.js +400 -0
  55. package/dist/components/new-trace-viewer/types.d.ts +1 -0
  56. package/dist/components/new-trace-viewer/types.d.ts.map +1 -0
  57. package/dist/components/new-trace-viewer/types.js +2 -0
  58. package/dist/components/new-trace-viewer/util/constants.d.ts +1 -0
  59. package/dist/components/new-trace-viewer/util/constants.d.ts.map +1 -0
  60. package/dist/components/new-trace-viewer/util/constants.js +2 -0
  61. package/dist/components/new-trace-viewer/utils.d.ts +46 -0
  62. package/dist/components/new-trace-viewer/utils.d.ts.map +1 -0
  63. package/dist/components/new-trace-viewer/utils.js +330 -0
  64. package/dist/components/run-trace-view.d.ts +2 -1
  65. package/dist/components/run-trace-view.d.ts.map +1 -1
  66. package/dist/components/run-trace-view.js +3 -3
  67. package/dist/components/sidebar/attribute-panel.d.ts +7 -1
  68. package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
  69. package/dist/components/sidebar/attribute-panel.js +131 -70
  70. package/dist/components/sidebar/conversation-view.js +1 -1
  71. package/dist/components/sidebar/copyable-data-block.d.ts +1 -0
  72. package/dist/components/sidebar/copyable-data-block.d.ts.map +1 -1
  73. package/dist/components/sidebar/copyable-data-block.js +16 -15
  74. package/dist/components/sidebar/detail-card.d.ts +5 -6
  75. package/dist/components/sidebar/detail-card.d.ts.map +1 -1
  76. package/dist/components/sidebar/detail-card.js +32 -16
  77. package/dist/components/sidebar/entity-detail-panel.d.ts +3 -1
  78. package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -1
  79. package/dist/components/sidebar/entity-detail-panel.js +20 -37
  80. package/dist/components/sidebar/events-list.d.ts.map +1 -1
  81. package/dist/components/sidebar/events-list.js +21 -15
  82. package/dist/components/sidebar/resolve-hook-modal.js +1 -1
  83. package/dist/components/sidebar/sidebar-data-context.d.ts +29 -0
  84. package/dist/components/sidebar/sidebar-data-context.d.ts.map +1 -0
  85. package/dist/components/sidebar/sidebar-data-context.js +19 -0
  86. package/dist/components/stream-viewer.d.ts +1 -1
  87. package/dist/components/stream-viewer.d.ts.map +1 -1
  88. package/dist/components/stream-viewer.js +3 -27
  89. package/dist/components/trace-viewer/components/map.js +1 -1
  90. package/dist/components/trace-viewer/components/markers.js +1 -1
  91. package/dist/components/trace-viewer/components/node.js +1 -1
  92. package/dist/components/trace-viewer/components/search-input.js +1 -1
  93. package/dist/components/trace-viewer/components/search.js +1 -1
  94. package/dist/components/trace-viewer/components/span-content.js +1 -1
  95. package/dist/components/trace-viewer/components/span-detail-panel.js +1 -1
  96. package/dist/components/trace-viewer/components/span-segments.js +1 -1
  97. package/dist/components/trace-viewer/components/span-strategies.js +1 -1
  98. package/dist/components/trace-viewer/components/ui.js +1 -1
  99. package/dist/components/trace-viewer/components/zoom-button.js +1 -1
  100. package/dist/components/trace-viewer/components/zoom-icons.js +1 -1
  101. package/dist/components/trace-viewer/context.js +1 -1
  102. package/dist/components/trace-viewer/index.js +1 -1
  103. package/dist/components/trace-viewer/trace-viewer.js +1 -1
  104. package/dist/components/trace-viewer/types.js +1 -1
  105. package/dist/components/trace-viewer/util/constants.js +1 -1
  106. package/dist/components/trace-viewer/util/scrollbar-width.js +1 -1
  107. package/dist/components/trace-viewer/util/timing.d.ts +1 -1
  108. package/dist/components/trace-viewer/util/timing.d.ts.map +1 -1
  109. package/dist/components/trace-viewer/util/timing.js +6 -9
  110. package/dist/components/trace-viewer/util/tree.js +1 -1
  111. package/dist/components/trace-viewer/util/use-immediate-style.js +1 -1
  112. package/dist/components/trace-viewer/util/use-streaming-spans.js +1 -1
  113. package/dist/components/trace-viewer/util/use-trackpad-zoom.js +1 -1
  114. package/dist/components/trace-viewer/worker.js +1 -1
  115. package/dist/components/trace-viewer-new.d.ts +14 -0
  116. package/dist/components/trace-viewer-new.d.ts.map +1 -0
  117. package/dist/components/trace-viewer-new.js +22 -0
  118. package/dist/components/ui/alert.js +1 -1
  119. package/dist/components/ui/button.d.ts +10 -0
  120. package/dist/components/ui/button.d.ts.map +1 -0
  121. package/dist/components/ui/button.js +46 -0
  122. package/dist/components/ui/card.js +1 -1
  123. package/dist/components/ui/data-inspector.d.ts +39 -1
  124. package/dist/components/ui/data-inspector.d.ts.map +1 -1
  125. package/dist/components/ui/data-inspector.js +207 -22
  126. package/dist/components/ui/decrypt-button.js +1 -1
  127. package/dist/components/ui/error-card.js +1 -1
  128. package/dist/components/ui/error-stack-block.d.ts.map +1 -1
  129. package/dist/components/ui/error-stack-block.js +27 -19
  130. package/dist/components/ui/icon-button.d.ts +19 -0
  131. package/dist/components/ui/icon-button.d.ts.map +1 -0
  132. package/dist/components/ui/icon-button.js +29 -0
  133. package/dist/components/ui/inspector-theme.d.ts +9 -10
  134. package/dist/components/ui/inspector-theme.d.ts.map +1 -1
  135. package/dist/components/ui/inspector-theme.js +39 -72
  136. package/dist/components/ui/kbd.d.ts +6 -0
  137. package/dist/components/ui/kbd.d.ts.map +1 -0
  138. package/dist/components/ui/kbd.js +6 -0
  139. package/dist/components/ui/load-more-button.js +1 -1
  140. package/dist/components/ui/menu-dropdown.js +1 -1
  141. package/dist/components/ui/skeleton.js +1 -1
  142. package/dist/components/ui/spinner.js +1 -1
  143. package/dist/components/ui/timestamp-tooltip.js +1 -1
  144. package/dist/components/ui/tooltip.d.ts +10 -0
  145. package/dist/components/ui/tooltip.d.ts.map +1 -0
  146. package/dist/components/ui/tooltip.js +12 -0
  147. package/dist/components/workflow-trace-view.d.ts +3 -1
  148. package/dist/components/workflow-trace-view.d.ts.map +1 -1
  149. package/dist/components/workflow-trace-view.js +10 -5
  150. package/dist/components/workflow-traces/event-colors.js +1 -1
  151. package/dist/components/workflow-traces/trace-colors.js +1 -1
  152. package/dist/components/workflow-traces/trace-span-construction.d.ts +2 -2
  153. package/dist/components/workflow-traces/trace-span-construction.d.ts.map +1 -1
  154. package/dist/components/workflow-traces/trace-span-construction.js +19 -6
  155. package/dist/components/workflow-traces/trace-time-utils.js +1 -1
  156. package/dist/hooks/use-dark-mode.js +1 -1
  157. package/dist/hooks/use-intersection-observer.d.ts +17 -0
  158. package/dist/hooks/use-intersection-observer.d.ts.map +1 -0
  159. package/dist/hooks/use-intersection-observer.js +29 -0
  160. package/dist/hooks/use-load-more-on-scroll.d.ts +21 -0
  161. package/dist/hooks/use-load-more-on-scroll.d.ts.map +1 -0
  162. package/dist/hooks/use-load-more-on-scroll.js +28 -0
  163. package/dist/hooks/use-reduced-motion.d.ts +10 -0
  164. package/dist/hooks/use-reduced-motion.d.ts.map +1 -0
  165. package/dist/hooks/use-reduced-motion.js +29 -0
  166. package/dist/index.d.ts +3 -1
  167. package/dist/index.d.ts.map +1 -1
  168. package/dist/index.js +3 -2
  169. package/dist/lib/event-analysis.js +1 -1
  170. package/dist/lib/event-materialization.js +1 -1
  171. package/dist/lib/exact-event-search-id.d.ts +25 -0
  172. package/dist/lib/exact-event-search-id.d.ts.map +1 -0
  173. package/dist/lib/exact-event-search-id.js +39 -0
  174. package/dist/lib/hydration.d.ts +14 -1
  175. package/dist/lib/hydration.d.ts.map +1 -1
  176. package/dist/lib/hydration.js +157 -4
  177. package/dist/lib/stream-display.d.ts +18 -0
  178. package/dist/lib/stream-display.d.ts.map +1 -0
  179. package/dist/lib/stream-display.js +30 -0
  180. package/dist/lib/toast.js +1 -1
  181. package/dist/lib/trace-builder.d.ts.map +1 -1
  182. package/dist/lib/trace-builder.js +3 -2
  183. package/dist/lib/utils.d.ts +9 -9
  184. package/dist/lib/utils.d.ts.map +1 -1
  185. package/dist/lib/utils.js +27 -32
  186. package/dist/styles.css +475 -1
  187. package/package.json +6 -4
  188. package/src/components/event-list-view.tsx +421 -262
  189. package/src/components/index.ts +13 -1
  190. package/src/components/new-trace-viewer/components/copy-button.tsx +68 -0
  191. package/src/components/new-trace-viewer/components/event-list.tsx +135 -0
  192. package/src/components/new-trace-viewer/components/middle-truncate/copy-selection.ts +114 -0
  193. package/src/components/new-trace-viewer/components/middle-truncate/middle-truncate.tsx +157 -0
  194. package/src/components/new-trace-viewer/components/middle-truncate/truncate.ts +132 -0
  195. package/src/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.ts +167 -0
  196. package/src/components/new-trace-viewer/components/split-pane.tsx +198 -0
  197. package/src/components/new-trace-viewer/components/timeline.tsx +560 -0
  198. package/src/components/new-trace-viewer/components/trace-viewer-skeleton.tsx +94 -0
  199. package/src/components/new-trace-viewer/components/use-row-window.ts +93 -0
  200. package/src/components/new-trace-viewer/context.tsx +90 -0
  201. package/src/components/new-trace-viewer/detail-panel.tsx +55 -0
  202. package/src/components/new-trace-viewer/icons.tsx +79 -0
  203. package/src/components/new-trace-viewer/search.ts +178 -0
  204. package/src/components/new-trace-viewer/trace-viewer.tsx +762 -0
  205. package/src/components/new-trace-viewer/types.ts +0 -0
  206. package/src/components/new-trace-viewer/util/constants.ts +0 -0
  207. package/src/components/new-trace-viewer/utils.ts +482 -0
  208. package/src/components/run-trace-view.tsx +3 -0
  209. package/src/components/sidebar/attribute-panel.tsx +240 -196
  210. package/src/components/sidebar/copyable-data-block.tsx +49 -27
  211. package/src/components/sidebar/detail-card.tsx +119 -59
  212. package/src/components/sidebar/entity-detail-panel.tsx +92 -148
  213. package/src/components/sidebar/events-list.tsx +51 -76
  214. package/src/components/sidebar/sidebar-data-context.tsx +62 -0
  215. package/src/components/stream-viewer.tsx +18 -40
  216. package/src/components/trace-viewer/util/timing.ts +5 -9
  217. package/src/components/trace-viewer-new.tsx +57 -0
  218. package/src/components/ui/button.tsx +68 -0
  219. package/src/components/ui/data-inspector.tsx +427 -31
  220. package/src/components/ui/error-stack-block.tsx +39 -30
  221. package/src/components/ui/icon-button.tsx +53 -0
  222. package/src/components/ui/inspector-theme.ts +39 -81
  223. package/src/components/ui/kbd.tsx +21 -0
  224. package/src/components/ui/tooltip.tsx +47 -0
  225. package/src/components/workflow-trace-view.tsx +12 -2
  226. package/src/components/workflow-traces/trace-span-construction.ts +24 -6
  227. package/src/hooks/use-intersection-observer.ts +57 -0
  228. package/src/hooks/use-load-more-on-scroll.ts +49 -0
  229. package/src/hooks/use-reduced-motion.ts +34 -0
  230. package/src/index.ts +9 -0
  231. package/src/lib/exact-event-search-id.ts +67 -0
  232. package/src/lib/hydration.ts +169 -1
  233. package/src/lib/stream-display.ts +48 -0
  234. package/src/lib/trace-builder.ts +2 -1
  235. package/src/lib/utils.ts +27 -32
  236. package/src/styles.css +475 -1
  237. package/dist/components/error-boundary.js.map +0 -1
  238. package/dist/components/event-list-view.js.map +0 -1
  239. package/dist/components/hook-actions.js.map +0 -1
  240. package/dist/components/index.js.map +0 -1
  241. package/dist/components/run-trace-view.js.map +0 -1
  242. package/dist/components/sidebar/attribute-panel.js.map +0 -1
  243. package/dist/components/sidebar/conversation-view.js.map +0 -1
  244. package/dist/components/sidebar/copyable-data-block.js.map +0 -1
  245. package/dist/components/sidebar/detail-card.js.map +0 -1
  246. package/dist/components/sidebar/entity-detail-panel.js.map +0 -1
  247. package/dist/components/sidebar/events-list.js.map +0 -1
  248. package/dist/components/sidebar/resolve-hook-modal.js.map +0 -1
  249. package/dist/components/stream-viewer.js.map +0 -1
  250. package/dist/components/trace-viewer/components/map.js.map +0 -1
  251. package/dist/components/trace-viewer/components/markers.js.map +0 -1
  252. package/dist/components/trace-viewer/components/node.js.map +0 -1
  253. package/dist/components/trace-viewer/components/search-input.js.map +0 -1
  254. package/dist/components/trace-viewer/components/search.js.map +0 -1
  255. package/dist/components/trace-viewer/components/span-content.js.map +0 -1
  256. package/dist/components/trace-viewer/components/span-detail-panel.js.map +0 -1
  257. package/dist/components/trace-viewer/components/span-segments.js.map +0 -1
  258. package/dist/components/trace-viewer/components/span-strategies.js.map +0 -1
  259. package/dist/components/trace-viewer/components/ui.js.map +0 -1
  260. package/dist/components/trace-viewer/components/zoom-button.js.map +0 -1
  261. package/dist/components/trace-viewer/components/zoom-icons.js.map +0 -1
  262. package/dist/components/trace-viewer/context.js.map +0 -1
  263. package/dist/components/trace-viewer/index.js.map +0 -1
  264. package/dist/components/trace-viewer/trace-viewer.js.map +0 -1
  265. package/dist/components/trace-viewer/types.js.map +0 -1
  266. package/dist/components/trace-viewer/util/constants.js.map +0 -1
  267. package/dist/components/trace-viewer/util/scrollbar-width.js.map +0 -1
  268. package/dist/components/trace-viewer/util/timing.js.map +0 -1
  269. package/dist/components/trace-viewer/util/tree.js.map +0 -1
  270. package/dist/components/trace-viewer/util/use-immediate-style.js.map +0 -1
  271. package/dist/components/trace-viewer/util/use-streaming-spans.js.map +0 -1
  272. package/dist/components/trace-viewer/util/use-trackpad-zoom.js.map +0 -1
  273. package/dist/components/trace-viewer/worker.js.map +0 -1
  274. package/dist/components/ui/alert.js.map +0 -1
  275. package/dist/components/ui/card.js.map +0 -1
  276. package/dist/components/ui/data-inspector.js.map +0 -1
  277. package/dist/components/ui/decrypt-button.js.map +0 -1
  278. package/dist/components/ui/error-card.js.map +0 -1
  279. package/dist/components/ui/error-stack-block.js.map +0 -1
  280. package/dist/components/ui/inspector-theme.js.map +0 -1
  281. package/dist/components/ui/load-more-button.js.map +0 -1
  282. package/dist/components/ui/menu-dropdown.js.map +0 -1
  283. package/dist/components/ui/skeleton.js.map +0 -1
  284. package/dist/components/ui/spinner.js.map +0 -1
  285. package/dist/components/ui/timestamp-tooltip.js.map +0 -1
  286. package/dist/components/workflow-trace-view.js.map +0 -1
  287. package/dist/components/workflow-traces/event-colors.js.map +0 -1
  288. package/dist/components/workflow-traces/trace-colors.js.map +0 -1
  289. package/dist/components/workflow-traces/trace-span-construction.js.map +0 -1
  290. package/dist/components/workflow-traces/trace-time-utils.js.map +0 -1
  291. package/dist/hooks/use-dark-mode.js.map +0 -1
  292. package/dist/index.js.map +0 -1
  293. package/dist/lib/event-analysis.js.map +0 -1
  294. package/dist/lib/event-materialization.js.map +0 -1
  295. package/dist/lib/hydration.js.map +0 -1
  296. package/dist/lib/toast.js.map +0 -1
  297. package/dist/lib/trace-builder.js.map +0 -1
  298. package/dist/lib/utils.js.map +0 -1
@@ -1,16 +1,15 @@
1
1
  'use client';
2
2
 
3
3
  import { EVENT_DATA_REF_FIELDS, type Event } from '@workflow/world';
4
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
5
- import { isExpiredMarker } from '../../lib/hydration';
4
+ import { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
5
+ import { hasEncryptedFields, isExpiredMarker } from '../../lib/hydration';
6
6
  import { ErrorCard } from '../ui/error-card';
7
7
  import {
8
8
  ErrorStackBlock,
9
9
  isStructuredErrorWithStack,
10
10
  } from '../ui/error-stack-block';
11
11
  import { Skeleton } from '../ui/skeleton';
12
- import { localMillisecondTime } from './attribute-panel';
13
- import { CopyableDataBlock } from './copyable-data-block';
12
+ import { CopyableDataBlock, EncryptedDataBlock } from './copyable-data-block';
14
13
  import { DetailCard } from './detail-card';
15
14
 
16
15
  /**
@@ -94,7 +93,7 @@ function EventItem({
94
93
 
95
94
  // When the encryption key changes and this event was previously expanded,
96
95
  // re-load the data so it gets decrypted
97
- useEffect(() => {
96
+ useLayoutEffect(() => {
98
97
  if (!encryptionKey || !wasExpandedRef.current) return;
99
98
  loadedDataRef.current = null;
100
99
  setLoadedData(null);
@@ -102,25 +101,27 @@ function EventItem({
102
101
  }, [encryptionKey, loadEventData]);
103
102
 
104
103
  const createdAt = new Date(event.createdAt);
104
+ const createdAtTime = createdAt.toLocaleTimeString(undefined, {
105
+ hour: 'numeric',
106
+ minute: 'numeric',
107
+ second: 'numeric',
108
+ });
105
109
 
106
110
  const displayPayload = isLoading ? loadedData : mergedDisplay;
107
111
 
108
112
  return (
109
113
  <DetailCard
110
- summaryClassName="text-base py-2"
114
+ variant="card"
115
+ summaryClassName="px-3 py-2"
111
116
  summary={
112
- <>
113
- <span
114
- className="font-medium"
115
- style={{ color: 'var(--ds-gray-1000)' }}
116
- >
117
+ <div className="flex w-full items-center justify-between gap-3">
118
+ <span className="text-gray-1000 text-label-12 font-mono">
117
119
  {event.eventType}
118
- </span>{' '}
119
- -{' '}
120
- <span style={{ color: 'var(--ds-gray-700)' }}>
121
- {localMillisecondTime(createdAt.getTime())}
122
120
  </span>
123
- </>
121
+ <span className="shrink-0 text-label-13 text-gray-900">
122
+ {createdAtTime}
123
+ </span>
124
+ </div>
124
125
  }
125
126
  onToggle={
126
127
  canHaveData
@@ -131,44 +132,17 @@ function EventItem({
131
132
  }
132
133
  >
133
134
  {/* Event attributes */}
134
- <div
135
- className="flex flex-col divide-y rounded-md border overflow-hidden"
136
- style={{
137
- borderColor: 'var(--ds-gray-300)',
138
- backgroundColor: 'var(--ds-gray-100)',
139
- }}
140
- >
141
- <div
142
- className="flex min-h-[32px] items-center justify-between gap-4 px-2.5 py-1.5"
143
- style={{ borderColor: 'var(--ds-gray-300)' }}
144
- >
145
- <span className="text-[14px]" style={{ color: 'var(--ds-gray-700)' }}>
146
- eventId
147
- </span>
148
- <span
149
- className="max-w-[70%] truncate text-right text-[13px] font-mono"
150
- style={{ color: 'var(--ds-gray-1000)' }}
151
- title={event.eventId}
152
- >
135
+ <div className="flex flex-col bg-background-200 [&:has(+_*)]:border-b [&:has(+_*)]:border-gray-alpha-400">
136
+ <div className="flex items-center justify-between gap-2 py-2 px-3">
137
+ <span className="text-label-12 text-gray-900">Event ID</span>
138
+ <span className="max-w-[70%] truncate text-right text-label-12 font-mono">
153
139
  {event.eventId}
154
140
  </span>
155
141
  </div>
156
142
  {event.correlationId && (
157
- <div
158
- className="flex min-h-[32px] items-center justify-between gap-4 px-2.5 py-1.5"
159
- style={{ borderColor: 'var(--ds-gray-300)' }}
160
- >
161
- <span
162
- className="text-[14px]"
163
- style={{ color: 'var(--ds-gray-700)' }}
164
- >
165
- correlationId
166
- </span>
167
- <span
168
- className="max-w-[70%] truncate text-right text-[13px] font-mono"
169
- style={{ color: 'var(--ds-gray-1000)' }}
170
- title={event.correlationId}
171
- >
143
+ <div className="flex items-center justify-between gap-2 py-2 px-3">
144
+ <span className="text-label-12 text-gray-900">Correlation ID</span>
145
+ <span className="max-w-[70%] truncate text-right text-label-12 font-mono">
172
146
  {event.correlationId}
173
147
  </span>
174
148
  </div>
@@ -177,12 +151,7 @@ function EventItem({
177
151
 
178
152
  {/* Loading state */}
179
153
  {isLoading && (
180
- <div
181
- className="mt-2 rounded-md border p-3"
182
- style={{
183
- borderColor: 'var(--ds-gray-300)',
184
- }}
185
- >
154
+ <div className="p-3">
186
155
  <Skeleton className="h-4 w-[35%]" />
187
156
  <Skeleton className="mt-2 h-4 w-[90%]" />
188
157
  <Skeleton className="mt-2 h-4 w-[75%]" />
@@ -200,7 +169,7 @@ function EventItem({
200
169
 
201
170
  {/* Event data */}
202
171
  {displayPayload != null && (
203
- <div className="mt-2">
172
+ <div className="[&>div]:border-none [&>div]:rounded-none">
204
173
  <EventDataBlock eventType={event.eventType} data={displayPayload} />
205
174
  </div>
206
175
  )}
@@ -255,6 +224,10 @@ function EventDataBlock({
255
224
  );
256
225
  }
257
226
 
227
+ if (hasEncryptedFields({ eventType, eventData: data })) {
228
+ return <EncryptedDataBlock />;
229
+ }
230
+
258
231
  // For error events (step_failed, step_retrying), the eventData has the shape
259
232
  // { error: StructuredError, stack?: string, ... }. Check both the top-level
260
233
  // value and the nested `error` field for a stack trace.
@@ -308,26 +281,28 @@ export function EventsList({
308
281
  [events]
309
282
  );
310
283
 
284
+ const hasEvents = sortedEvents.length > 0 && !error;
285
+
286
+ if (!hasEvents && !isLoading) {
287
+ return <DetailCard summary="Events" disabled />;
288
+ }
289
+
311
290
  return (
312
- <div className="mt-2" style={{ color: 'var(--ds-gray-1000)' }}>
313
- <h3
314
- className="text-heading-16 font-medium mt-4 mb-2"
315
- style={{ color: 'var(--ds-gray-1000)' }}
316
- >
317
- Events {!isLoading && `(${sortedEvents.length})`}
318
- </h3>
291
+ <DetailCard summary="Events" contentClassName="mb-0" defaultOpen>
319
292
  {isLoading ? (
320
- <div className="flex flex-col gap-4">
321
- <Skeleton className="h-9 w-full rounded-md" />
322
- <Skeleton className="h-9 w-full rounded-md" />
323
- <Skeleton className="h-9 w-full rounded-md" />
293
+ <div className="flex flex-col -mx-4">
294
+ {[0, 1, 2].map((i) => (
295
+ <div
296
+ key={i}
297
+ className="flex items-center justify-between gap-3 bg-background-200 px-4 py-2"
298
+ >
299
+ <Skeleton className="h-4 w-32 rounded" />
300
+ <Skeleton className="h-3 w-16 rounded" />
301
+ </div>
302
+ ))}
324
303
  </div>
325
- ) : null}
326
- {!isLoading && !error && sortedEvents.length === 0 && (
327
- <div className="text-sm">No events found</div>
328
- )}
329
- {sortedEvents.length > 0 && !error ? (
330
- <div className="flex flex-col gap-4">
304
+ ) : (
305
+ <div className="flex flex-col -mx-4">
331
306
  {sortedEvents.map((event) => (
332
307
  <EventItem
333
308
  key={event.eventId}
@@ -337,7 +312,7 @@ export function EventsList({
337
312
  />
338
313
  ))}
339
314
  </div>
340
- ) : null}
341
- </div>
315
+ )}
316
+ </DetailCard>
342
317
  );
343
318
  }
@@ -0,0 +1,62 @@
1
+ 'use client';
2
+
3
+ import { createContext, useContext, type ReactNode } from 'react';
4
+ import type { Event, Hook, Step, WorkflowRun } from '@workflow/world';
5
+ import type { SpanSelectionInfo } from './entity-detail-panel';
6
+
7
+ export interface SidebarDataContextValue {
8
+ run: WorkflowRun;
9
+ events: Event[];
10
+ spanDetailData: WorkflowRun | Step | Hook | Event | null;
11
+ spanDetailError?: Error | null;
12
+ spanDetailLoading?: boolean;
13
+ onSpanSelect: (info: SpanSelectionInfo) => void;
14
+ onStreamClick?: (streamId: string) => void;
15
+ onRunClick?: (runId: string) => void;
16
+ onWakeUpSleep?: (
17
+ runId: string,
18
+ correlationId: string
19
+ ) => Promise<{ stoppedCount: number }>;
20
+ onLoadEventData?: (
21
+ correlationId: string,
22
+ eventId: string
23
+ ) => Promise<unknown | null>;
24
+ onResolveHook?: (
25
+ hookToken: string,
26
+ payload: unknown,
27
+ hook?: Hook
28
+ ) => Promise<void>;
29
+ encryptionKey?: Uint8Array;
30
+ onDecrypt?: () => void;
31
+ isDecrypting?: boolean;
32
+ hasEncryptedData?: boolean;
33
+ }
34
+
35
+ const SidebarDataContext = createContext<SidebarDataContextValue | null>(null);
36
+ SidebarDataContext.displayName = 'SidebarDataContext';
37
+
38
+ export function SidebarDataProvider({
39
+ value,
40
+ children,
41
+ }: {
42
+ value: SidebarDataContextValue;
43
+ children: ReactNode;
44
+ }) {
45
+ return (
46
+ <SidebarDataContext.Provider value={value}>
47
+ {children}
48
+ </SidebarDataContext.Provider>
49
+ );
50
+ }
51
+
52
+ export function useSidebarData(): SidebarDataContextValue {
53
+ const ctx = useContext(SidebarDataContext);
54
+ if (!ctx) {
55
+ throw new Error('useSidebarData must be used within a SidebarDataProvider');
56
+ }
57
+ return ctx;
58
+ }
59
+
60
+ export function useSidebarDataOptional(): SidebarDataContextValue | null {
61
+ return useContext(SidebarDataContext);
62
+ }
@@ -5,37 +5,13 @@ import { Virtuoso, type VirtuosoHandle } from 'react-virtuoso';
5
5
  import { DataInspector } from './ui/data-inspector';
6
6
  import { Skeleton } from './ui/skeleton';
7
7
 
8
- // ──────────────────────────────────────────────────────────────────────────
9
- // Helpers
10
- // ──────────────────────────────────────────────────────────────────────────
11
-
12
- function deserializeChunkText(text: string): string {
13
- try {
14
- const parsed = JSON.parse(text);
15
- if (typeof parsed === 'string') {
16
- return parsed;
17
- }
18
- return JSON.stringify(parsed, null, 2);
19
- } catch {
20
- return text;
21
- }
22
- }
23
-
24
- function parseChunkData(text: string): unknown {
25
- try {
26
- return JSON.parse(text);
27
- } catch {
28
- return text;
29
- }
30
- }
31
-
32
8
  // ──────────────────────────────────────────────────────────────────────────
33
9
  // Types
34
10
  // ──────────────────────────────────────────────────────────────────────────
35
11
 
36
12
  export interface StreamChunk {
37
13
  id: number;
38
- text: string;
14
+ value: unknown;
39
15
  }
40
16
 
41
17
  type Chunk = StreamChunk;
@@ -62,8 +38,6 @@ const ChunkRow = React.memo(function ChunkRow({
62
38
  chunk: Chunk;
63
39
  index: number;
64
40
  }) {
65
- const parsed = parseChunkData(chunk.text);
66
-
67
41
  return (
68
42
  <div
69
43
  className="text-[11px] rounded-md border p-3"
@@ -72,22 +46,26 @@ const ChunkRow = React.memo(function ChunkRow({
72
46
  backgroundColor: 'var(--ds-gray-100)',
73
47
  }}
74
48
  >
75
- <span
76
- className="select-none mr-2"
77
- style={{ color: 'var(--ds-gray-500)' }}
78
- >
79
- [{index}]
80
- </span>
81
- {typeof parsed === 'string' ? (
49
+ <div className="flex items-start gap-2">
82
50
  <span
83
- className="whitespace-pre-wrap break-words"
84
- style={{ color: 'var(--ds-gray-1000)' }}
51
+ className="select-none pt-px"
52
+ style={{ color: 'var(--ds-gray-500)' }}
85
53
  >
86
- {deserializeChunkText(parsed)}
54
+ [{index}]
87
55
  </span>
88
- ) : (
89
- <DataInspector data={parsed} expandLevel={1} />
90
- )}
56
+ <div className="min-w-0 flex-1">
57
+ {typeof chunk.value === 'string' ? (
58
+ <span
59
+ className="whitespace-pre-wrap break-words"
60
+ style={{ color: 'var(--ds-gray-1000)' }}
61
+ >
62
+ {chunk.value}
63
+ </span>
64
+ ) : (
65
+ <DataInspector data={chunk.value} expandLevel={1} />
66
+ )}
67
+ </div>
68
+ </div>
91
69
  </div>
92
70
  );
93
71
  });
@@ -14,22 +14,18 @@ export function getMsInHighRes(ms: number): [number, number] {
14
14
  }
15
15
 
16
16
  /**
17
- * Formats a duration for timeline display (compact single-unit format).
17
+ * Formats a duration for timeline display (compact format).
18
18
  * @deprecated Use formatDuration(ms, true) instead.
19
19
  */
20
20
  export const formatDurationForTimeline = (ms: number): string =>
21
21
  formatDuration(ms, true);
22
22
 
23
- const timeSelectionFormatter = new Intl.NumberFormat(undefined, {
24
- minimumFractionDigits: 2,
25
- maximumFractionDigits: 2,
26
- });
27
-
28
23
  export function formatTimeSelection(ms: number): string {
29
- if (ms >= 1000) {
30
- return `${timeSelectionFormatter.format(ms / 1000)}s`;
24
+ const roundedMs = Math.round(ms);
25
+ if (roundedMs < 1000) {
26
+ return `${roundedMs}ms`;
31
27
  }
32
- return `${timeSelectionFormatter.format(ms)}ms`;
28
+ return `${Math.round(ms / 1000)}s`;
33
29
  }
34
30
 
35
31
  /**
@@ -0,0 +1,57 @@
1
+ import type { WorkflowRun } from '@workflow/core/runtime';
2
+ import type { Event } from '@workflow/world';
3
+ import { useMemo } from 'react';
4
+ import { buildTrace, type TraceWithMeta } from '../lib/trace-builder';
5
+ import { TraceViewerSkeleton } from './new-trace-viewer/components/trace-viewer-skeleton';
6
+ import { NewTraceViewer as NewTraceViewerComponent } from './new-trace-viewer/trace-viewer';
7
+ import {
8
+ type SidebarDataContextValue,
9
+ SidebarDataProvider,
10
+ } from './sidebar/sidebar-data-context';
11
+ import type { Trace } from './trace-viewer/types';
12
+
13
+ const NewTraceViewer = ({
14
+ run,
15
+ events,
16
+ sidebarData,
17
+ onLoadMore,
18
+ hasMore,
19
+ isLoadingMore,
20
+ loading = false,
21
+ }: {
22
+ run: WorkflowRun;
23
+ events: Event[];
24
+ sidebarData: SidebarDataContextValue;
25
+ onLoadMore?: () => void | Promise<void>;
26
+ hasMore?: boolean;
27
+ isLoadingMore?: boolean;
28
+ loading?: boolean;
29
+ }) => {
30
+ const traceWithMeta: TraceWithMeta | undefined = useMemo(() => {
31
+ if (!run?.runId) {
32
+ return undefined;
33
+ }
34
+ return buildTrace(run, events, new Date());
35
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- `new Date()` is intentionally not a dep
36
+ }, [run, events]);
37
+ const trace = traceWithMeta;
38
+
39
+ if (!trace || (loading && events.length === 0)) {
40
+ return <TraceViewerSkeleton />;
41
+ }
42
+
43
+ return (
44
+ <SidebarDataProvider value={sidebarData}>
45
+ <div className="relative w-full h-full flex">
46
+ <NewTraceViewerComponent
47
+ trace={trace as Trace}
48
+ onLoadMore={onLoadMore}
49
+ hasMore={hasMore}
50
+ isLoadingMore={isLoadingMore}
51
+ />
52
+ </div>
53
+ </SidebarDataProvider>
54
+ );
55
+ };
56
+
57
+ export { NewTraceViewer };
@@ -0,0 +1,68 @@
1
+ import * as React from 'react';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+ import { cn } from '../../lib/utils';
4
+
5
+ const buttonVariants = cva(
6
+ [
7
+ 'outline-none m-0 border-0 align-baseline no-underline group/trigger',
8
+ 'relative cursor-pointer select-none transform translate-z-0',
9
+ 'inline-flex max-w-full items-center justify-center gap-x-1 whitespace-nowrap rounded-md font-medium',
10
+ '!text-gray-100',
11
+ 'bg-gray-1000',
12
+ 'transition-[border-color,background,color,transform,box-shadow] duration-150 ease-in-out',
13
+ // Geist invert hover: literal fallbacks (no token dep, so it resolves in any
14
+ // consuming app), darkened via ancestor theme class without a registered variant.
15
+ 'hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_22%))]',
16
+ '[.dark-theme_&]:hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))]',
17
+ '[[data-theme=dark]_&]:hover:bg-[var(--themed-hover-bg,_hsl(0,_0%,_80%))]',
18
+ // Geist focus ring as arbitrary properties (no bare `outline`/ambiguous
19
+ // arbitrary-color utilities, which differ between Tailwind v3 and v4).
20
+ 'focus-visible:[outline:2px_solid_var(--ds-focus-color)] focus-visible:[outline-offset:2px]',
21
+ // disabled styles
22
+ 'disabled:cursor-not-allowed aria-disabled:cursor-not-allowed',
23
+ 'disabled:bg-gray-100 disabled:!text-gray-700 disabled:hover:bg-gray-100',
24
+ 'aria-disabled:bg-gray-100 aria-disabled:text-gray-700 aria-disabled:hover:bg-gray-100',
25
+ ],
26
+ {
27
+ variants: {
28
+ variant: {
29
+ default: '',
30
+ secondary:
31
+ '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)]',
32
+ ghost:
33
+ '[--themed-bg:_transparent] [--themed-fg:_var(--ds-gray-1000)] [--themed-hover-bg:_var(--ds-gray-alpha-100)]',
34
+ },
35
+ size: {
36
+ default: 'h-10 px-4 text-[14px]',
37
+ sm: 'h-8 px-3 text-[14px]',
38
+ xs: 'h-6 px-1.5 py-0.5 text-button-12 rounded-[4px]',
39
+ icon: 'h-8 w-8',
40
+ },
41
+ },
42
+ defaultVariants: {
43
+ variant: 'default',
44
+ size: 'default',
45
+ },
46
+ }
47
+ );
48
+
49
+ export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
50
+ VariantProps<typeof buttonVariants>;
51
+
52
+ export function Button({
53
+ className,
54
+ variant,
55
+ size,
56
+ type = 'button',
57
+ ...props
58
+ }: ButtonProps) {
59
+ return (
60
+ <button
61
+ type={type}
62
+ className={cn(buttonVariants({ variant, size, className }))}
63
+ {...props}
64
+ />
65
+ );
66
+ }
67
+
68
+ export { buttonVariants };