@agent-native/core 0.120.1 → 0.120.3

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 (396) hide show
  1. package/corpus/README.md +3 -3
  2. package/corpus/core/CHANGELOG.md +29 -0
  3. package/corpus/core/docs/content/extensions.mdx +23 -4
  4. package/corpus/core/package.json +1 -1
  5. package/corpus/core/src/agent/production-agent.ts +4 -0
  6. package/corpus/core/src/agent/run-manager.ts +36 -10
  7. package/corpus/core/src/agent/types.ts +2 -0
  8. package/corpus/core/src/cli/context-xray-local.ts +1 -1
  9. package/corpus/core/src/cli/index.ts +63 -18
  10. package/corpus/core/src/cli/skills.ts +5 -0
  11. package/corpus/core/src/cli/telemetry.ts +118 -1
  12. package/corpus/core/src/client/AgentPanel.tsx +10 -0
  13. package/corpus/core/src/client/CommandMenu.tsx +13 -1
  14. package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +39 -4
  15. package/corpus/core/src/client/analytics.ts +13 -0
  16. package/corpus/core/src/client/error-capture.ts +6 -1
  17. package/corpus/core/src/client/extensions/ExtensionsListPage.tsx +28 -8
  18. package/corpus/core/src/client/extensions/agent-native-extension-runtime.ts +1 -1
  19. package/corpus/core/src/client/navigation/index.ts +2 -0
  20. package/corpus/core/src/client/org/OrgSwitcher.tsx +14 -32
  21. package/corpus/core/src/client/settings/ExtensionsSettingsContent.tsx +24 -0
  22. package/corpus/core/src/client/settings/SettingsPanel.tsx +10 -0
  23. package/corpus/core/src/deploy/build.ts +3 -0
  24. package/corpus/core/src/extensions/theme.ts +1 -1
  25. package/corpus/core/src/localization/default-messages.ts +2 -0
  26. package/corpus/core/src/server/analytics.ts +154 -25
  27. package/corpus/core/src/server/core-routes-plugin.ts +10 -1
  28. package/corpus/core/src/server/framework-request-handler.ts +17 -26
  29. package/corpus/core/src/styles/agent-native.css +13 -0
  30. package/corpus/core/src/templates/chat/app/components/layout/Layout.tsx +3 -0
  31. package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +113 -51
  32. package/corpus/core/src/templates/chat/app/global.css +1 -1
  33. package/corpus/core/src/templates/chat/app/routes/extensions._index.tsx +2 -2
  34. package/corpus/core/src/templates/chat/netlify.toml +1 -0
  35. package/corpus/core/src/templates/default/app/global.css +1 -1
  36. package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +16 -0
  37. package/corpus/core/src/tracking/error-capture.ts +151 -0
  38. package/corpus/core/src/tracking/index.ts +5 -0
  39. package/corpus/core/src/vite/client.ts +6 -0
  40. package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +27 -43
  41. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +19 -8
  42. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +2 -2
  43. package/corpus/templates/analytics/AGENTS.md +20 -8
  44. package/corpus/templates/analytics/actions/get-explorer-dashboard.ts +3 -0
  45. package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +140 -46
  46. package/corpus/templates/analytics/actions/migrate-analytics-artifacts.ts +48 -0
  47. package/corpus/templates/analytics/actions/save-analysis.ts +2 -3
  48. package/corpus/templates/analytics/actions/view-screen.ts +1 -1
  49. package/corpus/templates/analytics/app/components/dashboard/CumulativeNetChart.tsx +1 -1
  50. package/corpus/templates/analytics/app/components/dashboard/DashboardHistoryPanel.tsx +1 -4
  51. package/corpus/templates/analytics/app/components/dashboard/DashboardMetadata.tsx +77 -0
  52. package/corpus/templates/analytics/app/components/dashboard/DashboardPanelSkeleton.tsx +7 -1
  53. package/corpus/templates/analytics/app/components/dashboard/DataTable.tsx +1 -1
  54. package/corpus/templates/analytics/app/components/dashboard/DateRangePicker.tsx +2 -2
  55. package/corpus/templates/analytics/app/components/dashboard/MetricCard.tsx +1 -1
  56. package/corpus/templates/analytics/app/components/dashboard/RecentActivity.tsx +1 -1
  57. package/corpus/templates/analytics/app/components/dashboard/RevenueChart.tsx +1 -1
  58. package/corpus/templates/analytics/app/components/dashboard/RevenueComparisonChart.tsx +1 -1
  59. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +41 -9
  60. package/corpus/templates/analytics/app/components/dashboard/StatsCard.tsx +1 -1
  61. package/corpus/templates/analytics/app/components/dashboard/TimeSeriesChart.tsx +1 -1
  62. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +2 -0
  63. package/corpus/templates/analytics/app/components/layout/Layout.tsx +28 -14
  64. package/corpus/templates/analytics/app/components/layout/NewDashboardDialog.tsx +1 -0
  65. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +255 -626
  66. package/corpus/templates/analytics/app/global.css +31 -1
  67. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +2 -2
  68. package/corpus/templates/analytics/app/i18n-data.ts +80 -0
  69. package/corpus/templates/analytics/app/lib/dashboard-report-capture.ts +42 -0
  70. package/corpus/templates/analytics/app/pages/Agents.tsx +49 -2
  71. package/corpus/templates/analytics/app/pages/adhoc/_shared/KpiChart.tsx +1 -1
  72. package/corpus/templates/analytics/app/pages/adhoc/explorer/components/ChartTypePicker.tsx +1 -1
  73. package/corpus/templates/analytics/app/pages/adhoc/explorer/components/DateRangePicker.tsx +1 -1
  74. package/corpus/templates/analytics/app/pages/adhoc/explorer/components/EventRow.tsx +1 -1
  75. package/corpus/templates/analytics/app/pages/adhoc/explorer/components/SqlPreview.tsx +2 -2
  76. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +54 -11
  77. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +3 -3
  78. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/EmailReportDialog.tsx +2 -2
  79. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +1 -1
  80. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +4 -54
  81. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +178 -69
  82. package/corpus/templates/analytics/app/pages/analyses/AnalysisDetail.tsx +2 -2
  83. package/corpus/templates/analytics/app/root.tsx +28 -0
  84. package/corpus/templates/analytics/app/routes/analyses._index.tsx +3 -2
  85. package/corpus/templates/analytics/app/routes/extensions._index.tsx +2 -2
  86. package/corpus/templates/analytics/changelog/2026-07-23-analytics-now-groups-saved-analyses-and-embedded-extensions-.md +6 -0
  87. package/corpus/templates/analytics/changelog/2026-07-23-dashboard-menus-show-who-created-and-last-updated-each-dashb.md +6 -0
  88. package/corpus/templates/analytics/changelog/2026-07-23-dashboard-usage-now-loads-reliably-for-organizations-with-ma.md +6 -0
  89. package/corpus/templates/analytics/changelog/2026-07-23-long-dashboard-building-requests-now-continue-without-stoppi.md +6 -0
  90. package/corpus/templates/analytics/changelog/2026-07-24-analytics-charts-now-explain-slow-loads-and-offer-a-direct-r.md +6 -0
  91. package/corpus/templates/analytics/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  92. package/corpus/templates/analytics/changelog/2026-07-24-daily-dashboard-emails-now-load-signed-reports-more-reliably.md +6 -0
  93. package/corpus/templates/analytics/changelog/2026-07-24-manage-agent-is-clearly-marked-as-a-link-to-its-dedicated-pa.md +6 -0
  94. package/corpus/templates/analytics/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  95. package/corpus/templates/analytics/netlify.toml +4 -0
  96. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +1 -1
  97. package/corpus/templates/analytics/server/db/schema.ts +9 -0
  98. package/corpus/templates/analytics/server/jobs/dashboard-report.ts +21 -0
  99. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +0 -1
  100. package/corpus/templates/analytics/server/lib/agent-readable-resource-context.ts +1 -0
  101. package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +11 -0
  102. package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +54 -0
  103. package/corpus/templates/analytics/server/lib/dashboard-report.ts +235 -26
  104. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +4 -1
  105. package/corpus/templates/analytics/server/lib/migrate-analytics-artifacts.ts +1062 -0
  106. package/corpus/templates/analytics/server/plugins/agent-chat.ts +6 -52
  107. package/corpus/templates/analytics/server/plugins/core-routes.ts +1 -1
  108. package/corpus/templates/analytics/server/plugins/db.ts +19 -0
  109. package/corpus/templates/analytics/shared/dashboard-report-timeouts.ts +1 -1
  110. package/corpus/templates/assets/actions/generate-image-batch.ts +36 -1
  111. package/corpus/templates/assets/actions/generate-image.ts +28 -1
  112. package/corpus/templates/assets/app/components/asset/AssetPreviewDialog.tsx +376 -0
  113. package/corpus/templates/assets/app/components/create/RecentDraftsSection.tsx +14 -4
  114. package/corpus/templates/assets/app/components/layout/Layout.tsx +5 -0
  115. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +164 -82
  116. package/corpus/templates/assets/app/global.css +1 -1
  117. package/corpus/templates/assets/app/i18n-data.ts +10 -0
  118. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +99 -10
  119. package/corpus/templates/assets/app/routes/extensions._index.tsx +2 -2
  120. package/corpus/templates/assets/app/routes/library.tsx +21 -198
  121. package/corpus/templates/assets/changelog/2026-07-21-unified-asset-preview-click-any-asset-to-open-one-preview-wi.md +6 -0
  122. package/corpus/templates/assets/changelog/2026-07-23-assets-image-generation-now-recovers-after-a-completed-tool-.md +6 -0
  123. package/corpus/templates/assets/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  124. package/corpus/templates/assets/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  125. package/corpus/templates/assets/netlify.toml +1 -0
  126. package/corpus/templates/brain/app/components/layout/Layout.tsx +3 -0
  127. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +114 -51
  128. package/corpus/templates/brain/app/global.css +1 -1
  129. package/corpus/templates/brain/app/routes/extensions._index.tsx +2 -2
  130. package/corpus/templates/brain/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  131. package/corpus/templates/brain/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  132. package/corpus/templates/brain/netlify.toml +1 -0
  133. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +110 -57
  134. package/corpus/templates/calendar/app/global.css +1 -1
  135. package/corpus/templates/calendar/app/routes/_app.extensions._index.tsx +2 -16
  136. package/corpus/templates/calendar/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  137. package/corpus/templates/calendar/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  138. package/corpus/templates/calendar/netlify.toml +1 -0
  139. package/corpus/templates/chat/app/components/layout/Layout.tsx +3 -0
  140. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +113 -51
  141. package/corpus/templates/chat/app/global.css +1 -1
  142. package/corpus/templates/chat/app/routes/extensions._index.tsx +2 -2
  143. package/corpus/templates/chat/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  144. package/corpus/templates/chat/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  145. package/corpus/templates/chat/netlify.toml +1 -0
  146. package/corpus/templates/clips/app/components/library/library-layout.tsx +117 -37
  147. package/corpus/templates/clips/app/components/library/organization-switcher.tsx +2 -2
  148. package/corpus/templates/clips/app/components/player/video-player.tsx +16 -1
  149. package/corpus/templates/clips/app/global.css +1 -1
  150. package/corpus/templates/clips/app/hooks/use-view-tracking.ts +55 -12
  151. package/corpus/templates/clips/app/routes/_app.extensions._index.tsx +2 -16
  152. package/corpus/templates/clips/app/routes/embed.$shareId.tsx +6 -5
  153. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +7 -7
  154. package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -5
  155. package/corpus/templates/clips/changelog/2026-07-23-agent-settings-are-clearly-labeled-manage-agent-in-the-sideb.md +6 -0
  156. package/corpus/templates/clips/changelog/2026-07-23-meeting-recording-meters-and-dismissed-prompts.md +6 -0
  157. package/corpus/templates/clips/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  158. package/corpus/templates/clips/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  159. package/corpus/templates/clips/desktop/src/hooks/useMicMeter.ts +1 -1
  160. package/corpus/templates/clips/desktop/src/lib/meeting-notification-dismissal.ts +2 -0
  161. package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +1 -3
  162. package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +86 -0
  163. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +24 -0
  164. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +5 -69
  165. package/corpus/templates/clips/desktop/src/styles.css +35 -3
  166. package/corpus/templates/clips/desktop/src-tauri/src/adhoc_meetings_watcher.rs +13 -44
  167. package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +119 -17
  168. package/corpus/templates/clips/netlify.toml +1 -0
  169. package/corpus/templates/clips/server/plugins/db.ts +113 -68
  170. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +69 -49
  171. package/corpus/templates/content/app/global.css +1 -1
  172. package/corpus/templates/content/app/routes/_app.extensions._index.tsx +2 -2
  173. package/corpus/templates/content/changelog/2026-07-23-agent-settings-are-clearly-labeled-manage-agent-in-the-sideb.md +6 -0
  174. package/corpus/templates/content/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  175. package/corpus/templates/content/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  176. package/corpus/templates/content/netlify.toml +1 -0
  177. package/corpus/templates/design/app/components/layout/Sidebar.tsx +115 -42
  178. package/corpus/templates/design/app/entry.client.tsx +14 -1
  179. package/corpus/templates/design/app/global.css +1 -1
  180. package/corpus/templates/design/app/routes/extensions._index.tsx +2 -2
  181. package/corpus/templates/design/changelog/2026-07-23-agent-settings-are-clearly-labeled-manage-agent-in-the-sideb.md +6 -0
  182. package/corpus/templates/design/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  183. package/corpus/templates/design/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  184. package/corpus/templates/design/netlify.toml +1 -0
  185. package/corpus/templates/dispatch/app/dispatch-extensions.tsx +1 -1
  186. package/corpus/templates/dispatch/app/global.css +1 -1
  187. package/corpus/templates/dispatch/changelog/2026-07-23-agent-settings-are-clearly-labeled-manage-agent-in-the-sideb.md +6 -0
  188. package/corpus/templates/dispatch/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  189. package/corpus/templates/dispatch/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  190. package/corpus/templates/dispatch/netlify.toml +1 -0
  191. package/corpus/templates/forms/app/components/layout/Layout.tsx +3 -0
  192. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +113 -82
  193. package/corpus/templates/forms/app/global.css +1 -1
  194. package/corpus/templates/forms/app/routes/_app.extensions._index.tsx +2 -2
  195. package/corpus/templates/forms/changelog/2026-07-23-agent-settings-are-clearly-labeled-manage-agent-in-the-sideb.md +6 -0
  196. package/corpus/templates/forms/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  197. package/corpus/templates/forms/changelog/2026-07-24-forms-sidebar-actions-now-keep-search-language-feedback-and-.md +6 -0
  198. package/corpus/templates/forms/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  199. package/corpus/templates/forms/netlify.toml +1 -0
  200. package/corpus/templates/macros/app/components/DailyProgress.tsx +5 -5
  201. package/corpus/templates/macros/app/components/ExerciseCard.tsx +2 -2
  202. package/corpus/templates/macros/app/components/MealCard.tsx +2 -2
  203. package/corpus/templates/macros/app/components/WeightCard.tsx +2 -2
  204. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +92 -34
  205. package/corpus/templates/macros/app/components/ui/button.tsx +1 -2
  206. package/corpus/templates/macros/app/components/ui/card.tsx +1 -1
  207. package/corpus/templates/macros/app/global.css +1 -1
  208. package/corpus/templates/macros/app/routes/_index.tsx +1 -1
  209. package/corpus/templates/macros/app/routes/analytics.tsx +4 -7
  210. package/corpus/templates/macros/app/routes/extensions._index.tsx +2 -2
  211. package/corpus/templates/macros/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  212. package/corpus/templates/macros/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  213. package/corpus/templates/macros/netlify.toml +1 -0
  214. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +125 -46
  215. package/corpus/templates/mail/app/global.css +1 -1
  216. package/corpus/templates/mail/app/routes/extensions._index.tsx +2 -2
  217. package/corpus/templates/mail/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  218. package/corpus/templates/mail/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  219. package/corpus/templates/mail/netlify.toml +1 -0
  220. package/corpus/templates/plan/app/components/layout/Layout.tsx +3 -0
  221. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +128 -65
  222. package/corpus/templates/plan/app/global.css +1 -1
  223. package/corpus/templates/plan/app/routes/extensions._index.tsx +2 -2
  224. package/corpus/templates/plan/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  225. package/corpus/templates/plan/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  226. package/corpus/templates/plan/netlify.toml +1 -0
  227. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +116 -36
  228. package/corpus/templates/slides/app/global.css +1 -1
  229. package/corpus/templates/slides/app/routes/extensions._index.tsx +2 -2
  230. package/corpus/templates/slides/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  231. package/corpus/templates/slides/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  232. package/corpus/templates/slides/netlify.toml +1 -0
  233. package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +37 -6
  234. package/corpus/templates/tasks/app/global.css +1 -1
  235. package/corpus/templates/tasks/app/routes/extensions._index.tsx +2 -2
  236. package/corpus/templates/tasks/app/routes/settings.tsx +31 -0
  237. package/corpus/templates/tasks/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  238. package/corpus/templates/tasks/netlify.toml +1 -0
  239. package/corpus/toolkit/CHANGELOG.md +8 -0
  240. package/corpus/toolkit/README.md +8 -1
  241. package/corpus/toolkit/agent-native.eject.json +1 -1
  242. package/corpus/toolkit/package.json +1 -1
  243. package/corpus/toolkit/src/app-shell/index.ts +1 -0
  244. package/corpus/toolkit/src/app-shell/sidebar-footer-actions.tsx +48 -0
  245. package/corpus/toolkit/src/chat-history.css +52 -1
  246. package/corpus/toolkit/src/design-system/default-adapter.tsx +1 -1
  247. package/corpus/toolkit/src/ui/button.tsx +1 -2
  248. package/corpus/toolkit/src/ui/card.tsx +1 -1
  249. package/corpus/toolkit/src/ui/table.tsx +4 -11
  250. package/dist/agent/production-agent.d.ts.map +1 -1
  251. package/dist/agent/production-agent.js +4 -0
  252. package/dist/agent/production-agent.js.map +1 -1
  253. package/dist/agent/run-manager.d.ts +9 -0
  254. package/dist/agent/run-manager.d.ts.map +1 -1
  255. package/dist/agent/run-manager.js +25 -10
  256. package/dist/agent/run-manager.js.map +1 -1
  257. package/dist/agent/types.d.ts +2 -2
  258. package/dist/agent/types.d.ts.map +1 -1
  259. package/dist/agent/types.js.map +1 -1
  260. package/dist/cli/context-xray-local.js +1 -1
  261. package/dist/cli/context-xray-local.js.map +1 -1
  262. package/dist/cli/index.js +56 -17
  263. package/dist/cli/index.js.map +1 -1
  264. package/dist/cli/skills.d.ts.map +1 -1
  265. package/dist/cli/skills.js +5 -0
  266. package/dist/cli/skills.js.map +1 -1
  267. package/dist/cli/telemetry.d.ts +7 -0
  268. package/dist/cli/telemetry.d.ts.map +1 -1
  269. package/dist/cli/telemetry.js +91 -1
  270. package/dist/cli/telemetry.js.map +1 -1
  271. package/dist/client/AgentPanel.d.ts +7 -1
  272. package/dist/client/AgentPanel.d.ts.map +1 -1
  273. package/dist/client/AgentPanel.js +2 -2
  274. package/dist/client/AgentPanel.js.map +1 -1
  275. package/dist/client/CommandMenu.d.ts +2 -0
  276. package/dist/client/CommandMenu.d.ts.map +1 -1
  277. package/dist/client/CommandMenu.js +12 -1
  278. package/dist/client/CommandMenu.js.map +1 -1
  279. package/dist/client/agent-page/AgentTabsPage.d.ts +4 -0
  280. package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -1
  281. package/dist/client/agent-page/AgentTabsPage.js +8 -4
  282. package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
  283. package/dist/client/analytics.d.ts.map +1 -1
  284. package/dist/client/analytics.js +7 -0
  285. package/dist/client/analytics.js.map +1 -1
  286. package/dist/client/error-capture.d.ts.map +1 -1
  287. package/dist/client/error-capture.js +8 -1
  288. package/dist/client/error-capture.js.map +1 -1
  289. package/dist/client/extensions/ExtensionsListPage.d.ts +5 -1
  290. package/dist/client/extensions/ExtensionsListPage.d.ts.map +1 -1
  291. package/dist/client/extensions/ExtensionsListPage.js +6 -4
  292. package/dist/client/extensions/ExtensionsListPage.js.map +1 -1
  293. package/dist/client/extensions/agent-native-extension-runtime.js +1 -1
  294. package/dist/client/extensions/agent-native-extension-runtime.js.map +1 -1
  295. package/dist/client/navigation/index.d.ts +1 -1
  296. package/dist/client/navigation/index.d.ts.map +1 -1
  297. package/dist/client/navigation/index.js +1 -1
  298. package/dist/client/navigation/index.js.map +1 -1
  299. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  300. package/dist/client/org/OrgSwitcher.js +9 -13
  301. package/dist/client/org/OrgSwitcher.js.map +1 -1
  302. package/dist/client/settings/ExtensionsSettingsContent.d.ts +2 -0
  303. package/dist/client/settings/ExtensionsSettingsContent.d.ts.map +1 -0
  304. package/dist/client/settings/ExtensionsSettingsContent.js +10 -0
  305. package/dist/client/settings/ExtensionsSettingsContent.js.map +1 -0
  306. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  307. package/dist/client/settings/SettingsPanel.js +10 -1
  308. package/dist/client/settings/SettingsPanel.js.map +1 -1
  309. package/dist/deploy/build.js +1 -0
  310. package/dist/deploy/build.js.map +1 -1
  311. package/dist/extensions/theme.js +1 -1
  312. package/dist/extensions/theme.js.map +1 -1
  313. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  314. package/dist/localization/default-messages.d.ts +2 -0
  315. package/dist/localization/default-messages.d.ts.map +1 -1
  316. package/dist/localization/default-messages.js +2 -0
  317. package/dist/localization/default-messages.js.map +1 -1
  318. package/dist/observability/routes.d.ts +3 -3
  319. package/dist/progress/routes.d.ts +1 -1
  320. package/dist/provider-api/actions/custom-provider-registration.d.ts +7 -7
  321. package/dist/provider-api/actions/provider-api.d.ts +9 -9
  322. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  323. package/dist/resources/handlers.d.ts +1 -1
  324. package/dist/server/analytics.d.ts +9 -4
  325. package/dist/server/analytics.d.ts.map +1 -1
  326. package/dist/server/analytics.js +111 -22
  327. package/dist/server/analytics.js.map +1 -1
  328. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  329. package/dist/server/core-routes-plugin.js +8 -1
  330. package/dist/server/core-routes-plugin.js.map +1 -1
  331. package/dist/server/framework-request-handler.d.ts.map +1 -1
  332. package/dist/server/framework-request-handler.js +17 -27
  333. package/dist/server/framework-request-handler.js.map +1 -1
  334. package/dist/server/realtime-token.d.ts +1 -1
  335. package/dist/styles/agent-native.css +13 -0
  336. package/dist/templates/chat/app/components/layout/Layout.tsx +3 -0
  337. package/dist/templates/chat/app/components/layout/Sidebar.tsx +113 -51
  338. package/dist/templates/chat/app/global.css +1 -1
  339. package/dist/templates/chat/app/routes/extensions._index.tsx +2 -2
  340. package/dist/templates/chat/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  341. package/dist/templates/chat/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  342. package/dist/templates/chat/netlify.toml +1 -0
  343. package/dist/templates/default/app/global.css +1 -1
  344. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +16 -0
  345. package/dist/tracking/error-capture.d.ts +14 -0
  346. package/dist/tracking/error-capture.d.ts.map +1 -0
  347. package/dist/tracking/error-capture.js +113 -0
  348. package/dist/tracking/error-capture.js.map +1 -0
  349. package/dist/tracking/index.d.ts +1 -0
  350. package/dist/tracking/index.d.ts.map +1 -1
  351. package/dist/tracking/index.js +1 -0
  352. package/dist/tracking/index.js.map +1 -1
  353. package/dist/vite/client.d.ts.map +1 -1
  354. package/dist/vite/client.js +2 -0
  355. package/dist/vite/client.js.map +1 -1
  356. package/docs/content/extensions.mdx +23 -4
  357. package/package.json +2 -2
  358. package/src/agent/production-agent.ts +4 -0
  359. package/src/agent/run-manager.ts +36 -10
  360. package/src/agent/types.ts +2 -0
  361. package/src/cli/context-xray-local.ts +1 -1
  362. package/src/cli/index.ts +63 -18
  363. package/src/cli/skills.ts +5 -0
  364. package/src/cli/telemetry.ts +118 -1
  365. package/src/client/AgentPanel.tsx +10 -0
  366. package/src/client/CommandMenu.tsx +13 -1
  367. package/src/client/agent-page/AgentTabsPage.tsx +39 -4
  368. package/src/client/analytics.ts +13 -0
  369. package/src/client/error-capture.ts +6 -1
  370. package/src/client/extensions/ExtensionsListPage.tsx +28 -8
  371. package/src/client/extensions/agent-native-extension-runtime.ts +1 -1
  372. package/src/client/navigation/index.ts +2 -0
  373. package/src/client/org/OrgSwitcher.tsx +14 -32
  374. package/src/client/settings/ExtensionsSettingsContent.tsx +24 -0
  375. package/src/client/settings/SettingsPanel.tsx +10 -0
  376. package/src/deploy/build.ts +3 -0
  377. package/src/extensions/theme.ts +1 -1
  378. package/src/localization/default-messages.ts +2 -0
  379. package/src/server/analytics.ts +154 -25
  380. package/src/server/core-routes-plugin.ts +10 -1
  381. package/src/server/framework-request-handler.ts +17 -26
  382. package/src/styles/agent-native.css +13 -0
  383. package/src/templates/chat/app/components/layout/Layout.tsx +3 -0
  384. package/src/templates/chat/app/components/layout/Sidebar.tsx +113 -51
  385. package/src/templates/chat/app/global.css +1 -1
  386. package/src/templates/chat/app/routes/extensions._index.tsx +2 -2
  387. package/src/templates/chat/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  388. package/src/templates/chat/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  389. package/src/templates/chat/netlify.toml +1 -0
  390. package/src/templates/default/app/global.css +1 -1
  391. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +16 -0
  392. package/src/tracking/error-capture.ts +151 -0
  393. package/src/tracking/index.ts +5 -0
  394. package/src/vite/client.ts +6 -0
  395. package/corpus/templates/analytics/app/components/layout/NewAnalysisDialog.tsx +0 -165
  396. package/corpus/templates/analytics/app/pages/analyses/AnalysesList.tsx +0 -175
