@larkup/workspace-app 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (440) hide show
  1. package/LICENSE +176 -0
  2. package/README.md +4 -2
  3. package/assets/github.svg +3 -0
  4. package/assets/icons/Confluence.png +0 -0
  5. package/assets/icons/Instagram.png +0 -0
  6. package/assets/icons/Northflank.png +0 -0
  7. package/assets/icons/Salesforce.png +0 -0
  8. package/assets/icons/agentskills.png +0 -0
  9. package/assets/icons/airtable.png +0 -0
  10. package/assets/icons/asana.png +0 -0
  11. package/assets/icons/ashby.png +0 -0
  12. package/assets/icons/audio.png +0 -0
  13. package/assets/icons/aws-kendra.png +0 -0
  14. package/assets/icons/aws.svg +38 -0
  15. package/assets/icons/azure-ai-search.png +0 -0
  16. package/assets/icons/azure.svg +1 -0
  17. package/assets/icons/bigquery.png +0 -0
  18. package/assets/icons/bing.png +0 -0
  19. package/assets/icons/bitbucket.png +0 -0
  20. package/assets/icons/brave.png +0 -0
  21. package/assets/icons/browserbase.png +0 -0
  22. package/assets/icons/calendly.png +0 -0
  23. package/assets/icons/chroma.png +0 -0
  24. package/assets/icons/cloudflare.png +0 -0
  25. package/assets/icons/cohere.svg +30 -0
  26. package/assets/icons/databricks.png +0 -0
  27. package/assets/icons/daytonaio.png +0 -0
  28. package/assets/icons/daytonaio2.png +0 -0
  29. package/assets/icons/deepgram.png +0 -0
  30. package/assets/icons/deepl.png +0 -0
  31. package/assets/icons/digital-ocean.webp +0 -0
  32. package/assets/icons/discord.png +0 -0
  33. package/assets/icons/e2b-2.png +0 -0
  34. package/assets/icons/e2b.png +0 -0
  35. package/assets/icons/elevenlabs.png +0 -0
  36. package/assets/icons/email.png +0 -0
  37. package/assets/icons/exa.png +0 -0
  38. package/assets/icons/excel.png +0 -0
  39. package/assets/icons/fal.png +0 -0
  40. package/assets/icons/firecrawl.png +0 -0
  41. package/assets/icons/firecrawl2.png +0 -0
  42. package/assets/icons/flyio.jpeg +0 -0
  43. package/assets/icons/gcp.svg +1 -0
  44. package/assets/icons/gemini.svg +1 -0
  45. package/assets/icons/gmail.png +0 -0
  46. package/assets/icons/google-analytics.png +0 -0
  47. package/assets/icons/google-calender.png +0 -0
  48. package/assets/icons/google-docs.png +0 -0
  49. package/assets/icons/google-drive.png +0 -0
  50. package/assets/icons/google-maps.png +0 -0
  51. package/assets/icons/google-meet.png +0 -0
  52. package/assets/icons/google-sheets.png +0 -0
  53. package/assets/icons/google-slides.png +0 -0
  54. package/assets/icons/google-tasks.png +0 -0
  55. package/assets/icons/google.png +0 -0
  56. package/assets/icons/grok.png +0 -0
  57. package/assets/icons/hubspot.png +0 -0
  58. package/assets/icons/image.png +0 -0
  59. package/assets/icons/jina.svg +1 -0
  60. package/assets/icons/jira.png +0 -0
  61. package/assets/icons/lancedb2.png +0 -0
  62. package/assets/icons/linear.png +0 -0
  63. package/assets/icons/linux.png +0 -0
  64. package/assets/icons/looker.png +0 -0
  65. package/assets/icons/luma.png +0 -0
  66. package/assets/icons/mac.png +0 -0
  67. package/assets/icons/markdown.png +0 -0
  68. package/assets/icons/mcp.png +0 -0
  69. package/assets/icons/mcp.svg +1 -0
  70. package/assets/icons/messenger.svg +1 -0
  71. package/assets/icons/microsoft-intra.png +0 -0
  72. package/assets/icons/microsoft-onenote.png +0 -0
  73. package/assets/icons/microsoft-planner.png +0 -0
  74. package/assets/icons/microsoft-teams.png +0 -0
  75. package/assets/icons/miro.png +0 -0
  76. package/assets/icons/mistral.svg +469 -0
  77. package/assets/icons/modal.png +0 -0
  78. package/assets/icons/ngrok.png +0 -0
  79. package/assets/icons/nomic.png +0 -0
  80. package/assets/icons/onedrive.png +0 -0
  81. package/assets/icons/openai.svg +1 -0
  82. package/assets/icons/outlook-calendar.png +0 -0
  83. package/assets/icons/outlook-email.png +0 -0
  84. package/assets/icons/outlook.png +0 -0
  85. package/assets/icons/pdf.png +0 -0
  86. package/assets/icons/personio.png +0 -0
  87. package/assets/icons/pgvector2.png +0 -0
  88. package/assets/icons/phone.png +0 -0
  89. package/assets/icons/pinecone.png +0 -0
  90. package/assets/icons/pipedrive.png +0 -0
  91. package/assets/icons/power-pi.png +0 -0
  92. package/assets/icons/pylon.png +0 -0
  93. package/assets/icons/python.png +0 -0
  94. package/assets/icons/qdrant.svg +35 -0
  95. package/assets/icons/revai.png +0 -0
  96. package/assets/icons/revai.svg +1 -0
  97. package/assets/icons/sap.png +0 -0
  98. package/assets/icons/serpapi.svg +34 -0
  99. package/assets/icons/serper.png +0 -0
  100. package/assets/icons/servicenow.png +0 -0
  101. package/assets/icons/sharepoint.png +0 -0
  102. package/assets/icons/slack.png +0 -0
  103. package/assets/icons/snowflake.png +0 -0
  104. package/assets/icons/statistia.png +0 -0
  105. package/assets/icons/stripe.png +0 -0
  106. package/assets/icons/supabase.png +0 -0
  107. package/assets/icons/tableau.png +0 -0
  108. package/assets/icons/tavily.png +0 -0
  109. package/assets/icons/telegram.png +0 -0
  110. package/assets/icons/typescript.png +0 -0
  111. package/assets/icons/vercel copy.svg +1 -0
  112. package/assets/icons/vercel.svg +1 -0
  113. package/assets/icons/vertex-ai.png +0 -0
  114. package/assets/icons/video.png +0 -0
  115. package/assets/icons/voyage-light.png +0 -0
  116. package/assets/icons/weaviate.webp +0 -0
  117. package/assets/icons/webcontainers.svg +11 -0
  118. package/assets/icons/webhook.png +0 -0
  119. package/assets/icons/whatsapp copy.png +0 -0
  120. package/assets/icons/whatsapp.png +0 -0
  121. package/assets/icons/windows.png +0 -0
  122. package/assets/icons/word.png +0 -0
  123. package/assets/icons/zendesk.png +0 -0
  124. package/assets/icons/zoom.png +0 -0
  125. package/assets/notion-white.png +0 -0
  126. package/assets/notion.png +0 -0
  127. package/dist-types/asset-server.d.ts +3 -0
  128. package/dist-types/asset-server.d.ts.map +1 -0
  129. package/dist-types/components/alerts/generic-alert.d.ts +15 -0
  130. package/dist-types/components/alerts/generic-alert.d.ts.map +1 -0
  131. package/dist-types/components/chat/canvas/doc-editor-provider.d.ts +62 -0
  132. package/dist-types/components/chat/canvas/doc-editor-provider.d.ts.map +1 -0
  133. package/dist-types/components/chat/canvas/document-canvas.d.ts +7 -0
  134. package/dist-types/components/chat/canvas/document-canvas.d.ts.map +1 -0
  135. package/dist-types/components/chat/canvas/document-field.d.ts +13 -0
  136. package/dist-types/components/chat/canvas/document-field.d.ts.map +1 -0
  137. package/dist-types/components/chat/canvas/document-viewer.d.ts +2 -0
  138. package/dist-types/components/chat/canvas/document-viewer.d.ts.map +1 -0
  139. package/dist-types/components/chat/canvas/file-attachment-button.d.ts +9 -0
  140. package/dist-types/components/chat/canvas/file-attachment-button.d.ts.map +1 -0
  141. package/dist-types/components/chat/chat-workspace.d.ts +4 -0
  142. package/dist-types/components/chat/chat-workspace.d.ts.map +1 -0
  143. package/dist-types/components/chat/message-actions.d.ts +11 -0
  144. package/dist-types/components/chat/message-actions.d.ts.map +1 -0
  145. package/dist-types/components/chat/message-item.d.ts +20 -0
  146. package/dist-types/components/chat/message-item.d.ts.map +1 -0
  147. package/dist-types/components/chat/message-queue.d.ts +15 -0
  148. package/dist-types/components/chat/message-queue.d.ts.map +1 -0
  149. package/dist-types/components/chat/tools/chat-chart.d.ts +6 -0
  150. package/dist-types/components/chat/tools/chat-chart.d.ts.map +1 -0
  151. package/dist-types/components/chat/tools/chat-citations.d.ts +32 -0
  152. package/dist-types/components/chat/tools/chat-citations.d.ts.map +1 -0
  153. package/dist-types/components/chat/tools/chat-data-table.d.ts +14 -0
  154. package/dist-types/components/chat/tools/chat-data-table.d.ts.map +1 -0
  155. package/dist-types/components/chat/tools/chat-file-export.d.ts +5 -0
  156. package/dist-types/components/chat/tools/chat-file-export.d.ts.map +1 -0
  157. package/dist-types/components/chat/tools/chat-media-preview.d.ts +35 -0
  158. package/dist-types/components/chat/tools/chat-media-preview.d.ts.map +1 -0
  159. package/dist-types/components/chat/tools/chat-sandbox-result.d.ts +17 -0
  160. package/dist-types/components/chat/tools/chat-sandbox-result.d.ts.map +1 -0
  161. package/dist-types/components/chat/tools/chat-signature-request.d.ts +13 -0
  162. package/dist-types/components/chat/tools/chat-signature-request.d.ts.map +1 -0
  163. package/dist-types/components/chat/tools/chat-tabs.d.ts +17 -0
  164. package/dist-types/components/chat/tools/chat-tabs.d.ts.map +1 -0
  165. package/dist-types/components/chat/tools/corpus-data-result.d.ts +36 -0
  166. package/dist-types/components/chat/tools/corpus-data-result.d.ts.map +1 -0
  167. package/dist-types/components/chat/tools/knowledge-base-result.d.ts +14 -0
  168. package/dist-types/components/chat/tools/knowledge-base-result.d.ts.map +1 -0
  169. package/dist-types/components/chat/tools/visual-placement-modal.d.ts +23 -0
  170. package/dist-types/components/chat/tools/visual-placement-modal.d.ts.map +1 -0
  171. package/dist-types/components/configure/custom-model-modal.d.ts +13 -0
  172. package/dist-types/components/configure/custom-model-modal.d.ts.map +1 -0
  173. package/dist-types/components/configure/store-fields.d.ts +11 -0
  174. package/dist-types/components/configure/store-fields.d.ts.map +1 -0
  175. package/dist-types/components/data/corpus-panel.d.ts +12 -0
  176. package/dist-types/components/data/corpus-panel.d.ts.map +1 -0
  177. package/dist-types/components/data/data-entry-mode-switch.d.ts +13 -0
  178. package/dist-types/components/data/data-entry-mode-switch.d.ts.map +1 -0
  179. package/dist-types/components/data/data-primary-action.d.ts +7 -0
  180. package/dist-types/components/data/data-primary-action.d.ts.map +1 -0
  181. package/dist-types/components/data/data-workspace.d.ts +6 -0
  182. package/dist-types/components/data/data-workspace.d.ts.map +1 -0
  183. package/dist-types/components/data/groups-panel.d.ts +5 -0
  184. package/dist-types/components/data/groups-panel.d.ts.map +1 -0
  185. package/dist-types/components/data/integration-resources-panel.d.ts +9 -0
  186. package/dist-types/components/data/integration-resources-panel.d.ts.map +1 -0
  187. package/dist-types/components/data/integrations-panel.d.ts +5 -0
  188. package/dist-types/components/data/integrations-panel.d.ts.map +1 -0
  189. package/dist-types/components/data/jobs-panel.d.ts +6 -0
  190. package/dist-types/components/data/jobs-panel.d.ts.map +1 -0
  191. package/dist-types/components/data/jobs-tracking-button.d.ts +2 -0
  192. package/dist-types/components/data/jobs-tracking-button.d.ts.map +1 -0
  193. package/dist-types/components/data/live-media-progress.d.ts +9 -0
  194. package/dist-types/components/data/live-media-progress.d.ts.map +1 -0
  195. package/dist-types/components/data/media-indexing-jobs-panel.d.ts +34 -0
  196. package/dist-types/components/data/media-indexing-jobs-panel.d.ts.map +1 -0
  197. package/dist-types/components/data/media-panel.d.ts +58 -0
  198. package/dist-types/components/data/media-panel.d.ts.map +1 -0
  199. package/dist-types/components/data/notion-panel.d.ts +6 -0
  200. package/dist-types/components/data/notion-panel.d.ts.map +1 -0
  201. package/dist-types/components/data/paste-panel.d.ts +7 -0
  202. package/dist-types/components/data/paste-panel.d.ts.map +1 -0
  203. package/dist-types/components/data/project-data-page.d.ts +3 -0
  204. package/dist-types/components/data/project-data-page.d.ts.map +1 -0
  205. package/dist-types/components/data/scrape-panel.d.ts +9 -0
  206. package/dist-types/components/data/scrape-panel.d.ts.map +1 -0
  207. package/dist-types/components/data/tabular-preview.d.ts +10 -0
  208. package/dist-types/components/data/tabular-preview.d.ts.map +1 -0
  209. package/dist-types/components/data/tool-indexing-dialog.d.ts +54 -0
  210. package/dist-types/components/data/tool-indexing-dialog.d.ts.map +1 -0
  211. package/dist-types/components/data/upload-panel.d.ts +7 -0
  212. package/dist-types/components/data/upload-panel.d.ts.map +1 -0
  213. package/dist-types/components/data/web-crawler-status.d.ts +3 -0
  214. package/dist-types/components/data/web-crawler-status.d.ts.map +1 -0
  215. package/dist-types/components/projects/project-form-dialog.d.ts +10 -0
  216. package/dist-types/components/projects/project-form-dialog.d.ts.map +1 -0
  217. package/dist-types/components/projects/project-provider.d.ts +34 -0
  218. package/dist-types/components/projects/project-provider.d.ts.map +1 -0
  219. package/dist-types/components/settings/general/agent-customization-section.d.ts +2 -0
  220. package/dist-types/components/settings/general/agent-customization-section.d.ts.map +1 -0
  221. package/dist-types/components/settings/general/mcp-connections-section.d.ts +2 -0
  222. package/dist-types/components/settings/general/mcp-connections-section.d.ts.map +1 -0
  223. package/dist-types/components/settings/general/model-combobox.d.ts +24 -0
  224. package/dist-types/components/settings/general/model-combobox.d.ts.map +1 -0
  225. package/dist-types/components/settings/general/models-section.d.ts +2 -0
  226. package/dist-types/components/settings/general/models-section.d.ts.map +1 -0
  227. package/dist-types/components/settings/general/sandbox-section.d.ts +7 -0
  228. package/dist-types/components/settings/general/sandbox-section.d.ts.map +1 -0
  229. package/dist-types/components/settings/general/search-scraping-section.d.ts +2 -0
  230. package/dist-types/components/settings/general/search-scraping-section.d.ts.map +1 -0
  231. package/dist-types/components/settings/general/storage-indexing-section.d.ts +2 -0
  232. package/dist-types/components/settings/general/storage-indexing-section.d.ts.map +1 -0
  233. package/dist-types/components/ui/alert-dialog.d.ts +19 -0
  234. package/dist-types/components/ui/alert-dialog.d.ts.map +1 -0
  235. package/dist-types/components/ui/alert.d.ts +11 -0
  236. package/dist-types/components/ui/alert.d.ts.map +1 -0
  237. package/dist-types/components/ui/badge.d.ts +8 -0
  238. package/dist-types/components/ui/badge.d.ts.map +1 -0
  239. package/dist-types/components/ui/card.d.ts +2 -0
  240. package/dist-types/components/ui/card.d.ts.map +1 -0
  241. package/dist-types/components/ui/checkbox.d.ts +4 -0
  242. package/dist-types/components/ui/checkbox.d.ts.map +1 -0
  243. package/dist-types/components/ui/collapsible.d.ts +6 -0
  244. package/dist-types/components/ui/collapsible.d.ts.map +1 -0
  245. package/dist-types/components/ui/command.d.ts +20 -0
  246. package/dist-types/components/ui/command.d.ts.map +1 -0
  247. package/dist-types/components/ui/dialog.d.ts +18 -0
  248. package/dist-types/components/ui/dialog.d.ts.map +1 -0
  249. package/dist-types/components/ui/dropdown-menu.d.ts +30 -0
  250. package/dist-types/components/ui/dropdown-menu.d.ts.map +1 -0
  251. package/dist-types/components/ui/input-group.d.ts +19 -0
  252. package/dist-types/components/ui/input-group.d.ts.map +1 -0
  253. package/dist-types/components/ui/input.d.ts +4 -0
  254. package/dist-types/components/ui/input.d.ts.map +1 -0
  255. package/dist-types/components/ui/line-tabs.d.ts +15 -0
  256. package/dist-types/components/ui/line-tabs.d.ts.map +1 -0
  257. package/dist-types/components/ui/popover.d.ts +10 -0
  258. package/dist-types/components/ui/popover.d.ts.map +1 -0
  259. package/dist-types/components/ui/progress.d.ts +8 -0
  260. package/dist-types/components/ui/progress.d.ts.map +1 -0
  261. package/dist-types/components/ui/scroll-area.d.ts +6 -0
  262. package/dist-types/components/ui/scroll-area.d.ts.map +1 -0
  263. package/dist-types/components/ui/sheet.d.ts +15 -0
  264. package/dist-types/components/ui/sheet.d.ts.map +1 -0
  265. package/dist-types/components/ui/slider.d.ts +4 -0
  266. package/dist-types/components/ui/slider.d.ts.map +1 -0
  267. package/dist-types/components/ui/switch.d.ts +6 -0
  268. package/dist-types/components/ui/switch.d.ts.map +1 -0
  269. package/dist-types/components/ui/table.d.ts +2 -0
  270. package/dist-types/components/ui/table.d.ts.map +1 -0
  271. package/dist-types/components/ui/tabs.d.ts +11 -0
  272. package/dist-types/components/ui/tabs.d.ts.map +1 -0
  273. package/dist-types/components/ui/textarea.d.ts +2 -0
  274. package/dist-types/components/ui/textarea.d.ts.map +1 -0
  275. package/dist-types/components/ui/tooltip.d.ts +7 -0
  276. package/dist-types/components/ui/tooltip.d.ts.map +1 -0
  277. package/dist-types/hooks/use-copy-to-clipboard.d.ts +5 -0
  278. package/dist-types/hooks/use-copy-to-clipboard.d.ts.map +1 -0
  279. package/dist-types/hooks/use-integration-auth.d.ts +10 -0
  280. package/dist-types/hooks/use-integration-auth.d.ts.map +1 -0
  281. package/dist-types/hooks/use-live-media-progress.d.ts +14 -0
  282. package/dist-types/hooks/use-live-media-progress.d.ts.map +1 -0
  283. package/dist-types/hooks/use-notion-auth.d.ts +9 -0
  284. package/dist-types/hooks/use-notion-auth.d.ts.map +1 -0
  285. package/dist-types/host.d.ts +20 -0
  286. package/dist-types/host.d.ts.map +1 -0
  287. package/dist-types/lib/browser-cache.d.ts +7 -0
  288. package/dist-types/lib/browser-cache.d.ts.map +1 -0
  289. package/dist-types/lib/chat/chart-config.d.ts +2 -0
  290. package/dist-types/lib/chat/chart-config.d.ts.map +1 -0
  291. package/dist-types/lib/chat/data-export.d.ts +2 -0
  292. package/dist-types/lib/chat/data-export.d.ts.map +1 -0
  293. package/dist-types/lib/chat/live-tool-progress.d.ts +44 -0
  294. package/dist-types/lib/chat/live-tool-progress.d.ts.map +1 -0
  295. package/dist-types/lib/chat/message-feedback.d.ts +2 -0
  296. package/dist-types/lib/chat/message-feedback.d.ts.map +1 -0
  297. package/dist-types/lib/chat/table-presentation.d.ts +2 -0
  298. package/dist-types/lib/chat/table-presentation.d.ts.map +1 -0
  299. package/dist-types/lib/chat/tool-output.d.ts +3 -0
  300. package/dist-types/lib/chat/tool-output.d.ts.map +1 -0
  301. package/dist-types/lib/chat-supporting-clip.d.ts +11 -0
  302. package/dist-types/lib/chat-supporting-clip.d.ts.map +1 -0
  303. package/dist-types/lib/constants/stores.d.ts +6 -0
  304. package/dist-types/lib/constants/stores.d.ts.map +1 -0
  305. package/dist-types/lib/constants/tools.d.ts +27 -0
  306. package/dist-types/lib/constants/tools.d.ts.map +1 -0
  307. package/dist-types/lib/error-formatter.d.ts +2 -0
  308. package/dist-types/lib/error-formatter.d.ts.map +1 -0
  309. package/dist-types/lib/jobs-client.d.ts +7 -0
  310. package/dist-types/lib/jobs-client.d.ts.map +1 -0
  311. package/dist-types/lib/media/pdf.d.ts +6 -0
  312. package/dist-types/lib/media/pdf.d.ts.map +1 -0
  313. package/dist-types/lib/media/progress.d.ts +61 -0
  314. package/dist-types/lib/media/progress.d.ts.map +1 -0
  315. package/dist-types/lib/media/source-selection.d.ts +10 -0
  316. package/dist-types/lib/media/source-selection.d.ts.map +1 -0
  317. package/dist-types/lib/media/tool-indexing-estimate.d.ts +13 -0
  318. package/dist-types/lib/media/tool-indexing-estimate.d.ts.map +1 -0
  319. package/dist-types/lib/media/video-intelligence-capacity.d.ts +2 -0
  320. package/dist-types/lib/media/video-intelligence-capacity.d.ts.map +1 -0
  321. package/dist-types/lib/media/video-runtime-scope.d.ts +2 -0
  322. package/dist-types/lib/media/video-runtime-scope.d.ts.map +1 -0
  323. package/dist-types/lib/shared/error-formatter.d.ts +2 -0
  324. package/dist-types/lib/shared/error-formatter.d.ts.map +1 -0
  325. package/dist-types/lib/utils.d.ts +3 -0
  326. package/dist-types/lib/utils.d.ts.map +1 -0
  327. package/dist-types/storage.d.ts +5 -0
  328. package/dist-types/storage.d.ts.map +1 -0
  329. package/dist-types/store/chat-store.d.ts +19 -0
  330. package/dist-types/store/chat-store.d.ts.map +1 -0
  331. package/dist-types/store/scrape-store.d.ts +42 -0
  332. package/dist-types/store/scrape-store.d.ts.map +1 -0
  333. package/package.json +579 -3
  334. package/scripts/build-assets.mjs +12 -0
  335. package/src/asset-data.json +1 -0
  336. package/src/asset-server.ts +19 -0
  337. package/src/components/alerts/generic-alert.tsx +76 -0
  338. package/src/components/chat/canvas/doc-editor-provider.tsx +338 -0
  339. package/src/components/chat/canvas/document-canvas.tsx +98 -0
  340. package/src/components/chat/canvas/document-field.tsx +167 -0
  341. package/src/components/chat/canvas/document-viewer.tsx +446 -0
  342. package/src/components/chat/canvas/file-attachment-button.tsx +88 -0
  343. package/src/components/chat/chat-workspace.tsx +1552 -0
  344. package/src/components/chat/message-actions.tsx +96 -0
  345. package/src/components/chat/message-item.tsx +1398 -0
  346. package/src/components/chat/message-queue.tsx +86 -0
  347. package/src/components/chat/tools/chat-chart.tsx +558 -0
  348. package/src/components/chat/tools/chat-citations.tsx +152 -0
  349. package/src/components/chat/tools/chat-data-table.tsx +373 -0
  350. package/src/components/chat/tools/chat-file-export.tsx +49 -0
  351. package/src/components/chat/tools/chat-media-preview.tsx +466 -0
  352. package/src/components/chat/tools/chat-sandbox-result.tsx +130 -0
  353. package/src/components/chat/tools/chat-signature-request.tsx +810 -0
  354. package/src/components/chat/tools/chat-tabs.tsx +59 -0
  355. package/src/components/chat/tools/corpus-data-result.tsx +194 -0
  356. package/src/components/chat/tools/knowledge-base-result.tsx +345 -0
  357. package/src/components/chat/tools/visual-placement-modal.tsx +308 -0
  358. package/src/components/configure/custom-model-modal.tsx +209 -0
  359. package/src/components/configure/store-fields.tsx +129 -0
  360. package/src/components/data/corpus-panel.tsx +1223 -0
  361. package/src/components/data/data-entry-mode-switch.tsx +53 -0
  362. package/src/components/data/data-primary-action.ts +6 -0
  363. package/src/components/data/data-workspace.tsx +623 -0
  364. package/src/components/data/groups-panel.tsx +530 -0
  365. package/src/components/data/integration-resources-panel.tsx +282 -0
  366. package/src/components/data/integrations-panel.tsx +392 -0
  367. package/src/components/data/jobs-panel.tsx +490 -0
  368. package/src/components/data/jobs-tracking-button.tsx +224 -0
  369. package/src/components/data/live-media-progress.tsx +79 -0
  370. package/src/components/data/media-indexing-jobs-panel.tsx +190 -0
  371. package/src/components/data/media-panel.tsx +2905 -0
  372. package/src/components/data/notion-panel.tsx +408 -0
  373. package/src/components/data/paste-panel.tsx +82 -0
  374. package/src/components/data/project-data-page.tsx +55 -0
  375. package/src/components/data/scrape-panel.tsx +1290 -0
  376. package/src/components/data/tabular-preview.tsx +205 -0
  377. package/src/components/data/tool-indexing-dialog.tsx +210 -0
  378. package/src/components/data/upload-panel.tsx +1313 -0
  379. package/src/components/data/web-crawler-status.tsx +132 -0
  380. package/src/components/projects/project-form-dialog.tsx +97 -0
  381. package/src/components/projects/project-provider.tsx +143 -0
  382. package/src/components/settings/general/agent-customization-section.tsx +620 -0
  383. package/src/components/settings/general/mcp-connections-section.tsx +907 -0
  384. package/src/components/settings/general/model-combobox.tsx +235 -0
  385. package/src/components/settings/general/models-section.tsx +909 -0
  386. package/src/components/settings/general/sandbox-section.tsx +394 -0
  387. package/src/components/settings/general/search-scraping-section.tsx +757 -0
  388. package/src/components/settings/general/storage-indexing-section.tsx +394 -0
  389. package/src/components/ui/alert-dialog.tsx +162 -0
  390. package/src/components/ui/alert.tsx +69 -0
  391. package/src/components/ui/badge.tsx +49 -0
  392. package/src/components/ui/card.tsx +9 -0
  393. package/src/components/ui/checkbox.tsx +28 -0
  394. package/src/components/ui/collapsible.tsx +17 -0
  395. package/src/components/ui/command.tsx +175 -0
  396. package/src/components/ui/dialog.tsx +138 -0
  397. package/src/components/ui/dropdown-menu.tsx +267 -0
  398. package/src/components/ui/input-group.tsx +146 -0
  399. package/src/components/ui/input.tsx +19 -0
  400. package/src/components/ui/line-tabs.tsx +49 -0
  401. package/src/components/ui/popover.tsx +77 -0
  402. package/src/components/ui/progress.tsx +66 -0
  403. package/src/components/ui/scroll-area.tsx +51 -0
  404. package/src/components/ui/sheet.tsx +125 -0
  405. package/src/components/ui/slider.tsx +52 -0
  406. package/src/components/ui/switch.tsx +32 -0
  407. package/src/components/ui/table.tsx +10 -0
  408. package/src/components/ui/tabs.tsx +77 -0
  409. package/src/components/ui/textarea.tsx +1 -0
  410. package/src/components/ui/tooltip.tsx +54 -0
  411. package/src/hooks/use-copy-to-clipboard.ts +25 -0
  412. package/src/hooks/use-integration-auth.ts +39 -0
  413. package/src/hooks/use-live-media-progress.ts +71 -0
  414. package/src/hooks/use-notion-auth.ts +66 -0
  415. package/src/host.ts +55 -0
  416. package/src/lib/browser-cache.ts +17 -0
  417. package/src/lib/chat/chart-config.ts +1 -0
  418. package/src/lib/chat/data-export.ts +1 -0
  419. package/src/lib/chat/live-tool-progress.ts +69 -0
  420. package/src/lib/chat/message-feedback.ts +1 -0
  421. package/src/lib/chat/table-presentation.ts +1 -0
  422. package/src/lib/chat/tool-output.ts +14 -0
  423. package/src/lib/chat-supporting-clip.ts +16 -0
  424. package/src/lib/constants/stores.ts +12 -0
  425. package/src/lib/constants/tools.ts +178 -0
  426. package/src/lib/error-formatter.ts +30 -0
  427. package/src/lib/jobs-client.ts +27 -0
  428. package/src/lib/media/pdf.ts +57 -0
  429. package/src/lib/media/progress.ts +209 -0
  430. package/src/lib/media/source-selection.ts +47 -0
  431. package/src/lib/media/tool-indexing-estimate.ts +39 -0
  432. package/src/lib/media/video-intelligence-capacity.ts +1 -0
  433. package/src/lib/media/video-runtime-scope.ts +1 -0
  434. package/src/lib/shared/error-formatter.ts +1 -0
  435. package/src/lib/utils.ts +6 -0
  436. package/src/source.css +1 -0
  437. package/src/storage.ts +16 -0
  438. package/src/store/chat-store.ts +19 -0
  439. package/src/store/scrape-store.ts +76 -0
  440. package/src/styles.d.ts +1 -0
