@agent-native/core 0.69.0 → 0.70.0

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 (200) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +48 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/changelog/parse.ts +245 -0
  5. package/corpus/core/src/cli/changelog.ts +199 -0
  6. package/corpus/core/src/cli/index.ts +19 -0
  7. package/corpus/core/src/cli/recap.ts +24 -1
  8. package/corpus/core/src/cli/skills.ts +72 -45
  9. package/corpus/core/src/client/CommandMenu.tsx +183 -75
  10. package/corpus/core/src/client/agent-chat-adapter.ts +44 -7
  11. package/corpus/core/src/client/analytics.ts +181 -0
  12. package/corpus/core/src/client/changelog/Changelog.tsx +321 -0
  13. package/corpus/core/src/client/index.ts +11 -0
  14. package/corpus/core/src/client/mcp-apps/McpAppRenderer.tsx +54 -0
  15. package/corpus/core/src/client/settings/useBuilderStatus.ts +82 -20
  16. package/corpus/core/src/mcp/build-server.ts +1 -1
  17. package/corpus/core/src/mcp/embed-app.ts +112 -6
  18. package/corpus/core/src/server/attribution.ts +211 -0
  19. package/corpus/core/src/server/auth.ts +6 -0
  20. package/corpus/core/src/server/better-auth-instance.ts +49 -5
  21. package/corpus/core/src/server/builder-browser.ts +27 -1
  22. package/corpus/core/src/server/core-routes-plugin.ts +58 -0
  23. package/corpus/core/src/server/google-oauth.ts +19 -6
  24. package/corpus/core/src/shared/mcp-embed-headers.ts +1 -1
  25. package/corpus/core/src/styles/agent-conversation.css +21 -0
  26. package/corpus/core/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
  27. package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
  28. package/corpus/templates/analytics/CHANGELOG.md +10 -0
  29. package/corpus/templates/analytics/actions/install-dashboard-template.ts +2 -2
  30. package/corpus/templates/analytics/actions/open-traffic-dashboard.ts +1 -1
  31. package/corpus/templates/analytics/actions/update-dashboard.ts +5 -3
  32. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +180 -144
  33. package/corpus/templates/analytics/app/components/layout/Header.tsx +2 -2
  34. package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -5
  35. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +221 -213
  36. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +6 -3
  37. package/corpus/templates/analytics/app/lib/demo-dashboard-path.ts +1 -1
  38. package/corpus/templates/analytics/app/lib/last-opened.ts +2 -1
  39. package/corpus/templates/analytics/app/pages/Settings.tsx +4 -0
  40. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +3 -3
  41. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +2 -2
  42. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +101 -99
  43. package/corpus/templates/analytics/app/pages/overview/OverviewPage.tsx +1 -1
  44. package/corpus/templates/analytics/app/routes/adhoc.$id.tsx +18 -5
  45. package/corpus/templates/analytics/app/routes/catalog.tsx +1 -1
  46. package/corpus/templates/analytics/app/routes/dashboards.$id.tsx +9 -0
  47. package/corpus/templates/analytics/app/routes/traffic.tsx +1 -1
  48. package/corpus/templates/analytics/changelog/2026-06-23-the-dashboards-and-analyses-sidebar-settings-buttons-now-sta.md +6 -0
  49. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +145 -0
  50. package/corpus/templates/analytics/server/db/index.ts +1 -1
  51. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +9 -2
  52. package/corpus/templates/analytics/server/lib/demo-dashboards.ts +1 -1
  53. package/corpus/templates/analytics/server/plugins/agent-chat.ts +2 -2
  54. package/corpus/templates/analytics/server/plugins/core-routes.ts +6 -6
  55. package/corpus/templates/assets/CHANGELOG.md +10 -0
  56. package/corpus/templates/assets/app/root.tsx +7 -1
  57. package/corpus/templates/assets/app/routes/settings.tsx +6 -0
  58. package/corpus/templates/brain/CHANGELOG.md +10 -0
  59. package/corpus/templates/brain/app/root.tsx +7 -1
  60. package/corpus/templates/brain/app/routes/settings.tsx +8 -1
  61. package/corpus/templates/calendar/CHANGELOG.md +10 -0
  62. package/corpus/templates/calendar/app/pages/Settings.tsx +4 -0
  63. package/corpus/templates/calendar/app/root.tsx +7 -1
  64. package/corpus/templates/chat/CHANGELOG.md +10 -0
  65. package/corpus/templates/chat/app/root.tsx +7 -1
  66. package/corpus/templates/clips/CHANGELOG.md +10 -0
  67. package/corpus/templates/clips/app/components/player/share-dialog.tsx +33 -7
  68. package/corpus/templates/clips/app/components/player/sign-in-prompt-dialog.tsx +8 -0
  69. package/corpus/templates/clips/app/components/player/video-player.tsx +150 -20
  70. package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +7 -11
  71. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +31 -0
  72. package/corpus/templates/clips/app/components/sharing/slack-share-hint.tsx +71 -0
  73. package/corpus/templates/clips/app/root.tsx +7 -1
  74. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +15 -1
  75. package/corpus/templates/clips/app/routes/record.tsx +78 -5
  76. package/corpus/templates/clips/app/routes/share.$shareId.tsx +86 -5
  77. package/corpus/templates/clips/changelog/2026-06-23-clips-shared-in-slack-no-longer-show-a-could-not-start-playb.md +6 -0
  78. package/corpus/templates/clips/changelog/2026-06-23-made-the-play-button-on-shared-and-embedded-clips-scale-with.md +6 -0
  79. package/corpus/templates/clips/changelog/2026-06-23-public-clip-share-links-now-show-whether-they-ll-play-inline.md +6 -0
  80. package/corpus/templates/clips/changelog/2026-06-23-screen-camera-recordings-now-keep-the-presenter-s-face-in-th.md +6 -0
  81. package/corpus/templates/clips/desktop/src/lib/recorder.ts +20 -0
  82. package/corpus/templates/clips/desktop/src/main.tsx +3 -0
  83. package/corpus/templates/clips/desktop/src/overlays/region-record-border.tsx +76 -0
  84. package/corpus/templates/clips/desktop/src/styles.css +49 -0
  85. package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +2 -1
  86. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +67 -1
  87. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -0
  88. package/corpus/templates/clips/desktop/src-tauri/src/util.rs +4 -1
  89. package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +51 -1
  90. package/corpus/templates/clips/shared/share-attribution.ts +79 -0
  91. package/corpus/templates/content/CHANGELOG.md +10 -0
  92. package/corpus/templates/content/app/root.tsx +7 -1
  93. package/corpus/templates/design/CHANGELOG.md +10 -0
  94. package/corpus/templates/design/actions/generate-design.ts +4 -0
  95. package/corpus/templates/design/app/root.tsx +7 -1
  96. package/corpus/templates/design/app/routes/settings.tsx +10 -2
  97. package/corpus/templates/dispatch/CHANGELOG.md +10 -0
  98. package/corpus/templates/dispatch/app/root.tsx +7 -1
  99. package/corpus/templates/forms/CHANGELOG.md +10 -0
  100. package/corpus/templates/forms/app/root.tsx +7 -1
  101. package/corpus/templates/macros/CHANGELOG.md +10 -0
  102. package/corpus/templates/macros/app/root.tsx +7 -1
  103. package/corpus/templates/mail/CHANGELOG.md +10 -0
  104. package/corpus/templates/mail/app/components/layout/CommandPalette.tsx +3 -0
  105. package/corpus/templates/mail/app/pages/SettingsPage.tsx +27 -0
  106. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +31 -17
  107. package/corpus/templates/plan/.agents/skills/visual-plan/references/wireframe.md +7 -4
  108. package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +34 -24
  109. package/corpus/templates/plan/.agents/skills/visual-recap/references/wireframe.md +7 -4
  110. package/corpus/templates/plan/AGENTS.md +4 -0
  111. package/corpus/templates/plan/CHANGELOG.md +10 -0
  112. package/corpus/templates/plan/actions/view-screen.ts +5 -0
  113. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +98 -1
  114. package/corpus/templates/plan/app/pages/PlansPage.tsx +107 -7
  115. package/corpus/templates/plan/app/root.tsx +7 -1
  116. package/corpus/templates/plan/shared/share-attribution.ts +72 -0
  117. package/corpus/templates/slides/CHANGELOG.md +10 -0
  118. package/corpus/templates/slides/app/root.tsx +7 -1
  119. package/corpus/templates/videos/CHANGELOG.md +4 -151
  120. package/corpus/templates/videos/app/root.tsx +7 -1
  121. package/dist/changelog/parse.d.ts +70 -0
  122. package/dist/changelog/parse.d.ts.map +1 -0
  123. package/dist/changelog/parse.js +200 -0
  124. package/dist/changelog/parse.js.map +1 -0
  125. package/dist/cli/changelog.d.ts +4 -0
  126. package/dist/cli/changelog.d.ts.map +1 -0
  127. package/dist/cli/changelog.js +166 -0
  128. package/dist/cli/changelog.js.map +1 -0
  129. package/dist/cli/index.js +18 -0
  130. package/dist/cli/index.js.map +1 -1
  131. package/dist/cli/recap.d.ts.map +1 -1
  132. package/dist/cli/recap.js +22 -1
  133. package/dist/cli/recap.js.map +1 -1
  134. package/dist/cli/skills.d.ts +3 -3
  135. package/dist/cli/skills.d.ts.map +1 -1
  136. package/dist/cli/skills.js +72 -45
  137. package/dist/cli/skills.js.map +1 -1
  138. package/dist/client/CommandMenu.d.ts +17 -1
  139. package/dist/client/CommandMenu.d.ts.map +1 -1
  140. package/dist/client/CommandMenu.js +49 -13
  141. package/dist/client/CommandMenu.js.map +1 -1
  142. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  143. package/dist/client/agent-chat-adapter.js +43 -6
  144. package/dist/client/agent-chat-adapter.js.map +1 -1
  145. package/dist/client/analytics.d.ts +18 -0
  146. package/dist/client/analytics.d.ts.map +1 -1
  147. package/dist/client/analytics.js +177 -0
  148. package/dist/client/analytics.js.map +1 -1
  149. package/dist/client/changelog/Changelog.d.ts +47 -0
  150. package/dist/client/changelog/Changelog.d.ts.map +1 -0
  151. package/dist/client/changelog/Changelog.js +138 -0
  152. package/dist/client/changelog/Changelog.js.map +1 -0
  153. package/dist/client/index.d.ts +2 -1
  154. package/dist/client/index.d.ts.map +1 -1
  155. package/dist/client/index.js +2 -1
  156. package/dist/client/index.js.map +1 -1
  157. package/dist/client/mcp-apps/McpAppRenderer.d.ts +1 -0
  158. package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -1
  159. package/dist/client/mcp-apps/McpAppRenderer.js +42 -1
  160. package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -1
  161. package/dist/client/settings/useBuilderStatus.d.ts +2 -0
  162. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  163. package/dist/client/settings/useBuilderStatus.js +58 -10
  164. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  165. package/dist/mcp/build-server.js +1 -1
  166. package/dist/mcp/build-server.js.map +1 -1
  167. package/dist/mcp/embed-app.d.ts.map +1 -1
  168. package/dist/mcp/embed-app.js +112 -6
  169. package/dist/mcp/embed-app.js.map +1 -1
  170. package/dist/server/attribution.d.ts +83 -0
  171. package/dist/server/attribution.d.ts.map +1 -0
  172. package/dist/server/attribution.js +178 -0
  173. package/dist/server/attribution.js.map +1 -0
  174. package/dist/server/auth.d.ts.map +1 -1
  175. package/dist/server/auth.js +7 -0
  176. package/dist/server/auth.js.map +1 -1
  177. package/dist/server/better-auth-instance.d.ts +9 -1
  178. package/dist/server/better-auth-instance.d.ts.map +1 -1
  179. package/dist/server/better-auth-instance.js +32 -2
  180. package/dist/server/better-auth-instance.js.map +1 -1
  181. package/dist/server/builder-browser.d.ts +4 -0
  182. package/dist/server/builder-browser.d.ts.map +1 -1
  183. package/dist/server/builder-browser.js +20 -1
  184. package/dist/server/builder-browser.js.map +1 -1
  185. package/dist/server/core-routes-plugin.d.ts +25 -0
  186. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  187. package/dist/server/core-routes-plugin.js +38 -0
  188. package/dist/server/core-routes-plugin.js.map +1 -1
  189. package/dist/server/google-oauth.d.ts.map +1 -1
  190. package/dist/server/google-oauth.js +16 -2
  191. package/dist/server/google-oauth.js.map +1 -1
  192. package/dist/shared/mcp-embed-headers.js +1 -1
  193. package/dist/shared/mcp-embed-headers.js.map +1 -1
  194. package/dist/styles/agent-conversation.css +21 -0
  195. package/dist/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
  196. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
  197. package/package.json +1 -1
  198. package/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
  199. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
  200. /package/corpus/templates/analytics/app/routes/{dashboards.tsx → dashboards._index.tsx} +0 -0
