@agent-native/core 0.115.4 → 0.117.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 (487) hide show
  1. package/agent-native.eject.json +1 -0
  2. package/corpus/README.md +3 -3
  3. package/corpus/core/CHANGELOG.md +43 -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 +4 -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/analytics.ts +7 -0
  36. package/corpus/core/src/client/chat/message-components.tsx +43 -16
  37. package/corpus/core/src/client/chat/tool-call-display.tsx +30 -18
  38. package/corpus/core/src/client/chat/tool-render-registry.tsx +2 -0
  39. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +19 -2
  40. package/corpus/core/src/client/resources/ResourceTree.tsx +7 -10
  41. package/corpus/core/src/client/resources/ResourcesPanel.tsx +33 -70
  42. package/corpus/core/src/client/resources/mcp-connection-resume.ts +107 -0
  43. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +65 -12
  44. package/corpus/core/src/client/resources/mcp-integration-logos.ts +4 -0
  45. package/corpus/core/src/client/sse-event-processor.ts +50 -14
  46. package/corpus/core/src/client/use-db-sync.ts +370 -21
  47. package/corpus/core/src/collab/client.ts +26 -2
  48. package/corpus/core/src/connections/catalog.ts +7 -1
  49. package/corpus/core/src/db/ddl-guard.ts +49 -10
  50. package/corpus/core/src/deploy/build.ts +25 -2
  51. package/corpus/core/src/eject/remote-mcp-presets.ts +37 -5
  52. package/corpus/core/src/guards/explicit-collab-access.ts +229 -0
  53. package/corpus/core/src/guards/index.ts +1 -0
  54. package/corpus/core/src/localization/default-messages.ts +54 -5
  55. package/corpus/core/src/mcp/connect-route.ts +34 -51
  56. package/corpus/core/src/provider-api/index.ts +1 -1
  57. package/corpus/core/src/realtime-protocol.ts +92 -0
  58. package/corpus/core/src/server/collab-plugin.ts +137 -18
  59. package/corpus/core/src/server/core-routes-plugin.ts +7 -0
  60. package/corpus/core/src/server/index.ts +2 -0
  61. package/corpus/core/src/server/poll-events.ts +29 -8
  62. package/corpus/core/src/server/poll.ts +1123 -865
  63. package/corpus/core/src/server/realtime-token.ts +106 -0
  64. package/corpus/core/src/server/sentry-config.ts +40 -0
  65. package/corpus/core/src/server/short-lived-token.ts +156 -0
  66. package/corpus/core/src/server/sse.ts +15 -0
  67. package/corpus/core/src/server/ssr-handler.ts +9 -3
  68. package/corpus/core/src/styles/agent-native.css +40 -0
  69. package/corpus/core/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  70. package/corpus/core/src/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
  71. package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  72. package/corpus/core/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  73. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  74. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
  75. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  76. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
  77. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  78. package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +1 -1
  79. package/corpus/templates/analytics/AGENTS.md +7 -2
  80. package/corpus/templates/analytics/actions/export-dashboard-panel-to-google-sheet.ts +144 -0
  81. package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -88
  82. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +34 -37
  83. package/corpus/templates/analytics/app/global.css +0 -4
  84. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +2 -7
  85. package/corpus/templates/analytics/app/i18n-data.ts +107 -0
  86. package/corpus/templates/analytics/app/lib/data-source-status.ts +9 -0
  87. package/corpus/templates/analytics/app/lib/sql-query.ts +1 -2
  88. package/corpus/templates/analytics/app/pages/Ask.tsx +2 -7
  89. package/corpus/templates/analytics/app/pages/DataSources.tsx +48 -0
  90. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +59 -0
  91. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -0
  92. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/report-panel-window.ts +3 -1
  93. package/corpus/templates/analytics/changelog/2026-07-22-clear-background-chat-progress.md +6 -0
  94. package/corpus/templates/analytics/changelog/2026-07-22-daily-dashboard-email-query-batches.md +6 -0
  95. package/corpus/templates/analytics/changelog/2026-07-22-export-table-panels-directly-to-google-sheets.md +6 -0
  96. package/corpus/templates/analytics/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  97. package/corpus/templates/analytics/changelog/2026-07-22-recent-chats-can-expand-in-the-sidebar.md +6 -0
  98. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +8 -8
  99. package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +31 -0
  100. package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +3 -5
  101. package/corpus/templates/analytics/server/lib/dashboard-report.ts +12 -0
  102. package/corpus/templates/analytics/server/lib/first-party-dashboard-repair.ts +3 -5
  103. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +150 -21
  104. package/corpus/templates/analytics/server/lib/google-sheets-export.ts +188 -0
  105. package/corpus/templates/analytics/server/lib/provider-api.ts +7 -2
  106. package/corpus/templates/analytics/server/plugins/collab.ts +6 -3
  107. package/corpus/templates/analytics/shared/sql-query-limits.ts +1 -0
  108. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  109. package/corpus/templates/assets/.agents/skills/real-time-collab/SKILL.md +35 -13
  110. package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +1 -1
  111. package/corpus/templates/assets/app/components/layout/Layout.tsx +1 -1
  112. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +54 -62
  113. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +2 -6
  114. package/corpus/templates/assets/app/routes/_index.tsx +8 -5
  115. package/corpus/templates/assets/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  116. package/corpus/templates/assets/changelog/2026-07-22-recent-chats-expand-from-a-compact-list.md +6 -0
  117. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  118. package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +1 -1
  119. package/corpus/templates/brain/actions/rotate-source-ingest-token.ts +77 -0
  120. package/corpus/templates/brain/app/components/layout/Layout.tsx +5 -1
  121. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +38 -51
  122. package/corpus/templates/brain/app/hooks/use-navigation-state.ts +2 -9
  123. package/corpus/templates/brain/app/i18n-data.ts +120 -0
  124. package/corpus/templates/brain/app/routes/sources.tsx +156 -5
  125. package/corpus/templates/brain/changelog/2026-07-22-chat-runs-always-end-with-an-answer.md +6 -0
  126. package/corpus/templates/brain/changelog/2026-07-22-clear-background-chat-progress.md +6 -0
  127. package/corpus/templates/brain/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  128. package/corpus/templates/brain/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  129. package/corpus/templates/brain/changelog/2026-07-22-long-chat-titles-stay-inside-the-sidebar.md +6 -0
  130. package/corpus/templates/brain/changelog/2026-07-22-new-clips-and-webhook-sources-now-show-their-secure-connecti.md +6 -0
  131. package/corpus/templates/brain/jobs/emit-netlify-brain-queue-cron.ts +125 -0
  132. package/corpus/templates/brain/netlify.toml +5 -1
  133. package/corpus/templates/brain/scripts/configure-prod-clips-source.ts +50 -0
  134. package/corpus/templates/brain/server/lib/capture-sanitization.ts +64 -6
  135. package/corpus/templates/brain/server/plugins/agent-chat.ts +4 -0
  136. package/corpus/templates/brain/server/plugins/brain-jobs.ts +1 -0
  137. package/corpus/templates/brain/server/routes/api/brain/queue/run.post.ts +55 -0
  138. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  139. package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +1 -1
  140. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  141. package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  142. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -0
  143. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +43 -67
  144. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +2 -7
  145. package/corpus/templates/chat/app/routes/_index.tsx +8 -5
  146. package/corpus/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  147. package/corpus/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  148. package/corpus/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  149. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  150. package/corpus/templates/clips/AGENTS.md +9 -1
  151. package/corpus/templates/clips/actions/export-to-brain.ts +82 -6
  152. package/corpus/templates/clips/actions/request-transcript.ts +25 -14
  153. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +12 -0
  154. package/corpus/templates/clips/app/i18n/en-US.ts +1 -0
  155. package/corpus/templates/clips/changelog/2026-07-22-clips-transcripts-now-retry-brain-export.md +5 -0
  156. package/corpus/templates/clips/changelog/2026-07-22-german-umlauts-and-other-non-ascii-characters-now-paste-corr.md +6 -0
  157. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +26 -3
  158. package/corpus/templates/clips/jobs/emit-netlify-brain-export-cron.ts +118 -0
  159. package/corpus/templates/clips/netlify.toml +4 -1
  160. package/corpus/templates/clips/scripts/configure-prod-brain-export.ts +92 -0
  161. package/corpus/templates/clips/server/jobs/brain-export.ts +182 -0
  162. package/corpus/templates/clips/server/lib/brain-export-state.ts +42 -0
  163. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +5 -1
  164. package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
  165. package/corpus/templates/clips/server/register-secrets.ts +42 -0
  166. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +10 -1
  167. package/corpus/templates/clips/server/routes/api/clips/brain-export/run.post.ts +45 -0
  168. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  169. package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +1 -1
  170. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +566 -299
  171. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +14 -0
  172. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -1
  173. package/corpus/templates/content/app/i18n-data.ts +90 -0
  174. package/corpus/templates/content/server/plugins/collab.ts +1 -1
  175. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  176. package/corpus/templates/crm/actions/_crm-data-program-actions.ts +15 -0
  177. package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +2 -0
  178. package/corpus/templates/crm/actions/run.ts +2 -6
  179. package/corpus/templates/crm/actions/update-crm-record.ts +4 -2
  180. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +6 -0
  181. package/corpus/templates/crm/changelog/2026-07-22-crm-field-validation-now-explains-which-fields-cannot-be-edi.md +6 -0
  182. package/corpus/templates/crm/changelog/2026-07-22-fixed-hubspot-contact-syncs-missing-records-updated-after-th.md +6 -0
  183. package/corpus/templates/crm/changelog/2026-07-22-fixed-pipeline-dashboard-panels-so-their-opportunity-data-lo.md +6 -0
  184. package/corpus/templates/crm/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  185. package/corpus/templates/crm/server/crm/hubspot-adapter.ts +4 -1
  186. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  187. package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
  188. package/corpus/templates/design/server/plugins/collab.ts +11 -8
  189. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  190. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  191. package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +1 -1
  192. package/corpus/templates/forms/app/components/layout/Layout.tsx +1 -0
  193. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +1 -1
  194. package/corpus/templates/forms/app/hooks/use-navigation-state.ts +2 -9
  195. package/corpus/templates/forms/app/root.tsx +1 -6
  196. package/corpus/templates/forms/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  197. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  198. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  199. package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +1 -1
  200. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +2 -2
  201. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  202. package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +1 -1
  203. package/corpus/templates/plan/app/components/layout/Layout.tsx +5 -1
  204. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +57 -72
  205. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +2 -9
  206. package/corpus/templates/plan/app/lib/create-plan-routing.ts +2 -2
  207. package/corpus/templates/plan/app/pages/PlanChatPage.tsx +0 -1
  208. package/corpus/templates/plan/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  209. package/corpus/templates/plan/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  210. package/corpus/templates/plan/changelog/2026-07-22-recent-chats-and-sidebar-controls-are-more-compact.md +6 -0
  211. package/corpus/templates/plan/server/plugins/collab.ts +5 -2
  212. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  213. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +1 -1
  214. package/corpus/templates/slides/server/plugins/collab.ts +11 -8
  215. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  216. package/corpus/templates/tasks/.agents/skills/real-time-sync/SKILL.md +1 -1
  217. package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +5 -22
  218. package/corpus/templates/tasks/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  219. package/corpus/toolkit/CHANGELOG.md +7 -0
  220. package/corpus/toolkit/README.md +12 -3
  221. package/corpus/toolkit/package.json +1 -1
  222. package/corpus/toolkit/src/chat-history/ChatHistoryRail.tsx +89 -0
  223. package/corpus/toolkit/src/chat-history/index.ts +5 -0
  224. package/corpus/toolkit/src/chat-history.css +59 -0
  225. package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +106 -36
  226. package/corpus/toolkit/src/composer/VoiceButton.tsx +49 -0
  227. package/corpus/toolkit/src/composer/realtime-voice-audio-level.ts +2 -1
  228. package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +5 -3
  229. package/corpus/toolkit/src/styles.css +35 -0
  230. package/dist/agent/production-agent.d.ts.map +1 -1
  231. package/dist/agent/production-agent.js +13 -3
  232. package/dist/agent/production-agent.js.map +1 -1
  233. package/dist/cli/doctor.d.ts +1 -1
  234. package/dist/cli/doctor.d.ts.map +1 -1
  235. package/dist/cli/doctor.js +5 -2
  236. package/dist/cli/doctor.js.map +1 -1
  237. package/dist/client/AgentPanel.d.ts +1 -0
  238. package/dist/client/AgentPanel.d.ts.map +1 -1
  239. package/dist/client/AgentPanel.js +38 -18
  240. package/dist/client/AgentPanel.js.map +1 -1
  241. package/dist/client/AssistantChat.d.ts.map +1 -1
  242. package/dist/client/AssistantChat.js +55 -20
  243. package/dist/client/AssistantChat.js.map +1 -1
  244. package/dist/client/FeedbackButton.d.ts +4 -2
  245. package/dist/client/FeedbackButton.d.ts.map +1 -1
  246. package/dist/client/FeedbackButton.js +18 -2
  247. package/dist/client/FeedbackButton.js.map +1 -1
  248. package/dist/client/MultiTabAssistantChat.d.ts +1 -1
  249. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  250. package/dist/client/MultiTabAssistantChat.js +2 -3
  251. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  252. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  253. package/dist/client/agent-chat-adapter.js +11 -3
  254. package/dist/client/agent-chat-adapter.js.map +1 -1
  255. package/dist/client/agent-page/AgentTabFrame.d.ts +3 -1
  256. package/dist/client/agent-page/AgentTabFrame.d.ts.map +1 -1
  257. package/dist/client/agent-page/AgentTabFrame.js +3 -2
  258. package/dist/client/agent-page/AgentTabFrame.js.map +1 -1
  259. package/dist/client/agent-page/AgentTabsPage.d.ts +2 -0
  260. package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -1
  261. package/dist/client/agent-page/AgentTabsPage.js +26 -15
  262. package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
  263. package/dist/client/analytics.d.ts +10 -0
  264. package/dist/client/analytics.d.ts.map +1 -1
  265. package/dist/client/analytics.js.map +1 -1
  266. package/dist/client/chat/message-components.d.ts +6 -1
  267. package/dist/client/chat/message-components.d.ts.map +1 -1
  268. package/dist/client/chat/message-components.js +17 -11
  269. package/dist/client/chat/message-components.js.map +1 -1
  270. package/dist/client/chat/tool-call-display.d.ts +11 -1
  271. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  272. package/dist/client/chat/tool-call-display.js +16 -17
  273. package/dist/client/chat/tool-call-display.js.map +1 -1
  274. package/dist/client/chat/tool-render-registry.d.ts +2 -0
  275. package/dist/client/chat/tool-render-registry.d.ts.map +1 -1
  276. package/dist/client/chat/tool-render-registry.js.map +1 -1
  277. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  278. package/dist/client/resources/McpConnectionSuggestion.js +15 -1
  279. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  280. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  281. package/dist/client/resources/ResourceTree.js +3 -3
  282. package/dist/client/resources/ResourceTree.js.map +1 -1
  283. package/dist/client/resources/ResourcesPanel.d.ts +1 -0
  284. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  285. package/dist/client/resources/ResourcesPanel.js +34 -20
  286. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  287. package/dist/client/resources/mcp-connection-resume.d.ts +11 -0
  288. package/dist/client/resources/mcp-connection-resume.d.ts.map +1 -0
  289. package/dist/client/resources/mcp-connection-resume.js +95 -0
  290. package/dist/client/resources/mcp-connection-resume.js.map +1 -0
  291. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  292. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  293. package/dist/client/resources/mcp-integration-catalog.js +63 -8
  294. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  295. package/dist/client/resources/mcp-integration-logos.d.ts.map +1 -1
  296. package/dist/client/resources/mcp-integration-logos.js +4 -0
  297. package/dist/client/resources/mcp-integration-logos.js.map +1 -1
  298. package/dist/client/sse-event-processor.d.ts +5 -0
  299. package/dist/client/sse-event-processor.d.ts.map +1 -1
  300. package/dist/client/sse-event-processor.js +39 -13
  301. package/dist/client/sse-event-processor.js.map +1 -1
  302. package/dist/client/use-db-sync.d.ts +4 -3
  303. package/dist/client/use-db-sync.d.ts.map +1 -1
  304. package/dist/client/use-db-sync.js +332 -21
  305. package/dist/client/use-db-sync.js.map +1 -1
  306. package/dist/collab/client.d.ts.map +1 -1
  307. package/dist/collab/client.js +26 -2
  308. package/dist/collab/client.js.map +1 -1
  309. package/dist/collab/routes.d.ts +1 -1
  310. package/dist/connections/catalog.d.ts +1 -1
  311. package/dist/connections/catalog.d.ts.map +1 -1
  312. package/dist/connections/catalog.js +7 -1
  313. package/dist/connections/catalog.js.map +1 -1
  314. package/dist/db/ddl-guard.d.ts +7 -2
  315. package/dist/db/ddl-guard.d.ts.map +1 -1
  316. package/dist/db/ddl-guard.js +21 -9
  317. package/dist/db/ddl-guard.js.map +1 -1
  318. package/dist/deploy/build.d.ts.map +1 -1
  319. package/dist/deploy/build.js +25 -2
  320. package/dist/deploy/build.js.map +1 -1
  321. package/dist/eject/remote-mcp-presets.d.ts.map +1 -1
  322. package/dist/eject/remote-mcp-presets.js +33 -3
  323. package/dist/eject/remote-mcp-presets.js.map +1 -1
  324. package/dist/guards/explicit-collab-access.d.ts +8 -0
  325. package/dist/guards/explicit-collab-access.d.ts.map +1 -0
  326. package/dist/guards/explicit-collab-access.js +214 -0
  327. package/dist/guards/explicit-collab-access.js.map +1 -0
  328. package/dist/guards/index.d.ts +1 -0
  329. package/dist/guards/index.d.ts.map +1 -1
  330. package/dist/guards/index.js +1 -0
  331. package/dist/guards/index.js.map +1 -1
  332. package/dist/localization/default-messages.d.ts +43 -0
  333. package/dist/localization/default-messages.d.ts.map +1 -1
  334. package/dist/localization/default-messages.js +48 -5
  335. package/dist/localization/default-messages.js.map +1 -1
  336. package/dist/mcp/connect-route.d.ts.map +1 -1
  337. package/dist/mcp/connect-route.js +34 -48
  338. package/dist/mcp/connect-route.js.map +1 -1
  339. package/dist/observability/routes.d.ts +5 -5
  340. package/dist/provider-api/actions/custom-provider-registration.d.ts +7 -7
  341. package/dist/provider-api/actions/provider-api.d.ts +7 -7
  342. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  343. package/dist/provider-api/index.js +1 -1
  344. package/dist/provider-api/index.js.map +1 -1
  345. package/dist/realtime-protocol.d.ts +40 -0
  346. package/dist/realtime-protocol.d.ts.map +1 -0
  347. package/dist/realtime-protocol.js +69 -0
  348. package/dist/realtime-protocol.js.map +1 -0
  349. package/dist/resources/handlers.d.ts +1 -1
  350. package/dist/secrets/routes.d.ts +3 -3
  351. package/dist/server/collab-plugin.d.ts +34 -3
  352. package/dist/server/collab-plugin.d.ts.map +1 -1
  353. package/dist/server/collab-plugin.js +65 -12
  354. package/dist/server/collab-plugin.js.map +1 -1
  355. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  356. package/dist/server/core-routes-plugin.js +3 -0
  357. package/dist/server/core-routes-plugin.js.map +1 -1
  358. package/dist/server/index.d.ts +1 -1
  359. package/dist/server/index.d.ts.map +1 -1
  360. package/dist/server/index.js.map +1 -1
  361. package/dist/server/poll-events.d.ts +7 -1
  362. package/dist/server/poll-events.d.ts.map +1 -1
  363. package/dist/server/poll-events.js +24 -7
  364. package/dist/server/poll-events.js.map +1 -1
  365. package/dist/server/poll.d.ts +223 -42
  366. package/dist/server/poll.d.ts.map +1 -1
  367. package/dist/server/poll.js +849 -737
  368. package/dist/server/poll.js.map +1 -1
  369. package/dist/server/realtime-token.d.ts +34 -0
  370. package/dist/server/realtime-token.d.ts.map +1 -0
  371. package/dist/server/realtime-token.js +85 -0
  372. package/dist/server/realtime-token.js.map +1 -0
  373. package/dist/server/sentry-config.d.ts +12 -0
  374. package/dist/server/sentry-config.d.ts.map +1 -1
  375. package/dist/server/sentry-config.js +34 -0
  376. package/dist/server/sentry-config.js.map +1 -1
  377. package/dist/server/short-lived-token.d.ts +46 -0
  378. package/dist/server/short-lived-token.d.ts.map +1 -1
  379. package/dist/server/short-lived-token.js +104 -0
  380. package/dist/server/short-lived-token.js.map +1 -1
  381. package/dist/server/sse.d.ts +1 -1
  382. package/dist/server/sse.d.ts.map +1 -1
  383. package/dist/server/sse.js +4 -0
  384. package/dist/server/sse.js.map +1 -1
  385. package/dist/server/ssr-handler.d.ts.map +1 -1
  386. package/dist/server/ssr-handler.js +5 -3
  387. package/dist/server/ssr-handler.js.map +1 -1
  388. package/dist/server/transcribe-voice.d.ts +1 -1
  389. package/dist/styles/agent-native.css +40 -0
  390. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  391. package/dist/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  392. package/dist/templates/chat/app/components/layout/Layout.tsx +1 -0
  393. package/dist/templates/chat/app/components/layout/Sidebar.tsx +43 -67
  394. package/dist/templates/chat/app/hooks/use-navigation-state.ts +2 -7
  395. package/dist/templates/chat/app/routes/_index.tsx +8 -5
  396. package/dist/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  397. package/dist/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  398. package/dist/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  399. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  400. package/dist/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
  401. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  402. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  403. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  404. package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
  405. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  406. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
  407. package/docs/AGENTS.md +1 -1
  408. package/docs/content/agent-mentions.mdx +2 -2
  409. package/docs/content/{workspace.mdx → agent-resources.mdx} +1 -7
  410. package/docs/content/agent-teams.mdx +4 -4
  411. package/docs/content/dispatch.mdx +10 -10
  412. package/docs/content/drop-in-agent.mdx +4 -4
  413. package/docs/content/external-agents.mdx +1 -1
  414. package/docs/content/frames.mdx +1 -1
  415. package/docs/content/integrations.mdx +13 -2
  416. package/docs/content/key-concepts.mdx +2 -2
  417. package/docs/content/mcp-clients.mdx +7 -1
  418. package/docs/content/multi-app-workspace.mdx +3 -3
  419. package/docs/content/real-time-collaboration.mdx +33 -15
  420. package/docs/content/recurring-jobs.mdx +7 -7
  421. package/docs/content/skills-guide.mdx +4 -4
  422. package/docs/content/template-brain.mdx +1 -1
  423. package/docs/content/toolkit-collaboration.mdx +1 -1
  424. package/docs/content/using-your-agent.mdx +1 -1
  425. package/docs/content/what-is-agent-native.mdx +4 -4
  426. package/docs/content/workspace-management.mdx +4 -4
  427. package/package.json +6 -3
  428. package/src/agent/production-agent.ts +13 -3
  429. package/src/cli/doctor.ts +6 -1
  430. package/src/client/AgentPanel.tsx +79 -41
  431. package/src/client/AssistantChat.tsx +71 -25
  432. package/src/client/FeedbackButton.tsx +33 -7
  433. package/src/client/MultiTabAssistantChat.tsx +6 -8
  434. package/src/client/agent-chat-adapter.ts +11 -2
  435. package/src/client/agent-page/AgentTabFrame.tsx +22 -3
  436. package/src/client/agent-page/AgentTabsPage.tsx +34 -19
  437. package/src/client/analytics.ts +7 -0
  438. package/src/client/chat/message-components.tsx +43 -16
  439. package/src/client/chat/tool-call-display.tsx +30 -18
  440. package/src/client/chat/tool-render-registry.tsx +2 -0
  441. package/src/client/resources/McpConnectionSuggestion.tsx +19 -2
  442. package/src/client/resources/ResourceTree.tsx +7 -10
  443. package/src/client/resources/ResourcesPanel.tsx +33 -70
  444. package/src/client/resources/mcp-connection-resume.ts +107 -0
  445. package/src/client/resources/mcp-integration-catalog.ts +65 -12
  446. package/src/client/resources/mcp-integration-logos.ts +4 -0
  447. package/src/client/sse-event-processor.ts +50 -14
  448. package/src/client/use-db-sync.ts +370 -21
  449. package/src/collab/client.ts +26 -2
  450. package/src/connections/catalog.ts +7 -1
  451. package/src/db/ddl-guard.ts +49 -10
  452. package/src/deploy/build.ts +25 -2
  453. package/src/eject/remote-mcp-presets.ts +37 -5
  454. package/src/guards/explicit-collab-access.ts +229 -0
  455. package/src/guards/index.ts +1 -0
  456. package/src/localization/default-messages.ts +54 -5
  457. package/src/mcp/connect-route.ts +34 -51
  458. package/src/provider-api/index.ts +1 -1
  459. package/src/realtime-protocol.ts +92 -0
  460. package/src/server/collab-plugin.ts +137 -18
  461. package/src/server/core-routes-plugin.ts +7 -0
  462. package/src/server/index.ts +2 -0
  463. package/src/server/poll-events.ts +29 -8
  464. package/src/server/poll.ts +1123 -865
  465. package/src/server/realtime-token.ts +106 -0
  466. package/src/server/sentry-config.ts +40 -0
  467. package/src/server/short-lived-token.ts +156 -0
  468. package/src/server/sse.ts +15 -0
  469. package/src/server/ssr-handler.ts +9 -3
  470. package/src/styles/agent-native.css +40 -0
  471. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  472. package/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  473. package/src/templates/chat/app/components/layout/Layout.tsx +1 -0
  474. package/src/templates/chat/app/components/layout/Sidebar.tsx +43 -67
  475. package/src/templates/chat/app/hooks/use-navigation-state.ts +2 -7
  476. package/src/templates/chat/app/routes/_index.tsx +8 -5
  477. package/src/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  478. package/src/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  479. package/src/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  480. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  481. package/src/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
  482. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  483. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  484. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  485. package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
  486. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  487. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/collab/client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Client-side hook for collaborative document editing via Yjs.\n *\n * Creates a STABLE Y.Doc per docId that never changes identity. This allows\n * TipTap's Collaboration extension to bind once without editor recreation.\n * Server state is applied to the existing doc when it arrives.\n *\n * Also manages Yjs Awareness for cursor positions and user presence,\n * synced via polling to the server's awareness endpoint.\n *\n * Connection sharing: connections live in a module-level, ref-counted registry\n * keyed by docId (mirroring the SyncTransport registry in use-db-sync.ts).\n * Every `useCollaborativeDoc` mount for the same docId attaches to ONE shared\n * connection — one Y.Doc, one Awareness, one state fetch, one poll loop, one\n * awareness POST cycle — instead of each hook instance opening an independent\n * connection and doubling all collab traffic (e.g. a presence bar and the\n * editor mounting the hook for the same doc). The first subscriber starts the\n * connection; the last one leaving tears it down after a short linger so\n * StrictMode double-mounts and rapid unmount/remounts don't thrash the doc.\n *\n * Transport improvements (vs previous version):\n * - Local update POSTs are debounced and coalesced with Y.mergeUpdates (~80ms)\n * to avoid per-keystroke requests. The batch is flushed immediately on\n * visibilitychange/pagehide and before each poll/awareness cycle.\n * - GET state?stateVector= is NOT fetched on every poll cycle. It is fetched:\n * (a) on (re)connect / initial load, (b) when a poll response indicates a\n * gap (version jump > ring-buffer size), (c) after applying an update fails,\n * and (d) as a low-frequency safety net every STATE_VECTOR_FETCH_INTERVAL\n * poll cycles (~15×).\n * - Network errors use exponential backoff with jitter (cap ~15s), reset on\n * success.\n * - SSE fast-path: collab events are received push-style from\n * /_agent-native/events (the framework SSE stream). While SSE is\n * healthy the poll loop relaxes to a slow cadence (10–15s). If SSE is\n * unavailable the 2s poll resumes automatically.\n */\n\nimport {\n dedupeCollabUsersByEmail,\n type CollabUser,\n} from \"@agent-native/toolkit/collab-ui\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { Awareness } from \"y-protocols/awareness\";\nimport * as Y from \"yjs\";\n\nimport { agentNativePath } from \"../client/api-path.js\";\nimport { subscribeSyncEvents, type SyncEvent } from \"../client/use-db-sync.js\";\nexport {\n dedupeCollabUsersByEmail,\n emailToColor,\n emailToName,\n isReconcileLeadClient,\n type CollabUser,\n} from \"@agent-native/toolkit/collab-ui\";\n\nexport interface UseCollaborativeDocOptions {\n /** Document ID to collaborate on. Pass null to disable. */\n docId: string | null;\n /** Poll interval in ms when SSE is unavailable. Default: 2000 */\n pollInterval?: number;\n /** Poll interval in ms while SSE is healthy. Default: 12000 */\n pollIntervalWithSse?: number;\n /** Pause remote update/presence polling while the tab is hidden. Default: true */\n pauseWhenHidden?: boolean;\n /** Base URL for collab endpoints. Default: \"/_agent-native/collab\" */\n baseUrl?: string;\n /** Request source ID for jitter prevention (e.g., tab ID). */\n requestSource?: string;\n /** Current user info for cursor labels. */\n user?: CollabUser;\n}\n\nexport interface UseCollaborativeDocResult {\n /** The Yjs document instance. Stable per docId — never changes identity. */\n ydoc: Y.Doc | null;\n /** Yjs Awareness instance for cursor/presence sync. */\n awareness: Awareness | null;\n /** Whether the initial state is still loading from the server. */\n isLoading: boolean;\n /** Whether the doc is synced with the server. */\n isSynced: boolean;\n /** Active users on this document (from awareness). */\n activeUsers: CollabUser[];\n /** True briefly when the AI agent makes an edit (for presence indicator). */\n agentActive: boolean;\n /** True when the AI agent has an active awareness entry (durable presence). */\n agentPresent: boolean;\n}\n\nfunction isDocumentHidden(): boolean {\n return (\n typeof document !== \"undefined\" && document.visibilityState === \"hidden\"\n );\n}\n\n/**\n * Content equality for deduped active-user lists. `dedupeCollabUsersByEmail`\n * always allocates a fresh array (and fresh per-user objects), so callers\n * that only want to know \"did the actual user set change\" need this instead\n * of an identity check. Order-sensitive: the dedupe helper iterates awareness\n * states in a stable Map insertion order, so a reordering here does reflect\n * a real change (a client joined/left and re-joined).\n */\nfunction collabUsersEqual(a: CollabUser[], b: CollabUser[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const left = a[i]!;\n const right = b[i]!;\n if (\n left.email !== right.email ||\n left.name !== right.name ||\n left.color !== right.color\n ) {\n return false;\n }\n }\n return true;\n}\n\nexport interface RemoteAwarenessSnapshot {\n clientId: number;\n state: unknown;\n}\n\nexport function reconcileRemoteAwarenessStates(\n states: Map<number, unknown>,\n localClientId: number,\n remoteStates: RemoteAwarenessSnapshot[],\n): { added: number[]; updated: number[]; removed: number[] } {\n const incoming = new Set<number>();\n const added: number[] = [];\n const updated: number[] = [];\n const removed: number[] = [];\n\n for (const remote of remoteStates) {\n if (\n !Number.isFinite(remote.clientId) ||\n remote.clientId === localClientId\n ) {\n continue;\n }\n incoming.add(remote.clientId);\n const hadState = states.has(remote.clientId);\n states.set(remote.clientId, remote.state);\n (hadState ? updated : added).push(remote.clientId);\n }\n\n for (const clientId of Array.from(states.keys())) {\n if (clientId === localClientId) continue;\n if (incoming.has(clientId)) continue;\n states.delete(clientId);\n removed.push(clientId);\n }\n\n return { added, updated, removed };\n}\n\n// Base64 helpers\nfunction uint8ArrayToBase64(arr: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < arr.length; i++) {\n binary += String.fromCharCode(arr[i]);\n }\n return btoa(binary);\n}\n\nfunction base64ToUint8Array(b64: string): Uint8Array {\n const binary = atob(b64);\n const arr = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n arr[i] = binary.charCodeAt(i);\n }\n return arr;\n}\n\n/** Debounce delay for coalescing local Yjs update POSTs (ms). */\nconst UPDATE_DEBOUNCE_MS = 80;\n\n/** Fetch state-vector every N poll cycles as a low-frequency safety net. */\nconst STATE_VECTOR_FETCH_INTERVAL = 15;\n\n/** Poll ring-buffer size on the server (MAX_BUFFER in poll.ts). */\nconst POLL_RING_BUFFER_SIZE = 200;\n\n/** Exponential backoff: base delay (ms), multiplier, cap (ms). */\nconst BACKOFF_BASE_MS = 500;\nconst BACKOFF_MAX_MS = 15_000;\n\nfunction calcBackoff(consecutiveErrors: number): number {\n const exp = Math.min(consecutiveErrors, 10);\n const delay = BACKOFF_BASE_MS * Math.pow(2, exp);\n // Add jitter: ±25%\n const jitter = delay * 0.25 * (Math.random() * 2 - 1);\n return Math.min(delay + jitter, BACKOFF_MAX_MS);\n}\n\n// ---------------------------------------------------------------------------\n// Fast awareness helper — throttled per (docId, ydocId) pair so multiple\n// setLocalStateField calls within a 150ms window are coalesced into one POST.\n// ---------------------------------------------------------------------------\n\nconst _awarenessThrottleTimers = new Map<\n string,\n ReturnType<typeof setTimeout>\n>();\n\nfunction scheduleAwarenessPush(\n baseUrl: string,\n docId: string,\n clientId: number,\n getState: () => Record<string, unknown> | null,\n): void {\n if (typeof window === \"undefined\") return;\n const key = `${docId}::${clientId}`;\n if (_awarenessThrottleTimers.has(key)) return; // already scheduled\n\n const timer = setTimeout(() => {\n _awarenessThrottleTimers.delete(key);\n const state = getState();\n fetch(`${baseUrl}/${docId}/awareness`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n clientId,\n state: state ? JSON.stringify(state) : null,\n }),\n }).catch(() => {}); // best-effort; poll cycle is the baseline fallback\n }, 150);\n\n _awarenessThrottleTimers.set(key, timer);\n}\n\n// ---------------------------------------------------------------------------\n// Shared per-docId collab connection\n//\n// One CollabDocConnection per (baseUrl, docId) pair is held in a module-level\n// registry (the same pattern as SyncTransport in use-db-sync.ts). Every\n// `useCollaborativeDoc` mount for a docId subscribes to the shared connection,\n// so a tab runs exactly ONE state fetch, ONE poll fallback loop, and ONE\n// awareness POST cycle per document no matter how many components mount the\n// hook (e.g. a presence bar + the editor for the same doc).\n//\n// Lifecycle: the connection is created on first render that needs it (the\n// Y.Doc must exist during render so TipTap can bind on mount), starts its\n// network activity when the first subscriber attaches, and is disposed a short\n// linger after the last subscriber detaches. The linger keeps StrictMode's\n// mount→unmount→mount and rapid route remounts from destroying and refetching\n// the doc, and doubles as the cleanup path for connections created by a render\n// that React later discarded (no subscriber ever attaches).\n// ---------------------------------------------------------------------------\n\n/**\n * Shared reactive state each subscriber mirrors into its own React state.\n * Replaced immutably on every change so hooks can bail out on identity.\n */\ninterface CollabDocSnapshot {\n isLoading: boolean;\n isSynced: boolean;\n activeUsers: CollabUser[];\n agentActive: boolean;\n agentPresent: boolean;\n}\n\ninterface CollabDocSubscription {\n /** Requested poll interval; the connection uses the MIN across subscribers. */\n pollInterval: number;\n /** Requested relaxed interval while SSE is healthy (MIN across subscribers). */\n pollIntervalWithSse: number;\n /**\n * Whether this subscriber wants polling paused while the tab is hidden.\n * The connection pauses only when ALL subscribers request it.\n */\n pauseWhenHidden: boolean;\n /**\n * Echo-suppression tag. The connection adopts the first defined value and\n * uses it for BOTH tagging outgoing updates and filtering incoming echoes,\n * so suppression stays self-consistent even when subscribers pass different\n * per-tab IDs (all values identify the same tab).\n */\n requestSource?: string;\n onSnapshot: (snapshot: CollabDocSnapshot) => void;\n}\n\nconst EMPTY_SNAPSHOT: CollabDocSnapshot = Object.freeze({\n isLoading: false,\n isSynced: false,\n activeUsers: [],\n agentActive: false,\n agentPresent: false,\n});\n\n/**\n * How long a connection with zero subscribers lingers before disposal.\n * Long enough to absorb StrictMode double-mounts and route-level remounts\n * (which would otherwise destroy the Y.Doc, refetch server state, and lose\n * echo-suppression context), short enough that navigating away stops the\n * doc's traffic promptly.\n */\nconst DISPOSE_LINGER_MS = 1000;\n\nclass CollabDocConnection {\n readonly ydoc: Y.Doc;\n readonly awareness: Awareness;\n /** Immutable snapshot of the shared reactive state (replaced on change). */\n snapshot: CollabDocSnapshot;\n disposed = false;\n\n private subscribers = new Map<symbol, CollabDocSubscription>();\n private disposeTimer: ReturnType<typeof setTimeout> | null = null;\n private started = false;\n private docMissing = false;\n private requestSource: string | undefined;\n private lastSetUser: CollabUser | null = null;\n\n // Local-update batching (debounced + coalesced with Y.mergeUpdates).\n private pendingUpdates: Uint8Array[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private updateHandlerAttached = false;\n\n // Poll loop + SSE fast path.\n private syncActive = false;\n private pollTimer: ReturnType<typeof setTimeout> | null = null;\n private consecutiveErrors = 0;\n private pollCycleCount = 0;\n private pollVersion = 0;\n private lastPolledVersion = 0;\n private sseActive = false;\n private sseSubscribedWithPause: boolean | null = null;\n private unsubscribeCollabEvents: (() => void) | null = null;\n private unsubscribeAwarenessEvents: (() => void) | null = null;\n private agentTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(\n readonly docId: string,\n private readonly baseUrl: string,\n /**\n * Detached connections are created for SSR renders only: a per-hook\n * Y.Doc/Awareness with no registry entry and no network activity\n * (matching the previous per-hook behavior on the server). They are\n * never started and are reclaimed by GC with the render.\n */\n readonly detached = false,\n ) {\n this.ydoc = new Y.Doc();\n this.awareness = new Awareness(this.ydoc);\n this.snapshot = {\n isLoading: true,\n isSynced: false,\n activeUsers: [],\n agentActive: false,\n agentPresent: false,\n };\n\n // Track active users / agent presence from awareness changes, and drive\n // the fast (throttled) awareness push once a local user is published.\n this.awareness.on(\"change\", this.handleAwarenessChange);\n\n // Orphan guard: the connection is created during render (the Y.Doc must\n // exist before mount), so a discarded render can create one that never\n // gets a subscriber. The linger timer disposes it; the first `add()`\n // cancels the timer.\n if (!detached) this.scheduleDispose();\n }\n\n private get registryKey(): string {\n return collabRegistryKey(this.docId, this.baseUrl);\n }\n\n // -------------------------------------------------------------------------\n // Subscriber management (ref-counting)\n // -------------------------------------------------------------------------\n\n add(id: symbol, sub: CollabDocSubscription): void {\n this.subscribers.set(id, sub);\n if (this.disposeTimer) {\n clearTimeout(this.disposeTimer);\n this.disposeTimer = null;\n }\n // Adopt the first defined echo-suppression tag for the connection's\n // lifetime (see CollabDocSubscription.requestSource).\n if (!this.requestSource && sub.requestSource) {\n this.requestSource = sub.requestSource;\n }\n if (!this.started) {\n this.started = true;\n this.start();\n } else {\n // A joining subscriber can change the effective poll cadence or the\n // pause-when-hidden aggregate; pick both up without waiting a cycle.\n this.resubscribeCollabEventsIfPauseChanged();\n this.reschedulePoll();\n }\n }\n\n remove(id: symbol): void {\n this.subscribers.delete(id);\n if (this.subscribers.size === 0) {\n this.scheduleDispose();\n } else {\n this.resubscribeCollabEventsIfPauseChanged();\n this.reschedulePoll();\n }\n }\n\n private scheduleDispose(): void {\n if (this.disposeTimer) clearTimeout(this.disposeTimer);\n this.disposeTimer = setTimeout(() => {\n this.disposeTimer = null;\n this.dispose();\n }, DISPOSE_LINGER_MS);\n }\n\n /**\n * Tear the connection down: stop all loops and listeners, flush any pending\n * local updates, clear awareness local state (via destroy), and destroy the\n * Y.Doc. Also used by the test-only registry reset. @internal\n */\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n if (this.disposeTimer) {\n clearTimeout(this.disposeTimer);\n this.disposeTimer = null;\n }\n this.stopSync();\n this.unsubscribeAwarenessEvents?.();\n this.unsubscribeAwarenessEvents = null;\n this.flushPendingUpdates(true);\n this.detachUpdateHandler();\n if (this.agentTimer) {\n clearTimeout(this.agentTimer);\n this.agentTimer = null;\n }\n // Detach our change listener BEFORE destroy so the destroy-time\n // `setLocalState(null)` does not schedule a push (matches the previous\n // per-hook effect cleanup ordering).\n this.awareness.off(\"change\", this.handleAwarenessChange);\n this.awareness.destroy();\n this.ydoc.destroy();\n if (collabConnectionRegistry.get(this.registryKey) === this) {\n collabConnectionRegistry.delete(this.registryKey);\n }\n }\n\n // -------------------------------------------------------------------------\n // Derived settings (aggregate over active subscribers)\n // -------------------------------------------------------------------------\n\n private get effectivePollInterval(): number {\n let min = Infinity;\n for (const sub of this.subscribers.values()) {\n if (sub.pollInterval < min) min = sub.pollInterval;\n }\n return isFinite(min) ? min : 2000;\n }\n\n private get effectivePollIntervalWithSse(): number {\n let min = Infinity;\n for (const sub of this.subscribers.values()) {\n if (sub.pollIntervalWithSse < min) min = sub.pollIntervalWithSse;\n }\n return isFinite(min) ? min : 12_000;\n }\n\n private get effectivePauseWhenHidden(): boolean {\n // Pause only if every subscriber has opted in.\n for (const sub of this.subscribers.values()) {\n if (!sub.pauseWhenHidden) return false;\n }\n return true;\n }\n\n // -------------------------------------------------------------------------\n // Shared state fan-out\n // -------------------------------------------------------------------------\n\n private setSnapshot(patch: Partial<CollabDocSnapshot>): void {\n this.snapshot = { ...this.snapshot, ...patch };\n for (const sub of this.subscribers.values()) {\n sub.onSnapshot(this.snapshot);\n }\n }\n\n private markAgentActive(): void {\n this.setSnapshot({ agentActive: true });\n if (this.agentTimer) clearTimeout(this.agentTimer);\n this.agentTimer = setTimeout(() => {\n this.agentTimer = null;\n this.setSnapshot({ agentActive: false });\n }, 3000);\n }\n\n // -------------------------------------------------------------------------\n // Awareness: local identity, active-user tracking, fast push\n // -------------------------------------------------------------------------\n\n /**\n * Publish the local user identity (cursor label) and current visibility.\n * Set once per tab — repeated calls with the same identity are no-ops so\n * multiple subscribers for the same user don't re-emit awareness updates.\n */\n setUser(user: CollabUser): void {\n if (this.disposed) return;\n const prev = this.lastSetUser;\n if (\n prev &&\n prev.name === user.name &&\n prev.email === user.email &&\n prev.color === user.color\n ) {\n return;\n }\n this.lastSetUser = {\n name: user.name,\n email: user.email,\n color: user.color,\n };\n this.awareness.setLocalStateField(\"user\", {\n name: user.name,\n email: user.email,\n color: user.color,\n });\n // Also publish this tab's visibility so peers can elect a VISIBLE client\n // to apply external snapshots (see isReconcileLeadClient) — a backgrounded\n // tab pauses its poll and must not hold that role.\n this.awareness.setLocalStateField(\"visible\", !isDocumentHidden());\n }\n\n private handleAwarenessChange = (\n _changes?: { added: number[]; updated: number[]; removed: number[] },\n origin?: unknown,\n ): void => {\n const users: CollabUser[] = [];\n let hasAgent = false;\n this.awareness.getStates().forEach((state, clientId) => {\n if (clientId === this.ydoc.clientID) return; // Skip self\n if (state.user) {\n users.push(state.user as CollabUser);\n if ((state.user as CollabUser).email === \"agent@system\") {\n hasAgent = true;\n }\n }\n });\n const nextActiveUsers = dedupeCollabUsersByEmail(users);\n // Awareness \"change\" fires for every remote broadcast — including cursor\n // jiggles, re-published-but-unchanged heartbeat state, and edits to\n // presence fields (recentEdits, selection) that don't affect who's\n // active. dedupeCollabUsersByEmail always returns a fresh array, so\n // without this comparison every one of those events would hand\n // `activeUsers` a new identity and force every consumer (e.g. a\n // full-page editor keying a useMemo/effect off it) to re-render even\n // though the actual user list is unchanged. Reuse the previous\n // reference when the deduped content is the same, matching the\n // stable-ref discipline `usePresence`'s shallowEqualOthers already\n // applies to `others`.\n const activeUsers = collabUsersEqual(\n this.snapshot.activeUsers,\n nextActiveUsers,\n )\n ? this.snapshot.activeUsers\n : nextActiveUsers;\n if (\n activeUsers !== this.snapshot.activeUsers ||\n hasAgent !== this.snapshot.agentPresent\n ) {\n this.setSnapshot({ activeUsers, agentPresent: hasAgent });\n }\n\n // Fast awareness push: whenever OUR OWN awareness state changes (e.g.\n // cursor moves, setPresence() calls), schedule a throttled POST so peers\n // receive updates at ~150ms instead of waiting for the next poll cycle.\n // Gated on origin === \"local\": this listener also fires for remote\n // awareness changes (poll/SSE call `awareness.emit(\"change\", [changes,\n // \"remote\"])` after reconciling incoming states — see\n // applyAwarenessEvent/poll above). Without the origin check, every\n // peer's cursor move would also re-trigger THIS client to re-broadcast\n // its own unchanged state, turning one person moving their mouse into\n // O(n) redundant POSTs from every other connected client (an awareness\n // storm that gets worse as more people join the doc). Only active once a\n // local user identity has been published (matches the previous per-hook\n // gating on `user`). The poll cycle remains the authoritative baseline.\n if (this.lastSetUser && origin === \"local\" && !this.disposed) {\n scheduleAwarenessPush(\n this.baseUrl,\n this.docId,\n this.ydoc.clientID,\n () => this.awareness.getLocalState() as Record<string, unknown> | null,\n );\n }\n };\n\n // -------------------------------------------------------------------------\n // Startup: initial state fetch, update handler, sync loops\n // -------------------------------------------------------------------------\n\n private start(): void {\n this.attachUpdateHandler();\n this.fetchInitialState();\n this.startSync();\n\n // SSE fast-path for awareness: listen on the SHARED framework transport\n // and apply awareness-change events immediately so peers receive cursor\n // moves push-style without waiting for the next poll cycle. Kept alive\n // even when the doc is missing (matches the previous per-hook behavior).\n this.unsubscribeAwarenessEvents = subscribeSyncEvents({\n onEvents: (events) => {\n if (this.disposed) return;\n for (const data of events) this.applyAwarenessEvent(data);\n },\n });\n }\n\n private fetchInitialState(): void {\n fetch(`${this.baseUrl}/${this.docId}/state`)\n .then(async (res) => {\n if (this.disposed) return;\n if (res.status === 404 || res.status === 403) {\n this.markDocMissing();\n return;\n }\n const data = (await res.json().catch(() => null)) as {\n state?: string;\n } | null;\n if (this.disposed) return;\n if (data?.state) {\n const binary = base64ToUint8Array(data.state);\n if (binary.length > 4) {\n Y.applyUpdate(this.ydoc, binary, \"remote\");\n }\n }\n this.setSnapshot({ isLoading: false, isSynced: true });\n })\n .catch(() => {\n if (this.disposed) return;\n this.setSnapshot({ isLoading: false, isSynced: true });\n });\n }\n\n /**\n * The initial state fetch returned 404/403 — the doc doesn't exist or isn't\n * accessible. Stop doc-update traffic (poll loop, update POSTs, collab SSE\n * handling) so we don't spam the console with errors against it. The\n * awareness SSE subscription stays (matches previous behavior).\n */\n private markDocMissing(): void {\n this.docMissing = true;\n this.flushPendingUpdates(true);\n this.detachUpdateHandler();\n this.stopSync();\n this.setSnapshot({ isLoading: false, isSynced: true });\n }\n\n // -------------------------------------------------------------------------\n // Local update batching\n // -------------------------------------------------------------------------\n\n private handleDocUpdate = (update: Uint8Array, origin: unknown): void => {\n if (origin === \"remote\") return;\n this.pendingUpdates.push(update);\n if (this.flushTimer) clearTimeout(this.flushTimer);\n this.flushTimer = setTimeout(\n () => this.flushPendingUpdates(),\n UPDATE_DEBOUNCE_MS,\n );\n };\n\n private handlePageHide = (): void => {\n this.flushPendingUpdates(true /* keepalive */);\n };\n\n private attachUpdateHandler(): void {\n if (this.updateHandlerAttached || this.docMissing) return;\n this.updateHandlerAttached = true;\n this.ydoc.on(\"update\", this.handleDocUpdate);\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"pagehide\", this.handlePageHide);\n }\n }\n\n private detachUpdateHandler(): void {\n if (!this.updateHandlerAttached) return;\n this.updateHandlerAttached = false;\n this.ydoc.off(\"update\", this.handleDocUpdate);\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"pagehide\", this.handlePageHide);\n }\n }\n\n private flushPendingUpdates(keepalive = false): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n if (this.pendingUpdates.length === 0) return;\n const toSend = this.pendingUpdates;\n this.pendingUpdates = [];\n\n const merged = toSend.length === 1 ? toSend[0] : Y.mergeUpdates(toSend);\n fetch(`${this.baseUrl}/${this.docId}/update`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n update: uint8ArrayToBase64(merged),\n requestSource: this.requestSource,\n }),\n ...(keepalive ? { keepalive: true } : {}),\n }).catch(() => {});\n }\n\n // -------------------------------------------------------------------------\n // Remote sync: SSE fast path + poll fallback loop\n // -------------------------------------------------------------------------\n\n private startSync(): void {\n if (this.syncActive || this.docMissing || this.disposed) return;\n this.syncActive = true;\n\n this.subscribeCollabEvents();\n\n if (!this.effectivePauseWhenHidden || !isDocumentHidden()) {\n void this.poll();\n }\n window.addEventListener(\"focus\", this.handleFocus);\n document.addEventListener(\"visibilitychange\", this.handleVisibilityChange);\n }\n\n private stopSync(): void {\n if (!this.syncActive) return;\n this.syncActive = false;\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n this.unsubscribeCollabEvents?.();\n this.unsubscribeCollabEvents = null;\n this.sseSubscribedWithPause = null;\n window.removeEventListener(\"focus\", this.handleFocus);\n document.removeEventListener(\n \"visibilitychange\",\n this.handleVisibilityChange,\n );\n }\n\n /**\n * SSE fast-path: subscribe to the SHARED framework transport for\n * /_agent-native/events instead of opening a dedicated EventSource per\n * collab doc. A tab holds exactly one SSE connection regardless of how many\n * docs are mounted. Collab update events arrive push-style; we apply them\n * immediately, avoiding ~2s polling latency for peer edits.\n *\n * NOTE: SSE events are subject to the same server-side access scoping as\n * polling — the server only pushes events that canSeeChangeForUser allows.\n */\n private subscribeCollabEvents(): void {\n const pauseWhenHidden = this.effectivePauseWhenHidden;\n this.sseSubscribedWithPause = pauseWhenHidden;\n this.unsubscribeCollabEvents = subscribeSyncEvents({\n onEvents: (events) => {\n if (this.disposed || !this.syncActive) return;\n for (const change of events) this.handleSharedEvent(change);\n },\n onSseStateChange: (connected) => {\n this.sseActive = connected;\n if (connected) this.consecutiveErrors = 0;\n },\n pauseWhenHidden,\n });\n }\n\n /**\n * The pause-when-hidden aggregate can flip when subscribers join or leave;\n * the shared-transport subscription captures it at subscribe time, so\n * re-subscribe when it changes.\n */\n private resubscribeCollabEventsIfPauseChanged(): void {\n if (!this.syncActive) return;\n if (this.sseSubscribedWithPause === this.effectivePauseWhenHidden) return;\n this.unsubscribeCollabEvents?.();\n this.subscribeCollabEvents();\n }\n\n private handleSharedEvent(change: SyncEvent): void {\n if (\n change.source === \"collab\" &&\n change.docId === this.docId &&\n typeof change.update === \"string\"\n ) {\n // Own echo — skip entirely (including the version tracking below, so\n // the next poll re-delivers and dedupe happens there; matches the\n // previous per-hook behavior).\n if (this.requestSource && change.requestSource === this.requestSource) {\n return;\n }\n try {\n Y.applyUpdate(this.ydoc, base64ToUint8Array(change.update), \"remote\");\n } catch {\n // Malformed update — trigger state-vector fetch on next poll\n }\n\n if (change.requestSource === \"agent\") {\n this.markAgentActive();\n }\n }\n\n // Keep the poll cursor updated from shared-transport events so the poll\n // loop starts from the right version when SSE drops.\n if (typeof change.version === \"number\") {\n this.pollVersion = Math.max(this.pollVersion, change.version);\n }\n }\n\n private getActivePollInterval(): number {\n return this.sseActive\n ? this.effectivePollIntervalWithSse\n : this.effectivePollInterval;\n }\n\n private schedulePoll(): void {\n if (!this.syncActive || this.disposed) return;\n if (this.effectivePauseWhenHidden && isDocumentHidden()) return;\n this.pollTimer = setTimeout(() => {\n this.pollTimer = null;\n void this.poll();\n }, this.getActivePollInterval());\n }\n\n /**\n * A subscriber joined or left, potentially changing the effective interval.\n * If a poll is already scheduled, reschedule with the new cadence (the next\n * natural tick would pick it up anyway; this just avoids a stale long wait\n * when a faster subscriber joins).\n */\n private reschedulePoll(): void {\n if (this.pollTimer === null) return;\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n this.schedulePoll();\n }\n\n private async fetchStateVector(): Promise<void> {\n try {\n const stateVector = uint8ArrayToBase64(Y.encodeStateVector(this.ydoc));\n const stateRes = await fetch(\n `${this.baseUrl}/${this.docId}/state?stateVector=${encodeURIComponent(stateVector)}`,\n );\n if (stateRes.ok) {\n const stateData = (await stateRes.json().catch(() => null)) as {\n state?: string;\n } | null;\n if (this.disposed) return;\n if (stateData?.state) {\n const binary = base64ToUint8Array(stateData.state);\n if (binary.length > 2) {\n Y.applyUpdate(this.ydoc, binary, \"remote\");\n }\n }\n }\n } catch {\n // Non-fatal; the next poll cycle will retry\n }\n }\n\n private async poll(): Promise<void> {\n if (!this.syncActive || this.disposed) return;\n\n // Flush any pending local updates before polling so the server has the\n // latest state before we read remote changes.\n this.flushPendingUpdates();\n\n try {\n const res = await fetch(\n agentNativePath(`/_agent-native/poll?since=${this.pollVersion}`),\n );\n if (!res.ok) throw new Error(\"HTTP \" + res.status);\n\n const data = await res.json();\n if (!this.syncActive || this.disposed) return;\n const { version, events } = data as {\n version: number;\n events: Array<{\n source: string;\n docId?: string;\n update?: string;\n requestSource?: string;\n }>;\n };\n\n // Detect ring-buffer overflow: if the version jumped by more than the\n // ring buffer size, some events were evicted and we need a state-vector\n // fetch to reconcile the gap.\n const versionGap = version - this.lastPolledVersion;\n const hadGap = versionGap > POLL_RING_BUFFER_SIZE;\n\n for (const evt of events) {\n if (evt.source === \"collab\" && evt.docId === this.docId && evt.update) {\n if (this.requestSource && evt.requestSource === this.requestSource) {\n continue;\n }\n try {\n Y.applyUpdate(this.ydoc, base64ToUint8Array(evt.update), \"remote\");\n } catch {\n // Failed to apply — fetch full state-vector below\n await this.fetchStateVector();\n }\n\n if (evt.requestSource === \"agent\") {\n this.markAgentActive();\n }\n }\n }\n\n this.pollVersion = version;\n this.lastPolledVersion = version;\n this.pollCycleCount++;\n this.consecutiveErrors = 0;\n\n // Fetch state-vector only when needed:\n // 1. Ring-buffer overflow detected (missed events).\n // 2. Low-frequency safety net every STATE_VECTOR_FETCH_INTERVAL cycles.\n // 3. NOT on every cycle (the previous behavior causing 3 requests/cycle).\n const shouldFetchStateVector =\n hadGap || this.pollCycleCount % STATE_VECTOR_FETCH_INTERVAL === 0;\n\n if (shouldFetchStateVector) {\n await this.fetchStateVector();\n }\n\n // Sync awareness (cursor positions)\n const localState = this.awareness.getLocalState();\n if (localState && !this.disposed) {\n try {\n const awarenessRes = await fetch(\n `${this.baseUrl}/${this.docId}/awareness`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n clientId: this.ydoc.clientID,\n state: JSON.stringify(localState),\n }),\n },\n );\n if (awarenessRes.ok && !this.disposed) {\n const awarenessData = await awarenessRes.json();\n const remoteStates: RemoteAwarenessSnapshot[] = [];\n for (const remote of awarenessData.states || []) {\n try {\n const remoteState = JSON.parse(remote.state);\n remoteStates.push({\n clientId: Number(remote.clientId),\n state: remoteState,\n });\n } catch {\n // Invalid state — skip\n }\n }\n if (this.disposed) return;\n const changes = reconcileRemoteAwarenessStates(\n this.awareness.getStates() as Map<number, unknown>,\n this.ydoc.clientID,\n remoteStates,\n );\n if (\n changes.added.length ||\n changes.updated.length ||\n changes.removed.length\n ) {\n this.awareness.emit(\"change\", [changes, \"remote\"]);\n }\n }\n } catch {\n // Awareness sync failure is non-fatal\n }\n }\n } catch {\n // Network error — exponential backoff\n this.consecutiveErrors++;\n const backoff = calcBackoff(this.consecutiveErrors);\n if (this.syncActive && !this.disposed) {\n this.pollTimer = setTimeout(() => {\n this.pollTimer = null;\n void this.poll();\n }, backoff);\n }\n return;\n }\n\n this.schedulePoll();\n }\n\n private pollNow(): void {\n if (!this.syncActive || this.disposed) return;\n if (this.effectivePauseWhenHidden && isDocumentHidden()) return;\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n void this.poll();\n }\n\n /**\n * Publish this tab's visibility to peers. A hidden tab pauses its poll, so\n * we push the state immediately (keepalive) instead of waiting for the next\n * cycle — otherwise peers keep treating a backgrounded tab as the visible\n * lead and an agent edit never lands on the tab the user is actually viewing.\n */\n private publishVisibility(visible: boolean): void {\n this.awareness.setLocalStateField(\"visible\", visible);\n const localState = this.awareness.getLocalState();\n if (!localState) return;\n fetch(`${this.baseUrl}/${this.docId}/awareness`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n clientId: this.ydoc.clientID,\n state: JSON.stringify(localState),\n }),\n keepalive: true,\n }).catch(() => {});\n }\n\n private handleVisibilityChange = (): void => {\n const visible = document.visibilityState === \"visible\";\n this.publishVisibility(visible);\n if (visible) {\n // Also flush any pending updates when coming back into view\n this.flushPendingUpdates();\n this.pollNow();\n } else if (this.effectivePauseWhenHidden && this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n };\n\n private handleFocus = (): void => {\n this.pollNow();\n };\n\n // -------------------------------------------------------------------------\n // Awareness SSE fast-path\n // -------------------------------------------------------------------------\n\n private applyAwarenessEvent(data: SyncEvent): void {\n if (\n data.source !== \"awareness\" ||\n data.type !== \"awareness-change\" ||\n data.docId !== this.docId\n ) {\n return;\n }\n const states = Array.isArray(data.states)\n ? (data.states as Array<{ clientId: number; state: string }>)\n : [];\n const remoteStates: RemoteAwarenessSnapshot[] = [];\n for (const remote of states) {\n try {\n remoteStates.push({\n clientId: Number(remote.clientId),\n state: JSON.parse(remote.state),\n });\n } catch {\n // Invalid state entry — skip\n }\n }\n const changes = reconcileRemoteAwarenessStates(\n this.awareness.getStates() as Map<number, unknown>,\n this.ydoc.clientID,\n remoteStates,\n );\n if (\n changes.added.length ||\n changes.updated.length ||\n changes.removed.length\n ) {\n this.awareness.emit(\"change\", [changes, \"remote\"]);\n }\n }\n}\n\n/**\n * Registry of active connections keyed by \"<baseUrl>\\0<docId>\".\n * Module-level singleton: survives React render cycles, shared across all\n * hook instances in the same browser tab.\n */\nconst collabConnectionRegistry = new Map<string, CollabDocConnection>();\n\nfunction collabRegistryKey(docId: string, baseUrl: string): string {\n return `${baseUrl}\\0${docId}`;\n}\n\nfunction getOrCreateCollabConnection(\n docId: string,\n baseUrl: string,\n): CollabDocConnection {\n const key = collabRegistryKey(docId, baseUrl);\n let conn = collabConnectionRegistry.get(key);\n if (!conn || conn.disposed) {\n conn = new CollabDocConnection(docId, baseUrl);\n collabConnectionRegistry.set(key, conn);\n }\n return conn;\n}\n\n// ---------------------------------------------------------------------------\n// Internal test helpers — reset/inspect the connection registry between tests.\n// ---------------------------------------------------------------------------\n/** @internal */\nexport function _resetCollabDocRegistryForTests(): void {\n for (const conn of Array.from(collabConnectionRegistry.values())) {\n conn.dispose();\n }\n collabConnectionRegistry.clear();\n}\n\n/** @internal — current registry size, for leak assertions in tests. */\nexport function _collabDocRegistrySizeForTests(): number {\n return collabConnectionRegistry.size;\n}\n\nexport function useCollaborativeDoc(\n options: UseCollaborativeDocOptions,\n): UseCollaborativeDocResult {\n const {\n docId,\n pollInterval = 2000,\n pollIntervalWithSse = 12000,\n pauseWhenHidden = true,\n baseUrl = agentNativePath(\"/_agent-native/collab\"),\n requestSource,\n user,\n } = options;\n\n // Bumped when the effect finds the memoized connection was disposed in the\n // render→effect gap (rare: a suspended transition outliving the linger\n // window) so the memo below re-acquires a live one.\n const [generation, setGeneration] = useState(0);\n\n // Shared connection per docId. Acquired during render so the Y.Doc identity\n // is available on first render (TipTap binds on mount); get-or-create is\n // idempotent, so StrictMode's double render returns the same instance.\n const conn = useMemo(() => {\n void generation;\n if (!docId) return null;\n if (typeof window === \"undefined\") {\n // SSR render: per-hook detached doc, never started (matches the\n // previous per-hook behavior on the server).\n return new CollabDocConnection(docId, baseUrl, true);\n }\n return getOrCreateCollabConnection(docId, baseUrl);\n }, [docId, baseUrl, generation]);\n\n const [snapshot, setSnapshot] = useState<CollabDocSnapshot>(() =>\n conn ? conn.snapshot : EMPTY_SNAPSHOT,\n );\n\n // Render-time reset when the connection identity changes (docId switch) so\n // consumers never see the previous doc's state for a frame.\n const [prevConn, setPrevConn] = useState(conn);\n if (prevConn !== conn) {\n setPrevConn(conn);\n setSnapshot(conn ? conn.snapshot : EMPTY_SNAPSHOT);\n }\n\n // Subscribe (ref-count) — the first subscriber starts the connection, the\n // last one leaving schedules its teardown.\n useEffect(() => {\n if (!conn || conn.detached) return;\n if (conn.disposed) {\n // Disposed between render and effect — re-acquire a live connection.\n setGeneration((g) => g + 1);\n return;\n }\n const id = Symbol(\"useCollaborativeDoc\");\n conn.add(id, {\n pollInterval,\n pollIntervalWithSse,\n pauseWhenHidden,\n requestSource,\n onSnapshot: setSnapshot,\n });\n // Re-sync in case the connection changed state between render and effect.\n setSnapshot(conn.snapshot);\n return () => {\n conn.remove(id);\n };\n }, [conn, pollInterval, pollIntervalWithSse, pauseWhenHidden, requestSource]);\n\n // Publish local user identity for cursor labels (set once per tab; the\n // connection dedupes repeated identical identities across subscribers).\n useEffect(() => {\n if (!conn || conn.detached || !user) return;\n conn.setUser({ name: user.name, email: user.email, color: user.color });\n }, [conn, user?.name, user?.email, user?.color]);\n\n return {\n ydoc: conn ? conn.ydoc : null,\n awareness: conn ? conn.awareness : null,\n isLoading: snapshot.isLoading,\n isSynced: snapshot.isSynced,\n activeUsers: snapshot.activeUsers,\n agentActive: snapshot.agentActive,\n agentPresent: snapshot.agentPresent,\n };\n}\n"]}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/collab/client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Client-side hook for collaborative document editing via Yjs.\n *\n * Creates a STABLE Y.Doc per docId that never changes identity. This allows\n * TipTap's Collaboration extension to bind once without editor recreation.\n * Server state is applied to the existing doc when it arrives.\n *\n * Also manages Yjs Awareness for cursor positions and user presence,\n * synced via polling to the server's awareness endpoint.\n *\n * Connection sharing: connections live in a module-level, ref-counted registry\n * keyed by docId (mirroring the SyncTransport registry in use-db-sync.ts).\n * Every `useCollaborativeDoc` mount for the same docId attaches to ONE shared\n * connection — one Y.Doc, one Awareness, one state fetch, one poll loop, one\n * awareness POST cycle — instead of each hook instance opening an independent\n * connection and doubling all collab traffic (e.g. a presence bar and the\n * editor mounting the hook for the same doc). The first subscriber starts the\n * connection; the last one leaving tears it down after a short linger so\n * StrictMode double-mounts and rapid unmount/remounts don't thrash the doc.\n *\n * Transport improvements (vs previous version):\n * - Local update POSTs are debounced and coalesced with Y.mergeUpdates (~80ms)\n * to avoid per-keystroke requests. The batch is flushed immediately on\n * visibilitychange/pagehide and before each poll/awareness cycle.\n * - GET state?stateVector= is NOT fetched on every poll cycle. It is fetched:\n * (a) on (re)connect / initial load, (b) when a poll response indicates a\n * gap (version jump > ring-buffer size), (c) after applying an update fails,\n * and (d) as a low-frequency safety net every STATE_VECTOR_FETCH_INTERVAL\n * poll cycles (~15×).\n * - Network errors use exponential backoff with jitter (cap ~15s), reset on\n * success.\n * - SSE fast-path: collab events are received push-style from\n * /_agent-native/events (the framework SSE stream). While SSE is\n * healthy the poll loop relaxes to a slow cadence (10–15s). If SSE is\n * unavailable the 2s poll resumes automatically.\n */\n\nimport {\n dedupeCollabUsersByEmail,\n type CollabUser,\n} from \"@agent-native/toolkit/collab-ui\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { Awareness } from \"y-protocols/awareness\";\nimport * as Y from \"yjs\";\n\nimport { agentNativePath } from \"../client/api-path.js\";\nimport { subscribeSyncEvents, type SyncEvent } from \"../client/use-db-sync.js\";\nimport { REALTIME_CAP_NO_AWARENESS } from \"../realtime-protocol.js\";\nexport {\n dedupeCollabUsersByEmail,\n emailToColor,\n emailToName,\n isReconcileLeadClient,\n type CollabUser,\n} from \"@agent-native/toolkit/collab-ui\";\n\nexport interface UseCollaborativeDocOptions {\n /** Document ID to collaborate on. Pass null to disable. */\n docId: string | null;\n /** Poll interval in ms when SSE is unavailable. Default: 2000 */\n pollInterval?: number;\n /** Poll interval in ms while SSE is healthy. Default: 12000 */\n pollIntervalWithSse?: number;\n /** Pause remote update/presence polling while the tab is hidden. Default: true */\n pauseWhenHidden?: boolean;\n /** Base URL for collab endpoints. Default: \"/_agent-native/collab\" */\n baseUrl?: string;\n /** Request source ID for jitter prevention (e.g., tab ID). */\n requestSource?: string;\n /** Current user info for cursor labels. */\n user?: CollabUser;\n}\n\nexport interface UseCollaborativeDocResult {\n /** The Yjs document instance. Stable per docId — never changes identity. */\n ydoc: Y.Doc | null;\n /** Yjs Awareness instance for cursor/presence sync. */\n awareness: Awareness | null;\n /** Whether the initial state is still loading from the server. */\n isLoading: boolean;\n /** Whether the doc is synced with the server. */\n isSynced: boolean;\n /** Active users on this document (from awareness). */\n activeUsers: CollabUser[];\n /** True briefly when the AI agent makes an edit (for presence indicator). */\n agentActive: boolean;\n /** True when the AI agent has an active awareness entry (durable presence). */\n agentPresent: boolean;\n}\n\nfunction isDocumentHidden(): boolean {\n return (\n typeof document !== \"undefined\" && document.visibilityState === \"hidden\"\n );\n}\n\n/**\n * Content equality for deduped active-user lists. `dedupeCollabUsersByEmail`\n * always allocates a fresh array (and fresh per-user objects), so callers\n * that only want to know \"did the actual user set change\" need this instead\n * of an identity check. Order-sensitive: the dedupe helper iterates awareness\n * states in a stable Map insertion order, so a reordering here does reflect\n * a real change (a client joined/left and re-joined).\n */\nfunction collabUsersEqual(a: CollabUser[], b: CollabUser[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const left = a[i]!;\n const right = b[i]!;\n if (\n left.email !== right.email ||\n left.name !== right.name ||\n left.color !== right.color\n ) {\n return false;\n }\n }\n return true;\n}\n\nexport interface RemoteAwarenessSnapshot {\n clientId: number;\n state: unknown;\n}\n\nexport function reconcileRemoteAwarenessStates(\n states: Map<number, unknown>,\n localClientId: number,\n remoteStates: RemoteAwarenessSnapshot[],\n): { added: number[]; updated: number[]; removed: number[] } {\n const incoming = new Set<number>();\n const added: number[] = [];\n const updated: number[] = [];\n const removed: number[] = [];\n\n for (const remote of remoteStates) {\n if (\n !Number.isFinite(remote.clientId) ||\n remote.clientId === localClientId\n ) {\n continue;\n }\n incoming.add(remote.clientId);\n const hadState = states.has(remote.clientId);\n states.set(remote.clientId, remote.state);\n (hadState ? updated : added).push(remote.clientId);\n }\n\n for (const clientId of Array.from(states.keys())) {\n if (clientId === localClientId) continue;\n if (incoming.has(clientId)) continue;\n states.delete(clientId);\n removed.push(clientId);\n }\n\n return { added, updated, removed };\n}\n\n// Base64 helpers\nfunction uint8ArrayToBase64(arr: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < arr.length; i++) {\n binary += String.fromCharCode(arr[i]);\n }\n return btoa(binary);\n}\n\nfunction base64ToUint8Array(b64: string): Uint8Array {\n const binary = atob(b64);\n const arr = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n arr[i] = binary.charCodeAt(i);\n }\n return arr;\n}\n\n/** Debounce delay for coalescing local Yjs update POSTs (ms). */\nconst UPDATE_DEBOUNCE_MS = 80;\n\n/** Fetch state-vector every N poll cycles as a low-frequency safety net. */\nconst STATE_VECTOR_FETCH_INTERVAL = 15;\n\n/** Poll ring-buffer size on the server (MAX_BUFFER in poll.ts). */\nconst POLL_RING_BUFFER_SIZE = 200;\n\n/** Exponential backoff: base delay (ms), multiplier, cap (ms). */\nconst BACKOFF_BASE_MS = 500;\nconst BACKOFF_MAX_MS = 15_000;\n\nfunction calcBackoff(consecutiveErrors: number): number {\n const exp = Math.min(consecutiveErrors, 10);\n const delay = BACKOFF_BASE_MS * Math.pow(2, exp);\n // Add jitter: ±25%\n const jitter = delay * 0.25 * (Math.random() * 2 - 1);\n return Math.min(delay + jitter, BACKOFF_MAX_MS);\n}\n\n// ---------------------------------------------------------------------------\n// Fast awareness helper — throttled per (docId, ydocId) pair so multiple\n// setLocalStateField calls within a 150ms window are coalesced into one POST.\n// ---------------------------------------------------------------------------\n\nconst _awarenessThrottleTimers = new Map<\n string,\n ReturnType<typeof setTimeout>\n>();\n\nfunction scheduleAwarenessPush(\n baseUrl: string,\n docId: string,\n clientId: number,\n getState: () => Record<string, unknown> | null,\n): void {\n if (typeof window === \"undefined\") return;\n const key = `${docId}::${clientId}`;\n if (_awarenessThrottleTimers.has(key)) return; // already scheduled\n\n const timer = setTimeout(() => {\n _awarenessThrottleTimers.delete(key);\n const state = getState();\n fetch(`${baseUrl}/${docId}/awareness`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n clientId,\n state: state ? JSON.stringify(state) : null,\n }),\n }).catch(() => {}); // best-effort; poll cycle is the baseline fallback\n }, 150);\n\n _awarenessThrottleTimers.set(key, timer);\n}\n\n// ---------------------------------------------------------------------------\n// Shared per-docId collab connection\n//\n// One CollabDocConnection per (baseUrl, docId) pair is held in a module-level\n// registry (the same pattern as SyncTransport in use-db-sync.ts). Every\n// `useCollaborativeDoc` mount for a docId subscribes to the shared connection,\n// so a tab runs exactly ONE state fetch, ONE poll fallback loop, and ONE\n// awareness POST cycle per document no matter how many components mount the\n// hook (e.g. a presence bar + the editor for the same doc).\n//\n// Lifecycle: the connection is created on first render that needs it (the\n// Y.Doc must exist during render so TipTap can bind on mount), starts its\n// network activity when the first subscriber attaches, and is disposed a short\n// linger after the last subscriber detaches. The linger keeps StrictMode's\n// mount→unmount→mount and rapid route remounts from destroying and refetching\n// the doc, and doubles as the cleanup path for connections created by a render\n// that React later discarded (no subscriber ever attaches).\n// ---------------------------------------------------------------------------\n\n/**\n * Shared reactive state each subscriber mirrors into its own React state.\n * Replaced immutably on every change so hooks can bail out on identity.\n */\ninterface CollabDocSnapshot {\n isLoading: boolean;\n isSynced: boolean;\n activeUsers: CollabUser[];\n agentActive: boolean;\n agentPresent: boolean;\n}\n\ninterface CollabDocSubscription {\n /** Requested poll interval; the connection uses the MIN across subscribers. */\n pollInterval: number;\n /** Requested relaxed interval while SSE is healthy (MIN across subscribers). */\n pollIntervalWithSse: number;\n /**\n * Whether this subscriber wants polling paused while the tab is hidden.\n * The connection pauses only when ALL subscribers request it.\n */\n pauseWhenHidden: boolean;\n /**\n * Echo-suppression tag. The connection adopts the first defined value and\n * uses it for BOTH tagging outgoing updates and filtering incoming echoes,\n * so suppression stays self-consistent even when subscribers pass different\n * per-tab IDs (all values identify the same tab).\n */\n requestSource?: string;\n onSnapshot: (snapshot: CollabDocSnapshot) => void;\n}\n\nconst EMPTY_SNAPSHOT: CollabDocSnapshot = Object.freeze({\n isLoading: false,\n isSynced: false,\n activeUsers: [],\n agentActive: false,\n agentPresent: false,\n});\n\n/**\n * How long a connection with zero subscribers lingers before disposal.\n * Long enough to absorb StrictMode double-mounts and route-level remounts\n * (which would otherwise destroy the Y.Doc, refetch server state, and lose\n * echo-suppression context), short enough that navigating away stops the\n * doc's traffic promptly.\n */\nconst DISPOSE_LINGER_MS = 1000;\n\nclass CollabDocConnection {\n readonly ydoc: Y.Doc;\n readonly awareness: Awareness;\n /** Immutable snapshot of the shared reactive state (replaced on change). */\n snapshot: CollabDocSnapshot;\n disposed = false;\n\n private subscribers = new Map<symbol, CollabDocSubscription>();\n private disposeTimer: ReturnType<typeof setTimeout> | null = null;\n private started = false;\n private docMissing = false;\n private requestSource: string | undefined;\n private lastSetUser: CollabUser | null = null;\n\n // Local-update batching (debounced + coalesced with Y.mergeUpdates).\n private pendingUpdates: Uint8Array[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private updateHandlerAttached = false;\n\n // Poll loop + SSE fast path.\n private syncActive = false;\n private pollTimer: ReturnType<typeof setTimeout> | null = null;\n private consecutiveErrors = 0;\n private pollCycleCount = 0;\n private pollVersion = 0;\n private lastPolledVersion = 0;\n private sseActive = false;\n // Whether the active SSE stream actually forwards awareness. The hosted\n // Realtime Gateway advertises `no-awareness` (it can't see the in-process\n // awareness emitter), so on that transport we must NOT relax the presence\n // poll cadence — otherwise remote cursors go stale. In-process SSE forwards\n // awareness and sends no handshake, so this stays true there.\n private sseAwarenessCovered = false;\n private sseSubscribedWithPause: boolean | null = null;\n private unsubscribeCollabEvents: (() => void) | null = null;\n private unsubscribeAwarenessEvents: (() => void) | null = null;\n private agentTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(\n readonly docId: string,\n private readonly baseUrl: string,\n /**\n * Detached connections are created for SSR renders only: a per-hook\n * Y.Doc/Awareness with no registry entry and no network activity\n * (matching the previous per-hook behavior on the server). They are\n * never started and are reclaimed by GC with the render.\n */\n readonly detached = false,\n ) {\n this.ydoc = new Y.Doc();\n this.awareness = new Awareness(this.ydoc);\n this.snapshot = {\n isLoading: true,\n isSynced: false,\n activeUsers: [],\n agentActive: false,\n agentPresent: false,\n };\n\n // Track active users / agent presence from awareness changes, and drive\n // the fast (throttled) awareness push once a local user is published.\n this.awareness.on(\"change\", this.handleAwarenessChange);\n\n // Orphan guard: the connection is created during render (the Y.Doc must\n // exist before mount), so a discarded render can create one that never\n // gets a subscriber. The linger timer disposes it; the first `add()`\n // cancels the timer.\n if (!detached) this.scheduleDispose();\n }\n\n private get registryKey(): string {\n return collabRegistryKey(this.docId, this.baseUrl);\n }\n\n // -------------------------------------------------------------------------\n // Subscriber management (ref-counting)\n // -------------------------------------------------------------------------\n\n add(id: symbol, sub: CollabDocSubscription): void {\n this.subscribers.set(id, sub);\n if (this.disposeTimer) {\n clearTimeout(this.disposeTimer);\n this.disposeTimer = null;\n }\n // Adopt the first defined echo-suppression tag for the connection's\n // lifetime (see CollabDocSubscription.requestSource).\n if (!this.requestSource && sub.requestSource) {\n this.requestSource = sub.requestSource;\n }\n if (!this.started) {\n this.started = true;\n this.start();\n } else {\n // A joining subscriber can change the effective poll cadence or the\n // pause-when-hidden aggregate; pick both up without waiting a cycle.\n this.resubscribeCollabEventsIfPauseChanged();\n this.reschedulePoll();\n }\n }\n\n remove(id: symbol): void {\n this.subscribers.delete(id);\n if (this.subscribers.size === 0) {\n this.scheduleDispose();\n } else {\n this.resubscribeCollabEventsIfPauseChanged();\n this.reschedulePoll();\n }\n }\n\n private scheduleDispose(): void {\n if (this.disposeTimer) clearTimeout(this.disposeTimer);\n this.disposeTimer = setTimeout(() => {\n this.disposeTimer = null;\n this.dispose();\n }, DISPOSE_LINGER_MS);\n }\n\n /**\n * Tear the connection down: stop all loops and listeners, flush any pending\n * local updates, clear awareness local state (via destroy), and destroy the\n * Y.Doc. Also used by the test-only registry reset. @internal\n */\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n if (this.disposeTimer) {\n clearTimeout(this.disposeTimer);\n this.disposeTimer = null;\n }\n this.stopSync();\n this.unsubscribeAwarenessEvents?.();\n this.unsubscribeAwarenessEvents = null;\n this.flushPendingUpdates(true);\n this.detachUpdateHandler();\n if (this.agentTimer) {\n clearTimeout(this.agentTimer);\n this.agentTimer = null;\n }\n // Detach our change listener BEFORE destroy so the destroy-time\n // `setLocalState(null)` does not schedule a push (matches the previous\n // per-hook effect cleanup ordering).\n this.awareness.off(\"change\", this.handleAwarenessChange);\n this.awareness.destroy();\n this.ydoc.destroy();\n if (collabConnectionRegistry.get(this.registryKey) === this) {\n collabConnectionRegistry.delete(this.registryKey);\n }\n }\n\n // -------------------------------------------------------------------------\n // Derived settings (aggregate over active subscribers)\n // -------------------------------------------------------------------------\n\n private get effectivePollInterval(): number {\n let min = Infinity;\n for (const sub of this.subscribers.values()) {\n if (sub.pollInterval < min) min = sub.pollInterval;\n }\n return isFinite(min) ? min : 2000;\n }\n\n private get effectivePollIntervalWithSse(): number {\n let min = Infinity;\n for (const sub of this.subscribers.values()) {\n if (sub.pollIntervalWithSse < min) min = sub.pollIntervalWithSse;\n }\n return isFinite(min) ? min : 12_000;\n }\n\n private get effectivePauseWhenHidden(): boolean {\n // Pause only if every subscriber has opted in.\n for (const sub of this.subscribers.values()) {\n if (!sub.pauseWhenHidden) return false;\n }\n return true;\n }\n\n // -------------------------------------------------------------------------\n // Shared state fan-out\n // -------------------------------------------------------------------------\n\n private setSnapshot(patch: Partial<CollabDocSnapshot>): void {\n this.snapshot = { ...this.snapshot, ...patch };\n for (const sub of this.subscribers.values()) {\n sub.onSnapshot(this.snapshot);\n }\n }\n\n private markAgentActive(): void {\n this.setSnapshot({ agentActive: true });\n if (this.agentTimer) clearTimeout(this.agentTimer);\n this.agentTimer = setTimeout(() => {\n this.agentTimer = null;\n this.setSnapshot({ agentActive: false });\n }, 3000);\n }\n\n // -------------------------------------------------------------------------\n // Awareness: local identity, active-user tracking, fast push\n // -------------------------------------------------------------------------\n\n /**\n * Publish the local user identity (cursor label) and current visibility.\n * Set once per tab — repeated calls with the same identity are no-ops so\n * multiple subscribers for the same user don't re-emit awareness updates.\n */\n setUser(user: CollabUser): void {\n if (this.disposed) return;\n const prev = this.lastSetUser;\n if (\n prev &&\n prev.name === user.name &&\n prev.email === user.email &&\n prev.color === user.color\n ) {\n return;\n }\n this.lastSetUser = {\n name: user.name,\n email: user.email,\n color: user.color,\n };\n this.awareness.setLocalStateField(\"user\", {\n name: user.name,\n email: user.email,\n color: user.color,\n });\n // Also publish this tab's visibility so peers can elect a VISIBLE client\n // to apply external snapshots (see isReconcileLeadClient) — a backgrounded\n // tab pauses its poll and must not hold that role.\n this.awareness.setLocalStateField(\"visible\", !isDocumentHidden());\n }\n\n private handleAwarenessChange = (\n _changes?: { added: number[]; updated: number[]; removed: number[] },\n origin?: unknown,\n ): void => {\n const users: CollabUser[] = [];\n let hasAgent = false;\n this.awareness.getStates().forEach((state, clientId) => {\n if (clientId === this.ydoc.clientID) return; // Skip self\n if (state.user) {\n users.push(state.user as CollabUser);\n if ((state.user as CollabUser).email === \"agent@system\") {\n hasAgent = true;\n }\n }\n });\n const nextActiveUsers = dedupeCollabUsersByEmail(users);\n // Awareness \"change\" fires for every remote broadcast — including cursor\n // jiggles, re-published-but-unchanged heartbeat state, and edits to\n // presence fields (recentEdits, selection) that don't affect who's\n // active. dedupeCollabUsersByEmail always returns a fresh array, so\n // without this comparison every one of those events would hand\n // `activeUsers` a new identity and force every consumer (e.g. a\n // full-page editor keying a useMemo/effect off it) to re-render even\n // though the actual user list is unchanged. Reuse the previous\n // reference when the deduped content is the same, matching the\n // stable-ref discipline `usePresence`'s shallowEqualOthers already\n // applies to `others`.\n const activeUsers = collabUsersEqual(\n this.snapshot.activeUsers,\n nextActiveUsers,\n )\n ? this.snapshot.activeUsers\n : nextActiveUsers;\n if (\n activeUsers !== this.snapshot.activeUsers ||\n hasAgent !== this.snapshot.agentPresent\n ) {\n this.setSnapshot({ activeUsers, agentPresent: hasAgent });\n }\n\n // Fast awareness push: whenever OUR OWN awareness state changes (e.g.\n // cursor moves, setPresence() calls), schedule a throttled POST so peers\n // receive updates at ~150ms instead of waiting for the next poll cycle.\n // Gated on origin === \"local\": this listener also fires for remote\n // awareness changes (poll/SSE call `awareness.emit(\"change\", [changes,\n // \"remote\"])` after reconciling incoming states — see\n // applyAwarenessEvent/poll above). Without the origin check, every\n // peer's cursor move would also re-trigger THIS client to re-broadcast\n // its own unchanged state, turning one person moving their mouse into\n // O(n) redundant POSTs from every other connected client (an awareness\n // storm that gets worse as more people join the doc). Only active once a\n // local user identity has been published (matches the previous per-hook\n // gating on `user`). The poll cycle remains the authoritative baseline.\n if (this.lastSetUser && origin === \"local\" && !this.disposed) {\n scheduleAwarenessPush(\n this.baseUrl,\n this.docId,\n this.ydoc.clientID,\n () => this.awareness.getLocalState() as Record<string, unknown> | null,\n );\n }\n };\n\n // -------------------------------------------------------------------------\n // Startup: initial state fetch, update handler, sync loops\n // -------------------------------------------------------------------------\n\n private start(): void {\n this.attachUpdateHandler();\n this.fetchInitialState();\n this.startSync();\n\n // SSE fast-path for awareness: listen on the SHARED framework transport\n // and apply awareness-change events immediately so peers receive cursor\n // moves push-style without waiting for the next poll cycle. Kept alive\n // even when the doc is missing (matches the previous per-hook behavior).\n this.unsubscribeAwarenessEvents = subscribeSyncEvents({\n onEvents: (events) => {\n if (this.disposed) return;\n for (const data of events) this.applyAwarenessEvent(data);\n },\n });\n }\n\n private fetchInitialState(): void {\n fetch(`${this.baseUrl}/${this.docId}/state`)\n .then(async (res) => {\n if (this.disposed) return;\n if (res.status === 404 || res.status === 403) {\n this.markDocMissing();\n return;\n }\n const data = (await res.json().catch(() => null)) as {\n state?: string;\n } | null;\n if (this.disposed) return;\n if (data?.state) {\n const binary = base64ToUint8Array(data.state);\n if (binary.length > 4) {\n Y.applyUpdate(this.ydoc, binary, \"remote\");\n }\n }\n this.setSnapshot({ isLoading: false, isSynced: true });\n })\n .catch(() => {\n if (this.disposed) return;\n this.setSnapshot({ isLoading: false, isSynced: true });\n });\n }\n\n /**\n * The initial state fetch returned 404/403 — the doc doesn't exist or isn't\n * accessible. Stop doc-update traffic (poll loop, update POSTs, collab SSE\n * handling) so we don't spam the console with errors against it. The\n * awareness SSE subscription stays (matches previous behavior).\n */\n private markDocMissing(): void {\n this.docMissing = true;\n this.flushPendingUpdates(true);\n this.detachUpdateHandler();\n this.stopSync();\n this.setSnapshot({ isLoading: false, isSynced: true });\n }\n\n // -------------------------------------------------------------------------\n // Local update batching\n // -------------------------------------------------------------------------\n\n private handleDocUpdate = (update: Uint8Array, origin: unknown): void => {\n if (origin === \"remote\") return;\n this.pendingUpdates.push(update);\n if (this.flushTimer) clearTimeout(this.flushTimer);\n this.flushTimer = setTimeout(\n () => this.flushPendingUpdates(),\n UPDATE_DEBOUNCE_MS,\n );\n };\n\n private handlePageHide = (): void => {\n this.flushPendingUpdates(true /* keepalive */);\n };\n\n private attachUpdateHandler(): void {\n if (this.updateHandlerAttached || this.docMissing) return;\n this.updateHandlerAttached = true;\n this.ydoc.on(\"update\", this.handleDocUpdate);\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"pagehide\", this.handlePageHide);\n }\n }\n\n private detachUpdateHandler(): void {\n if (!this.updateHandlerAttached) return;\n this.updateHandlerAttached = false;\n this.ydoc.off(\"update\", this.handleDocUpdate);\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"pagehide\", this.handlePageHide);\n }\n }\n\n private flushPendingUpdates(keepalive = false): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n if (this.pendingUpdates.length === 0) return;\n const toSend = this.pendingUpdates;\n this.pendingUpdates = [];\n\n const merged = toSend.length === 1 ? toSend[0] : Y.mergeUpdates(toSend);\n fetch(`${this.baseUrl}/${this.docId}/update`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n update: uint8ArrayToBase64(merged),\n requestSource: this.requestSource,\n }),\n ...(keepalive ? { keepalive: true } : {}),\n }).catch(() => {});\n }\n\n // -------------------------------------------------------------------------\n // Remote sync: SSE fast path + poll fallback loop\n // -------------------------------------------------------------------------\n\n private startSync(): void {\n if (this.syncActive || this.docMissing || this.disposed) return;\n this.syncActive = true;\n\n this.subscribeCollabEvents();\n\n if (!this.effectivePauseWhenHidden || !isDocumentHidden()) {\n void this.poll();\n }\n window.addEventListener(\"focus\", this.handleFocus);\n document.addEventListener(\"visibilitychange\", this.handleVisibilityChange);\n }\n\n private stopSync(): void {\n if (!this.syncActive) return;\n this.syncActive = false;\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n this.unsubscribeCollabEvents?.();\n this.unsubscribeCollabEvents = null;\n this.sseSubscribedWithPause = null;\n window.removeEventListener(\"focus\", this.handleFocus);\n document.removeEventListener(\n \"visibilitychange\",\n this.handleVisibilityChange,\n );\n }\n\n /**\n * SSE fast-path: subscribe to the SHARED framework transport for\n * /_agent-native/events instead of opening a dedicated EventSource per\n * collab doc. A tab holds exactly one SSE connection regardless of how many\n * docs are mounted. Collab update events arrive push-style; we apply them\n * immediately, avoiding ~2s polling latency for peer edits.\n *\n * NOTE: SSE events are subject to the same server-side access scoping as\n * polling — the server only pushes events that canSeeChangeForUser allows.\n */\n private subscribeCollabEvents(): void {\n const pauseWhenHidden = this.effectivePauseWhenHidden;\n this.sseSubscribedWithPause = pauseWhenHidden;\n this.unsubscribeCollabEvents = subscribeSyncEvents({\n onEvents: (events) => {\n if (this.disposed || !this.syncActive) return;\n for (const change of events) this.handleSharedEvent(change);\n },\n onSseStateChange: (connected, capabilities) => {\n const wasActive = this.sseActive;\n this.sseActive = connected;\n // Only treat SSE as covering awareness when it's connected AND does not\n // advertise `no-awareness` (the hosted gateway does). Drives whether we\n // relax the presence poll — see getActivePollInterval.\n const awarenessCovered =\n connected && !capabilities?.includes(REALTIME_CAP_NO_AWARENESS);\n const coverageFlipped = awarenessCovered !== this.sseAwarenessCovered;\n this.sseAwarenessCovered = awarenessCovered;\n // The gateway handshake lands AFTER onopen, so a relaxed poll timer\n // scheduled at connect can already be pending when `no-awareness`\n // arrives. Reschedule only for that mid-connection capability flip so\n // the fast presence cadence applies immediately; connect/disconnect\n // transitions keep the pre-existing next-natural-tick behavior.\n if (coverageFlipped && connected === wasActive) this.reschedulePoll();\n if (connected) this.consecutiveErrors = 0;\n },\n pauseWhenHidden,\n });\n }\n\n /**\n * The pause-when-hidden aggregate can flip when subscribers join or leave;\n * the shared-transport subscription captures it at subscribe time, so\n * re-subscribe when it changes.\n */\n private resubscribeCollabEventsIfPauseChanged(): void {\n if (!this.syncActive) return;\n if (this.sseSubscribedWithPause === this.effectivePauseWhenHidden) return;\n this.unsubscribeCollabEvents?.();\n this.subscribeCollabEvents();\n }\n\n private handleSharedEvent(change: SyncEvent): void {\n if (\n change.source === \"collab\" &&\n change.docId === this.docId &&\n typeof change.update === \"string\"\n ) {\n // Own echo — skip entirely (including the version tracking below, so\n // the next poll re-delivers and dedupe happens there; matches the\n // previous per-hook behavior).\n if (this.requestSource && change.requestSource === this.requestSource) {\n return;\n }\n try {\n Y.applyUpdate(this.ydoc, base64ToUint8Array(change.update), \"remote\");\n } catch {\n // Malformed update — trigger state-vector fetch on next poll\n }\n\n if (change.requestSource === \"agent\") {\n this.markAgentActive();\n }\n }\n\n // Keep the poll cursor updated from shared-transport events so the poll\n // loop starts from the right version when SSE drops.\n if (typeof change.version === \"number\") {\n this.pollVersion = Math.max(this.pollVersion, change.version);\n }\n }\n\n private getActivePollInterval(): number {\n // Relax to the slow cadence only when SSE is genuinely carrying awareness;\n // on a `no-awareness` hosted stream keep the fast cadence so presence/\n // cursor state doesn't go stale (the gateway doesn't forward awareness).\n return this.sseActive && this.sseAwarenessCovered\n ? this.effectivePollIntervalWithSse\n : this.effectivePollInterval;\n }\n\n private schedulePoll(): void {\n if (!this.syncActive || this.disposed) return;\n if (this.effectivePauseWhenHidden && isDocumentHidden()) return;\n this.pollTimer = setTimeout(() => {\n this.pollTimer = null;\n void this.poll();\n }, this.getActivePollInterval());\n }\n\n /**\n * A subscriber joined or left, potentially changing the effective interval.\n * If a poll is already scheduled, reschedule with the new cadence (the next\n * natural tick would pick it up anyway; this just avoids a stale long wait\n * when a faster subscriber joins).\n */\n private reschedulePoll(): void {\n if (this.pollTimer === null) return;\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n this.schedulePoll();\n }\n\n private async fetchStateVector(): Promise<void> {\n try {\n const stateVector = uint8ArrayToBase64(Y.encodeStateVector(this.ydoc));\n const stateRes = await fetch(\n `${this.baseUrl}/${this.docId}/state?stateVector=${encodeURIComponent(stateVector)}`,\n );\n if (stateRes.ok) {\n const stateData = (await stateRes.json().catch(() => null)) as {\n state?: string;\n } | null;\n if (this.disposed) return;\n if (stateData?.state) {\n const binary = base64ToUint8Array(stateData.state);\n if (binary.length > 2) {\n Y.applyUpdate(this.ydoc, binary, \"remote\");\n }\n }\n }\n } catch {\n // Non-fatal; the next poll cycle will retry\n }\n }\n\n private async poll(): Promise<void> {\n if (!this.syncActive || this.disposed) return;\n\n // Flush any pending local updates before polling so the server has the\n // latest state before we read remote changes.\n this.flushPendingUpdates();\n\n try {\n const res = await fetch(\n agentNativePath(`/_agent-native/poll?since=${this.pollVersion}`),\n );\n if (!res.ok) throw new Error(\"HTTP \" + res.status);\n\n const data = await res.json();\n if (!this.syncActive || this.disposed) return;\n const { version, events } = data as {\n version: number;\n events: Array<{\n source: string;\n docId?: string;\n update?: string;\n requestSource?: string;\n }>;\n };\n\n // Detect ring-buffer overflow: if the version jumped by more than the\n // ring buffer size, some events were evicted and we need a state-vector\n // fetch to reconcile the gap.\n const versionGap = version - this.lastPolledVersion;\n const hadGap = versionGap > POLL_RING_BUFFER_SIZE;\n\n for (const evt of events) {\n if (evt.source === \"collab\" && evt.docId === this.docId && evt.update) {\n if (this.requestSource && evt.requestSource === this.requestSource) {\n continue;\n }\n try {\n Y.applyUpdate(this.ydoc, base64ToUint8Array(evt.update), \"remote\");\n } catch {\n // Failed to apply — fetch full state-vector below\n await this.fetchStateVector();\n }\n\n if (evt.requestSource === \"agent\") {\n this.markAgentActive();\n }\n }\n }\n\n this.pollVersion = version;\n this.lastPolledVersion = version;\n this.pollCycleCount++;\n this.consecutiveErrors = 0;\n\n // Fetch state-vector only when needed:\n // 1. Ring-buffer overflow detected (missed events).\n // 2. Low-frequency safety net every STATE_VECTOR_FETCH_INTERVAL cycles.\n // 3. NOT on every cycle (the previous behavior causing 3 requests/cycle).\n const shouldFetchStateVector =\n hadGap || this.pollCycleCount % STATE_VECTOR_FETCH_INTERVAL === 0;\n\n if (shouldFetchStateVector) {\n await this.fetchStateVector();\n }\n\n // Sync awareness (cursor positions)\n const localState = this.awareness.getLocalState();\n if (localState && !this.disposed) {\n try {\n const awarenessRes = await fetch(\n `${this.baseUrl}/${this.docId}/awareness`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n clientId: this.ydoc.clientID,\n state: JSON.stringify(localState),\n }),\n },\n );\n if (awarenessRes.ok && !this.disposed) {\n const awarenessData = await awarenessRes.json();\n const remoteStates: RemoteAwarenessSnapshot[] = [];\n for (const remote of awarenessData.states || []) {\n try {\n const remoteState = JSON.parse(remote.state);\n remoteStates.push({\n clientId: Number(remote.clientId),\n state: remoteState,\n });\n } catch {\n // Invalid state — skip\n }\n }\n if (this.disposed) return;\n const changes = reconcileRemoteAwarenessStates(\n this.awareness.getStates() as Map<number, unknown>,\n this.ydoc.clientID,\n remoteStates,\n );\n if (\n changes.added.length ||\n changes.updated.length ||\n changes.removed.length\n ) {\n this.awareness.emit(\"change\", [changes, \"remote\"]);\n }\n }\n } catch {\n // Awareness sync failure is non-fatal\n }\n }\n } catch {\n // Network error — exponential backoff\n this.consecutiveErrors++;\n const backoff = calcBackoff(this.consecutiveErrors);\n if (this.syncActive && !this.disposed) {\n this.pollTimer = setTimeout(() => {\n this.pollTimer = null;\n void this.poll();\n }, backoff);\n }\n return;\n }\n\n this.schedulePoll();\n }\n\n private pollNow(): void {\n if (!this.syncActive || this.disposed) return;\n if (this.effectivePauseWhenHidden && isDocumentHidden()) return;\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n void this.poll();\n }\n\n /**\n * Publish this tab's visibility to peers. A hidden tab pauses its poll, so\n * we push the state immediately (keepalive) instead of waiting for the next\n * cycle — otherwise peers keep treating a backgrounded tab as the visible\n * lead and an agent edit never lands on the tab the user is actually viewing.\n */\n private publishVisibility(visible: boolean): void {\n this.awareness.setLocalStateField(\"visible\", visible);\n const localState = this.awareness.getLocalState();\n if (!localState) return;\n fetch(`${this.baseUrl}/${this.docId}/awareness`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n clientId: this.ydoc.clientID,\n state: JSON.stringify(localState),\n }),\n keepalive: true,\n }).catch(() => {});\n }\n\n private handleVisibilityChange = (): void => {\n const visible = document.visibilityState === \"visible\";\n this.publishVisibility(visible);\n if (visible) {\n // Also flush any pending updates when coming back into view\n this.flushPendingUpdates();\n this.pollNow();\n } else if (this.effectivePauseWhenHidden && this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n };\n\n private handleFocus = (): void => {\n this.pollNow();\n };\n\n // -------------------------------------------------------------------------\n // Awareness SSE fast-path\n // -------------------------------------------------------------------------\n\n private applyAwarenessEvent(data: SyncEvent): void {\n if (\n data.source !== \"awareness\" ||\n data.type !== \"awareness-change\" ||\n data.docId !== this.docId\n ) {\n return;\n }\n const states = Array.isArray(data.states)\n ? (data.states as Array<{ clientId: number; state: string }>)\n : [];\n const remoteStates: RemoteAwarenessSnapshot[] = [];\n for (const remote of states) {\n try {\n remoteStates.push({\n clientId: Number(remote.clientId),\n state: JSON.parse(remote.state),\n });\n } catch {\n // Invalid state entry — skip\n }\n }\n const changes = reconcileRemoteAwarenessStates(\n this.awareness.getStates() as Map<number, unknown>,\n this.ydoc.clientID,\n remoteStates,\n );\n if (\n changes.added.length ||\n changes.updated.length ||\n changes.removed.length\n ) {\n this.awareness.emit(\"change\", [changes, \"remote\"]);\n }\n }\n}\n\n/**\n * Registry of active connections keyed by \"<baseUrl>\\0<docId>\".\n * Module-level singleton: survives React render cycles, shared across all\n * hook instances in the same browser tab.\n */\nconst collabConnectionRegistry = new Map<string, CollabDocConnection>();\n\nfunction collabRegistryKey(docId: string, baseUrl: string): string {\n return `${baseUrl}\\0${docId}`;\n}\n\nfunction getOrCreateCollabConnection(\n docId: string,\n baseUrl: string,\n): CollabDocConnection {\n const key = collabRegistryKey(docId, baseUrl);\n let conn = collabConnectionRegistry.get(key);\n if (!conn || conn.disposed) {\n conn = new CollabDocConnection(docId, baseUrl);\n collabConnectionRegistry.set(key, conn);\n }\n return conn;\n}\n\n// ---------------------------------------------------------------------------\n// Internal test helpers — reset/inspect the connection registry between tests.\n// ---------------------------------------------------------------------------\n/** @internal */\nexport function _resetCollabDocRegistryForTests(): void {\n for (const conn of Array.from(collabConnectionRegistry.values())) {\n conn.dispose();\n }\n collabConnectionRegistry.clear();\n}\n\n/** @internal — current registry size, for leak assertions in tests. */\nexport function _collabDocRegistrySizeForTests(): number {\n return collabConnectionRegistry.size;\n}\n\nexport function useCollaborativeDoc(\n options: UseCollaborativeDocOptions,\n): UseCollaborativeDocResult {\n const {\n docId,\n pollInterval = 2000,\n pollIntervalWithSse = 12000,\n pauseWhenHidden = true,\n baseUrl = agentNativePath(\"/_agent-native/collab\"),\n requestSource,\n user,\n } = options;\n\n // Bumped when the effect finds the memoized connection was disposed in the\n // render→effect gap (rare: a suspended transition outliving the linger\n // window) so the memo below re-acquires a live one.\n const [generation, setGeneration] = useState(0);\n\n // Shared connection per docId. Acquired during render so the Y.Doc identity\n // is available on first render (TipTap binds on mount); get-or-create is\n // idempotent, so StrictMode's double render returns the same instance.\n const conn = useMemo(() => {\n void generation;\n if (!docId) return null;\n if (typeof window === \"undefined\") {\n // SSR render: per-hook detached doc, never started (matches the\n // previous per-hook behavior on the server).\n return new CollabDocConnection(docId, baseUrl, true);\n }\n return getOrCreateCollabConnection(docId, baseUrl);\n }, [docId, baseUrl, generation]);\n\n const [snapshot, setSnapshot] = useState<CollabDocSnapshot>(() =>\n conn ? conn.snapshot : EMPTY_SNAPSHOT,\n );\n\n // Render-time reset when the connection identity changes (docId switch) so\n // consumers never see the previous doc's state for a frame.\n const [prevConn, setPrevConn] = useState(conn);\n if (prevConn !== conn) {\n setPrevConn(conn);\n setSnapshot(conn ? conn.snapshot : EMPTY_SNAPSHOT);\n }\n\n // Subscribe (ref-count) — the first subscriber starts the connection, the\n // last one leaving schedules its teardown.\n useEffect(() => {\n if (!conn || conn.detached) return;\n if (conn.disposed) {\n // Disposed between render and effect — re-acquire a live connection.\n setGeneration((g) => g + 1);\n return;\n }\n const id = Symbol(\"useCollaborativeDoc\");\n conn.add(id, {\n pollInterval,\n pollIntervalWithSse,\n pauseWhenHidden,\n requestSource,\n onSnapshot: setSnapshot,\n });\n // Re-sync in case the connection changed state between render and effect.\n setSnapshot(conn.snapshot);\n return () => {\n conn.remove(id);\n };\n }, [conn, pollInterval, pollIntervalWithSse, pauseWhenHidden, requestSource]);\n\n // Publish local user identity for cursor labels (set once per tab; the\n // connection dedupes repeated identical identities across subscribers).\n useEffect(() => {\n if (!conn || conn.detached || !user) return;\n conn.setUser({ name: user.name, email: user.email, color: user.color });\n }, [conn, user?.name, user?.email, user?.color]);\n\n return {\n ydoc: conn ? conn.ydoc : null,\n awareness: conn ? conn.awareness : null,\n isLoading: snapshot.isLoading,\n isSynced: snapshot.isSynced,\n activeUsers: snapshot.activeUsers,\n agentActive: snapshot.agentActive,\n agentPresent: snapshot.agentPresent,\n };\n}\n"]}
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
26
26
  * Body: { update: string (base64), requestSource?: string }
