@agent-native/core 0.120.2 → 0.120.4

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 (278) hide show
  1. package/corpus/README.md +3 -3
  2. package/corpus/core/CHANGELOG.md +28 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/cli/context-xray-local.ts +1 -1
  5. package/corpus/core/src/cli/index.ts +63 -18
  6. package/corpus/core/src/cli/skills.ts +5 -0
  7. package/corpus/core/src/cli/telemetry.ts +118 -1
  8. package/corpus/core/src/client/AgentPanel.tsx +10 -0
  9. package/corpus/core/src/client/CommandMenu.tsx +13 -1
  10. package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +39 -4
  11. package/corpus/core/src/client/analytics.ts +13 -0
  12. package/corpus/core/src/client/error-capture.ts +6 -1
  13. package/corpus/core/src/client/extensions/ExtensionsListPage.tsx +12 -5
  14. package/corpus/core/src/client/extensions/agent-native-extension-runtime.ts +1 -1
  15. package/corpus/core/src/client/navigation/index.ts +2 -0
  16. package/corpus/core/src/client/org/OrgSwitcher.tsx +14 -32
  17. package/corpus/core/src/client/settings/ExtensionsSettingsContent.tsx +1 -1
  18. package/corpus/core/src/extensions/theme.ts +1 -1
  19. package/corpus/core/src/localization/default-messages.ts +2 -0
  20. package/corpus/core/src/server/core-routes-plugin.ts +10 -1
  21. package/corpus/core/src/server/framework-request-handler.ts +17 -26
  22. package/corpus/core/src/styles/agent-native.css +13 -0
  23. package/corpus/core/src/templates/chat/app/components/layout/Layout.tsx +3 -0
  24. package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +78 -45
  25. package/corpus/core/src/templates/chat/app/global.css +1 -1
  26. package/corpus/core/src/templates/default/app/global.css +1 -1
  27. package/corpus/core/src/tracking/error-capture.ts +151 -0
  28. package/corpus/core/src/tracking/index.ts +5 -0
  29. package/corpus/templates/analytics/app/components/dashboard/CumulativeNetChart.tsx +1 -1
  30. package/corpus/templates/analytics/app/components/dashboard/DashboardHistoryPanel.tsx +1 -4
  31. package/corpus/templates/analytics/app/components/dashboard/DashboardPanelSkeleton.tsx +1 -1
  32. package/corpus/templates/analytics/app/components/dashboard/DataTable.tsx +1 -1
  33. package/corpus/templates/analytics/app/components/dashboard/DateRangePicker.tsx +2 -2
  34. package/corpus/templates/analytics/app/components/dashboard/MetricCard.tsx +1 -1
  35. package/corpus/templates/analytics/app/components/dashboard/RecentActivity.tsx +1 -1
  36. package/corpus/templates/analytics/app/components/dashboard/RevenueChart.tsx +1 -1
  37. package/corpus/templates/analytics/app/components/dashboard/RevenueComparisonChart.tsx +1 -1
  38. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +41 -9
  39. package/corpus/templates/analytics/app/components/dashboard/StatsCard.tsx +1 -1
  40. package/corpus/templates/analytics/app/components/dashboard/TimeSeriesChart.tsx +1 -1
  41. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +2 -0
  42. package/corpus/templates/analytics/app/components/layout/Layout.tsx +28 -14
  43. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +152 -124
  44. package/corpus/templates/analytics/app/global.css +5 -5
  45. package/corpus/templates/analytics/app/lib/dashboard-report-capture.ts +42 -0
  46. package/corpus/templates/analytics/app/pages/adhoc/_shared/KpiChart.tsx +1 -1
  47. package/corpus/templates/analytics/app/pages/adhoc/explorer/components/ChartTypePicker.tsx +1 -1
  48. package/corpus/templates/analytics/app/pages/adhoc/explorer/components/DateRangePicker.tsx +1 -1
  49. package/corpus/templates/analytics/app/pages/adhoc/explorer/components/EventRow.tsx +1 -1
  50. package/corpus/templates/analytics/app/pages/adhoc/explorer/components/SqlPreview.tsx +2 -2
  51. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +3 -3
  52. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/EmailReportDialog.tsx +2 -2
  53. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +1 -1
  54. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +1 -1
  55. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +162 -51
  56. package/corpus/templates/analytics/app/root.tsx +28 -0
  57. package/corpus/templates/analytics/changelog/2026-07-24-analytics-charts-now-explain-slow-loads-and-offer-a-direct-r.md +6 -0
  58. package/corpus/templates/analytics/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  59. package/corpus/templates/analytics/changelog/2026-07-24-daily-dashboard-emails-now-load-signed-reports-more-reliably.md +6 -0
  60. package/corpus/templates/analytics/changelog/2026-07-24-manage-agent-is-clearly-marked-as-a-link-to-its-dedicated-pa.md +6 -0
  61. package/corpus/templates/analytics/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  62. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +1 -1
  63. package/corpus/templates/analytics/server/db/schema.ts +5 -0
  64. package/corpus/templates/analytics/server/jobs/dashboard-report.ts +21 -0
  65. package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +11 -0
  66. package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +54 -0
  67. package/corpus/templates/analytics/server/lib/dashboard-report.ts +235 -26
  68. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +4 -1
  69. package/corpus/templates/analytics/server/plugins/db.ts +9 -0
  70. package/corpus/templates/analytics/shared/dashboard-report-timeouts.ts +1 -1
  71. package/corpus/templates/assets/app/components/asset/AssetPreviewDialog.tsx +376 -0
  72. package/corpus/templates/assets/app/components/create/RecentDraftsSection.tsx +14 -4
  73. package/corpus/templates/assets/app/components/layout/Layout.tsx +5 -0
  74. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +118 -74
  75. package/corpus/templates/assets/app/global.css +1 -1
  76. package/corpus/templates/assets/app/i18n-data.ts +10 -0
  77. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +99 -10
  78. package/corpus/templates/assets/app/routes/library.tsx +21 -198
  79. package/corpus/templates/assets/changelog/2026-07-21-unified-asset-preview-click-any-asset-to-open-one-preview-wi.md +6 -0
  80. package/corpus/templates/assets/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  81. package/corpus/templates/assets/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  82. package/corpus/templates/brain/app/components/layout/Layout.tsx +3 -0
  83. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +76 -43
  84. package/corpus/templates/brain/app/global.css +1 -1
  85. package/corpus/templates/brain/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  86. package/corpus/templates/brain/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  87. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +67 -52
  88. package/corpus/templates/calendar/app/global.css +1 -1
  89. package/corpus/templates/calendar/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  90. package/corpus/templates/calendar/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  91. package/corpus/templates/chat/app/components/layout/Layout.tsx +3 -0
  92. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +78 -45
  93. package/corpus/templates/chat/app/global.css +1 -1
  94. package/corpus/templates/chat/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  95. package/corpus/templates/chat/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  96. package/corpus/templates/clips/app/components/library/library-layout.tsx +65 -31
  97. package/corpus/templates/clips/app/components/library/organization-switcher.tsx +2 -2
  98. package/corpus/templates/clips/app/components/player/video-player.tsx +16 -1
  99. package/corpus/templates/clips/app/global.css +1 -1
  100. package/corpus/templates/clips/app/hooks/use-view-tracking.ts +55 -12
  101. package/corpus/templates/clips/app/routes/embed.$shareId.tsx +6 -5
  102. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +7 -7
  103. package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -5
  104. package/corpus/templates/clips/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  105. package/corpus/templates/clips/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  106. package/corpus/templates/clips/server/plugins/db.ts +113 -68
  107. package/corpus/templates/content/actions/update-document.ts +145 -91
  108. package/corpus/templates/content/app/components/editor/CommentComposer.tsx +4 -1
  109. package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +366 -164
  110. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +51 -28
  111. package/corpus/templates/content/app/components/editor/database/sidebar.tsx +19 -8
  112. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +66 -42
  113. package/corpus/templates/content/app/global.css +1 -1
  114. package/corpus/templates/content/app/i18n-data.ts +15 -0
  115. package/corpus/templates/content/changelog/2026-07-23-shared-pages-now-keep-durable-content-visible-and-comment-th.md +6 -0
  116. package/corpus/templates/content/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  117. package/corpus/templates/content/changelog/2026-07-24-comment-drafts-now-stay-open-when-saving-fails-and-long-live.md +6 -0
  118. package/corpus/templates/content/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  119. package/corpus/templates/design/actions/update-file.ts +85 -18
  120. package/corpus/templates/design/app/components/layout/Sidebar.tsx +65 -30
  121. package/corpus/templates/design/app/entry.client.tsx +14 -1
  122. package/corpus/templates/design/app/global.css +1 -1
  123. package/corpus/templates/design/app/lib/design-save-outbox.ts +39 -0
  124. package/corpus/templates/design/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  125. package/corpus/templates/design/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  126. package/corpus/templates/dispatch/app/global.css +1 -1
  127. package/corpus/templates/dispatch/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  128. package/corpus/templates/dispatch/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  129. package/corpus/templates/forms/app/components/layout/Layout.tsx +3 -0
  130. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +72 -37
  131. package/corpus/templates/forms/app/global.css +1 -1
  132. package/corpus/templates/forms/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  133. package/corpus/templates/forms/changelog/2026-07-24-forms-sidebar-actions-now-keep-search-language-feedback-and-.md +6 -0
  134. package/corpus/templates/forms/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  135. package/corpus/templates/macros/app/components/DailyProgress.tsx +5 -5
  136. package/corpus/templates/macros/app/components/ExerciseCard.tsx +2 -2
  137. package/corpus/templates/macros/app/components/MealCard.tsx +2 -2
  138. package/corpus/templates/macros/app/components/WeightCard.tsx +2 -2
  139. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +56 -29
  140. package/corpus/templates/macros/app/components/ui/button.tsx +1 -2
  141. package/corpus/templates/macros/app/components/ui/card.tsx +1 -1
  142. package/corpus/templates/macros/app/global.css +1 -1
  143. package/corpus/templates/macros/app/routes/_index.tsx +1 -1
  144. package/corpus/templates/macros/app/routes/analytics.tsx +4 -7
  145. package/corpus/templates/macros/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  146. package/corpus/templates/macros/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  147. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +125 -37
  148. package/corpus/templates/mail/app/global.css +1 -1
  149. package/corpus/templates/mail/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  150. package/corpus/templates/mail/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  151. package/corpus/templates/plan/app/components/layout/Layout.tsx +3 -0
  152. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +90 -60
  153. package/corpus/templates/plan/app/global.css +1 -1
  154. package/corpus/templates/plan/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  155. package/corpus/templates/plan/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  156. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +69 -32
  157. package/corpus/templates/slides/app/global.css +1 -1
  158. package/corpus/templates/slides/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  159. package/corpus/templates/slides/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  160. package/corpus/templates/tasks/app/global.css +1 -1
  161. package/corpus/templates/tasks/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  162. package/corpus/toolkit/CHANGELOG.md +14 -0
  163. package/corpus/toolkit/README.md +8 -1
  164. package/corpus/toolkit/agent-native.eject.json +1 -1
  165. package/corpus/toolkit/package.json +1 -1
  166. package/corpus/toolkit/src/app-shell/index.ts +1 -0
  167. package/corpus/toolkit/src/app-shell/sidebar-footer-actions.tsx +48 -0
  168. package/corpus/toolkit/src/chat-history.css +52 -1
  169. package/corpus/toolkit/src/design-system/default-adapter.tsx +1 -1
  170. package/corpus/toolkit/src/editor/useCollabReconcile.ts +83 -15
  171. package/corpus/toolkit/src/ui/button.tsx +1 -2
  172. package/corpus/toolkit/src/ui/card.tsx +1 -1
  173. package/corpus/toolkit/src/ui/table.tsx +4 -11
  174. package/dist/cli/context-xray-local.js +1 -1
  175. package/dist/cli/context-xray-local.js.map +1 -1
  176. package/dist/cli/index.js +56 -17
  177. package/dist/cli/index.js.map +1 -1
  178. package/dist/cli/skills.d.ts.map +1 -1
  179. package/dist/cli/skills.js +5 -0
  180. package/dist/cli/skills.js.map +1 -1
  181. package/dist/cli/telemetry.d.ts +7 -0
  182. package/dist/cli/telemetry.d.ts.map +1 -1
  183. package/dist/cli/telemetry.js +91 -1
  184. package/dist/cli/telemetry.js.map +1 -1
  185. package/dist/client/AgentPanel.d.ts +7 -1
  186. package/dist/client/AgentPanel.d.ts.map +1 -1
  187. package/dist/client/AgentPanel.js +2 -2
  188. package/dist/client/AgentPanel.js.map +1 -1
  189. package/dist/client/CommandMenu.d.ts +2 -0
  190. package/dist/client/CommandMenu.d.ts.map +1 -1
  191. package/dist/client/CommandMenu.js +12 -1
  192. package/dist/client/CommandMenu.js.map +1 -1
  193. package/dist/client/agent-page/AgentTabsPage.d.ts +4 -0
  194. package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -1
  195. package/dist/client/agent-page/AgentTabsPage.js +8 -4
  196. package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
  197. package/dist/client/analytics.d.ts.map +1 -1
  198. package/dist/client/analytics.js +7 -0
  199. package/dist/client/analytics.js.map +1 -1
  200. package/dist/client/error-capture.d.ts.map +1 -1
  201. package/dist/client/error-capture.js +8 -1
  202. package/dist/client/error-capture.js.map +1 -1
  203. package/dist/client/extensions/ExtensionsListPage.d.ts.map +1 -1
  204. package/dist/client/extensions/ExtensionsListPage.js +2 -2
  205. package/dist/client/extensions/ExtensionsListPage.js.map +1 -1
  206. package/dist/client/extensions/agent-native-extension-runtime.js +1 -1
  207. package/dist/client/extensions/agent-native-extension-runtime.js.map +1 -1
  208. package/dist/client/navigation/index.d.ts +1 -1
  209. package/dist/client/navigation/index.d.ts.map +1 -1
  210. package/dist/client/navigation/index.js +1 -1
  211. package/dist/client/navigation/index.js.map +1 -1
  212. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  213. package/dist/client/org/OrgSwitcher.js +9 -13
  214. package/dist/client/org/OrgSwitcher.js.map +1 -1
  215. package/dist/client/settings/ExtensionsSettingsContent.js +1 -1
  216. package/dist/client/settings/ExtensionsSettingsContent.js.map +1 -1
  217. package/dist/collab/awareness.d.ts +2 -2
  218. package/dist/collab/awareness.d.ts.map +1 -1
  219. package/dist/collab/struct-routes.d.ts +1 -1
  220. package/dist/extensions/theme.js +1 -1
  221. package/dist/extensions/theme.js.map +1 -1
  222. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  223. package/dist/localization/default-messages.d.ts +2 -0
  224. package/dist/localization/default-messages.d.ts.map +1 -1
  225. package/dist/localization/default-messages.js +2 -0
  226. package/dist/localization/default-messages.js.map +1 -1
  227. package/dist/provider-api/actions/provider-api.d.ts +2 -2
  228. package/dist/secrets/routes.d.ts +9 -9
  229. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  230. package/dist/server/core-routes-plugin.js +8 -1
  231. package/dist/server/core-routes-plugin.js.map +1 -1
  232. package/dist/server/framework-request-handler.d.ts.map +1 -1
  233. package/dist/server/framework-request-handler.js +17 -27
  234. package/dist/server/framework-request-handler.js.map +1 -1
  235. package/dist/server/realtime-token.d.ts +1 -1
  236. package/dist/styles/agent-native.css +13 -0
  237. package/dist/templates/chat/app/components/layout/Layout.tsx +3 -0
  238. package/dist/templates/chat/app/components/layout/Sidebar.tsx +78 -45
  239. package/dist/templates/chat/app/global.css +1 -1
  240. package/dist/templates/chat/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  241. package/dist/templates/chat/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  242. package/dist/templates/default/app/global.css +1 -1
  243. package/dist/tracking/error-capture.d.ts +14 -0
  244. package/dist/tracking/error-capture.d.ts.map +1 -0
  245. package/dist/tracking/error-capture.js +113 -0
  246. package/dist/tracking/error-capture.js.map +1 -0
  247. package/dist/tracking/index.d.ts +1 -0
  248. package/dist/tracking/index.d.ts.map +1 -1
  249. package/dist/tracking/index.js +1 -0
  250. package/dist/tracking/index.js.map +1 -1
  251. package/package.json +2 -2
  252. package/src/cli/context-xray-local.ts +1 -1
  253. package/src/cli/index.ts +63 -18
  254. package/src/cli/skills.ts +5 -0
  255. package/src/cli/telemetry.ts +118 -1
  256. package/src/client/AgentPanel.tsx +10 -0
  257. package/src/client/CommandMenu.tsx +13 -1
  258. package/src/client/agent-page/AgentTabsPage.tsx +39 -4
  259. package/src/client/analytics.ts +13 -0
  260. package/src/client/error-capture.ts +6 -1
  261. package/src/client/extensions/ExtensionsListPage.tsx +12 -5
  262. package/src/client/extensions/agent-native-extension-runtime.ts +1 -1
  263. package/src/client/navigation/index.ts +2 -0
  264. package/src/client/org/OrgSwitcher.tsx +14 -32
  265. package/src/client/settings/ExtensionsSettingsContent.tsx +1 -1
  266. package/src/extensions/theme.ts +1 -1
  267. package/src/localization/default-messages.ts +2 -0
  268. package/src/server/core-routes-plugin.ts +10 -1
  269. package/src/server/framework-request-handler.ts +17 -26
  270. package/src/styles/agent-native.css +13 -0
  271. package/src/templates/chat/app/components/layout/Layout.tsx +3 -0
  272. package/src/templates/chat/app/components/layout/Sidebar.tsx +78 -45
  273. package/src/templates/chat/app/global.css +1 -1
  274. package/src/templates/chat/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  275. package/src/templates/chat/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  276. package/src/templates/default/app/global.css +1 -1
  277. package/src/tracking/error-capture.ts +151 -0
  278. package/src/tracking/index.ts +5 -0
