@moldable-ai/ui 0.2.19 → 0.2.21

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 (464) hide show
  1. package/dist/catalog/catalog-coverage.d.ts +15 -0
  2. package/dist/catalog/catalog-coverage.d.ts.map +1 -0
  3. package/dist/catalog/catalog-coverage.js +44 -0
  4. package/dist/catalog/catalog-manifest.d.ts +6 -0
  5. package/dist/catalog/catalog-manifest.d.ts.map +1 -0
  6. package/dist/catalog/catalog-manifest.js +117 -0
  7. package/dist/catalog/catalog-types.d.ts +64 -0
  8. package/dist/catalog/catalog-types.d.ts.map +1 -0
  9. package/dist/catalog/catalog-types.js +20 -0
  10. package/dist/catalog/component-catalog.d.ts +14 -0
  11. package/dist/catalog/component-catalog.d.ts.map +1 -0
  12. package/dist/catalog/component-catalog.js +49 -0
  13. package/dist/catalog/core-catalog-exclusions.d.ts +8 -0
  14. package/dist/catalog/core-catalog-exclusions.d.ts.map +1 -0
  15. package/dist/catalog/core-catalog-exclusions.js +151 -0
  16. package/dist/catalog/core-catalog.d.ts +2 -0
  17. package/dist/catalog/core-catalog.d.ts.map +1 -0
  18. package/dist/catalog/core-catalog.js +19 -0
  19. package/dist/catalog/core-collection-stories.d.ts +3 -0
  20. package/dist/catalog/core-collection-stories.d.ts.map +1 -0
  21. package/dist/catalog/core-collection-stories.js +42 -0
  22. package/dist/catalog/core-control-stories.d.ts +3 -0
  23. package/dist/catalog/core-control-stories.d.ts.map +1 -0
  24. package/dist/catalog/core-control-stories.js +94 -0
  25. package/dist/catalog/core-feedback-stories.d.ts +3 -0
  26. package/dist/catalog/core-feedback-stories.d.ts.map +1 -0
  27. package/dist/catalog/core-feedback-stories.js +50 -0
  28. package/dist/catalog/core-foundation-stories.d.ts +3 -0
  29. package/dist/catalog/core-foundation-stories.d.ts.map +1 -0
  30. package/dist/catalog/core-foundation-stories.js +53 -0
  31. package/dist/catalog/core-navigation-stories.d.ts +3 -0
  32. package/dist/catalog/core-navigation-stories.d.ts.map +1 -0
  33. package/dist/catalog/core-navigation-stories.js +25 -0
  34. package/dist/catalog/core-overlay-stories.d.ts +3 -0
  35. package/dist/catalog/core-overlay-stories.d.ts.map +1 -0
  36. package/dist/catalog/core-overlay-stories.js +20 -0
  37. package/dist/catalog/index.d.ts +7 -0
  38. package/dist/catalog/index.d.ts.map +1 -0
  39. package/dist/catalog/index.js +6 -0
  40. package/dist/components/app-error-boundary.d.ts +1 -0
  41. package/dist/components/app-error-boundary.d.ts.map +1 -1
  42. package/dist/components/app-error-boundary.js +13 -0
  43. package/dist/components/chat/chat-image-lightbox.d.ts +9 -0
  44. package/dist/components/chat/chat-image-lightbox.d.ts.map +1 -0
  45. package/dist/components/chat/chat-image-lightbox.js +9 -0
  46. package/dist/components/chat/chat-message.d.ts +19 -1
  47. package/dist/components/chat/chat-message.d.ts.map +1 -1
  48. package/dist/components/chat/chat-message.js +66 -16
  49. package/dist/components/chat/chat-messages.d.ts +5 -2
  50. package/dist/components/chat/chat-messages.d.ts.map +1 -1
  51. package/dist/components/chat/chat-messages.js +61 -6
  52. package/dist/components/chat/chat-panel.d.ts +49 -6
  53. package/dist/components/chat/chat-panel.d.ts.map +1 -1
  54. package/dist/components/chat/chat-panel.js +196 -163
  55. package/dist/components/chat/conversation-history.d.ts +39 -5
  56. package/dist/components/chat/conversation-history.d.ts.map +1 -1
  57. package/dist/components/chat/conversation-history.js +192 -26
  58. package/dist/components/chat/index.d.ts +2 -2
  59. package/dist/components/chat/index.d.ts.map +1 -1
  60. package/dist/components/chat/index.js +1 -1
  61. package/dist/components/chat/tool-handlers.d.ts.map +1 -1
  62. package/dist/components/chat/tool-handlers.js +40 -2
  63. package/dist/components/chat/vertical-scroll-fade.d.ts +6 -0
  64. package/dist/components/chat/vertical-scroll-fade.d.ts.map +1 -0
  65. package/dist/components/chat/vertical-scroll-fade.js +12 -0
  66. package/dist/components/native-capabilities/bluetooth-panel-helpers.d.ts +9 -0
  67. package/dist/components/native-capabilities/bluetooth-panel-helpers.d.ts.map +1 -0
  68. package/dist/components/native-capabilities/bluetooth-panel-helpers.js +37 -0
  69. package/dist/components/native-capabilities/bluetooth-panel.d.ts +56 -0
  70. package/dist/components/native-capabilities/bluetooth-panel.d.ts.map +1 -0
  71. package/dist/components/native-capabilities/bluetooth-panel.js +470 -0
  72. package/dist/components/native-capabilities/camera-preview.d.ts +39 -0
  73. package/dist/components/native-capabilities/camera-preview.d.ts.map +1 -0
  74. package/dist/components/native-capabilities/camera-preview.js +228 -0
  75. package/dist/components/native-capabilities/capability-badge.d.ts +23 -0
  76. package/dist/components/native-capabilities/capability-badge.d.ts.map +1 -0
  77. package/dist/components/native-capabilities/capability-badge.js +39 -0
  78. package/dist/components/native-capabilities/capability-matrix.d.ts +14 -0
  79. package/dist/components/native-capabilities/capability-matrix.d.ts.map +1 -0
  80. package/dist/components/native-capabilities/capability-matrix.js +97 -0
  81. package/dist/components/native-capabilities/clipboard-button.d.ts +26 -0
  82. package/dist/components/native-capabilities/clipboard-button.d.ts.map +1 -0
  83. package/dist/components/native-capabilities/clipboard-button.js +99 -0
  84. package/dist/components/native-capabilities/device-io-controls.d.ts +4 -0
  85. package/dist/components/native-capabilities/device-io-controls.d.ts.map +1 -0
  86. package/dist/components/native-capabilities/device-io-controls.js +28 -0
  87. package/dist/components/native-capabilities/device-list.d.ts +20 -0
  88. package/dist/components/native-capabilities/device-list.d.ts.map +1 -0
  89. package/dist/components/native-capabilities/device-list.js +14 -0
  90. package/dist/components/native-capabilities/display-map.d.ts +23 -0
  91. package/dist/components/native-capabilities/display-map.d.ts.map +1 -0
  92. package/dist/components/native-capabilities/display-map.js +114 -0
  93. package/dist/components/native-capabilities/haptic-button.d.ts +26 -0
  94. package/dist/components/native-capabilities/haptic-button.d.ts.map +1 -0
  95. package/dist/components/native-capabilities/haptic-button.js +94 -0
  96. package/dist/components/native-capabilities/hid-panel.d.ts +40 -0
  97. package/dist/components/native-capabilities/hid-panel.d.ts.map +1 -0
  98. package/dist/components/native-capabilities/hid-panel.js +373 -0
  99. package/dist/components/native-capabilities/index.d.ts +27 -0
  100. package/dist/components/native-capabilities/index.d.ts.map +1 -0
  101. package/dist/components/native-capabilities/index.js +26 -0
  102. package/dist/components/native-capabilities/live-indicator.d.ts +15 -0
  103. package/dist/components/native-capabilities/live-indicator.d.ts.map +1 -0
  104. package/dist/components/native-capabilities/live-indicator.js +26 -0
  105. package/dist/components/native-capabilities/local-auth-button.d.ts +33 -0
  106. package/dist/components/native-capabilities/local-auth-button.d.ts.map +1 -0
  107. package/dist/components/native-capabilities/local-auth-button.js +115 -0
  108. package/dist/components/native-capabilities/location-panel.d.ts +29 -0
  109. package/dist/components/native-capabilities/location-panel.d.ts.map +1 -0
  110. package/dist/components/native-capabilities/location-panel.js +146 -0
  111. package/dist/components/native-capabilities/microphone-meter.d.ts +35 -0
  112. package/dist/components/native-capabilities/microphone-meter.d.ts.map +1 -0
  113. package/dist/components/native-capabilities/microphone-meter.js +244 -0
  114. package/dist/components/native-capabilities/midi-monitor.d.ts +54 -0
  115. package/dist/components/native-capabilities/midi-monitor.d.ts.map +1 -0
  116. package/dist/components/native-capabilities/midi-monitor.js +534 -0
  117. package/dist/components/native-capabilities/native-capability-panel.d.ts +11 -0
  118. package/dist/components/native-capabilities/native-capability-panel.d.ts.map +1 -0
  119. package/dist/components/native-capabilities/native-capability-panel.js +28 -0
  120. package/dist/components/native-capabilities/notification-panel.d.ts +24 -0
  121. package/dist/components/native-capabilities/notification-panel.d.ts.map +1 -0
  122. package/dist/components/native-capabilities/notification-panel.js +124 -0
  123. package/dist/components/native-capabilities/power-blocker-controller.d.ts +19 -0
  124. package/dist/components/native-capabilities/power-blocker-controller.d.ts.map +1 -0
  125. package/dist/components/native-capabilities/power-blocker-controller.js +83 -0
  126. package/dist/components/native-capabilities/power-panel.d.ts +67 -0
  127. package/dist/components/native-capabilities/power-panel.d.ts.map +1 -0
  128. package/dist/components/native-capabilities/power-panel.js +309 -0
  129. package/dist/components/native-capabilities/readout.d.ts +10 -0
  130. package/dist/components/native-capabilities/readout.d.ts.map +1 -0
  131. package/dist/components/native-capabilities/readout.js +11 -0
  132. package/dist/components/native-capabilities/screen-share-preview.d.ts +36 -0
  133. package/dist/components/native-capabilities/screen-share-preview.d.ts.map +1 -0
  134. package/dist/components/native-capabilities/screen-share-preview.js +191 -0
  135. package/dist/components/native-capabilities/secure-storage-panel.d.ts +36 -0
  136. package/dist/components/native-capabilities/secure-storage-panel.d.ts.map +1 -0
  137. package/dist/components/native-capabilities/secure-storage-panel.js +193 -0
  138. package/dist/components/native-capabilities/serial-console.d.ts +64 -0
  139. package/dist/components/native-capabilities/serial-console.d.ts.map +1 -0
  140. package/dist/components/native-capabilities/serial-console.js +399 -0
  141. package/dist/components/native-capabilities/shortcut-recorder.d.ts +35 -0
  142. package/dist/components/native-capabilities/shortcut-recorder.d.ts.map +1 -0
  143. package/dist/components/native-capabilities/shortcut-recorder.js +217 -0
  144. package/dist/components/native-capabilities/stream-log.d.ts +35 -0
  145. package/dist/components/native-capabilities/stream-log.d.ts.map +1 -0
  146. package/dist/components/native-capabilities/stream-log.js +65 -0
  147. package/dist/components/native-capabilities/system-audio-monitor.d.ts +34 -0
  148. package/dist/components/native-capabilities/system-audio-monitor.d.ts.map +1 -0
  149. package/dist/components/native-capabilities/system-audio-monitor.js +275 -0
  150. package/dist/components/native-capabilities/usb-panel.d.ts +54 -0
  151. package/dist/components/native-capabilities/usb-panel.d.ts.map +1 -0
  152. package/dist/components/native-capabilities/usb-panel.js +363 -0
  153. package/dist/components/native-capabilities/use-capability.d.ts +20 -0
  154. package/dist/components/native-capabilities/use-capability.d.ts.map +1 -0
  155. package/dist/components/native-capabilities/use-capability.js +61 -0
  156. package/dist/components/ui/alert-dialog.d.ts +7 -3
  157. package/dist/components/ui/alert-dialog.d.ts.map +1 -1
  158. package/dist/components/ui/alert-dialog.js +9 -5
  159. package/dist/components/ui/alert.d.ts +19 -3
  160. package/dist/components/ui/alert.d.ts.map +1 -1
  161. package/dist/components/ui/alert.js +25 -8
  162. package/dist/components/ui/app-frame.d.ts +28 -0
  163. package/dist/components/ui/app-frame.d.ts.map +1 -0
  164. package/dist/components/ui/app-frame.js +95 -0
  165. package/dist/components/ui/button-group.d.ts +1 -1
  166. package/dist/components/ui/button.js +1 -1
  167. package/dist/components/ui/collapsible.d.ts +9 -1
  168. package/dist/components/ui/collapsible.d.ts.map +1 -1
  169. package/dist/components/ui/collapsible.js +13 -2
  170. package/dist/components/ui/collection-navigation.d.ts +8 -0
  171. package/dist/components/ui/collection-navigation.d.ts.map +1 -0
  172. package/dist/components/ui/collection-navigation.js +19 -0
  173. package/dist/components/ui/color-well.d.ts +13 -0
  174. package/dist/components/ui/color-well.d.ts.map +1 -0
  175. package/dist/components/ui/color-well.js +30 -0
  176. package/dist/components/ui/command.d.ts +5 -1
  177. package/dist/components/ui/command.d.ts.map +1 -1
  178. package/dist/components/ui/command.js +13 -1
  179. package/dist/components/ui/confirm-dialog.d.ts +19 -0
  180. package/dist/components/ui/confirm-dialog.d.ts.map +1 -0
  181. package/dist/components/ui/confirm-dialog.js +45 -0
  182. package/dist/components/ui/date-field.d.ts +19 -0
  183. package/dist/components/ui/date-field.d.ts.map +1 -0
  184. package/dist/components/ui/date-field.js +54 -0
  185. package/dist/components/ui/date-picker.d.ts +24 -0
  186. package/dist/components/ui/date-picker.d.ts.map +1 -0
  187. package/dist/components/ui/date-picker.js +92 -0
  188. package/dist/components/ui/dialog.d.ts +4 -2
  189. package/dist/components/ui/dialog.d.ts.map +1 -1
  190. package/dist/components/ui/dialog.js +8 -5
  191. package/dist/components/ui/edge-fade.d.ts +11 -0
  192. package/dist/components/ui/edge-fade.d.ts.map +1 -0
  193. package/dist/components/ui/edge-fade.js +41 -0
  194. package/dist/components/ui/empty.d.ts +7 -2
  195. package/dist/components/ui/empty.d.ts.map +1 -1
  196. package/dist/components/ui/empty.js +20 -7
  197. package/dist/components/ui/field.d.ts +1 -1
  198. package/dist/components/ui/grid.d.ts +24 -0
  199. package/dist/components/ui/grid.d.ts.map +1 -0
  200. package/dist/components/ui/grid.js +258 -0
  201. package/dist/components/ui/icon-button.d.ts +15 -0
  202. package/dist/components/ui/icon-button.d.ts.map +1 -0
  203. package/dist/components/ui/icon-button.js +15 -0
  204. package/dist/components/ui/index.d.ts +23 -0
  205. package/dist/components/ui/index.d.ts.map +1 -1
  206. package/dist/components/ui/index.js +23 -0
  207. package/dist/components/ui/input-group.d.ts +1 -1
  208. package/dist/components/ui/inspector.d.ts +15 -0
  209. package/dist/components/ui/inspector.d.ts.map +1 -0
  210. package/dist/components/ui/inspector.js +26 -0
  211. package/dist/components/ui/kbd.d.ts +1 -1
  212. package/dist/components/ui/list.d.ts +28 -0
  213. package/dist/components/ui/list.d.ts.map +1 -0
  214. package/dist/components/ui/list.js +235 -0
  215. package/dist/components/ui/material.d.ts +34 -0
  216. package/dist/components/ui/material.d.ts.map +1 -0
  217. package/dist/components/ui/material.js +34 -0
  218. package/dist/components/ui/message-scroller-controller.d.ts +162 -0
  219. package/dist/components/ui/message-scroller-controller.d.ts.map +1 -0
  220. package/dist/components/ui/message-scroller-controller.js +888 -0
  221. package/dist/components/ui/message-scroller-layout-stability.d.ts +33 -0
  222. package/dist/components/ui/message-scroller-layout-stability.d.ts.map +1 -0
  223. package/dist/components/ui/message-scroller-layout-stability.js +153 -0
  224. package/dist/components/ui/message-scroller-policy.d.ts +74 -0
  225. package/dist/components/ui/message-scroller-policy.d.ts.map +1 -0
  226. package/dist/components/ui/message-scroller-policy.js +129 -0
  227. package/dist/components/ui/message-scroller-primitive.d.ts +55 -0
  228. package/dist/components/ui/message-scroller-primitive.d.ts.map +1 -0
  229. package/dist/components/ui/message-scroller-primitive.js +226 -0
  230. package/dist/components/ui/message-scroller.d.ts +11 -0
  231. package/dist/components/ui/message-scroller.d.ts.map +1 -0
  232. package/dist/components/ui/message-scroller.js +25 -0
  233. package/dist/components/ui/navigation-button-group.d.ts +16 -0
  234. package/dist/components/ui/navigation-button-group.d.ts.map +1 -0
  235. package/dist/components/ui/navigation-button-group.js +9 -0
  236. package/dist/components/ui/notification-dot.d.ts +4 -0
  237. package/dist/components/ui/notification-dot.d.ts.map +1 -0
  238. package/dist/components/ui/notification-dot.js +7 -0
  239. package/dist/components/ui/number-input.d.ts +16 -0
  240. package/dist/components/ui/number-input.d.ts.map +1 -0
  241. package/dist/components/ui/number-input.js +56 -0
  242. package/dist/components/ui/panel.d.ts +18 -0
  243. package/dist/components/ui/panel.d.ts.map +1 -0
  244. package/dist/components/ui/panel.js +40 -0
  245. package/dist/components/ui/popover.d.ts +9 -2
  246. package/dist/components/ui/popover.d.ts.map +1 -1
  247. package/dist/components/ui/popover.js +14 -4
  248. package/dist/components/ui/scroll-area.d.ts +8 -2
  249. package/dist/components/ui/scroll-area.d.ts.map +1 -1
  250. package/dist/components/ui/scroll-area.js +6 -3
  251. package/dist/components/ui/search-field.d.ts +19 -0
  252. package/dist/components/ui/search-field.d.ts.map +1 -0
  253. package/dist/components/ui/search-field.js +64 -0
  254. package/dist/components/ui/segmented-control.d.ts +21 -0
  255. package/dist/components/ui/segmented-control.d.ts.map +1 -0
  256. package/dist/components/ui/segmented-control.js +62 -0
  257. package/dist/components/ui/sheet.d.ts +4 -2
  258. package/dist/components/ui/sheet.d.ts.map +1 -1
  259. package/dist/components/ui/sheet.js +12 -9
  260. package/dist/components/ui/sidebar.js +1 -1
  261. package/dist/components/ui/sonner.d.ts +4 -3
  262. package/dist/components/ui/sonner.d.ts.map +1 -1
  263. package/dist/components/ui/sonner.js +7 -6
  264. package/dist/components/ui/split-view.d.ts +11 -0
  265. package/dist/components/ui/split-view.d.ts.map +1 -0
  266. package/dist/components/ui/split-view.js +13 -0
  267. package/dist/components/ui/status.d.ts +13 -0
  268. package/dist/components/ui/status.d.ts.map +1 -0
  269. package/dist/components/ui/status.js +36 -0
  270. package/dist/components/ui/table.d.ts +11 -2
  271. package/dist/components/ui/table.d.ts.map +1 -1
  272. package/dist/components/ui/table.js +33 -6
  273. package/dist/components/ui/text.d.ts +17 -0
  274. package/dist/components/ui/text.d.ts.map +1 -0
  275. package/dist/components/ui/text.js +55 -0
  276. package/dist/components/ui/toggle.d.ts +12 -4
  277. package/dist/components/ui/toggle.d.ts.map +1 -1
  278. package/dist/components/ui/toggle.js +13 -2
  279. package/dist/components/ui/toolbar.d.ts +27 -0
  280. package/dist/components/ui/toolbar.d.ts.map +1 -0
  281. package/dist/components/ui/toolbar.js +71 -0
  282. package/dist/components/ui/tooltip.d.ts +8 -3
  283. package/dist/components/ui/tooltip.d.ts.map +1 -1
  284. package/dist/components/ui/tooltip.js +11 -6
  285. package/dist/index.d.ts +2 -2
  286. package/dist/index.d.ts.map +1 -1
  287. package/dist/index.js +4 -4
  288. package/dist/lib/frame-lifecycle.d.ts +29 -0
  289. package/dist/lib/frame-lifecycle.d.ts.map +1 -1
  290. package/dist/lib/frame-lifecycle.js +85 -0
  291. package/dist/lib/native-capabilities/access.d.ts +13 -0
  292. package/dist/lib/native-capabilities/access.d.ts.map +1 -0
  293. package/dist/lib/native-capabilities/access.js +53 -0
  294. package/dist/lib/native-capabilities/bluetooth-access.d.ts +14 -0
  295. package/dist/lib/native-capabilities/bluetooth-access.d.ts.map +1 -0
  296. package/dist/lib/native-capabilities/bluetooth-access.js +43 -0
  297. package/dist/lib/native-capabilities/bluetooth-connection.d.ts +19 -0
  298. package/dist/lib/native-capabilities/bluetooth-connection.d.ts.map +1 -0
  299. package/dist/lib/native-capabilities/bluetooth-connection.js +88 -0
  300. package/dist/lib/native-capabilities/bluetooth-gatt.d.ts +7 -0
  301. package/dist/lib/native-capabilities/bluetooth-gatt.d.ts.map +1 -0
  302. package/dist/lib/native-capabilities/bluetooth-gatt.js +77 -0
  303. package/dist/lib/native-capabilities/bluetooth-internal.d.ts +10 -0
  304. package/dist/lib/native-capabilities/bluetooth-internal.d.ts.map +1 -0
  305. package/dist/lib/native-capabilities/bluetooth-internal.js +105 -0
  306. package/dist/lib/native-capabilities/bluetooth-native-fallback.d.ts +33 -0
  307. package/dist/lib/native-capabilities/bluetooth-native-fallback.d.ts.map +1 -0
  308. package/dist/lib/native-capabilities/bluetooth-native-fallback.js +214 -0
  309. package/dist/lib/native-capabilities/bluetooth-types.d.ts +85 -0
  310. package/dist/lib/native-capabilities/bluetooth-types.d.ts.map +1 -0
  311. package/dist/lib/native-capabilities/bluetooth-types.js +2 -0
  312. package/dist/lib/native-capabilities/bluetooth.d.ts +7 -0
  313. package/dist/lib/native-capabilities/bluetooth.d.ts.map +1 -0
  314. package/dist/lib/native-capabilities/bluetooth.js +4 -0
  315. package/dist/lib/native-capabilities/bridge.d.ts +23 -0
  316. package/dist/lib/native-capabilities/bridge.d.ts.map +1 -0
  317. package/dist/lib/native-capabilities/bridge.js +266 -0
  318. package/dist/lib/native-capabilities/capabilities.d.ts +7 -0
  319. package/dist/lib/native-capabilities/capabilities.d.ts.map +1 -0
  320. package/dist/lib/native-capabilities/capabilities.js +95 -0
  321. package/dist/lib/native-capabilities/clipboard.d.ts +11 -0
  322. package/dist/lib/native-capabilities/clipboard.d.ts.map +1 -0
  323. package/dist/lib/native-capabilities/clipboard.js +58 -0
  324. package/dist/lib/native-capabilities/device-io-errors.d.ts +11 -0
  325. package/dist/lib/native-capabilities/device-io-errors.d.ts.map +1 -0
  326. package/dist/lib/native-capabilities/device-io-errors.js +82 -0
  327. package/dist/lib/native-capabilities/displays.d.ts +38 -0
  328. package/dist/lib/native-capabilities/displays.d.ts.map +1 -0
  329. package/dist/lib/native-capabilities/displays.js +12 -0
  330. package/dist/lib/native-capabilities/global-shortcuts.d.ts +86 -0
  331. package/dist/lib/native-capabilities/global-shortcuts.d.ts.map +1 -0
  332. package/dist/lib/native-capabilities/global-shortcuts.js +351 -0
  333. package/dist/lib/native-capabilities/haptics.d.ts +25 -0
  334. package/dist/lib/native-capabilities/haptics.d.ts.map +1 -0
  335. package/dist/lib/native-capabilities/haptics.js +18 -0
  336. package/dist/lib/native-capabilities/hid-native.d.ts +26 -0
  337. package/dist/lib/native-capabilities/hid-native.d.ts.map +1 -0
  338. package/dist/lib/native-capabilities/hid-native.js +229 -0
  339. package/dist/lib/native-capabilities/hid.d.ts +52 -0
  340. package/dist/lib/native-capabilities/hid.d.ts.map +1 -0
  341. package/dist/lib/native-capabilities/hid.js +163 -0
  342. package/dist/lib/native-capabilities/index.d.ts +40 -0
  343. package/dist/lib/native-capabilities/index.d.ts.map +1 -0
  344. package/dist/lib/native-capabilities/index.js +21 -0
  345. package/dist/lib/native-capabilities/local-authentication.d.ts +32 -0
  346. package/dist/lib/native-capabilities/local-authentication.d.ts.map +1 -0
  347. package/dist/lib/native-capabilities/local-authentication.js +46 -0
  348. package/dist/lib/native-capabilities/location.d.ts +49 -0
  349. package/dist/lib/native-capabilities/location.d.ts.map +1 -0
  350. package/dist/lib/native-capabilities/location.js +114 -0
  351. package/dist/lib/native-capabilities/media-permissions.d.ts +28 -0
  352. package/dist/lib/native-capabilities/media-permissions.d.ts.map +1 -0
  353. package/dist/lib/native-capabilities/media-permissions.js +37 -0
  354. package/dist/lib/native-capabilities/media.d.ts +17 -0
  355. package/dist/lib/native-capabilities/media.d.ts.map +1 -0
  356. package/dist/lib/native-capabilities/media.js +104 -0
  357. package/dist/lib/native-capabilities/midi-access.d.ts +13 -0
  358. package/dist/lib/native-capabilities/midi-access.d.ts.map +1 -0
  359. package/dist/lib/native-capabilities/midi-access.js +68 -0
  360. package/dist/lib/native-capabilities/midi-internal.d.ts +12 -0
  361. package/dist/lib/native-capabilities/midi-internal.d.ts.map +1 -0
  362. package/dist/lib/native-capabilities/midi-internal.js +88 -0
  363. package/dist/lib/native-capabilities/midi-native-fallback.d.ts +27 -0
  364. package/dist/lib/native-capabilities/midi-native-fallback.d.ts.map +1 -0
  365. package/dist/lib/native-capabilities/midi-native-fallback.js +127 -0
  366. package/dist/lib/native-capabilities/midi-ports.d.ts +6 -0
  367. package/dist/lib/native-capabilities/midi-ports.d.ts.map +1 -0
  368. package/dist/lib/native-capabilities/midi-ports.js +115 -0
  369. package/dist/lib/native-capabilities/midi-types.d.ts +25 -0
  370. package/dist/lib/native-capabilities/midi-types.d.ts.map +1 -0
  371. package/dist/lib/native-capabilities/midi-types.js +1 -0
  372. package/dist/lib/native-capabilities/midi.d.ts +6 -0
  373. package/dist/lib/native-capabilities/midi.d.ts.map +1 -0
  374. package/dist/lib/native-capabilities/midi.js +3 -0
  375. package/dist/lib/native-capabilities/native-device-io.d.ts +28 -0
  376. package/dist/lib/native-capabilities/native-device-io.d.ts.map +1 -0
  377. package/dist/lib/native-capabilities/native-device-io.js +91 -0
  378. package/dist/lib/native-capabilities/native-device-lifecycle.d.ts +13 -0
  379. package/dist/lib/native-capabilities/native-device-lifecycle.d.ts.map +1 -0
  380. package/dist/lib/native-capabilities/native-device-lifecycle.js +40 -0
  381. package/dist/lib/native-capabilities/notifications.d.ts +38 -0
  382. package/dist/lib/native-capabilities/notifications.d.ts.map +1 -0
  383. package/dist/lib/native-capabilities/notifications.js +50 -0
  384. package/dist/lib/native-capabilities/power-session.d.ts +113 -0
  385. package/dist/lib/native-capabilities/power-session.d.ts.map +1 -0
  386. package/dist/lib/native-capabilities/power-session.js +264 -0
  387. package/dist/lib/native-capabilities/secure-storage.d.ts +36 -0
  388. package/dist/lib/native-capabilities/secure-storage.d.ts.map +1 -0
  389. package/dist/lib/native-capabilities/secure-storage.js +64 -0
  390. package/dist/lib/native-capabilities/serial-native.d.ts +23 -0
  391. package/dist/lib/native-capabilities/serial-native.d.ts.map +1 -0
  392. package/dist/lib/native-capabilities/serial-native.js +181 -0
  393. package/dist/lib/native-capabilities/serial.d.ts +76 -0
  394. package/dist/lib/native-capabilities/serial.d.ts.map +1 -0
  395. package/dist/lib/native-capabilities/serial.js +215 -0
  396. package/dist/lib/native-capabilities/system-audio.d.ts +127 -0
  397. package/dist/lib/native-capabilities/system-audio.d.ts.map +1 -0
  398. package/dist/lib/native-capabilities/system-audio.js +330 -0
  399. package/dist/lib/native-capabilities/types.d.ts +62 -0
  400. package/dist/lib/native-capabilities/types.d.ts.map +1 -0
  401. package/dist/lib/native-capabilities/types.js +27 -0
  402. package/dist/lib/native-capabilities/usb-native.d.ts +39 -0
  403. package/dist/lib/native-capabilities/usb-native.d.ts.map +1 -0
  404. package/dist/lib/native-capabilities/usb-native.js +217 -0
  405. package/dist/lib/native-capabilities/usb.d.ts +85 -0
  406. package/dist/lib/native-capabilities/usb.d.ts.map +1 -0
  407. package/dist/lib/native-capabilities/usb.js +225 -0
  408. package/dist/lib/theme.d.ts.map +1 -1
  409. package/dist/lib/theme.js +2 -1
  410. package/docs/README.md +39 -0
  411. package/docs/accessibility.md +32 -0
  412. package/docs/adaptive-materials.md +79 -0
  413. package/docs/app-anatomy.md +74 -0
  414. package/docs/component-catalog.md +82 -0
  415. package/docs/component-guide-template.md +37 -0
  416. package/docs/design-tokens.md +185 -0
  417. package/docs/foundations.md +58 -0
  418. package/docs/native-integration.md +33 -0
  419. package/docs/standalone-app-windows.md +136 -0
  420. package/package.json +8 -3
  421. package/src/components/ui/alert-dialog.md +31 -0
  422. package/src/components/ui/alert.md +77 -0
  423. package/src/components/ui/app-frame.md +38 -0
  424. package/src/components/ui/badge.md +57 -0
  425. package/src/components/ui/button.md +76 -0
  426. package/src/components/ui/collapsible.md +52 -0
  427. package/src/components/ui/color-well.md +11 -0
  428. package/src/components/ui/combobox.md +42 -0
  429. package/src/components/ui/command.md +54 -0
  430. package/src/components/ui/date-field.md +32 -0
  431. package/src/components/ui/date-picker.md +55 -0
  432. package/src/components/ui/dialog.md +40 -0
  433. package/src/components/ui/edge-fade.md +7 -0
  434. package/src/components/ui/empty.md +87 -0
  435. package/src/components/ui/field.md +77 -0
  436. package/src/components/ui/grid.md +109 -0
  437. package/src/components/ui/icon-button.md +36 -0
  438. package/src/components/ui/inspector.md +11 -0
  439. package/src/components/ui/item.md +87 -0
  440. package/src/components/ui/list.md +140 -0
  441. package/src/components/ui/material.md +51 -0
  442. package/src/components/ui/navigation-button-group.md +46 -0
  443. package/src/components/ui/notification-dot.md +7 -0
  444. package/src/components/ui/number-input.md +19 -0
  445. package/src/components/ui/panel.md +11 -0
  446. package/src/components/ui/popover.md +31 -0
  447. package/src/components/ui/resizable.md +66 -0
  448. package/src/components/ui/scroll-area.md +72 -0
  449. package/src/components/ui/search-field.md +33 -0
  450. package/src/components/ui/segmented-control.md +36 -0
  451. package/src/components/ui/sheet.md +30 -0
  452. package/src/components/ui/sidebar.md +113 -0
  453. package/src/components/ui/sonner.md +37 -0
  454. package/src/components/ui/split-view.md +15 -0
  455. package/src/components/ui/status.md +12 -0
  456. package/src/components/ui/table.md +37 -0
  457. package/src/components/ui/tabs.md +66 -0
  458. package/src/components/ui/text.md +17 -0
  459. package/src/components/ui/toggle-button.md +48 -0
  460. package/src/components/ui/toggle-group.md +80 -0
  461. package/src/components/ui/toggle.md +73 -0
  462. package/src/components/ui/toolbar.md +26 -0
  463. package/src/components/ui/tooltip.md +31 -0
  464. package/src/styles/index.css +704 -3
