@agent-native/core 0.79.27 → 0.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +26 -0
  3. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +41 -0
  4. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +51 -0
  5. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +50 -0
  6. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +49 -0
  7. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +44 -0
  8. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +46 -0
  9. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +44 -0
  10. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +48 -0
  11. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +36 -0
  12. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +38 -0
  13. package/corpus/core/docs/content/template-design.mdx +45 -0
  14. package/corpus/core/package.json +2 -1
  15. package/corpus/core/src/agent/engine/index.ts +1 -0
  16. package/corpus/core/src/agent/engine/registry.ts +40 -0
  17. package/corpus/core/src/agent/production-agent.ts +6 -2
  18. package/corpus/core/src/cli/design-connect.ts +490 -0
  19. package/corpus/core/src/cli/index.ts +16 -0
  20. package/corpus/core/src/cli/skills.ts +126 -3
  21. package/corpus/core/src/client/AssistantChat.tsx +43 -7
  22. package/corpus/core/src/client/agent-chat.ts +27 -3
  23. package/corpus/core/src/client/blocks/library/MermaidBlock.tsx +1 -1
  24. package/corpus/core/src/client/blocks/library/diagram.tsx +2 -2
  25. package/corpus/core/src/client/blocks/library/wireframe.tsx +1 -1
  26. package/corpus/core/src/client/chat/message-components.tsx +1 -1
  27. package/corpus/core/src/client/chat-model-groups.ts +1 -2
  28. package/corpus/core/src/client/components/LiveCursorOverlay.tsx +33 -66
  29. package/corpus/core/src/client/composer/TiptapComposer.tsx +99 -24
  30. package/corpus/core/src/client/composer/useVoiceDictation.ts +429 -260
  31. package/corpus/core/src/client/frame-protocol.ts +17 -2
  32. package/corpus/core/src/client/rich-markdown-editor/RegistryBlockNode.tsx +2 -2
  33. package/corpus/core/src/client/sharing/ShareButton.tsx +20 -15
  34. package/corpus/core/src/client/use-agent-engine-configured.ts +80 -28
  35. package/corpus/core/src/server/transcribe-voice.ts +57 -22
  36. package/corpus/core/src/shared/mcp-embed-headers.ts +23 -1
  37. package/corpus/core/src/styles/agent-native.css +56 -7
  38. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  39. package/corpus/core/src/vite/client.ts +2 -0
  40. package/corpus/core/src/voice/index.ts +18 -0
  41. package/corpus/core/src/voice/voice-cleanup-prompt.ts +38 -0
  42. package/corpus/core/src/voice/voice-context.ts +217 -0
  43. package/corpus/core/src/voice/voice-replacements.ts +75 -0
  44. package/corpus/templates/analytics/AGENTS.md +4 -3
  45. package/corpus/templates/analytics/actions/list-session-recordings.ts +6 -1
  46. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +557 -400
  47. package/corpus/templates/analytics/app/global.css +0 -4
  48. package/corpus/templates/analytics/app/i18n/zh-TW.ts +2 -0
  49. package/corpus/templates/analytics/app/i18n-data.ts +20 -0
  50. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +33 -8
  51. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +7 -0
  52. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +7 -0
  53. package/corpus/templates/analytics/changelog/2026-06-28-ask-tab-now-matches-the-darker-app-background.md +6 -0
  54. package/corpus/templates/analytics/changelog/2026-06-28-dashboard-email-reports-now-use-cleaner-light-mode-snapshots.md +6 -0
  55. package/corpus/templates/analytics/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  56. package/corpus/templates/analytics/changelog/2026-06-28-sessions-now-show-only-signed-in-recordings-with-playable-re.md +6 -0
  57. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +3 -3
  58. package/corpus/templates/analytics/server/lib/dashboard-report.ts +29 -7
  59. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +5 -2
  60. package/corpus/templates/analytics/server/lib/session-replay.ts +24 -4
  61. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +4 -4
  62. package/corpus/templates/assets/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  63. package/corpus/templates/brain/app/components/layout/Layout.tsx +29 -2
  64. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +131 -42
  65. package/corpus/templates/brain/app/i18n/zh-TW.ts +2 -0
  66. package/corpus/templates/brain/app/i18n-data.ts +20 -0
  67. package/corpus/templates/brain/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  68. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +29 -1
  69. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +417 -299
  70. package/corpus/templates/calendar/app/i18n/zh-TW.ts +2 -0
  71. package/corpus/templates/calendar/app/i18n-data.ts +20 -0
  72. package/corpus/templates/calendar/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  73. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +6 -19
  74. package/corpus/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  75. package/corpus/templates/clips/AGENTS.md +4 -0
  76. package/corpus/templates/clips/actions/cleanup-transcript.ts +39 -9
  77. package/corpus/templates/clips/actions/finalize-meeting.ts +81 -12
  78. package/corpus/templates/clips/actions/lib/agents-md-context.ts +4 -1
  79. package/corpus/templates/clips/app/components/library/library-layout.tsx +3 -3
  80. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +1 -1
  81. package/corpus/templates/clips/app/components/player/share-dialog.tsx +2 -2
  82. package/corpus/templates/clips/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
  83. package/corpus/templates/clips/desktop/src/lib/personal-vocabulary.ts +13 -8
  84. package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +60 -1
  85. package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +1 -1
  86. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +1 -1
  87. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -5
  88. package/corpus/templates/content/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  89. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +137 -0
  90. package/corpus/templates/design/AGENTS.md +95 -5
  91. package/corpus/templates/design/DESIGN.md +82 -0
  92. package/corpus/templates/design/DEVELOPING.md +43 -0
  93. package/corpus/templates/design/actions/add-localhost-screens.ts +426 -0
  94. package/corpus/templates/design/actions/apply-shader.ts +277 -0
  95. package/corpus/templates/design/actions/apply-visual-edit.ts +303 -0
  96. package/corpus/templates/design/actions/connect-localhost.ts +183 -0
  97. package/corpus/templates/design/actions/edit-design.ts +195 -42
  98. package/corpus/templates/design/actions/generate-design.ts +71 -1
  99. package/corpus/templates/design/actions/generate-screens.ts +193 -0
  100. package/corpus/templates/design/actions/get-code-layer-projection.ts +191 -0
  101. package/corpus/templates/design/actions/get-shader.ts +119 -0
  102. package/corpus/templates/design/actions/list-localhost-connections.ts +95 -0
  103. package/corpus/templates/design/actions/navigate.ts +55 -2
  104. package/corpus/templates/design/actions/view-screen.ts +68 -1
  105. package/corpus/templates/design/agent-native.app-skill.json +10 -0
  106. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +761 -0
  107. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +2057 -103
  108. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +74 -38
  109. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +399 -0
  110. package/corpus/templates/design/app/components/design/EditPanel.tsx +3185 -439
  111. package/corpus/templates/design/app/components/design/LayersPanel.tsx +1124 -0
  112. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +3116 -147
  113. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +700 -13
  114. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +107 -63
  115. package/corpus/templates/design/app/components/design/index.ts +0 -5
  116. package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +286 -0
  117. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +699 -0
  118. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +461 -0
  119. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +166 -0
  120. package/corpus/templates/design/app/components/design/inspector/FigmaColorPicker.tsx +1420 -0
  121. package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +420 -0
  122. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +215 -0
  123. package/corpus/templates/design/app/components/design/inspector/ShaderControls.stories.tsx +71 -0
  124. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +518 -0
  125. package/corpus/templates/design/app/components/design/inspector/ShaderEffectRow.tsx +106 -0
  126. package/corpus/templates/design/app/components/design/inspector/figma-icons.tsx +361 -0
  127. package/corpus/templates/design/app/components/design/inspector/index.ts +60 -0
  128. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +201 -0
  129. package/corpus/templates/design/app/components/design/types.ts +23 -0
  130. package/corpus/templates/design/app/components/layout/Layout.tsx +24 -13
  131. package/corpus/templates/design/app/components/layout/Sidebar.tsx +4 -4
  132. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +474 -36
  133. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +22 -5
  134. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +24 -11
  135. package/corpus/templates/design/app/global.css +121 -3
  136. package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -0
  137. package/corpus/templates/design/app/hooks/use-navigation-state.ts +130 -8
  138. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +329 -0
  139. package/corpus/templates/design/app/i18n/zh-TW.ts +264 -0
  140. package/corpus/templates/design/app/i18n-data.ts +2790 -1
  141. package/corpus/templates/design/app/pages/DesignEditor.tsx +5108 -851
  142. package/corpus/templates/design/changelog/2026-06-28-annotate-mode-now-combines-drawing-and-comment-pins-in-one-c.md +6 -0
  143. package/corpus/templates/design/changelog/2026-06-28-design-editor-panel-borders-are-cleaner-so-the-canvas-edge-s.md +6 -0
  144. package/corpus/templates/design/changelog/2026-06-28-drawing-prompts-now-reliably-open-and-submit-to-the-design-a.md +6 -0
  145. package/corpus/templates/design/changelog/2026-06-28-editor-app-menus-now-use-an-outline-agent-native-mark-with-b.md +6 -0
  146. package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +6 -0
  147. package/corpus/templates/design/changelog/2026-06-28-layer-selection-now-updates-chat-context-without-opening-the.md +6 -0
  148. package/corpus/templates/design/changelog/2026-06-28-layer-selections-now-preserve-hidden-and-locked-canvas-state.md +6 -0
  149. package/corpus/templates/design/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  150. package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +6 -0
  151. package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +6 -0
  152. package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-handles-zooming-drawing-opening-and-dele.md +6 -0
  153. package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-selects-screens-on-click-and-opens-them-.md +6 -0
  154. package/corpus/templates/design/changelog/2026-06-28-screen-overview-zooms-into-the-active-screen-with-smoother-e.md +6 -0
  155. package/corpus/templates/design/changelog/2026-06-28-selected-element-chips-in-chat-are-shorter-and-easier-to-sca.md +6 -0
  156. package/corpus/templates/design/changelog/2026-06-28-the-design-editor-toolbar-is-more-compact-and-the-app-menu-m.md +6 -0
  157. package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-at-the-top-of-the-design-sidebar-instead-of-.md +6 -0
  158. package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-in-the-right-inspector-beside-the-design-tab.md +6 -0
  159. package/corpus/templates/design/changelog/2026-06-29-active-sidebar-rows-use-soft-highlights.md +6 -0
  160. package/corpus/templates/design/changelog/2026-06-29-agents-can-now-open-screen-overview-focus-screens-and-add.md +6 -0
  161. package/corpus/templates/design/changelog/2026-06-29-design-agents-now-edit-broad-copy-changes-more-reliably.md +6 -0
  162. package/corpus/templates/design/changelog/2026-06-29-design-editor-extensions-now-run-inline-beside-the-artboard.md +6 -0
  163. package/corpus/templates/design/changelog/2026-06-29-sidebars-use-darker-chrome-and-chat-warns-immediately.md +6 -0
  164. package/corpus/templates/design/changelog/2026-06-29-visual-edit-can-open-localhost-routes-as-url-backed-screens.md +6 -0
  165. package/corpus/templates/design/package.json +1 -0
  166. package/corpus/templates/design/server/db/schema.ts +26 -0
  167. package/corpus/templates/design/server/lib/design-snapshot.ts +1 -1
  168. package/corpus/templates/design/server/plugins/agent-chat.ts +3 -0
  169. package/corpus/templates/design/shared/api.ts +27 -0
  170. package/corpus/templates/design/shared/canvas-frames.ts +103 -0
  171. package/corpus/templates/design/shared/canvas-math.ts +1058 -0
  172. package/corpus/templates/design/shared/code-layer.ts +2212 -0
  173. package/corpus/templates/design/shared/color-utils.ts +180 -0
  174. package/corpus/templates/design/shared/generation-session.ts +61 -0
  175. package/corpus/templates/design/shared/shader-presets.ts +782 -0
  176. package/corpus/templates/design/shared/shader-safety.ts +137 -0
  177. package/corpus/templates/design/shared/source-mode.ts +237 -0
  178. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +149 -6
  179. package/corpus/templates/forms/app/i18n/ar-SA.ts +2 -0
  180. package/corpus/templates/forms/app/i18n/de-DE.ts +2 -0
  181. package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
  182. package/corpus/templates/forms/app/i18n/es-ES.ts +2 -0
  183. package/corpus/templates/forms/app/i18n/fr-FR.ts +2 -0
  184. package/corpus/templates/forms/app/i18n/hi-IN.ts +2 -0
  185. package/corpus/templates/forms/app/i18n/ja-JP.ts +2 -0
  186. package/corpus/templates/forms/app/i18n/ko-KR.ts +2 -0
  187. package/corpus/templates/forms/app/i18n/pt-BR.ts +2 -0
  188. package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
  189. package/corpus/templates/forms/app/i18n/zh-TW.ts +2 -0
  190. package/corpus/templates/forms/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  191. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +2 -2
  192. package/corpus/templates/macros/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
  193. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +408 -247
  194. package/corpus/templates/mail/app/i18n/ar-SA.ts +4 -0
  195. package/corpus/templates/mail/app/i18n/de-DE.ts +4 -0
  196. package/corpus/templates/mail/app/i18n/en-US.ts +4 -0
  197. package/corpus/templates/mail/app/i18n/es-ES.ts +4 -0
  198. package/corpus/templates/mail/app/i18n/fr-FR.ts +4 -0
  199. package/corpus/templates/mail/app/i18n/hi-IN.ts +4 -0
  200. package/corpus/templates/mail/app/i18n/ja-JP.ts +4 -0
  201. package/corpus/templates/mail/app/i18n/ko-KR.ts +4 -0
  202. package/corpus/templates/mail/app/i18n/pt-BR.ts +4 -0
  203. package/corpus/templates/mail/app/i18n/zh-CN.ts +4 -0
  204. package/corpus/templates/mail/app/i18n/zh-TW.ts +4 -0
  205. package/corpus/templates/mail/changelog/2026-06-28-pinned-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  206. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +6 -8
  207. package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +1 -1
  208. package/corpus/templates/plan/app/global.css +61 -78
  209. package/corpus/templates/plan/app/pages/PlansPage.tsx +8 -0
  210. package/corpus/templates/plan/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  211. package/corpus/templates/plan/changelog/2026-06-28-plans-use-the-shared-neutral-light-and-dark-theme.md +6 -0
  212. package/corpus/templates/plan/changelog/2026-06-28-sending-open-feedback-from-a-plan-now-opens-the-inline-plan-.md +6 -0
  213. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +5 -5
  214. package/corpus/templates/slides/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  215. package/corpus/templates/videos/app/components/Sidebar.tsx +2 -2
  216. package/corpus/templates/videos/app/components/layout/Layout.tsx +29 -2
  217. package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +113 -30
  218. package/corpus/templates/videos/app/i18n/ar-SA.ts +2 -0
  219. package/corpus/templates/videos/app/i18n/de-DE.ts +2 -0
  220. package/corpus/templates/videos/app/i18n/en-US.ts +2 -0
  221. package/corpus/templates/videos/app/i18n/es-ES.ts +2 -0
  222. package/corpus/templates/videos/app/i18n/fr-FR.ts +2 -0
  223. package/corpus/templates/videos/app/i18n/hi-IN.ts +2 -0
  224. package/corpus/templates/videos/app/i18n/ja-JP.ts +2 -0
  225. package/corpus/templates/videos/app/i18n/ko-KR.ts +2 -0
  226. package/corpus/templates/videos/app/i18n/pt-BR.ts +2 -0
  227. package/corpus/templates/videos/app/i18n/zh-CN.ts +2 -0
  228. package/corpus/templates/videos/app/i18n/zh-TW.ts +2 -0
  229. package/corpus/templates/videos/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  230. package/dist/agent/engine/index.d.ts +1 -1
  231. package/dist/agent/engine/index.d.ts.map +1 -1
  232. package/dist/agent/engine/index.js +1 -1
  233. package/dist/agent/engine/index.js.map +1 -1
  234. package/dist/agent/engine/registry.d.ts +9 -0
  235. package/dist/agent/engine/registry.d.ts.map +1 -1
  236. package/dist/agent/engine/registry.js +37 -0
  237. package/dist/agent/engine/registry.js.map +1 -1
  238. package/dist/agent/production-agent.d.ts.map +1 -1
  239. package/dist/agent/production-agent.js +4 -3
  240. package/dist/agent/production-agent.js.map +1 -1
  241. package/dist/cli/design-connect.d.ts +52 -0
  242. package/dist/cli/design-connect.d.ts.map +1 -0
  243. package/dist/cli/design-connect.js +409 -0
  244. package/dist/cli/design-connect.js.map +1 -0
  245. package/dist/cli/index.js +15 -0
  246. package/dist/cli/index.js.map +1 -1
  247. package/dist/cli/skills.d.ts +3 -0
  248. package/dist/cli/skills.d.ts.map +1 -1
  249. package/dist/cli/skills.js +121 -3
  250. package/dist/cli/skills.js.map +1 -1
  251. package/dist/client/AssistantChat.d.ts.map +1 -1
  252. package/dist/client/AssistantChat.js +38 -8
  253. package/dist/client/AssistantChat.js.map +1 -1
  254. package/dist/client/agent-chat.d.ts +6 -0
  255. package/dist/client/agent-chat.d.ts.map +1 -1
  256. package/dist/client/agent-chat.js +17 -3
  257. package/dist/client/agent-chat.js.map +1 -1
  258. package/dist/client/blocks/library/MermaidBlock.js +1 -1
  259. package/dist/client/blocks/library/MermaidBlock.js.map +1 -1
  260. package/dist/client/blocks/library/diagram.js +1 -1
  261. package/dist/client/blocks/library/diagram.js.map +1 -1
  262. package/dist/client/blocks/library/wireframe.js +1 -1
  263. package/dist/client/blocks/library/wireframe.js.map +1 -1
  264. package/dist/client/chat/message-components.js +1 -1
  265. package/dist/client/chat/message-components.js.map +1 -1
  266. package/dist/client/chat-model-groups.d.ts.map +1 -1
  267. package/dist/client/chat-model-groups.js +1 -2
  268. package/dist/client/chat-model-groups.js.map +1 -1
  269. package/dist/client/components/LiveCursorOverlay.d.ts +1 -2
  270. package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -1
  271. package/dist/client/components/LiveCursorOverlay.js +19 -40
  272. package/dist/client/components/LiveCursorOverlay.js.map +1 -1
  273. package/dist/client/composer/TiptapComposer.d.ts +3 -1
  274. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  275. package/dist/client/composer/TiptapComposer.js +86 -24
  276. package/dist/client/composer/TiptapComposer.js.map +1 -1
  277. package/dist/client/composer/useVoiceDictation.d.ts +9 -0
  278. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  279. package/dist/client/composer/useVoiceDictation.js +154 -32
  280. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  281. package/dist/client/frame-protocol.d.ts +17 -2
  282. package/dist/client/frame-protocol.d.ts.map +1 -1
  283. package/dist/client/frame-protocol.js.map +1 -1
  284. package/dist/client/rich-markdown-editor/RegistryBlockNode.js +2 -2
  285. package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -1
  286. package/dist/client/sharing/ShareButton.d.ts +2 -0
  287. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  288. package/dist/client/sharing/ShareButton.js +7 -6
  289. package/dist/client/sharing/ShareButton.js.map +1 -1
  290. package/dist/client/use-agent-engine-configured.d.ts +5 -0
  291. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  292. package/dist/client/use-agent-engine-configured.js +51 -25
  293. package/dist/client/use-agent-engine-configured.js.map +1 -1
  294. package/dist/collab/awareness.d.ts +2 -2
  295. package/dist/collab/awareness.d.ts.map +1 -1
  296. package/dist/collab/routes.d.ts +1 -1
  297. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  298. package/dist/notifications/routes.d.ts +3 -3
  299. package/dist/observability/routes.d.ts +8 -8
  300. package/dist/progress/routes.d.ts +1 -1
  301. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  302. package/dist/server/transcribe-voice.d.ts.map +1 -1
  303. package/dist/server/transcribe-voice.js +40 -24
  304. package/dist/server/transcribe-voice.js.map +1 -1
  305. package/dist/shared/mcp-embed-headers.d.ts +1 -0
  306. package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
  307. package/dist/shared/mcp-embed-headers.js +20 -1
  308. package/dist/shared/mcp-embed-headers.js.map +1 -1
  309. package/dist/styles/agent-native.css +56 -7
  310. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  311. package/dist/vite/client.d.ts.map +1 -1
  312. package/dist/vite/client.js +2 -0
  313. package/dist/vite/client.js.map +1 -1
  314. package/dist/voice/index.d.ts +5 -0
  315. package/dist/voice/index.d.ts.map +1 -0
  316. package/dist/voice/index.js +4 -0
  317. package/dist/voice/index.js.map +1 -0
  318. package/dist/voice/voice-cleanup-prompt.d.ts +6 -0
  319. package/dist/voice/voice-cleanup-prompt.d.ts.map +1 -0
  320. package/dist/voice/voice-cleanup-prompt.js +26 -0
  321. package/dist/voice/voice-cleanup-prompt.js.map +1 -0
  322. package/dist/voice/voice-context.d.ts +25 -0
  323. package/dist/voice/voice-context.d.ts.map +1 -0
  324. package/dist/voice/voice-context.js +156 -0
  325. package/dist/voice/voice-context.js.map +1 -0
  326. package/dist/voice/voice-replacements.d.ts +4 -0
  327. package/dist/voice/voice-replacements.d.ts.map +1 -0
  328. package/dist/voice/voice-replacements.js +52 -0
  329. package/dist/voice/voice-replacements.js.map +1 -0
  330. package/docs/content/locales/ar-SA/template-design.mdx +41 -0
  331. package/docs/content/locales/de-DE/template-design.mdx +51 -0
  332. package/docs/content/locales/es-ES/template-design.mdx +50 -0
  333. package/docs/content/locales/fr-FR/template-design.mdx +49 -0
  334. package/docs/content/locales/hi-IN/template-design.mdx +44 -0
  335. package/docs/content/locales/ja-JP/template-design.mdx +46 -0
  336. package/docs/content/locales/ko-KR/template-design.mdx +44 -0
  337. package/docs/content/locales/pt-BR/template-design.mdx +48 -0
  338. package/docs/content/locales/zh-CN/template-design.mdx +36 -0
  339. package/docs/content/locales/zh-TW/template-design.mdx +38 -0
  340. package/docs/content/template-design.mdx +45 -0
  341. package/package.json +2 -1
  342. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  343. package/corpus/templates/design/app/components/design/DesignToolbar.tsx +0 -339
  344. package/corpus/templates/design/app/components/design/PresentMode.tsx +0 -68
  345. package/corpus/templates/design/app/components/design/ViewportTabs.tsx +0 -149
  346. package/corpus/templates/design/app/components/design/ZoomControls.tsx +0 -157