27
27
  */
28
28
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
29
- error: string;
30
29
  ok?: undefined;
30
+ error: string;
31
31
  } | {
32
32
  error?: undefined;
33
33
  ok: boolean;
@@ -120,7 +120,7 @@ export declare const WORKSPACE_CONNECTION_PROVIDERS: readonly [{
120
120
  readonly required: true;
121
121
  }];
122
122
  readonly capabilities: readonly ["search", "import", "docs"];
123
- readonly recommendedTemplateUses: readonly ["brain", "content", "slides", "dispatch"];
123
+ readonly recommendedTemplateUses: readonly ["brain", "content", "slides", "dispatch", "analytics"];
124
124
  readonly oauth: {
125
125
  readonly provider: "google";
126
126
  readonly authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth";
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/connections/catalog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/connections/catalog.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,6BAA6B,GACrC,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,UAAU,GACV,KAAK,GACL,MAAM,GACN,MAAM,CAAC;AAEX,MAAM,MAAM,8BAA8B,GACtC,WAAW,GACX,OAAO,GACP,UAAU,GACV,OAAO,GACP,SAAS,GACT,KAAK,GACL,QAAQ,GACR,UAAU,GACV,OAAO,GACP,MAAM,GACN,QAAQ,CAAC;AAEb,MAAM,MAAM,6BAA6B,GACrC,OAAO,GACP,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,OAAO,GACP,cAAc,GACd,SAAS,GACT,YAAY,GACZ,MAAM,GACN,QAAQ,GACR,SAAS,GACT,OAAO,GACP,SAAS,CAAC;AAEd,MAAM,WAAW,gCAAgC;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,6BAA6B,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,SAAS,gCAAgC,EAAE,CAAC;IAC5D,YAAY,EAAE,SAAS,6BAA6B,EAAE,CAAC;IACvD,uBAAuB,EAAE,SAAS,8BAA8B,EAAE,CAAC;IACnE,KAAK,CAAC,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,gBAAgB,EAAE,MAAM,CAAC;QACzB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;KAC3B,CAAC;CACH;AAED,MAAM,WAAW,uCAAuC;IACtD,UAAU,CAAC,EAAE,6BAA6B,CAAC;IAC3C,WAAW,CAAC,EAAE,8BAA8B,CAAC;IAC7C,iBAAiB,CAAC,EAAE,SAAS,2BAA2B,EAAE,CAAC;CAC5D;AAED,wBAAgB,iCAAiC,CAC/C,KAAK,CAAC,CAAC,SAAS,2BAA2B,EAC3C,QAAQ,EAAE,CAAC,GAAG,CAAC,CAEhB;AAED,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkTgB,CAAC;AAO5D,wBAAgB,gCAAgC,CAC9C,OAAO,GAAE,uCAA4C,GACpD,2BAA2B,EAAE,CAwB/B;AAED,wBAAgB,iCAAiC,CAC/C,SAAS,GAAE,SAAS,2BAA2B,EAAO,GACrD,2BAA2B,EAAE,CAE/B;AAED,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,MAAM,EACV,SAAS,GAAE,SAAS,2BAA2B,EAAO,GACrD,2BAA2B,GAAG,SAAS,CAOzC;AAED,wBAAgB,+BAA+B,CAC7C,EAAE,EAAE,MAAM,GACT,EAAE,IAAI,6BAA6B,CAErC;AAED,wBAAgB,2CAA2C,CACzD,WAAW,EAAE,8BAA8B,EAC3C,iBAAiB,GAAE,SAAS,2BAA2B,EAAO,GAC7D,2BAA2B,EAAE,CAE/B;AAED,wBAAgB,6CAA6C,CAC3D,UAAU,EAAE,6BAA6B,EACzC,iBAAiB,GAAE,SAAS,2BAA2B,EAAO,GAC7D,2BAA2B,EAAE,CAE/B;AAED,wBAAgB,mCAAmC,CACjD,YAAY,EAAE,2BAA2B,GAAG,MAAM,EAClD,UAAU,EAAE,6BAA6B,GACxC,OAAO,CAMT"}
@@ -116,7 +116,13 @@ export const WORKSPACE_CONNECTION_PROVIDERS = [
116
116
  },
117
117
  ],
118
118
  capabilities: ["search", "import", "docs"],
119
- recommendedTemplateUses: ["brain", "content", "slides", "dispatch"],
119
+ recommendedTemplateUses: [
120
+ "brain",
121
+ "content",
122
+ "slides",
123
+ "dispatch",
124
+ "analytics",
125
+ ],
120
126
  oauth: {
121
127
  provider: "google",
122
128
  authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth",
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/connections/catalog.ts"],"names":[],"mappings":"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","sourcesContent":["export type WorkspaceConnectionCapability =\n | \"search\"\n | \"import\"\n | \"messages\"\n | \"meetings\"\n | \"crm\"\n | \"code\"\n | \"docs\";\n\nexport type WorkspaceConnectionTemplateUse =\n | \"analytics\"\n | \"brain\"\n | \"calendar\"\n | \"clips\"\n | \"content\"\n | \"crm\"\n | \"design\"\n | \"dispatch\"\n | \"forms\"\n | \"mail\"\n | \"slides\";\n\nexport type WorkspaceConnectionProviderId =\n | \"slack\"\n | \"github\"\n | \"figma\"\n | \"notion\"\n | \"gmail\"\n | \"google_drive\"\n | \"hubspot\"\n | \"salesforce\"\n | \"jira\"\n | \"sentry\"\n | \"granola\"\n | \"clips\"\n | \"generic\";\n\nexport interface WorkspaceConnectionCredentialKey {\n key: string;\n label: string;\n description?: string;\n required?: boolean;\n}\n\nexport interface WorkspaceConnectionProvider {\n id: WorkspaceConnectionProviderId;\n label: string;\n description: string;\n credentialKeys: readonly WorkspaceConnectionCredentialKey[];\n capabilities: readonly WorkspaceConnectionCapability[];\n recommendedTemplateUses: readonly WorkspaceConnectionTemplateUse[];\n oauth?: {\n provider: string;\n authorizationUrl: string;\n tokenUrl: string;\n refreshUrl?: string;\n scopes: readonly string[];\n };\n}\n\nexport interface ListWorkspaceConnectionProvidersOptions {\n capability?: WorkspaceConnectionCapability;\n templateUse?: WorkspaceConnectionTemplateUse;\n providerOverrides?: readonly WorkspaceConnectionProvider[];\n}\n\nexport function defineWorkspaceConnectionProvider<\n const T extends WorkspaceConnectionProvider,\n>(provider: T): T {\n return provider;\n}\n\nexport const WORKSPACE_CONNECTION_PROVIDERS = [\n defineWorkspaceConnectionProvider({\n id: \"slack\",\n label: \"Slack\",\n description:\n \"Workspace conversations and channel history for company memory, support workflows, and messaging automations.\",\n credentialKeys: [\n {\n key: \"SLACK_BOT_TOKEN\",\n label: \"Slack bot token (legacy)\",\n description:\n \"Legacy single-workspace fallback. For new messaging automations, connect Slack from Settings → Messaging instead.\",\n required: true,\n },\n ],\n capabilities: [\"search\", \"import\", \"messages\"],\n recommendedTemplateUses: [\"brain\", \"dispatch\", \"analytics\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"github\",\n label: \"GitHub\",\n description:\n \"Repository, issue, pull request, and code context for product memory, engineering workflows, and analytics.\",\n credentialKeys: [\n {\n key: \"GITHUB_TOKEN\",\n label: \"GitHub token (fallback)\",\n description:\n \"Optional fine-grained token fallback. OAuth is preferred for new connections.\",\n required: false,\n },\n ],\n oauth: {\n provider: \"github\",\n authorizationUrl: \"https://github.com/login/oauth/authorize\",\n tokenUrl: \"https://github.com/login/oauth/access_token\",\n scopes: [\"repo\", \"read:org\", \"read:user\", \"user:email\"],\n },\n capabilities: [\"search\", \"import\", \"code\", \"docs\"],\n recommendedTemplateUses: [\"brain\", \"analytics\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"figma\",\n label: \"Figma\",\n description:\n \"Design files, frames, components, rendered previews, and library context for creative workflows.\",\n credentialKeys: [\n {\n key: \"FIGMA_ACCESS_TOKEN\",\n label: \"Figma personal access token (fallback)\",\n description:\n \"Optional fallback for local or individual use. Workspace OAuth is preferred.\",\n required: false,\n },\n ],\n oauth: {\n provider: \"figma\",\n authorizationUrl: \"https://www.figma.com/oauth\",\n tokenUrl: \"https://api.figma.com/v1/oauth/token\",\n refreshUrl: \"https://api.figma.com/v1/oauth/token\",\n scopes: [\n \"current_user:read\",\n \"file_content:read\",\n \"file_metadata:read\",\n \"projects:read\",\n ],\n },\n capabilities: [\"search\", \"import\", \"docs\"],\n recommendedTemplateUses: [\"brain\", \"design\", \"slides\", \"content\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"notion\",\n label: \"Notion\",\n description:\n \"Workspace docs, wikis, pages, and databases for knowledge capture and search.\",\n credentialKeys: [],\n oauth: {\n provider: \"notion\",\n authorizationUrl: \"https://api.notion.com/v1/oauth/authorize\",\n tokenUrl: \"https://api.notion.com/v1/oauth/token\",\n refreshUrl: \"https://api.notion.com/v1/oauth/token\",\n scopes: [],\n },\n capabilities: [\"search\", \"import\", \"docs\"],\n recommendedTemplateUses: [\"brain\", \"content\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"gmail\",\n label: \"Gmail\",\n description:\n \"Mailbox messages and threads for search, triage, customer context, and agent replies.\",\n credentialKeys: [\n {\n key: \"GOOGLE_CLIENT_ID\",\n label: \"Google OAuth client ID\",\n required: true,\n },\n {\n key: \"GOOGLE_CLIENT_SECRET\",\n label: \"Google OAuth client secret\",\n required: true,\n },\n ],\n capabilities: [\"search\", \"import\", \"messages\"],\n recommendedTemplateUses: [\"mail\", \"brain\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"google_drive\",\n label: \"Google Drive\",\n description:\n \"Drive files, Docs, Sheets, and Slides for document search and import workflows.\",\n credentialKeys: [\n {\n key: \"GOOGLE_CLIENT_ID\",\n label: \"Google OAuth client ID\",\n required: true,\n },\n {\n key: \"GOOGLE_CLIENT_SECRET\",\n label: \"Google OAuth client secret\",\n required: true,\n },\n ],\n capabilities: [\"search\", \"import\", \"docs\"],\n recommendedTemplateUses: [\"brain\", \"content\", \"slides\", \"dispatch\"],\n oauth: {\n provider: \"google\",\n authorizationUrl: \"https://accounts.google.com/o/oauth2/v2/auth\",\n tokenUrl: \"https://oauth2.googleapis.com/token\",\n scopes: [\"https://www.googleapis.com/auth/drive.file\"],\n },\n }),\n defineWorkspaceConnectionProvider({\n id: \"hubspot\",\n label: \"HubSpot\",\n description:\n \"CRM records, companies, contacts, deals, and engagement history for customer-aware apps.\",\n credentialKeys: [\n {\n key: \"HUBSPOT_PRIVATE_APP_TOKEN\",\n label: \"HubSpot private app token (fallback)\",\n description:\n \"Optional private app token fallback. OAuth is preferred for new connections.\",\n required: false,\n },\n {\n key: \"HUBSPOT_ACCESS_TOKEN\",\n label: \"HubSpot access token (fallback)\",\n description:\n \"Optional legacy access token fallback for existing HubSpot setups.\",\n required: false,\n },\n ],\n oauth: {\n provider: \"hubspot\",\n authorizationUrl: \"https://app.hubspot.com/oauth/authorize\",\n tokenUrl: \"https://api.hubapi.com/oauth/v3/token\",\n refreshUrl: \"https://api.hubapi.com/oauth/v3/token\",\n scopes: [\n \"oauth\",\n \"crm.objects.contacts.read\",\n \"crm.objects.companies.read\",\n \"crm.objects.deals.read\",\n \"crm.objects.tickets.read\",\n \"crm.schemas.contacts.read\",\n \"crm.schemas.companies.read\",\n \"crm.schemas.deals.read\",\n \"crm.schemas.tickets.read\",\n ],\n },\n capabilities: [\"search\", \"import\", \"crm\"],\n recommendedTemplateUses: [\"analytics\", \"brain\", \"crm\", \"mail\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"salesforce\",\n label: \"Salesforce\",\n description:\n \"CRM accounts, contacts, opportunities, custom objects, and activity history for customer-aware apps.\",\n credentialKeys: [],\n oauth: {\n provider: \"salesforce\",\n authorizationUrl:\n \"https://login.salesforce.com/services/oauth2/authorize\",\n tokenUrl: \"https://login.salesforce.com/services/oauth2/token\",\n refreshUrl: \"https://login.salesforce.com/services/oauth2/token\",\n scopes: [\"api\", \"refresh_token\", \"id\"],\n },\n capabilities: [\"search\", \"import\", \"crm\"],\n recommendedTemplateUses: [\"analytics\", \"brain\", \"crm\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"jira\",\n label: \"Jira Cloud\",\n description:\n \"Projects, issues, sprints, and delivery context for engineering analytics and product workflows.\",\n credentialKeys: [\n {\n key: \"JIRA_BASE_URL\",\n label: \"Jira base URL (fallback)\",\n description:\n \"Optional site URL for API-token fallback connections. OAuth connections discover their site automatically.\",\n required: false,\n },\n {\n key: \"JIRA_USER_EMAIL\",\n label: \"Jira email (fallback)\",\n description:\n \"Optional Atlassian account email for API-token fallback connections.\",\n required: false,\n },\n {\n key: \"JIRA_API_TOKEN\",\n label: \"Jira API token (fallback)\",\n description:\n \"Optional API token fallback for existing Jira Cloud setups. OAuth is preferred for new connections.\",\n required: false,\n },\n ],\n oauth: {\n provider: \"jira\",\n authorizationUrl: \"https://auth.atlassian.com/authorize\",\n tokenUrl: \"https://auth.atlassian.com/oauth/token\",\n refreshUrl: \"https://auth.atlassian.com/oauth/token\",\n scopes: [\"read:jira-work\", \"read:jira-user\", \"offline_access\"],\n },\n capabilities: [\"search\", \"import\", \"code\", \"docs\"],\n recommendedTemplateUses: [\"analytics\", \"brain\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"sentry\",\n label: \"Sentry\",\n description:\n \"Error tracking, performance issues, projects, and release context for engineering analytics.\",\n credentialKeys: [\n {\n key: \"SENTRY_AUTH_TOKEN\",\n label: \"Sentry auth token (fallback)\",\n description:\n \"Optional auth token fallback for self-hosted or local Sentry setups. OAuth is preferred for sentry.io.\",\n required: false,\n },\n {\n key: \"SENTRY_SERVER_TOKEN\",\n label: \"Sentry server token (fallback)\",\n description:\n \"Optional server token fallback for existing Sentry deployments.\",\n required: false,\n },\n ],\n oauth: {\n provider: \"sentry\",\n authorizationUrl: \"https://sentry.io/oauth/authorize/\",\n tokenUrl: \"https://sentry.io/oauth/token/\",\n refreshUrl: \"https://sentry.io/oauth/token/\",\n scopes: [\"org:read\", \"project:read\", \"event:read\", \"team:read\"],\n },\n capabilities: [\"search\", \"import\", \"docs\"],\n recommendedTemplateUses: [\"analytics\", \"brain\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"granola\",\n label: \"Granola\",\n description:\n \"Meeting notes and transcripts for company memory and follow-up workflows.\",\n credentialKeys: [\n {\n key: \"GRANOLA_API_KEY\",\n label: \"Granola API key\",\n description:\n \"API key for accessible team notes; templates should respect Granola's workspace visibility.\",\n required: true,\n },\n ],\n capabilities: [\"search\", \"import\", \"meetings\", \"docs\"],\n recommendedTemplateUses: [\"brain\", \"calendar\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"clips\",\n label: \"Clips\",\n description:\n \"Agent-native Clips exports and recordings for transcript import and searchable meeting context.\",\n credentialKeys: [],\n capabilities: [\"search\", \"import\", \"meetings\"],\n recommendedTemplateUses: [\"brain\", \"clips\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"generic\",\n label: \"Generic\",\n description:\n \"Custom webhooks, CSV exports, transcript drops, and one-off sources that do not need a first-class provider yet.\",\n credentialKeys: [],\n capabilities: [\"search\", \"import\", \"docs\"],\n recommendedTemplateUses: [\n \"brain\",\n \"analytics\",\n \"content\",\n \"dispatch\",\n \"forms\",\n ],\n }),\n] as const satisfies readonly WorkspaceConnectionProvider[];\n\nconst PROVIDERS_BY_ID = new Map<\n WorkspaceConnectionProviderId,\n WorkspaceConnectionProvider\n>(WORKSPACE_CONNECTION_PROVIDERS.map((provider) => [provider.id, provider]));\n\nexport function listWorkspaceConnectionProviders(\n options: ListWorkspaceConnectionProvidersOptions = {},\n): WorkspaceConnectionProvider[] {\n return mergeWorkspaceConnectionProviders(options.providerOverrides)\n .filter((provider) => {\n if (\n options.capability &&\n !includesWorkspaceConnectionCapability(\n provider.capabilities,\n options.capability,\n )\n ) {\n return false;\n }\n if (\n options.templateUse &&\n !includesWorkspaceConnectionTemplateUse(\n provider.recommendedTemplateUses,\n options.templateUse,\n )\n ) {\n return false;\n }\n return true;\n })\n .map((provider) => ({ ...provider }));\n}\n\nexport function mergeWorkspaceConnectionProviders(\n overrides: readonly WorkspaceConnectionProvider[] = [],\n): WorkspaceConnectionProvider[] {\n return mergeDefinitionsById(WORKSPACE_CONNECTION_PROVIDERS, overrides);\n}\n\nexport function getWorkspaceConnectionProvider(\n id: string,\n overrides: readonly WorkspaceConnectionProvider[] = [],\n): WorkspaceConnectionProvider | undefined {\n const provider = overrides.length\n ? mergeWorkspaceConnectionProviders(overrides).find(\n (candidate) => candidate.id === id,\n )\n : PROVIDERS_BY_ID.get(id as WorkspaceConnectionProviderId);\n return provider ? { ...provider } : undefined;\n}\n\nexport function isWorkspaceConnectionProviderId(\n id: string,\n): id is WorkspaceConnectionProviderId {\n return PROVIDERS_BY_ID.has(id as WorkspaceConnectionProviderId);\n}\n\nexport function listWorkspaceConnectionProvidersForTemplate(\n templateUse: WorkspaceConnectionTemplateUse,\n providerOverrides: readonly WorkspaceConnectionProvider[] = [],\n): WorkspaceConnectionProvider[] {\n return listWorkspaceConnectionProviders({ templateUse, providerOverrides });\n}\n\nexport function listWorkspaceConnectionProvidersForCapability(\n capability: WorkspaceConnectionCapability,\n providerOverrides: readonly WorkspaceConnectionProvider[] = [],\n): WorkspaceConnectionProvider[] {\n return listWorkspaceConnectionProviders({ capability, providerOverrides });\n}\n\nexport function workspaceConnectionProviderSupports(\n providerOrId: WorkspaceConnectionProvider | string,\n capability: WorkspaceConnectionCapability,\n): boolean {\n const provider =\n typeof providerOrId === \"string\"\n ? getWorkspaceConnectionProvider(providerOrId)\n : providerOrId;\n return provider?.capabilities.includes(capability) ?? false;\n}\n\nfunction includesWorkspaceConnectionCapability(\n capabilities: readonly WorkspaceConnectionCapability[],\n capability: WorkspaceConnectionCapability,\n): boolean {\n return capabilities.includes(capability);\n}\n\nfunction includesWorkspaceConnectionTemplateUse(\n templateUses: readonly WorkspaceConnectionTemplateUse[],\n templateUse: WorkspaceConnectionTemplateUse,\n): boolean {\n return templateUses.includes(templateUse);\n}\nimport { mergeDefinitionsById } from \"../shared/merge-by-id.js\";\n"]}
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/connections/catalog.ts"],"names":[],"mappings":"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","sourcesContent":["export type WorkspaceConnectionCapability =\n | \"search\"\n | \"import\"\n | \"messages\"\n | \"meetings\"\n | \"crm\"\n | \"code\"\n | \"docs\";\n\nexport type WorkspaceConnectionTemplateUse =\n | \"analytics\"\n | \"brain\"\n | \"calendar\"\n | \"clips\"\n | \"content\"\n | \"crm\"\n | \"design\"\n | \"dispatch\"\n | \"forms\"\n | \"mail\"\n | \"slides\";\n\nexport type WorkspaceConnectionProviderId =\n | \"slack\"\n | \"github\"\n | \"figma\"\n | \"notion\"\n | \"gmail\"\n | \"google_drive\"\n | \"hubspot\"\n | \"salesforce\"\n | \"jira\"\n | \"sentry\"\n | \"granola\"\n | \"clips\"\n | \"generic\";\n\nexport interface WorkspaceConnectionCredentialKey {\n key: string;\n label: string;\n description?: string;\n required?: boolean;\n}\n\nexport interface WorkspaceConnectionProvider {\n id: WorkspaceConnectionProviderId;\n label: string;\n description: string;\n credentialKeys: readonly WorkspaceConnectionCredentialKey[];\n capabilities: readonly WorkspaceConnectionCapability[];\n recommendedTemplateUses: readonly WorkspaceConnectionTemplateUse[];\n oauth?: {\n provider: string;\n authorizationUrl: string;\n tokenUrl: string;\n refreshUrl?: string;\n scopes: readonly string[];\n };\n}\n\nexport interface ListWorkspaceConnectionProvidersOptions {\n capability?: WorkspaceConnectionCapability;\n templateUse?: WorkspaceConnectionTemplateUse;\n providerOverrides?: readonly WorkspaceConnectionProvider[];\n}\n\nexport function defineWorkspaceConnectionProvider<\n const T extends WorkspaceConnectionProvider,\n>(provider: T): T {\n return provider;\n}\n\nexport const WORKSPACE_CONNECTION_PROVIDERS = [\n defineWorkspaceConnectionProvider({\n id: \"slack\",\n label: \"Slack\",\n description:\n \"Workspace conversations and channel history for company memory, support workflows, and messaging automations.\",\n credentialKeys: [\n {\n key: \"SLACK_BOT_TOKEN\",\n label: \"Slack bot token (legacy)\",\n description:\n \"Legacy single-workspace fallback. For new messaging automations, connect Slack from Settings → Messaging instead.\",\n required: true,\n },\n ],\n capabilities: [\"search\", \"import\", \"messages\"],\n recommendedTemplateUses: [\"brain\", \"dispatch\", \"analytics\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"github\",\n label: \"GitHub\",\n description:\n \"Repository, issue, pull request, and code context for product memory, engineering workflows, and analytics.\",\n credentialKeys: [\n {\n key: \"GITHUB_TOKEN\",\n label: \"GitHub token (fallback)\",\n description:\n \"Optional fine-grained token fallback. OAuth is preferred for new connections.\",\n required: false,\n },\n ],\n oauth: {\n provider: \"github\",\n authorizationUrl: \"https://github.com/login/oauth/authorize\",\n tokenUrl: \"https://github.com/login/oauth/access_token\",\n scopes: [\"repo\", \"read:org\", \"read:user\", \"user:email\"],\n },\n capabilities: [\"search\", \"import\", \"code\", \"docs\"],\n recommendedTemplateUses: [\"brain\", \"analytics\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"figma\",\n label: \"Figma\",\n description:\n \"Design files, frames, components, rendered previews, and library context for creative workflows.\",\n credentialKeys: [\n {\n key: \"FIGMA_ACCESS_TOKEN\",\n label: \"Figma personal access token (fallback)\",\n description:\n \"Optional fallback for local or individual use. Workspace OAuth is preferred.\",\n required: false,\n },\n ],\n oauth: {\n provider: \"figma\",\n authorizationUrl: \"https://www.figma.com/oauth\",\n tokenUrl: \"https://api.figma.com/v1/oauth/token\",\n refreshUrl: \"https://api.figma.com/v1/oauth/token\",\n scopes: [\n \"current_user:read\",\n \"file_content:read\",\n \"file_metadata:read\",\n \"projects:read\",\n ],\n },\n capabilities: [\"search\", \"import\", \"docs\"],\n recommendedTemplateUses: [\"brain\", \"design\", \"slides\", \"content\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"notion\",\n label: \"Notion\",\n description:\n \"Workspace docs, wikis, pages, and databases for knowledge capture and search.\",\n credentialKeys: [],\n oauth: {\n provider: \"notion\",\n authorizationUrl: \"https://api.notion.com/v1/oauth/authorize\",\n tokenUrl: \"https://api.notion.com/v1/oauth/token\",\n refreshUrl: \"https://api.notion.com/v1/oauth/token\",\n scopes: [],\n },\n capabilities: [\"search\", \"import\", \"docs\"],\n recommendedTemplateUses: [\"brain\", \"content\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"gmail\",\n label: \"Gmail\",\n description:\n \"Mailbox messages and threads for search, triage, customer context, and agent replies.\",\n credentialKeys: [\n {\n key: \"GOOGLE_CLIENT_ID\",\n label: \"Google OAuth client ID\",\n required: true,\n },\n {\n key: \"GOOGLE_CLIENT_SECRET\",\n label: \"Google OAuth client secret\",\n required: true,\n },\n ],\n capabilities: [\"search\", \"import\", \"messages\"],\n recommendedTemplateUses: [\"mail\", \"brain\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"google_drive\",\n label: \"Google Drive\",\n description:\n \"Drive files, Docs, Sheets, and Slides for document search and import workflows.\",\n credentialKeys: [\n {\n key: \"GOOGLE_CLIENT_ID\",\n label: \"Google OAuth client ID\",\n required: true,\n },\n {\n key: \"GOOGLE_CLIENT_SECRET\",\n label: \"Google OAuth client secret\",\n required: true,\n },\n ],\n capabilities: [\"search\", \"import\", \"docs\"],\n recommendedTemplateUses: [\n \"brain\",\n \"content\",\n \"slides\",\n \"dispatch\",\n \"analytics\",\n ],\n oauth: {\n provider: \"google\",\n authorizationUrl: \"https://accounts.google.com/o/oauth2/v2/auth\",\n tokenUrl: \"https://oauth2.googleapis.com/token\",\n scopes: [\"https://www.googleapis.com/auth/drive.file\"],\n },\n }),\n defineWorkspaceConnectionProvider({\n id: \"hubspot\",\n label: \"HubSpot\",\n description:\n \"CRM records, companies, contacts, deals, and engagement history for customer-aware apps.\",\n credentialKeys: [\n {\n key: \"HUBSPOT_PRIVATE_APP_TOKEN\",\n label: \"HubSpot private app token (fallback)\",\n description:\n \"Optional private app token fallback. OAuth is preferred for new connections.\",\n required: false,\n },\n {\n key: \"HUBSPOT_ACCESS_TOKEN\",\n label: \"HubSpot access token (fallback)\",\n description:\n \"Optional legacy access token fallback for existing HubSpot setups.\",\n required: false,\n },\n ],\n oauth: {\n provider: \"hubspot\",\n authorizationUrl: \"https://app.hubspot.com/oauth/authorize\",\n tokenUrl: \"https://api.hubapi.com/oauth/v3/token\",\n refreshUrl: \"https://api.hubapi.com/oauth/v3/token\",\n scopes: [\n \"oauth\",\n \"crm.objects.contacts.read\",\n \"crm.objects.companies.read\",\n \"crm.objects.deals.read\",\n \"crm.objects.tickets.read\",\n \"crm.schemas.contacts.read\",\n \"crm.schemas.companies.read\",\n \"crm.schemas.deals.read\",\n \"crm.schemas.tickets.read\",\n ],\n },\n capabilities: [\"search\", \"import\", \"crm\"],\n recommendedTemplateUses: [\"analytics\", \"brain\", \"crm\", \"mail\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"salesforce\",\n label: \"Salesforce\",\n description:\n \"CRM accounts, contacts, opportunities, custom objects, and activity history for customer-aware apps.\",\n credentialKeys: [],\n oauth: {\n provider: \"salesforce\",\n authorizationUrl:\n \"https://login.salesforce.com/services/oauth2/authorize\",\n tokenUrl: \"https://login.salesforce.com/services/oauth2/token\",\n refreshUrl: \"https://login.salesforce.com/services/oauth2/token\",\n scopes: [\"api\", \"refresh_token\", \"id\"],\n },\n capabilities: [\"search\", \"import\", \"crm\"],\n recommendedTemplateUses: [\"analytics\", \"brain\", \"crm\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"jira\",\n label: \"Jira Cloud\",\n description:\n \"Projects, issues, sprints, and delivery context for engineering analytics and product workflows.\",\n credentialKeys: [\n {\n key: \"JIRA_BASE_URL\",\n label: \"Jira base URL (fallback)\",\n description:\n \"Optional site URL for API-token fallback connections. OAuth connections discover their site automatically.\",\n required: false,\n },\n {\n key: \"JIRA_USER_EMAIL\",\n label: \"Jira email (fallback)\",\n description:\n \"Optional Atlassian account email for API-token fallback connections.\",\n required: false,\n },\n {\n key: \"JIRA_API_TOKEN\",\n label: \"Jira API token (fallback)\",\n description:\n \"Optional API token fallback for existing Jira Cloud setups. OAuth is preferred for new connections.\",\n required: false,\n },\n ],\n oauth: {\n provider: \"jira\",\n authorizationUrl: \"https://auth.atlassian.com/authorize\",\n tokenUrl: \"https://auth.atlassian.com/oauth/token\",\n refreshUrl: \"https://auth.atlassian.com/oauth/token\",\n scopes: [\"read:jira-work\", \"read:jira-user\", \"offline_access\"],\n },\n capabilities: [\"search\", \"import\", \"code\", \"docs\"],\n recommendedTemplateUses: [\"analytics\", \"brain\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"sentry\",\n label: \"Sentry\",\n description:\n \"Error tracking, performance issues, projects, and release context for engineering analytics.\",\n credentialKeys: [\n {\n key: \"SENTRY_AUTH_TOKEN\",\n label: \"Sentry auth token (fallback)\",\n description:\n \"Optional auth token fallback for self-hosted or local Sentry setups. OAuth is preferred for sentry.io.\",\n required: false,\n },\n {\n key: \"SENTRY_SERVER_TOKEN\",\n label: \"Sentry server token (fallback)\",\n description:\n \"Optional server token fallback for existing Sentry deployments.\",\n required: false,\n },\n ],\n oauth: {\n provider: \"sentry\",\n authorizationUrl: \"https://sentry.io/oauth/authorize/\",\n tokenUrl: \"https://sentry.io/oauth/token/\",\n refreshUrl: \"https://sentry.io/oauth/token/\",\n scopes: [\"org:read\", \"project:read\", \"event:read\", \"team:read\"],\n },\n capabilities: [\"search\", \"import\", \"docs\"],\n recommendedTemplateUses: [\"analytics\", \"brain\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"granola\",\n label: \"Granola\",\n description:\n \"Meeting notes and transcripts for company memory and follow-up workflows.\",\n credentialKeys: [\n {\n key: \"GRANOLA_API_KEY\",\n label: \"Granola API key\",\n description:\n \"API key for accessible team notes; templates should respect Granola's workspace visibility.\",\n required: true,\n },\n ],\n capabilities: [\"search\", \"import\", \"meetings\", \"docs\"],\n recommendedTemplateUses: [\"brain\", \"calendar\", \"dispatch\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"clips\",\n label: \"Clips\",\n description:\n \"Agent-native Clips exports and recordings for transcript import and searchable meeting context.\",\n credentialKeys: [],\n capabilities: [\"search\", \"import\", \"meetings\"],\n recommendedTemplateUses: [\"brain\", \"clips\"],\n }),\n defineWorkspaceConnectionProvider({\n id: \"generic\",\n label: \"Generic\",\n description:\n \"Custom webhooks, CSV exports, transcript drops, and one-off sources that do not need a first-class provider yet.\",\n credentialKeys: [],\n capabilities: [\"search\", \"import\", \"docs\"],\n recommendedTemplateUses: [\n \"brain\",\n \"analytics\",\n \"content\",\n \"dispatch\",\n \"forms\",\n ],\n }),\n] as const satisfies readonly WorkspaceConnectionProvider[];\n\nconst PROVIDERS_BY_ID = new Map<\n WorkspaceConnectionProviderId,\n WorkspaceConnectionProvider\n>(WORKSPACE_CONNECTION_PROVIDERS.map((provider) => [provider.id, provider]));\n\nexport function listWorkspaceConnectionProviders(\n options: ListWorkspaceConnectionProvidersOptions = {},\n): WorkspaceConnectionProvider[] {\n return mergeWorkspaceConnectionProviders(options.providerOverrides)\n .filter((provider) => {\n if (\n options.capability &&\n !includesWorkspaceConnectionCapability(\n provider.capabilities,\n options.capability,\n )\n ) {\n return false;\n }\n if (\n options.templateUse &&\n !includesWorkspaceConnectionTemplateUse(\n provider.recommendedTemplateUses,\n options.templateUse,\n )\n ) {\n return false;\n }\n return true;\n })\n .map((provider) => ({ ...provider }));\n}\n\nexport function mergeWorkspaceConnectionProviders(\n overrides: readonly WorkspaceConnectionProvider[] = [],\n): WorkspaceConnectionProvider[] {\n return mergeDefinitionsById(WORKSPACE_CONNECTION_PROVIDERS, overrides);\n}\n\nexport function getWorkspaceConnectionProvider(\n id: string,\n overrides: readonly WorkspaceConnectionProvider[] = [],\n): WorkspaceConnectionProvider | undefined {\n const provider = overrides.length\n ? mergeWorkspaceConnectionProviders(overrides).find(\n (candidate) => candidate.id === id,\n )\n : PROVIDERS_BY_ID.get(id as WorkspaceConnectionProviderId);\n return provider ? { ...provider } : undefined;\n}\n\nexport function isWorkspaceConnectionProviderId(\n id: string,\n): id is WorkspaceConnectionProviderId {\n return PROVIDERS_BY_ID.has(id as WorkspaceConnectionProviderId);\n}\n\nexport function listWorkspaceConnectionProvidersForTemplate(\n templateUse: WorkspaceConnectionTemplateUse,\n providerOverrides: readonly WorkspaceConnectionProvider[] = [],\n): WorkspaceConnectionProvider[] {\n return listWorkspaceConnectionProviders({ templateUse, providerOverrides });\n}\n\nexport function listWorkspaceConnectionProvidersForCapability(\n capability: WorkspaceConnectionCapability,\n providerOverrides: readonly WorkspaceConnectionProvider[] = [],\n): WorkspaceConnectionProvider[] {\n return listWorkspaceConnectionProviders({ capability, providerOverrides });\n}\n\nexport function workspaceConnectionProviderSupports(\n providerOrId: WorkspaceConnectionProvider | string,\n capability: WorkspaceConnectionCapability,\n): boolean {\n const provider =\n typeof providerOrId === \"string\"\n ? getWorkspaceConnectionProvider(providerOrId)\n : providerOrId;\n return provider?.capabilities.includes(capability) ?? false;\n}\n\nfunction includesWorkspaceConnectionCapability(\n capabilities: readonly WorkspaceConnectionCapability[],\n capability: WorkspaceConnectionCapability,\n): boolean {\n return capabilities.includes(capability);\n}\n\nfunction includesWorkspaceConnectionTemplateUse(\n templateUses: readonly WorkspaceConnectionTemplateUse[],\n templateUse: WorkspaceConnectionTemplateUse,\n): boolean {\n return templateUses.includes(templateUse);\n}\nimport { mergeDefinitionsById } from \"../shared/merge-by-id.js\";\n"]}
@@ -39,7 +39,7 @@ import { type DbExec } from "./client.js";
39
39
  * This is a plain read (no lock), so it never blocks on an `ACCESS EXCLUSIVE`
