@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,482 @@
1
+ "use client";
2
+ import {
3
+ getStreamdownPluginsKey,
4
+ useStreamdownMermaidOptions,
5
+ useStreamdownPlugins,
6
+ useStreamdownTranslations
7
+ } from "./chunk-PQBF6ZIQ.js";
8
+ import {
9
+ stripSanitizerOverrides,
10
+ warnOnTrustedPluginSlots
11
+ } from "./chunk-DZW6LM22.js";
12
+
13
+ // src/message.tsx
14
+ import { Avatar, AvatarFallback, AvatarImage, Button } from "@elabs-ai/components-ui";
15
+ import { ButtonGroup, ButtonGroupText, Skeleton } from "@elabs-ai/components-ui";
16
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@elabs-ai/components-ui";
17
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
18
+ import { useLocale } from "@elabs-ai/components-ui";
19
+ import { cva } from "class-variance-authority";
20
+ import { BotIcon, ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
21
+ import { createContext, memo, useCallback, useContext, useEffect, useMemo, useState } from "react";
22
+ import { Streamdown } from "streamdown";
23
+ import { jsx, jsxs } from "react/jsx-runtime";
24
+ var Message = ({ className, from, ...props }) => /* @__PURE__ */ jsx(
25
+ "div",
26
+ {
27
+ className: cn(
28
+ "group flex w-full max-w-[95%] flex-col gap-2",
29
+ // NOTE `is-user` / `is-assistant` are LOAD-BEARING, not decorative: they
30
+ // are what `MessageContent`'s `group-[.is-user]:…` selectors compile
31
+ // against (`.group.is-user &`). `data-role` below is their semantic twin
32
+ // for querying/testing — don't dedupe the two, removing the class would
33
+ // silently kill the `--chat-user` fill in every theme.
34
+ from === "user" ? "is-user ms-auto justify-end" : "is-assistant",
35
+ className
36
+ ),
37
+ "data-role": from,
38
+ "data-slot": "message",
39
+ ...props
40
+ }
41
+ );
42
+ var MessageContent = ({ children, className, ...props }) => /* @__PURE__ */ jsx(
43
+ "div",
44
+ {
45
+ className: cn(
46
+ "flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-hidden text-body",
47
+ // The user turn is the 08 fill channel: the revalued `--chat-user` tint +
48
+ // its AA-validated foreground (research 11 §B.1 MSG-1). The assistant
49
+ // branch stays bare — its separation is the AgentMessage rail.
50
+ "group-[.is-user]:ms-auto group-[.is-user]:rounded-lg group-[.is-user]:bg-chat-user group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-chat-user-foreground",
51
+ "group-[.is-assistant]:text-foreground",
52
+ className
53
+ ),
54
+ "data-slot": "message-content",
55
+ ...props,
56
+ children
57
+ }
58
+ );
59
+ var MessageHeader = ({ className, ...props }) => /* @__PURE__ */ jsx(
60
+ "div",
61
+ {
62
+ className: cn("flex items-center gap-2 text-meta text-muted-foreground", className),
63
+ "data-slot": "message-header",
64
+ ...props
65
+ }
66
+ );
67
+ var MessageAvatar = ({
68
+ src,
69
+ name,
70
+ role = "user",
71
+ className,
72
+ children,
73
+ ...props
74
+ }) => {
75
+ if (role === "agent") {
76
+ return /* @__PURE__ */ jsxs(
77
+ Avatar,
78
+ {
79
+ "aria-label": name ? `${name} (agent)` : "Agent",
80
+ role: "img",
81
+ className: cn("size-6 bg-primary text-primary-foreground", className),
82
+ "data-role": "agent",
83
+ "data-slot": "message-avatar",
84
+ ...props,
85
+ children: [
86
+ src ? /* @__PURE__ */ jsx(AvatarImage, { alt: name ?? "", src }) : null,
87
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-primary text-primary-foreground", children: /* @__PURE__ */ jsx(BotIcon, { "aria-hidden": "true", size: 14 }) })
88
+ ]
89
+ }
90
+ );
91
+ }
92
+ return /* @__PURE__ */ jsxs(
93
+ Avatar,
94
+ {
95
+ className: cn("size-6", className),
96
+ "data-role": role,
97
+ "data-slot": "message-avatar",
98
+ ...props,
99
+ children: [
100
+ src ? /* @__PURE__ */ jsx(AvatarImage, { alt: name ?? "", src }) : null,
101
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "text-meta", children: children ?? name?.slice(0, 1).toUpperCase() ?? "?" })
102
+ ]
103
+ }
104
+ );
105
+ };
106
+ var UserMessage = (props) => /* @__PURE__ */ jsx(Message, { from: "user", ...props });
107
+ var agentMessageVariants = cva("", {
108
+ variants: {
109
+ /**
110
+ * "Final answer" is a VISUAL axis, not a behavioural mode (research 11
111
+ * §B.2): `answer` applies the 08 green left rail. It sits on the message
112
+ * wrapper — never on `MessageContent`, whose `overflow-hidden` would clip
113
+ * it (research 11 §G.1).
114
+ */
115
+ emphasis: {
116
+ default: "",
117
+ answer: "border-s-4 border-s-primary ps-4"
118
+ }
119
+ },
120
+ defaultVariants: { emphasis: "default" }
121
+ });
122
+ var AgentMessage = ({ className, emphasis, ...props }) => /* @__PURE__ */ jsx(
123
+ Message,
124
+ {
125
+ from: "assistant",
126
+ className: cn(agentMessageVariants({ emphasis }), className),
127
+ ...props
128
+ }
129
+ );
130
+ var messageActionsVariants = cva(
131
+ [
132
+ "flex items-center gap-1",
133
+ // Follow the bubble to the right on a user turn — the SAME selector
134
+ // `MessageContent` uses for the `--chat-user` fill above. Without it the row
135
+ // sits at the flex-column's cross-start (left) edge while the bubble it acts
136
+ // on is `ms-auto`'d to the right, so a `bar` pill renders under the PREVIOUS
137
+ // (assistant) message: "Edit" appears to edit the agent's answer. It was
138
+ // invisible before only because a `plain` row stretched full-width and had
139
+ // no drawn box; `w-fit` is what made the misplacement visible.
140
+ "group-[.is-user]:ms-auto"
141
+ ],
142
+ {
143
+ variants: {
144
+ /**
145
+ * How the row presents itself. Two VISUAL values, per `cva`'s remit — no
146
+ * behaviour forks on this axis.
147
+ * - `plain` (default): a bare inline row, the pre-#existing shape. Unchanged
148
+ * for every consumer that never sets the prop.
149
+ * - `bar`: a floating pill that reads as chrome sitting ABOVE the transcript
150
+ * rather than as more message content. Per ADR 0020 a floating surface
151
+ * takes `shadow-ring-*` and NO border — the ring bakes the 1px edge in as
152
+ * the shadow's last layer, so there is no second crisp stroke beside it,
153
+ * and because the hairline sits OUTSIDE `--shadow-strength` the pill keeps
154
+ * a drawn edge at high decoration / `data-decoration="8|9|10"` where the lift
155
+ * is zeroed.
156
+ */
157
+ appearance: {
158
+ plain: "",
159
+ bar: "w-fit rounded-full bg-popover p-0.5 shadow-ring-sm"
160
+ },
161
+ /**
162
+ * When the row is visible.
163
+ * - `always` (default): in flow, always shown.
164
+ * - `hover`: faded out at rest, revealed when the pointer is anywhere over
165
+ * the parent `Message`, when focus lands inside the row, or while a menu
166
+ * inside it is open.
167
+ */
168
+ reveal: {
169
+ always: "",
170
+ hover: [
171
+ "transition-opacity duration-fast ease-standard motion-reduce:transition-none",
172
+ // Hover-reveal is gated on the POINTER, not on a breakpoint: a touch
173
+ // device has no hover state at all, so hiding the row there would make
174
+ // it unreachable (you cannot tap what you cannot see, and there is no
175
+ // gesture that reveals it first). `pointer-coarse` therefore never
176
+ // takes the `opacity-0` at all and the row stays visible. Note this is
177
+ // a stronger guarantee than the `md:` breakpoint proxy used by the
178
+ // `@elabs-ai/components-ui` Sidebar — a ≥md tablet is
179
+ // exactly the case that proxy gets wrong.
180
+ "pointer-fine:opacity-0",
181
+ // Reveal on: the parent Message (`Message` sets the bare `group` class
182
+ // — see the load-bearing note there), the row itself, keyboard focus
183
+ // landing inside it, and an open menu launched from it (a `⋯ more`
184
+ // trigger carries `data-state="open"`; without this the row fades out
185
+ // from under the menu the moment the pointer travels to it).
186
+ "pointer-fine:group-hover:opacity-100",
187
+ "pointer-fine:hover:opacity-100",
188
+ "pointer-fine:focus-within:opacity-100",
189
+ "pointer-fine:has-[[data-state=open]]:opacity-100"
190
+ ]
191
+ }
192
+ },
193
+ defaultVariants: { appearance: "plain", reveal: "always" }
194
+ }
195
+ );
196
+ var MessageActions = ({
197
+ appearance,
198
+ className,
199
+ children,
200
+ label,
201
+ reveal,
202
+ ...props
203
+ }) => {
204
+ const { t } = useLocale();
205
+ return /* @__PURE__ */ jsx(
206
+ "div",
207
+ {
208
+ "aria-label": label ?? t("ai.message.actions"),
209
+ className: cn(messageActionsVariants({ appearance, reveal }), className),
210
+ "data-slot": "message-actions",
211
+ role: "group",
212
+ ...props,
213
+ children
214
+ }
215
+ );
216
+ };
217
+ var MessageAction = ({
218
+ tooltip,
219
+ children,
220
+ label,
221
+ variant = "ghost",
222
+ size = "icon-sm",
223
+ ...props
224
+ }) => {
225
+ const button = /* @__PURE__ */ jsxs(Button, { "data-slot": "message-action", size, type: "button", variant, ...props, children: [
226
+ children,
227
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: label || tooltip })
228
+ ] });
229
+ if (tooltip) {
230
+ return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
231
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: button }),
232
+ /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { children: tooltip }) })
233
+ ] }) });
234
+ }
235
+ return button;
236
+ };
237
+ var MessageBranchContext = createContext(null);
238
+ var useMessageBranch = () => {
239
+ const context = useContext(MessageBranchContext);
240
+ if (!context) {
241
+ throw new Error("MessageBranch components must be used within MessageBranch");
242
+ }
243
+ return context;
244
+ };
245
+ var MessageBranch = ({
246
+ branch: branchProp,
247
+ defaultBranch = 0,
248
+ onBranchChange,
249
+ className,
250
+ ...props
251
+ }) => {
252
+ const isControlled = branchProp !== void 0;
253
+ const [internalBranch, setInternalBranch] = useState(defaultBranch);
254
+ const currentBranch = isControlled ? branchProp : internalBranch;
255
+ const [branches, setBranches] = useState([]);
256
+ const handleBranchChange = useCallback(
257
+ (newBranch) => {
258
+ if (!isControlled) setInternalBranch(newBranch);
259
+ onBranchChange?.(newBranch);
260
+ },
261
+ [isControlled, onBranchChange]
262
+ );
263
+ const goToPrevious = useCallback(() => {
264
+ const newBranch = currentBranch > 0 ? currentBranch - 1 : branches.length - 1;
265
+ handleBranchChange(newBranch);
266
+ }, [currentBranch, branches.length, handleBranchChange]);
267
+ const goToNext = useCallback(() => {
268
+ const newBranch = currentBranch < branches.length - 1 ? currentBranch + 1 : 0;
269
+ handleBranchChange(newBranch);
270
+ }, [currentBranch, branches.length, handleBranchChange]);
271
+ const contextValue = useMemo(
272
+ () => ({
273
+ branches,
274
+ currentBranch,
275
+ goToNext,
276
+ goToPrevious,
277
+ setBranches,
278
+ totalBranches: branches.length
279
+ }),
280
+ [branches, currentBranch, goToNext, goToPrevious]
281
+ );
282
+ return /* @__PURE__ */ jsx(MessageBranchContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
283
+ "div",
284
+ {
285
+ className: cn("grid w-full gap-2 [&>div]:pb-0", className),
286
+ "data-slot": "message-branch",
287
+ ...props
288
+ }
289
+ ) });
290
+ };
291
+ var MessageBranchContent = ({ children, id, ...props }) => {
292
+ const { currentBranch, setBranches } = useMessageBranch();
293
+ const childrenArray = useMemo(
294
+ () => Array.isArray(children) ? children : [children],
295
+ [children]
296
+ );
297
+ useEffect(() => {
298
+ setBranches(childrenArray);
299
+ }, [childrenArray, setBranches]);
300
+ return childrenArray.map((branch, index) => /* @__PURE__ */ jsx(
301
+ "div",
302
+ {
303
+ className: cn(
304
+ "grid gap-2 overflow-hidden [&>div]:pb-0",
305
+ index === currentBranch ? "block" : "hidden"
306
+ ),
307
+ "data-slot": "message-branch-content",
308
+ id: id ? `${id}-${index}` : void 0,
309
+ ...props,
310
+ children: branch
311
+ },
312
+ branch.key
313
+ ));
314
+ };
315
+ var MessageBranchSelector = ({ className, ...props }) => {
316
+ const { totalBranches } = useMessageBranch();
317
+ if (totalBranches <= 1) {
318
+ return null;
319
+ }
320
+ return /* @__PURE__ */ jsx(
321
+ ButtonGroup,
322
+ {
323
+ className: cn(
324
+ "[&>*:not(:first-child)]:rounded-s-md [&>*:not(:last-child)]:rounded-e-md",
325
+ className
326
+ ),
327
+ "data-slot": "message-branch-selector",
328
+ orientation: "horizontal",
329
+ ...props
330
+ }
331
+ );
332
+ };
333
+ var MessageBranchPrevious = ({ children, ...props }) => {
334
+ const { t } = useLocale();
335
+ const { goToPrevious, totalBranches } = useMessageBranch();
336
+ return /* @__PURE__ */ jsx(
337
+ Button,
338
+ {
339
+ "aria-label": t("ai.message.previousBranch"),
340
+ "data-slot": "message-branch-previous",
341
+ disabled: totalBranches <= 1,
342
+ onClick: goToPrevious,
343
+ size: "icon-sm",
344
+ type: "button",
345
+ variant: "ghost",
346
+ ...props,
347
+ children: children ?? /* @__PURE__ */ jsx(ChevronLeftIcon, { size: 14, "data-rtl-flip": true })
348
+ }
349
+ );
350
+ };
351
+ var MessageBranchNext = ({ children, ...props }) => {
352
+ const { t } = useLocale();
353
+ const { goToNext, totalBranches } = useMessageBranch();
354
+ return /* @__PURE__ */ jsx(
355
+ Button,
356
+ {
357
+ "aria-label": t("ai.message.nextBranch"),
358
+ "data-slot": "message-branch-next",
359
+ disabled: totalBranches <= 1,
360
+ onClick: goToNext,
361
+ size: "icon-sm",
362
+ type: "button",
363
+ variant: "ghost",
364
+ ...props,
365
+ children: children ?? /* @__PURE__ */ jsx(ChevronRightIcon, { size: 14, "data-rtl-flip": true })
366
+ }
367
+ );
368
+ };
369
+ var MessageBranchPage = ({ className, ...props }) => {
370
+ const { currentBranch, totalBranches } = useMessageBranch();
371
+ return /* @__PURE__ */ jsxs(
372
+ ButtonGroupText,
373
+ {
374
+ className: cn("border-none bg-transparent text-muted-foreground shadow-none", className),
375
+ "data-slot": "message-branch-page",
376
+ ...props,
377
+ children: [
378
+ currentBranch + 1,
379
+ " of ",
380
+ totalBranches
381
+ ]
382
+ }
383
+ );
384
+ };
385
+ var MessageResponse = memo(
386
+ ({ className, loading = false, plugins: pluginOverrides, ...props }) => {
387
+ stripSanitizerOverrides(props);
388
+ const translations = useStreamdownTranslations();
389
+ const { t } = useLocale();
390
+ const internalPlugins = useStreamdownPlugins(
391
+ typeof props.children === "string" ? props.children : ""
392
+ );
393
+ const plugins = useMemo(() => {
394
+ warnOnTrustedPluginSlots(pluginOverrides, internalPlugins);
395
+ return { ...internalPlugins, ...pluginOverrides };
396
+ }, [internalPlugins, pluginOverrides]);
397
+ const mermaidOptions = useStreamdownMermaidOptions();
398
+ if (loading) {
399
+ return /* @__PURE__ */ jsxs(
400
+ "div",
401
+ {
402
+ className: cn("space-y-2", className),
403
+ "data-slot": "message-response",
404
+ role: "status",
405
+ "aria-live": "polite",
406
+ children: [
407
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: t("loading") }),
408
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-64" }),
409
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-52" }),
410
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-40" })
411
+ ]
412
+ }
413
+ );
414
+ }
415
+ return /* @__PURE__ */ jsx(
416
+ Streamdown,
417
+ {
418
+ className: cn(
419
+ "size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0",
420
+ // Brand prose scale (research 11 §B.1 MSG-3): map the streamed markdown
421
+ // element tree onto the 07 type roles. Descendant-selector className —
422
+ // NOT a `components` map — so streaming stays cheap.
423
+ "[&_h1]:text-title [&_h2]:text-subtitle [&_h3]:text-subtitle",
424
+ "[&_p]:text-body [&_li]:text-body [&_code]:text-code",
425
+ className
426
+ ),
427
+ "data-slot": "message-response",
428
+ plugins,
429
+ translations,
430
+ mermaid: mermaidOptions,
431
+ ...props
432
+ },
433
+ getStreamdownPluginsKey(internalPlugins)
434
+ );
435
+ },
436
+ // A hand-picked field list (`children`/`isAnimating`/`loading`) silently
437
+ // went stale as `MessageResponseProps` grew: `className`, `components`,
438
+ // `plugins`, `mode` and every other `Streamdown` prop passed through
439
+ // `...props` were never compared, so a caller-driven change to any of them
440
+ // (e.g. toggling `mode="static"`/`"streaming"`, swapping `components`, or
441
+ // overriding a `plugins` slot) rendered stale content until an unrelated
442
+ // prop also changed. Compare every own key on BOTH sides with `Object.is`
443
+ // instead, so a newly added prop is covered for free.
444
+ (prevProps, nextProps) => {
445
+ const prevKeys = Object.keys(prevProps);
446
+ const nextKeys = Object.keys(nextProps);
447
+ if (prevKeys.length !== nextKeys.length) return false;
448
+ return prevKeys.every((key) => Object.is(prevProps[key], nextProps[key]));
449
+ }
450
+ );
451
+ MessageResponse.displayName = "MessageResponse";
452
+ var MessageToolbar = ({ className, children, ...props }) => /* @__PURE__ */ jsx(
453
+ "div",
454
+ {
455
+ className: cn("mt-4 flex w-full items-center justify-between gap-4", className),
456
+ "data-slot": "message-toolbar",
457
+ ...props,
458
+ children
459
+ }
460
+ );
461
+
462
+ export {
463
+ Message,
464
+ MessageContent,
465
+ MessageHeader,
466
+ MessageAvatar,
467
+ UserMessage,
468
+ agentMessageVariants,
469
+ AgentMessage,
470
+ messageActionsVariants,
471
+ MessageActions,
472
+ MessageAction,
473
+ MessageBranch,
474
+ MessageBranchContent,
475
+ MessageBranchSelector,
476
+ MessageBranchPrevious,
477
+ MessageBranchNext,
478
+ MessageBranchPage,
479
+ MessageResponse,
480
+ MessageToolbar
481
+ };
482
+ //# sourceMappingURL=chunk-ADOYAGGK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/message.tsx"],"sourcesContent":["\"use client\";\n\nimport { Avatar, AvatarFallback, AvatarImage, Button } from \"@elabs-ai/components-ui\";\nimport { ButtonGroup, ButtonGroupText, 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 { cva, type VariantProps } from \"class-variance-authority\";\nimport { stripSanitizerOverrides, warnOnTrustedPluginSlots } from \"./_streamdown-safety\";\nimport {\n getStreamdownPluginsKey,\n useStreamdownMermaidOptions,\n useStreamdownPlugins,\n useStreamdownTranslations,\n} from \"./_streamdown-i18n\";\nimport type { UIMessage } from \"ai\";\nimport { BotIcon, ChevronLeftIcon, ChevronRightIcon } from \"lucide-react\";\nimport type { ComponentProps, HTMLAttributes, ReactElement } from \"react\";\nimport { createContext, memo, useCallback, useContext, useEffect, useMemo, useState } from \"react\";\nimport { Streamdown } from \"streamdown\";\n\nexport type MessageProps = HTMLAttributes<HTMLDivElement> & {\n from: UIMessage[\"role\"];\n};\n\nexport const Message = ({ className, from, ...props }: MessageProps) => (\n <div\n className={cn(\n \"group flex w-full max-w-[95%] flex-col gap-2\",\n // NOTE `is-user` / `is-assistant` are LOAD-BEARING, not decorative: they\n // are what `MessageContent`'s `group-[.is-user]:…` selectors compile\n // against (`.group.is-user &`). `data-role` below is their semantic twin\n // for querying/testing — don't dedupe the two, removing the class would\n // silently kill the `--chat-user` fill in every theme.\n from === \"user\" ? \"is-user ms-auto justify-end\" : \"is-assistant\",\n className,\n )}\n data-role={from}\n data-slot=\"message\"\n {...props}\n />\n);\n\nexport type MessageContentProps = HTMLAttributes<HTMLDivElement>;\n\nexport const MessageContent = ({ children, className, ...props }: MessageContentProps) => (\n <div\n className={cn(\n \"flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-hidden text-body\",\n // The user turn is the 08 fill channel: the revalued `--chat-user` tint +\n // its AA-validated foreground (research 11 §B.1 MSG-1). The assistant\n // branch stays bare — its separation is the AgentMessage rail.\n \"group-[.is-user]:ms-auto group-[.is-user]:rounded-lg group-[.is-user]:bg-chat-user group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-chat-user-foreground\",\n \"group-[.is-assistant]:text-foreground\",\n className,\n )}\n data-slot=\"message-content\"\n {...props}\n >\n {children}\n </div>\n);\n\nexport type MessageHeaderProps = HTMLAttributes<HTMLDivElement>;\n\n/**\n * Optional identity row above the bubble — avatar + name + timestamp\n * (research 11 §B.1 MSG-2). A slot, not baked structure.\n */\nexport const MessageHeader = ({ className, ...props }: MessageHeaderProps) => (\n <div\n className={cn(\"flex items-center gap-2 text-meta text-muted-foreground\", className)}\n data-slot=\"message-header\"\n {...props}\n />\n);\n\nexport type MessageAvatarProps = ComponentProps<typeof Avatar> & {\n /** Image source for the participant. */\n src?: string;\n /** Participant name — drives the image alt + the fallback initial, and the accessible label. */\n name?: string;\n /**\n * Visual identity role.\n * - `\"user\"` (default): shows the initial letter as a fallback.\n * - `\"agent\"`: shows a branded Bot icon on a primary (green) ground instead\n * of a text initial, matching the agent identity convention.\n */\n role?: \"user\" | \"agent\";\n};\n\n/**\n * Thin preset over the `@elabs-ai/components-ui` Avatar sized for inline chat (NOT a new\n * avatar primitive — research 11 §B.1 MSG-2).\n *\n * When `role=\"agent\"`, renders a filled primary-green circle with a centered\n * Bot icon (lucide-react `BotIcon`) and an accessible label derived from\n * `name`. The primary/primary-foreground token pair is the agent identity\n * colour across both themes (green on light/dark; theme-adapted\n * on others).\n */\nexport const MessageAvatar = ({\n src,\n name,\n role = \"user\",\n className,\n children,\n ...props\n}: MessageAvatarProps) => {\n if (role === \"agent\") {\n return (\n <Avatar\n aria-label={name ? `${name} (agent)` : \"Agent\"}\n // `role=\"img\"` is LOAD-BEARING, not decoration (#386). Radix's\n // `Avatar.Root` renders a plain `<span>`, whose implicit role is\n // `generic` — and ARIA PROHIBITS `aria-label` on `generic`, so axe's\n // `aria-prohibited-attr` reds the story AND assistive tech never\n // announces the name. `img` is the role permitted to carry a name for a\n // graphic whose contents (the Bot glyph) are not text — the same\n // precedent a titled `@elabs-ai/components-icons` `Icon`\n // uses (.claude/rules/icons.md). Only the agent branch takes it: the\n // user branch's fallback initial is real text content, so naming it too\n // would add an `img` per message for no gain.\n role=\"img\"\n className={cn(\"size-6 bg-primary text-primary-foreground\", className)}\n data-role=\"agent\"\n data-slot=\"message-avatar\"\n {...props}\n >\n {src ? <AvatarImage alt={name ?? \"\"} src={src} /> : null}\n <AvatarFallback className=\"bg-primary text-primary-foreground\">\n <BotIcon aria-hidden=\"true\" size={14} />\n </AvatarFallback>\n </Avatar>\n );\n }\n\n return (\n <Avatar\n className={cn(\"size-6\", className)}\n data-role={role}\n data-slot=\"message-avatar\"\n {...props}\n >\n {src ? <AvatarImage alt={name ?? \"\"} src={src} /> : null}\n <AvatarFallback className=\"text-meta\">\n {children ?? name?.slice(0, 1).toUpperCase() ?? \"?\"}\n </AvatarFallback>\n </Avatar>\n );\n};\n\nexport type UserMessageProps = Omit<MessageProps, \"from\">;\n\n/**\n * Named front door for a user turn (research 11 §B.2) — a thin preset over\n * `Message from=\"user\"`; the chat-user fill comes from `MessageContent`.\n */\nexport const UserMessage = (props: UserMessageProps) => <Message from=\"user\" {...props} />;\n\nexport const agentMessageVariants = cva(\"\", {\n variants: {\n /**\n * \"Final answer\" is a VISUAL axis, not a behavioural mode (research 11\n * §B.2): `answer` applies the 08 green left rail. It sits on the message\n * wrapper — never on `MessageContent`, whose `overflow-hidden` would clip\n * it (research 11 §G.1).\n */\n emphasis: {\n default: \"\",\n answer: \"border-s-4 border-s-primary ps-4\",\n },\n },\n defaultVariants: { emphasis: \"default\" },\n});\n\nexport type AgentMessageEmphasis = NonNullable<\n VariantProps<typeof agentMessageVariants>[\"emphasis\"]\n>;\n\nexport type AgentMessageProps = Omit<MessageProps, \"from\"> &\n VariantProps<typeof agentMessageVariants>;\n\n/**\n * Named front door for an assistant turn (research 11 §B.2). KPI band / prose /\n * footer are COMPOSED children (`MetricGrid` + `MessageResponse` +\n * `SourceList`), not baked-in layout.\n */\nexport const AgentMessage = ({ className, emphasis, ...props }: AgentMessageProps) => (\n <Message\n from=\"assistant\"\n className={cn(agentMessageVariants({ emphasis }), className)}\n {...props}\n />\n);\n\nexport const messageActionsVariants = cva(\n [\n \"flex items-center gap-1\",\n // Follow the bubble to the right on a user turn — the SAME selector\n // `MessageContent` uses for the `--chat-user` fill above. Without it the row\n // sits at the flex-column's cross-start (left) edge while the bubble it acts\n // on is `ms-auto`'d to the right, so a `bar` pill renders under the PREVIOUS\n // (assistant) message: \"Edit\" appears to edit the agent's answer. It was\n // invisible before only because a `plain` row stretched full-width and had\n // no drawn box; `w-fit` is what made the misplacement visible.\n \"group-[.is-user]:ms-auto\",\n ],\n {\n variants: {\n /**\n * How the row presents itself. Two VISUAL values, per `cva`'s remit — no\n * behaviour forks on this axis.\n * - `plain` (default): a bare inline row, the pre-#existing shape. Unchanged\n * for every consumer that never sets the prop.\n * - `bar`: a floating pill that reads as chrome sitting ABOVE the transcript\n * rather than as more message content. Per ADR 0020 a floating surface\n * takes `shadow-ring-*` and NO border — the ring bakes the 1px edge in as\n * the shadow's last layer, so there is no second crisp stroke beside it,\n * and because the hairline sits OUTSIDE `--shadow-strength` the pill keeps\n * a drawn edge at high decoration / `data-decoration=\"8|9|10\"` where the lift\n * is zeroed.\n */\n appearance: {\n plain: \"\",\n bar: \"w-fit rounded-full bg-popover p-0.5 shadow-ring-sm\",\n },\n /**\n * When the row is visible.\n * - `always` (default): in flow, always shown.\n * - `hover`: faded out at rest, revealed when the pointer is anywhere over\n * the parent `Message`, when focus lands inside the row, or while a menu\n * inside it is open.\n */\n reveal: {\n always: \"\",\n hover: [\n \"transition-opacity duration-fast ease-standard motion-reduce:transition-none\",\n // Hover-reveal is gated on the POINTER, not on a breakpoint: a touch\n // device has no hover state at all, so hiding the row there would make\n // it unreachable (you cannot tap what you cannot see, and there is no\n // gesture that reveals it first). `pointer-coarse` therefore never\n // takes the `opacity-0` at all and the row stays visible. Note this is\n // a stronger guarantee than the `md:` breakpoint proxy used by the\n // `@elabs-ai/components-ui` Sidebar — a ≥md tablet is\n // exactly the case that proxy gets wrong.\n \"pointer-fine:opacity-0\",\n // Reveal on: the parent Message (`Message` sets the bare `group` class\n // — see the load-bearing note there), the row itself, keyboard focus\n // landing inside it, and an open menu launched from it (a `⋯ more`\n // trigger carries `data-state=\"open\"`; without this the row fades out\n // from under the menu the moment the pointer travels to it).\n \"pointer-fine:group-hover:opacity-100\",\n \"pointer-fine:hover:opacity-100\",\n \"pointer-fine:focus-within:opacity-100\",\n \"pointer-fine:has-[[data-state=open]]:opacity-100\",\n ],\n },\n },\n defaultVariants: { appearance: \"plain\", reveal: \"always\" },\n },\n);\n\nexport type MessageActionsProps = ComponentProps<\"div\"> &\n VariantProps<typeof messageActionsVariants> & {\n /**\n * Accessible name for the group. Defaults to the `ai.message.actions`\n * microcopy key. Naming matters more here than on an always-visible row:\n * assistive tech reaches these controls whether or not a pointer ever\n * revealed them, so the group has to say what they act on.\n */\n label?: string;\n };\n\n/**\n * A row of per-message controls (copy, pin, retry, a `⋯` menu, …).\n *\n * **Presentational only** — it lays the controls out and decides when they are\n * visible; it ships no clipboard call, no pin state and no persistence. Every\n * `MessageAction` inside it is a bare `Button`: give it an `onClick`, and for a\n * toggle (pin, bookmark) an `aria-pressed` the host owns. That is the D5\n * boundary (`docs/DECISIONS.md` §D5) — brand-ui renders, the app acts.\n *\n * `reveal=\"hover\"` reads the parent `Message`'s `group` class, so the row must\n * be rendered INSIDE a `Message` for pointer-reveal to fire. Standing alone it\n * still reveals on its own hover and on focus-within, but not from the bubble.\n */\nexport const MessageActions = ({\n appearance,\n className,\n children,\n label,\n reveal,\n ...props\n}: MessageActionsProps) => {\n const { t } = useLocale();\n\n return (\n <div\n aria-label={label ?? t(\"ai.message.actions\")}\n className={cn(messageActionsVariants({ appearance, reveal }), className)}\n data-slot=\"message-actions\"\n role=\"group\"\n {...props}\n >\n {children}\n </div>\n );\n};\n\nexport type MessageActionProps = ComponentProps<typeof Button> & {\n tooltip?: string;\n label?: string;\n};\n\nexport const MessageAction = ({\n tooltip,\n children,\n label,\n variant = \"ghost\",\n size = \"icon-sm\",\n ...props\n}: MessageActionProps) => {\n const button = (\n <Button data-slot=\"message-action\" size={size} type=\"button\" variant={variant} {...props}>\n {children}\n <span className=\"sr-only\">{label || tooltip}</span>\n </Button>\n );\n\n if (tooltip) {\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent>\n <p>{tooltip}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n }\n\n return button;\n};\n\ninterface MessageBranchContextType {\n currentBranch: number;\n totalBranches: number;\n goToPrevious: () => void;\n goToNext: () => void;\n branches: ReactElement[];\n setBranches: (branches: ReactElement[]) => void;\n}\n\nconst MessageBranchContext = createContext<MessageBranchContextType | null>(null);\n\nconst useMessageBranch = () => {\n const context = useContext(MessageBranchContext);\n\n if (!context) {\n throw new Error(\"MessageBranch components must be used within MessageBranch\");\n }\n\n return context;\n};\n\nexport type MessageBranchProps = HTMLAttributes<HTMLDivElement> & {\n /**\n * Controlled current branch index. When set, `MessageBranch` no longer\n * tracks its own state — the host owns it and must update `branch` from\n * `onBranchChange` (or elsewhere) to move the selection. Omit for the\n * uncontrolled default (see `defaultBranch`).\n */\n branch?: number;\n defaultBranch?: number;\n onBranchChange?: (branchIndex: number) => void;\n};\n\nexport const MessageBranch = ({\n branch: branchProp,\n defaultBranch = 0,\n onBranchChange,\n className,\n ...props\n}: MessageBranchProps) => {\n // Derived once and never flipped, per the repo's controlled/uncontrolled\n // convention (component-api.md) — mirrors MessageFeedback/MessageEdit.\n const isControlled = branchProp !== undefined;\n const [internalBranch, setInternalBranch] = useState(defaultBranch);\n const currentBranch = isControlled ? branchProp : internalBranch;\n const [branches, setBranches] = useState<ReactElement[]>([]);\n\n const handleBranchChange = useCallback(\n (newBranch: number) => {\n if (!isControlled) setInternalBranch(newBranch);\n onBranchChange?.(newBranch);\n },\n [isControlled, onBranchChange],\n );\n\n const goToPrevious = useCallback(() => {\n const newBranch = currentBranch > 0 ? currentBranch - 1 : branches.length - 1;\n handleBranchChange(newBranch);\n }, [currentBranch, branches.length, handleBranchChange]);\n\n const goToNext = useCallback(() => {\n const newBranch = currentBranch < branches.length - 1 ? currentBranch + 1 : 0;\n handleBranchChange(newBranch);\n }, [currentBranch, branches.length, handleBranchChange]);\n\n const contextValue = useMemo<MessageBranchContextType>(\n () => ({\n branches,\n currentBranch,\n goToNext,\n goToPrevious,\n setBranches,\n totalBranches: branches.length,\n }),\n [branches, currentBranch, goToNext, goToPrevious],\n );\n\n return (\n <MessageBranchContext.Provider value={contextValue}>\n <div\n className={cn(\"grid w-full gap-2 [&>div]:pb-0\", className)}\n data-slot=\"message-branch\"\n {...props}\n />\n </MessageBranchContext.Provider>\n );\n};\n\nexport type MessageBranchContentProps = HTMLAttributes<HTMLDivElement>;\n\nexport const MessageBranchContent = ({ children, id, ...props }: MessageBranchContentProps) => {\n const { currentBranch, setBranches } = useMessageBranch();\n const childrenArray = useMemo(\n () => (Array.isArray(children) ? children : [children]),\n [children],\n );\n\n // Always resync — an earlier length-gate (`branches.length !==\n // childrenArray.length`) skipped this when a branch's CONTENT changed\n // (e.g. an edited message) without the branch COUNT changing, leaving\n // `context.branches` stale relative to what is actually rendered.\n useEffect(() => {\n setBranches(childrenArray);\n }, [childrenArray, setBranches]);\n\n return childrenArray.map((branch, index) => (\n <div\n className={cn(\n \"grid gap-2 overflow-hidden [&>div]:pb-0\",\n index === currentBranch ? \"block\" : \"hidden\",\n )}\n data-slot=\"message-branch-content\"\n // Spreading a caller-supplied `id` onto every mapped branch produced\n // duplicate DOM ids (one per branch); suffix it per index instead so\n // each branch keeps a unique, stable id.\n id={id ? `${id}-${index}` : undefined}\n key={branch.key}\n {...props}\n >\n {branch}\n </div>\n ));\n};\n\nexport type MessageBranchSelectorProps = ComponentProps<typeof ButtonGroup>;\n\nexport const MessageBranchSelector = ({ className, ...props }: MessageBranchSelectorProps) => {\n const { totalBranches } = useMessageBranch();\n\n // Don't render if there's only one branch\n if (totalBranches <= 1) {\n return null;\n }\n\n return (\n <ButtonGroup\n className={cn(\n \"[&>*:not(:first-child)]:rounded-s-md [&>*:not(:last-child)]:rounded-e-md\",\n className,\n )}\n data-slot=\"message-branch-selector\"\n orientation=\"horizontal\"\n {...props}\n />\n );\n};\n\nexport type MessageBranchPreviousProps = ComponentProps<typeof Button>;\n\nexport const MessageBranchPrevious = ({ children, ...props }: MessageBranchPreviousProps) => {\n const { t } = useLocale();\n const { goToPrevious, totalBranches } = useMessageBranch();\n\n return (\n <Button\n aria-label={t(\"ai.message.previousBranch\")}\n data-slot=\"message-branch-previous\"\n disabled={totalBranches <= 1}\n onClick={goToPrevious}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"ghost\"\n {...props}\n >\n {children ?? <ChevronLeftIcon size={14} data-rtl-flip />}\n </Button>\n );\n};\n\nexport type MessageBranchNextProps = ComponentProps<typeof Button>;\n\nexport const MessageBranchNext = ({ children, ...props }: MessageBranchNextProps) => {\n const { t } = useLocale();\n const { goToNext, totalBranches } = useMessageBranch();\n\n return (\n <Button\n aria-label={t(\"ai.message.nextBranch\")}\n data-slot=\"message-branch-next\"\n disabled={totalBranches <= 1}\n onClick={goToNext}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"ghost\"\n {...props}\n >\n {children ?? <ChevronRightIcon size={14} data-rtl-flip />}\n </Button>\n );\n};\n\nexport type MessageBranchPageProps = HTMLAttributes<HTMLSpanElement>;\n\nexport const MessageBranchPage = ({ className, ...props }: MessageBranchPageProps) => {\n const { currentBranch, totalBranches } = useMessageBranch();\n\n return (\n <ButtonGroupText\n className={cn(\"border-none bg-transparent text-muted-foreground shadow-none\", className)}\n data-slot=\"message-branch-page\"\n {...props}\n >\n {currentBranch + 1} of {totalBranches}\n </ButtonGroupText>\n );\n};\n\n/**\n * `rehypePlugins` is NOT exposed on `MessageResponse` (#36, fixed). This\n * renders untrusted, streamed model output — the type-level `Omit` below plus\n * a runtime `stripSanitizerOverrides()` call before the `{...props}` spread\n * onto `<Streamdown>` keep Streamdown's default sanitiser chain (rehype-raw →\n * rehype-sanitize → rehype-harden) non-overridable, even through a JS consumer\n * or a force-cast.\n *\n * `remarkPlugins` IS supported: the remark stage runs upstream of that chain\n * and cannot bypass it (PR #74 review, round 1). See `MarkdownView`'s TSDoc and\n * `packages/ai/src/_streamdown-safety.ts` for the full security model.\n */\nexport type MessageResponseProps = Omit<ComponentProps<typeof Streamdown>, \"rehypePlugins\"> & {\n /**\n * No content has arrived yet (loading-states.md `loading`) — renders\n * skeleton lines at the body line-height instead of `<Streamdown>`, so the\n * bubble reserves its space before the first token.\n * @default false\n */\n loading?: boolean;\n /**\n * Custom renderers for markdown elements. **Semantics differ from\n * `MarkdownView`:** `components` here REPLACES (not merges) per key against\n * Streamdown's own defaults, since `MessageResponse` has no internal\n * component map to merge with. See `MarkdownView` for merge-over-defaults\n * semantics and `#10` for details.\n */\n components?: ComponentProps<typeof Streamdown>[\"components\"];\n /**\n * Streamdown plugin-slot overrides (`cjk`/`code`/`math`/`mermaid`/\n * `renderers`), **merged** per key over the internal defaults, so a\n * consumer's entry wins for its key; every key the consumer does not set\n * keeps the reactive, i18n-aware internal default. Same semantics as\n * `MarkdownView` (#10 fix round).\n *\n * **This narrow `plugins` prop can only APPEND — it can never displace\n * Streamdown's default `rehypePlugins` chain** (`rehype-raw` →\n * `rehype-sanitize` → `rehype-harden`). `MessageResponse` never sets\n * `rehypePlugins` itself, and nothing in `PluginConfig` removes a member of\n * that pipeline. But two of the five slots are **not** upstream of it and\n * must be treated as TRUSTED CODE (#76):\n * - **`math.rehypePlugin` runs AFTER `rehype-sanitize`/`rehype-harden`** —\n * it is appended to the end of the rehype pipeline (verified against\n * `streamdown@2.5.0`'s `dist/chunk-BO2N2NFS.js`), so its output is never\n * re-sanitised. Replacing it emits a dev-only `console.warn`; the plugin\n * still runs (the seam is deliberate, not a hole to close). The sharp\n * edge in practice is KaTeX's `trust` option — it disables KaTeX's own\n * sanitisation, so leave it off for model-authored content.\n * - **`mermaid` never enters the rehype/remark pipeline at all.** Its\n * render output is written via `dangerouslySetInnerHTML` (streamdown's\n * only such sink); brand-ui's default pins mermaid's strict security\n * level, and a replacement must sanitise its own SVG. Also dev-warned.\n * - `cjk` (remark-stage, re-sanitised downstream), `code` (feeds\n * `shikiTheme` only) and `renderers` (ordinary React components) do not\n * bypass sanitisation and are never warned about.\n *\n * See `docs/CSP-AND-NETWORK.md` §1 and\n * `packages/ai/src/_streamdown-safety.ts`; `MarkdownView`'s TSDoc carries\n * the same model for the sibling surface.\n */\n plugins?: ComponentProps<typeof Streamdown>[\"plugins\"];\n};\n\nexport const MessageResponse = memo(\n ({ className, loading = false, plugins: pluginOverrides, ...props }: MessageResponseProps) => {\n // Streamdown installs [rehypeRaw, rehypeSanitize, harden] as the DEFAULT VALUE of\n // `rehypePlugins`; a supplied array REPLACES it. This component renders untrusted,\n // streamed model output, so the chain is not overridable. Widen with `allowedTags` /\n // `literalTagContent`, which merge into the sanitize schema. See issue #36.\n // `remarkPlugins` is deliberately left alone — it runs upstream of the rehype\n // chain and cannot bypass it (PR #74 review; see `_streamdown-safety.ts`).\n stripSanitizerOverrides(props);\n // Streamdown renders its own chrome (code copy, table menus, Mermaid\n // toolbar); route its labels through the locale seam (#310). Spread AFTER\n // so an explicit `translations` prop still wins (ADR 0017 override chain).\n const translations = useStreamdownTranslations();\n const { t } = useLocale();\n // Brand-token-derived `code` plugin, not the package's static github-*\n // default (#315 follow-up) — re-derives when the active theme changes.\n // `math`/`cjk` are lazy-loaded off the raw markdown source (#perf-5, see\n // `_streamdown-i18n.ts`) — pass `props.children` so they load only when\n // this message actually needs them.\n const internalPlugins = useStreamdownPlugins(\n typeof props.children === \"string\" ? props.children : \"\",\n );\n // MERGED per key over the internal defaults — the same semantics as\n // `MarkdownView`'s `plugins` prop (#10 fix round, M4): a consumer entry\n // wins for its key; every key the consumer does not set keeps the\n // reactive, i18n-aware internal default. Previously this component\n // REPLACED `plugins` wholesale (`{...props}` spread after `plugins=`),\n // the opposite of `MarkdownView` for the same prop on a sibling\n // Streamdown surface — aligned so both components mean the same thing by\n // \"override a plugin slot\".\n // `math.rehypePlugin`/`mermaid` are the two slots that land in the DOM\n // after (or outside) the sanitiser chain, so replacing one is a\n // TRUSTED-CODE decision. The runtime half of that documented boundary is a\n // dev warning — the plugin still runs; stripping it would break the\n // legitimate use (#76).\n const plugins = useMemo(() => {\n warnOnTrustedPluginSlots(pluginOverrides, internalPlugins);\n return { ...internalPlugins, ...pluginOverrides };\n }, [internalPlugins, pluginOverrides]);\n // The TOP-LEVEL Streamdown `mermaid` prop — catches a failed diagram\n // render, including a missing `mermaid` optional peer (issue #33).\n const mermaidOptions = useStreamdownMermaidOptions();\n\n if (loading) {\n return (\n <div\n className={cn(\"space-y-2\", className)}\n data-slot=\"message-response\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <span className=\"sr-only\">{t(\"loading\")}</span>\n {/* Fixed (not percentage) widths: MessageContent is `w-fit`, so a\n skeleton row sized in `%` has nothing definite to shrink-wrap\n around and collapses to zero width. */}\n <Skeleton className=\"h-5 w-64\" />\n <Skeleton className=\"h-5 w-52\" />\n <Skeleton className=\"h-5 w-40\" />\n </div>\n );\n }\n\n return (\n <Streamdown\n className={cn(\n \"size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0\",\n // Brand prose scale (research 11 §B.1 MSG-3): map the streamed markdown\n // element tree onto the 07 type roles. Descendant-selector className —\n // NOT a `components` map — so streaming stays cheap.\n \"[&_h1]:text-title [&_h2]:text-subtitle [&_h3]:text-subtitle\",\n \"[&_p]:text-body [&_li]:text-body [&_code]:text-code\",\n className,\n )}\n // Forces a remount the first time the lazy math/cjk slot resolves —\n // see `getStreamdownPluginsKey`'s doc in `_streamdown-i18n.ts` for why.\n key={getStreamdownPluginsKey(internalPlugins)}\n data-slot=\"message-response\"\n plugins={plugins}\n translations={translations}\n mermaid={mermaidOptions}\n {...props}\n />\n );\n },\n // A hand-picked field list (`children`/`isAnimating`/`loading`) silently\n // went stale as `MessageResponseProps` grew: `className`, `components`,\n // `plugins`, `mode` and every other `Streamdown` prop passed through\n // `...props` were never compared, so a caller-driven change to any of them\n // (e.g. toggling `mode=\"static\"`/`\"streaming\"`, swapping `components`, or\n // overriding a `plugins` slot) rendered stale content until an unrelated\n // prop also changed. Compare every own key on BOTH sides with `Object.is`\n // instead, so a newly added prop is covered for free.\n (prevProps, nextProps) => {\n const prevKeys = Object.keys(prevProps) as (keyof MessageResponseProps)[];\n const nextKeys = Object.keys(nextProps) as (keyof MessageResponseProps)[];\n if (prevKeys.length !== nextKeys.length) return false;\n return prevKeys.every((key) => Object.is(prevProps[key], nextProps[key]));\n },\n);\n\nMessageResponse.displayName = \"MessageResponse\";\n\nexport type MessageToolbarProps = ComponentProps<\"div\">;\n\nexport const MessageToolbar = ({ className, children, ...props }: MessageToolbarProps) => (\n <div\n className={cn(\"mt-4 flex w-full items-center justify-between gap-4\", className)}\n data-slot=\"message-toolbar\"\n {...props}\n >\n {children}\n </div>\n);\n"],"mappings":"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","names":[]}
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ import {
3
+ lazyFlowPart
4
+ } from "./chunk-NMVNNO3L.js";
5
+
6
+ // src/canvas.tsx
7
+ import { Skeleton } from "@elabs-ai/components-ui";
8
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
9
+ import { Suspense } from "react";
10
+ import { jsx } from "react/jsx-runtime";
11
+ var CanvasImpl = lazyFlowPart((m) => m.Canvas);
12
+ var Canvas = ({ className, ...props }) => (
13
+ // The canvas fills the box its parent gives it, so the skeleton reserves the
14
+ // same space and the engine chunk arrives without a layout shift.
15
+ /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Skeleton, { className: cn("size-full", className) }), children: /* @__PURE__ */ jsx(CanvasImpl, { className, ...props }) })
16
+ );
17
+
18
+ export {
19
+ Canvas
20
+ };
21
+ //# sourceMappingURL=chunk-BA3AEMOU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/canvas.tsx"],"sourcesContent":["\"use client\";\n\nimport { Skeleton } from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport type { ReactFlowProps } from \"@xyflow/react\";\nimport type { ReactNode } from \"react\";\nimport { Suspense } from \"react\";\n\nimport { lazyFlowPart } from \"./_flow-lazy\";\n\nexport type CanvasProps = ReactFlowProps & {\n children?: ReactNode;\n};\n\n/**\n * React Flow — and its stylesheet — is reached through a dynamic import: it\n * declares no `sideEffects`, so a static import would put the whole engine in\n * every consumer's entry chunk, a canvas rendered or not. `ReactFlowProps` above\n * is a TYPE import and erases. See ADR 0019 and `pnpm heavy-deps:check`.\n */\nconst CanvasImpl = lazyFlowPart<CanvasProps>((m) => m.Canvas);\n\nexport const Canvas = ({ className, ...props }: CanvasProps) => (\n // The canvas fills the box its parent gives it, so the skeleton reserves the\n // same space and the engine chunk arrives without a layout shift.\n <Suspense fallback={<Skeleton className={cn(\"size-full\", className)} />}>\n <CanvasImpl className={className} {...props} />\n </Suspense>\n);\n"],"mappings":";;;;;;AAEA,SAAS,gBAAgB;AACzB,SAAS,UAAU;AAGnB,SAAS,gBAAgB;AAmBH;AALtB,IAAM,aAAa,aAA0B,CAAC,MAAM,EAAE,MAAM;AAErD,IAAM,SAAS,CAAC,EAAE,WAAW,GAAG,MAAM;AAAA;AAAA;AAAA,EAG3C,oBAAC,YAAS,UAAU,oBAAC,YAAS,WAAW,GAAG,aAAa,SAAS,GAAG,GACnE,8BAAC,cAAW,WAAuB,GAAG,OAAO,GAC/C;AAAA;","names":[]}