@workflow/web-shared 4.1.0-beta.47 → 4.1.0-beta.49

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 (301) hide show
  1. package/README.md +26 -52
  2. package/dist/components/error-boundary.d.ts.map +1 -0
  3. package/dist/{error-boundary.js → components/error-boundary.js} +1 -1
  4. package/dist/components/error-boundary.js.map +1 -0
  5. package/dist/{event-list-view.d.ts → components/event-list-view.d.ts} +2 -3
  6. package/dist/components/event-list-view.d.ts.map +1 -0
  7. package/dist/{event-list-view.js → components/event-list-view.js} +9 -17
  8. package/dist/components/event-list-view.js.map +1 -0
  9. package/dist/{hook-actions.d.ts → components/hook-actions.d.ts} +2 -3
  10. package/dist/components/hook-actions.d.ts.map +1 -0
  11. package/dist/{hook-actions.js → components/hook-actions.js} +3 -4
  12. package/dist/components/hook-actions.js.map +1 -0
  13. package/dist/components/index.d.ts +10 -0
  14. package/dist/components/index.d.ts.map +1 -0
  15. package/dist/components/index.js +8 -0
  16. package/dist/components/index.js.map +1 -0
  17. package/dist/components/run-trace-view.d.ts +22 -0
  18. package/dist/components/run-trace-view.d.ts.map +1 -0
  19. package/dist/components/run-trace-view.js +11 -0
  20. package/dist/components/run-trace-view.js.map +1 -0
  21. package/dist/components/sidebar/attribute-panel.d.ts.map +1 -0
  22. package/dist/{sidebar → components/sidebar}/attribute-panel.js +3 -3
  23. package/dist/components/sidebar/attribute-panel.js.map +1 -0
  24. package/dist/components/sidebar/conversation-view.d.ts.map +1 -0
  25. package/dist/components/sidebar/conversation-view.js.map +1 -0
  26. package/dist/components/sidebar/detail-card.d.ts.map +1 -0
  27. package/dist/components/sidebar/detail-card.js.map +1 -0
  28. package/dist/components/sidebar/entity-detail-panel.d.ts +32 -0
  29. package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -0
  30. package/dist/{sidebar → components/sidebar}/entity-detail-panel.js +61 -49
  31. package/dist/components/sidebar/entity-detail-panel.js.map +1 -0
  32. package/dist/components/sidebar/events-list.d.ts +8 -0
  33. package/dist/components/sidebar/events-list.d.ts.map +1 -0
  34. package/dist/components/sidebar/events-list.js +16 -0
  35. package/dist/components/sidebar/events-list.js.map +1 -0
  36. package/dist/components/sidebar/resolve-hook-modal.d.ts.map +1 -0
  37. package/dist/components/sidebar/resolve-hook-modal.js.map +1 -0
  38. package/dist/components/stream-viewer.d.ts +18 -0
  39. package/dist/components/stream-viewer.d.ts.map +1 -0
  40. package/dist/{stream-viewer.js → components/stream-viewer.js} +1 -59
  41. package/dist/components/stream-viewer.js.map +1 -0
  42. package/dist/components/trace-viewer/components/map.d.ts.map +1 -0
  43. package/dist/components/trace-viewer/components/map.js.map +1 -0
  44. package/dist/components/trace-viewer/components/markers.d.ts.map +1 -0
  45. package/dist/components/trace-viewer/components/markers.js.map +1 -0
  46. package/dist/components/trace-viewer/components/node.d.ts.map +1 -0
  47. package/dist/components/trace-viewer/components/node.js.map +1 -0
  48. package/dist/components/trace-viewer/components/search-input.d.ts.map +1 -0
  49. package/dist/components/trace-viewer/components/search-input.js.map +1 -0
  50. package/dist/components/trace-viewer/components/search.d.ts.map +1 -0
  51. package/dist/components/trace-viewer/components/search.js.map +1 -0
  52. package/dist/components/trace-viewer/components/span-detail-panel.d.ts.map +1 -0
  53. package/dist/components/trace-viewer/components/span-detail-panel.js.map +1 -0
  54. package/dist/components/trace-viewer/components/ui.d.ts.map +1 -0
  55. package/dist/components/trace-viewer/components/ui.js.map +1 -0
  56. package/dist/components/trace-viewer/components/zoom-button.d.ts.map +1 -0
  57. package/dist/components/trace-viewer/components/zoom-button.js.map +1 -0
  58. package/dist/components/trace-viewer/components/zoom-icons.d.ts.map +1 -0
  59. package/dist/components/trace-viewer/components/zoom-icons.js.map +1 -0
  60. package/dist/components/trace-viewer/context.d.ts.map +1 -0
  61. package/dist/components/trace-viewer/context.js.map +1 -0
  62. package/dist/components/trace-viewer/index.d.ts.map +1 -0
  63. package/dist/components/trace-viewer/index.js.map +1 -0
  64. package/dist/components/trace-viewer/trace-viewer.d.ts.map +1 -0
  65. package/dist/components/trace-viewer/trace-viewer.js.map +1 -0
  66. package/dist/components/trace-viewer/types.d.ts.map +1 -0
  67. package/dist/components/trace-viewer/types.js.map +1 -0
  68. package/dist/components/trace-viewer/util/constants.d.ts.map +1 -0
  69. package/dist/components/trace-viewer/util/constants.js.map +1 -0
  70. package/dist/components/trace-viewer/util/scrollbar-width.d.ts.map +1 -0
  71. package/dist/components/trace-viewer/util/scrollbar-width.js.map +1 -0
  72. package/dist/{trace-viewer → components/trace-viewer}/util/timing.d.ts +1 -1
  73. package/dist/components/trace-viewer/util/timing.d.ts.map +1 -0
  74. package/dist/{trace-viewer → components/trace-viewer}/util/timing.js +1 -1
  75. package/dist/components/trace-viewer/util/timing.js.map +1 -0
  76. package/dist/components/trace-viewer/util/tree.d.ts.map +1 -0
  77. package/dist/components/trace-viewer/util/tree.js.map +1 -0
  78. package/dist/components/trace-viewer/util/use-immediate-style.d.ts.map +1 -0
  79. package/dist/components/trace-viewer/util/use-immediate-style.js.map +1 -0
  80. package/dist/components/trace-viewer/util/use-streaming-spans.d.ts.map +1 -0
  81. package/dist/components/trace-viewer/util/use-streaming-spans.js.map +1 -0
  82. package/dist/components/trace-viewer/util/use-trackpad-zoom.d.ts.map +1 -0
  83. package/dist/components/trace-viewer/util/use-trackpad-zoom.js.map +1 -0
  84. package/dist/components/trace-viewer/worker.d.ts.map +1 -0
  85. package/dist/components/trace-viewer/worker.js.map +1 -0
  86. package/dist/components/workflow-trace-view.d.ts +24 -0
  87. package/dist/components/workflow-trace-view.d.ts.map +1 -0
  88. package/dist/components/workflow-trace-view.js +152 -0
  89. package/dist/components/workflow-trace-view.js.map +1 -0
  90. package/dist/components/workflow-traces/event-colors.d.ts.map +1 -0
  91. package/dist/components/workflow-traces/event-colors.js.map +1 -0
  92. package/dist/components/workflow-traces/trace-colors.d.ts.map +1 -0
  93. package/dist/components/workflow-traces/trace-colors.js.map +1 -0
  94. package/dist/components/workflow-traces/trace-span-construction.d.ts.map +1 -0
  95. package/dist/components/workflow-traces/trace-span-construction.js.map +1 -0
  96. package/dist/components/workflow-traces/trace-time-utils.d.ts.map +1 -0
  97. package/dist/components/workflow-traces/trace-time-utils.js.map +1 -0
  98. package/dist/index.d.ts +3 -13
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +2 -9
  101. package/dist/index.js.map +1 -1
  102. package/package.json +15 -11
  103. package/src/components/error-boundary.tsx +79 -0
  104. package/src/components/event-list-view.tsx +429 -0
  105. package/src/components/hook-actions.tsx +167 -0
  106. package/src/components/index.d.ts +1 -0
  107. package/src/components/index.ts +23 -0
  108. package/src/components/run-trace-view.tsx +75 -0
  109. package/src/components/sidebar/attribute-panel.tsx +938 -0
  110. package/src/components/sidebar/conversation-view.tsx +235 -0
  111. package/src/components/sidebar/detail-card.tsx +43 -0
  112. package/src/components/sidebar/entity-detail-panel.tsx +338 -0
  113. package/src/components/sidebar/events-list.tsx +119 -0
  114. package/src/components/sidebar/resolve-hook-modal.tsx +219 -0
  115. package/src/components/stream-viewer.tsx +143 -0
  116. package/src/components/trace-viewer/components/map.tsx +226 -0
  117. package/src/components/trace-viewer/components/markers.tsx +564 -0
  118. package/src/components/trace-viewer/components/node.tsx +259 -0
  119. package/src/components/trace-viewer/components/search-input.tsx +52 -0
  120. package/src/components/trace-viewer/components/search.tsx +47 -0
  121. package/src/components/trace-viewer/components/span-detail-panel.tsx +650 -0
  122. package/src/components/trace-viewer/components/ui.tsx +156 -0
  123. package/src/components/trace-viewer/components/zoom-button.tsx +61 -0
  124. package/src/components/trace-viewer/components/zoom-icons.tsx +65 -0
  125. package/src/components/trace-viewer/context.tsx +633 -0
  126. package/src/components/trace-viewer/index.tsx +4 -0
  127. package/src/components/trace-viewer/modules.d.ts +16 -0
  128. package/src/components/trace-viewer/trace-viewer.module.css +1292 -0
  129. package/src/components/trace-viewer/trace-viewer.tsx +448 -0
  130. package/src/components/trace-viewer/types.ts +234 -0
  131. package/src/components/trace-viewer/util/constants.ts +8 -0
  132. package/src/components/trace-viewer/util/scrollbar-width.ts +13 -0
  133. package/src/components/trace-viewer/util/timing.ts +33 -0
  134. package/src/components/trace-viewer/util/tree.ts +277 -0
  135. package/src/components/trace-viewer/util/use-immediate-style.ts +38 -0
  136. package/src/components/trace-viewer/util/use-streaming-spans.ts +415 -0
  137. package/src/components/trace-viewer/util/use-trackpad-zoom.tsx +51 -0
  138. package/src/components/trace-viewer/worker.ts +128 -0
  139. package/src/components/ui/alert.tsx +59 -0
  140. package/src/components/ui/card.tsx +88 -0
  141. package/src/components/ui/error-card.tsx +65 -0
  142. package/src/components/ui/skeleton.tsx +15 -0
  143. package/src/components/workflow-trace-view.tsx +306 -0
  144. package/src/components/workflow-traces/event-colors.ts +94 -0
  145. package/src/components/workflow-traces/trace-colors.ts +112 -0
  146. package/src/components/workflow-traces/trace-span-construction.ts +299 -0
  147. package/src/components/workflow-traces/trace-time-utils.ts +50 -0
  148. package/src/hooks/use-dark-mode.ts +34 -0
  149. package/src/index.d.ts +1 -0
  150. package/src/index.ts +29 -0
  151. package/src/lib/event-analysis.ts +231 -0
  152. package/src/lib/utils.ts +166 -0
  153. package/dist/api/workflow-api-client.d.ts +0 -543
  154. package/dist/api/workflow-api-client.d.ts.map +0 -1
  155. package/dist/api/workflow-api-client.js +0 -953
  156. package/dist/api/workflow-api-client.js.map +0 -1
  157. package/dist/api/workflow-server-actions.d.ts +0 -230
  158. package/dist/api/workflow-server-actions.d.ts.map +0 -1
  159. package/dist/api/workflow-server-actions.js +0 -861
  160. package/dist/api/workflow-server-actions.js.map +0 -1
  161. package/dist/error-boundary.d.ts.map +0 -1
  162. package/dist/error-boundary.js.map +0 -1
  163. package/dist/event-list-view.d.ts.map +0 -1
  164. package/dist/event-list-view.js.map +0 -1
  165. package/dist/hook-actions.d.ts.map +0 -1
  166. package/dist/hook-actions.js.map +0 -1
  167. package/dist/run-trace-view.d.ts +0 -8
  168. package/dist/run-trace-view.d.ts.map +0 -1
  169. package/dist/run-trace-view.js +0 -15
  170. package/dist/run-trace-view.js.map +0 -1
  171. package/dist/sidebar/attribute-panel.d.ts.map +0 -1
  172. package/dist/sidebar/attribute-panel.js.map +0 -1
  173. package/dist/sidebar/conversation-view.d.ts.map +0 -1
  174. package/dist/sidebar/conversation-view.js.map +0 -1
  175. package/dist/sidebar/detail-card.d.ts.map +0 -1
  176. package/dist/sidebar/detail-card.js.map +0 -1
  177. package/dist/sidebar/entity-detail-panel.d.ts +0 -12
  178. package/dist/sidebar/entity-detail-panel.d.ts.map +0 -1
  179. package/dist/sidebar/entity-detail-panel.js.map +0 -1
  180. package/dist/sidebar/events-list.d.ts +0 -9
  181. package/dist/sidebar/events-list.d.ts.map +0 -1
  182. package/dist/sidebar/events-list.js +0 -36
  183. package/dist/sidebar/events-list.js.map +0 -1
  184. package/dist/sidebar/resolve-hook-modal.d.ts.map +0 -1
  185. package/dist/sidebar/resolve-hook-modal.js.map +0 -1
  186. package/dist/stream-viewer.d.ts +0 -13
  187. package/dist/stream-viewer.d.ts.map +0 -1
  188. package/dist/stream-viewer.js.map +0 -1
  189. package/dist/trace-viewer/components/map.d.ts.map +0 -1
  190. package/dist/trace-viewer/components/map.js.map +0 -1
  191. package/dist/trace-viewer/components/markers.d.ts.map +0 -1
  192. package/dist/trace-viewer/components/markers.js.map +0 -1
  193. package/dist/trace-viewer/components/node.d.ts.map +0 -1
  194. package/dist/trace-viewer/components/node.js.map +0 -1
  195. package/dist/trace-viewer/components/search-input.d.ts.map +0 -1
  196. package/dist/trace-viewer/components/search-input.js.map +0 -1
  197. package/dist/trace-viewer/components/search.d.ts.map +0 -1
  198. package/dist/trace-viewer/components/search.js.map +0 -1
  199. package/dist/trace-viewer/components/span-detail-panel.d.ts.map +0 -1
  200. package/dist/trace-viewer/components/span-detail-panel.js.map +0 -1
  201. package/dist/trace-viewer/components/ui.d.ts.map +0 -1
  202. package/dist/trace-viewer/components/ui.js.map +0 -1
  203. package/dist/trace-viewer/components/zoom-button.d.ts.map +0 -1
  204. package/dist/trace-viewer/components/zoom-button.js.map +0 -1
  205. package/dist/trace-viewer/components/zoom-icons.d.ts.map +0 -1
  206. package/dist/trace-viewer/components/zoom-icons.js.map +0 -1
  207. package/dist/trace-viewer/context.d.ts.map +0 -1
  208. package/dist/trace-viewer/context.js.map +0 -1
  209. package/dist/trace-viewer/index.d.ts.map +0 -1
  210. package/dist/trace-viewer/index.js.map +0 -1
  211. package/dist/trace-viewer/trace-viewer.d.ts.map +0 -1
  212. package/dist/trace-viewer/trace-viewer.js.map +0 -1
  213. package/dist/trace-viewer/types.d.ts.map +0 -1
  214. package/dist/trace-viewer/types.js.map +0 -1
  215. package/dist/trace-viewer/util/constants.d.ts.map +0 -1
  216. package/dist/trace-viewer/util/constants.js.map +0 -1
  217. package/dist/trace-viewer/util/scrollbar-width.d.ts.map +0 -1
  218. package/dist/trace-viewer/util/scrollbar-width.js.map +0 -1
  219. package/dist/trace-viewer/util/timing.d.ts.map +0 -1
  220. package/dist/trace-viewer/util/timing.js.map +0 -1
  221. package/dist/trace-viewer/util/tree.d.ts.map +0 -1
  222. package/dist/trace-viewer/util/tree.js.map +0 -1
  223. package/dist/trace-viewer/util/use-immediate-style.d.ts.map +0 -1
  224. package/dist/trace-viewer/util/use-immediate-style.js.map +0 -1
  225. package/dist/trace-viewer/util/use-streaming-spans.d.ts.map +0 -1
  226. package/dist/trace-viewer/util/use-streaming-spans.js.map +0 -1
  227. package/dist/trace-viewer/util/use-trackpad-zoom.d.ts.map +0 -1
  228. package/dist/trace-viewer/util/use-trackpad-zoom.js.map +0 -1
  229. package/dist/trace-viewer/worker.d.ts.map +0 -1
  230. package/dist/trace-viewer/worker.js.map +0 -1
  231. package/dist/workflow-trace-view.d.ts +0 -14
  232. package/dist/workflow-trace-view.d.ts.map +0 -1
  233. package/dist/workflow-trace-view.js +0 -135
  234. package/dist/workflow-trace-view.js.map +0 -1
  235. package/dist/workflow-traces/event-colors.d.ts.map +0 -1
  236. package/dist/workflow-traces/event-colors.js.map +0 -1
  237. package/dist/workflow-traces/trace-colors.d.ts.map +0 -1
  238. package/dist/workflow-traces/trace-colors.js.map +0 -1
  239. package/dist/workflow-traces/trace-span-construction.d.ts.map +0 -1
  240. package/dist/workflow-traces/trace-span-construction.js.map +0 -1
  241. package/dist/workflow-traces/trace-time-utils.d.ts.map +0 -1
  242. package/dist/workflow-traces/trace-time-utils.js.map +0 -1
  243. package/server/README.md +0 -1
  244. package/server/package.json +0 -4
  245. /package/dist/{error-boundary.d.ts → components/error-boundary.d.ts} +0 -0
  246. /package/dist/{sidebar → components/sidebar}/attribute-panel.d.ts +0 -0
  247. /package/dist/{sidebar → components/sidebar}/conversation-view.d.ts +0 -0
  248. /package/dist/{sidebar → components/sidebar}/conversation-view.js +0 -0
  249. /package/dist/{sidebar → components/sidebar}/detail-card.d.ts +0 -0
  250. /package/dist/{sidebar → components/sidebar}/detail-card.js +0 -0
  251. /package/dist/{sidebar → components/sidebar}/resolve-hook-modal.d.ts +0 -0
  252. /package/dist/{sidebar → components/sidebar}/resolve-hook-modal.js +0 -0
  253. /package/dist/{trace-viewer → components/trace-viewer}/components/map.d.ts +0 -0
  254. /package/dist/{trace-viewer → components/trace-viewer}/components/map.js +0 -0
  255. /package/dist/{trace-viewer → components/trace-viewer}/components/markers.d.ts +0 -0
  256. /package/dist/{trace-viewer → components/trace-viewer}/components/markers.js +0 -0
  257. /package/dist/{trace-viewer → components/trace-viewer}/components/node.d.ts +0 -0
  258. /package/dist/{trace-viewer → components/trace-viewer}/components/node.js +0 -0
  259. /package/dist/{trace-viewer → components/trace-viewer}/components/search-input.d.ts +0 -0
  260. /package/dist/{trace-viewer → components/trace-viewer}/components/search-input.js +0 -0
  261. /package/dist/{trace-viewer → components/trace-viewer}/components/search.d.ts +0 -0
  262. /package/dist/{trace-viewer → components/trace-viewer}/components/search.js +0 -0
  263. /package/dist/{trace-viewer → components/trace-viewer}/components/span-detail-panel.d.ts +0 -0
  264. /package/dist/{trace-viewer → components/trace-viewer}/components/span-detail-panel.js +0 -0
  265. /package/dist/{trace-viewer → components/trace-viewer}/components/ui.d.ts +0 -0
  266. /package/dist/{trace-viewer → components/trace-viewer}/components/ui.js +0 -0
  267. /package/dist/{trace-viewer → components/trace-viewer}/components/zoom-button.d.ts +0 -0
  268. /package/dist/{trace-viewer → components/trace-viewer}/components/zoom-button.js +0 -0
  269. /package/dist/{trace-viewer → components/trace-viewer}/components/zoom-icons.d.ts +0 -0
  270. /package/dist/{trace-viewer → components/trace-viewer}/components/zoom-icons.js +0 -0
  271. /package/dist/{trace-viewer → components/trace-viewer}/context.d.ts +0 -0
  272. /package/dist/{trace-viewer → components/trace-viewer}/context.js +0 -0
  273. /package/dist/{trace-viewer → components/trace-viewer}/index.d.ts +0 -0
  274. /package/dist/{trace-viewer → components/trace-viewer}/index.js +0 -0
  275. /package/dist/{trace-viewer → components/trace-viewer}/trace-viewer.d.ts +0 -0
  276. /package/dist/{trace-viewer → components/trace-viewer}/trace-viewer.js +0 -0
  277. /package/dist/{trace-viewer → components/trace-viewer}/trace-viewer.module.css +0 -0
  278. /package/dist/{trace-viewer → components/trace-viewer}/types.d.ts +0 -0
  279. /package/dist/{trace-viewer → components/trace-viewer}/types.js +0 -0
  280. /package/dist/{trace-viewer → components/trace-viewer}/util/constants.d.ts +0 -0
  281. /package/dist/{trace-viewer → components/trace-viewer}/util/constants.js +0 -0
  282. /package/dist/{trace-viewer → components/trace-viewer}/util/scrollbar-width.d.ts +0 -0
  283. /package/dist/{trace-viewer → components/trace-viewer}/util/scrollbar-width.js +0 -0
  284. /package/dist/{trace-viewer → components/trace-viewer}/util/tree.d.ts +0 -0
  285. /package/dist/{trace-viewer → components/trace-viewer}/util/tree.js +0 -0
  286. /package/dist/{trace-viewer → components/trace-viewer}/util/use-immediate-style.d.ts +0 -0
  287. /package/dist/{trace-viewer → components/trace-viewer}/util/use-immediate-style.js +0 -0
  288. /package/dist/{trace-viewer → components/trace-viewer}/util/use-streaming-spans.d.ts +0 -0
  289. /package/dist/{trace-viewer → components/trace-viewer}/util/use-streaming-spans.js +0 -0
  290. /package/dist/{trace-viewer → components/trace-viewer}/util/use-trackpad-zoom.d.ts +0 -0
  291. /package/dist/{trace-viewer → components/trace-viewer}/util/use-trackpad-zoom.js +0 -0
  292. /package/dist/{trace-viewer → components/trace-viewer}/worker.d.ts +0 -0
  293. /package/dist/{trace-viewer → components/trace-viewer}/worker.js +0 -0
  294. /package/dist/{workflow-traces → components/workflow-traces}/event-colors.d.ts +0 -0
  295. /package/dist/{workflow-traces → components/workflow-traces}/event-colors.js +0 -0
  296. /package/dist/{workflow-traces → components/workflow-traces}/trace-colors.d.ts +0 -0
  297. /package/dist/{workflow-traces → components/workflow-traces}/trace-colors.js +0 -0
  298. /package/dist/{workflow-traces → components/workflow-traces}/trace-span-construction.d.ts +0 -0
  299. /package/dist/{workflow-traces → components/workflow-traces}/trace-span-construction.js +0 -0
  300. /package/dist/{workflow-traces → components/workflow-traces}/trace-time-utils.d.ts +0 -0
  301. /package/dist/{workflow-traces → components/workflow-traces}/trace-time-utils.js +0 -0