40
40
  * lock the way `CREATE`/`ALTER` would.
41
41
  */
42
- export declare function pgTableExists(table: string, injectedClient?: DbExec): Promise<boolean>;
42
+ export declare function pgTableExists(table: string, injectedClient?: DbExec, dialectIsPostgres?: boolean): Promise<boolean>;
43
43
  /**
44
44
  * True when running against Postgres AND the given column already exists on the
45
45
  * given table in the `public` schema. Returns `false` on SQLite, for invalid
@@ -58,7 +58,7 @@ export declare function pgColumnExists(table: string, column: string, injectedCl
58
58
  * connection this can hang just like a `CREATE`/`ALTER` would; checking first
59
59
  * skips the lock on the already-migrated hot path.
60
60
  */
61
- export declare function pgIndexExists(indexName: string, injectedClient?: DbExec): Promise<boolean>;
61
+ export declare function pgIndexExists(indexName: string, injectedClient?: DbExec, dialectIsPostgres?: boolean): Promise<boolean>;
62
62
  /**
63
63
  * Probe → guarded-DDL → re-probe sequence for one piece of on-demand schema.
64
64
  *
@@ -96,6 +96,8 @@ export declare function ensureSchemaObject(options: {
96
96
  lockTimeout?: string;
97
97
  /** Injectable client for tests. */