@@ -4,20 +4,54 @@ export interface ConversationMeta {
4
4
  createdAt: string;
5
5
  updatedAt: string;
6
6
  messageCount: number;
7
+ appId?: string | null;
8
+ appName?: string | null;
9
+ appIcon?: string | null;
10
+ /** Optional presentation-only grouping for chats that still use the Chats runtime. */
11
+ groupId?: string | null;
12
+ groupName?: string | null;
13
+ groupIcon?: string | null;
14
+ isActive?: boolean;
7
15
  }
8
- interface ConversationHistoryProps {
16
+ export interface ConversationGroup {
17
+ id: string;
18
+ appId: string | null;
19
+ label: string;
20
+ icon?: string | null;
21
+ conversations: ConversationMeta[];
22
+ }
23
+ export declare function getConversationGroupId(appId: string | null, groupId?: string | null): string;
24
+ export declare function isConversationIconImageSource(icon?: string | null): icon is string;
25
+ interface ConversationListProps {
9
26
  conversations: ConversationMeta[];
10
27
  currentConversationId?: string | null;
28
+ currentAppId?: string | null;
11
29
  onSelect: (id: string) => void;
12
- onDelete?: (id: string) => void;
13
- onNewChat?: () => void;
14
- newChatDisabled?: boolean;
30
+ onArchive?: (id: string) => void;
31
+ onArchiveGroup?: (group: ConversationGroup) => void;
15
32
  disabled?: boolean;
16
33
  className?: string;
34
+ }
35
+ interface ConversationHistoryProps extends ConversationListProps {
36
+ onNewChat?: () => void;
37
+ newChatDisabled?: boolean;
17
38
  dropdownAlign?: 'start' | 'center' | 'end';
18
39
  dropdownSide?: 'top' | 'right' | 'bottom' | 'left';
19
40
  tooltipSide?: 'top' | 'right' | 'bottom' | 'left';
41
+ hasMoreConversations?: boolean;
42
+ isLoadingMoreConversations?: boolean;
43
+ onLoadMoreConversations?: () => void | Promise<unknown>;
44
+ }
45
+ interface ConversationSidebarProps extends ConversationListProps {
46
+ onNewChat?: () => void;
47
+ newChatDisabled?: boolean;
48
+ hideScrollbar?: boolean;
49
+ hasMoreConversations?: boolean;
50
+ isLoadingMoreConversations?: boolean;
51
+ onLoadMoreConversations?: () => void | Promise<unknown>;
20
52
  }
21
- export declare function ConversationHistory({ conversations, currentConversationId, onSelect, onDelete, onNewChat, newChatDisabled, disabled, className, dropdownAlign, dropdownSide, tooltipSide, }: ConversationHistoryProps): import("react/jsx-runtime").JSX.Element | null;
53
+ export declare function groupConversations(conversations: ConversationMeta[], currentAppId?: string | null): ConversationGroup[];
54
+ export declare function ConversationSidebar({ conversations, currentConversationId, currentAppId, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled, hideScrollbar, hasMoreConversations, isLoadingMoreConversations, onLoadMoreConversations, disabled, className, }: ConversationSidebarProps): import("react/jsx-runtime").JSX.Element;
55
+ export declare function ConversationHistory({ conversations, currentConversationId, currentAppId, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled, disabled, className, dropdownAlign, dropdownSide, tooltipSide, hasMoreConversations, isLoadingMoreConversations, onLoadMoreConversations, }: ConversationHistoryProps): import("react/jsx-runtime").JSX.Element | null;
22
56
  export {};
23
57
  //# sourceMappingURL=conversation-history.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-history.d.ts","sourceRoot":"","sources":["../../../src/components/chat/conversation-history.tsx"],"names":[],"mappings":"AAkBA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,UAAU,wBAAwB;IAChC,aAAa,EAAE,gBAAgB,EAAE,CAAA;IACjC,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;IAC1C,YAAY,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IAClD,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;CAClD;AAiBD,wBAAgB,mBAAmB,CAAC,EAClC,aAAa,EACb,qBAAqB,EACrB,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,eAAuB,EACvB,QAAgB,EAChB,SAAS,EACT,aAAuB,EACvB,YAAuB,EACvB,WAAsB,GACvB,EAAE,wBAAwB,kDA6F1B"}
1
+ {"version":3,"file":"conversation-history.d.ts","sourceRoot":"","sources":["../../../src/components/chat/conversation-history.tsx"],"names":[],"mappings":"AAiCA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,aAAa,EAAE,gBAAgB,EAAE,CAAA;CAClC;AAOD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,MAAM,CAIR;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GACnB,IAAI,IAAI,MAAM,CAIhB;AAED,UAAU,qBAAqB;IAC7B,aAAa,EAAE,gBAAgB,EAAE,CAAA;IACjC,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,UAAU,wBAAyB,SAAQ,qBAAqB;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,aAAa,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;IAC1C,YAAY,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IAClD,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IACjD,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,uBAAuB,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACxD;AAED,UAAU,wBAAyB,SAAQ,qBAAqB;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,uBAAuB,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACxD;AAED,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,gBAAgB,EAAE,EACjC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAC3B,iBAAiB,EAAE,CA8CrB;AAyMD,wBAAgB,mBAAmB,CAAC,EAClC,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,cAAc,EACd,SAAS,EACT,eAAuB,EACvB,aAAqB,EACrB,oBAA4B,EAC5B,0BAAkC,EAClC,uBAAuB,EACvB,QAAgB,EAChB,SAAS,GACV,EAAE,wBAAwB,2CAuH1B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,cAAc,EACd,SAAS,EACT,eAAuB,EACvB,QAAgB,EAChB,SAAS,EACT,aAAuB,EACvB,YAAuB,EACvB,WAAsB,EACtB,oBAA4B,EAC5B,0BAAkC,EAClC,uBAAuB,GACxB,EAAE,wBAAwB,kDAgG1B"}
@@ -1,32 +1,198 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Clock, Plus, Trash2 } from 'lucide-react';
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Archive, ChevronDown, Folder, LoaderCircle, MessageCircle, Plus, } from 'lucide-react';
3
+ import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';
3
4
  import { cn } from '../../lib/utils';
