@agent-native/core 0.119.1 → 0.119.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 (233) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +21 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/a2a/client.ts +4 -0
  5. package/corpus/core/src/agent/production-agent.ts +1 -0
  6. package/corpus/core/src/cli/create.ts +44 -5
  7. package/corpus/core/src/client/AssistantChat.tsx +11 -50
  8. package/corpus/core/src/client/ErrorBoundary.tsx +25 -19
  9. package/corpus/core/src/client/agent-page/AgentTabFrame.tsx +1 -1
  10. package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +23 -0
  11. package/corpus/core/src/client/components/ui/message-scroller.tsx +1 -9
  12. package/corpus/core/src/client/resources/ResourceTree.tsx +3 -3
  13. package/corpus/core/src/client/resources/ResourcesPanel.tsx +64 -60
  14. package/corpus/core/src/client/settings/AccountSettingsCard.tsx +228 -0
  15. package/corpus/core/src/client/settings/SecretsSection.tsx +7 -5
  16. package/corpus/core/src/client/settings/SettingsPanel.tsx +67 -244
  17. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +88 -21
  18. package/corpus/core/src/client/settings/agent-settings-search.ts +0 -2
  19. package/corpus/core/src/client/settings/index.ts +7 -0
  20. package/corpus/core/src/client/vite-dev-recovery-script.ts +18 -1
  21. package/corpus/core/src/db/client.ts +65 -15
  22. package/corpus/core/src/db/index.ts +2 -0
  23. package/corpus/core/src/localization/default-messages.ts +1 -0
  24. package/corpus/core/src/server/email.ts +33 -1
  25. package/corpus/core/src/styles/agent-native.css +23 -0
  26. package/corpus/core/src/templates/default/.agents/skills/frontend-design/SKILL.md +28 -0
  27. package/corpus/core/src/templates/default/app/routes/settings.tsx +2 -0
  28. package/corpus/core/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +28 -0
  29. package/corpus/core/src/vite/client.ts +76 -8
  30. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +28 -0
  31. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +3 -1
  32. package/corpus/templates/analytics/app/components/layout/Layout.tsx +9 -13
  33. package/corpus/templates/analytics/app/components/layout/layout-route-policy.ts +2 -2
  34. package/corpus/templates/analytics/app/global.css +0 -5
  35. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +0 -13
  36. package/corpus/templates/analytics/app/lib/sql-query.ts +15 -2
  37. package/corpus/templates/analytics/app/pages/Settings.tsx +2 -24
  38. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +6 -0
  39. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +11 -1
  40. package/corpus/templates/analytics/app/pages/analyses/AnalysisDetail.tsx +8 -1
  41. package/corpus/templates/analytics/app/pages/settings/settings-search.ts +1 -1
  42. package/corpus/templates/analytics/changelog/2026-07-22-fixed-dashboards-and-analyses-missing-a-copyable-share-link.md +6 -0
  43. package/corpus/templates/analytics/changelog/2026-07-23-ask-analytics-is-better-centered-with-a-quieter-chat-rail-an.md +6 -0
  44. package/corpus/templates/analytics/changelog/2026-07-23-daily-dashboard-emails-load-read-heavy-panels-reliably.md +6 -0
  45. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +2 -2
  46. package/corpus/templates/analytics/server/jobs/dashboard-report.ts +39 -5
  47. package/corpus/templates/analytics/server/lib/dashboard-report.ts +186 -62
  48. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +3 -0
  49. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +18 -2
  50. package/corpus/templates/analytics/shared/dashboard-report-timeouts.ts +3 -0
  51. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +28 -0
  52. package/corpus/templates/assets/app/components/layout/Layout.tsx +3 -4
  53. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +1 -1
  54. package/corpus/templates/assets/app/global.css +0 -5
  55. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +0 -22
  56. package/corpus/templates/assets/app/routes/settings.tsx +2 -0
  57. package/corpus/templates/assets/changelog/2026-07-23-create-and-chat-surfaces-are-better-centered-with-quieter-ch.md +6 -0
  58. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +28 -0
  59. package/corpus/templates/brain/app/components/layout/Layout.tsx +1 -1
  60. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +1 -1
  61. package/corpus/templates/brain/app/global.css +0 -9
  62. package/corpus/templates/brain/app/hooks/use-navigation-state.ts +0 -12
  63. package/corpus/templates/brain/app/i18n-data.ts +1 -0
  64. package/corpus/templates/brain/app/lib/settings-navigation.ts +1 -1
  65. package/corpus/templates/brain/app/routes/settings.tsx +21 -22
  66. package/corpus/templates/brain/changelog/2026-07-23-ask-brain-is-better-centered-with-quieter-chat-history-and-a.md +6 -0
  67. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +28 -0
  68. package/corpus/templates/calendar/app/pages/Settings.tsx +2 -0
  69. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +28 -0
  70. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
  71. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +1 -1
  72. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +0 -15
  73. package/corpus/templates/chat/app/routes/settings.tsx +2 -0
  74. package/corpus/templates/chat/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +6 -0
  75. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +28 -0
  76. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +2 -0
  77. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +28 -0
  78. package/corpus/templates/content/app/routes/_app.settings.tsx +2 -0
  79. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +28 -0
  80. package/corpus/templates/design/app/routes/settings.tsx +2 -0
  81. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +28 -0
  82. package/corpus/templates/dispatch/app/routes/settings.tsx +2 -0
  83. package/corpus/templates/dispatch/changelog/2026-07-23-quieter-progressive-disclosure.md +6 -0
  84. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +28 -0
  85. package/corpus/templates/forms/app/global.css +0 -5
  86. package/corpus/templates/forms/app/hooks/use-navigation-state.ts +0 -7
  87. package/corpus/templates/forms/app/root.tsx +1 -7
  88. package/corpus/templates/forms/app/routes/_app.settings.tsx +2 -0
  89. package/corpus/templates/forms/changelog/2026-07-23-ask-forms-is-better-centered-with-quieter-chat-history-and-a.md +6 -0
  90. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +28 -0
  91. package/corpus/templates/macros/app/routes/settings.tsx +2 -0
  92. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +28 -0
  93. package/corpus/templates/mail/app/pages/SettingsPage.tsx +3 -1
  94. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +28 -0
  95. package/corpus/templates/plan/app/components/layout/Layout.tsx +2 -2
  96. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +1 -13
  97. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +0 -4
  98. package/corpus/templates/plan/app/routes/settings.tsx +2 -0
  99. package/corpus/templates/plan/changelog/2026-07-23-ask-plan-is-now-a-clean-full-page-chat-surface-with-better-c.md +6 -0
  100. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +28 -0
  101. package/corpus/templates/slides/app/routes/settings.tsx +2 -0
  102. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +28 -0
  103. package/corpus/toolkit/CHANGELOG.md +6 -0
  104. package/corpus/toolkit/package.json +1 -1
  105. package/corpus/toolkit/src/chat-history.css +2 -2
  106. package/corpus/toolkit/src/composer/PromptComposer.tsx +0 -31
  107. package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +7 -2
  108. package/corpus/toolkit/src/styles.css +183 -36
  109. package/dist/a2a/client.d.ts +2 -0
  110. package/dist/a2a/client.d.ts.map +1 -1
  111. package/dist/a2a/client.js +2 -0
  112. package/dist/a2a/client.js.map +1 -1
  113. package/dist/agent/production-agent.d.ts.map +1 -1
  114. package/dist/agent/production-agent.js +1 -0
  115. package/dist/agent/production-agent.js.map +1 -1
  116. package/dist/cli/create.d.ts +2 -1
  117. package/dist/cli/create.d.ts.map +1 -1
  118. package/dist/cli/create.js +43 -6
  119. package/dist/cli/create.js.map +1 -1
  120. package/dist/client/AssistantChat.d.ts.map +1 -1
  121. package/dist/client/AssistantChat.js +11 -42
  122. package/dist/client/AssistantChat.js.map +1 -1
  123. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  124. package/dist/client/ErrorBoundary.js +3 -2
  125. package/dist/client/ErrorBoundary.js.map +1 -1
  126. package/dist/client/agent-page/AgentTabFrame.js +1 -1
  127. package/dist/client/agent-page/AgentTabFrame.js.map +1 -1
  128. package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -1
  129. package/dist/client/agent-page/AgentTabsPage.js +13 -1
  130. package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
  131. package/dist/client/components/ui/message-scroller.d.ts.map +1 -1
  132. package/dist/client/components/ui/message-scroller.js +2 -2
  133. package/dist/client/components/ui/message-scroller.js.map +1 -1
  134. package/dist/client/resources/ResourceTree.js +2 -2
  135. package/dist/client/resources/ResourceTree.js.map +1 -1
  136. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  137. package/dist/client/resources/ResourcesPanel.js +11 -11
  138. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  139. package/dist/client/settings/AccountSettingsCard.d.ts +9 -0
  140. package/dist/client/settings/AccountSettingsCard.d.ts.map +1 -0
  141. package/dist/client/settings/AccountSettingsCard.js +78 -0
  142. package/dist/client/settings/AccountSettingsCard.js.map +1 -0
  143. package/dist/client/settings/SecretsSection.d.ts.map +1 -1
  144. package/dist/client/settings/SecretsSection.js +2 -2
  145. package/dist/client/settings/SecretsSection.js.map +1 -1
  146. package/dist/client/settings/SettingsPanel.d.ts +3 -0
  147. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  148. package/dist/client/settings/SettingsPanel.js +25 -77
  149. package/dist/client/settings/SettingsPanel.js.map +1 -1
  150. package/dist/client/settings/SettingsTabsPage.d.ts +5 -1
  151. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  152. package/dist/client/settings/SettingsTabsPage.js +35 -9
  153. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  154. package/dist/client/settings/agent-settings-search.d.ts.map +1 -1
  155. package/dist/client/settings/agent-settings-search.js +0 -2
  156. package/dist/client/settings/agent-settings-search.js.map +1 -1
  157. package/dist/client/settings/index.d.ts +2 -1
  158. package/dist/client/settings/index.d.ts.map +1 -1
  159. package/dist/client/settings/index.js +2 -1
  160. package/dist/client/settings/index.js.map +1 -1
  161. package/dist/client/vite-dev-recovery-script.d.ts.map +1 -1
  162. package/dist/client/vite-dev-recovery-script.js +18 -1
  163. package/dist/client/vite-dev-recovery-script.js.map +1 -1
  164. package/dist/collab/routes.d.ts +1 -1
  165. package/dist/db/client.d.ts +18 -8
  166. package/dist/db/client.d.ts.map +1 -1
  167. package/dist/db/client.js +34 -11
  168. package/dist/db/client.js.map +1 -1
  169. package/dist/db/index.d.ts +1 -1
  170. package/dist/db/index.d.ts.map +1 -1
  171. package/dist/db/index.js.map +1 -1
  172. package/dist/localization/default-messages.d.ts +1 -0
  173. package/dist/localization/default-messages.d.ts.map +1 -1
  174. package/dist/localization/default-messages.js +1 -0
  175. package/dist/localization/default-messages.js.map +1 -1
  176. package/dist/notifications/routes.d.ts +1 -1
  177. package/dist/provider-api/actions/custom-provider-registration.d.ts +7 -7
  178. package/dist/provider-api/actions/provider-api.d.ts +7 -7
  179. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  180. package/dist/resources/handlers.d.ts +1 -1
  181. package/dist/secrets/routes.d.ts +9 -9
  182. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  183. package/dist/server/email.d.ts +1 -0
  184. package/dist/server/email.d.ts.map +1 -1
  185. package/dist/server/email.js +29 -1
  186. package/dist/server/email.js.map +1 -1
  187. package/dist/server/realtime-token.d.ts +1 -1
  188. package/dist/styles/agent-native.css +23 -0
  189. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +28 -0
  190. package/dist/templates/chat/app/components/layout/Layout.tsx +1 -1
  191. package/dist/templates/chat/app/components/layout/Sidebar.tsx +1 -1
  192. package/dist/templates/chat/app/hooks/use-navigation-state.ts +0 -15
  193. package/dist/templates/chat/app/routes/settings.tsx +2 -0
  194. package/dist/templates/chat/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +6 -0
  195. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +28 -0
  196. package/dist/templates/default/app/routes/settings.tsx +2 -0
  197. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +28 -0
  198. package/dist/vite/client.d.ts.map +1 -1
  199. package/dist/vite/client.js +68 -6
  200. package/dist/vite/client.js.map +1 -1
  201. package/package.json +2 -2
  202. package/src/a2a/client.ts +4 -0
  203. package/src/agent/production-agent.ts +1 -0
  204. package/src/cli/create.ts +44 -5
  205. package/src/client/AssistantChat.tsx +11 -50
  206. package/src/client/ErrorBoundary.tsx +25 -19
  207. package/src/client/agent-page/AgentTabFrame.tsx +1 -1
  208. package/src/client/agent-page/AgentTabsPage.tsx +23 -0
  209. package/src/client/components/ui/message-scroller.tsx +1 -9
  210. package/src/client/resources/ResourceTree.tsx +3 -3
  211. package/src/client/resources/ResourcesPanel.tsx +64 -60
  212. package/src/client/settings/AccountSettingsCard.tsx +228 -0
  213. package/src/client/settings/SecretsSection.tsx +7 -5
  214. package/src/client/settings/SettingsPanel.tsx +67 -244
  215. package/src/client/settings/SettingsTabsPage.tsx +88 -21
  216. package/src/client/settings/agent-settings-search.ts +0 -2
  217. package/src/client/settings/index.ts +7 -0
  218. package/src/client/vite-dev-recovery-script.ts +18 -1
  219. package/src/db/client.ts +65 -15
  220. package/src/db/index.ts +2 -0
  221. package/src/localization/default-messages.ts +1 -0
  222. package/src/server/email.ts +33 -1
  223. package/src/styles/agent-native.css +23 -0
  224. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +28 -0
  225. package/src/templates/chat/app/components/layout/Layout.tsx +1 -1
  226. package/src/templates/chat/app/components/layout/Sidebar.tsx +1 -1
  227. package/src/templates/chat/app/hooks/use-navigation-state.ts +0 -15
  228. package/src/templates/chat/app/routes/settings.tsx +2 -0
  229. package/src/templates/chat/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +6 -0
  230. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +28 -0
  231. package/src/templates/default/app/routes/settings.tsx +2 -0
  232. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +28 -0
  233. package/src/vite/client.ts +76 -8