@@ -21,6 +21,15 @@ import {
21
21
  IconRefresh,
22
22
  IconPin,
23
23
  IconPinnedFilled,
24
+ IconArchive,
25
+ IconClock,
26
+ IconFileText,
27
+ IconInbox,
28
+ IconLayoutSidebarLeftCollapse,
29
+ IconLayoutSidebarLeftExpand,
30
+ IconMailForward,
31
+ IconStar,
32
+ IconTrash,
24
33
  } from "@tabler/icons-react";
25
34
  import { useQueryClient } from "@tanstack/react-query";
26
35
  import { useState, useCallback, useRef, useEffect, useMemo } from "react";
@@ -86,6 +95,7 @@ type SnoozeTarget = {
86
95
  accountEmail?: string;
87
96
  };
88
97
  const COMPOSE_FULLSCREEN_PARAM = "composeFullscreen";
98
+ const SIDEBAR_COLLAPSE_KEY = "mail-sidebar-collapsed";
89
99
 
90
100
  function AccountAvatar({
91
101
  email,
@@ -351,11 +361,23 @@ function AppLayoutInner({ children }: AppLayoutProps) {
351
361
  if (typeof window === "undefined") return false;
352
362
  return localStorage.getItem("mail-sidebar-pinned") === "true";
353
363
  });
364
+ const [sidebarCollapsed, setSidebarCollapsed] = useState(() => {
365
+ if (typeof window === "undefined") return false;
366
+ return localStorage.getItem(SIDEBAR_COLLAPSE_KEY) === "true";
367
+ });
354
368
  useEffect(() => {
355
369
  if (sidebarPinned) localStorage.setItem("mail-sidebar-pinned", "true");
356
370
  else localStorage.removeItem("mail-sidebar-pinned");
357
371
  }, [sidebarPinned]);
372
+ useEffect(() => {
373
+ if (sidebarCollapsed) {
374
+ localStorage.setItem(SIDEBAR_COLLAPSE_KEY, "true");
375
+ } else {
376
+ localStorage.removeItem(SIDEBAR_COLLAPSE_KEY);
377
+ }
378
+ }, [sidebarCollapsed]);
358
379
  const showSidebar = sidebarOpen || (sidebarPinned && !isMobile);
380
+ const showCollapsedSidebar = sidebarPinned && sidebarCollapsed && !isMobile;
359
381
  const closeSidebar = useCallback(() => {
360
382
  if (!sidebarPinned || isMobile) setSidebarOpen(false);
361
383
  }, [sidebarPinned, isMobile]);
@@ -971,6 +993,58 @@ function AppLayoutInner({ children }: AppLayoutProps) {
971
993
  labelThreadCounts.unread["__inboxTotal"] ??
972
994
  labelThreadCounts.unread["inbox"] ??
973
995
  0;
996
+ const railNavItems = [
997
+ {
998
+ id: "inbox",
999
+ label: t("mail.views.inbox"),
1000
+ href: "/inbox",
1001
+ icon: IconInbox,
1002
+ count: inboxSidebarUnreadCount,
1003
+ },
1004
+ {
1005
+ id: "unread",
1006
+ label: t("mail.views.unread"),
1007
+ href: "/unread",
1008
+ icon: IconMailForward,
1009
+ },
1010
+ {
1011
+ id: "starred",
1012
+ label: t("mail.views.starred"),
1013
+ href: "/starred",
1014
+ icon: IconStar,
1015
+ },
1016
+ {
1017
+ id: "snoozed",
1018
+ label: t("mail.views.snoozed"),
1019
+ href: "/snoozed",
1020
+ icon: IconClock,
1021
+ },
1022
+ {
1023
+ id: "sent",
1024
+ label: t("mail.views.sent"),
1025
+ href: "/sent",
1026
+ icon: IconMailForward,
1027
+ },
1028
+ {
1029
+ id: "draft-queue",
1030
+ label: t("mail.views.draftQueue"),
1031
+ href: "/draft-queue",
1032
+ icon: IconFileText,
1033
+ count: queuedDrafts.count,
1034
+ },
1035
+ {
1036
+ id: "archive",
1037
+ label: t("mail.views.archive"),
1038
+ href: "/archive",
1039
+ icon: IconArchive,
1040
+ },
1041
+ {
1042
+ id: "trash",
1043
+ label: t("mail.views.trash"),
1044
+ href: "/trash",
1045
+ icon: IconTrash,
1046
+ },
1047
+ ];
974
1048
 
975
1049
  const accountFilterValue = useMemo(
976
1050
  () => ({ activeAccounts, allAccounts: accounts }),
@@ -1348,274 +1422,359 @@ function AppLayoutInner({ children }: AppLayoutProps) {
1348
1422
  )}
1349
1423
  <div
1350
1424
  className={cn(
1351
- "flex w-64 flex-col overflow-hidden bg-background/85 backdrop-blur-2xl border-e border-border/30 shadow-2xl",
1425
+ "flex flex-col overflow-hidden bg-background/85 backdrop-blur-2xl border-e border-border/30 shadow-2xl transition-[width] duration-200 ease-out",
1426
+ showCollapsedSidebar ? "w-12" : "w-64",
1352
1427
  sidebarPinned && !isMobile
1353
1428
  ? "absolute start-0 top-12 bottom-0 z-10"
1354
1429
  : "fixed start-0 top-0 bottom-0 z-40",
1355
1430
  )}
1356
1431
  >
1357
- <div className="flex h-12 shrink-0 items-center justify-between border-b border-border/20 px-4">
1358
- <span className="text-[13px] font-medium text-foreground">
1359
- {t("mail.appName")}
1360
- </span>
1361
- <Tooltip>
1362
- <TooltipTrigger asChild>
1363
- <button
1364
- type="button"
1365
- onClick={() => {
1366
- setSidebarPinned((value) => !value);
1367
- setSidebarOpen(true);
1368
- }}
1369
- className={cn(
1370
- "flex h-7 w-7 items-center justify-center rounded text-muted-foreground hover:bg-accent/50 hover:text-foreground",
1371
- sidebarPinned && "text-foreground bg-accent/50",
1372
- )}
1373
- aria-label={
1374
- sidebarPinned
1375
- ? t("mail.toolbar.unpinSidebar")
1376
- : t("mail.toolbar.pinSidebar")
1377
- }
1378
- >
1379
- {sidebarPinned ? (
1380
- <IconPinnedFilled className="h-4 w-4" />
1381
- ) : (
1382
- <IconPin className="h-4 w-4" />
1383
- )}
1384
- </button>
1385
- </TooltipTrigger>
1386
- <TooltipContent>
1387
- {sidebarPinned
1388
- ? t("mail.toolbar.unpinSidebar")
1389
- : t("mail.toolbar.pinSidebar")}
1390
- </TooltipContent>
1391
- </Tooltip>
1392
- </div>
1393
- <div className="min-h-0 flex-1 overflow-y-auto">
1394
- {/* Accounts */}
1395
- {hasAccounts && (
1396
- <div className="px-4 pt-5 pb-4 border-b border-border/20">
1397
- <div className="space-y-2">
1398
- {accounts.map((account) => {
1399
- const isActive =
1400
- activeAccounts.size === 0 ||
1401
- activeAccounts.has(account.email);
1402
- return (
1432
+ <div
1433
+ className={cn(
1434
+ "flex h-12 shrink-0 items-center border-b border-border/20",
1435
+ showCollapsedSidebar
1436
+ ? "justify-center px-1"
1437
+ : "justify-between px-4",
1438
+ )}
1439
+ >
1440
+ {showCollapsedSidebar ? (
1441
+ <Tooltip>
1442
+ <TooltipTrigger asChild>
1443
+ <button
1444
+ type="button"
1445
+ onClick={() => setSidebarCollapsed(false)}
1446
+ className="flex h-10 w-10 items-center justify-center rounded text-muted-foreground hover:bg-accent/50 hover:text-foreground"
1447
+ aria-label={t("sidebar.expandSidebar")}
1448
+ >
1449
+ <IconLayoutSidebarLeftExpand className="h-4 w-4 rtl:-scale-x-100" />
1450
+ </button>
1451
+ </TooltipTrigger>
1452
+ <TooltipContent side="right">
1453
+ {t("sidebar.expandSidebar")}
1454
+ </TooltipContent>
1455
+ </Tooltip>
1456
+ ) : (
1457
+ <>
1458
+ <span className="text-[13px] font-medium text-foreground">
1459
+ {t("mail.appName")}
1460
+ </span>
1461
+ <div className="flex items-center gap-1">
1462
+ {sidebarPinned && !isMobile ? (
1463
+ <Tooltip>
1464
+ <TooltipTrigger asChild>
1465
+ <button
1466
+ type="button"
1467
+ onClick={() => setSidebarCollapsed(true)}
1468
+ className="flex h-7 w-7 items-center justify-center rounded text-muted-foreground hover:bg-accent/50 hover:text-foreground"
1469
+ aria-label={t("sidebar.collapseSidebar")}
1470
+ >
1471
+ <IconLayoutSidebarLeftCollapse className="h-4 w-4 rtl:-scale-x-100" />
1472
+ </button>
1473
+ </TooltipTrigger>
1474
+ <TooltipContent>
1475
+ {t("sidebar.collapseSidebar")}
1476
+ </TooltipContent>
1477
+ </Tooltip>
1478
+ ) : null}
1479
+ <Tooltip>
1480
+ <TooltipTrigger asChild>
1403
1481
  <button
1404
- key={account.email}
1482
+ type="button"
1405
1483
  onClick={() => {
1406
- setActiveAccounts((prev) => {
1407
- const next = new Set(prev);
1408
- if (next.size === 0) {
1409
- for (const a of accounts) {
1410
- if (a.email !== account.email)
1411
- next.add(a.email);
1412
- }
1413
- } else if (next.has(account.email)) {
1414
- next.delete(account.email);
1415
- if (next.size === 0) return new Set();
1416
- } else {
1417
- next.add(account.email);
1418
- if (next.size === accounts.length)
1419
- return new Set();
1420
- }
1421
- return next;
1422
- });
1484
+ setSidebarPinned((value) => !value);
1485
+ setSidebarOpen(true);
1423
1486
  }}
1424
1487
  className={cn(
1425
- "flex w-full items-center gap-3 rounded-lg px-2 py-1.5 text-start transition-all",
1426
- isActive ? "opacity-100" : "opacity-30",
1488
+ "flex h-7 w-7 items-center justify-center rounded text-muted-foreground hover:bg-accent/50 hover:text-foreground",
1489
+ sidebarPinned && "text-foreground bg-accent/50",
1427
1490
  )}
1491
+ aria-label={
1492
+ sidebarPinned
1493
+ ? t("mail.toolbar.unpinSidebar")
1494
+ : t("mail.toolbar.pinSidebar")
1495
+ }
1428
1496
  >
1429
- <AccountAvatar
1430
- email={account.email}
1431
- photoUrl={account.photoUrl}
1432
- imageClassName="h-8 w-8 rounded-full object-cover shrink-0"
1433
- fallbackClassName="h-8 w-8 rounded-full bg-primary/20 flex items-center justify-center text-[12px] font-semibold text-primary shrink-0"
1434
- />
1435
- <span className="text-[13px] text-foreground truncate">
1436
- {account.email}
1437
- </span>
1497
+ {sidebarPinned ? (
1498
+ <IconPinnedFilled className="h-4 w-4" />
1499
+ ) : (
1500
+ <IconPin className="h-4 w-4" />
1501
+ )}
1438
1502
  </button>
1439
- );
1440
- })}
1503
+ </TooltipTrigger>
1504
+ <TooltipContent>
1505
+ {sidebarPinned
1506
+ ? t("mail.toolbar.unpinSidebar")
1507
+ : t("mail.toolbar.pinSidebar")}
1508
+ </TooltipContent>
1509
+ </Tooltip>
1441
1510
  </div>
1442
- </div>
1511
+ </>
1443
1512
  )}
1444
-
1445
- <div className="p-4">
1446
- <div className="space-y-0.5">
1447
- {[
1448
- {
1449
- id: "inbox",
1450
- label: t("mail.views.inbox"),
1451
- href: "/inbox",
1452
- },
1453
- {
1454
- id: "unread",
1455
- label: t("mail.views.unread"),
1456
- href: "/unread",
1457
- },
1458
- {
1459
- id: "starred",
1460
- label: t("mail.views.starred"),
1461
- href: "/starred",
1462
- },
1463
- {
1464
- id: "snoozed",
1465
- label: t("mail.views.snoozed"),
1466
- href: "/snoozed",
1467
- },
1468
- {
1469
- id: "sent",
1470
- label: t("mail.views.sent"),
1471
- href: "/sent",
1472
- },
1473
- {
1474
- id: "draft-queue",
1475
- label: t("mail.views.draftQueue"),
1476
- href: "/draft-queue",
1477
- },
1478
- {
1479
- id: "scheduled",
1480
- label: t("mail.views.scheduled"),
1481
- href: "/scheduled",
1482
- },
1483
- {
1484
- id: "drafts",
1485
- label: t("mail.views.drafts"),
1486
- href: "/drafts",
1487
- },
1488
- {
1489
- id: "archive",
1490
- label: t("mail.views.archive"),
1491
- href: "/archive",
1492
- },
1493
- {
1494
- id: "trash",
1495
- label: t("mail.views.trash"),
1496
- href: "/trash",
1497
- },
1498
- ].map((item) => (
1499
- <Link
1500
- key={item.id}
1501
- to={item.href}
1502
- onClick={closeSidebar}
1503
- className={cn(
1504
- "flex items-center justify-between rounded-md px-3 py-2.5 text-[14px] transition-colors min-h-[44px]",
1505
- view === item.id
1506
- ? "bg-accent/60 text-foreground font-medium"
1507
- : "text-foreground/70 hover:bg-accent/30",
1508
- )}
1509
- >
1510
- <span>{item.label}</span>
1511
- {item.id === "draft-queue" &&
1512
- queuedDrafts.count > 0 && (
1513
- <span className="text-[12px] text-amber-300 tabular-nums">
1514
- {queuedDrafts.count}
1515
- </span>
1516
- )}
1517
- {item.id === "inbox" && inboxSidebarUnreadCount > 0 && (
1518
- <span className="text-[12px] text-muted-foreground/50 tabular-nums">
1519
- {inboxSidebarUnreadCount}
1520
- </span>
1521
- )}
1522
- </Link>
1523
- ))}
1524
- </div>
1525
-
1526
- {/* Pinned labels */}
1527
- {pinnedLabels.filter(
1528
- (l) => !collapsibleViews.some((v) => v.id === l),
1529
- ).length > 0 && (
1530
- <>
1531
- <h2 className="text-[11px] font-medium text-muted-foreground/50 uppercase tracking-wider mt-5 mb-3">
1532
- {t("mail.views.labels")}
1533
- </h2>
1534
- <div className="space-y-0.5">
1535
- {visibleTabs
1536
- .filter((t) => t.id !== "inbox" && t.type === "label")
1537
- .map((tab) => {
1538
- const count = getUnreadCount(tab.id);
1539
- const depth = labelDepth(
1540
- tab.fullLabel ?? tab.label,
1541
- );
1513
+ </div>
1514
+ {showCollapsedSidebar ? (
1515
+ <nav className="flex min-h-0 flex-1 flex-col items-center gap-1 overflow-y-auto px-1 py-2">
1516
+ {railNavItems.map((item) => {
1517
+ const Icon = item.icon;
1518
+ const isActive = view === item.id;
1519
+ return (
1520
+ <Tooltip key={item.id}>
1521
+ <TooltipTrigger asChild>
1522
+ <Link
1523
+ to={item.href}
1524
+ aria-label={item.label}
1525
+ className={cn(
1526
+ "relative flex h-10 w-10 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground",
1527
+ isActive && "bg-accent/60 text-foreground",
1528
+ )}
1529
+ >
1530
+ <Icon className="h-4 w-4" />
1531
+ {item.count && item.count > 0 ? (
1532
+ <span className="absolute end-1 top-1 h-1.5 w-1.5 rounded-full bg-primary" />
1533
+ ) : null}
1534
+ </Link>
1535
+ </TooltipTrigger>
1536
+ <TooltipContent side="right">
1537
+ {item.label}
1538
+ </TooltipContent>
1539
+ </Tooltip>
1540
+ );
1541
+ })}
1542
+ </nav>
1543
+ ) : (
1544
+ <>
1545
+ <div className="min-h-0 flex-1 overflow-y-auto">
1546
+ {/* Accounts */}
1547
+ {hasAccounts && (
1548
+ <div className="px-4 pt-5 pb-4 border-b border-border/20">
1549
+ <div className="space-y-2">
1550
+ {accounts.map((account) => {
1551
+ const isActive =
1552
+ activeAccounts.size === 0 ||
1553
+ activeAccounts.has(account.email);
1542
1554
  return (
1543
- <Link
1544
- key={tab.id}
1545
- to={tab.href}
1546
- onClick={closeSidebar}
1555
+ <button
1556
+ key={account.email}
1557
+ onClick={() => {
1558
+ setActiveAccounts((prev) => {
1559
+ const next = new Set(prev);
1560
+ if (next.size === 0) {
1561
+ for (const a of accounts) {
1562
+ if (a.email !== account.email)
1563
+ next.add(a.email);
1564
+ }
1565
+ } else if (next.has(account.email)) {
1566
+ next.delete(account.email);
1567
+ if (next.size === 0) return new Set();
1568
+ } else {
1569
+ next.add(account.email);
1570
+ if (next.size === accounts.length)
1571
+ return new Set();
1572
+ }
1573
+ return next;
1574
+ });
1575
+ }}
1547
1576
  className={cn(
1548
- "flex items-center justify-between rounded-md px-3 py-2.5 text-[14px] transition-colors min-h-[44px]",
1549
- tab.isActive
1550
- ? "bg-accent/60 text-foreground font-medium"
1551
- : "text-foreground/70 hover:bg-accent/30",
1577
+ "flex w-full items-center gap-3 rounded-lg px-2 py-1.5 text-start transition-all",
1578
+ isActive ? "opacity-100" : "opacity-30",
1552
1579
  )}
1553
1580
  >
1554
- <span
1555
- className="flex min-w-0 items-center gap-2"
1556
- style={{ paddingLeft: depth * 12 }}
1557
- >
1558
- {tab.color && (
1559
- <span
1560
- className="h-2 w-2 rounded-full shrink-0"
1561
- style={{ backgroundColor: tab.color }}
1562
- />
1563
- )}
1564
- <span
1565
- className="truncate"
1566
- title={tab.fullLabel}
1567
- >
1568
- {shortLabelName(tab.fullLabel ?? tab.label)}
1569
- </span>
1581
+ <AccountAvatar
1582
+ email={account.email}
1583
+ photoUrl={account.photoUrl}
1584
+ imageClassName="h-8 w-8 rounded-full object-cover shrink-0"
1585
+ fallbackClassName="h-8 w-8 rounded-full bg-primary/20 flex items-center justify-center text-[12px] font-semibold text-primary shrink-0"
1586
+ />
1587
+ <span className="text-[13px] text-foreground truncate">
1588
+ {account.email}
1570
1589
  </span>
1571
- {count > 0 && (
1572
- <span className="text-[12px] text-muted-foreground/50 tabular-nums">
1573
- {count}
1574
- </span>
1575
- )}
1576
- </Link>
1590
+ </button>
1577
1591
  );
1578
1592
  })}
1593
+ </div>
1579
1594
  </div>
1580
- </>
1581
- )}
1582
- </div>
1583
- </div>
1595
+ )}
1584
1596
 
1585
- <div className="shrink-0 border-t border-border/20">
1586
- <div className="px-2 py-1">
1587
- <ExtensionsSidebarSection />
1588
- </div>
1597
+ <div className="p-4">
1598
+ <div className="space-y-0.5">
1599
+ {[
1600
+ {
1601
+ id: "inbox",
1602
+ label: t("mail.views.inbox"),
1603
+ href: "/inbox",
1604
+ },
1605
+ {
1606
+ id: "unread",
1607
+ label: t("mail.views.unread"),
1608
+ href: "/unread",
1609
+ },
1610
+ {
1611
+ id: "starred",
1612
+ label: t("mail.views.starred"),
1613
+ href: "/starred",
1614
+ },
1615
+ {
1616
+ id: "snoozed",
1617
+ label: t("mail.views.snoozed"),
1618
+ href: "/snoozed",
1619
+ },
1620
+ {
1621
+ id: "sent",
1622
+ label: t("mail.views.sent"),
1623
+ href: "/sent",
1624
+ },
1625
+ {
1626
+ id: "draft-queue",
1627
+ label: t("mail.views.draftQueue"),
1628
+ href: "/draft-queue",
1629
+ },
1630
+ {
1631
+ id: "scheduled",
1632
+ label: t("mail.views.scheduled"),
1633
+ href: "/scheduled",
1634
+ },
1635
+ {
1636
+ id: "drafts",
1637
+ label: t("mail.views.drafts"),
1638
+ href: "/drafts",
1639
+ },
1640
+ {
1641
+ id: "archive",
1642
+ label: t("mail.views.archive"),
1643
+ href: "/archive",
1644
+ },
1645
+ {
1646
+ id: "trash",
1647
+ label: t("mail.views.trash"),
1648
+ href: "/trash",
1649
+ },
1650
+ ].map((item) => (
1651
+ <Link
1652
+ key={item.id}
1653
+ to={item.href}
1654
+ onClick={closeSidebar}
1655
+ className={cn(
1656
+ "flex items-center justify-between rounded-md px-3 py-2.5 text-[14px] transition-colors min-h-[44px]",
1657
+ view === item.id
1658
+ ? "bg-accent/60 text-foreground font-medium"
1659
+ : "text-foreground/70 hover:bg-accent/30",
1660
+ )}
1661
+ >
1662
+ <span>{item.label}</span>
1663
+ {item.id === "draft-queue" &&
1664
+ queuedDrafts.count > 0 && (
1665
+ <span className="text-[12px] text-amber-300 tabular-nums">
1666
+ {queuedDrafts.count}
1667
+ </span>
1668
+ )}
1669
+ {item.id === "inbox" &&
1670
+ inboxSidebarUnreadCount > 0 && (
1671
+ <span className="text-[12px] text-muted-foreground/50 tabular-nums">
1672
+ {inboxSidebarUnreadCount}
1673
+ </span>
1674
+ )}
1675
+ </Link>
1676
+ ))}
1677
+ </div>
1589
1678
 
1590
- <div className="border-t border-border/20 px-3 py-2">
1591
- <OrgSwitcher />
1592
- </div>
1679
+ {/* Pinned labels */}
1680
+ {pinnedLabels.filter(
1681
+ (l) => !collapsibleViews.some((v) => v.id === l),
1682
+ ).length > 0 && (
1683
+ <>
1684
+ <h2 className="text-[11px] font-medium text-muted-foreground/50 uppercase tracking-wider mt-5 mb-3">
1685
+ {t("mail.views.labels")}
1686
+ </h2>
1687
+ <div className="space-y-0.5">
1688
+ {visibleTabs
1689
+ .filter(
1690
+ (t) => t.id !== "inbox" && t.type === "label",
1691
+ )
1692
+ .map((tab) => {
1693
+ const count = getUnreadCount(tab.id);
1694
+ const depth = labelDepth(
1695
+ tab.fullLabel ?? tab.label,
1696
+ );
1697
+ return (
1698
+ <Link
1699
+ key={tab.id}
1700
+ to={tab.href}
1701
+ onClick={closeSidebar}
1702
+ className={cn(
1703
+ "flex items-center justify-between rounded-md px-3 py-2.5 text-[14px] transition-colors min-h-[44px]",
1704
+ tab.isActive
1705
+ ? "bg-accent/60 text-foreground font-medium"
1706
+ : "text-foreground/70 hover:bg-accent/30",
1707
+ )}
1708
+ >
1709
+ <span
1710
+ className="flex min-w-0 items-center gap-2"
1711
+ style={{ paddingLeft: depth * 12 }}
1712
+ >
1713
+ {tab.color && (
1714
+ <span
1715
+ className="h-2 w-2 rounded-full shrink-0"
1716
+ style={{ backgroundColor: tab.color }}
1717
+ />
1718
+ )}
1719
+ <span
1720
+ className="truncate"
1721
+ title={tab.fullLabel}
1722
+ >
1723
+ {shortLabelName(
1724
+ tab.fullLabel ?? tab.label,
1725
+ )}
1726
+ </span>
1727
+ </span>
1728
+ {count > 0 && (
1729
+ <span className="text-[12px] text-muted-foreground/50 tabular-nums">
1730
+ {count}
1731
+ </span>
1732
+ )}
1733
+ </Link>
1734
+ );
1735
+ })}
1736
+ </div>
1737
+ </>
1738
+ )}
1739
+ </div>
1740
+ </div>
1593
1741
 
1594
- <div className="flex items-center gap-1 border-t border-border/20 px-2 py-2">
1595
- <DevDatabaseLink />
1596
- <FeedbackButton className="min-w-0 flex-1" />
1597
- <Tooltip>
1598
- <TooltipTrigger asChild>
1599
- <Link
1600
- to="/settings"
1601
- onClick={closeSidebar}
1602
- aria-label={t("mail.toolbar.settings")}
1603
- className={cn(
1604
- "flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground",
1605
- location.pathname === "/settings" &&
1606
- "bg-accent/60 text-foreground",
1607
- )}
1608
- >
1609
- <IconSettings className="h-4 w-4" />
1610
- </Link>
1611
- </TooltipTrigger>
1612
- <TooltipContent>
1613
- {t("mail.toolbar.settings")}
1614
- </TooltipContent>
1615
- </Tooltip>
1616
- <ThemeToggle className="h-8 w-8 shrink-0" />
1617
- </div>
1618
- </div>
1742
+ <div className="shrink-0">
1743
+ <div className="px-2 py-1">
1744
+ <ExtensionsSidebarSection />
1745
+ </div>
1746
+
1747
+ <div className="px-3 py-2">
1748
+ <OrgSwitcher />
1749
+ </div>
1750
+
1751
+ <div className="flex items-center gap-1 px-2 py-2">
1752
+ <DevDatabaseLink />
1753
+ <FeedbackButton className="min-w-0 flex-1" />
1754
+ <Tooltip>
1755
+ <TooltipTrigger asChild>
1756
+ <Link
1757
+ to="/settings"
1758
+ onClick={closeSidebar}
1759
+ aria-label={t("mail.toolbar.settings")}
1760
+ className={cn(
1761
+ "flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground",
1762
+ location.pathname === "/settings" &&
1763
+ "bg-accent/60 text-foreground",
1764
+ )}
1765
+ >
1766
+ <IconSettings className="h-4 w-4" />
1767
+ </Link>
1768
+ </TooltipTrigger>
1769
+ <TooltipContent>
1770
+ {t("mail.toolbar.settings")}
1771
+ </TooltipContent>
1772
+ </Tooltip>
1773
+ <ThemeToggle className="h-8 w-8 shrink-0" />
1774
+ </div>
1775
+ </div>
1776
+ </>
1777
+ )}
1619
1778
  </div>
1620
1779
  </>
1621
1780
  )}
@@ -1623,7 +1782,9 @@ function AppLayoutInner({ children }: AppLayoutProps) {
1623
1782
  <div
1624
1783
  className={cn(
1625
1784
  "flex min-h-0 flex-1 flex-col",
1626
- sidebarPinned && !isMobile && "ps-64",
1785
+ sidebarPinned &&
1786
+ !isMobile &&
1787
+ (showCollapsedSidebar ? "ps-12" : "ps-64"),
1627
1788
  )}
1628
1789
  >
1629
1790
  <InvitationBanner />
@@ -1917,16 +2078,16 @@ function StandardLayout({ children }: AppLayoutProps) {
1917
2078
  </div>
1918
2079
  </div>
1919
2080
 
1920
- <div className="shrink-0 border-t border-border/20">
2081
+ <div className="shrink-0">
1921
2082
  <div className="px-2 py-1">
1922
2083
  <ExtensionsSidebarSection />
1923
2084
  </div>
1924
2085
 
1925
- <div className="border-t border-border/20 px-3 py-2">
2086
+ <div className="px-3 py-2">
1926
2087
  <OrgSwitcher />
1927
2088
  </div>
1928
2089
 
1929
- <div className="flex items-center gap-1 border-t border-border/20 px-2 py-2">
2090
+ <div className="flex items-center gap-1 px-2 py-2">
1930
2091
  <DevDatabaseLink />
1931
2092
  <FeedbackButton className="min-w-0 flex-1" />
1932
2093
  <div className="flex shrink-0 items-center gap-0.5">