5
+ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '../ui/alert-dialog';
4
6
  import { Button } from '../ui/button';
5
- import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, } from '../ui/dropdown-menu';
7
+ import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';
6
8
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from '../ui/tooltip';
7
- function formatRelativeTime(dateStr) {
8
- const date = new Date(dateStr);
9
- const now = new Date();
10
- const diffMs = now.getTime() - date.getTime();
11
- const diffMins = Math.floor(diffMs / 60000);
12
- const diffHours = Math.floor(diffMs / 3600000);
13
- const diffDays = Math.floor(diffMs / 86400000);
14
- if (diffMins < 1)
15
- return 'Just now';
16
- if (diffMins < 60)
17
- return `${diffMins}m ago`;
18
- if (diffHours < 24)
19
- return `${diffHours}h ago`;
20
- if (diffDays < 7)
21
- return `${diffDays}d ago`;
22
- return date.toLocaleDateString();
9
+ import { getVerticalScrollMask, } from './vertical-scroll-fade';
10
+ const CHATS_GROUP_ID = 'scope:chats';
11
+ const CUSTOM_GROUP_PREFIX = 'scope:group:';
12
+ const COLLAPSED_GROUP_CONVERSATION_LIMIT = 5;
13
+ const IMAGE_ICON_URL_PATTERN = /^(?:asset|https?|blob|data):/i;
14
+ export function getConversationGroupId(appId, groupId) {
15
+ if (appId !== null)
16
+ return `scope:app:${appId}`;
17
+ if (groupId === 'chats')
18
+ return CHATS_GROUP_ID;
19
+ return groupId ? `${CUSTOM_GROUP_PREFIX}${groupId}` : CHATS_GROUP_ID;
23
20
  }
24
- export function ConversationHistory({ conversations, currentConversationId, onSelect, onDelete, onNewChat, newChatDisabled = false, disabled = false, className, dropdownAlign = 'start', dropdownSide = 'bottom', tooltipSide = 'bottom', }) {
25
- if (conversations.length === 0 && !onNewChat) {
26
- return null;
21
+ export function isConversationIconImageSource(icon) {
22
+ return Boolean(icon && (icon.startsWith('/') || IMAGE_ICON_URL_PATTERN.test(icon)));
23
+ }
24
+ export function groupConversations(conversations, currentAppId) {
25
+ const byScope = new Map();
26
+ for (const conversation of conversations) {
27
+ const appId = conversation.appId ?? null;
28
+ const id = getConversationGroupId(appId, conversation.groupId);
29
+ const existing = byScope.get(id);
30
+ if (existing) {
31
+ existing.conversations.push(conversation);
32
+ continue;
33
+ }
34
+ byScope.set(id, {
35
+ id,
36
+ appId,
37
+ label: appId
38
+ ? conversation.appName || appId
39
+ : conversation.groupName || conversation.groupId || 'Chats',
40
+ icon: id === CHATS_GROUP_ID
41
+ ? null
42
+ : appId
43
+ ? conversation.appIcon
44
+ : conversation.groupIcon,
45
+ conversations: [conversation],
46
+ });
47
+ }
48
+ const groups = [...byScope.values()];
49
+ for (const group of groups) {
50
+ group.conversations.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
51
+ }
52
+ return groups.sort((a, b) => {
53
+ const aIsChats = a.id === CHATS_GROUP_ID;
54
+ const bIsChats = b.id === CHATS_GROUP_ID;
55
+ if (aIsChats !== bIsChats)
56
+ return aIsChats ? 1 : -1;
57
+ if (currentAppId != null) {
58
+ if (a.appId === currentAppId)
59
+ return -1;
60
+ if (b.appId === currentAppId)
61
+ return 1;
62
+ }
63
+ const aUpdated = a.conversations[0]?.updatedAt ?? '';
64
+ const bUpdated = b.conversations[0]?.updatedAt ?? '';
65
+ return bUpdated.localeCompare(aUpdated) || a.label.localeCompare(b.label);
66
+ });
67
+ }
68
+ function AppScopeIcon({ icon, isChats, }) {
69
+ if (isChats)
70
+ return _jsx(MessageCircle, { className: "size-4" });
71
+ if (isConversationIconImageSource(icon)) {
72
+ return _jsx("img", { src: icon, alt: "", className: "size-4 rounded object-cover" });
27
73
  }
28
- return (_jsx(TooltipProvider, { children: _jsxs(DropdownMenu, { children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-sm", disabled: disabled, className: cn('text-muted-foreground hover:text-foreground cursor-pointer', className), children: _jsx(Clock, { className: "size-4" }) }) }) }), _jsx(TooltipContent, { side: tooltipSide, children: _jsx("p", { children: "Conversation history" }) })] }), _jsxs(DropdownMenuContent, { align: dropdownAlign, side: dropdownSide, className: "w-64", children: [onNewChat && (_jsxs(_Fragment, { children: [_jsxs(DropdownMenuItem, { onClick: onNewChat, disabled: newChatDisabled, title: "New conversation (Cmd+Shift+O)", className: "flex cursor-pointer items-center gap-2", children: [_jsx(Plus, { className: "size-4" }), _jsx("span", { children: "New conversation" }), _jsx(DropdownMenuShortcut, { children: "\u2318\u21E7O" })] }), conversations.length > 0 && _jsx(DropdownMenuSeparator, {})] })), conversations.length > 0 && (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-muted-foreground px-2 py-1.5 text-xs font-medium", children: "Recent conversations" }), _jsx(DropdownMenuSeparator, {})] })), _jsx("div", { className: "max-h-64 overflow-y-auto", children: conversations.slice(0, 20).map((conv) => (_jsxs(DropdownMenuItem, { onClick: () => onSelect(conv.id), className: cn('group flex cursor-pointer items-start gap-2 py-2', conv.id === currentConversationId && 'bg-accent'), children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "truncate text-sm", children: conv.title }), _jsxs("p", { className: "text-muted-foreground text-xs", children: [formatRelativeTime(conv.updatedAt), " \u00B7 ", conv.messageCount, ' ', "messages"] })] }), onDelete && (_jsx(Button, { variant: "ghost", size: "icon-sm", onClick: (e) => {
29
- e.stopPropagation();
30
- onDelete(conv.id);
31
- }, className: "text-muted-foreground hover:text-destructive size-6 shrink-0 opacity-0 group-hover:opacity-100", children: _jsx(Trash2, { className: "size-3" }) }))] }, conv.id))) })] })] }) }));
74
+ if (icon)
75
+ return _jsx("span", { className: "text-sm leading-none", children: icon });
76
+ return _jsx(Folder, { className: "size-4" });
77
+ }
78
+ function ConversationList({ conversations, currentConversationId, currentAppId, onSelect, onArchive, onArchiveGroup, disabled = false, className, }) {
79
+ const groups = useMemo(() => groupConversations(conversations, currentAppId), [conversations, currentAppId]);
80
+ const [collapsedGroups, setCollapsedGroups] = useState(() => new Set());
81
+ const [expandedGroups, setExpandedGroups] = useState(() => new Set());
82
+ const [groupPendingArchive, setGroupPendingArchive] = useState(null);
83
+ const listIdPrefix = useId();
84
+ return (_jsxs("nav", { "aria-label": "Conversations", className: cn('space-y-1', className), children: [groups.map((group) => {
85
+ const isCollapsed = collapsedGroups.has(group.id);
86
+ const isShowingAll = expandedGroups.has(group.id);
87
+ const hasMoreConversations = group.conversations.length > COLLAPSED_GROUP_CONVERSATION_LIMIT;
88
+ const visibleConversations = isShowingAll
89
+ ? group.conversations
90
+ : group.conversations.slice(0, COLLAPSED_GROUP_CONVERSATION_LIMIT);
91
+ const listId = `${listIdPrefix}-${encodeURIComponent(group.id)}`;
92
+ return (_jsxs("section", { "data-conversation-group": group.id, children: [_jsxs("div", { className: "group/conversation-scope relative flex items-center", children: [_jsxs("button", { type: "button", "aria-expanded": !isCollapsed, "aria-controls": listId, onClick: () => setCollapsedGroups((current) => {
93
+ const next = new Set(current);
94
+ if (next.has(group.id))
95
+ next.delete(group.id);
96
+ else
97
+ next.add(group.id);
98
+ return next;
99
+ }), className: "text-foreground hover:bg-accent/60 flex h-9 min-w-0 flex-1 cursor-pointer items-center gap-2 rounded-lg px-2 pr-9 text-left text-sm font-medium transition-colors", children: [_jsx(ChevronDown, { className: cn('text-muted-foreground size-3.5 shrink-0 transition-transform', isCollapsed && '-rotate-90') }), _jsx("span", { className: "text-muted-foreground flex size-4 shrink-0 items-center justify-center", children: _jsx(AppScopeIcon, { icon: group.icon, isChats: group.id === CHATS_GROUP_ID }) }), _jsx("span", { className: "truncate", children: group.label })] }), onArchiveGroup && (_jsx("button", { type: "button", onClick: () => setGroupPendingArchive(group), className: "text-muted-foreground hover:text-foreground focus-visible:ring-ring absolute right-1 flex size-7 cursor-pointer items-center justify-center rounded-md opacity-0 transition-opacity focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 group-focus-within/conversation-scope:opacity-100 group-hover/conversation-scope:opacity-100", "aria-label": `Archive all chats in ${group.label}`, children: _jsx(Archive, { className: "size-3.5" }) }))] }), !isCollapsed && (_jsxs("ul", { id: listId, className: "ml-5 space-y-0.5 py-0.5", children: [visibleConversations.map((conversation) => (_jsxs("li", { "data-conversation-id": conversation.id, className: cn('group/conversation relative flex min-w-0 items-center rounded-lg', conversation.id === currentConversationId && 'bg-accent'), children: [_jsx("button", { type: "button", disabled: disabled, onClick: () => onSelect(conversation.id), "aria-current": conversation.id === currentConversationId
100
+ ? 'page'
101
+ : undefined, className: "min-w-0 flex-1 cursor-pointer truncate rounded-lg py-1.5 pl-3 pr-8 text-left text-sm disabled:cursor-default", children: conversation.title }), conversation.isActive && (_jsx(LoaderCircle, { className: "text-muted-foreground absolute right-2 size-3.5 animate-spin", "aria-label": "Conversation is working" })), onArchive && !conversation.isActive && (_jsx("button", { type: "button", onClick: (event) => {
102
+ event.stopPropagation();
103
+ onArchive(conversation.id);
104
+ }, disabled: disabled, className: "text-muted-foreground hover:text-foreground focus-visible:ring-ring absolute right-1 flex size-7 cursor-pointer items-center justify-center rounded-md opacity-0 transition-opacity focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 disabled:cursor-default group-focus-within/conversation:opacity-100 group-hover/conversation:opacity-100", "aria-label": `Archive ${conversation.title}`, children: _jsx(Archive, { className: "size-3.5" }) }))] }, conversation.id))), hasMoreConversations && (_jsx("li", { children: _jsx("button", { type: "button", onClick: () => setExpandedGroups((current) => {
105
+ const next = new Set(current);
106
+ if (next.has(group.id))
107
+ next.delete(group.id);
108
+ else
109
+ next.add(group.id);
110
+ return next;
111
+ }), className: "text-muted-foreground hover:bg-accent/60 hover:text-foreground flex h-7 w-full cursor-pointer items-center rounded-lg px-3 text-left text-xs transition-colors", "aria-label": `${isShowingAll ? 'Show fewer' : 'Show all'} ${group.label} conversations`, children: isShowingAll ? 'Show less' : 'Show all' }) }))] }))] }, group.id));
112
+ }), _jsx(AlertDialog, { open: groupPendingArchive !== null, onOpenChange: (open) => {
113
+ if (!open)
114
+ setGroupPendingArchive(null);
115
+ }, children: _jsxs(AlertDialogContent, { size: "sm", children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Archive all chats?" }), _jsxs(AlertDialogDescription, { children: ["Archive all ", groupPendingArchive?.conversations.length ?? 0, " chats in \u201C", groupPendingArchive?.label, "\u201D? You can restore them later from Settings."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { className: "cursor-pointer", children: "Cancel" }), _jsx(AlertDialogAction, { className: "cursor-pointer", onClick: () => {
116
+ if (groupPendingArchive) {
117
+ onArchiveGroup?.(groupPendingArchive);
118
+ }
119
+ setGroupPendingArchive(null);
120
+ }, children: "Archive all" })] })] }) })] }));
121
+ }
122
+ export function ConversationSidebar({ conversations, currentConversationId, currentAppId, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled = false, hideScrollbar = false, hasMoreConversations = false, isLoadingMoreConversations = false, onLoadMoreConversations, disabled = false, className, }) {
123
+ const scrollContainerRef = useRef(null);
124
+ const [scrollFadeEdges, setScrollFadeEdges] = useState({
125
+ top: false,
126
+ bottom: false,
127
+ });
128
+ const updateScrollFadeEdges = useCallback((element) => {
129
+ const scrollElement = element ?? scrollContainerRef.current;
130
+ if (!scrollElement)
131
+ return;
132
+ const next = {
133
+ top: scrollElement.scrollTop > 1,
134
+ bottom: scrollElement.scrollTop + scrollElement.clientHeight <
135
+ scrollElement.scrollHeight - 1,
136
+ };
137
+ setScrollFadeEdges((current) => current.top === next.top && current.bottom === next.bottom
138
+ ? current
139
+ : next);
140
+ }, []);
141
+ useEffect(() => {
142
+ const scrollElement = scrollContainerRef.current;
143
+ if (!scrollElement)
144
+ return;
145
+ updateScrollFadeEdges(scrollElement);
146
+ if (typeof ResizeObserver === 'undefined')
147
+ return;
148
+ const resizeObserver = new ResizeObserver(() => {
149
+ updateScrollFadeEdges(scrollElement);
150
+ });
151
+ resizeObserver.observe(scrollElement);
152
+ const content = scrollElement.firstElementChild;
153
+ if (content instanceof HTMLElement)
154
+ resizeObserver.observe(content);
155
+ return () => resizeObserver.disconnect();
156
+ }, [conversations, updateScrollFadeEdges]);
157
+ const scrollMask = getVerticalScrollMask(scrollFadeEdges);
158
+ const handleScroll = useCallback((element) => {
159
+ updateScrollFadeEdges(element);
160
+ if (hasMoreConversations &&
161
+ !isLoadingMoreConversations &&
162
+ element.scrollHeight - element.scrollTop - element.clientHeight < 120) {
163
+ void onLoadMoreConversations?.();
164
+ }
165
+ }, [
166
+ hasMoreConversations,
167
+ isLoadingMoreConversations,
168
+ onLoadMoreConversations,
169
+ updateScrollFadeEdges,
170
+ ]);
171
+ return (_jsxs("div", { className: cn('flex min-h-0 flex-col', className), children: [onNewChat && (_jsxs(Button, { variant: "ghost", onClick: onNewChat, disabled: newChatDisabled, className: "mb-3 w-full cursor-pointer justify-start gap-2", children: [_jsx(Plus, { className: "size-4" }), "New conversation"] })), _jsxs("div", { ref: scrollContainerRef, className: cn('min-h-0 flex-1 overflow-y-auto pb-8', hideScrollbar &&
172
+ '[scrollbar-width:none] [&::-webkit-scrollbar]:hidden'), "data-conversation-scroll-fade": true, "data-scroll-fade-top": scrollFadeEdges.top || undefined, "data-scroll-fade-bottom": scrollFadeEdges.bottom || undefined, onScroll: (event) => handleScroll(event.currentTarget), style: {
173
+ maskImage: scrollMask,
174
+ WebkitMaskImage: scrollMask,
175
+ }, children: [_jsx(ConversationList, { conversations: conversations, currentConversationId: currentConversationId, currentAppId: currentAppId, onSelect: onSelect, onArchive: onArchive, onArchiveGroup: hasMoreConversations ? undefined : onArchiveGroup, disabled: disabled }), hasMoreConversations && (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", disabled: isLoadingMoreConversations, onClick: () => void onLoadMoreConversations?.(), className: "text-muted-foreground mt-1 w-full cursor-pointer", children: [isLoadingMoreConversations && (_jsx(LoaderCircle, { className: "size-3.5 animate-spin" })), "Load older conversations"] }))] })] }));
176
+ }
177
+ export function ConversationHistory({ conversations, currentConversationId, currentAppId, onSelect, onArchive, onArchiveGroup, onNewChat, newChatDisabled = false, disabled = false, className, dropdownAlign = 'start', dropdownSide = 'bottom', tooltipSide = 'bottom', hasMoreConversations = false, isLoadingMoreConversations = false, onLoadMoreConversations, }) {
178
+ const [isOpen, setIsOpen] = useState(false);
179
+ if (conversations.length === 0 && !onNewChat)
180
+ return null;
181
+ return (_jsx(TooltipProvider, { children: _jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-sm", disabled: disabled, className: cn('text-muted-foreground hover:text-foreground cursor-pointer', className), "aria-label": "Conversations", children: _jsx(MessageCircle, { className: "size-4" }) }) }) }), _jsx(TooltipContent, { side: tooltipSide, children: "Conversations" })] }), _jsxs(PopoverContent, { align: dropdownAlign, side: dropdownSide, className: "w-72 p-2", children: [onNewChat && (_jsxs(Button, { type: "button", variant: "ghost", onClick: () => {
182
+ onNewChat();
183
+ setIsOpen(false);
184
+ }, disabled: newChatDisabled, title: "New conversation (Cmd+Shift+O)", className: "mb-1 flex w-full cursor-pointer items-center justify-start gap-2", children: [_jsx(Plus, { className: "size-4" }), _jsx("span", { children: "New conversation" }), _jsx("span", { className: "text-muted-foreground ml-auto text-xs", children: "\u2318\u21E7O" })] })), _jsxs("div", { className: "max-h-80 overflow-y-auto", onScroll: (event) => {
185
+ const element = event.currentTarget;
186
+ if (hasMoreConversations &&
187
+ !isLoadingMoreConversations &&
188
+ element.scrollHeight -
189
+ element.scrollTop -
190
+ element.clientHeight <
191
+ 120) {
192
+ void onLoadMoreConversations?.();
193
+ }
194
+ }, children: [_jsx(ConversationList, { conversations: conversations, currentConversationId: currentConversationId, currentAppId: currentAppId, onSelect: (id) => {
195
+ onSelect(id);
196
+ setIsOpen(false);
197
+ }, onArchive: onArchive, onArchiveGroup: hasMoreConversations ? undefined : onArchiveGroup, disabled: disabled }), hasMoreConversations && (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", disabled: isLoadingMoreConversations, onClick: () => void onLoadMoreConversations?.(), className: "text-muted-foreground mt-1 w-full cursor-pointer", children: [isLoadingMoreConversations && (_jsx(LoaderCircle, { className: "size-3.5 animate-spin" })), "Load older conversations"] }))] })] })] }) }));
32
198
  }
@@ -6,8 +6,8 @@ export { RestoreDialog, type CheckpointInfo, type RestoreDialogProps, } from './
6
6
  export { ModelSelector, type ModelOption } from './model-selector';
7
7
  export { ModelEffortSelector, resolveModelEffortPresetIndex, type ModelEffortPresetOption, type ModelProviderOption, } from './model-effort-selector';
8
8
  export { ReasoningEffortSelector, type ReasoningEffortOption, } from './reasoning-effort-selector';
9
- export { ConversationHistory, type ConversationMeta, } from './conversation-history';
10
- export { ChatPanel, type ChatAuthIssue, type ChatContextUsage, type ChatPanelProps, type QueuedChatMessage, type ToolProgressData, resolveChatAuthIssue, } from './chat-panel';
9
+ export { ConversationHistory, ConversationSidebar, groupConversations, type ConversationGroup, type ConversationMeta, } from './conversation-history';
10
+ export { ChatPanel, type ChatAuthIssue, type ChatContextUsage, type ChatPlanUsage, type ChatPlanUsageWindow, type ChatPanelProps, type QueuedChatMessage, type ToolProgressData, resolveChatAuthIssue, } from './chat-panel';
11
11
  export { ThinkingTimeline, ThinkingTimelineMarker, type ThinkingTimelineItem, type ThinkingTimelineProps, } from './thinking-timeline';
12
12
  export { getToolHandler, DEFAULT_TOOL_HANDLERS, type ToolHandler, } from './tool-handlers';
13
13
  export { ToolProgressProvider, useToolProgress, useToolCallProgress, } from './tool-progress-context';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/chat/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,cAAc,GACpB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,QAAQ,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC/E,OAAO,EACL,aAAa,EACb,KAAK,cAAc,EACnB,KAAK,kBAAkB,GACxB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,GACzB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,uBAAuB,EACvB,KAAK,qBAAqB,GAC3B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EACL,mBAAmB,EACnB,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,SAAS,EACT,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,oBAAoB,GACrB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,KAAK,WAAW,GACjB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,mBAAmB,GACpB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,KAAK,uBAAuB,GAC7B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/chat/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,cAAc,GACpB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,QAAQ,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC/E,OAAO,EACL,aAAa,EACb,KAAK,cAAc,EACnB,KAAK,kBAAkB,GACxB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAClE,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,GACzB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,uBAAuB,EACvB,KAAK,qBAAqB,GAC3B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,SAAS,EACT,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,oBAAoB,GACrB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,KAAK,WAAW,GACjB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,mBAAmB,GACpB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,KAAK,uBAAuB,GAC7B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAA"}
@@ -6,7 +6,7 @@ export { RestoreDialog, } from './restore-dialog';
6
6
  export { ModelSelector } from './model-selector';
7
7
  export { ModelEffortSelector, resolveModelEffortPresetIndex, } from './model-effort-selector';
8
8
  export { ReasoningEffortSelector, } from './reasoning-effort-selector';
9
- export { ConversationHistory, } from './conversation-history';
9
+ export { ConversationHistory, ConversationSidebar, groupConversations, } from './conversation-history';
10
10
  export { ChatPanel, resolveChatAuthIssue, } from './chat-panel';
11
11
  export { ThinkingTimeline, ThinkingTimelineMarker, } from './thinking-timeline';
12
12
  export { getToolHandler, DEFAULT_TOOL_HANDLERS, } from './tool-handlers';
@@ -1 +1 @@
1
- {"version":3,"file":"tool-handlers.d.ts","sourceRoot":"","sources":["../../../src/components/chat/tool-handlers.tsx"],"names":[],"mappings":"AAwBA,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAA;AAEhD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAW5D,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AAEtE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,SAAS,GAAG,UAAU,CAAA;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,OAAO,CAAA;CACd;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IAExB,YAAY,EAAE,MAAM,CAAA;IAEpB,MAAM,CAAC,EAAE,sBAAsB,CAAA;IAE/B,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,SAAS,CAAA;IAGhE,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,KAAK,SAAS,CAAA;IAG7C,eAAe,CAAC,EAAE,CAChB,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,qBAAqB,KAC5B,SAAS,CAAA;IAGd,cAAc,CAAC,EAAE,CACf,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,uBAAuB,KAC/B,SAAS,CAAA;CACf,CAAA;AAqSD;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAqvE7D,CAAA;AAoBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAmC5D"}
1
+ {"version":3,"file":"tool-handlers.d.ts","sourceRoot":"","sources":["../../../src/components/chat/tool-handlers.tsx"],"names":[],"mappings":"AAwBA,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAA;AAGhD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAW5D,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AAEtE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,SAAS,GAAG,UAAU,CAAA;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,OAAO,CAAA;CACd;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IAExB,YAAY,EAAE,MAAM,CAAA;IAEpB,MAAM,CAAC,EAAE,sBAAsB,CAAA;IAE/B,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,SAAS,CAAA;IAGhE,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,KAAK,SAAS,CAAA;IAG7C,eAAe,CAAC,EAAE,CAChB,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,qBAAqB,KAC5B,SAAS,CAAA;IAGd,cAAc,CAAC,EAAE,CACf,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,uBAAuB,KAC/B,SAAS,CAAA;CACf,CAAA;AAqSD;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CA81E7D,CAAA;AAoBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAmC5D"}
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { AlertTriangle, BookOpen, Camera, Check, CheckCheck, Copy, Database, Download, FileCode, FileText, FolderOpen, Globe, Info, Package, Plus, Search, Sparkles, Terminal, Trash2, X, } from 'lucide-react';
4
4
  import { useState } from 'react';
5
5
  import { cn } from '../../lib/utils';
6
+ import { ChatImageLightbox } from './chat-image-lightbox';
6
7
  import { ThinkingTimelineMarker } from './thinking-timeline';
7
8
  import { ToolApproval, ToolApprovalAction, ToolApprovalActions, ToolApprovalDangerousHelp, ToolApprovalHeader, ToolApprovalHelp, ToolApprovalRequest, ToolApprovalSandboxHelp, } from './tool-approval';
8
9
  /**
@@ -123,11 +124,48 @@ export const DEFAULT_TOOL_HANDLERS = {
123
124
  if (!result) {
124
125
  return (_jsx(LoadingIndicator, { icon: Sparkles, children: "Viewing image..." }, toolCallId));
125
126
  }
127
+ const parts = Array.isArray(result.value) ? result.value : [];
128
+ const image = parts.find((part) => (part.type === 'image-data' || part.type === 'media') &&
129
+ part.data &&
130
+ part.mediaType?.startsWith('image/'));
131
+ const imageSrc = result.imageUrl ??
132
+ (image?.data && image.mediaType
133
+ ? `data:${image.mediaType};base64,${image.data}`
134
+ : undefined);
135
+ if (imageSrc) {
136
+ return (_jsxs("details", { className: "border-border bg-muted text-muted-foreground my-1 max-w-2xl overflow-hidden rounded-md border text-xs", children: [_jsxs("summary", { className: "flex cursor-pointer list-none items-center gap-2 px-2 py-1.5", children: [_jsx(Sparkles, { className: "size-3.5 shrink-0" }), _jsx("span", { className: "min-w-0 truncate", children: result.imagePath
137
+ ? `Viewed ${getFileName(result.imagePath)}`
138
+ : 'Viewed image' })] }), _jsx("div", { className: "border-border border-t p-2", children: _jsx(ChatImageLightbox, { src: imageSrc, alt: result.imagePath
139
+ ? getFileName(result.imagePath)
140
+ : 'Image viewed by Moldable', className: "bg-background block size-20 rounded-2xl border", imageClassName: "size-full object-cover" }) })] }, toolCallId));
141
+ }
126
142
  return (_jsxs("div", { className: "bg-muted text-muted-foreground my-1 inline-flex max-w-full items-center gap-2 rounded-md px-2 py-1 text-xs", children: [_jsx(Sparkles, { className: "size-3.5 shrink-0" }), _jsx("span", { className: "min-w-0 truncate", children: result.imagePath
127
143
  ? `Viewed ${getFileName(result.imagePath)}`
128
144
  : 'Viewed image' })] }, toolCallId));
129
145
  },
130
146
  },
147
+ showImages: {
148
+ loadingLabel: 'Showing images...',
149
+ marker: ThinkingTimelineMarker.Default,
150
+ inline: true,
151
+ renderLoading: (args) => {
152
+ const { images } = (args ?? {});
153
+ const count = images?.length ?? 0;
154
+ return (_jsx(LoadingIndicator, { icon: Sparkles, children: count === 1 && images?.[0]?.imagePath
155
+ ? `Showing ${getFileName(images[0].imagePath)}...`
156
+ : count > 1
157
+ ? `Showing ${count} images...`
158
+ : 'Showing images...' }));
159
+ },
160
+ renderOutput: (output, toolCallId) => {
161
+ const result = output;
162
+ const images = result?.images?.filter((image) => Boolean(image.imageUrl));
163
+ if (!images?.length) {
164
+ return (_jsx(LoadingIndicator, { icon: Sparkles, children: "Showing images..." }, toolCallId));
165
+ }
166
+ return (_jsx("div", { className: "my-2 flex max-w-full gap-2 overflow-x-auto", children: images.map((image, index) => (_jsx(ChatImageLightbox, { src: image.imageUrl, alt: image.altText || image.filename || 'Image shown by Moldable', className: "border-border bg-muted block size-20 shrink-0 rounded-2xl border", imageClassName: "size-full object-cover" }, `${image.imageUrl}-${index}`))) }, toolCallId));
167
+ },
168
+ },
131
169
  generateImage: {
132
170
  loadingLabel: 'Generating image...',
133
171
  marker: ThinkingTimelineMarker.Default,
@@ -165,7 +203,7 @@ export const DEFAULT_TOOL_HANDLERS = {
165
203
  ? `Generated image saved at ${result.imagePath}.`
166
204
  : 'Generated image saved.' })] }, toolCallId));
167
205
  }
168
- return (_jsxs("figure", { className: "my-2 min-w-0 max-w-2xl", children: [_jsx("div", { className: "border-border bg-muted overflow-hidden rounded-lg border", children: _jsx("img", { src: imageSrc, alt: result.prompt || 'Generated image', className: "block max-h-[420px] w-full object-contain" }) }), _jsxs("figcaption", { className: "text-muted-foreground mt-1 flex min-w-0 items-center gap-1 text-xs", children: [_jsx(Sparkles, { className: "size-3 shrink-0" }), _jsx("span", { className: "truncate", children: result.imagePath
206
+ return (_jsxs("figure", { className: "my-2 min-w-0 max-w-2xl", children: [_jsx(ChatImageLightbox, { src: imageSrc, alt: result.prompt || 'Generated image', className: "border-border bg-muted block max-w-full rounded-2xl border", imageClassName: "block max-h-[420px] w-full object-contain" }), _jsxs("figcaption", { className: "text-muted-foreground mt-1 flex min-w-0 items-center gap-1 text-xs", children: [_jsx(Sparkles, { className: "size-3 shrink-0" }), _jsx("span", { className: "truncate", children: result.imagePath
169
207
  ? `${getFileName(result.imagePath)}${result.size ? ` - ${result.size}` : ''}`
170
208
  : result.size || 'Generated image' })] })] }, toolCallId));
171
209
  },
@@ -193,7 +231,7 @@ export const DEFAULT_TOOL_HANDLERS = {
193
231
  if (!image?.data || !image.mediaType) {
194
232
  return (_jsxs("div", { className: "bg-muted text-muted-foreground my-1 inline-flex max-w-full items-center gap-2 rounded-md px-2 py-1 text-xs", children: [_jsx(Camera, { className: "size-3.5 shrink-0" }), _jsx("span", { className: "truncate", children: text || 'Screenshot captured' }), _jsx(Check, { className: "size-3 shrink-0 text-green-600" })] }, toolCallId));
195
233
  }
196
- return (_jsxs("figure", { className: "my-2 min-w-0 max-w-2xl", children: [_jsx("div", { className: "border-border bg-muted overflow-hidden rounded-lg border", children: _jsx("img", { src: `data:${image.mediaType};base64,${image.data}`, alt: "Current app screenshot", className: "block max-h-[420px] w-full object-contain" }) }), text && (_jsxs("figcaption", { className: "text-muted-foreground mt-1 flex items-center gap-1 text-xs", children: [_jsx(Camera, { className: "size-3" }), _jsx("span", { className: "truncate", children: text })] }))] }, toolCallId));
234
+ return (_jsxs("figure", { className: "my-2 min-w-0 max-w-2xl", children: [_jsx(ChatImageLightbox, { src: `data:${image.mediaType};base64,${image.data}`, alt: "Current app screenshot", className: "border-border bg-muted block max-w-full rounded-2xl border", imageClassName: "block max-h-[420px] w-full object-contain" }), text && (_jsxs("figcaption", { className: "text-muted-foreground mt-1 flex items-center gap-1 text-xs", children: [_jsx(Camera, { className: "size-3" }), _jsx("span", { className: "truncate", children: text })] }))] }, toolCallId));
197
235
  },
198
236
  },
199
237
  listMoldableAppApi: {
@@ -0,0 +1,6 @@
1
+ export interface VerticalScrollFadeEdges {
2
+ top: boolean;
3
+ bottom: boolean;
4
+ }
5
+ export declare function getVerticalScrollMask({ top, bottom }: VerticalScrollFadeEdges, fadeSize?: string): string;
6
+ //# sourceMappingURL=vertical-scroll-fade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vertical-scroll-fade.d.ts","sourceRoot":"","sources":["../../../src/components/chat/vertical-scroll-fade.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,OAAO,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,wBAAgB,qBAAqB,CACnC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,uBAAuB,EACxC,QAAQ,SAAW,GAClB,MAAM,CAWR"}
@@ -0,0 +1,12 @@
1
+ export function getVerticalScrollMask({ top, bottom }, fadeSize = '2.5rem') {
2
+ if (top && bottom) {
3
+ return `linear-gradient(to bottom, transparent 0%, black ${fadeSize}, black calc(100% - ${fadeSize}), transparent 100%)`;
4
+ }
5
+ if (top) {
6
+ return `linear-gradient(to bottom, transparent 0%, black ${fadeSize}, black 100%)`;
7
+ }
8
+ if (bottom) {
9
+ return `linear-gradient(to bottom, black 0%, black calc(100% - ${fadeSize}), transparent 100%)`;
10
+ }
11
+ return 'none';
12
+ }
@@ -0,0 +1,9 @@
1
+ export type BluetoothSubscriptionCleanup = () => Promise<void>;
2
+ /**
3
+ * Stops every active observer before returning. Successful entries are removed,
4
+ * while failed entries stay registered so the caller can retry cleanup.
5
+ */
6
+ export declare function cleanupBluetoothSubscriptions(subscriptions: Map<string, BluetoothSubscriptionCleanup>): Promise<void>;
7
+ /** Parses a compact or separator-delimited hexadecimal Bluetooth value. */
8
+ export declare function parseBluetoothHexBytes(value: string): Uint8Array<ArrayBuffer>;
9
+ //# sourceMappingURL=bluetooth-panel-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bluetooth-panel-helpers.d.ts","sourceRoot":"","sources":["../../../src/components/native-capabilities/bluetooth-panel-helpers.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,4BAA4B,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;AAE9D;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,4BAA4B,CAAC,GACvD,OAAO,CAAC,IAAI,CAAC,CAef;AAED,2EAA2E;AAC3E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAqB7E"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Stops every active observer before returning. Successful entries are removed,
3
+ * while failed entries stay registered so the caller can retry cleanup.
4
+ */
5
+ export async function cleanupBluetoothSubscriptions(subscriptions) {
6
+ const failures = [];
7
+ await Promise.all([...subscriptions].map(async ([key, stop]) => {
8
+ try {
9
+ await stop();
10
+ if (subscriptions.get(key) === stop)
11
+ subscriptions.delete(key);
12
+ }
13
+ catch (cause) {
14
+ failures.push(cause);
15
+ }
16
+ }));
17
+ if (failures.length > 0)
18
+ throw failures[0];
19
+ }
20
+ /** Parses a compact or separator-delimited hexadecimal Bluetooth value. */
21
+ export function parseBluetoothHexBytes(value) {
22
+ const normalized = value
23
+ .trim()
24
+ .replace(/0x/gi, '')
25
+ .replace(/[\s,:-]+/g, '');
26
+ if (normalized.length === 0) {
27
+ throw new TypeError('Enter at least one hexadecimal byte.');
28
+ }
29
+ if (normalized.length % 2 !== 0 || !/^[0-9a-f]+$/i.test(normalized)) {
30
+ throw new TypeError('Use complete hexadecimal bytes, such as 01 A0 FF.');
31
+ }
32
+ const bytes = new Uint8Array(new ArrayBuffer(normalized.length / 2));
33
+ for (let index = 0; index < bytes.length; index++) {
34
+ bytes[index] = Number.parseInt(normalized.slice(index * 2, index * 2 + 2), 16);
35
+ }
36
+ return bytes;
37
+ }
@@ -0,0 +1,56 @@
1
+ import * as React from 'react';
2
+ import { type MoldableBluetoothConnection, type MoldableBluetoothDevice, type MoldableBluetoothRemoteGATTCharacteristic, type MoldableNativeBluetoothDevice } from '../../lib/native-capabilities';
3
+ export type MoldableBluetoothStatus = 'idle' | 'requesting' | 'connecting' | 'connected' | 'error';
4
+ export interface MoldableBluetoothCharacteristicInfo {
5
+ serviceUuid: string;
6
+ uuid: string;
7
+ /** Property names when the runtime exposes them; empty when unknown. */
8
+ properties: string[];
9
+ /** Web Bluetooth handle; null on the desktop bridge (UUIDs drive I/O). */
10
+ characteristic: MoldableBluetoothRemoteGATTCharacteristic | null;
11
+ }
12
+ export interface MoldableBluetoothServiceInfo {
13
+ uuid: string;
14
+ characteristics: MoldableBluetoothCharacteristicInfo[];
15
+ }
16
+ export interface UseMoldableBluetoothOptions {
17
+ onValue?: (characteristic: MoldableBluetoothCharacteristicInfo, value: DataView) => void;
18
+ }
19
+ /**
20
+ * Bluetooth LE state machine behind `BluetoothPanel`. Handles both transports
21
+ * returned by `requestMoldableBluetoothWithFallback`: Web Bluetooth (GATT
22
+ * connection + service discovery) and the desktop bridge (UUID-addressed I/O
23
+ * on an already-connected device).
24
+ */
25
+ export declare function useMoldableBluetooth(options?: UseMoldableBluetoothOptions): {
26
+ status: MoldableBluetoothStatus;
27
+ device: MoldableBluetoothDevice | MoldableNativeBluetoothDevice | null;
28
+ connection: MoldableBluetoothConnection | null;
29
+ disconnecting: boolean;
30
+ services: MoldableBluetoothServiceInfo[];
31
+ subscribedUuids: string[];
32
+ error: Error | null;
33
+ entries: import("./stream-log").StreamLogEntry[];
34
+ request: (serviceUuid?: string) => Promise<void>;
35
+ connect: () => Promise<void>;
36
+ disconnect: () => Promise<void>;
37
+ read: (characteristic: MoldableBluetoothCharacteristicInfo) => Promise<void>;
38
+ subscribe: (characteristic: MoldableBluetoothCharacteristicInfo) => Promise<void>;
39
+ unsubscribe: (characteristic: MoldableBluetoothCharacteristicInfo) => Promise<void>;
40
+ write: (characteristic: MoldableBluetoothCharacteristicInfo, bytes: BufferSource) => Promise<void>;
41
+ writeHex: (characteristic: MoldableBluetoothCharacteristicInfo, value: string) => Promise<void>;
42
+ clearEntries: () => void;
43
+ };
44
+ export interface BluetoothPanelProps extends React.ComponentProps<'div'> {
45
+ /** Prefill and scope scanning/discovery to one GATT service UUID. */
46
+ serviceUuid?: string;
47
+ onValue?: (characteristic: MoldableBluetoothCharacteristicInfo, value: DataView) => void;
48
+ }
49
+ /**
50
+ * Bluetooth LE panel: scan (optionally scoped to a service UUID), connect,
51
+ * browse discovered characteristics, and read, write, or subscribe to values
52
+ * with a live hex log.
53
+ */
54
+ declare function BluetoothPanel({ className, serviceUuid, onValue, ...props }: BluetoothPanelProps): import("react/jsx-runtime").JSX.Element;
55
+ export { BluetoothPanel };
56
+ //# sourceMappingURL=bluetooth-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bluetooth-panel.d.ts","sourceRoot":"","sources":["../../../src/components/native-capabilities/bluetooth-panel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EACL,KAAK,2BAA2B,EAChC,KAAK,uBAAuB,EAC5B,KAAK,yCAAyC,EAG9C,KAAK,6BAA6B,EAQnC,MAAM,+BAA+B,CAAA;AAqBtC,MAAM,MAAM,uBAAuB,GAC/B,MAAM,GACN,YAAY,GACZ,YAAY,GACZ,WAAW,GACX,OAAO,CAAA;AAgDX,MAAM,WAAW,mCAAmC;IAClD,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,wEAAwE;IACxE,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,0EAA0E;IAC1E,cAAc,EAAE,yCAAyC,GAAG,IAAI,CAAA;CACjE;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,mCAAmC,EAAE,CAAA;CACvD;AA+ED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,CAAC,EAAE,CACR,cAAc,EAAE,mCAAmC,EACnD,KAAK,EAAE,QAAQ,KACZ,IAAI,CAAA;CACV;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,2BAAgC;;;;;;;;;4BAkJlB,MAAM;;;2BAiDJ,mCAAmC;gCA0BnC,mCAAmC;kCAqCnC,mCAAmC;4BAqBxC,mCAAmC,SAC5C,YAAY;+BAmCH,mCAAmC,SAC5C,MAAM;;EAsClB;AAED,MAAM,WAAW,mBAAoB,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IACtE,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,CACR,cAAc,EAAE,mCAAmC,EACnD,KAAK,EAAE,QAAQ,KACZ,IAAI,CAAA;CACV;AAED;;;;GAIG;AACH,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,WAAW,EACX,OAAO,EACP,GAAG,KAAK,EACT,EAAE,mBAAmB,2CAiPrB;AAED,OAAO,EAAE,cAAc,EAAE,CAAA"}