@@ -35,6 +35,34 @@ Then implement working code that is cohesive, accessible, responsive, and polish
35
35
 
36
36
  Default to Apple/Linear-level restraint: make the primary workflow obvious, then remove everything that does not help that workflow right now. A polished UI often has fewer visible controls, fewer borders, fewer labels, and fewer explanatory surfaces than the first reasonable implementation.
37
37
 
38
+ ### Progressive Disclosure Is A Design Requirement
39
+
40
+ Treat an all-at-once interface as a defect to fix during design, not as a
41
+ styling preference. Before coding, inventory every piece of content and action
42
+ on the surface, then assign each one to the smallest useful visibility level:
43
+
44
+ 1. **Immediate** — the page title, current state, one primary action, and the
45
+ compact context needed to choose what to do next.
46
+ 2. **Expanded** — the details needed for the selected item or active workflow.
47
+ 3. **On demand** — advanced settings, diagnostics, credentials, metadata,
48
+ destructive actions, documentation, and rarely used tools.
49
+
50
+ Use single-select accordions or simple disclosure rows for sibling panels when
51
+ the user is choosing one item at a time. Inside an expanded panel, keep another
52
+ layer for independent concerns instead of dumping every form, explanation, and
53
+ secondary action into the first reveal. Prefer one flat panel with alignment,
54
+ dividers, and whitespace over nested cards; provider or product icons should
55
+ not receive decorative borders or containers unless the container communicates
56
+ state or interaction. A collapsed row should still show the item name, status,
57
+ and a concise summary so the user can scan the whole surface without opening
58
+ everything.
59
+
60
+ Before shipping, ask: “What can disappear until the user asks for it?” Then
61
+ verify collapsed, expanded, loading, empty, error, and narrow-width states.
62
+ If the first viewport contains multiple forms, repeated explanatory copy,
63
+ documentation links, and controls for unrelated tasks, the surface has not
64
+ passed this requirement yet.
65
+
38
66
  - **Start by subtracting**: Before adding a visible control, banner, toolbar row, card, or explanatory block, ask what can be removed, merged, renamed, or moved into an existing affordance.
