@agent-native/core 0.69.0 → 0.70.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/README.md +15 -15
  2. package/corpus/README.md +2 -2
  3. package/corpus/core/CHANGELOG.md +109 -0
  4. package/corpus/core/docs/design/durable-agent-runs.md +217 -0
  5. package/corpus/core/package.json +1 -1
  6. package/corpus/core/src/action.ts +89 -0
  7. package/corpus/core/src/agent/model-config.ts +0 -2
  8. package/corpus/core/src/agent/run-loop-with-resume.ts +48 -0
  9. package/corpus/core/src/changelog/parse.ts +245 -0
  10. package/corpus/core/src/cli/changelog.ts +199 -0
  11. package/corpus/core/src/cli/index.ts +19 -0
  12. package/corpus/core/src/cli/recap.ts +24 -1
  13. package/corpus/core/src/cli/skills.ts +74 -47
  14. package/corpus/core/src/client/AgentPanel.tsx +5 -3
  15. package/corpus/core/src/client/AssistantChat.tsx +8 -0
  16. package/corpus/core/src/client/CommandMenu.tsx +183 -75
  17. package/corpus/core/src/client/agent-chat-adapter.ts +44 -7
  18. package/corpus/core/src/client/analytics.ts +181 -0
  19. package/corpus/core/src/client/changelog/Changelog.tsx +321 -0
  20. package/corpus/core/src/client/client-surface.ts +41 -0
  21. package/corpus/core/src/client/composer/TiptapComposer.tsx +123 -12
  22. package/corpus/core/src/client/feedback-context.ts +4 -0
  23. package/corpus/core/src/client/index.ts +12 -0
  24. package/corpus/core/src/client/mcp-apps/McpAppRenderer.tsx +54 -0
  25. package/corpus/core/src/client/settings/useBuilderStatus.ts +82 -20
  26. package/corpus/core/src/client/sse-event-processor.ts +7 -1
  27. package/corpus/core/src/mcp/build-server.ts +57 -1
  28. package/corpus/core/src/mcp/embed-app.ts +197 -7
  29. package/corpus/core/src/mcp/oauth-route.ts +109 -13
  30. package/corpus/core/src/server/attribution.ts +211 -0
  31. package/corpus/core/src/server/auth.ts +6 -0
  32. package/corpus/core/src/server/better-auth-instance.ts +49 -5
  33. package/corpus/core/src/server/builder-browser.ts +27 -1
  34. package/corpus/core/src/server/core-routes-plugin.ts +136 -0
  35. package/corpus/core/src/server/google-oauth.ts +19 -6
  36. package/corpus/core/src/server/onboarding-html.ts +35 -0
  37. package/corpus/core/src/shared/mcp-embed-headers.ts +1 -1
  38. package/corpus/core/src/styles/agent-conversation.css +21 -0
  39. package/corpus/core/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
  40. package/corpus/core/src/templates/workspace-core/.agents/skills/reliable-mutations/SKILL.md +72 -0
  41. package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
  42. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +22 -0
  43. package/corpus/templates/analytics/AGENTS.md +8 -1
  44. package/corpus/templates/analytics/CHANGELOG.md +10 -0
  45. package/corpus/templates/analytics/actions/install-dashboard-template.ts +99 -4
  46. package/corpus/templates/analytics/actions/open-traffic-dashboard.ts +1 -1
  47. package/corpus/templates/analytics/actions/update-dashboard.ts +39 -8
  48. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +30 -3
  49. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +180 -144
  50. package/corpus/templates/analytics/app/components/layout/Header.tsx +2 -3
  51. package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -5
  52. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +221 -215
  53. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +6 -6
  54. package/corpus/templates/analytics/app/lib/demo-dashboard-path.ts +1 -1
  55. package/corpus/templates/analytics/app/lib/last-opened.ts +2 -1
  56. package/corpus/templates/analytics/app/pages/Settings.tsx +4 -0
  57. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +3 -3
  58. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +2 -2
  59. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +32 -2
  60. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +101 -99
  61. package/corpus/templates/analytics/app/pages/overview/OverviewPage.tsx +1 -1
  62. package/corpus/templates/analytics/app/routes/adhoc.$id.tsx +18 -5
  63. package/corpus/templates/analytics/app/routes/catalog.tsx +1 -1
  64. package/corpus/templates/analytics/app/routes/dashboards.$id.tsx +9 -0
  65. package/corpus/templates/analytics/app/routes/traffic.tsx +1 -1
  66. package/corpus/templates/analytics/changelog/2026-06-23-long-dashboard-and-analysis-names-in-the-sidebar-now-truncat.md +6 -0
  67. package/corpus/templates/analytics/changelog/2026-06-23-open-any-dashboard-chart-full-screen-in-a-modal-from-the-pan.md +6 -0
  68. package/corpus/templates/analytics/changelog/2026-06-23-the-dashboards-and-analyses-sidebar-settings-buttons-now-sta.md +6 -0
  69. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +145 -0
  70. package/corpus/templates/analytics/server/db/index.ts +1 -1
  71. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +9 -2
  72. package/corpus/templates/analytics/server/lib/demo-dashboards.ts +1 -1
  73. package/corpus/templates/analytics/server/plugins/agent-chat.ts +2 -2
  74. package/corpus/templates/analytics/server/plugins/core-routes.ts +6 -6
  75. package/corpus/templates/assets/CHANGELOG.md +10 -0
  76. package/corpus/templates/assets/actions/generate-image.ts +24 -0
  77. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +2 -2
  78. package/corpus/templates/assets/app/global.css +17 -1
  79. package/corpus/templates/assets/app/root.tsx +7 -1
  80. package/corpus/templates/assets/app/routes/_index.tsx +94 -14
  81. package/corpus/templates/assets/app/routes/settings.tsx +6 -0
  82. package/corpus/templates/assets/changelog/2026-06-23-chat-dates-in-the-sidebar-no-longer-wrap-onto-two-lines.md +6 -0
  83. package/corpus/templates/assets/changelog/2026-06-23-clicking-image-video-or-refine-on-the-start-screen-now-drops.md +6 -0
  84. package/corpus/templates/assets/changelog/2026-06-23-pick-your-image-generation-model-right-from-the-chat-model-m.md +6 -0
  85. package/corpus/templates/brain/CHANGELOG.md +10 -0
  86. package/corpus/templates/brain/app/root.tsx +7 -1
  87. package/corpus/templates/brain/app/routes/settings.tsx +8 -1
  88. package/corpus/templates/calendar/CHANGELOG.md +10 -0
  89. package/corpus/templates/calendar/app/pages/Settings.tsx +4 -0
  90. package/corpus/templates/calendar/app/root.tsx +7 -1
  91. package/corpus/templates/chat/CHANGELOG.md +10 -0
  92. package/corpus/templates/chat/app/root.tsx +7 -1
  93. package/corpus/templates/clips/CHANGELOG.md +10 -0
  94. package/corpus/templates/clips/app/components/library/library-grid.tsx +1 -20
  95. package/corpus/templates/clips/app/components/player/share-dialog.tsx +33 -7
  96. package/corpus/templates/clips/app/components/player/sign-in-prompt-dialog.tsx +8 -0
  97. package/corpus/templates/clips/app/components/player/video-player.tsx +150 -20
  98. package/corpus/templates/clips/app/components/recorder/countdown-overlay.tsx +72 -48
  99. package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +7 -11
  100. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +31 -0
  101. package/corpus/templates/clips/app/components/sharing/slack-share-hint.tsx +71 -0
  102. package/corpus/templates/clips/app/lib/countdown-audio-cue.ts +35 -17
  103. package/corpus/templates/clips/app/root.tsx +7 -1
  104. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +15 -1
  105. package/corpus/templates/clips/app/routes/record.tsx +78 -5
  106. package/corpus/templates/clips/app/routes/share.$shareId.tsx +86 -5
  107. package/corpus/templates/clips/changelog/2026-06-23-clips-shared-in-slack-no-longer-show-a-could-not-start-playb.md +6 -0
  108. package/corpus/templates/clips/changelog/2026-06-23-made-the-play-button-on-shared-and-embedded-clips-scale-with.md +6 -0
  109. package/corpus/templates/clips/changelog/2026-06-23-public-clip-share-links-now-show-whether-they-ll-play-inline.md +6 -0
  110. package/corpus/templates/clips/changelog/2026-06-23-removed-select-button-from-library-hover-a-clip-to-select-it.md +6 -0
  111. package/corpus/templates/clips/changelog/2026-06-23-screen-camera-recordings-now-keep-the-presenter-s-face-in-th.md +6 -0
  112. package/corpus/templates/clips/changelog/2026-06-23-shared-video-links-now-play-for-anyone-without-signing-in.md +6 -0
  113. package/corpus/templates/clips/changelog/2026-06-23-skip-or-cancel-the-recording-countdown-with-buttons-beside-t.md +6 -0
  114. package/corpus/templates/clips/changelog/2026-06-23-the-desktop-camera-bubble-now-looks-sharp-the-instant-it-ope.md +6 -0
  115. package/corpus/templates/clips/changelog/2026-06-23-the-desktop-recording-widget-now-grows-downward-only-when-yo.md +6 -0
  116. package/corpus/templates/clips/changelog/2026-06-23-the-recording-start-sound-is-now-a-softer-more-modern-chime.md +6 -0
  117. package/corpus/templates/clips/chrome-extension/public/manifest.json +17 -8
  118. package/corpus/templates/clips/chrome-extension/src/background.ts +769 -180
  119. package/corpus/templates/clips/chrome-extension/src/content-script.ts +177 -0
  120. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +466 -329
  121. package/corpus/templates/clips/chrome-extension/src/overlay.css +377 -0
  122. package/corpus/templates/clips/chrome-extension/src/overlay.html +12 -0
  123. package/corpus/templates/clips/chrome-extension/src/overlay.ts +330 -0
  124. package/corpus/templates/clips/chrome-extension/src/permission.html +227 -0
  125. package/corpus/templates/clips/chrome-extension/src/permission.ts +105 -0
  126. package/corpus/templates/clips/chrome-extension/src/popup.html +3 -0
  127. package/corpus/templates/clips/chrome-extension/src/popup.ts +50 -2
  128. package/corpus/templates/clips/chrome-extension/src/styles.css +50 -0
  129. package/corpus/templates/clips/chrome-extension/vite.config.ts +3 -0
  130. package/corpus/templates/clips/desktop/src/lib/audio-cue.ts +41 -24
  131. package/corpus/templates/clips/desktop/src/lib/bubble-webrtc.ts +119 -2
  132. package/corpus/templates/clips/desktop/src/lib/recorder.ts +20 -0
  133. package/corpus/templates/clips/desktop/src/main.tsx +3 -0
  134. package/corpus/templates/clips/desktop/src/overlays/countdown.tsx +21 -2
  135. package/corpus/templates/clips/desktop/src/overlays/region-record-border.tsx +76 -0
  136. package/corpus/templates/clips/desktop/src/styles.css +119 -2
  137. package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +2 -1
  138. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +140 -1
  139. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -0
  140. package/corpus/templates/clips/desktop/src-tauri/src/util.rs +4 -1
  141. package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +85 -6
  142. package/corpus/templates/clips/shared/share-attribution.ts +79 -0
  143. package/corpus/templates/content/AGENTS.md +20 -3
  144. package/corpus/templates/content/CHANGELOG.md +10 -0
  145. package/corpus/templates/content/actions/_database-utils.ts +15 -0
  146. package/corpus/templates/content/actions/_property-utils.ts +371 -4
  147. package/corpus/templates/content/actions/configure-document-property.ts +35 -1
  148. package/corpus/templates/content/actions/create-content-database.ts +5 -1
  149. package/corpus/templates/content/actions/delete-document-property.ts +52 -2
  150. package/corpus/templates/content/actions/duplicate-document-property.ts +34 -17
  151. package/corpus/templates/content/actions/reorder-document-property.ts +79 -0
  152. package/corpus/templates/content/actions/set-document-property.ts +39 -0
  153. package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +806 -0
  154. package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +226 -68
  155. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +59 -30
  156. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +25 -1
  157. package/corpus/templates/content/app/components/editor/blockFieldSaveController.ts +180 -0
  158. package/corpus/templates/content/app/components/editor/blockFieldSaveRegistry.ts +179 -0
  159. package/corpus/templates/content/app/components/editor/previewDocumentSaveController.ts +244 -0
  160. package/corpus/templates/content/app/components/editor/previewDocumentSaveRegistry.ts +132 -0
  161. package/corpus/templates/content/app/global.css +9 -0
  162. package/corpus/templates/content/app/hooks/use-document-properties.ts +21 -0
  163. package/corpus/templates/content/app/root.tsx +7 -1
  164. package/corpus/templates/content/server/db/schema.ts +30 -0
  165. package/corpus/templates/content/server/plugins/db.ts +87 -0
  166. package/corpus/templates/content/shared/api.ts +7 -0
  167. package/corpus/templates/content/shared/properties.ts +109 -0
  168. package/corpus/templates/design/CHANGELOG.md +10 -0
  169. package/corpus/templates/design/actions/generate-design.ts +4 -0
  170. package/corpus/templates/design/app/root.tsx +7 -1
  171. package/corpus/templates/design/app/routes/settings.tsx +10 -2
  172. package/corpus/templates/dispatch/CHANGELOG.md +10 -0
  173. package/corpus/templates/dispatch/app/root.tsx +7 -1
  174. package/corpus/templates/forms/.agents/skills/form-responses/SKILL.md +10 -0
  175. package/corpus/templates/forms/CHANGELOG.md +10 -0
  176. package/corpus/templates/forms/actions/export-responses.ts +6 -0
  177. package/corpus/templates/forms/actions/list-responses.ts +2 -0
  178. package/corpus/templates/forms/actions/response-insights.ts +2 -0
  179. package/corpus/templates/forms/app/pages/ResponsesPage.tsx +138 -1
  180. package/corpus/templates/forms/app/root.tsx +7 -1
  181. package/corpus/templates/forms/changelog/2026-06-23-response-tables-now-show-the-page-each-submission-came-from-.md +6 -0
  182. package/corpus/templates/forms/changelog/2026-06-23-response-tables-now-show-whether-feedback-came-from-the-web-.md +6 -0
  183. package/corpus/templates/forms/server/db/schema.ts +7 -0
  184. package/corpus/templates/forms/server/handlers/submissions.ts +19 -2
  185. package/corpus/templates/forms/server/lib/integrations.ts +76 -2
  186. package/corpus/templates/forms/server/plugins/db.ts +20 -0
  187. package/corpus/templates/forms/shared/types.ts +12 -0
  188. package/corpus/templates/macros/CHANGELOG.md +10 -0
  189. package/corpus/templates/macros/app/root.tsx +7 -1
  190. package/corpus/templates/mail/CHANGELOG.md +10 -0
  191. package/corpus/templates/mail/app/components/layout/CommandPalette.tsx +3 -0
  192. package/corpus/templates/mail/app/pages/SettingsPage.tsx +27 -0
  193. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +31 -17
  194. package/corpus/templates/plan/.agents/skills/visual-plan/references/wireframe.md +7 -4
  195. package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +34 -24
  196. package/corpus/templates/plan/.agents/skills/visual-recap/references/wireframe.md +7 -4
  197. package/corpus/templates/plan/AGENTS.md +4 -0
  198. package/corpus/templates/plan/CHANGELOG.md +10 -0
  199. package/corpus/templates/plan/actions/view-screen.ts +5 -0
  200. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +98 -1
  201. package/corpus/templates/plan/app/components/plan/wireframe/html-artboard.css +3 -1
  202. package/corpus/templates/plan/app/pages/PlansPage.tsx +107 -7
  203. package/corpus/templates/plan/app/root.tsx +7 -1
  204. package/corpus/templates/plan/changelog/2026-06-23-large-diagrams-in-a-plan-now-scroll-within-their-block-inste.md +6 -0
  205. package/corpus/templates/plan/shared/share-attribution.ts +72 -0
  206. package/corpus/templates/slides/CHANGELOG.md +10 -0
  207. package/corpus/templates/slides/app/root.tsx +7 -1
  208. package/corpus/templates/videos/CHANGELOG.md +4 -151
  209. package/corpus/templates/videos/app/root.tsx +7 -1
  210. package/dist/action.js +87 -0
  211. package/dist/action.js.map +1 -1
  212. package/dist/agent/engine/builder-engine.d.ts +1 -1
  213. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  214. package/dist/agent/model-config.d.ts +2 -2
  215. package/dist/agent/model-config.d.ts.map +1 -1
  216. package/dist/agent/model-config.js +0 -2
  217. package/dist/agent/model-config.js.map +1 -1
  218. package/dist/agent/run-loop-with-resume.d.ts +13 -0
  219. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  220. package/dist/agent/run-loop-with-resume.js +44 -0
  221. package/dist/agent/run-loop-with-resume.js.map +1 -1
  222. package/dist/changelog/parse.d.ts +70 -0
  223. package/dist/changelog/parse.d.ts.map +1 -0
  224. package/dist/changelog/parse.js +200 -0
  225. package/dist/changelog/parse.js.map +1 -0
  226. package/dist/cli/changelog.d.ts +4 -0
  227. package/dist/cli/changelog.d.ts.map +1 -0
  228. package/dist/cli/changelog.js +166 -0
  229. package/dist/cli/changelog.js.map +1 -0
  230. package/dist/cli/index.js +18 -0
  231. package/dist/cli/index.js.map +1 -1
  232. package/dist/cli/recap.d.ts.map +1 -1
  233. package/dist/cli/recap.js +22 -1
  234. package/dist/cli/recap.js.map +1 -1
  235. package/dist/cli/skills.d.ts +3 -3
  236. package/dist/cli/skills.d.ts.map +1 -1
  237. package/dist/cli/skills.js +74 -47
  238. package/dist/cli/skills.js.map +1 -1
  239. package/dist/client/AgentPanel.d.ts.map +1 -1
  240. package/dist/client/AgentPanel.js +5 -3
  241. package/dist/client/AgentPanel.js.map +1 -1
  242. package/dist/client/AssistantChat.d.ts +6 -1
  243. package/dist/client/AssistantChat.d.ts.map +1 -1
  244. package/dist/client/AssistantChat.js +2 -2
  245. package/dist/client/AssistantChat.js.map +1 -1
  246. package/dist/client/CommandMenu.d.ts +17 -1
  247. package/dist/client/CommandMenu.d.ts.map +1 -1
  248. package/dist/client/CommandMenu.js +49 -13
  249. package/dist/client/CommandMenu.js.map +1 -1
  250. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  251. package/dist/client/agent-chat-adapter.js +43 -6
  252. package/dist/client/agent-chat-adapter.js.map +1 -1
  253. package/dist/client/analytics.d.ts +18 -0
  254. package/dist/client/analytics.d.ts.map +1 -1
  255. package/dist/client/analytics.js +177 -0
  256. package/dist/client/analytics.js.map +1 -1
  257. package/dist/client/changelog/Changelog.d.ts +47 -0
  258. package/dist/client/changelog/Changelog.d.ts.map +1 -0
  259. package/dist/client/changelog/Changelog.js +138 -0
  260. package/dist/client/changelog/Changelog.js.map +1 -0
  261. package/dist/client/client-surface.d.ts +17 -0
  262. package/dist/client/client-surface.d.ts.map +1 -0
  263. package/dist/client/client-surface.js +24 -0
  264. package/dist/client/client-surface.js.map +1 -0
  265. package/dist/client/composer/TiptapComposer.d.ts +26 -1
  266. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  267. package/dist/client/composer/TiptapComposer.js +27 -5
  268. package/dist/client/composer/TiptapComposer.js.map +1 -1
  269. package/dist/client/feedback-context.d.ts +3 -0
  270. package/dist/client/feedback-context.d.ts.map +1 -1
  271. package/dist/client/feedback-context.js +2 -0
  272. package/dist/client/feedback-context.js.map +1 -1
  273. package/dist/client/index.d.ts +3 -1
  274. package/dist/client/index.d.ts.map +1 -1
  275. package/dist/client/index.js +3 -1
  276. package/dist/client/index.js.map +1 -1
  277. package/dist/client/mcp-apps/McpAppRenderer.d.ts +1 -0
  278. package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -1
  279. package/dist/client/mcp-apps/McpAppRenderer.js +42 -1
  280. package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -1
  281. package/dist/client/settings/useBuilderStatus.d.ts +2 -0
  282. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  283. package/dist/client/settings/useBuilderStatus.js +58 -10
  284. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  285. package/dist/client/sse-event-processor.d.ts.map +1 -1
  286. package/dist/client/sse-event-processor.js +7 -1
  287. package/dist/client/sse-event-processor.js.map +1 -1
  288. package/dist/mcp/build-server.d.ts +21 -0
  289. package/dist/mcp/build-server.d.ts.map +1 -1
  290. package/dist/mcp/build-server.js +43 -1
  291. package/dist/mcp/build-server.js.map +1 -1
  292. package/dist/mcp/embed-app.d.ts.map +1 -1
  293. package/dist/mcp/embed-app.js +197 -7
  294. package/dist/mcp/embed-app.js.map +1 -1
  295. package/dist/mcp/oauth-route.d.ts.map +1 -1
  296. package/dist/mcp/oauth-route.js +95 -12
  297. package/dist/mcp/oauth-route.js.map +1 -1
  298. package/dist/server/attribution.d.ts +83 -0
  299. package/dist/server/attribution.d.ts.map +1 -0
  300. package/dist/server/attribution.js +178 -0
  301. package/dist/server/attribution.js.map +1 -0
  302. package/dist/server/auth.d.ts.map +1 -1
  303. package/dist/server/auth.js +7 -0
  304. package/dist/server/auth.js.map +1 -1
  305. package/dist/server/better-auth-instance.d.ts +9 -1
  306. package/dist/server/better-auth-instance.d.ts.map +1 -1
  307. package/dist/server/better-auth-instance.js +32 -2
  308. package/dist/server/better-auth-instance.js.map +1 -1
  309. package/dist/server/builder-browser.d.ts +4 -0
  310. package/dist/server/builder-browser.d.ts.map +1 -1
  311. package/dist/server/builder-browser.js +20 -1
  312. package/dist/server/builder-browser.js.map +1 -1
  313. package/dist/server/core-routes-plugin.d.ts +25 -0
  314. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  315. package/dist/server/core-routes-plugin.js +101 -0
  316. package/dist/server/core-routes-plugin.js.map +1 -1
  317. package/dist/server/google-oauth.d.ts.map +1 -1
  318. package/dist/server/google-oauth.js +16 -2
  319. package/dist/server/google-oauth.js.map +1 -1
  320. package/dist/server/onboarding-html.d.ts.map +1 -1
  321. package/dist/server/onboarding-html.js +35 -0
  322. package/dist/server/onboarding-html.js.map +1 -1
  323. package/dist/shared/mcp-embed-headers.js +1 -1
  324. package/dist/shared/mcp-embed-headers.js.map +1 -1
  325. package/dist/styles/agent-conversation.css +21 -0
  326. package/dist/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
  327. package/dist/templates/workspace-core/.agents/skills/reliable-mutations/SKILL.md +72 -0
  328. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
  329. package/docs/design/durable-agent-runs.md +217 -0
  330. package/package.json +1 -1
  331. package/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
  332. package/src/templates/workspace-core/.agents/skills/reliable-mutations/SKILL.md +72 -0
  333. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
  334. package/corpus/templates/analytics/app/pages/About.tsx +0 -108
  335. package/corpus/templates/analytics/app/routes/about.tsx +0 -9
  336. /package/corpus/templates/analytics/app/routes/{dashboards.tsx → dashboards._index.tsx} +0 -0
