@agent-native/core 0.115.4 → 0.116.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (408) hide show
  1. package/agent-native.eject.json +1 -0
  2. package/corpus/README.md +3 -3
  3. package/corpus/core/CHANGELOG.md +28 -0
  4. package/corpus/core/agent-native.eject.json +1 -0
  5. package/corpus/core/docs/AGENTS.md +1 -1
  6. package/corpus/core/docs/content/agent-mentions.mdx +2 -2
  7. package/corpus/core/docs/content/{workspace.mdx → agent-resources.mdx} +1 -7
  8. package/corpus/core/docs/content/agent-teams.mdx +4 -4
  9. package/corpus/core/docs/content/dispatch.mdx +10 -10
  10. package/corpus/core/docs/content/drop-in-agent.mdx +4 -4
  11. package/corpus/core/docs/content/external-agents.mdx +1 -1
  12. package/corpus/core/docs/content/frames.mdx +1 -1
  13. package/corpus/core/docs/content/integrations.mdx +13 -2
  14. package/corpus/core/docs/content/key-concepts.mdx +2 -2
  15. package/corpus/core/docs/content/mcp-clients.mdx +7 -1
  16. package/corpus/core/docs/content/multi-app-workspace.mdx +3 -3
  17. package/corpus/core/docs/content/real-time-collaboration.mdx +33 -15
  18. package/corpus/core/docs/content/recurring-jobs.mdx +7 -7
  19. package/corpus/core/docs/content/skills-guide.mdx +4 -4
  20. package/corpus/core/docs/content/template-brain.mdx +1 -1
  21. package/corpus/core/docs/content/toolkit-collaboration.mdx +1 -1
  22. package/corpus/core/docs/content/using-your-agent.mdx +1 -1
  23. package/corpus/core/docs/content/what-is-agent-native.mdx +4 -4
  24. package/corpus/core/docs/content/workspace-management.mdx +4 -4
  25. package/corpus/core/package.json +1 -1
  26. package/corpus/core/src/agent/production-agent.ts +13 -3
  27. package/corpus/core/src/cli/doctor.ts +6 -1
  28. package/corpus/core/src/client/AgentPanel.tsx +79 -41
  29. package/corpus/core/src/client/AssistantChat.tsx +71 -25
  30. package/corpus/core/src/client/FeedbackButton.tsx +33 -7
  31. package/corpus/core/src/client/MultiTabAssistantChat.tsx +6 -8
  32. package/corpus/core/src/client/agent-chat-adapter.ts +11 -2
  33. package/corpus/core/src/client/agent-page/AgentTabFrame.tsx +22 -3
  34. package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +34 -19
  35. package/corpus/core/src/client/chat/message-components.tsx +43 -16
  36. package/corpus/core/src/client/chat/tool-call-display.tsx +30 -18
  37. package/corpus/core/src/client/chat/tool-render-registry.tsx +2 -0
  38. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +19 -2
  39. package/corpus/core/src/client/resources/ResourceTree.tsx +7 -10
  40. package/corpus/core/src/client/resources/ResourcesPanel.tsx +33 -70
  41. package/corpus/core/src/client/resources/mcp-connection-resume.ts +107 -0
  42. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +65 -12
  43. package/corpus/core/src/client/resources/mcp-integration-logos.ts +4 -0
  44. package/corpus/core/src/client/sse-event-processor.ts +50 -14
  45. package/corpus/core/src/client/use-db-sync.ts +16 -6
  46. package/corpus/core/src/connections/catalog.ts +7 -1
  47. package/corpus/core/src/eject/remote-mcp-presets.ts +37 -5
  48. package/corpus/core/src/guards/explicit-collab-access.ts +229 -0
  49. package/corpus/core/src/guards/index.ts +1 -0
  50. package/corpus/core/src/localization/default-messages.ts +54 -5
  51. package/corpus/core/src/mcp/connect-route.ts +34 -51
  52. package/corpus/core/src/provider-api/index.ts +1 -1
  53. package/corpus/core/src/server/collab-plugin.ts +137 -18
  54. package/corpus/core/src/server/index.ts +2 -0
  55. package/corpus/core/src/styles/agent-native.css +40 -0
  56. package/corpus/core/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  57. package/corpus/core/src/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
  58. package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  59. package/corpus/core/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  60. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  61. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
  62. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  63. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
  64. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  65. package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +1 -1
  66. package/corpus/templates/analytics/AGENTS.md +7 -2
  67. package/corpus/templates/analytics/actions/export-dashboard-panel-to-google-sheet.ts +144 -0
  68. package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -88
  69. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +34 -37
  70. package/corpus/templates/analytics/app/global.css +0 -4
  71. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +2 -7
  72. package/corpus/templates/analytics/app/i18n-data.ts +107 -0
  73. package/corpus/templates/analytics/app/lib/data-source-status.ts +9 -0
  74. package/corpus/templates/analytics/app/lib/sql-query.ts +1 -2
  75. package/corpus/templates/analytics/app/pages/Ask.tsx +2 -7
  76. package/corpus/templates/analytics/app/pages/DataSources.tsx +48 -0
  77. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +59 -0
  78. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -0
  79. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/report-panel-window.ts +3 -1
  80. package/corpus/templates/analytics/changelog/2026-07-22-clear-background-chat-progress.md +6 -0
  81. package/corpus/templates/analytics/changelog/2026-07-22-daily-dashboard-email-query-batches.md +6 -0
  82. package/corpus/templates/analytics/changelog/2026-07-22-export-table-panels-directly-to-google-sheets.md +6 -0
  83. package/corpus/templates/analytics/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  84. package/corpus/templates/analytics/changelog/2026-07-22-recent-chats-can-expand-in-the-sidebar.md +6 -0
  85. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +8 -8
  86. package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +31 -0
  87. package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +3 -5
  88. package/corpus/templates/analytics/server/lib/dashboard-report.ts +12 -0
  89. package/corpus/templates/analytics/server/lib/first-party-dashboard-repair.ts +3 -5
  90. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +150 -21
  91. package/corpus/templates/analytics/server/lib/google-sheets-export.ts +188 -0
  92. package/corpus/templates/analytics/server/lib/provider-api.ts +7 -2
  93. package/corpus/templates/analytics/server/plugins/collab.ts +6 -3
  94. package/corpus/templates/analytics/shared/sql-query-limits.ts +1 -0
  95. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  96. package/corpus/templates/assets/.agents/skills/real-time-collab/SKILL.md +35 -13
  97. package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +1 -1
  98. package/corpus/templates/assets/app/components/layout/Layout.tsx +1 -1
  99. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +54 -62
  100. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +2 -6
  101. package/corpus/templates/assets/app/routes/_index.tsx +8 -5
  102. package/corpus/templates/assets/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  103. package/corpus/templates/assets/changelog/2026-07-22-recent-chats-expand-from-a-compact-list.md +6 -0
  104. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  105. package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +1 -1
  106. package/corpus/templates/brain/actions/rotate-source-ingest-token.ts +77 -0
  107. package/corpus/templates/brain/app/components/layout/Layout.tsx +5 -1
  108. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +38 -51
  109. package/corpus/templates/brain/app/hooks/use-navigation-state.ts +2 -9
  110. package/corpus/templates/brain/app/i18n-data.ts +120 -0
  111. package/corpus/templates/brain/app/routes/sources.tsx +156 -5
  112. package/corpus/templates/brain/changelog/2026-07-22-chat-runs-always-end-with-an-answer.md +6 -0
  113. package/corpus/templates/brain/changelog/2026-07-22-clear-background-chat-progress.md +6 -0
  114. package/corpus/templates/brain/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  115. package/corpus/templates/brain/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  116. package/corpus/templates/brain/changelog/2026-07-22-long-chat-titles-stay-inside-the-sidebar.md +6 -0
  117. package/corpus/templates/brain/changelog/2026-07-22-new-clips-and-webhook-sources-now-show-their-secure-connecti.md +6 -0
  118. package/corpus/templates/brain/jobs/emit-netlify-brain-queue-cron.ts +125 -0
  119. package/corpus/templates/brain/netlify.toml +5 -1
  120. package/corpus/templates/brain/scripts/configure-prod-clips-source.ts +50 -0
  121. package/corpus/templates/brain/server/lib/capture-sanitization.ts +64 -6
  122. package/corpus/templates/brain/server/plugins/agent-chat.ts +4 -0
  123. package/corpus/templates/brain/server/plugins/brain-jobs.ts +1 -0
  124. package/corpus/templates/brain/server/routes/api/brain/queue/run.post.ts +55 -0
  125. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  126. package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +1 -1
  127. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  128. package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  129. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -0
  130. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +43 -67
  131. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +2 -7
  132. package/corpus/templates/chat/app/routes/_index.tsx +8 -5
  133. package/corpus/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  134. package/corpus/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  135. package/corpus/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  136. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  137. package/corpus/templates/clips/AGENTS.md +9 -1
  138. package/corpus/templates/clips/actions/export-to-brain.ts +82 -6
  139. package/corpus/templates/clips/actions/request-transcript.ts +25 -14
  140. package/corpus/templates/clips/changelog/2026-07-22-clips-transcripts-now-retry-brain-export.md +5 -0
  141. package/corpus/templates/clips/changelog/2026-07-22-german-umlauts-and-other-non-ascii-characters-now-paste-corr.md +6 -0
  142. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +26 -3
  143. package/corpus/templates/clips/jobs/emit-netlify-brain-export-cron.ts +118 -0
  144. package/corpus/templates/clips/netlify.toml +4 -1
  145. package/corpus/templates/clips/scripts/configure-prod-brain-export.ts +92 -0
  146. package/corpus/templates/clips/server/jobs/brain-export.ts +182 -0
  147. package/corpus/templates/clips/server/lib/brain-export-state.ts +42 -0
  148. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +5 -1
  149. package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
  150. package/corpus/templates/clips/server/register-secrets.ts +42 -0
  151. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +10 -1
  152. package/corpus/templates/clips/server/routes/api/clips/brain-export/run.post.ts +45 -0
  153. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  154. package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +1 -1
  155. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -1
  156. package/corpus/templates/content/server/plugins/collab.ts +1 -1
  157. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  158. package/corpus/templates/crm/actions/_crm-data-program-actions.ts +15 -0
  159. package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +2 -0
  160. package/corpus/templates/crm/actions/run.ts +2 -6
  161. package/corpus/templates/crm/actions/update-crm-record.ts +4 -2
  162. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +6 -0
  163. package/corpus/templates/crm/changelog/2026-07-22-crm-field-validation-now-explains-which-fields-cannot-be-edi.md +6 -0
  164. package/corpus/templates/crm/changelog/2026-07-22-fixed-hubspot-contact-syncs-missing-records-updated-after-th.md +6 -0
  165. package/corpus/templates/crm/changelog/2026-07-22-fixed-pipeline-dashboard-panels-so-their-opportunity-data-lo.md +6 -0
  166. package/corpus/templates/crm/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  167. package/corpus/templates/crm/server/crm/hubspot-adapter.ts +4 -1
  168. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  169. package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
  170. package/corpus/templates/design/server/plugins/collab.ts +11 -8
  171. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  172. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  173. package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +1 -1
  174. package/corpus/templates/forms/app/components/layout/Layout.tsx +1 -0
  175. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +1 -1
  176. package/corpus/templates/forms/app/hooks/use-navigation-state.ts +2 -9
  177. package/corpus/templates/forms/app/root.tsx +1 -6
  178. package/corpus/templates/forms/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  179. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  180. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  181. package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +1 -1
  182. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +2 -2
  183. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  184. package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +1 -1
  185. package/corpus/templates/plan/app/components/layout/Layout.tsx +5 -1
  186. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +57 -72
  187. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +2 -9
  188. package/corpus/templates/plan/app/lib/create-plan-routing.ts +2 -2
  189. package/corpus/templates/plan/app/pages/PlanChatPage.tsx +0 -1
  190. package/corpus/templates/plan/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  191. package/corpus/templates/plan/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  192. package/corpus/templates/plan/changelog/2026-07-22-recent-chats-and-sidebar-controls-are-more-compact.md +6 -0
  193. package/corpus/templates/plan/server/plugins/collab.ts +5 -2
  194. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  195. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +1 -1
  196. package/corpus/templates/slides/server/plugins/collab.ts +11 -8
  197. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  198. package/corpus/templates/tasks/.agents/skills/real-time-sync/SKILL.md +1 -1
  199. package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +5 -22
  200. package/corpus/templates/tasks/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  201. package/corpus/toolkit/CHANGELOG.md +7 -0
  202. package/corpus/toolkit/README.md +12 -3
  203. package/corpus/toolkit/package.json +1 -1
  204. package/corpus/toolkit/src/chat-history/ChatHistoryRail.tsx +89 -0
  205. package/corpus/toolkit/src/chat-history/index.ts +5 -0
  206. package/corpus/toolkit/src/chat-history.css +59 -0
  207. package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +106 -36
  208. package/corpus/toolkit/src/composer/VoiceButton.tsx +49 -0
  209. package/corpus/toolkit/src/composer/realtime-voice-audio-level.ts +2 -1
  210. package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +5 -3
  211. package/corpus/toolkit/src/styles.css +35 -0
  212. package/dist/agent/production-agent.d.ts.map +1 -1
  213. package/dist/agent/production-agent.js +13 -3
  214. package/dist/agent/production-agent.js.map +1 -1
  215. package/dist/cli/doctor.d.ts +1 -1
  216. package/dist/cli/doctor.d.ts.map +1 -1
  217. package/dist/cli/doctor.js +5 -2
  218. package/dist/cli/doctor.js.map +1 -1
  219. package/dist/client/AgentPanel.d.ts +1 -0
  220. package/dist/client/AgentPanel.d.ts.map +1 -1
  221. package/dist/client/AgentPanel.js +38 -18
  222. package/dist/client/AgentPanel.js.map +1 -1
  223. package/dist/client/AssistantChat.d.ts.map +1 -1
  224. package/dist/client/AssistantChat.js +55 -20
  225. package/dist/client/AssistantChat.js.map +1 -1
  226. package/dist/client/FeedbackButton.d.ts +4 -2
  227. package/dist/client/FeedbackButton.d.ts.map +1 -1
  228. package/dist/client/FeedbackButton.js +18 -2
  229. package/dist/client/FeedbackButton.js.map +1 -1
  230. package/dist/client/MultiTabAssistantChat.d.ts +1 -1
  231. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  232. package/dist/client/MultiTabAssistantChat.js +2 -3
  233. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  234. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  235. package/dist/client/agent-chat-adapter.js +11 -3
  236. package/dist/client/agent-chat-adapter.js.map +1 -1
  237. package/dist/client/agent-page/AgentTabFrame.d.ts +3 -1
  238. package/dist/client/agent-page/AgentTabFrame.d.ts.map +1 -1
  239. package/dist/client/agent-page/AgentTabFrame.js +3 -2
  240. package/dist/client/agent-page/AgentTabFrame.js.map +1 -1
  241. package/dist/client/agent-page/AgentTabsPage.d.ts +2 -0
  242. package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -1
  243. package/dist/client/agent-page/AgentTabsPage.js +26 -15
  244. package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
  245. package/dist/client/chat/message-components.d.ts +6 -1
  246. package/dist/client/chat/message-components.d.ts.map +1 -1
  247. package/dist/client/chat/message-components.js +17 -11
  248. package/dist/client/chat/message-components.js.map +1 -1
  249. package/dist/client/chat/tool-call-display.d.ts +11 -1
  250. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  251. package/dist/client/chat/tool-call-display.js +16 -17
  252. package/dist/client/chat/tool-call-display.js.map +1 -1
  253. package/dist/client/chat/tool-render-registry.d.ts +2 -0
  254. package/dist/client/chat/tool-render-registry.d.ts.map +1 -1
  255. package/dist/client/chat/tool-render-registry.js.map +1 -1
  256. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  257. package/dist/client/resources/McpConnectionSuggestion.js +15 -1
  258. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  259. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  260. package/dist/client/resources/ResourceTree.js +3 -3
  261. package/dist/client/resources/ResourceTree.js.map +1 -1
  262. package/dist/client/resources/ResourcesPanel.d.ts +1 -0
  263. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  264. package/dist/client/resources/ResourcesPanel.js +34 -20
  265. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  266. package/dist/client/resources/mcp-connection-resume.d.ts +11 -0
  267. package/dist/client/resources/mcp-connection-resume.d.ts.map +1 -0
  268. package/dist/client/resources/mcp-connection-resume.js +95 -0
  269. package/dist/client/resources/mcp-connection-resume.js.map +1 -0
  270. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  271. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  272. package/dist/client/resources/mcp-integration-catalog.js +63 -8
  273. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  274. package/dist/client/resources/mcp-integration-logos.d.ts.map +1 -1
  275. package/dist/client/resources/mcp-integration-logos.js +4 -0
  276. package/dist/client/resources/mcp-integration-logos.js.map +1 -1
  277. package/dist/client/sse-event-processor.d.ts +5 -0
  278. package/dist/client/sse-event-processor.d.ts.map +1 -1
  279. package/dist/client/sse-event-processor.js +39 -13
  280. package/dist/client/sse-event-processor.js.map +1 -1
  281. package/dist/client/use-db-sync.d.ts +3 -2
  282. package/dist/client/use-db-sync.d.ts.map +1 -1
  283. package/dist/client/use-db-sync.js +17 -6
  284. package/dist/client/use-db-sync.js.map +1 -1
  285. package/dist/collab/routes.d.ts +1 -1
  286. package/dist/connections/catalog.d.ts +1 -1
  287. package/dist/connections/catalog.d.ts.map +1 -1
  288. package/dist/connections/catalog.js +7 -1
  289. package/dist/connections/catalog.js.map +1 -1
  290. package/dist/eject/remote-mcp-presets.d.ts.map +1 -1
  291. package/dist/eject/remote-mcp-presets.js +33 -3
  292. package/dist/eject/remote-mcp-presets.js.map +1 -1
  293. package/dist/guards/explicit-collab-access.d.ts +8 -0
  294. package/dist/guards/explicit-collab-access.d.ts.map +1 -0
  295. package/dist/guards/explicit-collab-access.js +214 -0
  296. package/dist/guards/explicit-collab-access.js.map +1 -0
  297. package/dist/guards/index.d.ts +1 -0
  298. package/dist/guards/index.d.ts.map +1 -1
  299. package/dist/guards/index.js +1 -0
  300. package/dist/guards/index.js.map +1 -1
  301. package/dist/localization/default-messages.d.ts +43 -0
  302. package/dist/localization/default-messages.d.ts.map +1 -1
  303. package/dist/localization/default-messages.js +48 -5
  304. package/dist/localization/default-messages.js.map +1 -1
  305. package/dist/mcp/connect-route.d.ts.map +1 -1
  306. package/dist/mcp/connect-route.js +34 -48
  307. package/dist/mcp/connect-route.js.map +1 -1
  308. package/dist/notifications/routes.d.ts +3 -3
  309. package/dist/observability/routes.d.ts +1 -1
  310. package/dist/progress/routes.d.ts +1 -1
  311. package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
  312. package/dist/provider-api/actions/provider-api.d.ts +7 -7
  313. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  314. package/dist/provider-api/index.js +1 -1
  315. package/dist/provider-api/index.js.map +1 -1
  316. package/dist/server/collab-plugin.d.ts +34 -3
  317. package/dist/server/collab-plugin.d.ts.map +1 -1
  318. package/dist/server/collab-plugin.js +65 -12
  319. package/dist/server/collab-plugin.js.map +1 -1
  320. package/dist/server/index.d.ts +1 -1
  321. package/dist/server/index.d.ts.map +1 -1
  322. package/dist/server/index.js.map +1 -1
  323. package/dist/styles/agent-native.css +40 -0
  324. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  325. package/dist/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  326. package/dist/templates/chat/app/components/layout/Layout.tsx +1 -0
  327. package/dist/templates/chat/app/components/layout/Sidebar.tsx +43 -67
  328. package/dist/templates/chat/app/hooks/use-navigation-state.ts +2 -7
  329. package/dist/templates/chat/app/routes/_index.tsx +8 -5
  330. package/dist/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  331. package/dist/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  332. package/dist/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  333. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  334. package/dist/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
  335. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  336. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  337. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  338. package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
  339. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  340. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
  341. package/docs/AGENTS.md +1 -1
  342. package/docs/content/agent-mentions.mdx +2 -2
  343. package/docs/content/{workspace.mdx → agent-resources.mdx} +1 -7
  344. package/docs/content/agent-teams.mdx +4 -4
  345. package/docs/content/dispatch.mdx +10 -10
  346. package/docs/content/drop-in-agent.mdx +4 -4
  347. package/docs/content/external-agents.mdx +1 -1
  348. package/docs/content/frames.mdx +1 -1
  349. package/docs/content/integrations.mdx +13 -2
  350. package/docs/content/key-concepts.mdx +2 -2
  351. package/docs/content/mcp-clients.mdx +7 -1
  352. package/docs/content/multi-app-workspace.mdx +3 -3
  353. package/docs/content/real-time-collaboration.mdx +33 -15
  354. package/docs/content/recurring-jobs.mdx +7 -7
  355. package/docs/content/skills-guide.mdx +4 -4
  356. package/docs/content/template-brain.mdx +1 -1
  357. package/docs/content/toolkit-collaboration.mdx +1 -1
  358. package/docs/content/using-your-agent.mdx +1 -1
  359. package/docs/content/what-is-agent-native.mdx +4 -4
  360. package/docs/content/workspace-management.mdx +4 -4
  361. package/package.json +3 -3
  362. package/src/agent/production-agent.ts +13 -3
  363. package/src/cli/doctor.ts +6 -1
  364. package/src/client/AgentPanel.tsx +79 -41
  365. package/src/client/AssistantChat.tsx +71 -25
  366. package/src/client/FeedbackButton.tsx +33 -7
  367. package/src/client/MultiTabAssistantChat.tsx +6 -8
  368. package/src/client/agent-chat-adapter.ts +11 -2
  369. package/src/client/agent-page/AgentTabFrame.tsx +22 -3
  370. package/src/client/agent-page/AgentTabsPage.tsx +34 -19
  371. package/src/client/chat/message-components.tsx +43 -16
  372. package/src/client/chat/tool-call-display.tsx +30 -18
  373. package/src/client/chat/tool-render-registry.tsx +2 -0
  374. package/src/client/resources/McpConnectionSuggestion.tsx +19 -2
  375. package/src/client/resources/ResourceTree.tsx +7 -10
  376. package/src/client/resources/ResourcesPanel.tsx +33 -70
  377. package/src/client/resources/mcp-connection-resume.ts +107 -0
  378. package/src/client/resources/mcp-integration-catalog.ts +65 -12
  379. package/src/client/resources/mcp-integration-logos.ts +4 -0
  380. package/src/client/sse-event-processor.ts +50 -14
  381. package/src/client/use-db-sync.ts +16 -6
  382. package/src/connections/catalog.ts +7 -1
  383. package/src/eject/remote-mcp-presets.ts +37 -5
  384. package/src/guards/explicit-collab-access.ts +229 -0
  385. package/src/guards/index.ts +1 -0
  386. package/src/localization/default-messages.ts +54 -5
  387. package/src/mcp/connect-route.ts +34 -51
  388. package/src/provider-api/index.ts +1 -1
  389. package/src/server/collab-plugin.ts +137 -18
  390. package/src/server/index.ts +2 -0
  391. package/src/styles/agent-native.css +40 -0
  392. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  393. package/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  394. package/src/templates/chat/app/components/layout/Layout.tsx +1 -0
  395. package/src/templates/chat/app/components/layout/Sidebar.tsx +43 -67
  396. package/src/templates/chat/app/hooks/use-navigation-state.ts +2 -7
  397. package/src/templates/chat/app/routes/_index.tsx +8 -5
  398. package/src/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  399. package/src/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  400. package/src/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  401. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  402. package/src/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
  403. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  404. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  405. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  406. package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
  407. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  408. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Require generated apps to choose how collaboration events are scoped.