@@ -0,0 +1,88 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+
5
+ import { cn } from '../../lib/utils';
6
+
7
+ const Card = React.forwardRef<
8
+ HTMLDivElement,
9
+ React.HTMLAttributes<HTMLDivElement>
10
+ >(({ className, ...props }, ref) => (
11
+ <div
12
+ ref={ref}
13
+ className={cn(
14
+ 'rounded-lg border bg-card text-card-foreground shadow-sm',
15
+ className
16
+ )}
17
+ {...props}
18
+ />
19
+ ));
20
+ Card.displayName = 'Card';
21
+
22
+ const CardHeader = React.forwardRef<
23
+ HTMLDivElement,
24
+ React.HTMLAttributes<HTMLDivElement>
25
+ >(({ className, ...props }, ref) => (
26
+ <div
27
+ ref={ref}
28
+ className={cn('flex flex-col space-y-1.5 p-6', className)}
29
+ {...props}
30
+ />
31
+ ));
32
+ CardHeader.displayName = 'CardHeader';
33
+
34
+ const CardTitle = React.forwardRef<
35
+ HTMLDivElement,
36
+ React.HTMLAttributes<HTMLDivElement>
37
+ >(({ className, ...props }, ref) => (
38
+ <div
39
+ ref={ref}
40
+ className={cn(
41
+ 'text-2xl font-semibold leading-none tracking-tight',
42
+ className
43
+ )}
44
+ {...props}
45
+ />
46
+ ));
47
+ CardTitle.displayName = 'CardTitle';
48
+
49
+ const CardDescription = React.forwardRef<
50
+ HTMLDivElement,
51
+ React.HTMLAttributes<HTMLDivElement>
52
+ >(({ className, ...props }, ref) => (
53
+ <div
54
+ ref={ref}
55
+ className={cn('text-sm text-muted-foreground', className)}
56
+ {...props}
57
+ />
58
+ ));
59
+ CardDescription.displayName = 'CardDescription';
60
+
61
+ const CardContent = React.forwardRef<
62
+ HTMLDivElement,
63
+ React.HTMLAttributes<HTMLDivElement>
64
+ >(({ className, ...props }, ref) => (
65
+ <div ref={ref} className={cn('p-6 pt-0', className)} {...props} />
66
+ ));
67
+ CardContent.displayName = 'CardContent';
68
+
69
+ const CardFooter = React.forwardRef<
70
+ HTMLDivElement,
71
+ React.HTMLAttributes<HTMLDivElement>
72
+ >(({ className, ...props }, ref) => (
73
+ <div
74
+ ref={ref}
75
+ className={cn('flex items-center p-6 pt-0', className)}
76
+ {...props}
77
+ />
78
+ ));
79
+ CardFooter.displayName = 'CardFooter';
80
+
81
+ export {
82
+ Card,
83
+ CardHeader,
84
+ CardFooter,
85
+ CardTitle,
86
+ CardDescription,
87
+ CardContent,
88
+ };
@@ -0,0 +1,65 @@
1
+ 'use client';
2
+
3
+ import { AlertCircle, ChevronDown } from 'lucide-react';
4
+ import { useState } from 'react';
5
+ import { cn } from '../../lib/utils';
6
+
7
+ interface ErrorCardProps {
8
+ /** Title shown in the header */
9
+ title: string;
10
+ /** Error message or details to show when expanded */
11
+ details?: string;
12
+ /** Additional class names */
13
+ className?: string;
14
+ }
15
+
16
+ /**
17
+ * A collapsible error card that shows a title with an error icon,
18
+ * and expands to reveal details when clicked.
19
+ */
20
+ export function ErrorCard({
21
+ title,
22
+ className,
23
+ details = 'Unknown error',
24
+ }: ErrorCardProps) {
25
+ const [isExpanded, setIsExpanded] = useState(false);
26
+
27
+ return (
28
+ <div className="flex justify-center w-full">
29
+ <div
30
+ className={cn(
31
+ 'rounded-lg border border-destructive/50 bg-destructive/5 w-full max-w-[800px]',
32
+ className
33
+ )}
34
+ >
35
+ <button
36
+ type="button"
37
+ onClick={() => setIsExpanded(!isExpanded)}
38
+ className="w-full px-4 py-3 flex items-center justify-between gap-2 text-left hover:bg-destructive/10 transition-colors"
39
+ >
40
+ <div className="flex items-center gap-2 text-destructive">
41
+ <AlertCircle className="h-4 w-4 shrink-0" />
42
+ <span className="font-medium text-sm">{title}</span>
43
+ </div>
44
+ <div className="flex items-center gap-1.5 text-destructive/70">
45
+ <span className="text-xs">Click to show details</span>
46
+ <ChevronDown
47
+ className={cn(
48
+ 'h-4 w-4 transition-transform duration-200',
49
+ isExpanded && 'rotate-180'
50
+ )}
51
+ />
52
+ </div>
53
+ </button>
54
+
55
+ {isExpanded && details && (
56
+ <div className="px-4 pb-3 border-t border-destructive/20">
57
+ <pre className="mt-3 p-3 rounded-md bg-destructive/10 text-destructive text-xs font-mono whitespace-pre-wrap break-words overflow-auto">
58
+ {details}
59
+ </pre>
60
+ </div>
61
+ )}
62
+ </div>
63
+ </div>
64
+ );
65
+ }
@@ -0,0 +1,15 @@
1
+ import { cn } from '../../lib/utils';
2
+
3
+ function Skeleton({
4
+ className,
5
+ ...props
6
+ }: React.HTMLAttributes<HTMLDivElement>) {
7
+ return (
8
+ <div
9
+ className={cn('animate-pulse rounded-md bg-muted', className)}
10
+ {...props}
11
+ />
12
+ );
13
+ }
14
+
15
+ export { Skeleton };
@@ -0,0 +1,306 @@
1
+ 'use client';
2
+
3
+ import type { Event, Hook, Step, WorkflowRun } from '@workflow/world';
4
+ import { useCallback, useEffect, useMemo, useState } from 'react';
5
+ import { toast } from 'sonner';
6
+ import { ErrorBoundary } from './error-boundary';
7
+ import {
8
+ EntityDetailPanel,
9
+ type SpanSelectionInfo,
10
+ } from './sidebar/entity-detail-panel';
11
+ import {
12
+ TraceViewerContextProvider,
13
+ TraceViewerTimeline,
14
+ } from './trace-viewer';
15
+ import type { Span } from './trace-viewer/types';
16
+ import { Skeleton } from './ui/skeleton';
17
+ import {
18
+ getCustomSpanClassName,
19
+ getCustomSpanEventClassName,
20
+ } from './workflow-traces/trace-colors';
21
+ import {
22
+ hookToSpan,
23
+ runToSpan,
24
+ stepToSpan,
25
+ WORKFLOW_LIBRARY,
26
+ waitToSpan,
27
+ } from './workflow-traces/trace-span-construction';
28
+ import { otelTimeToMs } from './workflow-traces/trace-time-utils';
29
+
30
+ const RE_RENDER_INTERVAL_MS = 2000;
31
+
32
+ type GroupedEvents = {
33
+ eventsByStepId: Map<string, Event[]>;
34
+ eventsByHookId: Map<string, Event[]>;
35
+ runLevelEvents: Event[];
36
+ timerEvents: Map<string, Event[]>;
37
+ hookEvents: Map<string, Event[]>;
38
+ };
39
+
40
+ const isTimerEvent = (eventType: string) =>
41
+ eventType === 'wait_created' || eventType === 'wait_completed';
42
+
43
+ const isHookLifecycleEvent = (eventType: string) =>
44
+ eventType === 'hook_received' ||
45
+ eventType === 'hook_created' ||
46
+ eventType === 'hook_disposed';
47
+
48
+ const pushEvent = (
49
+ map: Map<string, Event[]>,
50
+ correlationId: string,
51
+ event: Event
52
+ ) => {
53
+ const existing = map.get(correlationId);
54
+ if (existing) {
55
+ existing.push(event);
56
+ return;
57
+ }
58
+ map.set(correlationId, [event]);
59
+ };
60
+
61
+ const groupEventsByCorrelation = (
62
+ events: Event[],
63
+ steps: Step[],
64
+ hooks: Hook[]
65
+ ): GroupedEvents => {
66
+ const eventsByStepId = new Map<string, Event[]>();
67
+ const eventsByHookId = new Map<string, Event[]>();
68
+ const runLevelEvents: Event[] = [];
69
+ const timerEvents = new Map<string, Event[]>();
70
+ const hookEvents = new Map<string, Event[]>();
71
+ const stepIds = new Set(steps.map((step) => step.stepId));
72
+ const hookIds = new Set(hooks.map((hook) => hook.hookId));
73
+
74
+ for (const event of events) {
75
+ const correlationId = event.correlationId;
76
+ if (!correlationId) {
77
+ runLevelEvents.push(event);
78
+ continue;
79
+ }
80
+
81
+ if (isTimerEvent(event.eventType)) {
82
+ pushEvent(timerEvents, correlationId, event);
83
+ continue;
84
+ }
85
+
86
+ if (isHookLifecycleEvent(event.eventType)) {
87
+ pushEvent(hookEvents, correlationId, event);
88
+ continue;
89
+ }
90
+
91
+ if (stepIds.has(correlationId)) {
92
+ pushEvent(eventsByStepId, correlationId, event);
93
+ continue;
94
+ }
95
+
96
+ if (hookIds.has(correlationId)) {
97
+ pushEvent(eventsByHookId, correlationId, event);
98
+ continue;
99
+ }
100
+
101
+ runLevelEvents.push(event);
102
+ }
103
+
104
+ return {
105
+ eventsByStepId,
106
+ eventsByHookId,
107
+ runLevelEvents,
108
+ timerEvents,
109
+ hookEvents,
110
+ };
111
+ };
112
+
113
+ const buildSpans = (
114
+ run: WorkflowRun,
115
+ steps: Step[],
116
+ groupedEvents: GroupedEvents,
117
+ now: Date
118
+ ) => {
119
+ const stepSpans = steps.map((step) => {
120
+ const stepEvents = groupedEvents.eventsByStepId.get(step.stepId) || [];
121
+ return stepToSpan(step, stepEvents, now);
122
+ });
123
+
124
+ const hookSpans = Array.from(groupedEvents.hookEvents.values())
125
+ .map((events) => hookToSpan(events, run, now))
126
+ .filter((span): span is Span => span !== null);
127
+
128
+ const waitSpans = Array.from(groupedEvents.timerEvents.values())
129
+ .map((events) => waitToSpan(events, run, now))
130
+ .filter((span): span is Span => span !== null);
131
+
132
+ return {
133
+ runSpan: runToSpan(run, groupedEvents.runLevelEvents, now),
134
+ spans: [...stepSpans, ...hookSpans, ...waitSpans],
135
+ };
136
+ };
137
+
138
+ const cascadeSpans = (runSpan: Span, spans: Span[]) => {
139
+ const sortedSpans = [
140
+ runSpan,
141
+ ...spans.slice().sort((a, b) => {
142
+ const aStart = otelTimeToMs(a.startTime);
143
+ const bStart = otelTimeToMs(b.startTime);
144
+ return aStart - bStart;
145
+ }),
146
+ ];
147
+
148
+ return sortedSpans.map((span, index) => {
149
+ const parentSpanId =
150
+ index === 0 ? undefined : String(sortedSpans[index - 1].spanId);
151
+ return {
152
+ ...span,
153
+ parentSpanId,
154
+ };
155
+ });
156
+ };
157
+
158
+ const buildTrace = (
159
+ run: WorkflowRun,
160
+ steps: Step[],
161
+ hooks: Hook[],
162
+ events: Event[],
163
+ now: Date
164
+ ) => {
165
+ const groupedEvents = groupEventsByCorrelation(events, steps, hooks);
166
+ const { runSpan, spans } = buildSpans(run, steps, groupedEvents, now);
167
+ const sortedCascadingSpans = cascadeSpans(runSpan, spans);
168
+
169
+ return {
170
+ traceId: run.runId,
171
+ rootSpanId: run.runId,
172
+ spans: sortedCascadingSpans,
173
+ resources: [
174
+ {
175
+ name: 'workflow',
176
+ attributes: {
177
+ 'service.name': WORKFLOW_LIBRARY.name,
178
+ },
179
+ },
180
+ ],
181
+ };
182
+ };
183
+
184
+ /** Re-export SpanSelectionInfo for consumers */
185
+ export type { SpanSelectionInfo };
186
+
187
+ export const WorkflowTraceViewer = ({
188
+ run,
189
+ steps,
190
+ hooks,
191
+ events,
192
+ isLoading,
193
+ error,
194
+ spanDetailData,
195
+ spanDetailLoading,
196
+ spanDetailError,
197
+ onWakeUpSleep,
198
+ onResolveHook,
199
+ onStreamClick,
200
+ onSpanSelect,
201
+ }: {
202
+ run: WorkflowRun;
203
+ steps: Step[];
204
+ hooks: Hook[];
205
+ events: Event[];
206
+ isLoading?: boolean;
207
+ error?: Error | null;
208
+ spanDetailData?: WorkflowRun | Step | Hook | Event | null;
209
+ spanDetailLoading?: boolean;
210
+ spanDetailError?: Error | null;
211
+ onWakeUpSleep?: (
212
+ runId: string,
213
+ correlationId: string
214
+ ) => Promise<{ stoppedCount: number }>;
215
+ onResolveHook?: (
216
+ hookToken: string,
217
+ payload: unknown,
218
+ hook?: Hook
219
+ ) => Promise<void>;
220
+ /** Callback when a stream reference is clicked in the detail panel */
221
+ onStreamClick?: (streamId: string) => void;
222
+ /** Callback when a span is selected. */
223
+ onSpanSelect?: (info: SpanSelectionInfo) => void;
224
+ }) => {
225
+ const [now, setNow] = useState(() => new Date());
226
+
227
+ useEffect(() => {
228
+ if (!run?.completedAt) {
229
+ const interval = setInterval(() => {
230
+ setNow(new Date());
231
+ }, RE_RENDER_INTERVAL_MS);
232
+ return () => clearInterval(interval);
233
+ }
234
+ return undefined;
235
+ }, [run?.completedAt]);
236
+
237
+ const trace = useMemo(() => {
238
+ if (!run) {
239
+ return undefined;
240
+ }
241
+ return buildTrace(run, steps, hooks, events, now);
242
+ }, [run, steps, hooks, events, now]);
243
+
244
+ useEffect(() => {
245
+ if (error && !isLoading) {
246
+ console.error(error);
247
+ toast.error('Error loading workflow trace data', {
248
+ description: error.message,
249
+ });
250
+ }
251
+ }, [error, isLoading]);
252
+
253
+ const DetailPanel = () => {
254
+ const handleSpanSelect = useCallback(
255
+ (info: SpanSelectionInfo) => {
256
+ onSpanSelect?.(info);
257
+ },
258
+ [onSpanSelect]
259
+ );
260
+
261
+ return (
262
+ <EntityDetailPanel
263
+ run={run}
264
+ onStreamClick={onStreamClick}
265
+ spanDetailData={spanDetailData ?? null}
266
+ spanDetailError={spanDetailError}
267
+ spanDetailLoading={spanDetailLoading}
268
+ onSpanSelect={handleSpanSelect}
269
+ onWakeUpSleep={onWakeUpSleep}
270
+ onResolveHook={onResolveHook}
271
+ />
272
+ );
273
+ };
274
+
275
+ if (isLoading || !trace) {
276
+ return (
277
+ <div className="relative w-full h-full">
278
+ <div className="border-b border-gray-alpha-400 w-full" />
279
+ <Skeleton className="w-full ml-2 mt-1 mb-1 h-[56px]" />
280
+ <div className="p-2 relative w-full">
281
+ <Skeleton className="w-full mt-6 h-[20px]" />
282
+ <Skeleton className="w-[10%] mt-2 ml-6 h-[20px]" />
283
+ <Skeleton className="w-[10%] mt-2 ml-12 h-[20px]" />
284
+ <Skeleton className="w-[20%] mt-2 ml-16 h-[20px]" />
285
+ </div>
286
+ </div>
287
+ );
288
+ }
289
+
290
+ return (
291
+ <div className="relative w-full h-full">
292
+ <TraceViewerContextProvider
293
+ withPanel
294
+ customSpanClassNameFunc={getCustomSpanClassName}
295
+ customSpanEventClassNameFunc={getCustomSpanEventClassName}
296
+ customPanelComponent={
297
+ <ErrorBoundary title="Failed to load entity details">
298
+ <DetailPanel />
299
+ </ErrorBoundary>
300
+ }
301
+ >
302
+ <TraceViewerTimeline height="100%" trace={trace} withPanel />
303
+ </TraceViewerContextProvider>
304
+ </div>
305
+ );
306
+ };
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Color utilities for workflow event markers
3
+ */
4
+
5
+ import type { Event } from '@workflow/world';
6
+
7
+ export interface EventColorPalette {
8
+ /** Color of the diamond/marker itself */
9
+ color: string;
10
+ /** Background color for hover info popup */
11
+ background: string;
12
+ /** Border color for hover info popup */
13
+ border: string;
14
+ /** Text color for event name in hover popup */
15
+ text: string;
16
+ /** Secondary text color for timestamp in hover popup */
17
+ secondary: string;
18
+ }
19
+
20
+ /**
21
+ * Get the color palette for an event based on its type
22
+ * - Red for failures (step_failed, run_failed)
23
+ * - Orange/yellow for retries (step_retrying)
24
+ * - Purple for webhook-related events
25
+ * - Blue otherwise (default)
26
+ */
27
+ export function getEventColor(
28
+ eventType: Event['eventType']
29
+ ): EventColorPalette {
30
+ // Failures - Red
31
+ if (eventType === 'step_failed' || eventType === 'run_failed') {
32
+ return {
33
+ color: 'var(--ds-red-600)',
34
+ background: 'var(--ds-red-100)',
35
+ border: 'var(--ds-red-500)',
36
+ text: 'var(--ds-red-900)',
37
+ secondary: 'var(--ds-red-700)',
38
+ };
39
+ }
40
+
41
+ // Retries - Orange/Yellow
42
+ if (eventType === 'step_retrying') {
43
+ return {
44
+ color: 'var(--ds-amber-600)',
45
+ background: 'var(--ds-amber-100)',
46
+ border: 'var(--ds-amber-500)',
47
+ text: 'var(--ds-amber-900)',
48
+ secondary: 'var(--ds-amber-700)',
49
+ };
50
+ }
51
+
52
+ // Webhook-related - Purple
53
+ if (
54
+ eventType === 'hook_created' ||
55
+ eventType === 'hook_received' ||
56
+ eventType === 'hook_disposed'
57
+ ) {
58
+ return {
59
+ color: 'var(--ds-purple-600)',
60
+ background: 'var(--ds-purple-100)',
61
+ border: 'var(--ds-purple-500)',
62
+ text: 'var(--ds-purple-900)',
63
+ secondary: 'var(--ds-purple-700)',
64
+ };
65
+ }
66
+
67
+ // Default - Blue
68
+ return {
69
+ color: 'var(--ds-blue-600)',
70
+ background: 'var(--ds-blue-100)',
71
+ border: 'var(--ds-blue-500)',
72
+ text: 'var(--ds-blue-900)',
73
+ secondary: 'var(--ds-blue-700)',
74
+ };
75
+ }
76
+
77
+ /**
78
+ * Determine whether to show a vertical line for an event
79
+ * - Show vertical lines for hook-related events
80
+ * - Hide vertical lines for all other workflow events by default
81
+ */
82
+ export function shouldShowVerticalLine(eventType: Event['eventType']): boolean {
83
+ // Show vertical lines for hook-related events
84
+ if (
85
+ eventType === 'hook_created' ||
86
+ eventType === 'hook_received' ||
87
+ eventType === 'hook_disposed'
88
+ ) {
89
+ return true;
90
+ }
91
+
92
+ // Hide vertical lines for all other workflow events
93
+ return false;
94
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Color utilities for workflow traces
3
+ */
4
+
5
+ import type { Step, WorkflowRun } from '@workflow/world';
6
+ import styles from '../trace-viewer/trace-viewer.module.css';
7
+ import type { SpanNode, SpanNodeEvent } from '../trace-viewer/types';
8
+
9
+ /**
10
+ * Get the CSS class name for a workflow entity based on its status
11
+ */
12
+ function getStatusClassName(
13
+ status: Step['status'] | WorkflowRun['status'],
14
+ isStripped = false
15
+ ): string {
16
+ if (isStripped && status === 'pending') {
17
+ return styles.spanPendingStriped;
18
+ }
19
+
20
+ switch (status) {
21
+ case 'running':
22
+ return styles.spanRunning;
23
+ case 'pending':
24
+ return styles.spanPending;
25
+ case 'completed':
26
+ return styles.spanCompleted;
27
+ case 'cancelled':
28
+ return styles.spanCancelled;
29
+ case 'failed':
30
+ return styles.spanFailed;
31
+ default:
32
+ return '';
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Check if a step name indicates it's a sleep step
38
+ */
39
+ function isSleepStep(stepName: string): boolean {
40
+ return String(stepName).toLowerCase().endsWith('sleep');
41
+ }
42
+
43
+ /**
44
+ * Get custom CSS class name for a span based on its attributes
45
+ * This is called dynamically by the trace viewer to style spans
46
+ */
47
+ export const getCustomSpanClassName = (span: SpanNode): string => {
48
+ const attributes = span.span.attributes;
49
+ const resource = attributes?.resource;
50
+
51
+ if (resource === 'step') {
52
+ const stepData = attributes.data as Step;
53
+ const stepName = stepData?.stepName;
54
+
55
+ // DEPRECATED: Check if it's a sleep step
56
+ if (stepName && isSleepStep(stepName)) {
57
+ return styles.spanSleep;
58
+ }
59
+
60
+ // Regular step - use status colors
61
+ const isStripped = stepData?.status === 'pending';
62
+ return getStatusClassName(stepData?.status, isStripped);
63
+ }
64
+
65
+ if (resource === 'run') {
66
+ const runData = attributes.data as WorkflowRun;
67
+ return getStatusClassName(runData?.status, false);
68
+ }
69
+
70
+ if (resource === 'hook') {
71
+ return styles.spanHook;
72
+ }
73
+
74
+ if (resource === 'sleep') {
75
+ return styles.spanSleep;
76
+ }
77
+
78
+ // Default: no custom class
79
+ return '';
80
+ };
81
+
82
+ /**
83
+ * Get custom CSS class name for a span event based on its type
84
+ * This is called dynamically by the trace viewer to style event markers
85
+ */
86
+ export const getCustomSpanEventClassName = (
87
+ spanEvent: SpanNodeEvent
88
+ ): string => {
89
+ const eventName = spanEvent.event.name;
90
+
91
+ // Failure events - Red
92
+ if (eventName === 'step_failed' || eventName === 'run_failed') {
93
+ return styles.eventFailed;
94
+ }
95
+
96
+ // Retry events - Orange/Yellow
97
+ if (eventName === 'step_retrying') {
98
+ return styles.eventRetrying;
99
+ }
100
+
101
+ // Webhook-related events - Purple
102
+ if (
103
+ eventName === 'hook_created' ||
104
+ eventName === 'hook_received' ||
105
+ eventName === 'hook_disposed'
106
+ ) {
107
+ return styles.eventHook;
108
+ }
109
+
110
+ // Default - Blue
111
+ return styles.eventDefault;
112
+ };