@agent-native/core 0.79.27 → 0.80.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 (497) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +34 -0
  3. package/corpus/core/docs/content/locales/ar-SA/skills-guide.mdx +5 -0
  4. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +55 -1
  5. package/corpus/core/docs/content/locales/de-DE/skills-guide.mdx +5 -0
  6. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +66 -1
  7. package/corpus/core/docs/content/locales/es-ES/skills-guide.mdx +5 -0
  8. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +65 -1
  9. package/corpus/core/docs/content/locales/fr-FR/skills-guide.mdx +5 -0
  10. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +64 -1
  11. package/corpus/core/docs/content/locales/hi-IN/skills-guide.mdx +5 -0
  12. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +59 -1
  13. package/corpus/core/docs/content/locales/ja-JP/skills-guide.mdx +5 -0
  14. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +62 -1
  15. package/corpus/core/docs/content/locales/ko-KR/skills-guide.mdx +5 -0
  16. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +58 -1
  17. package/corpus/core/docs/content/locales/pt-BR/skills-guide.mdx +5 -0
  18. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +62 -1
  19. package/corpus/core/docs/content/locales/zh-CN/skills-guide.mdx +5 -0
  20. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +50 -1
  21. package/corpus/core/docs/content/locales/zh-TW/skills-guide.mdx +5 -0
  22. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +52 -1
  23. package/corpus/core/docs/content/skills-guide.mdx +5 -0
  24. package/corpus/core/docs/content/template-design.mdx +59 -1
  25. package/corpus/core/package.json +2 -1
  26. package/corpus/core/src/agent/engine/index.ts +1 -0
  27. package/corpus/core/src/agent/engine/registry.ts +40 -0
  28. package/corpus/core/src/agent/production-agent.ts +6 -2
  29. package/corpus/core/src/application-state/handlers.ts +1 -1
  30. package/corpus/core/src/brand-kit/index.ts +1 -1
  31. package/corpus/core/src/cli/design-connect.ts +490 -0
  32. package/corpus/core/src/cli/index.ts +16 -0
  33. package/corpus/core/src/cli/skills.ts +144 -3
  34. package/corpus/core/src/client/AgentPanel.tsx +1 -1
  35. package/corpus/core/src/client/AssistantChat.tsx +43 -7
  36. package/corpus/core/src/client/MultiTabAssistantChat.tsx +1 -1
  37. package/corpus/core/src/client/agent-chat.ts +27 -3
  38. package/corpus/core/src/client/blocks/library/MermaidBlock.tsx +1 -1
  39. package/corpus/core/src/client/blocks/library/diagram.tsx +2 -2
  40. package/corpus/core/src/client/blocks/library/wireframe.tsx +1 -1
  41. package/corpus/core/src/client/chat/message-components.tsx +1 -1
  42. package/corpus/core/src/client/chat-model-groups.ts +1 -2
  43. package/corpus/core/src/client/components/LiveCursorOverlay.tsx +33 -66
  44. package/corpus/core/src/client/composer/TiptapComposer.tsx +99 -24
  45. package/corpus/core/src/client/composer/useVoiceDictation.ts +429 -260
  46. package/corpus/core/src/client/extensions/portable-extension.ts +1 -1
  47. package/corpus/core/src/client/frame-protocol.ts +17 -2
  48. package/corpus/core/src/client/rich-markdown-editor/RegistryBlockNode.tsx +2 -2
  49. package/corpus/core/src/client/sharing/ShareButton.tsx +20 -15
  50. package/corpus/core/src/client/use-agent-engine-configured.ts +80 -28
  51. package/corpus/core/src/code-agents/transcript-normalizer.ts +1 -1
  52. package/corpus/core/src/extensions/path.ts +1 -4
  53. package/corpus/core/src/integrations/a2a-continuation-processor.ts +1 -1
  54. package/corpus/core/src/mcp/build-server.ts +1 -1
  55. package/corpus/core/src/org/handlers.ts +5 -5
  56. package/corpus/core/src/org/plugin.ts +2 -2
  57. package/corpus/core/src/scripts/call-agent.ts +1 -1
  58. package/corpus/core/src/scripts/db/safety.ts +1 -1
  59. package/corpus/core/src/server/auth.ts +3 -0
  60. package/corpus/core/src/server/builder-design-systems.ts +308 -0
  61. package/corpus/core/src/server/core-routes-plugin.ts +29 -3
  62. package/corpus/core/src/server/index.ts +8 -0
  63. package/corpus/core/src/server/transcribe-voice.ts +57 -22
  64. package/corpus/core/src/shared/mcp-embed-headers.ts +23 -1
  65. package/corpus/core/src/styles/agent-native.css +60 -4
  66. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  67. package/corpus/core/src/usage/store.ts +2 -2
  68. package/corpus/core/src/vite/client.ts +2 -0
  69. package/corpus/core/src/voice/index.ts +18 -0
  70. package/corpus/core/src/voice/voice-cleanup-prompt.ts +38 -0
  71. package/corpus/core/src/voice/voice-context.ts +217 -0
  72. package/corpus/core/src/voice/voice-replacements.ts +75 -0
  73. package/corpus/templates/analytics/AGENTS.md +4 -3
  74. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +298 -15
  75. package/corpus/templates/analytics/actions/get-sql-dashboard.ts +9 -4
  76. package/corpus/templates/analytics/actions/list-session-recordings.ts +6 -1
  77. package/corpus/templates/analytics/actions/mutate-dashboard.ts +18 -2
  78. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +12 -2
  79. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +557 -400
  80. package/corpus/templates/analytics/app/global.css +0 -4
  81. package/corpus/templates/analytics/app/hooks/use-replay-storage-status.ts +66 -0
  82. package/corpus/templates/analytics/app/i18n/zh-TW.ts +39 -0
  83. package/corpus/templates/analytics/app/i18n-data.ts +424 -0
  84. package/corpus/templates/analytics/app/pages/Settings.tsx +333 -0
  85. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +2 -1
  86. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/dashboard-layout.ts +121 -3
  87. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +82 -34
  88. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +7 -0
  89. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +144 -36
  90. package/corpus/templates/analytics/changelog/2026-06-28-ask-tab-now-matches-the-darker-app-background.md +6 -0
  91. package/corpus/templates/analytics/changelog/2026-06-28-dashboard-email-reports-now-use-cleaner-light-mode-snapshots.md +6 -0
  92. package/corpus/templates/analytics/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  93. package/corpus/templates/analytics/changelog/2026-06-28-sessions-now-show-only-signed-in-recordings-with-playable-re.md +6 -0
  94. package/corpus/templates/analytics/changelog/2026-06-29-analytics-agents-can-now-place-new-charts-into-requested-das.md +6 -0
  95. package/corpus/templates/analytics/changelog/2026-06-29-analytics-queries-now-report-failed-source-query-errors-inst.md +6 -0
  96. package/corpus/templates/analytics/changelog/2026-06-29-charts-can-now-be-dropped-between-full-dashboard-rows-to-cre.md +6 -0
  97. package/corpus/templates/analytics/changelog/2026-06-29-dashboard-email-reports-include-the-full-dashboard-image-wit.md +6 -0
  98. package/corpus/templates/analytics/changelog/2026-06-29-main-surface-border-reaches-the-top.md +6 -0
  99. package/corpus/templates/analytics/changelog/2026-06-29-session-replay-now-records-playable-sessions-in-production-a.md +6 -0
  100. package/corpus/templates/analytics/changelog/2026-06-29-set-up-session-replay-storage-from-settings-connect-builder-.md +6 -0
  101. package/corpus/templates/analytics/scripts/cleanup-empty-session-recordings.ts +102 -0
  102. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +3 -3
  103. package/corpus/templates/analytics/server/lib/dashboard-report.ts +75 -30
  104. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +5 -2
  105. package/corpus/templates/analytics/server/lib/real-data-actions.ts +81 -20
  106. package/corpus/templates/analytics/server/lib/replay-storage.ts +79 -0
  107. package/corpus/templates/analytics/server/lib/s3-upload-provider.ts +255 -0
  108. package/corpus/templates/analytics/server/lib/session-replay.ts +53 -12
  109. package/corpus/templates/analytics/server/plugins/agent-chat.ts +11 -2
  110. package/corpus/templates/analytics/server/plugins/onboarding.ts +97 -0
  111. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +4 -4
  112. package/corpus/templates/assets/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  113. package/corpus/templates/brain/app/components/layout/Layout.tsx +29 -2
  114. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +131 -42
  115. package/corpus/templates/brain/app/i18n/zh-TW.ts +2 -0
  116. package/corpus/templates/brain/app/i18n-data.ts +20 -0
  117. package/corpus/templates/brain/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  118. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +29 -1
  119. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +417 -299
  120. package/corpus/templates/calendar/app/i18n/zh-TW.ts +2 -0
  121. package/corpus/templates/calendar/app/i18n-data.ts +20 -0
  122. package/corpus/templates/calendar/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  123. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +6 -19
  124. package/corpus/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  125. package/corpus/templates/clips/AGENTS.md +4 -0
  126. package/corpus/templates/clips/actions/cleanup-transcript.ts +39 -9
  127. package/corpus/templates/clips/actions/finalize-meeting.ts +81 -12
  128. package/corpus/templates/clips/actions/lib/agents-md-context.ts +4 -1
  129. package/corpus/templates/clips/app/components/library/library-layout.tsx +3 -3
  130. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +1 -1
  131. package/corpus/templates/clips/app/components/player/share-dialog.tsx +2 -2
  132. package/corpus/templates/clips/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
  133. package/corpus/templates/clips/desktop/src/lib/personal-vocabulary.ts +13 -8
  134. package/corpus/templates/clips/desktop/src/lib/recorder.ts +24 -0
  135. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +105 -5
  136. package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +60 -1
  137. package/corpus/templates/content/actions/set-image-alt-text.ts +1 -1
  138. package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +1 -1
  139. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +1 -1
  140. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -5
  141. package/corpus/templates/content/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  142. package/corpus/templates/content/shared/document-export.ts +1 -1
  143. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +8 -18
  144. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +154 -0
  145. package/corpus/templates/design/AGENTS.md +95 -5
  146. package/corpus/templates/design/DESIGN.md +82 -0
  147. package/corpus/templates/design/DEVELOPING.md +43 -0
  148. package/corpus/templates/design/actions/add-localhost-screens.ts +453 -0
  149. package/corpus/templates/design/actions/apply-shader.ts +277 -0
  150. package/corpus/templates/design/actions/apply-visual-edit.ts +303 -0
  151. package/corpus/templates/design/actions/connect-localhost.ts +183 -0
  152. package/corpus/templates/design/actions/edit-design.ts +195 -42
  153. package/corpus/templates/design/actions/generate-design.ts +71 -1
  154. package/corpus/templates/design/actions/generate-screens.ts +193 -0
  155. package/corpus/templates/design/actions/get-code-layer-projection.ts +191 -0
  156. package/corpus/templates/design/actions/get-shader.ts +119 -0
  157. package/corpus/templates/design/actions/index-design-system-with-builder.ts +259 -0
  158. package/corpus/templates/design/actions/list-localhost-connections.ts +95 -0
  159. package/corpus/templates/design/actions/navigate.ts +55 -2
  160. package/corpus/templates/design/actions/update-file.ts +9 -2
  161. package/corpus/templates/design/actions/view-screen.ts +68 -1
  162. package/corpus/templates/design/agent-native.app-skill.json +10 -0
  163. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +719 -0
  164. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +2120 -103
  165. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +74 -38
  166. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +401 -0
  167. package/corpus/templates/design/app/components/design/EditPanel.tsx +3966 -440
  168. package/corpus/templates/design/app/components/design/LayersPanel.tsx +1473 -0
  169. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +3940 -147
  170. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +700 -13
  171. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +105 -63
  172. package/corpus/templates/design/app/components/design/index.ts +0 -5
  173. package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +353 -0
  174. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +1589 -0
  175. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +511 -0
  176. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +395 -0
  177. package/corpus/templates/design/app/components/design/inspector/FigmaColorPicker.tsx +2010 -0
  178. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +601 -0
  179. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +242 -0
  180. package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +420 -0
  181. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +238 -0
  182. package/corpus/templates/design/app/components/design/inspector/ShaderControls.stories.tsx +71 -0
  183. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +575 -0
  184. package/corpus/templates/design/app/components/design/inspector/ShaderEffectRow.tsx +106 -0
  185. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +423 -0
  186. package/corpus/templates/design/app/components/design/inspector/figma-icons.tsx +741 -0
  187. package/corpus/templates/design/app/components/design/inspector/index.ts +87 -0
  188. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +201 -0
  189. package/corpus/templates/design/app/components/design/types.ts +23 -0
  190. package/corpus/templates/design/app/components/layout/Layout.tsx +24 -13
  191. package/corpus/templates/design/app/components/layout/Sidebar.tsx +4 -4
  192. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +474 -36
  193. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +22 -5
  194. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +24 -11
  195. package/corpus/templates/design/app/global.css +149 -5
  196. package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -0
  197. package/corpus/templates/design/app/hooks/use-navigation-state.ts +130 -8
  198. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +329 -0
  199. package/corpus/templates/design/app/i18n/zh-TW.ts +277 -0
  200. package/corpus/templates/design/app/i18n-data.ts +3028 -1
  201. package/corpus/templates/design/app/pages/DesignEditor.tsx +5831 -904
  202. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +57 -221
  203. package/corpus/templates/design/changelog/2026-06-28-annotate-mode-now-combines-drawing-and-comment-pins-in-one-c.md +6 -0
  204. package/corpus/templates/design/changelog/2026-06-28-design-editor-panel-borders-are-cleaner-so-the-canvas-edge-s.md +6 -0
  205. package/corpus/templates/design/changelog/2026-06-28-drawing-prompts-now-reliably-open-and-submit-to-the-design-a.md +6 -0
  206. package/corpus/templates/design/changelog/2026-06-28-editor-app-menus-now-use-an-outline-agent-native-mark-with-b.md +6 -0
  207. package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +6 -0
  208. package/corpus/templates/design/changelog/2026-06-28-layer-selection-now-updates-chat-context-without-opening-the.md +6 -0
  209. package/corpus/templates/design/changelog/2026-06-28-layer-selections-now-preserve-hidden-and-locked-canvas-state.md +6 -0
  210. package/corpus/templates/design/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  211. package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +6 -0
  212. package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +6 -0
  213. package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-handles-zooming-drawing-opening-and-dele.md +6 -0
  214. package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-selects-screens-on-click-and-opens-them-.md +6 -0
  215. package/corpus/templates/design/changelog/2026-06-28-screen-overview-zooms-into-the-active-screen-with-smoother-e.md +6 -0
  216. package/corpus/templates/design/changelog/2026-06-28-selected-element-chips-in-chat-are-shorter-and-easier-to-sca.md +6 -0
  217. package/corpus/templates/design/changelog/2026-06-28-the-design-editor-toolbar-is-more-compact-and-the-app-menu-m.md +6 -0
  218. package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-at-the-top-of-the-design-sidebar-instead-of-.md +6 -0
  219. package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-in-the-right-inspector-beside-the-design-tab.md +6 -0
  220. package/corpus/templates/design/changelog/2026-06-29-active-sidebar-rows-use-soft-highlights.md +6 -0
  221. package/corpus/templates/design/changelog/2026-06-29-agents-can-now-open-screen-overview-focus-screens-and-add.md +6 -0
  222. package/corpus/templates/design/changelog/2026-06-29-canvas-selection-no-longer-flashes-broken-prototype-html-whe.md +6 -0
  223. package/corpus/templates/design/changelog/2026-06-29-command-menu-selections-are-clearer-in-dark-mode.md +6 -0
  224. package/corpus/templates/design/changelog/2026-06-29-design-agents-now-edit-broad-copy-changes-more-reliably.md +6 -0
  225. package/corpus/templates/design/changelog/2026-06-29-design-editor-extensions-now-run-inline-beside-the-artboard.md +6 -0
  226. package/corpus/templates/design/changelog/2026-06-29-design-mode-top-chrome-now-groups-collaborators-preview-shar.md +6 -0
  227. package/corpus/templates/design/changelog/2026-06-29-element-selection-now-stays-on-the-intended-layer-after-sele.md +6 -0
  228. package/corpus/templates/design/changelog/2026-06-29-screen-overview-full-view-controls-now-sit-above-frames-inst.md +6 -0
  229. package/corpus/templates/design/changelog/2026-06-29-screen-overview-tools-can-draw-shapes-create-screens-and-kee.md +6 -0
  230. package/corpus/templates/design/changelog/2026-06-29-sidebars-use-darker-chrome-and-chat-warns-immediately.md +6 -0
  231. package/corpus/templates/design/changelog/2026-06-29-the-pen-tool-now-creates-anchor-based-bezier-vectors-with-ha.md +6 -0
  232. package/corpus/templates/design/changelog/2026-06-29-visual-edit-can-open-localhost-routes-as-url-backed-screens.md +6 -0
  233. package/corpus/templates/design/package.json +1 -0
  234. package/corpus/templates/design/server/db/schema.ts +26 -0
  235. package/corpus/templates/design/server/handlers/import-figma-system.ts +38 -85
  236. package/corpus/templates/design/server/lib/design-snapshot.ts +9 -1
  237. package/corpus/templates/design/server/plugins/agent-chat.ts +3 -0
  238. package/corpus/templates/design/shared/api.ts +27 -0
  239. package/corpus/templates/design/shared/canvas-frames.ts +103 -0
  240. package/corpus/templates/design/shared/canvas-math.ts +1058 -0
  241. package/corpus/templates/design/shared/code-layer.ts +2412 -0
  242. package/corpus/templates/design/shared/color-utils.ts +180 -0
  243. package/corpus/templates/design/shared/generation-session.ts +61 -0
  244. package/corpus/templates/design/shared/html-content.ts +21 -0
  245. package/corpus/templates/design/shared/pen-path.ts +207 -0
  246. package/corpus/templates/design/shared/shader-presets.ts +782 -0
  247. package/corpus/templates/design/shared/shader-safety.ts +137 -0
  248. package/corpus/templates/design/shared/source-mode.ts +237 -0
  249. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +149 -6
  250. package/corpus/templates/forms/app/i18n/ar-SA.ts +2 -0
  251. package/corpus/templates/forms/app/i18n/de-DE.ts +2 -0
  252. package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
  253. package/corpus/templates/forms/app/i18n/es-ES.ts +2 -0
  254. package/corpus/templates/forms/app/i18n/fr-FR.ts +2 -0
  255. package/corpus/templates/forms/app/i18n/hi-IN.ts +2 -0
  256. package/corpus/templates/forms/app/i18n/ja-JP.ts +2 -0
  257. package/corpus/templates/forms/app/i18n/ko-KR.ts +2 -0
  258. package/corpus/templates/forms/app/i18n/pt-BR.ts +2 -0
  259. package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
  260. package/corpus/templates/forms/app/i18n/zh-TW.ts +2 -0
  261. package/corpus/templates/forms/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  262. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +2 -2
  263. package/corpus/templates/macros/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
  264. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +408 -247
  265. package/corpus/templates/mail/app/i18n/ar-SA.ts +4 -0
  266. package/corpus/templates/mail/app/i18n/de-DE.ts +4 -0
  267. package/corpus/templates/mail/app/i18n/en-US.ts +4 -0
  268. package/corpus/templates/mail/app/i18n/es-ES.ts +4 -0
  269. package/corpus/templates/mail/app/i18n/fr-FR.ts +4 -0
  270. package/corpus/templates/mail/app/i18n/hi-IN.ts +4 -0
  271. package/corpus/templates/mail/app/i18n/ja-JP.ts +4 -0
  272. package/corpus/templates/mail/app/i18n/ko-KR.ts +4 -0
  273. package/corpus/templates/mail/app/i18n/pt-BR.ts +4 -0
  274. package/corpus/templates/mail/app/i18n/zh-CN.ts +4 -0
  275. package/corpus/templates/mail/app/i18n/zh-TW.ts +4 -0
  276. package/corpus/templates/mail/app/lib/utils.ts +2 -2
  277. package/corpus/templates/mail/changelog/2026-06-28-pinned-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  278. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +6 -8
  279. package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +1 -1
  280. package/corpus/templates/plan/app/global.css +61 -78
  281. package/corpus/templates/plan/app/pages/PlansPage.tsx +8 -0
  282. package/corpus/templates/plan/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  283. package/corpus/templates/plan/changelog/2026-06-28-plans-use-the-shared-neutral-light-and-dark-theme.md +6 -0
  284. package/corpus/templates/plan/changelog/2026-06-28-sending-open-feedback-from-a-plan-now-opens-the-inline-plan-.md +6 -0
  285. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +9 -10
  286. package/corpus/templates/slides/AGENTS.md +3 -2
  287. package/corpus/templates/slides/actions/import-file.ts +26 -17
  288. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +259 -0
  289. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +35 -167
  290. package/corpus/templates/slides/app/components/design-system/fig-import-response.ts +9 -13
  291. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +5 -5
  292. package/corpus/templates/slides/app/context/DeckContext.tsx +1 -1
  293. package/corpus/templates/slides/app/i18n/ar-SA.ts +9 -37
  294. package/corpus/templates/slides/app/i18n/de-DE.ts +10 -25
  295. package/corpus/templates/slides/app/i18n/en-US.ts +9 -26
  296. package/corpus/templates/slides/app/i18n/es-ES.ts +10 -28
  297. package/corpus/templates/slides/app/i18n/fr-FR.ts +10 -28
  298. package/corpus/templates/slides/app/i18n/hi-IN.ts +9 -26
  299. package/corpus/templates/slides/app/i18n/ja-JP.ts +10 -22
  300. package/corpus/templates/slides/app/i18n/ko-KR.ts +9 -23
  301. package/corpus/templates/slides/app/i18n/pt-BR.ts +10 -28
  302. package/corpus/templates/slides/app/i18n/zh-CN.ts +9 -22
  303. package/corpus/templates/slides/app/i18n/zh-TW.ts +9 -22
  304. package/corpus/templates/slides/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  305. package/corpus/templates/slides/server/handlers/import-figma-system.ts +44 -12
  306. package/corpus/templates/slides/server/lib/chat-attachments.ts +1 -1
  307. package/corpus/templates/videos/app/components/NewCompositionPopover.tsx +1 -1
  308. package/corpus/templates/videos/app/components/Sidebar.tsx +2 -2
  309. package/corpus/templates/videos/app/components/layout/Layout.tsx +29 -2
  310. package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +113 -30
  311. package/corpus/templates/videos/app/i18n/ar-SA.ts +2 -0
  312. package/corpus/templates/videos/app/i18n/de-DE.ts +2 -0
  313. package/corpus/templates/videos/app/i18n/en-US.ts +2 -0
  314. package/corpus/templates/videos/app/i18n/es-ES.ts +2 -0
  315. package/corpus/templates/videos/app/i18n/fr-FR.ts +2 -0
  316. package/corpus/templates/videos/app/i18n/hi-IN.ts +2 -0
  317. package/corpus/templates/videos/app/i18n/ja-JP.ts +2 -0
  318. package/corpus/templates/videos/app/i18n/ko-KR.ts +2 -0
  319. package/corpus/templates/videos/app/i18n/pt-BR.ts +2 -0
  320. package/corpus/templates/videos/app/i18n/zh-CN.ts +2 -0
  321. package/corpus/templates/videos/app/i18n/zh-TW.ts +2 -0
  322. package/corpus/templates/videos/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  323. package/dist/agent/engine/index.d.ts +1 -1
  324. package/dist/agent/engine/index.d.ts.map +1 -1
  325. package/dist/agent/engine/index.js +1 -1
  326. package/dist/agent/engine/index.js.map +1 -1
  327. package/dist/agent/engine/registry.d.ts +9 -0
  328. package/dist/agent/engine/registry.d.ts.map +1 -1
  329. package/dist/agent/engine/registry.js +37 -0
  330. package/dist/agent/engine/registry.js.map +1 -1
  331. package/dist/agent/production-agent.d.ts.map +1 -1
  332. package/dist/agent/production-agent.js +4 -3
  333. package/dist/agent/production-agent.js.map +1 -1
  334. package/dist/application-state/handlers.js +1 -1
  335. package/dist/application-state/handlers.js.map +1 -1
  336. package/dist/brand-kit/index.d.ts +1 -1
  337. package/dist/brand-kit/index.js +1 -1
  338. package/dist/brand-kit/index.js.map +1 -1
  339. package/dist/cli/design-connect.d.ts +52 -0
  340. package/dist/cli/design-connect.d.ts.map +1 -0
  341. package/dist/cli/design-connect.js +409 -0
  342. package/dist/cli/design-connect.js.map +1 -0
  343. package/dist/cli/index.js +15 -0
  344. package/dist/cli/index.js.map +1 -1
  345. package/dist/cli/skills.d.ts +3 -0
  346. package/dist/cli/skills.d.ts.map +1 -1
  347. package/dist/cli/skills.js +139 -3
  348. package/dist/cli/skills.js.map +1 -1
  349. package/dist/client/AgentPanel.js +1 -1
  350. package/dist/client/AgentPanel.js.map +1 -1
  351. package/dist/client/AssistantChat.d.ts.map +1 -1
  352. package/dist/client/AssistantChat.js +38 -8
  353. package/dist/client/AssistantChat.js.map +1 -1
  354. package/dist/client/MultiTabAssistantChat.js +1 -1
  355. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  356. package/dist/client/agent-chat.d.ts +6 -0
  357. package/dist/client/agent-chat.d.ts.map +1 -1
  358. package/dist/client/agent-chat.js +17 -3
  359. package/dist/client/agent-chat.js.map +1 -1
  360. package/dist/client/blocks/library/MermaidBlock.js +1 -1
  361. package/dist/client/blocks/library/MermaidBlock.js.map +1 -1
  362. package/dist/client/blocks/library/diagram.js +1 -1
  363. package/dist/client/blocks/library/diagram.js.map +1 -1
  364. package/dist/client/blocks/library/wireframe.js +1 -1
  365. package/dist/client/blocks/library/wireframe.js.map +1 -1
  366. package/dist/client/chat/message-components.js +1 -1
  367. package/dist/client/chat/message-components.js.map +1 -1
  368. package/dist/client/chat-model-groups.d.ts.map +1 -1
  369. package/dist/client/chat-model-groups.js +1 -2
  370. package/dist/client/chat-model-groups.js.map +1 -1
  371. package/dist/client/components/LiveCursorOverlay.d.ts +1 -2
  372. package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -1
  373. package/dist/client/components/LiveCursorOverlay.js +19 -40
  374. package/dist/client/components/LiveCursorOverlay.js.map +1 -1
  375. package/dist/client/composer/TiptapComposer.d.ts +3 -1
  376. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  377. package/dist/client/composer/TiptapComposer.js +86 -24
  378. package/dist/client/composer/TiptapComposer.js.map +1 -1
  379. package/dist/client/composer/useVoiceDictation.d.ts +9 -0
  380. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  381. package/dist/client/composer/useVoiceDictation.js +154 -32
  382. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  383. package/dist/client/extensions/portable-extension.d.ts +1 -1
  384. package/dist/client/extensions/portable-extension.d.ts.map +1 -1
  385. package/dist/client/extensions/portable-extension.js.map +1 -1
  386. package/dist/client/frame-protocol.d.ts +17 -2
  387. package/dist/client/frame-protocol.d.ts.map +1 -1
  388. package/dist/client/frame-protocol.js.map +1 -1
  389. package/dist/client/rich-markdown-editor/RegistryBlockNode.js +2 -2
  390. package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -1
  391. package/dist/client/sharing/ShareButton.d.ts +2 -0
  392. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  393. package/dist/client/sharing/ShareButton.js +7 -6
  394. package/dist/client/sharing/ShareButton.js.map +1 -1
  395. package/dist/client/use-agent-engine-configured.d.ts +5 -0
  396. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  397. package/dist/client/use-agent-engine-configured.js +51 -25
  398. package/dist/client/use-agent-engine-configured.js.map +1 -1
  399. package/dist/code-agents/transcript-normalizer.js +1 -1
  400. package/dist/code-agents/transcript-normalizer.js.map +1 -1
  401. package/dist/collab/routes.d.ts +1 -1
  402. package/dist/extensions/path.d.ts +1 -1
  403. package/dist/extensions/path.d.ts.map +1 -1
  404. package/dist/extensions/path.js.map +1 -1
  405. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  406. package/dist/integrations/a2a-continuation-processor.js +1 -1
  407. package/dist/integrations/a2a-continuation-processor.js.map +1 -1
  408. package/dist/mcp/build-server.d.ts +1 -1
  409. package/dist/mcp/build-server.d.ts.map +1 -1
  410. package/dist/mcp/build-server.js.map +1 -1
  411. package/dist/notifications/routes.d.ts +3 -3
  412. package/dist/observability/routes.d.ts +5 -5
  413. package/dist/org/handlers.js +5 -5
  414. package/dist/org/handlers.js.map +1 -1
  415. package/dist/org/plugin.js +2 -2
  416. package/dist/org/plugin.js.map +1 -1
  417. package/dist/scripts/call-agent.js +1 -1
  418. package/dist/scripts/call-agent.js.map +1 -1
  419. package/dist/scripts/db/safety.js +1 -1
  420. package/dist/scripts/db/safety.js.map +1 -1
  421. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  422. package/dist/server/auth.d.ts.map +1 -1
  423. package/dist/server/auth.js +3 -0
  424. package/dist/server/auth.js.map +1 -1
  425. package/dist/server/builder-design-systems.d.ts +28 -0
  426. package/dist/server/builder-design-systems.d.ts.map +1 -0
  427. package/dist/server/builder-design-systems.js +217 -0
  428. package/dist/server/builder-design-systems.js.map +1 -0
  429. package/dist/server/core-routes-plugin.d.ts +1 -0
  430. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  431. package/dist/server/core-routes-plugin.js +20 -3
  432. package/dist/server/core-routes-plugin.js.map +1 -1
  433. package/dist/server/index.d.ts +1 -0
  434. package/dist/server/index.d.ts.map +1 -1
  435. package/dist/server/index.js +1 -0
  436. package/dist/server/index.js.map +1 -1
  437. package/dist/server/transcribe-voice.d.ts +1 -1
  438. package/dist/server/transcribe-voice.d.ts.map +1 -1
  439. package/dist/server/transcribe-voice.js +40 -24
  440. package/dist/server/transcribe-voice.js.map +1 -1
  441. package/dist/shared/mcp-embed-headers.d.ts +1 -0
  442. package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
  443. package/dist/shared/mcp-embed-headers.js +20 -1
  444. package/dist/shared/mcp-embed-headers.js.map +1 -1
  445. package/dist/styles/agent-native.css +60 -4
  446. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  447. package/dist/usage/store.js +2 -2
  448. package/dist/usage/store.js.map +1 -1
  449. package/dist/vite/client.d.ts.map +1 -1
  450. package/dist/vite/client.js +2 -0
  451. package/dist/vite/client.js.map +1 -1
  452. package/dist/voice/index.d.ts +5 -0
  453. package/dist/voice/index.d.ts.map +1 -0
  454. package/dist/voice/index.js +4 -0
  455. package/dist/voice/index.js.map +1 -0
  456. package/dist/voice/voice-cleanup-prompt.d.ts +6 -0
  457. package/dist/voice/voice-cleanup-prompt.d.ts.map +1 -0
  458. package/dist/voice/voice-cleanup-prompt.js +26 -0
  459. package/dist/voice/voice-cleanup-prompt.js.map +1 -0
  460. package/dist/voice/voice-context.d.ts +25 -0
  461. package/dist/voice/voice-context.d.ts.map +1 -0
  462. package/dist/voice/voice-context.js +156 -0
  463. package/dist/voice/voice-context.js.map +1 -0
  464. package/dist/voice/voice-replacements.d.ts +4 -0
  465. package/dist/voice/voice-replacements.d.ts.map +1 -0
  466. package/dist/voice/voice-replacements.js +52 -0
  467. package/dist/voice/voice-replacements.js.map +1 -0
  468. package/docs/content/locales/ar-SA/skills-guide.mdx +5 -0
  469. package/docs/content/locales/ar-SA/template-design.mdx +55 -1
  470. package/docs/content/locales/de-DE/skills-guide.mdx +5 -0
  471. package/docs/content/locales/de-DE/template-design.mdx +66 -1
  472. package/docs/content/locales/es-ES/skills-guide.mdx +5 -0
  473. package/docs/content/locales/es-ES/template-design.mdx +65 -1
  474. package/docs/content/locales/fr-FR/skills-guide.mdx +5 -0
  475. package/docs/content/locales/fr-FR/template-design.mdx +64 -1
  476. package/docs/content/locales/hi-IN/skills-guide.mdx +5 -0
  477. package/docs/content/locales/hi-IN/template-design.mdx +59 -1
  478. package/docs/content/locales/ja-JP/skills-guide.mdx +5 -0
  479. package/docs/content/locales/ja-JP/template-design.mdx +62 -1
  480. package/docs/content/locales/ko-KR/skills-guide.mdx +5 -0
  481. package/docs/content/locales/ko-KR/template-design.mdx +58 -1
  482. package/docs/content/locales/pt-BR/skills-guide.mdx +5 -0
  483. package/docs/content/locales/pt-BR/template-design.mdx +62 -1
  484. package/docs/content/locales/zh-CN/skills-guide.mdx +5 -0
  485. package/docs/content/locales/zh-CN/template-design.mdx +50 -1
  486. package/docs/content/locales/zh-TW/skills-guide.mdx +5 -0
  487. package/docs/content/locales/zh-TW/template-design.mdx +52 -1
  488. package/docs/content/skills-guide.mdx +5 -0
  489. package/docs/content/template-design.mdx +59 -1
  490. package/package.json +2 -1
  491. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  492. package/corpus/templates/design/actions/import-figma-file.ts +0 -166
  493. package/corpus/templates/design/app/components/design/DesignToolbar.tsx +0 -339
  494. package/corpus/templates/design/app/components/design/PresentMode.tsx +0 -68
  495. package/corpus/templates/design/app/components/design/ViewportTabs.tsx +0 -149
  496. package/corpus/templates/design/app/components/design/ZoomControls.tsx +0 -157
  497. package/corpus/templates/slides/server/lib/fig-design-system.ts +0 -110