@@ -236,7 +236,7 @@ function SidebarSectionSettingsPopover({
236
236
  <PopoverTrigger asChild>
237
237
  <button
238
238
  type="button"
239
- className="flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/65 transition-all hover:bg-sidebar-accent hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring"
239
+ className="flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/65 opacity-0 transition-all hover:bg-sidebar-accent hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring group-hover/section:opacity-100 data-[state=open]:opacity-100"
240
240
  aria-label={`${label} settings`}
241
241
  >
242
242
  <IconSettings className="h-3.5 w-3.5" />
@@ -734,7 +734,7 @@ function SortableDashboardItem({
734
734
  visibility: Visibility,
735
735
  ) => Promise<void>;
736
736
  }) {
737
- const href = `/adhoc/${d.id}`;
737
+ const href = `/dashboards/${d.id}`;
738
738
  const { mutateAsync: deleteView } = useDeleteDashboardView();
739
739
  const [deletingViewId, setDeletingViewId] = useState<string | null>(null);
740
740
 
@@ -1337,7 +1337,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
1337
1337
  );
1338
1338
 
1339
1339
  const activeDashboardId = useMemo(() => {
1340
- const match = location.pathname.match(/^\/adhoc\/([^/]+)/);
1340
+ const match = location.pathname.match(/^\/(?:adhoc|dashboards)\/([^/]+)/);
1341
1341
  if (!match?.[1]) return null;
1342
1342
  return new URLSearchParams(location.search).get("id") || match[1];
1343
1343
  }, [location.pathname, location.search]);
@@ -1830,7 +1830,9 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
1830
1830
  [sidebarWidth],
1831
1831
  );
