@agent-native/core 0.14.8 → 0.15.1

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 (544) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  3. package/dist/agent/engine/builder-engine.js +30 -9
  4. package/dist/agent/engine/builder-engine.js.map +1 -1
  5. package/dist/agent/engine/registry.d.ts.map +1 -1
  6. package/dist/agent/engine/registry.js +14 -4
  7. package/dist/agent/engine/registry.js.map +1 -1
  8. package/dist/agent/production-agent.d.ts.map +1 -1
  9. package/dist/agent/production-agent.js +71 -4
  10. package/dist/agent/production-agent.js.map +1 -1
  11. package/dist/agent/types.d.ts +9 -0
  12. package/dist/agent/types.d.ts.map +1 -1
  13. package/dist/agent/types.js.map +1 -1
  14. package/dist/appearance/actions/change-appearance.d.ts +3 -0
  15. package/dist/appearance/actions/change-appearance.d.ts.map +1 -0
  16. package/dist/appearance/actions/change-appearance.js +29 -0
  17. package/dist/appearance/actions/change-appearance.js.map +1 -0
  18. package/dist/chat-threads/store.d.ts +53 -2
  19. package/dist/chat-threads/store.d.ts.map +1 -1
  20. package/dist/chat-threads/store.js +172 -12
  21. package/dist/chat-threads/store.js.map +1 -1
  22. package/dist/cli/create.d.ts.map +1 -1
  23. package/dist/cli/create.js +114 -37
  24. package/dist/cli/create.js.map +1 -1
  25. package/dist/cli/index.js +30 -4
  26. package/dist/cli/index.js.map +1 -1
  27. package/dist/cli/workspace-dev.d.ts +25 -1
  28. package/dist/cli/workspace-dev.d.ts.map +1 -1
  29. package/dist/cli/workspace-dev.js +275 -49
  30. package/dist/cli/workspace-dev.js.map +1 -1
  31. package/dist/client/AgentPanel.d.ts +23 -4
  32. package/dist/client/AgentPanel.d.ts.map +1 -1
  33. package/dist/client/AgentPanel.js +276 -53
  34. package/dist/client/AgentPanel.js.map +1 -1
  35. package/dist/client/AppearancePicker.d.ts +11 -0
  36. package/dist/client/AppearancePicker.d.ts.map +1 -0
  37. package/dist/client/AppearancePicker.js +16 -0
  38. package/dist/client/AppearancePicker.js.map +1 -0
  39. package/dist/client/AssistantChat.d.ts +35 -0
  40. package/dist/client/AssistantChat.d.ts.map +1 -1
  41. package/dist/client/AssistantChat.js +315 -32
  42. package/dist/client/AssistantChat.js.map +1 -1
  43. package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
  44. package/dist/client/ConnectBuilderCard.js +5 -2
  45. package/dist/client/ConnectBuilderCard.js.map +1 -1
  46. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  47. package/dist/client/ErrorBoundary.js +8 -10
  48. package/dist/client/ErrorBoundary.js.map +1 -1
  49. package/dist/client/FeedbackButton.d.ts.map +1 -1
  50. package/dist/client/FeedbackButton.js +1 -1
  51. package/dist/client/FeedbackButton.js.map +1 -1
  52. package/dist/client/MultiTabAssistantChat.d.ts +13 -1
  53. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  54. package/dist/client/MultiTabAssistantChat.js +217 -38
  55. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  56. package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
  57. package/dist/client/NewWorkspaceAppFlow.js +37 -14
  58. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  59. package/dist/client/agent-chat-adapter.d.ts +5 -0
  60. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  61. package/dist/client/agent-chat-adapter.js +4 -0
  62. package/dist/client/agent-chat-adapter.js.map +1 -1
  63. package/dist/client/agent-sidebar-state.d.ts +12 -0
  64. package/dist/client/agent-sidebar-state.d.ts.map +1 -1
  65. package/dist/client/agent-sidebar-state.js +8 -0
  66. package/dist/client/agent-sidebar-state.js.map +1 -1
  67. package/dist/client/analytics.d.ts.map +1 -1
  68. package/dist/client/analytics.js +175 -3
  69. package/dist/client/analytics.js.map +1 -1
  70. package/dist/client/appearance.d.ts +40 -0
  71. package/dist/client/appearance.d.ts.map +1 -0
  72. package/dist/client/appearance.js +114 -0
  73. package/dist/client/appearance.js.map +1 -0
  74. package/dist/client/builder-frame.d.ts +1 -0
  75. package/dist/client/builder-frame.d.ts.map +1 -1
  76. package/dist/client/builder-frame.js +19 -9
  77. package/dist/client/builder-frame.js.map +1 -1
  78. package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
  79. package/dist/client/components/CodeRequiredDialog.js +10 -2
  80. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  81. package/dist/client/components/ui/dropdown-menu.js +2 -2
  82. package/dist/client/components/ui/dropdown-menu.js.map +1 -1
  83. package/dist/client/components/ui/hover-card.js +1 -1
  84. package/dist/client/components/ui/hover-card.js.map +1 -1
  85. package/dist/client/components/ui/popover.js +1 -1
  86. package/dist/client/components/ui/popover.js.map +1 -1
  87. package/dist/client/composer/PromptComposer.d.ts +7 -0
  88. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  89. package/dist/client/composer/PromptComposer.js +63 -32
  90. package/dist/client/composer/PromptComposer.js.map +1 -1
  91. package/dist/client/composer/TiptapComposer.d.ts +5 -0
  92. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  93. package/dist/client/composer/TiptapComposer.js +36 -6
  94. package/dist/client/composer/TiptapComposer.js.map +1 -1
  95. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  96. package/dist/client/composer/useVoiceDictation.js +13 -1
  97. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  98. package/dist/client/dev-mode.d.ts +14 -0
  99. package/dist/client/dev-mode.d.ts.map +1 -0
  100. package/dist/client/dev-mode.js +14 -0
  101. package/dist/client/dev-mode.js.map +1 -0
  102. package/dist/client/error-format.d.ts +3 -2
  103. package/dist/client/error-format.d.ts.map +1 -1
  104. package/dist/client/error-format.js +9 -2
  105. package/dist/client/error-format.js.map +1 -1
  106. package/dist/client/extensions/EmbeddedTool.d.ts +20 -0
  107. package/dist/client/extensions/EmbeddedTool.d.ts.map +1 -0
  108. package/dist/client/extensions/EmbeddedTool.js +199 -0
  109. package/dist/client/extensions/EmbeddedTool.js.map +1 -0
  110. package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
  111. package/dist/client/extensions/ExtensionViewer.js +24 -2
  112. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  113. package/dist/client/extensions/ToolEditor.d.ts +5 -0
  114. package/dist/client/extensions/ToolEditor.d.ts.map +1 -0
  115. package/dist/client/extensions/ToolEditor.js +129 -0
  116. package/dist/client/extensions/ToolEditor.js.map +1 -0
  117. package/dist/client/extensions/ToolViewer.d.ts +5 -0
  118. package/dist/client/extensions/ToolViewer.d.ts.map +1 -0
  119. package/dist/client/extensions/ToolViewer.js +400 -0
  120. package/dist/client/extensions/ToolViewer.js.map +1 -0
  121. package/dist/client/extensions/ToolViewerPage.d.ts +2 -0
  122. package/dist/client/extensions/ToolViewerPage.d.ts.map +1 -0
  123. package/dist/client/extensions/ToolViewerPage.js +24 -0
  124. package/dist/client/extensions/ToolViewerPage.js.map +1 -0
  125. package/dist/client/extensions/ToolsListPage.d.ts +2 -0
  126. package/dist/client/extensions/ToolsListPage.d.ts.map +1 -0
  127. package/dist/client/extensions/ToolsListPage.js +67 -0
  128. package/dist/client/extensions/ToolsListPage.js.map +1 -0
  129. package/dist/client/extensions/ToolsSidebarSection.d.ts +2 -0
  130. package/dist/client/extensions/ToolsSidebarSection.d.ts.map +1 -0
  131. package/dist/client/extensions/ToolsSidebarSection.js +236 -0
  132. package/dist/client/extensions/ToolsSidebarSection.js.map +1 -0
  133. package/dist/client/extensions/tool-order.d.ts +7 -0
  134. package/dist/client/extensions/tool-order.d.ts.map +1 -0
  135. package/dist/client/extensions/tool-order.js +47 -0
  136. package/dist/client/extensions/tool-order.js.map +1 -0
  137. package/dist/client/index.d.ts +8 -1
  138. package/dist/client/index.d.ts.map +1 -1
  139. package/dist/client/index.js +7 -0
  140. package/dist/client/index.js.map +1 -1
  141. package/dist/client/onboarding/OnboardingPanel.js +1 -0
  142. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  143. package/dist/client/org/InvitationBanner.d.ts.map +1 -1
  144. package/dist/client/org/InvitationBanner.js +23 -2
  145. package/dist/client/org/InvitationBanner.js.map +1 -1
  146. package/dist/client/org/OrgSwitcher.d.ts +5 -4
  147. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  148. package/dist/client/org/OrgSwitcher.js +57 -9
  149. package/dist/client/org/OrgSwitcher.js.map +1 -1
  150. package/dist/client/org/hooks.d.ts.map +1 -1
  151. package/dist/client/org/hooks.js +10 -6
  152. package/dist/client/org/hooks.js.map +1 -1
  153. package/dist/client/org/workspace-app-links.d.ts +31 -0
  154. package/dist/client/org/workspace-app-links.d.ts.map +1 -0
  155. package/dist/client/org/workspace-app-links.js +268 -0
  156. package/dist/client/org/workspace-app-links.js.map +1 -0
  157. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  158. package/dist/client/resources/ResourcesPanel.js +18 -5
  159. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  160. package/dist/client/resources/use-resources.d.ts +18 -13
  161. package/dist/client/resources/use-resources.d.ts.map +1 -1
  162. package/dist/client/resources/use-resources.js +24 -6
  163. package/dist/client/resources/use-resources.js.map +1 -1
  164. package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -1
  165. package/dist/client/settings/BackgroundAgentSection.js +9 -1
  166. package/dist/client/settings/BackgroundAgentSection.js.map +1 -1
  167. package/dist/client/settings/BrowserSection.d.ts.map +1 -1
  168. package/dist/client/settings/BrowserSection.js +16 -1
  169. package/dist/client/settings/BrowserSection.js.map +1 -1
  170. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  171. package/dist/client/settings/SettingsPanel.js +4 -1
  172. package/dist/client/settings/SettingsPanel.js.map +1 -1
  173. package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
  174. package/dist/client/settings/VoiceTranscriptionSection.js +5 -5
  175. package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
  176. package/dist/client/settings/useBuilderStatus.d.ts +8 -0
  177. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  178. package/dist/client/settings/useBuilderStatus.js +50 -13
  179. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  180. package/dist/client/settings/useBuilderStatus.spec.d.ts +2 -0
  181. package/dist/client/settings/useBuilderStatus.spec.d.ts.map +1 -0
  182. package/dist/client/settings/useBuilderStatus.spec.js +64 -0
  183. package/dist/client/settings/useBuilderStatus.spec.js.map +1 -0
  184. package/dist/client/sharing/ShareButton.d.ts +5 -0
  185. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  186. package/dist/client/sharing/ShareButton.js +60 -6
  187. package/dist/client/sharing/ShareButton.js.map +1 -1
  188. package/dist/client/theme.js +1 -1
  189. package/dist/client/theme.js.map +1 -1
  190. package/dist/client/tools/EmbeddedTool.d.ts +20 -0
  191. package/dist/client/tools/EmbeddedTool.d.ts.map +1 -0
  192. package/dist/client/tools/EmbeddedTool.js +199 -0
  193. package/dist/client/tools/EmbeddedTool.js.map +1 -0
  194. package/dist/client/tools/ExtensionSlot.d.ts +27 -0
  195. package/dist/client/tools/ExtensionSlot.d.ts.map +1 -0
  196. package/dist/client/tools/ExtensionSlot.js +96 -0
  197. package/dist/client/tools/ExtensionSlot.js.map +1 -0
  198. package/dist/client/tools/ToolEditor.d.ts +5 -0
  199. package/dist/client/tools/ToolEditor.d.ts.map +1 -0
  200. package/dist/client/tools/ToolEditor.js +129 -0
  201. package/dist/client/tools/ToolEditor.js.map +1 -0
  202. package/dist/client/tools/ToolViewer.d.ts +5 -0
  203. package/dist/client/tools/ToolViewer.d.ts.map +1 -0
  204. package/dist/client/tools/ToolViewer.js +400 -0
  205. package/dist/client/tools/ToolViewer.js.map +1 -0
  206. package/dist/client/tools/ToolViewerPage.d.ts +2 -0
  207. package/dist/client/tools/ToolViewerPage.d.ts.map +1 -0
  208. package/dist/client/tools/ToolViewerPage.js +24 -0
  209. package/dist/client/tools/ToolViewerPage.js.map +1 -0
  210. package/dist/client/tools/ToolsListPage.d.ts +2 -0
  211. package/dist/client/tools/ToolsListPage.d.ts.map +1 -0
  212. package/dist/client/tools/ToolsListPage.js +67 -0
  213. package/dist/client/tools/ToolsListPage.js.map +1 -0
  214. package/dist/client/tools/ToolsSidebarSection.d.ts +2 -0
  215. package/dist/client/tools/ToolsSidebarSection.d.ts.map +1 -0
  216. package/dist/client/tools/ToolsSidebarSection.js +236 -0
  217. package/dist/client/tools/ToolsSidebarSection.js.map +1 -0
  218. package/dist/client/tools/iframe-bridge.d.ts +38 -0
  219. package/dist/client/tools/iframe-bridge.d.ts.map +1 -0
  220. package/dist/client/tools/iframe-bridge.js +207 -0
  221. package/dist/client/tools/iframe-bridge.js.map +1 -0
  222. package/dist/client/tools/index.d.ts +8 -0
  223. package/dist/client/tools/index.d.ts.map +1 -0
  224. package/dist/client/tools/index.js +8 -0
  225. package/dist/client/tools/index.js.map +1 -0
  226. package/dist/client/tools/tool-order.d.ts +7 -0
  227. package/dist/client/tools/tool-order.d.ts.map +1 -0
  228. package/dist/client/tools/tool-order.js +47 -0
  229. package/dist/client/tools/tool-order.js.map +1 -0
  230. package/dist/client/transcription/BuilderTranscriptionCta.d.ts.map +1 -1
  231. package/dist/client/transcription/BuilderTranscriptionCta.js +2 -3
  232. package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -1
  233. package/dist/client/use-change-version.d.ts +46 -0
  234. package/dist/client/use-change-version.d.ts.map +1 -0
  235. package/dist/client/use-change-version.js +135 -0
  236. package/dist/client/use-change-version.js.map +1 -0
  237. package/dist/client/use-chat-threads.d.ts +16 -2
  238. package/dist/client/use-chat-threads.d.ts.map +1 -1
  239. package/dist/client/use-chat-threads.js +87 -12
  240. package/dist/client/use-chat-threads.js.map +1 -1
  241. package/dist/client/use-chat-threads.spec.d.ts +2 -0
  242. package/dist/client/use-chat-threads.spec.d.ts.map +1 -0
  243. package/dist/client/use-chat-threads.spec.js +85 -0
  244. package/dist/client/use-chat-threads.spec.js.map +1 -0
  245. package/dist/client/use-db-sync.d.ts +5 -2
  246. package/dist/client/use-db-sync.d.ts.map +1 -1
  247. package/dist/client/use-db-sync.js +41 -16
  248. package/dist/client/use-db-sync.js.map +1 -1
  249. package/dist/client/use-pinch-zoom.d.ts +35 -0
  250. package/dist/client/use-pinch-zoom.d.ts.map +1 -0
  251. package/dist/client/use-pinch-zoom.js +105 -0
  252. package/dist/client/use-pinch-zoom.js.map +1 -0
  253. package/dist/deploy/workspace-deploy.d.ts.map +1 -1
  254. package/dist/deploy/workspace-deploy.js +99 -5
  255. package/dist/deploy/workspace-deploy.js.map +1 -1
  256. package/dist/extensions/actions.d.ts.map +1 -1
  257. package/dist/extensions/actions.js +3 -0
  258. package/dist/extensions/actions.js.map +1 -1
  259. package/dist/extensions/store.d.ts +5 -0
  260. package/dist/extensions/store.d.ts.map +1 -1
  261. package/dist/extensions/store.js +16 -1
  262. package/dist/extensions/store.js.map +1 -1
  263. package/dist/file-upload/actions/upload-image.d.ts +3 -0
  264. package/dist/file-upload/actions/upload-image.d.ts.map +1 -0
  265. package/dist/file-upload/actions/upload-image.js +145 -0
  266. package/dist/file-upload/actions/upload-image.js.map +1 -0
  267. package/dist/file-upload/builder.d.ts.map +1 -1
  268. package/dist/file-upload/builder.js +31 -11
  269. package/dist/file-upload/builder.js.map +1 -1
  270. package/dist/file-upload/index.d.ts +1 -0
  271. package/dist/file-upload/index.d.ts.map +1 -1
  272. package/dist/file-upload/index.js +1 -0
  273. package/dist/file-upload/index.js.map +1 -1
  274. package/dist/file-upload/pre-upload-attachments.d.ts +39 -0
  275. package/dist/file-upload/pre-upload-attachments.d.ts.map +1 -0
  276. package/dist/file-upload/pre-upload-attachments.js +110 -0
  277. package/dist/file-upload/pre-upload-attachments.js.map +1 -0
  278. package/dist/file-upload/registry.d.ts.map +1 -1
  279. package/dist/file-upload/registry.js +8 -7
  280. package/dist/file-upload/registry.js.map +1 -1
  281. package/dist/onboarding/default-steps.js +1 -1
  282. package/dist/onboarding/default-steps.js.map +1 -1
  283. package/dist/org/context.d.ts +15 -1
  284. package/dist/org/context.d.ts.map +1 -1
  285. package/dist/org/context.js +25 -0
  286. package/dist/org/context.js.map +1 -1
  287. package/dist/org/handlers.d.ts +2 -2
  288. package/dist/org/handlers.d.ts.map +1 -1
  289. package/dist/org/handlers.js +3 -17
  290. package/dist/org/handlers.js.map +1 -1
  291. package/dist/org/index.d.ts +1 -1
  292. package/dist/org/index.d.ts.map +1 -1
  293. package/dist/org/index.js +1 -1
  294. package/dist/org/index.js.map +1 -1
  295. package/dist/resources/handlers.d.ts +6 -0
  296. package/dist/resources/handlers.d.ts.map +1 -1
  297. package/dist/resources/handlers.js +30 -6
  298. package/dist/resources/handlers.js.map +1 -1
  299. package/dist/resources/script-helpers.d.ts +11 -2
  300. package/dist/resources/script-helpers.d.ts.map +1 -1
  301. package/dist/resources/script-helpers.js +20 -3
  302. package/dist/resources/script-helpers.js.map +1 -1
  303. package/dist/resources/store.d.ts +28 -3
  304. package/dist/resources/store.d.ts.map +1 -1
  305. package/dist/resources/store.js +170 -20
  306. package/dist/resources/store.js.map +1 -1
  307. package/dist/scripts/resources/list.d.ts +1 -1
  308. package/dist/scripts/resources/list.d.ts.map +1 -1
  309. package/dist/scripts/resources/list.js +16 -4
  310. package/dist/scripts/resources/list.js.map +1 -1
  311. package/dist/scripts/resources/write.d.ts +1 -1
  312. package/dist/scripts/resources/write.d.ts.map +1 -1
  313. package/dist/scripts/resources/write.js +47 -3
  314. package/dist/scripts/resources/write.js.map +1 -1
  315. package/dist/server/action-discovery.d.ts.map +1 -1
  316. package/dist/server/action-discovery.js +8 -3
  317. package/dist/server/action-discovery.js.map +1 -1
  318. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  319. package/dist/server/agent-chat-plugin.js +214 -25
  320. package/dist/server/agent-chat-plugin.js.map +1 -1
  321. package/dist/server/agent-discovery.d.ts +35 -0
  322. package/dist/server/agent-discovery.d.ts.map +1 -1
  323. package/dist/server/agent-discovery.js +139 -8
  324. package/dist/server/agent-discovery.js.map +1 -1
  325. package/dist/server/app-url.d.ts +12 -6
  326. package/dist/server/app-url.d.ts.map +1 -1
  327. package/dist/server/app-url.js +58 -11
  328. package/dist/server/app-url.js.map +1 -1
  329. package/dist/server/auth.d.ts +22 -0
  330. package/dist/server/auth.d.ts.map +1 -1
  331. package/dist/server/auth.js +316 -65
  332. package/dist/server/auth.js.map +1 -1
  333. package/dist/server/better-auth-instance.d.ts +0 -4
  334. package/dist/server/better-auth-instance.d.ts.map +1 -1
  335. package/dist/server/better-auth-instance.js +0 -3
  336. package/dist/server/better-auth-instance.js.map +1 -1
  337. package/dist/server/builder-browser.d.ts.map +1 -1
  338. package/dist/server/builder-browser.js +23 -0
  339. package/dist/server/builder-browser.js.map +1 -1
  340. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  341. package/dist/server/core-routes-plugin.js +29 -14
  342. package/dist/server/core-routes-plugin.js.map +1 -1
  343. package/dist/server/credential-provider.d.ts +14 -0
  344. package/dist/server/credential-provider.d.ts.map +1 -1
  345. package/dist/server/credential-provider.js +88 -11
  346. package/dist/server/credential-provider.js.map +1 -1
  347. package/dist/server/google-auth-plugin.d.ts.map +1 -1
  348. package/dist/server/google-auth-plugin.js +65 -17
  349. package/dist/server/google-auth-plugin.js.map +1 -1
  350. package/dist/server/google-oauth.d.ts.map +1 -1
  351. package/dist/server/google-oauth.js +47 -17
  352. package/dist/server/google-oauth.js.map +1 -1
  353. package/dist/server/index.d.ts +1 -1
  354. package/dist/server/index.d.ts.map +1 -1
  355. package/dist/server/index.js +1 -1
  356. package/dist/server/index.js.map +1 -1
  357. package/dist/server/local-migration.d.ts +41 -0
  358. package/dist/server/local-migration.d.ts.map +1 -0
  359. package/dist/server/local-migration.js +235 -0
  360. package/dist/server/local-migration.js.map +1 -0
  361. package/dist/server/oauth-public-origin.d.ts.map +1 -1
  362. package/dist/server/oauth-public-origin.js +19 -1
  363. package/dist/server/oauth-public-origin.js.map +1 -1
  364. package/dist/server/onboarding-html.d.ts.map +1 -1
  365. package/dist/server/onboarding-html.js +74 -19
  366. package/dist/server/onboarding-html.js.map +1 -1
  367. package/dist/server/poll.d.ts.map +1 -1
  368. package/dist/server/poll.js +20 -5
  369. package/dist/server/poll.js.map +1 -1
  370. package/dist/server/request-context.d.ts +8 -0
  371. package/dist/server/request-context.d.ts.map +1 -1
  372. package/dist/server/request-context.js.map +1 -1
  373. package/dist/shared/index.d.ts +2 -0
  374. package/dist/shared/index.d.ts.map +1 -1
  375. package/dist/shared/index.js +2 -0
  376. package/dist/shared/index.js.map +1 -1
  377. package/dist/shared/llm-connection.d.ts +10 -0
  378. package/dist/shared/llm-connection.d.ts.map +1 -0
  379. package/dist/shared/llm-connection.js +29 -0
  380. package/dist/shared/llm-connection.js.map +1 -0
  381. package/dist/shared/workspace-app-audience.d.ts +25 -0
  382. package/dist/shared/workspace-app-audience.d.ts.map +1 -0
  383. package/dist/shared/workspace-app-audience.js +126 -0
  384. package/dist/shared/workspace-app-audience.js.map +1 -0
  385. package/dist/shared/workspace-app-id.d.ts +1 -1
  386. package/dist/shared/workspace-app-id.d.ts.map +1 -1
  387. package/dist/shared/workspace-app-id.js +1 -0
  388. package/dist/shared/workspace-app-id.js.map +1 -1
  389. package/dist/sharing/access.d.ts.map +1 -1
  390. package/dist/sharing/access.js +46 -5
  391. package/dist/sharing/access.js.map +1 -1
  392. package/dist/sharing/actions/list-resource-shares.d.ts.map +1 -1
  393. package/dist/sharing/actions/list-resource-shares.js +8 -1
  394. package/dist/sharing/actions/list-resource-shares.js.map +1 -1
  395. package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -1
  396. package/dist/sharing/actions/set-resource-visibility.js +12 -3
  397. package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
  398. package/dist/sharing/actions/share-resource.d.ts.map +1 -1
  399. package/dist/sharing/actions/share-resource.js +50 -1
  400. package/dist/sharing/actions/share-resource.js.map +1 -1
  401. package/dist/sharing/registry.d.ts +26 -0
  402. package/dist/sharing/registry.d.ts.map +1 -1
  403. package/dist/sharing/registry.js.map +1 -1
  404. package/dist/styles/agent-native.css +91 -0
  405. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +72 -0
  406. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +60 -37
  407. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +28 -17
  408. package/dist/templates/default/.agents/skills/shadcn-ui/SKILL.md +79 -0
  409. package/dist/templates/default/AGENTS.md +22 -19
  410. package/dist/templates/default/actions/navigate.ts +3 -0
  411. package/dist/templates/default/app/hooks/use-navigation-state.ts +29 -5
  412. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +251 -0
  413. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +264 -0
  414. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +130 -0
  415. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +112 -0
  416. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +88 -0
  417. package/dist/templates/workspace-core/.agents/skills/automations/SKILL.md +191 -0
  418. package/dist/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +74 -0
  419. package/dist/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +75 -0
  420. package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +190 -0
  421. package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +168 -0
  422. package/dist/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +163 -0
  423. package/dist/templates/workspace-core/.agents/skills/extension-points/SKILL.md +205 -0
  424. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +720 -0
  425. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +92 -0
  426. package/dist/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +285 -0
  427. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +192 -0
  428. package/dist/templates/workspace-core/.agents/skills/onboarding/SKILL.md +43 -0
  429. package/dist/templates/workspace-core/.agents/skills/portability/SKILL.md +84 -0
  430. package/dist/templates/workspace-core/.agents/skills/qa/SKILL.md +313 -0
  431. package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +112 -0
  432. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +165 -0
  433. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +41 -0
  434. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +239 -0
  435. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +191 -0
  436. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +79 -0
  437. package/dist/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +73 -0
  438. package/dist/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +79 -0
  439. package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +217 -0
  440. package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +132 -0
  441. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +150 -0
  442. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +124 -0
  443. package/dist/templates/workspace-core/AGENTS.md +16 -1
  444. package/dist/templates/workspace-root/AGENTS.md +35 -0
  445. package/dist/templates/workspace-root/README.md +7 -0
  446. package/dist/tools/actions.d.ts +3 -0
  447. package/dist/tools/actions.d.ts.map +1 -0
  448. package/dist/tools/actions.js +272 -0
  449. package/dist/tools/actions.js.map +1 -0
  450. package/dist/tools/fetch-tool.d.ts +23 -0
  451. package/dist/tools/fetch-tool.d.ts.map +1 -0
  452. package/dist/tools/fetch-tool.js +178 -0
  453. package/dist/tools/fetch-tool.js.map +1 -0
  454. package/dist/tools/html-shell.d.ts +45 -0
  455. package/dist/tools/html-shell.d.ts.map +1 -0
  456. package/dist/tools/html-shell.js +514 -0
  457. package/dist/tools/html-shell.js.map +1 -0
  458. package/dist/tools/proxy-security.d.ts +12 -0
  459. package/dist/tools/proxy-security.d.ts.map +1 -0
  460. package/dist/tools/proxy-security.js +158 -0
  461. package/dist/tools/proxy-security.js.map +1 -0
  462. package/dist/tools/routes.d.ts +2 -0
  463. package/dist/tools/routes.d.ts.map +1 -0
  464. package/dist/tools/routes.js +627 -0
  465. package/dist/tools/routes.js.map +1 -0
  466. package/dist/tools/schema.d.ts +664 -0
  467. package/dist/tools/schema.d.ts.map +1 -0
  468. package/dist/tools/schema.js +146 -0
  469. package/dist/tools/schema.js.map +1 -0
  470. package/dist/tools/slots/routes.d.ts +15 -0
  471. package/dist/tools/slots/routes.d.ts.map +1 -0
  472. package/dist/tools/slots/routes.js +94 -0
  473. package/dist/tools/slots/routes.js.map +1 -0
  474. package/dist/tools/slots/schema.d.ts +303 -0
  475. package/dist/tools/slots/schema.d.ts.map +1 -0
  476. package/dist/tools/slots/schema.js +76 -0
  477. package/dist/tools/slots/schema.js.map +1 -0
  478. package/dist/tools/slots/store.d.ts +66 -0
  479. package/dist/tools/slots/store.d.ts.map +1 -0
  480. package/dist/tools/slots/store.js +227 -0
  481. package/dist/tools/slots/store.js.map +1 -0
  482. package/dist/tools/store.d.ts +40 -0
  483. package/dist/tools/store.d.ts.map +1 -0
  484. package/dist/tools/store.js +193 -0
  485. package/dist/tools/store.js.map +1 -0
  486. package/dist/tools/theme.d.ts +2 -0
  487. package/dist/tools/theme.d.ts.map +1 -0
  488. package/dist/tools/theme.js +67 -0
  489. package/dist/tools/theme.js.map +1 -0
  490. package/dist/tools/url-safety.d.ts +24 -0
  491. package/dist/tools/url-safety.d.ts.map +1 -0
  492. package/dist/tools/url-safety.js +224 -0
  493. package/dist/tools/url-safety.js.map +1 -0
  494. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  495. package/dist/vite/action-types-plugin.js +4 -0
  496. package/dist/vite/action-types-plugin.js.map +1 -1
  497. package/docs/content/authentication.md +36 -0
  498. package/docs/content/creating-templates.md +15 -0
  499. package/docs/content/dispatch.md +3 -3
  500. package/docs/content/multi-app-workspace.md +5 -0
  501. package/docs/content/tracking.md +12 -0
  502. package/docs/content/workspace-management.md +39 -4
  503. package/package.json +15 -12
  504. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +72 -0
  505. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +60 -37
  506. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +28 -17
  507. package/src/templates/default/.agents/skills/shadcn-ui/SKILL.md +79 -0
  508. package/src/templates/default/AGENTS.md +22 -19
  509. package/src/templates/default/actions/navigate.ts +3 -0
  510. package/src/templates/default/app/hooks/use-navigation-state.ts +29 -5
  511. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +251 -0
  512. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +264 -0
  513. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +130 -0
  514. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +112 -0
  515. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +88 -0
  516. package/src/templates/workspace-core/.agents/skills/automations/SKILL.md +191 -0
  517. package/src/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +74 -0
  518. package/src/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +75 -0
  519. package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +190 -0
  520. package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +168 -0
  521. package/src/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +163 -0
  522. package/src/templates/workspace-core/.agents/skills/extension-points/SKILL.md +205 -0
  523. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +720 -0
  524. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +92 -0
  525. package/src/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +285 -0
  526. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +192 -0
  527. package/src/templates/workspace-core/.agents/skills/onboarding/SKILL.md +43 -0
  528. package/src/templates/workspace-core/.agents/skills/portability/SKILL.md +84 -0
  529. package/src/templates/workspace-core/.agents/skills/qa/SKILL.md +313 -0
  530. package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +112 -0
  531. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +165 -0
  532. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +41 -0
  533. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +239 -0
  534. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +191 -0
  535. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +79 -0
  536. package/src/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +73 -0
  537. package/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +79 -0
  538. package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +217 -0
  539. package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +132 -0
  540. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +150 -0
  541. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +124 -0
  542. package/src/templates/workspace-core/AGENTS.md +16 -1
  543. package/src/templates/workspace-root/AGENTS.md +35 -0
  544. package/src/templates/workspace-root/README.md +7 -0
