@vendoai/ui 0.4.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 (525) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +7 -0
  3. package/dist/chrome/activity-ledger.d.ts +14 -0
  4. package/dist/chrome/activity-ledger.d.ts.map +1 -0
  5. package/dist/chrome/activity-ledger.js +40 -0
  6. package/dist/chrome/activity-ledger.js.map +1 -0
  7. package/dist/chrome/activity-panel.d.ts +7 -0
  8. package/dist/chrome/activity-panel.d.ts.map +1 -0
  9. package/dist/chrome/activity-panel.js +27 -0
  10. package/dist/chrome/activity-panel.js.map +1 -0
  11. package/dist/chrome/activity-semantics.d.ts +42 -0
  12. package/dist/chrome/activity-semantics.d.ts.map +1 -0
  13. package/dist/chrome/activity-semantics.js +119 -0
  14. package/dist/chrome/activity-semantics.js.map +1 -0
  15. package/dist/chrome/approval-card.d.ts +22 -0
  16. package/dist/chrome/approval-card.d.ts.map +1 -0
  17. package/dist/chrome/approval-card.js +95 -0
  18. package/dist/chrome/approval-card.js.map +1 -0
  19. package/dist/chrome/approval-sheet.d.ts +23 -0
  20. package/dist/chrome/approval-sheet.d.ts.map +1 -0
  21. package/dist/chrome/approval-sheet.js +72 -0
  22. package/dist/chrome/approval-sheet.js.map +1 -0
  23. package/dist/chrome/automations-panel.d.ts +3 -0
  24. package/dist/chrome/automations-panel.d.ts.map +1 -0
  25. package/dist/chrome/automations-panel.js +305 -0
  26. package/dist/chrome/automations-panel.js.map +1 -0
  27. package/dist/chrome/build-beat.d.ts +70 -0
  28. package/dist/chrome/build-beat.d.ts.map +1 -0
  29. package/dist/chrome/build-beat.js +101 -0
  30. package/dist/chrome/build-beat.js.map +1 -0
  31. package/dist/chrome/chrome-css.d.ts +7 -0
  32. package/dist/chrome/chrome-css.d.ts.map +1 -0
  33. package/dist/chrome/chrome-css.js +2042 -0
  34. package/dist/chrome/chrome-css.js.map +1 -0
  35. package/dist/chrome/chrome-root.d.ts +13 -0
  36. package/dist/chrome/chrome-root.d.ts.map +1 -0
  37. package/dist/chrome/chrome-root.js +39 -0
  38. package/dist/chrome/chrome-root.js.map +1 -0
  39. package/dist/chrome/clipboard.d.ts +4 -0
  40. package/dist/chrome/clipboard.d.ts.map +1 -0
  41. package/dist/chrome/clipboard.js +49 -0
  42. package/dist/chrome/clipboard.js.map +1 -0
  43. package/dist/chrome/connect-card.d.ts +19 -0
  44. package/dist/chrome/connect-card.d.ts.map +1 -0
  45. package/dist/chrome/connect-card.js +57 -0
  46. package/dist/chrome/connect-card.js.map +1 -0
  47. package/dist/chrome/connect-dock.d.ts +25 -0
  48. package/dist/chrome/connect-dock.d.ts.map +1 -0
  49. package/dist/chrome/connect-dock.js +192 -0
  50. package/dist/chrome/connect-dock.js.map +1 -0
  51. package/dist/chrome/connected-accounts-panel.d.ts +14 -0
  52. package/dist/chrome/connected-accounts-panel.d.ts.map +1 -0
  53. package/dist/chrome/connected-accounts-panel.js +157 -0
  54. package/dist/chrome/connected-accounts-panel.js.map +1 -0
  55. package/dist/chrome/dev-mode.d.ts +5 -0
  56. package/dist/chrome/dev-mode.d.ts.map +1 -0
  57. package/dist/chrome/dev-mode.js +7 -0
  58. package/dist/chrome/dev-mode.js.map +1 -0
  59. package/dist/chrome/discoverability.d.ts +33 -0
  60. package/dist/chrome/discoverability.d.ts.map +1 -0
  61. package/dist/chrome/discoverability.js +63 -0
  62. package/dist/chrome/discoverability.js.map +1 -0
  63. package/dist/chrome/embeds.d.ts +21 -0
  64. package/dist/chrome/embeds.d.ts.map +1 -0
  65. package/dist/chrome/embeds.js +181 -0
  66. package/dist/chrome/embeds.js.map +1 -0
  67. package/dist/chrome/fluid-thinking.d.ts +15 -0
  68. package/dist/chrome/fluid-thinking.d.ts.map +1 -0
  69. package/dist/chrome/fluid-thinking.js +37 -0
  70. package/dist/chrome/fluid-thinking.js.map +1 -0
  71. package/dist/chrome/humanize.d.ts +46 -0
  72. package/dist/chrome/humanize.d.ts.map +1 -0
  73. package/dist/chrome/humanize.js +104 -0
  74. package/dist/chrome/humanize.js.map +1 -0
  75. package/dist/chrome/index.d.ts +39 -0
  76. package/dist/chrome/index.d.ts.map +1 -0
  77. package/dist/chrome/index.js +38 -0
  78. package/dist/chrome/index.js.map +1 -0
  79. package/dist/chrome/markdown.d.ts +23 -0
  80. package/dist/chrome/markdown.d.ts.map +1 -0
  81. package/dist/chrome/markdown.js +149 -0
  82. package/dist/chrome/markdown.js.map +1 -0
  83. package/dist/chrome/morph-toast.d.ts +43 -0
  84. package/dist/chrome/morph-toast.d.ts.map +1 -0
  85. package/dist/chrome/morph-toast.js +89 -0
  86. package/dist/chrome/morph-toast.js.map +1 -0
  87. package/dist/chrome/no-policy-notice.d.ts +8 -0
  88. package/dist/chrome/no-policy-notice.d.ts.map +1 -0
  89. package/dist/chrome/no-policy-notice.js +18 -0
  90. package/dist/chrome/no-policy-notice.js.map +1 -0
  91. package/dist/chrome/onest-font.gen.d.ts +10 -0
  92. package/dist/chrome/onest-font.gen.d.ts.map +1 -0
  93. package/dist/chrome/onest-font.gen.js +10 -0
  94. package/dist/chrome/onest-font.gen.js.map +1 -0
  95. package/dist/chrome/overlay-registry.d.ts +66 -0
  96. package/dist/chrome/overlay-registry.d.ts.map +1 -0
  97. package/dist/chrome/overlay-registry.js +103 -0
  98. package/dist/chrome/overlay-registry.js.map +1 -0
  99. package/dist/chrome/palette-hotkey.d.ts +42 -0
  100. package/dist/chrome/palette-hotkey.d.ts.map +1 -0
  101. package/dist/chrome/palette-hotkey.js +91 -0
  102. package/dist/chrome/palette-hotkey.js.map +1 -0
  103. package/dist/chrome/policy-notice-body.d.ts +3 -0
  104. package/dist/chrome/policy-notice-body.d.ts.map +1 -0
  105. package/dist/chrome/policy-notice-body.js +6 -0
  106. package/dist/chrome/policy-notice-body.js.map +1 -0
  107. package/dist/chrome/takeover-portal.d.ts +16 -0
  108. package/dist/chrome/takeover-portal.d.ts.map +1 -0
  109. package/dist/chrome/takeover-portal.js +21 -0
  110. package/dist/chrome/takeover-portal.js.map +1 -0
  111. package/dist/chrome/thread/attachments.d.ts +24 -0
  112. package/dist/chrome/thread/attachments.d.ts.map +1 -0
  113. package/dist/chrome/thread/attachments.js +50 -0
  114. package/dist/chrome/thread/attachments.js.map +1 -0
  115. package/dist/chrome/thread/composer.d.ts +63 -0
  116. package/dist/chrome/thread/composer.d.ts.map +1 -0
  117. package/dist/chrome/thread/composer.js +259 -0
  118. package/dist/chrome/thread/composer.js.map +1 -0
  119. package/dist/chrome/thread/index.d.ts +41 -0
  120. package/dist/chrome/thread/index.d.ts.map +1 -0
  121. package/dist/chrome/thread/index.js +258 -0
  122. package/dist/chrome/thread/index.js.map +1 -0
  123. package/dist/chrome/thread/message-data.d.ts +35 -0
  124. package/dist/chrome/thread/message-data.d.ts.map +1 -0
  125. package/dist/chrome/thread/message-data.js +127 -0
  126. package/dist/chrome/thread/message-data.js.map +1 -0
  127. package/dist/chrome/thread/message-list.d.ts +30 -0
  128. package/dist/chrome/thread/message-list.d.ts.map +1 -0
  129. package/dist/chrome/thread/message-list.js +11 -0
  130. package/dist/chrome/thread/message-list.js.map +1 -0
  131. package/dist/chrome/thread/message.d.ts +18 -0
  132. package/dist/chrome/thread/message.d.ts.map +1 -0
  133. package/dist/chrome/thread/message.js +57 -0
  134. package/dist/chrome/thread/message.js.map +1 -0
  135. package/dist/chrome/thread/parts.d.ts +53 -0
  136. package/dist/chrome/thread/parts.d.ts.map +1 -0
  137. package/dist/chrome/thread/parts.js +184 -0
  138. package/dist/chrome/thread/parts.js.map +1 -0
  139. package/dist/chrome/thread/scrolling.d.ts +26 -0
  140. package/dist/chrome/thread/scrolling.d.ts.map +1 -0
  141. package/dist/chrome/thread/scrolling.js +214 -0
  142. package/dist/chrome/thread/scrolling.js.map +1 -0
  143. package/dist/chrome/truncate.d.ts +12 -0
  144. package/dist/chrome/truncate.d.ts.map +1 -0
  145. package/dist/chrome/truncate.js +18 -0
  146. package/dist/chrome/truncate.js.map +1 -0
  147. package/dist/chrome/vendo-activities.d.ts +24 -0
  148. package/dist/chrome/vendo-activities.d.ts.map +1 -0
  149. package/dist/chrome/vendo-activities.js +38 -0
  150. package/dist/chrome/vendo-activities.js.map +1 -0
  151. package/dist/chrome/vendo-overlay.d.ts +63 -0
  152. package/dist/chrome/vendo-overlay.d.ts.map +1 -0
  153. package/dist/chrome/vendo-overlay.js +256 -0
  154. package/dist/chrome/vendo-overlay.js.map +1 -0
  155. package/dist/chrome/vendo-page.d.ts +3 -0
  156. package/dist/chrome/vendo-page.d.ts.map +1 -0
  157. package/dist/chrome/vendo-page.js +162 -0
  158. package/dist/chrome/vendo-page.js.map +1 -0
  159. package/dist/chrome/vendo-palette.d.ts +29 -0
  160. package/dist/chrome/vendo-palette.d.ts.map +1 -0
  161. package/dist/chrome/vendo-palette.js +95 -0
  162. package/dist/chrome/vendo-palette.js.map +1 -0
  163. package/dist/chrome/vendo-slot.d.ts +79 -0
  164. package/dist/chrome/vendo-slot.d.ts.map +1 -0
  165. package/dist/chrome/vendo-slot.js +153 -0
  166. package/dist/chrome/vendo-slot.js.map +1 -0
  167. package/dist/chrome/vendo-toasts.d.ts +40 -0
  168. package/dist/chrome/vendo-toasts.d.ts.map +1 -0
  169. package/dist/chrome/vendo-toasts.js +135 -0
  170. package/dist/chrome/vendo-toasts.js.map +1 -0
  171. package/dist/chrome/vendo-trigger.d.ts +24 -0
  172. package/dist/chrome/vendo-trigger.d.ts.map +1 -0
  173. package/dist/chrome/vendo-trigger.js +30 -0
  174. package/dist/chrome/vendo-trigger.js.map +1 -0
  175. package/dist/chrome/waiting-queue.d.ts +8 -0
  176. package/dist/chrome/waiting-queue.d.ts.map +1 -0
  177. package/dist/chrome/waiting-queue.js +21 -0
  178. package/dist/chrome/waiting-queue.js.map +1 -0
  179. package/dist/client-impl.d.ts +4 -0
  180. package/dist/client-impl.d.ts.map +1 -0
  181. package/dist/client-impl.js +160 -0
  182. package/dist/client-impl.js.map +1 -0
  183. package/dist/client.d.ts +136 -0
  184. package/dist/client.d.ts.map +1 -0
  185. package/dist/client.js +2 -0
  186. package/dist/client.js.map +1 -0
  187. package/dist/context.d.ts +97 -0
  188. package/dist/context.d.ts.map +1 -0
  189. package/dist/context.js +71 -0
  190. package/dist/context.js.map +1 -0
  191. package/dist/eject-templates/activities/index.tsx +113 -0
  192. package/dist/eject-templates/templates.json +29 -0
  193. package/dist/eject-templates/thread/attachments.tsx +69 -0
  194. package/dist/eject-templates/thread/composer.tsx +409 -0
  195. package/dist/eject-templates/thread/index.tsx +422 -0
  196. package/dist/eject-templates/thread/message-data.ts +151 -0
  197. package/dist/eject-templates/thread/message-list.tsx +123 -0
  198. package/dist/eject-templates/thread/message.tsx +149 -0
  199. package/dist/eject-templates/thread/parts.tsx +293 -0
  200. package/dist/eject-templates/thread/scrolling.ts +223 -0
  201. package/dist/embeds.d.ts +28 -0
  202. package/dist/embeds.d.ts.map +1 -0
  203. package/dist/embeds.js +2 -0
  204. package/dist/embeds.js.map +1 -0
  205. package/dist/hooks/index.d.ts +18 -0
  206. package/dist/hooks/index.d.ts.map +1 -0
  207. package/dist/hooks/index.js +19 -0
  208. package/dist/hooks/index.js.map +1 -0
  209. package/dist/hooks/scripted-transport.d.ts +44 -0
  210. package/dist/hooks/scripted-transport.d.ts.map +1 -0
  211. package/dist/hooks/scripted-transport.js +58 -0
  212. package/dist/hooks/scripted-transport.js.map +1 -0
  213. package/dist/hooks/use-activity.d.ts +17 -0
  214. package/dist/hooks/use-activity.d.ts.map +1 -0
  215. package/dist/hooks/use-activity.js +50 -0
  216. package/dist/hooks/use-activity.js.map +1 -0
  217. package/dist/hooks/use-app.d.ts +19 -0
  218. package/dist/hooks/use-app.d.ts.map +1 -0
  219. package/dist/hooks/use-app.js +66 -0
  220. package/dist/hooks/use-app.js.map +1 -0
  221. package/dist/hooks/use-approvals.d.ts +13 -0
  222. package/dist/hooks/use-approvals.d.ts.map +1 -0
  223. package/dist/hooks/use-approvals.js +14 -0
  224. package/dist/hooks/use-approvals.js.map +1 -0
  225. package/dist/hooks/use-apps.d.ts +17 -0
  226. package/dist/hooks/use-apps.d.ts.map +1 -0
  227. package/dist/hooks/use-apps.js +30 -0
  228. package/dist/hooks/use-apps.js.map +1 -0
  229. package/dist/hooks/use-automations.d.ts +25 -0
  230. package/dist/hooks/use-automations.d.ts.map +1 -0
  231. package/dist/hooks/use-automations.js +30 -0
  232. package/dist/hooks/use-automations.js.map +1 -0
  233. package/dist/hooks/use-connections.d.ts +12 -0
  234. package/dist/hooks/use-connections.d.ts.map +1 -0
  235. package/dist/hooks/use-connections.js +15 -0
  236. package/dist/hooks/use-connections.js.map +1 -0
  237. package/dist/hooks/use-connector-catalog.d.ts +8 -0
  238. package/dist/hooks/use-connector-catalog.d.ts.map +1 -0
  239. package/dist/hooks/use-connector-catalog.js +52 -0
  240. package/dist/hooks/use-connector-catalog.js.map +1 -0
  241. package/dist/hooks/use-grants.d.ts +13 -0
  242. package/dist/hooks/use-grants.d.ts.map +1 -0
  243. package/dist/hooks/use-grants.js +14 -0
  244. package/dist/hooks/use-grants.js.map +1 -0
  245. package/dist/hooks/use-mobile-takeover.d.ts +22 -0
  246. package/dist/hooks/use-mobile-takeover.d.ts.map +1 -0
  247. package/dist/hooks/use-mobile-takeover.js +66 -0
  248. package/dist/hooks/use-mobile-takeover.js.map +1 -0
  249. package/dist/hooks/use-resource.d.ts +21 -0
  250. package/dist/hooks/use-resource.d.ts.map +1 -0
  251. package/dist/hooks/use-resource.js +79 -0
  252. package/dist/hooks/use-resource.js.map +1 -0
  253. package/dist/hooks/use-slot-app.d.ts +19 -0
  254. package/dist/hooks/use-slot-app.d.ts.map +1 -0
  255. package/dist/hooks/use-slot-app.js +18 -0
  256. package/dist/hooks/use-slot-app.js.map +1 -0
  257. package/dist/hooks/use-threads.d.ts +16 -0
  258. package/dist/hooks/use-threads.d.ts.map +1 -0
  259. package/dist/hooks/use-threads.js +15 -0
  260. package/dist/hooks/use-threads.js.map +1 -0
  261. package/dist/hooks/use-vendo-overlay.d.ts +31 -0
  262. package/dist/hooks/use-vendo-overlay.d.ts.map +1 -0
  263. package/dist/hooks/use-vendo-overlay.js +23 -0
  264. package/dist/hooks/use-vendo-overlay.js.map +1 -0
  265. package/dist/hooks/use-vendo-status.d.ts +6 -0
  266. package/dist/hooks/use-vendo-status.d.ts.map +1 -0
  267. package/dist/hooks/use-vendo-status.js +28 -0
  268. package/dist/hooks/use-vendo-status.js.map +1 -0
  269. package/dist/hooks/use-vendo-thread.d.ts +39 -0
  270. package/dist/hooks/use-vendo-thread.d.ts.map +1 -0
  271. package/dist/hooks/use-vendo-thread.js +185 -0
  272. package/dist/hooks/use-vendo-thread.js.map +1 -0
  273. package/dist/index.d.ts +12 -0
  274. package/dist/index.d.ts.map +1 -0
  275. package/dist/index.js +12 -0
  276. package/dist/index.js.map +1 -0
  277. package/dist/kit/charts/bar.d.ts +16 -0
  278. package/dist/kit/charts/bar.d.ts.map +1 -0
  279. package/dist/kit/charts/bar.js +21 -0
  280. package/dist/kit/charts/bar.js.map +1 -0
  281. package/dist/kit/charts/donut.d.ts +16 -0
  282. package/dist/kit/charts/donut.d.ts.map +1 -0
  283. package/dist/kit/charts/donut.js +17 -0
  284. package/dist/kit/charts/donut.js.map +1 -0
  285. package/dist/kit/charts/line.d.ts +19 -0
  286. package/dist/kit/charts/line.d.ts.map +1 -0
  287. package/dist/kit/charts/line.js +21 -0
  288. package/dist/kit/charts/line.js.map +1 -0
  289. package/dist/kit/charts/progress.d.ts +12 -0
  290. package/dist/kit/charts/progress.d.ts.map +1 -0
  291. package/dist/kit/charts/progress.js +25 -0
  292. package/dist/kit/charts/progress.js.map +1 -0
  293. package/dist/kit/charts/sanitize.d.ts +24 -0
  294. package/dist/kit/charts/sanitize.d.ts.map +1 -0
  295. package/dist/kit/charts/sanitize.js +50 -0
  296. package/dist/kit/charts/sanitize.js.map +1 -0
  297. package/dist/kit/charts/sparkline.d.ts +11 -0
  298. package/dist/kit/charts/sparkline.d.ts.map +1 -0
  299. package/dist/kit/charts/sparkline.js +17 -0
  300. package/dist/kit/charts/sparkline.js.map +1 -0
  301. package/dist/kit/data/badge.d.ts +13 -0
  302. package/dist/kit/data/badge.d.ts.map +1 -0
  303. package/dist/kit/data/badge.js +12 -0
  304. package/dist/kit/data/badge.js.map +1 -0
  305. package/dist/kit/data/card-list.d.ts +23 -0
  306. package/dist/kit/data/card-list.d.ts.map +1 -0
  307. package/dist/kit/data/card-list.js +43 -0
  308. package/dist/kit/data/card-list.js.map +1 -0
  309. package/dist/kit/data/data-table.d.ts +32 -0
  310. package/dist/kit/data/data-table.d.ts.map +1 -0
  311. package/dist/kit/data/data-table.js +153 -0
  312. package/dist/kit/data/data-table.js.map +1 -0
  313. package/dist/kit/data/stat.d.ts +15 -0
  314. package/dist/kit/data/stat.d.ts.map +1 -0
  315. package/dist/kit/data/stat.js +28 -0
  316. package/dist/kit/data/stat.js.map +1 -0
  317. package/dist/kit/feedback/accordion.d.ts +15 -0
  318. package/dist/kit/feedback/accordion.d.ts.map +1 -0
  319. package/dist/kit/feedback/accordion.js +33 -0
  320. package/dist/kit/feedback/accordion.js.map +1 -0
  321. package/dist/kit/feedback/callout.d.ts +13 -0
  322. package/dist/kit/feedback/callout.d.ts.map +1 -0
  323. package/dist/kit/feedback/callout.js +24 -0
  324. package/dist/kit/feedback/callout.js.map +1 -0
  325. package/dist/kit/feedback/tabs.d.ts +14 -0
  326. package/dist/kit/feedback/tabs.d.ts.map +1 -0
  327. package/dist/kit/feedback/tabs.js +37 -0
  328. package/dist/kit/feedback/tabs.js.map +1 -0
  329. package/dist/kit/format.d.ts +60 -0
  330. package/dist/kit/format.d.ts.map +1 -0
  331. package/dist/kit/format.js +123 -0
  332. package/dist/kit/format.js.map +1 -0
  333. package/dist/kit/forms/button.d.ts +17 -0
  334. package/dist/kit/forms/button.d.ts.map +1 -0
  335. package/dist/kit/forms/button.js +33 -0
  336. package/dist/kit/forms/button.js.map +1 -0
  337. package/dist/kit/forms/checkbox.d.ts +9 -0
  338. package/dist/kit/forms/checkbox.d.ts.map +1 -0
  339. package/dist/kit/forms/checkbox.js +9 -0
  340. package/dist/kit/forms/checkbox.js.map +1 -0
  341. package/dist/kit/forms/date-picker.d.ts +13 -0
  342. package/dist/kit/forms/date-picker.d.ts.map +1 -0
  343. package/dist/kit/forms/date-picker.js +9 -0
  344. package/dist/kit/forms/date-picker.js.map +1 -0
  345. package/dist/kit/forms/disclaimer.d.ts +8 -0
  346. package/dist/kit/forms/disclaimer.d.ts.map +1 -0
  347. package/dist/kit/forms/disclaimer.js +20 -0
  348. package/dist/kit/forms/disclaimer.js.map +1 -0
  349. package/dist/kit/forms/field.d.ts +18 -0
  350. package/dist/kit/forms/field.d.ts.map +1 -0
  351. package/dist/kit/forms/field.js +19 -0
  352. package/dist/kit/forms/field.js.map +1 -0
  353. package/dist/kit/forms/form.d.ts +10 -0
  354. package/dist/kit/forms/form.d.ts.map +1 -0
  355. package/dist/kit/forms/form.js +9 -0
  356. package/dist/kit/forms/form.js.map +1 -0
  357. package/dist/kit/forms/input.d.ts +14 -0
  358. package/dist/kit/forms/input.d.ts.map +1 -0
  359. package/dist/kit/forms/input.js +9 -0
  360. package/dist/kit/forms/input.js.map +1 -0
  361. package/dist/kit/forms/select.d.ts +21 -0
  362. package/dist/kit/forms/select.d.ts.map +1 -0
  363. package/dist/kit/forms/select.js +35 -0
  364. package/dist/kit/forms/select.js.map +1 -0
  365. package/dist/kit/forms/textarea.d.ts +12 -0
  366. package/dist/kit/forms/textarea.d.ts.map +1 -0
  367. package/dist/kit/forms/textarea.js +9 -0
  368. package/dist/kit/forms/textarea.js.map +1 -0
  369. package/dist/kit/index.d.ts +42 -0
  370. package/dist/kit/index.d.ts.map +1 -0
  371. package/dist/kit/index.js +45 -0
  372. package/dist/kit/index.js.map +1 -0
  373. package/dist/kit/kit-prompt.d.ts +7 -0
  374. package/dist/kit/kit-prompt.d.ts.map +1 -0
  375. package/dist/kit/kit-prompt.js +7 -0
  376. package/dist/kit/kit-prompt.js.map +1 -0
  377. package/dist/kit/layout.d.ts +29 -0
  378. package/dist/kit/layout.d.ts.map +1 -0
  379. package/dist/kit/layout.js +64 -0
  380. package/dist/kit/layout.js.map +1 -0
  381. package/dist/kit/registry.d.ts +11 -0
  382. package/dist/kit/registry.d.ts.map +1 -0
  383. package/dist/kit/registry.js +34 -0
  384. package/dist/kit/registry.js.map +1 -0
  385. package/dist/kit/schema.d.ts +9 -0
  386. package/dist/kit/schema.d.ts.map +1 -0
  387. package/dist/kit/schema.js +9 -0
  388. package/dist/kit/schema.js.map +1 -0
  389. package/dist/kit/tokens.d.ts +33 -0
  390. package/dist/kit/tokens.d.ts.map +1 -0
  391. package/dist/kit/tokens.js +48 -0
  392. package/dist/kit/tokens.js.map +1 -0
  393. package/dist/kit/values.d.ts +55 -0
  394. package/dist/kit/values.d.ts.map +1 -0
  395. package/dist/kit/values.js +108 -0
  396. package/dist/kit/values.js.map +1 -0
  397. package/dist/theme.d.ts +25 -0
  398. package/dist/theme.d.ts.map +1 -0
  399. package/dist/theme.js +100 -0
  400. package/dist/theme.js.map +1 -0
  401. package/dist/tree/bindings.d.ts +4 -0
  402. package/dist/tree/bindings.d.ts.map +1 -0
  403. package/dist/tree/bindings.js +20 -0
  404. package/dist/tree/bindings.js.map +1 -0
  405. package/dist/tree/branded.d.ts +124 -0
  406. package/dist/tree/branded.d.ts.map +1 -0
  407. package/dist/tree/branded.js +319 -0
  408. package/dist/tree/branded.js.map +1 -0
  409. package/dist/tree/error-boundary.d.ts +22 -0
  410. package/dist/tree/error-boundary.d.ts.map +1 -0
  411. package/dist/tree/error-boundary.js +25 -0
  412. package/dist/tree/error-boundary.js.map +1 -0
  413. package/dist/tree/fluid-reveal.d.ts +22 -0
  414. package/dist/tree/fluid-reveal.d.ts.map +1 -0
  415. package/dist/tree/fluid-reveal.js +28 -0
  416. package/dist/tree/fluid-reveal.js.map +1 -0
  417. package/dist/tree/forming-skeleton.d.ts +14 -0
  418. package/dist/tree/forming-skeleton.d.ts.map +1 -0
  419. package/dist/tree/forming-skeleton.js +36 -0
  420. package/dist/tree/forming-skeleton.js.map +1 -0
  421. package/dist/tree/frames.d.ts +52 -0
  422. package/dist/tree/frames.d.ts.map +1 -0
  423. package/dist/tree/frames.js +143 -0
  424. package/dist/tree/frames.js.map +1 -0
  425. package/dist/tree/host-mount.d.ts +24 -0
  426. package/dist/tree/host-mount.d.ts.map +1 -0
  427. package/dist/tree/host-mount.js +0 -0
  428. package/dist/tree/host-mount.js.map +1 -0
  429. package/dist/tree/index.d.ts +9 -0
  430. package/dist/tree/index.d.ts.map +1 -0
  431. package/dist/tree/index.js +9 -0
  432. package/dist/tree/index.js.map +1 -0
  433. package/dist/tree/jail/JailedComponent.d.ts +41 -0
  434. package/dist/tree/jail/JailedComponent.d.ts.map +1 -0
  435. package/dist/tree/jail/JailedComponent.js +269 -0
  436. package/dist/tree/jail/JailedComponent.js.map +1 -0
  437. package/dist/tree/jail/runtime-bundle.gen.d.ts +3 -0
  438. package/dist/tree/jail/runtime-bundle.gen.d.ts.map +1 -0
  439. package/dist/tree/jail/runtime-bundle.gen.js +3 -0
  440. package/dist/tree/jail/runtime-bundle.gen.js.map +1 -0
  441. package/dist/tree/jail/runtime-entry.d.ts +18 -0
  442. package/dist/tree/jail/runtime-entry.d.ts.map +1 -0
  443. package/dist/tree/jail/runtime-entry.js +440 -0
  444. package/dist/tree/jail/runtime-entry.js.map +1 -0
  445. package/dist/tree/jail/viewport-css.d.ts +17 -0
  446. package/dist/tree/jail/viewport-css.d.ts.map +1 -0
  447. package/dist/tree/jail/viewport-css.js +32 -0
  448. package/dist/tree/jail/viewport-css.js.map +1 -0
  449. package/dist/tree/mcp-shim/entry.d.ts +2 -0
  450. package/dist/tree/mcp-shim/entry.d.ts.map +1 -0
  451. package/dist/tree/mcp-shim/entry.js +45 -0
  452. package/dist/tree/mcp-shim/entry.js.map +1 -0
  453. package/dist/tree/mcp-shim/http-open-card.d.ts +5 -0
  454. package/dist/tree/mcp-shim/http-open-card.d.ts.map +1 -0
  455. package/dist/tree/mcp-shim/http-open-card.js +61 -0
  456. package/dist/tree/mcp-shim/http-open-card.js.map +1 -0
  457. package/dist/tree/mcp-shim/shim-core.d.ts +58 -0
  458. package/dist/tree/mcp-shim/shim-core.d.ts.map +1 -0
  459. package/dist/tree/mcp-shim/shim-core.js +176 -0
  460. package/dist/tree/mcp-shim/shim-core.js.map +1 -0
  461. package/dist/tree/mcp-shim/theme.d.ts +8 -0
  462. package/dist/tree/mcp-shim/theme.d.ts.map +1 -0
  463. package/dist/tree/mcp-shim/theme.js +36 -0
  464. package/dist/tree/mcp-shim/theme.js.map +1 -0
  465. package/dist/tree/notice.d.ts +8 -0
  466. package/dist/tree/notice.d.ts.map +1 -0
  467. package/dist/tree/notice.js +30 -0
  468. package/dist/tree/notice.js.map +1 -0
  469. package/dist/tree/primitives.d.ts +30 -0
  470. package/dist/tree/primitives.d.ts.map +1 -0
  471. package/dist/tree/primitives.js +105 -0
  472. package/dist/tree/primitives.js.map +1 -0
  473. package/dist/tree/renderer-v2.d.ts +15 -0
  474. package/dist/tree/renderer-v2.d.ts.map +1 -0
  475. package/dist/tree/renderer-v2.js +71 -0
  476. package/dist/tree/renderer-v2.js.map +1 -0
  477. package/dist/tree/renderer.d.ts +77 -0
  478. package/dist/tree/renderer.d.ts.map +1 -0
  479. package/dist/tree/renderer.js +376 -0
  480. package/dist/tree/renderer.js.map +1 -0
  481. package/dist/voice/driver.d.ts +94 -0
  482. package/dist/voice/driver.d.ts.map +1 -0
  483. package/dist/voice/driver.js +2 -0
  484. package/dist/voice/driver.js.map +1 -0
  485. package/dist/voice/index.d.ts +7 -0
  486. package/dist/voice/index.d.ts.map +1 -0
  487. package/dist/voice/index.js +5 -0
  488. package/dist/voice/index.js.map +1 -0
  489. package/dist/voice/realtime-driver.d.ts +57 -0
  490. package/dist/voice/realtime-driver.d.ts.map +1 -0
  491. package/dist/voice/realtime-driver.js +592 -0
  492. package/dist/voice/realtime-driver.js.map +1 -0
  493. package/dist/voice/stage.d.ts +12 -0
  494. package/dist/voice/stage.d.ts.map +1 -0
  495. package/dist/voice/stage.js +259 -0
  496. package/dist/voice/stage.js.map +1 -0
  497. package/dist/voice/use-voice-approvals.d.ts +16 -0
  498. package/dist/voice/use-voice-approvals.d.ts.map +1 -0
  499. package/dist/voice/use-voice-approvals.js +77 -0
  500. package/dist/voice/use-voice-approvals.js.map +1 -0
  501. package/dist/voice/use-voice.d.ts +26 -0
  502. package/dist/voice/use-voice.d.ts.map +1 -0
  503. package/dist/voice/use-voice.js +201 -0
  504. package/dist/voice/use-voice.js.map +1 -0
  505. package/dist/voice/voice-act.d.ts +13 -0
  506. package/dist/voice/voice-act.d.ts.map +1 -0
  507. package/dist/voice/voice-act.js +301 -0
  508. package/dist/voice/voice-act.js.map +1 -0
  509. package/dist/voice/voice-blob.d.ts +17 -0
  510. package/dist/voice/voice-blob.d.ts.map +1 -0
  511. package/dist/voice/voice-blob.js +67 -0
  512. package/dist/voice/voice-blob.js.map +1 -0
  513. package/dist/voice/voice-consent.d.ts +17 -0
  514. package/dist/voice/voice-consent.d.ts.map +1 -0
  515. package/dist/voice/voice-consent.js +45 -0
  516. package/dist/voice/voice-consent.js.map +1 -0
  517. package/dist/voice/voice-drawer.d.ts +10 -0
  518. package/dist/voice/voice-drawer.d.ts.map +1 -0
  519. package/dist/voice/voice-drawer.js +22 -0
  520. package/dist/voice/voice-drawer.js.map +1 -0
  521. package/dist/wire-types.d.ts +238 -0
  522. package/dist/wire-types.d.ts.map +1 -0
  523. package/dist/wire-types.js +2 -0
  524. package/dist/wire-types.js.map +1 -0
  525. package/package.json +106 -0
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Ejected from @vendoai/ui v0.4.0 — yours to edit.
3
+ * Presentation only: data and wire logic still flow through @vendoai/ui
4
+ * imports, so protocol updates keep working while these pixels are yours.
5
+ */
6
+ import type { RiskLabel } from "@vendoai/core";
7
+ import type { UIMessage } from "ai";
8
+ import type { ComponentProps } from "react";
9
+ import { FluidThinking } from "../fluid-thinking.js";
10
+ import { ThreadMessage } from "./message.js";
11
+ import { ThreadApprovals, ThreadConnectRequests } from "./parts.js";
12
+ import type { useMessageWindow, useStickToBottom } from "./scrolling.js";
13
+
14
+ /** The transcript pane: the windowed message list (ENG-218), parked approval
15
+ and connect cards, the ENG-217 streaming indicators, and the jump-to-latest
16
+ affordance (ENG-213). Pure presentation over the thread-level state. */
17
+ export function MessageList({
18
+ scroll, messageWindow, busy, risks, isRestored,
19
+ activeAssistantId, lastUserId, lastAssistantId, onEditLast, onRegenerateLast,
20
+ approvals, guardApprovals, cardRefs, respond, onMorph,
21
+ messages, sendMessage, awaitingFirstChunk, working,
22
+ }: {
23
+ scroll: ReturnType<typeof useStickToBottom>;
24
+ messageWindow: ReturnType<typeof useMessageWindow>;
25
+ busy: boolean;
26
+ risks: Map<string, RiskLabel>;
27
+ isRestored: (id: string) => boolean;
28
+ activeAssistantId?: string | undefined;
29
+ lastUserId?: string | undefined;
30
+ lastAssistantId?: string | undefined;
31
+ onEditLast: () => void;
32
+ onRegenerateLast: () => void;
33
+ approvals: ComponentProps<typeof ThreadApprovals>["approvals"];
34
+ guardApprovals: ComponentProps<typeof ThreadApprovals>["guardApprovals"];
35
+ cardRefs: ComponentProps<typeof ThreadApprovals>["cardRefs"];
36
+ respond: ComponentProps<typeof ThreadApprovals>["respond"];
37
+ onMorph: ComponentProps<typeof ThreadApprovals>["onMorph"];
38
+ messages: UIMessage[];
39
+ sendMessage: ComponentProps<typeof ThreadConnectRequests>["sendMessage"];
40
+ awaitingFirstChunk: boolean;
41
+ working: boolean;
42
+ }) {
43
+ return (
44
+ <div className="fl-msglist-wrap">
45
+ {/* role="log" — aria-label is prohibited on a roleless div (WCAG 4.1.2), and a
46
+ streaming message list is exactly what "log" names. */}
47
+ <div
48
+ className="fl-msglist"
49
+ role="log"
50
+ aria-label="Conversation messages"
51
+ aria-live="polite"
52
+ aria-busy={busy}
53
+ ref={scroll.listRef}
54
+ onScroll={() => { scroll.onScroll(); messageWindow.onNearTop(); }}
55
+ >
56
+ {messageWindow.hasOlder ? (
57
+ <button
58
+ type="button"
59
+ className="fl-load-older"
60
+ onClick={messageWindow.loadOlder}
61
+ >
62
+ Show {messageWindow.olderCount} earlier message{messageWindow.olderCount === 1 ? "" : "s"}
63
+ </button>
64
+ ) : null}
65
+ {messageWindow.windowed.map(message => (
66
+ <ThreadMessage
67
+ key={message.id}
68
+ message={message}
69
+ restored={isRestored(message.id)}
70
+ risks={risks}
71
+ busy={busy}
72
+ activeAssistantId={activeAssistantId}
73
+ lastUserId={lastUserId}
74
+ lastAssistantId={lastAssistantId}
75
+ onEditLast={onEditLast}
76
+ onRegenerateLast={onRegenerateLast}
77
+ />
78
+ ))}
79
+ <ThreadApprovals
80
+ approvals={approvals}
81
+ risks={risks}
82
+ guardApprovals={guardApprovals}
83
+ cardRefs={cardRefs}
84
+ respond={respond}
85
+ onMorph={onMorph}
86
+ />
87
+ <ThreadConnectRequests messages={messages} sendMessage={sendMessage} />
88
+ {awaitingFirstChunk ? (
89
+ <>
90
+ <div className="fl-generating">
91
+ <span className="fl-pulse" aria-hidden="true" />
92
+ Generating&hellip;
93
+ </div>
94
+ <div className="fl-skeleton" aria-hidden="true">
95
+ <div className="fl-skeleton-bar" />
96
+ <div className="fl-skeleton-bar" />
97
+ <div className="fl-skeleton-bar" />
98
+ </div>
99
+ </>
100
+ ) : null}
101
+ {working ? <FluidThinking label="Working" /> : null}
102
+ </div>
103
+ {/* Lane picks 3A + 6B — the jump affordance is a docked bar with a
104
+ count and snippet ("2 new replies · …"); at mobile widths the same
105
+ element re-clothes as a bottom-center pill (pure CSS, see the lane
106
+ block in chrome-css). Activating it is the same re-stick as before. */}
107
+ {scroll.showJump ? (
108
+ <button
109
+ type="button"
110
+ className="fl-newbar"
111
+ aria-label={`Jump to latest — ${scroll.unseenCount === 1 ? "1 new reply" : `${scroll.unseenCount} new replies`}`}
112
+ onClick={scroll.jumpToLatest}
113
+ >
114
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
115
+ <path d="M12 5v14" /><path d="m19 12-7 7-7-7" />
116
+ </svg>
117
+ {scroll.unseenCount === 1 ? "1 new reply" : `${scroll.unseenCount} new replies`}
118
+ {scroll.snippet ? <small>{scroll.snippet}</small> : null}
119
+ </button>
120
+ ) : null}
121
+ </div>
122
+ );
123
+ }
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Ejected from @vendoai/ui v0.4.0 — yours to edit.
3
+ * Presentation only: data and wire logic still flow through @vendoai/ui
4
+ * imports, so protocol updates keep working while these pixels are yours.
5
+ */
6
+ import type { RiskLabel } from "@vendoai/core";
7
+ import { isToolUIPart, type UIMessage } from "ai";
8
+ import { Fragment } from "react";
9
+ import { useVendoContext } from "../../context.js";
10
+ import { useCopyFeedback } from "../clipboard.js";
11
+ import { toolTitle } from "../humanize.js";
12
+ import { SentAttachment, type FilePart } from "./attachments.js";
13
+ import { assistantText, collapseToolRuns, toolName, userText } from "./message-data.js";
14
+ import { ThreadPart } from "./parts.js";
15
+
16
+ /** Lane pick 8C — the settled turn's quiet sources row: every completed tool
17
+ call the turn drew on, as informational chips ("what did it read?"). The
18
+ full mechanical record stays in the Activity panel; these are the in-place
19
+ scent. Only read-risk calls qualify — writes are actions, not sources. */
20
+ function TurnSources({ message, risks }: { message: UIMessage; risks: Map<string, RiskLabel> }) {
21
+ const { tools } = useVendoContext();
22
+ // Identical repeated calls collapse to one chip with a ×N count — the same
23
+ // ENG-216 run-collapse identity (name + args) the old beat stack used.
24
+ const sources = collapseToolRuns(message.parts).filter(({ part }) =>
25
+ isToolUIPart(part) && part.state === "output-available"
26
+ && (risks.get(part.toolCallId) ?? "read") === "read");
27
+ if (sources.length === 0) return null;
28
+ return (
29
+ <div className="fl-sources" aria-label="Sources">
30
+ {sources.map(({ part, count }) => {
31
+ const toolPart = part as Extract<UIMessage["parts"][number], { toolCallId: string }>;
32
+ const name = toolName(toolPart);
33
+ return (
34
+ <span className="fl-source" key={toolPart.toolCallId} title="Recorded in Activity">
35
+ <i aria-hidden="true" />
36
+ {toolTitle(name, tools[name])}
37
+ {count > 1 ? <span className="fl-source-count" aria-label={`repeated ${count} times`}>×{count}</span> : null}
38
+ </span>
39
+ );
40
+ })}
41
+ </div>
42
+ );
43
+ }
44
+
45
+ /** ENG-225 — the copy turn action (.fl-turn-actions design). */
46
+ function CopyTurnButton({ text }: { text: string }) {
47
+ const [copied, copy] = useCopyFeedback();
48
+ return (
49
+ <button type="button" className="fl-turn-btn" aria-label="Copy message" onClick={() => copy(text)}>
50
+ {copied ? (
51
+ <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
52
+ <path d="M20 6 9 17l-5-5" />
53
+ </svg>
54
+ ) : (
55
+ <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
56
+ <rect width="13" height="13" x="9" y="9" rx="2" /><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
57
+ </svg>
58
+ )}
59
+ {copied ? "Copied" : "Copy"}
60
+ </button>
61
+ );
62
+ }
63
+
64
+ /** One turn in the transcript: the user attachments beside the bubble
65
+ (ENG-225), the article with its stream parts, and the settled-turn
66
+ actions (Copy always; Edit on the last user turn, Regenerate on the
67
+ last assistant turn — ENG-215). */
68
+ export function ThreadMessage({ message, restored, risks, busy, activeAssistantId, lastUserId, lastAssistantId, onEditLast, onRegenerateLast }: {
69
+ message: UIMessage;
70
+ restored: boolean;
71
+ risks: Map<string, RiskLabel>;
72
+ busy: boolean;
73
+ activeAssistantId?: string | undefined;
74
+ lastUserId?: string | undefined;
75
+ lastAssistantId?: string | undefined;
76
+ onEditLast: () => void;
77
+ onRegenerateLast: () => void;
78
+ }) {
79
+ // ENG-225 — a user turn's attachments render BESIDE the bubble
80
+ // (the designed .fl-turn-user-att block), not inside it; a
81
+ // files-only send has no bubble at all.
82
+ const sentFiles = message.role === "user"
83
+ ? message.parts.filter((part): part is FilePart => part.type === "file")
84
+ : [];
85
+ const bubbleText = message.role === "user" ? userText(message) : assistantText(message);
86
+ const skipBubble = message.role === "user" && bubbleText.length === 0
87
+ && message.parts.every(part => part.type === "file");
88
+ // ENG-225 — every settled turn carries a Copy action (hover-
89
+ // revealed, see chrome-css); Edit stays on the last user turn and
90
+ // Regenerate on the last assistant turn (ENG-215). The actively
91
+ // streaming turn gets no actions — its text is still arriving.
92
+ const streamingTurn = busy && message.role === "assistant" && message.id === activeAssistantId;
93
+ const showEdit = !busy && message.role === "user" && message.id === lastUserId;
94
+ const showRegenerate = !busy && message.role === "assistant" && message.id === lastAssistantId;
95
+ const showActions = !streamingTurn && (bubbleText.length > 0 || showEdit || showRegenerate);
96
+ return (
97
+ <Fragment>
98
+ {sentFiles.length > 0 ? (
99
+ <div className={`fl-turn-user-att${restored ? " fl-no-entrance" : ""}`}>
100
+ {sentFiles.map((part, index) => <SentAttachment key={index} part={part} />)}
101
+ </div>
102
+ ) : null}
103
+ {skipBubble ? null : (
104
+ <article
105
+ className={`${message.role === "user" ? "fl-turn-user" : "fl-turn-assistant"}${
106
+ restored ? " fl-no-entrance" : ""}`}
107
+ data-role={message.role}
108
+ aria-label={`${message.role} message`}
109
+ >
110
+ {collapseToolRuns(message.parts).map(({ part, index, count }) => (
111
+ <ThreadPart
112
+ key={`${message.id}-${index}`}
113
+ part={part}
114
+ partKey={`${message.id}-${index}`}
115
+ role={message.role}
116
+ restored={restored}
117
+ count={count}
118
+ risks={risks}
119
+ />
120
+ ))}
121
+ {!streamingTurn && message.role === "assistant" ? (
122
+ <TurnSources message={message} risks={risks} />
123
+ ) : null}
124
+ {showActions ? (
125
+ <div className="fl-turn-actions">
126
+ {bubbleText.length > 0 ? <CopyTurnButton text={bubbleText} /> : null}
127
+ {showEdit ? (
128
+ <button type="button" className="fl-turn-btn" aria-label="Edit message" onClick={onEditLast}>
129
+ <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
130
+ <path d="M12 20h9" /><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z" />
131
+ </svg>
132
+ Edit
133
+ </button>
134
+ ) : null}
135
+ {showRegenerate ? (
136
+ <button type="button" className="fl-turn-btn" aria-label="Regenerate" onClick={onRegenerateLast}>
137
+ <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
138
+ <path d="M3 12a9 9 0 0 1 15-6.7L21 8" /><path d="M21 3v5h-5" /><path d="M21 12a9 9 0 0 1-15 6.7L3 16" /><path d="M3 21v-5h5" />
139
+ </svg>
140
+ Regenerate
141
+ </button>
142
+ ) : null}
143
+ </div>
144
+ ) : null}
145
+ </article>
146
+ )}
147
+ </Fragment>
148
+ );
149
+ }
@@ -0,0 +1,293 @@
1
+ /**
2
+ * Ejected from @vendoai/ui v0.4.0 — yours to edit.
3
+ * Presentation only: data and wire logic still flow through @vendoai/ui
4
+ * imports, so protocol updates keep working while these pixels are yours.
5
+ */
6
+ import type { ApprovalRequest, Json, RiskLabel, VendoViewPart } from "@vendoai/core";
7
+ import { isToolUIPart, type UIMessage } from "ai";
8
+ import { useState } from "react";
9
+ import { useVendoContext } from "../../context.js";
10
+ import { useMobileTakeover } from "../../hooks/use-mobile-takeover.js";
11
+ import { PayloadView } from "../../tree/renderer.js";
12
+ import { ApprovalCard } from "../approval-card.js";
13
+ import { ApprovalSheet } from "../approval-sheet.js";
14
+ import { BuildBeat, toolPresentation } from "../build-beat.js";
15
+ import { ConnectCard } from "../connect-card.js";
16
+ import { toolTitle } from "../humanize.js";
17
+ import { Markdown } from "../markdown.js";
18
+ import type { MorphToastProps } from "../morph-toast.js";
19
+ import { LONG_TEXT_CAP, truncateHead } from "../truncate.js";
20
+ import { SentAttachment } from "./attachments.js";
21
+ import {
22
+ appTitle,
23
+ partData,
24
+ preview,
25
+ SYNTHESIZED_CREATED_AT,
26
+ toolName,
27
+ } from "./message-data.js";
28
+
29
+ /** ENG-218 — a plain user turn (rendered verbatim, not markdown) collapses when
30
+ huge so a pasted log doesn't flood the thread with DOM. Assistant turns get
31
+ the same treatment inside <Markdown>. */
32
+ function UserText({ text, restored }: { text: string; restored?: boolean }) {
33
+ const [expanded, setExpanded] = useState(false);
34
+ const collapsible = restored === true && text.length > LONG_TEXT_CAP;
35
+ const shown = collapsible && !expanded ? truncateHead(text) : text;
36
+ if (!collapsible) return <div className="fl-usertext">{text}</div>;
37
+ // Lane pick 3D — the collapsed head sits under a gradient fade with a
38
+ // centered pill (GitHub-fold style) instead of a hard cut + inline link:
39
+ // the fade shows the content continues, and the control sits where the
40
+ // eye stops. Expanded keeps the pill below for symmetry.
41
+ return (
42
+ <div className={`fl-fold${expanded ? " fl-fold--open" : ""}`}>
43
+ <div className="fl-usertext">{shown}</div>
44
+ <div className="fl-fold-veil">
45
+ <button type="button" className="fl-more fl-fold-pill" aria-expanded={expanded} onClick={() => setExpanded(value => !value)}>
46
+ {expanded ? "Show less" : `Show full message (${(text.length / 1000).toFixed(0)}k chars)`}
47
+ </button>
48
+ </div>
49
+ </div>
50
+ );
51
+ }
52
+
53
+ /** One stream part in a turn: text (user verbatim / assistant markdown with the
54
+ ENG-217 caret choreography), assistant files, tool build beats, and the
55
+ jailed generated-view app card (06-apps §§8–9). */
56
+ export function ThreadPart({ part, partKey, role, restored, count = 1, risks }: {
57
+ part: UIMessage["parts"][number];
58
+ partKey: string;
59
+ role: UIMessage["role"];
60
+ restored: boolean;
61
+ count?: number;
62
+ risks: Map<string, RiskLabel>;
63
+ }) {
64
+ const { client, components, onPin } = useVendoContext();
65
+ if (part.type === "text") {
66
+ if (role === "user") return <UserText text={part.text} restored={restored} />;
67
+ // ENG-217 — lone caret while the streamed turn is still empty (stable
68
+ // line box); once text flows, Markdown's .fl-md--streaming trailing
69
+ // caret takes over.
70
+ if (part.state === "streaming" && part.text.trim().length === 0) {
71
+ return <span className="fl-caret" aria-hidden="true" />;
72
+ }
73
+ return <Markdown text={part.text} streaming={part.state === "streaming"} restored={restored} />;
74
+ }
75
+ if (part.type === "file") {
76
+ // ENG-225 — user attachments render beside the bubble (see the message
77
+ // map); an assistant-authored file lands inline in the turn.
78
+ if (role === "user") return null;
79
+ return <SentAttachment part={part} />;
80
+ }
81
+ if (isToolUIPart(part)) {
82
+ // Lane pick C1 — live progress moved to the StatusRibbon above the
83
+ // composer, so working/done calls leave NO transcript line (the
84
+ // mechanical record stays in the Activity panel). A FAILED call is
85
+ // content, not progress: it keeps the error beat so the failure stays
86
+ // readable after the turn settles.
87
+ if (part.state !== "output-error") return null;
88
+ const risk = risks.get(part.toolCallId) ?? "read";
89
+ return <BuildBeat part={part} risk={risk} count={count} />;
90
+ }
91
+ if (part.type === "data-vendo-view") {
92
+ const data = partData(part) as Partial<VendoViewPart>;
93
+ if (typeof data.appId !== "string" || !data.payload) return null;
94
+ // 06-apps §§8–9 — in-thread surfaces are conversational previews, never
95
+ // the approved in-client venue and never a drift report: both fields are
96
+ // server-authoritative, so whatever the stream carried, render jailed
97
+ // and notice-free.
98
+ const {
99
+ inClient: _neverInThread,
100
+ pinDrift: _serverOnly,
101
+ ...payload
102
+ } = data.payload as typeof data.payload & { inClient?: unknown; pinDrift?: unknown };
103
+ const streaming = (payload as { streaming?: boolean }).streaming === true;
104
+ const appId = data.appId;
105
+ return (
106
+ // The generated view lives inside a clear app boundary — a titled
107
+ // frame — so it reads as a distinct piece of software, not loose
108
+ // content bleeding into the surrounding chat text.
109
+ <div className="fl-uihost fl-appcard" key={`${partKey}-${appId}`}>
110
+ {/* Pick C (ui-lane-renderer): the bar narrates forming → live. The
111
+ data-state contract ("building" | "ready") is shared with the
112
+ thread lane; the label pair stays mounted so the swap crossfades. */}
113
+ <div className="fl-appcard-bar" data-state={streaming ? "building" : "ready"}>
114
+ <span className="fl-appcard-dot" aria-hidden="true" />
115
+ <span className="fl-boot-labels fl-appcard-name">
116
+ {/* Both labels stay mounted for the renderer lane's crossfade;
117
+ aria-hidden tracks data-state so screen readers hear only the
118
+ ACTIVE one (AI-review catch — the CSS-faded label was still
119
+ announced, including a stale "Building…" after ready). */}
120
+ <span className="fl-boot-building" aria-hidden={!streaming}>Building your view…</span>
121
+ <span className="fl-boot-ready" aria-hidden={streaming}>{appTitle(payload) ?? "Your app"}</span>
122
+ </span>
123
+ {/* Lane pick C5 (5A+5D) — the pin lives ON the bar (visible only once
124
+ the view is ready), replacing the old full-width footer row. The
125
+ renderer lane's data-state/label/hairline markup above is the
126
+ shared contract and stays untouched. */}
127
+ {!streaming && onPin ? (
128
+ <button
129
+ type="button"
130
+ className="fl-barpin"
131
+ onClick={() => onPin({ appId, payload })}
132
+ >
133
+ <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
134
+ <path d="M12 17v5M9 3h6l-1 7 3 3H7l3-3-1-7Z" />
135
+ </svg>
136
+ Pin to dashboard
137
+ </button>
138
+ ) : null}
139
+ <span className="fl-boot-hairline" aria-hidden="true" />
140
+ </div>
141
+ <div className="fl-appcard-body">
142
+ <PayloadView
143
+ payload={payload}
144
+ components={components}
145
+ onAction={({ action, payload: actionPayload }) => client.apps.call(appId, action, actionPayload ?? {})}
146
+ />
147
+ </div>
148
+ </div>
149
+ );
150
+ }
151
+ return null;
152
+ }
153
+
154
+ type ToolPart = Extract<UIMessage["parts"][number], { toolCallId: string }>;
155
+
156
+ /** The parked in-thread approval cards: each synthesizes an ApprovalRequest
157
+ from the wire parts (ENG-216), morphs into the top-right toast on approve
158
+ (ENG-205), and decides the guard's record over the wire before resuming
159
+ the model loop (05 §1). */
160
+ export function ThreadApprovals({ approvals, risks, guardApprovals, cardRefs, respond, onMorph }: {
161
+ approvals: (ToolPart & { state: "approval-requested"; approval: { id: string } })[];
162
+ risks: Map<string, RiskLabel>;
163
+ guardApprovals: Map<string, { approvalId?: string; invalidatedGrant?: ApprovalRequest["invalidatedGrant"] }>;
164
+ cardRefs: React.MutableRefObject<Map<string, HTMLDivElement | null>>;
165
+ respond: (response: { id: string; approved: boolean }) => void;
166
+ onMorph: (morph: Omit<MorphToastProps, "onDone">) => void;
167
+ }) {
168
+ const { client, theme, tools } = useVendoContext();
169
+ // Lane pick 1-H — below the mobile breakpoint the NEWEST parked approval
170
+ // presents as a bottom sheet (thumb-zone consent); older parked ones stay
171
+ // in-list behind it so the thread record is complete when the sheet closes.
172
+ const mobile = useMobileTakeover().active;
173
+ return (
174
+ <>
175
+ {approvals.map((part, index) => {
176
+ const risk = risks.get(part.toolCallId) ?? "read";
177
+ const input = "input" in part ? part.input : undefined;
178
+ const guardApproval = guardApprovals.get(part.toolCallId);
179
+ const name = toolName(part);
180
+ const approval: ApprovalRequest = {
181
+ id: part.approval.id,
182
+ call: { id: part.toolCallId, tool: name, args: input as Json },
183
+ // The wire approval part carries no descriptor (01-core), so the
184
+ // name is the raw tool id (ApprovalCard humanizes it) and the
185
+ // description is left to host metadata — never a fabricated
186
+ // "Approve <tool>" sentence.
187
+ descriptor: { name, description: tools[name]?.description ?? "", inputSchema: {}, risk },
188
+ inputPreview: preview(input),
189
+ ...(guardApproval?.invalidatedGrant === undefined
190
+ ? {}
191
+ : { invalidatedGrant: guardApproval.invalidatedGrant }),
192
+ // ENG-216 — the in-thread card renders inside the live conversation,
193
+ // which IS its context, and the wire carries no ctx: rather than
194
+ // invent a principal/venue/presence and stamp a per-render `new
195
+ // Date()`, we hide the context byline in-thread (showContext=false)
196
+ // and only structurally-true, stable values ride here (never shown).
197
+ ctx: { principal: { kind: "user", subject: "" }, venue: "chat", presence: "present" },
198
+ createdAt: SYNTHESIZED_CREATED_AT,
199
+ };
200
+ const guardApprovalId = guardApproval?.approvalId;
201
+ const asSheet = mobile && index === approvals.length - 1;
202
+ const card = (
203
+ <div key={part.approval.id} ref={element => { cardRefs.current.set(part.approval.id, element); }}>
204
+ <ApprovalCard
205
+ approval={approval}
206
+ showContext={false}
207
+ allowRemember={guardApprovalId !== undefined}
208
+ onDecide={async decision => {
209
+ // The approved card lifts into the top-right notification
210
+ // (ENG-205 morph) as the run resumes underneath it.
211
+ if (decision.approve) {
212
+ const card = cardRefs.current.get(part.approval.id)?.querySelector<HTMLElement>(".fl-approval");
213
+ if (card) {
214
+ const presentation = toolPresentation(name, input, tools[name]);
215
+ const rect = card.getBoundingClientRect();
216
+ card.style.transition = "opacity .22s ease";
217
+ card.style.opacity = "0";
218
+ onMorph({
219
+ startRect: { top: rect.top, left: rect.left, width: rect.width, height: rect.height },
220
+ title: `${presentation.title} — approved`,
221
+ sub: presentation.sub ?? "Runs as you · recorded in Activity",
222
+ logoUrl: presentation.logoUrl,
223
+ theme,
224
+ });
225
+ }
226
+ }
227
+ // Decide the guard's approval record over the wire FIRST so the
228
+ // resumed execution replays as approved (05 §1) — the native
229
+ // response alone only tells the model loop to continue.
230
+ if (guardApprovalId !== undefined) {
231
+ await client.approvals.decide([guardApprovalId], decision);
232
+ }
233
+ respond({ id: part.approval.id, approved: decision.approve });
234
+ }}
235
+ />
236
+ </div>
237
+ );
238
+ return asSheet ? (
239
+ <ApprovalSheet key={part.approval.id} label={`Approval for ${toolTitle(name, tools[name])}`}>
240
+ {card}
241
+ </ApprovalSheet>
242
+ ) : card;
243
+ })}
244
+ </>
245
+ );
246
+ }
247
+
248
+ /** 04-actions §3 — connector calls that ended `connect-required`, from the
249
+ LAST assistant message only: a stale turn must not re-offer a connect
250
+ (the persistent panel covers standing management). The typed outcome on
251
+ the native tool part is the source of truth; the data-vendo-connect part
252
+ mirrors it for streaming consumers, matching the approvals pattern. */
253
+ export function ThreadConnectRequests({ messages, sendMessage }: {
254
+ messages: UIMessage[];
255
+ sendMessage: (message: { text: string }) => unknown;
256
+ }) {
257
+ const lastMessage = messages.at(-1);
258
+ const connectRequests = (lastMessage?.role === "assistant" ? lastMessage.parts : [])
259
+ .filter(isToolUIPart)
260
+ .flatMap(part => {
261
+ if (part.state !== "output-available") return [];
262
+ const output = part.output as { status?: unknown; connect?: unknown } | undefined;
263
+ const connect = output?.status === "connect-required"
264
+ ? output.connect as { connector?: unknown; toolkit?: unknown; message?: unknown } | undefined
265
+ : undefined;
266
+ if (typeof connect?.connector !== "string" || typeof connect.toolkit !== "string") return [];
267
+ return [{
268
+ part,
269
+ connector: connect.connector,
270
+ toolkit: connect.toolkit,
271
+ message: typeof connect.message === "string" ? connect.message : `Connect ${connect.toolkit} to continue.`,
272
+ }];
273
+ });
274
+ return (
275
+ <>
276
+ {connectRequests.map(({ part, connector, toolkit, message }) => (
277
+ <ConnectCard
278
+ key={`connect-${part.toolCallId}`}
279
+ connector={connector}
280
+ toolkit={toolkit}
281
+ message={message}
282
+ onConnected={() => {
283
+ // The retry: the account is live, so continue the turn — the
284
+ // model re-issues the call, which now executes.
285
+ void sendMessage({
286
+ text: `I connected my ${toolkit} account — retry ${toolName(part)}.`,
287
+ });
288
+ }}
289
+ />
290
+ ))}
291
+ </>
292
+ );
293
+ }