@agent-native/core 0.115.4 → 0.116.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 (408) hide show
  1. package/agent-native.eject.json +1 -0
  2. package/corpus/README.md +3 -3
  3. package/corpus/core/CHANGELOG.md +28 -0
  4. package/corpus/core/agent-native.eject.json +1 -0
  5. package/corpus/core/docs/AGENTS.md +1 -1
  6. package/corpus/core/docs/content/agent-mentions.mdx +2 -2
  7. package/corpus/core/docs/content/{workspace.mdx → agent-resources.mdx} +1 -7
  8. package/corpus/core/docs/content/agent-teams.mdx +4 -4
  9. package/corpus/core/docs/content/dispatch.mdx +10 -10
  10. package/corpus/core/docs/content/drop-in-agent.mdx +4 -4
  11. package/corpus/core/docs/content/external-agents.mdx +1 -1
  12. package/corpus/core/docs/content/frames.mdx +1 -1
  13. package/corpus/core/docs/content/integrations.mdx +13 -2
  14. package/corpus/core/docs/content/key-concepts.mdx +2 -2
  15. package/corpus/core/docs/content/mcp-clients.mdx +7 -1
  16. package/corpus/core/docs/content/multi-app-workspace.mdx +3 -3
  17. package/corpus/core/docs/content/real-time-collaboration.mdx +33 -15
  18. package/corpus/core/docs/content/recurring-jobs.mdx +7 -7
  19. package/corpus/core/docs/content/skills-guide.mdx +4 -4
  20. package/corpus/core/docs/content/template-brain.mdx +1 -1
  21. package/corpus/core/docs/content/toolkit-collaboration.mdx +1 -1
  22. package/corpus/core/docs/content/using-your-agent.mdx +1 -1
  23. package/corpus/core/docs/content/what-is-agent-native.mdx +4 -4
  24. package/corpus/core/docs/content/workspace-management.mdx +4 -4
  25. package/corpus/core/package.json +1 -1
  26. package/corpus/core/src/agent/production-agent.ts +13 -3
  27. package/corpus/core/src/cli/doctor.ts +6 -1
  28. package/corpus/core/src/client/AgentPanel.tsx +79 -41
  29. package/corpus/core/src/client/AssistantChat.tsx +71 -25
  30. package/corpus/core/src/client/FeedbackButton.tsx +33 -7
  31. package/corpus/core/src/client/MultiTabAssistantChat.tsx +6 -8
  32. package/corpus/core/src/client/agent-chat-adapter.ts +11 -2
  33. package/corpus/core/src/client/agent-page/AgentTabFrame.tsx +22 -3
  34. package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +34 -19
  35. package/corpus/core/src/client/chat/message-components.tsx +43 -16
  36. package/corpus/core/src/client/chat/tool-call-display.tsx +30 -18
  37. package/corpus/core/src/client/chat/tool-render-registry.tsx +2 -0
  38. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +19 -2
  39. package/corpus/core/src/client/resources/ResourceTree.tsx +7 -10
  40. package/corpus/core/src/client/resources/ResourcesPanel.tsx +33 -70
  41. package/corpus/core/src/client/resources/mcp-connection-resume.ts +107 -0
  42. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +65 -12
  43. package/corpus/core/src/client/resources/mcp-integration-logos.ts +4 -0
  44. package/corpus/core/src/client/sse-event-processor.ts +50 -14
  45. package/corpus/core/src/client/use-db-sync.ts +16 -6
  46. package/corpus/core/src/connections/catalog.ts +7 -1
  47. package/corpus/core/src/eject/remote-mcp-presets.ts +37 -5
  48. package/corpus/core/src/guards/explicit-collab-access.ts +229 -0
  49. package/corpus/core/src/guards/index.ts +1 -0
  50. package/corpus/core/src/localization/default-messages.ts +54 -5
  51. package/corpus/core/src/mcp/connect-route.ts +34 -51
  52. package/corpus/core/src/provider-api/index.ts +1 -1
  53. package/corpus/core/src/server/collab-plugin.ts +137 -18
  54. package/corpus/core/src/server/index.ts +2 -0
  55. package/corpus/core/src/styles/agent-native.css +40 -0
  56. package/corpus/core/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  57. package/corpus/core/src/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
  58. package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  59. package/corpus/core/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  60. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  61. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
  62. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  63. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
  64. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  65. package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +1 -1
  66. package/corpus/templates/analytics/AGENTS.md +7 -2
  67. package/corpus/templates/analytics/actions/export-dashboard-panel-to-google-sheet.ts +144 -0
  68. package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -88
  69. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +34 -37
  70. package/corpus/templates/analytics/app/global.css +0 -4
  71. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +2 -7
  72. package/corpus/templates/analytics/app/i18n-data.ts +107 -0
  73. package/corpus/templates/analytics/app/lib/data-source-status.ts +9 -0
  74. package/corpus/templates/analytics/app/lib/sql-query.ts +1 -2
  75. package/corpus/templates/analytics/app/pages/Ask.tsx +2 -7
  76. package/corpus/templates/analytics/app/pages/DataSources.tsx +48 -0
  77. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +59 -0
  78. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -0
  79. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/report-panel-window.ts +3 -1
  80. package/corpus/templates/analytics/changelog/2026-07-22-clear-background-chat-progress.md +6 -0
  81. package/corpus/templates/analytics/changelog/2026-07-22-daily-dashboard-email-query-batches.md +6 -0
  82. package/corpus/templates/analytics/changelog/2026-07-22-export-table-panels-directly-to-google-sheets.md +6 -0
  83. package/corpus/templates/analytics/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  84. package/corpus/templates/analytics/changelog/2026-07-22-recent-chats-can-expand-in-the-sidebar.md +6 -0
  85. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +8 -8
  86. package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +31 -0
  87. package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +3 -5
  88. package/corpus/templates/analytics/server/lib/dashboard-report.ts +12 -0
  89. package/corpus/templates/analytics/server/lib/first-party-dashboard-repair.ts +3 -5
  90. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +150 -21
  91. package/corpus/templates/analytics/server/lib/google-sheets-export.ts +188 -0
  92. package/corpus/templates/analytics/server/lib/provider-api.ts +7 -2
  93. package/corpus/templates/analytics/server/plugins/collab.ts +6 -3
  94. package/corpus/templates/analytics/shared/sql-query-limits.ts +1 -0
  95. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  96. package/corpus/templates/assets/.agents/skills/real-time-collab/SKILL.md +35 -13
  97. package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +1 -1
  98. package/corpus/templates/assets/app/components/layout/Layout.tsx +1 -1
  99. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +54 -62
  100. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +2 -6
  101. package/corpus/templates/assets/app/routes/_index.tsx +8 -5
  102. package/corpus/templates/assets/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  103. package/corpus/templates/assets/changelog/2026-07-22-recent-chats-expand-from-a-compact-list.md +6 -0
  104. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  105. package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +1 -1
  106. package/corpus/templates/brain/actions/rotate-source-ingest-token.ts +77 -0
  107. package/corpus/templates/brain/app/components/layout/Layout.tsx +5 -1
  108. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +38 -51
  109. package/corpus/templates/brain/app/hooks/use-navigation-state.ts +2 -9
  110. package/corpus/templates/brain/app/i18n-data.ts +120 -0
  111. package/corpus/templates/brain/app/routes/sources.tsx +156 -5
  112. package/corpus/templates/brain/changelog/2026-07-22-chat-runs-always-end-with-an-answer.md +6 -0
  113. package/corpus/templates/brain/changelog/2026-07-22-clear-background-chat-progress.md +6 -0
  114. package/corpus/templates/brain/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  115. package/corpus/templates/brain/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  116. package/corpus/templates/brain/changelog/2026-07-22-long-chat-titles-stay-inside-the-sidebar.md +6 -0
  117. package/corpus/templates/brain/changelog/2026-07-22-new-clips-and-webhook-sources-now-show-their-secure-connecti.md +6 -0
  118. package/corpus/templates/brain/jobs/emit-netlify-brain-queue-cron.ts +125 -0
  119. package/corpus/templates/brain/netlify.toml +5 -1
  120. package/corpus/templates/brain/scripts/configure-prod-clips-source.ts +50 -0
  121. package/corpus/templates/brain/server/lib/capture-sanitization.ts +64 -6
  122. package/corpus/templates/brain/server/plugins/agent-chat.ts +4 -0
  123. package/corpus/templates/brain/server/plugins/brain-jobs.ts +1 -0
  124. package/corpus/templates/brain/server/routes/api/brain/queue/run.post.ts +55 -0
  125. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  126. package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +1 -1
  127. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  128. package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  129. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -0
  130. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +43 -67
  131. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +2 -7
  132. package/corpus/templates/chat/app/routes/_index.tsx +8 -5
  133. package/corpus/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  134. package/corpus/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  135. package/corpus/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  136. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  137. package/corpus/templates/clips/AGENTS.md +9 -1
  138. package/corpus/templates/clips/actions/export-to-brain.ts +82 -6
  139. package/corpus/templates/clips/actions/request-transcript.ts +25 -14
  140. package/corpus/templates/clips/changelog/2026-07-22-clips-transcripts-now-retry-brain-export.md +5 -0
  141. package/corpus/templates/clips/changelog/2026-07-22-german-umlauts-and-other-non-ascii-characters-now-paste-corr.md +6 -0
  142. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +26 -3
  143. package/corpus/templates/clips/jobs/emit-netlify-brain-export-cron.ts +118 -0
  144. package/corpus/templates/clips/netlify.toml +4 -1
  145. package/corpus/templates/clips/scripts/configure-prod-brain-export.ts +92 -0
  146. package/corpus/templates/clips/server/jobs/brain-export.ts +182 -0
  147. package/corpus/templates/clips/server/lib/brain-export-state.ts +42 -0
  148. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +5 -1
  149. package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
  150. package/corpus/templates/clips/server/register-secrets.ts +42 -0
  151. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +10 -1
  152. package/corpus/templates/clips/server/routes/api/clips/brain-export/run.post.ts +45 -0
  153. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  154. package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +1 -1
  155. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -1
  156. package/corpus/templates/content/server/plugins/collab.ts +1 -1
  157. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  158. package/corpus/templates/crm/actions/_crm-data-program-actions.ts +15 -0
  159. package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +2 -0
  160. package/corpus/templates/crm/actions/run.ts +2 -6
  161. package/corpus/templates/crm/actions/update-crm-record.ts +4 -2
  162. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +6 -0
  163. package/corpus/templates/crm/changelog/2026-07-22-crm-field-validation-now-explains-which-fields-cannot-be-edi.md +6 -0
  164. package/corpus/templates/crm/changelog/2026-07-22-fixed-hubspot-contact-syncs-missing-records-updated-after-th.md +6 -0
  165. package/corpus/templates/crm/changelog/2026-07-22-fixed-pipeline-dashboard-panels-so-their-opportunity-data-lo.md +6 -0
  166. package/corpus/templates/crm/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  167. package/corpus/templates/crm/server/crm/hubspot-adapter.ts +4 -1
  168. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  169. package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
  170. package/corpus/templates/design/server/plugins/collab.ts +11 -8
  171. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  172. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  173. package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +1 -1
  174. package/corpus/templates/forms/app/components/layout/Layout.tsx +1 -0
  175. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +1 -1
  176. package/corpus/templates/forms/app/hooks/use-navigation-state.ts +2 -9
  177. package/corpus/templates/forms/app/root.tsx +1 -6
  178. package/corpus/templates/forms/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  179. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  180. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  181. package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +1 -1
  182. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +2 -2
  183. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  184. package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +1 -1
  185. package/corpus/templates/plan/app/components/layout/Layout.tsx +5 -1
  186. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +57 -72
  187. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +2 -9
  188. package/corpus/templates/plan/app/lib/create-plan-routing.ts +2 -2
  189. package/corpus/templates/plan/app/pages/PlanChatPage.tsx +0 -1
  190. package/corpus/templates/plan/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  191. package/corpus/templates/plan/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  192. package/corpus/templates/plan/changelog/2026-07-22-recent-chats-and-sidebar-controls-are-more-compact.md +6 -0
  193. package/corpus/templates/plan/server/plugins/collab.ts +5 -2
  194. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  195. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +1 -1
  196. package/corpus/templates/slides/server/plugins/collab.ts +11 -8
  197. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  198. package/corpus/templates/tasks/.agents/skills/real-time-sync/SKILL.md +1 -1
  199. package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +5 -22
  200. package/corpus/templates/tasks/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  201. package/corpus/toolkit/CHANGELOG.md +7 -0
  202. package/corpus/toolkit/README.md +12 -3
  203. package/corpus/toolkit/package.json +1 -1
  204. package/corpus/toolkit/src/chat-history/ChatHistoryRail.tsx +89 -0
  205. package/corpus/toolkit/src/chat-history/index.ts +5 -0
  206. package/corpus/toolkit/src/chat-history.css +59 -0
  207. package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +106 -36
  208. package/corpus/toolkit/src/composer/VoiceButton.tsx +49 -0
  209. package/corpus/toolkit/src/composer/realtime-voice-audio-level.ts +2 -1
  210. package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +5 -3
  211. package/corpus/toolkit/src/styles.css +35 -0
  212. package/dist/agent/production-agent.d.ts.map +1 -1
  213. package/dist/agent/production-agent.js +13 -3
  214. package/dist/agent/production-agent.js.map +1 -1
  215. package/dist/cli/doctor.d.ts +1 -1
  216. package/dist/cli/doctor.d.ts.map +1 -1
  217. package/dist/cli/doctor.js +5 -2
  218. package/dist/cli/doctor.js.map +1 -1
  219. package/dist/client/AgentPanel.d.ts +1 -0
  220. package/dist/client/AgentPanel.d.ts.map +1 -1
  221. package/dist/client/AgentPanel.js +38 -18
  222. package/dist/client/AgentPanel.js.map +1 -1
  223. package/dist/client/AssistantChat.d.ts.map +1 -1
  224. package/dist/client/AssistantChat.js +55 -20
  225. package/dist/client/AssistantChat.js.map +1 -1
  226. package/dist/client/FeedbackButton.d.ts +4 -2
  227. package/dist/client/FeedbackButton.d.ts.map +1 -1
  228. package/dist/client/FeedbackButton.js +18 -2
  229. package/dist/client/FeedbackButton.js.map +1 -1
  230. package/dist/client/MultiTabAssistantChat.d.ts +1 -1
  231. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  232. package/dist/client/MultiTabAssistantChat.js +2 -3
  233. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  234. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  235. package/dist/client/agent-chat-adapter.js +11 -3
  236. package/dist/client/agent-chat-adapter.js.map +1 -1
  237. package/dist/client/agent-page/AgentTabFrame.d.ts +3 -1
  238. package/dist/client/agent-page/AgentTabFrame.d.ts.map +1 -1
  239. package/dist/client/agent-page/AgentTabFrame.js +3 -2
  240. package/dist/client/agent-page/AgentTabFrame.js.map +1 -1
  241. package/dist/client/agent-page/AgentTabsPage.d.ts +2 -0
  242. package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -1
  243. package/dist/client/agent-page/AgentTabsPage.js +26 -15
  244. package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
  245. package/dist/client/chat/message-components.d.ts +6 -1
  246. package/dist/client/chat/message-components.d.ts.map +1 -1
  247. package/dist/client/chat/message-components.js +17 -11
  248. package/dist/client/chat/message-components.js.map +1 -1
  249. package/dist/client/chat/tool-call-display.d.ts +11 -1
  250. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  251. package/dist/client/chat/tool-call-display.js +16 -17
  252. package/dist/client/chat/tool-call-display.js.map +1 -1
  253. package/dist/client/chat/tool-render-registry.d.ts +2 -0
  254. package/dist/client/chat/tool-render-registry.d.ts.map +1 -1
  255. package/dist/client/chat/tool-render-registry.js.map +1 -1
  256. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  257. package/dist/client/resources/McpConnectionSuggestion.js +15 -1
  258. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  259. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  260. package/dist/client/resources/ResourceTree.js +3 -3
  261. package/dist/client/resources/ResourceTree.js.map +1 -1
  262. package/dist/client/resources/ResourcesPanel.d.ts +1 -0
  263. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  264. package/dist/client/resources/ResourcesPanel.js +34 -20
  265. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  266. package/dist/client/resources/mcp-connection-resume.d.ts +11 -0
  267. package/dist/client/resources/mcp-connection-resume.d.ts.map +1 -0
  268. package/dist/client/resources/mcp-connection-resume.js +95 -0
  269. package/dist/client/resources/mcp-connection-resume.js.map +1 -0
  270. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  271. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  272. package/dist/client/resources/mcp-integration-catalog.js +63 -8
  273. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  274. package/dist/client/resources/mcp-integration-logos.d.ts.map +1 -1
  275. package/dist/client/resources/mcp-integration-logos.js +4 -0
  276. package/dist/client/resources/mcp-integration-logos.js.map +1 -1
  277. package/dist/client/sse-event-processor.d.ts +5 -0
  278. package/dist/client/sse-event-processor.d.ts.map +1 -1
  279. package/dist/client/sse-event-processor.js +39 -13
  280. package/dist/client/sse-event-processor.js.map +1 -1
  281. package/dist/client/use-db-sync.d.ts +3 -2
  282. package/dist/client/use-db-sync.d.ts.map +1 -1
  283. package/dist/client/use-db-sync.js +17 -6
  284. package/dist/client/use-db-sync.js.map +1 -1
  285. package/dist/collab/routes.d.ts +1 -1
  286. package/dist/connections/catalog.d.ts +1 -1
  287. package/dist/connections/catalog.d.ts.map +1 -1
  288. package/dist/connections/catalog.js +7 -1
  289. package/dist/connections/catalog.js.map +1 -1
  290. package/dist/eject/remote-mcp-presets.d.ts.map +1 -1
  291. package/dist/eject/remote-mcp-presets.js +33 -3
  292. package/dist/eject/remote-mcp-presets.js.map +1 -1
  293. package/dist/guards/explicit-collab-access.d.ts +8 -0
  294. package/dist/guards/explicit-collab-access.d.ts.map +1 -0
  295. package/dist/guards/explicit-collab-access.js +214 -0
  296. package/dist/guards/explicit-collab-access.js.map +1 -0
  297. package/dist/guards/index.d.ts +1 -0
  298. package/dist/guards/index.d.ts.map +1 -1
  299. package/dist/guards/index.js +1 -0
  300. package/dist/guards/index.js.map +1 -1
  301. package/dist/localization/default-messages.d.ts +43 -0
  302. package/dist/localization/default-messages.d.ts.map +1 -1
  303. package/dist/localization/default-messages.js +48 -5
  304. package/dist/localization/default-messages.js.map +1 -1
  305. package/dist/mcp/connect-route.d.ts.map +1 -1
  306. package/dist/mcp/connect-route.js +34 -48
  307. package/dist/mcp/connect-route.js.map +1 -1
  308. package/dist/notifications/routes.d.ts +3 -3
  309. package/dist/observability/routes.d.ts +1 -1
  310. package/dist/progress/routes.d.ts +1 -1
  311. package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
  312. package/dist/provider-api/actions/provider-api.d.ts +7 -7
  313. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  314. package/dist/provider-api/index.js +1 -1
  315. package/dist/provider-api/index.js.map +1 -1
  316. package/dist/server/collab-plugin.d.ts +34 -3
  317. package/dist/server/collab-plugin.d.ts.map +1 -1
  318. package/dist/server/collab-plugin.js +65 -12
  319. package/dist/server/collab-plugin.js.map +1 -1
  320. package/dist/server/index.d.ts +1 -1
  321. package/dist/server/index.d.ts.map +1 -1
  322. package/dist/server/index.js.map +1 -1
  323. package/dist/styles/agent-native.css +40 -0
  324. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  325. package/dist/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  326. package/dist/templates/chat/app/components/layout/Layout.tsx +1 -0
  327. package/dist/templates/chat/app/components/layout/Sidebar.tsx +43 -67
  328. package/dist/templates/chat/app/hooks/use-navigation-state.ts +2 -7
  329. package/dist/templates/chat/app/routes/_index.tsx +8 -5
  330. package/dist/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  331. package/dist/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  332. package/dist/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  333. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  334. package/dist/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
  335. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  336. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  337. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  338. package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
  339. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  340. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
  341. package/docs/AGENTS.md +1 -1
  342. package/docs/content/agent-mentions.mdx +2 -2
  343. package/docs/content/{workspace.mdx → agent-resources.mdx} +1 -7
  344. package/docs/content/agent-teams.mdx +4 -4
  345. package/docs/content/dispatch.mdx +10 -10
  346. package/docs/content/drop-in-agent.mdx +4 -4
  347. package/docs/content/external-agents.mdx +1 -1
  348. package/docs/content/frames.mdx +1 -1
  349. package/docs/content/integrations.mdx +13 -2
  350. package/docs/content/key-concepts.mdx +2 -2
  351. package/docs/content/mcp-clients.mdx +7 -1
  352. package/docs/content/multi-app-workspace.mdx +3 -3
  353. package/docs/content/real-time-collaboration.mdx +33 -15
  354. package/docs/content/recurring-jobs.mdx +7 -7
  355. package/docs/content/skills-guide.mdx +4 -4
  356. package/docs/content/template-brain.mdx +1 -1
  357. package/docs/content/toolkit-collaboration.mdx +1 -1
  358. package/docs/content/using-your-agent.mdx +1 -1
  359. package/docs/content/what-is-agent-native.mdx +4 -4
  360. package/docs/content/workspace-management.mdx +4 -4
  361. package/package.json +3 -3
  362. package/src/agent/production-agent.ts +13 -3
  363. package/src/cli/doctor.ts +6 -1
  364. package/src/client/AgentPanel.tsx +79 -41
  365. package/src/client/AssistantChat.tsx +71 -25
  366. package/src/client/FeedbackButton.tsx +33 -7
  367. package/src/client/MultiTabAssistantChat.tsx +6 -8
  368. package/src/client/agent-chat-adapter.ts +11 -2
  369. package/src/client/agent-page/AgentTabFrame.tsx +22 -3
  370. package/src/client/agent-page/AgentTabsPage.tsx +34 -19
  371. package/src/client/chat/message-components.tsx +43 -16
  372. package/src/client/chat/tool-call-display.tsx +30 -18
  373. package/src/client/chat/tool-render-registry.tsx +2 -0
  374. package/src/client/resources/McpConnectionSuggestion.tsx +19 -2
  375. package/src/client/resources/ResourceTree.tsx +7 -10
  376. package/src/client/resources/ResourcesPanel.tsx +33 -70
  377. package/src/client/resources/mcp-connection-resume.ts +107 -0
  378. package/src/client/resources/mcp-integration-catalog.ts +65 -12
  379. package/src/client/resources/mcp-integration-logos.ts +4 -0
  380. package/src/client/sse-event-processor.ts +50 -14
  381. package/src/client/use-db-sync.ts +16 -6
  382. package/src/connections/catalog.ts +7 -1
  383. package/src/eject/remote-mcp-presets.ts +37 -5
  384. package/src/guards/explicit-collab-access.ts +229 -0
  385. package/src/guards/index.ts +1 -0
  386. package/src/localization/default-messages.ts +54 -5
  387. package/src/mcp/connect-route.ts +34 -51
  388. package/src/provider-api/index.ts +1 -1
  389. package/src/server/collab-plugin.ts +137 -18
  390. package/src/server/index.ts +2 -0
  391. package/src/styles/agent-native.css +40 -0
  392. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  393. package/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  394. package/src/templates/chat/app/components/layout/Layout.tsx +1 -0
  395. package/src/templates/chat/app/components/layout/Sidebar.tsx +43 -67
  396. package/src/templates/chat/app/hooks/use-navigation-state.ts +2 -7
  397. package/src/templates/chat/app/routes/_index.tsx +8 -5
  398. package/src/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  399. package/src/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  400. package/src/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  401. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  402. package/src/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
  403. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  404. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  405. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  406. package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
  407. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  408. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
