@agent-native/core 0.99.3 → 0.100.1

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 (382) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +21 -0
  3. package/corpus/core/docs/content/agent-surfaces.mdx +43 -0
  4. package/corpus/core/docs/content/external-agents.mdx +11 -0
  5. package/corpus/core/docs/content/locales/ar-SA/agent-surfaces.mdx +30 -0
  6. package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +9 -0
  7. package/corpus/core/docs/content/locales/de-DE/agent-surfaces.mdx +34 -0
  8. package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +10 -0
  9. package/corpus/core/docs/content/locales/es-ES/agent-surfaces.mdx +34 -0
  10. package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +10 -0
  11. package/corpus/core/docs/content/locales/fr-FR/agent-surfaces.mdx +34 -0
  12. package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +11 -0
  13. package/corpus/core/docs/content/locales/hi-IN/agent-surfaces.mdx +31 -0
  14. package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +9 -0
  15. package/corpus/core/docs/content/locales/ja-JP/agent-surfaces.mdx +32 -0
  16. package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +10 -0
  17. package/corpus/core/docs/content/locales/ko-KR/agent-surfaces.mdx +32 -0
  18. package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +9 -0
  19. package/corpus/core/docs/content/locales/pt-BR/agent-surfaces.mdx +33 -0
  20. package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +10 -0
  21. package/corpus/core/docs/content/locales/zh-CN/agent-surfaces.mdx +29 -0
  22. package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +8 -0
  23. package/corpus/core/docs/content/locales/zh-TW/agent-surfaces.mdx +29 -0
  24. package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +8 -0
  25. package/corpus/core/package.json +1 -1
  26. package/corpus/core/src/agent/context-xray/actions/context-evict.ts +11 -0
  27. package/corpus/core/src/agent/context-xray/actions/context-pin.ts +11 -0
  28. package/corpus/core/src/agent/context-xray/actions/context-preview-get.ts +134 -0
  29. package/corpus/core/src/agent/context-xray/actions/context-restore.ts +11 -0
  30. package/corpus/core/src/agent/context-xray/actions/errors.ts +20 -0
  31. package/corpus/core/src/agent/context-xray/manifest.ts +106 -7
  32. package/corpus/core/src/agent/engine/context-directives-transform.ts +5 -1
  33. package/corpus/core/src/agent/production-agent.ts +100 -38
  34. package/corpus/core/src/agent/run-loop-with-resume.ts +7 -2
  35. package/corpus/core/src/client/AgentPanel.tsx +35 -8
  36. package/corpus/core/src/client/agent-page/AgentContextTab.tsx +501 -0
  37. package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +370 -0
  38. package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +1084 -0
  39. package/corpus/core/src/client/agent-page/types.ts +18 -0
  40. package/corpus/core/src/client/agent-page/use-jobs.ts +150 -0
  41. package/corpus/core/src/client/context-xray/ContextMeter.tsx +22 -5
  42. package/corpus/core/src/client/context-xray/ContextTreemap.tsx +16 -1
  43. package/corpus/core/src/client/context-xray/ContextXRayPanel.tsx +168 -3
  44. package/corpus/core/src/client/context-xray/format.ts +6 -0
  45. package/corpus/core/src/client/index.ts +6 -0
  46. package/corpus/core/src/client/resources/ResourcesPanel.tsx +51 -23
  47. package/corpus/core/src/client/settings/AutomationsSection.tsx +407 -387
  48. package/corpus/core/src/jobs/actions/list-recurring-jobs.ts +105 -0
  49. package/corpus/core/src/jobs/actions/manage-recurring-job.ts +85 -0
  50. package/corpus/core/src/jobs/tools.ts +1 -1
  51. package/corpus/core/src/localization/default-messages.ts +110 -0
  52. package/corpus/core/src/mcp/build-server.ts +1 -0
  53. package/corpus/core/src/mcp/connect-route.ts +62 -65
  54. package/corpus/core/src/server/action-discovery.ts +23 -0
  55. package/corpus/core/src/server/agent-chat/prompt-resources.ts +174 -2
  56. package/corpus/core/src/server/agent-chat-plugin.ts +175 -2
  57. package/corpus/core/src/server/auth.ts +1 -7
  58. package/corpus/core/src/server/google-oauth.ts +1 -7
  59. package/corpus/core/src/server/workspace-oauth.ts +31 -0
  60. package/corpus/core/src/shared/context-xray.ts +84 -1
  61. package/corpus/core/src/shared/mcp-connect-content.ts +130 -0
  62. package/corpus/core/src/templates/default/app/routes/_index.tsx +11 -0
  63. package/corpus/core/src/templates/default/app/routes/agent.tsx +33 -0
  64. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  65. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +59 -0
  66. package/corpus/core/src/templates/workspace-core/.agents/skills/context-xray/SKILL.md +25 -0
  67. package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +7 -0
  68. package/corpus/core/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +9 -0
  69. package/corpus/core/src/triggers/actions/list-automations.ts +99 -0
  70. package/corpus/core/src/triggers/actions/manage-automation.ts +78 -0
  71. package/corpus/templates/analytics/actions/data-source-status.ts +33 -15
  72. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
  73. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +149 -24
  74. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +17 -0
  75. package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -0
  76. package/corpus/templates/analytics/app/components/layout/Layout.tsx +1 -0
  77. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +8 -0
  78. package/corpus/templates/analytics/app/i18n/zh-TW.ts +1 -0
  79. package/corpus/templates/analytics/app/i18n-data.ts +1 -0
  80. package/corpus/templates/analytics/app/routes/agent.tsx +5 -0
  81. package/corpus/templates/analytics/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  82. package/corpus/templates/analytics/changelog/2026-07-13-analytics-answers-can-use-built-in-first-party-event-data.md +6 -0
  83. package/corpus/templates/analytics/changelog/2026-07-13-chart-legends-can-filter-to-one-series-or-hide-a-series-on-h.md +6 -0
  84. package/corpus/templates/analytics/changelog/2026-07-13-gpt-5-6-luna-answers-now-recover-normally-instead-of-showing.md +6 -0
  85. package/corpus/templates/analytics/server/plugins/agent-chat.ts +11 -2
  86. package/corpus/templates/assets/app/components/layout/Header.tsx +1 -0
  87. package/corpus/templates/assets/app/components/layout/Layout.tsx +1 -0
  88. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +2 -0
  89. package/corpus/templates/assets/app/routes/agent.tsx +5 -0
  90. package/corpus/templates/assets/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  91. package/corpus/templates/brain/app/components/layout/Layout.tsx +1 -0
  92. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +4 -1
  93. package/corpus/templates/brain/app/lib/brain.ts +11 -0
  94. package/corpus/templates/brain/app/root.tsx +15 -1
  95. package/corpus/templates/brain/app/routes/agent.tsx +11 -0
  96. package/corpus/templates/brain/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  97. package/corpus/templates/calendar/AGENTS.md +9 -0
  98. package/corpus/templates/calendar/actions/list-events.ts +659 -44
  99. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +1 -0
  100. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +2 -0
  101. package/corpus/templates/calendar/app/root.tsx +17 -1
  102. package/corpus/templates/calendar/app/routes/_app.agent.tsx +25 -0
  103. package/corpus/templates/calendar/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  104. package/corpus/templates/calendar/changelog/2026-07-13-calendar-inventory-reads-report-source-coverage.md +6 -0
  105. package/corpus/templates/calendar/server/lib/calendar-connector-catalog.ts +8 -0
  106. package/corpus/templates/calendar/server/lib/google-calendar.ts +173 -51
  107. package/corpus/templates/calendar/server/lib/ical-fetcher.ts +13 -2
  108. package/corpus/templates/calendar/server/plugins/agent-chat.ts +5 -3
  109. package/corpus/templates/calendar/shared/api.ts +2 -0
  110. package/corpus/templates/chat/app/components/layout/Header.tsx +1 -0
  111. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -0
  112. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +7 -0
  113. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +3 -0
  114. package/corpus/templates/chat/app/root.tsx +24 -2
  115. package/corpus/templates/chat/app/routes/agent.tsx +15 -0
  116. package/corpus/templates/chat/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  117. package/corpus/templates/clips/app/components/library/library-layout.tsx +8 -0
  118. package/corpus/templates/clips/app/i18n/ar-SA.ts +2 -0
  119. package/corpus/templates/clips/app/i18n/de-DE.ts +2 -0
  120. package/corpus/templates/clips/app/i18n/en-US.ts +2 -0
  121. package/corpus/templates/clips/app/i18n/es-ES.ts +2 -0
  122. package/corpus/templates/clips/app/i18n/fr-FR.ts +2 -0
  123. package/corpus/templates/clips/app/i18n/hi-IN.ts +2 -0
  124. package/corpus/templates/clips/app/i18n/ja-JP.ts +2 -0
  125. package/corpus/templates/clips/app/i18n/ko-KR.ts +2 -0
  126. package/corpus/templates/clips/app/i18n/pt-BR.ts +2 -0
  127. package/corpus/templates/clips/app/i18n/zh-CN.ts +2 -0
  128. package/corpus/templates/clips/app/i18n/zh-TW.ts +2 -0
  129. package/corpus/templates/clips/app/root.tsx +7 -1
  130. package/corpus/templates/clips/app/routes/_app.agent.tsx +15 -0
  131. package/corpus/templates/clips/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  132. package/corpus/templates/content/app/components/layout/Layout.tsx +1 -0
  133. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +36 -0
  134. package/corpus/templates/content/app/i18n/zh-TW.ts +2 -0
  135. package/corpus/templates/content/app/i18n-data.ts +44 -6
  136. package/corpus/templates/content/app/root.tsx +8 -0
  137. package/corpus/templates/content/app/routes/_app.agent.tsx +15 -0
  138. package/corpus/templates/content/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  139. package/corpus/templates/design/app/components/layout/Layout.tsx +1 -0
  140. package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -0
  141. package/corpus/templates/design/app/i18n/zh-TW.ts +2 -0
  142. package/corpus/templates/design/app/i18n-data.ts +20 -0
  143. package/corpus/templates/design/app/root.tsx +7 -1
  144. package/corpus/templates/design/app/routes/agent.tsx +15 -0
  145. package/corpus/templates/design/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  146. package/corpus/templates/dispatch/app/dispatch-extensions.tsx +10 -1
  147. package/corpus/templates/dispatch/app/i18n/zh-TW.ts +2 -0
  148. package/corpus/templates/dispatch/app/i18n-data.ts +20 -0
  149. package/corpus/templates/dispatch/app/root.tsx +7 -2
  150. package/corpus/templates/dispatch/app/routes/agent.tsx +18 -0
  151. package/corpus/templates/dispatch/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  152. package/corpus/templates/forms/app/components/layout/Layout.tsx +1 -0
  153. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +35 -0
  154. package/corpus/templates/forms/app/i18n/ar-SA.ts +2 -0
  155. package/corpus/templates/forms/app/i18n/de-DE.ts +2 -0
  156. package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
  157. package/corpus/templates/forms/app/i18n/es-ES.ts +2 -0
  158. package/corpus/templates/forms/app/i18n/fr-FR.ts +2 -0
  159. package/corpus/templates/forms/app/i18n/hi-IN.ts +2 -0
  160. package/corpus/templates/forms/app/i18n/ja-JP.ts +2 -0
  161. package/corpus/templates/forms/app/i18n/ko-KR.ts +2 -0
  162. package/corpus/templates/forms/app/i18n/pt-BR.ts +2 -0
  163. package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
  164. package/corpus/templates/forms/app/i18n/zh-TW.ts +2 -0
  165. package/corpus/templates/forms/app/root.tsx +6 -1
  166. package/corpus/templates/forms/app/routes/_app.agent.tsx +15 -0
  167. package/corpus/templates/forms/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  168. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +14 -2
  169. package/corpus/templates/macros/app/components/layout/Header.tsx +1 -0
  170. package/corpus/templates/macros/app/root.tsx +17 -2
  171. package/corpus/templates/macros/app/routes/agent.tsx +15 -0
  172. package/corpus/templates/macros/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  173. package/corpus/templates/mail/AGENTS.md +12 -0
  174. package/corpus/templates/mail/actions/list-emails.ts +486 -4
  175. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +42 -0
  176. package/corpus/templates/mail/app/components/layout/CommandPalette.tsx +6 -0
  177. package/corpus/templates/mail/app/routes/agent.tsx +15 -0
  178. package/corpus/templates/mail/changelog/2026-07-13-coverage-aware-connected-inbox-inventory.md +6 -0
  179. package/corpus/templates/mail/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  180. package/corpus/templates/mail/server/db/schema.ts +17 -0
  181. package/corpus/templates/mail/server/lib/google-auth.ts +33 -5
  182. package/corpus/templates/mail/server/lib/inventory-cursor.ts +406 -0
  183. package/corpus/templates/mail/server/lib/list-inbox-emails.ts +21 -2
  184. package/corpus/templates/mail/server/lib/mail-connector-catalog.ts +8 -0
  185. package/corpus/templates/mail/server/plugins/agent-chat.ts +4 -9
  186. package/corpus/templates/mail/server/plugins/db.ts +20 -0
  187. package/corpus/templates/plan/app/components/layout/Header.tsx +1 -0
  188. package/corpus/templates/plan/app/components/layout/Layout.tsx +1 -0
  189. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +2 -0
  190. package/corpus/templates/plan/app/root.tsx +8 -0
  191. package/corpus/templates/plan/app/routes/agent.tsx +15 -0
  192. package/corpus/templates/plan/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  193. package/corpus/templates/slides/app/components/layout/Header.tsx +1 -0
  194. package/corpus/templates/slides/app/components/layout/Layout.tsx +1 -0
  195. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +2 -0
  196. package/corpus/templates/slides/app/root.tsx +10 -1
  197. package/corpus/templates/slides/app/routes/agent.tsx +15 -0
  198. package/corpus/templates/slides/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  199. package/dist/agent/context-xray/actions/context-evict.js +5 -2
  200. package/dist/agent/context-xray/actions/context-evict.js.map +1 -1
  201. package/dist/agent/context-xray/actions/context-pin.js +5 -2
  202. package/dist/agent/context-xray/actions/context-pin.js.map +1 -1
  203. package/dist/agent/context-xray/actions/context-preview-get.d.ts +17 -0
  204. package/dist/agent/context-xray/actions/context-preview-get.d.ts.map +1 -0
  205. package/dist/agent/context-xray/actions/context-preview-get.js +94 -0
  206. package/dist/agent/context-xray/actions/context-preview-get.js.map +1 -0
  207. package/dist/agent/context-xray/actions/context-restore.js +5 -2
  208. package/dist/agent/context-xray/actions/context-restore.js.map +1 -1
  209. package/dist/agent/context-xray/actions/errors.d.ts +3 -0
  210. package/dist/agent/context-xray/actions/errors.d.ts.map +1 -1
  211. package/dist/agent/context-xray/actions/errors.js +6 -0
  212. package/dist/agent/context-xray/actions/errors.js.map +1 -1
  213. package/dist/agent/context-xray/manifest.d.ts +18 -1
  214. package/dist/agent/context-xray/manifest.d.ts.map +1 -1
  215. package/dist/agent/context-xray/manifest.js +68 -6
  216. package/dist/agent/context-xray/manifest.js.map +1 -1
  217. package/dist/agent/engine/context-directives-transform.d.ts +2 -0
  218. package/dist/agent/engine/context-directives-transform.d.ts.map +1 -1
  219. package/dist/agent/engine/context-directives-transform.js +2 -1
  220. package/dist/agent/engine/context-directives-transform.js.map +1 -1
  221. package/dist/agent/production-agent.d.ts +15 -0
  222. package/dist/agent/production-agent.d.ts.map +1 -1
  223. package/dist/agent/production-agent.js +74 -36
  224. package/dist/agent/production-agent.js.map +1 -1
  225. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  226. package/dist/agent/run-loop-with-resume.js +6 -3
  227. package/dist/agent/run-loop-with-resume.js.map +1 -1
  228. package/dist/client/AgentPanel.d.ts +5 -1
  229. package/dist/client/AgentPanel.d.ts.map +1 -1
  230. package/dist/client/AgentPanel.js +9 -11
  231. package/dist/client/AgentPanel.js.map +1 -1
  232. package/dist/client/agent-page/AgentContextTab.d.ts +5 -0
  233. package/dist/client/agent-page/AgentContextTab.d.ts.map +1 -0
  234. package/dist/client/agent-page/AgentContextTab.js +202 -0
  235. package/dist/client/agent-page/AgentContextTab.js.map +1 -0
  236. package/dist/client/agent-page/AgentJobsTab.d.ts +3 -0
  237. package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -0
  238. package/dist/client/agent-page/AgentJobsTab.js +98 -0
  239. package/dist/client/agent-page/AgentJobsTab.js.map +1 -0
  240. package/dist/client/agent-page/AgentTabsPage.d.ts +20 -0
  241. package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -0
  242. package/dist/client/agent-page/AgentTabsPage.js +420 -0
  243. package/dist/client/agent-page/AgentTabsPage.js.map +1 -0
  244. package/dist/client/agent-page/types.d.ts +17 -0
  245. package/dist/client/agent-page/types.d.ts.map +1 -0
  246. package/dist/client/agent-page/types.js +9 -0
  247. package/dist/client/agent-page/types.js.map +1 -0
  248. package/dist/client/agent-page/use-jobs.d.ts +61 -0
  249. package/dist/client/agent-page/use-jobs.d.ts.map +1 -0
  250. package/dist/client/agent-page/use-jobs.js +71 -0
  251. package/dist/client/agent-page/use-jobs.js.map +1 -0
  252. package/dist/client/context-xray/ContextMeter.d.ts +3 -1
  253. package/dist/client/context-xray/ContextMeter.d.ts.map +1 -1
  254. package/dist/client/context-xray/ContextMeter.js +14 -5
  255. package/dist/client/context-xray/ContextMeter.js.map +1 -1
  256. package/dist/client/context-xray/ContextTreemap.d.ts +3 -2
  257. package/dist/client/context-xray/ContextTreemap.d.ts.map +1 -1
  258. package/dist/client/context-xray/ContextTreemap.js +9 -1
  259. package/dist/client/context-xray/ContextTreemap.js.map +1 -1
  260. package/dist/client/context-xray/ContextXRayPanel.d.ts.map +1 -1
  261. package/dist/client/context-xray/ContextXRayPanel.js +95 -20
  262. package/dist/client/context-xray/ContextXRayPanel.js.map +1 -1
  263. package/dist/client/context-xray/format.d.ts.map +1 -1
  264. package/dist/client/context-xray/format.js +12 -0
  265. package/dist/client/context-xray/format.js.map +1 -1
  266. package/dist/client/index.d.ts +3 -0
  267. package/dist/client/index.d.ts.map +1 -1
  268. package/dist/client/index.js +1 -0
  269. package/dist/client/index.js.map +1 -1
  270. package/dist/client/resources/ResourcesPanel.d.ts +9 -1
  271. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  272. package/dist/client/resources/ResourcesPanel.js +26 -10
  273. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  274. package/dist/client/settings/AutomationsSection.d.ts +9 -0
  275. package/dist/client/settings/AutomationsSection.d.ts.map +1 -1
  276. package/dist/client/settings/AutomationsSection.js +128 -147
  277. package/dist/client/settings/AutomationsSection.js.map +1 -1
  278. package/dist/collab/routes.d.ts +1 -1
  279. package/dist/collab/struct-routes.d.ts +1 -1
  280. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  281. package/dist/jobs/actions/list-recurring-jobs.d.ts +21 -0
  282. package/dist/jobs/actions/list-recurring-jobs.d.ts.map +1 -0
  283. package/dist/jobs/actions/list-recurring-jobs.js +74 -0
  284. package/dist/jobs/actions/list-recurring-jobs.js.map +1 -0
  285. package/dist/jobs/actions/manage-recurring-job.d.ts +18 -0
  286. package/dist/jobs/actions/manage-recurring-job.d.ts.map +1 -0
  287. package/dist/jobs/actions/manage-recurring-job.js +68 -0
  288. package/dist/jobs/actions/manage-recurring-job.js.map +1 -0
  289. package/dist/jobs/tools.d.ts +13 -0
  290. package/dist/jobs/tools.d.ts.map +1 -1
  291. package/dist/jobs/tools.js +1 -1
  292. package/dist/jobs/tools.js.map +1 -1
  293. package/dist/localization/default-messages.d.ts +96 -0
  294. package/dist/localization/default-messages.d.ts.map +1 -1
  295. package/dist/localization/default-messages.js +96 -0
  296. package/dist/localization/default-messages.js.map +1 -1
  297. package/dist/mcp/build-server.d.ts.map +1 -1
  298. package/dist/mcp/build-server.js +1 -0
  299. package/dist/mcp/build-server.js.map +1 -1
  300. package/dist/mcp/connect-route.d.ts.map +1 -1
  301. package/dist/mcp/connect-route.js +44 -59
  302. package/dist/mcp/connect-route.js.map +1 -1
  303. package/dist/notifications/routes.d.ts +1 -1
  304. package/dist/observability/routes.d.ts +5 -5
  305. package/dist/progress/routes.d.ts +1 -1
  306. package/dist/resources/handlers.d.ts +3 -3
  307. package/dist/secrets/routes.d.ts +9 -9
  308. package/dist/server/action-discovery.d.ts.map +1 -1
  309. package/dist/server/action-discovery.js +23 -0
  310. package/dist/server/action-discovery.js.map +1 -1
  311. package/dist/server/agent-chat/prompt-resources.d.ts +14 -0
  312. package/dist/server/agent-chat/prompt-resources.d.ts.map +1 -1
  313. package/dist/server/agent-chat/prompt-resources.js +139 -2
  314. package/dist/server/agent-chat/prompt-resources.js.map +1 -1
  315. package/dist/server/agent-chat-plugin.d.ts +1 -0
  316. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  317. package/dist/server/agent-chat-plugin.js +136 -3
  318. package/dist/server/agent-chat-plugin.js.map +1 -1
  319. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  320. package/dist/server/auth.d.ts.map +1 -1
  321. package/dist/server/auth.js +1 -4
  322. package/dist/server/auth.js.map +1 -1
  323. package/dist/server/google-oauth.d.ts.map +1 -1
  324. package/dist/server/google-oauth.js +1 -4
  325. package/dist/server/google-oauth.js.map +1 -1
  326. package/dist/server/workspace-oauth.d.ts +11 -0
  327. package/dist/server/workspace-oauth.d.ts.map +1 -0
  328. package/dist/server/workspace-oauth.js +25 -0
  329. package/dist/server/workspace-oauth.js.map +1 -0
  330. package/dist/shared/context-xray.d.ts +45 -1
  331. package/dist/shared/context-xray.d.ts.map +1 -1
  332. package/dist/shared/context-xray.js +12 -0
  333. package/dist/shared/context-xray.js.map +1 -1
  334. package/dist/shared/mcp-connect-content.d.ts +37 -0
  335. package/dist/shared/mcp-connect-content.d.ts.map +1 -0
  336. package/dist/shared/mcp-connect-content.js +92 -0
  337. package/dist/shared/mcp-connect-content.js.map +1 -0
  338. package/dist/templates/default/app/routes/_index.tsx +11 -0
  339. package/dist/templates/default/app/routes/agent.tsx +33 -0
  340. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  341. package/dist/templates/workspace-core/.agents/skills/agent-page/SKILL.md +59 -0
  342. package/dist/templates/workspace-core/.agents/skills/context-xray/SKILL.md +25 -0
  343. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +7 -0
  344. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +9 -0
  345. package/dist/triggers/actions/list-automations.d.ts +24 -0
  346. package/dist/triggers/actions/list-automations.d.ts.map +1 -0
  347. package/dist/triggers/actions/list-automations.js +72 -0
  348. package/dist/triggers/actions/list-automations.js.map +1 -0
  349. package/dist/triggers/actions/manage-automation.d.ts +18 -0
  350. package/dist/triggers/actions/manage-automation.d.ts.map +1 -0
  351. package/dist/triggers/actions/manage-automation.js +60 -0
  352. package/dist/triggers/actions/manage-automation.js.map +1 -0
  353. package/docs/content/agent-surfaces.mdx +43 -0
  354. package/docs/content/external-agents.mdx +11 -0
  355. package/docs/content/locales/ar-SA/agent-surfaces.mdx +30 -0
  356. package/docs/content/locales/ar-SA/external-agents.mdx +9 -0
  357. package/docs/content/locales/de-DE/agent-surfaces.mdx +34 -0
  358. package/docs/content/locales/de-DE/external-agents.mdx +10 -0
  359. package/docs/content/locales/es-ES/agent-surfaces.mdx +34 -0
  360. package/docs/content/locales/es-ES/external-agents.mdx +10 -0
  361. package/docs/content/locales/fr-FR/agent-surfaces.mdx +34 -0
  362. package/docs/content/locales/fr-FR/external-agents.mdx +11 -0
  363. package/docs/content/locales/hi-IN/agent-surfaces.mdx +31 -0
  364. package/docs/content/locales/hi-IN/external-agents.mdx +9 -0
  365. package/docs/content/locales/ja-JP/agent-surfaces.mdx +32 -0
  366. package/docs/content/locales/ja-JP/external-agents.mdx +10 -0
  367. package/docs/content/locales/ko-KR/agent-surfaces.mdx +32 -0
  368. package/docs/content/locales/ko-KR/external-agents.mdx +9 -0
  369. package/docs/content/locales/pt-BR/agent-surfaces.mdx +33 -0
  370. package/docs/content/locales/pt-BR/external-agents.mdx +10 -0
  371. package/docs/content/locales/zh-CN/agent-surfaces.mdx +29 -0
  372. package/docs/content/locales/zh-CN/external-agents.mdx +8 -0
  373. package/docs/content/locales/zh-TW/agent-surfaces.mdx +29 -0
  374. package/docs/content/locales/zh-TW/external-agents.mdx +8 -0
  375. package/package.json +1 -1
  376. package/src/templates/default/app/routes/_index.tsx +11 -0
  377. package/src/templates/default/app/routes/agent.tsx +33 -0
  378. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  379. package/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +59 -0
  380. package/src/templates/workspace-core/.agents/skills/context-xray/SKILL.md +25 -0
  381. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +7 -0
  382. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +9 -0