@@ -0,0 +1,77 @@
1
+ 'use client';
2
+
3
+ import { Tabs as TabsPrimitive } from '@base-ui/react/tabs';
4
+ import { cva, type VariantProps } from 'class-variance-authority';
5
+
6
+ import { cn } from '@larkup/workspace-app/lib/utils';
7
+
8
+ function Tabs({ className, orientation = 'horizontal', ...props }: TabsPrimitive.Root.Props) {
9
+ return (
10
+ <TabsPrimitive.Root
11
+ data-slot="tabs"
12
+ data-orientation={orientation}
13
+ className={cn('group/tabs flex gap-2 data-horizontal:flex-col', className)}
14
+ {...props}
15
+ />
16
+ );
17
+ }
18
+
19
+ const tabsListVariants = cva(
20
+ 'group/tabs-list inline-flex w-fit items-center justify-center rounded-[5px] h-11! border bg-white p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none',
21
+ {
22
+ variants: {
23
+ variant: {
24
+ default: 'bg-muted',
25
+ line: 'gap-1 bg-transparent',
26
+ },
27
+ },
28
+ defaultVariants: {
29
+ variant: 'default',
30
+ },
31
+ },
32
+ );
33
+
34
+ function TabsList({
35
+ className,
36
+ variant = 'default',
37
+ ...props
38
+ }: TabsPrimitive.List.Props & VariantProps<typeof tabsListVariants>) {
39
+ return (
40
+ <TabsPrimitive.List
41
+ data-slot="tabs-list"
42
+ data-variant={variant}
43
+ className={cn(tabsListVariants({ variant }), className)}
44
+ {...props}
45
+ />
46
+ );
47
+ }
48
+
49
+ function TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {
50
+ return (
51
+ <TabsPrimitive.Tab
52
+ data-slot="tabs-trigger"
53
+ className={cn(
54
+ "relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-lg border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active: group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
55
+ 'group-data-[variant=line]/tabs-list:border-0 group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:border-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent',
56
+ 'data-active:bg-muted/70 data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground',
57
+ 'after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:-bottom-1.25 group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100',
58
+ 'border shadow-none! data-active:border-border cursor-pointer',
59
+ // "border shadow-none!",
60
+ className,
61
+ )}
62
+ {...props}
63
+ />
64
+ );
65
+ }
66
+
67
+ function TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {
68
+ return (
69
+ <TabsPrimitive.Panel
70
+ data-slot="tabs-content"
71
+ className={cn('flex-1 text-sm outline-none', className)}
72
+ {...props}
73
+ />
74
+ );
75
+ }
76
+
77
+ export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };
@@ -0,0 +1 @@
1
+ export { Textarea } from '@larkup/workspace-ui';
@@ -0,0 +1,54 @@
1
+ 'use client';
2
+
3
+ import { Tooltip as TooltipPrimitive } from '@base-ui/react/tooltip';
4
+
5
+ import { cn } from '../../lib/utils';
6
+
7
+ function TooltipProvider({ delay = 0, ...props }: TooltipPrimitive.Provider.Props) {
8
+ return <TooltipPrimitive.Provider data-slot="tooltip-provider" delay={delay} {...props} />;
9
+ }
10
+
11
+ function Tooltip({ ...props }: TooltipPrimitive.Root.Props) {
12
+ return <TooltipPrimitive.Root data-slot="tooltip" {...props} />;
13
+ }
14
+
15
+ function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {
16
+ return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
17
+ }
18
+
19
+ function TooltipContent({
20
+ className,
21
+ side = 'top',
22
+ sideOffset = 4,
23
+ align = 'center',
24
+ alignOffset = 0,
25
+ children,
26
+ ...props
27
+ }: TooltipPrimitive.Popup.Props &
28
+ Pick<TooltipPrimitive.Positioner.Props, 'align' | 'alignOffset' | 'side' | 'sideOffset'>) {
29
+ return (
30
+ <TooltipPrimitive.Portal>
31
+ <TooltipPrimitive.Positioner
32
+ align={align}
33
+ alignOffset={alignOffset}
34
+ side={side}
35
+ sideOffset={sideOffset}
36
+ className="isolate z-50"
37
+ >
38
+ <TooltipPrimitive.Popup
39
+ data-slot="tooltip-content"
40
+ className={cn(
41
+ 'z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',
42
+ className,
43
+ )}
44
+ {...props}
45
+ >
46
+ {children}
47
+ <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-xs bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5" />
48
+ </TooltipPrimitive.Popup>
49
+ </TooltipPrimitive.Positioner>
50
+ </TooltipPrimitive.Portal>
51
+ );
52
+ }
53
+
54
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
@@ -0,0 +1,25 @@
1
+ 'use client';
2
+
3
+ import { useCallback, useRef, useState } from 'react';
4
+
5
+ export function useCopyToClipboard(resetDelay = 2000) {
6
+ const [copied, setCopied] = useState(false);
7
+ const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
8
+
9
+ const copy = useCallback(
10
+ async (text: string) => {
11
+ if (!text) return;
12
+ try {
13
+ await navigator.clipboard.writeText(text);
14
+ setCopied(true);
15
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
16
+ timeoutRef.current = setTimeout(() => setCopied(false), resetDelay);
17
+ } catch (err) {
18
+ console.error('Copy to clipboard failed', err);
19
+ }
20
+ },
21
+ [resetDelay],
22
+ );
23
+
24
+ return { copied, copy };
25
+ }
@@ -0,0 +1,39 @@
1
+ import { integrationAuthorizationUrl } from '../host';
2
+ import { useEffect } from 'react';
3
+
4
+ interface Options {
5
+ onSuccess?: (integration: string) => void;
6
+ onError?: (error: string, integration: string) => void;
7
+ }
8
+
9
+ /** Opens the shared OAuth proxy for a registry integration. */
10
+ export function useIntegrationAuth({ onSuccess, onError }: Options = {}) {
11
+ useEffect(() => {
12
+ const onMessage = (event: MessageEvent) => {
13
+ if (
14
+ event.origin !== window.location.origin ||
15
+ event.data?.type !== 'integration_oauth' ||
16
+ typeof event.data.integration !== 'string'
17
+ )
18
+ return;
19
+ event.data.status === 'connected'
20
+ ? onSuccess?.(event.data.integration)
21
+ : onError?.('Failed to connect integration', event.data.integration);
22
+ };
23
+ window.addEventListener('message', onMessage);
24
+ return () => window.removeEventListener('message', onMessage);
25
+ }, [onError, onSuccess]);
26
+
27
+ function connect(integration: string) {
28
+ const proxyUrl =
29
+ process.env.NEXT_PUBLIC_INTEGRATIONS_PROXY_URL || 'https://larkup-proxy.vercel.app/api/oauth';
30
+ const callback = `${window.location.origin}/api/integrations/${integration}/callback`;
31
+ window.open(
32
+ integrationAuthorizationUrl(integration) ??
33
+ `${proxyUrl}/${integration}?redirect_to=${encodeURIComponent(callback)}`,
34
+ `${integration}-connection`,
35
+ 'width=600,height=800,toolbar=0,scrollbars=1,status=1,resizable=1',
36
+ );
37
+ }
38
+ return { connect };
39
+ }
@@ -0,0 +1,71 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useRef, useState } from 'react';
4
+ import {
5
+ advanceMediaProcessingProgress,
6
+ isMediaStepTelemetryStale,
7
+ primaryRunningMediaStep,
8
+ smoothMediaProcessingProgress,
9
+ type MediaProgressStep,
10
+ } from '../lib/media/progress';
11
+
12
+ type LiveMediaAsset = {
13
+ id: string;
14
+ processingProgress?: number;
15
+ processingStatus: string;
16
+ processingPaused?: boolean;
17
+ processingStartedAt?: string;
18
+ durationSecs?: number;
19
+ processingSteps?: MediaProgressStep[];
20
+ };
21
+
22
+ /** Smooths sparse worker updates without crossing the active stage boundary. */
23
+ export function useLiveMediaProgress(asset: LiveMediaAsset): number {
24
+ const latestAsset = useRef(asset);
25
+ latestAsset.current = asset;
26
+ const attempt = `${asset.id}:${asset.processingStartedAt ?? ''}`;
27
+ const previousAttempt = useRef(attempt);
28
+ const [displayed, setDisplayed] = useState(() =>
29
+ asset.processingStatus === 'completed'
30
+ ? 100
31
+ : Math.max(0, Math.min(100, asset.processingProgress ?? 0)),
32
+ );
33
+
34
+ if (previousAttempt.current !== attempt) {
35
+ previousAttempt.current = attempt;
36
+ }
37
+
38
+ useEffect(() => {
39
+ setDisplayed(
40
+ asset.processingStatus === 'completed'
41
+ ? 100
42
+ : Math.max(0, Math.min(100, asset.processingProgress ?? 0)),
43
+ );
44
+ }, [attempt]);
45
+
46
+ useEffect(() => {
47
+ if (asset.processingStatus === 'completed') {
48
+ setDisplayed(100);
49
+ return;
50
+ }
51
+ if (asset.processingStatus !== 'processing' || asset.processingPaused) return;
52
+
53
+ let previousTick = Date.now();
54
+ const tick = () => {
55
+ const now = Date.now();
56
+ const elapsedMs = now - previousTick;
57
+ previousTick = now;
58
+ const currentAsset = latestAsset.current;
59
+ const confirmed = smoothMediaProcessingProgress(currentAsset, now);
60
+ const activeStep = primaryRunningMediaStep(currentAsset.processingSteps);
61
+ const workerActive = Boolean(activeStep && !isMediaStepTelemetryStale(activeStep, now));
62
+ setDisplayed((current) =>
63
+ advanceMediaProcessingProgress(current, confirmed, elapsedMs, workerActive),
64
+ );
65
+ };
66
+ const timer = window.setInterval(tick, 250);
67
+ return () => window.clearInterval(timer);
68
+ }, [asset.processingPaused, asset.processingStatus, attempt]);
69
+
70
+ return displayed;
71
+ }
@@ -0,0 +1,66 @@
1
+ import { integrationAuthorizationUrl } from '../host';
2
+ import { useEffect } from 'react';
3
+
4
+ interface UseNotionAuthOptions {
5
+ onSuccess?: () => void;
6
+ onError?: (error: string) => void;
7
+ }
8
+
9
+ export function useNotionAuth({ onSuccess, onError }: UseNotionAuthOptions = {}) {
10
+ useEffect(() => {
11
+ const handleMessage = (event: MessageEvent) => {
12
+ if (event.origin !== window.location.origin) return;
13
+
14
+ if (event.data?.type === 'notion_oauth') {
15
+ if (event.data.status === 'connected') {
16
+ onSuccess?.();
17
+ } else if (event.data.status === 'error') {
18
+ onError?.(event.data.error || 'Failed to connect to Notion');
19
+ }
20
+ }
21
+ };
22
+
23
+ window.addEventListener('message', handleMessage);
24
+ return () => window.removeEventListener('message', handleMessage);
25
+ }, [onSuccess, onError]);
26
+
27
+ const connectToNotion = (onClosePopup?: () => void) => {
28
+ const customAuthUrl =
29
+ process.env.NEXT_PUBLIC_NOTION_AUTHORIZATION_URL ||
30
+ `${
31
+ process.env.NEXT_PUBLIC_INTEGRATIONS_PROXY_URL ||
32
+ 'https://larkup-proxy.vercel.app/api/oauth'
33
+ }/notion`;
34
+
35
+ const redirectUri = `${window.location.origin}/api/integrations/notion/callback`;
36
+ const authUrl =
37
+ integrationAuthorizationUrl('notion') ??
38
+ `${customAuthUrl}?redirect_to=${encodeURIComponent(redirectUri)}`;
39
+
40
+ const width = 600;
41
+ const height = 800;
42
+ const left = window.innerWidth / 2 - window.innerWidth / 2 + window.screenX; // Wait, window.innerWidth / 2 - width / 2
43
+ const top = window.innerHeight / 2 - window.innerHeight / 2 + window.screenY;
44
+
45
+ // fixing the left and top calculations:
46
+ const calculatedLeft = window.innerWidth / 2 - width / 2 + window.screenX;
47
+ const calculatedTop = window.innerHeight / 2 - height / 2 + window.screenY;
48
+
49
+ const popup = window.open(
50
+ authUrl,
51
+ 'Notion Connection',
52
+ `width=${width},height=${height},left=${calculatedLeft},top=${calculatedTop},toolbar=0,scrollbars=1,status=1,resizable=1`,
53
+ );
54
+
55
+ if (popup) {
56
+ const timer = setInterval(() => {
57
+ if (popup.closed) {
58
+ clearInterval(timer);
59
+ onClosePopup?.();
60
+ }
61
+ }, 500);
62
+ }
63
+ };
64
+
65
+ return { connectToNotion };
66
+ }
package/src/host.ts ADDED
@@ -0,0 +1,55 @@
1
+ export interface WorkspaceCapabilities {
2
+ sandboxProviders?: string[];
3
+ vectorStores?: string[];
4
+ managedStorage?: boolean;
5
+ durableDocumentSessions?: boolean;
6
+ }
7
+ let capabilities: WorkspaceCapabilities = {};
8
+ export function workspaceCapabilities(): WorkspaceCapabilities {
9
+ return capabilities;
10
+ }
11
+ /** Configure once in a browser host; resolve the active project per request. */
12
+ let hostFetch: typeof globalThis.fetch | undefined;
13
+ let resolveApiBase: (() => string) | undefined;
14
+ let resolveIntegrationAuthorization: ((integration: string) => string) | undefined;
15
+ let resolveStorageScope: (() => string) | undefined;
16
+ export function configureWorkspaceHost(options: {
17
+ capabilities?: WorkspaceCapabilities;
18
+ apiBase: () => string;
19
+ storageScope: () => string;
20
+ integrationAuthorizationUrl?: (integration: string) => string;
21
+ fetch?: typeof globalThis.fetch;
22
+ }) {
23
+ if (typeof window === 'undefined') return;
24
+ capabilities = options.capabilities ?? {};
25
+ resolveApiBase = options.apiBase;
26
+ hostFetch = options.fetch;
27
+ resolveStorageScope = options.storageScope;
28
+ resolveIntegrationAuthorization = options.integrationAuthorizationUrl;
29
+ }
30
+ export function workspaceUrl(url: string): string {
31
+ if (!url.startsWith('/api/')) return url;
32
+ const base = resolveApiBase?.();
33
+ if (!base) return url;
34
+ const normalizedBase = base.replace(/\/$/, '');
35
+ // Server-returned media URLs may already be scoped by the browser host.
36
+ // Keep this helper idempotent so shared previews work in both Local and
37
+ // Cloud without either UI knowing the other's route prefix.
38
+ if (url === normalizedBase || url.startsWith(`${normalizedBase}/`)) return url;
39
+ return normalizedBase + url.slice(4);
40
+ }
41
+
42
+ export function workspaceStorageScope(): string {
43
+ return resolveStorageScope?.() ?? '';
44
+ }
45
+
46
+ export function integrationAuthorizationUrl(integration: string): string | undefined {
47
+ return resolveIntegrationAuthorization?.(integration);
48
+ }
49
+
50
+ export const workspaceFetch: typeof globalThis.fetch = (input, init) =>
51
+ (hostFetch ?? globalThis.fetch)(input, init);
52
+ export function workspaceStorageKey(key: string): string {
53
+ const scope = workspaceStorageScope();
54
+ return scope ? `${scope}:${key}` : key;
55
+ }
@@ -0,0 +1,17 @@
1
+ export const SCRAPE_RECENT_QUERIES_STORAGE_KEY = 'scrape_recent_queries';
2
+ export const MEDIA_RECENT_URLS_STORAGE_KEY = 'media_recent_urls';
3
+ export const RECENT_ADD_HISTORY_CLEARED_EVENT = 'larkup:recent-add-history-cleared';
4
+
5
+ export const RECENT_ADD_HISTORY_STORAGE_KEYS = [
6
+ SCRAPE_RECENT_QUERIES_STORAGE_KEY,
7
+ MEDIA_RECENT_URLS_STORAGE_KEY,
8
+ ] as const;
9
+
10
+ /** Clear disposable Add-page history and notify panels already mounted in this browser tab. */
11
+ export function clearRecentAddHistory(
12
+ storage: Pick<Storage, 'removeItem'>,
13
+ eventTarget?: Pick<EventTarget, 'dispatchEvent'>,
14
+ ) {
15
+ for (const key of RECENT_ADD_HISTORY_STORAGE_KEYS) storage.removeItem(key);
16
+ eventTarget?.dispatchEvent(new Event(RECENT_ADD_HISTORY_CLEARED_EVENT));
17
+ }
@@ -0,0 +1 @@
1
+ export * from '@larkup/core/chart-config';
@@ -0,0 +1 @@
1
+ export * from '@larkup/core/data-export';
@@ -0,0 +1,69 @@
1
+ export type LiveToolActivity = {
2
+ toolCallId?: string;
3
+ phase?: 'waking-up' | 'analyzing';
4
+ percent: number;
5
+ label: string;
6
+ message: string;
7
+ startedAt?: string;
8
+ updatedAt?: string;
9
+ };
10
+
11
+ /**
12
+ * A worker reports 100% when *its* pass is done, but the chat turn is not:
13
+ * the evidence still has to be validated, stored, activated, and re-queried,
14
+ * and a second range may follow. Showing a full bar through all of that reads
15
+ * as a hang, so a running tool call never displays a completed bar -- the row
16
+ * disappears when the call actually returns.
17
+ */
18
+ export const RUNNING_PROGRESS_CEILING = 97;
19
+
20
+ /** Past this the bar stops claiming a position and just shows motion. */
21
+ export const INDETERMINATE_THRESHOLD = 90;
22
+
23
+ /** A tool can be working through local indexed context before a worker exists. */
24
+ export const PENDING_PROGRESS_CEILING = 82;
25
+
26
+ /**
27
+ * Give every executing tool visible motion immediately, even before it has a
28
+ * worker percentage to report. This is deliberately time-based UX, not a
29
+ * completion estimate; authoritative activity replaces it as soon as one is
30
+ * available and only the tool result removes the row.
31
+ */
32
+ export function smoothPendingToolProgress(startedAt: number, now = Date.now()) {
33
+ const elapsedMs = Math.max(0, now - startedAt);
34
+ const initial = 4;
35
+ const estimated =
36
+ initial + (PENDING_PROGRESS_CEILING - initial) * (1 - Math.exp(-elapsedMs / 55_000));
37
+ return Math.max(initial, Math.min(PENDING_PROGRESS_CEILING, estimated));
38
+ }
39
+
40
+ /**
41
+ * Cloud workers publish real stage boundaries, not a progress event for every
42
+ * second of GPU work. Keep the bar alive between those events without
43
+ * pretending the job is complete: the estimate asymptotically approaches a
44
+ * pre-completion ceiling and an actual worker update always wins.
45
+ */
46
+ export function smoothLiveToolProgress(activity: LiveToolActivity, now = Date.now()) {
47
+ const reported = Math.max(0, Math.min(RUNNING_PROGRESS_CEILING, activity.percent));
48
+ const changedAt = Date.parse(activity.updatedAt ?? activity.startedAt ?? '');
49
+ if (!Number.isFinite(changedAt)) return reported;
50
+ const elapsedMs = Math.max(0, now - changedAt);
51
+ const ceiling = activity.phase === 'waking-up' ? 28 : RUNNING_PROGRESS_CEILING;
52
+ if (reported >= ceiling) return reported;
53
+ const estimated = reported + (ceiling - reported) * (1 - Math.exp(-elapsedMs / 75_000));
54
+ return Math.round(Math.max(reported, Math.min(ceiling, estimated)));
55
+ }
56
+
57
+ /** A consecutive bounded source read belongs to the same chat tool call. */
58
+ export function keepToolProgressMonotonic(previous: number | undefined, current: number) {
59
+ return Math.min(RUNNING_PROGRESS_CEILING, Math.max(previous ?? 0, current));
60
+ }
61
+
62
+ /**
63
+ * Near the ceiling the remaining work has no measurable position -- the bar
64
+ * would sit still while real work continues. Swing it instead: motion without
65
+ * a false claim about how much is left.
66
+ */
67
+ export function isIndeterminateProgress(percent: number) {
68
+ return percent >= INDETERMINATE_THRESHOLD;
69
+ }
@@ -0,0 +1 @@
1
+ export * from '@larkup/core/message-feedback';
@@ -0,0 +1 @@
1
+ export * from '@larkup/core/table-presentation';
@@ -0,0 +1,14 @@
1
+ /** Decode the transport wrappers AI providers may use for structured tool output. */
2
+ export function decodeToolOutput(value: unknown): unknown {
3
+ if (typeof value === 'string') {
4
+ try {
5
+ return decodeToolOutput(JSON.parse(value));
6
+ } catch {
7
+ return undefined;
8
+ }
9
+ }
10
+ if (value && typeof value === 'object' && (value as { type?: string }).type === 'json') {
11
+ return decodeToolOutput((value as { value?: unknown }).value);
12
+ }
13
+ return value && typeof value === 'object' ? value : undefined;
14
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Returns true only for the first assistant response in a chat transcript,
3
+ * so its first supporting clip (if a video search produced one) auto-opens
4
+ * instead of staying collapsed behind a "Watch supporting clip" click. This
5
+ * has no memory across reloads (no sessionStorage) — the first message's
6
+ * clip auto-opens the same way every time the chat is loaded.
7
+ */
8
+ export function shouldAutoOpenSupportingClip(
9
+ messages: readonly { role: string }[],
10
+ messageIndex: number,
11
+ ): boolean {
12
+ return (
13
+ messages[messageIndex]?.role === 'assistant' &&
14
+ messageIndex === messages.findIndex((message) => message.role === 'assistant')
15
+ );
16
+ }
@@ -0,0 +1,12 @@
1
+ export type StoreMeta = { iconSrc: string; pillBg: string };
2
+
3
+ export const STORE_META: Record<string, StoreMeta> = {
4
+ lancedb: {
5
+ iconSrc: '/icons/lancedb2.png',
6
+ pillBg: 'bg-yellow-50 dark:bg-yellow-950/40',
7
+ },
8
+ pinecone: {
9
+ iconSrc: '/icons/pinecone.png',
10
+ pillBg: 'bg-green-50 dark:bg-green-950/40',
11
+ },
12
+ };