@keboola/design 13.2.0 → 15.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 (321) hide show
  1. package/AGENTS.md +16 -24
  2. package/CHANGELOG.md +194 -0
  3. package/COMPONENT-API.md +109 -105
  4. package/dist/{AIKit-C5FbKjwa.js → AIKit-CaAW4GLx.js} +2216 -307
  5. package/dist/AIKit-CaAW4GLx.js.map +1 -0
  6. package/dist/{Alert-DuAGeYyM.js → Alert-Chz6KZ7e.js} +11 -20
  7. package/dist/Alert-Chz6KZ7e.js.map +1 -0
  8. package/dist/{AlertModal-BDle9ZVQ.js → AlertModal-D4AtpvLS.js} +15 -35
  9. package/dist/AlertModal-D4AtpvLS.js.map +1 -0
  10. package/dist/{AppShell-B03fj1j7.js → AppShell-C8V1KRr_.js} +2 -2
  11. package/dist/{AppShell-B03fj1j7.js.map → AppShell-C8V1KRr_.js.map} +1 -1
  12. package/dist/{AutoSaveTextarea-jiqNeeE4.js → AutoSaveTextarea-BbMhC5Aq.js} +3 -3
  13. package/dist/AutoSaveTextarea-BbMhC5Aq.js.map +1 -0
  14. package/dist/{Badge-Ba3epgcI.js → Badge-5GHIsgRS.js} +14 -3
  15. package/dist/Badge-5GHIsgRS.js.map +1 -0
  16. package/dist/{BrandEditor-Dq168RJc.js → BrandEditor-CTGtQUFZ.js} +8 -10
  17. package/dist/BrandEditor-CTGtQUFZ.js.map +1 -0
  18. package/dist/{BrandLogo-BfITD0im.js → BrandLogo-DkESE19K.js} +2 -2
  19. package/dist/{BrandLogo-BfITD0im.js.map → BrandLogo-DkESE19K.js.map} +1 -1
  20. package/dist/{Breadcrumb-CUyYu5Bi.js → Breadcrumb-B2YSNON4.js} +55 -13
  21. package/dist/Breadcrumb-B2YSNON4.js.map +1 -0
  22. package/dist/{Button-D2JqBAq7.js → Button-BNkyYU8u.js} +9 -185
  23. package/dist/Button-BNkyYU8u.js.map +1 -0
  24. package/dist/{Card-Bpc_ZlL4.js → Card-DxjGiqH8.js} +11 -18
  25. package/dist/Card-DxjGiqH8.js.map +1 -0
  26. package/dist/{Checkbox-D9rafoKh.js → Checkbox-CHDDJyAA.js} +20 -45
  27. package/dist/Checkbox-CHDDJyAA.js.map +1 -0
  28. package/dist/{Clipboard-BHWUodAx.js → Clipboard-DlwVZS1P.js} +2 -2
  29. package/dist/{Clipboard-BHWUodAx.js.map → Clipboard-DlwVZS1P.js.map} +1 -1
  30. package/dist/{ClipboardButton-Urg-kZbh.js → ClipboardButton-B1Hr_n_Z.js} +3 -3
  31. package/dist/{ClipboardButton-Urg-kZbh.js.map → ClipboardButton-B1Hr_n_Z.js.map} +1 -1
  32. package/dist/{CodeEditor-Y0iE-SwV.js → CodeEditor-DVSPdfdo.js} +24 -31
  33. package/dist/CodeEditor-DVSPdfdo.js.map +1 -0
  34. package/dist/{ColorInput-D1nC0X6i.js → ColorInput-B_eZIu39.js} +5 -7
  35. package/dist/ColorInput-B_eZIu39.js.map +1 -0
  36. package/dist/{ColorModeSwitch-Cxee8jnB.js → ColorModeSwitch-B6UEzG0H.js} +3 -3
  37. package/dist/{ColorModeSwitch-Cxee8jnB.js.map → ColorModeSwitch-B6UEzG0H.js.map} +1 -1
  38. package/dist/{Combobox-B1Kjoy5J.js → Combobox-CaKqgstG.js} +250 -56
  39. package/dist/Combobox-CaKqgstG.js.map +1 -0
  40. package/dist/{Command-BuOA3V18.js → Command-DhXmqFLT.js} +51 -33
  41. package/dist/Command-DhXmqFLT.js.map +1 -0
  42. package/dist/{CopyField-DsOVtV2Q.js → CopyField-D0Pg4Z0R.js} +2 -2
  43. package/dist/{CopyField-DsOVtV2Q.js.map → CopyField-D0Pg4Z0R.js.map} +1 -1
  44. package/dist/{DateInput-BlKkequE.js → DateInput-BgbMDJkm.js} +5 -7
  45. package/dist/DateInput-BgbMDJkm.js.map +1 -0
  46. package/dist/{DatePicker-CgHAu9KX.js → DatePicker-BXpDRo-R.js} +2 -2
  47. package/dist/{DatePicker-CgHAu9KX.js.map → DatePicker-BXpDRo-R.js.map} +1 -1
  48. package/dist/{DateRangeInput-DOxJHw8V.js → DateRangeInput-BW0-_jV0.js} +5 -7
  49. package/dist/DateRangeInput-BW0-_jV0.js.map +1 -0
  50. package/dist/{DateRangePicker-CXpXPMoh.js → DateRangePicker-C4-DoWac.js} +7 -12
  51. package/dist/DateRangePicker-C4-DoWac.js.map +1 -0
  52. package/dist/{DropdownMenu-DtRYcKEx.js → DropdownMenu-CcVbZ_5u.js} +35 -64
  53. package/dist/DropdownMenu-CcVbZ_5u.js.map +1 -0
  54. package/dist/{FieldItem-Cf1E3rfQ.js → FieldItem-BHUqgSO1.js} +3 -3
  55. package/dist/{FieldItem-Cf1E3rfQ.js.map → FieldItem-BHUqgSO1.js.map} +1 -1
  56. package/dist/{FileUpload-D6vPG3WB.js → FileUpload-BYFONpEl.js} +3 -3
  57. package/dist/FileUpload-BYFONpEl.js.map +1 -0
  58. package/dist/{Form-CuaAn-lR.js → Form-CAofWyMI.js} +8 -8
  59. package/dist/{Form-CuaAn-lR.js.map → Form-CAofWyMI.js.map} +1 -1
  60. package/dist/{FormGroup-D4O96YPm.js → FormGroup-V5kIgQRN.js} +3 -3
  61. package/dist/{FormGroup-D4O96YPm.js.map → FormGroup-V5kIgQRN.js.map} +1 -1
  62. package/dist/{FullScreenModal-CUuAakh3.js → FullScreenModal-DAvvlGOz.js} +2 -5
  63. package/dist/FullScreenModal-DAvvlGOz.js.map +1 -0
  64. package/dist/HoverCard-Cv5rmvJq.js +26 -0
  65. package/dist/HoverCard-Cv5rmvJq.js.map +1 -0
  66. package/dist/{InlineEdit-DSMIEUUa.js → InlineEdit-D4P0SvCB.js} +5 -9
  67. package/dist/InlineEdit-D4P0SvCB.js.map +1 -0
  68. package/dist/{InputGroup-Dm014ruw.js → InputGroup-CZv_7QlM.js} +39 -146
  69. package/dist/InputGroup-CZv_7QlM.js.map +1 -0
  70. package/dist/{Kbd-Du93F3o4.js → Kbd-CflKthfu.js} +5 -14
  71. package/dist/Kbd-CflKthfu.js.map +1 -0
  72. package/dist/MermaidDiagram-Te-5gOCU.js +199 -0
  73. package/dist/MermaidDiagram-Te-5gOCU.js.map +1 -0
  74. package/dist/{Modal-DQIauzar.js → Modal-CbUz-5YH.js} +19 -37
  75. package/dist/Modal-CbUz-5YH.js.map +1 -0
  76. package/dist/{ModalTitle-CTECVgL8.js → ModalTitle-cy0Ht9VY.js} +2 -2
  77. package/dist/{ModalTitle-CTECVgL8.js.map → ModalTitle-cy0Ht9VY.js.map} +1 -1
  78. package/dist/{MultiActionButtonGroup-xKqiucAN.js → MultiActionButtonGroup-Dzig87s1.js} +3 -3
  79. package/dist/{MultiActionButtonGroup-xKqiucAN.js.map → MultiActionButtonGroup-Dzig87s1.js.map} +1 -1
  80. package/dist/{Navbar-CtVYcRFn.js → Navbar-DHUS7XiU.js} +2 -2
  81. package/dist/{Navbar-CtVYcRFn.js.map → Navbar-DHUS7XiU.js.map} +1 -1
  82. package/dist/OtpInput-CY8yCaJk.js.map +1 -1
  83. package/dist/{PageToolbar-B_e7HGva.js → PageToolbar-DJ5tdYla.js} +4 -4
  84. package/dist/{PageToolbar-B_e7HGva.js.map → PageToolbar-DJ5tdYla.js.map} +1 -1
  85. package/dist/{Pagination-DDp6PRqf.js → Pagination-D27x5KmH.js} +2 -2
  86. package/dist/{Pagination-DDp6PRqf.js.map → Pagination-D27x5KmH.js.map} +1 -1
  87. package/dist/{Popconfirm-BgV6a0sl.js → Popconfirm-DwLCYNaF.js} +3 -3
  88. package/dist/{Popconfirm-BgV6a0sl.js.map → Popconfirm-DwLCYNaF.js.map} +1 -1
  89. package/dist/{Popover-BU7nGOv-.js → Popover-DtUDwUVO.js} +24 -37
  90. package/dist/Popover-DtUDwUVO.js.map +1 -0
  91. package/dist/{RadioGroup-C2vk5acr.js → RadioGroup-B0TwHjBb.js} +9 -13
  92. package/dist/RadioGroup-B0TwHjBb.js.map +1 -0
  93. package/dist/{Search-CVrv3hqf.js → Search-vyZwGKMU.js} +3 -3
  94. package/dist/{Search-CVrv3hqf.js.map → Search-vyZwGKMU.js.map} +1 -1
  95. package/dist/{SearchInput-BnU6YHgT.js → SearchInput-DyYXyw3u.js} +4 -6
  96. package/dist/SearchInput-DyYXyw3u.js.map +1 -0
  97. package/dist/{SectionNav-XlhvXXdF.js → SectionNav-tLK3iF6c.js} +5 -5
  98. package/dist/{SectionNav-XlhvXXdF.js.map → SectionNav-tLK3iF6c.js.map} +1 -1
  99. package/dist/{Select-CjQgU_6K.js → Select-B22hB_-w.js} +11 -25
  100. package/dist/Select-B22hB_-w.js.map +1 -0
  101. package/dist/{Sheet-utw4_rUa.js → Sheet-0TWKTqid.js} +12 -15
  102. package/dist/Sheet-0TWKTqid.js.map +1 -0
  103. package/dist/{Sidebar-CKaxOPwY.js → Sidebar-C5hdANBU.js} +11 -11
  104. package/dist/Sidebar-C5hdANBU.js.map +1 -0
  105. package/dist/{Slider-Rcc2qVct.js → Slider-DrcsM8_G.js} +4 -4
  106. package/dist/Slider-DrcsM8_G.js.map +1 -0
  107. package/dist/{Stepper-BBPembeK.js → Stepper-CQrUPVFL.js} +2 -2
  108. package/dist/Stepper-CQrUPVFL.js.map +1 -0
  109. package/dist/Switch-DccpSpzC.js +66 -0
  110. package/dist/Switch-DccpSpzC.js.map +1 -0
  111. package/dist/{Table-CgSC-fSo.js → Table-CilEvpMq.js} +62 -3
  112. package/dist/Table-CilEvpMq.js.map +1 -0
  113. package/dist/{Tabs-C0uvkPHc.js → Tabs-Ck4uWf8U.js} +2 -2
  114. package/dist/{Tabs-C0uvkPHc.js.map → Tabs-Ck4uWf8U.js.map} +1 -1
  115. package/dist/{TextInput-B5TDDOty.js → TextInput-CR0_USaY.js} +4 -7
  116. package/dist/TextInput-CR0_USaY.js.map +1 -0
  117. package/dist/{ThemeProvider-Dt9b67sW.js → ThemeProvider-BTK7AL-T.js} +21 -8
  118. package/dist/ThemeProvider-BTK7AL-T.js.map +1 -0
  119. package/dist/{TimePicker-DyyV3nw8.js → TimePicker-CoRpiEM3.js} +2 -2
  120. package/dist/{TimePicker-DyyV3nw8.js.map → TimePicker-CoRpiEM3.js.map} +1 -1
  121. package/dist/{Toast-BGnUL4jV.js → Toast-937n7n8i.js} +2 -2
  122. package/dist/{Toast-BGnUL4jV.js.map → Toast-937n7n8i.js.map} +1 -1
  123. package/dist/ToggleAllTooltip-DEjbWFoj.js +37 -0
  124. package/dist/ToggleAllTooltip-DEjbWFoj.js.map +1 -0
  125. package/dist/{ZoomableSvg-D8sXKpoV.js → ZoomableSvg-DnFXo2L4.js} +85 -81
  126. package/dist/ZoomableSvg-DnFXo2L4.js.map +1 -0
  127. package/dist/editors.js +4 -4
  128. package/dist/flint.js +10 -45
  129. package/dist/flint.js.map +1 -1
  130. package/dist/highlightCode-D354tCXO.js +81 -0
  131. package/dist/highlightCode-D354tCXO.js.map +1 -0
  132. package/dist/index.d.ts +843 -443
  133. package/dist/index.js +62 -63
  134. package/dist/internal/blocks/AIKit.js +2 -2
  135. package/dist/internal/blocks/AppShell.js +1 -1
  136. package/dist/internal/blocks/AuthLayout.js +1 -1
  137. package/dist/internal/blocks/AutoSaveTextarea.js +1 -1
  138. package/dist/internal/blocks/BrandEditor.js +1 -1
  139. package/dist/internal/blocks/ChartPanel.js +1 -1
  140. package/dist/internal/blocks/ChipEditor.js +5 -9
  141. package/dist/internal/blocks/ChipEditor.js.map +1 -1
  142. package/dist/internal/blocks/ClipboardButton.js +1 -1
  143. package/dist/internal/blocks/ColorInput.js +1 -1
  144. package/dist/internal/blocks/ColorModeSwitch.js +1 -1
  145. package/dist/internal/blocks/Command.js +1 -1
  146. package/dist/internal/blocks/CopyField.js +1 -1
  147. package/dist/internal/blocks/DateInput.js +1 -1
  148. package/dist/internal/blocks/DateRangeInput.js +1 -1
  149. package/dist/internal/blocks/DiagramShared/DiagramSkeleton.js.map +1 -1
  150. package/dist/internal/blocks/EmptyConfigurationActionCard.js +1 -1
  151. package/dist/internal/blocks/ErrorState.js +18 -29
  152. package/dist/internal/blocks/ErrorState.js.map +1 -1
  153. package/dist/internal/blocks/ExportMenu.js +3 -3
  154. package/dist/internal/blocks/ExportMenu.js.map +1 -1
  155. package/dist/internal/blocks/Form/connectors/ComboboxField.js +2 -2
  156. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +1 -1
  157. package/dist/internal/blocks/Form.js +1 -1
  158. package/dist/internal/blocks/FormGroup.js +1 -1
  159. package/dist/internal/blocks/InlineEdit.js +1 -1
  160. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
  161. package/dist/internal/blocks/MultiCombobox.js +202 -70
  162. package/dist/internal/blocks/MultiCombobox.js.map +1 -1
  163. package/dist/internal/blocks/NumberInput.js +2 -4
  164. package/dist/internal/blocks/NumberInput.js.map +1 -1
  165. package/dist/internal/blocks/PageToolbar.js +1 -1
  166. package/dist/internal/blocks/PasswordInput.js +3 -5
  167. package/dist/internal/blocks/PasswordInput.js.map +1 -1
  168. package/dist/internal/blocks/SearchInput.js +1 -1
  169. package/dist/internal/blocks/SearchInputWithNavigation.js +6 -7
  170. package/dist/internal/blocks/SearchInputWithNavigation.js.map +1 -1
  171. package/dist/internal/blocks/SectionNav.js +1 -1
  172. package/dist/internal/blocks/SplitButton.js +2 -2
  173. package/dist/internal/blocks/StatCard.js +1 -1
  174. package/dist/internal/blocks/TextInput.js +1 -1
  175. package/dist/internal/blocks/Textarea.js +3 -8
  176. package/dist/internal/blocks/Textarea.js.map +1 -1
  177. package/dist/internal/blocks/TimeInput.js +4 -6
  178. package/dist/internal/blocks/TimeInput.js.map +1 -1
  179. package/dist/internal/components/Alert.js +1 -1
  180. package/dist/internal/components/AlertModal.js +1 -1
  181. package/dist/internal/components/Avatar.js +1 -1
  182. package/dist/internal/components/Badge.js +1 -1
  183. package/dist/internal/components/BrandLogo.js +1 -1
  184. package/dist/internal/components/Breadcrumb.js +1 -1
  185. package/dist/internal/components/Button.js +2 -2
  186. package/dist/internal/components/ButtonGroup.js +1 -1
  187. package/dist/internal/components/ButtonGroup.js.map +1 -1
  188. package/dist/internal/components/Card.js +1 -1
  189. package/dist/internal/components/Checkbox.js +1 -1
  190. package/dist/internal/components/Clipboard.js +1 -1
  191. package/dist/internal/components/CollapsiblePanel.js +1 -1
  192. package/dist/internal/components/Combobox.js +1 -1
  193. package/dist/internal/components/DatePicker.js +1 -1
  194. package/dist/internal/components/DateRangePicker.js +1 -1
  195. package/dist/internal/components/DropdownMenu.js +1 -1
  196. package/dist/internal/components/FileUpload.js +1 -1
  197. package/dist/internal/components/FullScreenModal.js +1 -1
  198. package/dist/internal/components/HoverCard.js +1 -1
  199. package/dist/internal/components/InputGroup.js +1 -1
  200. package/dist/internal/components/Kbd.js +1 -1
  201. package/dist/internal/components/Modal.js +1 -1
  202. package/dist/internal/components/Navbar.js +1 -1
  203. package/dist/internal/components/Pagination.js +1 -1
  204. package/dist/internal/components/Popconfirm.js +1 -1
  205. package/dist/internal/components/Popover.js +1 -1
  206. package/dist/internal/components/RadioGroup.js +1 -1
  207. package/dist/internal/components/Search.js +1 -1
  208. package/dist/internal/components/Select.js +1 -1
  209. package/dist/internal/components/Sheet.js +1 -1
  210. package/dist/internal/components/Sidebar.js +1 -1
  211. package/dist/internal/components/Skeleton/Skeleton.js +2 -2
  212. package/dist/internal/components/Skeleton/Skeleton.js.map +1 -1
  213. package/dist/internal/components/Slider.js +1 -1
  214. package/dist/internal/components/Stepper.js +1 -1
  215. package/dist/internal/components/Switch.js +1 -1
  216. package/dist/internal/components/Table.js +1 -1
  217. package/dist/internal/components/Tabs.js +1 -1
  218. package/dist/internal/components/ThemeProvider.js +3 -4
  219. package/dist/internal/components/TimePicker.js +1 -1
  220. package/dist/internal/components/Toast.js +2 -2
  221. package/dist/internal/components/Toggle.js +13 -3
  222. package/dist/internal/components/Toggle.js.map +1 -1
  223. package/dist/internal/components/Tooltip.js +1 -1
  224. package/dist/internal/components/Truncated.js +1 -1
  225. package/dist/internal/components/ZoomableSvg.js +1 -1
  226. package/dist/internal/utils.js +1 -1
  227. package/dist/markdown-editor.js +16 -18
  228. package/dist/markdown-editor.js.map +1 -1
  229. package/dist/mermaid.d.ts +1 -2
  230. package/dist/mermaid.js +1 -1
  231. package/dist/rjsf.js +121 -43
  232. package/dist/rjsf.js.map +1 -1
  233. package/dist/styles-DxazJ8Mz.js +81 -0
  234. package/dist/styles-DxazJ8Mz.js.map +1 -0
  235. package/dist/styles-T8xwr0sR.js +73 -0
  236. package/dist/styles-T8xwr0sR.js.map +1 -0
  237. package/dist/styles.css +1 -1
  238. package/dist/svgCache-Dhmbe-7i.js +26 -0
  239. package/dist/svgCache-Dhmbe-7i.js.map +1 -0
  240. package/dist/svgTransforms-Hnvev3Vs.js +38 -0
  241. package/dist/svgTransforms-Hnvev3Vs.js.map +1 -0
  242. package/dist/testing.d.ts +0 -2
  243. package/dist/testing.js +3 -10
  244. package/dist/testing.js.map +1 -1
  245. package/dist/{useColorSchemeState-Cw4MCXUs.js → themeScopeContext-CEVXbYvZ.js} +43 -15
  246. package/dist/themeScopeContext-CEVXbYvZ.js.map +1 -0
  247. package/dist/{useThemeAttributes-B199Regy.js → themeTokens-DCeb62ap.js} +22 -4
  248. package/dist/themeTokens-DCeb62ap.js.map +1 -0
  249. package/dist/{toast-D6Z6MOB5.js → toast-Y3cTMBW8.js} +7 -10
  250. package/dist/toast-Y3cTMBW8.js.map +1 -0
  251. package/dist/{utils-p6tjltbX.js → utils-DwC9u0tM.js} +39 -49
  252. package/dist/utils-DwC9u0tM.js.map +1 -0
  253. package/dist/vega.js +2 -2
  254. package/dist/vegaTheme-ISwGXvof.js +49 -0
  255. package/dist/vegaTheme-ISwGXvof.js.map +1 -0
  256. package/dist/{vegaTheme-VQMWTlBw.js → vegaTokens-DCkvpIVE.js} +36 -44
  257. package/dist/vegaTokens-DCkvpIVE.js.map +1 -0
  258. package/package.json +3 -4
  259. package/src/styles.css +4 -39
  260. package/src/theme.css +42 -0
  261. package/dist/AIKit-C5FbKjwa.js.map +0 -1
  262. package/dist/Alert-DuAGeYyM.js.map +0 -1
  263. package/dist/AlertModal-BDle9ZVQ.js.map +0 -1
  264. package/dist/AutoSaveTextarea-jiqNeeE4.js.map +0 -1
  265. package/dist/Badge-Ba3epgcI.js.map +0 -1
  266. package/dist/BrandEditor-Dq168RJc.js.map +0 -1
  267. package/dist/Breadcrumb-CUyYu5Bi.js.map +0 -1
  268. package/dist/Button-D2JqBAq7.js.map +0 -1
  269. package/dist/Card-Bpc_ZlL4.js.map +0 -1
  270. package/dist/Checkbox-D9rafoKh.js.map +0 -1
  271. package/dist/CodeEditor-Y0iE-SwV.js.map +0 -1
  272. package/dist/ColorInput-D1nC0X6i.js.map +0 -1
  273. package/dist/Combobox-B1Kjoy5J.js.map +0 -1
  274. package/dist/Command-BuOA3V18.js.map +0 -1
  275. package/dist/DateInput-BlKkequE.js.map +0 -1
  276. package/dist/DateRangeInput-DOxJHw8V.js.map +0 -1
  277. package/dist/DateRangePicker-CXpXPMoh.js.map +0 -1
  278. package/dist/DiagramSource-jTwmmi9g.js +0 -11
  279. package/dist/DiagramSource-jTwmmi9g.js.map +0 -1
  280. package/dist/DropdownMenu-DtRYcKEx.js.map +0 -1
  281. package/dist/FileUpload-D6vPG3WB.js.map +0 -1
  282. package/dist/FullScreenModal-CUuAakh3.js.map +0 -1
  283. package/dist/HoverCard-Cy6nhg4u.js +0 -31
  284. package/dist/HoverCard-Cy6nhg4u.js.map +0 -1
  285. package/dist/InlineEdit-DSMIEUUa.js.map +0 -1
  286. package/dist/InputGroup-Dm014ruw.js.map +0 -1
  287. package/dist/Kbd-Du93F3o4.js.map +0 -1
  288. package/dist/MermaidDiagram-D2ThT8Q-.js +0 -302
  289. package/dist/MermaidDiagram-D2ThT8Q-.js.map +0 -1
  290. package/dist/Modal-DQIauzar.js.map +0 -1
  291. package/dist/Popover-BU7nGOv-.js.map +0 -1
  292. package/dist/RadioGroup-C2vk5acr.js.map +0 -1
  293. package/dist/SearchInput-BnU6YHgT.js.map +0 -1
  294. package/dist/Select-CjQgU_6K.js.map +0 -1
  295. package/dist/Sheet-utw4_rUa.js.map +0 -1
  296. package/dist/Sidebar-CKaxOPwY.js.map +0 -1
  297. package/dist/Slider-Rcc2qVct.js.map +0 -1
  298. package/dist/Stepper-BBPembeK.js.map +0 -1
  299. package/dist/Switch-Dw4tvQls.js +0 -201
  300. package/dist/Switch-Dw4tvQls.js.map +0 -1
  301. package/dist/Table-CgSC-fSo.js.map +0 -1
  302. package/dist/TextInput-B5TDDOty.js.map +0 -1
  303. package/dist/ThemeProvider-Dt9b67sW.js.map +0 -1
  304. package/dist/ZoomableSvg-D8sXKpoV.js.map +0 -1
  305. package/dist/context-U293r3v-.js +0 -29
  306. package/dist/context-U293r3v-.js.map +0 -1
  307. package/dist/defaults-i_xG2F_1.js +0 -32
  308. package/dist/defaults-i_xG2F_1.js.map +0 -1
  309. package/dist/styles-BDA5rQz3.js +0 -127
  310. package/dist/styles-BDA5rQz3.js.map +0 -1
  311. package/dist/styles-YQdM7G8c.js +0 -159
  312. package/dist/styles-YQdM7G8c.js.map +0 -1
  313. package/dist/svgTransforms-Dw2hRA-i.js +0 -51
  314. package/dist/svgTransforms-Dw2hRA-i.js.map +0 -1
  315. package/dist/themeTokens-7DEab0kp.js +0 -31
  316. package/dist/themeTokens-7DEab0kp.js.map +0 -1
  317. package/dist/toast-D6Z6MOB5.js.map +0 -1
  318. package/dist/useColorSchemeState-Cw4MCXUs.js.map +0 -1
  319. package/dist/useThemeAttributes-B199Regy.js.map +0 -1
  320. package/dist/utils-p6tjltbX.js.map +0 -1
  321. package/dist/vegaTheme-VQMWTlBw.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"AIKit-C5FbKjwa.js","names":["renderVariantIcon","LinkIcon","TableIcon","Table"],"sources":["../src/blocks/AIKit/AnswerActions.tsx","../src/blocks/AIKit/CollapsibleBody.tsx","../src/blocks/AIKit/CollapsibleStepHeader.tsx","../src/blocks/AIKit/hasMotion.ts","../src/blocks/AIKit/InlineStepDetail.tsx","../src/blocks/AIKit/InlineStepLabel.tsx","../src/blocks/AIKit/AnswerSummary.tsx","../src/blocks/AIKit/ChatInlineIcon.tsx","../src/blocks/AIKit/FileDownloadChip.tsx","../src/blocks/AIKit/InlineStepGroup.tsx","../src/blocks/AIKit/DiagramBlock.tsx","../src/blocks/AIKit/diagramChunk.ts","../src/blocks/AIKit/Markdown.tsx","../src/blocks/AIKit/MarkdownTable.tsx","../src/blocks/AIKit/MessageBubble.tsx","../src/blocks/AIKit/PlanApproval.tsx","../src/blocks/AIKit/PlanRewritingIndicator.tsx","../src/blocks/AIKit/constants.ts","../src/blocks/AIKit/AnimatedHeight.tsx","../src/blocks/AIKit/PromptInputAction.tsx","../src/blocks/AIKit/PromptInputCommands.tsx","../src/blocks/AIKit/PromptInputMenuTrigger.tsx","../src/blocks/AIKit/PromptInputSubmit.tsx","../src/blocks/AIKit/PromptInput.tsx","../src/blocks/AIKit/Question.tsx","../src/blocks/AIKit/QuestionBlock.tsx","../src/blocks/AIKit/SuggestedPrompt.tsx","../src/blocks/AIKit/ThinkingIndicator.tsx","../src/blocks/AIKit/ToolCall/ToolCallApproval.tsx","../src/blocks/AIKit/ToolCall/ToolCallChip.tsx","../src/blocks/AIKit/ToolCallStatusHeader.tsx","../src/blocks/AIKit/usageStatsHelpers.ts","../src/blocks/AIKit/UsageBar.tsx","../src/blocks/AIKit/UsageStatsRing.tsx","../src/blocks/AIKit/UsageStats.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { ButtonGroup } from '../../components/ButtonGroup';\nimport { Tooltip } from '../../components/Tooltip';\nimport { ThumbsDown, ThumbsUp } from '../../icons';\nimport { cn } from '../../utils';\nimport { ClipboardButton } from '../ClipboardButton';\n\n/** Which way a reader rated an answer. */\nexport type AnswerVote = 'up' | 'down';\n\nconst VOTE_BUTTONS = [\n { vote: 'up', icon: <ThumbsUp className=\"tw:size-4\" /> },\n { vote: 'down', icon: <ThumbsDown className=\"tw:size-4\" /> },\n] as const;\n\nconst DEFAULT_LABELS = { up: 'Good answer', down: 'Bad answer' } as const;\n\n/** Roomier for a panel; compact for a dense transcript. */\nconst SIZES = {\n small: { button: 'icon-xs', gap: 'extra-small' },\n medium: { button: 'icon-sm', gap: 'little-small' },\n} as const;\n\ntype Props = {\n /** The answer as text, for the clipboard; empty or absent draws no copy button. */\n copyText?: string;\n /** The vote already recorded against this answer, or `null` for none. */\n vote: AnswerVote | null;\n onVote: (vote: AnswerVote) => void;\n /** Extra controls, e.g. a report button; drawn ahead of copy. */\n actions?: ReactNode;\n /** What the thumbs call the thing rated: \"response\" or \"answer\". */\n labels?: { up: string; down: string };\n /** Announced politely once a vote lands, if set. */\n confirmation?: { up: string; down: string };\n size?: keyof typeof SIZES;\n /** `inline` (default): one group. `split`: votes left, actions right, at the bubble's edges. */\n layout?: 'inline' | 'split';\n /** Fires on copy; the button does the copying itself. */\n onCopy?: () => void;\n};\n\n/**\n * Copy and thumbs up/down for a finished answer.\n *\n * - Always rendered, never hover-only, so it is reachable without a pointer.\n * - A vote can be changed but not withdrawn; pressing the pressed one re-sends it.\n * - The caller owns the recorded vote and the write.\n */\nexport const AnswerActions = ({\n copyText,\n vote,\n onVote,\n onCopy,\n actions,\n labels = DEFAULT_LABELS,\n confirmation,\n size = 'small',\n layout = 'inline',\n}: Props) => {\n const { button, gap } = SIZES[size];\n\n const votes = VOTE_BUTTONS.map(({ vote: candidate, icon }) => {\n const isRecorded = vote === candidate;\n const label = labels[candidate];\n\n return (\n <Tooltip key={candidate} tooltip={label} placement=\"top\" triggerAsChild>\n <Button\n size={button}\n variant=\"invisible\"\n className={cn(\n isRecorded &&\n candidate === 'up' &&\n 'tw:bg-success/10 tw:text-success tw:hover:not-disabled:bg-success/20 tw:hover:not-disabled:text-success',\n isRecorded &&\n candidate === 'down' &&\n 'tw:bg-destructive/10 tw:text-destructive tw:hover:not-disabled:bg-destructive/20 tw:hover:not-disabled:text-destructive',\n )}\n aria-label={label}\n aria-pressed={isRecorded}\n onClick={() => onVote(candidate)}\n >\n {icon}\n </Button>\n </Tooltip>\n );\n });\n\n const copy = copyText ? (\n <ClipboardButton\n text={copyText}\n tooltip=\"Copy answer\"\n size={button}\n variant=\"invisible\"\n onClick={onCopy}\n />\n ) : null;\n\n // Mounted empty: a live region that arrives with its text is generally not announced.\n const said = confirmation ? (\n <span\n aria-live=\"polite\"\n className=\"tw:ml-1 tw:text-xs tw:font-medium tw:text-foreground tw:empty:hidden tw:animate-in tw:fade-in tw:slide-in-from-left-1 tw:duration-300\"\n >\n {vote ? confirmation[vote] : ''}\n </span>\n ) : null;\n\n if (layout === 'split') {\n return (\n <div className=\"tw:flex tw:w-full tw:items-center tw:justify-between tw:gap-2\">\n <ButtonGroup space={gap} aria-label=\"Answer actions\">\n {votes}\n {said}\n </ButtonGroup>\n <ButtonGroup space={gap}>\n {actions}\n {copy}\n </ButtonGroup>\n </div>\n );\n }\n\n return (\n <ButtonGroup space={gap} aria-label=\"Answer actions\">\n {copy}\n {votes}\n {actions}\n {said}\n </ButtonGroup>\n );\n};\n","import type { ReactNode, TransitionEvent } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = {\n isExpanded: boolean;\n isClosing: boolean;\n onClosed: () => void;\n children: ReactNode;\n};\n\nexport const CollapsibleBody = ({ isExpanded, isClosing, onClosed, children }: Props) => {\n const handleTransitionEnd = (event: TransitionEvent<HTMLDivElement>) => {\n if (event.target !== event.currentTarget) return;\n if (event.propertyName !== 'grid-template-rows') return;\n if (!isExpanded) onClosed();\n };\n\n return (\n <div\n className={cn(\n 'tw:grid tw:transition-[grid-template-rows] tw:duration-300 tw:ease-out tw:motion-reduce:transition-none',\n isExpanded ? 'tw:grid-rows-[1fr]' : 'tw:grid-rows-[0fr]',\n )}\n onTransitionEnd={handleTransitionEnd}\n >\n <div className=\"tw:min-h-0 tw:overflow-hidden\">{(isExpanded || isClosing) && children}</div>\n </div>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { ChevronDown, CircleCheck, Loader2, XCircle } from '../../icons';\nimport { cn } from '../../utils';\n\ntype Variant = 'success' | 'error' | 'processing' | 'dismissed';\n\ntype Props = {\n isExpanded: boolean;\n onToggle: () => void;\n label: ReactNode;\n variant?: Variant;\n};\n\n// Chrome speaks grey: step headers are meta-information, so they read in\n// muted ink and darken on hover — blue is reserved for genuinely interactive\n// elements (links, buttons), and status colour lives only in the icon. Error\n// keeps its tinted label: a failed step is content, not chrome.\nconst variantClasses: Record<Variant, string> = {\n success:\n 'tw:text-muted-foreground tw:focus-visible:outline-ring tw:not-disabled:hover:text-foreground',\n error:\n 'tw:text-destructive tw:focus-visible:outline-destructive tw:not-disabled:hover:text-destructive',\n processing:\n 'tw:text-muted-foreground tw:focus-visible:outline-ring tw:not-disabled:hover:text-foreground',\n dismissed:\n 'tw:text-muted-foreground tw:focus-visible:outline-ring tw:not-disabled:hover:text-foreground',\n};\n\n// Icons one step quieter than the label so the row reads text-first.\nconst iconClasses = 'tw:size-3.5 tw:shrink-0 tw:basis-3.5 tw:opacity-70';\n\n// What the icon says, for a reader who is not looking at it. Joins the button's accessible name,\n// so a closed group announces how the run came out and not only what it was called.\nconst variantStatus: Record<Variant, string> = {\n success: 'finished',\n error: 'failed',\n processing: 'running',\n dismissed: 'not run',\n};\n\nconst renderVariantIcon = (variant: Variant) => {\n if (variant === 'processing') {\n return <Loader2 className={cn(iconClasses, 'tw:animate-spin')} />;\n }\n // `error` and `dismissed` share the mark and take their ink from the\n // button's variant class — `destructive` for a real failure,\n // `muted-foreground` for a step the user waved off.\n if (variant === 'error' || variant === 'dismissed') {\n return <XCircle className={iconClasses} />;\n }\n return <CircleCheck className={iconClasses} />;\n};\n\nexport const CollapsibleStepHeader = ({\n isExpanded,\n onToggle,\n label,\n variant = 'success',\n}: Props) => {\n // `data-variant` is how the run came out, for a selector: an E2E test asserting on an outcome\n // would otherwise have to read the icon's shape or the label's ink.\n return (\n <button\n type=\"button\"\n aria-expanded={isExpanded}\n onClick={onToggle}\n data-variant={variant}\n className={cn(\n 'tw:flex tw:w-fit tw:items-center tw:gap-1.5 tw:text-left tw:text-xs tw:font-medium tw:transition-colors tw:focus-visible:outline tw:focus-visible:outline-2 tw:focus-visible:outline-offset-2 tw:disabled:opacity-40',\n variantClasses[variant],\n )}\n >\n {renderVariantIcon(variant)}\n <span className=\"tw:min-w-0\">\n {label}\n <span className=\"tw:sr-only\">{` (${variantStatus[variant]})`}</span>\n {/* A word joiner (U+2060) keeps the chevron on the label's last line —\n an inline chevron with nothing binding it to the preceding word\n orphans onto a line of its own at some container widths. */}\n <span className=\"tw:whitespace-nowrap\">\n {'⁠'}\n <ChevronDown\n className={cn(\n 'tw:ml-1.5 tw:inline-block tw:size-3.5 tw:align-middle tw:transition-transform',\n isExpanded && 'tw:rotate-180',\n )}\n />\n </span>\n </span>\n </button>\n );\n};\n","export const hasMotion = () =>\n typeof window.matchMedia === 'function' &&\n !window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n","import type { ReactNode } from 'react';\n\ntype Props = {\n children: ReactNode;\n};\n\nexport const InlineStepDetail = ({ children }: Props) => (\n // `ml-2.5` is half of the `size-5` icon box `InlineStepLabel` puts beside a\n // step, so the rule falls on that icon's centre line rather than 2px inside\n // it. Anything drawing a run of steps can then line its own connector up with\n // the same number.\n <div className=\"tw:ml-2.5 tw:whitespace-pre-wrap tw:border-l tw:border-border tw:pl-3 tw:text-xs tw:text-muted-foreground\">\n {children}\n </div>\n);\n\nexport type { Props as InlineStepDetailProps };\n","import type { ReactNode } from 'react';\n\nimport { CircleCheck, Loader2, XCircle } from '../../icons';\n\ntype Variant = 'processing' | 'success' | 'error' | 'dismissed';\n\ntype Props = {\n variant: Variant;\n children: ReactNode;\n};\n\n// Only a real error takes status red; success/dismissed stay muted.\nconst renderVariantIcon = (variant: Variant) => {\n if (variant === 'processing') {\n return <Loader2 className=\"tw:size-3.5 tw:animate-spin tw:text-muted-foreground\" />;\n }\n if (variant === 'error') {\n return <XCircle className=\"tw:size-3.5 tw:text-destructive\" />;\n }\n if (variant === 'dismissed') {\n return <XCircle className=\"tw:size-3.5 tw:text-muted-foreground/50\" />;\n }\n return <CircleCheck className=\"tw:size-3.5 tw:text-muted-foreground/50\" />;\n};\n\nexport const InlineStepLabel = ({ variant, children }: Props) => (\n <div className=\"tw:flex tw:min-w-0 tw:items-center tw:gap-1\">\n {/* Masks a connector behind it with `--inline-step-surface` (transparent when unset).\n `relative` is required: the absolute connector otherwise paints above static content. */}\n <div className=\"tw:relative tw:flex tw:size-5 tw:shrink-0 tw:items-center tw:justify-center tw:[background:var(--inline-step-surface,transparent)]\">\n {renderVariantIcon(variant)}\n </div>\n <div className=\"tw:flex tw:min-w-0 tw:flex-wrap tw:items-center tw:gap-x-1.5 tw:gap-y-1 tw:text-xs tw:font-medium tw:text-muted-foreground\">\n {children}\n </div>\n </div>\n);\n\nexport type { Variant as InlineStepLabelVariant, Props as InlineStepLabelProps };\n","import { useState } from 'react';\n\nimport { CollapsibleBody } from './CollapsibleBody';\nimport { CollapsibleStepHeader } from './CollapsibleStepHeader';\nimport { hasMotion } from './hasMotion';\nimport { InlineStepDetail } from './InlineStepDetail';\nimport { InlineStepLabel } from './InlineStepLabel';\n\ntype AnswerItem = {\n question: string;\n answer?: string;\n};\n\ntype Variant = 'success' | 'dismissed';\n\ntype Props = {\n items: readonly AnswerItem[];\n variant?: Variant;\n noAnswerLabel?: string;\n onExpandToggle?: (next: boolean) => void;\n};\n\nconst SECTION_LABELS: Record<Variant, string> = {\n success: 'Answered questions',\n dismissed: 'Dismissed questions',\n};\n\nexport const AnswerSummary = ({\n items,\n variant = 'success',\n noAnswerLabel = 'No answer',\n onExpandToggle,\n}: Props) => {\n const [isExpanded, setIsExpanded] = useState(false);\n const [isClosing, setIsClosing] = useState(false);\n const toggle = () => {\n const next = !isExpanded;\n if (!next) setIsClosing(hasMotion());\n setIsExpanded(next);\n onExpandToggle?.(next);\n };\n const count = items.length;\n const [firstItem] = items;\n const label = count === 1 && firstItem ? firstItem.question : `${count} questions`;\n\n return (\n <section className=\"tw:mt-4 tw:flex tw:flex-col\" aria-label={SECTION_LABELS[variant]}>\n <CollapsibleStepHeader\n isExpanded={isExpanded}\n onToggle={toggle}\n variant={variant}\n label={label}\n />\n\n <CollapsibleBody\n isExpanded={isExpanded}\n isClosing={isClosing}\n onClosed={() => setIsClosing(false)}\n >\n <div className=\"tw:flex tw:flex-col tw:gap-4 tw:pt-4 tw:pl-5\">\n {items.map(({ question, answer }, index) => (\n <div key={`${index}-${question}`} className=\"tw:flex tw:flex-col tw:gap-1\">\n <InlineStepLabel variant={variant}>{question}</InlineStepLabel>\n <InlineStepDetail>\n {answer && answer.length > 0 ? answer : noAnswerLabel}\n </InlineStepDetail>\n </div>\n ))}\n </div>\n </CollapsibleBody>\n </section>\n );\n};\n\nexport type {\n AnswerItem as AnswerSummaryItem,\n Props as AnswerSummaryProps,\n Variant as AnswerSummaryVariant,\n};\n","import type { ChatInlineIconName } from '@keboola/agent-vocabulary';\n\nimport type { LucideIcon } from '../../icons';\nimport {\n AlertCircle,\n ArrowDown,\n ArrowLeft,\n ArrowRight,\n ArrowUp,\n Ban,\n BarChart3,\n Bell,\n Bug,\n Calendar,\n Check,\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n ChevronUp,\n Circle,\n CircleAlert,\n CircleCheck,\n CircleHelp,\n CirclePause,\n CirclePlay,\n CirclePlus,\n CircleStop,\n CircleX,\n Clock,\n Cog,\n Copy,\n Database,\n Download,\n Ellipsis,\n ExternalLink,\n Eye,\n File,\n FilePen,\n FileText,\n Flag,\n Folder,\n Gauge,\n GitBranch,\n GitMerge,\n GitPullRequest,\n Globe,\n Hand,\n History,\n Hourglass,\n Info,\n Key,\n Layers,\n LineChart,\n Link as LinkIcon,\n List,\n ListChecks,\n Loader2,\n Lock,\n Mail,\n Minus,\n Pencil,\n Play,\n Plus,\n RefreshCw,\n Rocket,\n RotateCcw,\n RotateCw,\n Save,\n Search,\n Send,\n Settings,\n Sparkles,\n Star,\n Table as TableIcon,\n ThumbsDown,\n ThumbsUp,\n Trash2,\n TriangleAlert,\n Upload,\n User,\n Users,\n WandSparkles,\n Warehouse,\n Workflow,\n X,\n Zap,\n} from '../../icons';\nimport { cn } from '../../utils';\n\n/**\n * The Lucide component each `icon:<name>` token draws.\n *\n * - Names are FontAwesome-solid ones, published as `CHAT_INLINE_ICON_NAMES`.\n * - The `satisfies` is the drift guard: a name the prompt teaches and this map lacks fails to compile.\n * - Read through `Object.hasOwn`: `icon:constructor` would otherwise hit `Object.prototype`.\n */\nconst ICON_REGISTRY: Record<string, LucideIcon | undefined> = {\n 'alert-circle': AlertCircle,\n 'arrow-down': ArrowDown,\n 'arrow-left': ArrowLeft,\n 'arrow-right': ArrowRight,\n 'arrow-rotate-back': RotateCcw,\n 'arrow-rotate-left': RotateCcw,\n 'arrow-rotate-right': RotateCw,\n 'arrow-up': ArrowUp,\n 'arrow-up-right-from-square': ExternalLink,\n 'arrows-rotate': RefreshCw,\n analytics: BarChart3,\n ban: Ban,\n bell: Bell,\n bug: Bug,\n calendar: Calendar,\n changes: FilePen,\n 'chart-line': LineChart,\n check: Check,\n 'check-circle': CircleCheck,\n 'chevron-down': ChevronDown,\n 'chevron-left': ChevronLeft,\n 'chevron-right': ChevronRight,\n 'chevron-up': ChevronUp,\n circle: Circle,\n 'circle-check': CircleCheck,\n 'circle-exclamation': CircleAlert,\n 'circle-info': Info,\n 'circle-pause': CirclePause,\n 'circle-play': CirclePlay,\n 'circle-plus': CirclePlus,\n 'circle-question': CircleHelp,\n 'circle-stop': CircleStop,\n 'circle-xmark': CircleX,\n clock: Clock,\n 'clock-rotate-left': History,\n 'code-branch': GitBranch,\n 'code-merge': GitMerge,\n 'code-pull-request': GitPullRequest,\n cog: Cog,\n configuration: Settings,\n copy: Copy,\n database: Database,\n 'diagram-project': Workflow,\n download: Download,\n ellipsis: Ellipsis,\n envelope: Mail,\n 'exclamation-circle': CircleAlert,\n 'exclamation-triangle': TriangleAlert,\n eye: Eye,\n file: File,\n 'file-lines': FileText,\n flag: Flag,\n folder: Folder,\n gauge: Gauge,\n gear: Settings,\n globe: Globe,\n hand: Hand,\n 'hourglass-half': Hourglass,\n 'info-circle': Info,\n key: Key,\n 'layer-group': Layers,\n link: LinkIcon,\n 'list-check': ListChecks,\n 'list-ul': List,\n lock: Lock,\n 'magnifying-glass': Search,\n minus: Minus,\n 'paper-plane-top': Send,\n pen: Pencil,\n play: Play,\n plus: Plus,\n refresh: RefreshCw,\n rocket: Rocket,\n save: Save,\n 'save-changes': Save,\n search: Search,\n spinner: Loader2,\n sparkles: Sparkles,\n star: Star,\n stop: CircleStop,\n table: TableIcon,\n 'thumbs-down': ThumbsDown,\n 'thumbs-up': ThumbsUp,\n transformation: WandSparkles,\n trash: Trash2,\n 'triangle-exclamation': TriangleAlert,\n upload: Upload,\n user: User,\n 'user-group': Users,\n warning: TriangleAlert,\n warehouse: Warehouse,\n xmark: X,\n zap: Zap,\n} satisfies Record<ChatInlineIconName, LucideIcon>;\n\n/**\n * Extra classes a single name needs.\n *\n * - `spinner` spins (per `MAINTAINING.md`): a still `Loader2` reads as a broken ring.\n * - Read through `Object.hasOwn`, like the registry.\n */\nconst ICON_CLASSES: Record<string, string | undefined> = {\n spinner: 'tw:animate-spin',\n};\n\n/**\n * A whole `icon:<name>` token and nothing else.\n *\n * - Must match the name shape `remarkIconSyntax` (`@keboola/kai-chat`) accepts.\n * - Anchored, so inline code like `` `icon: database` `` or `` `icon:` `` stays code.\n */\nconst TOKEN = /^icon:([a-z][a-z0-9-]*)$/;\n\n/** Built once: an answer is re-parsed per streamed chunk, so `isArriving` runs per code node. */\nconst ICON_NAMES = Object.keys(ICON_REGISTRY);\n\n/** Whether a name is a strict prefix of a registry name: `tabl` → `true`, `table-name` → `false`. */\nconst isArriving = (name: string): boolean =>\n ICON_NAMES.some((key) => key.length > name.length && key.startsWith(name));\n\n/**\n * The icon name in a code node's text, if the text is a token — drawn, or still arriving.\n *\n * - An unknown name → `undefined`, so the call site's `<code>` fall-through keeps the text.\n * - A prefix of a known name is a token still streaming; `<ChatInlineIcon />` draws it blank.\n * - A name that is both (`save`, of `save-changes`) is drawn now.\n */\nexport const getChatInlineIconName = (text: string): string | undefined => {\n const name = TOKEN.exec(text)?.[1];\n if (name === undefined) return undefined;\n return Object.hasOwn(ICON_REGISTRY, name) || isArriving(name) ? name : undefined;\n};\n\ntype Props = {\n /** The name from the token, without the `icon:` prefix. */\n name: string;\n};\n\n/**\n * One inline `icon:<name>` token, drawn at the size of the text it leads.\n *\n * - An unknown name (a token still arriving) renders nothing.\n * - `mr` widens the single source space, which reads as cramped beside a glyph.\n * - The heavier stroke holds its own beside a bold heading.\n * - `aria-hidden`: the token's text is removed, so the glyph has no label to announce.\n */\nexport const ChatInlineIcon = ({ name }: Props) => {\n const Icon = Object.hasOwn(ICON_REGISTRY, name) ? ICON_REGISTRY[name] : undefined;\n\n if (Icon === undefined) return null;\n\n return (\n <Icon\n aria-hidden\n className={cn(\n 'tw:mr-[0.15em] tw:inline-block tw:size-[1em] tw:shrink-0 tw:align-[-0.125em] tw:text-muted-foreground',\n Object.hasOwn(ICON_CLASSES, name) ? ICON_CLASSES[name] : undefined,\n )}\n strokeWidth={2.25}\n />\n );\n};\n","import { Button } from '../../components/Button';\nimport { Download, FileText } from '../../icons';\nimport { cn } from '../../utils';\n\ntype Props = {\n /** The file's own name, as the reader will see it saved. */\n fileName: string;\n /** Where it sits in the workspace, shown on hover — what tells two `report.pdf`s apart. */\n filePath?: string;\n /** Its size, when known. Absent draws nothing rather than claiming a file is empty. */\n size?: string;\n /** Whether a download is in flight — the host owns the fetch and the save. */\n isPending?: boolean;\n onDownload: () => void;\n className?: string;\n};\n\n/**\n * A file the agent wrote, offered inside its own answer.\n *\n * - The whole chip is the control: a small icon beside a truncating filename is hard to hit.\n * - Presentation only — the host fetches and saves, through its own auth.\n */\nexport const FileDownloadChip = ({\n fileName,\n filePath,\n size,\n isPending = false,\n onDownload,\n className,\n}: Props) => (\n <Button\n variant=\"secondary\"\n size=\"small\"\n isLoading={isPending}\n // `aria-disabled`, not `disabled`: a disabled chip drops focus mid-download.\n aria-disabled={isPending}\n // By path: `title` isn't in the accessible name, so two `report.pdf`s would sound alike.\n aria-label={`Download ${filePath ?? fileName}`}\n title={filePath}\n onClick={() => {\n if (!isPending) onDownload();\n }}\n className={cn('tw:max-w-full tw:justify-start tw:gap-2 tw:font-normal', className)}\n >\n <FileText className=\"tw:size-4 tw:shrink-0 tw:text-muted-foreground\" />\n <span className=\"tw:truncate\">{fileName}</span>\n {size !== undefined && (\n <span className=\"tw:shrink-0 tw:text-xs tw:text-muted-foreground\">{size}</span>\n )}\n {!isPending && <Download className=\"tw:size-4 tw:shrink-0\" />}\n </Button>\n);\n","import type { CSSProperties, ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { CollapsibleStepHeader } from './CollapsibleStepHeader';\nimport type { InlineStepLabelVariant } from './InlineStepLabel';\n\n/** The surface colour, as the custom property the step icons mask against. */\nconst surfaceStyle = (\n surface: string,\n): CSSProperties & Record<'--inline-step-surface', string> => ({\n '--inline-step-surface': surface,\n});\n\ntype Props = {\n label: ReactNode;\n /** How the whole run reads in one mark. */\n variant?: InlineStepLabelVariant;\n isExpanded: boolean;\n onToggle: () => void;\n /** The CSS colour behind the group; step icons mask the connector with it. Must match the\n * actual surface (e.g. a panel), not the page background. */\n surface?: string;\n 'aria-label'?: string;\n /** E2E anchor; selectors in `packages/e2e-testing` break silently if it moves. */\n 'data-testid'?: string;\n className?: string;\n /** The rows: `InlineStepLabel`, `InlineStepDetail`, and whatever a host draws between them. */\n children: ReactNode;\n};\n\n/**\n * A collapsible run of agent steps behind one summary line; rows arrive as children.\n *\n * - Connector sits at the icon centre line (`pl-5` + half a `size-5` box), drawn once so it\n * survives icon-less rows.\n * - Animates `grid-template-rows`; children stay mounted while closed.\n * - `role=\"group\"`, not a `region` landmark: dozens per transcript would drown real landmarks.\n */\nexport const InlineStepGroup = ({\n label,\n variant = 'success',\n isExpanded,\n onToggle,\n surface = 'rgb(var(--background))',\n 'aria-label': ariaLabel,\n 'data-testid': testId,\n className,\n children,\n}: Props) => (\n <section\n role=\"group\"\n className={cn('tw:flex tw:flex-col', className)}\n aria-label={ariaLabel}\n data-testid={testId}\n >\n <CollapsibleStepHeader\n isExpanded={isExpanded}\n onToggle={onToggle}\n label={label}\n variant={variant}\n />\n\n <div\n className={cn(\n 'tw:grid tw:transition-[grid-template-rows] tw:duration-200 tw:ease-out tw:motion-reduce:transition-none',\n isExpanded ? 'tw:grid-rows-[1fr]' : 'tw:grid-rows-[0fr]',\n )}\n >\n {/* `0fr` hides only visually; `inert` + `aria-hidden` drop it from a11y tree and tab order. */}\n <div\n className=\"tw:min-h-0 tw:overflow-hidden\"\n inert={!isExpanded}\n aria-hidden={isExpanded ? undefined : true}\n >\n <div\n style={surfaceStyle(surface)}\n className=\"tw:relative tw:flex tw:flex-col tw:gap-4 tw:pt-4 tw:pl-5\"\n >\n <span\n aria-hidden=\"true\"\n className=\"tw:pointer-events-none tw:absolute tw:top-4 tw:bottom-0 tw:left-[30px] tw:w-px tw:bg-border\"\n />\n {children}\n </div>\n </div>\n </div>\n </section>\n);\n\nexport type { Props as InlineStepGroupProps };\n","import { useEffect, useState } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { DiagramSkeleton } from '../DiagramShared/DiagramSkeleton';\nimport { DiagramSource } from '../DiagramShared/DiagramSource';\n\nimport type { DiagramComponent, DiagramLoader } from './diagramChunk';\n\n/**\n * One diagram block: a skeleton while its chunk loads, the fence source plus a retry if it fails.\n *\n * - Each attempt is a fresh fetch; the loader drops its rejected promise and logs the failure.\n * - Retry is manual: a chunk gone after a deploy never returns, so a timer would loop forever.\n * - A new `load` resets the block, or a dialect switch keeps the previous renderer.\n * - Functions in state go through the setter form, or React calls them.\n */\nexport const DiagramBlock = ({ load, code }: { load: DiagramLoader; code: string }) => {\n const [Diagram, setDiagram] = useState<DiagramComponent | null>(null);\n const [failed, setFailed] = useState(false);\n const [attempt, setAttempt] = useState(0);\n\n // Reset during render, not in an effect, so a dialect change never paints the old renderer.\n const [prevLoad, setPrevLoad] = useState(() => load);\n if (load !== prevLoad) {\n setPrevLoad(() => load);\n setDiagram(null);\n setFailed(false);\n }\n\n useEffect(() => {\n let cancelled = false;\n load().then(\n (component) => {\n if (!cancelled) setDiagram(() => component);\n },\n () => {\n if (!cancelled) setFailed(true);\n },\n );\n return () => {\n cancelled = true;\n };\n // `attempt` is the retry trigger — bumping it re-runs the import.\n }, [load, attempt]);\n\n if (Diagram) return <Diagram code={code} />;\n\n if (failed) {\n return (\n <div>\n <DiagramSource code={code} />\n <Button\n variant=\"inline\"\n size=\"small\"\n className=\"tw:mb-3\"\n onClick={() => {\n setFailed(false);\n setAttempt((count) => count + 1);\n }}\n >\n Try again\n </Button>\n </div>\n );\n }\n\n return <DiagramSkeleton />;\n};\n","import type { ComponentType } from 'react';\n\nexport type DiagramComponent = ComponentType<{ code: string }>;\nexport type DiagramLoader = () => Promise<DiagramComponent>;\n\n/**\n * An on-demand diagram chunk, shared between mounts and retryable.\n *\n * - Not `lazy()`: it memoizes a failed import, stranding every diagram until a reload.\n * - A resolved import is kept; a failed one is cleared so the next mount retries.\n * - Same contract as `getFlintRuntime()` in `FlintChart`.\n * - Failures are logged here, where the chunk's name is known.\n */\nexport const diagramChunk = (name: string, load: DiagramLoader): DiagramLoader => {\n let pending: Promise<DiagramComponent> | null = null;\n return () => {\n pending ??= load().catch((error: unknown) => {\n console.error(`[AIKit] failed to load the ${name} chunk`, error);\n pending = null;\n throw error;\n });\n return pending;\n };\n};\n","import { createContext, isValidElement, use } from 'react';\nimport type { ComponentPropsWithoutRef, PropsWithChildren, ReactNode } from 'react';\nimport type { Components, ExtraProps, Options } from 'react-markdown';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nimport { Table } from '../../components/Table';\nimport { cn } from '../../utils';\nimport { ClipboardButton } from '../ClipboardButton';\n\nimport { ChatInlineIcon, getChatInlineIconName } from './ChatInlineIcon';\nimport { DiagramBlock } from './DiagramBlock';\nimport type { DiagramLoader } from './diagramChunk';\nimport { diagramChunk } from './diagramChunk';\n\n// Both chunks are heavy (elkjs, vega) and rarely needed, so they load on demand.\nconst loadMermaid = diagramChunk('MermaidDiagram', () =>\n import('@keboola/design/mermaid').then((module) => module.MermaidDiagram),\n);\n\nconst loadFlint = diagramChunk('FlintChart', () =>\n import('@keboola/design/flint').then((module) => module.FlintChart),\n);\n\n// The one definition of how a Keboola answer reads.\n//\n// - Rhythm lives in `tw:prose-answer` (`src/styles.css`), palette in `typography.ts`\n// (`@keboola/tailwind-config`); don't layer utilities here.\n// - `tw:prose-code-chip` on both: otherwise chrome keeps `#c7254e` (3.36:1 on dark).\nconst PROSE_CLASS = {\n answer: 'tw:prose tw:prose-answer tw:prose-code-chip tw:break-words',\n chrome: 'tw:prose tw:prose-sm tw:prose-code-chip tw:break-words',\n} as const;\n\n/**\n * Which reading rhythm the surface wears.\n *\n * - `answer`: an assistant reply, 78ch measure.\n * - `chrome`: uncapped, dense; for content a model did not write.\n */\ntype Rhythm = keyof typeof PROSE_CLASS;\n\nconst getText = (node: ReactNode): string => {\n if (typeof node === 'string') return node;\n if (typeof node === 'number') return String(node);\n if (Array.isArray(node)) return node.map(getText).join('');\n if (\n isValidElement(node) &&\n typeof node.props === 'object' &&\n node.props !== null &&\n 'children' in node.props\n ) {\n return getText((node.props as { children: ReactNode }).children);\n }\n return '';\n};\n\nconst getLanguage = (element: ReactNode): string | undefined => {\n if (!isValidElement(element)) return undefined;\n const { props } = element;\n if (typeof props !== 'object' || props === null || !('className' in props)) return undefined;\n if (typeof props.className !== 'string') return undefined;\n return props.className.match(/language-(\\S+)/)?.[1];\n};\n\n/** Always run; a caller's plugins are appended, never substituted. */\nconst baseRemarkPlugins: NonNullable<Options['remarkPlugins']> = [remarkGfm];\n\n/**\n * Fence language → the on-demand chunk that draws it.\n *\n * - Dialects come from kai-agent's prompt; keep in sync with kbc-ui `markdownComponents.tsx`.\n * - `flint-chart`: alias models emit unprompted.\n * - Read via `Object.hasOwn`: ```constructor would otherwise hit `Object.prototype` and throw.\n */\nconst DIAGRAM_CHUNKS: Record<string, DiagramLoader | undefined> = {\n mermaid: loadMermaid,\n flint: loadFlint,\n 'flint-chart': loadFlint,\n};\n\n/**\n * The fence languages this renderer draws instead of printing.\n *\n * - Streaming callers hold an open fence back as plain code, or every keystroke fetches the chunk.\n * - Frozen: it is shared across every app in the bundle.\n */\nexport const DIAGRAM_LANGUAGES: readonly string[] = Object.freeze(Object.keys(DIAGRAM_CHUNKS));\n\n/**\n * Whether the `code` being rendered sits inside a fenced block.\n *\n * - Set by `pre`: a fence without info string has no `language-…` class, like inline code.\n */\nconst CodeBlockContext = createContext(false);\n\n/**\n * The `code` renderer: an inline `icon:<name>` token becomes the icon it names.\n *\n * - Fenced blocks never swap.\n * - Unknown names stay code; a name still streaming renders nothing.\n */\nconst MarkdownCode = ({\n children,\n className,\n ...props\n}: ComponentPropsWithoutRef<'code'> & ExtraProps) => {\n const { node: _node, ...rest } = props;\n const isBlock = use(CodeBlockContext);\n const name = isBlock ? undefined : getChatInlineIconName(getText(children));\n if (name !== undefined) return <ChatInlineIcon name={name} />;\n return (\n <code className={className} {...rest}>\n {children}\n </code>\n );\n};\n\n// Strip react-markdown's hast `node` before spreading onto a DOM element.\nconst baseComponents: Components = {\n // Diagrams replace the whole `<pre>`; a `<div>` inside `<pre><code>` is invalid HTML.\n pre({ children, ...props }: ComponentPropsWithoutRef<'pre'> & ExtraProps) {\n const child = Array.isArray(children) ? children[0] : children;\n const code = getText(child).replace(/\\n$/, '');\n const language = getLanguage(child);\n const load =\n language !== undefined && Object.hasOwn(DIAGRAM_CHUNKS, language)\n ? DIAGRAM_CHUNKS[language]\n : undefined;\n if (load) {\n if (!code.trim()) return null;\n return <DiagramBlock load={load} code={code} />;\n }\n const { node: _node, ...rest } = props;\n return (\n <div className=\"tw:group tw:relative\">\n <span className=\"tw:absolute tw:right-2 tw:top-2 tw:opacity-0 tw:transition-opacity tw:group-focus-within:opacity-100 tw:group-hover:opacity-100\">\n <ClipboardButton text={code} tooltip=\"Copy\" size=\"icon-xs\" variant=\"outline\" />\n </span>\n <pre {...rest}>\n <CodeBlockContext value={true}>{children}</CodeBlockContext>\n </pre>\n </div>\n );\n },\n code: MarkdownCode,\n a({ children, href, ...props }: ComponentPropsWithoutRef<'a'> & ExtraProps) {\n const { node: _node, ...rest } = props;\n const isExternal = !!href && /^https?:\\/\\//.test(href);\n return (\n <a\n href={href}\n {...(isExternal ? { target: '_blank', rel: 'noopener noreferrer' } : null)}\n {...rest}\n >\n {children}\n </a>\n );\n },\n table({ className, ...props }: ComponentPropsWithoutRef<'table'> & ExtraProps) {\n const { node: _node, ...rest } = props;\n return (\n <div className=\"tw:not-prose tw:my-4\">\n <Table bordered className={cn('tw:!mb-0', className)} {...rest} />\n </div>\n );\n },\n thead(props: ComponentPropsWithoutRef<'thead'> & ExtraProps) {\n const { node: _node, ...rest } = props;\n return <Table.Header {...rest} />;\n },\n tbody(props: ComponentPropsWithoutRef<'tbody'> & ExtraProps) {\n const { node: _node, ...rest } = props;\n return <Table.Body {...rest} />;\n },\n tr(props: ComponentPropsWithoutRef<'tr'> & ExtraProps) {\n const { node: _node, ...rest } = props;\n return <Table.Row {...rest} />;\n },\n th(props: ComponentPropsWithoutRef<'th'> & ExtraProps) {\n const { node: _node, ...rest } = props;\n return <Table.Head {...rest} />;\n },\n td(props: ComponentPropsWithoutRef<'td'> & ExtraProps) {\n const { node: _node, ...rest } = props;\n return <Table.Cell {...rest} />;\n },\n};\n\ntype BlockProps = {\n /** GFM source; ```mermaid/```flint fences render as diagrams. */\n children: string;\n /** Appended after GFM. Keep in a module constant, or the caller's memo breaks. */\n remarkPlugins?: NonNullable<Options['remarkPlugins']>;\n /** Merged by key; an override **replaces** the built-in renderer, not wraps it.\n * Keep in a module constant. */\n components?: Components;\n};\n\ntype Props = BlockProps & { className?: string; rhythm?: Rhythm };\n\n/**\n * The prose surface an answer is drawn on.\n *\n * - Wrap all `Block`s of one answer in one `Root`, so `:first-child`/`:last-child` span the reply.\n * - `data-prose` is `MessageBubble`'s colour hook; Tailwind can't target `tw:prose` directly.\n * - Spacing overrides need `!`: `tw:prose-answer` rules are `(0,2,1)`, above `[&_p]:mb-1`.\n */\nconst MarkdownRoot = ({\n children,\n className,\n rhythm = 'answer',\n}: PropsWithChildren<{ className?: string; rhythm?: Rhythm }>) => (\n <div data-prose className={cn(PROSE_CLASS[rhythm], className)}>\n {children}\n </div>\n);\n\n/** One parsed piece of an answer, with no surface of its own; memoise at the call site. */\nconst MarkdownBlock = ({ children, remarkPlugins, components: componentOverrides }: BlockProps) => (\n <ReactMarkdown\n remarkPlugins={\n remarkPlugins === undefined ? baseRemarkPlugins : [...baseRemarkPlugins, ...remarkPlugins]\n }\n components={\n componentOverrides === undefined\n ? baseComponents\n : { ...baseComponents, ...componentOverrides }\n }\n >\n {children}\n </ReactMarkdown>\n);\n\n/**\n * Read-only GFM Markdown renderer with design-token typography.\n *\n * - Needs a `TooltipProvider` at the app root (code copy button).\n * - Pass `rhythm=\"chrome\"` for content a model did not write.\n */\nexport const Markdown = ({ className, rhythm, ...blockProps }: Props) => (\n <MarkdownRoot className={className} rhythm={rhythm}>\n <MarkdownBlock {...blockProps} />\n </MarkdownRoot>\n);\n\nMarkdown.Root = MarkdownRoot;\nMarkdown.Block = MarkdownBlock;\n","import { type ReactNode, useCallback, useEffect, useRef, useState } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { Tooltip } from '../../components/Tooltip';\nimport { Maximize2 } from '../../icons';\nimport { cn } from '../../utils';\n\n/** How much wider than its column a table has to be before the column is the wrong surface. */\nconst EXPAND_RATIO = 1.5;\n\n/**\n * The fade's end colour — must match the host's surface, or it draws a strip over the data.\n *\n * - Full class strings: Tailwind reads literals.\n */\nconst FADE_SURFACE = {\n card: 'tw:from-card',\n background: 'tw:from-background',\n} as const;\n\ntype Surface = keyof typeof FADE_SURFACE;\n\ntype Props = {\n /** A `Table bordered` at intrinsic width (`tw:min-w-max`) — otherwise it wraps and never overflows. */\n children: ReactNode;\n /** What the host paints behind the table; paint `Table`'s header band this colour too. */\n surface?: Surface;\n /** Host controls left of the expand action; hover reveal is the host's (`tw:group` on `className`). */\n actions?: ReactNode;\n /** Opens the table somewhere wider; omit where there is nowhere to go (the fade still draws). */\n onExpand?: () => void;\n className?: string;\n};\n\n/**\n * A table in an answer that shows when it is cut off on the right.\n *\n * - Controls sit in a fixed-height rail above the grid, so they never cover rows or shift them.\n * - The fade shows only while content remains to the right.\n * - A painted gradient, not `tw:scroll-fade-x`: that needs scroll-driven animations, which the\n * `baseline-widely-available` build floor lacks, and must sit on `Table`'s own container.\n * - Past `EXPAND_RATIO` the expand action shows without hover.\n */\nexport const MarkdownTable = ({\n children,\n actions,\n onExpand,\n surface = 'card',\n className,\n}: Props) => {\n const frameRef = useRef<HTMLDivElement>(null);\n const [overflow, setOverflow] = useState({ scrollable: false, atEnd: true, ratio: 1 });\n\n // Scrolls `Table`'s own container (the frame's first child); the frame stays visible for the fade.\n const measure = useCallback(() => {\n const box = frameRef.current?.firstElementChild;\n if (!box) return;\n\n const { scrollLeft, scrollWidth, clientWidth } = box;\n const hidden = scrollWidth - clientWidth;\n\n setOverflow({\n scrollable: hidden > 1,\n atEnd: scrollLeft >= hidden - 1,\n ratio: clientWidth > 0 ? scrollWidth / clientWidth : 1,\n });\n }, []);\n\n useEffect(() => {\n const box = frameRef.current?.firstElementChild;\n if (!box) return;\n\n measure();\n box.addEventListener('scroll', measure, { passive: true });\n\n // Both widths move independently:\n // - the box's, when the panel resizes without the viewport;\n // - the grid's, as streamed cells widen it inside a box that never moves.\n const observer = new ResizeObserver(measure);\n observer.observe(box);\n if (box.firstElementChild) observer.observe(box.firstElementChild);\n\n return () => {\n box.removeEventListener('scroll', measure);\n observer.disconnect();\n };\n }, [measure]);\n\n const showExpand = !!onExpand && overflow.scrollable && overflow.ratio >= EXPAND_RATIO;\n\n return (\n <div className={className}>\n {(actions || onExpand) && (\n // Hover controls go left: a hidden reveal span keeps its width and would leave a gap.\n <div className=\"tw:flex tw:h-8 tw:items-center tw:justify-end tw:gap-1\">\n {actions}\n {showExpand && (\n // Not a native `title`: it renders under the pointer, over the header row.\n <Tooltip\n tooltip=\"This table is wider than the space it has\"\n placement=\"top\"\n triggerAsChild\n >\n <Button size=\"small\" variant=\"invisible\" onClick={onExpand}>\n <Maximize2 className=\"tw:size-3.5\" />\n Open wider\n </Button>\n </Tooltip>\n )}\n </div>\n )}\n\n <div ref={frameRef} className=\"tw:relative\">\n {children}\n\n {overflow.scrollable && !overflow.atEnd && (\n <span\n aria-hidden\n data-testid=\"markdown-table-fade\"\n className={cn(\n 'tw:pointer-events-none tw:absolute tw:inset-y-px tw:right-px tw:w-12 tw:rounded-r-[10px] tw:bg-gradient-to-l tw:to-transparent',\n FADE_SURFACE[surface],\n )}\n />\n )}\n </div>\n </div>\n );\n};\n","import type { ComponentProps, PropsWithChildren, ReactNode } from 'react';\nimport { cva } from 'class-variance-authority';\n\nimport type { Avatar } from '../../components/Avatar';\n\n// No per-message avatar: alignment carries the turn and a narrow panel keeps its width.\nconst containerClasses = cva(['tw:flex', 'tw:max-w-full', 'tw:gap-3'], {\n variants: {\n variant: {\n user: ['tw:justify-end'],\n assistant: ['tw:justify-start', 'tw:w-full'],\n },\n },\n defaultVariants: {\n variant: 'assistant',\n },\n});\n\nconst stackClasses = cva(['tw:flex', 'tw:min-w-0', 'tw:flex-1', 'tw:flex-col', 'tw:gap-2'], {\n variants: {\n variant: {\n user: ['tw:items-end'],\n assistant: [],\n },\n },\n defaultVariants: {\n variant: 'assistant',\n },\n});\n\nconst contentClasses = cva(\n [\n 'tw:flex',\n 'tw:flex-col',\n // Small gap: prose already spaces its blocks.\n 'tw:gap-3',\n 'tw:break-words',\n 'tw:leading-relaxed',\n 'tw:text-foreground',\n // `data-prose`, not `tw:prose`: Tailwind scans raw bytes, so a `\\:` escape reaches it doubled.\n 'tw:[&_[data-prose]]:text-foreground',\n ],\n {\n variants: {\n variant: {\n assistant: ['tw:flex-1', 'tw:w-full', 'tw:min-w-0', 'tw:[&>*]:min-w-0'],\n user: [\n // A share of the column, so a docked panel keeps the left gutter; a margin would push\n // a `w-fit` bubble past the column. The absolute cap bounds a fullscreen panel.\n 'tw:max-w-[min(85%,40rem)]',\n 'tw:w-fit',\n 'tw:bg-muted',\n // Tighter vertically, with a smaller radius, so a one-line message reads as speech.\n 'tw:px-3',\n 'tw:py-2',\n 'tw:rounded-xl',\n 'tw:overflow-hidden',\n 'tw:wrap-anywhere',\n ],\n },\n },\n\n defaultVariants: {\n variant: 'assistant',\n },\n },\n);\n\ntype Props = {\n variant: 'user' | 'assistant';\n actions?: ReactNode;\n createdAt?: string;\n /** @deprecated No avatar is rendered; accepted so existing call sites keep compiling. */\n user?: ComponentProps<typeof Avatar>['user'];\n} & PropsWithChildren;\n\nexport const MessageBubble = ({ variant, children, actions, createdAt }: Props) => {\n return (\n <div className={containerClasses({ variant })} data-testid={`chat-message-${variant}`}>\n <div className={stackClasses({ variant })}>\n {/* Timestamp on the user's bubble only: on an answer the native tooltip would cover\n tables and code. */}\n <div\n className={contentClasses({ variant })}\n title={variant === 'user' ? createdAt : undefined}\n >\n {children}\n </div>\n {actions}\n </div>\n </div>\n );\n};\n","import { type FormEvent, type KeyboardEvent, type ReactNode, useState } from 'react';\n\nimport { Badge } from '../../components/Badge';\nimport { Button } from '../../components/Button';\nimport {\n FullScreenModal,\n FullScreenModalBody,\n FullScreenModalHeader,\n} from '../../components/FullScreenModal';\nimport { Tooltip } from '../../components/Tooltip';\nimport { ChevronDown, Maximize2, Minimize2, Send, X } from '../../icons';\nimport { cn } from '../../utils';\nimport { Textarea } from '../Textarea';\n\nimport { CollapsibleBody } from './CollapsibleBody';\nimport { hasMotion } from './hasMotion';\n\ntype PlanApprovalStatus = 'pending' | 'approved' | 'dismissed' | 'changes-requested';\n\ntype PlanApprovalProps = {\n status: PlanApprovalStatus;\n title: string;\n summary?: ReactNode;\n stepCount?: number;\n planBody?: ReactNode;\n\n defaultExpanded?: boolean;\n isExpanded?: boolean;\n onExpandToggle?: (next: boolean) => void;\n\n onApprove?: () => void;\n onRequestChanges?: (reason: string) => void;\n onClose?: () => void;\n isSubmitting?: boolean;\n approveTooltip?: ReactNode;\n\n pendingPillLabel?: string;\n approvedPillLabel?: string;\n dismissedPillLabel?: string;\n changesRequestedPillLabel?: string;\n approveLabel?: string;\n requestChangesLabel?: string;\n cancelLabel?: string;\n showMoreLabel?: string;\n showLessLabel?: string;\n closeLabel?: string;\n fullScreenLabel?: string;\n exitFullScreenLabel?: string;\n changeRequestPlaceholder?: string;\n changeRequestSubmitLabel?: string;\n stepCountLabel?: (count: number) => string;\n\n className?: string;\n};\n\nconst defaultStepCountLabel = (count: number) => `${count} step${count === 1 ? '' : 's'}`;\n\nconst StatusPill = ({\n status,\n pendingLabel,\n approvedLabel,\n dismissedLabel,\n changesRequestedLabel,\n}: {\n status: PlanApprovalStatus;\n pendingLabel: string;\n approvedLabel: string;\n dismissedLabel: string;\n changesRequestedLabel: string;\n}) => {\n if (status === 'approved') {\n return (\n <Badge color=\"green\" variant=\"pill\" className=\"tw:normal-case tw:tracking-normal\">\n {approvedLabel}\n </Badge>\n );\n }\n if (status === 'dismissed') {\n return (\n <Badge color=\"gray\" variant=\"pill\" className=\"tw:normal-case tw:tracking-normal\">\n {dismissedLabel}\n </Badge>\n );\n }\n if (status === 'changes-requested') {\n return (\n <Badge color=\"blue\" variant=\"pill\" className=\"tw:normal-case tw:tracking-normal\">\n {changesRequestedLabel}\n </Badge>\n );\n }\n return (\n <Badge color=\"green\" variant=\"pill\" className=\"tw:normal-case tw:tracking-normal\">\n {pendingLabel}\n </Badge>\n );\n};\n\nconst ExpandToggle = ({\n isExpanded,\n onToggle,\n showMoreLabel,\n showLessLabel,\n}: {\n isExpanded: boolean;\n onToggle: () => void;\n showMoreLabel: string;\n showLessLabel: string;\n}) => (\n <button\n type=\"button\"\n onClick={onToggle}\n aria-expanded={isExpanded}\n className=\"tw:inline-flex tw:cursor-pointer tw:items-center tw:gap-1 tw:bg-transparent tw:p-0 tw:text-sm tw:font-medium tw:text-secondary-500 tw:hover:text-secondary-600 tw:focus-visible:outline tw:focus-visible:outline-2 tw:focus-visible:outline-offset-2 tw:focus-visible:outline-ring tailwindcss-preflight\"\n >\n <span>{isExpanded ? showLessLabel : showMoreLabel}</span>\n <ChevronDown\n className={cn('tw:size-5 tw:transition-transform', isExpanded && 'tw:rotate-180')}\n />\n </button>\n);\n\nconst ChangeRequestForm = ({\n value,\n onValueChange,\n onSubmit,\n onKeyDown,\n placeholder,\n submitLabel,\n formLabel,\n canSubmit,\n isSubmitting,\n}: {\n value: string;\n onValueChange: (value: string) => void;\n onSubmit: (event?: FormEvent) => void;\n onKeyDown: (event: KeyboardEvent<HTMLTextAreaElement>) => void;\n placeholder: string;\n submitLabel: string;\n formLabel: string;\n canSubmit: boolean;\n isSubmitting: boolean;\n}) => (\n <form\n onSubmit={onSubmit}\n className=\"tw:border-0 tw:border-t tw:border-solid tw:border-border tw:bg-card tw:text-card-foreground tw:px-4 tw:py-3\"\n aria-label={formLabel}\n >\n <div className=\"tw:relative\">\n <Textarea\n value={value}\n onValueChange={onValueChange}\n placeholder={placeholder}\n maxRows={4}\n autoFocus\n onKeyDown={onKeyDown}\n containerClassName=\"tw:pr-12\"\n disabled={isSubmitting}\n aria-label={placeholder}\n data-testid=\"plan-change-request-input\"\n />\n <Button\n type=\"submit\"\n variant=\"invisible\"\n size=\"icon-sm\"\n aria-label={submitLabel}\n disabled={!canSubmit}\n className=\"tw:absolute tw:right-2 tw:top-1/2 tw:-translate-y-1/2 tw:[&_svg]:text-secondary-500 tw:not-disabled:hover:[&_svg]:text-secondary-600\"\n data-testid=\"plan-change-request-submit\"\n >\n <Send className=\"tw:size-4\" />\n </Button>\n </div>\n </form>\n);\n\nconst PlanActions = ({\n isRequestingChanges,\n isSubmitting,\n onApprove,\n onRequestChanges,\n onOpenRequestChanges,\n onCancelChangeRequest,\n approveLabel,\n requestChangesLabel,\n cancelLabel,\n approveTooltip,\n}: {\n isRequestingChanges: boolean;\n isSubmitting: boolean;\n onApprove?: () => void;\n onRequestChanges?: (reason: string) => void;\n onOpenRequestChanges: () => void;\n onCancelChangeRequest: () => void;\n approveLabel: string;\n requestChangesLabel: string;\n cancelLabel: string;\n approveTooltip?: ReactNode;\n}) => (\n <div className=\"tw:flex tw:shrink-0 tw:items-center tw:gap-2\">\n {isRequestingChanges ? (\n <Button\n variant=\"outline\"\n size=\"small\"\n onClick={onCancelChangeRequest}\n disabled={isSubmitting}\n data-testid=\"plan-cancel-button\"\n className=\"tw:shrink-0 tw:whitespace-nowrap\"\n >\n {cancelLabel}\n </Button>\n ) : (\n onRequestChanges && (\n <Button\n variant=\"outline\"\n size=\"small\"\n onClick={onOpenRequestChanges}\n disabled={isSubmitting}\n data-testid=\"plan-request-changes-button\"\n className=\"tw:shrink-0 tw:whitespace-nowrap\"\n >\n {requestChangesLabel}\n </Button>\n )\n )}\n {onApprove &&\n (approveTooltip ? (\n <Tooltip tooltip={approveTooltip} placement=\"top\" triggerAsChild>\n <Button\n variant=\"primary\"\n size=\"small\"\n onClick={onApprove}\n disabled={isSubmitting || isRequestingChanges}\n data-testid=\"plan-approve-button\"\n className=\"tw:shrink-0 tw:whitespace-nowrap\"\n >\n {approveLabel}\n </Button>\n </Tooltip>\n ) : (\n <Button\n variant=\"primary\"\n size=\"small\"\n onClick={onApprove}\n disabled={isSubmitting || isRequestingChanges}\n data-testid=\"plan-approve-button\"\n className=\"tw:shrink-0 tw:whitespace-nowrap\"\n >\n {approveLabel}\n </Button>\n ))}\n </div>\n);\n\nexport const PlanApproval = ({\n status,\n title,\n summary,\n stepCount,\n planBody,\n\n defaultExpanded = false,\n isExpanded: isExpandedProp,\n onExpandToggle,\n\n onApprove,\n onRequestChanges,\n onClose,\n isSubmitting = false,\n approveTooltip,\n\n pendingPillLabel = 'Ready for approval',\n approvedPillLabel = 'Approved',\n dismissedPillLabel = 'Dismissed',\n changesRequestedPillLabel = 'Changes Requested',\n approveLabel = 'Approve',\n requestChangesLabel = 'Request Changes',\n cancelLabel = 'Cancel',\n showMoreLabel = 'Show more',\n showLessLabel = 'Show less',\n closeLabel = 'Dismiss plan',\n fullScreenLabel = 'View full screen',\n exitFullScreenLabel = 'Exit full screen',\n changeRequestPlaceholder = 'What would you like to change in the plan?',\n changeRequestSubmitLabel = 'Send change request',\n stepCountLabel = defaultStepCountLabel,\n\n className,\n}: PlanApprovalProps) => {\n const [uncontrolledExpanded, setUncontrolledExpanded] = useState(defaultExpanded);\n const isExpanded = isExpandedProp ?? uncontrolledExpanded;\n const [isRequestingChanges, setIsRequestingChanges] = useState(false);\n const [changeRequest, setChangeRequest] = useState('');\n const [isFullScreen, setIsFullScreen] = useState(false);\n\n const isPending = status === 'pending';\n const showActions = isPending && (onApprove || onRequestChanges);\n const showClose = isPending && Boolean(onClose);\n const canShowPlanBody = planBody != null;\n const trimmedChangeRequest = changeRequest.trim();\n const canSubmitChangeRequest = trimmedChangeRequest.length > 0 && !isSubmitting;\n\n const [isClosing, setIsClosing] = useState(false);\n\n const toggleExpanded = () => {\n const next = !isExpanded;\n if (!next) setIsClosing(hasMotion());\n if (isExpandedProp === undefined) {\n setUncontrolledExpanded(next);\n }\n onExpandToggle?.(next);\n };\n\n const handleOpenRequestChanges = () => {\n setIsRequestingChanges(true);\n if (!isExpanded) {\n toggleExpanded();\n }\n };\n\n const handleCancelChangeRequest = () => {\n setIsRequestingChanges(false);\n setChangeRequest('');\n };\n\n const handleSubmitChangeRequest = (event?: FormEvent) => {\n event?.preventDefault();\n if (!canSubmitChangeRequest) return;\n onRequestChanges?.(trimmedChangeRequest);\n };\n\n const handleTextareaKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n handleSubmitChangeRequest();\n }\n };\n\n const showChangeRequestForm = isRequestingChanges && isPending;\n\n const changeRequestForm = (\n <ChangeRequestForm\n value={changeRequest}\n onValueChange={setChangeRequest}\n onSubmit={handleSubmitChangeRequest}\n onKeyDown={handleTextareaKeyDown}\n placeholder={changeRequestPlaceholder}\n submitLabel={changeRequestSubmitLabel}\n formLabel={requestChangesLabel}\n canSubmit={canSubmitChangeRequest}\n isSubmitting={isSubmitting}\n />\n );\n\n const planActions = (\n <PlanActions\n isRequestingChanges={isRequestingChanges}\n isSubmitting={isSubmitting}\n onApprove={onApprove}\n onRequestChanges={onRequestChanges}\n onOpenRequestChanges={handleOpenRequestChanges}\n onCancelChangeRequest={handleCancelChangeRequest}\n approveLabel={approveLabel}\n requestChangesLabel={requestChangesLabel}\n cancelLabel={cancelLabel}\n approveTooltip={approveTooltip}\n />\n );\n\n return (\n <>\n {/* Two surface tiers: shell on `background`; plan body, form and action bar on `card`.\n\n - Each tier pins its foreground too, or it inherits the host's ink and can read\n same-on-same in one scheme. */}\n <section\n aria-label={title}\n className={cn(\n 'tw:flex tw:w-full tw:max-w-[800px] tw:flex-col tw:overflow-hidden tw:rounded-xl tw:border tw:border-solid tw:border-border tw:bg-background tw:text-foreground',\n className,\n )}\n data-testid=\"plan-approval-root\"\n data-plan-status={status}\n >\n <div className=\"tw:flex tw:items-start tw:gap-2 tw:pl-4 tw:pr-2 tw:pt-4\">\n <div className=\"tw:flex tw:min-w-0 tw:flex-1 tw:flex-col tw:gap-2 tw:pb-4\">\n <div className=\"tw:flex tw:items-center tw:gap-3\">\n <StatusPill\n status={status}\n pendingLabel={pendingPillLabel}\n approvedLabel={approvedPillLabel}\n dismissedLabel={dismissedPillLabel}\n changesRequestedLabel={changesRequestedPillLabel}\n />\n {/* 12px `muted-foreground` sits at the AA floor (4.55:1 in light).\n\n - The ratio is pinned in `tokenBlocks.test.ts`; fix headroom in the token. */}\n {stepCount != null && stepCount > 0 && (\n <span className=\"tw:text-xs tw:leading-4 tw:text-muted-foreground\">\n {stepCountLabel(stepCount)}\n </span>\n )}\n </div>\n <p className=\"tw:m-0 tw:text-base tw:font-semibold tw:leading-6\">{title}</p>\n </div>\n <div className=\"tw:flex tw:items-center tw:gap-2\">\n {canShowPlanBody && !isFullScreen && (\n <Tooltip tooltip={fullScreenLabel} placement=\"top\" triggerAsChild>\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n aria-label={fullScreenLabel}\n onClick={() => setIsFullScreen(true)}\n data-testid=\"plan-fullscreen-button\"\n >\n <Maximize2 className=\"tw:size-4\" />\n </Button>\n </Tooltip>\n )}\n {showClose && !isFullScreen && (\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n aria-label={closeLabel}\n onClick={onClose}\n disabled={isSubmitting}\n data-testid=\"plan-close-button\"\n >\n <X className=\"tw:size-4\" />\n </Button>\n )}\n </div>\n </div>\n\n {summary != null && (\n <div\n className={cn(\n 'tw:whitespace-pre-wrap tw:border-0 tw:border-t tw:border-solid tw:border-border tw:px-4 tw:pt-4 tw:text-sm',\n isExpanded && canShowPlanBody ? 'tw:pb-4' : 'tw:pb-2',\n )}\n >\n {summary}\n </div>\n )}\n\n {canShowPlanBody && (\n <CollapsibleBody\n isExpanded={isExpanded}\n isClosing={isClosing}\n onClosed={() => setIsClosing(false)}\n >\n <div className=\"tw:max-h-[400px] tw:overflow-y-auto tw:border-0 tw:border-t tw:border-solid tw:border-border tw:bg-card tw:p-4 tw:text-sm tw:text-card-foreground\">\n {planBody}\n </div>\n </CollapsibleBody>\n )}\n\n {!isFullScreen && (\n <>\n {showChangeRequestForm && changeRequestForm}\n\n <div\n className={cn(\n 'tw:flex tw:items-center tw:gap-2 tw:overflow-x-auto tw:border-0 tw:border-t tw:border-solid tw:border-border tw:bg-card tw:px-4 tw:py-3 tw:text-card-foreground',\n canShowPlanBody ? 'tw:justify-between' : 'tw:justify-end',\n )}\n >\n {canShowPlanBody && (\n <div className=\"tw:shrink-0\">\n <ExpandToggle\n isExpanded={isExpanded}\n onToggle={toggleExpanded}\n showMoreLabel={showMoreLabel}\n showLessLabel={showLessLabel}\n />\n </div>\n )}\n\n {showActions && planActions}\n </div>\n </>\n )}\n </section>\n\n {canShowPlanBody && isFullScreen && (\n <FullScreenModal onEscapeKeyDown={() => setIsFullScreen(false)}>\n <FullScreenModalHeader\n title={\n <div className=\"tw:flex tw:min-w-0 tw:items-center tw:gap-3\">\n <StatusPill\n status={status}\n pendingLabel={pendingPillLabel}\n approvedLabel={approvedPillLabel}\n dismissedLabel={dismissedPillLabel}\n changesRequestedLabel={changesRequestedPillLabel}\n />\n <span className=\"tw:truncate\">{title}</span>\n </div>\n }\n onClose={() => setIsFullScreen(false)}\n showPreviousTitle={false}\n >\n <div className=\"tw:flex tw:items-center tw:gap-2\">\n {showClose && (\n <Tooltip tooltip={closeLabel} placement=\"bottom\" triggerAsChild>\n <Button\n variant=\"outline\"\n size=\"icon\"\n aria-label={closeLabel}\n onClick={onClose}\n disabled={isSubmitting}\n data-testid=\"plan-close-button\"\n >\n <X className=\"tw:size-4\" />\n </Button>\n </Tooltip>\n )}\n <Tooltip tooltip={exitFullScreenLabel} placement=\"bottom\" triggerAsChild>\n <Button\n variant=\"outline\"\n size=\"icon\"\n aria-label={exitFullScreenLabel}\n onClick={() => setIsFullScreen(false)}\n data-testid=\"plan-exit-fullscreen-button\"\n >\n <Minimize2 className=\"tw:size-4\" />\n </Button>\n </Tooltip>\n </div>\n </FullScreenModalHeader>\n {/* Portalled to `document.body`, so body and footer pin their own surface and ink. */}\n <FullScreenModalBody className=\"tw:bg-card tw:px-6 tw:py-4 tw:text-card-foreground\">\n <div className=\"tw:mx-auto tw:w-full tw:max-w-[800px] tw:text-sm\">{planBody}</div>\n </FullScreenModalBody>\n {(showChangeRequestForm || showActions) && (\n <div className=\"tw:shrink-0 tw:border-0 tw:border-t tw:border-solid tw:border-border tw:bg-card tw:text-card-foreground\">\n <div className=\"tw:mx-auto tw:w-full tw:max-w-[800px]\">\n {showChangeRequestForm && changeRequestForm}\n {showActions && (\n <div className=\"tw:flex tw:justify-end tw:px-4 tw:py-3\">{planActions}</div>\n )}\n </div>\n </div>\n )}\n </FullScreenModal>\n )}\n </>\n );\n};\n\nexport type { PlanApprovalStatus, PlanApprovalProps };\n","import { Loader2 } from '../../icons';\n\ntype PlanRewritingIndicatorProps = {\n label?: string;\n};\n\nexport const PlanRewritingIndicator = ({\n label = 'Rewriting the plan...',\n}: PlanRewritingIndicatorProps) => (\n <div\n className=\"tw:flex tw:items-center tw:gap-2\"\n role=\"status\"\n data-testid=\"plan-rewriting-indicator\"\n >\n <Loader2 className=\"tw:size-4 tw:animate-spin tw:text-secondary-500\" />\n <span className=\"tw:text-sm tw:italic tw:text-secondary-500\">{label}</span>\n </div>\n);\n\nexport type { PlanRewritingIndicatorProps };\n","/**\n * Names the container query `PromptInput`'s `inline` row reads to fold into the stacked layout.\n *\n * It has to sit on an **ancestor**: a container query matches descendants only, so the field that\n * would read it cannot name it, and its own wrapper is the width the fold changes. A host that\n * never names it keeps the one-line row at every width.\n */\nexport const PROMPT_INPUT_CONTAINER = 'tw:@container/composer';\n","import { type ReactNode, type TransitionEvent, useLayoutEffect, useRef, useState } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { hasMotion } from './hasMotion';\n\ntype Props = {\n children: ReactNode;\n className?: string;\n};\n\n/**\n * A box whose height eases to whatever its content measures.\n *\n * - Content is measured with a `ResizeObserver`; without one (jsdom) the box is plain `auto`.\n * - The first measurement lands without a transition, so mounting with content does not grow in.\n * - Overflow is clipped only while the height moves, so focus rings are not cut off at rest.\n * - `prefers-reduced-motion` drops the transition.\n */\nexport const AnimatedHeight = ({ children, className }: Props) => {\n const contentRef = useRef<HTMLDivElement>(null);\n const heightRef = useRef<number>(undefined);\n const [height, setHeight] = useState<number>();\n const [isAnimating, setIsAnimating] = useState(false);\n\n useLayoutEffect(() => {\n const node = contentRef.current;\n if (!node || typeof ResizeObserver === 'undefined') return;\n\n const observer = new ResizeObserver(() => {\n const next = node.offsetHeight;\n const prev = heightRef.current;\n if (prev !== undefined && prev !== next && hasMotion()) setIsAnimating(true);\n heightRef.current = next;\n setHeight(next);\n });\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n const handleTransitionEnd = (event: TransitionEvent<HTMLDivElement>) => {\n if (event.target !== event.currentTarget || event.propertyName !== 'height') return;\n setIsAnimating(false);\n };\n\n return (\n <div\n style={{ height }}\n onTransitionEnd={handleTransitionEnd}\n className={cn(\n 'tw:transition-[height] tw:duration-200 tw:ease-out tw:motion-reduce:transition-none',\n isAnimating && 'tw:overflow-hidden',\n className,\n )}\n >\n <div ref={contentRef}>{children}</div>\n </div>\n );\n};\n","import type { ComponentProps, MouseEventHandler } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\ntype Props = ComponentProps<'button'>;\n\nexport const PromptInputAction = ({ ref, onMouseDown, ...rest }: Props) => {\n const handleOnMouseDown: MouseEventHandler<HTMLButtonElement> = (event) => {\n // Prevents focus stealing by PromptInput.\n event.stopPropagation();\n onMouseDown?.(event);\n };\n\n return <Slot {...rest} ref={ref} onMouseDown={handleOnMouseDown}></Slot>;\n};\n","import {\n type ComponentRef,\n type CSSProperties,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { Truncated } from '../../components/Truncated';\nimport { cn } from '../../utils';\nimport { Command } from '../Command';\n\n/** What the menu needs above or below the composer before it will open on that side. */\nconst MENU_HEIGHT = 440;\n/** As tall as the list ever gets, however much room there is. */\nconst MENU_MAX_HEIGHT = 416;\n/** Space kept from the measured edge; `POPUP_CHROME` is the popup's own border and padding. */\nconst MENU_GUTTER = 16;\nconst POPUP_CHROME = 10;\n\n/**\n * The rows a typed filter leaves.\n *\n * - An empty filter keeps everything.\n * - A row matches on its label or its value.\n * - Matching nothing falls back to the action rows.\n */\nexport const matchesFilter = (items: PromptCommand[], filterValue: string): PromptCommand[] => {\n if (!filterValue) return items;\n const query = filterValue.toLowerCase();\n const matched = items.filter(\n (item) => item.label.toLowerCase().includes(query) || item.value.toLowerCase().includes(query),\n );\n return matched.length > 0 ? matched : items.filter((item) => item.onSelect !== undefined);\n};\n\n/**\n * The band the menu has to stay inside: the window, narrowed by every ancestor that clips.\n *\n * - The chat sidebar's panel clips well below the window's top edge.\n */\nconst CLIPS = new Set(['hidden', 'auto', 'scroll', 'clip', 'overlay']);\n\nconst clipBand = (node: Element) => {\n let top = 0;\n let bottom = window.innerHeight;\n let parent = node.parentElement;\n while (parent) {\n const { overflowY, overflowX } = window.getComputedStyle(parent);\n if (CLIPS.has(overflowY) || CLIPS.has(overflowX)) {\n const box = parent.getBoundingClientRect();\n top = Math.max(top, box.top);\n bottom = Math.min(bottom, box.bottom);\n }\n parent = parent.parentElement;\n }\n return { top, bottom };\n};\n\nexport type PromptCommand = {\n label: string;\n value: string;\n description?: string;\n group: string;\n /** A leading adornment, for a list whose rows are things rather than commands. */\n icon?: ReactNode;\n /** The row's own rendering, in place of the label; the filter still matches `label`. */\n content?: ReactNode;\n /** An action row: picking it runs this instead of inserting `value` into the message. */\n onSelect?: () => void;\n};\n\ntype Props = {\n items: PromptCommand[];\n open: boolean;\n onSelect: (item: PromptCommand) => void;\n filterValue: string;\n /** A node, not a string: an empty list is where a host points at what would fill it. */\n emptyText?: ReactNode;\n /** Takes the list's place in the popup — a small form the host opened from an action row. */\n panel?: ReactNode;\n /** A control on a group's heading line, for whatever that group's rows come from. */\n groupAction?: (group: string) => ReactNode;\n /** A group's heading, rendered by the host when the group key is an id rather than a name. */\n groupHeading?: (group: string) => ReactNode;\n children: ReactNode;\n};\n\nexport const PromptInputCommands = ({\n items,\n open,\n onSelect,\n filterValue,\n emptyText = 'No commands found',\n panel,\n groupAction,\n groupHeading,\n children,\n}: Props) => {\n const filtered = matchesFilter(items, filterValue);\n\n // Held here: cmdk only auto-picks on its own input changing, and the textarea drives the filter.\n // - The last row moved to while it matches, else the first match, so Enter always has a pick.\n const [highlighted, setHighlighted] = useState<string>();\n // Every opening starts at the top of the list.\n const [wasOpen, setWasOpen] = useState(open);\n if (open !== wasOpen) {\n setWasOpen(open);\n if (open) setHighlighted(undefined);\n }\n\n /**\n * Which side the menu opens on.\n *\n * - Above by default; below when there is not room above and more room below.\n * - Re-measured while open: the composer and the transcript above it move.\n */\n const rootRef = useRef<ComponentRef<'div'>>(null);\n const [below, setBelow] = useState(false);\n // Capped by the measured room, not a constant: the sidebar panel has far less than a full page.\n const [maxHeight, setMaxHeight] = useState(MENU_MAX_HEIGHT);\n\n const measure = useCallback(() => {\n const node = rootRef.current;\n const box = node?.getBoundingClientRect();\n if (!node || !box) return;\n const band = clipBand(node);\n const above = box.top - band.top;\n const under = band.bottom - box.bottom;\n const openBelow = above < MENU_HEIGHT && under > above;\n setBelow(openBelow);\n setMaxHeight(\n Math.max(\n 0,\n Math.min(MENU_MAX_HEIGHT, (openBelow ? under : above) - MENU_GUTTER - POPUP_CHROME),\n ),\n );\n }, []);\n\n // First measurement in the ref callback, so the side is settled before paint.\n const attachRoot = useCallback(\n (node: ComponentRef<'div'> | null) => {\n rootRef.current = node;\n if (node) measure();\n },\n [measure],\n );\n\n useEffect(() => {\n if (!open) return;\n\n const node = rootRef.current;\n const observer = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(measure) : null;\n if (node) observer?.observe(node);\n window.addEventListener('resize', measure);\n window.addEventListener('scroll', measure, true);\n return () => {\n observer?.disconnect();\n window.removeEventListener('resize', measure);\n window.removeEventListener('scroll', measure, true);\n };\n }, [open, measure]);\n\n const highlightedValue = filtered.some((item) => item.value === highlighted)\n ? highlighted\n : filtered[0]?.value;\n\n const groups = filtered.reduce<Record<string, PromptCommand[]>>((acc, item) => {\n const group = acc[item.group] ?? [];\n group.push(item);\n acc[item.group] = group;\n return acc;\n }, {});\n\n // A custom property: `Command.List` takes a class for its scroll viewport, not a style.\n const menuStyle: CSSProperties & Record<string, string> = {\n '--prompt-menu-max-h': `${maxHeight}px`,\n };\n\n return (\n <Command\n ref={attachRoot}\n loop\n className=\"tw:relative\"\n shouldFilter={false}\n value={highlightedValue ?? ''}\n onValueChange={setHighlighted}\n >\n {open && (\n <div\n className={cn(\n 'tw:absolute tw:left-0 tw:z-50 tw:w-full tw:max-w-lg',\n below ? 'tw:top-full tw:mt-1' : 'tw:bottom-full tw:mb-1',\n 'tw:rounded-[14px] tw:border tw:border-border tw:bg-popover tw:text-popover-foreground tw:shadow-lg',\n 'tw:p-1',\n )}\n style={menuStyle}\n >\n {panel ? (\n <div className=\"tw:p-3\">{panel}</div>\n ) : filtered.length === 0 ? (\n <div className=\"tw:py-3 tw:pl-4 tw:text-center tw:text-sm tw:text-muted-foreground\">\n {emptyText}\n </div>\n ) : (\n <Command.List\n className=\"tw:group-data-[variant=argo]/command:px-1 tw:group-data-[variant=argo]/command:pb-1\"\n // Radix lays viewport content out as a table sized to the longest row; block fits the popup.\n viewPortClassName=\"tw:max-h-[var(--prompt-menu-max-h)] tw:[&>div]:!block\"\n >\n {Object.entries(groups).map(([groupName, groupItems], index) => (\n <Command.Group\n key={groupName}\n // An empty group name gets no heading.\n heading={\n groupName ? (\n <span className=\"tw:flex tw:items-center tw:justify-between tw:gap-2\">\n <span className=\"tw:min-w-0 tw:truncate\">\n {groupHeading?.(groupName) ?? groupName}\n </span>\n {groupAction?.(groupName)}\n </span>\n ) : undefined\n }\n className={cn(\n 'tw:[&_[cmdk-group-heading]]:normal-case',\n 'tw:[&_[cmdk-group-heading]]:tracking-normal',\n 'tw:[&_[cmdk-group-heading]]:border-b-0',\n // `!`: `Command.Group` sets a padding on this selector that would not merge.\n 'tw:[&_[cmdk-group-heading]]:!py-0',\n 'tw:[&_[cmdk-group-heading]]:mt-2',\n 'tw:[&_[cmdk-group-heading]]:mb-1',\n 'tw:[&_[cmdk-group-heading]]:pl-2',\n 'tw:[&_[cmdk-group-heading]]:text-xs',\n index > 0 && 'tw:mt-3',\n )}\n >\n {groupItems.map((item) => (\n <Command.Item\n key={item.value}\n value={item.value}\n className=\"tw:w-full tw:min-w-0 tw:rounded-md\"\n onSelect={() => onSelect(item)}\n >\n {item.icon}\n <div className=\"tw:flex tw:min-w-0 tw:flex-1 tw:flex-col\">\n {item.content ?? <span className=\"tw:truncate\">{item.label}</span>}\n {item.description && (\n <Truncated\n text={item.description}\n twoLines\n className=\"tw:text-xs tw:text-muted-foreground\"\n />\n )}\n </div>\n </Command.Item>\n ))}\n </Command.Group>\n ))}\n </Command.List>\n )}\n </div>\n )}\n\n {children}\n </Command>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { Plus } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { PromptInputAction } from './PromptInputAction';\n\ntype Props = Omit<ComponentProps<typeof Button>, 'children' | 'size' | 'variant'> & {\n /** Whether the menu this opens is showing; the glyph turns into an × while it is. */\n open?: boolean;\n /** Sized up to match a large composer's send button. */\n large?: boolean;\n};\n\n/**\n * The composer's \"add to message\" button.\n *\n * - One glyph for both states: a plus rotated 45° reads as a close cross, so nothing swaps.\n * - `aria-expanded` mirrors `open`; the accessible name changes with it.\n * - Wrapped in `PromptInputAction` so a click does not hand focus to the textarea.\n */\nexport const PromptInputMenuTrigger = ({\n open = false,\n large = false,\n className,\n ref,\n ...props\n}: Props) => (\n <PromptInputAction>\n <Button\n ref={ref}\n type=\"button\"\n size={large ? 'icon' : 'icon-sm'}\n variant=\"invisible\"\n aria-expanded={open}\n aria-label={open ? 'Close menu' : 'Add to message'}\n data-testid=\"prompt-input-menu-trigger\"\n // Gray like the rest of the row: `invisible` hovers blue, and an open menu's own trigger\n // reads as pressed, not as a link.\n className={cn(\n 'tw:rounded-full',\n 'tw:hover:not-disabled:bg-muted tw:hover:not-disabled:text-foreground tw:hover:not-disabled:border-transparent',\n 'tw:aria-expanded:bg-muted',\n className,\n )}\n {...props}\n >\n {/* One extra quarter turn on the way to the ×: the glyph is symmetric every 90°, so the\n spin costs nothing and lands on the same cross. */}\n <Plus\n className={cn(\n large ? 'tw:size-5' : 'tw:size-4',\n 'tw:transition-transform tw:duration-300 tw:ease-out tw:motion-reduce:transition-none',\n open && 'tw:rotate-135',\n )}\n />\n </Button>\n </PromptInputAction>\n);\n","import type { ComponentProps, ReactNode } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { Tooltip } from '../../components/Tooltip';\nimport { CirclePause, Play, Send } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { PromptInputAction } from './PromptInputAction';\n\ntype SubmitStatus = 'submitted' | 'ready' | 'streaming' | 'interrupted';\n\ntype Props = Pick<ComponentProps<typeof Button>, 'disabled' | 'ref'> & {\n status?: SubmitStatus;\n};\n\n// The accessible name per status; must match PromptInput's `handleSubmit` actions.\nconst ARIA_LABEL_BY_STATUS: Record<SubmitStatus, string> = {\n ready: 'Send message',\n streaming: 'Stop',\n interrupted: 'Continue',\n submitted: 'Sending…',\n};\n\nexport const PromptInputSubmit = ({ ref, disabled, status = 'ready' }: Props) => {\n const icon: ReactNode = (() => {\n if (status === 'streaming') return <CirclePause className=\"tw:size-4\" />;\n if (status === 'interrupted') return <Play className=\"tw:size-4\" />;\n // Optical centring: the paper plane's ink sits ~1px up and right of its box.\n return <Send className=\"tw:size-4 tw:translate-x-[-1px] tw:translate-y-[1px]\" />;\n })();\n\n const getTooltipText = () => {\n if (status === 'streaming') return 'Stop';\n if (status === 'interrupted') return 'Continue';\n return undefined;\n };\n\n return (\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <PromptInputAction>\n <Button\n ref={ref}\n type=\"submit\"\n disabled={disabled}\n aria-label={ARIA_LABEL_BY_STATUS[status]}\n size=\"icon-sm\"\n // `primary` supplies foreground, focus ring and disabled state; the gradient covers its fill.\n variant=\"primary\"\n isLoading={status === 'submitted'}\n className={cn(\n 'tw:ml-auto tw:flex tw:items-center tw:rounded-full',\n 'tw:bg-gradient-to-br tw:bg-origin-border tw:from-[#61E4FF] tw:via-[#1F8FFF] tw:to-[#7C5CFF]',\n 'tw:hover:not-disabled:brightness-110',\n )}\n >\n {/* Button renders its own spinner while loading. */}\n {status !== 'submitted' && icon}\n </Button>\n </PromptInputAction>\n </Tooltip.Trigger>\n\n {getTooltipText() && (\n <Tooltip.Content placement=\"top\" variant=\"action\">\n {getTooltipText()}\n </Tooltip.Content>\n )}\n </Tooltip.Root>\n );\n};\n","import {\n type ChangeEventHandler,\n type ComponentProps,\n type ComponentRef,\n type FormEventHandler,\n type KeyboardEvent,\n type KeyboardEventHandler,\n type MouseEventHandler,\n type ReactNode,\n type RefObject,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\nimport TextareaAutosize from 'react-textarea-autosize';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\nimport { TooltipProvider } from '../../components/Tooltip';\nimport { cn } from '../../utils';\n\nimport { AnimatedHeight } from './AnimatedHeight';\nimport { PromptInputAction } from './PromptInputAction';\nimport type { PromptCommand } from './PromptInputCommands';\nimport { matchesFilter, PromptInputCommands } from './PromptInputCommands';\nimport { PromptInputMenuTrigger } from './PromptInputMenuTrigger';\nimport { PromptInputSubmit } from './PromptInputSubmit';\n\n// The `inline` fold, below 480px of the `PROMPT_INPUT_CONTAINER` container.\n//\n// - Classes written out, never interpolated: Tailwind scans source text.\n// - Variants only set properties the base classes leave unset: the app's utilities load later and win.\n// - A host that names no container keeps the one-line row.\nconst CMDK_HIJACKED_KEYS = new Set(['ArrowUp', 'ArrowDown', 'Home', 'End', 'Enter']);\n\n/**\n * Whether the composer's always-mounted cmdk root would act on this keystroke, cancelling its default.\n *\n * - cmdk acts on every `CMDK_HIJACKED_KEYS` key regardless of modifiers, except a modified Enter.\n * - The textarea and the form stop these from bubbling, or a focused button never clicks on Enter.\n */\nconst isCmdkNavigation = (event: Pick<KeyboardEvent, 'key' | 'metaKey' | 'ctrlKey' | 'altKey'>) =>\n CMDK_HIJACKED_KEYS.has(event.key) &&\n (event.key !== 'Enter' || !(event.metaKey || event.ctrlKey || event.altKey));\n\n/**\n * The `@token` the caret sits at the end of, if any.\n *\n * - `@` has to open a word: it must start the value or follow whitespace.\n * - The token holds no whitespace or second `@` and runs past the caret, so a mid-word pick takes the word.\n * - `start` indexes the `@` itself, so replacing `[start, end)` removes the token.\n */\nexport const findMentionToken = (value: string, caret: number) => {\n const before = value.slice(0, caret);\n const match = /(?:^|\\s)@([^\\s@]*)$/.exec(before);\n if (!match) return null;\n const typed = match[1] ?? '';\n const tail = /^[^\\s@]*/.exec(value.slice(caret))?.[0] ?? '';\n return { start: caret - typed.length - 1, end: caret + tail.length, query: typed + tail };\n};\n\n/**\n * The `/token` a message leads with, while the caret is still on it.\n *\n * - Only the first token: the Agent SDK expands a skill only at the start of a message.\n * - Text may follow it.\n * - The caret past the token closes the menu.\n */\nexport const findSlashToken = (value: string, caret: number) => {\n const match = /^\\/(\\S*)/.exec(value);\n if (!match) return null;\n const end = match[0].length;\n if (caret > end) return null;\n return { end, query: match[1] ?? '' };\n};\n\nconst promptInputVariants = cva(\n [\n 'tailwindcss-preflight',\n 'tw:relative',\n\n 'tw:flex',\n 'tw:gap-2',\n 'tw:justify-center',\n\n // Kai's gradient edge: a gradient under the border box (`bg-origin-border`), with the inset\n // shadow painting the card back over the interior so only the 2px edge shows.\n 'tw:border',\n 'tw:border-2',\n 'tw:border-transparent',\n 'tw:rounded-[14px]',\n 'tw:bg-gradient-to-bl',\n 'tw:from-[#61E4FF]',\n 'tw:via-[#1F8FFF]',\n 'tw:to-[#7C5CFF]',\n 'tw:bg-origin-border',\n 'tw:shadow-[inset_0_100vw_rgb(var(--card))]',\n\n // Focus adds only a ring; the border width never changes, so nothing shifts.\n 'tw:has-[textarea:focus]:ring-4',\n 'tw:has-[textarea:focus]:ring-ring/30',\n\n 'tw:cursor-text',\n 'tw:px-2',\n ],\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n // Both are columns: attachments sit in rows above the line.\n default: ['tw:flex-col', 'tw:pt-3', 'tw:pb-2'],\n inline: ['tw:flex-col', 'tw:py-3'],\n },\n },\n },\n);\n\nconst wrapperVariants = cva(null, {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: 'tw:rounded-[14px]',\n inline: '',\n },\n },\n});\n\ntype Props = {\n /** The textarea, for a host that has to put the caret back. Not `ref`: that name is the textarea's own. */\n textareaRef?: RefObject<ComponentRef<'textarea'> | null>;\n onSend?: (value: string) => void;\n onAbort?: () => void;\n onContinue?: () => void;\n value?: string;\n onValueChange?: (value: string) => void;\n defaultValue?: string;\n prefix?: ReactNode;\n suffix?: ReactNode;\n /** Images and chips already attached, in rows of their own above the text. */\n attachments?: ReactNode;\n className?: string;\n variant?: 'default' | 'inline';\n disableSubmit?: boolean;\n /** `/` menu: pick one and it becomes the start of the message. */\n commands?: PromptCommand[];\n /** A form in the popup's place, opened by a `commands` action row; menus stay closed, Escape calls `onClose`. */\n panel?: { content: ReactNode; onClose: () => void };\n /** A control on a `/` group's heading line — where that group's rows are managed. */\n commandsGroupAction?: (group: string) => ReactNode;\n /** `@` menu: things to attach or reference, reachable from anywhere in the text. */\n mentions?: PromptCommand[];\n /** Fires after the `@` token is replaced; the host attaches or opens whatever the item stands for. */\n onMentionSelect?: (item: PromptCommand) => void;\n /** What the `@` list says when it has nothing to list — the host owns that wording. */\n mentionsEmptyText?: ReactNode;\n /** An `@` group's heading — the group key names a bucket, the host says how a bucket looks. */\n mentionsGroupHeading?: (group: string) => ReactNode;\n /** More than one `@` pick per menu: each pick leaves a bare `@`, so the list stays open. */\n mentionsMultiple?: boolean;\n} & VariantProps<typeof promptInputVariants> &\n Pick<\n ComponentProps<typeof TextareaAutosize>,\n 'placeholder' | 'minRows' | 'maxRows' | 'disabled' | 'defaultValue' | 'autoFocus'\n > &\n ComponentProps<typeof PromptInputSubmit>;\n\nexport const PromptInput = ({\n onSend,\n onAbort,\n onContinue,\n prefix,\n variant,\n suffix,\n attachments,\n className,\n disabled,\n disableSubmit,\n value = '',\n onValueChange,\n status = 'ready',\n maxRows = 6,\n minRows,\n commands,\n commandsGroupAction,\n panel,\n mentions,\n onMentionSelect,\n mentionsEmptyText = 'Nothing to attach',\n mentionsGroupHeading,\n mentionsMultiple = false,\n autoFocus,\n textareaRef: publishedRef,\n ...textareaProps\n}: Props) => {\n const defaultMinRows = variant === 'inline' ? 1 : 2;\n const isDisabled =\n (disabled || disableSubmit || !value.trim()) &&\n status !== 'streaming' &&\n status !== 'interrupted';\n\n const textareaId = useId();\n const textareaRef = useRef<ComponentRef<'textarea'>>(null);\n\n // From the ref callback, not an effect: a host restructure recreates the element while this stays mounted.\n const setTextareaNode = useCallback(\n (node: ComponentRef<'textarea'> | null) => {\n textareaRef.current = node;\n if (publishedRef) publishedRef.current = node;\n },\n [publishedRef],\n );\n const [dismissedValue, setDismissedValue] = useState<string | null>(null);\n // The caret, for the `@` menu, with the value it belongs to.\n // - A value the host set moves the caret to its end, not a stale offset.\n const [caret, setCaret] = useState(0);\n const [caretValue, setCaretValue] = useState(value);\n const moveCaret = (next: number, forValue: string) => {\n setCaret(next);\n setCaretValue(forValue);\n };\n if (value !== caretValue) moveCaret(value.length, value);\n\n // `autoFocus` is applied imperatively with `preventScroll`, mount-only.\n // - The DOM attribute scrolls ancestors; in a panel still sliding in, that drags the page sideways.\n const autoFocusRef = useRef(autoFocus);\n useEffect(() => {\n if (autoFocusRef.current) textareaRef.current?.focus({ preventScroll: true });\n }, []);\n\n // Esc dismisses the menu for the current value; a changed value clears the dismissal.\n if (dismissedValue !== null && value !== dismissedValue) setDismissedValue(null);\n\n const hasCommands = !!commands && commands.length > 0;\n const panelOpen = panel !== undefined;\n // Wired, not filled: an `@` in a project with nothing to attach still opens, and says so.\n const hasMentions = mentions !== undefined;\n const hasMenus = hasCommands || hasMentions;\n const slashToken =\n hasCommands && !panelOpen && value !== dismissedValue\n ? findSlashToken(value, Math.min(caret, value.length))\n : null;\n const commandsOpen = slashToken !== null;\n const mentionToken =\n hasMentions && !commandsOpen && !panelOpen && value !== dismissedValue\n ? findMentionToken(value, Math.min(caret, value.length))\n : null;\n const mentionsOpen = mentionToken !== null;\n const menuOpen = commandsOpen || mentionsOpen || panelOpen;\n const menuItems = commandsOpen ? (commands ?? []) : (mentions ?? []);\n const menuFilter = commandsOpen ? slashToken.query : (mentionToken?.query ?? '');\n\n const handleSubmit = () => {\n if (isDisabled) return;\n if (status === 'streaming') onAbort?.();\n if (status === 'interrupted') onContinue?.();\n if (status === 'ready') onSend?.(value);\n };\n\n const handleOnSubmit: FormEventHandler<HTMLFormElement> = (event) => {\n event.preventDefault();\n handleSubmit();\n };\n\n const handleOnChange: ChangeEventHandler<HTMLTextAreaElement> = (event) => {\n moveCaret(event.target.selectionStart ?? event.target.value.length, event.target.value);\n onValueChange?.(event.target.value);\n };\n\n // Clicks and arrow keys move the caret without changing the value; `select` fires for both.\n const handleOnSelect: FormEventHandler<HTMLTextAreaElement> = (event) => {\n moveCaret(event.currentTarget.selectionStart ?? 0, event.currentTarget.value);\n };\n\n const handleMenuSelect = (item: PromptCommand) => {\n if (item.onSelect) {\n // An action is not a message: the token that reached it goes.\n const start = mentionToken?.start ?? 0;\n const end = mentionToken?.end ?? slashToken?.end;\n if (end !== undefined) {\n const next = value.slice(0, start) + value.slice(end);\n onValueChange?.(next);\n moveCaret(start, next);\n }\n item.onSelect();\n textareaRef.current?.focus();\n return;\n }\n if (mentionToken) {\n // The token goes; the item attaches through `onMentionSelect`, never as text.\n const keep = mentionsMultiple ? '@' : '';\n const next = value.slice(0, mentionToken.start) + keep + value.slice(mentionToken.end);\n const nextCaret = mentionToken.start + keep.length;\n onValueChange?.(next);\n moveCaret(nextCaret, next);\n // The value lands on the next render; the caret has to be placed after it.\n requestAnimationFrame(() => {\n textareaRef.current?.setSelectionRange(nextCaret, nextCaret);\n });\n onMentionSelect?.(item);\n } else {\n const rest = slashToken ? value.slice(slashToken.end).replace(/^\\s+/, '') : '';\n const head = `${item.value} `;\n onValueChange?.(head + rest);\n moveCaret(head.length, head + rest);\n requestAnimationFrame(() => {\n textareaRef.current?.setSelectionRange(head.length, head.length);\n });\n }\n textareaRef.current?.focus();\n };\n\n // A message that is only its token, or a bare `@` left by a multiple pick, goes on dismiss.\n const dismissMenu = () => {\n if (value.trim() === '/' || value.trim() === '@') {\n onValueChange?.('');\n return;\n }\n if (mentionToken && mentionToken.query === '') {\n const next = (value.slice(0, mentionToken.start) + value.slice(mentionToken.end)).replace(\n /\\s+$/,\n '',\n );\n onValueChange?.(next);\n moveCaret(next.length, next);\n return;\n }\n setDismissedValue(value);\n };\n\n const handleOnKeyDown: KeyboardEventHandler<HTMLTextAreaElement> = (event) => {\n if (menuOpen) {\n if (event.key === 'Escape') {\n event.preventDefault();\n if (panel) panel.onClose();\n else dismissMenu();\n return;\n }\n // A panel has its own controls; the textarea's keys are its own again.\n if (panelOpen) return;\n // Let cmdk handle these via bubbling; Enter with nothing to pick falls through to send.\n if (event.key === 'ArrowUp' || event.key === 'ArrowDown') return;\n if (event.key === 'Enter' && matchesFilter(menuItems, menuFilter).length > 0) return;\n } else if (hasMenus && isCmdkNavigation(event)) {\n // The always-mounted cmdk root would preventDefault these and break multiline editing.\n // - Keys cmdk ignores (Cmd+Enter) still reach document-level hotkeys.\n event.stopPropagation();\n }\n\n if (event.key === 'Enter' && !event.shiftKey && !event.ctrlKey && !event.metaKey) {\n event.preventDefault();\n if (status !== 'streaming') handleSubmit();\n }\n };\n\n // Keys from a control other than the textarea stop here, before the cmdk root cancels them.\n // - Otherwise a focused button in a slot never clicks on Enter.\n // - Portalled layers of those controls bubble here too, through React.\n const handleOnFormKeyDown: KeyboardEventHandler<HTMLFormElement> = (event) => {\n if (hasMenus && event.target !== textareaRef.current && isCmdkNavigation(event)) {\n event.stopPropagation();\n }\n };\n\n const handleOnMouseDown: MouseEventHandler<HTMLFormElement> = (event) => {\n const { currentTarget, target } = event;\n if (target === textareaRef.current) return;\n // A portalled layer's mousedown reaches here through React; it keeps its own focus.\n if (!(target instanceof Node && currentTarget.contains(target))) return;\n\n event.preventDefault();\n textareaRef.current?.focus();\n };\n\n const formEl = (\n <div className={wrapperVariants({ variant })}>\n {/*This is alright, just refocused into a textarea. */}\n {/* oxlint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}\n <form\n data-testid=\"prompt-input\"\n data-status={status}\n onKeyDown={handleOnFormKeyDown}\n onMouseDown={handleOnMouseDown}\n onSubmit={handleOnSubmit}\n className={cn(\n promptInputVariants({ variant }),\n disabled &&\n 'tw:bg-none tw:border-border tw:shadow-[inset_0_100vw_rgb(var(--muted))] tw:cursor-default',\n className,\n )}\n >\n {/* Always mounted so it can animate; `-mb-2` cancels the form gap so an empty box adds no space. */}\n <AnimatedHeight className=\"tw:-mb-2\">\n {attachments && <div className=\"tw:flex tw:flex-col tw:gap-2 tw:pb-4\">{attachments}</div>}\n </AnimatedHeight>\n\n <label htmlFor={textareaId} className=\"tw:sr-only\">\n Prompt Input\n </label>\n <div\n className={cn(\n 'tw:flex tw:min-w-0 tw:gap-2',\n variant === 'inline'\n ? 'tw:flex-row tw:items-center tw:@max-[480px]/composer:flex-wrap'\n : 'tw:flex-col',\n )}\n >\n {prefix && <div className=\"tw:flex tw:shrink-0 tw:items-center\">{prefix}</div>}\n <div\n className={cn(\n 'tw:flex tw:min-w-0 tw:items-center',\n // `grow`, not `flex-1`, so the folded basis has no base class to beat.\n variant === 'inline'\n ? 'tw:grow tw:@max-[480px]/composer:order-first tw:@max-[480px]/composer:basis-full'\n : 'tw:flex-1',\n )}\n >\n <TextareaAutosize\n {...textareaProps}\n disabled={disabled}\n minRows={minRows ?? defaultMinRows}\n maxRows={maxRows}\n id={textareaId}\n ref={setTextareaNode}\n value={value}\n onChange={handleOnChange}\n onSelect={handleOnSelect}\n onKeyDown={handleOnKeyDown}\n className={cn(\n 'tw:resize-none',\n 'tw:outline-hidden',\n 'tw:min-w-32 tw:flex-1',\n // Indent aligns the text with the menu button's glyph.\n // - No `px-0` inline: the app re-emits base classes later, which would beat the fold.\n variant === 'inline' ? 'tw:@max-[480px]/composer:pl-2' : 'tw:pl-2 tw:pr-0',\n 'tw:bg-transparent',\n\n disabled ? 'tw:text-muted-foreground' : 'tw:text-foreground',\n 'tw:text-sm',\n 'tw:font-sans',\n\n 'tw:transition-[width]',\n 'tw:delay-75',\n 'tw:ease-linear',\n 'tw:overflow-auto',\n )}\n />\n </div>\n\n <div\n className={cn(\n 'tw:flex tw:items-center tw:gap-1',\n // Optical spacing: the filled send button reads closer than the outline ones.\n 'tw:[&>*:last-child]:ml-1',\n 'tw:shrink-0',\n // Inline, send needs extra room from the field's rounded corner.\n variant === 'inline' &&\n 'tw:pr-2.5 tw:@max-[480px]/composer:grow tw:@max-[480px]/composer:pr-0',\n )}\n >\n {suffix}\n <PromptInputSubmit disabled={isDisabled} status={status} />\n </div>\n </div>\n </form>\n </div>\n );\n\n return (\n <TooltipProvider>\n {hasMenus ? (\n <PromptInputCommands\n items={menuItems}\n open={menuOpen}\n onSelect={handleMenuSelect}\n filterValue={menuFilter}\n emptyText={mentionsOpen ? mentionsEmptyText : 'No commands found'}\n panel={panel?.content}\n groupAction={commandsOpen ? commandsGroupAction : undefined}\n groupHeading={mentionsOpen ? mentionsGroupHeading : undefined}\n >\n {formEl}\n </PromptInputCommands>\n ) : (\n formEl\n )}\n </TooltipProvider>\n );\n};\n\nPromptInput.Action = PromptInputAction;\nPromptInput.MenuTrigger = PromptInputMenuTrigger;\n","import { type KeyboardEvent, type ReactNode, useEffect, useRef, useState } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { Kbd, keys } from '../../components/Kbd';\nimport { Progress } from '../../components/Progress';\nimport { Tooltip } from '../../components/Tooltip';\nimport {\n digitFromKeyCode,\n MAX_DIGIT_HOTKEY,\n useAltDigitHotkey,\n} from '../../hooks/useAltDigitHotkey';\nimport { ArrowDown, ArrowUp, Check, ChevronLeft, ChevronRight, X } from '../../icons';\nimport { cn } from '../../utils';\nimport { TextInput } from '../TextInput';\n\ntype QuestionOption = {\n id: string;\n label: string;\n description?: string;\n preview?: string;\n};\n\ntype Props = {\n question: string;\n header?: string;\n options: readonly QuestionOption[];\n multiSelect?: boolean;\n selectedOptionIds?: readonly string[];\n onSelectionChange?: (selectedIds: readonly string[]) => void;\n customAnswer?: string;\n onCustomAnswerChange?: (value: string) => void;\n onCustomAnswerConfirm?: () => void;\n showCustomAnswer?: boolean;\n customAnswerPlaceholder?: string;\n showSkip?: boolean;\n onSkip?: () => void;\n onClose?: () => void;\n onNext?: () => void;\n submitTooltip?: ReactNode;\n onPrevious?: () => void;\n currentStep?: number;\n totalSteps?: number;\n renderPreview?: (content: string) => ReactNode;\n /** Focuses the card on mount, unless the focused field already holds text. */\n autoFocus?: boolean;\n /** ⌥1–⌥9 picks an option from anywhere on the page, text fields included. */\n enableShortcuts?: boolean;\n className?: string;\n};\n\nconst isEditableTarget = (target: EventTarget | null) =>\n target instanceof HTMLElement &&\n (target.isContentEditable || ['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName));\n\nconst isFieldWithText = (element: Element | null) => {\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {\n return element.value !== '';\n }\n return element instanceof HTMLElement && element.isContentEditable && !!element.textContent;\n};\n\nconst hasCommandModifier = (e: KeyboardEvent) => e.altKey || e.ctrlKey || e.metaKey;\n\nconst SEND_KEY_CLASS = 'tw:!bg-white/20 tw:!text-primary-foreground';\n\nconst keyRange = (count: number) => (count > 1 ? `1–${count}` : '1');\n\n/** An option's key, or a blank slot past the ninth; a picked option's turns into a check. */\nconst OptionKey = ({ digit, checked }: { digit: number | null; checked: boolean }) =>\n digit === null && !checked ? (\n <span aria-hidden className=\"tw:w-5 tw:shrink-0\" />\n ) : (\n <Kbd\n aria-hidden\n className={cn('tw:-my-0.5', checked && 'tw:!bg-primary tw:!text-primary-foreground')}\n data-testid=\"question-option-digit\"\n >\n {checked ? (\n <Check className=\"tw:size-3 tw:animate-in tw:fade-in tw:zoom-in-50 tw:duration-150\" />\n ) : (\n digit\n )}\n </Kbd>\n );\n\nconst handleKeyDown = (callback: () => void) => (e: KeyboardEvent) => {\n if (hasCommandModifier(e) || e.repeat) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n callback();\n }\n};\n\nexport const Question = ({\n question,\n header,\n options,\n multiSelect = true,\n selectedOptionIds = [],\n onSelectionChange,\n customAnswer = '',\n onCustomAnswerChange,\n onCustomAnswerConfirm,\n showCustomAnswer = true,\n customAnswerPlaceholder = 'Type your answer…',\n showSkip = true,\n onSkip,\n onClose,\n onNext,\n submitTooltip,\n onPrevious,\n currentStep,\n totalSteps,\n renderPreview,\n autoFocus = false,\n enableShortcuts = false,\n className,\n}: Props) => {\n const [isCustomExpanded, setIsCustomExpanded] = useState(false);\n const [activeRow, setActiveRow] = useState(0);\n const [pendingId, setPendingId] = useState<string | null>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n const rowsRef = useRef<(HTMLDivElement | null)[]>([]);\n const customInputRef = useRef<HTMLInputElement>(null);\n const isCustomSelected = isCustomExpanded || customAnswer.length > 0;\n const hasSteps = currentStep != null && totalSteps != null;\n // A one-question card has nothing to step through: \"1 of 1\" over a full bar, with both\n // chevrons dead, describes a journey that does not exist. `hasSteps` still stands — it is what\n // makes this the last step, and so what makes the action read Submit rather than Next.\n const showStepControls = hasSteps && totalSteps > 1;\n const showSkipButton = showSkip && onSkip != null;\n // Single-select: the option a key picked, else the one already chosen.\n const chosenId = multiSelect ? null : (pendingId ?? selectedOptionIds[0] ?? null);\n const showSubmitButton = multiSelect || isCustomSelected || chosenId !== null;\n // Every slot in the footer is conditional, so the row itself has to be: a bordered strip with\n // nothing in it reads as a control that failed to render.\n const showFooter = showStepControls || showSkipButton || showSubmitButton;\n const progressValue = hasSteps ? (currentStep / totalSteps) * 100 : 0;\n const isFirstStep = currentStep === 1;\n const isLastStep = hasSteps && currentStep === totalSteps;\n const numberedCount = Math.min(options.length, MAX_DIGIT_HOTKEY);\n const otherDigit =\n showCustomAnswer && options.length < MAX_DIGIT_HOTKEY ? options.length + 1 : null;\n const rowCount = options.length + (showCustomAnswer ? 1 : 0);\n const tabbableRow = activeRow < rowCount ? activeRow : 0;\n\n const handleOptionToggle = (optionId: string) => {\n if (multiSelect) {\n const isSelected = selectedOptionIds.includes(optionId);\n const nextIds = isSelected\n ? selectedOptionIds.filter((id) => id !== optionId)\n : [...selectedOptionIds, optionId];\n onSelectionChange?.(nextIds);\n } else {\n // Single-select: picking a real option deselects \"Other\" and drops any\n // typed custom answer so it can't leak into the submitted answer.\n setIsCustomExpanded(false);\n setPendingId(null);\n onCustomAnswerChange?.('');\n onSelectionChange?.([optionId]);\n }\n };\n\n // A key press picks without sending: multi-select toggles, single-select waits for ⌘/Ctrl+Enter.\n const handleOptionKey = (optionId: string) => {\n if (multiSelect) {\n handleOptionToggle(optionId);\n } else {\n setIsCustomExpanded(false);\n onCustomAnswerChange?.('');\n setPendingId(optionId);\n }\n };\n\n useAltDigitHotkey({\n count: numberedCount,\n onDigit: (index) => handleOptionKey(options[index]!.id),\n enabled: enableShortcuts,\n ref: rootRef,\n });\n\n useEffect(() => {\n if (!autoFocus || isFieldWithText(document.activeElement)) return;\n rootRef.current?.focus({ preventScroll: true });\n }, [autoFocus]);\n\n const focusRow = (index: number) => {\n setActiveRow(index);\n rowsRef.current[index]?.focus();\n };\n\n /**\n * The card's own keys, never fired from a text field inside it; a held key acts once.\n *\n * 1. ↑ / ↓ move focus; a digit picks or toggles; Enter on a row selects or toggles it.\n * 2. ⌘/Ctrl+Enter sends: the selected option (single-select) or the next step; Space skips.\n * 3. Any other character starts a custom answer: focus moves to \"Other\", which receives it.\n * 4. A key the card takes stops here, so page shortcuts (`a`, `/`) never see it.\n */\n const handleCardKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey) && !e.altKey && !e.repeat) {\n if (!showSubmitButton) return;\n send();\n // Stops here, so the page's own ⌘/Ctrl+Enter does not send a second time.\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n\n if (e.key === 'ArrowUp' && e.target === customInputRef.current && !hasCommandModifier(e)) {\n e.preventDefault();\n focusRow(options.length);\n return;\n }\n\n if (e.defaultPrevented || hasCommandModifier(e) || isEditableTarget(e.target)) return;\n\n if ((e.key === 'ArrowDown' || e.key === 'ArrowUp') && rowCount > 0) {\n e.preventDefault();\n const delta = e.key === 'ArrowDown' ? 1 : -1;\n const target = e.target;\n const current = rowsRef.current.findIndex(\n (row) => target instanceof Node && !!row?.contains(target),\n );\n const from = current === -1 ? (delta > 0 ? -1 : rowCount) : current;\n focusRow((from + delta + rowCount) % rowCount);\n return;\n }\n\n if (e.repeat) return;\n\n const digit = digitFromKeyCode(e.code);\n if (digit !== null && digit === otherDigit) {\n e.preventDefault();\n e.stopPropagation();\n customInputRef.current?.focus();\n return;\n }\n\n if (digit !== null && digit <= numberedCount) {\n e.preventDefault();\n e.stopPropagation();\n handleOptionKey(options[digit - 1]!.id);\n return;\n }\n\n if (e.key === ' ' && e.target === e.currentTarget) {\n e.preventDefault();\n e.stopPropagation();\n if (showSkipButton) onSkip?.();\n return;\n }\n\n if (showCustomAnswer && digit === null && e.key.length === 1 && e.key !== ' ') {\n e.stopPropagation();\n customInputRef.current?.focus();\n return;\n }\n };\n\n // The single-select option chosen with Enter is sent here; otherwise the step goes on.\n const send = () => {\n if (!multiSelect && !isCustomSelected && chosenId) handleOptionToggle(chosenId);\n else onNext?.();\n };\n\n // The › chevron: a key-picked option not yet sent goes out instead of being dropped.\n const handleNextStep = () => {\n if (!multiSelect && pendingId) handleOptionToggle(pendingId);\n else onNext?.();\n };\n\n const handleCustomToggle = (checked: boolean) => {\n setIsCustomExpanded(checked);\n if (checked) {\n // Single-select: \"Other\" and a real option are mutually exclusive.\n if (!multiSelect) {\n onSelectionChange?.([]);\n }\n } else {\n onCustomAnswerChange?.('');\n }\n };\n\n // Typing into (or focusing) the custom input selects \"Other\" directly — no\n // need to click the row/checkbox first.\n const handleCustomFocus = () => {\n setIsCustomExpanded(true);\n setPendingId(null);\n if (!multiSelect) {\n onSelectionChange?.([]);\n }\n };\n\n const handleCustomRowClick = () => {\n // Multi-select: the row toggles the checkbox. Single-select: clicking only\n // selects (never deselects, so a second click can't wipe typed text) —\n // switch away by picking a real option instead.\n if (multiSelect) {\n handleCustomToggle(!isCustomSelected);\n } else {\n handleCustomFocus();\n }\n };\n\n // From the keyboard, opening \"Other\" also moves focus into its text box.\n const handleCustomRowKey = () => {\n const opens = !multiSelect || !isCustomSelected;\n handleCustomRowClick();\n if (opens) customInputRef.current?.focus();\n };\n\n const submitButton = (\n <Button variant=\"primary\" size=\"small\" onClick={send} data-testid=\"question-next-button\">\n {isLastStep ? 'Submit' : 'Next'}\n <Kbd aria-hidden casing=\"as-written\" className={SEND_KEY_CLASS}>\n {`${keys.mod.symbol} Enter`}\n </Kbd>\n </Button>\n );\n\n return (\n <div\n ref={rootRef}\n role=\"group\"\n aria-label={question}\n tabIndex={-1}\n onKeyDown={handleCardKeyDown}\n className={cn(\n 'tw:flex tw:max-w-[800px] tw:flex-col tw:gap-4 tw:overflow-hidden tw:rounded-xl tw:border tw:border-solid tw:border-border tw:bg-card tw:text-card-foreground tw:shadow-lg tw:outline-none',\n className,\n )}\n data-testid=\"question-root\"\n data-question-step={currentStep}\n data-question-total-steps={totalSteps}\n data-question-multi-select={multiSelect}\n >\n <div className=\"tw:flex tw:items-start tw:gap-2 tw:pl-4 tw:pr-2 tw:pt-4\">\n <div className=\"tw:flex tw:min-w-0 tw:flex-1 tw:flex-col tw:gap-1\">\n <p className=\"tw:m-0 tw:text-base tw:font-semibold tw:leading-6\">{question}</p>\n {header && (\n <p className=\"tw:m-0 tw:text-xs tw:leading-4 tw:text-muted-foreground\">{header}</p>\n )}\n </div>\n {onClose && (\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n aria-label=\"Close\"\n onClick={onClose}\n data-testid=\"question-close-button\"\n >\n <X className=\"tw:size-4\" />\n </Button>\n )}\n </div>\n\n <div className=\"tw:px-4\">\n <div className=\"tw:flex tw:flex-col tw:gap-4 tw:border-0 tw:border-l tw:border-solid tw:border-primary tw:px-4 tw:py-2\">\n {options.map((option, index) => {\n const digit = index < numberedCount ? index + 1 : null;\n const isSelected = selectedOptionIds.includes(option.id);\n return (\n <div\n key={option.id}\n ref={(row) => {\n rowsRef.current[index] = row;\n }}\n className=\"tw:-mx-2 tw:-my-1.5 tw:flex tw:cursor-pointer tw:items-start tw:gap-2 tw:rounded-md tw:px-2 tw:py-1.5 tw:outline-none tw:hover:bg-hover tw:focus-visible:ring-2 tw:focus-visible:ring-ring\"\n onClick={() => handleOptionToggle(option.id)}\n onKeyDown={(e) => {\n if (hasCommandModifier(e) || e.repeat) return;\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n handleOptionKey(option.id);\n }\n }}\n onFocus={() => setActiveRow(index)}\n role=\"button\"\n aria-pressed={multiSelect ? isSelected : chosenId === option.id}\n tabIndex={index === tabbableRow ? 0 : -1}\n aria-keyshortcuts={\n digit === null\n ? undefined\n : [String(digit), enableShortcuts && `Alt+${digit}`].filter(Boolean).join(' ')\n }\n data-question-option\n data-testid={`question-option-${option.id}`}\n >\n <OptionKey\n digit={digit}\n checked={multiSelect ? isSelected : chosenId === option.id}\n />\n <div className=\"tw:flex tw:min-w-0 tw:flex-1 tw:items-start tw:gap-3\">\n <div className=\"tw:flex tw:flex-col tw:gap-1.5\">\n <span className=\"tw:text-sm tw:font-medium tw:leading-none\">\n {option.label}\n </span>\n {option.description && (\n <span className=\"tw:text-sm tw:font-normal tw:leading-5 tw:text-muted-foreground\">\n {option.description}\n </span>\n )}\n </div>\n {option.preview && (\n <div\n data-testid=\"question-option-preview\"\n className={cn(\n 'tw:ml-auto tw:flex tw:max-h-40 tw:min-w-0 tw:max-w-[50%] tw:flex-col tw:overflow-hidden tw:rounded-md',\n !renderPreview &&\n 'tw:overflow-auto tw:border tw:border-solid tw:border-border tw:bg-muted tw:p-2 tw:text-foreground',\n )}\n >\n {renderPreview ? (\n renderPreview(option.preview)\n ) : (\n // `text-foreground` restates the ink the box above already\n // sets, and is not redundant: consuming apps ship a global\n // `pre { color; background-color; border }` rule that beats\n // inheritance but loses to a utility — the same reason\n // `border-0` and `bg-transparent` are spelled out here.\n <pre className=\"tw:m-0 tw:overflow-visible tw:border-0 tw:bg-transparent tw:p-0 tw:font-mono tw:text-xs tw:leading-5 tw:text-foreground\">\n {option.preview}\n </pre>\n )}\n </div>\n )}\n </div>\n </div>\n );\n })}\n\n {showCustomAnswer && (\n <div className=\"tw:flex tw:flex-col tw:gap-2\">\n <div\n ref={(row) => {\n rowsRef.current[options.length] = row;\n }}\n className=\"tw:-mx-2 tw:-my-1.5 tw:flex tw:cursor-pointer tw:items-start tw:gap-2 tw:rounded-md tw:px-2 tw:py-1.5 tw:outline-none tw:hover:bg-hover tw:focus-visible:ring-2 tw:focus-visible:ring-ring\"\n onClick={handleCustomRowClick}\n onKeyDown={handleKeyDown(handleCustomRowKey)}\n onFocus={() => setActiveRow(options.length)}\n role=\"button\"\n aria-pressed={isCustomSelected}\n aria-keyshortcuts={otherDigit === null ? undefined : String(otherDigit)}\n tabIndex={options.length === tabbableRow ? 0 : -1}\n >\n <OptionKey digit={otherDigit} checked={isCustomSelected} />\n <span\n className={cn(\n 'tw:flex-1 tw:text-sm tw:font-medium tw:leading-none',\n !multiSelect && isCustomSelected && 'tw:text-primary',\n )}\n >\n Other\n </span>\n </div>\n {/* Always rendered and editable: typing or focusing selects \"Other\"\n directly, and keeping it mounted avoids layout shift. */}\n <TextInput\n ref={customInputRef}\n value={customAnswer}\n onValueChange={(value) => onCustomAnswerChange?.(value)}\n onFocus={handleCustomFocus}\n onKeyDown={\n onCustomAnswerConfirm\n ? (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter' && !e.shiftKey && !(e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n onCustomAnswerConfirm();\n }\n }\n : undefined\n }\n placeholder={customAnswerPlaceholder}\n sizing=\"small\"\n testId=\"question-custom\"\n />\n </div>\n )}\n </div>\n </div>\n\n {numberedCount > 0 && (\n <div\n aria-hidden\n className=\"tw:-mt-1 tw:flex tw:flex-wrap tw:items-center tw:gap-x-3 tw:gap-y-1 tw:px-4 tw:text-xs tw:text-muted-foreground\"\n data-testid=\"question-keyboard-hint\"\n >\n <span className=\"tw:inline-flex tw:items-center tw:gap-1\">\n <Kbd casing=\"as-written\">{keyRange(numberedCount + (otherDigit === null ? 0 : 1))}</Kbd>\n {multiSelect ? 'toggle' : 'choose'}\n </span>\n {rowCount > 1 && (\n <span className=\"tw:inline-flex tw:items-center tw:gap-1\">\n <Kbd>\n <ArrowUp className=\"tw:size-3\" />\n <ArrowDown className=\"tw:size-3\" />\n </Kbd>\n move\n </span>\n )}\n <span className=\"tw:inline-flex tw:items-center tw:gap-1\">\n <Kbd casing=\"as-written\">Enter</Kbd>\n {multiSelect ? 'toggle' : 'select'}\n </span>\n </div>\n )}\n\n <div className=\"tw:flex tw:flex-col\">\n {showStepControls && (\n <Progress size=\"sm\" value={progressValue} className=\"tw:rounded-none\" />\n )}\n\n {showFooter && (\n <div\n className={cn(\n 'tw:flex tw:items-center tw:justify-end tw:gap-4 tw:px-4 tw:py-3',\n !showStepControls && 'tw:border-0 tw:border-t tw:border-solid tw:border-border',\n )}\n >\n {showStepControls && (\n <div className=\"tw:flex tw:items-center tw:gap-2\">\n <button\n type=\"button\"\n disabled={isFirstStep}\n className=\"tw:flex tw:cursor-pointer tw:items-center tw:justify-center tw:bg-transparent tw:p-0 tw:disabled:cursor-default tailwindcss-preflight\"\n onClick={onPrevious}\n aria-label=\"Previous step\"\n >\n <ChevronLeft\n className={cn(\n 'tw:size-5',\n isFirstStep ? 'tw:text-primary/25' : 'tw:text-primary',\n )}\n />\n </button>\n <span className=\"tw:text-xs tw:leading-4 tw:text-muted-foreground\">\n {currentStep} of {totalSteps}\n </span>\n <button\n type=\"button\"\n disabled={currentStep === totalSteps}\n className=\"tw:flex tw:cursor-pointer tw:items-center tw:justify-center tw:bg-transparent tw:p-0 tw:disabled:cursor-default tailwindcss-preflight\"\n onClick={handleNextStep}\n aria-label=\"Next step\"\n >\n <ChevronRight\n className={cn(\n 'tw:size-5',\n currentStep === totalSteps ? 'tw:text-primary/25' : 'tw:text-primary',\n )}\n />\n </button>\n </div>\n )}\n {showSkipButton && (\n <Tooltip\n tooltip={\n <Kbd variant=\"primary\" casing=\"as-written\">\n Space\n </Kbd>\n }\n placement=\"top\"\n triggerAsChild\n >\n <Button\n variant=\"outline\"\n size=\"small\"\n onClick={onSkip}\n aria-keyshortcuts=\"Space\"\n data-testid=\"question-skip-button\"\n >\n Skip\n </Button>\n </Tooltip>\n )}\n {showSubmitButton &&\n (submitTooltip ? (\n <Tooltip tooltip={submitTooltip} placement=\"top\" triggerAsChild>\n {submitButton}\n </Tooltip>\n ) : (\n submitButton\n ))}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport type { QuestionOption, Props as QuestionProps };\n","import { type ReactNode, useState } from 'react';\n\nimport type { QuestionOption } from './Question';\nimport { Question } from './Question';\n\ntype QuestionStep = {\n question: string;\n header?: string;\n options: readonly QuestionOption[];\n multiSelect?: boolean;\n showCustomAnswer?: boolean;\n customAnswerPlaceholder?: string;\n};\n\ntype QuestionAnswers = {\n selections: Record<number, readonly string[]>;\n customAnswers: Record<number, string>;\n};\n\ntype Props = {\n steps: readonly [QuestionStep, ...QuestionStep[]];\n showSkip?: boolean;\n onSubmit?: (answers: QuestionAnswers) => void;\n onClose?: () => void;\n renderPreview?: (content: string) => ReactNode;\n className?: string;\n};\n\nexport const QuestionBlock = ({\n steps,\n showSkip = true,\n onSubmit,\n onClose,\n renderPreview,\n className,\n}: Props) => {\n const [currentStep, setCurrentStep] = useState(1);\n const [selections, setSelections] = useState<Record<number, readonly string[]>>({});\n const [customAnswers, setCustomAnswers] = useState<Record<number, string>>({});\n const stepData = steps[currentStep - 1]!;\n const isLastStep = currentStep === steps.length;\n\n const advance = (updatedSelections?: Record<number, readonly string[]>) => {\n const finalSelections = updatedSelections ?? selections;\n if (isLastStep) {\n onSubmit?.({ selections: finalSelections, customAnswers });\n } else {\n setCurrentStep((s) => Math.min(s + 1, steps.length));\n }\n };\n\n const handleSelectionChange = (ids: readonly string[]) => {\n const updated = { ...selections, [currentStep]: ids };\n setSelections(updated);\n if (!stepData.multiSelect) {\n advance(updated);\n }\n };\n\n return (\n <Question\n key={currentStep}\n {...stepData}\n selectedOptionIds={selections[currentStep] ?? []}\n onSelectionChange={handleSelectionChange}\n customAnswer={customAnswers[currentStep] ?? ''}\n onCustomAnswerChange={(value) =>\n setCustomAnswers((prev) => ({ ...prev, [currentStep]: value }))\n }\n currentStep={currentStep}\n totalSteps={steps.length}\n showSkip={showSkip && !isLastStep}\n onNext={() => advance()}\n onPrevious={() => setCurrentStep((s) => Math.max(s - 1, 1))}\n onSkip={() => setCurrentStep((s) => Math.min(s + 1, steps.length))}\n onClose={onClose}\n renderPreview={renderPreview}\n className={className}\n />\n );\n};\n\nexport type { QuestionStep, QuestionAnswers, Props as QuestionBlockProps };\n","import type { ReactNode } from 'react';\n\nimport { Sparkles } from '../../icons';\nimport { cn } from '../../utils';\n\ntype Props = {\n label: string;\n disabled?: boolean;\n onClick: () => void;\n icon?: ReactNode;\n /** `bubble`: shaped like a chat message and outlined — a reply waiting to be sent. */\n variant?: 'row' | 'bubble';\n className?: string;\n};\n\nexport const SuggestedPrompt = ({\n label,\n disabled,\n onClick,\n icon,\n variant = 'row',\n className,\n}: Props) => {\n const isBubble = variant === 'bubble';\n return (\n <button\n type=\"button\"\n disabled={disabled}\n data-variant={variant}\n className={cn(\n 'tailwindcss-preflight tw:flex tw:items-center tw:justify-start tw:gap-2.5 tw:whitespace-nowrap',\n 'tw:text-left tw:text-sm tw:text-foreground tw:transition-colors',\n 'tw:focus-visible:outline-none tw:focus-visible:ring-2 tw:focus-visible:ring-ring tw:focus-visible:ring-offset-1',\n 'tw:disabled:cursor-not-allowed tw:disabled:opacity-disabled',\n isBubble\n ? [\n // The user bubble's shape, outlined on the card fill; hover and focus fill it in.\n 'tw:w-fit tw:max-w-[min(85%,40rem)] tw:rounded-xl tw:px-3 tw:py-2',\n 'tw:border tw:border-solid tw:border-border tw:bg-card',\n 'tw:not-disabled:hover:bg-hover tw:focus-visible:bg-hover',\n ]\n : 'tw:rounded-lg tw:px-3 tw:py-2 tw:font-medium tw:not-disabled:hover:bg-hover',\n className,\n )}\n onClick={onClick}\n >\n {icon ?? (\n // Lucide icons are stroke-based — paint the visible line with the AI\n // gradient (no fill, so the glyph keeps its outline silhouette instead\n // of becoming a solid block). The `*` selector catches every shape\n // element (path, circle, polyline, …) so multi-part icons don't lose\n // sub-shapes the way `path`-only selectors do.\n <Sparkles className=\"tw:size-4 tw:shrink-0 tw:basis-4 tw:[&_*]:stroke-aigradient-600\" />\n )}\n <div className=\"tw:whitespace-normal tw:text-left\">{label}</div>\n </button>\n );\n};\n","import { Loader2 } from '../../icons';\n\ntype ThinkingIndicatorProps = {\n label?: string;\n};\n\n/**\n * The agent's turn is in flight and has nothing to show yet.\n *\n * - Quiet chrome, matching the step rows it precedes (muted ink, no italic), so the hand-off\n * from \"Thinking...\" to the first step is seamless.\n * - `role=\"status\"` because a spinner is silence to a screen reader, and for much of a turn\n * this is all a transcript shows. The label is the announcement, so it is never decorative.\n * - The icon is hidden from the tree: it says the same thing as the label beside it.\n */\nexport const ThinkingIndicator = ({ label = 'Thinking...' }: ThinkingIndicatorProps) => {\n return (\n <div\n className=\"tw:flex tw:items-center tw:gap-1.5\"\n role=\"status\"\n data-testid=\"chat-thinking-indicator\"\n >\n <Loader2 aria-hidden className=\"tw:size-3.5 tw:animate-spin tw:text-muted-foreground\" />\n <span className=\"tw:text-xs tw:font-medium tw:text-muted-foreground\">{label}</span>\n </div>\n );\n};\n\nexport type { ThinkingIndicatorProps };\n","import { type ReactNode, useEffect } from 'react';\n\nimport { Badge } from '../../../components/Badge';\nimport { Button } from '../../../components/Button';\nimport { cn } from '../../../utils';\n\ntype ToolCallApprovalStatus = 'pending' | 'approved' | 'rejected' | 'expired';\n\ntype ToolCallApprovalProps = {\n /** The tool being called (e.g. `run_sql`). Rendered as a monospace tag. */\n toolName: string;\n /** Human-readable summary of what the tool will do. */\n title?: ReactNode;\n status: ToolCallApprovalStatus;\n onApprove?: () => void;\n onReject?: () => void;\n /** App-rendered detail — a diff, a `ToolCallChip`, a chart, arguments. */\n children?: ReactNode;\n /**\n * Replaces the default Approve/Reject buttons in the pending state. Use when\n * the call needs bespoke controls (e.g. an inline reason field).\n */\n actions?: ReactNode;\n isSubmitting?: boolean;\n /**\n * Opt into `Enter` = approve / `Escape` = reject while pending. Off by\n * default so the shortcuts never fire unexpectedly in a busy chat.\n */\n enableShortcuts?: boolean;\n approveLabel?: string;\n rejectLabel?: string;\n className?: string;\n};\n\nconst STATUS_BADGE: Record<\n ToolCallApprovalStatus,\n { label: string; color: 'blue' | 'green' | 'red' | 'gray' }\n> = {\n pending: { label: 'Needs approval', color: 'blue' },\n approved: { label: 'Approved', color: 'green' },\n rejected: { label: 'Rejected', color: 'red' },\n expired: { label: 'Expired', color: 'gray' },\n};\n\n/**\n * Per-tool-call approve/reject frame — the granular sibling of `PlanApproval`\n * (which approves a whole plan). Chrome + status + actions only: the app\n * renders the call detail as `children` and owns the SDK/permission wiring.\n */\nexport const ToolCallApproval = ({\n toolName,\n title,\n status,\n onApprove,\n onReject,\n children,\n actions,\n isSubmitting = false,\n enableShortcuts = false,\n approveLabel = 'Approve',\n rejectLabel = 'Reject',\n className,\n}: ToolCallApprovalProps) => {\n const isPending = status === 'pending';\n const hasCustomActions = actions != null;\n const showDefaultActions = isPending && !hasCustomActions && Boolean(onApprove || onReject);\n // Custom actions, like the defaults, only make sense while a decision is\n // still pending — never leave controls visible in a terminal state.\n const showActions = isPending && (showDefaultActions || hasCustomActions);\n const badge = STATUS_BADGE[status];\n\n useEffect(() => {\n if (!enableShortcuts || !isPending || isSubmitting) return;\n\n const isEditableTarget = (target: EventTarget | null) => {\n if (!(target instanceof HTMLElement)) return false;\n return (\n target.isContentEditable ||\n target.tagName === 'INPUT' ||\n target.tagName === 'TEXTAREA' ||\n target.tagName === 'SELECT'\n );\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n // Ignore key-repeat and keystrokes typed into a field.\n if (event.repeat || event.defaultPrevented || isEditableTarget(event.target)) return;\n\n if (\n event.key === 'Enter' &&\n !event.shiftKey &&\n !event.ctrlKey &&\n !event.metaKey &&\n onApprove\n ) {\n event.preventDefault();\n onApprove();\n } else if (event.key === 'Escape' && onReject) {\n event.preventDefault();\n onReject();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [enableShortcuts, isPending, isSubmitting, onApprove, onReject]);\n\n return (\n <section\n data-testid=\"tool-call-approval\"\n data-status={status}\n aria-label={typeof title === 'string' ? title : toolName}\n className={cn(\n 'tw:flex tw:w-full tw:max-w-[800px] tw:flex-col tw:gap-3 tw:overflow-hidden tw:rounded-xl tw:border tw:border-solid tw:border-border tw:bg-muted tw:p-4',\n className,\n )}\n >\n <div className=\"tw:flex tw:items-center tw:gap-2\">\n <Badge color={badge.color} variant=\"pill\" className=\"tw:normal-case tw:tracking-normal\">\n {badge.label}\n </Badge>\n <code className=\"tw:rounded tw:bg-background tw:px-1.5 tw:py-0.5 tw:font-mono tw:text-xs tw:text-foreground\">\n {toolName}\n </code>\n </div>\n\n {title != null && (\n <p className=\"tw:m-0 tw:text-sm tw:font-medium tw:text-foreground\">{title}</p>\n )}\n\n {children}\n\n {showActions && (\n <div className=\"tw:flex tw:items-center tw:justify-end tw:gap-2 tw:overflow-x-auto\">\n {actions ?? (\n <>\n {onReject && (\n <Button\n variant=\"outline\"\n size=\"small\"\n onClick={onReject}\n disabled={isSubmitting}\n className=\"tw:shrink-0 tw:whitespace-nowrap\"\n >\n {rejectLabel}\n </Button>\n )}\n {onApprove && (\n <Button\n variant=\"primary\"\n size=\"small\"\n onClick={onApprove}\n disabled={isSubmitting}\n className=\"tw:shrink-0 tw:whitespace-nowrap\"\n >\n {approveLabel}\n </Button>\n )}\n </>\n )}\n </div>\n )}\n </section>\n );\n};\n\nexport type { ToolCallApprovalStatus, ToolCallApprovalProps };\n","import type { MouseEventHandler, ReactNode } from 'react';\nimport { cva } from 'class-variance-authority';\n\nimport { CircleCheck, CircleX, Loader2 } from '../../../icons';\nimport { cn } from '../../../utils';\n\ntype ToolCallState = 'processing' | 'done' | 'error';\n\ntype ToolCallChipProps = {\n label: ReactNode;\n state: ToolCallState;\n /** Leading icon; defaults to a state glyph (spinner / check / x). */\n icon?: ReactNode;\n /** Trailing node (e.g. a chevron or count). */\n trailing?: ReactNode;\n /** When set, the chip renders as a button and fires this on click. */\n onClick?: MouseEventHandler<HTMLButtonElement>;\n className?: string;\n};\n\nconst chipClasses = cva(\n [\n 'tw:inline-flex tw:items-center tw:gap-1.5 tw:rounded-md tw:border tw:border-solid',\n 'tw:border-border tw:bg-muted tw:px-2 tw:py-1 tw:text-xs tw:text-foreground',\n ],\n {\n variants: {\n interactive: {\n true: 'tw:cursor-pointer tw:focus-visible:outline-hidden tw:focus-visible:ring-2 tw:focus-visible:ring-ring tw:not-disabled:hover:bg-hover',\n false: '',\n },\n },\n defaultVariants: { interactive: false },\n },\n);\n\nconst StateIcon = ({ state }: { state: ToolCallState }) => {\n if (state === 'processing') {\n return <Loader2 className=\"tw:size-3.5 tw:shrink-0 tw:animate-spin tw:text-muted-foreground\" />;\n }\n if (state === 'error') {\n return <CircleX className=\"tw:size-3.5 tw:shrink-0 tw:text-error-500\" />;\n }\n return <CircleCheck className=\"tw:size-3.5 tw:shrink-0 tw:text-primary\" />;\n};\n\n/**\n * Presentational chip summarising a single tool call (icon + label + optional\n * trailing action). It has **no** URL/router knowledge — wrap it in a `Link`\n * or pass `onClick` for navigation; the app owns deep-linking.\n */\nexport const ToolCallChip = ({\n label,\n state,\n icon,\n trailing,\n onClick,\n className,\n}: ToolCallChipProps) => {\n const content = (\n <>\n {icon ?? <StateIcon state={state} />}\n <span className=\"tw:min-w-0 tw:truncate\">{label}</span>\n {trailing != null && (\n <span className=\"tw:ml-auto tw:inline-flex tw:shrink-0 tw:items-center\">{trailing}</span>\n )}\n </>\n );\n\n if (onClick) {\n return (\n <button\n type=\"button\"\n data-testid=\"tool-call-chip\"\n data-state={state}\n onClick={onClick}\n className={cn('tailwindcss-preflight', chipClasses({ interactive: true }), className)}\n >\n {content}\n </button>\n );\n }\n\n return (\n <span\n data-testid=\"tool-call-chip\"\n data-state={state}\n className={cn(chipClasses({ interactive: false }), className)}\n >\n {content}\n </span>\n );\n};\n\nexport type { ToolCallChipProps, ToolCallState };\n","import type { ReactNode } from 'react';\nimport { cva } from 'class-variance-authority';\n\nimport type { LucideIcon } from '../../icons';\nimport { ChevronDown, TriangleAlert } from '../../icons';\nimport { cn } from '../../utils';\n\ntype ToolCallStatus = 'processing' | 'warning' | 'success' | 'error';\n\ntype Props = {\n icon: LucideIcon;\n iconSpin?: boolean;\n status: ToolCallStatus;\n text: ReactNode;\n needsConfirmation?: boolean;\n isCollapsible?: boolean;\n isCollapsed?: boolean;\n onToggleCollapse?: () => void;\n};\n\n// Neutral band for routine states; status is carried by icon and label tint.\n// Only warning and error, which need attention, get a soft background tint.\nconst headerVariants = cva(\n 'tw:flex tw:items-center tw:justify-between tw:gap-2 tw:px-2.5 tw:py-1.5',\n {\n variants: {\n // One boundary cue per state: tinted states end at their wash, untinted\n // ones get the hairline.\n status: {\n processing: 'tw:border-b tw:border-border/60',\n warning: 'tw:bg-warning/10',\n success: 'tw:border-b tw:border-border/60',\n error: 'tw:bg-destructive/10',\n },\n },\n defaultVariants: {\n status: 'success',\n },\n },\n);\n\nconst statusInk: Record<ToolCallStatus, string> = {\n processing: 'tw:text-muted-foreground',\n warning: 'tw:text-warning',\n success: 'tw:text-muted-foreground',\n error: 'tw:text-destructive',\n};\n\nconst statusIconInk: Record<ToolCallStatus, string> = {\n processing: 'tw:text-muted-foreground',\n warning: 'tw:text-warning',\n success: 'tw:text-success/70',\n error: 'tw:text-destructive',\n};\n\nexport const ToolCallStatusHeader = ({\n icon: IconComponent,\n iconSpin,\n status,\n text,\n needsConfirmation,\n isCollapsible,\n isCollapsed,\n onToggleCollapse,\n}: Props) => {\n return (\n <div\n role={isCollapsible ? 'button' : undefined}\n tabIndex={isCollapsible ? 0 : undefined}\n aria-expanded={isCollapsible ? !isCollapsed : undefined}\n data-status={status}\n className={cn(headerVariants({ status }), isCollapsible && 'tw:cursor-pointer')}\n onClick={isCollapsible ? onToggleCollapse : undefined}\n onKeyDown={\n isCollapsible\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onToggleCollapse?.();\n }\n }\n : undefined\n }\n >\n <div className=\"tw:flex tw:min-w-0 tw:flex-1 tw:items-center tw:gap-1.5\">\n <IconComponent\n className={cn(\n 'tw:size-3.5 tw:shrink-0',\n statusIconInk[status],\n iconSpin && 'tw:animate-spin',\n )}\n />\n {/* Awaiting confirmation, the label names the action being approved: full ink, so it\n reads at least as strongly as the content below it. */}\n <span\n data-testid=\"tool-status-text\"\n className={cn(\n 'tw:truncate tw:pr-0.5 tw:text-xs tw:font-medium',\n needsConfirmation ? 'tw:text-foreground' : statusInk[status],\n )}\n >\n {text}\n </span>\n </div>\n {(needsConfirmation || isCollapsible) && (\n <div className=\"tw:flex tw:shrink-0 tw:items-center tw:gap-2\">\n {needsConfirmation && (\n <div className=\"tw:flex tw:items-center tw:gap-1\">\n <span\n data-testid=\"tool-confirmation-required\"\n className=\"tw:text-xs tw:font-medium tw:text-warning\"\n >\n Confirmation required\n </span>\n <TriangleAlert className=\"tw:size-3.5 tw:text-warning\" />\n </div>\n )}\n {isCollapsible && (\n <ChevronDown\n className={cn(\n 'tw:size-3.5 tw:shrink-0 tw:text-muted-foreground',\n 'tw:transition-transform tw:duration-300 tw:ease-out tw:motion-reduce:transition-none',\n !isCollapsed && 'tw:rotate-180',\n )}\n />\n )}\n </div>\n )}\n </div>\n );\n};\n\nexport type { Props as ToolCallStatusHeaderProps, ToolCallStatus };\n","/**\n * Clamp a percentage to 0–100 and normalize non-finite input to 0.\n *\n * - `Progress`'s indicator is unclamped, so a value over 100 slides the bar off-screen.\n * - `NaN` normalizes to 0 — `Math.min`/`Math.max` propagate it, and it renders as no bar at all.\n */\nexport const clampPercentage = (value: number) =>\n Number.isFinite(value) ? Math.min(100, Math.max(0, value)) : 0;\n\n/**\n * A percentage as text — `72%`, `0.2%`, `99%`.\n *\n * - Whole numbers from 1% up; a decimal only below 1%, where rounding would read as `0%`.\n * - A non-zero share never prints as `0.0%` — it floors at `0.1%`.\n * - Never `100%` for a value under 100: the text would disagree with the at-limit state computed\n * from the raw value, exactly at the boundary everything else turns on.\n */\nexport const formatPercentage = (value: number) => {\n const oneDecimal = Math.round(value * 10) / 10;\n if (value > 0 && oneDecimal < 1) {\n return `${Math.max(0.1, oneDecimal).toFixed(1)}%`;\n }\n const rounded = Math.round(value);\n return `${value < 100 ? Math.min(rounded, 99) : rounded}%`;\n};\n","import type { ComponentProps, ReactNode } from 'react';\n\nimport { Progress } from '../../components/Progress';\nimport { cn } from '../../utils';\n\nimport { clampPercentage, formatPercentage } from './usageStatsHelpers';\n\ntype Props = Omit<ComponentProps<'span'>, 'children'> & {\n /** Share of the budget SPENT, 0–100; the bar fills with it, the figure shows what is LEFT. */\n value: number;\n label: ReactNode;\n /** Untoned by default: when to escalate is the host's product rule, not the bar's. */\n variant?: ComponentProps<typeof Progress>['variant'];\n};\n\n/**\n * One budget, as a labelled row over a bar.\n *\n * - `value` is clamped by `clampPercentage` — `Progress`'s indicator is unclamped.\n */\nexport const UsageBar = ({ value, label, variant, className, ...props }: Props) => (\n <span\n {...props}\n className={cn('tw:flex tw:flex-col tw:gap-1.5 tw:text-xs tw:text-muted-foreground', className)}\n >\n <span className=\"tw:flex tw:items-baseline tw:justify-between tw:gap-2\">\n <span>{label}</span>\n <span>{`${formatPercentage(Math.max(0, 100 - value))} left`}</span>\n </span>\n <Progress size=\"sm\" variant={variant} value={clampPercentage(value)} />\n </span>\n);\n","import { cn } from '../../utils';\n\nimport { clampPercentage } from './usageStatsHelpers';\n\ntype Props = {\n value: number;\n size?: number;\n strokeWidth?: number;\n className?: string;\n};\n\nexport const UsageStatsRing = ({ value, size = 16, strokeWidth = 2.5, className }: Props) => {\n const radius = Math.max(0, (size - strokeWidth) / 2 - 1);\n const circumference = 2 * Math.PI * radius;\n const offset = circumference * (1 - clampPercentage(value) / 100);\n\n return (\n <svg\n width={size}\n height={size}\n viewBox={`0 0 ${size} ${size}`}\n className={cn('tw:-rotate-90', className)}\n role=\"presentation\"\n >\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n strokeWidth={strokeWidth}\n // The unfilled remainder of the gauge: a muted mark, not a surface.\n className=\"tw:stroke-muted-foreground tw:opacity-50\"\n />\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={offset}\n className=\"tw:stroke-primary tw:transition-all\"\n />\n </svg>\n );\n};\n","import type { ComponentProps, ReactNode } from 'react';\n\nimport { HoverCard } from '../../components/HoverCard';\nimport { AlertCircle } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { clampPercentage } from './usageStatsHelpers';\nimport { UsageStatsRing } from './UsageStatsRing';\n\ntype Props = {\n value: number;\n /** `true`/`'error'` renders a red corner badge, `'warning'` an amber one. */\n alert?: boolean | 'warning' | 'error';\n children: ReactNode;\n className?: string;\n /** Accessible name for the trigger; defaults to a label carrying the value. */\n ariaLabel?: string;\n align?: ComponentProps<typeof HoverCard.Content>['align'];\n side?: ComponentProps<typeof HoverCard.Content>['side'];\n sideOffset?: ComponentProps<typeof HoverCard.Content>['sideOffset'];\n /** Hold the card open past a pointer leave, e.g. while a popover inside it is up. */\n open?: ComponentProps<typeof HoverCard>['open'];\n onOpenChange?: ComponentProps<typeof HoverCard>['onOpenChange'];\n};\n\nexport const UsageStats = ({\n value,\n alert = false,\n children,\n className,\n ariaLabel,\n align = 'end',\n side = 'top',\n sideOffset = 8,\n open,\n onOpenChange,\n}: Props) => {\n const hasAlert = Boolean(alert);\n const isWarning = alert === 'warning';\n const defaultLabel = `Usage: ${Math.round(clampPercentage(value))}%${hasAlert ? ' (usage alert)' : ''}`;\n return (\n <HoverCard open={open} onOpenChange={onOpenChange}>\n <HoverCard.Trigger asChild>\n <button\n type=\"button\"\n aria-label={ariaLabel ?? defaultLabel}\n // `shrink-0`: otherwise a `shrink-0` sibling (like `Button`) squashes the fixed ring.\n className={cn(\n 'tw:relative tw:inline-flex tw:size-8 tw:shrink-0 tw:items-center tw:justify-center',\n 'tw:cursor-pointer tw:rounded-full tw:border-0 tw:bg-transparent tw:p-0',\n 'tw:transition-colors tw:hover:bg-muted',\n 'tw:focus-visible:outline-hidden tw:focus-visible:ring-2 tw:focus-visible:ring-ring/50',\n className,\n )}\n >\n <UsageStatsRing value={value} />\n {hasAlert && (\n <AlertCircle\n data-testid=\"usage-stats-alert\"\n className={cn(\n 'tw:absolute tw:-right-0.5 tw:-top-0.5 tw:size-3',\n isWarning ? 'tw:text-warning-500' : 'tw:text-error-500',\n )}\n />\n )}\n </button>\n </HoverCard.Trigger>\n\n <HoverCard.Content align={align} side={side} sideOffset={sideOffset}>\n {children}\n </HoverCard.Content>\n </HoverCard>\n );\n};\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Alert-DuAGeYyM.js","names":[],"sources":["../src/components/Alert/AlertAction.tsx","../src/components/Alert/AlertCollapsibleIcon.tsx","../src/components/Alert/AlertDescription.tsx","../src/components/Alert/AlertIcon.tsx","../src/components/Alert/AlertRoot.tsx","../src/components/Alert/AlertTitle.tsx","../src/components/Alert/Alert.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'div'> & {\n asChild?: boolean;\n};\n\nexport const AlertAction = ({ ref, className, asChild = false, ...props }: Props) => {\n const Comp = asChild ? Slot : 'div';\n return (\n <Comp\n {...props}\n ref={ref}\n className={cn(\n 'tw:col-start-3',\n 'tw:row-start-1',\n 'tw:self-start',\n 'tw:flex',\n 'tw:gap-2',\n className,\n )}\n />\n );\n};\n","import { ChevronDown } from '../../icons';\nimport { cn } from '../../utils';\nimport { Tooltip } from '../Tooltip';\n\ntype Props = {\n open: boolean;\n};\n\nexport const AlertCollapsibleIcon = ({ open }: Props) => (\n <Tooltip placement=\"top\" tooltip={open ? 'Collapse alert' : 'Expand alert'} triggerAsChild>\n <ChevronDown\n className={cn(\n 'tw:mt-px',\n 'tw:size-5',\n 'tw:text-neutral-400',\n 'tw:group-data-[state=open]/alert:rotate-180',\n\n // Legacy tint uses fixed categorical hover scales; token tint uses themeable status colors.\n 'tw:group-data-[variant=info]/alert:group-data-[tint=legacy]/alert:group-hover:text-blue-600',\n 'tw:group-data-[variant=info]/alert:group-data-[tint=token]/alert:group-hover:text-info',\n 'tw:group-data-[variant=warning]/alert:group-data-[tint=legacy]/alert:group-hover:text-warning-600',\n 'tw:group-data-[variant=warning]/alert:group-data-[tint=token]/alert:group-hover:text-warning',\n 'tw:group-data-[variant=error]/alert:group-data-[tint=legacy]/alert:group-hover:text-error-600',\n 'tw:group-data-[variant=error]/alert:group-data-[tint=token]/alert:group-hover:text-destructive',\n 'tw:group-data-[variant=success]/alert:group-data-[tint=legacy]/alert:group-hover:text-green-600',\n 'tw:group-data-[variant=success]/alert:group-data-[tint=token]/alert:group-hover:text-success',\n )}\n />\n </Tooltip>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const AlertDescription = ({ ref, children, className, ...rest }: Props) => (\n <div\n {...rest}\n ref={ref}\n className={cn(\n 'tw:col-start-2',\n 'tw:group-has-[[data-slot=alert-title]]/alert:col-end-[-1]',\n\n // spacer before description when a title exists (pseudo-element so it animates with Collapsible)\n 'tw:group-has-[[data-slot=alert-title]]/alert:before:block',\n 'tw:group-has-[[data-slot=alert-title]]/alert:before:h-1',\n \"tw:group-has-[[data-slot=alert-title]]/alert:before:content-['']\",\n\n 'tw:wrap-anywhere',\n\n // Default size for nested Lucide icons; callers can override on the icon.\n \"tw:[&_svg.lucide:not([class*='tw:size-'])]:size-4\",\n 'tw:[&_svg]:shrink-0',\n\n className,\n )}\n >\n {children}\n </div>\n);\n","import type { ComponentProps, ReactNode } from 'react';\n\nimport { AlertTriangle, CircleCheck, Info } from '../../icons';\nimport { cn } from '../../utils';\n\nimport type { Variant } from './AlertRoot';\n\nconst VARIANT_ICONS: Record<Variant, ReactNode> = {\n info: <Info />,\n warning: <AlertTriangle />,\n error: <AlertTriangle />,\n success: <CircleCheck />,\n};\n\ntype Props = {\n variant: Variant;\n icon?: ReactNode;\n} & Omit<ComponentProps<'span'>, 'children'>;\n\nexport const AlertIcon = ({ variant, icon, className, ...rest }: Props) => (\n <span\n {...rest}\n data-slot=\"alert-icon\"\n className={cn(\n 'tw:inline-flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:self-start',\n 'tw:p-0.5',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-4',\n // Legacy tint uses fixed categorical icon scales; token tint uses themeable status colors.\n 'tw:group-data-[variant=info]/alert:group-data-[tint=legacy]/alert:text-blue-500',\n 'tw:group-data-[variant=info]/alert:group-data-[tint=token]/alert:text-info',\n 'tw:group-data-[variant=warning]/alert:group-data-[tint=legacy]/alert:text-warning-500',\n 'tw:group-data-[variant=warning]/alert:group-data-[tint=token]/alert:text-warning',\n 'tw:group-data-[variant=error]/alert:group-data-[tint=legacy]/alert:text-error-500',\n 'tw:group-data-[variant=error]/alert:group-data-[tint=token]/alert:text-destructive',\n 'tw:group-data-[variant=success]/alert:group-data-[tint=legacy]/alert:text-green-500',\n 'tw:group-data-[variant=success]/alert:group-data-[tint=token]/alert:text-success',\n className,\n )}\n >\n {icon ?? VARIANT_ICONS[variant]}\n </span>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\nimport { useArgoDesign } from '../ThemeProvider/context';\nimport { useThemeAttributes } from '../ThemeProvider/useThemeAttributes';\n\nexport type Variant = 'info' | 'warning' | 'error' | 'success';\n\ntype Props = {\n variant?: Variant;\n} & ComponentProps<'div'>;\n\nexport const AlertRoot = ({ ref, children, className, variant, ...rest }: Props) => {\n const renderArgo = useArgoDesign();\n const { scheme } = useThemeAttributes();\n const legacyTint = !renderArgo && scheme !== 'dark';\n return (\n <div\n {...rest}\n ref={ref}\n data-variant={variant}\n data-argo={renderArgo}\n data-tint={legacyTint ? 'legacy' : 'token'}\n className={cn(\n 'tw:group/alert',\n\n // layout\n 'tw:grid',\n 'tw:grid-cols-[0_1fr_auto]',\n 'tw:has-[[data-slot=alert-icon]]:grid-cols-[auto_1fr_auto]',\n 'tw:has-[[data-slot=alert-icon]]:gap-x-2',\n\n // fonts\n 'tw:text-sm',\n // Tint mode of the text.\n // - `legacy`: legacy design in the light scheme — fixed neutral text.\n // - `token`: everything else — the semantic foreground, legible on any brand and scheme.\n 'tw:data-[tint=legacy]:text-neutral-800',\n 'tw:data-[tint=token]:text-foreground',\n 'tw:text-left',\n\n 'tw:p-4',\n\n // border — legacy keeps a fixed radius; argo follows the brand radius token.\n 'tw:rounded',\n 'tw:data-[argo=true]:rounded-[var(--radius-lg,0.25rem)]',\n 'tw:border',\n 'tw:border-solid',\n\n // Tint mode of the background and border.\n // - `legacy`: legacy design in the light scheme — fixed pastel scales.\n // - `token`: everything else — status tokens (bg at 10%, border at 25%), so dark mode and\n // brand overrides stay legible.\n 'tw:data-[variant=info]:data-[tint=legacy]:bg-blue-100',\n 'tw:data-[variant=info]:data-[tint=legacy]:border-blue-200',\n 'tw:data-[variant=info]:data-[tint=token]:bg-info/10',\n 'tw:data-[variant=info]:data-[tint=token]:border-info/25',\n\n 'tw:data-[variant=warning]:data-[tint=legacy]:bg-warning-100',\n 'tw:data-[variant=warning]:data-[tint=legacy]:border-warning-300',\n 'tw:data-[variant=warning]:data-[tint=token]:bg-warning/10',\n 'tw:data-[variant=warning]:data-[tint=token]:border-warning/25',\n\n 'tw:data-[variant=error]:data-[tint=legacy]:bg-error-100',\n 'tw:data-[variant=error]:data-[tint=legacy]:border-error-200',\n 'tw:data-[variant=error]:data-[tint=token]:bg-destructive/10',\n 'tw:data-[variant=error]:data-[tint=token]:border-destructive/25',\n\n 'tw:data-[variant=success]:data-[tint=legacy]:bg-green-100',\n 'tw:data-[variant=success]:data-[tint=legacy]:border-green-200',\n 'tw:data-[variant=success]:data-[tint=token]:bg-success/10',\n 'tw:data-[variant=success]:data-[tint=token]:border-success/25',\n className,\n )}\n >\n {children}\n </div>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const AlertTitle = ({ ref, className, ...props }: Props) => (\n <div\n {...props}\n ref={ref}\n data-slot=\"alert-title\"\n className={cn(\n 'tw:group/alert-title',\n 'tw:flex',\n 'tw:col-start-2',\n 'tw:font-medium',\n 'tw:items-center',\n className,\n )}\n />\n);\n","import { useState } from 'react';\nimport type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '../../utils';\nimport { Collapsible } from '../Collapsible';\n\nimport { AlertAction } from './AlertAction';\nimport { AlertCollapsibleIcon } from './AlertCollapsibleIcon';\nimport { AlertDescription } from './AlertDescription';\nimport { AlertIcon } from './AlertIcon';\nimport { AlertRoot } from './AlertRoot';\nimport { AlertTitle } from './AlertTitle';\n\ntype CommonProps = {\n hideIcon?: boolean;\n icon?: ReactNode;\n} & Pick<ComponentProps<typeof Collapsible>, 'open' | 'onOpenChange' | 'defaultOpen'> &\n Omit<ComponentProps<typeof AlertRoot>, 'children'>;\n\ntype CollapsibleProps = {\n mode: 'collapsible';\n title: ReactNode;\n children: ReactNode;\n actions?: never;\n};\n\ntype DefaultProps = {\n mode?: 'default';\n title?: ReactNode;\n children?: ReactNode;\n actions?: ReactNode;\n};\n\n/** Discriminated by `mode`: `\"collapsible\"` requires `title` + `children` and takes no `actions`. */\ntype Props = CommonProps & (CollapsibleProps | DefaultProps);\n\n/**\n * Persistent inline banner for contextual messages tied to the page layout.\n *\n * **When to use:** in-page messages; `mode=\"collapsible\"` hides long error details.\n * **When NOT to use:** transient feedback (`toast()`), field errors (`FormGroup state=\"error\"`),\n * confirmations (`Popconfirm`).\n *\n * @see RECIPES.md#alert-with-action\n */\nexport const Alert = ({\n title,\n variant = 'info',\n children,\n hideIcon = false,\n icon,\n className,\n actions,\n mode = 'default',\n\n // collapsible props\n defaultOpen = true,\n open: openProp,\n onOpenChange: onOpenChangeProp,\n\n ...rest\n}: Props) => {\n const isControlled = openProp !== undefined;\n\n const [innerOpen, setInnerOpen] = useState(defaultOpen);\n const open = isControlled ? openProp : innerOpen;\n const handleOpenChange = (nextOpen: boolean) => {\n if (!isControlled) {\n setInnerOpen(nextOpen);\n }\n onOpenChangeProp?.(nextOpen);\n };\n\n const isCollapsible = mode === 'collapsible' && !!title && !!children && !actions;\n\n if (isCollapsible)\n return (\n <Collapsible open={open} onOpenChange={handleOpenChange} asChild>\n <AlertRoot {...rest} variant={variant} className={className}>\n <Collapsible.Trigger\n className={cn(\n 'tailwindcss-preflight',\n 'tw:group',\n 'tw:col-span-full',\n 'tw:grid',\n 'tw:grid-cols-subgrid',\n 'tw:rounded-sm',\n 'tw:focus-visible:outline',\n 'tw:focus-visible:outline-2',\n 'tw:focus-visible:outline-ring',\n )}\n >\n {!hideIcon && <AlertIcon variant={variant} icon={icon} />}\n <AlertTitle>{title}</AlertTitle>\n <AlertCollapsibleIcon open={open} />\n </Collapsible.Trigger>\n\n <Collapsible.Content asChild>\n <AlertDescription>{children}</AlertDescription>\n </Collapsible.Content>\n </AlertRoot>\n </Collapsible>\n );\n\n return (\n <AlertRoot {...rest} variant={variant} className={className}>\n {!hideIcon && <AlertIcon variant={variant} icon={icon} />}\n {title && <AlertTitle>{title}</AlertTitle>}\n {children && <AlertDescription>{children}</AlertDescription>}\n {actions && <AlertAction>{actions}</AlertAction>}\n </AlertRoot>\n );\n};\n"],"mappings":"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"}