@@ -392,6 +392,7 @@ export function AppLayout({ children }: AppLayoutProps) {
392
392
  position="right"
393
393
  defaultOpen
394
394
  emptyStateText={t("agentSidebar.emptyState")}
395
+ agentPageHref="/agent"
395
396
  suggestions={[
396
397
  t("agentSidebar.suggestions.today"),
397
398
  t("agentSidebar.suggestions.findSlot"),
@@ -7,6 +7,7 @@ import {
7
7
  import { ExtensionsSidebarSection } from "@agent-native/core/client/extensions";
8
8
  import { OrgSwitcher } from "@agent-native/core/client/org";
9
9
  import {
10
+ IconBrain,
10
11
  IconCalendar,
11
12
  IconSettings,
12
13
  IconLink,
@@ -97,6 +98,7 @@ const navItems = [
97
98
  labelKey: "navigation.bookingLinks",
98
99
  icon: IconLink,
99
100
  },
101
+ { path: "/agent", labelKey: "settings.agentTitle", icon: IconBrain },
100
102
  { path: "/settings", labelKey: "navigation.settings", icon: IconSettings },
101
103
  ];
102
104
 
@@ -15,7 +15,7 @@ import {
15
15
  useT,
16
16
  } from "@agent-native/core/client";
17
17
  import { resolveLocaleFromRequest } from "@agent-native/core/server";
18
- import { IconSun, IconMoon } from "@tabler/icons-react";
18
+ import { IconBrain, IconSun, IconMoon } from "@tabler/icons-react";
19
19
  import { useQueryClient } from "@tanstack/react-query";
20
20
  import { useTheme } from "next-themes";
21
21
  import { useCallback, useState } from "react";
@@ -25,6 +25,7 @@ import {
25
25
  Outlet,
26
26
  Scripts,
27
27
  ScrollRestoration,
28
+ useNavigate,
28
29
  useLoaderData,
29
30
  useLocation,
30
31
  useRouteLoaderData,
@@ -197,6 +198,7 @@ function isPublicBookingPath(pathname: string): boolean {
197
198
 
198
199
  function AppContent() {
199
200
  const [cmdkOpen, setCmdkOpen] = useState(false);
201
+ const navigate = useNavigate();
200
202
  const t = useT();
201
203
  useCommandMenuShortcut(useCallback(() => setCmdkOpen(true), []));
202
204
  return (
@@ -212,6 +214,20 @@ function AppContent() {
212
214
  <CommandMenu.Item onSelect={() => {}}>
213
215
  {t("root.commandSearch")}
214
216
  </CommandMenu.Item>
217
+ <CommandMenu.Item
218
+ onSelect={() => navigate("/agent")}
219
+ keywords={[
220
+ "agent",
221
+ "context",
222
+ "files",
223
+ "connections",
224
+ "jobs",
225
+ "access",
226
+ ]}
227
+ >
228
+ <IconBrain size={16} />
229
+ {t("settings.openAgentSettings")}
230
+ </CommandMenu.Item>
215
231
  </CommandMenu.Group>
216
232
  <CommandMenu.Group heading={t("root.commandAppearance")}>
217
233
  <ThemeToggleItem />
@@ -0,0 +1,25 @@
1
+ import { AgentTabsPage, useT } from "@agent-native/core/client";
2
+ import { useMemo } from "react";
3
+
4
+ import { useAppHeaderControls } from "@/components/layout/AppLayout";
5
+ import { messagesByLocale } from "@/i18n-data";
6
+
7
+ export function meta() {
8
+ return [{ title: messagesByLocale["en-US"].settings.agentTitle }];
9
+ }
10
+
11
+ export default function AgentRoute() {
12
+ const t = useT();
13
+ const controls = useMemo(
14
+ () => ({
15
+ left: (
16
+ <h1 className="truncate text-lg font-semibold tracking-tight">
17
+ {t("settings.agentTitle")}
18
+ </h1>
19
+ ),
20
+ }),
21
+ [t],
22
+ );
23
+ useAppHeaderControls(controls);
24
+ return <AgentTabsPage appName="Calendar" />;
25
+ }
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-07-13
4
+ ---
5
+
6
+ A full Agent page now brings context, files, connections, jobs, and external access together
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-13
4
+ ---
5
+
6
+ Direct Calendar reads now show which connected sources were covered, including partial connection or feed failures.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Deliberately narrow authenticated MCP surface for Calendar.
3
+ *
4
+ * External callers may read calendar coverage through list-events. Other
5
+ * actions remain available through the in-app agent, ask_app, or an explicit
6
+ * full-catalog connection; tool-search alone never makes them callable.
7
+ */
8
+ export const CALENDAR_CONNECTOR_CATALOG = ["list-events"] as const;
@@ -190,6 +190,22 @@ const LIST_EVENT_TYPES = [
190
190
  "outOfOffice",
191
191
  "workingLocation",
192
192
  ];
193
+ const GOOGLE_READ_CONCURRENCY = 4;
194
+
195
+ async function mapWithConcurrency<T, R>(
196
+ values: T[],
197
+ map: (value: T) => Promise<R>,
198
+ ): Promise<R[]> {
199
+ const results: R[] = [];
200
+ for (let index = 0; index < values.length; index += GOOGLE_READ_CONCURRENCY) {
201
+ results.push(
202
+ ...(await Promise.all(
203
+ values.slice(index, index + GOOGLE_READ_CONCURRENCY).map(map),
204
+ )),
205
+ );
206
+ }
207
+ return results;
208
+ }
193
209
 
194
210
  function mapReminders(
195
211
  event: any,
@@ -684,6 +700,85 @@ export async function getClientsWithErrors(forEmail?: string): Promise<{
684
700
  return { clients, errors };
685
701
  }
686
702
 
703
+ /**
704
+ * Resolve a caller's connected Google accounts without refreshing tokens. This
705
+ * is intentionally separate from `getClientsWithErrors`: callers that accept
706
+ * an account filter must reject an unowned requested account before they do
707
+ * provider work for any account.
708
+ */
709
+ export async function getOwnedAccountEmails(
710
+ forEmail?: string,
711
+ ): Promise<string[]> {
712
+ if (!forEmail) return [];
713
+ const accounts = await listOAuthAccountsByOwner("google", forEmail);
714
+ return accounts.map((account) => account.accountId);
715
+ }
716
+
717
+ export async function getClientsForAccountsWithErrors(
718
+ forEmail: string | undefined,
719
+ accountEmails?: string[],
720
+ ): Promise<{
721
+ clients: Array<{ email: string; accessToken: string }>;
722
+ errors: Array<{ email: string; error: string }>;
723
+ requestedAccounts: string[];
724
+ resolvedAccounts: string[];
725
+ }> {
726
+ if (!forEmail) {
727
+ return {
728
+ clients: [],
729
+ errors: [],
730
+ requestedAccounts: [],
731
+ resolvedAccounts: [],
732
+ };
733
+ }
734
+ const accounts = await listOAuthAccountsByOwner("google", forEmail);
735
+ const byNormalized = new Map(
736
+ accounts.map((account) => [
737
+ account.accountId.trim().toLowerCase(),
738
+ account,
739
+ ]),
740
+ );
741
+ const requestedAccounts = Array.from(
742
+ new Set(
743
+ (accountEmails ?? accounts.map((account) => account.accountId))
744
+ .map((email) => email.trim().toLowerCase())
745
+ .filter(Boolean),
746
+ ),
747
+ );
748
+ const unowned = requestedAccounts.filter((email) => !byNormalized.has(email));
749
+ if (unowned.length > 0) {
750
+ throw new Error(
751
+ `Google Calendar account not connected for this user: ${unowned.join(", ")}`,
752
+ );
753
+ }
754
+ const selected = requestedAccounts.map((email) => byNormalized.get(email)!);
755
+ const clients: Array<{ email: string; accessToken: string }> = [];
756
+ const errors: Array<{ email: string; error: string }> = [];
757
+ await mapWithConcurrency(selected, async (account) => {
758
+ try {
759
+ const accessToken = await getValidAccessToken(
760
+ account.accountId,
761
+ account.tokens as unknown as GoogleTokens,
762
+ forEmail,
763
+ );
764
+ clients.push({ email: account.accountId, accessToken });
765
+ } catch (err: any) {
766
+ errors.push({
767
+ email: account.accountId,
768
+ error: err?.message || "Unknown refresh error",
769
+ });
770
+ }
771
+ });
772
+ clients.sort((a, b) => a.email.localeCompare(b.email));
773
+ errors.sort((a, b) => a.email.localeCompare(b.email));
774
+ return {
775
+ clients,
776
+ errors,
777
+ requestedAccounts,
778
+ resolvedAccounts: selected.map((account) => account.accountId),
779
+ };
780
+ }
781
+
687
782
  export async function isConnected(forEmail?: string): Promise<boolean> {
688
783
  return isOAuthConnected("google", forEmail ?? "");
689
784
  }
@@ -779,12 +874,13 @@ export async function listEvents(
779
874
  timeMin: string,
780
875
  timeMax: string,
781
876
  forEmail?: string,
877
+ options: { accountEmails?: string[]; maxResults?: number } = {},
782
878
  ): Promise<{
783
879
  events: CalendarEvent[];
784
880
  errors: Array<{ email: string; error: string }>;
785
881
  }> {
786
882
  const { clients, errors: refreshErrors } =
787
- await getClientsWithErrors(forEmail);
883
+ await getClientsForAccountsWithErrors(forEmail, options.accountEmails);
788
884
  // Seed with refresh failures so a fully-dead connection (every account's
789
885
  // refresh_token revoked or invalidated by a GOOGLE_CLIENT_ID rotation)
790
886
  // reaches the caller — otherwise the result is indistinguishable from
@@ -792,8 +888,9 @@ export async function listEvents(
792
888
  const errors: Array<{ email: string; error: string }> = [...refreshErrors];
793
889
  if (clients.length === 0) return { events: [], errors };
794
890
 
795
- const allResults = await Promise.all(
796
- clients.map(async ({ email, accessToken }) => {
891
+ const allResults = await mapWithConcurrency(
892
+ clients,
893
+ async ({ email, accessToken }) => {
797
894
  try {
798
895
  const events: any[] = [];
799
896
  let pageToken: string | undefined;
@@ -803,7 +900,7 @@ export async function listEvents(
803
900
  timeMax,
804
901
  singleEvents: true,
805
902
  orderBy: "startTime",
806
- maxResults: 2500,
903
+ maxResults: options.maxResults ?? 2500,
807
904
  pageToken,
808
905
  eventTypes: LIST_EVENT_TYPES,
809
906
  });
@@ -883,7 +980,7 @@ export async function listEvents(
883
980
  errors.push({ email, error: error.message });
884
981
  return [];
885
982
  }
886
- }),
983
+ },
887
984
  );
888
985
 
889
986
  return { events: allResults.flat(), errors };
@@ -993,64 +1090,89 @@ export async function listOverlayEvents(
993
1090
  timeMax: string,
994
1091
  overlayEmails: string[],
995
1092
  forEmail?: string,
1093
+ options: { accountEmails?: string[] } = {},
996
1094
  ): Promise<{
997
1095
  events: CalendarEvent[];
998
1096
  errors: Array<{ email: string; error: string }>;
1097
+ accountErrors: Array<{ email: string; error: string }>;
999
1098
  }> {
1000
1099
  const { clients, errors: refreshErrors } =
1001
- await getClientsWithErrors(forEmail);
1002
- const errors: Array<{ email: string; error: string }> = [...refreshErrors];
1003
- if (clients.length === 0) return { events: [], errors };
1004
-
1005
- // Use the first available token to query other people's calendars
1006
- const { accessToken } = clients[0];
1100
+ await getClientsForAccountsWithErrors(forEmail, options.accountEmails);
1101
+ const errors: Array<{ email: string; error: string }> = [];
1102
+ if (clients.length === 0) {
1103
+ const message =
1104
+ refreshErrors[0]?.error ?? "Google Calendar is not connected";
1105
+ return {
1106
+ events: [],
1107
+ errors: overlayEmails.map((email) => ({ email, error: message })),
1108
+ accountErrors: refreshErrors,
1109
+ };
1110
+ }
1007
1111
 
1008
1112
  const allResults = await Promise.all(
1009
1113
  overlayEmails.map(async (overlayEmail) => {
1010
- try {
1011
- const response = await calendarListEvents(accessToken, overlayEmail, {
1012
- timeMin,
1013
- timeMax,
1014
- singleEvents: true,
1015
- orderBy: "startTime",
1016
- eventTypes: LIST_EVENT_TYPES,
1017
- });
1018
-
1019
- const events = response.items || [];
1020
- return events.map((event: any) => ({
1021
- id: `overlay-${overlayEmail}-${event.id}`,
1022
- title: event.summary || "Busy",
1023
- description: event.description || "",
1024
- start: event.start?.dateTime || event.start?.date || "",
1025
- end: event.end?.dateTime || event.end?.date || "",
1026
- startTimeZone: event.start?.timeZone || undefined,
1027
- endTimeZone: event.end?.timeZone || undefined,
1028
- location: event.location || "",
1029
- allDay: !event.start?.dateTime,
1030
- source: "google" as const,
1031
- googleEventId: event.id || undefined,
1032
- htmlLink: event.htmlLink || undefined,
1033
- eventType: event.eventType || "default",
1034
- accountEmail: undefined,
1035
- overlayEmail,
1036
- ...mapColor(event),
1037
- attendees: mapAttendees(event),
1038
- organizer: mapOrganizer(event),
1039
- createdAt: event.created || new Date().toISOString(),
1040
- updatedAt: event.updated || new Date().toISOString(),
1041
- }));
1042
- } catch (error: any) {
1043
- console.error(
1044
- `[listOverlayEvents] Error fetching ${overlayEmail}:`,
1045
- error.message,
1046
- );
1047
- errors.push({ email: overlayEmail, error: error.message });
1048
- return [];
1114
+ const accessErrors: string[] = [];
1115
+ for (const client of clients) {
1116
+ try {
1117
+ const events: any[] = [];
1118
+ let pageToken: string | undefined;
1119
+ do {
1120
+ const response = await calendarListEvents(
1121
+ client.accessToken,
1122
+ overlayEmail,
1123
+ {
1124
+ timeMin,
1125
+ timeMax,
1126
+ singleEvents: true,
1127
+ orderBy: "startTime",
1128
+ eventTypes: LIST_EVENT_TYPES,
1129
+ pageToken,
1130
+ },
1131
+ );
1132
+ events.push(...(response.items || []));
1133
+ pageToken = response.nextPageToken;
1134
+ } while (pageToken);
1135
+ return events.map((event: any) => ({
1136
+ id: `overlay-${overlayEmail}-${event.id}`,
1137
+ title: event.summary || "Busy",
1138
+ description: event.description || "",
1139
+ start: event.start?.dateTime || event.start?.date || "",
1140
+ end: event.end?.dateTime || event.end?.date || "",
1141
+ startTimeZone: event.start?.timeZone || undefined,
1142
+ endTimeZone: event.end?.timeZone || undefined,
1143
+ location: event.location || "",
1144
+ allDay: !event.start?.dateTime,
1145
+ source: "google" as const,
1146
+ googleEventId: event.id || undefined,
1147
+ htmlLink: event.htmlLink || undefined,
1148
+ eventType: event.eventType || "default",
1149
+ accountEmail: client.email,
1150
+ overlayEmail,
1151
+ ...mapColor(event),
1152
+ attendees: mapAttendees(event),
1153
+ organizer: mapOrganizer(event),
1154
+ createdAt: event.created || new Date().toISOString(),
1155
+ updatedAt: event.updated || new Date().toISOString(),
1156
+ }));
1157
+ } catch (error: any) {
1158
+ const message = error?.message || "Unable to read overlay calendar";
1159
+ console.error(
1160
+ `[listOverlayEvents] Error fetching ${overlayEmail} via ${client.email}:`,
1161
+ message,
1162
+ );
1163
+ accessErrors.push(`${client.email}: ${message}`);
1164
+ }
1049
1165
  }
1166
+
1167
+ errors.push({
1168
+ email: overlayEmail,
1169
+ error: `No selected Google account could read this overlay (${accessErrors.join("; ")})`,
1170
+ });
1171
+ return [];
1050
1172
  }),
1051
1173
  );
1052
1174
 
1053
- return { events: allResults.flat(), errors };
1175
+ return { events: allResults.flat(), errors, accountErrors: refreshErrors };
1054
1176
  }
1055
1177
 
1056
1178
  export async function getEvent(
@@ -273,6 +273,7 @@ export async function fetchICalEvents(
273
273
  color: string,
274
274
  from: string,
275
275
  to: string,
276
+ options: { throwOnError?: boolean } = {},
276
277
  ): Promise<CalendarEvent[]> {
277
278
  const httpUrl = normalizeUrl(url);
278
279
 
@@ -281,6 +282,7 @@ export async function fetchICalEvents(
281
282
  } catch {
282
283
  // Silently degrade — never echo the URL or reason back. A loud error
283
284
  // helps an attacker map internal infrastructure via probe responses.
285
+ if (options.throwOnError) throw new Error("ICS feed URL is not allowed");
284
286
  return [];
285
287
  }
286
288
 
@@ -294,9 +296,17 @@ export async function fetchICalEvents(
294
296
  },
295
297
  { maxRedirects: 3 },
296
298
  );
297
- if (!response.ok) return [];
299
+ if (!response.ok) {
300
+ if (options.throwOnError) throw new Error("ICS feed request failed");
301
+ return [];
302
+ }
298
303
  icsText = await response.text();
299
- } catch {
304
+ } catch (error) {
305
+ if (options.throwOnError) {
306
+ throw error instanceof Error
307
+ ? error
308
+ : new Error("ICS feed request failed");
309
+ }
300
310
  return [];
301
311
  }
302
312
 
@@ -323,6 +333,7 @@ export async function fetchICalEvents(
323
333
  location: e.location || "",
324
334
  allDay: e.allDay,
325
335
  source: "ical" as const,
336
+ sourceId: feedId,
326
337
  color,
327
338
  createdAt: now,
328
339
  updatedAt: now,
@@ -13,6 +13,7 @@ import { z } from "zod";
13
13
  // why `autoDiscoverActions` on its own produces 404s for action routes in
14
14
  // production.
15
15
  import actionsRegistry from "../../.generated/actions-registry.js";
16
+ import { CALENDAR_CONNECTOR_CATALOG } from "../lib/calendar-connector-catalog.js";
16
17
 
17
18
  // ---------------------------------------------------------------------------
18
19
  // Register calendar event-bus events
@@ -83,6 +84,7 @@ const INITIAL_TOOL_NAMES = [
83
84
  export default createAgentChatPlugin({
84
85
  appId: "calendar",
85
86
  initialToolNames: INITIAL_TOOL_NAMES,
87
+ connectorCatalog: [...CALENDAR_CONNECTOR_CATALOG],
86
88
  // Enable sandboxed JavaScript execution so Calendar agents can fetch,
87
89
  // paginate, and reduce provider data through providerFetch() without us
88
90
  // hardcoding one action per Google Calendar / CRM endpoint.
@@ -102,7 +104,7 @@ Google Calendar events are NOT stored in the local database. They are fetched li
102
104
 
103
105
  Provider-specific Calendar actions are shortcuts, not limits. If a first-class action cannot express the exact Google Calendar/CRM endpoint, calendar id, filter, request body, pagination mode, attendee search, recurrence field, or API version needed, call \`provider-api-catalog\` and \`provider-api-docs\` as needed, then call \`provider-api-request\` against the provider's real HTTP API. Use this raw provider API escape hatch instead of weakening the answer, broadening filters, or claiming Calendar cannot do something the underlying API can do.
104
106
 
105
- - \`pnpm action view-screen\` — See what the user is looking at (current view, date, events). ALWAYS run this first.
107
+ - \`pnpm action view-screen\` — See the visible UI state (current view, date, selected event). Use it for questions about what the user is looking at, not as a prerequisite for deterministic schedule reads.
106
108
  - \`pnpm action list-events --from YYYY-MM-DD --to YYYY-MM-DD\` — List events from Google Calendar. The --to date is exclusive, so use tomorrow for today's events.
107
109
  - \`pnpm action search-events --query "term" --from YYYY-MM-DD --to YYYY-MM-DD\` — Convenience bounded search by title, attendees, organizer, location, or description. For relationship history, all-calendar discovery, exact attendee/domain search, or custom pagination, prefer provider-api-request with provider=google_calendar.
108
110
  - \`pnpm action provider-api-catalog\` / \`provider-api-docs\` / \`provider-api-request\` — Inspect and call the real Google Calendar, Apollo, Gong, HubSpot, and Pylon APIs directly. For Google Calendar events.list pagination use provider=google_calendar, path=/calendars/primary/events, query={...}, fetchAllPages={cursorPath:"nextPageToken",cursorParam:"pageToken",itemsPath:"items"}. For large relationship-history scans, pass stageAs and pagination={nextCursorPath:"nextPageToken",cursorParam:"pageToken",maxPages:N} with itemsPath="items", then use query-staged-dataset.
@@ -125,14 +127,14 @@ Provider-specific Calendar actions are shortcuts, not limits. If a first-class a
125
127
  Use \`create-event\` or \`update-event --colorId 1..11\` when the user wants one specific Google Calendar event color changed. Use \`update-calendar-visual-preferences\` when the user wants broad app-layer display rules such as color-coding meetings by internal/external, 1:1/group, focus time, or one display color for all Google events.
126
128
 
127
129
  ## Google Connection Check
128
- Before answering schedule questions, run view-screen first for context, then use list-events for the requested date range even if the user is currently on Settings, Booking Links, or another non-calendar page. Do not infer a Google Calendar connection problem just because the current page is Settings. Only ask the user to reconnect Google if list-events or the explicit Google status reports an auth/connection error.
130
+ For broad, deterministic schedule reads, call list-events directly for the requested date range in inventory/coverage mode, even when UI context is irrelevant or the user is on Settings, Booking Links, or another non-calendar page. Do not require view-screen as a connection preflight, and do not infer a Google Calendar connection problem from the current screen. Only ask the user to reconnect Google if list-events or the explicit Google status reports an auth/connection error.
129
131
 
130
132
  When the user explicitly asks you to connect or reconnect Google Calendar, call \`connect-google-calendar\` and give them the returned link. Do not call raw HTTP/fetch/web-request against \`/_agent-native/google/auth-url\`; that route depends on the user's browser session and will return 401 from the agent backend.
131
133
 
132
134
  For relationship-history or frequency questions such as "who have I met at Adobe?" or "how often do I meet with Mattel?", prefer the raw Google Calendar API through provider-api-request so you can choose the exact timeMin/timeMax, q, calendarId, maxResults, and pageToken behavior. Stage large paginated results before analysis. Do not conclude there are no recurring meetings from the visible range or from a convenience action alone.
133
135
 
134
136
  ## Context Awareness
135
- The UI writes navigation state including the current view, date, view mode (day/week/month), and selected event ID. Always check view-screen to know what the user sees before responding.
137
+ The UI writes navigation state including the current view, date, view mode (day/week/month), and selected event ID. Check view-screen when the answer depends on that visible state; skip it for headless inventory/coverage reads with an explicit date range.
136
138
 
137
139
  When the user says "show me", "go to", "open", or "switch to" a view or date, ALWAYS use the \`navigate\` action to update the UI first, then fetch/display data. The user expects to SEE the result in the app.`,
138
140
  mentionProviders: async () => {
@@ -11,6 +11,8 @@ export interface CalendarEvent {
11
11
  location: string;
12
12
  allDay: boolean;
13
13
  source: "local" | "google" | "ical";
14
+ /** Stable feed/source identifier for non-Google inventory provenance. */
15
+ sourceId?: string;
14
16
  googleEventId?: string;
15
17
  /** Absolute Google Calendar web URL for Google events */
16
18
  htmlLink?: string;
@@ -11,6 +11,7 @@ import { APP_TITLE } from "@/lib/app-config";
11
11
  const pageTitleKeys: Record<string, string> = {
12
12
  "/": "navigation.chat",
13
13
  "/observability": "navigation.observability",
14
+ "/agent": "settings.agentTitle",
14
15
  "/settings": "navigation.settings",
15
16
  };
16
17
 
@@ -168,6 +168,7 @@ export function Layout({ children }: LayoutProps) {
168
168
  openOnChatRunning={chatHomeHandoffActive}
169
169
  onFullscreenRequest={openAskAgentFullscreen}
170
170
  emptyStateText={t("chat.inspectEmptyState")}
171
+ agentPageHref="/agent"
171
172
  suggestions={[
172
173
  t("chat.inspectSuggestionCapabilities"),
173
174
  t("chat.inspectSuggestionHello"),
@@ -11,6 +11,7 @@ import { OrgSwitcher } from "@agent-native/core/client/org";
11
11
  import {
12
12
  IconActivity,
13
13
  IconArchive,
14
+ IconBrain,
14
15
  IconDatabase,
15
16
  IconDots,
16
17
  IconEdit,
@@ -59,6 +60,12 @@ const navItems = [
59
60
  href: "/database",
60
61
  view: "database",
61
62
  },
63
+ {
64
+ icon: IconBrain,
65
+ labelKey: "settings.agentTitle",
66
+ href: "/agent",
67
+ view: "agent",
68
+ },
62
69
  {
63
70
  icon: IconSettings,
64
71
  labelKey: "navigation.settings",
@@ -60,6 +60,7 @@ function viewForPath(pathname: string): string {
60
60
  if (pathname.startsWith("/database")) return "database";
61
61
  if (pathname.startsWith("/extensions")) return "extensions";
62
62
  if (pathname.startsWith("/observability")) return "observability";
63
+ if (pathname.startsWith("/agent")) return "agent";
63
64
  if (pathname.startsWith("/team")) return "settings";
64
65
  return "chat";
65
66
  }
@@ -76,6 +77,8 @@ function pathForView(view?: string): string {
76
77
  return "/extensions";
77
78
  case "observability":
78
79
  return "/observability";
80
+ case "agent":
81
+ return "/agent";
79
82
  case "settings":
80
83
  return "/settings";
81
84
  case "team":
@@ -10,11 +10,18 @@ import {
10
10
  useCommandMenuShortcut,
11
11
  useT,
12
12
  } from "@agent-native/core/client";
13
- import { IconSun, IconMoon } from "@tabler/icons-react";
13
+ import { IconBrain, IconSun, IconMoon } from "@tabler/icons-react";
14
14
  import { useQueryClient } from "@tanstack/react-query";
15
15
  import { useTheme } from "next-themes";
16
16
  import { useCallback, useState } from "react";
17
- import { Links, Meta, Outlet, Scripts, ScrollRestoration } from "react-router";
17
+ import {
18
+ Links,
19
+ Meta,
20
+ Outlet,
21
+ Scripts,
22
+ ScrollRestoration,
23
+ useNavigate,
24
+ } from "react-router";
18
25
  import type { LinksFunction } from "react-router";
19
26
 
20
27
  import { Layout as AppLayout } from "@/components/layout/Layout";
@@ -109,6 +116,7 @@ function ThemeToggleItem() {
109
116
 
110
117
  function AppContent() {
111
118
  const [cmdkOpen, setCmdkOpen] = useState(false);
119
+ const navigate = useNavigate();
112
120
  const t = useT();
113
121
  useCommandMenuShortcut(useCallback(() => setCmdkOpen(true), []));
114
122
  return (
@@ -123,6 +131,20 @@ function AppContent() {
123
131
  <CommandMenu.Item onSelect={() => {}}>
124
132
  {t("root.commandSearch")}
125
133
  </CommandMenu.Item>
134
+ <CommandMenu.Item
135
+ onSelect={() => navigate("/agent")}
136
+ keywords={[
137
+ "agent",
138
+ "context",
139
+ "files",
140
+ "connections",
141
+ "jobs",
142
+ "access",
143
+ ]}
144
+ >
145
+ <IconBrain size={16} />
146
+ {t("settings.openAgentSettings")}
147
+ </CommandMenu.Item>
126
148
  </CommandMenu.Group>
127
149
  <CommandMenu.Group heading={t("root.commandAppearance")}>
128
150
  <ThemeToggleItem />
@@ -0,0 +1,15 @@
1
+ import { AgentTabsPage, useT } from "@agent-native/core/client";
2
+ import { useSetPageTitle } from "@agent-native/toolkit/app-shell";
3
+
4
+ import { APP_TITLE } from "@/lib/app-config";
5
+
6
+ export function meta() {
7
+ return [{ title: `Agent - ${APP_TITLE}` }];
8
+ }
9
+
10
+ export default function AgentRoute() {
11
+ const t = useT();
12
+ useSetPageTitle(t("settings.agentTitle"));
13
+
14
+ return <AgentTabsPage appName={APP_TITLE} />;
15
+ }
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-07-13
4
+ ---
5
+
6
+ A full Agent page now brings context, files, connections, jobs, and external access together