@elabs-ai/components-ai 4.2.0 → 5.1.0

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 (462) hide show
  1. package/README.md +1 -1
  2. package/dist/{_audio-player-media-chrome-T3XVXWRZ.js → _audio-player-media-chrome.js} +1 -1
  3. package/dist/_code-block-theme.js +12 -0
  4. package/dist/_code-block-theme.js.map +1 -0
  5. package/dist/{_flow-boundary-SHNWLQG5.js → _flow-boundary.js} +1 -1
  6. package/dist/_flow-boundary.js.map +1 -0
  7. package/dist/_flow-lazy.js +8 -0
  8. package/dist/_flow-lazy.js.map +1 -0
  9. package/dist/_lazy-boundary-conformance.js +2 -0
  10. package/dist/_lazy-boundary-conformance.js.map +1 -0
  11. package/dist/_lazy-cjk.js +13 -0
  12. package/dist/_lazy-cjk.js.map +1 -0
  13. package/dist/_lazy-engine-boundary.js +9 -0
  14. package/dist/_lazy-engine-boundary.js.map +1 -0
  15. package/dist/_lazy-math.js +13 -0
  16. package/dist/_lazy-math.js.map +1 -0
  17. package/dist/_lazy-mermaid.js +12 -0
  18. package/dist/_lazy-mermaid.js.map +1 -0
  19. package/dist/_mermaid-error-panel.js +9 -0
  20. package/dist/_mermaid-error-panel.js.map +1 -0
  21. package/dist/{_persona-rive-JEG44YHX.js → _persona-rive.js} +19 -24
  22. package/dist/_persona-rive.js.map +1 -0
  23. package/dist/_streamdown-i18n.js +21 -0
  24. package/dist/_streamdown-i18n.js.map +1 -0
  25. package/dist/_streamdown-safety.js +10 -0
  26. package/dist/_streamdown-safety.js.map +1 -0
  27. package/dist/_theme-scope-store.js +13 -0
  28. package/dist/_theme-scope-store.js.map +1 -0
  29. package/dist/a2ui/a2ui-surface.js +17 -0
  30. package/dist/a2ui/a2ui-surface.js.map +1 -0
  31. package/dist/a2ui/core/catalog.generated.js +10 -0
  32. package/dist/a2ui/core/catalog.generated.js.map +1 -0
  33. package/dist/a2ui/core/complete-json.js +10 -0
  34. package/dist/a2ui/core/complete-json.js.map +1 -0
  35. package/dist/a2ui/core/index.js +37 -0
  36. package/dist/a2ui/core/index.js.map +1 -0
  37. package/dist/a2ui/core/schema.js +11 -0
  38. package/dist/a2ui/core/schema.js.map +1 -0
  39. package/dist/a2ui/core/spec.js +10 -0
  40. package/dist/a2ui/core/spec.js.map +1 -0
  41. package/dist/a2ui/core/validate.js +16 -0
  42. package/dist/a2ui/core/validate.js.map +1 -0
  43. package/dist/a2ui/index.js +54 -0
  44. package/dist/a2ui/index.js.map +1 -0
  45. package/dist/a2ui/ui-catalog.js +18 -0
  46. package/dist/a2ui/ui-catalog.js.map +1 -0
  47. package/dist/agent-event.js +10 -0
  48. package/dist/agent-event.js.map +1 -0
  49. package/dist/agent-timeline.js +11 -0
  50. package/dist/agent-timeline.js.map +1 -0
  51. package/dist/agent.js +25 -0
  52. package/dist/agent.js.map +1 -0
  53. package/dist/artifact.js +23 -0
  54. package/dist/artifact.js.map +1 -0
  55. package/dist/asset-preview.js +22 -0
  56. package/dist/asset-preview.js.map +1 -0
  57. package/dist/attachments.js +33 -0
  58. package/dist/attachments.js.map +1 -0
  59. package/dist/audio-player.js +30 -0
  60. package/dist/audio-player.js.map +1 -0
  61. package/dist/audio-visualizer.js +9 -0
  62. package/dist/audio-visualizer.js.map +1 -0
  63. package/dist/canvas.js +10 -0
  64. package/dist/canvas.js.map +1 -0
  65. package/dist/chain-of-thought.js +22 -0
  66. package/dist/chain-of-thought.js.map +1 -0
  67. package/dist/chat-greeting.js +8 -0
  68. package/dist/chat-greeting.js.map +1 -0
  69. package/dist/chat-shell.js +9 -0
  70. package/dist/chat-shell.js.map +1 -0
  71. package/dist/checkpoint.js +13 -0
  72. package/dist/checkpoint.js.map +1 -0
  73. package/dist/chunk-2XOIG5TG.js +72 -0
  74. package/dist/chunk-2XOIG5TG.js.map +1 -0
  75. package/dist/chunk-34CQ2VHM.js +172 -0
  76. package/dist/chunk-34CQ2VHM.js.map +1 -0
  77. package/dist/chunk-3TDHPXZZ.js +60 -0
  78. package/dist/chunk-3TDHPXZZ.js.map +1 -0
  79. package/dist/chunk-3XNPMDZY.js +478 -0
  80. package/dist/chunk-3XNPMDZY.js.map +1 -0
  81. package/dist/chunk-3YPT3V7L.js +56 -0
  82. package/dist/chunk-3YPT3V7L.js.map +1 -0
  83. package/dist/chunk-475UEU2Q.js +87 -0
  84. package/dist/chunk-475UEU2Q.js.map +1 -0
  85. package/dist/chunk-4CBTII2I.js +95 -0
  86. package/dist/chunk-4CBTII2I.js.map +1 -0
  87. package/dist/chunk-4XRNIZMG.js +22 -0
  88. package/dist/chunk-4XRNIZMG.js.map +1 -0
  89. package/dist/chunk-5NNWUKK5.js +2 -0
  90. package/dist/chunk-5NNWUKK5.js.map +1 -0
  91. package/dist/chunk-5UOMU27Z.js +164 -0
  92. package/dist/chunk-5UOMU27Z.js.map +1 -0
  93. package/dist/chunk-5VGYZ62I.js +264 -0
  94. package/dist/chunk-5VGYZ62I.js.map +1 -0
  95. package/dist/chunk-6IQPH2OS.js +21 -0
  96. package/dist/chunk-6IQPH2OS.js.map +1 -0
  97. package/dist/chunk-6PB2MXCI.js +482 -0
  98. package/dist/chunk-6PB2MXCI.js.map +1 -0
  99. package/dist/chunk-7FD5CZEU.js +215 -0
  100. package/dist/chunk-7FD5CZEU.js.map +1 -0
  101. package/dist/chunk-7RL6KZDF.js +266 -0
  102. package/dist/chunk-7RL6KZDF.js.map +1 -0
  103. package/dist/chunk-ADOYAGGK.js +482 -0
  104. package/dist/chunk-ADOYAGGK.js.map +1 -0
  105. package/dist/chunk-BA3AEMOU.js +21 -0
  106. package/dist/chunk-BA3AEMOU.js.map +1 -0
  107. package/dist/chunk-BBHFOYML.js +336 -0
  108. package/dist/chunk-BBHFOYML.js.map +1 -0
  109. package/dist/chunk-BHUVISIY.js +221 -0
  110. package/dist/chunk-BHUVISIY.js.map +1 -0
  111. package/dist/chunk-BM2LWERA.js +100 -0
  112. package/dist/chunk-BM2LWERA.js.map +1 -0
  113. package/dist/chunk-CMOYXNPJ.js +211 -0
  114. package/dist/chunk-CMOYXNPJ.js.map +1 -0
  115. package/dist/chunk-CZP3RHC4.js +74 -0
  116. package/dist/chunk-CZP3RHC4.js.map +1 -0
  117. package/dist/chunk-DDG5JHQT.js +112 -0
  118. package/dist/chunk-DDG5JHQT.js.map +1 -0
  119. package/dist/chunk-DJODXO7I.js +38 -0
  120. package/dist/chunk-DJODXO7I.js.map +1 -0
  121. package/dist/chunk-DWJDJLPU.js +192 -0
  122. package/dist/chunk-DWJDJLPU.js.map +1 -0
  123. package/dist/chunk-DZW6LM22.js +45 -0
  124. package/dist/chunk-DZW6LM22.js.map +1 -0
  125. package/dist/chunk-ELGCZLZF.js +305 -0
  126. package/dist/chunk-ELGCZLZF.js.map +1 -0
  127. package/dist/chunk-EV3U6ZZB.js +209 -0
  128. package/dist/chunk-EV3U6ZZB.js.map +1 -0
  129. package/dist/chunk-EY7LVUKQ.js +87 -0
  130. package/dist/chunk-EY7LVUKQ.js.map +1 -0
  131. package/dist/chunk-F4C74F7M.js +230 -0
  132. package/dist/chunk-F4C74F7M.js.map +1 -0
  133. package/dist/chunk-FERYDFZA.js +108 -0
  134. package/dist/chunk-FERYDFZA.js.map +1 -0
  135. package/dist/chunk-FUIYG2DS.js +166 -0
  136. package/dist/chunk-FUIYG2DS.js.map +1 -0
  137. package/dist/chunk-GA7M34KU.js +236 -0
  138. package/dist/chunk-GA7M34KU.js.map +1 -0
  139. package/dist/chunk-GKYZT3LA.js +136 -0
  140. package/dist/chunk-GKYZT3LA.js.map +1 -0
  141. package/dist/chunk-H42LRUQ4.js +102 -0
  142. package/dist/chunk-H42LRUQ4.js.map +1 -0
  143. package/dist/chunk-HVXM2G5F.js +222 -0
  144. package/dist/chunk-HVXM2G5F.js.map +1 -0
  145. package/dist/chunk-I4RDAGVY.js +53 -0
  146. package/dist/chunk-I4RDAGVY.js.map +1 -0
  147. package/dist/chunk-IQJG4IDX.js +208 -0
  148. package/dist/chunk-IQJG4IDX.js.map +1 -0
  149. package/dist/chunk-IX2PXG4Y.js +144 -0
  150. package/dist/chunk-IX2PXG4Y.js.map +1 -0
  151. package/dist/chunk-IXICSOOP.js +287 -0
  152. package/dist/chunk-IXICSOOP.js.map +1 -0
  153. package/dist/chunk-JY5HSN4D.js +84 -0
  154. package/dist/chunk-JY5HSN4D.js.map +1 -0
  155. package/dist/chunk-L4SU3QJV.js +174 -0
  156. package/dist/chunk-L4SU3QJV.js.map +1 -0
  157. package/dist/chunk-LMNSBOBG.js +19 -0
  158. package/dist/chunk-LMNSBOBG.js.map +1 -0
  159. package/dist/chunk-MBI7D6IL.js +42 -0
  160. package/dist/chunk-MBI7D6IL.js.map +1 -0
  161. package/dist/chunk-MLFMYCPH.js +192 -0
  162. package/dist/chunk-MLFMYCPH.js.map +1 -0
  163. package/dist/chunk-MOK66734.js +33 -0
  164. package/dist/chunk-MOK66734.js.map +1 -0
  165. package/dist/chunk-MXTAWPYM.js +196 -0
  166. package/dist/chunk-MXTAWPYM.js.map +1 -0
  167. package/dist/chunk-NCL2UZKI.js +96 -0
  168. package/dist/chunk-NCL2UZKI.js.map +1 -0
  169. package/dist/chunk-NET4YLRY.js +107 -0
  170. package/dist/chunk-NET4YLRY.js.map +1 -0
  171. package/dist/chunk-NIG67CFM.js +329 -0
  172. package/dist/chunk-NIG67CFM.js.map +1 -0
  173. package/dist/chunk-NMVNNO3L.js +10 -0
  174. package/dist/chunk-NMVNNO3L.js.map +1 -0
  175. package/dist/chunk-NP7VID4K.js +2 -0
  176. package/dist/chunk-NP7VID4K.js.map +1 -0
  177. package/dist/chunk-NPUCMAG2.js +382 -0
  178. package/dist/chunk-NPUCMAG2.js.map +1 -0
  179. package/dist/chunk-NSCLRHES.js +102 -0
  180. package/dist/chunk-NSCLRHES.js.map +1 -0
  181. package/dist/chunk-OEUXHVFW.js +86 -0
  182. package/dist/chunk-OEUXHVFW.js.map +1 -0
  183. package/dist/chunk-ONBHFIMZ.js +137 -0
  184. package/dist/chunk-ONBHFIMZ.js.map +1 -0
  185. package/dist/chunk-OPH2HHL2.js +228 -0
  186. package/dist/chunk-OPH2HHL2.js.map +1 -0
  187. package/dist/chunk-OQERHIQP.js +287 -0
  188. package/dist/chunk-OQERHIQP.js.map +1 -0
  189. package/dist/chunk-P6YJAZFG.js +103 -0
  190. package/dist/chunk-P6YJAZFG.js.map +1 -0
  191. package/dist/chunk-PG7ERDOD.js +65 -0
  192. package/dist/chunk-PG7ERDOD.js.map +1 -0
  193. package/dist/chunk-PIB5JBMA.js +90 -0
  194. package/dist/chunk-PIB5JBMA.js.map +1 -0
  195. package/dist/chunk-PQ5BPIWQ.js +22 -0
  196. package/dist/chunk-PQ5BPIWQ.js.map +1 -0
  197. package/dist/chunk-PQBF6ZIQ.js +55 -0
  198. package/dist/chunk-PQBF6ZIQ.js.map +1 -0
  199. package/dist/chunk-PTWCTSZL.js +173 -0
  200. package/dist/chunk-PTWCTSZL.js.map +1 -0
  201. package/dist/chunk-QJUNPVOS.js +101 -0
  202. package/dist/chunk-QJUNPVOS.js.map +1 -0
  203. package/dist/chunk-QOBSEGCG.js +996 -0
  204. package/dist/chunk-QOBSEGCG.js.map +1 -0
  205. package/dist/chunk-QUDZOTRV.js +43 -0
  206. package/dist/chunk-QUDZOTRV.js.map +1 -0
  207. package/dist/chunk-RB7G65JC.js +213 -0
  208. package/dist/chunk-RB7G65JC.js.map +1 -0
  209. package/dist/chunk-RPHAOR7P.js +45 -0
  210. package/dist/chunk-RPHAOR7P.js.map +1 -0
  211. package/dist/chunk-RTCSH2AN.js +331 -0
  212. package/dist/chunk-RTCSH2AN.js.map +1 -0
  213. package/dist/chunk-S3ISPW3A.js +28 -0
  214. package/dist/chunk-S3ISPW3A.js.map +1 -0
  215. package/dist/chunk-SEVN656N.js +36 -0
  216. package/dist/chunk-SEVN656N.js.map +1 -0
  217. package/dist/chunk-SKVG672B.js +64 -0
  218. package/dist/chunk-SKVG672B.js.map +1 -0
  219. package/dist/chunk-SSGJ6MEM.js +1076 -0
  220. package/dist/chunk-SSGJ6MEM.js.map +1 -0
  221. package/dist/chunk-SSKZ2AED.js +118 -0
  222. package/dist/chunk-SSKZ2AED.js.map +1 -0
  223. package/dist/chunk-T56JFGXI.js +561 -0
  224. package/dist/chunk-T56JFGXI.js.map +1 -0
  225. package/dist/chunk-TCB6O74A.js +137 -0
  226. package/dist/chunk-TCB6O74A.js.map +1 -0
  227. package/dist/chunk-TTEYPO6X.js +57 -0
  228. package/dist/chunk-TTEYPO6X.js.map +1 -0
  229. package/dist/chunk-TWPHAJNM.js +462 -0
  230. package/dist/chunk-TWPHAJNM.js.map +1 -0
  231. package/dist/chunk-TXJJLP4O.js +336 -0
  232. package/dist/chunk-TXJJLP4O.js.map +1 -0
  233. package/dist/chunk-TZ6TB7VM.js +245 -0
  234. package/dist/chunk-TZ6TB7VM.js.map +1 -0
  235. package/dist/chunk-UBLKJJ7K.js +278 -0
  236. package/dist/chunk-UBLKJJ7K.js.map +1 -0
  237. package/dist/chunk-UCJ6IUFS.js +52 -0
  238. package/dist/chunk-UCJ6IUFS.js.map +1 -0
  239. package/dist/chunk-UCKFJ3QF.js +197 -0
  240. package/dist/chunk-UCKFJ3QF.js.map +1 -0
  241. package/dist/chunk-UPXSLILN.js +20 -0
  242. package/dist/chunk-UPXSLILN.js.map +1 -0
  243. package/dist/chunk-V4DORGWJ.js +92 -0
  244. package/dist/chunk-V4DORGWJ.js.map +1 -0
  245. package/dist/chunk-V6E5DYZD.js +80 -0
  246. package/dist/chunk-V6E5DYZD.js.map +1 -0
  247. package/dist/chunk-VLLYKF3P.js +96 -0
  248. package/dist/chunk-VLLYKF3P.js.map +1 -0
  249. package/dist/chunk-VLNBTOH6.js +43 -0
  250. package/dist/chunk-VLNBTOH6.js.map +1 -0
  251. package/dist/chunk-WMDSMSPL.js +303 -0
  252. package/dist/chunk-WMDSMSPL.js.map +1 -0
  253. package/dist/chunk-WU5BLGTF.js +149 -0
  254. package/dist/chunk-WU5BLGTF.js.map +1 -0
  255. package/dist/chunk-WYTZVSGK.js +245 -0
  256. package/dist/chunk-WYTZVSGK.js.map +1 -0
  257. package/dist/chunk-X47QMM6K.js +187 -0
  258. package/dist/chunk-X47QMM6K.js.map +1 -0
  259. package/dist/chunk-YHUSW7D2.js +40 -0
  260. package/dist/chunk-YHUSW7D2.js.map +1 -0
  261. package/dist/chunk-YSKD7UXX.js +126 -0
  262. package/dist/chunk-YSKD7UXX.js.map +1 -0
  263. package/dist/chunk-YYRDGWOU.js +72 -0
  264. package/dist/chunk-YYRDGWOU.js.map +1 -0
  265. package/dist/chunk-ZIGZMWM7.js +19 -0
  266. package/dist/chunk-ZIGZMWM7.js.map +1 -0
  267. package/dist/chunk-ZKRTUKNP.js +40 -0
  268. package/dist/chunk-ZKRTUKNP.js.map +1 -0
  269. package/dist/code-block.js +38 -0
  270. package/dist/code-block.js.map +1 -0
  271. package/dist/commit.js +51 -0
  272. package/dist/commit.js.map +1 -0
  273. package/dist/composer.js +15 -0
  274. package/dist/composer.js.map +1 -0
  275. package/dist/confirmation.js +53 -0
  276. package/dist/confirmation.js.map +1 -0
  277. package/dist/connection.js +8 -0
  278. package/dist/connection.js.map +1 -0
  279. package/dist/context-panel.js +25 -0
  280. package/dist/context-panel.js.map +1 -0
  281. package/dist/controls.js +10 -0
  282. package/dist/controls.js.map +1 -0
  283. package/dist/conversation.js +19 -0
  284. package/dist/conversation.js.map +1 -0
  285. package/dist/diff-view.js +15 -0
  286. package/dist/diff-view.js.map +1 -0
  287. package/dist/edge.js +10 -0
  288. package/dist/edge.js.map +1 -0
  289. package/dist/environment-variables.js +29 -0
  290. package/dist/environment-variables.js.map +1 -0
  291. package/dist/file-tree.js +23 -0
  292. package/dist/file-tree.js.map +1 -0
  293. package/dist/gallery.js +9 -0
  294. package/dist/gallery.js.map +1 -0
  295. package/dist/grouped-parts.js +21 -0
  296. package/dist/grouped-parts.js.map +1 -0
  297. package/dist/image.js +9 -0
  298. package/dist/image.js.map +1 -0
  299. package/dist/index.d.ts +366 -98
  300. package/dist/index.js +672 -13577
  301. package/dist/index.js.map +1 -1
  302. package/dist/inline-citation.js +39 -0
  303. package/dist/inline-citation.js.map +1 -0
  304. package/dist/jsx-preview.js +17 -0
  305. package/dist/jsx-preview.js.map +1 -0
  306. package/dist/markdown-view.js +17 -0
  307. package/dist/markdown-view.js.map +1 -0
  308. package/dist/message-compare.js +12 -0
  309. package/dist/message-compare.js.map +1 -0
  310. package/dist/message-edit.js +19 -0
  311. package/dist/message-edit.js.map +1 -0
  312. package/dist/message-feedback.js +11 -0
  313. package/dist/message-feedback.js.map +1 -0
  314. package/dist/message-form-spec.js +38 -0
  315. package/dist/message-form-spec.js.map +1 -0
  316. package/dist/message-form.js +26 -0
  317. package/dist/message-form.js.map +1 -0
  318. package/dist/message-table-spec.js +26 -0
  319. package/dist/message-table-spec.js.map +1 -0
  320. package/dist/message-table.js +12 -0
  321. package/dist/message-table.js.map +1 -0
  322. package/dist/message.js +51 -0
  323. package/dist/message.js.map +1 -0
  324. package/dist/mic-selector.js +27 -0
  325. package/dist/mic-selector.js.map +1 -0
  326. package/dist/model-provider-logo.js +13 -0
  327. package/dist/model-provider-logo.js.map +1 -0
  328. package/dist/motion-config.js +9 -0
  329. package/dist/motion-config.js.map +1 -0
  330. package/dist/node.js +22 -0
  331. package/dist/node.js.map +1 -0
  332. package/dist/open-in-chat.js +31 -0
  333. package/dist/open-in-chat.js.map +1 -0
  334. package/dist/package-info.js +25 -0
  335. package/dist/package-info.js.map +1 -0
  336. package/dist/panel.js +10 -0
  337. package/dist/panel.js.map +1 -0
  338. package/dist/part-groups.js +18 -0
  339. package/dist/part-groups.js.map +1 -0
  340. package/dist/permission-mode-select.js +9 -0
  341. package/dist/permission-mode-select.js.map +1 -0
  342. package/dist/persona-sources.js +8 -0
  343. package/dist/persona-sources.js.map +1 -0
  344. package/dist/persona.js +14 -0
  345. package/dist/persona.js.map +1 -0
  346. package/dist/plan.js +32 -0
  347. package/dist/plan.js.map +1 -0
  348. package/dist/prompt-input-effort.js +9 -0
  349. package/dist/prompt-input-effort.js.map +1 -0
  350. package/dist/prompt-input-mode.js +10 -0
  351. package/dist/prompt-input-mode.js.map +1 -0
  352. package/dist/prompt-input-slash.js +12 -0
  353. package/dist/prompt-input-slash.js.map +1 -0
  354. package/dist/prompt-input.js +89 -0
  355. package/dist/prompt-input.js.map +1 -0
  356. package/dist/queue.js +37 -0
  357. package/dist/queue.js.map +1 -0
  358. package/dist/reasoning.js +23 -0
  359. package/dist/reasoning.js.map +1 -0
  360. package/dist/sandbox.js +28 -0
  361. package/dist/sandbox.js.map +1 -0
  362. package/dist/schema-display.js +33 -0
  363. package/dist/schema-display.js.map +1 -0
  364. package/dist/selection-toolbar.js +11 -0
  365. package/dist/selection-toolbar.js.map +1 -0
  366. package/dist/session-header.js +9 -0
  367. package/dist/session-header.js.map +1 -0
  368. package/dist/session-status-bar.js +9 -0
  369. package/dist/session-status-bar.js.map +1 -0
  370. package/dist/shimmer.js +9 -0
  371. package/dist/shimmer.js.map +1 -0
  372. package/dist/snippet.js +17 -0
  373. package/dist/snippet.js.map +1 -0
  374. package/dist/sources.js +17 -0
  375. package/dist/sources.js.map +1 -0
  376. package/dist/speech-input.js +9 -0
  377. package/dist/speech-input.js.map +1 -0
  378. package/dist/stack-trace.js +27 -0
  379. package/dist/stack-trace.js.map +1 -0
  380. package/dist/suggestion.js +16 -0
  381. package/dist/suggestion.js.map +1 -0
  382. package/dist/task.js +18 -0
  383. package/dist/task.js.map +1 -0
  384. package/dist/test-results.js +43 -0
  385. package/dist/test-results.js.map +1 -0
  386. package/dist/token-usage.js +27 -0
  387. package/dist/token-usage.js.map +1 -0
  388. package/dist/tool-result-card.js +9 -0
  389. package/dist/tool-result-card.js.map +1 -0
  390. package/dist/tool.js +27 -0
  391. package/dist/tool.js.map +1 -0
  392. package/dist/toolbar.js +10 -0
  393. package/dist/toolbar.js.map +1 -0
  394. package/dist/transcription.js +11 -0
  395. package/dist/transcription.js.map +1 -0
  396. package/dist/turn-status.js +9 -0
  397. package/dist/turn-status.js.map +1 -0
  398. package/dist/use-audio-level.js +9 -0
  399. package/dist/use-audio-level.js.map +1 -0
  400. package/dist/voice-selector.js +47 -0
  401. package/dist/voice-selector.js.map +1 -0
  402. package/dist/web-preview.js +19 -0
  403. package/dist/web-preview.js.map +1 -0
  404. package/package.json +11 -9
  405. package/schemas/a2ui-surface.v1.schema.json +5434 -0
  406. package/src/_chat-shell-rail.tsx +3 -1
  407. package/src/_flow-boundary.tsx +2 -2
  408. package/src/_persona-rive.tsx +27 -41
  409. package/src/a2ui/a2ui-surface.stories.tsx +662 -0
  410. package/src/a2ui/a2ui-surface.test.tsx +201 -0
  411. package/src/a2ui/a2ui-surface.tsx +354 -0
  412. package/src/a2ui/catalog.source.json +772 -0
  413. package/src/a2ui/core/a2ui-core.test.ts +178 -0
  414. package/src/a2ui/core/catalog.generated.ts +1019 -0
  415. package/src/a2ui/core/complete-json.ts +81 -0
  416. package/src/a2ui/core/index.ts +10 -0
  417. package/src/a2ui/core/schema.ts +111 -0
  418. package/src/a2ui/core/spec.ts +148 -0
  419. package/src/a2ui/core/validate.ts +266 -0
  420. package/src/a2ui/index.ts +7 -0
  421. package/src/a2ui/ui-catalog.tsx +225 -0
  422. package/src/a2ui/wave1-chart-spec.test.ts +87 -0
  423. package/src/a2ui/wave2-chart-spec.test.ts +108 -0
  424. package/src/agentic-workspace.stories.tsx +6 -45
  425. package/src/chat-shell.test.tsx +40 -10
  426. package/src/chat-shell.tsx +90 -44
  427. package/src/chat.stories.tsx +47 -42
  428. package/src/composer.stories.tsx +4 -5
  429. package/src/composer.test.tsx +45 -0
  430. package/src/composer.tsx +104 -21
  431. package/src/context-panel.stories.tsx +1 -1
  432. package/src/context-panel.tsx +1 -1
  433. package/src/conversation.stories.tsx +1 -0
  434. package/src/conversation.test.tsx +16 -0
  435. package/src/conversation.tsx +16 -2
  436. package/src/diff-view.stories.tsx +79 -0
  437. package/src/diff-view.tsx +3 -2
  438. package/src/file-tree.tsx +24 -17
  439. package/src/gallery.stories.tsx +42 -0
  440. package/src/gallery.tsx +2 -2
  441. package/src/grouped-parts.stories.tsx +23 -0
  442. package/src/grouped-parts.tsx +1 -1
  443. package/src/index.ts +1 -0
  444. package/src/message-compare.stories.tsx +40 -0
  445. package/src/message-compare.tsx +2 -1
  446. package/src/message-form.tsx +1 -1
  447. package/src/message-table.stories.tsx +24 -0
  448. package/src/message-table.tsx +1 -1
  449. package/src/package-info.tsx +12 -9
  450. package/src/reasoning.stories.tsx +27 -0
  451. package/src/reasoning.tsx +1 -1
  452. package/src/session-header.stories.tsx +35 -1
  453. package/src/session-header.tsx +1 -1
  454. package/src/sources.stories.tsx +30 -0
  455. package/src/sources.tsx +4 -1
  456. package/src/templates-ai-assistant.stories.tsx +151 -87
  457. package/src/tool.stories.tsx +39 -0
  458. package/src/tool.tsx +3 -3
  459. package/src/toolbar.tsx +0 -10
  460. package/dist/_flow-boundary-SHNWLQG5.js.map +0 -1
  461. package/dist/_persona-rive-JEG44YHX.js.map +0 -1
  462. /package/dist/{_audio-player-media-chrome-T3XVXWRZ.js.map → _audio-player-media-chrome.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/motion-config.tsx"],"sourcesContent":["\"use client\";\n\nimport { useReducedMotion } from \"@elabs-ai/components-tokens\";\nimport { MotionConfig, type Transition } from \"motion/react\";\nimport type { ReactNode } from \"react\";\n\n/**\n * Default transition fed to descendant Motion components — mirrors the\n * `--duration-base` (180ms) and `--ease-standard` tokens in @elabs-ai/components-tokens so\n * JS-driven motion matches the CSS layer's timing. Override via the `transition`\n * prop. (Motion durations are in SECONDS; ease is a cubic-bezier [x1,y1,x2,y2].)\n */\nconst DEFAULT_MOTION_TRANSITION: Transition = {\n duration: 0.18,\n ease: [0.2, 0, 0, 1],\n};\n\nexport interface BrandMotionConfigProps {\n children: ReactNode;\n /** Override the default transition handed to descendant Motion components. */\n transition?: Transition;\n}\n\n/**\n * App-level wrapper that bridges the brand-ui motion preference into Motion\n * (motion.dev). It drives Motion's `reducedMotion` from `useReducedMotion()`\n * (user choice > OS setting) so JS-driven Motion components honor the SAME gate\n * as the CSS `--motion-factor` layer, and supplies a token-mirrored default\n * transition. Provider-OPTIONAL: without a `<ThemeProvider>` it degrades to\n * OS-only reduced-motion detection.\n *\n * Wrap the Motion-using subtree (e.g. the chat surface) once near the app root.\n *\n * NOTE: Motion's `reducedMotion=\"always\"` disables only transform/layout\n * animations (opacity/color persist — \"reduced != none\"). Components that loop\n * on other properties (e.g. {@link Shimmer}, which animates backgroundPosition)\n * must still branch on `useReducedMotion()` themselves.\n */\nexport function BrandMotionConfig({\n children,\n transition = DEFAULT_MOTION_TRANSITION,\n}: BrandMotionConfigProps) {\n const reducedMotion = useReducedMotion();\n return (\n <MotionConfig reducedMotion={reducedMotion ? \"always\" : \"never\"} transition={transition}>\n {children}\n </MotionConfig>\n );\n}\n"],"mappings":";;;AAEA,SAAS,wBAAwB;AACjC,SAAS,oBAAqC;AAyC1C;AAhCJ,IAAM,4BAAwC;AAAA,EAC5C,UAAU;AAAA,EACV,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC;AACrB;AAuBO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,aAAa;AACf,GAA2B;AACzB,QAAM,gBAAgB,iBAAiB;AACvC,SACE,oBAAC,gBAAa,eAAe,gBAAgB,WAAW,SAAS,YAC9D,UACH;AAEJ;","names":[]}