@@ -1,13 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import React, { useState, useRef, useEffect, useCallback, useMemo, forwardRef, useImperativeHandle, } from "react";
3
- import { AssistantRuntimeProvider, useLocalRuntime, useThreadRuntime, useThread, useAui, useComposer, useMessageRuntime, ThreadPrimitive, ComposerPrimitive, MessagePrimitive, } from "@assistant-ui/react";
4
- import { SimpleImageAttachmentAdapter, CompositeAttachmentAdapter, } from "@assistant-ui/react";
3
+ import { AssistantRuntimeProvider, useLocalRuntime, useThreadRuntime, useThread, useAui, useComposer, useComposerRuntime, useMessageRuntime, ThreadPrimitive, ComposerPrimitive, MessagePrimitive, } from "@assistant-ui/react";
4
+ import { CompositeAttachmentAdapter } from "@assistant-ui/react";
5
5
  import { MarkdownTextPrimitive } from "@assistant-ui/react-markdown";
6
- import ReactMarkdown from "react-markdown";
6
+ import ReactMarkdown, { defaultUrlTransform } from "react-markdown";
7
7
  import remarkGfm from "remark-gfm";
8
8
  import { createAgentChatAdapter } from "./agent-chat-adapter.js";
9
9
  import { getActiveRun } from "./active-run-state.js";