3
+ * Legacy `resourceType` callers remain valid during the access-option
4
+ * migration; this guard only reports implicit createCollabPlugin configs.
5
+ */
6
+
7
+ import {
8
+ lineColForOffset,
9
+ readFileSafe,
10
+ relPosix,
11
+ walk,
12
+ } from "./scan-utils.js";
13
+ import type { GuardFinding, GuardResult, GuardScanOptions } from "./types.js";
14
+
15
+ const SOURCE_FILE = /\.(?:[cm]?[jt]s|[jt]sx)$/;
16
+ const CALL = /\bcreateCollabPlugin\s*\(/g;
17
+ const EXPLICIT_ACCESS_KEYS = new Set(["access", "resourceType"]);
18
+ const FINDING_MESSAGE =
19
+ 'createCollabPlugin must declare access explicitly. Use access: { mode: "resource", resourceType: "..." } for scoped resources or access: { mode: "all-authenticated" } when deployment-wide delivery is intentional. Legacy resourceType is also accepted during migration.';
20
+
21
+ function maskCommentsAndStrings(contents: string): string {
22
+ const masked = contents.split("");
23
+ for (let i = 0; i < contents.length; i++) {
24
+ const char = contents[i];
25
+ if (char === '"' || char === "'" || char === "`") {
26
+ const end = skipQuoted(contents, i);
27
+ for (let cursor = i; cursor < end; cursor++) {
28
+ if (masked[cursor] !== "\n") masked[cursor] = " ";
29
+ }
30
+ i = end - 1;
31
+ continue;
32
+ }
33
+ if (contents.startsWith("//", i)) {
34
+ const newline = contents.indexOf("\n", i + 2);
35
+ const end = newline === -1 ? contents.length : newline;
36
+ for (let cursor = i; cursor < end; cursor++) masked[cursor] = " ";
37
+ i = end - 1;
38
+ continue;
39
+ }
40
+ if (contents.startsWith("/*", i)) {
41
+ const commentEnd = contents.indexOf("*/", i + 2);
42
+ const end = commentEnd === -1 ? contents.length : commentEnd + 2;
43
+ for (let cursor = i; cursor < end; cursor++) {
44
+ if (masked[cursor] !== "\n") masked[cursor] = " ";
45
+ }
46
+ i = end - 1;
47
+ }
48
+ }
49
+ return masked.join("");
50
+ }
51
+
52
+ function skipQuoted(contents: string, start: number): number {
53
+ const quote = contents[start];
54
+ let escaped = false;
55
+ for (let i = start + 1; i < contents.length; i++) {
56
+ const char = contents[i];
57
+ if (escaped) {
58
+ escaped = false;
59
+ } else if (char === "\\") {
60
+ escaped = true;
61
+ } else if (char === quote) {
62
+ return i + 1;
63
+ }
64
+ }
65
+ return contents.length;
66
+ }
67
+
68
+ function skipTrivia(contents: string, start: number): number {
69
+ let i = start;
70
+ while (i < contents.length) {
71
+ if (/\s/.test(contents[i] ?? "")) {
72
+ i++;
73
+ continue;
74
+ }
75
+ if (contents.startsWith("//", i)) {
76
+ const newline = contents.indexOf("\n", i + 2);
77
+ i = newline === -1 ? contents.length : newline + 1;
78
+ continue;
79
+ }
80
+ if (contents.startsWith("/*", i)) {
81
+ const end = contents.indexOf("*/", i + 2);
82
+ i = end === -1 ? contents.length : end + 2;
83
+ continue;
84
+ }
85
+ break;
86
+ }
87
+ return i;
88
+ }
89
+
90
+ function findObjectEnd(contents: string, start: number): number | null {
91
+ let depth = 0;
92
+ for (let i = start; i < contents.length; i++) {
93
+ const char = contents[i];
94
+ if (char === '"' || char === "'" || char === "`") {
95
+ i = skipQuoted(contents, i) - 1;
96
+ continue;
97
+ }
98
+ if (contents.startsWith("//", i)) {
99
+ const newline = contents.indexOf("\n", i + 2);
100
+ i = newline === -1 ? contents.length : newline;
101
+ continue;
102
+ }
103
+ if (contents.startsWith("/*", i)) {
104
+ const end = contents.indexOf("*/", i + 2);
105
+ i = end === -1 ? contents.length : end + 1;
106
+ continue;
107
+ }
108
+ if (char === "{") depth++;
109
+ if (char === "}" && --depth === 0) return i;
110
+ }
111
+ return null;
112
+ }
113
+
114
+ function hasExplicitAccessProperty(
115
+ contents: string,
116
+ objectStart: number,
117
+ objectEnd: number,
118
+ ): boolean {
119
+ let braceDepth = 0;
120
+ let bracketDepth = 0;
121
+ let parenDepth = 0;
122
+ let expectingProperty = true;
123
+
124
+ for (let i = objectStart + 1; i < objectEnd; i++) {
125
+ i = skipTrivia(contents, i);
126
+ if (i >= objectEnd) break;
127
+ const char = contents[i];
128
+
129
+ if (expectingProperty && (char === '"' || char === "'")) {
130
+ const tokenEnd = skipQuoted(contents, i);
131
+ const key = contents.slice(i + 1, tokenEnd - 1);
132
+ const afterKey = skipTrivia(contents, tokenEnd);
133
+ if (EXPLICIT_ACCESS_KEYS.has(key) && contents[afterKey] === ":") {
134
+ return true;
135
+ }
136
+ i = tokenEnd - 1;
137
+ expectingProperty = false;
138
+ continue;
139
+ }
140
+
141
+ if (expectingProperty && /[A-Za-z_$]/.test(char ?? "")) {
142
+ let tokenEnd = i + 1;
143
+ while (/[A-Za-z0-9_$]/.test(contents[tokenEnd] ?? "")) tokenEnd++;
144
+ const key = contents.slice(i, tokenEnd);
145
+ const afterKey = skipTrivia(contents, tokenEnd);
146
+ const delimiter = contents[afterKey];
147
+ if (
148
+ EXPLICIT_ACCESS_KEYS.has(key) &&
149
+ (delimiter === ":" || delimiter === "," || afterKey >= objectEnd)
150
+ ) {
151
+ return true;
152
+ }
153
+ i = tokenEnd - 1;
154
+ expectingProperty = false;
155
+ continue;
156
+ }
157
+
158
+ if (char === '"' || char === "'" || char === "`") {
159
+ i = skipQuoted(contents, i) - 1;
160
+ continue;
161
+ }
162
+ if (contents.startsWith("//", i) || contents.startsWith("/*", i)) {
163
+ i = skipTrivia(contents, i) - 1;
164
+ continue;
165
+ }
166
+
167
+ if (char === "{") braceDepth++;
168
+ else if (char === "}") braceDepth--;
169
+ else if (char === "[") bracketDepth++;
170
+ else if (char === "]") bracketDepth--;
171
+ else if (char === "(") parenDepth++;
172
+ else if (char === ")") parenDepth--;
173
+ else if (
174
+ char === "," &&
175
+ braceDepth === 0 &&
176
+ bracketDepth === 0 &&
177
+ parenDepth === 0
178
+ ) {
179
+ expectingProperty = true;
180
+ }
181
+ }
182
+
183
+ return false;
184
+ }
185
+
186
+ export function scanExplicitCollabAccess(
187
+ options: GuardScanOptions,
188
+ ): GuardResult {
189
+ const { root } = options;
190
+ const findings: GuardFinding[] = [];
191
+
192
+ for (const file of walk(root)) {
193
+ if (!SOURCE_FILE.test(file) || file.endsWith(".d.ts")) continue;
194
+ const contents = readFileSafe(file);
195
+ if (contents === null || !contents.includes("createCollabPlugin")) continue;
196
+ const searchable = maskCommentsAndStrings(contents);
197
+
198
+ CALL.lastIndex = 0;
199
+ let match: RegExpExecArray | null;
200
+ while ((match = CALL.exec(searchable)) !== null) {
201
+ const callStart = match.index;
202
+ const objectStart = skipTrivia(contents, CALL.lastIndex);
203
+ if (contents[objectStart] !== "{") {
204
+ if (contents[objectStart] === ")") {
205
+ const { line } = lineColForOffset(contents, callStart);
206
+ findings.push({
207
+ file: relPosix(root, file),
208
+ line,
209
+ message: FINDING_MESSAGE,
210
+ });
211
+ }
212
+ continue;
213
+ }
214
+ const objectEnd = findObjectEnd(contents, objectStart);
215
+ if (objectEnd === null) continue;
216
+ CALL.lastIndex = objectEnd + 1;
217
+
218
+ if (hasExplicitAccessProperty(contents, objectStart, objectEnd)) continue;
219
+ const { line } = lineColForOffset(contents, callStart);
220
+ findings.push({
221
+ file: relPosix(root, file),
222
+ line,
223
+ message: FINDING_MESSAGE,
224
+ });
225
+ }
226
+ }
227
+
228
+ return { name: "explicit-collab-access", findings };
229
+ }
@@ -12,6 +12,7 @@
12
12
 
13
13
  export { scanDbToolScoping } from "./db-tool-scoping.js";
14
14
  export type { DbToolScopingOptions } from "./db-tool-scoping.js";
15
+ export { scanExplicitCollabAccess } from "./explicit-collab-access.js";
15
16
  export { scanDrizzlePush } from "./no-drizzle-push.js";
16
17
  export { scanEnvCredentials } from "./no-env-credentials.js";
17
18
  export { scanEnvMutation } from "./no-env-mutation.js";
@@ -33,6 +33,47 @@ const messages = {
33
33
  openResourceSettings: "Open resource settings",
34
34
  backHome: "Back to home",
35
35
  },
36
+ agentResources: {
37
+ openDocs: "Open {{section}} documentation",
38
+ backToResources: "Back to agent resources",
39
+ createFile: {
40
+ nameLabel: "File name",
41
+ namePlaceholder: "notes/ideas",
42
+ menuDescription: "Add a new file by name",
43
+ },
44
+ files: {
45
+ title: "Files",
46
+ description: "Files the agent can read and write.",
47
+ },
48
+ instructions: {
49
+ title: "Instructions",
50
+ description:
51
+ "The rules, preferences, and project guidance that steer the agent.",
52
+ },
53
+ agents: {
54
+ title: "Agents",
55
+ description:
56
+ "Reusable profiles for focused sub-agents and delegated work.",
57
+ },
58
+ memory: {
59
+ title: "Memory",
60
+ description: "Durable notes the agent can retrieve across conversations.",
61
+ },
62
+ skills: {
63
+ title: "Skills",
64
+ description:
65
+ "Specialized instructions that give the agent repeatable abilities.",
66
+ },
67
+ learnings: {
68
+ title: "Learnings",
69
+ description:
70
+ "Corrections and patterns worth carrying forward for future work.",
71
+ },
72
+ remoteAgents: {
73
+ title: "Remote agents",
74
+ description: "Other agents this agent can call through A2A.",
75
+ },
76
+ },
36
77
  featureFlags: {
37
78
  title: "Feature flags",
38
79
  description: "Control staged capabilities without changing a deployment.",
@@ -276,7 +317,7 @@ const messages = {
276
317
  checkingAiConnection: "Checking AI connection...",
277
318
  voiceMode: {
278
319
  entryButtonLabel: "Use microphone",
279
- promptTitle: "Talk to your app",
320
+ promptTitle: "Use your voice",
280
321
  promptDescription:
281
322
  "Voice mode keeps listening while the agent navigates and takes actions.",
282
323
  setupTitle: "Set up voice mode",
@@ -285,8 +326,9 @@ const messages = {
285
326
  connectBuilder: "Connect Builder.io",
286
327
  useOpenAiKey: "Add your own keys",
287
328
  startWithOpenAiKey: "Start with OpenAI key",
288
- start: "Start voice mode",
289
- keepDictating: "Keep dictating",
329
+ start: "Real-time voice",
330
+ keepDictating: "Dictate",
331
+ rememberPreference: "Remember my preference",
290
332
  showChat: "Show chat",
291
333
  hideChat: "Hide chat",
292
334
  end: "End voice mode",
@@ -744,9 +786,9 @@ const messages = {
744
786
  connect: "Connect",
745
787
  connectWithOAuth: "Connect with OAuth",
746
788
  useApiToken: "Use API token",
747
- connectSuggestion: "Connect {{name}} to use this link in chat",
789
+ connectSuggestion: "Connect {{name}} to use it in chat",
748
790
  connectSuggestionWithApiToken:
749
- "Connect {{name}} with an API token to use this link in chat",
791
+ "Connect {{name}} with an API token to use it in chat",
750
792
  dismissSuggestion: "Dismiss integration suggestion",
751
793
  backToIntegrations: "Back to integrations",
752
794
  customTitle: "Add custom MCP server",
@@ -795,6 +837,13 @@ const messages = {
795
837
  setupNote:
796
838
  "Notion MCP uses user OAuth. Enterprise workspaces can audit MCP usage and allow or block clients; reconnect after admin policy changes.",
797
839
  },
840
+ granola: {
841
+ description: "Search meeting notes, transcripts, and action items.",
842
+ useCase:
843
+ "Meeting notes, recordings, transcripts, action items, follow-ups",
844
+ setupNote:
845
+ "Granola MCP uses browser OAuth. Authorize the signed-in Granola account and review which meeting notes and transcripts the agent can access.",
846
+ },
798
847
  semgrep: {
799
848
  description: "Scan code for security findings.",
800
849
  useCase: "Security scanning, vulnerability detection, code analysis",
@@ -467,10 +467,6 @@ function renderConnectPage(params: {
467
467
  });
468
468
  const safeMcpUrl = escapeHtml(mcpUrl);
469
469
  const connectTemplateValues = { appName, appUrl, mcpUrl, serverId };
470
- const brandMarkSvg = agentNativeMarkSvg(
471
- "brand-mark",
472
- "agent-native-connect-brand-gradient",
473
- );
474
470
  const flowMarkSvg = agentNativeMarkSvg(
475
471
  "flow-mark",
476
472
  "agent-native-connect-flow-gradient",
@@ -561,21 +557,6 @@ function renderConnectPage(params: {
561
557
  0 30px 90px rgba(0,0,0,0.5);
562
558
  padding: 1.25rem;
563
559
  }
564
- .topbar {
565
- display: flex; align-items: center; justify-content: space-between;
566
- gap: 0.75rem; margin-bottom: 1.75rem;
567
- }
568
- .brand-lockup {
569
- display: flex; align-items: center; gap: 0.55rem;
570
- color: var(--muted); font-size: 0.78rem; font-weight: 600;
571
- }
572
- .brand-mark { width: 18px; height: auto; display: block; }
573
- .app-pill {
574
- max-width: 50%; border: 1px solid var(--border);
575
- border-radius: 999px; padding: 0.28rem 0.55rem;
576
- color: var(--subtle); font-size: 0.72rem; line-height: 1;
577
- overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
578
- }
579
560
  .hero { padding: 0 0.75rem; text-align: center; }
580
561
  .flow {
581
562
  display: flex; align-items: center; justify-content: center;
@@ -597,11 +578,6 @@ function renderConnectPage(params: {
597
578
  background: linear-gradient(90deg, transparent, var(--border-strong), transparent);
598
579
  background-position: center;
599
580
  }
600
- .eyebrow {
601
- text-align: center; font-size: 0.72rem; font-weight: 600;
602
- letter-spacing: 0.08em; text-transform: uppercase;
603
- color: var(--subtle); margin-bottom: 0.55rem;
604
- }
605
581
  h1 {
606
582
  text-align: center; font-size: 1.45rem; font-weight: 680;
607
583
  line-height: 1.25; margin-bottom: 0.7rem;
@@ -714,8 +690,7 @@ function renderConnectPage(params: {
714
690
  .connections-title { font-weight: 600; color: var(--muted); }
715
691
  .connections-state {
716
692
  margin-left: auto; color: var(--subtle); font-size: 0.73rem;
717
- border: 1px solid var(--border); border-radius: 999px;
718
- padding: 0.18rem 0.45rem; line-height: 1;
693
+ line-height: 1;
719
694
  }
720
695
  .connections .chev {
721
696
  width: 7px; height: 7px; border-right: 1.5px solid currentColor;
@@ -738,8 +713,16 @@ function renderConnectPage(params: {
738
713
  margin-bottom: 0.9rem; display: none; line-height: 1.4; }
739
714
  .msg.err { display: block; color: var(--error); background: var(--error-bg);
740
715
  border: 1px solid rgba(252,165,165,0.16); }
741
- .msg.ok { display: block; color: var(--ok); background: var(--ok-bg);
716
+ .msg.ok { display: block; background: var(--ok-bg);
742
717
  border: 1px solid var(--ok-border); }
718
+ .msg-title {
719
+ display: block; color: var(--ok); font-size: 0.95rem;
720
+ font-weight: 700; line-height: 1.25;
721
+ }
722
+ .msg-copy {
723
+ display: block; color: rgba(134,239,172,0.72); font-size: 0.78rem;
724
+ line-height: 1.4; margin-top: 0.2rem;
725
+ }
743
726
  .result-panel { padding-top: 0.15rem; }
744
727
  .result-title {
745
728
  color: var(--text); font-size: 0.95rem; font-weight: 650;
@@ -757,9 +740,7 @@ function renderConnectPage(params: {
757
740
  body { align-items: flex-start; padding: 0.75rem; }
758
741
  .card { padding: 1rem; }
759
742
  .hero { padding: 0; }
760
- .topbar { margin-bottom: 1.35rem; }
761
743
  h1 { font-size: 1.3rem; }
762
- .app-pill { max-width: 46%; }
763
744
  pre { font-size: 0.72rem; }
764
745
  }
765
746
  /* MCP URL display + per-host tabs (the non-dev path). */
@@ -861,9 +842,6 @@ function renderConnectPage(params: {
861
842
  border-color: var(--ok-border) !important;
862
843
  }
863
844
  .static-token-mint .static-token-body { padding-top: 0.5rem; }
864
- .static-token-mint > summary .connections-state {
865
- font-style: normal;
866
- }
867
845
  @media (min-width: 560px) {
868
846
  .card { max-width: 580px; }
869
847
  }
@@ -872,17 +850,8 @@ function renderConnectPage(params: {
872
850
  </head>
873
851
  <body>
874
852
  <div class="card">
875
- <div class="topbar">
876
- <div class="brand-lockup">
877
- ${brandMarkSvg}
878
- <span>Agent Native</span>
879
- </div>
880
- <div class="app-pill" title="${safeApp}">${safeApp}</div>
881
- </div>
882
-
883
853
  <div class="hero">
884
- <!-- "Connect an external agent" is kept as the accessible consent label. -->
885
- <div class="flow" role="img" aria-label="Connect an external agent to ${safeApp}">
854
+ <div class="flow" role="img" aria-label="Authorize ${safeApp}">
886
855
  <span class="tile" aria-hidden="true">
887
856
  ${flowMarkSvg}
888
857
  </span>
@@ -892,7 +861,6 @@ function renderConnectPage(params: {
892
861
  </span>
893
862
  </div>
894
863
 
895
- <div class="eyebrow">Connect an external agent</div>
896
864
  <h1>${safeUserCode ? `Authorize ${safeApp} from your terminal?` : `Use ${safeApp} from your AI assistant`}</h1>
897
865
  <p class="identity">
898
866
  <span>Signed in as <strong>${safeEmail}</strong></span>
@@ -909,7 +877,6 @@ function renderConnectPage(params: {
909
877
  <details id="staticTokenMint" class="connections static-token-mint"${safeUserCode ? " open" : ""}>
910
878
  <summary>
911
879
  <span class="connections-title">${safeUserCode ? "Authorize this device" : MCP_STATIC_TOKEN_FALLBACK.title}</span>
912
- <span class="connections-state">${safeUserCode ? "From your terminal" : MCP_STATIC_TOKEN_FALLBACK.state}</span>
913
880
  <span class="chev" aria-hidden="true"></span>
914
881
  </summary>
915
882
  <div class="static-token-body">
@@ -939,7 +906,7 @@ function renderConnectPage(params: {
939
906
  <details id="connections" class="connections">
940
907
  <summary>
941
908
  <span class="connections-title">Existing connections</span>
942
- <span id="connectionsState" class="connections-state">Checking</span>
909
+ <span id="connectionsState" class="connections-state hidden" aria-live="polite"></span>
943
910
  <span class="chev" aria-hidden="true"></span>
944
911
  </summary>
945
912
  <div id="tokenList" class="token-list"><div class="empty-state">Checking connections...</div></div>
@@ -990,8 +957,20 @@ function renderConnectPage(params: {
990
957
  }, 1400);
991
958
  });
992
959
  });
993
- function showMsg(text, kind) {
994
- msgEl.textContent = text;
960
+ function showMsg(text, kind, title) {
961
+ msgEl.textContent = "";
962
+ if (title) {
963
+ var titleEl = document.createElement("strong");
964
+ titleEl.className = "msg-title";
965
+ titleEl.textContent = title;
966
+ msgEl.appendChild(titleEl);
967
+ var copyEl = document.createElement("span");
968
+ copyEl.className = "msg-copy";
969
+ copyEl.textContent = text;
970
+ msgEl.appendChild(copyEl);
971
+ } else {
972
+ msgEl.textContent = text;
973
+ }
995
974
  msgEl.className = "msg " + (kind || "err");
996
975
  }
997
976
  function clearMsg() { msgEl.className = "msg"; msgEl.textContent = ""; }
@@ -1039,19 +1018,22 @@ function renderConnectPage(params: {
1039
1018
  var res = await fetch(BASE + "/tokens", { credentials: "same-origin" });
1040
1019
  if (!res.ok) {
1041
1020
  connectionsStateEl.textContent = "Unavailable";
1021
+ connectionsStateEl.classList.remove("hidden");
1042
1022
  listEl.innerHTML = '<div class="empty-state">Could not load connections.</div>';
1043
1023
  return;
1044
1024
  }
1045
1025
  var data = await res.json();
1046
1026
  var tokens = (data && data.tokens) || [];
1047
1027
  if (!tokens.length) {
1048
- connectionsStateEl.textContent = "None";
1028
+ connectionsStateEl.textContent = "";
1029
+ connectionsStateEl.classList.add("hidden");
1049
1030
  connectionsEl.open = false;
1050
1031
  listEl.innerHTML = '<div class="empty-state">Created connections will appear here for revoking later.</div>';
1051
1032
  return;
1052
1033
  }
1053
1034
  var activeCount = tokens.filter(function (t) { return !t.revokedAt; }).length;
1054
- connectionsStateEl.textContent = activeCount === 1 ? "1 active" : activeCount + " active";
1035
+ connectionsStateEl.textContent = activeCount ? String(activeCount) : "";
1036
+ connectionsStateEl.classList.toggle("hidden", activeCount === 0);
1055
1037
  listEl.innerHTML = "";
1056
1038
  tokens.forEach(function (t) {
1057
1039
  var div = document.createElement("div");
@@ -1082,6 +1064,7 @@ function renderConnectPage(params: {
1082
1064
  });
1083
1065
  } catch (e) {
1084
1066
  connectionsStateEl.textContent = "Unavailable";
1067
+ connectionsStateEl.classList.remove("hidden");
1085
1068
  listEl.innerHTML = '<div class="empty-state">Could not load connections.</div>';
1086
1069
  }
1087
1070
  }
@@ -1098,7 +1081,7 @@ function renderConnectPage(params: {
1098
1081
  showMsg((a.data && a.data.error) || "Could not authorize this device code.");
1099
1082
  return;
1100
1083
  }
1101
- showMsg("Device authorized — finishing connection… you can return to your terminal.", "ok");
1084
+ showMsg("Finishing connection… you can return to your terminal.", "ok", "Device authorized");
1102
1085
  btn.classList.add("hidden");
1103
1086
  document.getElementById("mintForm").classList.add("hidden");
1104
1087
  var cc = document.getElementById("codeCallout");
@@ -1133,7 +1116,7 @@ function renderConnectPage(params: {
1133
1116
  });
1134
1117
  if (fresh.length > 0) {
1135
1118
  clearInterval(iv);
1136
- showMsg("Connected. This device can now act as you — manage or revoke it below.", "ok");
1119
+ showMsg("This device can now act as you — manage or revoke it below.", "ok", "Connected");
1137
1120
  loadTokens();
1138
1121
  return;
1139
1122
  }
@@ -1100,7 +1100,7 @@ const PROVIDER_CONFIGS: Record<ProviderApiId, ProviderApiConfig> = {
1100
1100
  docsUrls: ["https://developers.google.com/drive/api/reference/rest/v3"],
1101
1101
  specUrls: ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"],
1102
1102
  allowedHostSuffixes: ["googleapis.com"],
1103
- templateUses: ["brain", "content", "slides", "dispatch"],
1103
+ templateUses: ["brain", "content", "slides", "dispatch", "analytics"],
1104
1104
  examples: [
1105
1105
  { label: "List files", method: "GET", path: "/files" },
1106
1106
  { label: "Get file metadata", method: "GET", path: "/files/{fileId}" },