@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
@@ -14,9 +14,9 @@ import {
14
14
  ComposerPrimitive,
15
15
  useMessagePartReasoning,
16
16
  useMessagePartRuntime,
17
+ useAuiState,
17
18
  } from "@assistant-ui/react";
18
19
  import type { Attachment } from "@assistant-ui/react";
19
- import { useAuiState } from "@assistant-ui/store";
20
20
  import {
21
21
  IconX,
22
22
  IconCheck,
@@ -71,6 +71,7 @@ import {
71
71
  } from "./markdown-renderer.js";
72
72
  import {
73
73
  ToolCallFallback,
74
+ ToolActivityPresentation,
74
75
  FilesChangedSummary,
75
76
  ASSISTANT_VISIBLE_TOOL_CALL_LIMIT,
76
77
  ChatRunningContext,
@@ -862,7 +863,7 @@ export function assistantMessageHasUnresolvedTool(content: unknown): boolean {
862
863
  // Only the last assistant message may shimmer as "the currently running
863
864
  // tool" — an older message's dangling unresolved tool-call must never
864
865
  // shimmer once a later run is active.
865
- export function computeLatestRunningToolCallId(
866
+ export function computeActiveTailToolCallId(
866
867
  content: ContentPart[] | undefined,
867
868
  { chatRunning, isLast }: { chatRunning: boolean; isLast: boolean },
868
869
  ): string | null {
@@ -870,9 +871,7 @@ export function computeLatestRunningToolCallId(
870
871
  return (
871
872
  content?.reduce(
872
873
  (latestToolCallId, part) =>
873
- part.type === "tool-call" &&
874
- part.result === undefined &&
875
- (chatRunning || part.activity === true)
874
+ part.type === "tool-call" && (chatRunning || part.activity === true)
876
875
  ? part.toolCallId
877
876
  : latestToolCallId,
878
877
  null as string | null,
@@ -900,6 +899,18 @@ export function shouldShowAssistantMessageFooter({
900
899
  return statusIsTerminal;
901
900
  }
902
901
 
902
+ export function shouldShowMissingFinalResponse({
903
+ statusIsTerminal,
904
+ hasAssistantText,
905
+ hasUnresolvedTool,
906
+ }: {
907
+ statusIsTerminal: boolean;
908
+ hasAssistantText: boolean;
909
+ hasUnresolvedTool: boolean;
910
+ }): boolean {
911
+ return statusIsTerminal && !hasAssistantText && !hasUnresolvedTool;
912
+ }
913
+
903
914
  export function shouldShowAssistantWorkSummary({
904
915
  isLast,
905
916
  isComplete,
@@ -1061,12 +1072,18 @@ export function AssistantMessage() {
1061
1072
  const hasRenderableContent = assistantMessageHasRenderableContent(msg);
1062
1073
  const hasUnresolvedTool = assistantMessageHasUnresolvedTool(msg.content);
1063
1074
  const responseConnectionText = messageTextFromContent(msg.content);
1075
+ const statusIsTerminal = assistantMessageStatusIsTerminal(msg);
1076
+ const showMissingFinalResponse = shouldShowMissingFinalResponse({
1077
+ statusIsTerminal,
1078
+ hasAssistantText: responseConnectionText.trim().length > 0,
1079
+ hasUnresolvedTool,
1080
+ });
1064
1081
  const responseConnectionContext = latestUserMessageText(thread.messages);
1065
1082
  const isComplete = shouldShowAssistantMessageFooter({
1066
1083
  isLast,
1067
1084
  chatRunning,
1068
1085
  hasRenderableContent,
1069
- statusIsTerminal: assistantMessageStatusIsTerminal(msg),
1086
+ statusIsTerminal,
1070
1087
  hasUnresolvedTool,
1071
1088
  });
1072
1089
  const cpCtx = React.useContext(CheckpointContext);
@@ -1178,7 +1195,7 @@ export function AssistantMessage() {
1178
1195
  (p.type !== "tool-call" || p.activity !== true) &&
1179
1196
  isCollapsibleAssistantWorkPart(p),
1180
1197
  );
1181
- const latestRunningToolCallId = computeLatestRunningToolCallId(msgContent, {
1198
+ const activeTailToolCallId = computeActiveTailToolCallId(msgContent, {
1182
1199
  chatRunning,
1183
1200
  isLast,
1184
1201
  });
@@ -1226,21 +1243,31 @@ export function AssistantMessage() {
1226
1243
  case "reasoning":
1227
1244
  return <ReasoningMessagePart />;
1228
1245
  case "tool-call":
1229
- return (
1230
- part.toolUI ?? (
1231
- <ToolCallFallback
1232
- {...part}
1233
- isLatestRunning={
1234
- part.toolCallId === latestRunningToolCallId
1235
- }
1236
- />
1237
- )
1246
+ return part.toolUI ? (
1247
+ <ToolActivityPresentation
1248
+ toolName={part.toolName}
1249
+ isRunning={part.status?.type === "running"}
1250
+ isActiveTail={part.toolCallId === activeTailToolCallId}
1251
+ >
1252
+ {part.toolUI}
1253
+ </ToolActivityPresentation>
1254
+ ) : (
1255
+ <ToolCallFallback
1256
+ {...part}
1257
+ isActiveTail={part.toolCallId === activeTailToolCallId}
1258
+ />
1238
1259
  );
1239
1260
  default:
1240
1261
  return null;
1241
1262
  }
1242
1263
  }}
1243
1264
  </MessagePrimitive.GroupedParts>
1265
+ {showMissingFinalResponse && (
1266
+ <p role="status" className="text-muted-foreground">
1267
+ The agent stopped without sending a final message. Ask it to
1268
+ continue or retry.
1269
+ </p>
1270
+ )}
1244
1271
  {isComplete && hasCodeAgentTools && msgContent && (
1245
1272
  <FilesChangedSummary parts={msgContent} />
1246
1273
  )}
@@ -94,20 +94,22 @@ export const ApprovalContext = React.createContext<ApprovalContextValue | null>(
94
94
 
95
95
  export const TOOL_LONG_RUNNING_HINT_DELAY_MS = 45_000;
96
96
 
97
- function ToolLongRunningHintShell({
97
+ export function ToolActivityPresentation({
98
98
  toolName,
99
99
  isRunning,
100
+ isActiveTail,
100
101
  children,
101
102
  }: {
102
103
  toolName: string;
103
104
  isRunning: boolean;
105
+ isActiveTail: boolean;
104
106
  children: React.ReactNode;
105
107
  }) {
106
108
  const [showLongRunningHint, setShowLongRunningHint] = useState(false);
107
- // useState initializer runs once at mount: a row that mounts already
108
- // resolved never animates, while a tool appended during an active stream
109
- // mounts running and animates in.
110
- const [animateEntry] = useState(isRunning);
109
+ // A batched update can first reveal a tool with its result already attached.
110
+ // Presentation follows the active chat tail rather than execution state so
111
+ // that newly revealed completed tools still get their entrance motion.
112
+ const [animateEntry] = useState(isActiveTail);
111
113
 
112
114
  useEffect(() => {
113
115
  if (!isRunning) {
@@ -125,10 +127,10 @@ function ToolLongRunningHintShell({
125
127
  <div
126
128
  className={cn(
127
129
  "agent-tool-call",
128
- animateEntry &&
129
- "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:slide-in-from-bottom-1 motion-safe:duration-200 motion-safe:ease-[var(--ease-out-strong)]",
130
+ animateEntry && "agent-tool-call--entering",
130
131
  )}
131
132
  data-running={isRunning ? "true" : undefined}
133
+ data-active-tail={isActiveTail ? "true" : undefined}
132
134
  >
133
135
  {children}
134
136
  {isRunning && showLongRunningHint && (
@@ -554,6 +556,7 @@ export function ToolCallDisplay({
554
556
  approval,
555
557
  repeatCount,
556
558
  isLatestRunning = isRunning,
559
+ isActiveTail,
557
560
  }: {
558
561
  toolName: string;
559
562
  argsText?: string;
@@ -565,16 +568,24 @@ export function ToolCallDisplay({
565
568
  structuredMeta?: Record<string, unknown>;
566
569
  approval?: { approvalKey: string; dismissed?: boolean };
567
570
  repeatCount?: number;
571
+ /** The latest tool shown while the overall chat turn is still active. */
572
+ isActiveTail?: boolean;
573
+ /** @deprecated Use isActiveTail. */
568
574
  isLatestRunning?: boolean;
569
575
  }) {
576
+ const showActiveTail = isActiveTail ?? isLatestRunning;
570
577
  // Delegate to bespoke cells when structured metadata is present.
571
578
  // These must be separate components so hook order in ToolCallDisplayGeneric
572
579
  // is always stable (no conditional hook calls).
573
580
  const toolKind = structuredMeta?.toolKind as string | undefined;
574
581
  const wrapToolDisplay = (children: React.ReactNode) => (
575
- <ToolLongRunningHintShell toolName={toolName} isRunning={isRunning}>
582
+ <ToolActivityPresentation
583
+ toolName={toolName}
584
+ isRunning={isRunning}
585
+ isActiveTail={showActiveTail}
586
+ >
576
587
  {children}
577
- </ToolLongRunningHintShell>
588
+ </ToolActivityPresentation>
578
589
  );
579
590
  if (toolKind === "bash") {
580
591
  return wrapToolDisplay(
@@ -616,7 +627,7 @@ export function ToolCallDisplay({
616
627
  mcpApp={mcpApp}
617
628
  chatUI={chatUI}
618
629
  isRunning={isRunning}
619
- isLatestRunning={isLatestRunning}
630
+ isActiveTail={showActiveTail}
620
631
  approval={approval}
621
632
  repeatCount={repeatCount}
622
633
  />,
@@ -631,7 +642,7 @@ function ToolCallDisplayGeneric({
631
642
  mcpApp,
632
643
  chatUI,
633
644
  isRunning,
634
- isLatestRunning,
645
+ isActiveTail,
635
646
  approval,
636
647
  repeatCount,
637
648
  }: {
@@ -642,7 +653,7 @@ function ToolCallDisplayGeneric({
642
653
  mcpApp?: AgentMcpAppPayload;
643
654
  chatUI?: ActionChatUIConfig;
644
655
  isRunning: boolean;
645
- isLatestRunning: boolean;
656
+ isActiveTail: boolean;
646
657
  approval?: { approvalKey: string; dismissed?: boolean };
647
658
  repeatCount?: number;
648
659
  }) {
@@ -734,6 +745,7 @@ function ToolCallDisplayGeneric({
734
745
  resultText: result,
735
746
  resultJson: parsedResult,
736
747
  isRunning,
748
+ isActiveTail,
737
749
  chatUI,
738
750
  };
739
751
  const skipRegistryRenderer =
@@ -805,7 +817,7 @@ function ToolCallDisplayGeneric({
805
817
  <span
806
818
  className={cn(
807
819
  "min-w-0 truncate font-normal",
808
- isRunning && isLatestRunning && "agent-running-shimmer",
820
+ isActiveTail && "agent-running-shimmer",
809
821
  )}
810
822
  >
811
823
  {displayName}
@@ -888,6 +900,7 @@ export function ToolCallFallback({
888
900
  approval?: { approvalKey: string; dismissed?: boolean };
889
901
  repeatCount?: number;
890
902
  isLatestRunning?: boolean;
903
+ isActiveTail?: boolean;
891
904
  }) {
892
905
  const chatRunning = React.useContext(ChatRunningContext);
893
906
  const isRunning =
@@ -908,6 +921,7 @@ export function ToolCallFallback({
908
921
  chatUI={rest.chatUI}
909
922
  structuredMeta={rest.structuredMeta}
910
923
  isRunning={isRunning}
924
+ isActiveTail={rest.isActiveTail}
911
925
  isLatestRunning={rest.isLatestRunning}
912
926
  approval={rest.approval}
913
927
  repeatCount={rest.repeatCount}
@@ -935,11 +949,9 @@ export function ReconnectStreamMessage({
935
949
  content.at(-1)?.type === "text" ? content.length - 1 : -1;
936
950
  const streamingReasoningPartIndex =
937
951
  content.at(-1)?.type === "reasoning" ? content.length - 1 : -1;
938
- const latestRunningToolIndex = content.reduce(
952
+ const latestActiveToolIndex = content.reduce(
939
953
  (latestIndex, part, index) =>
940
- part.type === "tool-call" &&
941
- part.result === undefined &&
942
- (chatRunning || part.activity === true)
954
+ part.type === "tool-call" && (chatRunning || part.activity === true)
943
955
  ? index
944
956
  : latestIndex,
945
957
  -1,
@@ -983,7 +995,7 @@ export function ReconnectStreamMessage({
983
995
  isRunning={
984
996
  part.result === undefined && (chatRunning || part.activity === true)
985
997
  }
986
- isLatestRunning={i === latestRunningToolIndex}
998
+ isActiveTail={i === latestActiveToolIndex}
987
999
  approval={part.approval}
988
1000
  repeatCount={part.repeatCount}
989
1001
  />
@@ -8,6 +8,8 @@ export interface ToolRendererContext {
8
8
  resultText?: string;
9
9
  resultJson: unknown;
10
10
  isRunning: boolean;
11
+ /** True while this is the newest tool representing an active chat turn. */
12
+ isActiveTail?: boolean;
11
13
  chatUI?: ActionChatUIConfig;
12
14
  }
13
15
 
@@ -9,6 +9,11 @@ import { useEffect, useMemo, useState } from "react";
9
9
  import { agentNativePath } from "../api-path.js";
10
10
  import { openAgentSettings } from "../CommandMenu.js";
11
11
  import { useT } from "../i18n.js";
12
+ import {
13
+ clearMcpConnectionResume,
14
+ notifyMcpConnectionComplete,
15
+ saveMcpConnectionResume,
16
+ } from "./mcp-connection-resume.js";
12
17
  import {
13
18
  buildMcpOAuthStartUrl,
14
19
  findMcpIntegrationForText,
@@ -144,6 +149,7 @@ export function McpConnectionSuggestion({
144
149
  }
145
150
 
146
151
  if (canStartOAuth(integration)) {
152
+ saveMcpConnectionResume(variant === "response" ? contextText : text);
147
153
  window.location.assign(
148
154
  agentNativePath(
149
155
  buildMcpOAuthStartUrl({
@@ -162,6 +168,7 @@ export function McpConnectionSuggestion({
162
168
  integration.authMode === "none" &&
163
169
  integration.connectionMode === "direct"
164
170
  ) {
171
+ saveMcpConnectionResume(variant === "response" ? contextText : text);
165
172
  setConnecting(true);
166
173
  try {
167
174
  await createMcpServer.mutateAsync({
@@ -171,7 +178,9 @@ export function McpConnectionSuggestion({
171
178
  description: integration.description,
172
179
  });
173
180
  setDismissedId(integration.id);
181
+ notifyMcpConnectionComplete();
174
182
  } catch (cause) {
183
+ clearMcpConnectionResume();
175
184
  setError(
176
185
  cause instanceof Error ? cause.message : t("mcpIntegrations.failed"),
177
186
  );
@@ -181,6 +190,7 @@ export function McpConnectionSuggestion({
181
190
  return;
182
191
  }
183
192
 
193
+ saveMcpConnectionResume(variant === "response" ? contextText : text);
184
194
  setDialogOpen(true);
185
195
  };
186
196
 
@@ -262,13 +272,20 @@ export function McpConnectionSuggestion({
262
272
  )}
263
273
  <McpIntegrationDialog
264
274
  open={dialogOpen}
265
- onOpenChange={setDialogOpen}
275
+ onOpenChange={(open) => {
276
+ setDialogOpen(open);
277
+ if (!open) clearMcpConnectionResume();
278
+ }}
266
279
  initialIntegrationId={integration.id}
267
280
  defaultScope="user"
268
281
  canCreateOrgMcp={false}
269
282
  hasOrg={Boolean(mcpServersQuery.data?.orgId)}
270
283
  onCreateMcpServer={(args) => createMcpServer.mutateAsync(args)}
271
- onCreated={() => setDismissedId(integration.id)}
284
+ onCreated={() => {
285
+ setDismissedId(integration.id);
286
+ saveMcpConnectionResume(variant === "response" ? contextText : text);
287
+ notifyMcpConnectionComplete();
288
+ }}
272
289
  integrations={integrations}
273
290
  />
274
291
  </>
@@ -849,16 +849,13 @@ export function ResourceTree({
849
849
  )}
850
850
 
851
851
  {isEmpty && !creating && !isLoading && (
852
- <div className="flex items-start gap-2 border-y border-border/60 px-2 py-4">
853
- <IconFile className="mt-0.5 size-3.5 shrink-0 text-muted-foreground" />
854
- <div className="flex flex-col items-start gap-2">
855
- <p className="text-xs text-muted-foreground">
856
- {variant === "collection"
857
- ? "No resources in this collection yet"
858
- : "No files yet"}
859
- </p>
860
- {emptyStateAction}
861
- </div>
852
+ <div className="flex flex-col items-start border-y border-border/60 px-2 py-5">
853
+ <p className="ps-5 text-xs text-muted-foreground">
854
+ {variant === "collection"
855
+ ? "No resources in this collection yet"
856
+ : "No files yet"}
857
+ </p>
858
+ {emptyStateAction && <div className="mt-4">{emptyStateAction}</div>}
862
859
  </div>
863
860
  )}
864
861
  </div>
@@ -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}