10
10
  import { AgentAutoContinueSignal, readSSEStreamRaw, } from "./sse-event-processor.js";
11
+ import { captureError, trackEvent } from "./analytics.js";
11
12
  import { cn } from "./utils.js";
12
13
  import { TextAttachmentAdapter } from "./composer/attachment-accept.js";
13
14
  import { AgentTaskCard } from "./AgentTaskCard.js";
@@ -18,12 +19,40 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel,
18
19
  import { IframeEmbed, parseEmbedBody } from "./IframeEmbed.js";
19
20
  import { useDevMode } from "./use-dev-mode.js";
20
21
  import { agentNativePath } from "./api-path.js";
21
- import { BUILDER_SPACE_SETTINGS_URL } from "./error-format.js";
22
+ import { BUILDER_SPACE_SETTINGS_URL, NEW_CHAT_ACTION_HREF, } from "./error-format.js";
22
23
  import { ThumbsFeedback } from "./observability/ThumbsFeedback.js";
23
24
  import { TiptapComposer, } from "./composer/TiptapComposer.js";
24
25
  import { isPastedTextAttachmentName } from "./composer/pasted-text.js";
25
26
  import { PastedTextChip } from "./composer/PastedTextChip.js";
26
- import { IconMessage, IconX, IconPlayerStop, IconCheck, IconChevronDown, IconCopy, IconTerminal, IconLoader2, IconCircleX, IconSquareFilled, IconClock, IconFile, IconFolder, IconFileText, IconCheckbox, IconMail, IconUser, IconPresentation, IconStack2, IconMessageChatbot, IconLock, IconArrowBackUp, IconExternalLink, IconDots, IconGitFork, IconId, IconQuote, IconGauge, IconArrowRight, IconSettings, IconAlertTriangle, IconRefresh, IconPlayerPlay, IconClipboardList, IconSearch, IconArrowsMaximize, IconArrowsMinimize, } from "@tabler/icons-react";
27
+ import { IconMessage, IconX, IconPlayerStop, IconCheck, IconChevronDown, IconCopy, IconTerminal, IconLoader2, IconCircleX, IconSquareFilled, IconClock, IconFile, IconFolder, IconFileText, IconCheckbox, IconMail, IconUser, IconPresentation, IconStack2, IconMessageChatbot, IconLock, IconArrowBackUp, IconExternalLink, IconDots, IconGitFork, IconId, IconQuote, IconGauge, IconArrowRight, IconSettings, IconAlertTriangle, IconRefresh, IconPlayerPlay, IconClipboardList, IconSearch, IconArrowsMaximize, IconArrowsMinimize, IconPlus, } from "@tabler/icons-react";
28
+ class DownscalingImageAttachmentAdapter {
29
+ accept = "image/*";
30
+ async add(state) {
31
+ return {
32
+ id: state.file.name,
33
+ type: "image",
34
+ name: state.file.name,
35
+ contentType: state.file.type,
36
+ file: state.file,
37
+ status: { type: "requires-action", reason: "composer-send" },
38
+ };
39
+ }
40
+ async send(attachment) {
41
+ return {
42
+ ...attachment,
43
+ status: { type: "complete" },
44
+ content: [
45
+ {
46
+ type: "image",
47
+ image: await getImageFileDataURL(attachment.file),
48
+ },
49
+ ],
50
+ };
51
+ }
52
+ async remove() {
53
+ // noop
54
+ }
55
+ }
27
56
  class BinaryDocumentAttachmentAdapter {
28
57
  accept = "application/pdf,.pdf";
29
58
  async add(state) {
@@ -69,6 +98,51 @@ function getFileDataURL(file) {
69
98
  reader.readAsDataURL(file);
70
99
  });
71
100
  }
