@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
@@ -11,8 +11,6 @@ import {
11
11
  IconCode,
12
12
  IconClock,
13
13
  IconHierarchy2,
14
- IconExternalLink,
15
- IconHelp,
16
14
  IconPlugConnected,
17
15
  } from "@tabler/icons-react";
18
16
  import React, {
@@ -80,9 +78,15 @@ import {
80
78
  type TreeNode,
81
79
  } from "./use-resources.js";
82
80
 
83
- const WORKSPACE_DOCS_URL = "https://agent-native.com/docs/workspace";
84
81
  const LOCAL_WORKSPACE_RESOURCE_METADATA_SOURCE = "local-workspace-resource";
85
82
 
83
+ export function normalizeResourceFileName(name: string): string {
84
+ const trimmed = name.trim();
85
+ if (!trimmed || trimmed.endsWith("/")) return "";
86
+ const finalSegment = trimmed.split("/").pop() ?? "";
87
+ return /\.[^/]+$/.test(finalSegment) ? trimmed : `${trimmed}.md`;
88
+ }
89
+
86
90
  const EMPTY_RESOURCE_ACTION_LABELS: Record<ResourceView, string> = {
87
91
  files: "Add file",
88
92
  instructions: "Add instructions",
@@ -380,9 +384,9 @@ function CreateMenu({
380
384
  }, [view]);
381
385
 
382
386
  const submitFile = () => {
383
- const trimmed = value.trim();
384
- if (trimmed) {
385
- onCreateFile(trimmed);
387
+ const normalizedName = normalizeResourceFileName(value);
388
+ if (normalizedName) {
389
+ onCreateFile(normalizedName);
386
390
  setOpen(false);
387
391
  }
388
392
  };
@@ -606,7 +610,7 @@ The result should be a reusable agent profile, not a one-off task response.`,
606
610
  {
607
611
  icon: <IconPlus className="h-3.5 w-3.5" />,
608
612
  label: "Create File",
609
- desc: "Add a new file at a path",
613
+ desc: t("agentResources.createFile.menuDescription"),
610
614
  action: () => setView("file"),
611
615
  },
612
616
  {
@@ -843,7 +847,7 @@ The result should be a reusable agent profile, not a one-off task response.`,
843
847
  {view === "file" && (
844
848
  <div className="p-3">
845
849
  <label className="mb-1.5 block text-[11px] font-medium text-muted-foreground">
846
- File path
850
+ {t("agentResources.createFile.nameLabel")}
847
851
  </label>
848
852
  <input
849
853
  ref={inputRef as React.RefObject<HTMLInputElement>}
@@ -857,12 +861,12 @@ The result should be a reusable agent profile, not a one-off task response.`,
857
861
  }
858
862
  }}
859
863
  className="w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-[13px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent"
860
- placeholder="notes/ideas.md"
864
+ placeholder={t("agentResources.createFile.namePlaceholder")}
861
865
  />
862
866
  <div className="mt-2.5 flex justify-end">
863
867
  <button
864
868
  onClick={submitFile}
865
- disabled={!value.trim()}
869
+ disabled={!normalizeResourceFileName(value)}
866
870
  className="rounded-md bg-accent px-3 py-1.5 text-[12px] font-medium text-foreground hover:bg-accent/80 disabled:opacity-40 disabled:pointer-events-none"
867
871
  >
868
872
  Create
@@ -1145,9 +1149,9 @@ Create skill files under \`skills/<name>/SKILL.md\` to give the agent specialize
1145
1149
  |-------|------|-------------|
1146
1150
  | *(use the skill button to create one)* | \`skills/example/SKILL.md\` | |
1147
1151
 
1148
- ## Workspace files
1152
+ ## Agent resource files
1149
1153
 
1150
- Workspace resources are for files users intentionally add, edit, or manage. Agents may create hidden \`agent_scratch\` resources for temporary working notes, scripts, or intermediate results; only promote those files into workspace visibility when a user explicitly asks to keep them.
1154
+ Agent resources are files users intentionally add, edit, or manage. Agents may create hidden \`agent_scratch\` resources for temporary working notes, scripts, or intermediate results; only promote those files into the visible agent resources list when a user explicitly asks to keep them.
1151
1155
  `;
1152
1156
 
1153
1157
  const WORKSPACE_RESOURCE_OWNER = "__workspace__";
@@ -1185,6 +1189,7 @@ export function ResourcesPanel({
1185
1189
  resourceTreeVariant = "tree",
1186
1190
  mcpIntegrations,
1187
1191
  }: ResourcesPanelProps = {}) {
1192
+ const t = useT();
1188
1193
  const { data: org } = useOrg();
1189
1194
  // Non-admin org members get read-only access to organization resources.
1190
1195
  // Solo deployments (no orgId) behave as owner — users can edit their own.
@@ -1398,7 +1403,11 @@ export function ResourcesPanel({
1398
1403
 
1399
1404
  const handleCreateFile = useCallback(
1400
1405
  (parentPath: string, name: string, scope: ResourceScope) => {
1401
- const path = parentPath ? `${parentPath}/${name}` : name;
1406
+ const normalizedName = normalizeResourceFileName(name);
1407
+ if (!normalizedName) return;
1408
+ const path = parentPath
1409
+ ? `${parentPath}/${normalizedName}`
1410
+ : normalizedName;
1402
1411
  createResource.mutate(
1403
1412
  { path, content: "", shared: scope === "shared" },
1404
1413
  {
@@ -1421,8 +1430,14 @@ export function ResourcesPanel({
1421
1430
 
1422
1431
  const handleCreateFromToolbar = useCallback(
1423
1432
  (targetScope: ResourceScope, name: string) => {
1433
+ const normalizedName = normalizeResourceFileName(name);
1434
+ if (!normalizedName) return;
1424
1435
  createResource.mutate(
1425
- { path: name, content: "", shared: targetScope === "shared" },
1436
+ {
1437
+ path: normalizedName,
1438
+ content: "",
1439
+ shared: targetScope === "shared",
1440
+ },
1426
1441
  {
1427
1442
  onSuccess: (data) => {
1428
1443
  setSelectedResourceId(data.id);
@@ -1662,13 +1677,15 @@ export function ResourcesPanel({
1662
1677
  <TooltipTrigger asChild>
1663
1678
  <button
1664
1679
  onClick={handleBack}
1665
- aria-label="Back to workspace"
1680
+ aria-label={t("agentResources.backToResources")}
1666
1681
  className="flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:text-foreground hover:bg-accent/50"
1667
1682
  >
1668
1683
  <IconArrowLeft className="h-3.5 w-3.5" />
1669
1684
  </button>
1670
1685
  </TooltipTrigger>
1671
- <TooltipContent>Back to workspace</TooltipContent>
1686
+ <TooltipContent>
1687
+ {t("agentResources.backToResources")}
1688
+ </TooltipContent>
1672
1689
  </Tooltip>
1673
1690
  </TooltipProvider>
1674
1691
  {selectedMcpServer ? (
@@ -1843,24 +1860,6 @@ export function ResourcesPanel({
1843
1860
  </TooltipContent>
1844
1861
  </Tooltip>
1845
1862
  </TooltipProvider>
1846
- <TooltipProvider delayDuration={200}>
1847
- <Tooltip>
1848
- <TooltipTrigger asChild>
1849
- <a
1850
- href={WORKSPACE_DOCS_URL}
1851
- target="_blank"
1852
- rel="noopener noreferrer"
1853
- aria-label="Open Resources docs"
1854
- className="flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground hover:text-foreground hover:bg-accent/50"
1855
- >
1856
- <IconHelp className="h-3.5 w-3.5" />
1857
- </a>
1858
- </TooltipTrigger>
1859
- <TooltipContent side="left" sideOffset={8}>
1860
- Open Resources docs
1861
- </TooltipContent>
1862
- </Tooltip>
1863
- </TooltipProvider>
1864
1863
  </>
1865
1864
  )}
1866
1865
  <input
@@ -1915,42 +1914,6 @@ export function ResourcesPanel({
1915
1914
  )
1916
1915
  ) : (
1917
1916
  <div className="flex-1 min-h-0 overflow-y-auto">
1918
- {!personalTreeQuery.isLoading &&
1919
- !sharedTreeQuery.isLoading &&
1920
- !workspaceTreeQuery.isLoading &&
1921
- visibleWorkspaceTree.length === 0 &&
1922
- displayedPersonalTree.length === 0 &&
1923
- displayedSharedTree.length === 0 && (
1924
- <div className="mx-2 mt-2 rounded-md border border-border bg-muted/30 p-2.5 text-[11px] text-muted-foreground">
1925
- <p className="mb-1 font-medium text-foreground">
1926
- This is your Workspace
1927
- </p>
1928
- <p className="mb-1.5 leading-snug">
1929
- Files the agent reads and writes — notes, instructions,
1930
- skills, custom agents, scheduled jobs, and inherited
1931
- workspace context. They live in the database or, in local
1932
- file mode, in the attached repo.
1933
- </p>
1934
- <p className="mb-2 leading-snug">
1935
- <span className="text-foreground">Workspace</span> is
1936
- inherited from Dispatch or local file mode.{" "}
1937
- <span className="text-foreground">Organization</span> is
1938
- visible to everyone in your organization
1939
- {org?.orgId ? " — only admins can edit. " : ". "}
1940
- <span className="text-foreground">Personal</span> is just
1941
- for you.
1942
- </p>
1943
- <a
1944
- href={WORKSPACE_DOCS_URL}
1945
- target="_blank"
1946
- rel="noopener noreferrer"
1947
- className="inline-flex items-center gap-1 text-foreground hover:underline"
1948
- >
1949
- Learn more
1950
- <IconExternalLink className="h-3 w-3" />
1951
- </a>
1952
- </div>
1953
- )}
1954
1917
  {visibleWorkspaceTree.length > 0 && (
1955
1918
  <ResourceTree
1956
1919
  tree={visibleWorkspaceTree}
@@ -0,0 +1,107 @@
1
+ const MCP_CONNECTION_RESUME_STORAGE_KEY = "agent-native:mcp-connection-resume";
2
+ const MCP_CONNECTION_RESUME_EVENT = "agent-native:mcp-connection-complete";
3
+ const MCP_CONNECTION_RESUME_TTL_MS = 10 * 60 * 1_000;
4
+ const MCP_CONNECTION_RESUME_MAX_MESSAGE_LENGTH = 24_000;
5
+
6
+ export interface McpConnectionResumeRequest {
7
+ message: string;
8
+ returnUrl: string;
9
+ createdAt: number;
10
+ }
11
+
12
+ function currentReturnUrl(): string {
13
+ if (typeof window === "undefined") return "/";
14
+ return (
15
+ window.location.pathname + window.location.search + window.location.hash
16
+ );
17
+ }
18
+
19
+ function getSessionStorage(): Storage | null {
20
+ if (typeof window === "undefined") return null;
21
+ try {
22
+ return window.sessionStorage;
23
+ } catch {
24
+ return null;
25
+ }
26
+ }
27
+
28
+ export function saveMcpConnectionResume(message: string): boolean {
29
+ const trimmedMessage = message.trim();
30
+ if (
31
+ !trimmedMessage ||
32
+ trimmedMessage.length > MCP_CONNECTION_RESUME_MAX_MESSAGE_LENGTH
33
+ ) {
34
+ return false;
35
+ }
36
+ const storage = getSessionStorage();
37
+ if (!storage) return false;
38
+
39
+ const request: McpConnectionResumeRequest = {
40
+ message: trimmedMessage,
41
+ returnUrl: currentReturnUrl(),
42
+ createdAt: Date.now(),
43
+ };
44
+ try {
45
+ storage.setItem(MCP_CONNECTION_RESUME_STORAGE_KEY, JSON.stringify(request));
46
+ return true;
47
+ } catch {
48
+ return false;
49
+ }
50
+ }
51
+
52
+ export function clearMcpConnectionResume(): void {
53
+ const storage = getSessionStorage();
54
+ if (!storage) return;
55
+ try {
56
+ storage.removeItem(MCP_CONNECTION_RESUME_STORAGE_KEY);
57
+ } catch {
58
+ // Ignore storage-denied browsers; the pending request is best effort.
59
+ }
60
+ }
61
+
62
+ export function consumeMcpConnectionResume(
63
+ returnUrl = currentReturnUrl(),
64
+ ): McpConnectionResumeRequest | null {
65
+ const storage = getSessionStorage();
66
+ if (!storage) return null;
67
+
68
+ let request: McpConnectionResumeRequest;
69
+ try {
70
+ const raw = storage.getItem(MCP_CONNECTION_RESUME_STORAGE_KEY);
71
+ if (!raw) return null;
72
+ request = JSON.parse(raw) as McpConnectionResumeRequest;
73
+ } catch {
74
+ clearMcpConnectionResume();
75
+ return null;
76
+ }
77
+
78
+ if (
79
+ !request ||
80
+ typeof request.message !== "string" ||
81
+ typeof request.returnUrl !== "string" ||
82
+ typeof request.createdAt !== "number"
83
+ ) {
84
+ clearMcpConnectionResume();
85
+ return null;
86
+ }
87
+ if (Date.now() - request.createdAt > MCP_CONNECTION_RESUME_TTL_MS) {
88
+ clearMcpConnectionResume();
89
+ return null;
90
+ }
91
+ if (request.returnUrl !== returnUrl) return null;
92
+
93
+ clearMcpConnectionResume();
94
+ return request;
95
+ }
96
+
97
+ export function notifyMcpConnectionComplete(): void {
98
+ if (typeof window === "undefined") return;
99
+ window.dispatchEvent(new Event(MCP_CONNECTION_RESUME_EVENT));
100
+ }
101
+
102
+ export function addMcpConnectionCompleteListener(listener: () => void) {
103
+ if (typeof window === "undefined") return () => {};
104
+ window.addEventListener(MCP_CONNECTION_RESUME_EVENT, listener);
105
+ return () =>
106
+ window.removeEventListener(MCP_CONNECTION_RESUME_EVENT, listener);
107
+ }
@@ -49,6 +49,7 @@ export interface DefaultMcpIntegration {
49
49
  templateUses?: readonly string[];
50
50
  };
51
51
  headerPlaceholder?: string;
52
+ aliases?: string[];
52
53
  keywords: string[];
53
54
  }
54
55
 
@@ -121,6 +122,42 @@ export const DEFAULT_MCP_INTEGRATIONS: DefaultMcpIntegration[] = [
121
122
  setupNoteKey: "mcpIntegrations.catalog.notion.setupNote",
122
123
  keywords: ["docs", "knowledge", "notes", "pages"],
123
124
  },
125
+ {
126
+ id: "granola",
127
+ name: "Granola",
128
+ provider: "granola",
129
+ description: "Search meeting notes, transcripts, and action items.",
130
+ descriptionKey: "mcpIntegrations.catalog.granola.description",
131
+ useCase: "meeting notes, recordings, transcripts, action items, follow-ups",
132
+ useCaseKey: "mcpIntegrations.catalog.granola.useCase",
133
+ url: "https://mcp.granola.ai/mcp",
134
+ authMode: "oauth",
135
+ connectionMode: "oauth",
136
+ availability: "ready",
137
+ verification: "preflight-only",
138
+ logoUrl: mcpIntegrationLogo("granola"),
139
+ docsUrl: "https://docs.granola.ai/help-center/sharing/integrations/mcp",
140
+ setupNoteKey: "mcpIntegrations.catalog.granola.setupNote",
141
+ aliases: [
142
+ "meeting notes",
143
+ "meeting recordings",
144
+ "recordings",
145
+ "transcripts",
146
+ "action items",
147
+ "follow-ups",
148
+ "follow ups",
149
+ "decisions",
150
+ ],
151
+ keywords: [
152
+ "meetings",
153
+ "meeting notes",
154
+ "recordings",
155
+ "transcripts",
156
+ "action items",
157
+ "follow-ups",
158
+ "decisions",
159
+ ],
160
+ },
124
161
  {
125
162
  id: "semgrep",
126
163
  name: "Semgrep",
@@ -173,6 +210,7 @@ export const DEFAULT_MCP_INTEGRATIONS: DefaultMcpIntegration[] = [
173
210
  docsUrl:
174
211
  "https://developer.atlassian.com/cloud/rovo-mcp/guides/getting-started/",
175
212
  setupNoteKey: "mcpIntegrations.catalog.atlassian.setupNote",
213
+ aliases: ["jira", "confluence", "rovo"],
176
214
  keywords: ["atlassian", "jira", "confluence", "issues", "tickets"],
177
215
  },
178
216
  {
@@ -679,10 +717,19 @@ export function filterMcpIntegrations(
679
717
  }
680
718
 
681
719
  const MCP_LINK_HOSTS: Record<string, string[]> = {
720
+ context7: ["context7.com"],
721
+ sentry: ["sentry.io", "sentry.dev"],
682
722
  notion: ["notion.so", "notion.site"],
723
+ granola: ["granola.ai"],
724
+ semgrep: ["semgrep.dev", "semgrep.com"],
683
725
  canva: ["canva.com", "canva.ai"],
684
726
  figma: ["figma.com"],
685
727
  linear: ["linear.app"],
728
+ atlassian: ["atlassian.com", "atlassian.net", "jira.com", "confluence.com"],
729
+ supabase: ["supabase.com"],
730
+ neon: ["neon.tech"],
731
+ stripe: ["stripe.com"],
732
+ cloudflare: ["cloudflare.com"],
686
733
  github: ["github.com", "github.dev"],
687
734
  gitlab: ["gitlab.com"],
688
735
  slack: ["slack.com"],
@@ -694,6 +741,8 @@ const MCP_LINK_HOSTS: Record<string, string[]> = {
694
741
  paypal: ["paypal.com"],
695
742
  box: ["box.com"],
696
743
  netlify: ["netlify.com"],
744
+ vercel: ["vercel.com"],
745
+ zapier: ["zapier.com"],
697
746
  };
698
747
 
699
748
  function hostMatches(hostname: string, domain: string): boolean {
@@ -713,7 +762,12 @@ function findUrlForText(text: string): URL | null {
713
762
  }
714
763
 
715
764
  const MCP_RESOURCE_INTENT_PATTERN =
716
- /\b(?:connect|connected|connection|integration|integrate|link|page|document|doc|file|workspace|project|issue|design|board|channel|message|ticket|read|access|open|see|fetch|sync|import)\b/i;
765
+ /\b(?:action|add|access|board|check|connect|connected|connection|create|decision|design|document|doc|do|extract|fetch|file|find|follow[- ]?ups?|get|import|integration|integrate|issue|link|list|meeting|message|notes?|open|page|populate|project|pull|read|recordings?|review|search|see|summary|summarize|sync|task|ticket|todo|transcripts?|turn|use|workspace)\b/i;
766
+
767
+ function textContainsTerm(text: string, term: string): boolean {
768
+ const escaped = term.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
769
+ return new RegExp(`(^|[^a-z0-9])${escaped}([^a-z0-9]|$)`, "i").test(text);
770
+ }
717
771
 
718
772
  export function findMcpIntegrationForText(
719
773
  text: string,
@@ -734,17 +788,16 @@ export function findMcpIntegrationForText(
734
788
  MCP_RESOURCE_INTENT_PATTERN.test(normalizedText) ||
735
789
  isMcpConnectionFailureText(normalizedText);
736
790
  if (!hasResourceIntent) return null;
737
- return (
738
- integrations.find((integration) => {
739
- const aliases = [integration.name, integration.provider, integration.id];
740
- return aliases.some((alias) => {
741
- const escaped = alias.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
742
- return new RegExp(`(^|[^a-z0-9])${escaped}([^a-z0-9]|$)`, "i").test(
743
- normalizedText,
744
- );
745
- });
746
- }) ?? null
747
- );
791
+ const matchesCanonicalName = (integration: DefaultMcpIntegration) =>
792
+ [
793
+ integration.name,
794
+ integration.provider,
795
+ integration.id,
796
+ ...(integration.aliases ?? []),
797
+ ].some((alias) => textContainsTerm(normalizedText, alias));
798
+ const canonicalMatch = integrations.find(matchesCanonicalName);
799
+ if (canonicalMatch) return canonicalMatch;
800
+ return null;
748
801
  }
749
802
 
750
803
  export function isMcpConnectionFailureText(text: string): boolean {
@@ -23,6 +23,10 @@ const LOGOS = {
23
23
  mime: "image/svg+xml",
24
24
  data: "PHN2ZyBmaWxsPSIjMDAwMDAwIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+Tm90aW9uPC90aXRsZT48cGF0aCBkPSJNNC40NTkgNC4yMDhjLjc0Ni42MDYgMS4wMjYuNTYgMi40MjguNDY2bDEzLjIxNS0uNzkzYy4yOCAwIC4wNDctLjI4LS4wNDYtLjMyNkwxNy44NiAxLjk2OGMtLjQyLS4zMjYtLjk4MS0uNy0yLjA1NS0uNjA3TDMuMDEgMi4yOTVjLS40NjYuMDQ2LS41Ni4yOC0uMzc0LjQ2NnptLjc5MyAzLjA4djEzLjkwNGMwIC43NDcuMzczIDEuMDI3IDEuMjE0Ljk4bDE0LjUyMy0uODRjLjg0MS0uMDQ2LjkzNS0uNTYuOTM1LTEuMTY3VjYuMzU0YzAtLjYwNi0uMjMzLS45MzMtLjc0OC0uODg3bC0xNS4xNzcuODg3Yy0uNTYuMDQ3LS43NDcuMzI3LS43NDcuOTMzem0xNC4zMzcuNzQ1Yy4wOTMuNDIgMCAuODQtLjQyLjg4OGwtLjcuMTR2MTAuMjY0Yy0uNjA4LjMyNy0xLjE2OC41MTQtMS42MzUuNTE0LS43NDggMC0uOTM1LS4yMzQtMS40OTUtLjkzM2wtNC41NzctNy4xODZ2Ni45NTJMMTIuMjEgMTlzMCAuODQtMS4xNjguODRsLTMuMjIyLjE4NmMtLjA5My0uMTg2IDAtLjY1My4zMjctLjc0NmwuODQtLjIzM1Y5Ljg1NEw3LjgyMiA5Ljc2Yy0uMDk0LS40Mi4xNC0xLjAyNi43OTMtMS4wNzNsMy40NTYtLjIzMyA0Ljc2NCA3LjI3OXYtNi40NGwtMS4yMTUtLjEzOWMtLjA5My0uNTE0LjI4LS44ODcuNzQ3LS45MzN6TTEuOTM2IDEuMDM1bDEzLjMxLS45OGMxLjYzNC0uMTQgMi4wNTUtLjA0NyAzLjA4Mi43bDQuMjQ5IDIuOTg2Yy43LjUxMy45MzQuNjUzLjkzNCAxLjIxM3YxNi4zNzhjMCAxLjAyNi0uMzczIDEuNjM0LTEuNjggMS43MjZsLTE1LjQ1OC45MzRjLS45OC4wNDctMS40NDgtLjA5My0xLjk2Mi0uNzQ3bC0zLjEyOS00LjA2Yy0uNTYtLjc0Ny0uNzkzLTEuMzA2LS43OTMtMS45NlYyLjY2N2MwLS44MzkuMzc0LTEuNTQgMS40NDctMS42MzJ6Ii8+PC9zdmc+",
25
25
  },
26
+ granola: {
27
+ mime: "image/svg+xml",
28
+ data: "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiByeD0iNiIgZmlsbD0iI2Y0ZWZlNyIvPjxwYXRoIGQ9Ik00IDkuNWMyLjEtMi42IDQuOC0zLjkgOC0zLjlzNS45IDEuMyA4IDMuOWMtMi4xIDIuNi00LjggMy45LTggMy45cy01LjktMS4zLTgtMy45WiIgZmlsbD0iIzI4YTg3OCIvPjxwYXRoIGQ9Ik01LjMgMTIuMmMxLjkgMS43IDQuMSAyLjYgNi43IDIuNnM0LjgtLjkgNi43LTIuNmMtLjUgMy44LTMuMSA2LjItNi43IDYuMnMtNi4yLTIuNC02LjctNi4yWiIgZmlsbD0iIzEzOGY2OCIvPjxjaXJjbGUgY3g9IjkiIGN5PSI5LjUiIHI9IjEiIGZpbGw9IiNmZmYiLz48Y2lyY2xlIGN4PSIxMiIgY3k9IjkuNSIgcj0iMSIgZmlsbD0iI2ZmZiIvPjxjaXJjbGUgY3g9IjE1IiBjeT0iOS41IiByPSIxIiBmaWxsPSIjZmZmIi8+PC9zdmc+",
29
+ },
26
30
  linear: {
27
31
  mime: "image/svg+xml",
28
32
  data: "PHN2ZyBmaWxsPSIjNUU2QUQyIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+TGluZWFyPC90aXRsZT48cGF0aCBkPSJNMi44ODYgNC4xOEExMS45ODIgMTEuOTgyIDAgMCAxIDExLjk5IDBDMTguNjI0IDAgMjQgNS4zNzYgMjQgMTIuMDA5YzAgMy42NC0xLjYyIDYuOTAzLTQuMTggOS4xMDVMMi44ODcgNC4xOFpNMS44MTcgNS42MjZsMTYuNTU2IDE2LjU1NmMtLjUyNC4zMy0xLjA3NS42Mi0xLjY1Ljg2NkwuOTUxIDcuMjc3Yy4yNDctLjU3NS41MzctMS4xMjYuODY2LTEuNjVaTS4zMjIgOS4xNjNsMTQuNTE1IDE0LjUxNWMtLjcxLjE3Mi0xLjQ0My4yODItMi4xOTUuMzIyTDAgMTEuMzU4YTEyIDEyIDAgMCAxIC4zMjItMi4xOTVabS0uMTcgNC44NjIgOS44MjMgOS44MjRhMTIuMDIgMTIuMDIgMCAwIDEtOS44MjQtOS44MjRaIi8+PC9zdmc+",
@@ -974,6 +974,51 @@ function completedToolOnlyMessage(toolNames: string[]): string | null {
974
974
  return `The agent completed ${label}, but stopped before sending a final message. Review the completed tool card above or ask the agent to continue.`;
975
975
  }
976
976
 
977
+ export function appendMissingFinalResponseWarning(
978
+ content: ContentPart[],
979
+ completedToolNames?: Iterable<string>,
980
+ ): { message: string; errorCode: string; recoverable: true } | null {
981
+ const lastTextIndex = lastAssistantTextIndex(content);
982
+ const successfulToolNames = [
983
+ ...new Set(
984
+ completedToolNames ?? completedToolNamesAfterLastAssistantText(content),
985
+ ),
986
+ ];
987
+ let lastToolIndex = -1;
988
+ const materializedToolNames = new Set<string>();
989
+ for (let index = lastTextIndex + 1; index < content.length; index++) {
990
+ const part = content[index];
991
+ if (
992
+ part.type === "tool-call" &&
993
+ part.activity !== true &&
994
+ part.result !== undefined
995
+ ) {
996
+ lastToolIndex = index;
997
+ materializedToolNames.add(part.toolName);
998
+ }
999
+ }
1000
+ if (successfulToolNames.length === 0 && lastTextIndex > lastToolIndex) {
1001
+ return null;
1002
+ }
1003
+ const completedToolMessage = completedToolOnlyMessage(successfulToolNames);
1004
+ const message = completedToolMessage
1005
+ ? completedToolMessage
1006
+ : materializedToolNames.size > 0
1007
+ ? `The agent stopped after ${formatToolNames([...materializedToolNames])} without sending a final message. Review the tool card above or ask the agent to continue.`
1008
+ : "The agent stopped without sending a final message. Ask the agent to continue or retry.";
1009
+ if (!content.some((part) => part.type === "text" && part.text === message)) {
1010
+ content.push({ type: "text", text: message });
1011
+ }
1012
+ return {
1013
+ message,
1014
+ errorCode:
1015
+ successfulToolNames.length > 0 || materializedToolNames.size > 0
1016
+ ? "final_response_missing_after_tool"
1017
+ : "final_response_missing",
1018
+ recoverable: true,
1019
+ };
1020
+ }
1021
+
977
1022
  interface ProcessEventState {
978
1023
  completedToolsAfterLastAssistantText: Set<string>;
979
1024
  /** Set once `agent-chat:stream-progress` has been dispatched for the
@@ -1535,16 +1580,11 @@ export function processEvent(
1535
1580
  } as ChatModelRunResult,
1536
1581
  };
1537
1582
  }
1538
- const toolOnlyMessage = completedToolOnlyMessage(
1539
- state
1540
- ? [...state.completedToolsAfterLastAssistantText]
1541
- : completedToolNamesAfterLastAssistantText(content),
1583
+ const runWarning = appendMissingFinalResponseWarning(
1584
+ content,
1585
+ state ? state.completedToolsAfterLastAssistantText : undefined,
1542
1586
  );
1543
- if (toolOnlyMessage) {
1544
- content.push({
1545
- type: "text",
1546
- text: toolOnlyMessage,
1547
- });
1587
+ if (runWarning) {
1548
1588
  return {
1549
1589
  action: "done",
1550
1590
  result: {
@@ -1552,11 +1592,7 @@ export function processEvent(
1552
1592
  status: { type: "complete" as const, reason: "stop" as const },
1553
1593
  metadata: {
1554
1594
  custom: {
1555
- runWarning: {
1556
- message: toolOnlyMessage,
1557
- errorCode: "final_response_missing_after_tool",
1558
- recoverable: true,
1559
- },
1595
+ runWarning,
1560
1596
  },
1561
1597
  },
1562
1598
  } as ChatModelRunResult,