1832
1832
 
1833
- const isAdhocActive = location.pathname.startsWith("/adhoc");
1833
+ const isAdhocActive =
1834
+ location.pathname.startsWith("/adhoc") ||
1835
+ location.pathname.startsWith("/dashboards");
1834
1836
 
1835
1837
  return (
1836
1838
  <div
@@ -1945,227 +1947,233 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
1945
1947
  </Link>
1946
1948
 
1947
1949
  {/* Dashboards section */}
1948
- <div
1949
- className={cn(
1950
- "group/section flex w-full min-w-0 items-center rounded-lg transition-all hover:text-primary",
1951
- isAdhocActive
1952
- ? "text-sidebar-accent-foreground"
1953
- : "text-muted-foreground hover:bg-sidebar-accent/50",
1954
- )}
1955
- >
1956
- <button
1957
- type="button"
1958
- onClick={toggleDashOpen}
1959
- className="flex min-w-0 flex-1 items-center gap-3 px-3 py-2 text-left"
1960
- aria-expanded={dashOpen}
1961
- >
1962
- <IconChartBar className="h-4 w-4 shrink-0" />
1963
- <span className="min-w-0 flex-1 truncate">Dashboards</span>
1964
- </button>
1965
- <SidebarSectionSettingsPopover
1966
- label="Dashboards"
1967
- sortMode={dashboardSortMode}
1968
- onSortModeChange={setDashboardSortMode}
1969
- sharedOnly={dashFilter === "org"}
1970
- onSharedOnlyChange={(checked) =>
1971
- setDashFilter(checked ? "org" : "all")
1972
- }
1973
- />
1974
- <button
1975
- type="button"
1976
- onClick={toggleDashOpen}
1977
- className="mr-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/70 hover:bg-sidebar-accent hover:text-foreground"
1978
- aria-label={
1979
- dashOpen ? "Collapse dashboards" : "Expand dashboards"
1980
- }
1950
+ <div className="group/section space-y-1">
1951
+ <div
1952
+ className={cn(
1953
+ "flex w-full min-w-0 items-center rounded-lg transition-all hover:text-primary",
1954
+ isAdhocActive
1955
+ ? "text-sidebar-accent-foreground"
1956
+ : "text-muted-foreground hover:bg-sidebar-accent/50",
1957
+ )}
1981
1958
  >
1982
- <IconChevronDown
1983
- className={cn(
1984
- "h-3.5 w-3.5 shrink-0 transition-transform",
1985
- !dashOpen && "-rotate-90",
1986
- )}
1959
+ <button
1960
+ type="button"
1961
+ onClick={toggleDashOpen}
1962
+ className="flex min-w-0 flex-1 items-center gap-3 px-3 py-2 text-left"
1963
+ aria-expanded={dashOpen}
1964
+ >
1965
+ <IconChartBar className="h-4 w-4 shrink-0" />
1966
+ <span className="min-w-0 flex-1 truncate">Dashboards</span>
1967
+ </button>
1968
+ <SidebarSectionSettingsPopover
1969
+ label="Dashboards"
1970
+ sortMode={dashboardSortMode}
1971
+ onSortModeChange={setDashboardSortMode}
1972
+ sharedOnly={dashFilter === "org"}
1973
+ onSharedOnlyChange={(checked) =>
1974
+ setDashFilter(checked ? "org" : "all")
1975
+ }
1987
1976
  />
1988
- </button>
1989
- </div>
1990
-
1991
- {dashOpen && (
1992
- <DndContext
1993
- sensors={sensors}
1994
- collisionDetection={closestCenter}
1995
- onDragEnd={handleDashboardDragEnd}
1996
- >
1997
- <SortableContext
1998
- items={displayedDashboards.map((d) => d.id)}
1999
- strategy={verticalListSortingStrategy}
1977
+ <button
1978
+ type="button"
1979
+ onClick={toggleDashOpen}
1980
+ className="mr-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/70 hover:bg-sidebar-accent hover:text-foreground"
1981
+ aria-label={
1982
+ dashOpen ? "Collapse dashboards" : "Expand dashboards"
1983
+ }
2000
1984
  >
2001
- <div className="ml-4 min-w-0 space-y-0.5">
2002
- {displayedDashboards.map((d) => (
2003
- <SortableDashboardItem
2004
- key={d.id}
2005
- d={d}
2006
- isActive={activeDashboardId === d.id}
2007
- location={location}
2008
- favoriteIds={favoriteIds}
2009
- onToggleFavorite={toggleFavorite}
2010
- onDelete={handleDashboardDelete}
2011
- onRename={handleDashboardRename}
2012
- onArchive={handleDashboardArchive}
2013
- onSetVisibility={handleDashboardSetVisibility}
2014
- onPrefetch={prefetchDashboard}
2015
- views={allViewsMap[d.id]}
2016
- />
2017
- ))}
2018
- {filteredDashboards.length > SIDEBAR_PREVIEW_COUNT && (
2019
- <button
2020
- onClick={() => setDashShowAll(!dashShowAll)}
2021
- className="flex items-center gap-1 px-3 py-1 text-[11px] text-muted-foreground/70 hover:text-primary"
2022
- >
2023
- {dashShowAll
2024
- ? "Show less"
2025
- : `Show ${filteredDashboards.length - SIDEBAR_PREVIEW_COUNT} more`}
2026
- </button>
1985
+ <IconChevronDown
1986
+ className={cn(
1987
+ "h-3.5 w-3.5 shrink-0 transition-transform",
1988
+ !dashOpen && "-rotate-90",
2027
1989
  )}
2028
- {sqlDashboardsLoading &&
2029
- sqlDashboards.length === 0 &&
2030
- Array.from({ length: 3 }).map((_, i) => (
2031
- <div
2032
- key={`sql-skeleton-${i}`}
2033
- className="flex items-center gap-2 px-3 py-1"
2034
- >
2035
- <Skeleton className="h-3.5 w-3.5 shrink-0 rounded-sm" />
2036
- <Skeleton
2037
- className="h-3 rounded"
2038
- style={{ width: `${60 + ((i * 17) % 30)}%` }}
2039
- />
2040
- </div>
2041
- ))}
2042
- <NewDashboardDialog />
2043
- </div>
2044
- </SortableContext>
2045
- </DndContext>
2046
- )}
1990
+ />
1991
+ </button>
1992
+ </div>
2047
1993
 
2048
- {/* Analyses section */}
2049
- <div
2050
- className={cn(
2051
- "group/section flex w-full min-w-0 items-center rounded-lg transition-all hover:text-primary",
2052
- location.pathname.startsWith("/analyses")
2053
- ? "text-sidebar-accent-foreground"
2054
- : "text-muted-foreground hover:bg-sidebar-accent/50",
1994
+ {dashOpen && (
1995
+ <DndContext
1996
+ sensors={sensors}
1997
+ collisionDetection={closestCenter}
1998
+ onDragEnd={handleDashboardDragEnd}
1999
+ >
2000
+ <SortableContext
2001
+ items={displayedDashboards.map((d) => d.id)}
2002
+ strategy={verticalListSortingStrategy}
2003
+ >
2004
+ <div className="ml-4 min-w-0 space-y-0.5">
2005
+ {displayedDashboards.map((d) => (
2006
+ <SortableDashboardItem
2007
+ key={d.id}
2008
+ d={d}
2009
+ isActive={activeDashboardId === d.id}
2010
+ location={location}
2011
+ favoriteIds={favoriteIds}
2012
+ onToggleFavorite={toggleFavorite}
2013
+ onDelete={handleDashboardDelete}
2014
+ onRename={handleDashboardRename}
2015
+ onArchive={handleDashboardArchive}
2016
+ onSetVisibility={handleDashboardSetVisibility}
2017
+ onPrefetch={prefetchDashboard}
2018
+ views={allViewsMap[d.id]}
2019
+ />
2020
+ ))}
2021
+ {filteredDashboards.length > SIDEBAR_PREVIEW_COUNT && (
2022
+ <button
2023
+ onClick={() => setDashShowAll(!dashShowAll)}
2024
+ className="flex items-center gap-1 px-3 py-1 text-[11px] text-muted-foreground/70 hover:text-primary"
2025
+ >
2026
+ {dashShowAll
2027
+ ? "Show less"
2028
+ : `Show ${filteredDashboards.length - SIDEBAR_PREVIEW_COUNT} more`}
2029
+ </button>
2030
+ )}
2031
+ {sqlDashboardsLoading &&
2032
+ sqlDashboards.length === 0 &&
2033
+ Array.from({ length: 3 }).map((_, i) => (
2034
+ <div
2035
+ key={`sql-skeleton-${i}`}
2036
+ className="flex items-center gap-2 px-3 py-1"
2037
+ >
2038
+ <Skeleton className="h-3.5 w-3.5 shrink-0 rounded-sm" />
2039
+ <Skeleton
2040
+ className="h-3 rounded"
2041
+ style={{ width: `${60 + ((i * 17) % 30)}%` }}
2042
+ />
2043
+ </div>
2044
+ ))}
2045
+ <NewDashboardDialog />
2046
+ </div>
2047
+ </SortableContext>
2048
+ </DndContext>
2055
2049
  )}
2056
- >
2057
- <button
2058
- type="button"
2059
- onClick={toggleAnalysesOpen}
2060
- className="flex min-w-0 flex-1 items-center gap-3 px-3 py-2 text-left"
2061
- aria-expanded={analysesOpen}
2062
- >
2063
- <IconReportAnalytics className="h-4 w-4 shrink-0" />
2064
- <span className="min-w-0 flex-1 truncate">Analyses</span>
2065
- </button>
2066
- <SidebarSectionSettingsPopover
2067
- label="Analyses"
2068
- sortMode={analysisSortMode}
2069
- onSortModeChange={setAnalysisSortMode}
2070
- sharedOnly={analysisFilter === "org"}
2071
- onSharedOnlyChange={(checked) =>
2072
- setAnalysisFilter(checked ? "org" : "all")
2073
- }
2074
- showHidden={analysisHiddenFilter === "hidden"}
2075
- onShowHiddenChange={(checked) =>
2076
- setAnalysisHiddenFilter(checked ? "hidden" : "visible")
2077
- }
2078
- />
2079
- <button
2080
- type="button"
2081
- onClick={toggleAnalysesOpen}
2082
- className="mr-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/70 hover:bg-sidebar-accent hover:text-foreground"
2083
- aria-label={
2084
- analysesOpen ? "Collapse analyses" : "Expand analyses"
2085
- }
2086
- >
2087
- <IconChevronDown
2088
- className={cn(
2089
- "h-3.5 w-3.5 shrink-0 transition-transform",
2090
- !analysesOpen && "-rotate-90",
2091
- )}
2092
- />
2093
- </button>
2094
2050
  </div>
2095
2051
 
2096
- {analysesOpen && (
2097
- <DndContext
2098
- sensors={sensors}
2099
- collisionDetection={closestCenter}
2100
- onDragEnd={handleAnalysisDragEnd}
2052
+ {/* Analyses section */}
2053
+ <div className="group/section space-y-1">
2054
+ <div
2055
+ className={cn(
2056
+ "flex w-full min-w-0 items-center rounded-lg transition-all hover:text-primary",
2057
+ location.pathname.startsWith("/analyses")
2058
+ ? "text-sidebar-accent-foreground"
2059
+ : "text-muted-foreground hover:bg-sidebar-accent/50",
2060
+ )}
2101
2061
  >
2102
- <SortableContext
2103
- items={displayedAnalyses.map((a) => a.id)}
2104
- strategy={verticalListSortingStrategy}
2062
+ <button
2063
+ type="button"
2064
+ onClick={toggleAnalysesOpen}
2065
+ className="flex min-w-0 flex-1 items-center gap-3 px-3 py-2 text-left"
2066
+ aria-expanded={analysesOpen}
2105
2067
  >
2106
- <div className="ml-4 min-w-0 space-y-0.5">
2107
- {displayedAnalyses.map((a) => (
2108
- <SortableRow
2109
- key={a.id}
2110
- id={a.id}
2111
- favoriteKey={`analysis:${a.id}`}
2112
- name={a.name}
2113
- href={`/analyses/${a.id}`}
2114
- isActive={location.pathname === `/analyses/${a.id}`}
2115
- favoriteIds={favoriteIds}
2116
- onToggleFavorite={toggleFavorite}
2117
- onDelete={() => handleAnalysisDelete(a)}
2118
- onRename={(name) => handleAnalysisRename(a, name)}
2119
- hidden={analysisHiddenFilter === "hidden"}
2120
- onHide={
2121
- analysisHiddenFilter === "hidden"
2122
- ? undefined
2123
- : () => handleAnalysisHide(a)
2124
- }
2125
- onUnhide={
2126
- analysisHiddenFilter === "hidden"
2127
- ? () => handleAnalysisUnhide(a)
2128
- : undefined
2129
- }
2130
- visibility={a.visibility}
2131
- onSetVisibility={(v) => handleAnalysisSetVisibility(a, v)}
2132
- onPrefetch={() => prefetchAnalysis(a.id)}
2133
- />
2134
- ))}
2135
- {filteredAnalyses.length > SIDEBAR_PREVIEW_COUNT && (
2136
- <button
2137
- onClick={() => setAnalysesShowAll(!analysesShowAll)}
2138
- className="flex items-center gap-1 px-3 py-1 text-[11px] text-muted-foreground/70 hover:text-primary"
2139
- >
2140
- {analysesShowAll
2141
- ? "Show less"
2142
- : `Show ${filteredAnalyses.length - SIDEBAR_PREVIEW_COUNT} more`}
2143
- </button>
2068
+ <IconReportAnalytics className="h-4 w-4 shrink-0" />
2069
+ <span className="min-w-0 flex-1 truncate">Analyses</span>
2070
+ </button>
2071
+ <SidebarSectionSettingsPopover
2072
+ label="Analyses"
2073
+ sortMode={analysisSortMode}
2074
+ onSortModeChange={setAnalysisSortMode}
2075
+ sharedOnly={analysisFilter === "org"}
2076
+ onSharedOnlyChange={(checked) =>
2077
+ setAnalysisFilter(checked ? "org" : "all")
2078
+ }
2079
+ showHidden={analysisHiddenFilter === "hidden"}
2080
+ onShowHiddenChange={(checked) =>
2081
+ setAnalysisHiddenFilter(checked ? "hidden" : "visible")
2082
+ }
2083
+ />
2084
+ <button
2085
+ type="button"
2086
+ onClick={toggleAnalysesOpen}
2087
+ className="mr-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/70 hover:bg-sidebar-accent hover:text-foreground"
2088
+ aria-label={
2089
+ analysesOpen ? "Collapse analyses" : "Expand analyses"
2090
+ }
2091
+ >
2092
+ <IconChevronDown
2093
+ className={cn(
2094
+ "h-3.5 w-3.5 shrink-0 transition-transform",
2095
+ !analysesOpen && "-rotate-90",
2144
2096
  )}
2145
- {analysesLoading &&
2146
- sortedAnalyses.length === 0 &&
2147
- Array.from({ length: 3 }).map((_, i) => (
2148
- <div
2149
- key={`analysis-skeleton-${i}`}
2150
- className="flex items-center gap-2 px-3 py-1"
2151
- >
2152
- <Skeleton className="h-3.5 w-3.5 shrink-0 rounded-sm" />
2153
- <Skeleton
2154
- className="h-3 rounded"
2155
- style={{ width: `${60 + ((i * 17) % 30)}%` }}
2156
- />
2157
- </div>
2097
+ />
2098
+ </button>
2099
+ </div>
2100
+
2101
+ {analysesOpen && (
2102
+ <DndContext
2103
+ sensors={sensors}
2104
+ collisionDetection={closestCenter}
2105
+ onDragEnd={handleAnalysisDragEnd}
2106
+ >
2107
+ <SortableContext
2108
+ items={displayedAnalyses.map((a) => a.id)}
2109
+ strategy={verticalListSortingStrategy}
2110
+ >
2111
+ <div className="ml-4 min-w-0 space-y-0.5">
2112
+ {displayedAnalyses.map((a) => (
2113
+ <SortableRow
2114
+ key={a.id}
2115
+ id={a.id}
2116
+ favoriteKey={`analysis:${a.id}`}
2117
+ name={a.name}
2118
+ href={`/analyses/${a.id}`}
2119
+ isActive={location.pathname === `/analyses/${a.id}`}
2120
+ favoriteIds={favoriteIds}
2121
+ onToggleFavorite={toggleFavorite}
2122
+ onDelete={() => handleAnalysisDelete(a)}
2123
+ onRename={(name) => handleAnalysisRename(a, name)}
2124
+ hidden={analysisHiddenFilter === "hidden"}
2125
+ onHide={
2126
+ analysisHiddenFilter === "hidden"
2127
+ ? undefined
2128
+ : () => handleAnalysisHide(a)
2129
+ }
2130
+ onUnhide={
2131
+ analysisHiddenFilter === "hidden"
2132
+ ? () => handleAnalysisUnhide(a)
2133
+ : undefined
2134
+ }
2135
+ visibility={a.visibility}
2136
+ onSetVisibility={(v) =>
2137
+ handleAnalysisSetVisibility(a, v)
2138
+ }
2139
+ onPrefetch={() => prefetchAnalysis(a.id)}
2140
+ />
2158
2141
  ))}
2159
- {!analysesLoading && sortedAnalyses.length === 0 && (
2160
- <p className="px-3 py-1 text-[11px] text-muted-foreground/60">
2161
- No analyses yet
2162
- </p>
2163
- )}
2164
- <NewAnalysisDialog />
2165
- </div>
2166
- </SortableContext>
2167
- </DndContext>
2168
- )}
2142
+ {filteredAnalyses.length > SIDEBAR_PREVIEW_COUNT && (
2143
+ <button
2144
+ onClick={() => setAnalysesShowAll(!analysesShowAll)}
2145
+ className="flex items-center gap-1 px-3 py-1 text-[11px] text-muted-foreground/70 hover:text-primary"
2146
+ >
2147
+ {analysesShowAll
2148
+ ? "Show less"
2149
+ : `Show ${filteredAnalyses.length - SIDEBAR_PREVIEW_COUNT} more`}
2150
+ </button>
2151
+ )}
2152
+ {analysesLoading &&
2153
+ sortedAnalyses.length === 0 &&
2154
+ Array.from({ length: 3 }).map((_, i) => (
2155
+ <div
2156
+ key={`analysis-skeleton-${i}`}
2157
+ className="flex items-center gap-2 px-3 py-1"
2158
+ >
2159
+ <Skeleton className="h-3.5 w-3.5 shrink-0 rounded-sm" />
2160
+ <Skeleton
2161
+ className="h-3 rounded"
2162
+ style={{ width: `${60 + ((i * 17) % 30)}%` }}
2163
+ />
2164
+ </div>
2165
+ ))}
2166
+ {!analysesLoading && sortedAnalyses.length === 0 && (
2167
+ <p className="px-3 py-1 text-[11px] text-muted-foreground/60">
2168
+ No analyses yet
2169
+ </p>
2170
+ )}
2171
+ <NewAnalysisDialog />
2172
+ </div>
2173
+ </SortableContext>
2174
+ </DndContext>
2175
+ )}
2176
+ </div>
2169
2177
  </nav>
2170
2178
 
2171
2179
  <div className="mt-auto min-w-0 px-2 pt-2 text-sm font-medium lg:px-4">
@@ -26,9 +26,12 @@ export function useNavigationState() {
26
26
  state.view = "overview";
27
27
  } else if (pathname === "/ask") {
28
28
  state.view = "ask";
29
- } else if (pathname.startsWith("/adhoc/")) {
29
+ } else if (
30
+ pathname.startsWith("/dashboards/") ||
31
+ pathname.startsWith("/adhoc/")
32
+ ) {
30
33
  state.view = "adhoc";
31
- const match = pathname.match(/\/adhoc\/(.+)/);
34
+ const match = pathname.match(/\/(?:adhoc|dashboards)\/(.+)/);
32
35
  if (match) {
33
36
  state.dashboardId = match[1];
34
37
  localStorage.setItem("last-dashboard-id", match[1]);
@@ -68,7 +71,7 @@ export function useNavigationState() {
68
71
  },
69
72
  getCommandPath: (cmd) => {
70
73
  if (cmd.view === "adhoc" && cmd.dashboardId)
71
- return `/adhoc/${cmd.dashboardId}`;
74
+ return `/dashboards/${cmd.dashboardId}`;
72
75
  if (cmd.view === "analyses" && cmd.analysisId)
73
76
  return `/analyses/${cmd.analysisId}`;
74
77
  if (cmd.view === "analyses") return "/analyses";
@@ -8,7 +8,7 @@ export function demoNodeExporterDashboardPath(
8
8
  tab: DEMO_NODE_EXPORTER_DEFAULT_TAB,
9
9
  });
10
10
  if (options.intro) params.set("demoIntro", "1");
11
- return `/adhoc/${dashboardId}?${params.toString()}`;
11
+ return `/dashboards/${dashboardId}?${params.toString()}`;
12
12
  }
13
13
 
14
14
  export function withDemoIntro(path: string): string {
@@ -19,7 +19,8 @@ function isLastOpenedItem(value: unknown): value is LastOpenedItem {
19
19
  typeof item.id === "string" &&
20
20
  item.id.length > 0 &&
21
21
  typeof item.path === "string" &&
22
- (item.path.startsWith("/adhoc/") ||
22
+ (item.path.startsWith("/dashboards/") ||
23
+ item.path.startsWith("/adhoc/") ||
23
24
  item.path.startsWith("/analyses/") ||
24
25
  item.path.startsWith("/extensions/")) &&
25
26
  typeof item.updatedAt === "number"
@@ -1,13 +1,17 @@
1
+ import { ChangelogSettingsCard } from "@agent-native/core/client";
1
2
  import { useAuth } from "@/components/auth/AuthProvider";
2
3
  import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
3
4
  import { Button } from "@/components/ui/button";
4
5
  import { Link } from "react-router";
6
+ import changelog from "../../CHANGELOG.md?raw";
5
7
 
6
8
  export default function Settings() {
7
9
  const { auth } = useAuth();
8
10
 
9
11
  return (
10
12
  <div className="space-y-6 max-w-2xl">
13
+ <ChangelogSettingsCard markdown={changelog} />
14
+
11
15
  <Card className="bg-card border-border/50">
12
16
  <CardHeader>
13
17
  <CardTitle className="text-base">Account</CardTitle>
@@ -326,7 +326,7 @@ export default function ExplorerDashboardPage() {
326
326
  queryKey: ["explorer-dashboards-palette"],
327
327
  });
328
328
  toast.success(`Archived "${dashboard?.name ?? "dashboard"}"`);
329
- navigate("/adhoc/explorer");
329
+ navigate("/dashboards/explorer");
330
330
  } catch (err) {
331
331
  toast.error(
332
332
  err instanceof Error ? err.message : "Couldn't archive dashboard",
@@ -657,7 +657,7 @@ export default function ExplorerDashboardPage() {
657
657
  queryKey: ["explorer-dashboards-palette"],
658
658
  });
659
659
  setConfirmDeleteOpen(false);
660
- navigate("/adhoc/explorer");
660
+ navigate("/dashboards/explorer");
661
661
  } catch (err) {
662
662
  toast.error(
663
663
  err instanceof Error
@@ -717,7 +717,7 @@ export default function ExplorerDashboardPage() {
717
717
  onRemove={() => removeChart(chart.id)}
718
718
  onToggleWidth={() => toggleWidth(chart.id)}
719
719
  onEdit={() =>
720
- navigate(`/adhoc/explorer?config=${chart.configId}`)
720
+ navigate(`/dashboards/explorer?config=${chart.configId}`)
721
721
  }
722
722
  editable={canEdit}
723
723
  />
@@ -224,7 +224,7 @@ export function DashboardFilterBar({
224
224
  <Collapsible
225
225
  open={filtersOpen}
226
226
  onOpenChange={setFiltersOpen}
227
- className="rounded-lg border border-border bg-card p-3"
227
+ className="group rounded-lg border border-border bg-card p-3"
228
228
  >
229
229
  <div className="flex items-center justify-between gap-3">
230
230
  <div className="flex items-baseline gap-2">
@@ -235,7 +235,7 @@ export function DashboardFilterBar({
235
235
  auto-applied
236
236
  </span>
237
237
  </div>
238
- <div className="flex items-center gap-1">
238
+ <div className="flex items-center gap-1 opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100 group-data-[state=closed]:opacity-100">
239
239
  {onSaveView && filtersActive && (
240
240
  <Button
241
241
  variant="ghost"