@@ -108,10 +108,7 @@ export function DashboardHistoryPanel({
108
108
  ) : (
109
109
  <div className="space-y-1">
110
110
  {revisions.map((revision) => (
111
- <div
112
- key={revision.id}
113
- className="rounded-lg border border-border bg-card p-3"
114
- >
111
+ <div key={revision.id} className="rounded-lg bg-card p-3">
115
112
  <div className="flex items-start justify-between gap-3">
116
113
  <div className="min-w-0">
117
114
  <p className="truncate text-xs font-medium">
@@ -11,7 +11,7 @@ export function DashboardPanelSkeleton({
11
11
  <Skeleton
12
12
  {...props}
13
13
  className={cn(
14
- "dashboard-panel-skeleton bg-muted-foreground/25",
14
+ "dashboard-panel-skeleton bg-muted-foreground/18",
15
15
  className,
16
16
  )}
17
17
  />
@@ -217,7 +217,7 @@ export function DataTable({
217
217
  if (!title) return content;
218
218
 
219
219
  return (
220
- <Card className="bg-card border-border/50">
220
+ <Card className="bg-card">
221
221
  <CardHeader>
222
222
  <CardTitle className="text-base">{title}</CardTitle>
223
223
  </CardHeader>
@@ -27,7 +27,7 @@ export function dateRangeToInterval(range: DateRange): number {
27
27
 
28
28
  export function DateRangePicker({ value, onChange }: DateRangePickerProps) {
29
29
  return (
30
- <div className="flex items-center gap-1 rounded-lg border border-border p-1">
30
+ <div className="flex items-center gap-1 rounded-lg bg-card p-1">
31
31
  {options.map((opt) => (
32
32
  <Button
33
33
  key={opt.value}
@@ -35,7 +35,7 @@ export function DateRangePicker({ value, onChange }: DateRangePickerProps) {
35
35
  size="sm"
36
36
  className={cn(
37
37
  "h-7 px-3 text-xs",
38
- value === opt.value && "bg-secondary text-secondary-foreground",
38
+ value === opt.value && "bg-accent text-accent-foreground",
39
39
  )}
40
40
  onClick={() => onChange(opt.value)}
41
41
  >
@@ -19,7 +19,7 @@ export function MetricCard({
19
19
  error,
20
20
  }: MetricCardProps) {
21
21
  return (
22
- <Card className="bg-card border-border/50">
22
+ <Card className="bg-card">
23
23
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
24
24
  <CardTitle className="text-sm font-medium text-muted-foreground">
25
25
  {title}
@@ -51,7 +51,7 @@ export function RecentActivity() {
51
51
  const t = useT();
52
52
 
53
53
  return (
54
- <Card className="col-span-full lg:col-span-3 bg-card border-border/50">
54
+ <Card className="col-span-full lg:col-span-3 bg-card">
55
55
  <CardHeader>
56
56
  <CardTitle>{t("dashboard.recentSales")}</CardTitle>
57
57
  <CardDescription>
@@ -30,7 +30,7 @@ export function RevenueChart() {
30
30
  const t = useT();
31
31
 
32
32
  return (
33
- <Card className="col-span-full lg:col-span-4 bg-card border-border/50">
33
+ <Card className="col-span-full lg:col-span-4 bg-card">
34
34
  <CardHeader>
35
35
  <CardTitle>{t("dashboard.revenueOverTime")}</CardTitle>
36
36
  </CardHeader>
@@ -76,7 +76,7 @@ export function RevenueComparisonChart({
76
76
  }));
77
77
 
78
78
  return (
79
- <Card className="bg-card border-border/50">
79
+ <Card className="bg-card">
80
80
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
81
81
  <CardTitle className="text-base">{title}</CardTitle>
82
82
  </CardHeader>
@@ -12,6 +12,7 @@ import {
12
12
  IconChevronRight,
13
13
  IconAlertTriangle,
14
14
  IconInfoCircle,
15
+ IconRefresh,
15
16
  IconTrendingUp,
16
17
  IconTrendingDown,
17
18
  } from "@tabler/icons-react";
@@ -174,6 +175,27 @@ const PARTIAL_DAY_KEY_PREFIX = "__sql_chart_partial_day";
174
175
  const TABLE_PANEL_MIN_HEIGHT_CLASS = "min-h-[386px]";
175
176
  const TABLE_PANEL_SKELETON_ROWS = 10;
176
177
 
178
+ export function formatSqlChartError(error: unknown): string {
179
+ const message =
180
+ error instanceof Error
181
+ ? error.message
182
+ : typeof error === "string"
183
+ ? error
184
+ : String(error ?? "");
185
+ const readableMessage = message
186
+ .replace(/<[^>]*>/g, " ")
187
+ .replace(/\s+/g, " ")
188
+ .trim();
189
+
190
+ if (/inactivity timeout|too much time has passed/i.test(readableMessage)) {
191
+ return "This chart took too long to load. Try again.";
192
+ }
193
+ if (/internal server error/i.test(readableMessage)) {
194
+ return "This chart could not be loaded. Try again.";
195
+ }
196
+ return readableMessage || "This chart could not be loaded. Try again.";
197
+ }
198
+
177
199
  function formatYValue(
178
200
  value: number,
179
201
  formatter?: "number" | "currency" | "percent",
@@ -1108,6 +1130,7 @@ export function SqlChart({
1108
1130
  isLoading,
1109
1131
  isFetching,
1110
1132
  error: queryError,
1133
+ refetch,
1111
1134
  } = useSqlQuery(
1112
1135
  ["sql-chart", panel.id, sql, panel.source],
1113
1136
  sql,
@@ -1117,14 +1140,11 @@ export function SqlChart({
1117
1140
  );
1118
1141
 
1119
1142
  const rawRows = result?.rows ?? [];
1120
- const queryErrorMessage =
1121
- queryError instanceof Error
1122
- ? queryError.message
1123
- : queryError
1124
- ? String(queryError)
1125
- : undefined;
1126
1143
  const error =
1127
- rawRows.length === 0 ? (result?.error ?? queryErrorMessage) : undefined;
1144
+ rawRows.length === 0
1145
+ ? (result?.error ??
1146
+ (queryError ? formatSqlChartError(queryError) : undefined))
1147
+ : undefined;
1128
1148
 
1129
1149
  const { rows: queryRows, forcedYKeys } = useMemo(() => {
1130
1150
  if (panel.config?.pivot && rawRows.length) {
@@ -1209,9 +1229,21 @@ export function SqlChart({
1209
1229
  if (error) {
1210
1230
  return (
1211
1231
  <div
1212
- className={`flex flex-1 items-center justify-center px-4 ${placeholderPadY} ${placeholderMinH}`}
1232
+ className={`flex flex-1 flex-col items-center justify-center gap-3 px-4 ${placeholderPadY} ${placeholderMinH}`}
1233
+ role="alert"
1213
1234
  >
1214
- <p className="text-sm text-red-400 text-center break-all">{error}</p>
1235
+ <p className="text-center text-sm text-red-400 break-all">
1236
+ {formatSqlChartError(error)}
1237
+ </p>
1238
+ <Button
1239
+ type="button"
1240
+ variant="secondary"
1241
+ size="sm"
1242
+ onClick={() => void refetch()}
1243
+ >
1244
+ <IconRefresh className="mr-2 h-3.5 w-3.5" />
1245
+ {t("sqlDashboard.refresh")}
1246
+ </Button>
1215
1247
  </div>
1216
1248
  );
1217
1249
  }
@@ -20,7 +20,7 @@ export function StatsCard({
20
20
  trend,
21
21
  }: StatsCardProps) {
22
22
  return (
23
- <Card className="bg-card border-border/50 shadow-sm">
23
+ <Card className="bg-card shadow-sm">
24
24
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
25
25
  <CardTitle className="text-sm font-medium text-muted-foreground">
26
26
  {title}
@@ -49,7 +49,7 @@ export function TimeSeriesChart({
49
49
  };
50
50
 
51
51
  return (
52
- <Card className="bg-card border-border/50">
52
+ <Card className="bg-card">
53
53
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
54
54
  <CardTitle className="text-base">{title}</CardTitle>
55
55
  </CardHeader>
@@ -381,9 +381,11 @@ export function CommandPalette() {
381
381
  const openHandler = () => setOpen(true);
382
382
  document.addEventListener("keydown", handler);
383
383
  window.addEventListener("analytics:open-command-palette", openHandler);
384
+ window.addEventListener("agent-native:open-command-menu", openHandler);
384
385
  return () => {
385
386
  document.removeEventListener("keydown", handler);
386
387
  window.removeEventListener("analytics:open-command-palette", openHandler);
388
+ window.removeEventListener("agent-native:open-command-menu", openHandler);
387
389
  };
388
390
  }, []);
389
391
 
@@ -2,6 +2,7 @@ import {
2
2
  AgentSidebar,
3
3
  GuidedQuestionFlow,
4
4
  focusAgentChat,
5
+ isAgentChatHomeHandoffActive,
5
6
  markAgentChatHomeHandoff,
6
7
  navigateWithAgentChatViewTransition,
7
8
  useAgentChatHomeHandoff,
@@ -19,6 +20,7 @@ import {
19
20
  ANALYTICS_CHAT_STORAGE_KEY,
20
21
  markAnalyticsChatActivity,
21
22
  } from "@/lib/chat-handoff";
23
+ import { isDashboardReportScreenshot } from "@/lib/dashboard-report-capture";
22
24
  import { TAB_ID } from "@/lib/tab-id";
23
25
 
24
26
  import { Header } from "./Header";
@@ -33,12 +35,30 @@ interface LayoutProps {
33
35
  const BARE_ROUTES = new Set(["/chart"]);
34
36
 
35
37
  export function Layout({ children }: LayoutProps) {
38
+ const location = useLocation();
39
+
40
+ if (isDashboardReportScreenshot(location.search)) {
41
+ return <DashboardReportLayout>{children}</DashboardReportLayout>;
42
+ }
43
+
44
+ return <InteractiveLayout>{children}</InteractiveLayout>;
45
+ }
46
+
47
+ function DashboardReportLayout({ children }: LayoutProps) {
48
+ return (
49
+ <HeaderActionsProvider>
50
+ <main className="agent-native-app-main min-h-screen bg-background p-6 text-foreground md:p-8">
51
+ {children}
52
+ </main>
53
+ </HeaderActionsProvider>
54
+ );
55
+ }
56
+
57
+ function InteractiveLayout({ children }: LayoutProps) {
36
58
  useNavigationState();
37
59
  const location = useLocation();
38
60
  const navigate = useNavigate();
39
61
  const t = useT();
40
- const reportScreenshot =
41
- new URLSearchParams(location.search).get("reportScreenshot") === "1";
42
62
 
43
63
  // Analytics stages the active primary resource as composer context —
44
64
  // dashboards (`/dashboards/:id`, legacy `/adhoc/:id`) and ad-hoc analyses
@@ -102,12 +122,15 @@ export function Layout({ children }: LayoutProps) {
102
122
  const chatHomeHandoffActive = useAgentChatHomeHandoff({
103
123
  storageKey: ANALYTICS_CHAT_STORAGE_KEY,
104
124
  activePath: location.pathname,
105
- enabled: !isAskRoute && !reportScreenshot,
125
+ enabled: !isAskRoute,
106
126
  });
127
+ const chatHomeHandoffPending = isAgentChatHomeHandoffActive(
128
+ ANALYTICS_CHAT_STORAGE_KEY,
129
+ );
107
130
  useAgentChatHomeHandoffLinks({
108
131
  storageKey: ANALYTICS_CHAT_STORAGE_KEY,
109
132
  chatPath: "/ask",
110
- enabled: !reportScreenshot,
133
+ enabled: true,
111
134
  requireActiveHandoff: true,
112
135
  });
113
136
  useEffect(() => {
@@ -135,16 +158,6 @@ export function Layout({ children }: LayoutProps) {
135
158
  return <>{children}</>;
136
159
  }
137
160
 
138
- if (reportScreenshot) {
139
- return (
140
- <HeaderActionsProvider>
141
- <main className="agent-native-app-main min-h-screen bg-background p-6 text-foreground md:p-8">
142
- {children}
143
- </main>
144
- </HeaderActionsProvider>
145
- );
146
- }
147
-
148
161
  const contentFrame = (
149
162
  <div className="flex h-full flex-1 flex-col overflow-hidden">
150
163
  <MobileNav showNewChat={isAskRoute} />
@@ -195,6 +208,7 @@ export function Layout({ children }: LayoutProps) {
195
208
  position="right"
196
209
  defaultOpen={false}
197
210
  chatViewTransition
211
+ chatViewTransitionHandoff={chatHomeHandoffPending}
198
212
  storageKey={ANALYTICS_CHAT_STORAGE_KEY}
199
213
  browserTabId={TAB_ID}
200
214
  openOnChatRunning={chatHomeHandoffActive}
@@ -26,6 +26,7 @@ import {
26
26
  IconPlayerPlay,
27
27
  IconLayoutSidebarLeftCollapse,
28
28
  IconLayoutSidebarLeftExpand,
29
+ IconArrowUpRight,
29
30
  } from "@tabler/icons-react";
30
31
  import {
31
32
  useQuery,
@@ -94,8 +95,10 @@ import {
94
95
  useChangeVersions,
95
96
  } from "@agent-native/core/client/hooks";
96
97
  import { LanguagePicker, useT } from "@agent-native/core/client/i18n";
98
+ import { openCommandMenu } from "@agent-native/core/client/navigation";
97
99
  import { OrgSwitcher } from "@agent-native/core/client/org";
98
100
  import { FeedbackButton } from "@agent-native/core/client/ui";
101
+ import { SidebarFooterActions } from "@agent-native/toolkit/app-shell";
99
102
  import {
100
103
  ChatHistoryRail,
101
104
  type ChatHistoryItem,
@@ -184,6 +187,7 @@ const bottomItems = [
184
187
  icon: IconHierarchy2,
185
188
  labelKey: "settings.agentTitle",
186
189
  href: "/agent",
190
+ showExternalLinkIcon: true,
187
191
  },
188
192
  { icon: IconSettings, labelKey: "navigation.settings", href: "/settings" },
189
193
  ];
@@ -1263,7 +1267,13 @@ function persistedAnalyticsThreadId() {
1263
1267
  }
1264
1268
  }
1265
1269
 
1266
- function AnalyticsChatsSection({ isAskRoute }: { isAskRoute: boolean }) {
1270
+ function AnalyticsChatsSection({
1271
+ isAskRoute,
1272
+ open,
1273
+ }: {
1274
+ isAskRoute: boolean;
1275
+ open: boolean;
1276
+ }) {
1267
1277
  const navigate = useNavigate();
1268
1278
  const t = useT();
1269
1279
  const {
@@ -1365,57 +1375,63 @@ function AnalyticsChatsSection({ isAskRoute }: { isAskRoute: boolean }) {
1365
1375
  }
1366
1376
 
1367
1377
  return (
1368
- <div className="ms-4 min-w-0 space-y-0.5">
1369
- {chatsLoading &&
1370
- visibleThreads.length === 0 &&
1371
- Array.from({ length: 3 }).map((_, i) => (
1372
- <div
1373
- key={`chat-skeleton-${i}`}
1374
- className="flex items-center gap-2 px-3 py-1"
1375
- >
1376
- <Skeleton
1377
- className={cn(
1378
- "h-3.5 w-3.5 shrink-0 rounded-sm",
1379
- SIDEBAR_SKELETON_CLASS,
1380
- )}
1381
- />
1382
- <Skeleton
1383
- className={cn("h-3 rounded", SIDEBAR_SKELETON_CLASS)}
1384
- style={{ width: `${60 + ((i * 17) % 30)}%` }}
1385
- />
1386
- </div>
1387
- ))}
1388
- <ChatHistoryRail
1389
- items={chatItems}
1390
- activeId={displayedActiveThreadId}
1391
- onSelect={(threadId) => openThread(threadId)}
1392
- onNewChat={() => void handleNewChat()}
1393
- railLabels={{
1394
- newChat: t("chat.newChat"),
1395
- showMore: t("sidebar.showMore", {
1396
- count: Math.max(0, visibleThreads.length - SIDEBAR_PREVIEW_COUNT),
1397
- }),
1398
- showLess: t("sidebar.showLess"),
1399
- }}
1400
- renameMaxLength={160}
1401
- onTogglePin={(threadId) => {
1402
- const thread = visibleThreads.find((item) => item.id === threadId);
1403
- if (thread) void pinThread(threadId, !thread.pinnedAt);
1404
- }}
1405
- onRename={handleRenameThread}
1406
- onDelete={(threadId) => void handleArchiveThread(threadId)}
1407
- labels={{
1408
- options: (item) =>
1409
- t("chat.optionsFor", { title: item.titleText ?? "" }),
1410
- renameInput: (item) =>
1411
- t("chat.renameThread", { title: item.titleText ?? "" }),
1412
- rename: t("chat.renameChat"),
1413
- pin: t("chat.pinChat"),
1414
- unpin: t("chat.unpinChat"),
1415
- delete: t("chat.archiveChat"),
1416
- }}
1417
- className="min-w-0"
1418
- />
1378
+ <div
1379
+ className="an-chat-history-rail__collapse"
1380
+ data-state={open ? "open" : "closed"}
1381
+ aria-hidden={!open}
1382
+ >
1383
+ <div className="ms-4 min-w-0 space-y-0.5">
1384
+ {chatsLoading &&
1385
+ visibleThreads.length === 0 &&
1386
+ Array.from({ length: 3 }).map((_, i) => (
1387
+ <div
1388
+ key={`chat-skeleton-${i}`}
1389
+ className="flex items-center gap-2 px-3 py-1"
1390
+ >
1391
+ <Skeleton
1392
+ className={cn(
1393
+ "h-3.5 w-3.5 shrink-0 rounded-sm",
1394
+ SIDEBAR_SKELETON_CLASS,
1395
+ )}
1396
+ />
1397
+ <Skeleton
1398
+ className={cn("h-3 rounded", SIDEBAR_SKELETON_CLASS)}
1399
+ style={{ width: `${60 + ((i * 17) % 30)}%` }}
1400
+ />
1401
+ </div>
1402
+ ))}
1403
+ <ChatHistoryRail
1404
+ items={chatItems}
1405
+ activeId={displayedActiveThreadId}
1406
+ onSelect={(threadId) => openThread(threadId)}
1407
+ onNewChat={() => void handleNewChat()}
1408
+ railLabels={{
1409
+ newChat: t("chat.newChat"),
1410
+ showMore: t("sidebar.showMore", {
1411
+ count: Math.max(0, visibleThreads.length - SIDEBAR_PREVIEW_COUNT),
1412
+ }),
1413
+ showLess: t("sidebar.showLess"),
1414
+ }}
1415
+ renameMaxLength={160}
1416
+ onTogglePin={(threadId) => {
1417
+ const thread = visibleThreads.find((item) => item.id === threadId);
1418
+ if (thread) void pinThread(threadId, !thread.pinnedAt);
1419
+ }}
1420
+ onRename={handleRenameThread}
1421
+ onDelete={(threadId) => void handleArchiveThread(threadId)}
1422
+ labels={{
1423
+ options: (item) =>
1424
+ t("chat.optionsFor", { title: item.titleText ?? "" }),
1425
+ renameInput: (item) =>
1426
+ t("chat.renameThread", { title: item.titleText ?? "" }),
1427
+ rename: t("chat.renameChat"),
1428
+ pin: t("chat.pinChat"),
1429
+ unpin: t("chat.unpinChat"),
1430
+ delete: t("chat.archiveChat"),
1431
+ }}
1432
+ className="min-w-0"
1433
+ />
1434
+ </div>
1419
1435
  </div>
1420
1436
  );
1421
1437
  }
@@ -2096,6 +2112,63 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
2096
2112
  },
2097
2113
  ];
2098
2114
 
2115
+ const footerSearch = (
2116
+ <Tooltip>
2117
+ <TooltipTrigger asChild>
2118
+ <button
2119
+ type="button"
2120
+ onClick={openCommandMenu}
2121
+ aria-label={t("sidebar.search")}
2122
+ className="flex h-8 w-8 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-sidebar-accent/50 hover:text-foreground"
2123
+ >
2124
+ <IconSearch className="h-4 w-4" />
2125
+ </button>
2126
+ </TooltipTrigger>
2127
+ <TooltipContent side="top">
2128
+ {t("sidebar.searchShortcut", {
2129
+ shortcut: `${shortcutModifierLabel()}+K`,
2130
+ })}
2131
+ </TooltipContent>
2132
+ </Tooltip>
2133
+ );
2134
+ const footerTranslate = (
2135
+ <LanguagePicker variant="ghost-icon" label={t("settings.languageLabel")} />
2136
+ );
2137
+ const footerCollapse = !mobile ? (
2138
+ <Tooltip>
2139
+ <TooltipTrigger asChild>
2140
+ <button
2141
+ type="button"
2142
+ onClick={() => setSidebarCollapsed(!effectiveCollapsed)}
2143
+ aria-label={
2144
+ effectiveCollapsed
2145
+ ? t("sidebar.expandSidebar")
2146
+ : t("sidebar.collapseSidebar")
2147
+ }
2148
+ className="flex h-8 w-8 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-sidebar-accent/50 hover:text-foreground"
2149
+ >
2150
+ {effectiveCollapsed ? (
2151
+ <IconLayoutSidebarLeftExpand className="h-4 w-4 rtl:-scale-x-100" />
2152
+ ) : (
2153
+ <IconLayoutSidebarLeftCollapse className="h-4 w-4 rtl:-scale-x-100" />
2154
+ )}
2155
+ </button>
2156
+ </TooltipTrigger>
2157
+ <TooltipContent side="top">
2158
+ {effectiveCollapsed
2159
+ ? t("sidebar.expandSidebar")
2160
+ : t("sidebar.collapseSidebar")}
2161
+ </TooltipContent>
2162
+ </Tooltip>
2163
+ ) : null;
2164
+ const footerFeedback = (
2165
+ <FeedbackButton
2166
+ variant={effectiveCollapsed ? "icon" : "sidebar"}
2167
+ side="right"
2168
+ className={effectiveCollapsed ? "h-8 w-8" : "min-w-0"}
2169
+ />
2170
+ );
2171
+
2099
2172
  return (
2100
2173
  <div
2101
2174
  className="relative flex h-full min-w-0 flex-col overflow-hidden border-r border-border bg-sidebar text-sidebar-foreground transition-[width] duration-200 ease-out"
@@ -2111,24 +2184,6 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
2111
2184
  )}
2112
2185
  {effectiveCollapsed ? (
2113
2186
  <>
2114
- <div className="flex h-12 shrink-0 items-center justify-center border-b border-border px-1">
2115
- <Tooltip>
2116
- <TooltipTrigger asChild>
2117
- <button
2118
- type="button"
2119
- onClick={() => setSidebarCollapsed(false)}
2120
- aria-label={t("sidebar.expandSidebar")}
2121
- className="flex h-10 w-10 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-sidebar-accent/50 hover:text-foreground"
2122
- >
2123
- <IconLayoutSidebarLeftExpand className="h-4 w-4 rtl:-scale-x-100" />
2124
- </button>
2125
- </TooltipTrigger>
2126
- <TooltipContent side="right">
2127
- {t("sidebar.expandSidebar")}
2128
- </TooltipContent>
2129
- </Tooltip>
2130
- </div>
2131
-
2132
2187
  <nav className="flex min-h-0 flex-1 flex-col items-center gap-1 overflow-y-auto px-1 py-2">
2133
2188
  {collapsedNavItems.map((item) => {
2134
2189
  const Icon = item.icon;
@@ -2154,6 +2209,13 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
2154
2209
  );
2155
2210
  })}
2156
2211
  </nav>
2212
+ <SidebarFooterActions
2213
+ collapsed
2214
+ feedback={footerFeedback}
2215
+ translate={footerTranslate}
2216
+ search={footerSearch}
2217
+ collapse={footerCollapse}
2218
+ />
2157
2219
  </>
2158
2220
  ) : (
2159
2221
  <>
@@ -2178,23 +2240,6 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
2178
2240
  {t("navigation.brand")}
2179
2241
  </span>
2180
2242
  </Link>
2181
- {!mobile && (
2182
- <Tooltip>
2183
- <TooltipTrigger asChild>
2184
- <button
2185
- type="button"
2186
- onClick={() => setSidebarCollapsed(true)}
2187
- aria-label={t("sidebar.collapseSidebar")}
2188
- className="flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-sidebar-accent/50 hover:text-foreground"
2189
- >
2190
- <IconLayoutSidebarLeftCollapse className="h-4 w-4 rtl:-scale-x-100" />
2191
- </button>
2192
- </TooltipTrigger>
2193
- <TooltipContent side="right">
2194
- {t("sidebar.collapseSidebar")}
2195
- </TooltipContent>
2196
- </Tooltip>
2197
- )}
2198
2243
  </div>
2199
2244
  <div className="flex min-h-0 flex-1 flex-col overflow-y-auto overflow-x-hidden py-2">
2200
2245
  <nav className="grid min-w-0 items-start px-2 text-sm font-medium lg:px-4 space-y-1">
@@ -2248,7 +2293,9 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
2248
2293
  />
2249
2294
  </button>
2250
2295
  </div>
2251
- {askOpen && <AnalyticsChatsSection isAskRoute={isAskRoute} />}
2296
+ {askOpen && isAskRoute ? (
2297
+ <AnalyticsChatsSection isAskRoute open />
2298
+ ) : null}
2252
2299
  </div>
2253
2300
 
2254
2301
  {/* Sessions link */}
@@ -2525,7 +2572,15 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
2525
2572
  )}
2526
2573
  >
2527
2574
  <Icon className="h-4 w-4" />
2528
- {t(item.labelKey)}
2575
+ <span className="flex min-w-0 items-center gap-1">
2576
+ <span className="truncate">{t(item.labelKey)}</span>
2577
+ {item.showExternalLinkIcon && (
2578
+ <IconArrowUpRight
2579
+ aria-hidden="true"
2580
+ className="h-3.5 w-3.5 shrink-0 text-muted-foreground/70"
2581
+ />
2582
+ )}
2583
+ </span>
2529
2584
  </Link>
2530
2585
  );
2531
2586
  })}
@@ -2533,42 +2588,15 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
2533
2588
 
2534
2589
  <div className="space-y-2 pt-2">
2535
2590
  <OrgSwitcher />
2591
+ <DevDatabaseLink />
2536
2592
  <TooltipProvider delayDuration={200}>
2537
- <div className="flex items-center justify-end gap-1">
2538
- <DevDatabaseLink />
2539
- <FeedbackButton className="min-w-0 flex-1" />
2540
- <div className="flex shrink-0 items-center gap-0.5">
2541
- <Tooltip>
2542
- <TooltipTrigger asChild>
2543
- <button
2544
- onClick={() =>
2545
- window.dispatchEvent(
2546
- new CustomEvent(
2547
- "analytics:open-command-palette",
2548
- ),
2549
- )
2550
- }
2551
- aria-label={t("sidebar.search")}
2552
- className="flex items-center justify-center rounded-lg p-2 text-muted-foreground transition-colors hover:text-primary cursor-pointer hover:bg-sidebar-accent/50"
2553
- >
2554
- <IconSearch className="h-4 w-4" />
2555
- </button>
2556
- </TooltipTrigger>
2557
- <TooltipContent side="top">
2558
- <p>
2559
- {t("sidebar.searchShortcut", {
2560
- shortcut: `${shortcutModifierLabel()}+K`,
2561
- })}
2562
- </p>
2563
- </TooltipContent>
2564
- </Tooltip>
2565
- <LanguagePicker
2566
- variant="icon"
2567
- label={t("settings.languageLabel")}
2568
- className="[&_[data-language-picker-trigger]]:rounded-lg [&_[data-language-picker-trigger]]:border-0 [&_[data-language-picker-trigger]]:bg-transparent [&_[data-language-picker-trigger]]:text-muted-foreground [&_[data-language-picker-trigger]]:hover:bg-sidebar-accent/50 [&_[data-language-picker-trigger]]:hover:text-primary"
2569
- />
2570
- </div>
2571
- </div>
2593
+ <SidebarFooterActions
2594
+ feedback={footerFeedback}
2595
+ translate={footerTranslate}
2596
+ search={footerSearch}
2597
+ collapse={footerCollapse}
2598
+ className="px-0 py-0"
2599
+ />
2572
2600
  </TooltipProvider>
2573
2601
  </div>
2574
2602
  </div>