101
+ // Anthropic / OpenAI vision inputs choke on multi-megabyte images, and
102
+ // base64-encoding a raw screenshot eats enough heap to crash the composer
103
+ // (PayloadTooLarge / "Maximum call stack" in serializers). Downscale large
104
+ // images on the client before we ever serialize them.
105
+ const MAX_IMAGE_BYTES = 4 * 1024 * 1024;
106
+ const MAX_IMAGE_DIMENSION = 2048;
107
+ function loadImage(url) {
108
+ return new Promise((resolve, reject) => {
109
+ const img = new Image();
110
+ img.onload = () => resolve(img);
111
+ img.onerror = () => reject(new Error("Failed to decode pasted image"));
112
+ img.src = url;
113
+ });
114
+ }
115
+ async function getImageFileDataURL(file) {
116
+ if (file.size <= MAX_IMAGE_BYTES) {
117
+ return getFileDataURL(file);
118
+ }
119
+ if (typeof document === "undefined" || typeof Image === "undefined") {
120
+ return getFileDataURL(file);
121
+ }
122
+ const objectUrl = URL.createObjectURL(file);
123
+ try {
124
+ const img = await loadImage(objectUrl);
125
+ const ratio = Math.min(MAX_IMAGE_DIMENSION / img.naturalWidth, MAX_IMAGE_DIMENSION / img.naturalHeight, 1);
126
+ const width = Math.max(1, Math.round(img.naturalWidth * ratio));
127
+ const height = Math.max(1, Math.round(img.naturalHeight * ratio));
128
+ const canvas = document.createElement("canvas");
129
+ canvas.width = width;
130
+ canvas.height = height;
131
+ const ctx = canvas.getContext("2d");
132
+ if (!ctx) {
133
+ return getFileDataURL(file);
134
+ }
135
+ ctx.drawImage(img, 0, 0, width, height);
136
+ const useJpeg = file.type !== "image/png" || file.size > MAX_IMAGE_BYTES * 2;
137
+ return canvas.toDataURL(useJpeg ? "image/jpeg" : "image/png", 0.85);
138
+ }
139
+ catch {
140
+ return getFileDataURL(file);
141
+ }
142
+ finally {
143
+ URL.revokeObjectURL(objectUrl);
144
+ }
145
+ }
72
146
  function createUserMessageRunConfig(references, requestMode) {
73
147
  const custom = {};
74
148
  if (references && references.length > 0) {
@@ -145,7 +219,7 @@ async function serializeQueuedAttachments(attachments) {
145
219
  name,
146
220
  contentType: file.type,
147
221
  status: { type: "complete" },
148
- content: [{ type: "image", image: await getFileDataURL(file) }],
222
+ content: [{ type: "image", image: await getImageFileDataURL(file) }],
149
223
  });
150
224
  }
151
225
  else if (isTextLikeFile(file)) {
@@ -543,14 +617,23 @@ function HighlightedCodeBlock({ code, lang }) {
543
617
  }
544
618
  return (_jsx("pre", { children: _jsx("code", { className: lang ? `language-${lang}` : undefined, children: code }) }));
545
619
  }