39
67
  - **One primary action**: Each surface should have one dominant next action. Secondary actions belong in menus, popovers, command palettes, disclosure rows, or contextual hover/focus states unless they are used constantly.
40
68
  - **Progressively disclose rare work**: Advanced options, diagnostics, metadata, settings, import/export, destructive actions, and inspection tools should stay tucked away until requested. Prefer small icon triggers with tooltips, popovers, drawers, or detail panels over permanent chrome.
@@ -253,6 +253,9 @@ function nitroVitePlugin(
253
253
  * rate-limits an unrelated client-reload nudge); keep the two independent.
254
254
  */
255
255
  const NITRO_FULL_RELOAD_DEBOUNCE_MS = 300;
256
+ const OPTIMIZE_DEP_FULL_RELOAD_COOLDOWN_MS = 2_000;
257
+ const OPTIMIZE_DEP_FULL_RELOAD_WINDOW_MS = 30_000;
258
+ const OPTIMIZE_DEP_MAX_FULL_RELOADS = 3;
256
259
 
257
260
  /**
258
261
  * Wraps a single Nitro-provided Vite plugin so that, if it defines a
@@ -628,6 +631,10 @@ function hasCoreDep(pkg: string, cwd: string): boolean {
628
631
  }
629
632
 
630
633
  function hasOptimizeDep(pkg: string, cwd: string): boolean {
634
+ // The nested dependency entry below is rooted at @agent-native/core, so
635
+ // monorepo consumers need to retain it even though the source package does
636
+ // not list itself as a dependency.
637
+ if (pkg === "@agent-native/core" && findCorePackageRoot(cwd)) return true;
631
638
  return hasDep(pkg, cwd) || hasCoreDep(pkg, cwd);
632
639
  }
633
640
 
@@ -711,6 +718,47 @@ function getClientDedupe(cwd: string): string[] {
711
718
  * of dist/ at startup and never picks up new exports).
712
719
  */