98
98
  injectedClient?: DbExec;
99
+ /** Dialect override for injected per-app clients; defaults to the global. */
100
+ dialectIsPostgres?: boolean;
99
101
  }): Promise<boolean>;
100
102
  /**
101
103
  * Convenience wrapper: ensure a TABLE exists (probe via `pgTableExists`).
@@ -105,6 +107,7 @@ export declare function ensureSchemaObject(options: {
105
107
  export declare function ensureTableExists(table: string, createSql: string, options?: {
106
108
  lockTimeout?: string;
107
109
  injectedClient?: DbExec;
110
+ dialectIsPostgres?: boolean;
108
111
  }): Promise<boolean>;
109
112
  /**
110
113
  * Convenience wrapper: ensure a COLUMN exists (probe via `pgColumnExists`).
@@ -121,6 +124,7 @@ export declare function ensureColumnExists(table: string, column: string, addCol
121
124
  export declare function ensureIndexExists(indexName: string, createIndexSql: string, options?: {
122
125
  lockTimeout?: string;
123
126
  injectedClient?: DbExec;
127
+ dialectIsPostgres?: boolean;
124
128
  }): Promise<boolean>;
125
129
  /** True when an error looks like a Postgres `lock_timeout` (SQLSTATE 55P03). */
126
130
  export declare function isLockTimeoutError(err: unknown): boolean;