620
+ const CTA_BUTTON_CLASSES = "agent-markdown-cta mt-1 inline-flex items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background no-underline shadow-sm transition-colors hover:bg-foreground/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background cursor-pointer";
546
621
  const markdownComponents = {
547
622
  a(props) {
548
623
  const { href, children, className, rel: _rel, target: _target, ...rest } = props;
624
+ if (href === NEW_CHAT_ACTION_HREF) {
625
+ // In-app action: dispatch a CustomEvent that MultiTabAssistantChat
626
+ // listens for and opens a new chat tab. Not an external navigation.
627
+ return (_jsxs("button", { type: "button", onClick: (e) => {
628
+ e.preventDefault();
629
+ window.dispatchEvent(new CustomEvent("agent-chat:new-chat"));
630
+ }, className: cn(CTA_BUTTON_CLASSES, className), children: [_jsx(IconPlus, { size: 13, strokeWidth: 2, "aria-hidden": "true" }), _jsx("span", { children: children })] }));
631
+ }
549
632
  const isBuilderCta = isBuilderErrorCtaHref(href);
550
633
  if (!isBuilderCta) {
551
634
  return (_jsx("a", { href: href, className: className, ...rest, children: children }));
552
635
  }
553
- return (_jsxs("a", { href: href, target: "_blank", rel: "noreferrer", className: cn("agent-markdown-cta mt-1 inline-flex items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background no-underline shadow-sm transition-colors hover:bg-foreground/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background", className), ...rest, children: [_jsx("span", { children: children }), _jsx(IconExternalLink, { size: 13, strokeWidth: 2, "aria-hidden": "true" })] }));
636
+ return (_jsxs("a", { href: href, target: "_blank", rel: "noreferrer", className: cn(CTA_BUTTON_CLASSES, className), ...rest, children: [_jsx("span", { children: children }), _jsx(IconExternalLink, { size: 13, strokeWidth: 2, "aria-hidden": "true" })] }));
554
637
  },
555
638
  pre(props) {
556
639
  const { children, ...rest } = props;
@@ -587,11 +670,20 @@ function isBuilderErrorCtaHref(href) {
587
670
  return false;
588
671
  }
589
672
  }
673
+ // react-markdown's defaultUrlTransform strips href values whose protocol
674
+ // isn't on its safe list (https, mailto, etc.). Our in-app pseudo-href
675
+ // `agent-native:new-chat` would be blanked out by that, so let it through
676
+ // while delegating every other URL to the default transform for sanitization.
677
+ function markdownUrlTransform(value) {
678
+ if (value === NEW_CHAT_ACTION_HREF)
679
+ return value;
680
+ return defaultUrlTransform(value);
681
+ }
590
682
  function MarkdownText() {
591
683
  useEffect(() => {
592
684
  injectMarkdownStyles();
593
685
  }, []);
594
- return (_jsx(MarkdownTextPrimitive, { smooth: true, className: "agent-markdown break-words", remarkPlugins: [remarkGfm], components: markdownComponents }));
686
+ return (_jsx(MarkdownTextPrimitive, { smooth: true, className: "agent-markdown break-words", remarkPlugins: [remarkGfm], components: markdownComponents, urlTransform: markdownUrlTransform }));
595
687
  }
596
688
  // ─── Composer Attachment Preview ─────────────────────────────────────────────
597
689
  function getImageAttachmentSrc(attachment) {
@@ -891,7 +983,7 @@ function ToolCallDisplay({ toolName, argsText, args, result, isRunning, }) {
891
983
  const isExpanded = isAgentCall ? hasStreamText && expanded : expanded;
892
984
  return (_jsxs("div", { className: "my-1 overflow-hidden", children: [_jsxs("button", { onClick: () => canExpand && setExpanded(!isExpanded), "aria-expanded": canExpand ? isExpanded : undefined, className: cn("flex items-center gap-2 rounded-md px-2.5 py-1.5 text-xs font-mono w-full text-left overflow-hidden", isRunning
893
985
  ? "bg-muted text-muted-foreground"
894
- : "bg-muted text-muted-foreground hover:bg-accent"), children: [_jsx("span", { className: "shrink-0", children: isRunning ? (_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" })) : isAgentError ? (_jsx(IconCircleX, { className: "h-3 w-3 text-destructive" })) : result !== undefined ? (_jsx(IconCheck, { className: "h-3 w-3 text-emerald-500" })) : (_jsx(IconSquareFilled, { className: "h-3 w-3 text-muted-foreground" })) }), _jsxs("span", { className: "truncate min-w-0", children: [_jsx("span", { className: "font-medium", children: displayName }), argsStr && _jsxs("span", { className: "opacity-60 ml-1", children: ["(", argsStr, ")"] })] }), canExpand && (_jsx(IconChevronDown, { className: cn("ml-auto h-3 w-3 shrink-0 opacity-40", isExpanded && "rotate-180") }))] }), isExpanded && isAgentCall && hasStreamText && (_jsx("div", { ref: streamRef, className: "mt-1 rounded-md bg-muted/50 px-3 py-2 text-xs text-muted-foreground break-words max-h-48 overflow-y-auto agent-markdown prose prose-sm prose-invert max-w-none", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents, children: agentStreamText }) })), isExpanded && !isAgentCall && (hasArgs || result !== undefined) && (_jsxs("div", { className: "mt-1 space-y-2 rounded-md bg-muted/50 px-3 py-2 text-xs text-muted-foreground", children: [inputPayload && _jsx(ToolDetailViewer, { payload: inputPayload }), resultPayload && _jsx(ToolDetailViewer, { payload: resultPayload })] }))] }));
986
+ : "bg-muted text-muted-foreground hover:bg-accent"), children: [_jsx("span", { className: "shrink-0", children: isRunning ? (_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" })) : isAgentError ? (_jsx(IconCircleX, { className: "h-3 w-3 text-destructive" })) : result !== undefined ? (_jsx(IconCheck, { className: "h-3 w-3 text-emerald-500" })) : (_jsx(IconSquareFilled, { className: "h-3 w-3 text-muted-foreground" })) }), _jsxs("span", { className: "truncate min-w-0", children: [_jsx("span", { className: "font-medium", children: displayName }), argsStr && _jsxs("span", { className: "opacity-60 ml-1", children: ["(", argsStr, ")"] })] }), canExpand && (_jsx(IconChevronDown, { className: cn("ml-auto h-3 w-3 shrink-0 opacity-40", isExpanded && "rotate-180") }))] }), isExpanded && isAgentCall && hasStreamText && (_jsx("div", { ref: streamRef, className: "mt-1 rounded-md bg-muted/50 px-3 py-2 text-xs text-muted-foreground break-words max-h-48 overflow-y-auto agent-markdown prose prose-sm prose-invert max-w-none", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents, urlTransform: markdownUrlTransform, children: agentStreamText }) })), isExpanded && !isAgentCall && (hasArgs || result !== undefined) && (_jsxs("div", { className: "mt-1 space-y-2 rounded-md bg-muted/50 px-3 py-2 text-xs text-muted-foreground", children: [inputPayload && _jsx(ToolDetailViewer, { payload: inputPayload }), resultPayload && _jsx(ToolDetailViewer, { payload: resultPayload })] }))] }));
895
987
  }
896
988
  function ToolCallFallback({ toolName, args, argsText, result, }) {
897
989
  const chatRunning = React.useContext(ChatRunningContext);
@@ -913,7 +1005,7 @@ function ReconnectStreamMessage({ content }) {
913
1005
  }, [content]);
914
1006
  return (_jsx("div", { className: "flex justify-start", children: _jsxs("div", { className: "max-w-[95%] text-sm leading-relaxed text-foreground space-y-1", children: [content.map((part, i) => {
915
1007
  if (part.type === "text") {
916
- return (_jsx("div", { className: "agent-markdown break-words", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents, children: part.text }) }, `reconnect-text-${i}`));
1008
+ return (_jsx("div", { className: "agent-markdown break-words", children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents, urlTransform: markdownUrlTransform, children: part.text }) }, `reconnect-text-${i}`));
917
1009
  }
918
1010
  if (part.type === "tool-call") {
919
1011
  return (_jsx(ToolCallDisplay, { toolName: part.toolName, argsText: part.argsText, args: part.args, result: part.result, isRunning: part.result === undefined && chatRunning }, `reconnect-tool-${i}`));
@@ -953,9 +1045,7 @@ const richMentionPattern = /@\[([^\]|]+)\|([^\]]+)\]/g;
953
1045
  const plainMentionPattern = /((?:^|(?<=\s))@(\w+))/g;
954
1046
  function UserMessageText({ text }) {
955
1047
  // Strip injected <context>...</context> blocks before display
956
- const displayText = text
957
- .replace(/<context>[\s\S]*?<\/context>\n?/g, "")
958
- .trim();
1048
+ const displayText = displayableUserMessageText(text);
959
1049
  const parts = [];
960
1050
  let lastIndex = 0;
961
1051
  let match;
@@ -995,6 +1085,77 @@ function UserMessageText({ text }) {
995
1085
  }
996
1086
  return _jsx(_Fragment, { children: parts.length > 0 ? parts : displayText });
997
1087
  }
1088
+ export function displayableUserMessageText(text) {
1089
+ return text.replace(/<context>[\s\S]*?<\/context>\n?/g, "").trim();
1090
+ }
1091
+ export function isAssistantUiStaleIndexError(error) {
1092
+ const message = error instanceof Error ? error.message : String(error ?? "");
1093
+ return /^tapClientLookup: Index \d+ out of bounds \(length: \d+\)$/.test(message);
1094
+ }
1095
+ export class AssistantUiStaleIndexErrorBoundary extends React.Component {
1096
+ state = {
1097
+ error: null,
1098
+ retryToken: 0,
1099
+ };
1100
+ retryTimer = null;
1101
+ static getDerivedStateFromError(error) {
1102
+ return {
1103
+ error: error instanceof Error ? error : new Error(String(error ?? "")),
1104
+ };
1105
+ }
1106
+ componentDidCatch(error, info) {
1107
+ if (!isAssistantUiStaleIndexError(error))
1108
+ return;
1109
+ captureError(error, {
1110
+ tags: {
1111
+ component: this.props.componentName ?? "AssistantChat",
1112
+ recoverable: "assistant-ui-stale-message-index",
1113
+ },
1114
+ extra: {
1115
+ resetKey: this.props.resetKey,
1116
+ componentStack: info.componentStack,
1117
+ },
1118
+ });
1119
+ if (this.retryTimer)
1120
+ return;
1121
+ this.retryTimer = setTimeout(() => {
1122
+ this.retryTimer = null;
1123
+ this.setState((state) => {
1124
+ if (!state.error || !isAssistantUiStaleIndexError(state.error)) {
1125
+ return null;
1126
+ }
1127
+ return { error: null, retryToken: state.retryToken + 1 };
1128
+ });
1129
+ }, 0);
1130
+ }
1131
+ componentDidUpdate(prevProps) {
1132
+ if (this.state.error &&
1133
+ isAssistantUiStaleIndexError(this.state.error) &&
1134
+ prevProps.resetKey !== this.props.resetKey) {
1135
+ this.setState((state) => ({
1136
+ error: null,
1137
+ retryToken: state.retryToken + 1,
1138
+ }));
1139
+ }
1140
+ }
1141
+ componentWillUnmount() {
1142
+ if (this.retryTimer) {
1143
+ clearTimeout(this.retryTimer);
1144
+ }
1145
+ }
1146
+ render() {
1147
+ if (this.state.error) {
1148
+ if (!isAssistantUiStaleIndexError(this.state.error)) {
1149
+ throw this.state.error;
1150
+ }
1151
+ return null;
1152
+ }
1153
+ return (_jsx(React.Fragment, { children: this.props.children }, `${this.props.resetKey}:${this.state.retryToken}`));
1154
+ }
1155
+ }
1156
+ export function AssistantMessageListErrorBoundary({ resetKey, children, }) {
1157
+ return (_jsx(AssistantUiStaleIndexErrorBoundary, { resetKey: resetKey, componentName: "AssistantMessageList", children: children }));
1158
+ }
998
1159
  function UserMessageAttachments() {
999
1160
  const messageRuntime = useMessageRuntime();
1000
1161
  const msg = messageRuntime.getState();
@@ -1023,10 +1184,17 @@ function UserMessage() {
1023
1184
  const [isExpandable, setIsExpandable] = useState(false);
1024
1185
  const contentRef = useRef(null);
1025
1186
  const messageRuntime = useMessageRuntime();
1026
- const timestamp = formatMessageTimestamp(messageRuntime.getState().createdAt);
1187
+ const message = messageRuntime.getState();
1188
+ const timestamp = formatMessageTimestamp(message.createdAt);
1189
+ const hasDisplayableText = message.content
1190
+ ?.filter((part) => {
1191
+ return part.type === "text" && typeof part.text === "string";
1192
+ })
1193
+ .some((part) => displayableUserMessageText(part.text).length > 0) ??
1194
+ false;
1027
1195
  useEffect(() => {
1028
1196
  const el = contentRef.current;
1029
- if (!el)
1197
+ if (!el || !hasDisplayableText)
1030
1198
  return;
1031
1199
  const measure = () => {
1032
1200
  setIsExpandable(el.scrollHeight > 200);
@@ -1035,8 +1203,8 @@ function UserMessage() {
1035
1203
  const observer = new ResizeObserver(measure);
1036
1204
  observer.observe(el);
1037
1205
  return () => observer.disconnect();
1038
- }, []);
1039
- return (_jsx("div", { className: "group flex justify-end", style: { contentVisibility: "auto" }, children: _jsxs("div", { className: "max-w-[85%]", children: [_jsx(UserMessageAttachments, {}), _jsxs("div", { className: "relative rounded-lg bg-accent px-3 py-2 text-sm leading-relaxed text-foreground", onCopy: (e) => {
1206
+ }, [hasDisplayableText]);
1207
+ return (_jsx("div", { className: "group flex justify-end", style: { contentVisibility: "auto" }, children: _jsxs("div", { className: "max-w-[85%]", children: [_jsx(UserMessageAttachments, {}), hasDisplayableText && (_jsxs("div", { className: "relative rounded-lg bg-accent px-3 py-2 text-sm leading-relaxed text-foreground", onCopy: (e) => {
1040
1208
  const selection = window.getSelection();
1041
1209
  if (!selection || selection.rangeCount === 0)
1042
1210
  return;
@@ -1053,7 +1221,7 @@ function UserMessage() {
1053
1221
  e.clipboardData.setData("text/plain", div.textContent || "");
1054
1222
  }, children: [_jsx("div", { ref: contentRef, className: cn("whitespace-pre-wrap break-words", !expanded && isExpandable && "max-h-[200px] overflow-hidden"), children: _jsx(MessagePrimitive.Parts, { components: {
1055
1223
  Text: UserMessageText,
1056
- } }) }), !expanded && isExpandable && (_jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-14 rounded-b-lg bg-gradient-to-t from-accent via-accent/90 to-transparent" }))] }), isExpandable && (_jsxs("button", { type: "button", onClick: () => setExpanded((prev) => !prev), className: "mt-1 inline-flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { className: cn("h-3.5 w-3.5 transition-transform", expanded && "rotate-180") }), expanded ? "Collapse" : "Expand"] })), timestamp && (_jsx("div", { className: "mt-1 flex justify-end", children: _jsx(MessageTimestamp, { timestamp: timestamp, className: "opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100" }) }))] }) }));
1224
+ } }) }), !expanded && isExpandable && (_jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-14 rounded-b-lg bg-gradient-to-t from-accent via-accent/90 to-transparent" }))] })), hasDisplayableText && isExpandable && (_jsxs("button", { type: "button", onClick: () => setExpanded((prev) => !prev), className: "mt-1 inline-flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { className: cn("h-3.5 w-3.5 transition-transform", expanded && "rotate-180") }), expanded ? "Collapse" : "Expand"] })), timestamp && (_jsx("div", { className: "mt-1 flex justify-end", children: _jsx(MessageTimestamp, { timestamp: timestamp, className: "opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100" }) }))] }) }));
1057
1225
  }
1058
1226
  const CheckpointContext = React.createContext(null);
1059
1227
  const MessageActionsContext = React.createContext(null);
@@ -1217,6 +1385,7 @@ function ThinkingIndicator({ label = "Thinking" } = {}) {
1217
1385
  // session. See packages/desktop-app/src/main/index.ts.
1218
1386
  function BuilderConnectCta({ variant = "primary", onConnected, }) {
1219
1387
  const { configured, orgName, connecting, error, start } = useBuilderConnectFlow({
1388
+ trackingSource: "assistant_chat_builder_cta",
1220
1389
  onConnected,
1221
1390
  });
1222
1391
  const containerClass = variant === "compact"
@@ -1354,7 +1523,14 @@ function RunErrorRecoveryCard({ info, onContinue, onRetry, onFork, onDismiss, })
1354
1523
  }, [info]);
1355
1524
  return (_jsxs("div", { className: "rounded-lg border border-amber-500/25 bg-amber-500/[0.06] p-3 text-sm", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-amber-500/10 text-amber-700 dark:text-amber-300", children: _jsx(IconAlertTriangle, { size: 14 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium text-foreground", children: canRecover
1356
1525
  ? "The agent stopped before finishing"
1357
- : "The agent hit an error" }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: info.message }), shouldShowBuilderReconnect && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: "The current Builder.io or model-provider credential was rejected. Reconnect Builder.io, then retry this message." })), (info.runId || info.errorCode || info.details) && (_jsxs("button", { type: "button", onClick: () => setDetailsOpen((v) => !v), className: "mt-2 inline-flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { size: 12, className: cn("transition-transform", detailsOpen && "rotate-180") }), "Details"] })), detailsOpen && (_jsxs("div", { className: "mt-2 rounded-md border border-border/60 bg-background/70 p-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: [info.runId && _jsxs("div", { children: ["run: ", info.runId] }), info.errorCode && _jsxs("div", { children: ["code: ", info.errorCode] }), info.details && (_jsx("pre", { className: "mt-2 max-h-28 overflow-auto whitespace-pre-wrap break-words font-mono", children: info.details }))] }))] }), _jsx("button", { type: "button", onClick: onDismiss, "aria-label": "Dismiss", className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-background/80 hover:text-foreground", children: _jsx(IconX, { size: 14 }) })] }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [shouldShowBuilderReconnect && (_jsxs("a", { href: agentNativePath("/_agent-native/builder/connect"), target: "_blank", rel: "noreferrer", className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90", children: [_jsx(IconExternalLink, { size: 13 }), "Reconnect Builder.io"] })), canRecover && (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: onContinue, className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90", children: [_jsx(IconPlayerPlay, { size: 13 }), "Continue"] }), _jsxs("button", { type: "button", onClick: onRetry, className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconRefresh, { size: 13 }), isQueryError ? "Diagnose and retry" : "Retry"] })] })), canRecover && onFork && (_jsxs("button", { type: "button", onClick: onFork, title: "Fork this conversation into a separate chat thread.", "aria-label": "Fork this conversation into a separate chat thread", className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconGitFork, { size: 13 }), "Fork chat"] })), _jsxs("button", { type: "button", onClick: copyDetails, className: "ml-auto inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs font-medium text-muted-foreground hover:bg-background/80 hover:text-foreground", children: [copied ? _jsx(IconCheck, { size: 13 }) : _jsx(IconCopy, { size: 13 }), copied ? "Copied" : copyLabel] })] })] }));
1526
+ : "The agent hit an error" }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: info.message }), shouldShowBuilderReconnect && (_jsx("p", { className: "mt-2 text-xs leading-relaxed text-muted-foreground", children: "The current Builder.io or model-provider credential was rejected. Reconnect Builder.io, then retry this message." })), (info.runId || info.errorCode || info.details) && (_jsxs("button", { type: "button", onClick: () => setDetailsOpen((v) => !v), className: "mt-2 inline-flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { size: 12, className: cn("transition-transform", detailsOpen && "rotate-180") }), "Details"] })), detailsOpen && (_jsxs("div", { className: "mt-2 rounded-md border border-border/60 bg-background/70 p-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: [info.runId && _jsxs("div", { children: ["run: ", info.runId] }), info.errorCode && _jsxs("div", { children: ["code: ", info.errorCode] }), info.details && (_jsx("pre", { className: "mt-2 max-h-28 overflow-auto whitespace-pre-wrap break-words font-mono", children: info.details }))] }))] }), _jsx("button", { type: "button", onClick: onDismiss, "aria-label": "Dismiss", className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-background/80 hover:text-foreground", children: _jsx(IconX, { size: 14 }) })] }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [shouldShowBuilderReconnect && (_jsxs("a", { href: agentNativePath("/_agent-native/builder/connect"), target: "_blank", rel: "noreferrer", onClick: () => {
1527
+ trackEvent("builder connect clicked", {
1528
+ feature: "builder",
1529
+ stage: "client",
1530
+ source: "assistant_chat_reconnect_error",
1531
+ connect_url_kind: "default",
1532
+ });
1533
+ }, className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90", children: [_jsx(IconExternalLink, { size: 13 }), "Reconnect Builder.io"] })), canRecover && (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: onContinue, className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90", children: [_jsx(IconPlayerPlay, { size: 13 }), "Continue"] }), _jsxs("button", { type: "button", onClick: onRetry, className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconRefresh, { size: 13 }), isQueryError ? "Diagnose and retry" : "Retry"] })] })), canRecover && onFork && (_jsxs("button", { type: "button", onClick: onFork, title: "Fork this conversation into a separate chat thread.", "aria-label": "Fork this conversation into a separate chat thread", className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconGitFork, { size: 13 }), "Fork chat"] })), _jsxs("button", { type: "button", onClick: copyDetails, className: "ml-auto inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs font-medium text-muted-foreground hover:bg-background/80 hover:text-foreground", children: [copied ? _jsx(IconCheck, { size: 13 }) : _jsx(IconCopy, { size: 13 }), copied ? "Copied" : copyLabel] })] })] }));
1358
1534
  }
