@elabs-ai/components-ai 4.2.0 → 5.0.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-AXMNJMMH.js +984 -0
  106. package/dist/chunk-AXMNJMMH.js.map +1 -0
  107. package/dist/chunk-BA3AEMOU.js +21 -0
  108. package/dist/chunk-BA3AEMOU.js.map +1 -0
  109. package/dist/chunk-BBHFOYML.js +336 -0
  110. package/dist/chunk-BBHFOYML.js.map +1 -0
  111. package/dist/chunk-BHUVISIY.js +221 -0
  112. package/dist/chunk-BHUVISIY.js.map +1 -0
  113. package/dist/chunk-BM2LWERA.js +100 -0
  114. package/dist/chunk-BM2LWERA.js.map +1 -0
  115. package/dist/chunk-CMOYXNPJ.js +211 -0
  116. package/dist/chunk-CMOYXNPJ.js.map +1 -0
  117. package/dist/chunk-CZP3RHC4.js +74 -0
  118. package/dist/chunk-CZP3RHC4.js.map +1 -0
  119. package/dist/chunk-DDG5JHQT.js +112 -0
  120. package/dist/chunk-DDG5JHQT.js.map +1 -0
  121. package/dist/chunk-DJODXO7I.js +38 -0
  122. package/dist/chunk-DJODXO7I.js.map +1 -0
  123. package/dist/chunk-DWJDJLPU.js +192 -0
  124. package/dist/chunk-DWJDJLPU.js.map +1 -0
  125. package/dist/chunk-DZW6LM22.js +45 -0
  126. package/dist/chunk-DZW6LM22.js.map +1 -0
  127. package/dist/chunk-ELGCZLZF.js +305 -0
  128. package/dist/chunk-ELGCZLZF.js.map +1 -0
  129. package/dist/chunk-EV3U6ZZB.js +209 -0
  130. package/dist/chunk-EV3U6ZZB.js.map +1 -0
  131. package/dist/chunk-EY7LVUKQ.js +87 -0
  132. package/dist/chunk-EY7LVUKQ.js.map +1 -0
  133. package/dist/chunk-F4C74F7M.js +230 -0
  134. package/dist/chunk-F4C74F7M.js.map +1 -0
  135. package/dist/chunk-FERYDFZA.js +108 -0
  136. package/dist/chunk-FERYDFZA.js.map +1 -0
  137. package/dist/chunk-FUIYG2DS.js +166 -0
  138. package/dist/chunk-FUIYG2DS.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-LMNSBOBG.js +19 -0
  156. package/dist/chunk-LMNSBOBG.js.map +1 -0
  157. package/dist/chunk-MBI7D6IL.js +42 -0
  158. package/dist/chunk-MBI7D6IL.js.map +1 -0
  159. package/dist/chunk-MLFMYCPH.js +192 -0
  160. package/dist/chunk-MLFMYCPH.js.map +1 -0
  161. package/dist/chunk-MOK66734.js +33 -0
  162. package/dist/chunk-MOK66734.js.map +1 -0
  163. package/dist/chunk-MXTAWPYM.js +196 -0
  164. package/dist/chunk-MXTAWPYM.js.map +1 -0
  165. package/dist/chunk-NCL2UZKI.js +96 -0
  166. package/dist/chunk-NCL2UZKI.js.map +1 -0
  167. package/dist/chunk-NET4YLRY.js +107 -0
  168. package/dist/chunk-NET4YLRY.js.map +1 -0
  169. package/dist/chunk-NIG67CFM.js +329 -0
  170. package/dist/chunk-NIG67CFM.js.map +1 -0
  171. package/dist/chunk-NMVNNO3L.js +10 -0
  172. package/dist/chunk-NMVNNO3L.js.map +1 -0
  173. package/dist/chunk-NP7VID4K.js +2 -0
  174. package/dist/chunk-NP7VID4K.js.map +1 -0
  175. package/dist/chunk-NPUCMAG2.js +382 -0
  176. package/dist/chunk-NPUCMAG2.js.map +1 -0
  177. package/dist/chunk-NSCLRHES.js +102 -0
  178. package/dist/chunk-NSCLRHES.js.map +1 -0
  179. package/dist/chunk-OEUXHVFW.js +86 -0
  180. package/dist/chunk-OEUXHVFW.js.map +1 -0
  181. package/dist/chunk-ONBHFIMZ.js +137 -0
  182. package/dist/chunk-ONBHFIMZ.js.map +1 -0
  183. package/dist/chunk-OPH2HHL2.js +228 -0
  184. package/dist/chunk-OPH2HHL2.js.map +1 -0
  185. package/dist/chunk-OQERHIQP.js +287 -0
  186. package/dist/chunk-OQERHIQP.js.map +1 -0
  187. package/dist/chunk-P6YJAZFG.js +103 -0
  188. package/dist/chunk-P6YJAZFG.js.map +1 -0
  189. package/dist/chunk-PG7ERDOD.js +65 -0
  190. package/dist/chunk-PG7ERDOD.js.map +1 -0
  191. package/dist/chunk-PIB5JBMA.js +90 -0
  192. package/dist/chunk-PIB5JBMA.js.map +1 -0
  193. package/dist/chunk-PQ5BPIWQ.js +22 -0
  194. package/dist/chunk-PQ5BPIWQ.js.map +1 -0
  195. package/dist/chunk-PQBF6ZIQ.js +55 -0
  196. package/dist/chunk-PQBF6ZIQ.js.map +1 -0
  197. package/dist/chunk-PTWCTSZL.js +173 -0
  198. package/dist/chunk-PTWCTSZL.js.map +1 -0
  199. package/dist/chunk-QJUNPVOS.js +101 -0
  200. package/dist/chunk-QJUNPVOS.js.map +1 -0
  201. package/dist/chunk-QUDZOTRV.js +43 -0
  202. package/dist/chunk-QUDZOTRV.js.map +1 -0
  203. package/dist/chunk-RB7G65JC.js +213 -0
  204. package/dist/chunk-RB7G65JC.js.map +1 -0
  205. package/dist/chunk-RPHAOR7P.js +45 -0
  206. package/dist/chunk-RPHAOR7P.js.map +1 -0
  207. package/dist/chunk-RTCSH2AN.js +331 -0
  208. package/dist/chunk-RTCSH2AN.js.map +1 -0
  209. package/dist/chunk-S3ISPW3A.js +28 -0
  210. package/dist/chunk-S3ISPW3A.js.map +1 -0
  211. package/dist/chunk-SEVN656N.js +36 -0
  212. package/dist/chunk-SEVN656N.js.map +1 -0
  213. package/dist/chunk-SKVG672B.js +64 -0
  214. package/dist/chunk-SKVG672B.js.map +1 -0
  215. package/dist/chunk-SPQIU7GA.js +236 -0
  216. package/dist/chunk-SPQIU7GA.js.map +1 -0
  217. package/dist/chunk-SSGJ6MEM.js +1076 -0
  218. package/dist/chunk-SSGJ6MEM.js.map +1 -0
  219. package/dist/chunk-SSKZ2AED.js +118 -0
  220. package/dist/chunk-SSKZ2AED.js.map +1 -0
  221. package/dist/chunk-T56JFGXI.js +561 -0
  222. package/dist/chunk-T56JFGXI.js.map +1 -0
  223. package/dist/chunk-TCB6O74A.js +137 -0
  224. package/dist/chunk-TCB6O74A.js.map +1 -0
  225. package/dist/chunk-TTEYPO6X.js +57 -0
  226. package/dist/chunk-TTEYPO6X.js.map +1 -0
  227. package/dist/chunk-TWPHAJNM.js +462 -0
  228. package/dist/chunk-TWPHAJNM.js.map +1 -0
  229. package/dist/chunk-TXJJLP4O.js +336 -0
  230. package/dist/chunk-TXJJLP4O.js.map +1 -0
  231. package/dist/chunk-TZ6TB7VM.js +245 -0
  232. package/dist/chunk-TZ6TB7VM.js.map +1 -0
  233. package/dist/chunk-UBLKJJ7K.js +278 -0
  234. package/dist/chunk-UBLKJJ7K.js.map +1 -0
  235. package/dist/chunk-UCJ6IUFS.js +52 -0
  236. package/dist/chunk-UCJ6IUFS.js.map +1 -0
  237. package/dist/chunk-UCKFJ3QF.js +197 -0
  238. package/dist/chunk-UCKFJ3QF.js.map +1 -0
  239. package/dist/chunk-UPXSLILN.js +20 -0
  240. package/dist/chunk-UPXSLILN.js.map +1 -0
  241. package/dist/chunk-V4DORGWJ.js +92 -0
  242. package/dist/chunk-V4DORGWJ.js.map +1 -0
  243. package/dist/chunk-V6E5DYZD.js +80 -0
  244. package/dist/chunk-V6E5DYZD.js.map +1 -0
  245. package/dist/chunk-VLLYKF3P.js +96 -0
  246. package/dist/chunk-VLLYKF3P.js.map +1 -0
  247. package/dist/chunk-VLNBTOH6.js +43 -0
  248. package/dist/chunk-VLNBTOH6.js.map +1 -0
  249. package/dist/chunk-WMDSMSPL.js +303 -0
  250. package/dist/chunk-WMDSMSPL.js.map +1 -0
  251. package/dist/chunk-WU5BLGTF.js +149 -0
  252. package/dist/chunk-WU5BLGTF.js.map +1 -0
  253. package/dist/chunk-WYTZVSGK.js +245 -0
  254. package/dist/chunk-WYTZVSGK.js.map +1 -0
  255. package/dist/chunk-X47QMM6K.js +187 -0
  256. package/dist/chunk-X47QMM6K.js.map +1 -0
  257. package/dist/chunk-XNBKO32Y.js +174 -0
  258. package/dist/chunk-XNBKO32Y.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 +5425 -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 +1006 -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