@@ -17,7 +17,6 @@ import {
17
17
  useDroppable,
18
18
  DndContext,
19
19
  DragOverlay,
20
- pointerWithin,
21
20
  PointerSensor,
22
21
  useSensor,
23
22
  useSensors,
@@ -106,9 +105,11 @@ import { DashboardSkeleton } from "../DashboardSkeleton";
106
105
  import {
107
106
  availableDropSlotIdsForPanel,
108
107
  buildDashboardPanelGroups,
108
+ columnExpansionForDropSlot,
109
109
  distanceFromPointerToRect,
110
110
  dropSlotId,
111
111
  movePanelToDropSlot,
112
+ preferredDropSlotId,
112
113
  readDropSlot,
113
114
  removePanelFromLayout,
114
115
  sameDropSlot,
@@ -427,6 +428,7 @@ export default function SqlDashboardPage() {
427
428
  const navigate = useNavigate();
428
429
  const dashboardId = searchParams.get("id") || routeId;
429
430
  const reportScreenshot = searchParams.get("reportScreenshot") === "1";
431
+ const reportSettingsRequested = searchParams.get("reportSettings") === "1";
430
432
  const reportPanelLimit = reportScreenshot
431
433
  ? parseReportPanelLimit(searchParams.get("reportPanelLimit"))
432
434
  : null;
@@ -977,6 +979,11 @@ export default function SqlDashboardPage() {
977
979
  const slot = readDropSlot(event.over?.data.current);
978
980
  if (!slot) return;
979
981
  const panelId = String(event.active.id);
982
+ const columnExpansion = columnExpansionForDropSlot(
983
+ buildDashboardPanelGroups(dashboard.panels, dashboardColumns),
984
+ panelId,
985
+ slot,
986
+ );
980
987
  const nextPanels = movePanelToDropSlot(
981
988
  dashboard.panels,
982
989
  panelId,
@@ -984,9 +991,19 @@ export default function SqlDashboardPage() {
984
991
  dashboardColumns,
985
992
  );
986
993
  if (nextPanels === dashboard.panels) return;
994
+ const persistedPanels = columnExpansion?.sectionPanelId
995
+ ? nextPanels.map((panel) =>
996
+ panel.id === columnExpansion.sectionPanelId
997
+ ? { ...panel, columns: columnExpansion.columns }
998
+ : panel,
999
+ )
1000
+ : nextPanels;
987
1001
  persist({
988
1002
  ...dashboard,
989
- panels: nextPanels,
1003
+ ...(columnExpansion && !columnExpansion.sectionPanelId
1004
+ ? { columns: columnExpansion.columns }
1005
+ : {}),
1006
+ panels: persistedPanels,
990
1007
  });
991
1008
  },
992
1009
  [dashboard, dashboardColumns, persist],
@@ -1033,6 +1050,28 @@ export default function SqlDashboardPage() {
1033
1050
  return out;
1034
1051
  }, [dashboard?.filters, searchParams]);
1035
1052
 
1053
+ useEffect(() => {
1054
+ if (!reportScreenshot && reportSettingsRequested) {
1055
+ setEmailReportOpen(true);
1056
+ }
1057
+ }, [reportScreenshot, reportSettingsRequested]);
1058
+
1059
+ const handleEmailReportOpenChange = useCallback(
1060
+ (open: boolean) => {
1061
+ setEmailReportOpen(open);
1062
+ if (open || !reportSettingsRequested) return;
1063
+ setSearchParams(
1064
+ (prev) => {
1065
+ const next = new URLSearchParams(prev);
1066
+ next.delete("reportSettings");
1067
+ return next;
1068
+ },
1069
+ { replace: true },
1070
+ );
1071
+ },
1072
+ [reportSettingsRequested, setSearchParams],
1073
+ );
1074
+
1036
1075
  // Distinct tab values across panels in declaration order. When this is
1037
1076
  // non-empty the dashboard renders a tab strip and filters panels by tab.
1038
1077
  const tabs = useMemo<string[]>(() => {
@@ -1131,36 +1170,43 @@ export default function SqlDashboardPage() {
1131
1170
 
1132
1171
  if (droppableContainers.length === 0) return [];
1133
1172
 
1134
- const exactCollisions = pointerWithin({
1135
- ...args,
1136
- droppableContainers,
1137
- });
1138
- if (exactCollisions.length > 0) return exactCollisions;
1139
-
1140
1173
  if (!args.pointerCoordinates) return [];
1141
1174
 
1142
- let closestId: string | null = null;
1143
- let closestContainer: (typeof droppableContainers)[number] | null = null;
1144
- let closestValue = Number.MAX_VALUE;
1145
- for (const droppableContainer of droppableContainers) {
1175
+ const candidates = droppableContainers.flatMap((droppableContainer) => {
1146
1176
  const rect = args.droppableRects.get(droppableContainer.id);
1147
- if (!rect) continue;
1148
-
1149
- const value = distanceFromPointerToRect(args.pointerCoordinates, rect);
1150
- if (value < closestValue) {
1151
- closestId = String(droppableContainer.id);
1152
- closestContainer = droppableContainer;
1153
- closestValue = value;
1154
- }
1155
- }
1156
-
1157
- return closestId && closestContainer
1177
+ const slot = readDropSlot(droppableContainer.data.current);
1178
+ if (!rect || !slot) return [];
1179
+ return [
1180
+ {
1181
+ id: String(droppableContainer.id),
1182
+ slot,
1183
+ rect,
1184
+ },
1185
+ ];
1186
+ });
1187
+ const preferredId = preferredDropSlotId(
1188
+ args.pointerCoordinates,
1189
+ candidates,
1190
+ );
1191
+ const preferredContainer =
1192
+ preferredId === null
1193
+ ? null
1194
+ : (droppableContainers.find(
1195
+ (container) => String(container.id) === preferredId,
1196
+ ) ?? null);
1197
+ const preferredRect =
1198
+ preferredContainer && args.droppableRects.get(preferredContainer.id);
1199
+
1200
+ return preferredId && preferredContainer && preferredRect
1158
1201
  ? [
1159
1202
  {
1160
- id: closestId,
1203
+ id: preferredId,
1161
1204
  data: {
1162
- droppableContainer: closestContainer,
1163
- value: closestValue,
1205
+ droppableContainer: preferredContainer,
1206
+ value: distanceFromPointerToRect(
1207
+ args.pointerCoordinates,
1208
+ preferredRect,
1209
+ ),
1164
1210
  },
1165
1211
  },
1166
1212
  ]
@@ -1453,7 +1499,7 @@ export default function SqlDashboardPage() {
1453
1499
  {dashboardId ? (
1454
1500
  <EmailReportDialog
1455
1501
  open={emailReportOpen}
1456
- onOpenChange={setEmailReportOpen}
1502
+ onOpenChange={handleEmailReportOpenChange}
1457
1503
  dashboardId={dashboardId}
1458
1504
  dashboardName={dashboard.name}
1459
1505
  filters={currentReportFilters}
@@ -1565,7 +1611,7 @@ export default function SqlDashboardPage() {
1565
1611
  placeholder={t("sqlDashboard.addDescriptionPlaceholder")}
1566
1612
  className="text-sm resize-y"
1567
1613
  />
1568
- ) : dashboard.description ? (
1614
+ ) : !reportScreenshot && dashboard.description ? (
1569
1615
  <button
1570
1616
  className={
1571
1617
  canEdit
@@ -1637,12 +1683,14 @@ export default function SqlDashboardPage() {
1637
1683
  )}
1638
1684
 
1639
1685
  {/* Filters */}
1640
- {dashboard.filters && dashboard.filters.length > 0 && (
1641
- <DashboardFilterBar
1642
- filters={dashboard.filters}
1643
- onSaveView={canEdit ? handleSaveView : undefined}
1644
- />
1645
- )}
1686
+ {!reportScreenshot &&
1687
+ dashboard.filters &&
1688
+ dashboard.filters.length > 0 && (
1689
+ <DashboardFilterBar
1690
+ filters={dashboard.filters}
1691
+ onSaveView={canEdit ? handleSaveView : undefined}
1692
+ />
1693
+ )}
1646
1694
 
1647
1695
  {/* Panels grid */}
1648
1696
  {dashboard.panels.length === 0 ? (
@@ -1269,6 +1269,8 @@ function visitorLabel(
1269
1269
  recording: SessionRecordingSummary,
1270
1270
  t: ReturnType<typeof useT>,
1271
1271
  ): string {
1272
+ const email = emailLike(recording.userId) || emailLike(recording.userKey);
1273
+ if (email) return email;
1272
1274
  return (
1273
1275
  recording.userId ||
1274
1276
  recording.userKey ||
@@ -1277,6 +1279,11 @@ function visitorLabel(
1277
1279
  );
1278
1280
  }
1279
1281
 
1282
+ function emailLike(value: string | null): string | null {
1283
+ if (!value?.includes("@")) return null;
1284
+ return value;
1285
+ }
1286
+
1280
1287
  function formatDuration(ms: number | null): string {
1281
1288
  if (!ms || !Number.isFinite(ms) || ms <= 0) return "0s";
1282
1289
  const seconds = Math.round(ms / 1000);
@@ -1,16 +1,25 @@
1
1
  import { CodeSurface } from "@agent-native/core/blocks";
2
- import { useActionQuery, useT } from "@agent-native/core/client";
2
+ import {
3
+ useActionQuery,
4
+ useBuilderConnectFlow,
5
+ useBuilderStatus,
6
+ useT,
7
+ } from "@agent-native/core/client";
3
8
  import {
4
9
  IconChevronDown,
10
+ IconCheck,
11
+ IconCloud,
5
12
  IconCode,
6
13
  IconExternalLink,
7
14
  IconFilter,
15
+ IconLoader2,
8
16
  IconPlayerPlay,
9
17
  IconRefresh,
10
18
  IconSearch,
19
+ IconServer,
11
20
  } from "@tabler/icons-react";
12
21
  import { useMemo, useState } from "react";
13
- import { useNavigate, useSearchParams } from "react-router";
22
+ import { Link, useNavigate, useSearchParams } from "react-router";
14
23
 
15
24
  import { Badge } from "@/components/ui/badge";
16
25
  import { Button } from "@/components/ui/button";
@@ -24,6 +33,7 @@ import {
24
33
  SelectValue,
25
34
  } from "@/components/ui/select";
26
35
  import { Skeleton } from "@/components/ui/skeleton";
36
+ import { useReplayStorageStatus } from "@/hooks/use-replay-storage-status";
27
37
  import { cn } from "@/lib/utils";
28
38
 
29
39
  type ReplayRange = "24h" | "7d" | "30d" | "90d" | "all";
@@ -294,46 +304,137 @@ export default function SessionsPage() {
294
304
 
295
305
  function EmptySessionsState() {
296
306
  const t = useT();
307
+ const storageStatus = useReplayStorageStatus();
308
+ const showStorageHint =
309
+ !storageStatus.isLoading && !storageStatus.data?.configured;
297
310
  return (
298
- <div className="grid min-h-[380px] gap-6 p-6 lg:grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)] lg:p-8">
299
- <div className="flex flex-col justify-center gap-3">
300
- <div className="flex h-10 w-10 items-center justify-center rounded-md border bg-muted/40">
301
- <IconPlayerPlay className="h-5 w-5 text-primary" />
311
+ <div className="p-6 lg:p-8">
312
+ {showStorageHint ? <ReplayStorageHint /> : null}
313
+ <div className="grid min-h-[380px] gap-6 lg:grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)]">
314
+ <div className="flex flex-col justify-center gap-3">
315
+ <div className="flex h-10 w-10 items-center justify-center rounded-md border bg-muted/40">
316
+ <IconPlayerPlay className="h-5 w-5 text-primary" />
317
+ </div>
318
+ <div className="space-y-2">
319
+ <h2 className="text-lg font-semibold">
320
+ {t("sessions.noSessions")}
321
+ </h2>
322
+ <p className="max-w-xl text-sm text-muted-foreground">
323
+ {t("sessions.noSessionsDescription")}
324
+ </p>
325
+ </div>
302
326
  </div>
303
- <div className="space-y-2">
304
- <h2 className="text-lg font-semibold">{t("sessions.noSessions")}</h2>
305
- <p className="max-w-xl text-sm text-muted-foreground">
306
- {t("sessions.noSessionsDescription")}
307
- </p>
327
+ <div className="analytics-session-snippet overflow-hidden rounded-md border bg-muted/30">
328
+ <div className="flex items-center justify-between gap-3 border-b px-4 py-3">
329
+ <div className="flex min-w-0 items-center gap-2 text-sm font-medium">
330
+ <IconCode className="h-4 w-4 text-muted-foreground" />
331
+ <span className="truncate">
332
+ {t("sessions.installSnippetTitle")}
333
+ </span>
334
+ </div>
335
+ <Button
336
+ asChild
337
+ variant="ghost"
338
+ size="sm"
339
+ className="h-7 px-2 text-xs"
340
+ >
341
+ <a
342
+ href={SESSION_REPLAY_DOCS_URL}
343
+ target="_blank"
344
+ rel="noreferrer"
345
+ >
346
+ {t("common.docs")}
347
+ <IconExternalLink className="h-3.5 w-3.5" />
348
+ </a>
349
+ </Button>
350
+ </div>
351
+ <CodeSurface
352
+ code={SESSION_REPLAY_SNIPPET}
353
+ language="typescript"
354
+ maxLines={null}
355
+ showLanguageLabel={false}
356
+ className="mt-0"
357
+ />
308
358
  </div>
309
359
  </div>
310
- <div className="analytics-session-snippet overflow-hidden rounded-md border bg-muted/30">
311
- <div className="flex items-center justify-between gap-3 border-b px-4 py-3">
312
- <div className="flex min-w-0 items-center gap-2 text-sm font-medium">
313
- <IconCode className="h-4 w-4 text-muted-foreground" />
314
- <span className="truncate">
315
- {t("sessions.installSnippetTitle")}
316
- </span>
360
+ </div>
361
+ );
362
+ }
363
+
364
+ function ReplayStorageHint() {
365
+ const t = useT();
366
+ const storageStatus = useReplayStorageStatus();
367
+ const builderStatus = useBuilderStatus();
368
+ const builderConnect = useBuilderConnectFlow({
369
+ popupUrl:
370
+ builderStatus.status?.cliAuthUrl ?? builderStatus.status?.connectUrl,
371
+ trackingSource: "analytics_sessions_storage_hint",
372
+ trackingFlow: "replay_storage",
373
+ onConnected: async () => {
374
+ await Promise.all([storageStatus.refetch(), builderStatus.refetch()]);
375
+ },
376
+ });
377
+
378
+ const builderConnected = Boolean(
379
+ builderConnect.configured ||
380
+ builderStatus.status?.configured ||
381
+ storageStatus.data?.builderConfigured,
382
+ );
383
+ const builderStatusLoading =
384
+ storageStatus.isLoading ||
385
+ builderStatus.loading ||
386
+ !builderConnect.hasFetchedStatus;
387
+
388
+ return (
389
+ <div className="mb-6 flex flex-col gap-4 rounded-md border border-primary/30 bg-primary/5 p-4 sm:flex-row sm:items-center sm:justify-between">
390
+ <div className="flex min-w-0 items-start gap-3">
391
+ <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-background text-primary">
392
+ <IconCloud className="h-5 w-5" />
393
+ </div>
394
+ <div className="min-w-0">
395
+ <div className="text-sm font-medium">
396
+ {t("sessions.storageSetupTitle")}
317
397
  </div>
318
- <Button
319
- asChild
320
- variant="ghost"
321
- size="sm"
322
- className="h-7 px-2 text-xs"
323
- >
324
- <a href={SESSION_REPLAY_DOCS_URL} target="_blank" rel="noreferrer">
325
- {t("common.docs")}
326
- <IconExternalLink className="h-3.5 w-3.5" />
327
- </a>
328
- </Button>
398
+ <p className="mt-0.5 text-xs text-muted-foreground">
399
+ {t("sessions.storageSetupDescription")}
400
+ </p>
329
401
  </div>
330
- <CodeSurface
331
- code={SESSION_REPLAY_SNIPPET}
332
- language="typescript"
333
- maxLines={null}
334
- showLanguageLabel={false}
335
- className="mt-0"
336
- />
402
+ </div>
403
+ <div className="flex shrink-0 flex-wrap items-center gap-3">
404
+ <Button
405
+ type="button"
406
+ size="sm"
407
+ className="shrink-0"
408
+ onClick={() =>
409
+ builderConnect.start({
410
+ trackingSource: "analytics_sessions_storage_hint",
411
+ trackingFlow: "replay_storage",
412
+ })
413
+ }
414
+ disabled={
415
+ builderConnect.connecting ||
416
+ builderStatusLoading ||
417
+ builderConnected
418
+ }
419
+ >
420
+ {builderConnect.connecting ? (
421
+ <IconLoader2 className="h-4 w-4 animate-spin" />
422
+ ) : builderConnected ? (
423
+ <IconCheck className="h-4 w-4" />
424
+ ) : (
425
+ <IconExternalLink className="h-4 w-4" />
426
+ )}
427
+ {builderConnected
428
+ ? t("sessions.storageConnected")
429
+ : t("sessions.connectBuilder")}
430
+ </Button>
431
+ <Link
432
+ to="/settings#replay-storage"
433
+ className="inline-flex items-center gap-1.5 text-xs font-medium text-muted-foreground underline underline-offset-2 hover:text-foreground"
434
+ >
435
+ <IconServer className="h-3.5 w-3.5" />
436
+ {t("sessions.configureS3")}
437
+ </Link>
337
438
  </div>
338
439
  </div>
339
440
  );
@@ -374,6 +475,8 @@ function visitorLabel(
374
475
  recording: SessionRecordingSummary,
375
476
  t: ReturnType<typeof useT>,
376
477
  ): string {
478
+ const email = emailLike(recording.userId) || emailLike(recording.userKey);
479
+ if (email) return email;
377
480
  return (
378
481
  recording.userId ||
379
482
  recording.userKey ||
@@ -382,6 +485,11 @@ function visitorLabel(
382
485
  );
383
486
  }
384
487
 
488
+ function emailLike(value: string | null): string | null {
489
+ if (!value?.includes("@")) return null;
490
+ return value;
491
+ }
492
+
385
493
  function shortId(value: string): string {
386
494
  return value.length > 22
387
495
  ? `${value.slice(0, 10)}...${value.slice(-8)}`
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-28
4
+ ---
5
+
6
+ The Ask tab now matches the darker background used across the rest of Analytics.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-28
4
+ ---
5
+
6
+ Dashboard email reports now use cleaner light-mode snapshots with direct subscription settings links.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-28
4
+ ---
5
+
6
+ The left sidebar now collapses into an animated icon rail with quieter footer controls.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-28
4
+ ---
5
+
6
+ Sessions now show only signed-in recordings with playable replay events.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-29
4
+ ---
5
+
6
+ Analytics agents can now place new charts into requested dashboard rows.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-29
4
+ ---
5
+
6
+ Analytics queries now report failed source-query errors instead of falling back to a vague no-data message.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-29
4
+ ---
5
+
6
+ Charts can now be dropped between full dashboard rows to create wider rows.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-29
4
+ ---
5
+
6
+ Dashboard email reports include the full dashboard image without an extra image border.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-29
4
+ ---
5
+
6
+ The main dashboard surface border now reaches the top edge and keeps its rounded corners.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-29
4
+ ---
5
+
6
+ Session replay now records playable sessions in production and shows them to your whole workspace
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-06-29
4
+ ---
5
+
6
+ Set up session replay storage from settings: connect Builder.io or add S3-compatible storage
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ /**
4
+ * One-time maintenance for session replay rows created before the capture fix.
5
+ *
6
+ * Two jobs:
7
+ * 1. Delete empty "shell" recordings — rows that were created on ingest but
8
+ * never stored any replay data (chunk_count = 0, event_count = 0, and no
9
+ * session_replay_chunks rows). These exist because, before the ingest
10
+ * credential-scope fix, blob storage failed in production (no resolvable
11
+ * upload provider) and left unplayable husks behind. They are always
12
+ * filtered out of /sessions, so this is pure DB hygiene.
13
+ * 2. Backfill visibility "private" -> "org" for org-scoped recordings, so
14
+ * existing recordings follow the same org-visible model new ingests now use
15
+ * (teammates in the org can see them, not only the key owner).
16
+ *
17
+ * SAFE BY DEFAULT: dry-run unless you pass --apply. This connects to whatever
18
+ * DATABASE_URL the app is configured with, so double-check the target before
19
+ * using --apply against production.
20
+ *
21
+ * pnpm --filter analytics exec tsx scripts/cleanup-empty-session-recordings.ts # dry run
22
+ * pnpm --filter analytics exec tsx scripts/cleanup-empty-session-recordings.ts --apply # mutate
23
+ */
24
+
25
+ import path from "node:path";
26
+ import { pathToFileURL } from "node:url";
27
+
28
+ import { and, eq, isNotNull, sql } from "drizzle-orm";
29
+
30
+ import { getDb, schema } from "../server/db/index";
31
+ import migrations from "../server/plugins/db";
32
+
33
+ const apply = process.argv.includes("--apply");
34
+
35
+ const emptyShellCondition = and(
36
+ eq(schema.sessionRecordings.chunkCount, 0),
37
+ eq(schema.sessionRecordings.eventCount, 0),
38
+ sql`not exists (
39
+ select 1 from ${schema.sessionReplayChunks}
40
+ where ${schema.sessionReplayChunks.recordingId} = ${schema.sessionRecordings.id}
41
+ )`,
42
+ );
43
+
44
+ const orgPrivateCondition = and(
45
+ isNotNull(schema.sessionRecordings.orgId),
46
+ eq(schema.sessionRecordings.visibility, "private"),
47
+ );
48
+
49
+ async function countWhere(condition: unknown): Promise<number> {
50
+ const db = getDb() as any;
51
+ const rows = await db
52
+ .select({ n: sql<number>`count(*)::int` })
53
+ .from(schema.sessionRecordings)
54
+ .where(condition);
55
+ return Number(rows[0]?.n ?? 0);
56
+ }
57
+
58
+ async function main() {
59
+ await migrations({});
60
+ const db = getDb() as any;
61
+
62
+ const emptyShells = await countWhere(emptyShellCondition);
63
+ const orgPrivate = await countWhere(orgPrivateCondition);
64
+
65
+ console.log(`[cleanup] mode: ${apply ? "APPLY (mutating)" : "dry-run"}`);
66
+ console.log(`[cleanup] empty shell recordings to delete: ${emptyShells}`);
67
+ console.log(
68
+ `[cleanup] org-scoped recordings to make org-visible: ${orgPrivate}`,
69
+ );
70
+
71
+ if (!apply) {
72
+ console.log("[cleanup] dry-run only — re-run with --apply to mutate.");
73
+ return;
74
+ }
75
+
76
+ // Backfill visibility first so we don't widen rows we're about to delete.
77
+ await db
78
+ .update(schema.sessionRecordings)
79
+ .set({ visibility: "org" })
80
+ .where(orgPrivateCondition);
81
+ console.log(
82
+ `[cleanup] backfilled ${orgPrivate} recordings to visibility=org`,
83
+ );
84
+
85
+ await db.delete(schema.sessionRecordings).where(emptyShellCondition);
86
+ console.log(`[cleanup] deleted ${emptyShells} empty shell recordings`);
87
+ }
88
+
89
+ function isDirectRun(): boolean {
90
+ const entrypoint = process.argv[1];
91
+ return Boolean(
92
+ entrypoint &&
93
+ import.meta.url === pathToFileURL(path.resolve(entrypoint)).href,
94
+ );
95
+ }
96
+
97
+ if (isDirectRun()) {
98
+ main().catch((error) => {
99
+ console.error(error);
100
+ process.exit(1);
101
+ });
102
+ }