1359
1535
  function LoopLimitContinueCard({ info, onContinue, }) {
1360
1536
  const [settings, setSettings] = useState(null);
@@ -1493,12 +1669,64 @@ function ensureMessageMetadata(repo) {
1493
1669
  // Re-export for backwards compatibility
1494
1670
  import { extractThreadMeta, normalizeThreadRepository, } from "../agent/thread-data-builder.js";
1495
1671
  export { extractThreadMeta };
1496
- const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateText, suggestions, showHeader = true, onSwitchToCli, className, apiUrl, tabId, threadId, onMessageCountChange, onSaveThread, onGenerateTitle, composerSlot, composerDisabled = false, composerDisabledPlaceholder, isNewThread, onSlashCommand, execMode, onExecModeChange, planModeDisabled, planModeDisabledReason, selectedModel, defaultModel, selectedEngine, selectedEffort, availableModels, onModelChange, onEffortChange, onForkChat, }, ref) {
1672
+ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateText, suggestions, emptyStateAddon, showHeader = true, onSwitchToCli, className, apiUrl, tabId, threadId, onMessageCountChange, onSaveThread, onGenerateTitle, composerSlot, composerDisabled = false, composerDisabledPlaceholder, isNewThread, onSlashCommand, execMode, onExecModeChange, planModeDisabled, planModeDisabledReason, selectedModel, defaultModel, selectedEngine, selectedEffort, availableModels, onModelChange, onEffortChange, onForkChat, }, ref) {
1497
1673
  const scrollRef = useRef(null);
1498
1674
  const thread = useThread();
1499
1675
  const threadRuntime = useThreadRuntime();
1676
+ const composerRuntime = useComposerRuntime();
1500
1677
  const isRuntimeRunning = thread.isRunning;
1501
1678
  const messages = thread.messages;
1679
+ const messageListResetKey = useMemo(() => messages.map((message) => message.id).join("|"), [messages]);
1680
+ // Chat-wide drag-and-drop: users expect to drop a file anywhere on the agent
1681
+ // sidebar (thread, header, composer) and have it attach — same as ChatGPT,
1682
+ // Claude.ai, Linear, Slack, etc. Tiptap's own `handleDrop` only fires inside
1683
+ // the contenteditable; drops on the message thread or the composer
1684
+ // attachment strip otherwise navigate to the file (browser default), which
1685
+ // is why "upload does nothing" — the chat refreshes to the dropped image.
1686
+ const [dropActive, setDropActive] = useState(false);
1687
+ const dropDepthRef = useRef(0);
1688
+ const handleChatDragEnter = useCallback((e) => {
1689
+ if (!Array.from(e.dataTransfer?.types ?? []).includes("Files"))
1690
+ return;
1691
+ e.preventDefault();
1692
+ dropDepthRef.current += 1;
1693
+ setDropActive(true);
1694
+ }, []);
1695
+ const handleChatDragOver = useCallback((e) => {
1696
+ if (!Array.from(e.dataTransfer?.types ?? []).includes("Files"))
1697
+ return;
1698
+ e.preventDefault();
1699
+ if (e.dataTransfer)
1700
+ e.dataTransfer.dropEffect = "copy";
1701
+ }, []);
1702
+ const handleChatDragLeave = useCallback((e) => {
1703
+ if (!Array.from(e.dataTransfer?.types ?? []).includes("Files"))
1704
+ return;
1705
+ dropDepthRef.current = Math.max(0, dropDepthRef.current - 1);
1706
+ if (dropDepthRef.current === 0)
1707
+ setDropActive(false);
1708
+ }, []);
1709
+ const handleChatDrop = useCallback((e) => {
1710
+ const files = Array.from(e.dataTransfer?.files ?? []);
1711
+ if (files.length === 0)
1712
+ return;
1713
+ e.preventDefault();
1714
+ e.stopPropagation();
1715
+ dropDepthRef.current = 0;
1716
+ setDropActive(false);
1717
+ // Mirror TiptapComposer's paste/drop name-uniqueness so consecutive
1718
+ // screenshots (all named `image.png`) don't collide on the
1719
+ // SimpleImageAttachmentAdapter id.
1720
+ const attachments = files.map((file) => {
1721
+ if (!file.type.startsWith("image/"))
1722
+ return file;
1723
+ const uniqueName = `${Date.now()}-${Math.random().toString(36).slice(2)}-${file.name}`;
1724
+ return new File([file], uniqueName, { type: file.type });
1725
+ });
1726
+ void Promise.all(attachments.map((file) => composerRuntime.addAttachment(file))).catch((error) => {
1727
+ console.error("Error adding dropped chat attachment:", error);
1728
+ });
1729
+ }, [composerRuntime]);
1502
1730
  // Patch the underlying assistant-ui MessageRepository so addOrUpdateMessage
1503
1731
  // can't throw "Parent message not found" mid-run. assistant-ui calls
1504
1732
  // `repository.clear()` from `runtime.import()` and from `resetHead(null)`,
@@ -1721,6 +1949,19 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1721
1949
  clearTimeout(maxReconnectTimer);
1722
1950
  }