@@ -5,7 +5,11 @@
5
5
  * ```ts
6
6
  * // server/plugins/collab.ts
7
7
  * import { createCollabPlugin } from "@agent-native/core/server";
8
- * export default createCollabPlugin({ table: "documents", contentColumn: "content" });
8
+ * export default createCollabPlugin({
9
+ * table: "documents",
10
+ * contentColumn: "content",
11
+ * access: { mode: "resource", resourceType: "document" },
12
+ * });
9
13
  * ```
10
14
  */
11
15
 
@@ -52,12 +56,47 @@ type CollabAwarenessScope = {
52
56
  resourceId?: string;
53
57
  };
54
58
 
59
+ export type CollabResourceIdResolver = (
60
+ docId: string,
61
+ ) => string | null | Promise<string | null>;
62
+
63
+ export type CollabAccess =
64
+ | {
65
+ mode: "resource";
66
+ /** The shareable resource type registered via `registerShareableResource`. */
67
+ resourceType: string;
68
+ /** Map a collab document id to its parent shareable resource id. */
69
+ resolveResourceId?: CollabResourceIdResolver;
70
+ }
71
+ | {
72
+ /** Deliver collaboration events to every authenticated user. */
73
+ mode: "all-authenticated";
74
+ };
75
+
76
+ type NormalizedCollabAccess =
77
+ | {
78
+ mode: "resource";
79
+ resourceType: string;
80
+ resolveResourceId?: CollabResourceIdResolver;
81
+ }
82
+ | {
83
+ mode: "all-authenticated";
84
+ explicit: boolean;
85
+ };
86
+
55
87
  /**
56
- * Whether the no-resourceType warning has already been logged once per server
57
- * process. Avoids flooding logs on every request in templates that deliberately
58
- * have no sharing model.
88
+ * Tables whose implicit all-authenticated warning has already been logged in
89
+ * this process. Avoids duplicate warnings during hot reloads while still
90
+ * identifying every affected table.
59
91
  */