@@ -0,0 +1,55 @@
1
+ "use client";
2
+ import {
3
+ useLazyMathPlugin
4
+ } from "./chunk-VLNBTOH6.js";
5
+ import {
6
+ lazyMermaid
7
+ } from "./chunk-PG7ERDOD.js";
8
+ import {
9
+ MermaidErrorPanel
10
+ } from "./chunk-SEVN656N.js";
11
+ import {
12
+ useThemeScopeRevision
13
+ } from "./chunk-3TDHPXZZ.js";
14
+ import {
15
+ buildCodeBlockTheme
16
+ } from "./chunk-SSKZ2AED.js";
17
+ import {
18
+ useLazyCjkPlugin
19
+ } from "./chunk-QUDZOTRV.js";
20
+
21
+ // src/_streamdown-i18n.ts
22
+ import {
23
+ STREAMDOWN_TRANSLATION_KEYS,
24
+ useStreamdownTranslations
25
+ } from "@elabs-ai/components-ui";
26
+ import { createCodePlugin } from "@streamdown/code";
27
+ import { useMemo } from "react";
28
+ function useReactiveCodePlugin() {
29
+ const revision = useThemeScopeRevision(null);
30
+ return useMemo(() => {
31
+ const theme = buildCodeBlockTheme();
32
+ return createCodePlugin({ themes: [theme, theme] });
33
+ }, [revision]);
34
+ }
35
+ function useStreamdownPlugins(text = "") {
36
+ const code = useReactiveCodePlugin();
37
+ const math = useLazyMathPlugin(text);
38
+ const cjk = useLazyCjkPlugin(text);
39
+ return useMemo(() => ({ cjk, code, math, mermaid: lazyMermaid }), [cjk, code, math]);
40
+ }
41
+ function getStreamdownPluginsKey(plugins) {
42
+ return `${plugins.math ? "math" : "no-math"}:${plugins.cjk ? "cjk" : "no-cjk"}`;
43
+ }
44
+ var MERMAID_OPTIONS = { errorComponent: MermaidErrorPanel };
45
+ function useStreamdownMermaidOptions() {
46
+ return MERMAID_OPTIONS;
47
+ }
48
+
49
+ export {
50
+ useStreamdownTranslations,
51
+ useStreamdownPlugins,
52
+ getStreamdownPluginsKey,
53
+ useStreamdownMermaidOptions
54
+ };
55
+ //# sourceMappingURL=chunk-PQBF6ZIQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/_streamdown-i18n.ts"],"sourcesContent":["\"use client\";\n\n/**\n * The shared Streamdown wiring for every streamed-markdown surface in\n * `@elabs-ai/components-ai` — the plugin set and the locale bridge.\n *\n * Why the locale bridge exists (#310)\n * -----------------------------------\n * Streamdown renders its own chrome inside the markdown it draws: a code-block\n * header with a copy control, table copy/download menus, a Mermaid toolbar, an\n * external-link interstitial. Those labels live in the dependency, not in our\n * source, so `pnpm microcopy:check` structurally cannot see them and a\n * `<LocaleProvider>` used to stop at the Streamdown boundary — every localized\n * app leaked \"Copy Code\" / \"Download diagram\" / \"You're about to visit an\n * external website.\" in English.\n *\n * Streamdown exposes the whole set through one `translations` prop, so the fix\n * is to map its keys onto our `ai.streamdown.*` namespace and resolve them with\n * `t()`. The English defaults in\n * `packages/ui/src/components/locale-provider/messages.ts` are byte-identical to\n * streamdown's own, so this is a no-op for anyone who overrides nothing.\n *\n * Memoization matters: Streamdown puts `translations` into a React context, so a\n * fresh object per render would re-render every code block and table in the\n * document. The map is memoized on `t`, which is itself stable per locale.\n */\nimport {\n STREAMDOWN_TRANSLATION_KEYS,\n useStreamdownTranslations,\n type StreamdownTranslationKey,\n} from \"@elabs-ai/components-ui\";\nimport { createCodePlugin } from \"@streamdown/code\";\nimport { useMemo } from \"react\";\nimport type { StreamdownTranslations } from \"streamdown\";\nimport { buildCodeBlockTheme } from \"./_code-block-theme\";\nimport { useLazyCjkPlugin } from \"./_lazy-cjk\";\nimport { useLazyMathPlugin } from \"./_lazy-math\";\nimport { lazyMermaid } from \"./_lazy-mermaid\";\nimport { MermaidErrorPanel } from \"./_mermaid-error-panel\";\nimport { useThemeScopeRevision } from \"./_theme-scope-store\";\n\n/**\n * Reactive replacement for `@streamdown/code`'s pre-configured `code` export\n * (issue #315 follow-up, the \"major\" carve-out: only `<CodeBlock>` had been\n * de-GitHub-ed — every fenced code block rendered through `Message`/\n * `MarkdownView`/`Reasoning`'s Streamdown instance still went through this\n * plugin, whose `getThemes()` is FROZEN at import time to\n * `[\"github-light\", \"github-dark\"]`).\n *\n * Streamdown's dual-theme mechanism (`createCodePlugin({ themes: [light, dark] })`)\n * expects exactly TWO themes and picks between them purely via the `.dark` CSS\n * selector — but brand-ui ships EVERY theme, not just Shiki's light/dark,\n * and any dark-declaring theme matches `.dark` too (see `_code-block-theme.ts`). Passing a real\n * light/dark PAIR would still force such a theme into the dark slot. Instead\n * this pins BOTH slots to `buildCodeBlockTheme()` — the SAME brand-token-derived\n * theme the active `data-theme` resolves to — so whichever slot the `.dark`\n * selector picks, it's the CORRECT theme for whatever is actually active.\n *\n * Re-derives on every `data-theme` mutation and returns a NEW plugin object\n * each time, because Streamdown only re-reads `plugins.code.getThemes()` when\n * the `plugins.code` object's REFERENCE changes (see streamdown's internal\n * `shikiTheme` memo) — a mutated-in-place plugin would never be picked up.\n *\n * The mutation watch itself comes from the SHARED, ref-counted store in\n * `./_theme-scope-store` (perf review §3.3) rather than a `MutationObserver`\n * instantiated per hook call — every simultaneously-mounted\n * `MessageResponse`/`MarkdownView` (and every `CodeBlock`) in a message-dense\n * conversation now shares exactly one observer per distinct scope element,\n * instead of one each. This hook has no element of its own to scope to (it\n * runs before Streamdown renders anything), so it resolves to the document's\n * theme scope (`getThemeScope(null)` → closest `[data-theme]` on `<html>`,\n * same as its prior always-`<html>` behaviour) — a genuinely region-scoped\n * derivation would need a ref to the rendered surface, which no current call\n * site (`message.tsx`, `markdown-view.tsx`, `reasoning.tsx`) has available.\n */\nfunction useReactiveCodePlugin() {\n const revision = useThemeScopeRevision(null);\n\n return useMemo(() => {\n const theme = buildCodeBlockTheme();\n return createCodePlugin({ themes: [theme, theme] });\n // eslint-disable-next-line react-hooks/exhaustive-deps -- revision is the trigger; the theme itself is re-read live off document.documentElement.\n }, [revision]);\n}\n\n/**\n * The plugin set every `@elabs-ai/components-ai` markdown surface renders with.\n *\n * `mermaid` is the LAZY plugin (`./_lazy-mermaid`): the engine + d3 + DOMPurify\n * load on first diagram render, not in the entry chunk of every consumer.\n * `math`/`cjk` are ALSO lazy (`./_lazy-math`, `./_lazy-cjk`, #perf-5): KaTeX\n * (~600 KB) and the CJK remark plugins load only once `text` — the raw\n * markdown source about to render — actually needs them, sniffed by a cheap\n * regex rather than shipped unconditionally in every consumer's entry chunk.\n * Both resolve to `undefined` (the slot is simply absent) until their content\n * cue fires and the dynamic import resolves; see the two modules' docs for the\n * one-paint tradeoff this makes and why it can't be avoided the way Mermaid's\n * render-time laziness is.\n *\n * `code` is the reactive, brand-token-derived plugin above (#315) — never the\n * `@streamdown/code` package's static `github-light`/`github-dark` default.\n * Memoized so Streamdown sees a referentially stable `plugins` prop except when\n * the active theme (or a lazy slot) actually changes.\n *\n * @param text The raw markdown source about to render — used only to decide\n * whether the math/CJK plugins are needed. Pass `\"\"` to never load them\n * speculatively.\n */\nexport function useStreamdownPlugins(text = \"\") {\n const code = useReactiveCodePlugin();\n const math = useLazyMathPlugin(text);\n const cjk = useLazyCjkPlugin(text);\n return useMemo(() => ({ cjk, code, math, mermaid: lazyMermaid }), [cjk, code, math]);\n}\n\n/**\n * A React `key` for the `<Streamdown>` element that renders with\n * {@link useStreamdownPlugins}'s result — pass it as `key={getStreamdownPluginsKey(plugins)}`\n * on the `<Streamdown>` JSX, never inside the `plugins` object itself.\n *\n * Why this exists (#perf-5 follow-up): Streamdown v2.5.0's `rehypePlugins`/\n * `remarkPlugins` are `useMemo`'d with `plugins.math`/`plugins.cjk` in their\n * dependency arrays, and its `Block`/`Streamdown` components' custom `memo`\n * comparators do check plugin reference equality — on paper, a fresh\n * `plugins.math` object arriving after the lazy `import()` resolves should be\n * enough to make Streamdown rebuild its processing pipeline with the math\n * plugin included. Empirically (verified directly against the real\n * `streamdown` package, not a mock) it does not: once a block has rendered\n * once without `plugins.math`/`plugins.cjk`, Streamdown's internal processor\n * cache keeps serving the plugin-less result even after the reference\n * changes, and the literal `$$…$$`/CJK-remark-less markdown source stays\n * un-rendered indefinitely.\n *\n * Forcing React to unmount and remount the `<Streamdown>` element — by\n * changing its `key` — sidesteps that internal cache entirely (a fresh\n * instance has no stale cache to serve) and reliably picks up the lazily\n * loaded plugin. The cost is a one-time full remount of that Streamdown\n * instance the first time its lazy math/CJK slot resolves — at most once per\n * mounted instance, since after that the key is stable again. Filed for\n * upstream investigation; if a future `streamdown` release fixes the\n * underlying cache, this key can be dropped without changing any call site's\n * behavior (an unchanging key is a no-op).\n */\nexport function getStreamdownPluginsKey(plugins: {\n readonly cjk?: unknown;\n readonly math?: unknown;\n}): string {\n return `${plugins.math ? \"math\" : \"no-math\"}:${plugins.cjk ? \"cjk\" : \"no-cjk\"}`;\n}\n\n/**\n * The top-level Streamdown `mermaid` prop (distinct from `plugins.mermaid`,\n * the LAZY `DiagramPlugin` `useStreamdownPlugins()` wires above) — this is\n * where a FAILED render is caught (issue #33). Streamdown hands its\n * `errorComponent` a plain STRING describing what went wrong;\n * `MermaidErrorPanel` decides whether that string names a missing optional\n * peer (`mermaid` not installed — a capability gap, `StatePanel kind=\"empty\"`)\n * or a genuine diagram render failure (`StatePanel kind=\"error\"`, with retry).\n *\n * A stable module-level object, not a fresh one per render: Streamdown only\n * re-reads `mermaid.errorComponent` when this reference changes, and\n * `MermaidErrorPanel` never varies at runtime. Exported as a hook to match\n * `useStreamdownPlugins()`'s call-site shape.\n */\nconst MERMAID_OPTIONS = { errorComponent: MermaidErrorPanel };\nexport function useStreamdownMermaidOptions() {\n return MERMAID_OPTIONS;\n}\n\n/*\n * The translation MAP moved down to `@elabs-ai/components-ui`\n * (`lib/streamdown-translations.ts`) when `@elabs-ai/components-viewer`\n * became a second Streamdown renderer — the two packages may not import each\n * other. What stays here is the half that needs the dependency itself: the\n * proof that the shared key list is still COMPLETE.\n */\n\n// `satisfies` proves every key in the shared list is real…\nconst _keysAreReal =\n STREAMDOWN_TRANSLATION_KEYS satisfies readonly (keyof StreamdownTranslations)[];\nvoid _keysAreReal;\n\n// …and this proves the converse. If a streamdown upgrade ADDS a translation\n// key, the assignment below stops building until the shared list (and the\n// `ai.streamdown.*` English defaults) catch up, instead of silently leaking\n// that key in English. The tripwire lives in the package that pins the version.\ntype MissingTranslationKeys = Exclude<keyof StreamdownTranslations, StreamdownTranslationKey>;\nconst _noMissingTranslationKeys: [MissingTranslationKeys] extends [never] ? true : false = true;\nvoid _noMissingTranslationKeys;\n\nexport { useStreamdownTranslations };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA0BA;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,wBAAwB;AACjC,SAAS,eAAe;AA2CxB,SAAS,wBAAwB;AAC/B,QAAM,WAAW,sBAAsB,IAAI;AAE3C,SAAO,QAAQ,MAAM;AACnB,UAAM,QAAQ,oBAAoB;AAClC,WAAO,iBAAiB,EAAE,QAAQ,CAAC,OAAO,KAAK,EAAE,CAAC;AAAA,EAEpD,GAAG,CAAC,QAAQ,CAAC;AACf;AAyBO,SAAS,qBAAqB,OAAO,IAAI;AAC9C,QAAM,OAAO,sBAAsB;AACnC,QAAM,OAAO,kBAAkB,IAAI;AACnC,QAAM,MAAM,iBAAiB,IAAI;AACjC,SAAO,QAAQ,OAAO,EAAE,KAAK,MAAM,MAAM,SAAS,YAAY,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC;AACrF;AA8BO,SAAS,wBAAwB,SAG7B;AACT,SAAO,GAAG,QAAQ,OAAO,SAAS,SAAS,IAAI,QAAQ,MAAM,QAAQ,QAAQ;AAC/E;AAgBA,IAAM,kBAAkB,EAAE,gBAAgB,kBAAkB;AACrD,SAAS,8BAA8B;AAC5C,SAAO;AACT;","names":[]}
@@ -0,0 +1,173 @@
1
+ "use client";
2
+ import {
3
+ CodeBlock
4
+ } from "./chunk-TWPHAJNM.js";
5
+
6
+ // src/tool.tsx
7
+ import { Skeleton, StatusBadge, useLocale } from "@elabs-ai/components-ui";
8
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@elabs-ai/components-ui";
9
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
10
+ import { ChevronDownIcon, WrenchIcon } from "lucide-react";
11
+ import { isValidElement } from "react";
12
+ import { jsx, jsxs } from "react/jsx-runtime";
13
+ var Tool = ({ className, ...props }) => /* @__PURE__ */ jsx(
14
+ Collapsible,
15
+ {
16
+ className: cn("group not-prose mb-4 w-full rounded-md border", className),
17
+ ...props
18
+ }
19
+ );
20
+ function safeJsonStringify(value) {
21
+ try {
22
+ return JSON.stringify(value, (_key, v) => typeof v === "bigint" ? `${v.toString()}n` : v, 2);
23
+ } catch {
24
+ return String(value);
25
+ }
26
+ }
27
+ var statusFromToolState = (state) => {
28
+ switch (state) {
29
+ case "input-streaming":
30
+ return "pending";
31
+ case "input-available":
32
+ return "running";
33
+ case "approval-requested":
34
+ return "awaiting-approval";
35
+ case "approval-responded":
36
+ return "running";
37
+ case "output-available":
38
+ return "complete";
39
+ case "output-denied":
40
+ return "denied";
41
+ case "output-error":
42
+ return "failed";
43
+ }
44
+ };
45
+ var getStatusBadge = (status) => /* @__PURE__ */ jsx(StatusBadge, { status: statusFromToolState(status) });
46
+ var ToolHeader = ({
47
+ className,
48
+ title,
49
+ summary,
50
+ type,
51
+ state,
52
+ toolName,
53
+ ...props
54
+ }) => {
55
+ const derivedName = type === "dynamic-tool" ? toolName : type.split("-").slice(1).join("-");
56
+ return /* @__PURE__ */ jsxs(
57
+ CollapsibleTrigger,
58
+ {
59
+ className: cn("flex w-full items-center justify-between gap-4 p-3", className),
60
+ ...props,
61
+ children: [
62
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
63
+ /* @__PURE__ */ jsx(WrenchIcon, { className: "size-4 shrink-0 text-muted-foreground" }),
64
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-body font-medium", children: title ?? derivedName }),
65
+ getStatusBadge(state),
66
+ summary ? /* @__PURE__ */ jsx("span", { className: "truncate text-meta text-muted-foreground", children: summary }) : null
67
+ ] }),
68
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 shrink-0 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" })
69
+ ]
70
+ }
71
+ );
72
+ };
73
+ var ToolContent = ({ className, ...props }) => /* @__PURE__ */ jsx(
74
+ CollapsibleContent,
75
+ {
76
+ className: cn(
77
+ "data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 space-y-4 p-4 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=open]:[--tw-ease:var(--ease-entrance)] data-[state=closed]:[--tw-ease:var(--ease-exit)]",
78
+ className
79
+ ),
80
+ ...props
81
+ }
82
+ );
83
+ var ToolDetails = ({
84
+ className,
85
+ label,
86
+ defaultOpen = false,
87
+ children,
88
+ ...props
89
+ }) => {
90
+ const { t } = useLocale();
91
+ return /* @__PURE__ */ jsxs(
92
+ Collapsible,
93
+ {
94
+ className: cn("group/tool-details not-prose", className),
95
+ defaultOpen,
96
+ ...props,
97
+ children: [
98
+ /* @__PURE__ */ jsxs(CollapsibleTrigger, { className: "flex items-center gap-1 rounded-sm text-meta text-muted-foreground transition-colors hover:text-foreground focus-ring", children: [
99
+ /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-3.5 transition-transform group-data-[state=open]/tool-details:rotate-180" }),
100
+ label ?? t("ai.tool.showTechnicalDetails")
101
+ ] }),
102
+ /* @__PURE__ */ jsx(CollapsibleContent, { className: "mt-3 space-y-4", children })
103
+ ]
104
+ }
105
+ );
106
+ };
107
+ var ToolInput = ({ className, input, ...props }) => {
108
+ const { t } = useLocale();
109
+ return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2 overflow-hidden", className), ...props, children: [
110
+ /* @__PURE__ */ jsx("h4", { className: "text-eyebrow uppercase text-muted-foreground", children: t("ai.schemaDisplay.parameters") }),
111
+ /* @__PURE__ */ jsx("div", { className: "rounded-md bg-muted/50", children: /* @__PURE__ */ jsx(CodeBlock, { code: safeJsonStringify(input), language: "json" }) })
112
+ ] });
113
+ };
114
+ var ToolOutput = ({
115
+ className,
116
+ output,
117
+ errorText,
118
+ isStreaming = false,
119
+ ...props
120
+ }) => {
121
+ const { t } = useLocale();
122
+ const hasOutput = output !== void 0;
123
+ if (!(hasOutput || errorText || isStreaming)) {
124
+ return null;
125
+ }
126
+ const showError = !isStreaming && Boolean(errorText);
127
+ const pending = isStreaming && !hasOutput && !errorText;
128
+ let Output = null;
129
+ if (hasOutput) {
130
+ if (isValidElement(output)) {
131
+ Output = output;
132
+ } else if (typeof output === "string") {
133
+ Output = /* @__PURE__ */ jsx(CodeBlock, { code: output, language: "text" });
134
+ } else {
135
+ Output = /* @__PURE__ */ jsx(CodeBlock, { code: safeJsonStringify(output), language: "json" });
136
+ }
137
+ }
138
+ return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2", className), ...props, children: [
139
+ /* @__PURE__ */ jsx("h4", { className: "text-eyebrow uppercase text-muted-foreground", children: showError ? t("ai.tool.error") : t("ai.tool.result") }),
140
+ pending ? /* @__PURE__ */ jsxs("div", { className: "space-y-2 rounded-md bg-muted/50 p-3", role: "status", "aria-live": "polite", children: [
141
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: t("loading") }),
142
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }),
143
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }),
144
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/2" })
145
+ ] }) : /* @__PURE__ */ jsxs(
146
+ "div",
147
+ {
148
+ className: cn(
149
+ "overflow-x-auto rounded-md text-caption [&_table]:w-full",
150
+ // #124: this colours the ambient text of the error/result body —
151
+ // running text, so the error branch takes the ink rung.
152
+ showError ? "bg-destructive/10 text-destructive-text" : "bg-muted/50 text-foreground"
153
+ ),
154
+ children: [
155
+ showError && /* @__PURE__ */ jsx("div", { children: errorText }),
156
+ Output
157
+ ]
158
+ }
159
+ )
160
+ ] });
161
+ };
162
+
163
+ export {
164
+ Tool,
165
+ statusFromToolState,
166
+ getStatusBadge,
167
+ ToolHeader,
168
+ ToolContent,
169
+ ToolDetails,
170
+ ToolInput,
171
+ ToolOutput
172
+ };
173
+ //# sourceMappingURL=chunk-PTWCTSZL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tool.tsx"],"sourcesContent":["\"use client\";\n\nimport { Skeleton, StatusBadge, useLocale, type Status } from \"@elabs-ai/components-ui\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport type { DynamicToolUIPart, ToolUIPart } from \"ai\";\nimport { ChevronDownIcon, WrenchIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { isValidElement } from \"react\";\nimport type { BundledLanguage } from \"shiki\";\n\nimport { CodeBlock } from \"./code-block\";\n\nexport type ToolProps = ComponentProps<typeof Collapsible>;\n\nexport const Tool = ({ className, ...props }: ToolProps) => (\n <Collapsible\n className={cn(\"group not-prose mb-4 w-full rounded-md border\", className)}\n {...props}\n />\n);\n\nexport type ToolPart = ToolUIPart | DynamicToolUIPart;\n\n/**\n * `JSON.stringify` throws on a circular reference or a `BigInt` — both\n * realistic shapes for tool input/output payloads a model produced. Falls\n * back to a readable placeholder instead of crashing the message render.\n */\nfunction safeJsonStringify(value: unknown): string {\n try {\n return JSON.stringify(value, (_key, v) => (typeof v === \"bigint\" ? `${v.toString()}n` : v), 2);\n } catch {\n return String(value);\n }\n}\n\nexport type ToolHeaderProps = {\n title?: string;\n /**\n * The business summary line (\"3 documents found\", \"8 rows reconciled\"),\n * shown beside the name + StatusBadge (#192, research 10 §B.5). Falls back\n * to nothing — the derived tool name still labels the row.\n */\n summary?: ReactNode;\n className?: string;\n} & (\n | { type: ToolUIPart[\"type\"]; state: ToolUIPart[\"state\"]; toolName?: never }\n | {\n type: DynamicToolUIPart[\"type\"];\n state: DynamicToolUIPart[\"state\"];\n toolName: string;\n }\n);\n\n/**\n * Map the AI-SDK `ToolUIPart` 7-state machine onto the canonical `Status`\n * enum (#189, research 10 §B.1 mapping a). Lives here — not in `@elabs-ai/components-ui` —\n * because it is typed against the SDK union; the `ai` import stays TYPES-ONLY\n * (D6, gate-enforced by `pnpm ai:types-only`).\n */\nexport const statusFromToolState = (state: ToolPart[\"state\"]): Status => {\n switch (state) {\n case \"input-streaming\":\n return \"pending\";\n case \"input-available\":\n return \"running\";\n case \"approval-requested\":\n return \"awaiting-approval\";\n case \"approval-responded\":\n return \"running\";\n case \"output-available\":\n return \"complete\";\n case \"output-denied\":\n return \"denied\";\n case \"output-error\":\n return \"failed\";\n }\n};\n\n/** Same signature as before #189; renders the canonical StatusBadge. */\nexport const getStatusBadge = (status: ToolPart[\"state\"]) => (\n <StatusBadge status={statusFromToolState(status)} />\n);\n\nexport const ToolHeader = ({\n className,\n title,\n summary,\n type,\n state,\n toolName,\n ...props\n}: ToolHeaderProps) => {\n const derivedName = type === \"dynamic-tool\" ? toolName : type.split(\"-\").slice(1).join(\"-\");\n\n return (\n <CollapsibleTrigger\n className={cn(\"flex w-full items-center justify-between gap-4 p-3\", className)}\n {...props}\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <WrenchIcon className=\"size-4 shrink-0 text-muted-foreground\" />\n <span className=\"shrink-0 text-body font-medium\">{title ?? derivedName}</span>\n {getStatusBadge(state)}\n {summary ? (\n <span className=\"truncate text-meta text-muted-foreground\">{summary}</span>\n ) : null}\n </div>\n <ChevronDownIcon className=\"size-4 shrink-0 text-muted-foreground transition-transform group-data-[state=open]:rotate-180\" />\n </CollapsibleTrigger>\n );\n};\n\nexport type ToolContentProps = ComponentProps<typeof CollapsibleContent>;\n\nexport const ToolContent = ({ className, ...props }: ToolContentProps) => (\n <CollapsibleContent\n className={cn(\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 space-y-4 p-4 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=open]:[--tw-ease:var(--ease-entrance)] data-[state=closed]:[--tw-ease:var(--ease-exit)]\",\n className,\n )}\n {...props}\n />\n);\n\nexport type ToolDetailsProps = ComponentProps<typeof Collapsible> & {\n /** The disclosure label. */\n label?: ReactNode;\n};\n\n/**\n * The technical view, behind disclosure — the PACKAGE DEFAULT for tool JSON\n * (#192, research 10 §B.5): a nested collapsible, COLLAPSED by default,\n * holding `ToolInput`/`ToolOutput`. The header carries the business `summary`;\n * the raw payload is one expand away, never the headline.\n */\nexport const ToolDetails = ({\n className,\n label,\n defaultOpen = false,\n children,\n ...props\n}: ToolDetailsProps) => {\n const { t } = useLocale();\n return (\n <Collapsible\n className={cn(\"group/tool-details not-prose\", className)}\n defaultOpen={defaultOpen}\n {...props}\n >\n <CollapsibleTrigger className=\"flex items-center gap-1 rounded-sm text-meta text-muted-foreground transition-colors hover:text-foreground focus-ring\">\n <ChevronDownIcon className=\"size-3.5 transition-transform group-data-[state=open]/tool-details:rotate-180\" />\n {label ?? t(\"ai.tool.showTechnicalDetails\")}\n </CollapsibleTrigger>\n <CollapsibleContent className=\"mt-3 space-y-4\">{children}</CollapsibleContent>\n </Collapsible>\n );\n};\n\nexport type ToolInputProps = ComponentProps<\"div\"> & {\n input: ToolPart[\"input\"];\n};\n\nexport const ToolInput = ({ className, input, ...props }: ToolInputProps) => {\n const { t } = useLocale();\n return (\n <div className={cn(\"space-y-2 overflow-hidden\", className)} {...props}>\n <h4 className=\"text-eyebrow uppercase text-muted-foreground\">\n {t(\"ai.schemaDisplay.parameters\")}\n </h4>\n <div className=\"rounded-md bg-muted/50\">\n <CodeBlock code={safeJsonStringify(input)} language=\"json\" />\n </div>\n </div>\n );\n};\n\nexport type ToolOutputProps = ComponentProps<\"div\"> & {\n /**\n * The tool result. Objects/strings render as JSON inside the technical view.\n *\n * @deprecated Passing a pre-rendered **React element** here (the \"rich\n * output under a muted Result heading\" path) is deprecated since #192\n * (research 10 §B.5): a produced artifact is the HEADLINE, not a technical\n * detail — host it in a `<ToolResultCard>` and keep `ToolOutput` for the\n * JSON payload behind `<ToolDetails>`. The element path still renders for\n * existing consumers (e.g. the copy-owned `ai-chart` registry block) but\n * will be removed in a future release.\n */\n output: ToolPart[\"output\"];\n errorText: ToolPart[\"errorText\"];\n /**\n * The call has not produced output yet (loading-states.md `isStreaming`) —\n * derive it from the existing `statusFromToolState(state)` mapping\n * (`\"input-streaming\"`/`\"input-available\"` → not yet `\"complete\"`/`\"failed\"`)\n * rather than a second source of truth. While true and no `output`/\n * `errorText` has arrived, renders a layout-shaped skeleton in the Result\n * slot instead of `null`, so the technical view reserves its space. A\n * still-running call is never a terminal failure — the error branch is\n * suppressed while `isStreaming` per the loading-states.md error rule, even\n * if a stale `errorText` is still set from a previous render.\n * @default false\n */\n isStreaming?: boolean;\n};\n\nexport const ToolOutput = ({\n className,\n output,\n errorText,\n isStreaming = false,\n ...props\n}: ToolOutputProps) => {\n const { t } = useLocale();\n\n // `output` is a defined-but-falsy result (`0`, `false`, `\"\"`) for plenty of\n // real tools (a count, a boolean check, an empty-string field) — only\n // `undefined` means \"no output (yet)\".\n const hasOutput = output !== undefined;\n\n if (!(hasOutput || errorText || isStreaming)) {\n return null;\n }\n\n const showError = !isStreaming && Boolean(errorText);\n const pending = isStreaming && !hasOutput && !errorText;\n\n let Output: ReactNode = null;\n\n if (hasOutput) {\n if (isValidElement(output)) {\n Output = output;\n } else if (typeof output === \"string\") {\n // A tool result is arbitrary text, not guaranteed JSON — forcing the\n // JSON highlighter on it mis-colours ordinary strings. Shiki's own\n // `BundledLanguage` union (grammar-backed languages) omits its\n // hard-coded plain-text pseudo-languages (`isPlainLang`:\n // \"plaintext\" | \"txt\" | \"text\" | \"plain\") — `createHighlighter`/\n // `codeToTokens` accept and special-case them with no grammar load\n // (verified: `getLoadedLanguages()` stays empty, no throw), so this\n // is a type-only gap, not a runtime one.\n Output = <CodeBlock code={output} language={\"text\" as BundledLanguage} />;\n } else {\n // Objects, arrays, numbers, booleans, null, bigint — all safe to\n // stringify for display.\n Output = <CodeBlock code={safeJsonStringify(output)} language=\"json\" />;\n }\n }\n\n return (\n <div className={cn(\"space-y-2\", className)} {...props}>\n <h4 className=\"text-eyebrow uppercase text-muted-foreground\">\n {showError ? t(\"ai.tool.error\") : t(\"ai.tool.result\")}\n </h4>\n {pending ? (\n <div className=\"space-y-2 rounded-md bg-muted/50 p-3\" role=\"status\" aria-live=\"polite\">\n <span className=\"sr-only\">{t(\"loading\")}</span>\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n ) : (\n <div\n className={cn(\n \"overflow-x-auto rounded-md text-caption [&_table]:w-full\",\n // #124: this colours the ambient text of the error/result body —\n // running text, so the error branch takes the ink rung.\n showError ? \"bg-destructive/10 text-destructive-text\" : \"bg-muted/50 text-foreground\",\n )}\n >\n {showError && <div>{errorText}</div>}\n {Output}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,101 @@
1
+ "use client";
2
+ import {
3
+ AgentStep
4
+ } from "./chunk-UCJ6IUFS.js";
5
+
6
+ // src/agent-event.tsx
7
+ import { Webhook } from "lucide-react";
8
+ import { forwardRef } from "react";
9
+ import {
10
+ StatusIcon,
11
+ agentEventOutcomeStatus,
12
+ formatElapsed,
13
+ useLocale
14
+ } from "@elabs-ai/components-ui";
15
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
16
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
17
+ function isCheckResultList(checks) {
18
+ return Array.isArray(checks);
19
+ }
20
+ function AgentEventCheckRow({ check }) {
21
+ const { t } = useLocale();
22
+ const { label, ok, detail, durationMs } = check;
23
+ const statusWord = t(ok ? "ai.agentEvent.checkPassed" : "ai.agentEvent.checkFailed");
24
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "agent-event-check", "data-ok": ok, className: "flex flex-col gap-1", children: [
25
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-1.5 gap-y-0.5 min-w-0", children: [
26
+ /* @__PURE__ */ jsx(StatusIcon, { status: ok ? "complete" : "failed", className: "size-3.5 shrink-0" }),
27
+ /* @__PURE__ */ jsx("span", { className: "text-caption font-medium text-foreground truncate", children: label }),
28
+ /* @__PURE__ */ jsx(
29
+ "span",
30
+ {
31
+ "data-slot": "agent-event-check-status",
32
+ className: cn("text-caption", ok ? "text-success-text" : "text-destructive-text"),
33
+ children: statusWord
34
+ }
35
+ ),
36
+ durationMs !== void 0 && /* @__PURE__ */ jsx("span", { className: "text-caption text-muted-foreground tabular-nums shrink-0", children: formatElapsed(durationMs) })
37
+ ] }),
38
+ detail !== void 0 && detail !== "" && /* @__PURE__ */ jsx(
39
+ "p",
40
+ {
41
+ "data-slot": "agent-event-check-detail",
42
+ className: "ps-5 text-caption text-muted-foreground break-words",
43
+ children: detail
44
+ }
45
+ )
46
+ ] });
47
+ }
48
+ function AgentEventChecks({ checks }) {
49
+ const { t } = useLocale();
50
+ if (isCheckResultList(checks)) {
51
+ if (checks.length === 0) return null;
52
+ return /* @__PURE__ */ jsx("div", { "data-slot": "agent-event-checks", className: "flex flex-col gap-1.5", children: checks.map((check, index) => /* @__PURE__ */ jsx(AgentEventCheckRow, { check }, `${check.label}-${index}`)) });
53
+ }
54
+ const { ran, passed } = checks;
55
+ return /* @__PURE__ */ jsx(
56
+ "p",
57
+ {
58
+ "data-slot": "agent-event-checks-summary",
59
+ className: "text-meta text-muted-foreground tabular-nums",
60
+ children: t("ai.agentEvent.checksSummary", { passed, ran })
61
+ }
62
+ );
63
+ }
64
+ var PHASE_KEY = {
65
+ before: "ai.agentEvent.phaseBefore",
66
+ after: "ai.agentEvent.phaseAfter",
67
+ lifecycle: "ai.agentEvent.phaseLifecycle"
68
+ };
69
+ var AgentEvent = forwardRef(function AgentEvent2({ label, phase, outcome = "ok", durationMs, checks, icon: Icon = Webhook, summary, ...props }, ref) {
70
+ const { t } = useLocale();
71
+ const status = agentEventOutcomeStatus(outcome);
72
+ const phaseLabel = phase === void 0 ? void 0 : t(PHASE_KEY[phase]);
73
+ const name = phaseLabel ? /* @__PURE__ */ jsxs(Fragment, { children: [
74
+ label,
75
+ " ",
76
+ /* @__PURE__ */ jsxs("span", { "data-slot": "agent-event-phase", className: "text-meta font-normal text-muted-foreground", children: [
77
+ "\xB7 ",
78
+ phaseLabel
79
+ ] })
80
+ ] }) : label;
81
+ return /* @__PURE__ */ jsx(
82
+ AgentStep,
83
+ {
84
+ ref,
85
+ icon: Icon,
86
+ name,
87
+ status,
88
+ summary,
89
+ timestamp: durationMs === void 0 ? void 0 : formatElapsed(durationMs),
90
+ "data-slot": "agent-event",
91
+ ...props,
92
+ children: checks ? /* @__PURE__ */ jsx(AgentEventChecks, { checks }) : null
93
+ }
94
+ );
95
+ });
96
+ AgentEvent.displayName = "AgentEvent";
97
+
98
+ export {
99
+ AgentEvent
100
+ };
101
+ //# sourceMappingURL=chunk-QJUNPVOS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/agent-event.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * AgentEvent — the lifecycle/hook event line (#109).\n *\n * Nothing in the trace vocabulary (`Message` → `Tool` → `Task`/`AgentStep`)\n * has a place for something the *runtime* did to the agent: a lifecycle hook\n * (`user_prompt_submit`, `stop`) or a policy/guard check\n * (`pre_tool_use`/`post_tool_use`) that fired around a tool call. `AgentEvent`\n * fills that gap as an `AgentStep` VARIANT on the existing `AgentTimeline`\n * rail — not a second spine. It sits in the same `<ol>` as ordinary steps,\n * distinguished by glyph and label rather than by a different layout\n * (docs/decisions/2026-09-01-brainless-adoption-architecture.md § 6, and the\n * `Task`/`TaskItem` precedent this file follows in `./agent-timeline`).\n *\n * `outcome` maps onto the existing closed 7-state `Status` (`@elabs-ai/components-ui`) —\n * no eighth status is introduced. `checks` renders a gate's verdicts: an\n * array renders each check as icon + accessible pass/fail TEXT (never colour\n * alone — the greyscale test in `.claude/rules/accessibility.md`); a count\n * summary renders `passed/ran` as plain text.\n */\nimport { Webhook, type LucideIcon } from \"lucide-react\";\nimport { forwardRef, type ReactNode } from \"react\";\nimport {\n StatusIcon,\n agentEventOutcomeStatus,\n formatElapsed,\n useLocale,\n type AgentEventOutcome,\n type AgentEventPhase,\n type CheckResult,\n type CheckSummary,\n} from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport { AgentStep, type AgentStepProps } from \"./agent-timeline\";\n\n// `AgentEventPhase`, `AgentEventOutcome` and the outcome→`Status` mapping\n// (`agentEventOutcomeStatus`, formerly this file's private `OUTCOME_STATUS`)\n// moved to `@elabs-ai/components-ui` (`lib/agent-event-model.ts`) — the\n// terminal CLI look-alike family's own event line (issue #117) reuses the\n// same model, and `@elabs-ai/components-ai`/`@elabs-ai/components-terminal`\n// are layer-2 DAG siblings that may not import each other (T0; see\n// docs/decisions/2026-09-01-brainless-adoption-architecture.md § 4). Imported\n// above; NOT re-exported from here — a consumer imports `AgentEventPhase`/\n// `AgentEventOutcome` from `@elabs-ai/components-ui`.\n\nexport interface AgentEventProps extends Omit<\n AgentStepProps,\n \"name\" | \"status\" | \"children\" | \"icon\" | \"timestamp\"\n> {\n /** The runtime event name, verbatim as the runtime emits it — e.g. `\"user_prompt_submit\"`, `\"pre_tool_use\"`, `\"stop\"`. */\n label: string;\n /** When this event fired relative to the action it gates. See `AgentEventPhase`. */\n phase?: AgentEventPhase;\n /** The event's verdict. @default \"ok\" */\n outcome?: AgentEventOutcome;\n /** Wall-clock duration of the event, in milliseconds. Rendered with the shared `formatElapsed`. */\n durationMs?: number;\n /** Gate checks the event ran: individual verdicts, or a count summary. */\n checks?: CheckSummary | CheckResult[];\n /** Optional leading glyph on the title row (Lucide). @default Webhook */\n icon?: LucideIcon;\n}\n\nfunction isCheckResultList(checks: CheckSummary | CheckResult[]): checks is CheckResult[] {\n return Array.isArray(checks);\n}\n\n/**\n * A single gate-check verdict row: icon + label + accessible status word +\n * optional duration + optional detail. Mirrors the anatomy of `ChangeReview`'s\n * check row (`packages/ui/src/components/change-review/change-review.tsx`) so\n * the two `CheckResult` surfaces read as one convention — reimplemented here\n * (rather than imported) because that row is a private, unexported function.\n *\n * The pass/fail signal is carried by TWO non-colour cues — `StatusIcon`'s\n * distinct glyph (decorative, `aria-hidden`) and the visible status word\n * (what reaches assistive tech) — so it survives in greyscale (WCAG 1.4.1).\n */\nfunction AgentEventCheckRow({ check }: { check: CheckResult }) {\n const { t } = useLocale();\n const { label, ok, detail, durationMs } = check;\n const statusWord = t(ok ? \"ai.agentEvent.checkPassed\" : \"ai.agentEvent.checkFailed\");\n\n return (\n <div data-slot=\"agent-event-check\" data-ok={ok} className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-x-1.5 gap-y-0.5 min-w-0\">\n <StatusIcon status={ok ? \"complete\" : \"failed\"} className=\"size-3.5 shrink-0\" />\n <span className=\"text-caption font-medium text-foreground truncate\">{label}</span>\n <span\n data-slot=\"agent-event-check-status\"\n className={cn(\"text-caption\", ok ? \"text-success-text\" : \"text-destructive-text\")}\n >\n {statusWord}\n </span>\n {durationMs !== undefined && (\n <span className=\"text-caption text-muted-foreground tabular-nums shrink-0\">\n {formatElapsed(durationMs)}\n </span>\n )}\n </div>\n {detail !== undefined && detail !== \"\" && (\n <p\n data-slot=\"agent-event-check-detail\"\n className=\"ps-5 text-caption text-muted-foreground break-words\"\n >\n {detail}\n </p>\n )}\n </div>\n );\n}\n\n/** The checks section: a flat list of verdict rows, or a `passed/ran` count line. */\nfunction AgentEventChecks({ checks }: { checks: CheckSummary | CheckResult[] }) {\n const { t } = useLocale();\n\n if (isCheckResultList(checks)) {\n if (checks.length === 0) return null;\n return (\n <div data-slot=\"agent-event-checks\" className=\"flex flex-col gap-1.5\">\n {checks.map((check, index) => (\n <AgentEventCheckRow key={`${check.label}-${index}`} check={check} />\n ))}\n </div>\n );\n }\n\n const { ran, passed } = checks;\n return (\n <p\n data-slot=\"agent-event-checks-summary\"\n className=\"text-meta text-muted-foreground tabular-nums\"\n >\n {t(\"ai.agentEvent.checksSummary\", { passed, ran })}\n </p>\n );\n}\n\nconst PHASE_KEY: Record<AgentEventPhase, string> = {\n before: \"ai.agentEvent.phaseBefore\",\n after: \"ai.agentEvent.phaseAfter\",\n lifecycle: \"ai.agentEvent.phaseLifecycle\",\n};\n\n/**\n * One lifecycle/hook event line on the `AgentTimeline` rail — an `AgentStep`\n * variant, never a second spine. Composes `AgentStep` exactly as `TaskItem`\n * does in `./agent-timeline`, so it rides the same `TimelineRoot`/`TimelineItem`\n * primitives every other trace entry uses.\n */\nexport const AgentEvent = forwardRef<HTMLLIElement, AgentEventProps>(function AgentEvent(\n { label, phase, outcome = \"ok\", durationMs, checks, icon: Icon = Webhook, summary, ...props },\n ref,\n) {\n const { t } = useLocale();\n const status = agentEventOutcomeStatus(outcome);\n const phaseLabel = phase === undefined ? undefined : t(PHASE_KEY[phase]);\n\n const name: ReactNode = phaseLabel ? (\n <>\n {label}{\" \"}\n <span data-slot=\"agent-event-phase\" className=\"text-meta font-normal text-muted-foreground\">\n · {phaseLabel}\n </span>\n </>\n ) : (\n label\n );\n\n return (\n <AgentStep\n ref={ref}\n icon={Icon}\n name={name}\n status={status}\n summary={summary}\n timestamp={durationMs === undefined ? undefined : formatElapsed(durationMs)}\n data-slot=\"agent-event\"\n {...props}\n >\n {checks ? <AgentEventChecks checks={checks} /> : null}\n </AgentStep>\n );\n});\n\nAgentEvent.displayName = \"AgentEvent\";\n"],"mappings":";;;;;;AAqBA,SAAS,eAAgC;AACzC,SAAS,kBAAkC;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AACP,SAAS,UAAU;AAqDb,SA0EF,UAzEI,KADF;AAtBN,SAAS,kBAAkB,QAA+D;AACxF,SAAO,MAAM,QAAQ,MAAM;AAC7B;AAaA,SAAS,mBAAmB,EAAE,MAAM,GAA2B;AAC7D,QAAM,EAAE,EAAE,IAAI,UAAU;AACxB,QAAM,EAAE,OAAO,IAAI,QAAQ,WAAW,IAAI;AAC1C,QAAM,aAAa,EAAE,KAAK,8BAA8B,2BAA2B;AAEnF,SACE,qBAAC,SAAI,aAAU,qBAAoB,WAAS,IAAI,WAAU,uBACxD;AAAA,yBAAC,SAAI,WAAU,2DACb;AAAA,0BAAC,cAAW,QAAQ,KAAK,aAAa,UAAU,WAAU,qBAAoB;AAAA,MAC9E,oBAAC,UAAK,WAAU,qDAAqD,iBAAM;AAAA,MAC3E;AAAA,QAAC;AAAA;AAAA,UACC,aAAU;AAAA,UACV,WAAW,GAAG,gBAAgB,KAAK,sBAAsB,uBAAuB;AAAA,UAE/E;AAAA;AAAA,MACH;AAAA,MACC,eAAe,UACd,oBAAC,UAAK,WAAU,4DACb,wBAAc,UAAU,GAC3B;AAAA,OAEJ;AAAA,IACC,WAAW,UAAa,WAAW,MAClC;AAAA,MAAC;AAAA;AAAA,QACC,aAAU;AAAA,QACV,WAAU;AAAA,QAET;AAAA;AAAA,IACH;AAAA,KAEJ;AAEJ;AAGA,SAAS,iBAAiB,EAAE,OAAO,GAA6C;AAC9E,QAAM,EAAE,EAAE,IAAI,UAAU;AAExB,MAAI,kBAAkB,MAAM,GAAG;AAC7B,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,WACE,oBAAC,SAAI,aAAU,sBAAqB,WAAU,yBAC3C,iBAAO,IAAI,CAAC,OAAO,UAClB,oBAAC,sBAAmD,SAA3B,GAAG,MAAM,KAAK,IAAI,KAAK,EAAkB,CACnE,GACH;AAAA,EAEJ;AAEA,QAAM,EAAE,KAAK,OAAO,IAAI;AACxB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAU;AAAA,MAET,YAAE,+BAA+B,EAAE,QAAQ,IAAI,CAAC;AAAA;AAAA,EACnD;AAEJ;AAEA,IAAM,YAA6C;AAAA,EACjD,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,WAAW;AACb;AAQO,IAAM,aAAa,WAA2C,SAASA,YAC5E,EAAE,OAAO,OAAO,UAAU,MAAM,YAAY,QAAQ,MAAM,OAAO,SAAS,SAAS,GAAG,MAAM,GAC5F,KACA;AACA,QAAM,EAAE,EAAE,IAAI,UAAU;AACxB,QAAM,SAAS,wBAAwB,OAAO;AAC9C,QAAM,aAAa,UAAU,SAAY,SAAY,EAAE,UAAU,KAAK,CAAC;AAEvE,QAAM,OAAkB,aACtB,iCACG;AAAA;AAAA,IAAO;AAAA,IACR,qBAAC,UAAK,aAAU,qBAAoB,WAAU,+CAA8C;AAAA;AAAA,MACvF;AAAA,OACL;AAAA,KACF,IAEA;AAGF,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,eAAe,SAAY,SAAY,cAAc,UAAU;AAAA,MAC1E,aAAU;AAAA,MACT,GAAG;AAAA,MAEH,mBAAS,oBAAC,oBAAiB,QAAgB,IAAK;AAAA;AAAA,EACnD;AAEJ,CAAC;AAED,WAAW,cAAc;","names":["AgentEvent"]}