1723
1951
  if (noProgressDuringReconnect && reconnectRunIdRef.current === runId) {
1952
+ captureError(new Error("agent-chat:reconnect_no_progress"), {
1953
+ tags: {
1954
+ context: "agent-native-chat",
1955
+ errorCode: "reconnect_no_progress",
1956
+ reconnectTimedOut: String(reconnectTimedOut),
1957
+ },
1958
+ extra: {
1959
+ runId,
1960
+ threadId: threadId ?? null,
1961
+ tabId: tabId ?? null,
1962
+ contentLength: latestContent.length,
1963
+ },
1964
+ });
1724
1965
  try {
1725
1966
  await fetch(`${apiUrl}/runs/${encodeURIComponent(runId)}/abort`, {
1726
1967
  method: "POST",
@@ -2093,16 +2334,35 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2093
2334
  useEffect(() => {
2094
2335
  if (!authError)
2095
2336
  return;
2337
+ // Auto-recovery (`checkAuthSession`) runs immediately + at 250ms. If the
2338
+ // card is still showing 3 seconds later, recovery failed and the user
2339
+ // is about to hit "Refresh chat" — that's the "Reload UI required"
2340
+ // symptom we want signal on.
2341
+ const stuckCapture = window.setTimeout(() => {
2342
+ captureError(new Error("agent-chat:auth_error_card_stuck"), {
2343
+ tags: {
2344
+ context: "agent-native-chat",
2345
+ errorCode: "auth_error_card",
2346
+ sessionAvailable: String(authSessionAvailable),
2347
+ sessionExpired: String(!!authError.sessionExpired),
2348
+ },
2349
+ extra: {
2350
+ threadId: threadId ?? null,
2351
+ tabId: tabId ?? null,
2352
+ },
2353
+ });
2354
+ }, 3000);
2096
2355
  const handler = () => void checkAuthSession();
2097
2356
  const timer = window.setTimeout(handler, 250);
2098
2357
  window.addEventListener("focus", handler);
2099
2358
  window.addEventListener("agent-engine:configured-changed", handler);
2100
2359
  return () => {
2360
+ window.clearTimeout(stuckCapture);
2101
2361
  window.clearTimeout(timer);
2102
2362
  window.removeEventListener("focus", handler);
2103
2363
  window.removeEventListener("agent-engine:configured-changed", handler);
2104
2364
  };
2105
- }, [authError, checkAuthSession]);
2365
+ }, [authError, authSessionAvailable, checkAuthSession, tabId, threadId]);
2106
2366
  // Listen for loop-limit events from the adapter
2107
2367
  useEffect(() => {
2108
2368
  const handler = (e) => {
@@ -2260,6 +2520,13 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2260
2520
  // Selection context attached via Cmd+I is one-shot — clear it as soon
2261
2521
  // as the user actually sends a message so it can't be re-used.
2262
2522
  clearPendingSelection();
2523
+ // Sending a message is an explicit user action — always anchor to the
2524
+ // bottom so the new message and any reply land in view, even if the
2525
+ // user had scrolled up to read history. The sticky-bottom override
2526
+ // exists to stop streaming from yanking the viewport, not to swallow
2527
+ // direct sends.
2528
+ isNearBottomRef.current = true;
2529
+ setShowScrollToBottom(false);
2263
2530
  const queuedAttachments = await serializeQueuedAttachments(attachments);
2264
2531
  // Snapshot the exec mode at enqueue time when the caller didn't
2265
2532
  // pass an explicit override. Without this, a plan-mode message that
@@ -2317,7 +2584,19 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2317
2584
  focusComposer() {
2318
2585
  tiptapRef.current?.focus();
2319
2586
  },
2320
- }), [addToQueue, thread.isRunning]);
2587
+ exportThreadSnapshot() {
2588
+ if (messages.length === 0)
2589
+ return null;
2590
+ const repo = threadRuntime.export();
2591
+ const { title, preview } = extractThreadMeta(repo);
2592
+ return {
2593
+ threadData: JSON.stringify(repo),
2594
+ title,
2595
+ preview,
2596
+ messageCount: messages.length,
2597
+ };
2598
+ },
2599
+ }), [addToQueue, messages.length, thread.isRunning, threadRuntime]);
2321
2600
  // Track whether user has scrolled away from bottom
2322
2601
  const isNearBottomRef = useRef(true);
2323
2602
  const [showScrollToBottom, setShowScrollToBottom] = useState(false);
@@ -2462,7 +2741,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2462
2741
  (!userStoppedRunRef.current.runId ||
2463
2742
  !visibleRunError.runId ||
2464
2743
  userStoppedRunRef.current.runId === visibleRunError.runId));