@@ -1,6 +1,7 @@
1
1
  /**
2
- * AI assistant template — the canonical full-screen AI assistant composition
3
- * (app-shell + chat shell: Conversation + PromptInput). This story is the
2
+ * AI assistant template — the canonical full-screen AI assistant composition:
3
+ * app-shell nav, an immersive `ChatShell` (transcript scrolls behind a floating
4
+ * `Composer`, one centred reading column) and the `ContextPanel` right rail. This story is the
4
5
  * single source of truth: `pnpm gen:templates` derives the consumer template
5
6
  * source (`docs/playbooks/templates/ai-assistant.tsx`) from it.
6
7
  * Verify across both themes with globals=theme:<slug>.
@@ -10,8 +11,10 @@ import { useState } from "react";
10
11
  import { AppIcon } from "@elabs-ai/components-icons";
11
12
  import {
12
13
  Button,
14
+ NavUser,
13
15
  Sidebar,
14
16
  SidebarContent,
17
+ SidebarFooter,
15
18
  SidebarGroup,
16
19
  SidebarGroupContent,
17
20
  SidebarHeader,
@@ -23,7 +26,16 @@ import {
23
26
  SidebarTrigger,
24
27
  } from "@elabs-ai/components-ui";
25
28
  import {
29
+ AssetPreview,
30
+ ChatShell,
26
31
  Composer,
32
+ ContextPanel,
33
+ ContextPanelBody,
34
+ ContextPanelDetail,
35
+ ContextPanelHeader,
36
+ ContextPanelProvider,
37
+ ContextPanelSection,
38
+ ContextPanelTrigger,
27
39
  Conversation,
28
40
  ConversationContent,
29
41
  ConversationEmptyState,
@@ -31,6 +43,9 @@ import {
31
43
  Message,
32
44
  MessageContent,
33
45
  MessageResponse,
46
+ ProducedAssetTree,
47
+ useContextPanel,
48
+ type ContextAsset,
34
49
  } from "./index";
35
50
  import { Bot, History, Home, MessageSquare, Settings } from "lucide-react";
36
51
 
@@ -47,10 +62,36 @@ const nav = [
47
62
  { id: "settings", label: "Settings", icon: Settings },
48
63
  ];
49
64
 
65
+ /** Right rail root — what the assistant produced; selecting one drills in. */
66
+ function ContextRailRoot({ assets }: { assets: ContextAsset[] }) {
67
+ const { state, actions } = useContextPanel();
68
+ return (
69
+ <ContextPanelSection label="Produced assets">
70
+ <ProducedAssetTree
71
+ assets={assets}
72
+ selectedId={state.selectedAsset?.id}
73
+ onSelect={actions.openDetail}
74
+ />
75
+ </ContextPanelSection>
76
+ );
77
+ }
78
+
79
+ /** Right rail detail — the focused asset, with Back in the panel header. */
80
+ function ContextRailDetail() {
81
+ const { state } = useContextPanel();
82
+ return (
83
+ <ContextPanelDetail>
84
+ {state.selectedAsset ? <AssetPreview asset={state.selectedAsset} /> : null}
85
+ </ContextPanelDetail>
86
+ );
87
+ }
88
+
50
89
  function AiAssistantTemplate() {
51
90
  const [active, setActive] = useState("chat");
52
91
  const [messages, setMessages] = useState<ChatMessage[]>([]);
53
92
  const [status, setStatus] = useState<"ready" | "submitted">("ready");
93
+ // Files the assistant produced — wire to your runtime's tool outputs.
94
+ const [assets] = useState<ContextAsset[]>([]);
54
95
 
55
96
  function send(text: string) {
56
97
  setMessages((m) => [...m, { id: crypto.randomUUID(), role: "user", text }]);
@@ -61,98 +102,121 @@ function AiAssistantTemplate() {
61
102
  }
62
103
 
63
104
  return (
64
- <SidebarProvider>
65
- <Sidebar collapsible="icon">
66
- <SidebarHeader className="px-3 py-2">
67
- <div className="flex items-center gap-2">
68
- <AppIcon height={20} aria-hidden />
69
- <span className="truncate font-semibold group-data-[collapsible=icon]:hidden">
70
- Assistant
71
- </span>
72
- </div>
73
- </SidebarHeader>
74
- <SidebarContent>
75
- <SidebarGroup>
76
- <SidebarGroupContent>
77
- <SidebarMenu>
78
- {nav.map((n) => (
79
- <SidebarMenuItem key={n.id}>
80
- <SidebarMenuButton
81
- isActive={active === n.id}
82
- tooltip={n.label}
83
- onClick={() => setActive(n.id)}
84
- >
85
- <n.icon aria-hidden="true" />
86
- <span>{n.label}</span>
87
- </SidebarMenuButton>
88
- </SidebarMenuItem>
89
- ))}
90
- </SidebarMenu>
91
- </SidebarGroupContent>
92
- </SidebarGroup>
93
- </SidebarContent>
94
- </Sidebar>
95
- <SidebarInset className="flex flex-col overflow-hidden">
96
- <header className="flex h-14 shrink-0 items-center gap-2 border-b px-4">
97
- <SidebarTrigger />
98
- <h1 className="text-body font-medium">AI Assistant</h1>
99
- </header>
100
- <div className="flex flex-1 flex-col overflow-hidden">
101
- <Conversation className="flex-1">
102
- <ConversationContent>
103
- {messages.length === 0 ? (
104
- <ConversationEmptyState
105
- icon={<MessageSquare className="size-8" aria-hidden="true" />}
106
- title="Start the conversation"
107
- description="Ask anything to begin."
108
- actions={
109
- <>
110
- <Button
111
- onClick={() => send("What can you help me with?")}
112
- size="sm"
113
- variant="outline"
105
+ // The provider wraps the whole shell so the header trigger and the right
106
+ // rail share one open/closed state.
107
+ <ContextPanelProvider>
108
+ <SidebarProvider className="h-svh min-h-0">
109
+ <Sidebar collapsible="icon">
110
+ <SidebarHeader className="px-3 py-2">
111
+ <div className="flex items-center gap-2">
112
+ <AppIcon height={20} aria-hidden />
113
+ <span className="truncate font-semibold group-data-[collapsible=icon]:hidden">
114
+ Assistant
115
+ </span>
116
+ </div>
117
+ </SidebarHeader>
118
+ <SidebarContent>
119
+ <SidebarGroup>
120
+ <SidebarGroupContent>
121
+ <SidebarMenu>
122
+ {nav.map((n) => (
123
+ <SidebarMenuItem key={n.id}>
124
+ <SidebarMenuButton
125
+ isActive={active === n.id}
126
+ tooltip={n.label}
127
+ onClick={() => setActive(n.id)}
114
128
  >
115
- What can you help me with?
116
- </Button>
117
- <Button
118
- onClick={() => send("Summarize my recent activity")}
119
- size="sm"
120
- variant="outline"
121
- >
122
- Summarize my recent activity
123
- </Button>
124
- </>
125
- }
129
+ <n.icon aria-hidden="true" />
130
+ <span>{n.label}</span>
131
+ </SidebarMenuButton>
132
+ </SidebarMenuItem>
133
+ ))}
134
+ </SidebarMenu>
135
+ </SidebarGroupContent>
136
+ </SidebarGroup>
137
+ </SidebarContent>
138
+ <SidebarFooter>
139
+ <NavUser user={{ name: "Avery Rao", email: "avery@example.com" }} />
140
+ </SidebarFooter>
141
+ </Sidebar>
142
+ <SidebarInset className="flex min-w-0 flex-col overflow-hidden">
143
+ <header className="flex h-header shrink-0 items-center gap-2 border-b px-4">
144
+ <SidebarTrigger />
145
+ <h1 className="text-body font-medium">AI Assistant</h1>
146
+ <ContextPanelTrigger className="ms-auto" />
147
+ </header>
148
+ {/* `bare`: the transcript scrolls behind the floating composer and
149
+ both share one centred reading column. */}
150
+ <div className="min-h-0 flex-1">
151
+ <ChatShell
152
+ variant="bare"
153
+ composer={
154
+ <Composer
155
+ placeholder="Send a message…"
156
+ status={status === "submitted" ? "Generating…" : "Awaiting your input"}
157
+ sendStatus={status}
158
+ onSubmit={(message) => {
159
+ const text = message.text?.trim();
160
+ if (text) send(text);
161
+ }}
126
162
  />
127
- ) : (
128
- messages.map((m) => (
129
- <Message from={m.role} key={m.id}>
130
- <MessageContent>
131
- <MessageResponse>{m.text}</MessageResponse>
132
- </MessageContent>
133
- </Message>
134
- ))
135
- )}
136
- </ConversationContent>
137
- <ConversationScrollButton />
138
- </Conversation>
139
- <Composer
140
- placeholder="Send a message…"
141
- status={status === "submitted" ? "Generating…" : "Awaiting your input"}
142
- sendStatus={status}
143
- onSubmit={(message) => {
144
- const text = message.text?.trim();
145
- if (text) send(text);
146
- }}
163
+ }
164
+ >
165
+ <Conversation className="flex-1">
166
+ <ConversationContent>
167
+ {messages.length === 0 ? (
168
+ <ConversationEmptyState
169
+ icon={<MessageSquare className="size-8" aria-hidden="true" />}
170
+ title="Start the conversation"
171
+ description="Ask anything to begin."
172
+ actions={
173
+ <>
174
+ <Button
175
+ onClick={() => send("What can you help me with?")}
176
+ size="sm"
177
+ variant="outline"
178
+ >
179
+ What can you help me with?
180
+ </Button>
181
+ <Button
182
+ onClick={() => send("Summarize my recent activity")}
183
+ size="sm"
184
+ variant="outline"
185
+ >
186
+ Summarize my recent activity
187
+ </Button>
188
+ </>
189
+ }
190
+ />
191
+ ) : (
192
+ messages.map((m) => (
193
+ <Message from={m.role} key={m.id}>
194
+ <MessageContent>
195
+ <MessageResponse>{m.text}</MessageResponse>
196
+ </MessageContent>
197
+ </Message>
198
+ ))
199
+ )}
200
+ </ConversationContent>
201
+ <ConversationScrollButton />
202
+ </Conversation>
203
+ </ChatShell>
204
+ </div>
205
+ </SidebarInset>
206
+ <ContextPanel>
207
+ <ContextPanelHeader title="Context" />
208
+ <ContextPanelBody
209
+ root={<ContextRailRoot assets={assets} />}
210
+ detail={<ContextRailDetail />}
147
211
  />
148
- </div>
149
- </SidebarInset>
150
- </SidebarProvider>
212
+ </ContextPanel>
213
+ </SidebarProvider>
214
+ </ContextPanelProvider>
151
215
  );
152
216
  }
153
217
 
154
218
  const meta = {
155
- title: "Patterns/Templates/AI Assistant",
219
+ title: "Patterns/Templates/Starters/AI Assistant",
156
220
  parameters: { layout: "fullscreen" },
157
221
  tags: ["autodocs"],
158
222
  } satisfies Meta;
@@ -1,4 +1,5 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react-vite";
2
+ import { expect, userEvent } from "storybook/test";
2
3
  import {
3
4
  Tool,
4
5
  ToolContent,
@@ -68,3 +69,41 @@ export const Streaming: Story = {
68
69
  );
69
70
  },
70
71
  };
