@agent-native/core 0.121.2 → 0.122.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 (588) hide show
  1. package/README.md +4 -12
  2. package/corpus/README.md +2 -2
  3. package/corpus/core/CHANGELOG.md +148 -0
  4. package/corpus/core/docs/content/actions.mdx +2 -2
  5. package/corpus/core/docs/content/agent-surfaces.mdx +1 -1
  6. package/corpus/core/docs/content/authentication.mdx +2 -0
  7. package/corpus/core/docs/content/deployment.mdx +36 -0
  8. package/corpus/core/docs/content/http-api.mdx +266 -0
  9. package/corpus/core/docs/content/syncing-template-changes.mdx +159 -0
  10. package/corpus/core/package.json +2 -1
  11. package/corpus/core/src/a2a/activity.ts +38 -27
  12. package/corpus/core/src/a2a/client.ts +57 -4
  13. package/corpus/core/src/agent/engine/builder-engine.ts +35 -4
  14. package/corpus/core/src/agent/run-manager.ts +20 -1
  15. package/corpus/core/src/agent/run-store.ts +4 -1
  16. package/corpus/core/src/agent/types.ts +28 -8
  17. package/corpus/core/src/chat-threads/store.ts +45 -0
  18. package/corpus/core/src/checkpoints/index.ts +2 -0
  19. package/corpus/core/src/checkpoints/route-match.ts +13 -0
  20. package/corpus/core/src/cli/create.ts +105 -17
  21. package/corpus/core/src/cli/index.ts +20 -0
  22. package/corpus/core/src/cli/template-baseline.ts +410 -0
  23. package/corpus/core/src/cli/template-sync.ts +1004 -0
  24. package/corpus/core/src/cli/templates-meta.ts +1 -0
  25. package/corpus/core/src/client/AssistantChat.tsx +38 -12
  26. package/corpus/core/src/client/NewWorkspaceAppFlow.tsx +75 -10
  27. package/corpus/core/src/client/chat/message-components.tsx +127 -66
  28. package/corpus/core/src/client/chat/tool-call-display.tsx +29 -5
  29. package/corpus/core/src/client/error-format.ts +18 -0
  30. package/corpus/core/src/client/org/OrgSwitcher.tsx +30 -8
  31. package/corpus/core/src/client/org/TeamPage.tsx +7 -6
  32. package/corpus/core/src/client/settings/SettingsPanel.tsx +9 -9
  33. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +12 -2
  34. package/corpus/core/src/client/sse-event-processor.ts +3 -0
  35. package/corpus/core/src/data-widgets/index.ts +41 -0
  36. package/corpus/core/src/deploy/build.ts +11 -9
  37. package/corpus/core/src/extensions/url-safety.ts +67 -4
  38. package/corpus/core/src/integrations/webhook-handler.ts +63 -9
  39. package/corpus/core/src/org/auto-join-domain.ts +4 -3
  40. package/corpus/core/src/org/context.ts +108 -39
  41. package/corpus/core/src/org/index.ts +5 -0
  42. package/corpus/core/src/org/service-identity.ts +60 -0
  43. package/corpus/core/src/provider-api/index.ts +22 -1
  44. package/corpus/core/src/scripts/docs/search.ts +12 -1
  45. package/corpus/core/src/server/agent-chat/context-tools.ts +9 -4
  46. package/corpus/core/src/server/agent-chat/framework-prompts.ts +38 -66
  47. package/corpus/core/src/server/agent-chat-plugin.ts +17 -10
  48. package/corpus/core/src/server/agents-bundle.ts +84 -5
  49. package/corpus/core/src/server/auth.ts +4 -3
  50. package/corpus/core/src/server/builder-browser.ts +47 -19
  51. package/corpus/core/src/server/core-routes-plugin.ts +2 -2
  52. package/corpus/core/src/server/credential-provider.ts +209 -68
  53. package/corpus/core/src/server/index.ts +3 -0
  54. package/corpus/core/src/server/prompts/framework-core-compact.ts +6 -13
  55. package/corpus/core/src/server/prompts/framework-core.ts +9 -21
  56. package/corpus/core/src/server/prompts/index.ts +0 -1
  57. package/corpus/core/src/server/prompts/shared-rules.ts +19 -11
  58. package/corpus/core/src/server/ssr-handler.ts +13 -2
  59. package/corpus/core/src/settings/user-settings.ts +13 -1
  60. package/corpus/core/src/shared/cache-control.ts +141 -0
  61. package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  62. package/corpus/core/src/templates/chat/_gitignore +1 -0
  63. package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +0 -7
  64. package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  65. package/corpus/core/src/templates/default/app/root.tsx +1 -1
  66. package/corpus/core/src/templates/default/public/manifest.json +2 -2
  67. package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  68. package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
  69. package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  70. package/corpus/core/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
  71. package/corpus/core/src/vite/agents-bundle-plugin.ts +7 -6
  72. package/corpus/core/src/vite/client.ts +69 -3
  73. package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +4 -5
  74. package/corpus/templates/analytics/.agents/skills/admin-surfaces/SKILL.md +55 -0
  75. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +10 -0
  76. package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +62 -0
  77. package/corpus/templates/analytics/.agents/skills/dashboard-ops/SKILL.md +85 -0
  78. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +27 -2
  79. package/corpus/templates/analytics/.agents/skills/data-querying/references/inline-chart-embeds.md +139 -0
  80. package/corpus/templates/analytics/.agents/skills/monitoring/SKILL.md +77 -0
  81. package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  82. package/corpus/templates/analytics/AGENTS.md +91 -563
  83. package/corpus/templates/analytics/_gitignore +1 -0
  84. package/corpus/templates/analytics/actions/bigquery.ts +12 -4
  85. package/corpus/templates/analytics/actions/generate-chart.ts +5 -5
  86. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +30 -1
  87. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -23
  88. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +3 -0
  89. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +1 -1
  90. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +1 -0
  91. package/corpus/templates/analytics/app/routes/_index.tsx +1 -1
  92. package/corpus/templates/analytics/changelog/2026-07-24-analytics-finds-saved-dashboards-and-queries-far-more-reliab.md +6 -0
  93. package/corpus/templates/analytics/changelog/2026-07-24-notion-access-errors-now-explain-that-a-page-needs-sharing-w.md +6 -0
  94. package/corpus/templates/analytics/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  95. package/corpus/templates/analytics/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  96. package/corpus/templates/analytics/package.json +1 -1
  97. package/corpus/templates/analytics/public/manifest.json +1 -1
  98. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +7 -0
  99. package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +191 -30
  100. package/corpus/templates/analytics/server/lib/bigquery.ts +11 -1
  101. package/corpus/templates/analytics/server/lib/notion.ts +15 -4
  102. package/corpus/templates/analytics/server/plugins/agent-chat.ts +10 -0
  103. package/corpus/templates/analytics/server/plugins/auth.ts +1 -1
  104. package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  105. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +0 -2
  106. package/corpus/templates/assets/app/routes/_index.tsx +1 -1
  107. package/corpus/templates/assets/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  108. package/corpus/templates/assets/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  109. package/corpus/templates/assets/server/plugins/auth.ts +1 -1
  110. package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  111. package/corpus/templates/brain/_gitignore +1 -0
  112. package/corpus/templates/brain/app/lib/brain.ts +0 -7
  113. package/corpus/templates/brain/app/routes/_index.tsx +1 -2
  114. package/corpus/templates/brain/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  115. package/corpus/templates/brain/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  116. package/corpus/templates/brain/package.json +1 -1
  117. package/corpus/templates/brain/public/manifest.json +1 -1
  118. package/corpus/templates/brain/server/plugins/auth.ts +1 -1
  119. package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  120. package/corpus/templates/calendar/_gitignore +1 -0
  121. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +0 -6
  122. package/corpus/templates/calendar/app/routes/_app._index.tsx +1 -1
  123. package/corpus/templates/calendar/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  124. package/corpus/templates/calendar/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  125. package/corpus/templates/calendar/package.json +1 -1
  126. package/corpus/templates/calendar/public/manifest.json +1 -1
  127. package/corpus/templates/calendar/server/plugins/auth.ts +1 -1
  128. package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  129. package/corpus/templates/chat/_gitignore +1 -0
  130. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +0 -7
  131. package/corpus/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  132. package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  133. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +34 -0
  134. package/corpus/templates/clips/AGENTS.md +5 -4
  135. package/corpus/templates/clips/_gitignore +1 -0
  136. package/corpus/templates/clips/actions/cleanup-transcript.ts +5 -0
  137. package/corpus/templates/clips/actions/get-recording-insights.ts +44 -8
  138. package/corpus/templates/clips/actions/get-recording-player-data.ts +39 -70
  139. package/corpus/templates/clips/actions/import-loom-recording.ts +53 -98
  140. package/corpus/templates/clips/actions/lib/loom-import-job.ts +260 -0
  141. package/corpus/templates/clips/actions/list-clip-views.ts +2 -4
  142. package/corpus/templates/clips/actions/list-recordings.ts +69 -19
  143. package/corpus/templates/clips/actions/list-viewers.ts +5 -2
  144. package/corpus/templates/clips/actions/regenerate-summary.ts +5 -1
  145. package/corpus/templates/clips/actions/request-transcript.ts +28 -1
  146. package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +21 -1
  147. package/corpus/templates/clips/app/components/library/library-layout.tsx +0 -7
  148. package/corpus/templates/clips/app/components/meetings/quick-ask-sidebar.tsx +14 -1
  149. package/corpus/templates/clips/app/components/player/insights-panel.tsx +8 -20
  150. package/corpus/templates/clips/app/components/player/recording-views-badge.tsx +335 -0
  151. package/corpus/templates/clips/app/components/player/video-player.tsx +13 -8
  152. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +2 -1
  153. package/corpus/templates/clips/app/i18n/en-US.ts +13 -2
  154. package/corpus/templates/clips/app/lib/capture-permissions.ts +110 -0
  155. package/corpus/templates/clips/app/lib/recording-link.ts +32 -0
  156. package/corpus/templates/clips/app/routes/_app.library._index.tsx +1 -1
  157. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +27 -0
  158. package/corpus/templates/clips/app/routes/_index.tsx +1 -1
  159. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +52 -15
  160. package/corpus/templates/clips/app/routes/record.tsx +82 -31
  161. package/corpus/templates/clips/app/routes/share.$shareId.tsx +42 -31
  162. package/corpus/templates/clips/changelog/2026-07-24-clip-pages-now-show-a-view-count-with-viewer-avatars-next-to.md +6 -0
  163. package/corpus/templates/clips/changelog/2026-07-24-clip-summaries-read-like-a-description-you-d-write-yourself-.md +6 -0
  164. package/corpus/templates/clips/changelog/2026-07-24-clip-view-counts-now-separate-human-views-from-agent-views-s.md +6 -0
  165. package/corpus/templates/clips/changelog/2026-07-24-clips-actions-can-now-be-called-by-org-service-tokens-so-ext.md +6 -0
  166. package/corpus/templates/clips/changelog/2026-07-24-clips-no-longer-briefly-shows-a-dock-icon-while-launching.md +6 -0
  167. package/corpus/templates/clips/changelog/2026-07-24-fixed-owner-and-editor-share-links-redirecting-to-the-record.md +6 -0
  168. package/corpus/templates/clips/changelog/2026-07-24-meeting-and-note-recordings-now-start-as-a-compact-pill-on-t.md +6 -0
  169. package/corpus/templates/clips/changelog/2026-07-24-new-clips-now-copy-a-shareable-link-instead-of-the-owner-onl.md +6 -0
  170. package/corpus/templates/clips/changelog/2026-07-24-opening-a-share-link-as-the-clip-s-owner-now-goes-straight-t.md +6 -0
  171. package/corpus/templates/clips/changelog/2026-07-24-permissions-and-rewind-controls-now-use-compact-consistent-h.md +6 -0
  172. package/corpus/templates/clips/changelog/2026-07-24-quitting-the-desktop-app-no-longer-shows-a-false-macos-crash.md +6 -0
  173. package/corpus/templates/clips/changelog/2026-07-24-screen-recording-permission-errors-now-name-the-exact-app-to.md +6 -0
  174. package/corpus/templates/clips/changelog/2026-07-24-the-desktop-app-now-copies-a-new-clip-s-share-link-to-your-c.md +6 -0
  175. package/corpus/templates/clips/changelog/2026-07-24-the-recording-toolbar-now-stays-above-other-apps-including-o.md +6 -0
  176. package/corpus/templates/clips/changelog/2026-07-24-transcript-captions-now-use-real-speech-timings-instead-of-a.md +6 -0
  177. package/corpus/templates/clips/changelog/2026-07-24-video-playback-no-longer-stutters-and-replays-the-last-momen.md +6 -0
  178. package/corpus/templates/clips/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  179. package/corpus/templates/clips/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  180. package/corpus/templates/clips/chrome-extension/src/background.ts +17 -1
  181. package/corpus/templates/clips/desktop/package.json +2 -0
  182. package/corpus/templates/clips/desktop/src/app.tsx +89 -0
  183. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +9 -3
  184. package/corpus/templates/clips/desktop/src/lib/audio-meter.ts +51 -0
  185. package/corpus/templates/clips/desktop/src/lib/native-notification.ts +44 -0
  186. package/corpus/templates/clips/desktop/src/lib/recording-link.ts +67 -0
  187. package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +35 -35
  188. package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +3 -2
  189. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +47 -46
  190. package/corpus/templates/clips/desktop/src/styles.css +127 -78
  191. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +7 -0
  192. package/corpus/templates/clips/desktop/src-tauri/Info.plist +6 -0
  193. package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +1 -0
  194. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +7 -3
  195. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -1
  196. package/corpus/templates/clips/desktop/src-tauri/src/main.rs +8 -0
  197. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +21 -10
  198. package/corpus/templates/clips/desktop/src-tauri/src/util.rs +40 -0
  199. package/corpus/templates/clips/server/db/schema.ts +27 -0
  200. package/corpus/templates/clips/server/lib/agent-views.ts +145 -0
  201. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +2 -1
  202. package/corpus/templates/clips/server/lib/public-agent-context.ts +7 -0
  203. package/corpus/templates/clips/server/lib/recording-share-grant.ts +79 -0
  204. package/corpus/templates/clips/server/lib/recordings.ts +51 -3
  205. package/corpus/templates/clips/server/plugins/auth.ts +1 -1
  206. package/corpus/templates/clips/server/plugins/db.ts +31 -0
  207. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +56 -3
  208. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +49 -17
  209. package/corpus/templates/clips/shared/recording-link.ts +43 -0
  210. package/corpus/templates/clips/shared/share-attribution.ts +4 -0
  211. package/corpus/templates/clips/shared/share-dashboard-redirect.ts +42 -0
  212. package/corpus/templates/clips/shared/view-analytics.ts +26 -0
  213. package/corpus/templates/content/.agents/skills/content/SKILL.md +5 -0
  214. package/corpus/templates/content/.agents/skills/content/references/local-file-mode.md +135 -0
  215. package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +12 -0
  216. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +238 -0
  217. package/corpus/templates/content/.agents/skills/document-editing/references/document-behavior.md +91 -0
  218. package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  219. package/corpus/templates/content/AGENTS.md +62 -583
  220. package/corpus/templates/content/_gitignore +1 -0
  221. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -39
  222. package/corpus/templates/content/app/routes/_app._index.tsx +1 -2
  223. package/corpus/templates/content/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  224. package/corpus/templates/content/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  225. package/corpus/templates/content/package.json +1 -1
  226. package/corpus/templates/content/public/manifest.json +1 -1
  227. package/corpus/templates/content/server/plugins/auth.ts +1 -1
  228. package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +11 -0
  229. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +50 -8
  230. package/corpus/templates/design/.agents/skills/design-generation/references/code-layers.md +81 -0
  231. package/corpus/templates/design/.agents/skills/design-generation/references/code-workspace.md +42 -0
  232. package/corpus/templates/design/.agents/skills/design-generation/references/editor-extensions.md +34 -0
  233. package/corpus/templates/design/.agents/skills/responsive-breakpoints/SKILL.md +4 -1
  234. package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  235. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +17 -0
  236. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +8196 -0
  237. package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +265 -0
  238. package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +642 -0
  239. package/corpus/templates/design/.generated/bridge/motion-preview.generated.ts +571 -0
  240. package/corpus/templates/design/.generated/bridge/nav.generated.ts +91 -0
  241. package/corpus/templates/design/.generated/bridge/sample.generated.ts +23 -0
  242. package/corpus/templates/design/.generated/bridge/shader-fill-preview.generated.ts +263 -0
  243. package/corpus/templates/design/.generated/bridge/shader-runtime.generated.ts +518 -0
  244. package/corpus/templates/design/.generated/bridge/tweak.generated.ts +20 -0
  245. package/corpus/templates/design/.generated/bridge/zoom.generated.ts +32 -0
  246. package/corpus/templates/design/AGENTS.md +88 -503
  247. package/corpus/templates/design/_gitignore +1 -0
  248. package/corpus/templates/design/app/components/layout/Sidebar.tsx +0 -2
  249. package/corpus/templates/design/app/routes/_index.tsx +1 -1
  250. package/corpus/templates/design/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  251. package/corpus/templates/design/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  252. package/corpus/templates/design/server/plugins/auth.ts +1 -1
  253. package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  254. package/corpus/templates/dispatch/_gitignore +1 -0
  255. package/corpus/templates/dispatch/app/dispatch-extensions.tsx +1 -10
  256. package/corpus/templates/dispatch/app/routes/overview.tsx +1 -1
  257. package/corpus/templates/dispatch/changelog/2026-07-24-signing-in-now-puts-you-in-your-companys-workspace.md +6 -0
  258. package/corpus/templates/dispatch/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  259. package/corpus/templates/dispatch/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  260. package/corpus/templates/dispatch/package.json +1 -1
  261. package/corpus/templates/dispatch/public/manifest.json +1 -1
  262. package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  263. package/corpus/templates/forms/_gitignore +1 -0
  264. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +0 -35
  265. package/corpus/templates/forms/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  266. package/corpus/templates/forms/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  267. package/corpus/templates/forms/package.json +1 -1
  268. package/corpus/templates/forms/public/manifest.json +1 -1
  269. package/corpus/templates/forms/server/lib/public-form-ssr.ts +2 -2
  270. package/corpus/templates/forms/server/plugins/auth.ts +1 -1
  271. package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  272. package/corpus/templates/macros/_gitignore +1 -0
  273. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +0 -2
  274. package/corpus/templates/macros/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  275. package/corpus/templates/macros/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  276. package/corpus/templates/macros/package.json +1 -1
  277. package/corpus/templates/macros/server/plugins/auth.ts +2 -2
  278. package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  279. package/corpus/templates/mail/_gitignore +1 -0
  280. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +0 -39
  281. package/corpus/templates/mail/app/routes/$view.$threadId.tsx +1 -1
  282. package/corpus/templates/mail/app/routes/$view.tsx +1 -1
  283. package/corpus/templates/mail/app/routes/_index.tsx +1 -1
  284. package/corpus/templates/mail/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  285. package/corpus/templates/mail/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  286. package/corpus/templates/mail/package.json +1 -1
  287. package/corpus/templates/mail/public/manifest.json +1 -1
  288. package/corpus/templates/mail/server/plugins/auth.ts +1 -1
  289. package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  290. package/corpus/templates/plan/_gitignore +1 -0
  291. package/corpus/templates/plan/agent-native.app-skill.json +1 -1
  292. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +4 -9
  293. package/corpus/templates/plan/app/lib/app-config.ts +1 -1
  294. package/corpus/templates/plan/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  295. package/corpus/templates/plan/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  296. package/corpus/templates/plan/package.json +1 -1
  297. package/corpus/templates/plan/public/manifest.json +1 -1
  298. package/corpus/templates/plan/server/plugins/auth.ts +1 -1
  299. package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  300. package/corpus/templates/slides/_gitignore +1 -0
  301. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +0 -2
  302. package/corpus/templates/slides/app/routes/_index.tsx +1 -1
  303. package/corpus/templates/slides/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  304. package/corpus/templates/slides/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  305. package/corpus/templates/slides/package.json +1 -1
  306. package/corpus/templates/slides/public/manifest.json +1 -1
  307. package/corpus/templates/slides/server/plugins/auth.ts +1 -1
  308. package/corpus/templates/slides/server/plugins/db.ts +4 -0
  309. package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  310. package/corpus/templates/tasks/AGENTS.md +1 -1
  311. package/corpus/templates/tasks/_gitignore +1 -0
  312. package/dist/a2a/activity.d.ts +4 -1
  313. package/dist/a2a/activity.d.ts.map +1 -1
  314. package/dist/a2a/activity.js +27 -16
  315. package/dist/a2a/activity.js.map +1 -1
  316. package/dist/a2a/client.d.ts.map +1 -1
  317. package/dist/a2a/client.js +58 -4
  318. package/dist/a2a/client.js.map +1 -1
  319. package/dist/agent/engine/builder-engine.d.ts +1 -0
  320. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  321. package/dist/agent/engine/builder-engine.js +31 -4
  322. package/dist/agent/engine/builder-engine.js.map +1 -1
  323. package/dist/agent/run-manager.d.ts.map +1 -1
  324. package/dist/agent/run-manager.js +18 -1
  325. package/dist/agent/run-manager.js.map +1 -1
  326. package/dist/agent/run-store.d.ts +1 -0
  327. package/dist/agent/run-store.d.ts.map +1 -1
  328. package/dist/agent/run-store.js +2 -1
  329. package/dist/agent/run-store.js.map +1 -1
  330. package/dist/agent/types.d.ts +12 -1
  331. package/dist/agent/types.d.ts.map +1 -1
  332. package/dist/agent/types.js +21 -1
  333. package/dist/agent/types.js.map +1 -1
  334. package/dist/chat-threads/store.d.ts +10 -0
  335. package/dist/chat-threads/store.d.ts.map +1 -1
  336. package/dist/chat-threads/store.js +41 -0
  337. package/dist/chat-threads/store.js.map +1 -1
  338. package/dist/checkpoints/index.d.ts +1 -0
  339. package/dist/checkpoints/index.d.ts.map +1 -1
  340. package/dist/checkpoints/index.js +1 -0
  341. package/dist/checkpoints/index.js.map +1 -1
  342. package/dist/checkpoints/route-match.d.ts +8 -0
  343. package/dist/checkpoints/route-match.d.ts.map +1 -0
  344. package/dist/checkpoints/route-match.js +13 -0
  345. package/dist/checkpoints/route-match.js.map +1 -0
  346. package/dist/cli/create.d.ts +35 -4
  347. package/dist/cli/create.d.ts.map +1 -1
  348. package/dist/cli/create.js +69 -19
  349. package/dist/cli/create.js.map +1 -1
  350. package/dist/cli/index.js +19 -0
  351. package/dist/cli/index.js.map +1 -1
  352. package/dist/cli/template-baseline.d.ts +54 -0
  353. package/dist/cli/template-baseline.d.ts.map +1 -0
  354. package/dist/cli/template-baseline.js +334 -0
  355. package/dist/cli/template-baseline.js.map +1 -0
  356. package/dist/cli/template-sync.d.ts +57 -0
  357. package/dist/cli/template-sync.d.ts.map +1 -0
  358. package/dist/cli/template-sync.js +787 -0
  359. package/dist/cli/template-sync.js.map +1 -0
  360. package/dist/cli/templates-meta.d.ts.map +1 -1
  361. package/dist/cli/templates-meta.js +1 -0
  362. package/dist/cli/templates-meta.js.map +1 -1
  363. package/dist/client/AssistantChat.d.ts +2 -1
  364. package/dist/client/AssistantChat.d.ts.map +1 -1
  365. package/dist/client/AssistantChat.js +38 -10
  366. package/dist/client/AssistantChat.js.map +1 -1
  367. package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
  368. package/dist/client/NewWorkspaceAppFlow.js +32 -2
  369. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  370. package/dist/client/chat/message-components.d.ts +20 -0
  371. package/dist/client/chat/message-components.d.ts.map +1 -1
  372. package/dist/client/chat/message-components.js +81 -46
  373. package/dist/client/chat/message-components.js.map +1 -1
  374. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  375. package/dist/client/chat/tool-call-display.js +14 -6
  376. package/dist/client/chat/tool-call-display.js.map +1 -1
  377. package/dist/client/error-format.d.ts.map +1 -1
  378. package/dist/client/error-format.js +13 -0
  379. package/dist/client/error-format.js.map +1 -1
  380. package/dist/client/org/OrgSwitcher.d.ts +8 -1
  381. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  382. package/dist/client/org/OrgSwitcher.js +3 -2
  383. package/dist/client/org/OrgSwitcher.js.map +1 -1
  384. package/dist/client/org/TeamPage.d.ts.map +1 -1
  385. package/dist/client/org/TeamPage.js +1 -1
  386. package/dist/client/org/TeamPage.js.map +1 -1
  387. package/dist/client/settings/SettingsPanel.js +9 -9
  388. package/dist/client/settings/SettingsPanel.js.map +1 -1
  389. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  390. package/dist/client/settings/SettingsTabsPage.js +7 -4
  391. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  392. package/dist/client/sse-event-processor.d.ts.map +1 -1
  393. package/dist/client/sse-event-processor.js +3 -0
  394. package/dist/client/sse-event-processor.js.map +1 -1
  395. package/dist/collab/awareness.d.ts +2 -2
  396. package/dist/collab/awareness.d.ts.map +1 -1
  397. package/dist/collab/struct-routes.d.ts +1 -1
  398. package/dist/data-widgets/index.d.ts +3 -0
  399. package/dist/data-widgets/index.d.ts.map +1 -1
  400. package/dist/data-widgets/index.js +33 -0
  401. package/dist/data-widgets/index.js.map +1 -1
  402. package/dist/deploy/build.d.ts.map +1 -1
  403. package/dist/deploy/build.js +11 -7
  404. package/dist/deploy/build.js.map +1 -1
  405. package/dist/eject/provider-api-definitions.d.ts +1 -0
  406. package/dist/eject/provider-api-definitions.d.ts.map +1 -1
  407. package/dist/extensions/url-safety.d.ts +9 -16
  408. package/dist/extensions/url-safety.d.ts.map +1 -1
  409. package/dist/extensions/url-safety.js +48 -4
  410. package/dist/extensions/url-safety.js.map +1 -1
  411. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  412. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  413. package/dist/integrations/webhook-handler.js +46 -9
  414. package/dist/integrations/webhook-handler.js.map +1 -1
  415. package/dist/notifications/routes.d.ts +2 -2
  416. package/dist/observability/routes.d.ts +3 -3
  417. package/dist/org/auto-join-domain.d.ts +3 -2
  418. package/dist/org/auto-join-domain.d.ts.map +1 -1
  419. package/dist/org/auto-join-domain.js +1 -1
  420. package/dist/org/auto-join-domain.js.map +1 -1
  421. package/dist/org/context.d.ts.map +1 -1
  422. package/dist/org/context.js +84 -28
  423. package/dist/org/context.js.map +1 -1
  424. package/dist/org/index.d.ts +1 -0
  425. package/dist/org/index.d.ts.map +1 -1
  426. package/dist/org/index.js +1 -0
  427. package/dist/org/index.js.map +1 -1
  428. package/dist/org/service-identity.d.ts +43 -0
  429. package/dist/org/service-identity.d.ts.map +1 -0
  430. package/dist/org/service-identity.js +34 -0
  431. package/dist/org/service-identity.js.map +1 -0
  432. package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
  433. package/dist/provider-api/actions/provider-api.d.ts +13 -11
  434. package/dist/provider-api/actions/provider-api.d.ts.map +1 -1
  435. package/dist/provider-api/index.d.ts +4 -0
  436. package/dist/provider-api/index.d.ts.map +1 -1
  437. package/dist/provider-api/index.js +17 -1
  438. package/dist/provider-api/index.js.map +1 -1
  439. package/dist/scripts/docs/search.d.ts.map +1 -1
  440. package/dist/scripts/docs/search.js +12 -1
  441. package/dist/scripts/docs/search.js.map +1 -1
  442. package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
  443. package/dist/server/agent-chat/context-tools.js +3 -3
  444. package/dist/server/agent-chat/context-tools.js.map +1 -1
  445. package/dist/server/agent-chat/framework-prompts.d.ts +8 -3
  446. package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
  447. package/dist/server/agent-chat/framework-prompts.js +33 -62
  448. package/dist/server/agent-chat/framework-prompts.js.map +1 -1
  449. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  450. package/dist/server/agent-chat-plugin.js +16 -10
  451. package/dist/server/agent-chat-plugin.js.map +1 -1
  452. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  453. package/dist/server/agents-bundle.d.ts +18 -0
  454. package/dist/server/agents-bundle.d.ts.map +1 -1
  455. package/dist/server/agents-bundle.js +70 -4
  456. package/dist/server/agents-bundle.js.map +1 -1
  457. package/dist/server/auth.d.ts.map +1 -1
  458. package/dist/server/auth.js +4 -3
  459. package/dist/server/auth.js.map +1 -1
  460. package/dist/server/builder-browser.d.ts.map +1 -1
  461. package/dist/server/builder-browser.js +43 -19
  462. package/dist/server/builder-browser.js.map +1 -1
  463. package/dist/server/core-routes-plugin.js +2 -2
  464. package/dist/server/core-routes-plugin.js.map +1 -1
  465. package/dist/server/credential-provider.d.ts +38 -2
  466. package/dist/server/credential-provider.d.ts.map +1 -1
  467. package/dist/server/credential-provider.js +142 -64
  468. package/dist/server/credential-provider.js.map +1 -1
  469. package/dist/server/index.d.ts +1 -1
  470. package/dist/server/index.d.ts.map +1 -1
  471. package/dist/server/index.js +1 -1
  472. package/dist/server/index.js.map +1 -1
  473. package/dist/server/prompts/framework-core-compact.d.ts +1 -1
  474. package/dist/server/prompts/framework-core-compact.d.ts.map +1 -1
  475. package/dist/server/prompts/framework-core-compact.js +7 -13
  476. package/dist/server/prompts/framework-core-compact.js.map +1 -1
  477. package/dist/server/prompts/framework-core.d.ts +1 -1
  478. package/dist/server/prompts/framework-core.d.ts.map +1 -1
  479. package/dist/server/prompts/framework-core.js +10 -21
  480. package/dist/server/prompts/framework-core.js.map +1 -1
  481. package/dist/server/prompts/index.d.ts +1 -1
  482. package/dist/server/prompts/index.d.ts.map +1 -1
  483. package/dist/server/prompts/index.js +1 -1
  484. package/dist/server/prompts/index.js.map +1 -1
  485. package/dist/server/prompts/shared-rules.d.ts +16 -10
  486. package/dist/server/prompts/shared-rules.d.ts.map +1 -1
  487. package/dist/server/prompts/shared-rules.js +19 -10
  488. package/dist/server/prompts/shared-rules.js.map +1 -1
  489. package/dist/server/ssr-handler.d.ts +1 -1
  490. package/dist/server/ssr-handler.d.ts.map +1 -1
  491. package/dist/server/ssr-handler.js +10 -3
  492. package/dist/server/ssr-handler.js.map +1 -1
  493. package/dist/server/transcribe-voice.d.ts +1 -1
  494. package/dist/settings/user-settings.d.ts.map +1 -1
  495. package/dist/settings/user-settings.js +13 -1
  496. package/dist/settings/user-settings.js.map +1 -1
  497. package/dist/shared/cache-control.d.ts +52 -0
  498. package/dist/shared/cache-control.d.ts.map +1 -1
  499. package/dist/shared/cache-control.js +107 -0
  500. package/dist/shared/cache-control.js.map +1 -1
  501. package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  502. package/dist/templates/chat/_gitignore +1 -0
  503. package/dist/templates/chat/app/components/layout/Sidebar.tsx +0 -7
  504. package/dist/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  505. package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  506. package/dist/templates/default/app/root.tsx +1 -1
  507. package/dist/templates/default/public/manifest.json +2 -2
  508. package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  509. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
  510. package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  511. package/dist/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
  512. package/dist/vite/agents-bundle-plugin.d.ts.map +1 -1
  513. package/dist/vite/agents-bundle-plugin.js +8 -7
  514. package/dist/vite/agents-bundle-plugin.js.map +1 -1
  515. package/dist/vite/client.d.ts.map +1 -1
  516. package/dist/vite/client.js +66 -1
  517. package/dist/vite/client.js.map +1 -1
  518. package/docs/content/actions.mdx +2 -2
  519. package/docs/content/agent-surfaces.mdx +1 -1
  520. package/docs/content/authentication.mdx +2 -0
  521. package/docs/content/deployment.mdx +36 -0
  522. package/docs/content/http-api.mdx +266 -0
  523. package/docs/content/syncing-template-changes.mdx +159 -0
  524. package/package.json +4 -3
  525. package/src/a2a/activity.ts +38 -27
  526. package/src/a2a/client.ts +57 -4
  527. package/src/agent/engine/builder-engine.ts +35 -4
  528. package/src/agent/run-manager.ts +20 -1
  529. package/src/agent/run-store.ts +4 -1
  530. package/src/agent/types.ts +28 -8
  531. package/src/chat-threads/store.ts +45 -0
  532. package/src/checkpoints/index.ts +2 -0
  533. package/src/checkpoints/route-match.ts +13 -0
  534. package/src/cli/create.ts +105 -17
  535. package/src/cli/index.ts +20 -0
  536. package/src/cli/template-baseline.ts +410 -0
  537. package/src/cli/template-sync.ts +1004 -0
  538. package/src/cli/templates-meta.ts +1 -0
  539. package/src/client/AssistantChat.tsx +38 -12
  540. package/src/client/NewWorkspaceAppFlow.tsx +75 -10
  541. package/src/client/chat/message-components.tsx +127 -66
  542. package/src/client/chat/tool-call-display.tsx +29 -5
  543. package/src/client/error-format.ts +18 -0
  544. package/src/client/org/OrgSwitcher.tsx +30 -8
  545. package/src/client/org/TeamPage.tsx +7 -6
  546. package/src/client/settings/SettingsPanel.tsx +9 -9
  547. package/src/client/settings/SettingsTabsPage.tsx +12 -2
  548. package/src/client/sse-event-processor.ts +3 -0
  549. package/src/data-widgets/index.ts +41 -0
  550. package/src/deploy/build.ts +11 -9
  551. package/src/extensions/url-safety.ts +67 -4
  552. package/src/integrations/webhook-handler.ts +63 -9
  553. package/src/org/auto-join-domain.ts +4 -3
  554. package/src/org/context.ts +108 -39
  555. package/src/org/index.ts +5 -0
  556. package/src/org/service-identity.ts +60 -0
  557. package/src/provider-api/index.ts +22 -1
  558. package/src/scripts/docs/search.ts +12 -1
  559. package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +25 -36
  560. package/src/server/agent-chat/context-tools.ts +9 -4
  561. package/src/server/agent-chat/framework-prompts.ts +38 -66
  562. package/src/server/agent-chat-plugin.ts +17 -10
  563. package/src/server/agents-bundle.ts +84 -5
  564. package/src/server/auth.ts +4 -3
  565. package/src/server/builder-browser.ts +47 -19
  566. package/src/server/core-routes-plugin.ts +2 -2
  567. package/src/server/credential-provider.ts +209 -68
  568. package/src/server/index.ts +3 -0
  569. package/src/server/prompts/framework-core-compact.ts +6 -13
  570. package/src/server/prompts/framework-core.ts +9 -21
  571. package/src/server/prompts/index.ts +0 -1
  572. package/src/server/prompts/shared-rules.ts +19 -11
  573. package/src/server/ssr-handler.ts +13 -2
  574. package/src/settings/user-settings.ts +13 -1
  575. package/src/shared/cache-control.ts +141 -0
  576. package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  577. package/src/templates/chat/_gitignore +1 -0
  578. package/src/templates/chat/app/components/layout/Sidebar.tsx +0 -7
  579. package/src/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  580. package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  581. package/src/templates/default/app/root.tsx +1 -1
  582. package/src/templates/default/public/manifest.json +2 -2
  583. package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  584. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
  585. package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  586. package/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
  587. package/src/vite/agents-bundle-plugin.ts +7 -6
  588. package/src/vite/client.ts +69 -3