@@ -147,5 +151,6 @@ export declare function isLockTimeoutError(err: unknown): boolean;
147
151
  export declare function runGuardedDdl(ddl: string, options?: {
148
152
  lockTimeout?: string;
149
153
  injectedClient?: DbExec;
154
+ dialectIsPostgres?: boolean;
150
155
  }): Promise<boolean>;
151
156
  //# sourceMappingURL=ddl-guard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ddl-guard.d.ts","sourceRoot":"","sources":["../../src/db/ddl-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAyB,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAIjE;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CAelB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CAiBlB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CAalB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE;IAChD,qEAAqE;IACrE,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBnB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9D,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9D,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9D,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAKxD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9D,OAAO,CAAC,OAAO,CAAC,CAmClB"}
1
+ {"version":3,"file":"ddl-guard.d.ts","sourceRoot":"","sources":["../../src/db/ddl-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAyB,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAIjE;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,cAAc,CAAC,EAAE,MAAM,EACvB,iBAAiB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,OAAO,CAAC,CAoBlB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CAiBlB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,EACvB,iBAAiB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,OAAO,CAAC,CAkBlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE;IAChD,qEAAqE;IACrE,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBnB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CACxB,GACL,OAAO,CAAC,OAAO,CAAC,CAUlB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9D,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CACxB,GACL,OAAO,CAAC,OAAO,CAAC,CAclB;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAKxD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CACxB,GACL,OAAO,CAAC,OAAO,CAAC,CAmClB"}