72
+
73
+ /**
74
+ * Focus indicator on ToolDetails trigger (#313): Tab to the disclosure
75
+ * trigger and assert the compound indicator's OUTLINE layer. The prior
76
+ * version read `buttons[0]` — but `ToolHeader` (rendered before `ToolDetails`
77
+ * in the DOM) is ALSO a `CollapsibleTrigger` (`tool.tsx:98`, the outer
78
+ * `Tool` row's own disclosure) with no focus styling of its own, so it is
79
+ * `buttons[0]` and receives the first Tab, not the `ToolDetails` trigger
80
+ * this issue is about (`tool.tsx:152`). Query the actual trigger by its
81
+ * accessible name (`t("ai.tool.showTechnicalDetails")`) instead of by index.
82
+ */
83
+ export const FocusIndicator: Story = {
84
+ render: () => (
85
+ // defaultOpen on the OUTER Tool — its ToolContent (and so ToolDetails'
86
+ // trigger) is hidden/unmounted when the outer Collapsible starts closed,
87
+ // as it does without this prop (see Default story). Without it the
88
+ // ToolDetails trigger this test targets isn't in the accessibility tree
89
+ // at all, and `getByRole` throws before ever reaching the focus check.
90
+ <Tool defaultOpen className="max-w-prose">
91
+ <ToolHeader type="tool-fetch" state="output-available" summary="Fetched data" />
92
+ <ToolContent>
93
+ <ToolDetails>
94
+ <ToolInput input={{ url: "https://example.com" }} />
95
+ <ToolOutput output={{ status: "ok" }} />
96
+ </ToolDetails>
97
+ </ToolContent>
98
+ </Tool>
99
+ ),
100
+ play: async ({ canvas }) => {
101
+ const trigger = canvas.getByRole("button", { name: /show technical details/i });
102
+ trigger.focus();
103
+ await expect(trigger).toHaveFocus();
104
+ const focused = getComputedStyle(trigger);
105
+ await expect(focused.boxShadow).not.toBe("none");
106
+ await expect(focused.outlineStyle).toBe("solid");
107
+ await expect(parseFloat(focused.outlineWidth)).toBeGreaterThan(0);
108
+ },
109
+ };
package/src/tool.tsx CHANGED
@@ -149,7 +149,7 @@ export const ToolDetails = ({
149
149
  defaultOpen={defaultOpen}
150
150
  {...props}
151
151
  >
152
- <CollapsibleTrigger className="flex items-center gap-1 rounded-sm text-meta text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring">
152
+ <CollapsibleTrigger className="flex items-center gap-1 rounded-sm text-meta text-muted-foreground transition-colors hover:text-foreground focus-ring">
153
153
  <ChevronDownIcon className="size-3.5 transition-transform group-data-[state=open]/tool-details:rotate-180" />
154
154
  {label ?? t("ai.tool.showTechnicalDetails")}
155
155
  </CollapsibleTrigger>
@@ -166,7 +166,7 @@ export const ToolInput = ({ className, input, ...props }: ToolInputProps) => {
166
166
  const { t } = useLocale();
167
167
  return (
168
168
  <div className={cn("space-y-2 overflow-hidden", className)} {...props}>
169
- <h4 className="text-meta uppercase text-muted-foreground">
169
+ <h4 className="text-eyebrow uppercase text-muted-foreground">
170
170
  {t("ai.schemaDisplay.parameters")}
171
171
  </h4>
172
172
  <div className="rounded-md bg-muted/50">
@@ -250,7 +250,7 @@ export const ToolOutput = ({
250
250
 
251
251
  return (
252
252
  <div className={cn("space-y-2", className)} {...props}>
253
- <h4 className="text-meta uppercase text-muted-foreground">
253
+ <h4 className="text-eyebrow uppercase text-muted-foreground">
254
254
  {showError ? t("ai.tool.error") : t("ai.tool.result")}
255
255
  </h4>
256
256
  {pending ? (
package/src/toolbar.tsx CHANGED
@@ -32,13 +32,3 @@ export const NodeToolbar = (props: NodeToolbarProps) => (
32
32
  <NodeToolbarImpl data-slot="node-toolbar" {...props} />
33
33
  </Suspense>
34
34
  );
35
-
36
- /**
37
- * @deprecated Renamed to {@link NodeToolbar}. `Toolbar` is now the WAI-ARIA
38
- * toolbar in `@elabs-ai/components-ui`. This alias will be removed in
39
- * the next major.
40
- */
41
- export const Toolbar = NodeToolbar;
42
-
43
- /** @deprecated Renamed to {@link NodeToolbarProps}. */
44
- export type ToolbarProps = NodeToolbarProps;
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/_flow-boundary.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * The React Flow half of `@elabs-ai/components-ai`'s in-chat agent\n * workspace graph — `Canvas`, `Controls`, `Edge`, `Node`, `Panel`, `Toolbar` —\n * split out so the engine can be `lazy()`-loaded.\n *\n * `@xyflow/react` declares no `sideEffects`, so the six static imports it used to\n * have (one per public module, plus `@xyflow/react/dist/style.css`) put the whole\n * engine into the entry chunk of every consumer, canvas rendered or not. **The\n * stylesheet import has to live here too**: a bare\n * `import \"@xyflow/react/dist/style.css\"` in `canvas.tsx` keeps the edge alive on\n * its own.\n *\n * This is ONE boundary for all six parts on purpose (see `_flow-lazy.ts`): six\n * boundaries would be six chunks all pulling the same engine. The public modules\n * keep their `import type { … } from \"@xyflow/react\"` lines (types erase) and\n * their prop types, and render a `lazy()` wrapper over the implementations here.\n * `connection.tsx` is type-only already and needs no boundary.\n *\n * See ADR 0019 and `pnpm heavy-deps:check`.\n *\n * @lazy-boundary This module must only ever be reached via `import()`. The gate\n * fails if anything imports it statically, which would put React Flow back in\n * the entry chunk and make the `lazy()` pointless.\n */\nimport { Card } from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport type { EdgeProps, InternalNode, Node as FlowNode } from \"@xyflow/react\";\nimport {\n Background,\n BaseEdge,\n Controls as ControlsPrimitive,\n getBezierPath,\n getSimpleBezierPath,\n Handle,\n NodeToolbar,\n Panel as PanelPrimitive,\n Position,\n ReactFlow,\n useInternalNode,\n} from \"@xyflow/react\";\n\nimport \"@xyflow/react/dist/style.css\";\n\nimport type { CanvasProps } from \"./canvas\";\nimport type { ControlsProps } from \"./controls\";\nimport type { NodeProps } from \"./node\";\nimport type { PanelProps } from \"./panel\";\nimport type { ToolbarProps } from \"./toolbar\";\n\nconst deleteKeyCode = [\"Backspace\", \"Delete\"];\n\n/**\n * The React Flow attribution badge is hidden on both canvas surfaces (here and\n * `@elabs-ai/components-flow`'s `CanvasShell`). `@xyflow/react` is\n * MIT — the licence requires the notice in source copies, not a rendered badge —\n * and xyflow asks that the badge only be hidden under a React Flow Pro\n * subscription. Keeping it is therefore a product/commercial decision, and this\n * repo's is to hide it. A consumer can restore it per-canvas with\n * `proOptions={{ hideAttribution: false }}`, which still wins via `...props`.\n */\nconst proOptions = { hideAttribution: true };\n\nexport const Canvas = ({ children, ...props }: CanvasProps) => (\n <ReactFlow\n deleteKeyCode={deleteKeyCode}\n fitView\n panOnDrag={false}\n panOnScroll\n proOptions={proOptions}\n selectionOnDrag={true}\n zoomOnDoubleClick={false}\n {...props}\n >\n <Background bgColor=\"var(--sidebar)\" />\n {children}\n </ReactFlow>\n);\n\nexport const Controls = ({ className, ...props }: ControlsProps) => (\n <ControlsPrimitive\n className={cn(\n \"gap-px overflow-hidden rounded-md border bg-card p-1 shadow-none!\",\n \"[&>button]:rounded-md [&>button]:border-none! [&>button]:bg-transparent! [&>button]:hover:bg-secondary!\",\n className,\n )}\n {...props}\n />\n);\n\nexport const EdgeTemporary = ({\n id,\n sourceX,\n sourceY,\n targetX,\n targetY,\n sourcePosition,\n targetPosition,\n}: EdgeProps) => {\n const [edgePath] = getSimpleBezierPath({\n sourcePosition,\n sourceX,\n sourceY,\n targetPosition,\n targetX,\n targetY,\n });\n\n return (\n <BaseEdge\n className=\"stroke-1 stroke-ring\"\n id={id}\n path={edgePath}\n style={{\n strokeDasharray: \"5, 5\",\n }}\n />\n );\n};\n\n/**\n * The point on `node` where an edge of `handleType` should attach, plus the side\n * it leaves from.\n *\n * Read from React Flow's **measured** `handleBounds` — the DOM box of the\n * painted dot — and taken at the box's OUTER edge, which is React Flow's own\n * convention (the anchor lands on the dot's rim, which keeps a `markerEnd`\n * visible).\n *\n * The two fallbacks matter as much as the happy path. `preferred` is only a\n * preference: `nodeTypes` is an open prop, so a consumer node may legitimately\n * put its handles on the top and bottom, and the shipped `Node`'s left/right\n * pair is a convenience rather than a constraint. And `handleBounds` is empty\n * until React Flow's first measurement pass, which on this canvas is a real\n * window because the engine arrives in a lazy chunk (ADR 0019). Both used to\n * resolve to `[0, 0]` — the CANVAS ORIGIN — so the edge was drawn hundreds of\n * pixels from either node (measured at 498.8px in the `VerticalHandles` story).\n * Falling back to any handle of the right type, and then to the node's own\n * border, keeps the line on the node in every case.\n */\nconst getHandleAnchor = (\n node: InternalNode<FlowNode>,\n handleType: \"source\" | \"target\",\n preferred: Position,\n) => {\n const bounds = node.internals.handleBounds?.[handleType] ?? [];\n const handle = bounds.find((h) => h.position === preferred) ?? bounds[0];\n const origin = node.internals.positionAbsolute;\n\n if (handle) {\n // Offset to the handle box's outer edge on its own side; the other axis is\n // centred.\n const offsetX =\n handle.position === Position.Left\n ? 0\n : handle.position === Position.Right\n ? handle.width\n : handle.width / 2;\n const offsetY =\n handle.position === Position.Top\n ? 0\n : handle.position === Position.Bottom\n ? handle.height\n : handle.height / 2;\n\n return {\n position: handle.position,\n x: origin.x + handle.x + offsetX,\n y: origin.y + handle.y + offsetY,\n };\n }\n\n // No measured handle at all — anchor on the node's own border midpoint.\n const width = node.measured.width ?? 0;\n const height = node.measured.height ?? 0;\n switch (preferred) {\n case Position.Left:\n return { position: preferred, x: origin.x, y: origin.y + height / 2 };\n case Position.Right:\n return { position: preferred, x: origin.x + width, y: origin.y + height / 2 };\n case Position.Top:\n return { position: preferred, x: origin.x + width / 2, y: origin.y };\n default:\n return { position: preferred, x: origin.x + width / 2, y: origin.y + height };\n }\n};\n\nconst getEdgeParams = (source: InternalNode<FlowNode>, target: InternalNode<FlowNode>) => {\n const from = getHandleAnchor(source, \"source\", Position.Right);\n const to = getHandleAnchor(target, \"target\", Position.Left);\n\n return {\n sourcePos: from.position,\n sx: from.x,\n sy: from.y,\n targetPos: to.position,\n tx: to.x,\n ty: to.y,\n };\n};\n\nexport const EdgeAnimated = ({ id, source, target, markerEnd, style }: EdgeProps) => {\n const sourceNode = useInternalNode(source);\n const targetNode = useInternalNode(target);\n\n if (!(sourceNode && targetNode)) {\n return null;\n }\n\n const { sx, sy, tx, ty, sourcePos, targetPos } = getEdgeParams(sourceNode, targetNode);\n\n const [edgePath] = getBezierPath({\n sourcePosition: sourcePos,\n sourceX: sx,\n sourceY: sy,\n targetPosition: targetPos,\n targetX: tx,\n targetY: ty,\n });\n\n return (\n <>\n <BaseEdge id={id} markerEnd={markerEnd} path={edgePath} style={style} />\n <circle fill=\"var(--primary)\" r=\"4\">\n <animateMotion dur=\"2s\" path={edgePath} repeatCount=\"indefinite\" />\n </circle>\n </>\n );\n};\n\nexport const Node = ({ handles, className, ...props }: NodeProps) => (\n <Card\n className={cn(\"node-container relative size-full h-auto w-sm gap-0 rounded-md p-0\", className)}\n {...props}\n >\n {handles.target && <Handle position={Position.Left} type=\"target\" />}\n {handles.source && <Handle position={Position.Right} type=\"source\" />}\n {props.children}\n </Card>\n);\n\nexport const Panel = ({ className, ...props }: PanelProps) => (\n <PanelPrimitive\n className={cn(\"m-4 overflow-hidden rounded-md border bg-card p-1\", className)}\n {...props}\n />\n);\n\nexport const Toolbar = ({ className, ...props }: ToolbarProps) => (\n <NodeToolbar\n className={cn(\"flex items-center gap-1 rounded-sm border bg-background p-1.5\", className)}\n position={Position.Bottom}\n {...props}\n />\n);\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/_persona-rive.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * The Rive half of `Persona`, split out so it can be `lazy()`-loaded.\n *\n * `@rive-app/react-webgl2` declares no `sideEffects`, so a static import from\n * `persona.tsx` put the whole WebGL2 runtime (and its `rive.wasm`) into the entry\n * chunk of every `@elabs-ai/components-ai` consumer — including the vast majority that never\n * render a `Persona`. Keeping every Rive *value* import in this module, reached\n * only through `lazy(() => import(\"./_persona-rive\"))`, confines it to its own\n * chunk. `persona.tsx` may still `import type` from Rive (types erase).\n *\n * See ADR 0019 and `pnpm heavy-deps:check`.\n *\n * @lazy-boundary This module must only ever be reached via `import()`. The gate\n * fails if anything imports it statically, which would put Rive back in the\n * entry chunk and make the `lazy()` pointless.\n */\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport { useReducedMotion } from \"@elabs-ai/components-tokens\";\nimport type { RiveParameters } from \"@rive-app/react-webgl2\";\n// `import type` from an optional peer is safe HERE ONLY because this module is\n// reached exclusively through `lazy(() => import(\"./_persona-rive\"))` — it is\n// never statically imported, so nothing in this file reaches the barrel's\n// `.d.ts` declaration graph. `persona.tsx`'s PUBLIC types must never do this\n// (issue #101) — see its module doc comment and `PersonaRiveEvent`/\n// `PersonaRiveEventCallback`, which this module imports below and proves\n// conformant against the real peer type at the bottom of this file.\n// A NAMED import (`import { useRive } from \"@rive-app/react-webgl2\"`) is a\n// static ESM binding a bundler must resolve at build time. Now that\n// `@rive-app/react-webgl2` is a genuinely optional peer (issue #33), a\n// consumer who has not installed it hits that resolution at the worst\n// possible time: Vite's own optional-peer-dependency handling swaps in a\n// build-time stub with no exports, and Rollup's static named-export check\n// then fails the WHOLE APP BUILD — not a runtime error `LazyEngineBoundary`\n// could ever see (confirmed against `fixtures/consumer-smoke`'s real Vite\n// build). A namespace import defers every one of these to a plain property\n// lookup, which Rollup does not statically validate, so the build always\n// succeeds; a genuinely missing peer instead resolves the destructured hooks\n// below to `undefined`, and the guard turns that into the render-phase throw\n// `LazyEngineBoundary` (see `persona.tsx`) already catches.\nimport * as RiveModule from \"@rive-app/react-webgl2\";\nimport type { ReactNode } from \"react\";\nimport { memo, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport type { AssertAssignable } from \"./_lazy-boundary-conformance\";\nimport type { PersonaRiveEventCallback } from \"./persona\";\nimport type { PersonaSource, PersonaState } from \"./persona-sources\";\n\nconst {\n useRive,\n useStateMachineInput,\n useViewModel,\n useViewModelInstance,\n useViewModelInstanceColor,\n} = RiveModule;\n\nif (!useRive) {\n throw new Error(\"Cannot find module '@rive-app/react-webgl2'\");\n}\n\n// Delays Rive initialization by one frame so that React Strict Mode's\n// immediate unmount cycle never creates a WebGL2 context. Only the\n// second (real) mount will initialise, avoiding context exhaustion.\nconst useStrictModeSafeInit = () => {\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n const id = requestAnimationFrame(() => setReady(true));\n return () => {\n cancelAnimationFrame(id);\n setReady(false);\n };\n }, []);\n\n return ready;\n};\n\n// The state machine name is always 'default' for Elements AI visuals\nconst stateMachine = \"default\";\n\nconst getCurrentTheme = (): \"light\" | \"dark\" => {\n if (typeof window !== \"undefined\") {\n if (document.documentElement.classList.contains(\"dark\")) {\n return \"dark\";\n }\n if (window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches) {\n return \"dark\";\n }\n }\n return \"light\";\n};\n\nconst useTheme = (enabled: boolean) => {\n const [theme, setTheme] = useState<\"light\" | \"dark\">(getCurrentTheme);\n\n useEffect(() => {\n // Skip if not enabled (avoids unnecessary observers for non-dynamic-color variants)\n if (!enabled) {\n return;\n }\n\n // Watch for classList changes\n const observer = new MutationObserver(() => {\n setTheme(getCurrentTheme());\n });\n\n observer.observe(document.documentElement, {\n attributeFilter: [\"class\"],\n attributes: true,\n });\n\n // Watch for OS-level theme changes\n let mql: MediaQueryList | null = null;\n const handleMediaChange = () => {\n setTheme(getCurrentTheme());\n };\n\n if (window.matchMedia) {\n mql = window.matchMedia(\"(prefers-color-scheme: dark)\");\n mql.addEventListener(\"change\", handleMediaChange);\n }\n\n return () => {\n observer.disconnect();\n if (mql) {\n mql.removeEventListener(\"change\", handleMediaChange);\n }\n };\n }, [enabled]);\n\n return theme;\n};\n\ninterface PersonaWithModelProps {\n rive: ReturnType<typeof useRive>[\"rive\"];\n source: PersonaSource;\n children: ReactNode;\n}\n\nconst PersonaWithModel = memo(({ rive, source, children }: PersonaWithModelProps) => {\n const theme = useTheme(source.dynamicColor);\n const viewModel = useViewModel(rive, { useDefault: true });\n const viewModelInstance = useViewModelInstance(viewModel, {\n rive,\n useDefault: true,\n });\n const viewModelInstanceColor = useViewModelInstanceColor(\"color\", viewModelInstance);\n\n useEffect(() => {\n if (!(viewModelInstanceColor && source.dynamicColor)) {\n return;\n }\n\n const [r, g, b] = theme === \"dark\" ? [255, 255, 255] : [0, 0, 0];\n viewModelInstanceColor.setRgb(r, g, b);\n }, [viewModelInstanceColor, theme, source.dynamicColor]);\n\n return children;\n});\n\nPersonaWithModel.displayName = \"PersonaWithModel\";\n\nconst PersonaWithoutModel = memo(({ children }: { children: ReactNode }) => children);\n\nPersonaWithoutModel.displayName = \"PersonaWithoutModel\";\n\nexport interface PersonaRiveProps {\n className?: string;\n onLoad?: PersonaRiveEventCallback;\n onLoadError?: PersonaRiveEventCallback;\n onPause?: PersonaRiveEventCallback;\n onPlay?: PersonaRiveEventCallback;\n onReady?: () => void;\n onStop?: PersonaRiveEventCallback;\n source: PersonaSource;\n /** Resolved `.riv` URL — `Persona`'s `src` override, or the variant default. */\n src: string;\n state: PersonaState;\n}\n\nconst PersonaRive = ({\n className,\n onLoad,\n onLoadError,\n onPause,\n onPlay,\n onReady,\n onStop,\n source,\n src,\n state,\n}: PersonaRiveProps) => {\n // Stabilize callbacks to prevent useRive from reinitializing\n const callbacksRef = useRef({ onLoad, onLoadError, onPause, onPlay, onReady, onStop });\n\n useEffect(() => {\n callbacksRef.current = { onLoad, onLoadError, onPause, onPlay, onReady, onStop };\n }, [onLoad, onLoadError, onPause, onPlay, onReady, onStop]);\n\n const stableCallbacks = useMemo(\n () => ({\n onLoad: ((loadedRive) =>\n callbacksRef.current.onLoad?.(loadedRive)) as RiveParameters[\"onLoad\"],\n onLoadError: ((err) =>\n callbacksRef.current.onLoadError?.(err)) as RiveParameters[\"onLoadError\"],\n onPause: ((event) => callbacksRef.current.onPause?.(event)) as RiveParameters[\"onPause\"],\n onPlay: ((event) => callbacksRef.current.onPlay?.(event)) as RiveParameters[\"onPlay\"],\n onReady: () => callbacksRef.current.onReady?.(),\n onStop: ((event) => callbacksRef.current.onStop?.(event)) as RiveParameters[\"onStop\"],\n }),\n [],\n );\n\n // Delay initialisation by one frame to avoid creating (and leaking)\n // a WebGL2 context during React Strict Mode's first throw-away mount.\n const ready = useStrictModeSafeInit();\n const prefersReducedMotion = useReducedMotion();\n\n const { rive, RiveComponent } = useRive(\n ready\n ? {\n autoplay: !prefersReducedMotion,\n onLoad: stableCallbacks.onLoad,\n onLoadError: stableCallbacks.onLoadError,\n onPause: stableCallbacks.onPause,\n onPlay: stableCallbacks.onPlay,\n onRiveReady: stableCallbacks.onReady,\n onStop: stableCallbacks.onStop,\n src,\n stateMachines: stateMachine,\n }\n : null,\n );\n\n // `autoplay` only governs the INITIAL mount — honor a mid-session\n // reduced-motion preference change by pausing/resuming the running\n // instance. The state-machine inputs below keep updating either way, so\n // the artwork still shows the correct resting pose while paused.\n useEffect(() => {\n if (!rive) return;\n if (prefersReducedMotion) {\n rive.pause();\n } else {\n rive.play();\n }\n }, [rive, prefersReducedMotion]);\n\n const listeningInput = useStateMachineInput(rive, stateMachine, \"listening\");\n const thinkingInput = useStateMachineInput(rive, stateMachine, \"thinking\");\n const speakingInput = useStateMachineInput(rive, stateMachine, \"speaking\");\n const asleepInput = useStateMachineInput(rive, stateMachine, \"asleep\");\n\n // Rive state machine inputs are mutable objects that must be set via direct\n // property assignment — this is the intended Rive API, not a React anti-pattern.\n useEffect(() => {\n if (listeningInput) {\n listeningInput.value = state === \"listening\";\n }\n if (thinkingInput) {\n thinkingInput.value = state === \"thinking\";\n }\n if (speakingInput) {\n speakingInput.value = state === \"speaking\";\n }\n if (asleepInput) {\n asleepInput.value = state === \"asleep\";\n }\n }, [state, listeningInput, thinkingInput, speakingInput, asleepInput]);\n\n const Wrapper = source.hasModel ? PersonaWithModel : PersonaWithoutModel;\n\n return (\n <Wrapper rive={rive} source={source}>\n <RiveComponent className={cn(\"size-16 shrink-0\", className)} />\n </Wrapper>\n );\n};\n\nexport default PersonaRive;\n\n/**\n * Conformance assertion (issue #101): compile-time proof that the owned\n * `PersonaRiveEventCallback` (declared in `persona.tsx`, structurally free of\n * `@rive-app/react-webgl2`/`@rive-app/webgl2`) is still assignable to the REAL\n * `RiveParameters[\"onLoad\"]` — and, since `onLoad`/`onLoadError`/`onPause`/\n * `onPlay`/`onStop` all share Rive's one `EventCallback` type, this single\n * check covers all five. `AssertAssignable`'s type parameter is constrained\n * (`TOwned extends TReal`), so if a future Rive release changes `Event`'s\n * shape in a way `PersonaRiveEvent` no longer satisfies, this line fails to\n * typecheck — caught by `pnpm --filter @elabs-ai/components-ai typecheck`\n * locally, never shipped as a silent mismatch to a consumer.\n *\n * `AssertAssignable` itself is shared with `_audio-player-media-chrome.tsx`\n * via `_lazy-boundary-conformance.ts` — see that module's doc comment for\n * what this check can and cannot prove (it is one-directional: it cannot\n * catch the owned type being NARROWER than the real one, which is exactly\n * what `PersonaRiveEvent[\"data\"]` is — see the CHANGELOG's \"Breaking (types)\"\n * entry).\n */\nexport type _PersonaRiveEventCallbackConformance = AssertAssignable<\n PersonaRiveEventCallback,\n NonNullable<RiveParameters[\"onLoad\"]>\n>;\n"],"mappings":"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","names":[]}