713
720
  function findCorePackageRoot(cwd: string): string | null {
721
+ const localSourceRoot = findLocalCoreSourceRoot(cwd);
722
+ if (localSourceRoot) return localSourceRoot;
723
+
724
+ // Published Core packages are installed as transitive dependency roots in
725
+ // pnpm. The consuming app cannot resolve Core's client-only dependencies
726
+ // from its own node_modules unless we first locate that installed package
727
+ // and read its manifest. This is also what lets optimizeDeps use Vite's
728
+ // nested-dependency syntax for standalone CLI-generated apps.
729
+ try {
730
+ const appRequire = createRequire(path.join(cwd, "package.json"));
731
+ const resolved = appRequire.resolve("@agent-native/core");
732
+ let dir = path.dirname(resolved);
733
+ for (let i = 0; i < 20; i++) {
734
+ const packageJsonPath = path.join(dir, "package.json");
735
+ if (fs.existsSync(packageJsonPath)) {
736
+ const packageJson = JSON.parse(
737
+ fs.readFileSync(packageJsonPath, "utf-8"),
738
+ ) as { name?: string };
739
+ if (packageJson.name === "@agent-native/core") {
740
+ return fs.realpathSync(dir);
741
+ }
742
+ }
743
+
744
+ const parent = path.dirname(dir);
745
+ if (parent === dir) break;
746
+ dir = parent;
747
+ }
748
+ } catch {
749
+ // The app may not have installed Core yet; fall through to null.
750
+ }
751
+
752
+ return null;
753
+ }
754
+
755
+ /**
756
+ * Locate a local framework checkout whose source should be aliased for HMR.
757
+ * This intentionally does not use Node package resolution: published Core
758
+ * tarballs include `src/` for source maps/docs, but must still be consumed
759
+ * through their built `dist/` exports.
760
+ */
761
+ function findLocalCoreSourceRoot(cwd: string): string | null {
714
762
  try {
715
763
  const pkg = JSON.parse(
716
764
  fs.readFileSync(path.join(cwd, "package.json"), "utf-8"),
@@ -746,7 +794,7 @@ function findCorePackageRoot(cwd: string): string | null {
746
794
  }
747
795
 
748
796
  function findCoreSrcDir(cwd: string): string | null {
749
- const root = findCorePackageRoot(cwd);
797
+ const root = findLocalCoreSourceRoot(cwd);
750
798
  return root ? path.join(root, "src") : null;
751
799
  }
752
800
 
@@ -858,6 +906,18 @@ function getDefaultOptimizeDeps(cwd: string): string[] {
858
906
  { specifier: "@libsql/client" },
859
907
  { specifier: "@amplitude/analytics-browser" },
860
908
  { specifier: "@assistant-ui/react" },
909
+ { specifier: "@assistant-ui/react-markdown" },
910
+ { specifier: "@assistant-ui/store" },
911
+ { specifier: "@assistant-ui/tap" },
912
+ {
913
+ specifier: "@agent-native/core > @assistant-ui/react > assistant-stream",
914
+ packageName: "@agent-native/core",
915
+ },
916
+ {
917
+ specifier:
918
+ "@agent-native/core > @assistant-ui/react > assistant-stream/utils",
919
+ packageName: "@agent-native/core",
920
+ },
861
921
  { specifier: "@codemirror/lang-sql" },
862
922
  { specifier: "@codemirror/theme-one-dark" },
863
923
  { specifier: "@excalidraw/excalidraw" },
@@ -1034,11 +1094,7 @@ function getDefaultOptimizeDeps(cwd: string): string[] {
1034
1094
  // then rebundles and reloads the editor. Its documented nested-dependency
1035
1095
  // syntax resolves the right-hand package from core's package directory,
1036
1096
  // while app-owned dependencies should remain direct entries.
1037
- if (
1038
- inMonorepo &&
1039
- !hasDep(dependencyName, cwd) &&
1040
- hasCoreDep(dependencyName, cwd)
1041
- ) {
1097
+ if (!hasDep(dependencyName, cwd) && hasCoreDep(dependencyName, cwd)) {
1042
1098
  return `@agent-native/core > ${specifier}`;
1043
1099
  }
1044
1100
  return specifier;
@@ -1487,7 +1543,8 @@ function fullReloadOnOptimizeDep504(): Plugin {
1487
1543
  name: "agent-native-full-reload-optimize-dep-504",
1488
1544
  apply: "serve",
1489
1545
  configureServer(server) {
1490
- let lastReloadAt = 0;
1546
+ let lastReloadAt: number | null = null;
1547
+ let reloadHistory: number[] = [];
1491
1548
  server.middlewares.use((req, res, next) => {
1492
1549
  const originalEnd = res.end;
1493
1550
  (res as unknown as { end: (...args: unknown[]) => unknown }).end = (
@@ -1499,8 +1556,17 @@ function fullReloadOnOptimizeDep504(): Plugin {
1499
1556
  statusMessage === "Outdated Optimize Dep"
1500
1557
  ) {
1501
1558
  const now = Date.now();
1502
- if (now - lastReloadAt > 500) {
1559
+ reloadHistory = reloadHistory.filter(
1560
+ (timestamp) =>
1561
+ now - timestamp < OPTIMIZE_DEP_FULL_RELOAD_WINDOW_MS,
1562
+ );
1563
+ if (
1564
+ (lastReloadAt === null ||
1565
+ now - lastReloadAt >= OPTIMIZE_DEP_FULL_RELOAD_COOLDOWN_MS) &&
1566
+ reloadHistory.length < OPTIMIZE_DEP_MAX_FULL_RELOADS
1567
+ ) {
1503
1568
  lastReloadAt = now;
1569
+ reloadHistory.push(now);
1504
1570
  server.ws.send({ type: "full-reload" });
1505
1571
  server.config.logger.info(
1506
1572
  `[agent-native] Vite optimized deps changed while loading ${
@@ -2093,6 +2159,7 @@ function ssrStubPlugin(packages: string[]): Plugin | null {
2093
2159
  "ThreadPrimitive",
2094
2160
  "WebLinksAddon",
2095
2161
  "captureException",
2162
+ "codeToHtml",
2096
2163
  "common",
2097
2164
  "createLowlight",
2098
2165
  "createNodeFromContent",
@@ -2112,6 +2179,7 @@ function ssrStubPlugin(packages: string[]): Plugin | null {
2112
2179
  "encodeStateAsUpdate",
2113
2180
  "mergeUpdates",
2114
2181
  "useAui",
2182
+ "useAuiState",
2115
2183
  "useComposer",
2116
2184
  "useComposerRuntime",
2117
2185
  "useCurrentEditor",
@@ -35,6 +35,34 @@ Then implement working code that is cohesive, accessible, responsive, and polish
35
35
 
36
36
  Default to Apple/Linear-level restraint: make the primary workflow obvious, then remove everything that does not help that workflow right now. A polished UI often has fewer visible controls, fewer borders, fewer labels, and fewer explanatory surfaces than the first reasonable implementation.
37
37
 
38
+ ### Progressive Disclosure Is A Design Requirement
39
+
40
+ Treat an all-at-once interface as a defect to fix during design, not as a
41
+ styling preference. Before coding, inventory every piece of content and action
42
+ on the surface, then assign each one to the smallest useful visibility level:
43
+
44
+ 1. **Immediate** — the page title, current state, one primary action, and the
45
+ compact context needed to choose what to do next.
46
+ 2. **Expanded** — the details needed for the selected item or active workflow.
47
+ 3. **On demand** — advanced settings, diagnostics, credentials, metadata,
48
+ destructive actions, documentation, and rarely used tools.
49
+
50
+ Use single-select accordions or simple disclosure rows for sibling panels when
51
+ the user is choosing one item at a time. Inside an expanded panel, keep another
52
+ layer for independent concerns instead of dumping every form, explanation, and
53
+ secondary action into the first reveal. Prefer one flat panel with alignment,
54
+ dividers, and whitespace over nested cards; provider or product icons should
55
+ not receive decorative borders or containers unless the container communicates
56
+ state or interaction. A collapsed row should still show the item name, status,
57
+ and a concise summary so the user can scan the whole surface without opening
58
+ everything.
59
+
60
+ Before shipping, ask: “What can disappear until the user asks for it?” Then
61
+ verify collapsed, expanded, loading, empty, error, and narrow-width states.
62
+ If the first viewport contains multiple forms, repeated explanatory copy,
63
+ documentation links, and controls for unrelated tasks, the surface has not
64
+ passed this requirement yet.
65
+
38
66
  - **Start by subtracting**: Before adding a visible control, banner, toolbar row, card, or explanatory block, ask what can be removed, merged, renamed, or moved into an existing affordance.
39
67
  - **One primary action**: Each surface should have one dominant next action. Secondary actions belong in menus, popovers, command palettes, disclosure rows, or contextual hover/focus states unless they are used constantly.
40
68
  - **Progressively disclose rare work**: Advanced options, diagnostics, metadata, settings, import/export, destructive actions, and inspection tools should stay tucked away until requested. Prefer small icon triggers with tooltips, popovers, drawers, or detail panels over permanent chrome.
@@ -1079,6 +1079,7 @@ interface SqlChartProps {
1079
1079
  resolvedSql?: string;
1080
1080
  className?: string;
1081
1081
  loadData?: boolean;
1082
+ reportScreenshot?: boolean;
1082
1083
  onExportCsvChange?: (handler: (() => void) | null) => void;
1083
1084
  /** Dashboard/panel state sent to slot-backed extension boxes. */
1084
1085
  extensionContext?: Record<string, unknown> | null;
@@ -1088,6 +1089,7 @@ export function SqlChart({
1088
1089
  panel,
1089
1090
  resolvedSql,
1090
1091
  loadData = true,
1092
+ reportScreenshot = false,
1091
1093
  onExportCsvChange,
1092
1094
  extensionContext,
1093
1095
  }: SqlChartProps) {
@@ -1110,7 +1112,7 @@ export function SqlChart({
1110
1112
  sql,
1111
1113
  panel.source,
1112
1114
  // Skip the query for section panels — they are pure layout with no data.
1113
- { enabled: shouldQuery },
1115
+ { enabled: shouldQuery, reportScreenshot },
1114
1116
  );
1115
1117
 
1116
1118
  const rawRows = result?.rows ?? [];
@@ -2,6 +2,7 @@ import {
2
2
  AgentSidebar,
3
3
  GuidedQuestionFlow,
4
4
  focusAgentChat,
5
+ markAgentChatHomeHandoff,
5
6
  navigateWithAgentChatViewTransition,
6
7
  useAgentChatHomeHandoff,
7
8
  useAgentChatHomeHandoffLinks,
@@ -22,10 +23,6 @@ import { TAB_ID } from "@/lib/tab-id";
22
23
 
23
24
  import { Header } from "./Header";
24
25
  import { HeaderActionsProvider } from "./HeaderActions";
25
- import {
26
- isAnalyticsSessionsRoute,
27
- shouldDefaultOpenAnalyticsSidebar,
28
- } from "./layout-route-policy";
29
26
  import { MobileNav } from "./MobileNav";
30
27
  import { Sidebar } from "./Sidebar";
31
28
 
@@ -94,7 +91,6 @@ export function Layout({ children }: LayoutProps) {
94
91
  const isExtensionsRoute =
95
92
  location.pathname === "/extensions" ||
96
93
  location.pathname.startsWith("/extensions/");
97
- const isSessionsRoute = isAnalyticsSessionsRoute(location.pathname);
98
94
  const isSessionDetailRoute = /^\/sessions\/[^/]+/.test(location.pathname);
99
95
  // Monitoring renders its own header row (section tabs / "Back to monitors"
100
96
  // + the relocated agent toggle), so skip the framework Header to avoid a
@@ -112,20 +108,23 @@ export function Layout({ children }: LayoutProps) {
112
108
  storageKey: ANALYTICS_CHAT_STORAGE_KEY,
113
109
  chatPath: "/ask",
114
110
  enabled: !reportScreenshot,
115
- requireActiveHandoff: false,
111
+ requireActiveHandoff: true,
116
112
  });
117
113
  useEffect(() => {
118
114
  function handleChatRunning(event: Event) {
119
115
  const detail = (event as CustomEvent).detail;
120
- if (typeof detail?.isRunning === "boolean") {
116
+ if (isAskRoute && typeof detail?.isRunning === "boolean") {
121
117
  markAnalyticsChatActivity();
118
+ if (detail.isRunning === true) {
119
+ markAgentChatHomeHandoff(ANALYTICS_CHAT_STORAGE_KEY);
120
+ }
122
121
  }
123
122
  }
124
123
 
125
124
  window.addEventListener("agentNative.chatRunning", handleChatRunning);
126
125
  return () =>
127
126
  window.removeEventListener("agentNative.chatRunning", handleChatRunning);
128
- }, []);
127
+ }, [isAskRoute]);
129
128
 
130
129
  function openAskAgentFullscreen() {
131
130
  focusAgentChat();
@@ -194,14 +193,11 @@ export function Layout({ children }: LayoutProps) {
194
193
  ) : (
195
194
  <AgentSidebar
196
195
  position="right"
197
- defaultOpen={
198
- chatHomeHandoffActive &&
199
- shouldDefaultOpenAnalyticsSidebar(location.pathname)
200
- }
196
+ defaultOpen={false}
201
197
  chatViewTransition
202
198
  storageKey={ANALYTICS_CHAT_STORAGE_KEY}
203
199
  browserTabId={TAB_ID}
204
- openOnChatRunning={chatHomeHandoffActive && !isSessionsRoute}
200
+ openOnChatRunning={chatHomeHandoffActive}
205
201
  onFullscreenRequest={openAskAgentFullscreen}
206
202
  emptyStateText={t("chat.emptyState")}
207
203
  agentPageHref="/agent"
@@ -2,6 +2,6 @@ export function isAnalyticsSessionsRoute(pathname: string): boolean {
2
2
  return pathname === "/sessions" || pathname.startsWith("/sessions/");
3
3
  }
4
4
 
5
- export function shouldDefaultOpenAnalyticsSidebar(pathname: string): boolean {
6
- return !isAnalyticsSessionsRoute(pathname);
5
+ export function shouldDefaultOpenAnalyticsSidebar(_pathname: string): boolean {
6
+ return false;
7
7
  }
@@ -138,11 +138,6 @@
138
138
  }
139
139
  }
140
140
 
141
- .analytics-chat-panel [data-agent-empty-state="centered"] {
142
- justify-content: center;
143
- padding-bottom: clamp(4rem, 12vh, 8rem);
144
- }
145
-
146
141
  .analytics-mobile-nav {
147
142
  height: 2.75rem;
148
143
  min-height: 2.75rem;
@@ -1,8 +1,5 @@
1
- import { markAgentChatHomeHandoff } from "@agent-native/core/client/agent-chat";
2
1
  import { useAgentRouteState } from "@agent-native/core/client/navigation";
3
- import { useLocation } from "react-router";
4
2
 
5
- import { ANALYTICS_CHAT_STORAGE_KEY } from "@/lib/chat-handoff";
6
3
  import { rememberLastOpened } from "@/lib/last-opened";
7
4
  import { TAB_ID } from "@/lib/tab-id";
8
5
 
@@ -24,7 +21,6 @@ interface NavigationState {
24
21
  const SESSION_FILTER_KEYS = ["range", "app", "q"] as const;
25
22
 
26
23
  export function useNavigationState() {
27
- const location = useLocation();
28
24
  useAgentRouteState<NavigationState>({
29
25
  browserTabId: TAB_ID,
30
26
  getNavigationState: ({ pathname, searchParams }) => {
@@ -156,18 +152,9 @@ export function useNavigationState() {
156
152
  if (cmd.view === "overview" || cmd.view === "home") return "/ask";
157
153
  return "/";
158
154
  },
159
- onNavigate: (_command, path) => {
160
- if (location.pathname === "/ask" && pathnameFromPath(path) !== "/ask") {
161
- markAgentChatHomeHandoff(ANALYTICS_CHAT_STORAGE_KEY);
162
- }
163
- },
164
155
  });
165
156
  }
166
157
 
167
- function pathnameFromPath(path: string): string {
168
- return path.split(/[?#]/, 1)[0] || "/";
169
- }
170
-
171
158
  function sessionFilters(
172
159
  searchParams?: URLSearchParams | Record<string, string>,
173
160
  ): Record<string, string> | undefined {
@@ -1,4 +1,5 @@
1
1
  import { callAction } from "@agent-native/core/client/hooks";
2
+ import { DASHBOARD_REPORT_ACTION_TIMEOUT_MS } from "@shared/dashboard-report-timeouts";
2
3
  import { MAX_CONCURRENT_SQL_QUERIES } from "@shared/sql-query-limits";
3
4
  import { useQuery } from "@tanstack/react-query";
4
5
 
@@ -6,6 +7,8 @@ import type { DataSourceType } from "@/pages/adhoc/sql-dashboard/types";
6
7
 
7
8
  import { addBytesProcessed } from "./cost-tracker";
8
9
 
10
+ export { DASHBOARD_REPORT_ACTION_TIMEOUT_MS };
11
+
9
12
  export interface SqlQueryResult {
10
13
  rows: Record<string, unknown>[];
11
14
  error?: string;
@@ -86,6 +89,7 @@ export async function executeSqlQuery(
86
89
  sql: string,
87
90
  source: DataSourceType,
88
91
  signal?: AbortSignal,
92
+ options?: { reportScreenshot?: boolean },
89
93
  ): Promise<SqlQueryResult> {
90
94
  const release = await acquireSqlQuerySlot(signal);
91
95
  let data: DashboardPanelQueryResponse;
@@ -93,7 +97,12 @@ export async function executeSqlQuery(
93
97
  data = await callAction<DashboardPanelQueryResponse>(
94
98
  "query-dashboard-panel",
95
99
  { query: sql, source },
96
- { signal },
100
+ {
101
+ signal,
102
+ ...(options?.reportScreenshot
103
+ ? { timeoutMs: DASHBOARD_REPORT_ACTION_TIMEOUT_MS }
104
+ : {}),
105
+ },
97
106
  );
98
107
  } finally {
99
108
  release();
@@ -128,12 +137,16 @@ export function useSqlQuery(
128
137
  refetchOnReconnect?: boolean | "always";
129
138
  refetchOnWindowFocus?: boolean | "always";
130
139
  retry?: boolean | number;
140
+ reportScreenshot?: boolean;
131
141
  staleTime?: number;
132
142
  },
133
143
  ) {
134
144
  return useQuery<SqlQueryResult>({
135
145
  queryKey,
136
- queryFn: ({ signal }) => executeSqlQuery(sql, source, signal),
146
+ queryFn: ({ signal }) =>
147
+ executeSqlQuery(sql, source, signal, {
148
+ reportScreenshot: options?.reportScreenshot,
149
+ }),
137
150
  enabled: options?.enabled ?? true,
138
151
  refetchInterval: options?.refetchInterval,
139
152
  refetchOnMount: options?.refetchOnMount ?? false,
@@ -1,8 +1,8 @@
1
1
  import { ChangelogSettingsCard } from "@agent-native/core/client/changelog";
2
- import { useSession } from "@agent-native/core/client/hooks";
3
2
  import { LanguagePicker, useT } from "@agent-native/core/client/i18n";
4
3
  import { TeamPage } from "@agent-native/core/client/org";
5
4
  import {
5
+ AccountSettingsCard,
6
6
  SettingsTabsPage,
7
7
  useAgentSettingsTabs,
8
8
  type SettingsTabItem,
@@ -28,11 +28,6 @@ import { AlertRulesSettingsCard } from "./settings/AlertRulesSettingsCard";
28
28
  import { buildAnalyticsGeneralSettingsSearchEntries } from "./settings/settings-search";
29
29
 
30
30
  export default function Settings() {
31
- // Settings is also reachable directly from the full-page agent surface.
32
- // Read the session from the framework's owning AppProviders boundary rather
33
- // than the template-local compatibility context, which may be remounted
34
- // independently during that route transition.
35
- const { session: auth } = useSession();
36
31
  const t = useT();
37
32
  const agentSettingsTabs = useAgentSettingsTabs();
38
33
  const replayStorageStatus = useReplayStorageStatus();
@@ -66,30 +61,13 @@ export default function Settings() {
66
61
 
67
62
  return (
68
63
  <SettingsTabsPage
64
+ account={<AccountSettingsCard />}
69
65
  teamLabel={t("navigation.team")}
70
66
  whatsNewLabel={t("root.whatsNew")}
71
67
  extraTabs={extraTabs}
72
68
  generalSearchEntries={generalSearchEntries}
73
69
  general={
74
70
  <div className="mx-auto w-full max-w-2xl space-y-6">
75
- <Card id="account" className="bg-card border-border/50 scroll-mt-16">
76
- <CardHeader>
77
- <CardTitle className="text-base">
78
- {t("settings.account")}
79
- </CardTitle>
80
- </CardHeader>
81
- <CardContent className="space-y-4">
82
- {auth && (
83
- <div className="flex items-center justify-between">
84
- <span className="text-sm text-muted-foreground">
85
- {t("settings.signedInAs")}
86
- </span>
87
- <span className="text-sm font-medium">{auth.email}</span>
88
- </div>
89
- )}
90
- </CardContent>
91
- </Card>
92
-
93
71
  <Card
94
72
  id="credentials"
95
73
  className="bg-card border-border/50 scroll-mt-16"
@@ -67,6 +67,7 @@ interface SqlChartCardProps {
67
67
  onSaveSql?: (sql: string) => Promise<void>;
68
68
  editable?: boolean;
69
69
  eagerLoad?: boolean;
70
+ reportScreenshot?: boolean;
70
71
  isDragSource?: boolean;
71
72
  selectedForChat?: boolean;
72
73
  onSelectForChat?: (options?: SelectDashboardPanelOptions) => void;
@@ -125,6 +126,7 @@ export function SqlChartCard({
125
126
  onSaveSql,
126
127
  editable = true,
127
128
  eagerLoad = false,
129
+ reportScreenshot = false,
128
130
  isDragSource = false,
129
131
  selectedForChat = false,
130
132
  onSelectForChat,
@@ -394,6 +396,7 @@ export function SqlChartCard({
394
396
  panel={panel}
395
397
  resolvedSql={resolvedSql}
396
398
  loadData
399
+ reportScreenshot={reportScreenshot}
397
400
  extensionContext={extensionContext}
398
401
  />
399
402
  )}
@@ -490,6 +493,7 @@ export function SqlChartCard({
490
493
  panel={panel}
491
494
  resolvedSql={resolvedSql}
492
495
  loadData
496
+ reportScreenshot={reportScreenshot}
493
497
  extensionContext={extensionContext}
494
498
  />
495
499
  </ChartFillHeight>
@@ -684,6 +688,7 @@ export function SqlChartCard({
684
688
  panel={panel}
685
689
  resolvedSql={resolvedSql}
686
690
  loadData={shouldLoadData}
691
+ reportScreenshot={reportScreenshot}
687
692
  onExportCsvChange={handleExportCsvChange}
688
693
  extensionContext={extensionContext}
689
694
  />
@@ -701,6 +706,7 @@ export function SqlChartCard({
701
706
  panel={panel}
702
707
  resolvedSql={resolvedSql}
703
708
  loadData
709
+ reportScreenshot={reportScreenshot}
704
710
  extensionContext={extensionContext}
705
711
  />
706
712
  </ChartFillHeight>
@@ -1,5 +1,5 @@
1
1
  import { generateTabId } from "@agent-native/core/client/agent-chat";
2
- import { agentNativePath } from "@agent-native/core/client/api-path";
2
+ import { agentNativePath, appPath } from "@agent-native/core/client/api-path";
3
3
  import {
4
4
  useCollaborativeDoc,
5
5
  emailToColor,
@@ -248,6 +248,7 @@ const PanelCell = memo(function PanelCell({
248
248
  remoteEditor,
249
249
  editable,
250
250
  eagerLoad,
251
+ reportScreenshot,
251
252
  isDragSource,
252
253
  selectedForChat,
253
254
  selectPanelForChat,
@@ -261,6 +262,7 @@ const PanelCell = memo(function PanelCell({
261
262
  remoteEditor: { color: string; name: string } | undefined;
262
263
  editable: boolean;
263
264
  eagerLoad: boolean;
265
+ reportScreenshot: boolean;
264
266
  isDragSource: boolean;
265
267
  selectedForChat: boolean;
266
268
  selectPanelForChat: (
@@ -348,6 +350,7 @@ const PanelCell = memo(function PanelCell({
348
350
  onSaveSql={(sql) => onSavePanel({ ...panel, sql })}
349
351
  editable={editable}
350
352
  eagerLoad={eagerLoad}
353
+ reportScreenshot={reportScreenshot}
351
354
  isDragSource={isDragSource}
352
355
  selectedForChat={selectedForChat}
353
356
  onSelectForChat={handleSelectForChat}
@@ -1384,6 +1387,11 @@ export default function SqlDashboardPage() {
1384
1387
  [saveView],
1385
1388
  );
1386
1389
 
1390
+ const dashboardShareUrl = useMemo(() => {
1391
+ if (!dashboardId || typeof window === "undefined") return undefined;
1392
+ return window.location.origin + appPath("/dashboards/" + dashboardId);
1393
+ }, [dashboardId]);
1394
+
1387
1395
  useSetPageTitle(
1388
1396
  reportScreenshot ? null : dashboard ? (
1389
1397
  <div className="flex min-w-0 items-center gap-2">
@@ -1436,6 +1444,7 @@ export default function SqlDashboardPage() {
1436
1444
  resourceId={dashboardId}
1437
1445
  resourceTitle={dashboard.name}
1438
1446
  variant="compact"
1447
+ shareUrl={dashboardShareUrl}
1439
1448
  shareTabs={{
1440
1449
  tabs: [
1441
1450
  {
@@ -1972,6 +1981,7 @@ export default function SqlDashboardPage() {
1972
1981
  }
1973
1982
  editable={canEdit}
1974
1983
  eagerLoad={reportScreenshot}
1984
+ reportScreenshot={reportScreenshot}
1975
1985
  isDragSource={activeDragPanelId === panel.id}
1976
1986
  selectedForChat={selectedPanelId === panel.id}
1977
1987
  selectPanelForChat={selectPanelForChat}
@@ -1,4 +1,5 @@
1
1
  import { useSendToAgentChat } from "@agent-native/core/client/agent-chat";
2
+ import { appPath } from "@agent-native/core/client/api-path";
2
3
  import {
3
4
  callAction,
4
5
  useActionMutation,
@@ -18,7 +19,7 @@ import {
18
19
  IconWorld,
19
20
  } from "@tabler/icons-react";
20
21
  import { useQuery, useQueryClient } from "@tanstack/react-query";
21
- import { useEffect, useState } from "react";
22
+ import { useEffect, useMemo, useState } from "react";
22
23
  import { useParams } from "react-router";
23
24
  import { Link, useNavigate } from "react-router";
24
25
 
@@ -168,6 +169,11 @@ export default function AnalysisDetail() {
168
169
  navigate("/analyses");
169
170
  };
170
171
 
172
+ const analysisShareUrl = useMemo(() => {
173
+ if (!analysis?.id || typeof window === "undefined") return undefined;
174
+ return window.location.origin + appPath("/analyses/" + analysis.id);
175
+ }, [analysis?.id]);
176
+
171
177
  useSetPageTitle(
172
178
  analysis ? (
173
179
  <h1 className="text-lg font-semibold tracking-tight truncate">
@@ -184,6 +190,7 @@ export default function AnalysisDetail() {
184
190
  resourceId={analysis.id}
185
191
  resourceTitle={analysis.name}
186
192
  variant="compact"
193
+ shareUrl={analysisShareUrl}
187
194
  />
188
195
  <Button
189
196
  variant="outline"
@@ -20,7 +20,7 @@ export function buildAnalyticsGeneralSettingsSearchEntries(
20
20
  {
21
21
  id: "analytics-account",
22
22
  label: t("settings.account"),
23
- keywords: "profile email signed in identity",
23
+ keywords: "profile photo avatar email signed in identity",
24
24
  hash: "account",
25
25
  },
26
26
  {
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-22
4
+ ---
5
+
6
+ Fixed dashboards and analyses missing a copyable share link
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-23
4
+ ---
5
+
6
+ Ask Analytics is better centered, with a quieter chat rail and a sidebar that stays closed until an active Ask conversation hands it off.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-23
4
+ ---
5
+
6
+ Daily dashboard emails now give read-heavy panels enough time to load and preserve completed image sections when a later section is unavailable.