@@ -378,6 +378,11 @@ function resolveScope() {
378
378
  return { orgId, email };
379
379
  }
380
380
 
381
+ /** Resulting panel count, used for the proof-of-done return summary. */
382
+ function countPanels(config: Record<string, unknown>): number {
383
+ return Array.isArray(config.panels) ? config.panels.length : 0;
384
+ }
385
+
381
386
  /**
382
387
  * Push a config update through the collab layer so open dashboard editors
383
388
  * receive the change in real time. Seeds the collab state if it doesn't
@@ -407,10 +412,20 @@ async function syncToCollab(
407
412
 
408
413
  export default defineAction({
409
414
  description:
410
- "Edit a SQL dashboard config (scope-aware). Prefer this over raw db-patch on the settings table — " +
415
+ "Edit a SQL dashboard config (scope-aware) atomically in ONE call. Prefer this over raw db-patch on the settings table — " +
411
416
  "it resolves org vs. user scope correctly so the edit lands on the row the UI actually renders. " +
412
- "Use `ops` for structural changes (reorder/insert/remove panels, update field values via JSON Pointer paths). " +
413
- "Use `config` to replace the entire dashboard config. The UI auto-refreshes after this action do NOT call `refresh-screen`.",
417
+ "BATCH ALL EDITS INTO A SINGLE CALL. Never call this action repeatedly in a loop: hosted agent runs have a ~40s budget, and many sequential update-dashboard calls time out mid-way and leave the dashboard in a partial state even though earlier calls looked like they succeeded. Put every change you want to make into one `ops` array (or one `config`). " +
418
+ "`ops` is an array of { op, path, from?, value? } applied in order in a single atomic save. " +
419
+ "`op` is one of: set | replace | remove | insert | move | move-before. " +
420
+ "`path` is a JSON Pointer into the config (e.g. `/panels/3` is the 4th panel, `/panels/3/title` is its title, `/name` is the dashboard name). The special index `-` means the end of an array: `/panels/-` appends. " +
421
+ "`value` is the panel or object to set/insert. `from` is the source JSON Pointer for move / move-before. " +
422
+ "To ADD N panels in one call, pass N entries of { op: 'insert', path: '/panels/-', value: <panel> }. " +
423
+ "To reorder: [{ op: 'move', from: '/panels/2', path: '/panels/0' }]. " +
424
+ "To edit a field: [{ op: 'replace', path: '/panels/0/title', value: 'Events by Day' }]. " +
425
+ "Use `config` to replace the entire dashboard config in one call. Provide `ops` OR `config`, not both. " +
426
+ "To add a shipped catalog template's panels to an existing dashboard, prefer `install-dashboard-template` with `mergePanels: true` — it appends the template's panels in one call without you having to author each panel. " +
427
+ "The result includes `panelCount` (resulting number of panels), `appliedOps` (count), and a `summary` string — use them as proof-of-done and report the new panel count back to the user instead of assuming success. " +
428
+ "The UI auto-refreshes after this action — do NOT call `refresh-screen`.",
414
429
  schema: z.object({
415
430
  dashboardId: z
416
431
  .string()
@@ -438,8 +453,11 @@ export default defineAction({
438
453
  )
439
454
  .optional()
440
455
  .describe(
441
- "Array of JSON-patch-style ops applied in order (or a JSON string). " +
442
- "Example reorder: [{op:'move', from:'/panels/2', path:'/panels/0'}]",
456
+ "Array of JSON-patch-style ops applied in order in ONE atomic save (or a JSON string). " +
457
+ "Each op is { op, path, from?, value? }. op ∈ set|replace|remove|insert|move|move-before. " +
458
+ "path is a JSON Pointer (e.g. '/panels/3', and '/panels/-' appends to the end). " +
459
+ "Add N panels at once with N {op:'insert', path:'/panels/-', value:<panel>} entries. " +
460
+ "Example reorder: [{op:'move', from:'/panels/2', path:'/panels/0'}].",
443
461
  ),
444
462
  config: z
445
463
  .preprocess(
@@ -480,6 +498,7 @@ export default defineAction({
480
498
  if (sqlError) throw new Error(sqlError);
481
499
  await upsertDashboard(args.dashboardId, "sql", args.config, ctx);
482
500
  await syncToCollab(args.dashboardId, args.config);
501
+ const panelCount = countPanels(args.config);
483
502
  return {
484
503
  id: args.dashboardId,
485
504
  dashboardId: args.dashboardId,
@@ -487,8 +506,13 @@ export default defineAction({
487
506
  typeof args.config.name === "string"
488
507
  ? args.config.name
489
508
  : args.dashboardId,
509
+ // Proof-of-done: lead with verifiable state so the agent/UI can
510
+ // confirm the new shape cheaply instead of assuming success.
511
+ panelCount,
512
+ appliedOps: 0,
513
+ summary: `Replaced dashboard "${args.dashboardId}"; it now has ${panelCount} panel(s).`,
490
514
  config: args.config,
491
- urlPath: `/adhoc/${args.dashboardId}`,
515
+ urlPath: `/dashboards/${args.dashboardId}`,
492
516
  deepLink: buildDeepLink({
493
517
  app: "analytics",
494
518
  view: "adhoc",
@@ -526,12 +550,18 @@ export default defineAction({
526
550
  );
527
551
  await syncToCollab(args.dashboardId, root as Record<string, unknown>);
528
552
 
553
+ const panelCount = countPanels(root as Record<string, unknown>);
529
554
  return {
530
555
  id: args.dashboardId,
531
556
  dashboardId: args.dashboardId,
532
557
  name: typeof root.name === "string" ? root.name : args.dashboardId,
558
+ // Proof-of-done: lead with verifiable state (op count + resulting panel
559
+ // count) so the agent/UI can confirm success without re-fetching.
560
+ panelCount,
561
+ appliedOps: details.length,
562
+ summary: `Applied ${details.length} op(s); dashboard "${args.dashboardId}" now has ${panelCount} panel(s).`,
533
563
  config: root,
534
- urlPath: `/adhoc/${args.dashboardId}`,
564
+ urlPath: `/dashboards/${args.dashboardId}`,
535
565
  deepLink: buildDeepLink({
536
566
  app: "analytics",
537
567
  view: "adhoc",
@@ -539,7 +569,8 @@ export default defineAction({
539
569
  }),
540
570
  message:
541
571
  `Dashboard "${args.dashboardId}" updated. ` +
542
- `Applied ${details.length} op(s): ${details.join("; ")}.`,
572
+ `Applied ${details.length} op(s): ${details.join("; ")}. ` +
573
+ `Now ${panelCount} panel(s).`,
543
574
  };
544
575
  },
545
576
  link: ({ result }) => {
@@ -1,5 +1,7 @@
1
1
  import {
2
+ createContext,
2
3
  useCallback,
4
+ useContext,
3
5
  useEffect,
4
6
  useMemo,
5
7
  useState,
@@ -248,6 +250,20 @@ function SeriesLegend({
248
250
  );
249
251
  }
250
252
 
253
+ // When a chart renders inside the full-screen modal it should grow to fill the
254
+ // available space rather than the fixed 250px card height. ChartFrame reads
255
+ // this via context so we avoid threading a prop through every renderer
256
+ // (line/area/bar/pie all share ChartFrame).
257
+ const ChartFillHeightContext = createContext(false);
258
+
259
+ export function ChartFillHeight({ children }: { children: ReactNode }) {
260
+ return (
261
+ <ChartFillHeightContext.Provider value={true}>
262
+ {children}
263
+ </ChartFillHeightContext.Provider>
264
+ );
265
+ }
266
+
251
267
  function ChartFrame({
252
268
  panel,
253
269
  legendKeys,
@@ -259,13 +275,24 @@ function ChartFrame({
259
275
  colors: string[];
260
276
  children: ReactNode;
261
277
  }) {
278
+ const fill = useContext(ChartFillHeightContext);
279
+ const chartHeight = fill ? "h-full min-h-[250px]" : "h-[250px]";
280
+
262
281
  if (!usesPrometheusPresentation(panel)) {
263
- return <div className="h-[250px] w-full overflow-visible">{children}</div>;
282
+ return (
283
+ <div className={`${chartHeight} w-full overflow-visible`}>{children}</div>
284
+ );
264
285
  }
265
286
 
266
287
  return (
267
- <div className="w-full overflow-hidden">
268
- <div className="h-[250px] w-full overflow-visible">{children}</div>
288
+ <div
289
+ className={`flex w-full flex-col overflow-hidden ${fill ? "h-full" : ""}`}
290
+ >
291
+ <div
292
+ className={`${chartHeight} w-full overflow-visible ${fill ? "flex-1" : ""}`}
293
+ >
294
+ {children}
295
+ </div>
269
296
  <SeriesLegend keys={legendKeys} colors={colors} panel={panel} />
270
297
  </div>
271
298
  );
@@ -16,6 +16,7 @@ import {
16
16
  IconLayoutDashboard,
17
17
  IconSun,
18
18
  IconMoon,
19
+ IconHistory,
19
20
  } from "@tabler/icons-react";
20
21
  import { useTheme } from "next-themes";
21
22
  import { dashboards } from "@/pages/adhoc/registry";
@@ -25,8 +26,10 @@ import {
25
26
  appApiPath,
26
27
  callAction,
27
28
  useChangeVersions,
29
+ ChangelogDialog,
28
30
  } from "@agent-native/core/client";
29
31
  import { extensionPath } from "@agent-native/core/client/extensions";
32
+ import changelog from "../../../CHANGELOG.md?raw";
30
33
  import { commandPaletteKeywords } from "./command-palette-search";
31
34
 
32
35
  interface SavedConfig {
@@ -47,11 +50,11 @@ interface ExtensionSearchItem {
47
50
  }
48
51
 
49
52
  const defaultTools = [
50
- { id: "explorer", name: "Explorer", href: "/adhoc/explorer" },
53
+ { id: "explorer", name: "Explorer", href: "/dashboards/explorer" },
51
54
  {
52
55
  id: "customer-health",
53
56
  name: "Customer Health",
54
- href: "/adhoc/customer-health",
57
+ href: "/dashboards/customer-health",
55
58
  },
56
59
  ];
57
60
 
@@ -181,6 +184,7 @@ function persistThemePreference(theme: "light" | "dark") {
181
184
 
182
185
  export function CommandPalette() {
183
186
  const [open, setOpen] = useState(false);
187
+ const [changelogOpen, setChangelogOpen] = useState(false);
184
188
  const [searchQuery, setSearchQuery] = useState("");
185
189
  const navigate = useNavigate();
186
190
  const { resolvedTheme, setTheme } = useTheme();
@@ -263,168 +267,200 @@ export function CommandPalette() {
263
267
  : sqlDashboards.filter((dashboard) => !dashboard.hiddenAt);
264
268
 
265
269
  return (
266
- <CommandDialog
267
- open={open}
268
- onOpenChange={(next) => {
269
- setOpen(next);
270
- if (!next) setSearchQuery("");
271
- }}
272
- >
273
- <CommandInput
274
- placeholder="Search dashboards, extensions, charts..."
275
- value={searchQuery}
276
- onValueChange={setSearchQuery}
277
- />
278
- <CommandList>
279
- {!asyncGroupsLoading && <CommandEmpty>No results found.</CommandEmpty>}
280
-
281
- {explorerDashboardsFetching && explorerDashboards.length === 0 && (
282
- <CommandLoadingGroup heading="Explorer Dashboards" rows={2} />
283
- )}
284
-
285
- {visibleExplorerDashboards.length > 0 && (
286
- <CommandGroup heading="Explorer Dashboards">
287
- {visibleExplorerDashboards.map((d) => (
288
- <CommandItem
289
- key={`ed-${d.id}`}
290
- onSelect={() => go(`/adhoc/explorer-dashboard?id=${d.id}`)}
291
- keywords={commandPaletteKeywords(
292
- d.name,
293
- "explorer dashboard",
294
- "dashboard",
295
- )}
296
- >
297
- <IconLayoutDashboard className="mr-2 h-4 w-4 text-muted-foreground" />
298
- <span className="truncate">{d.name}</span>
299
- {d.hiddenAt ? (
300
- <span className="ml-2 rounded border border-border px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">
301
- Hidden
302
- </span>
303
- ) : null}
304
- </CommandItem>
305
- ))}
306
- </CommandGroup>
307
- )}
308
-
309
- {sqlDashboardsFetching && sqlDashboards.length === 0 && (
310
- <CommandLoadingGroup heading="SQL Dashboards" rows={3} />
311
- )}
312
-
313
- {visibleSqlDashboards.length > 0 && (
314
- <CommandGroup heading="SQL Dashboards">
315
- {visibleSqlDashboards.map((d) => (
270
+ <>
271
+ <CommandDialog
272
+ open={open}
273
+ onOpenChange={(next) => {
274
+ setOpen(next);
275
+ if (!next) setSearchQuery("");
276
+ }}
277
+ >
278
+ <CommandInput
279
+ placeholder="Search dashboards, extensions, charts..."
280
+ value={searchQuery}
281
+ onValueChange={setSearchQuery}
282
+ />
283
+ <CommandList>
284
+ {!asyncGroupsLoading && (
285
+ <CommandEmpty>No results found.</CommandEmpty>
286
+ )}
287
+
288
+ {explorerDashboardsFetching && explorerDashboards.length === 0 && (
289
+ <CommandLoadingGroup heading="Explorer Dashboards" rows={2} />
290
+ )}
291
+
292
+ {visibleExplorerDashboards.length > 0 && (
293
+ <CommandGroup heading="Explorer Dashboards">
294
+ {visibleExplorerDashboards.map((d) => (
295
+ <CommandItem
296
+ key={`ed-${d.id}`}
297
+ onSelect={() =>
298
+ go(`/dashboards/explorer-dashboard?id=${d.id}`)
299
+ }
300
+ keywords={commandPaletteKeywords(
301
+ d.name,
302
+ "explorer dashboard",
303
+ "dashboard",
304
+ )}
305
+ >
306
+ <IconLayoutDashboard className="mr-2 h-4 w-4 text-muted-foreground" />
307
+ <span className="truncate">{d.name}</span>
308
+ {d.hiddenAt ? (
309
+ <span className="ml-2 rounded border border-border px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">
310
+ Hidden
311
+ </span>
312
+ ) : null}
313
+ </CommandItem>
314
+ ))}
315
+ </CommandGroup>
316
+ )}
317
+
318
+ {sqlDashboardsFetching && sqlDashboards.length === 0 && (
319
+ <CommandLoadingGroup heading="SQL Dashboards" rows={3} />
320
+ )}
321
+
322
+ {visibleSqlDashboards.length > 0 && (
323
+ <CommandGroup heading="SQL Dashboards">
324
+ {visibleSqlDashboards.map((d) => (
325
+ <CommandItem
326
+ key={`sql-${d.id}`}
327
+ onSelect={() => go(`/dashboards/${d.id}`)}
328
+ keywords={commandPaletteKeywords(
329
+ d.name,
330
+ "sql dashboard",
331
+ "dashboard",
332
+ )}
333
+ >
334
+ <IconLayoutDashboard className="mr-2 h-4 w-4 text-muted-foreground" />
335
+ <span className="truncate">{d.name}</span>
336
+ {d.hiddenAt ? (
337
+ <span className="ml-2 rounded border border-border px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">
338
+ Hidden
339
+ </span>
340
+ ) : null}
341
+ </CommandItem>
342
+ ))}
343
+ </CommandGroup>
344
+ )}
345
+
346
+ {extensionsFetching && extensions.length === 0 && (
347
+ <CommandLoadingGroup heading="Extensions" rows={3} />
348
+ )}
349
+
350
+ {extensions.length > 0 && (
351
+ <CommandGroup heading="Extensions">
352
+ {extensions.map((extension) => (
353
+ <CommandItem
354
+ key={`extension-${extension.id}`}
355
+ onSelect={() =>
356
+ go(extensionPath(extension.id, extension.name))
357
+ }
358
+ keywords={commandPaletteKeywords(
359
+ extension.name,
360
+ extension.description,
361
+ "extension",
362
+ "tool",
363
+ )}
364
+ >
365
+ <IconTool className="mr-2 h-4 w-4 text-muted-foreground" />
366
+ {extension.name}
367
+ </CommandItem>
368
+ ))}
369
+ </CommandGroup>
370
+ )}
371
+
372
+ <CommandGroup heading="Dashboards">
373
+ {dashboards.map((d) => (
316
374
  <CommandItem
317
- key={`sql-${d.id}`}
318
- onSelect={() => go(`/adhoc/${d.id}`)}
319
- keywords={commandPaletteKeywords(
320
- d.name,
321
- "sql dashboard",
322
- "dashboard",
323
- )}
375
+ key={`dash-${d.id}`}
376
+ onSelect={() => go(`/dashboards/${d.id}`)}
377
+ keywords={commandPaletteKeywords(d.name, "dashboard")}
324
378
  >
325
- <IconLayoutDashboard className="mr-2 h-4 w-4 text-muted-foreground" />
326
- <span className="truncate">{d.name}</span>
327
- {d.hiddenAt ? (
328
- <span className="ml-2 rounded border border-border px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">
329
- Hidden
330
- </span>
331
- ) : null}
379
+ <IconFlask className="mr-2 h-4 w-4 text-muted-foreground" />
380
+ {d.name}
332
381
  </CommandItem>
333
382
  ))}
334
383
  </CommandGroup>
335
- )}
336
-
337
- {extensionsFetching && extensions.length === 0 && (
338
- <CommandLoadingGroup heading="Extensions" rows={3} />
339
- )}
340
384
 
341
- {extensions.length > 0 && (
342
- <CommandGroup heading="Extensions">
343
- {extensions.map((extension) => (
385
+ <CommandGroup heading="Tools">
386
+ {defaultTools.map((t) => (
344
387
  <CommandItem
345
- key={`extension-${extension.id}`}
346
- onSelect={() => go(extensionPath(extension.id, extension.name))}
347
- keywords={commandPaletteKeywords(
348
- extension.name,
349
- extension.description,
350
- "extension",
351
- "tool",
352
- )}
388
+ key={`tool-${t.id}`}
389
+ onSelect={() => go(t.href)}
390
+ keywords={commandPaletteKeywords(t.name, "tool")}
353
391
  >
354
392
  <IconTool className="mr-2 h-4 w-4 text-muted-foreground" />
355
- {extension.name}
393
+ {t.name}
356
394
  </CommandItem>
357
395
  ))}
358
396
  </CommandGroup>
359
- )}
360
397
 
361
- <CommandGroup heading="Dashboards">
362
- {dashboards.map((d) => (
398
+ <CommandGroup heading="Appearance">
363
399
  <CommandItem
364
- key={`dash-${d.id}`}
365
- onSelect={() => go(`/adhoc/${d.id}`)}
366
- keywords={commandPaletteKeywords(d.name, "dashboard")}
400
+ onSelect={() => {
401
+ const nextTheme = isDark ? "light" : "dark";
402
+ setTheme(nextTheme);
403
+ persistThemePreference(nextTheme);
404
+ }}
405
+ keywords={["theme", "dark", "light", "mode"]}
367
406
  >
368
- <IconFlask className="mr-2 h-4 w-4 text-muted-foreground" />
369
- {d.name}
407
+ {isDark ? (
408
+ <IconSun className="mr-2 h-4 w-4 text-muted-foreground" />
409
+ ) : (
410
+ <IconMoon className="mr-2 h-4 w-4 text-muted-foreground" />
411
+ )}
412
+ Toggle {isDark ? "light" : "dark"} mode
370
413
  </CommandItem>
371
- ))}
372
- </CommandGroup>
414
+ </CommandGroup>
373
415
 
374
- <CommandGroup heading="Tools">
375
- {defaultTools.map((t) => (
416
+ <CommandGroup heading="Help">
376
417
  <CommandItem
377
- key={`tool-${t.id}`}
378
- onSelect={() => go(t.href)}
379
- keywords={commandPaletteKeywords(t.name, "tool")}
418
+ onSelect={() => {
419
+ setOpen(false);
420
+ setChangelogOpen(true);
421
+ }}
422
+ keywords={commandPaletteKeywords(
423
+ "What's new",
424
+ "changelog",
425
+ "updates",
426
+ "release notes",
427
+ "changes",
428
+ )}
380
429
  >
381
- <IconTool className="mr-2 h-4 w-4 text-muted-foreground" />
382
- {t.name}
430
+ <IconHistory className="mr-2 h-4 w-4 text-muted-foreground" />
431
+ What's new
383
432
  </CommandItem>
384
- ))}
385
- </CommandGroup>
386
-
387
- <CommandGroup heading="Appearance">
388
- <CommandItem
389
- onSelect={() => {
390
- const nextTheme = isDark ? "light" : "dark";
391
- setTheme(nextTheme);
392
- persistThemePreference(nextTheme);
393
- }}
394
- keywords={["theme", "dark", "light", "mode"]}
395
- >
396
- {isDark ? (
397
- <IconSun className="mr-2 h-4 w-4 text-muted-foreground" />
398
- ) : (
399
- <IconMoon className="mr-2 h-4 w-4 text-muted-foreground" />
400
- )}
401
- Toggle {isDark ? "light" : "dark"} mode
402
- </CommandItem>
403
- </CommandGroup>
404
-
405
- {savedChartsFetching && savedCharts.length === 0 && (
406
- <CommandLoadingGroup heading="Saved Charts" rows={2} />
407
- )}
408
-
409
- {savedCharts.length > 0 && (
410
- <CommandGroup heading="Saved Charts">
411
- {savedCharts.map((c) => (
412
- <CommandItem
413
- key={`chart-${c.id}`}
414
- onSelect={() => go(`/adhoc/explorer?config=${c.id}`)}
415
- keywords={commandPaletteKeywords(
416
- c.name,
417
- "saved chart",
418
- "chart",
419
- )}
420
- >
421
- <IconChartBar className="mr-2 h-4 w-4 text-muted-foreground" />
422
- {c.name}
423
- </CommandItem>
424
- ))}
425
433
  </CommandGroup>
426
- )}
427
- </CommandList>
428
- </CommandDialog>
434
+
435
+ {savedChartsFetching && savedCharts.length === 0 && (
436
+ <CommandLoadingGroup heading="Saved Charts" rows={2} />
437
+ )}
438
+
439
+ {savedCharts.length > 0 && (
440
+ <CommandGroup heading="Saved Charts">
441
+ {savedCharts.map((c) => (
442
+ <CommandItem
443
+ key={`chart-${c.id}`}
444
+ onSelect={() => go(`/dashboards/explorer?config=${c.id}`)}
445
+ keywords={commandPaletteKeywords(
446
+ c.name,
447
+ "saved chart",
448
+ "chart",
449
+ )}
450
+ >
451
+ <IconChartBar className="mr-2 h-4 w-4 text-muted-foreground" />
452
+ {c.name}
453
+ </CommandItem>
454
+ ))}
455
+ </CommandGroup>
456
+ )}
457
+ </CommandList>
458
+ </CommandDialog>
459
+ <ChangelogDialog
460
+ open={changelogOpen}
461
+ onOpenChange={setChangelogOpen}
462
+ markdown={changelog}
463
+ />
464
+ </>
429
465
  );
430
466
  }
@@ -15,16 +15,15 @@ const pageTitles: Record<string, string> = {
15
15
  "/data-dictionary": "Data Dictionary",
16
16
  "/catalog": "Template Catalog",
17
17
  "/analyses": "Analyses",
18
- "/adhoc/explorer": "Explorer",
18
+ "/dashboards/explorer": "Explorer",
19
19
  "/team": "Team",
20
20
  "/settings": "Settings",
21
- "/about": "About",
22
21
  };
23
22
 
24
23
  function resolveTitle(pathname: string): ReactNode {
25
24
  if (pageTitles[pathname]) return pageTitles[pathname];
26
25
 
27
- const adhocMatch = pathname.match(/^\/adhoc\/(.+)$/);
26
+ const adhocMatch = pathname.match(/^\/(?:adhoc|dashboards)\/(.+)$/);
28
27
  if (adhocMatch) {
29
28
  const id = adhocMatch[1];
30
29
  const dash = dashboards.find((d) => d.id === id);
@@ -29,12 +29,14 @@ export function Layout({ children }: LayoutProps) {
29
29
  const navigate = useNavigate();
30
30
 
31
31
  // Analytics has two distinct "primary resources" — dashboards
32
- // (`/adhoc/:id`) and ad-hoc analyses (`/analyses/:id`). Each binds the
33
- // chat to that artifact so a dashboard chat doesn't leak into a
34
- // different analysis (and vice versa). The list pages and overview
35
- // leave scope null so general data questions still work.
32
+ // (`/dashboards/:id`, legacy `/adhoc/:id`) and ad-hoc analyses
33
+ // (`/analyses/:id`). Each binds the chat to that artifact so a dashboard
34
+ // chat doesn't leak into a different analysis (and vice versa). The list
35
+ // pages and overview leave scope null so general data questions still work.
36
36
  const analyticsScope = useMemo(() => {
37
- const dashMatch = location.pathname.match(/^\/adhoc\/([^/]+)/);
37
+ const dashMatch = location.pathname.match(
38
+ /^\/(?:adhoc|dashboards)\/([^/]+)/,
39
+ );
38
40
  if (dashMatch?.[1]) {
39
41
  return { type: "dashboard" as const, id: dashMatch[1] };
40
42
  }