@@ -4,7 +4,6 @@ import { useDraggable } from "@dnd-kit/core";
4
4
  import {
5
5
  IconGripVertical,
6
6
  IconDotsVertical,
7
- IconExternalLink,
8
7
  IconMaximize,
9
8
  IconPencil,
10
9
  IconRefresh,
@@ -14,9 +13,8 @@ import {
14
13
  IconMessageCircle,
15
14
  IconBrandGoogle,
16
15
  } from "@tabler/icons-react";
17
- import { useIsFetching, useQueryClient } from "@tanstack/react-query";
16
+ import { useQueryClient } from "@tanstack/react-query";
18
17
  import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
19
- import { useNavigate } from "react-router";
20
18
  import { toast } from "sonner";
21
19
 
22
20
  import { ChartFillHeight, SqlChart } from "@/components/dashboard/SqlChart";
@@ -44,7 +42,6 @@ import {
44
42
  DropdownMenuSeparator,
45
43
  DropdownMenuTrigger,
46
44
  } from "@/components/ui/dropdown-menu";
47
- import { Spinner } from "@/components/ui/spinner";
48
45
  import {
49
46
  Tooltip,
50
47
  TooltipContent,
@@ -143,7 +140,6 @@ export function SqlChartCard({
143
140
  const [confirmOpen, setConfirmOpen] = useState(false);
144
141
  const [expanded, setExpanded] = useState(false);
145
142
  const [extRefreshKey, setExtRefreshKey] = useState(0);
146
- const navigate = useNavigate();
147
143
  const [exportCsv, setExportCsv] = useState<(() => void) | null>(null);
148
144
  const [shouldLoadData, setShouldLoadData] = useState(
149
145
  eagerLoad ||
@@ -161,17 +157,6 @@ export function SqlChartCard({
161
157
  ] as const,
162
158
  [panel.id, panel.source, panel.sql, resolvedSql],
163
159
  );
164
- const chartFetchCount = useIsFetching({ queryKey: chartQueryKey });
165
- const chartHasCachedData =
166
- queryClient.getQueryData(chartQueryKey) !== undefined;
167
- const isChartRefreshing = chartHasCachedData && chartFetchCount > 0;
168
- const extensionId =
169
- panel.chartType === "extension"
170
- ? ((panel.config as Record<string, unknown> | undefined)?.extensionId as
171
- | string
172
- | undefined)
173
- : undefined;
174
-
175
160
  const setCardNodeRef = useCallback((node: HTMLDivElement | null) => {
176
161
  cardRef.current = node;
177
162
  }, []);
@@ -373,7 +358,7 @@ export function SqlChartCard({
373
358
 
374
359
  // Extension panels render their sandboxed iframe full-bleed with no card chrome
375
360
  // or title — the extension owns its own UI. All viewers get the read-only
376
- // actions (full screen, refresh, open embedded extension); editable
361
+ // actions (full screen and refresh); editable
377
362
  // dashboards also get delete and drag.
378
363
  if (panel.chartType === "extension") {
379
364
  return (
@@ -386,7 +371,7 @@ export function SqlChartCard({
386
371
  data-dashboard-report-panel-id={panel.id}
387
372
  data-dashboard-report-panel-title={panel.title}
388
373
  className={cn(
389
- "dashboard-extension-card group relative h-full rounded-lg border border-transparent transition-colors",
374
+ "dashboard-extension-card group relative h-full rounded-lg transition-colors",
390
375
  selectedForChat && "border-foreground/35 ring-1 ring-foreground/10",
391
376
  )}
392
377
  >
@@ -429,22 +414,6 @@ export function SqlChartCard({
429
414
  <IconMaximize className="h-4 w-4 mr-2" />
430
415
  {t("sqlDashboard.fullScreen")}
431
416
  </DropdownMenuItem>
432
- {extensionId ? (
433
- <DropdownMenuItem
434
- onSelect={() =>
435
- navigate(
436
- `/extensions/${extensionId}/${encodeURIComponent(
437
- (panel.title ?? "extension")
438
- .toLowerCase()
439
- .replace(/[^a-z0-9]+/g, "-"),
440
- )}`,
441
- )
442
- }
443
- >
444
- <IconExternalLink className="h-4 w-4 mr-2" />
445
- Open embedded extension {/* i18n-ignore */}
446
- </DropdownMenuItem>
447
- ) : null}
448
417
  <DropdownMenuSeparator />
449
418
  <DropdownMenuItem onSelect={() => setExtRefreshKey((k) => k + 1)}>
450
419
  <IconRefresh className="h-4 w-4 mr-2" />
@@ -556,26 +525,7 @@ export function SqlChartCard({
556
525
  <CardTitle className="text-sm font-medium flex-1 truncate">
557
526
  {panel.title}
558
527
  </CardTitle>
559
- <div
560
- className={`flex items-center gap-1 transition-opacity ${
561
- isChartRefreshing
562
- ? "opacity-100"
563
- : "opacity-0 group-hover:opacity-100 focus-within:opacity-100"
564
- }`}
565
- >
566
- {isChartRefreshing ? (
567
- <Tooltip>
568
- <TooltipTrigger asChild>
569
- <span className="inline-flex size-6 items-center justify-center rounded text-muted-foreground">
570
- <Spinner
571
- className="size-3.5"
572
- aria-label={t("sqlDashboard.refreshing")}
573
- />
574
- </span>
575
- </TooltipTrigger>
576
- <TooltipContent>{t("sqlDashboard.refreshing")}</TooltipContent>
577
- </Tooltip>
578
- ) : null}
528
+ <div className="flex items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100">
579
529
  {editable && onSaveSql ? (
580
530
  <ViewSqlPopover
581
531
  panel={panel}
@@ -11,6 +11,7 @@ import {
11
11
  callAction,
12
12
  useChangeVersions,
13
13
  useActionMutation,
14
+ type AuthSession,
14
15
  } from "@agent-native/core/client/hooks";
15
16
  import { useT } from "@agent-native/core/client/i18n";
16
17
  import { ShareButton } from "@agent-native/core/client/sharing";
@@ -33,7 +34,6 @@ import {
33
34
  } from "@dnd-kit/core";
34
35
  import {
35
36
  IconArchive,
36
- IconClock,
37
37
  IconDotsVertical,
38
38
  IconEye,
39
39
  IconEyeOff,
@@ -45,7 +45,6 @@ import {
45
45
  IconPencil,
46
46
  IconPlus,
47
47
  IconTrash,
48
- IconUser,
49
48
  IconUsersGroup,
50
49
  IconWorld,
51
50
  IconX,
@@ -64,6 +63,7 @@ import { useSearchParams, useParams, useNavigate } from "react-router";
64
63
  import { toast } from "sonner";
65
64
 
66
65
  import { DashboardHistoryPanel } from "@/components/dashboard/DashboardHistoryPanel";
66
+ import { DashboardMetadata } from "@/components/dashboard/DashboardMetadata";
67
67
  import {
68
68
  DashboardTitleSkeleton,
69
69
  useSetPageTitle,
@@ -105,6 +105,12 @@ import {
105
105
  } from "@/hooks/use-dashboard-chat-context";
106
106
  import { useDashboardViews } from "@/hooks/use-dashboard-views";
107
107
  import { useUserPref } from "@/hooks/use-user-pref";
108
+ import {
109
+ DASHBOARD_REPORT_BOOTSTRAP_RETRY_DELAY_MS,
110
+ DASHBOARD_REPORT_BOOTSTRAP_TIMEOUT_MS,
111
+ dashboardReportCaptureError,
112
+ type DashboardReportCapturePhase,
113
+ } from "@/lib/dashboard-report-capture";
108
114
  import { incrementItemView } from "@/lib/item-popularity";
109
115
  import {
110
116
  sqlDashboardPrefetchKey,
@@ -386,7 +392,9 @@ type FetchedDashboard = {
386
392
  hiddenBy: string | null;
387
393
  visibility: "private" | "org" | "public";
388
394
  ownerEmail: string | null;
395
+ createdAt: string | null;
389
396
  updatedAt: string | null;
397
+ updatedBy: string | null;
390
398
  } & ResourceAccess;
391
399
 
392
400
  function parseDashboardDemoMetadata(
@@ -422,14 +430,31 @@ function parseDashboardCatalogMetadata(
422
430
  };
423
431
  }
424
432
 
425
- async function fetchDashboard(id: string): Promise<FetchedDashboard | null> {
433
+ async function fetchDashboard(
434
+ id: string,
435
+ options?: { reportScreenshot?: boolean },
436
+ ): Promise<FetchedDashboard | null> {
426
437
  try {
427
438
  const data: any = await callAction(
428
439
  "get-sql-dashboard",
429
440
  { id, includeConfig: true },
430
- { method: "GET" },
441
+ {
442
+ method: "GET",
443
+ ...(options?.reportScreenshot
444
+ ? { timeoutMs: DASHBOARD_REPORT_BOOTSTRAP_TIMEOUT_MS }
445
+ : {}),
446
+ },
431
447
  );
432
- if (!data || data.error) return null;
448
+ if (!data) return null;
449
+ if (data.error) {
450
+ throw new Error(
451
+ typeof data.message === "string" && data.message
452
+ ? data.message
453
+ : typeof data.error === "string"
454
+ ? data.error
455
+ : "Dashboard bootstrap failed",
456
+ );
457
+ }
433
458
  return {
434
459
  id,
435
460
  config: {
@@ -454,17 +479,52 @@ async function fetchDashboard(id: string): Promise<FetchedDashboard | null> {
454
479
  ? data.visibility
455
480
  : "private",
456
481
  ownerEmail: typeof data.ownerEmail === "string" ? data.ownerEmail : null,
482
+ createdAt: typeof data.createdAt === "string" ? data.createdAt : null,
457
483
  updatedAt: typeof data.updatedAt === "string" ? data.updatedAt : null,
484
+ updatedBy: typeof data.updatedBy === "string" ? data.updatedBy : null,
458
485
  role: typeof data.role === "string" ? data.role : undefined,
459
486
  canEdit: typeof data.canEdit === "boolean" ? data.canEdit : undefined,
460
487
  canManage:
461
488
  typeof data.canManage === "boolean" ? data.canManage : undefined,
462
489
  };
463
- } catch {
490
+ } catch (error) {
491
+ if (options?.reportScreenshot) throw error;
464
492
  return null;
465
493
  }
466
494
  }
467
495
 
496
+ function DashboardReportCaptureSurface({
497
+ phase,
498
+ panelIds,
499
+ error,
500
+ className,
501
+ children,
502
+ }: {
503
+ phase: DashboardReportCapturePhase;
504
+ panelIds?: string[];
505
+ error?: unknown;
506
+ className?: string;
507
+ children: React.ReactNode;
508
+ }) {
509
+ const captureError = error ? dashboardReportCaptureError(error) : undefined;
510
+
511
+ return (
512
+ <div
513
+ className={className}
514
+ data-dashboard-report-capture
515
+ data-dashboard-report-ready={phase === "ready" ? "true" : "false"}
516
+ data-dashboard-report-phase={phase}
517
+ data-dashboard-report-fetch-state={phase}
518
+ data-dashboard-report-error={captureError || undefined}
519
+ data-dashboard-report-panel-ids={
520
+ panelIds ? JSON.stringify(panelIds) : undefined
521
+ }
522
+ >
523
+ {children}
524
+ </div>
525
+ );
526
+ }
527
+
468
528
  /**
469
529
  * Save dashboard config via the update-dashboard action. Throws on error so
470
530
  * callers (e.g. the panel editor dialog) can surface BigQuery validation
@@ -481,13 +541,34 @@ async function saveDashboard(
481
541
  }
482
542
 
483
543
  export default function SqlDashboardPage() {
544
+ const [searchParams] = useSearchParams();
545
+
546
+ if (searchParams.get("reportScreenshot") === "1") {
547
+ return <SqlDashboardPageContent reportScreenshot session={null} />;
548
+ }
549
+
550
+ return <InteractiveSqlDashboardPage />;
551
+ }
552
+
553
+ function InteractiveSqlDashboardPage() {
554
+ const { session } = useSession();
555
+
556
+ return <SqlDashboardPageContent reportScreenshot={false} session={session} />;
557
+ }
558
+
559
+ function SqlDashboardPageContent({
560
+ reportScreenshot,
561
+ session,
562
+ }: {
563
+ reportScreenshot: boolean;
564
+ session: AuthSession | null;
565
+ }) {
484
566
  const t = useT();
485
567
  const [searchParams, setSearchParams] = useSearchParams();
486
568
  const { id: routeId } = useParams<{ id: string }>();
487
569
  const queryClient = useQueryClient();
488
570
  const navigate = useNavigate();
489
571
  const dashboardId = searchParams.get("id") || routeId;
490
- const reportScreenshot = searchParams.get("reportScreenshot") === "1";
491
572
  const reportSettingsRequested = searchParams.get("reportSettings") === "1";
492
573
  const reportPanelWindow = reportScreenshot
493
574
  ? parseReportPanelWindow(
@@ -503,9 +584,15 @@ export default function SqlDashboardPage() {
503
584
  "private" | "org" | "public" | null
504
585
  >(null);
505
586
  const [dashboardOwner, setDashboardOwner] = useState<string | null>(null);
587
+ const [dashboardCreatedAt, setDashboardCreatedAt] = useState<string | null>(
588
+ null,
589
+ );
506
590
  const [dashboardUpdatedAt, setDashboardUpdatedAt] = useState<string | null>(
507
591
  null,
508
592
  );
593
+ const [dashboardUpdatedBy, setDashboardUpdatedBy] = useState<string | null>(
594
+ null,
595
+ );
509
596
  const [resourceAccess, setResourceAccess] = useState<ResourceAccess | null>(
510
597
  null,
511
598
  );
@@ -564,8 +651,12 @@ export default function SqlDashboardPage() {
564
651
  enabled: !!dashboardId,
565
652
  queryFn: async () => {
566
653
  if (!dashboardId) return null;
567
- return fetchDashboard(dashboardId);
654
+ return fetchDashboard(dashboardId, { reportScreenshot });
568
655
  },
656
+ retry: reportScreenshot ? 1 : false,
657
+ retryDelay: reportScreenshot
658
+ ? DASHBOARD_REPORT_BOOTSTRAP_RETRY_DELAY_MS
659
+ : undefined,
569
660
  staleTime: 30_000,
570
661
  placeholderData: (prev) => prev,
571
662
  initialData: () => {
@@ -593,7 +684,6 @@ export default function SqlDashboardPage() {
593
684
  const [editingPanel, setEditingPanel] = useState<SqlPanel | null>(null);
594
685
 
595
686
  // ── Collaborative editing ──────────────────────────────────────────
596
- const { session } = useSession();
597
687
  const currentUser: CollabUser | undefined =
598
688
  !reportScreenshot && session?.email
599
689
  ? {
@@ -723,7 +813,9 @@ export default function SqlDashboardPage() {
723
813
  setHiddenAt(null);
724
814
  setDashboardVisibility(null);
725
815
  setDashboardOwner(null);
816
+ setDashboardCreatedAt(null);
726
817
  setDashboardUpdatedAt(null);
818
+ setDashboardUpdatedBy(null);
727
819
  setResourceAccess(null);
728
820
  if (!dashboardId) setLoaded(true);
729
821
  }, [dashboardId]);
@@ -756,7 +848,9 @@ export default function SqlDashboardPage() {
756
848
  setHiddenAt(fetched?.hiddenAt ?? null);
757
849
  setDashboardVisibility(fetchedVisibility);
758
850
  setDashboardOwner(fetched?.ownerEmail ?? null);
851
+ setDashboardCreatedAt(fetched?.createdAt ?? null);
759
852
  setDashboardUpdatedAt(fetched?.updatedAt ?? null);
853
+ setDashboardUpdatedBy(fetched?.updatedBy ?? null);
760
854
  setResourceAccess(
761
855
  fetched
762
856
  ? {
@@ -1502,57 +1596,7 @@ export default function SqlDashboardPage() {
1502
1596
  </TooltipTrigger>
1503
1597
  <TooltipContent>{t("sqlDashboard.details")}</TooltipContent>
1504
1598
  </Tooltip>
1505
- <DropdownMenuContent align="end" className="w-56">
1506
- <DropdownMenuLabel className="font-normal">
1507
- <div className="flex flex-col gap-1.5 text-xs text-muted-foreground">
1508
- {dashboardUpdatedAt && (
1509
- <span className="flex items-center gap-1.5">
1510
- <IconClock className="h-3 w-3" />
1511
- {t("sqlDashboard.updated", {
1512
- date: new Date(dashboardUpdatedAt).toLocaleDateString(
1513
- "en-US",
1514
- {
1515
- year: "numeric",
1516
- month: "short",
1517
- day: "numeric",
1518
- },
1519
- ),
1520
- })}
1521
- </span>
1522
- )}
1523
- {dashboardOwner && (
1524
- <span className="flex items-center gap-1.5">
1525
- <IconUser className="h-3 w-3" />
1526
- {dashboardOwner.split("@")[0]}
1527
- </span>
1528
- )}
1529
- {dashboardVisibility ? (
1530
- <span className="flex items-center gap-1.5">
1531
- {dashboardVisibility === "public" ? (
1532
- <IconWorld className="h-3 w-3" />
1533
- ) : dashboardVisibility === "org" ? (
1534
- <IconUsersGroup className="h-3 w-3" />
1535
- ) : (
1536
- <IconLock className="h-3 w-3" />
1537
- )}
1538
- {dashboardVisibility === "public"
1539
- ? t("sqlDashboard.public")
1540
- : dashboardVisibility === "org"
1541
- ? t("sqlDashboard.sharedWithOrg")
1542
- : t("sqlDashboard.private")}
1543
- </span>
1544
- ) : null}
1545
- {hiddenAt && (
1546
- <span className="flex items-center gap-1.5 font-medium text-amber-600 dark:text-amber-400">
1547
- <IconEyeOff className="h-3 w-3" />
1548
- {t("sqlDashboard.hidden")}
1549
- </span>
1550
- )}
1551
- </div>
1552
- </DropdownMenuLabel>
1553
- {(canEdit && !archivedAt) || canManage ? (
1554
- <DropdownMenuSeparator />
1555
- ) : null}
1599
+ <DropdownMenuContent align="end" className="w-72">
1556
1600
  {dashboardId && canEdit && !archivedAt ? (
1557
1601
  <DropdownMenuItem
1558
1602
  onSelect={(event) => {
@@ -1618,6 +1662,41 @@ export default function SqlDashboardPage() {
1618
1662
  {t("sqlDashboard.deletePermanently")}
1619
1663
  </DropdownMenuItem>
1620
1664
  ) : null}
1665
+ {dashboardId || (canEdit && !archivedAt) || canManage ? (
1666
+ <DropdownMenuSeparator />
1667
+ ) : null}
1668
+ <DropdownMenuLabel className="font-normal">
1669
+ <DashboardMetadata
1670
+ createdAt={dashboardCreatedAt}
1671
+ createdBy={dashboardOwner}
1672
+ updatedAt={dashboardUpdatedAt}
1673
+ updatedBy={dashboardUpdatedBy}
1674
+ />
1675
+ <div className="mt-2 flex flex-col gap-1.5 text-xs text-muted-foreground">
1676
+ {dashboardVisibility ? (
1677
+ <span className="flex items-center gap-1.5">
1678
+ {dashboardVisibility === "public" ? (
1679
+ <IconWorld className="h-3 w-3" />
1680
+ ) : dashboardVisibility === "org" ? (
1681
+ <IconUsersGroup className="h-3 w-3" />
1682
+ ) : (
1683
+ <IconLock className="h-3 w-3" />
1684
+ )}
1685
+ {dashboardVisibility === "public"
1686
+ ? t("sqlDashboard.public")
1687
+ : dashboardVisibility === "org"
1688
+ ? t("sqlDashboard.sharedWithOrg")
1689
+ : t("sqlDashboard.private")}
1690
+ </span>
1691
+ ) : null}
1692
+ {hiddenAt && (
1693
+ <span className="flex items-center gap-1.5 font-medium text-amber-600 dark:text-amber-400">
1694
+ <IconEyeOff className="h-3 w-3" />
1695
+ {t("sqlDashboard.hidden")}
1696
+ </span>
1697
+ )}
1698
+ </div>
1699
+ </DropdownMenuLabel>
1621
1700
  </DropdownMenuContent>
1622
1701
  </DropdownMenu>
1623
1702
  {dashboardId ? (
@@ -1689,6 +1768,15 @@ export default function SqlDashboardPage() {
1689
1768
  );
1690
1769
 
1691
1770
  if (!dashboardId) {
1771
+ if (reportScreenshot) {
1772
+ return (
1773
+ <DashboardReportCaptureSurface phase="missing">
1774
+ <div className="flex h-64 items-center justify-center text-muted-foreground">
1775
+ {t("sqlDashboard.noDashboardSelected")}
1776
+ </div>
1777
+ </DashboardReportCaptureSurface>
1778
+ );
1779
+ }
1692
1780
  return (
1693
1781
  <div className="flex items-center justify-center h-64 text-muted-foreground">
1694
1782
  {t("sqlDashboard.noDashboardSelected")}
@@ -1696,21 +1784,42 @@ export default function SqlDashboardPage() {
1696
1784
  );
1697
1785
  }
1698
1786
 
1787
+ if (reportScreenshot && dashboardQuery.isError) {
1788
+ return (
1789
+ <DashboardReportCaptureSurface phase="error" error={dashboardQuery.error}>
1790
+ <DashboardSkeleton />
1791
+ </DashboardReportCaptureSurface>
1792
+ );
1793
+ }
1794
+
1699
1795
  if (!loaded) {
1796
+ if (reportScreenshot) {
1797
+ return (
1798
+ <DashboardReportCaptureSurface phase="loading">
1799
+ <DashboardSkeleton />
1800
+ </DashboardReportCaptureSurface>
1801
+ );
1802
+ }
1700
1803
  return <DashboardSkeleton />;
1701
1804
  }
1702
1805
 
1703
- if (!dashboard) return <BlankDashboard />;
1806
+ if (!dashboard) {
1807
+ if (reportScreenshot) {
1808
+ return (
1809
+ <DashboardReportCaptureSurface phase="missing">
1810
+ <BlankDashboard />
1811
+ </DashboardReportCaptureSurface>
1812
+ );
1813
+ }
1814
+ return <BlankDashboard />;
1815
+ }
1704
1816
 
1705
1817
  return (
1706
- <div
1818
+ <DashboardReportCaptureSurface
1707
1819
  className="space-y-4"
1708
- data-dashboard-report-capture
1709
- data-dashboard-report-ready={loaded && dashboard ? "true" : "false"}
1710
- data-dashboard-report-panel-ids={
1711
- reportScreenshot
1712
- ? JSON.stringify(listReportablePanelIds(visiblePanels))
1713
- : undefined
1820
+ phase="ready"
1821
+ panelIds={
1822
+ reportScreenshot ? listReportablePanelIds(visiblePanels) : undefined
1714
1823
  }
1715
1824
  >
1716
1825
  {hiddenAt ? (
@@ -2033,6 +2142,6 @@ export default function SqlDashboardPage() {
2033
2142
  existingPanelTitles={dashboard.panels.map((p) => p.title)}
2034
2143
  />
2035
2144
  ) : null}
2036
- </div>
2145
+ </DashboardReportCaptureSurface>
2037
2146
  );
2038
2147
  }
@@ -151,12 +151,12 @@ export default function AnalysisDetail() {
151
151
  send({
152
152
  message: t("analyses.rerunMessage", { name: analysis.name }),
153
153
  context:
154
- `This is a re-run of a saved ad-hoc analysis. REAL_DATA_REQUIRED: run at least one real data-source query action before saving or answering; data-source-status, generate-chart, and save-analysis do not count as data queries. If no source can answer, report the exact unavailable/error result instead of saving guessed results.\n\n` +
154
+ `This is a re-run of a legacy saved ad-hoc analysis. Treat the refreshed result as a dashboard artifact: REAL_DATA_REQUIRED: run at least one real data-source query action before saving or answering; data-source-status and generate-chart do not count as data queries. If no source can answer, report the exact unavailable/error result instead of saving guessed results. If the report needs bespoke UI, create an extension and immediately embed it in a dashboard panel with config.extensionId. Only call save-analysis when the user explicitly asks to preserve this legacy analysis record.\n\n` +
155
155
  `Use these instructions to reproduce it:\n\n` +
156
156
  `Analysis ID: ${analysis.id}\n` +
157
157
  `Original question: ${analysis.question}\n\n` +
158
158
  `Instructions:\n${analysis.instructions}\n\n` +
159
- `After gathering the data, call save-analysis with id="${analysis.id}" to update the results.`,
159
+ `After gathering the data, call update-dashboard with a new dashboardId to save the refreshed artifact. If the user explicitly asked to update this legacy record instead, call save-analysis with id="${analysis.id}".`,
160
160
  submit: true,
161
161
  });
162
162
  };
@@ -6,6 +6,7 @@ import {
6
6
  createAgentNativeQueryClient,
7
7
  useDbSync,
8
8
  } from "@agent-native/core/client/hooks";
9
+ import { getEmbedAuthToken } from "@agent-native/core/client/host";
9
10
  import { getLocaleInitScript } from "@agent-native/core/client/i18n";
10
11
  import { getThemeInitScript } from "@agent-native/core/client/ui";
11
12
  import { useQueryClient } from "@tanstack/react-query";
@@ -31,6 +32,10 @@ import { TAB_ID } from "@/lib/tab-id";
31
32
  import { CommandPalette } from "./components/layout/CommandPalette";
32
33
  import { Layout as AppLayout } from "./components/layout/Layout";
33
34
  import { i18nCatalog } from "./i18n";
35
+ import {
36
+ hasDashboardReportEmbedToken,
37
+ isDashboardReportScreenshot,
38
+ } from "./lib/dashboard-report-capture";
34
39
 
35
40
  import stylesheet from "./global.css?url";
36
41
  configureTracking({
@@ -146,6 +151,11 @@ export default function Root() {
146
151
  // server/plugins/auth.ts.
147
152
  const isPublicStatusPath =
148
153
  location.pathname === "/status" || location.pathname.startsWith("/status/");
154
+ const isDashboardReportCapture = isDashboardReportScreenshot(location.search);
155
+ const hasReportEmbedToken = hasDashboardReportEmbedToken(
156
+ location.search,
157
+ getEmbedAuthToken(),
158
+ );
149
159
 
150
160
  if (isPublicStatusPath) {
151
161
  return (
@@ -163,6 +173,24 @@ export default function Root() {
163
173
  );
164
174
  }
165
175
 
176
+ if (isDashboardReportCapture && hasReportEmbedToken) {
177
+ return (
178
+ <AppToolkitProvider>
179
+ <AppProviders
180
+ queryClient={queryClient}
181
+ sessionBypass
182
+ defaultTheme="dark"
183
+ toaster={null}
184
+ i18n={{ catalog: i18nCatalog }}
185
+ >
186
+ <AppLayout>
187
+ <Outlet />
188
+ </AppLayout>
189
+ </AppProviders>
190
+ </AppToolkitProvider>
191
+ );
192
+ }
193
+
166
194
  return (
167
195
  // defaultTheme="dark": analytics defaults to dark mode if no stored preference.
168
196
  // toaster={null}: suppress AppProviders' built-in sonner; analytics renders
@@ -1,10 +1,11 @@
1
+ import { Navigate } from "react-router";
2
+
1
3
  import { messagesByLocale } from "@/i18n-data";
2
- import AnalysesList from "@/pages/analyses/AnalysesList";
3
4
 
4
5
  export function meta() {
5
6
  return [{ title: messagesByLocale["en-US"].routeTitles.analyses }];
6
7
  }
7
8
 
8
9
  export default function AnalysesRoute() {
9
- return <AnalysesList />;
10
+ return <Navigate to="/dashboards" replace />;
10
11
  }
@@ -1,4 +1,4 @@
1
- import { ExtensionsListPage } from "@agent-native/core/client/extensions";
1
+ import { Navigate } from "react-router";
2
2
 
3
3
  import { messagesByLocale } from "@/i18n-data";
4
4
 
@@ -7,5 +7,5 @@ export function meta() {
7
7
  }
8
8
 
9
9
  export default function ExtensionsRoute() {
10
- return <ExtensionsListPage />;
10
+ return <Navigate to="/settings#extensions" replace />;
11
11
  }
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: changed
3
+ date: 2026-07-23
4
+ ---
5
+
6
+ Analytics now groups saved analyses and embedded extensions under dashboards
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-23
4
+ ---
5
+
6
+ Dashboard menus show who created and last updated each dashboard, with admin usage sorting by views or edits.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-23
4
+ ---
5
+
6
+ Dashboard usage now loads reliably for organizations with many tracked events
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-23
4
+ ---
5
+
6
+ Long dashboard-building requests now continue without stopping mid-run
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Analytics charts now explain slow loads and offer a direct retry action.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Secondary controls and dashboard surfaces now use quieter borderless styling.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-24
4
+ ---
5
+
6
+ Daily dashboard emails now load signed reports more reliably instead of falling back to a link-only message