60
- let _unscoped_warning_logged = false;
92
+ const COLLAB_WARNING_TABLES_KEY =
93
+ "__agentNativeImplicitCollabAccessWarningTables__";
94
+ const collabWarningGlobal = globalThis as typeof globalThis & {
95
+ [COLLAB_WARNING_TABLES_KEY]?: Set<string>;
96
+ };
97
+ const _unscoped_warning_tables = (collabWarningGlobal[
98
+ COLLAB_WARNING_TABLES_KEY
99
+ ] ??= new Set<string>());
61
100
 
62
101
  export interface CollabPluginOptions {
63
102
  /** Table name containing document content. Default: "documents" */
@@ -77,18 +116,25 @@ export interface CollabPluginOptions {
77
116
  contentType?: "text" | "json";
78
117
  /** Column name for JSON content (used when contentType is "json"). */
79
118
  jsonColumn?: string;
119
+ /**
120
+ * Access policy for collaboration routes and event delivery.
121
+ * Use `resource` for registered shareable resources, or explicitly choose
122
+ * `all-authenticated` for deployment-wide collaboration.
123
+ */
124
+ access?: CollabAccess;
80
125
  /**
81
126
  * The shareable resource type registered via `registerShareableResource`.
82
127
  * Used to enforce access checks on collab routes.
83
- * Omit only for resources that are always public (no sharing model).
128
+ * @deprecated Use `access: { mode: "resource", resourceType }`.
84
129
  */
85
130
  resourceType?: string;
86
131
  /**
87
132
  * Map the collab document id to the shareable resource id. Many templates
88
133
  * use route-specific collab ids (for example, one doc per slide inside a
89
134
  * deck) while sharing is enforced at the parent resource level.
135
+ * @deprecated Use `access: { mode: "resource", resourceType, resolveResourceId }`.
90
136
  */
91
- resolveResourceId?: (docId: string) => string | null | Promise<string | null>;
137
+ resolveResourceId?: CollabResourceIdResolver;
92
138
  /**
93
139
  * Maximum allowed body size in bytes for write operations
94
140
  * (update/text/json/patch). Requests exceeding this are rejected with 413.
@@ -97,18 +143,100 @@ export interface CollabPluginOptions {
97
143
  maxPayloadBytes?: number;
98
144
  }
99
145
 
146
+ export function normalizeCollabAccess(
147
+ options: Pick<
148
+ CollabPluginOptions,
149
+ "access" | "resourceType" | "resolveResourceId"
150
+ >,
151
+ ): NormalizedCollabAccess {
152
+ const hasLegacyAccess =
153
+ options.resourceType !== undefined ||
154
+ options.resolveResourceId !== undefined;
155
+
156
+ if (options.access && hasLegacyAccess) {
157
+ throw new Error(
158
+ 'createCollabPlugin cannot combine "access" with the deprecated root "resourceType" or "resolveResourceId" options. Move those fields into access.',
159
+ );
160
+ }
161
+
162
+ if (options.access?.mode === "resource") {
163
+ if (!options.access.resourceType.trim()) {
164
+ throw new Error(
165
+ 'createCollabPlugin access mode "resource" requires a non-empty resourceType.',
166
+ );
167
+ }
168
+ return options.access;
169
+ }
170
+
171
+ if (options.access?.mode === "all-authenticated") {
172
+ return { mode: "all-authenticated", explicit: true };
173
+ }
174
+
175
+ if (options.access) {
176
+ throw new Error(
177
+ `createCollabPlugin received an unsupported access mode: ${String((options.access as { mode?: unknown }).mode)}`,
178
+ );
179
+ }
180
+
181
+ if (options.resourceType !== undefined) {
182
+ if (!options.resourceType.trim()) {
183
+ throw new Error(
184
+ 'createCollabPlugin "resourceType" must be a non-empty string when provided.',
185
+ );
186
+ }
187
+ return {
188
+ mode: "resource",
189
+ resourceType: options.resourceType,
190
+ resolveResourceId: options.resolveResourceId,
191
+ };
192
+ }
193
+
194
+ if (options.resolveResourceId !== undefined) {
195
+ throw new Error(
196
+ 'createCollabPlugin "resolveResourceId" requires a non-empty "resourceType".',
197
+ );
198
+ }
199
+
200
+ return { mode: "all-authenticated", explicit: false };
201
+ }
202
+
203
+ function warnForImplicitAllAuthenticatedAccess(table: string): void {
204
+ if (_unscoped_warning_tables.has(table)) return;
205
+ _unscoped_warning_tables.add(table);
206
+ console.warn(
207
+ `[collab] WARNING: createCollabPlugin for table "${table}" does not declare an access policy. ` +
208
+ "Collab events will be delivered to ALL authenticated users on this deployment without document-level access scoping. " +
209
+ 'Use access: { mode: "resource", resourceType: "..." } for access-scoped delivery, ' +
210
+ 'or access: { mode: "all-authenticated" } to explicitly acknowledge deployment-wide delivery.',
211
+ );
212
+ }
213
+
100
214
  export function createCollabPlugin(
101
215
  options: CollabPluginOptions = {},
102
216
  ): NitroPluginDef {
217
+ const normalizedAccess = normalizeCollabAccess(options);
103
218
  const {
104
219
  table = "documents",
105
220
  contentColumn = "content",
106
221
  idColumn = "id",
107
222
  autoSeed = true,
108
- resourceType,
109
- resolveResourceId,
110
223
  maxPayloadBytes = DEFAULT_MAX_PAYLOAD_BYTES,
111
224
  } = options;
225
+ const resourceType =
226
+ normalizedAccess.mode === "resource"
227
+ ? normalizedAccess.resourceType
228
+ : undefined;
229
+ const resolveResourceId =
230
+ normalizedAccess.mode === "resource"
231
+ ? normalizedAccess.resolveResourceId
232
+ : undefined;
233
+
234
+ if (
235
+ normalizedAccess.mode === "all-authenticated" &&
236
+ !normalizedAccess.explicit
237
+ ) {
238
+ warnForImplicitAllAuthenticatedAccess(table);
239
+ }
112
240
 
113
241
  return async (nitroApp: any) => {
114
242
  await awaitBootstrap(nitroApp);
@@ -129,15 +257,6 @@ export function createCollabPlugin(
129
257
  // who don't match owner/org — instead of only degrading them to the
130
258
  // poll fallback.
131
259
  // See also: SECURITY comment in poll.ts on canSeeChangeForUser.
132
- if (!resourceType && !_unscoped_warning_logged) {
133
- _unscoped_warning_logged = true;
134
- console.warn(
135
- "[collab] WARNING: createCollabPlugin called without resourceType. " +
136
- "Collab events will be delivered to ALL authenticated users on this deployment " +
137
- "without document-level access scoping. Set resourceType to enable access-scoped delivery.",
138
- );
139
- }
140
-
141
260
  const collabEmitter = getCollabEmitter();
142
261
  collabEmitter.on("collab", async (event) => {
143
262
  if (!resourceType) {
@@ -287,7 +287,9 @@ export {
287
287
  } from "../terminal/terminal-plugin.js";
288
288
  export {
289
289
  createCollabPlugin,
290
+ type CollabAccess,
290
291
  type CollabPluginOptions,
292
+ type CollabResourceIdResolver,
291
293
  } from "./collab-plugin.js";
292
294
 
293
295
  export {
@@ -927,7 +927,35 @@
927
927
  display: inline-block;
928
928
  }
929
929
 
930
+ .agent-tool-call {
931
+ position: relative;
932
+ }
933
+
930
934
  @media (prefers-reduced-motion: no-preference) {
935
+ .agent-tool-call--entering {
936
+ animation: agent-tool-call-enter 220ms var(--ease-out-strong) both;
937
+ }
938
+
939
+ .agent-tool-call[data-active-tail="true"]::after {
940
+ position: absolute;
941
+ z-index: 1;
942
+ inset: 0 0 auto;
943
+ height: 2rem;
944
+ pointer-events: none;
945
+ content: "";
946
+ background: linear-gradient(
947
+ 90deg,
948
+ transparent 0%,
949
+ transparent 38%,
950
+ hsl(var(--foreground) / 0.055) 50%,
951
+ transparent 62%,
952
+ transparent 100%
953
+ );
954
+ background-repeat: repeat;
955
+ background-size: 14rem 100%;
956
+ animation: agent-thinking-shine 2.6s linear infinite;
957
+ }
958
+
931
959
  @supports ((background-clip: text) or (-webkit-background-clip: text)) {
932
960
  .agent-thinking-indicator__text,
933
961
  .agent-running-shimmer {
@@ -960,6 +988,18 @@
960
988
  }
961
989
  }
962
990
 
991
+ @keyframes agent-tool-call-enter {
992
+ from {
993
+ opacity: 0;
994
+ transform: translateY(0.375rem);
995
+ }
996
+
997
+ to {
998
+ opacity: 1;
999
+ transform: translateY(0);
1000
+ }
1001
+ }
1002
+
963
1003
  @supports (view-transition-name: agent-native-chat) {
964
1004
  .agent-native-chat-view-transition {
965
1005
  contain: layout;
@@ -85,7 +85,10 @@ in the moment of agent use.
85
85
  approval, generative UI, progress, and screen-state exposure.
86
86
  - **Chat history kit**: presentational chat lists and recent-chat rails belong
87
87
  in Toolkit; Core keeps thread persistence, agent execution, transport, and
88
- page-to-sidebar handoff. Apps inject routing, labels, and domain actions.
88
+ page-to-sidebar handoff. Use Toolkit's `ChatHistoryRail` for the standard
89
+ five-item sidebar preview and a footer row with New chat followed by an
90
+ ellipsis disclosure up to fifteen. Apps inject routing, labels, and domain
91
+ actions.
89
92
  - **Agent page kit**: the full-page `/agent` surface (`AgentTabsPage` from
90
93
  `@agent-native/core/client`) with Context, Files, Connections, Jobs, and
91
94
  Access tabs plus a Personal/Organization scope toggle. The canonical home
@@ -16,7 +16,7 @@ metadata:
16
16
 
17
17
  Collaborative editing uses Yjs CRDT via TipTap. The agent and human users are
18
18
  equal participants — both edit the same Y.Doc and changes merge cleanly without
19
- conflicts. Always set `resourceType` on `createCollabPlugin`.
19
+ conflicts. Always choose an explicit `access` mode on `createCollabPlugin`.
20
20
 
21
21
  ## How It Works
22
22
 
@@ -104,7 +104,16 @@ in **different** regions merge fine through the CRDT.
104
104
 
105
105
  ## Security
106
106
 
107
- ### Always set `resourceType`
107
+ ### Always choose an explicit access mode
108
+
109
+ Inspect the schema and sharing registration before configuring collaboration:
110
+
111
+ - For owned or shareable records, use `mode: "resource"` and the resource type
112
+ registered through `registerShareableResource`.
113
+ - For records deliberately visible to every authenticated user on the
114
+ deployment, use `mode: "all-authenticated"`.
115
+ - Never invent a `resourceType` merely to silence a warning. Resource mode is
116
+ correct only when the matching ownership and sharing model exists.
108
117
 
109
118
  ```ts
110
119
  // server/plugins/collab.ts
@@ -114,14 +123,23 @@ export default createCollabPlugin({
114
123
  table: "documents",
115
124
  contentColumn: "content",
116
125
  idColumn: "id",
117
- resourceType: "document", // required
126
+ access: { mode: "resource", resourceType: "document" },
118
127
  });
119
128
  ```
120
129
 
121
- Without `resourceType`, the server logs a one-time warning and collab push
122
- events are delivered to **all authenticated users** without document-level
123
- scoping. Set it to the resource type name registered via
124
- `registerShareableResource`.
130
+ For intentionally deployment-wide authenticated collaboration:
131
+
132
+ ```ts
133
+ createCollabPlugin({
134
+ table: "todos",
135
+ contentColumn: "content",
136
+ access: { mode: "all-authenticated" },
137
+ });
138
+ ```
139
+
140
+ Omitting `access` is supported only for legacy compatibility and is deprecated.
141
+ It behaves like `all-authenticated`, logs a warning, and is flagged by Doctor.
142
+ Choose the mode explicitly so access intent is reviewable.
125
143
 
126
144
  Non-owner sharees who have explicit access fall back to state-vector catch-up
127
145
  (safe, slightly higher latency). Awareness routes require the same viewer
@@ -133,7 +151,10 @@ Write routes reject payloads exceeding `maxPayloadBytes` (default 2 MB) with
133
151
  HTTP 413. Override:
134
152
 
135
153
  ```ts
136
- createCollabPlugin({ resourceType: "document", maxPayloadBytes: 512 * 1024 });
154
+ createCollabPlugin({
155
+ access: { mode: "resource", resourceType: "document" },
156
+ maxPayloadBytes: 512 * 1024,
157
+ });
137
158
  ```
138
159
 
139
160
  ## Enabling Collaboration
@@ -144,7 +165,7 @@ createCollabPlugin({ resourceType: "document", maxPayloadBytes: 512 * 1024 });
144
165
  pnpm add @tiptap/extension-collaboration @tiptap/extension-collaboration-caret @tiptap/y-tiptap @tiptap/core
145
166
  ```
146
167
 
147
- ### 2. Add collab server plugin (with `resourceType`)
168
+ ### 2. Add collab server plugin (with explicit access)
148
169
 
149
170
  ```ts
150
171
  // server/plugins/collab.ts
@@ -154,7 +175,7 @@ export default createCollabPlugin({
154
175
  table: "documents",
155
176
  contentColumn: "content",
156
177
  idColumn: "id",
157
- resourceType: "document",
178
+ access: { mode: "resource", resourceType: "document" },
158
179
  });
159
180
  ```
160
181
 
@@ -343,9 +364,10 @@ the whole history — external/agent edits must not wipe the user's undo stack.
343
364
 
344
365
  ## Common Pitfalls
345
366
 
346
- - **Missing `resourceType`** — The server logs a warning on startup and
347
- delivers collab events to all authenticated users without access scoping.
348
- Always set `resourceType`.
367
+ - **Missing `access`** — Legacy omission behaves like `all-authenticated`, logs
368
+ a startup warning, and is flagged by Doctor. Choose `resource` for records
369
+ backed by ownership/sharing, or explicit `all-authenticated` for intentionally
370
+ deployment-wide records. Never invent a resource type to silence the warning.
349
371
  - **Don't pass `content` as a TipTap prop** when Collaboration is enabled —
350
372
  Yjs owns the content. Seed via `editor.commands.setContent()` only when the
351
373
  Y.XmlFragment is empty.
@@ -72,7 +72,7 @@ The agent modifies data in SQL, but the UI runs in the browser. SSE bridges same
72
72
  });
73
73
  ```
74
74
 
75
- `useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events.
75
+ `useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events. Hidden tabs keep that shared transport alive by default: SSE stays connected and active fallback polling relaxes to a 10-second floor (idle polling remains once per minute). Pass `pauseWhenHidden: true` only for a consumer that explicitly must stop all hidden-tab sync.
76
76
 
77
77
  ## Which sources to depend on
78
78
 
@@ -85,7 +85,10 @@ in the moment of agent use.
85
85
  approval, generative UI, progress, and screen-state exposure.
86
86
  - **Chat history kit**: presentational chat lists and recent-chat rails belong
87
87
  in Toolkit; Core keeps thread persistence, agent execution, transport, and
88
- page-to-sidebar handoff. Apps inject routing, labels, and domain actions.
88
+ page-to-sidebar handoff. Use Toolkit's `ChatHistoryRail` for the standard
89
+ five-item sidebar preview and a footer row with New chat followed by an
90
+ ellipsis disclosure up to fifteen. Apps inject routing, labels, and domain
91
+ actions.
89
92
  - **Agent page kit**: the full-page `/agent` surface (`AgentTabsPage` from
90
93
  `@agent-native/core/client`) with Context, Files, Connections, Jobs, and
91
94
  Access tabs plus a Personal/Organization scope toggle. The canonical home
@@ -85,7 +85,10 @@ in the moment of agent use.
85
85
  approval, generative UI, progress, and screen-state exposure.
86
86
  - **Chat history kit**: presentational chat lists and recent-chat rails belong
87
87
  in Toolkit; Core keeps thread persistence, agent execution, transport, and
88
- page-to-sidebar handoff. Apps inject routing, labels, and domain actions.
88
+ page-to-sidebar handoff. Use Toolkit's `ChatHistoryRail` for the standard
89
+ five-item sidebar preview and a footer row with New chat followed by an
90
+ ellipsis disclosure up to fifteen. Apps inject routing, labels, and domain
91
+ actions.
89
92
  - **Agent page kit**: the full-page `/agent` surface (`AgentTabsPage` from
90
93
  `@agent-native/core/client`) with Context, Files, Connections, Jobs, and
91
94
  Access tabs plus a Personal/Organization scope toggle. The canonical home
@@ -16,7 +16,7 @@ metadata:
16
16
 
17
17
  Collaborative editing uses Yjs CRDT via TipTap. The agent and human users are
18
18
  equal participants — both edit the same Y.Doc and changes merge cleanly without
19
- conflicts. Always set `resourceType` on `createCollabPlugin`.
19
+ conflicts. Always choose an explicit `access` mode on `createCollabPlugin`.
20
20
 
21
21
  ## How It Works
22
22
 
@@ -104,7 +104,16 @@ in **different** regions merge fine through the CRDT.
104
104
 
105
105
  ## Security
106
106
 
107
- ### Always set `resourceType`
107
+ ### Always choose an explicit access mode
108
+
109
+ Inspect the schema and sharing registration before configuring collaboration:
110
+
111
+ - For owned or shareable records, use `mode: "resource"` and the resource type
112
+ registered through `registerShareableResource`.
113
+ - For records deliberately visible to every authenticated user on the
114
+ deployment, use `mode: "all-authenticated"`.
115
+ - Never invent a `resourceType` merely to silence a warning. Resource mode is
116
+ correct only when the matching ownership and sharing model exists.
108
117
 
109
118
  ```ts
110
119
  // server/plugins/collab.ts
@@ -114,14 +123,23 @@ export default createCollabPlugin({
114
123
  table: "documents",
115
124
  contentColumn: "content",
116
125
  idColumn: "id",
117
- resourceType: "document", // required
126
+ access: { mode: "resource", resourceType: "document" },
118
127
  });
119
128
  ```
120
129
 
121
- Without `resourceType`, the server logs a one-time warning and collab push
122
- events are delivered to **all authenticated users** without document-level
123
- scoping. Set it to the resource type name registered via
124
- `registerShareableResource`.
130
+ For intentionally deployment-wide authenticated collaboration:
131
+
132
+ ```ts
133
+ createCollabPlugin({
134
+ table: "todos",
135
+ contentColumn: "content",
136
+ access: { mode: "all-authenticated" },
137
+ });
138
+ ```
139
+
140
+ Omitting `access` is supported only for legacy compatibility and is deprecated.
141
+ It behaves like `all-authenticated`, logs a warning, and is flagged by Doctor.
142
+ Choose the mode explicitly so access intent is reviewable.
125
143
 
126
144
  Non-owner sharees who have explicit access fall back to state-vector catch-up
127
145
  (safe, slightly higher latency). Awareness routes require the same viewer
@@ -133,7 +151,10 @@ Write routes reject payloads exceeding `maxPayloadBytes` (default 2 MB) with
133
151
  HTTP 413. Override:
134
152
 
135
153
  ```ts
136
- createCollabPlugin({ resourceType: "document", maxPayloadBytes: 512 * 1024 });
154
+ createCollabPlugin({
155
+ access: { mode: "resource", resourceType: "document" },
156
+ maxPayloadBytes: 512 * 1024,
157
+ });
137
158
  ```
138
159
 
139
160
  ## Enabling Collaboration
@@ -144,7 +165,7 @@ createCollabPlugin({ resourceType: "document", maxPayloadBytes: 512 * 1024 });
144
165
  pnpm add @tiptap/extension-collaboration @tiptap/extension-collaboration-caret @tiptap/y-tiptap @tiptap/core
145
166
  ```
146
167
 
147
- ### 2. Add collab server plugin (with `resourceType`)
168
+ ### 2. Add collab server plugin (with explicit access)
148
169
 
149
170
  ```ts
150
171
  // server/plugins/collab.ts
@@ -154,7 +175,7 @@ export default createCollabPlugin({
154
175
  table: "documents",
155
176
  contentColumn: "content",
156
177
  idColumn: "id",
157
- resourceType: "document",
178
+ access: { mode: "resource", resourceType: "document" },
158
179
  });
159
180
  ```
160
181
 
@@ -343,9 +364,10 @@ the whole history — external/agent edits must not wipe the user's undo stack.
343
364
 
344
365
  ## Common Pitfalls
345
366
 
346
- - **Missing `resourceType`** — The server logs a warning on startup and
347
- delivers collab events to all authenticated users without access scoping.
348
- Always set `resourceType`.
367
+ - **Missing `access`** — Legacy omission behaves like `all-authenticated`, logs
368
+ a startup warning, and is flagged by Doctor. Choose `resource` for records
369
+ backed by ownership/sharing, or explicit `all-authenticated` for intentionally
370
+ deployment-wide records. Never invent a resource type to silence the warning.
349
371
  - **Don't pass `content` as a TipTap prop** when Collaboration is enabled —
350
372
  Yjs owns the content. Seed via `editor.commands.setContent()` only when the
351
373
  Y.XmlFragment is empty.
@@ -72,7 +72,7 @@ The agent modifies data in SQL, but the UI runs in the browser. SSE bridges same
72
72
  });
73
73
  ```
74
74
 
75
- `useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events.
75
+ `useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events. Hidden tabs keep that shared transport alive by default: SSE stays connected and active fallback polling relaxes to a 10-second floor (idle polling remains once per minute). Pass `pauseWhenHidden: true` only for a consumer that explicitly must stop all hidden-tab sync.
76
76
 
77
77
  ## Which sources to depend on
78
78
 
@@ -24,9 +24,10 @@ shared agent sidebar.
24
24
  - **Always show the mic alongside the send button.** Cursor replaces send
25
25
  with mic when the composer is empty; their users complain. We keep both
26
26
  visible — Lovable does the same.
27
- - **Ask before switching modes.** The mic opens a shadcn popover offering
28
- **Start voice mode** and **Keep dictating**; never silently replace the
29
- established dictation behavior.
27
+ - **Ask before switching modes.** The mic opens a compact shadcn popover with
28
+ **Real-time voice** as the primary action and **Dictate** as the secondary;
29
+ never silently replace the established dictation behavior. Users can choose
30
+ **Remember my preference** to skip the chooser on later clicks.
30
31
  - **Dictation is click-to-toggle, not push-to-talk.** More forgiving in a sidebar, avoids
31
32
  host-app hotkey clashes. Keyboard shortcut is `Cmd/Ctrl+Shift+M` and
32
33
  `Escape` cancels mid-recording.
@@ -100,6 +101,9 @@ action before requesting microphone permission.
100
101
  `application_state["realtime-voice-prefs"]`. Keep this separate from
101
102
  `voice-transcription-prefs`, which configures editable dictation rather than
102
103
  the speech-to-speech session.
104
+ - Store the optional remembered chooser selection at
105
+ `application_state["voice-input-preference"]`. Keep it separate from both
106
+ mode-specific preference objects.
103
107
  - Missing-key failures should open Settings focused on the user-scoped
104
108
  `OPENAI_API_KEY` field. Never send, log, or echo the key to the browser.
105
109
 
@@ -147,11 +151,11 @@ Default behavior:
147
151
 
148
152
  | File | Purpose |
149
153
  | --------------------------------------------------------------------- | --------------------------------------------------- |
150
- | `packages/core/src/client/composer/useVoiceDictation.ts` | Provider-routing hook (MediaRecorder / Web Speech) |
151
- | `packages/core/src/client/composer/VoiceButton.tsx` | Mic button + live amplitude + cancel overlay |
152
- | `packages/core/src/client/composer/RealtimeVoiceMode.tsx` | Opt-in popover + persistent speech orb |
153
- | `packages/core/src/client/composer/useRealtimeVoiceMode.tsx` | WebRTC lifecycle, provider events, and tool bridge |
154
- | `packages/core/src/client/composer/TiptapComposer.tsx` | Wires the hook, insertion, and keyboard shortcut |
154
+ | `packages/toolkit/src/composer/useVoiceDictation.ts` | Provider-routing hook (MediaRecorder / Web Speech) |
155
+ | `packages/toolkit/src/composer/VoiceButton.tsx` | Mic button + live amplitude + cancel overlay |
156
+ | `packages/toolkit/src/composer/RealtimeVoiceMode.tsx` | Opt-in popover + persistent speech orb |
157
+ | `packages/toolkit/src/composer/useRealtimeVoiceMode.tsx` | WebRTC lifecycle, provider events, and tool bridge |
158
+ | `packages/toolkit/src/composer/TiptapComposer.tsx` | Wires the hook, insertion, and keyboard shortcut |
155
159
  | `packages/core/src/client/settings/VoiceTranscriptionSection.tsx` | Live source + cleanup controls in sidebar settings |
156
160
  | `packages/core/src/client/transcription/BuilderTranscriptionCta.tsx` | CTA shown when Builder account isn't connected |
157
161
  | `packages/core/src/client/transcription/use-live-transcription.ts` | Web Speech live-transcription hook for recordings |
@@ -85,7 +85,10 @@ in the moment of agent use.
85
85
  approval, generative UI, progress, and screen-state exposure.
86
86
  - **Chat history kit**: presentational chat lists and recent-chat rails belong
87
87
  in Toolkit; Core keeps thread persistence, agent execution, transport, and
88
- page-to-sidebar handoff. Apps inject routing, labels, and domain actions.
88
+ page-to-sidebar handoff. Use Toolkit's `ChatHistoryRail` for the standard
89
+ five-item sidebar preview and a footer row with New chat followed by an
90
+ ellipsis disclosure up to fifteen. Apps inject routing, labels, and domain
91
+ actions.
89
92
  - **Agent page kit**: the full-page `/agent` surface (`AgentTabsPage` from
90
93
  `@agent-native/core/client`) with Context, Files, Connections, Jobs, and
91
94
  Access tabs plus a Personal/Organization scope toggle. The canonical home
@@ -72,7 +72,7 @@ The agent modifies data in SQL, but the UI runs in the browser. SSE bridges same
72
72
  });
73
73
  ```
74
74
 
75
- `useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events.
75
+ `useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events. Hidden tabs keep that shared transport alive by default: SSE stays connected and active fallback polling relaxes to a 10-second floor (idle polling remains once per minute). Pass `pauseWhenHidden: true` only for a consumer that explicitly must stop all hidden-tab sync.
76
76
 
77
77
  ## Which sources to depend on
78
78
 
@@ -228,11 +228,16 @@ membership id when its native update status reports `update-available`.
228
228
  `dashboard-report-subscriptions` actions. They send daily snapshots scoped to
229
229
  the exact user/org context that created the subscription with saved URL
230
230
  filters; do not hand-wire custom email routes around that action surface.
231
+ - Table panels can be exported with `export-dashboard-panel-to-google-sheet`.
232
+ The action re-runs the accessible panel query with the dashboard's current
233
+ filter variables, creates a new Sheet through the connected Google Drive
234
+ workspace connection, and returns its URL plus bounded export metadata.
231
235
  Report PNGs are Playwright captures of the real dashboard route in
232
236
  `reportScreenshot=1` mode, authenticated by a short-lived embed-session token
233
237
  and embedded inline in email as ordered CID images. Complete dashboards are
234
- captured sequentially in bounded panel windows; every window must match the
235
- panel ids snapshotted at the start, and a failed or mismatched window
238
+ captured sequentially in four-panel windows matching the browser's four-query
239
+ concurrency limit; every window must match the panel ids snapshotted at the
240
+ start, and a failed or mismatched window
236
241
  invalidates the entire image set so the scheduler can retry instead of
237
242
  sending a partial report. Capture is capped at 10 windows and 14 MiB of raw
238
243
  PNG data, and subscriptions are capped at five distinct recipients; use a