@@ -37,3 +37,4 @@ data/.sessions.json
37
37
  learnings.md
38
38
 
39
39
  .vercel/
40
+ .agent-native/
@@ -96,10 +96,18 @@ export default defineAction({
96
96
  "BigQuery isn't connected for this workspace yet. Open Settings -> Data sources and add BIGQUERY_PROJECT_ID + GOOGLE_APPLICATION_CREDENTIALS_JSON (a service-account JSON key).",
97
97
  );
98
98
  }
99
- if (
100
- /BigQuery (API|poll) error/i.test(msg) ||
101
- /BigQuery query timed out/i.test(msg)
102
- ) {
99
+ // A timeout means the SQL was valid but slow. Routing it through the schema-error
100
+ // branch below told the model to go re-inspect the schema and rerun, which turns
101
+ // one slow query into a loop of 60-second attempts.
102
+ if (/BigQuery query timed out/i.test(msg)) {
103
+ return {
104
+ error: "bigquery_query_timeout",
105
+ message: extractBigQueryMessage(msg),
106
+ recoverable: true,
107
+ hint: "The SQL was valid but exceeded the 60-second warehouse budget. Do NOT inspect the schema and do NOT rerun this query as-is. Make it cheaper: narrow the date range, add a LIMIT, aggregate in SQL instead of returning raw rows, or filter on a partition/cluster column. If the full scan is genuinely required, run it through run-code with background: true instead of retrying here.",
108
+ };
109
+ }
110
+ if (/BigQuery (API|poll) error/i.test(msg)) {
103
111
  // Recoverable: hand the real error back to the model so it can inspect
104
112
  // the schema and self-correct, instead of force-ending the turn.
105
113
  return {
@@ -303,16 +303,16 @@ export function renderStaticChartSvg({
303
303
  * user's chair, the chat said "I'll do something else" and no chart appeared.
304
304
  *
305
305
  * For in-chat data questions the right answer is always the live `/chart`
306
- * embed (see AGENTS.md "Inline Charts in Chat"). Only `save-analysis`
307
- * artifacts need a static image, and those flows have full data in hand
308
- * before they call here.
306
+ * embed (see the `data-querying` skill's "Inline Charts In Chat" section for
307
+ * the full shape). Only `save-analysis` artifacts need a static image, and
308
+ * those flows have full data in hand before they call here.
309
309
  */
310
310
  const CHART_FALLBACK_HINT =
311
- "If you're answering an in-chat data question, do not retry generate-chart. Switch to the live /chart embed described in AGENTS.md ('Inline Charts in Chat') — it accepts a SqlPanel object directly and doesn't require pre-stringified JSON params. Only use generate-chart when you're building a save-analysis artifact.";
311
+ "If you're answering an in-chat data question, do not retry generate-chart. Switch to the live /chart embed instead — it accepts a SqlPanel object directly and doesn't require pre-stringified JSON params. See the data-querying skill's \"Inline Charts In Chat\" section for the embed syntax. Only use generate-chart when you're building a save-analysis artifact.";
312
312
 
313
313
  export default defineAction({
314
314
  description:
315
- "Render a static chart image to the media directory **for save-analysis artifacts only**. Uses PNG when the native renderer is available and a portable SVG fallback otherwise. For an in-chat answer to a data question, do NOT call this — emit a live `/chart` embed instead (see AGENTS.md 'Inline Charts in Chat'). The static image path exists for analyses that need to render outside this app (exports, archived reports). If validation here fails, switch to the live embed rather than retrying.",
315
+ 'Render a static chart image to the media directory **for save-analysis artifacts only**. Uses PNG when the native renderer is available and a portable SVG fallback otherwise. For an in-chat answer to a data question, do NOT call this — emit a live `/chart` embed instead (see the data-querying skill\'s "Inline Charts In Chat" section for the embed syntax). The static image path exists for analyses that need to render outside this app (exports, archived reports). If validation here fails, switch to the live embed rather than retrying.',
316
316
  schema: z.object({
317
317
  title: z.string().optional().describe("Chart title (required)"),
318
318
  labels: z.string().optional().describe("JSON array of x-axis labels"),
@@ -119,6 +119,9 @@ const CHART_LEGEND_PROPS = {
119
119
  } as const;
120
120
 
121
121
  const CHART_RESIZE_DEBOUNCE_MS = 50;
122
+ // Recharts' default series animation duration, plus room for the debounced
123
+ // resize callback that follows a lazy-loaded panel's first layout pass.
124
+ const CHART_ENTRY_ANIMATION_MS = 1500 + CHART_RESIZE_DEBOUNCE_MS * 2;
122
125
  const LEGEND_ACTION_CLOSE_DELAY_MS = 600;
123
126
 
124
127
  type ChartSize = {
@@ -136,12 +139,38 @@ export function hasChartSizeChanged(
136
139
  );
137
140
  }
138
141
 
142
+ export function shouldDisableChartAnimation(
143
+ entryAnimationSettled: boolean,
144
+ previous: ChartSize | null,
145
+ next: ChartSize,
146
+ ): boolean {
147
+ return entryAnimationSettled && hasChartSizeChanged(previous, next);
148
+ }
149
+
139
150
  function useChartResizeAnimation() {
140
151
  const [isAnimationActive, setIsAnimationActive] = useState(true);
141
152
  const firstSizeRef = useRef<ChartSize | null>(null);
153
+ // Switching Recharts to isAnimationActive=false mid-flight freezes the line's
154
+ // stroke-dasharray at whatever partial length it reached, leaving the series
155
+ // invisible forever. Lazy-loaded panels reflow right after mounting, so the
156
+ // entry animation has to be allowed to finish before a resize can disable it.
157
+ const entryAnimationSettledRef = useRef(false);
158
+ useEffect(() => {
159
+ const timer = setTimeout(() => {
160
+ entryAnimationSettledRef.current = true;
161
+ }, CHART_ENTRY_ANIMATION_MS);
162
+ return () => clearTimeout(timer);
163
+ }, []);
164
+
142
165
  const handleResize = useCallback((width: number, height: number) => {
143
166
  const nextSize = { width, height };
144
- if (hasChartSizeChanged(firstSizeRef.current, nextSize)) {
167
+ if (
168
+ shouldDisableChartAnimation(
169
+ entryAnimationSettledRef.current,
170
+ firstSizeRef.current,
171
+ nextSize,
172
+ )
173
+ ) {
145
174
  setIsAnimationActive(false);
146
175
  }
147
176
  firstSizeRef.current = nextSize;
@@ -19,14 +19,12 @@ import {
19
19
  IconLock,
20
20
  IconLink,
21
21
  IconMessageCircle,
22
- IconHierarchy2,
23
22
  IconUsersGroup,
24
23
  IconEye,
25
24
  IconEyeOff,
26
25
  IconPlayerPlay,
27
26
  IconLayoutSidebarLeftCollapse,
28
27
  IconLayoutSidebarLeftExpand,
29
- IconArrowUpRight,
30
28
  } from "@tabler/icons-react";
31
29
  import {
32
30
  useQuery,
@@ -183,12 +181,6 @@ import {
183
181
  import { CSS } from "@dnd-kit/utilities";
184
182
 
185
183
  const bottomItems = [
186
- {
187
- icon: IconHierarchy2,
188
- labelKey: "settings.agentTitle",
189
- href: "/agent",
190
- showExternalLinkIcon: true,
191
- },
192
184
  { icon: IconSettings, labelKey: "navigation.settings", href: "/settings" },
193
185
  ];
194
186
 
@@ -2098,12 +2090,6 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
2098
2090
  href: "/data-dictionary",
2099
2091
  active: location.pathname.startsWith("/data-dictionary"),
2100
2092
  },
2101
- {
2102
- icon: IconHierarchy2,
2103
- label: t("settings.agentTitle"),
2104
- href: "/agent",
2105
- active: location.pathname === "/agent",
2106
- },
2107
2093
  {
2108
2094
  icon: IconSettings,
2109
2095
  label: t("navigation.settings"),
@@ -2572,15 +2558,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
2572
2558
  )}
2573
2559
  >
2574
2560
  <Icon className="h-4 w-4" />
2575
- <span className="flex min-w-0 items-center gap-1">
2576
- <span className="truncate">{t(item.labelKey)}</span>
2577
- {item.showExternalLinkIcon && (
2578
- <IconArrowUpRight
2579
- aria-hidden="true"
2580
- className="h-3.5 w-3.5 shrink-0 text-muted-foreground/70"
2581
- />
2582
- )}
2583
- </span>
2561
+ <span className="truncate">{t(item.labelKey)}</span>
2584
2562
  </Link>
2585
2563
  );
2586
2564
  })}
@@ -259,6 +259,9 @@ export function DashboardFilterBar({
259
259
  className="group rounded-lg bg-card px-3 py-2"
260
260
  >
261
261
  <div className="flex flex-wrap items-end justify-between gap-3">
262
+ <span className="self-center text-xs font-medium text-muted-foreground group-data-[state=open]:hidden">
263
+ {t("sqlDashboard.filters")}
264
+ </span>
262
265
  <CollapsibleContent className="min-w-0 flex-1">
263
266
  <div className="flex flex-wrap gap-3 items-end">
264
267
  {uniqueFilters.map((f) => (
@@ -272,7 +272,7 @@ export function SqlChartCard({
272
272
  data-dragging={isDragSource ? "true" : undefined}
273
273
  className="dashboard-section-card group relative mt-2 first:mt-0"
274
274
  >
275
- <div className="flex items-center gap-2 border-b border-border pb-2">
275
+ <div className="flex items-center gap-2 pb-2">
276
276
  <h2 className="text-base font-semibold flex-1">{panel.title}</h2>
277
277
  {editable ? (
278
278
  <div className="flex items-center gap-1 opacity-0 group-hover:opacity-100">
@@ -1538,6 +1538,7 @@ function SqlDashboardPageContent({
1538
1538
  resourceId={dashboardId}
1539
1539
  resourceTitle={dashboard.name}
1540
1540
  variant="compact"
1541
+ triggerClassName="border-0 bg-accent text-accent-foreground hover:bg-accent/80 hover:text-accent-foreground"
1541
1542
  shareUrl={dashboardShareUrl}
1542
1543
  shareTabs={{
1543
1544
  tabs: [
@@ -1,7 +1,7 @@
1
1
  import { redirect, type LoaderFunctionArgs } from "react-router";
2
2
 
3
3
  const SEO_TITLE =
4
- "Agent-Native Analytics - Open Source Alternative to Amplitude & FullStory";
4
+ "Analytics - Open Source Alternative to Amplitude & FullStory";
5
5
  const SEO_DESCRIPTION =
6
6
  "Open Source analytics app and alternative to Amplitude and FullStory where AI agents connect to warehouses, product analytics, and CRM data to answer questions and build dashboards.";
7
7
 
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Analytics finds saved dashboards and queries far more reliably, and answers list and cohort questions in one query instead of grinding for minutes
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Notion access errors now explain that a page needs sharing with the integration, instead of naming an unrelated integration label
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-25
4
+ ---
5
+
6
+ App branding now uses the product name without the Agent-Native prefix.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-25
4
+ ---
5
+
6
+ Settings navigation now keeps Manage agent as a dedicated linked destination at the bottom.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "analytics",
3
- "displayName": "Agent-Native Analytics",
3
+ "displayName": "Analytics",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "Agent Native Analytics",
2
+ "name": "Analytics",
3
3
  "short_name": "Analytics",
4
4
  "description": "Analytics dashboard",
5
5
  "start_url": ".",
@@ -35,6 +35,13 @@ export const INITIAL_TOOL_NAMES = [
35
35
  "bigquery",
36
36
  "search-bigquery-schema",
37
37
  "list-data-dictionary",
38
+ // Bulk/cohort readers. Without these on the first surface a "list X excluding Y"
39
+ // question cannot reach any tool that answers it in one call, so the agent pays a
40
+ // tool-search round trip (~15 KB of results) before it can even start — or worse,
41
+ // enumerates the cohort page by page through whatever it can already see.
42
+ "provider-api-request",
43
+ "query-staged-dataset",
44
+ "hubspot-records",
38
45
  "navigate",
39
46
  ];
40
47
 
@@ -68,7 +68,8 @@ export type AnalyticsQueryCatalogCandidate =
68
68
  panelTitle: string;
69
69
  panelDescription?: string;
70
70
  source?: string;
71
- query: string | Record<string, unknown>;
71
+ /** Absent for extension/embed panels, which are matched on title and description. */
72
+ query?: string | Record<string, unknown>;
72
73
  timeScope?: string;
73
74
  }
74
75
  | {
@@ -105,43 +106,135 @@ function compactQuery(value: unknown): string | Record<string, unknown> | null {
105
106
  return null;
106
107
  }
107
108
 
108
- function searchTerms(search: string): string[] {
109
- const normalized = search
109
+ // Analytics vocabulary the corpus spells out but users abbreviate (or vice versa).
110
+ // Expansions match at reduced weight so they break ties without outranking a literal hit.
111
+ const SYNONYM_EXPANSIONS: Record<string, string[]> = {
112
+ account: ["company", "customer", "org"],
113
+ active: ["engaged"],
114
+ arr: ["annual", "recurring", "revenue"],
115
+ churn: ["cancel", "attrition", "downgrade"],
116
+ csql: ["sale", "qualified", "lead", "opportunity"],
117
+ customer: ["account", "company"],
118
+ dau: ["daily", "active", "user"],
119
+ deal: ["opportunity", "pipeline"],
120
+ error: ["5xx", "4xx", "exception", "failure", "fault"],
121
+ icp: ["ideal", "customer", "profile"],
122
+ mau: ["monthly", "active", "user"],
123
+ mql: ["marketing", "qualified", "lead"],
124
+ mrr: ["monthly", "recurring", "revenue"],
125
+ pageview: ["page", "view", "traffic", "session"],
126
+ pipeline: ["deal", "opportunity", "forecast"],
127
+ poc: ["proof", "concept", "trial", "pilot"],
128
+ revenue: ["bookings", "arr", "mrr", "won"],
129
+ signup: ["registration", "created", "onboard"],
130
+ traffic: ["pageview", "session", "visit"],
131
+ usage: ["active", "engagement"],
132
+ user: ["member", "person", "seat"],
133
+ wau: ["weekly", "active", "user"],
134
+ };
135
+
136
+ // Metric-shaped words that appear in a large share of titles and so discriminate
137
+ // almost nothing on their own. Scored down rather than dropped: "error rate" must
138
+ // still beat "rate", but four unrelated "... Rate" entries must not tie above the
139
+ // panel that actually matches "error".
140
+ const LOW_INFORMATION_TERMS = new Set([
141
+ "average",
142
+ "percent",
143
+ "percentage",
144
+ "rate",
145
+ "ratio",
146
+ "score",
147
+ "value",
148
+ "volume",
149
+ ]);
150
+
151
+ // Cheap plural folding. The corpus writes "Template"/"Deal" while users type
152
+ // "templates"/"deals"; exact substring matching missed every one of those.
153
+ function stem(token: string): string {
154
+ if (token.length > 4 && token.endsWith("ies"))
155
+ return `${token.slice(0, -3)}y`;
156
+ if (token.length > 4 && token.endsWith("sses")) return token.slice(0, -2);
157
+ if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss")) {
158
+ return token.slice(0, -1);
159
+ }
160
+ return token;
161
+ }
162
+
163
+ // Splits camelCase and snake_case so warehouse identifiers are searchable:
164
+ // `dim_hs_deals` -> dim, hs, deal.
165
+ function tokenize(value: string): string[] {
166
+ return value
167
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
110
168
  .toLowerCase()
111
169
  .replace(/[^a-z0-9]+/g, " ")
112
- .trim();
113
- if (!normalized) return [];
114
- const meaningful = normalized
170
+ .trim()
115
171
  .split(/\s+/)
116
- .filter((term) => term.length > 1 && !STOP_WORDS.has(term));
117
- return meaningful.length ? Array.from(new Set(meaningful)) : [normalized];
172
+ .filter(Boolean)
173
+ .map(stem);
174
+ }
175
+
176
+ function searchTerms(search: string): string[] {
177
+ const tokens = tokenize(search);
178
+ if (!tokens.length) return [];
179
+ const meaningful = tokens.filter(
180
+ (term) => term.length > 1 && !STOP_WORDS.has(term),
181
+ );
182
+ return Array.from(new Set(meaningful.length ? meaningful : tokens));
183
+ }
184
+
185
+ function expandedTerms(primary: string[]): string[] {
186
+ const primarySet = new Set(primary);
187
+ const expanded = new Set<string>();
188
+ for (const term of primary) {
189
+ for (const synonym of SYNONYM_EXPANSIONS[term] ?? []) {
190
+ const stemmed = stem(synonym);
191
+ if (!primarySet.has(stemmed)) expanded.add(stemmed);
192
+ }
193
+ }
194
+ return [...expanded];
118
195
  }
119
196
 
197
+ // SQL bodies run to 12k chars; scoring only needs the leading identifiers.
198
+ const MAX_SCORED_FIELD_CHARS = 4_000;
199
+
120
200
  function matchScore(
121
201
  search: string,
122
202
  weightedFields: Array<{ value: unknown; weight: number }>,
123
203
  ): { score: number; matchedTerms: string[] } {
124
204
  const terms = searchTerms(search);
125
205
  if (!terms.length) return { score: 0, matchedTerms: [] };
206
+ const synonyms = expandedTerms(terms);
126
207
 
127
208
  const normalizedSearch = search.toLowerCase().trim();
128
209
  const matched = new Set<string>();
129
210
  let score = 0;
130
211
  for (const field of weightedFields) {
131
- const value = text(field.value).toLowerCase();
132
- if (!value) continue;
133
- if (normalizedSearch.length > 2 && value.includes(normalizedSearch)) {
212
+ const raw = text(field.value).slice(0, MAX_SCORED_FIELD_CHARS);
213
+ if (!raw) continue;
214
+ const lowered = raw.toLowerCase();
215
+ const tokens = new Set(tokenize(raw));
216
+
217
+ if (normalizedSearch.length > 2 && lowered.includes(normalizedSearch)) {
134
218
  score += field.weight * 4;
135
219
  }
136
220
  for (const term of terms) {
137
- if (!value.includes(term)) continue;
221
+ if (!tokens.has(term) && !lowered.includes(term)) continue;
138
222
  matched.add(term);
139
- score += field.weight;
223
+ score += field.weight * (LOW_INFORMATION_TERMS.has(term) ? 0.3 : 1);
224
+ }
225
+ for (const synonym of synonyms) {
226
+ if (!tokens.has(synonym)) continue;
227
+ score += field.weight * 0.4;
140
228
  }
141
229
  }
142
230
 
143
- if (matched.size === terms.length) score += 40;
144
- return { score, matchedTerms: [...matched] };
231
+ // Proportional, not all-or-nothing: a 7-word question could never hit the old
232
+ // full-coverage bonus, so long real questions collapsed to near-random scores.
233
+ // Damped for short queries — at full strength every one-of-one-token match tied
234
+ // at the same score, so generic "... Rate" entries mass-tied above exact panels.
235
+ const coverageWeight = Math.min(terms.length, 3) / 3;
236
+ score += 40 * (matched.size / terms.length) * coverageWeight;
237
+ return { score: Math.round(score), matchedTerms: [...matched] };
145
238
  }
146
239
 
147
240
  function dashboardPanelCandidates(args: {
@@ -156,9 +249,15 @@ function dashboardPanelCandidates(args: {
156
249
  ? (args.config.panels as DashboardPanel[])
157
250
  : [];
158
251
 
252
+ const wantsDemo = /\bdemo\b|node exporter/i.test(args.search);
253
+
159
254
  return panels.flatMap((panel) => {
255
+ // 38k of the ~39k indexed panels are clones of the demo Node Exporter dashboard.
256
+ // They drown real saved work and are never the answer to a real data question.
257
+ if (!wantsDemo && text(panel.source) === "demo") return [];
258
+ // Panels without SQL (extensions, embeds) used to be dropped outright, which hid
259
+ // 61% of real dashboards from search even when their titles matched exactly.
160
260
  const query = compactQuery(panel.sql);
161
- if (!query) return [];
162
261
  const panelConfig =
163
262
  panel.config &&
164
263
  typeof panel.config === "object" &&
@@ -174,20 +273,49 @@ function dashboardPanelCandidates(args: {
174
273
  { value: args.dashboardDescription, weight: 6 },
175
274
  { value: panel.source, weight: 5 },
176
275
  {
177
- value: typeof query === "string" ? query : JSON.stringify(query),
178
- weight: 2,
276
+ // Weighted 2 against a title's 24, this 12x discount hid every panel whose
277
+ // match lived only in its SQL — the majority of them.
278
+ value: query
279
+ ? typeof query === "string"
280
+ ? query
281
+ : JSON.stringify(query)
282
+ : "",
283
+ weight: 8,
179
284
  },
180
285
  ]);
286
+ // Prefer the general panel over a narrower variant ("Signups" over "Clip Share
287
+ // Signups 30d"), but cap it: the original uncapped -12/token buried long,
288
+ // well-named panels under short vague ones.
181
289
  const requestedTerms = new Set(searchTerms(args.search));
182
- const titleSpecificityPenalty =
183
- searchTerms(panelTitle).filter((term) => !requestedTerms.has(term))
184
- .length * 12;
290
+ const unmatchedTitleTerms = searchTerms(panelTitle).filter(
291
+ (term) => !requestedTerms.has(term),
292
+ ).length;
293
+ const titleSpecificityPenalty = Math.min(unmatchedTitleTerms, 4) * 4;
294
+ // A panel with no SQL costs the agent another call to become useful, so it must
295
+ // not outrank an equally-relevant runnable one. Waived when the title is clearly
296
+ // on-topic: real questions carry clause words no title contains, so requiring
297
+ // full coverage here never fires and buries exact-topic panels.
298
+ const titleMatchedTerms = matchScore(args.search, [
299
+ { value: panelTitle, weight: 1 },
300
+ ]).matchedTerms;
301
+ const strongTitleTerms = titleMatchedTerms.filter(
302
+ (term) => !LOW_INFORMATION_TERMS.has(term),
303
+ ).length;
304
+ const titleIsOnTopic =
305
+ requestedTerms.size > 0 &&
306
+ (strongTitleTerms >= 2 ||
307
+ titleMatchedTerms.length / requestedTerms.size >= 0.6);
308
+ const missingQueryPenalty = query || titleIsOnTopic ? 0 : 10;
185
309
  const aggregateIntent =
186
310
  /\b(how many|count|number|total)\b/i.test(args.search) &&
187
311
  text(panel.chartType) === "metric"
188
312
  ? 20
189
313
  : 0;
190
- const score = rawScore - titleSpecificityPenalty + aggregateIntent;
314
+ const score =
315
+ rawScore -
316
+ titleSpecificityPenalty -
317
+ missingQueryPenalty +
318
+ aggregateIntent;
191
319
  if (score <= 0) return [];
192
320
 
193
321
  return [
@@ -205,7 +333,7 @@ function dashboardPanelCandidates(args: {
205
333
  panelTitle,
206
334
  ...(panelDescription ? { panelDescription } : {}),
207
335
  ...(text(panel.source) ? { source: text(panel.source) } : {}),
208
- query,
336
+ ...(query ? { query } : {}),
209
337
  ...(text(panelConfig.timeScope)
210
338
  ? { timeScope: text(panelConfig.timeScope) }
211
339
  : {}),
@@ -270,6 +398,26 @@ function dictionaryCandidates(
270
398
  });
271
399
  }
272
400
 
401
+ function candidateIsRunnable(
402
+ candidate: AnalyticsQueryCatalogCandidate,
403
+ ): boolean {
404
+ return candidate.kind === "dashboard-panel"
405
+ ? Boolean(candidate.query)
406
+ : Boolean(candidate.queryTemplate);
407
+ }
408
+
409
+ function candidateDedupeKey(candidate: AnalyticsQueryCatalogCandidate): string {
410
+ if (candidate.kind === "data-dictionary") return `dict:${candidate.id}`;
411
+ const query =
412
+ typeof candidate.query === "string"
413
+ ? candidate.query
414
+ : JSON.stringify(candidate.query ?? "");
415
+ return `panel:${candidate.panelTitle.toLowerCase()}:${query
416
+ .replace(/\s+/g, " ")
417
+ .trim()
418
+ .toLowerCase()}`;
419
+ }
420
+
273
421
  export function rankAnalyticsQueryCatalog(args: {
274
422
  search: string;
275
423
  dashboards: Array<{
@@ -296,13 +444,26 @@ export function rankAnalyticsQueryCatalog(args: {
296
444
  ...dictionaryCandidates(args.dictionaryEntries, args.search),
297
445
  ];
298
446
 
299
- return candidates
300
- .sort((a, b) => {
301
- if (b.score !== a.score) return b.score - a.score;
302
- if (a.kind !== b.kind) return a.kind === "data-dictionary" ? -1 : 1;
303
- return JSON.stringify(a).localeCompare(JSON.stringify(b));
304
- })
305
- .slice(0, args.limit);
447
+ const ranked = candidates.sort((a, b) => {
448
+ if (b.score !== a.score) return b.score - a.score;
449
+ // Prefer something the agent can run over something it must look up again.
450
+ const aRunnable = candidateIsRunnable(a);
451
+ const bRunnable = candidateIsRunnable(b);
452
+ if (aRunnable !== bRunnable) return aRunnable ? -1 : 1;
453
+ if (a.kind !== b.kind) return a.kind === "data-dictionary" ? -1 : 1;
454
+ return JSON.stringify(a).localeCompare(JSON.stringify(b));
455
+ });
456
+
457
+ // Cloned dashboards produce near-identical panels that otherwise eat every slot.
458
+ const seen = new Set<string>();
459
+ const deduped: AnalyticsQueryCatalogCandidate[] = [];
460
+ for (const candidate of ranked) {
461
+ if (deduped.length >= args.limit) break;
462
+ if (seen.has(candidateDedupeKey(candidate))) continue;
463
+ seen.add(candidateDedupeKey(candidate));
464
+ deduped.push(candidate);
465
+ }
466
+ return deduped;
306
467
  }
307
468
 
308
469
  async function listDictionaryEntries(args: {
@@ -239,6 +239,8 @@ export interface QueryResult {
239
239
  schema: { name: string; type: string }[];
240
240
  bytesProcessed: number;
241
241
  cached?: boolean;
242
+ /** True when BigQuery matched more rows than this first page returned. */
243
+ truncated?: boolean;
242
244
  }
243
245
 
244
246
  export interface RunQueryOptions {
@@ -516,11 +518,19 @@ export async function runQuery(
516
518
  const rows = data.rows ? rowsToObjects(data.rows, fields) : [];
517
519
  const bytesProcessed = parseInt(data.totalBytesProcessed || "0", 10);
518
520
 
521
+ // BigQuery reports the full match count; `rows` only holds the first page. Reporting
522
+ // rows.length as the total made every partial result look complete to the agent.
523
+ const reportedTotal = Number.parseInt(data.totalRows || "", 10);
524
+ const totalRows = Number.isFinite(reportedTotal)
525
+ ? reportedTotal
526
+ : rows.length;
527
+
519
528
  const result: QueryResult = {
520
529
  rows,
521
- totalRows: rows.length,
530
+ totalRows,
522
531
  schema,
523
532
  bytesProcessed,
533
+ ...(totalRows > rows.length ? { truncated: true } : {}),
524
534
  };
525
535
 
526
536
  setL1(cacheKey, result);
@@ -39,6 +39,19 @@ async function getApiKey(): Promise<string> {
39
39
  return credential.value;
40
40
  }
41
41
 
42
+ // The name Notion reports for a token is whatever label its creator typed in, so it
43
+ // routinely names an unrelated product. Never restate it as the current workspace.
44
+ const NOTION_ACCESS_HINT =
45
+ "This usually means the page or database was never shared with the Notion integration behind NOTION_API_KEY, not that the id is wrong. Fix it in Notion: open the page, then ••• → Connections → add the integration. The integration's Notion-side label may not match this app or workspace.";
46
+
47
+ function notionApiError(status: number, body: string): Error {
48
+ const suffix =
49
+ status === 401 || status === 403 || status === 404
50
+ ? ` ${NOTION_ACCESS_HINT}`
51
+ : "";
52
+ return new Error(`Notion API error ${status}: ${body}${suffix}`);
53
+ }
54
+
42
55
  async function notionGet(path: string): Promise<unknown> {
43
56
  const res = await fetch(`${NOTION_API}${path}`, {
44
57
  headers: {
@@ -47,8 +60,7 @@ async function notionGet(path: string): Promise<unknown> {
47
60
  },
48
61
  });
49
62
  if (!res.ok) {
50
- const text = await res.text();
51
- throw new Error(`Notion API error ${res.status}: ${text}`);
63
+ throw notionApiError(res.status, await res.text());
52
64
  }
53
65
  return res.json();
54
66
  }
@@ -64,8 +76,7 @@ async function notionPost(path: string, body: unknown): Promise<unknown> {
64
76
  body: JSON.stringify(body),
65
77
  });
66
78
  if (!res.ok) {
67
- const text = await res.text();
68
- throw new Error(`Notion API error ${res.status}: ${text}`);
79
+ throw notionApiError(res.status, await res.text());
69
80
  }
70
81
  return res.json();
71
82
  }