@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,245 @@
1
+ "use client";
2
+
3
+ // src/web-preview.tsx
4
+ import { Button } from "@elabs-ai/components-ui";
5
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@elabs-ai/components-ui";
6
+ import { Input } from "@elabs-ai/components-ui";
7
+ import { Skeleton } from "@elabs-ai/components-ui";
8
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@elabs-ai/components-ui";
9
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
10
+ import { useLocale } from "@elabs-ai/components-ui";
11
+ import { ChevronDownIcon } from "lucide-react";
12
+ import { createContext, useCallback, useContext, useMemo, useState } from "react";
13
+ import { jsx, jsxs } from "react/jsx-runtime";
14
+ var WebPreviewContext = createContext(null);
15
+ var useWebPreview = () => {
16
+ const context = useContext(WebPreviewContext);
17
+ if (!context) {
18
+ throw new Error("WebPreview components must be used within a WebPreview");
19
+ }
20
+ return context;
21
+ };
22
+ var WebPreview = ({
23
+ className,
24
+ children,
25
+ defaultUrl = "",
26
+ onUrlChange,
27
+ ...props
28
+ }) => {
29
+ const [url, setUrl] = useState(defaultUrl);
30
+ const [consoleOpen, setConsoleOpen] = useState(false);
31
+ const handleUrlChange = useCallback(
32
+ (newUrl) => {
33
+ setUrl(newUrl);
34
+ onUrlChange?.(newUrl);
35
+ },
36
+ [onUrlChange]
37
+ );
38
+ const contextValue = useMemo(
39
+ () => ({
40
+ consoleOpen,
41
+ setConsoleOpen,
42
+ setUrl: handleUrlChange,
43
+ url
44
+ }),
45
+ [consoleOpen, handleUrlChange, url]
46
+ );
47
+ return /* @__PURE__ */ jsx(WebPreviewContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
48
+ "div",
49
+ {
50
+ className: cn("flex size-full flex-col rounded-lg border bg-card", className),
51
+ ...props,
52
+ children
53
+ }
54
+ ) });
55
+ };
56
+ var WebPreviewNavigation = ({
57
+ className,
58
+ children,
59
+ ...props
60
+ }) => /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-1 border-b p-2", className), ...props, children });
61
+ var WebPreviewNavigationButton = ({
62
+ onClick,
63
+ disabled,
64
+ tooltip,
65
+ children,
66
+ ...props
67
+ }) => /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
68
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
69
+ Button,
70
+ {
71
+ "aria-label": tooltip,
72
+ className: "h-8 w-8 p-0 hover:text-foreground",
73
+ disabled,
74
+ onClick,
75
+ size: "sm",
76
+ variant: "ghost",
77
+ ...props,
78
+ children
79
+ }
80
+ ) }),
81
+ /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: tooltip }) })
82
+ ] }) });
83
+ var WebPreviewUrl = ({ value, onChange, onKeyDown, ...props }) => {
84
+ const { t } = useLocale();
85
+ const { url, setUrl } = useWebPreview();
86
+ const [prevUrl, setPrevUrl] = useState(url);
87
+ const [inputValue, setInputValue] = useState(url);
88
+ if (url !== prevUrl) {
89
+ setPrevUrl(url);
90
+ setInputValue(url);
91
+ }
92
+ const handleChange = (event) => {
93
+ setInputValue(event.target.value);
94
+ onChange?.(event);
95
+ };
96
+ const handleKeyDown = useCallback(
97
+ (event) => {
98
+ if (event.key === "Enter") {
99
+ const target = event.target;
100
+ setUrl(target.value);
101
+ }
102
+ onKeyDown?.(event);
103
+ },
104
+ [setUrl, onKeyDown]
105
+ );
106
+ return /* @__PURE__ */ jsx(
107
+ Input,
108
+ {
109
+ className: "h-8 flex-1 text-body",
110
+ onChange: onChange ?? handleChange,
111
+ onKeyDown: handleKeyDown,
112
+ placeholder: t("ai.webPreview.urlPlaceholder"),
113
+ value: value ?? inputValue,
114
+ ...props
115
+ }
116
+ );
117
+ };
118
+ var WebPreviewBody = ({
119
+ className,
120
+ loading,
121
+ src,
122
+ allowSameOrigin = false,
123
+ ...props
124
+ }) => {
125
+ const { url } = useWebPreview();
126
+ const { t } = useLocale();
127
+ const sandbox = [
128
+ "allow-scripts",
129
+ "allow-forms",
130
+ "allow-popups",
131
+ "allow-presentation",
132
+ allowSameOrigin && "allow-same-origin"
133
+ ].filter(Boolean).join(" ");
134
+ return /* @__PURE__ */ jsxs("div", { className: "relative flex-1", children: [
135
+ /* @__PURE__ */ jsx(
136
+ "iframe",
137
+ {
138
+ className: cn("size-full", className),
139
+ sandbox,
140
+ src: (src ?? url) || void 0,
141
+ title: t("ai.webPreview.previewTitle"),
142
+ ...props
143
+ }
144
+ ),
145
+ loading === true ? /* @__PURE__ */ jsxs(
146
+ "div",
147
+ {
148
+ className: "absolute inset-0 flex flex-col gap-2 bg-card p-4",
149
+ role: "status",
150
+ "aria-live": "polite",
151
+ children: [
152
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: t("loading") }),
153
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-1/3" }),
154
+ /* @__PURE__ */ jsx(Skeleton, { className: "flex-1" })
155
+ ]
156
+ }
157
+ ) : loading
158
+ ] });
159
+ };
160
+ var WebPreviewConsole = ({
161
+ className,
162
+ logs = [],
163
+ children,
164
+ ...props
165
+ }) => {
166
+ const { consoleOpen, setConsoleOpen } = useWebPreview();
167
+ const { t, formatDate } = useLocale();
168
+ return /* @__PURE__ */ jsxs(
169
+ Collapsible,
170
+ {
171
+ className: cn("border-t bg-muted/50 font-mono text-body", className),
172
+ onOpenChange: setConsoleOpen,
173
+ open: consoleOpen,
174
+ ...props,
175
+ children: [
176
+ /* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
177
+ Button,
178
+ {
179
+ className: "flex w-full items-center justify-between p-4 text-start font-medium hover:bg-muted/50",
180
+ variant: "ghost",
181
+ children: [
182
+ "Console",
183
+ /* @__PURE__ */ jsx(
184
+ ChevronDownIcon,
185
+ {
186
+ className: cn(
187
+ "h-4 w-4 transition-transform duration-base ease-standard",
188
+ consoleOpen && "rotate-180"
189
+ )
190
+ }
191
+ )
192
+ ]
193
+ }
194
+ ) }),
195
+ /* @__PURE__ */ jsx(
196
+ CollapsibleContent,
197
+ {
198
+ className: cn(
199
+ "px-4 pb-4",
200
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 outline-none data-[state=closed]:animate-out data-[state=open]:animate-in"
201
+ ),
202
+ children: /* @__PURE__ */ jsxs("div", { className: "max-h-48 space-y-1 overflow-y-auto", children: [
203
+ logs.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: t("ai.webPreview.noConsoleOutput") }) : logs.map((log) => /* @__PURE__ */ jsxs(
204
+ "div",
205
+ {
206
+ className: cn(
207
+ "text-meta",
208
+ // #124: console log lines are running text — ink rung, not
209
+ // the mark rung. `text-yellow-600` was also a raw, untokened
210
+ // Tailwind palette colour (styling-and-tokens.md); replaced
211
+ // with the warning tone's own ink rung.
212
+ log.level === "error" && "text-destructive-text",
213
+ log.level === "warn" && "text-warning-text",
214
+ log.level === "log" && "text-foreground"
215
+ ),
216
+ children: [
217
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: formatDate(log.timestamp, {
218
+ hour: "2-digit",
219
+ minute: "2-digit",
220
+ second: "2-digit"
221
+ }) }),
222
+ " ",
223
+ log.message
224
+ ]
225
+ },
226
+ `${log.timestamp.getTime()}-${log.level}-${log.message}`
227
+ )),
228
+ children
229
+ ] })
230
+ }
231
+ )
232
+ ]
233
+ }
234
+ );
235
+ };
236
+
237
+ export {
238
+ WebPreview,
239
+ WebPreviewNavigation,
240
+ WebPreviewNavigationButton,
241
+ WebPreviewUrl,
242
+ WebPreviewBody,
243
+ WebPreviewConsole
244
+ };
245
+ //# sourceMappingURL=chunk-TZ6TB7VM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/web-preview.tsx"],"sourcesContent":["\"use client\";\n\nimport { Button } from \"@elabs-ai/components-ui\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"@elabs-ai/components-ui\";\nimport { Input } from \"@elabs-ai/components-ui\";\nimport { Skeleton } from \"@elabs-ai/components-ui\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport { useLocale } from \"@elabs-ai/components-ui\";\nimport { ChevronDownIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { createContext, useCallback, useContext, useMemo, useState } from \"react\";\n\nexport interface WebPreviewContextValue {\n url: string;\n setUrl: (url: string) => void;\n consoleOpen: boolean;\n setConsoleOpen: (open: boolean) => void;\n}\n\nconst WebPreviewContext = createContext<WebPreviewContextValue | null>(null);\n\nconst useWebPreview = () => {\n const context = useContext(WebPreviewContext);\n if (!context) {\n throw new Error(\"WebPreview components must be used within a WebPreview\");\n }\n return context;\n};\n\nexport type WebPreviewProps = ComponentProps<\"div\"> & {\n defaultUrl?: string;\n onUrlChange?: (url: string) => void;\n};\n\nexport const WebPreview = ({\n className,\n children,\n defaultUrl = \"\",\n onUrlChange,\n ...props\n}: WebPreviewProps) => {\n const [url, setUrl] = useState(defaultUrl);\n const [consoleOpen, setConsoleOpen] = useState(false);\n\n const handleUrlChange = useCallback(\n (newUrl: string) => {\n setUrl(newUrl);\n onUrlChange?.(newUrl);\n },\n [onUrlChange],\n );\n\n const contextValue = useMemo<WebPreviewContextValue>(\n () => ({\n consoleOpen,\n setConsoleOpen,\n setUrl: handleUrlChange,\n url,\n }),\n [consoleOpen, handleUrlChange, url],\n );\n\n return (\n <WebPreviewContext.Provider value={contextValue}>\n <div\n className={cn(\"flex size-full flex-col rounded-lg border bg-card\", className)}\n {...props}\n >\n {children}\n </div>\n </WebPreviewContext.Provider>\n );\n};\n\nexport type WebPreviewNavigationProps = ComponentProps<\"div\">;\n\nexport const WebPreviewNavigation = ({\n className,\n children,\n ...props\n}: WebPreviewNavigationProps) => (\n <div className={cn(\"flex items-center gap-1 border-b p-2\", className)} {...props}>\n {children}\n </div>\n);\n\nexport type WebPreviewNavigationButtonProps = ComponentProps<typeof Button> & {\n tooltip?: string;\n};\n\nexport const WebPreviewNavigationButton = ({\n onClick,\n disabled,\n tooltip,\n children,\n ...props\n}: WebPreviewNavigationButtonProps) => (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n // These buttons are icon-only, and a Radix tooltip only contributes\n // `aria-describedby` while it is OPEN — so at rest the control had no\n // accessible name at all and axe's `button-name` red every story that\n // mounted one (#386). The tooltip text IS the name; spreading\n // `...props` afterwards keeps an explicit `aria-label` winning, and a\n // button that ships real text children keeps its own content as the\n // name because `tooltip` is then undefined. Mirrors `MessageAction`'s\n // `sr-only` label in message.tsx.\n aria-label={tooltip}\n className=\"h-8 w-8 p-0 hover:text-foreground\"\n disabled={disabled}\n onClick={onClick}\n size=\"sm\"\n variant=\"ghost\"\n {...props}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n <p>{tooltip}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n);\n\nexport type WebPreviewUrlProps = ComponentProps<typeof Input>;\n\nexport const WebPreviewUrl = ({ value, onChange, onKeyDown, ...props }: WebPreviewUrlProps) => {\n const { t } = useLocale();\n const { url, setUrl } = useWebPreview();\n const [prevUrl, setPrevUrl] = useState(url);\n const [inputValue, setInputValue] = useState(url);\n\n // Sync input value with context URL when it changes externally (derived state pattern)\n if (url !== prevUrl) {\n setPrevUrl(url);\n setInputValue(url);\n }\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setInputValue(event.target.value);\n onChange?.(event);\n };\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"Enter\") {\n const target = event.target as HTMLInputElement;\n setUrl(target.value);\n }\n onKeyDown?.(event);\n },\n [setUrl, onKeyDown],\n );\n\n return (\n <Input\n className=\"h-8 flex-1 text-body\"\n onChange={onChange ?? handleChange}\n onKeyDown={handleKeyDown}\n placeholder={t(\"ai.webPreview.urlPlaceholder\")}\n value={value ?? inputValue}\n {...props}\n />\n );\n};\n\nexport type WebPreviewBodyProps = Omit<ComponentProps<\"iframe\">, \"loading\"> & {\n /**\n * Not-ready placeholder over the iframe (loading-states.md `loading`\n * signal). Pass `true` for the default layout-shaped Skeleton filling the\n * iframe box, or a ReactNode to override with custom placeholder content.\n * `false`/`undefined` (default) renders nothing. Shadows (rather than\n * forwards) the native `<iframe loading=\"eager\"|\"lazy\">` attribute — this\n * component's box is always fully reserved, so lazy-loading the iframe\n * itself is not a use case here.\n * @default false\n */\n loading?: boolean | ReactNode;\n /**\n * Adds `allow-same-origin` to the iframe sandbox. **Opt-in, off by\n * default**: combined with `allow-scripts`, a same-origin previewed page\n * can script its way out of the sandbox restrictions entirely (its own\n * `<iframe>` reads as unsandboxed once it shares the origin). Only enable\n * this for content you trust to be same-origin-safe.\n * @default false\n */\n allowSameOrigin?: boolean;\n};\n\nexport const WebPreviewBody = ({\n className,\n loading,\n src,\n allowSameOrigin = false,\n ...props\n}: WebPreviewBodyProps) => {\n const { url } = useWebPreview();\n const { t } = useLocale();\n\n const sandbox = [\n \"allow-scripts\",\n \"allow-forms\",\n \"allow-popups\",\n \"allow-presentation\",\n allowSameOrigin && \"allow-same-origin\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className=\"relative flex-1\">\n <iframe\n className={cn(\"size-full\", className)}\n // oxlint-disable-next-line eslint-plugin-react(iframe-missing-sandbox)\n sandbox={sandbox}\n src={(src ?? url) || undefined}\n title={t(\"ai.webPreview.previewTitle\")}\n {...props}\n />\n {loading === true ? (\n <div\n className=\"absolute inset-0 flex flex-col gap-2 bg-card p-4\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <span className=\"sr-only\">{t(\"loading\")}</span>\n <Skeleton className=\"h-4 w-1/3\" />\n <Skeleton className=\"flex-1\" />\n </div>\n ) : (\n loading\n )}\n </div>\n );\n};\n\nexport type WebPreviewConsoleProps = ComponentProps<\"div\"> & {\n logs?: {\n level: \"log\" | \"warn\" | \"error\";\n message: string;\n timestamp: Date;\n }[];\n};\n\nexport const WebPreviewConsole = ({\n className,\n logs = [],\n children,\n ...props\n}: WebPreviewConsoleProps) => {\n const { consoleOpen, setConsoleOpen } = useWebPreview();\n const { t, formatDate } = useLocale();\n\n return (\n <Collapsible\n className={cn(\"border-t bg-muted/50 font-mono text-body\", className)}\n onOpenChange={setConsoleOpen}\n open={consoleOpen}\n {...props}\n >\n <CollapsibleTrigger asChild>\n <Button\n className=\"flex w-full items-center justify-between p-4 text-start font-medium hover:bg-muted/50\"\n variant=\"ghost\"\n >\n Console\n <ChevronDownIcon\n className={cn(\n \"h-4 w-4 transition-transform duration-base ease-standard\",\n consoleOpen && \"rotate-180\",\n )}\n />\n </Button>\n </CollapsibleTrigger>\n <CollapsibleContent\n className={cn(\n \"px-4 pb-4\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\",\n )}\n >\n <div className=\"max-h-48 space-y-1 overflow-y-auto\">\n {logs.length === 0 ? (\n <p className=\"text-muted-foreground\">{t(\"ai.webPreview.noConsoleOutput\")}</p>\n ) : (\n logs.map((log) => (\n <div\n className={cn(\n \"text-meta\",\n // #124: console log lines are running text — ink rung, not\n // the mark rung. `text-yellow-600` was also a raw, untokened\n // Tailwind palette colour (styling-and-tokens.md); replaced\n // with the warning tone's own ink rung.\n log.level === \"error\" && \"text-destructive-text\",\n log.level === \"warn\" && \"text-warning-text\",\n log.level === \"log\" && \"text-foreground\",\n )}\n key={`${log.timestamp.getTime()}-${log.level}-${log.message}`}\n >\n <span className=\"text-muted-foreground\">\n {formatDate(log.timestamp, {\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n })}\n </span>{\" \"}\n {log.message}\n </div>\n ))\n )}\n {children}\n </div>\n </CollapsibleContent>\n </Collapsible>\n );\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,278 @@
1
+ "use client";
2
+
3
+ // src/file-tree.tsx
4
+ import {
5
+ Collapsible,
6
+ CollapsibleContent,
7
+ CollapsibleTrigger,
8
+ fileIconFor,
9
+ useLocale
10
+ } from "@elabs-ai/components-ui";
11
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
12
+ import { cva } from "class-variance-authority";
13
+ import {
14
+ ChevronRightIcon,
15
+ DatabaseIcon,
16
+ FileCode2Icon,
17
+ FileIcon,
18
+ FileTextIcon,
19
+ FolderIcon,
20
+ FolderOpenIcon,
21
+ ImageIcon,
22
+ TableIcon
23
+ } from "lucide-react";
24
+ import { createContext, forwardRef, useCallback, useContext, useMemo, useState } from "react";
25
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
26
+ var noop = () => {
27
+ };
28
+ var FileTreeContext = createContext({
29
+ // oxlint-disable-next-line eslint-plugin-unicorn(no-new-builtin)
30
+ expandedPaths: /* @__PURE__ */ new Set(),
31
+ togglePath: noop
32
+ });
33
+ var fileTreeVariants = cva("", {
34
+ variants: {
35
+ variant: {
36
+ code: "rounded-lg border bg-background font-mono text-body",
37
+ document: "text-body"
38
+ }
39
+ },
40
+ defaultVariants: { variant: "code" }
41
+ });
42
+ var FileTree = forwardRef(function FileTree2({
43
+ expanded: controlledExpanded,
44
+ defaultExpanded = /* @__PURE__ */ new Set(),
45
+ selectedPath,
46
+ onSelect,
47
+ onExpandedChange,
48
+ variant,
49
+ className,
50
+ children,
51
+ ...props
52
+ }, ref) {
53
+ const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);
54
+ const expandedPaths = controlledExpanded ?? internalExpanded;
55
+ const togglePath = useCallback(
56
+ (path) => {
57
+ const newExpanded = new Set(expandedPaths);
58
+ if (newExpanded.has(path)) {
59
+ newExpanded.delete(path);
60
+ } else {
61
+ newExpanded.add(path);
62
+ }
63
+ setInternalExpanded(newExpanded);
64
+ onExpandedChange?.(newExpanded);
65
+ },
66
+ [expandedPaths, onExpandedChange]
67
+ );
68
+ const contextValue = useMemo(
69
+ () => ({ expandedPaths, onSelect, selectedPath, togglePath }),
70
+ [expandedPaths, onSelect, selectedPath, togglePath]
71
+ );
72
+ return /* @__PURE__ */ jsx(FileTreeContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
73
+ "div",
74
+ {
75
+ ref,
76
+ className: cn(fileTreeVariants({ variant }), className),
77
+ role: "tree",
78
+ ...props,
79
+ children: /* @__PURE__ */ jsx("div", { className: cn(variant === "document" ? void 0 : "p-2"), children })
80
+ }
81
+ ) });
82
+ });
83
+ var FileTreeIcon = ({ className, children, ...props }) => /* @__PURE__ */ jsx("span", { className: cn("shrink-0", className), ...props, children });
84
+ var FileTreeName = ({ className, children, ...props }) => /* @__PURE__ */ jsx("span", { className: cn("truncate", className), ...props, children });
85
+ var FileTreeFolderContext = createContext({
86
+ isExpanded: false,
87
+ name: "",
88
+ path: ""
89
+ });
90
+ var FileTreeFolder = ({
91
+ path,
92
+ name,
93
+ className,
94
+ children,
95
+ ...props
96
+ }) => {
97
+ const { t } = useLocale();
98
+ const { expandedPaths, togglePath, selectedPath, onSelect } = useContext(FileTreeContext);
99
+ const isExpanded = expandedPaths.has(path);
100
+ const isSelected = selectedPath === path;
101
+ const handleOpenChange = useCallback(() => {
102
+ togglePath(path);
103
+ }, [togglePath, path]);
104
+ const handleSelect = useCallback(() => {
105
+ onSelect?.(path);
106
+ }, [onSelect, path]);
107
+ const folderContextValue = useMemo(() => ({ isExpanded, name, path }), [isExpanded, name, path]);
108
+ return /* @__PURE__ */ jsx(FileTreeFolderContext.Provider, { value: folderContextValue, children: /* @__PURE__ */ jsx(Collapsible, { onOpenChange: handleOpenChange, open: isExpanded, children: /* @__PURE__ */ jsxs("div", { className: cn("", className), role: "treeitem", tabIndex: 0, ...props, children: [
109
+ /* @__PURE__ */ jsxs(
110
+ "div",
111
+ {
112
+ className: cn(
113
+ "flex w-full items-center gap-1 rounded px-2 py-1 text-start transition-colors hover:bg-muted/50",
114
+ isSelected && "bg-muted"
115
+ ),
116
+ children: [
117
+ /* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
118
+ "button",
119
+ {
120
+ "aria-label": t(
121
+ isExpanded ? "ai.fileTree.collapseFolder" : "ai.fileTree.expandFolder",
122
+ { name }
123
+ ),
124
+ className: "flex shrink-0 cursor-pointer items-center border-none bg-transparent p-0",
125
+ type: "button",
126
+ children: /* @__PURE__ */ jsx(
127
+ ChevronRightIcon,
128
+ {
129
+ "aria-hidden": "true",
130
+ className: cn(
131
+ "size-4 shrink-0 text-muted-foreground transition-transform",
132
+ isExpanded && "rotate-90"
133
+ ),
134
+ "data-rtl-flip": true
135
+ }
136
+ )
137
+ }
138
+ ) }),
139
+ /* @__PURE__ */ jsxs(
140
+ "button",
141
+ {
142
+ className: "flex min-w-0 flex-1 cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-start",
143
+ onClick: handleSelect,
144
+ type: "button",
145
+ children: [
146
+ /* @__PURE__ */ jsx(FileTreeIcon, { children: isExpanded ? /* @__PURE__ */ jsx(FolderOpenIcon, { className: "size-4 text-primary" }) : /* @__PURE__ */ jsx(FolderIcon, { className: "size-4 text-primary" }) }),
147
+ /* @__PURE__ */ jsx(FileTreeName, { children: name })
148
+ ]
149
+ }
150
+ )
151
+ ]
152
+ }
153
+ ),
154
+ /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", { className: "ms-4 border-s ps-2", children }) })
155
+ ] }) }) });
156
+ };
157
+ var FileTreeFileContext = createContext({
158
+ name: "",
159
+ path: ""
160
+ });
161
+ var FileTreeFile = ({
162
+ path,
163
+ name,
164
+ icon,
165
+ className,
166
+ children,
167
+ ...props
168
+ }) => {
169
+ const { selectedPath, onSelect } = useContext(FileTreeContext);
170
+ const isSelected = selectedPath === path;
171
+ const handleClick = useCallback(() => {
172
+ onSelect?.(path);
173
+ }, [onSelect, path]);
174
+ const handleKeyDown = useCallback(
175
+ (e) => {
176
+ if (e.key === "Enter" || e.key === " ") {
177
+ onSelect?.(path);
178
+ }
179
+ },
180
+ [onSelect, path]
181
+ );
182
+ const fileContextValue = useMemo(() => ({ name, path }), [name, path]);
183
+ return /* @__PURE__ */ jsx(FileTreeFileContext.Provider, { value: fileContextValue, children: /* @__PURE__ */ jsx(
184
+ "div",
185
+ {
186
+ className: cn(
187
+ "flex cursor-pointer items-center gap-1 rounded px-2 py-1 transition-colors hover:bg-muted/50",
188
+ isSelected && "bg-muted",
189
+ className
190
+ ),
191
+ onClick: handleClick,
192
+ onKeyDown: handleKeyDown,
193
+ role: "treeitem",
194
+ tabIndex: 0,
195
+ ...props,
196
+ children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
197
+ /* @__PURE__ */ jsx("span", { className: "size-4 shrink-0" }),
198
+ /* @__PURE__ */ jsx(FileTreeIcon, { children: icon ?? /* @__PURE__ */ jsx(FileIcon, { className: "size-4 text-muted-foreground" }) }),
199
+ /* @__PURE__ */ jsx(FileTreeName, { children: name })
200
+ ] })
201
+ }
202
+ ) });
203
+ };
204
+ var stopPropagation = (e) => e.stopPropagation();
205
+ var FileTreeActions = ({ className, children, ...props }) => /* @__PURE__ */ jsx(
206
+ "div",
207
+ {
208
+ className: cn("ms-auto flex items-center gap-1", className),
209
+ onClick: stopPropagation,
210
+ onKeyDown: stopPropagation,
211
+ role: "group",
212
+ ...props,
213
+ children
214
+ }
215
+ );
216
+ var PRODUCED_ASSET_ICONS = {
217
+ markdown: FileTextIcon,
218
+ code: FileCode2Icon,
219
+ sql: DatabaseIcon,
220
+ csv: TableIcon,
221
+ image: ImageIcon
222
+ };
223
+ function assetIcon(asset) {
224
+ return asset.source ? fileIconFor(asset.name, asset.mediaType) : PRODUCED_ASSET_ICONS[asset.type];
225
+ }
226
+ var ProducedAssetTree = forwardRef(
227
+ function ProducedAssetTree2({ assets, selectedId, onSelect, ...props }, ref) {
228
+ const { t } = useLocale();
229
+ const assetsById = useMemo(() => new Map(assets.map((asset) => [asset.id, asset])), [assets]);
230
+ const handleSelect = useCallback(
231
+ (path) => {
232
+ const asset = assetsById.get(path);
233
+ if (asset) onSelect?.(asset);
234
+ },
235
+ [assetsById, onSelect]
236
+ );
237
+ if (assets.length === 0) {
238
+ return /* @__PURE__ */ jsx(
239
+ "div",
240
+ {
241
+ ref,
242
+ "data-slot": "file-tree-empty",
243
+ className: cn("px-2 py-1 text-body text-muted-foreground", props.className),
244
+ children: t("ai.fileTree.noAssetsProduced")
245
+ }
246
+ );
247
+ }
248
+ return /* @__PURE__ */ jsx(
249
+ FileTree,
250
+ {
251
+ ref,
252
+ variant: "document",
253
+ selectedPath: selectedId,
254
+ onSelect: handleSelect,
255
+ ...props,
256
+ children: assets.map((asset) => {
257
+ const Icon = assetIcon(asset);
258
+ return /* @__PURE__ */ jsxs(FileTreeFile, { path: asset.id, name: asset.name, children: [
259
+ /* @__PURE__ */ jsx(FileTreeIcon, { children: /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true", className: "size-4 text-muted-foreground" }) }),
260
+ /* @__PURE__ */ jsx(FileTreeName, { children: asset.name })
261
+ ] }, asset.id);
262
+ })
263
+ }
264
+ );
265
+ }
266
+ );
267
+
268
+ export {
269
+ FileTree,
270
+ FileTreeIcon,
271
+ FileTreeName,
272
+ FileTreeFolder,
273
+ FileTreeFile,
274
+ FileTreeActions,
275
+ PRODUCED_ASSET_ICONS,
276
+ ProducedAssetTree
277
+ };
278
+ //# sourceMappingURL=chunk-UBLKJJ7K.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/file-tree.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n fileIconFor,\n useLocale,\n} from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport type { LucideIcon } from \"lucide-react\";\nimport {\n ChevronRightIcon,\n DatabaseIcon,\n FileCode2Icon,\n FileIcon,\n FileTextIcon,\n FolderIcon,\n FolderOpenIcon,\n ImageIcon,\n TableIcon,\n} from \"lucide-react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { createContext, forwardRef, useCallback, useContext, useMemo, useState } from \"react\";\nimport type { ContextAsset, ContextAssetType } from \"./context-panel\";\n\ninterface FileTreeContextType {\n expandedPaths: Set<string>;\n togglePath: (path: string) => void;\n selectedPath?: string;\n onSelect?: (path: string) => void;\n}\n\n// Default noop for context default value\n// oxlint-disable-next-line eslint(no-empty-function)\nconst noop = () => {};\n\nconst FileTreeContext = createContext<FileTreeContextType>({\n // oxlint-disable-next-line eslint-plugin-unicorn(no-new-builtin)\n expandedPaths: new Set(),\n togglePath: noop,\n});\n\n/**\n * Visual axis (#193, research 04 §4 ASSET-1): `code` (default, unchanged) is\n * the IDE source tree — mono + hard box; `document` is the produced-asset\n * look — sans body role, no box (section label + spacing separate it,\n * research 08), for trees of documents rather than source files.\n */\nconst fileTreeVariants = cva(\"\", {\n variants: {\n variant: {\n code: \"rounded-lg border bg-background font-mono text-body\",\n document: \"text-body\",\n },\n },\n defaultVariants: { variant: \"code\" },\n});\n\nexport type FileTreeVariant = NonNullable<VariantProps<typeof fileTreeVariants>[\"variant\"]>;\n\nexport type FileTreeProps = Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\"> &\n VariantProps<typeof fileTreeVariants> & {\n expanded?: Set<string>;\n defaultExpanded?: Set<string>;\n selectedPath?: string;\n onSelect?: (path: string) => void;\n onExpandedChange?: (expanded: Set<string>) => void;\n };\n\nexport const FileTree = forwardRef<HTMLDivElement, FileTreeProps>(function FileTree(\n {\n expanded: controlledExpanded,\n defaultExpanded = new Set(),\n selectedPath,\n onSelect,\n onExpandedChange,\n variant,\n className,\n children,\n ...props\n },\n ref,\n) {\n const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);\n const expandedPaths = controlledExpanded ?? internalExpanded;\n\n const togglePath = useCallback(\n (path: string) => {\n const newExpanded = new Set(expandedPaths);\n if (newExpanded.has(path)) {\n newExpanded.delete(path);\n } else {\n newExpanded.add(path);\n }\n setInternalExpanded(newExpanded);\n onExpandedChange?.(newExpanded);\n },\n [expandedPaths, onExpandedChange],\n );\n\n const contextValue = useMemo(\n () => ({ expandedPaths, onSelect, selectedPath, togglePath }),\n [expandedPaths, onSelect, selectedPath, togglePath],\n );\n\n return (\n <FileTreeContext.Provider value={contextValue}>\n <div\n ref={ref}\n className={cn(fileTreeVariants({ variant }), className)}\n role=\"tree\"\n {...props}\n >\n <div className={cn(variant === \"document\" ? undefined : \"p-2\")}>{children}</div>\n </div>\n </FileTreeContext.Provider>\n );\n});\n\nexport type FileTreeIconProps = HTMLAttributes<HTMLSpanElement>;\n\nexport const FileTreeIcon = ({ className, children, ...props }: FileTreeIconProps) => (\n <span className={cn(\"shrink-0\", className)} {...props}>\n {children}\n </span>\n);\n\nexport type FileTreeNameProps = HTMLAttributes<HTMLSpanElement>;\n\nexport const FileTreeName = ({ className, children, ...props }: FileTreeNameProps) => (\n <span className={cn(\"truncate\", className)} {...props}>\n {children}\n </span>\n);\n\ninterface FileTreeFolderContextType {\n path: string;\n name: string;\n isExpanded: boolean;\n}\n\nconst FileTreeFolderContext = createContext<FileTreeFolderContextType>({\n isExpanded: false,\n name: \"\",\n path: \"\",\n});\n\nexport type FileTreeFolderProps = HTMLAttributes<HTMLDivElement> & {\n path: string;\n name: string;\n};\n\nexport const FileTreeFolder = ({\n path,\n name,\n className,\n children,\n ...props\n}: FileTreeFolderProps) => {\n const { t } = useLocale();\n const { expandedPaths, togglePath, selectedPath, onSelect } = useContext(FileTreeContext);\n const isExpanded = expandedPaths.has(path);\n const isSelected = selectedPath === path;\n\n const handleOpenChange = useCallback(() => {\n togglePath(path);\n }, [togglePath, path]);\n\n const handleSelect = useCallback(() => {\n onSelect?.(path);\n }, [onSelect, path]);\n\n const folderContextValue = useMemo(() => ({ isExpanded, name, path }), [isExpanded, name, path]);\n\n return (\n <FileTreeFolderContext.Provider value={folderContextValue}>\n <Collapsible onOpenChange={handleOpenChange} open={isExpanded}>\n <div className={cn(\"\", className)} role=\"treeitem\" tabIndex={0} {...props}>\n <div\n className={cn(\n \"flex w-full items-center gap-1 rounded px-2 py-1 text-start transition-colors hover:bg-muted/50\",\n isSelected && \"bg-muted\",\n )}\n >\n <CollapsibleTrigger asChild>\n <button\n aria-label={t(\n isExpanded ? \"ai.fileTree.collapseFolder\" : \"ai.fileTree.expandFolder\",\n { name },\n )}\n className=\"flex shrink-0 cursor-pointer items-center border-none bg-transparent p-0\"\n type=\"button\"\n >\n <ChevronRightIcon\n aria-hidden=\"true\"\n className={cn(\n \"size-4 shrink-0 text-muted-foreground transition-transform\",\n isExpanded && \"rotate-90\",\n )}\n data-rtl-flip\n />\n </button>\n </CollapsibleTrigger>\n <button\n className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-start\"\n onClick={handleSelect}\n type=\"button\"\n >\n <FileTreeIcon>\n {isExpanded ? (\n <FolderOpenIcon className=\"size-4 text-primary\" />\n ) : (\n <FolderIcon className=\"size-4 text-primary\" />\n )}\n </FileTreeIcon>\n <FileTreeName>{name}</FileTreeName>\n </button>\n </div>\n <CollapsibleContent>\n <div className=\"ms-4 border-s ps-2\">{children}</div>\n </CollapsibleContent>\n </div>\n </Collapsible>\n </FileTreeFolderContext.Provider>\n );\n};\n\ninterface FileTreeFileContextType {\n path: string;\n name: string;\n}\n\nconst FileTreeFileContext = createContext<FileTreeFileContextType>({\n name: \"\",\n path: \"\",\n});\n\nexport type FileTreeFileProps = HTMLAttributes<HTMLDivElement> & {\n path: string;\n name: string;\n icon?: ReactNode;\n};\n\nexport const FileTreeFile = ({\n path,\n name,\n icon,\n className,\n children,\n ...props\n}: FileTreeFileProps) => {\n const { selectedPath, onSelect } = useContext(FileTreeContext);\n const isSelected = selectedPath === path;\n\n const handleClick = useCallback(() => {\n onSelect?.(path);\n }, [onSelect, path]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n onSelect?.(path);\n }\n },\n [onSelect, path],\n );\n\n const fileContextValue = useMemo(() => ({ name, path }), [name, path]);\n\n return (\n <FileTreeFileContext.Provider value={fileContextValue}>\n <div\n className={cn(\n \"flex cursor-pointer items-center gap-1 rounded px-2 py-1 transition-colors hover:bg-muted/50\",\n isSelected && \"bg-muted\",\n className,\n )}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n role=\"treeitem\"\n tabIndex={0}\n {...props}\n >\n {children ?? (\n <>\n {/* Spacer for alignment */}\n <span className=\"size-4 shrink-0\" />\n <FileTreeIcon>\n {icon ?? <FileIcon className=\"size-4 text-muted-foreground\" />}\n </FileTreeIcon>\n <FileTreeName>{name}</FileTreeName>\n </>\n )}\n </div>\n </FileTreeFileContext.Provider>\n );\n};\n\nexport type FileTreeActionsProps = HTMLAttributes<HTMLDivElement>;\n\nconst stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();\n\nexport const FileTreeActions = ({ className, children, ...props }: FileTreeActionsProps) => (\n <div\n className={cn(\"ms-auto flex items-center gap-1\", className)}\n onClick={stopPropagation}\n onKeyDown={stopPropagation}\n role=\"group\"\n {...props}\n >\n {children}\n </div>\n);\n\n/** Asset-type glyphs (lucide, research 04 §4) — doc / code / sql / csv / image. */\nexport const PRODUCED_ASSET_ICONS: Record<ContextAssetType, LucideIcon> = {\n markdown: FileTextIcon,\n code: FileCode2Icon,\n sql: DatabaseIcon,\n csv: TableIcon,\n image: ImageIcon,\n};\n\n/**\n * The glyph for one asset.\n *\n * A FILE-BACKED asset (`source` set — a PDF, a deck, a video reaching the rail\n * through `AssetPreview`'s `renderPreview` seam) carries a `type` from a closed\n * five-member union that cannot describe it, so the type-keyed glyph above\n * would lie: a PDF typed `code` would draw a code glyph. Its name and MIME do\n * know, so those go through the shared resolver instead (ADR 0024 §6).\n *\n * An asset with inline `content` keeps the type-keyed glyph exactly as before —\n * for those the author's `type` is the better answer, not a guess from a\n * filename.\n */\nfunction assetIcon(asset: ContextAsset): LucideIcon {\n return asset.source ? fileIconFor(asset.name, asset.mediaType) : PRODUCED_ASSET_ICONS[asset.type];\n}\n\nexport type ProducedAssetTreeProps = Omit<\n FileTreeProps,\n \"variant\" | \"onSelect\" | \"selectedPath\"\n> & {\n /** The produced assets, in display order. */\n assets: ContextAsset[];\n /** Selected asset id (mirror `useContextPanel().state.selectedAsset?.id`). */\n selectedId?: string;\n /** Called with the chosen asset — wire to `useContextPanel().actions.openDetail`. */\n onSelect?: (asset: ContextAsset) => void;\n};\n\n/**\n * ProducedAssetTree — the document-variant preset (#193, research 04 §4):\n * produced assets are documents, not source code, so the tree reads sans,\n * box-free, with first-class asset-type icons. Pair with `ContextPanelSection`\n * for the label; selection drives the ContextPanel drill-in.\n */\nexport const ProducedAssetTree = forwardRef<HTMLDivElement, ProducedAssetTreeProps>(\n function ProducedAssetTree({ assets, selectedId, onSelect, ...props }, ref) {\n const { t } = useLocale();\n const assetsById = useMemo(() => new Map(assets.map((asset) => [asset.id, asset])), [assets]);\n const handleSelect = useCallback(\n (path: string) => {\n const asset = assetsById.get(path);\n if (asset) onSelect?.(asset);\n },\n [assetsById, onSelect],\n );\n // Empty: a plain note, not an empty `role=\"tree\"` — a tree with no\n // `treeitem` fails `aria-required-children` and announces nothing useful.\n if (assets.length === 0) {\n return (\n <div\n ref={ref}\n data-slot=\"file-tree-empty\"\n className={cn(\"px-2 py-1 text-body text-muted-foreground\", props.className)}\n >\n {t(\"ai.fileTree.noAssetsProduced\")}\n </div>\n );\n }\n return (\n <FileTree\n ref={ref}\n variant=\"document\"\n selectedPath={selectedId}\n onSelect={handleSelect}\n {...props}\n >\n {assets.map((asset) => {\n const Icon = assetIcon(asset);\n return (\n <FileTreeFile key={asset.id} path={asset.id} name={asset.name}>\n <FileTreeIcon>\n <Icon aria-hidden=\"true\" className=\"size-4 text-muted-foreground\" />\n </FileTreeIcon>\n <FileTreeName>{asset.name}</FileTreeName>\n </FileTreeFile>\n );\n })}\n </FileTree>\n );\n },\n);\n"],"mappings":"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","names":["FileTree","ProducedAssetTree"]}
@@ -0,0 +1,52 @@
1
+ "use client";
2
+
3
+ // src/agent-timeline.tsx
4
+ import { StatusBadge, TimelineItem, TimelineRoot } from "@elabs-ai/components-ui";
5
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
6
+ import { forwardRef, memo } from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ var AgentTimeline = forwardRef(
9
+ function AgentTimeline2({ className, ...props }, ref) {
10
+ return /* @__PURE__ */ jsx(TimelineRoot, { ref, className: cn("not-prose w-full", className), ...props });
11
+ }
12
+ );
13
+ var AgentStep = memo(
14
+ forwardRef(function AgentStep2({
15
+ icon: Icon,
16
+ name,
17
+ summary,
18
+ status = "pending",
19
+ hideBadge = false,
20
+ className,
21
+ children,
22
+ ...props
23
+ }, ref) {
24
+ return /* @__PURE__ */ jsx(
25
+ TimelineItem,
26
+ {
27
+ ref,
28
+ status,
29
+ description: summary ? /* @__PURE__ */ jsx("span", { className: "text-meta text-muted-foreground", children: summary }) : void 0,
30
+ detail: children,
31
+ className: cn(
32
+ "fade-in-0 slide-in-from-top-2 animate-in [--tw-ease:var(--ease-entrance)] motion-reduce:animate-none",
33
+ className
34
+ ),
35
+ ...props,
36
+ children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2", children: [
37
+ Icon ? /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true", className: "size-4 shrink-0 text-muted-foreground" }) : null,
38
+ name,
39
+ hideBadge ? null : /* @__PURE__ */ jsx(StatusBadge, { size: "sm", status })
40
+ ] })
41
+ }
42
+ );
43
+ })
44
+ );
45
+ AgentTimeline.displayName = "AgentTimeline";
46
+ AgentStep.displayName = "AgentStep";
47
+
48
+ export {
49
+ AgentTimeline,
50
+ AgentStep
51
+ };
52
+ //# sourceMappingURL=chunk-UCJ6IUFS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/agent-timeline.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * AgentTimeline / AgentStep — the agent execution-trace rail (#192,\n * research 10 §B.3).\n *\n * The convergence compound of the execution-trace grammar: sequenced,\n * status-bearing agent steps render on ONE visual spine — the canonical\n * `@elabs-ai/components-ui` Timeline rail (`TimelineRoot`/`TimelineItem`, #190) — speaking\n * ONE status vocabulary — the closed 7-state `Status` enum (`StatusBadge`,\n * #189). `ChainOfThought`'s steps and `Task`'s body compose this instead of\n * hand-rolling rails; an inspect-only `Tool` call renders as an `AgentStep`\n * with its JSON behind a `ToolDetails` disclosure as children.\n *\n * Deliberately NOT converged (different speech-acts, research 10 §B.3):\n * `Plan` (a proposal, not an executed step), `Checkpoint` (a divider/restore\n * point), `Reasoning` (inline thinking prose).\n *\n * The shared rail is motion-free; the gated entrance animation lives here,\n * in the composing consumer (research 10 §B.2).\n */\nimport { StatusBadge, TimelineItem, TimelineRoot, type Status } from \"@elabs-ai/components-ui\";\nimport type { TimelineItemProps, TimelineRootProps } from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { forwardRef, memo, type ReactNode } from \"react\";\n\nexport type AgentTimelineProps = TimelineRootProps;\n\n/** The `<ol>` rail an agent run's steps sit on (canonical @elabs-ai/components-ui spine). */\nexport const AgentTimeline = forwardRef<HTMLOListElement, AgentTimelineProps>(\n function AgentTimeline({ className, ...props }, ref) {\n return <TimelineRoot ref={ref} className={cn(\"not-prose w-full\", className)} {...props} />;\n },\n);\n\nexport interface AgentStepProps extends Omit<TimelineItemProps, \"children\" | \"description\"> {\n /** Optional leading concept glyph on the title row (Lucide). */\n icon?: LucideIcon;\n /** What the agent did — the step's title (`text-body`). */\n name: ReactNode;\n /** The business summary line under the name (`text-meta`), not JSON. */\n summary?: ReactNode;\n /**\n * The canonical execution status (closed 7-state enum). Drives the rail\n * node AND the `StatusBadge`. `skipped` is the agent-step-only state with\n * no SDK source (research 10 §B.1).\n */\n status?: Status;\n /**\n * Drop the inline `StatusBadge` (the rail node still carries the status\n * color). For quiet prose rails — e.g. the `ChainOfThought` alias — where a\n * badge per step would shout.\n */\n hideBadge?: boolean;\n /** Rich detail under the node (e.g. a `ToolDetails` disclosure, results). */\n children?: ReactNode;\n}\n\n/**\n * One executed/executing step: icon + name + `StatusBadge` + business\n * summary, with composed children for detail. Memoized for long transcripts\n * (research 10 §G.6).\n */\nexport const AgentStep = memo(\n forwardRef<HTMLLIElement, AgentStepProps>(function AgentStep(\n {\n icon: Icon,\n name,\n summary,\n status = \"pending\",\n hideBadge = false,\n className,\n children,\n ...props\n },\n ref,\n ) {\n return (\n <TimelineItem\n ref={ref}\n status={status}\n description={\n summary ? <span className=\"text-meta text-muted-foreground\">{summary}</span> : undefined\n }\n detail={children}\n className={cn(\n \"fade-in-0 slide-in-from-top-2 animate-in [--tw-ease:var(--ease-entrance)] motion-reduce:animate-none\",\n className,\n )}\n {...props}\n >\n <span className=\"inline-flex items-center gap-2\">\n {Icon ? (\n <Icon aria-hidden=\"true\" className=\"size-4 shrink-0 text-muted-foreground\" />\n ) : null}\n {name}\n {hideBadge ? null : <StatusBadge size=\"sm\" status={status} />}\n </span>\n </TimelineItem>\n );\n }),\n);\n\nAgentTimeline.displayName = \"AgentTimeline\";\nAgentStep.displayName = \"AgentStep\";\n"],"mappings":";;;AAqBA,SAAS,aAAa,cAAc,oBAAiC;AAErE,SAAS,UAAU;AAEnB,SAAS,YAAY,YAA4B;AAOtC,cA4DH,YA5DG;AAFJ,IAAM,gBAAgB;AAAA,EAC3B,SAASA,eAAc,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AACnD,WAAO,oBAAC,gBAAa,KAAU,WAAW,GAAG,oBAAoB,SAAS,GAAI,GAAG,OAAO;AAAA,EAC1F;AACF;AA8BO,IAAM,YAAY;AAAA,EACvB,WAA0C,SAASC,WACjD;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,KACA;AACA,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,aACE,UAAU,oBAAC,UAAK,WAAU,mCAAmC,mBAAQ,IAAU;AAAA,QAEjF,QAAQ;AAAA,QACR,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ,+BAAC,UAAK,WAAU,kCACb;AAAA,iBACC,oBAAC,QAAK,eAAY,QAAO,WAAU,yCAAwC,IACzE;AAAA,UACH;AAAA,UACA,YAAY,OAAO,oBAAC,eAAY,MAAK,MAAK,QAAgB;AAAA,WAC7D;AAAA;AAAA,IACF;AAAA,EAEJ,CAAC;AACH;AAEA,cAAc,cAAc;AAC5B,UAAU,cAAc;","names":["AgentTimeline","AgentStep"]}