2465
- return (_jsx(CheckpointContext.Provider, { value: checkpointCtx, children: _jsx(MessageActionsContext.Provider, { value: messageActionsCtx, children: _jsx(ChatRunningContext.Provider, { value: isRunning, children: _jsxs("div", { className: cn("flex flex-1 flex-col h-full min-h-0 text-foreground", className), children: [showHeader && (_jsxs("div", { className: "flex h-11 shrink-0 items-center justify-between border-b border-border px-4", children: [_jsx("span", { className: "text-[13px] font-medium text-muted-foreground", children: "Agent" }), _jsx("div", { className: "flex items-center gap-1", children: onSwitchToCli && (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { onClick: onSwitchToCli, "aria-label": "Switch to CLI", className: "flex items-center gap-1 text-[12px] text-muted-foreground hover:text-foreground px-2 py-1 rounded-md hover:bg-accent", children: [_jsx(IconTerminal, { className: "h-3.5 w-3.5" }), "CLI"] }) }), _jsx(TooltipContent, { children: "Switch to CLI" })] }) })) })] })), _jsx("div", { ref: scrollRef, className: "flex-1 overflow-y-auto overflow-x-hidden min-h-0", children: authError ? (_jsxs("div", { className: "flex flex-col items-center justify-center h-full px-4 gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-destructive/10", children: _jsx(IconLock, { className: "h-5 w-5 text-destructive" }) }), _jsxs("div", { className: "text-center max-w-[280px]", children: [_jsx("p", { className: "text-sm font-medium text-foreground mb-1", children: authSessionAvailable
2744
+ return (_jsx(CheckpointContext.Provider, { value: checkpointCtx, children: _jsx(MessageActionsContext.Provider, { value: messageActionsCtx, children: _jsx(ChatRunningContext.Provider, { value: isRunning, children: _jsxs("div", { className: cn("relative flex flex-1 flex-col h-full min-h-0 text-foreground", className), onDragEnter: handleChatDragEnter, onDragOver: handleChatDragOver, onDragLeave: handleChatDragLeave, onDrop: handleChatDrop, children: [dropActive && (_jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 z-50 flex items-center justify-center rounded-md border-2 border-dashed border-primary/70 bg-primary/5 backdrop-blur-[1px]", children: _jsx("span", { className: "rounded-md bg-background/90 px-3 py-1.5 text-xs font-medium text-foreground shadow-sm", children: "Drop to attach" }) })), showHeader && (_jsxs("div", { className: "flex h-11 shrink-0 items-center justify-between border-b border-border px-4", children: [_jsx("span", { className: "text-[13px] font-medium text-muted-foreground", children: "Agent" }), _jsx("div", { className: "flex items-center gap-1", children: onSwitchToCli && (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { onClick: onSwitchToCli, "aria-label": "Switch to CLI", className: "flex items-center gap-1 text-[12px] text-muted-foreground hover:text-foreground px-2 py-1 rounded-md hover:bg-accent", children: [_jsx(IconTerminal, { className: "h-3.5 w-3.5" }), "CLI"] }) }), _jsx(TooltipContent, { children: "Switch to CLI" })] }) })) })] })), _jsx("div", { ref: scrollRef, className: "flex-1 overflow-y-auto overflow-x-hidden min-h-0", children: authError ? (_jsxs("div", { className: "flex flex-col items-center justify-center h-full px-4 gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-destructive/10", children: _jsx(IconLock, { className: "h-5 w-5 text-destructive" }) }), _jsxs("div", { className: "text-center max-w-[280px]", children: [_jsx("p", { className: "text-sm font-medium text-foreground mb-1", children: authSessionAvailable
2466
2745
  ? "Chat session needs refresh"
2467
2746
  : authError.sessionExpired
2468
2747
  ? "Session expired"
@@ -2488,15 +2767,15 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2488
2767
  window.location.reload();
2489
2768
  }, className: authSessionAvailable
2490
2769
  ? "text-xs text-background bg-foreground hover:opacity-90 px-3 py-1.5 rounded-md"
2491
- : "text-xs text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md border border-border hover:bg-accent", children: "Refresh chat" })] })] })) : missingApiKey && messages.length === 0 ? (_jsx("div", { className: "flex flex-col items-center justify-center h-full px-2", children: _jsx(BuilderSetupCard, { onConnected: handleBuilderConnected, bouncePulse: missingKeyBouncePulse }) })) : isRestoring ? (_jsxs("div", { className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "flex justify-end", children: _jsx("div", { className: "h-8 w-32 rounded-lg bg-muted animate-pulse" }) }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("div", { className: "h-4 w-48 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-64 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-40 rounded bg-muted animate-pulse" })] })] })) : messages.length === 0 && !isReconnecting ? (_jsxs("div", { className: "flex flex-col items-center justify-center gap-4 py-16 px-4 h-full", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-muted", children: _jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground" }) }), _jsx("p", { className: "text-sm text-muted-foreground text-center max-w-[240px]", children: emptyStateText ?? "How can I help you?" }), suggestions && suggestions.length > 0 && (_jsx("div", { className: "flex flex-col gap-1.5 w-full max-w-[280px]", children: suggestions.map((suggestion) => (_jsx("button", { onClick: () => {
2770
+ : "text-xs text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md border border-border hover:bg-accent", children: "Refresh chat" })] })] })) : missingApiKey && messages.length === 0 ? (_jsx("div", { className: "flex flex-col items-center justify-center h-full px-2", children: _jsx(BuilderSetupCard, { onConnected: handleBuilderConnected, bouncePulse: missingKeyBouncePulse }) })) : isRestoring ? (_jsxs("div", { className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "flex justify-end", children: _jsx("div", { className: "h-8 w-32 rounded-lg bg-muted animate-pulse" }) }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("div", { className: "h-4 w-48 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-64 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-40 rounded bg-muted animate-pulse" })] })] })) : messages.length === 0 && !isReconnecting ? (_jsxs("div", { className: "flex flex-col items-center justify-center gap-4 py-16 px-4 h-full", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-muted", children: _jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground" }) }), _jsx("p", { className: "text-sm text-muted-foreground text-center max-w-[240px]", children: emptyStateText ?? "How can I help you?" }), emptyStateAddon, suggestions && suggestions.length > 0 && (_jsx("div", { className: "flex flex-col gap-1.5 w-full max-w-[280px]", children: suggestions.map((suggestion) => (_jsx("button", { onClick: () => {
2492
2771
  threadRuntime.append({
2493
2772
  role: "user",
2494
2773
  content: [{ type: "text", text: suggestion }],
2495
2774
  });
2496
- }, className: "w-full rounded-lg border border-border px-3 py-2 text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground", children: suggestion }, suggestion))) }))] })) : (_jsxs("div", { className: "agent-thread-content flex flex-col gap-4 px-4 py-4", children: [_jsx(ThreadPrimitive.Messages, { components: {
2497
- UserMessage,
2498
- AssistantMessage,
2499
- } }), missingApiKey && (_jsx(BuilderSetupCard, { onConnected: handleBuilderConnected, bouncePulse: missingKeyBouncePulse })), visibleLoopLimit && !showRunningInUI && (_jsx(LoopLimitContinueCard, { info: visibleLoopLimit, onContinue: () => {
2775
+ }, className: "w-full rounded-lg border border-border px-3 py-2 text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground", children: suggestion }, suggestion))) }))] })) : (_jsxs("div", { className: "agent-thread-content flex flex-col gap-4 px-4 py-4", children: [_jsx(AssistantMessageListErrorBoundary, { resetKey: messageListResetKey, children: _jsx(ThreadPrimitive.Messages, { components: {
2776
+ UserMessage,
2777
+ AssistantMessage,
2778
+ } }) }), missingApiKey && (_jsx(BuilderSetupCard, { onConnected: handleBuilderConnected, bouncePulse: missingKeyBouncePulse })), visibleLoopLimit && !showRunningInUI && (_jsx(LoopLimitContinueCard, { info: visibleLoopLimit, onContinue: () => {
2500
2779
  setShowContinue(false);
2501
2780
  setLoopLimitInfo(null);
2502
2781
  addToQueue("Continue from where you left off.");
@@ -2568,7 +2847,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2568
2847
  }));
2569
2848
  }, className: "shrink-0 flex h-7 w-7 items-center justify-center rounded-md bg-muted text-foreground hover:bg-muted/80", children: _jsx(IconPlayerStop, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Stop generating" })] })) : undefined })] }) })] }) }) }) }));
2570
2849
  });
2571
- export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = agentNativePath("/_agent-native/agent-chat"), tabId, threadId, ...props }, ref) {
2850
+ export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = agentNativePath("/_agent-native/agent-chat"), tabId, browserTabId, threadId, contextScope, ...props }, ref) {
2572
2851
  const modelRef = useRef(props.selectedModel);
2573
2852
  modelRef.current = props.selectedModel;
2574
2853
  const engineRef = useRef(props.selectedEngine);
@@ -2577,6 +2856,8 @@ export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = agentN
2577
2856
  effortRef.current = props.selectedEffort;
2578
2857
  const execModeRef = useRef(props.execMode);
2579
2858
  execModeRef.current = props.execMode;
2859
+ const scopeRef = useRef(contextScope);
2860
+ scopeRef.current = contextScope;
2580
2861
  const adapter = useMemo(() => createAgentChatAdapter({
2581
2862
  apiUrl,
2582
2863
  tabId,
@@ -2585,15 +2866,17 @@ export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = agentN
2585
2866
  engineRef,
2586
2867
  effortRef,
2587
2868
  execModeRef,
2588
- }), [apiUrl, tabId, threadId]);
2869
+ browserTabId,
2870
+ scopeRef,
2871
+ }), [apiUrl, tabId, threadId, browserTabId]);
2589
2872
  const attachmentAdapter = useMemo(() => new CompositeAttachmentAdapter([
2590
- new SimpleImageAttachmentAdapter(),
2873
+ new DownscalingImageAttachmentAdapter(),
2591
2874
  new BinaryDocumentAttachmentAdapter(),
2592
2875
  new TextAttachmentAdapter(),
2593
2876
  ]), []);
2594
2877
  const runtime = useLocalRuntime(adapter, {
2595
2878
  adapters: { attachments: attachmentAdapter },
2596
2879
  });
2597
- return (_jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx(ThreadPrimitive.Root, { className: "flex flex-1 flex-col h-full min-h-0 overflow-x-hidden", children: _jsx(AssistantChatInner, { ref: ref, ...props, apiUrl: apiUrl, tabId: tabId, threadId: threadId }) }) }));
2880
+ return (_jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx(ThreadPrimitive.Root, { className: "flex flex-1 flex-col h-full min-h-0 overflow-x-hidden", children: _jsx(AssistantUiStaleIndexErrorBoundary, { resetKey: `${tabId ?? ""}:${threadId ?? ""}`, componentName: "AssistantChat", children: _jsx(AssistantChatInner, { ref: ref, ...props, apiUrl: apiUrl, tabId: tabId, threadId: threadId }) }) }) }));
2598
2881
  });
2599
2882
  //# sourceMappingURL=AssistantChat.js.map