@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
@@ -0,0 +1,137 @@
1
+ /**
2
+ * shader-safety.ts
3
+ *
4
+ * Pure utility helpers for the GPU shader-effects feature.
5
+ * No imports from @paper-design/shaders-react — safe to use anywhere.
6
+ */
7
+
8
+ // ---------------------------------------------------------------------------
9
+ // Reduced-motion detection
10
+ // ---------------------------------------------------------------------------
11
+
12
+ /**
13
+ * Check if the user prefers reduced motion.
14
+ * Safe to call SSR (returns false on the server).
15
+ */
16
+ export function prefersReducedMotion(): boolean {
17
+ if (typeof window === "undefined") return false;
18
+ return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
19
+ }
20
+
21
+ // ---------------------------------------------------------------------------
22
+ // WebGL availability check (memoized)
23
+ // ---------------------------------------------------------------------------
24
+
25
+ let _webGLAvailable: boolean | null = null;
26
+
27
+ /**
28
+ * Check if WebGL is available in the current browser environment.
29
+ * Safe to call SSR (returns false on the server).
30
+ * Result is cached after the first call.
31
+ */
32
+ export function isWebGLAvailable(): boolean {
33
+ if (typeof window === "undefined") return false;
34
+ if (_webGLAvailable !== null) return _webGLAvailable;
35
+
36
+ try {
37
+ const canvas = document.createElement("canvas");
38
+ const ctx =
39
+ canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
40
+ _webGLAvailable = ctx !== null;
41
+ } catch {
42
+ _webGLAvailable = false;
43
+ }
44
+
45
+ return _webGLAvailable;
46
+ }
47
+
48
+ // ---------------------------------------------------------------------------
49
+ // Per-artboard WebGL context counter
50
+ // ---------------------------------------------------------------------------
51
+
52
+ /**
53
+ * Browsers support ~8-16 WebGL contexts per page; we cap at this value per
54
+ * artboard to stay well within that limit.
55
+ */
56
+ export const MAX_SHADERS_PER_ARTBOARD = 5;
57
+
58
+ const _shaderCounts = new Map<string, number>();
59
+
60
+ /**
61
+ * Register a shader instance for an artboard.
62
+ * Returns true if the instance is within budget, false if over limit.
63
+ */
64
+ export function registerShaderInstance(artboardId: string): boolean {
65
+ const current = _shaderCounts.get(artboardId) ?? 0;
66
+ const next = current + 1;
67
+ _shaderCounts.set(artboardId, next);
68
+ return next <= MAX_SHADERS_PER_ARTBOARD;
69
+ }
70
+
71
+ /**
72
+ * Unregister a shader instance when the component unmounts.
73
+ */
74
+ export function unregisterShaderInstance(artboardId: string): void {
75
+ const current = _shaderCounts.get(artboardId) ?? 0;
76
+ const next = Math.max(0, current - 1);
77
+ if (next === 0) {
78
+ _shaderCounts.delete(artboardId);
79
+ } else {
80
+ _shaderCounts.set(artboardId, next);
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Get current shader instance count for an artboard.
86
+ */
87
+ export function getShaderCount(artboardId: string): number {
88
+ return _shaderCounts.get(artboardId) ?? 0;
89
+ }
90
+
91
+ // ---------------------------------------------------------------------------
92
+ // Fallback CSS gradient
93
+ // ---------------------------------------------------------------------------
94
+
95
+ /**
96
+ * Build a fallback CSS linear-gradient from a colors array.
97
+ * Used when WebGL is unavailable or the context limit is hit.
98
+ *
99
+ * Examples:
100
+ * buildFallbackGradient(["#e0eaff", "#241d9a", "#f75092"])
101
+ * → "linear-gradient(135deg, #e0eaff, #241d9a, #f75092)"
102
+ *
103
+ * buildFallbackGradient(["#241d9a"], "#e0eaff")
104
+ * → "linear-gradient(135deg, #e0eaff, #241d9a)"
105
+ *
106
+ * buildFallbackGradient(["#241d9a"])
107
+ * → "#241d9a"
108
+ */
109
+ export function buildFallbackGradient(
110
+ colors: string[],
111
+ colorBack?: string,
112
+ ): string {
113
+ const stops = colorBack ? [colorBack, ...colors] : [...colors];
114
+
115
+ if (stops.length === 1) {
116
+ return stops[0];
117
+ }
118
+
119
+ return `linear-gradient(135deg, ${stops.join(", ")})`;
120
+ }
121
+
122
+ // ---------------------------------------------------------------------------
123
+ // Speed resolution
124
+ // ---------------------------------------------------------------------------
125
+
126
+ /**
127
+ * Returns the effective animation speed.
128
+ * Returns 0 if the user prefers reduced motion or animated is false.
129
+ * NOT a React hook — just a pure function.
130
+ */
131
+ export function resolveShaderSpeed(
132
+ requestedSpeed: number,
133
+ animated: boolean,
134
+ ): number {
135
+ if (!animated || prefersReducedMotion()) return 0;
136
+ return requestedSpeed;
137
+ }
@@ -0,0 +1,237 @@
1
+ export const DESIGN_SOURCE_TYPES = ["inline", "localhost", "fusion"] as const;
2
+
3
+ export type DesignSourceType = (typeof DESIGN_SOURCE_TYPES)[number];
4
+
5
+ export const DESIGN_BRIDGE_OPERATIONS = [
6
+ "select",
7
+ "resolveNodeToFile",
8
+ "readFile",
9
+ "applyEdit",
10
+ "writeFile",
11
+ "captureSnapshot",
12
+ "captureState",
13
+ ] as const;
14
+
15
+ export type DesignBridgeOperation = (typeof DESIGN_BRIDGE_OPERATIONS)[number];
16
+
17
+ export type DesignBridgeOperationStatus = "available" | "planned" | "disabled";
18
+
19
+ export interface DesignBridgeCapability {
20
+ operation: DesignBridgeOperation;
21
+ status: DesignBridgeOperationStatus;
22
+ reason?: string;
23
+ }
24
+
25
+ export interface LocalhostDesignRoute {
26
+ id: string;
27
+ path: string;
28
+ title: string;
29
+ sourceFile?: string;
30
+ sourceKind?: "react-router" | "html" | "manual";
31
+ screenshotUrl?: string;
32
+ metadata?: Record<string, unknown>;
33
+ }
34
+
35
+ export interface LocalhostDesignRouteManifest {
36
+ version: 1;
37
+ sourceType: "localhost";
38
+ devServerUrl: string;
39
+ rootPath?: string;
40
+ routes: LocalhostDesignRoute[];
41
+ generatedAt: string;
42
+ }
43
+
44
+ export interface LocalhostDesignConnectionConfig {
45
+ id: string;
46
+ sourceType: "localhost";
47
+ name: string;
48
+ devServerUrl: string;
49
+ bridgeUrl?: string;
50
+ rootPath?: string;
51
+ routeManifest: LocalhostDesignRouteManifest;
52
+ capabilities: DesignBridgeCapability[];
53
+ status: "connected" | "detected" | "manual" | "error";
54
+ lastSeenAt?: string;
55
+ createdAt?: string;
56
+ updatedAt?: string;
57
+ }
58
+
59
+ export interface InlineDesignSource {
60
+ sourceType: "inline";
61
+ designId?: string;
62
+ fileId?: string;
63
+ filename?: string;
64
+ revision?: string;
65
+ }
66
+
67
+ export interface LocalhostDesignSource {
68
+ sourceType: "localhost";
69
+ connectionId: string;
70
+ routeId?: string;
71
+ path?: string;
72
+ url?: string;
73
+ bridgeUrl?: string;
74
+ revision?: string;
75
+ }
76
+
77
+ export interface FusionDesignSource {
78
+ sourceType: "fusion";
79
+ externalId?: string;
80
+ url?: string;
81
+ revision?: string;
82
+ metadata?: Record<string, unknown>;
83
+ }
84
+
85
+ export type DesignSourceDescriptor =
86
+ | InlineDesignSource
87
+ | LocalhostDesignSource
88
+ | FusionDesignSource;
89
+
90
+ export interface FlowCanvasSnapshotRef {
91
+ id: string;
92
+ sourceType: DesignSourceType;
93
+ capturedAt: string;
94
+ imageUrl?: string;
95
+ stateUrl?: string;
96
+ contentHash?: string;
97
+ width?: number;
98
+ height?: number;
99
+ }
100
+
101
+ export interface FlowCanvasArtboard {
102
+ id: string;
103
+ title: string;
104
+ sourceType: DesignSourceType;
105
+ source: DesignSourceDescriptor;
106
+ routeId?: string;
107
+ path?: string;
108
+ x: number;
109
+ y: number;
110
+ width: number;
111
+ height: number;
112
+ snapshot?: FlowCanvasSnapshotRef;
113
+ metadata?: Record<string, unknown>;
114
+ }
115
+
116
+ export interface FlowCanvasEdge {
117
+ id: string;
118
+ fromArtboardId: string;
119
+ toArtboardId: string;
120
+ trigger?: string;
121
+ derivedFrom?: {
122
+ operation: "captureState" | "captureSnapshot" | "manual";
123
+ sourceNodeId?: string;
124
+ selector?: string;
125
+ };
126
+ metadata?: Record<string, unknown>;
127
+ }
128
+
129
+ export type DesignBridgeRequest =
130
+ | {
131
+ operation: "select";
132
+ source: DesignSourceDescriptor;
133
+ selector?: string;
134
+ nodeId?: string;
135
+ }
136
+ | {
137
+ operation: "resolveNodeToFile";
138
+ source: DesignSourceDescriptor;
139
+ selector?: string;
140
+ nodeId?: string;
141
+ }
142
+ | {
143
+ operation: "readFile";
144
+ source: DesignSourceDescriptor;
145
+ path: string;
146
+ }
147
+ | {
148
+ operation: "applyEdit";
149
+ source: DesignSourceDescriptor;
150
+ path: string;
151
+ edit: {
152
+ kind: "replace" | "instruction";
153
+ search?: string;
154
+ replacement?: string;
155
+ instruction?: string;
156
+ };
157
+ }
158
+ | {
159
+ operation: "writeFile";
160
+ source: DesignSourceDescriptor;
161
+ path: string;
162
+ content: string;
163
+ }
164
+ | {
165
+ operation: "captureSnapshot" | "captureState";
166
+ source: DesignSourceDescriptor;
167
+ routeId?: string;
168
+ path?: string;
169
+ };
170
+
171
+ export interface DesignBridgeResponse<T = unknown> {
172
+ ok: boolean;
173
+ operation: DesignBridgeOperation;
174
+ data?: T;
175
+ error?: string;
176
+ }
177
+
178
+ export function isDesignSourceType(value: unknown): value is DesignSourceType {
179
+ return (
180
+ typeof value === "string" &&
181
+ (DESIGN_SOURCE_TYPES as readonly string[]).includes(value)
182
+ );
183
+ }
184
+
185
+ export function normalizeDesignSourceType(
186
+ value: unknown,
187
+ ): DesignSourceType | null {
188
+ if (isDesignSourceType(value)) return value;
189
+ if (typeof value !== "string") return null;
190
+ const normalized = value.trim().toLowerCase();
191
+ if (
192
+ normalized === "design-file" ||
193
+ normalized === "inline-html" ||
194
+ normalized === "sql" ||
195
+ normalized === "snapshot"
196
+ ) {
197
+ return "inline";
198
+ }
199
+ if (
200
+ normalized === "local" ||
201
+ normalized === "local-file" ||
202
+ normalized === "localhost" ||
203
+ normalized === "dev-server"
204
+ ) {
205
+ return "localhost";
206
+ }
207
+ if (normalized === "fusion" || normalized === "remote-url") {
208
+ return "fusion";
209
+ }
210
+ return null;
211
+ }
212
+
213
+ export function makeLocalhostRouteId(path: string): string {
214
+ const normalized = path.trim() || "/";
215
+ if (normalized === "/") return "route-root";
216
+ const slug = normalized
217
+ .replace(/^\/+/, "")
218
+ .replace(/[^a-zA-Z0-9]+/g, "-")
219
+ .replace(/^-+|-+$/g, "")
220
+ .toLowerCase();
221
+ return slug ? `route-${slug}` : "route-wildcard";
222
+ }
223
+
224
+ export function titleFromRoutePath(path: string): string {
225
+ const normalized = path.trim();
226
+ if (!normalized || normalized === "/") return "Home";
227
+ if (normalized === "/*" || normalized === "*") return "Wildcard";
228
+ return (
229
+ normalized
230
+ .replace(/^\/+/, "")
231
+ .replace(/[:$]/g, "")
232
+ .replace(/[-_/]+/g, " ")
233
+ .replace(/\s+/g, " ")
234
+ .trim()
235
+ .replace(/\b\w/g, (char) => char.toUpperCase()) || "Screen"
236
+ );
237
+ }
@@ -17,6 +17,8 @@ import {
17
17
  IconMessageCircle,
18
18
  IconSettings,
19
19
  IconForms,
20
+ IconLayoutSidebarLeftCollapse,
21
+ IconLayoutSidebarLeftExpand,
20
22
  } from "@tabler/icons-react";
21
23
  import { useState, useRef, useEffect, type MouseEvent } from "react";
22
24
  import { Link, useLocation, useNavigate } from "react-router";
@@ -41,6 +43,8 @@ import { useCreateForm } from "@/hooks/use-forms";
41
43
  import { useIsMobile } from "@/hooks/use-mobile";
42
44
  import { cn } from "@/lib/utils";
43
45
 
46
+ const SIDEBAR_COLLAPSE_KEY = "forms.sidebar.collapsed";
47
+
44
48
  export function Sidebar() {
45
49
  const location = useLocation();
46
50
  const navigate = useNavigate();
@@ -55,6 +59,15 @@ export function Sidebar() {
55
59
  const textareaRef = useRef<HTMLTextAreaElement>(null);
56
60
  const isMobile = useIsMobile();
57
61
  const [mobileOpen, setMobileOpen] = useState(false);
62
+ const [collapsed, setCollapsed] = useState<boolean>(() => {
63
+ if (typeof window === "undefined") return false;
64
+ try {
65
+ return window.localStorage.getItem(SIDEBAR_COLLAPSE_KEY) === "1";
66
+ } catch {
67
+ return false;
68
+ }
69
+ });
70
+ const effectiveCollapsed = collapsed && !isMobile;
58
71
 
59
72
  useEffect(() => {
60
73
  if (popoverOpen) {
@@ -63,6 +76,15 @@ export function Sidebar() {
63
76
  }
64
77
  }, [popoverOpen]);
65
78
 
79
+ useEffect(() => {
80
+ if (typeof window === "undefined") return;
81
+ try {
82
+ window.localStorage.setItem(SIDEBAR_COLLAPSE_KEY, collapsed ? "1" : "0");
83
+ } catch {
84
+ // Ignore storage failures; the in-memory preference still works.
85
+ }
86
+ }, [collapsed]);
87
+
66
88
  function handleSkip() {
67
89
  setPopoverOpen(false);
68
90
  const tempId = crypto.randomUUID().replace(/-/g, "").slice(0, 10);
@@ -170,10 +192,113 @@ export function Sidebar() {
170
192
  </PopoverContent>
171
193
  );
172
194
 
173
- const sidebarContent = (
195
+ const sidebarContent = effectiveCollapsed ? (
196
+ <div className="agent-layout-left-drawer flex h-screen w-12 min-w-0 shrink-0 flex-col items-center overflow-hidden border-e border-border bg-muted/30 py-2 transition-[width] duration-200 ease-out">
197
+ <TooltipProvider delayDuration={0}>
198
+ <Tooltip>
199
+ <TooltipTrigger asChild>
200
+ <button
201
+ type="button"
202
+ onClick={() => setCollapsed(false)}
203
+ className="flex h-10 w-10 items-center justify-center rounded-md text-muted-foreground/55 transition-colors hover:bg-accent/50 hover:text-muted-foreground"
204
+ aria-label={t("sidebar.expandSidebar")}
205
+ >
206
+ <IconLayoutSidebarLeftExpand className="h-4 w-4 rtl:-scale-x-100" />
207
+ </button>
208
+ </TooltipTrigger>
209
+ <TooltipContent side="right">
210
+ {t("sidebar.expandSidebar")}
211
+ </TooltipContent>
212
+ </Tooltip>
213
+
214
+ <nav className="mt-1 flex min-h-0 flex-1 flex-col items-center gap-1 overflow-y-auto">
215
+ <Tooltip>
216
+ <TooltipTrigger asChild>
217
+ <Link
218
+ to="/ask"
219
+ onClick={navigateHomeChat}
220
+ aria-label={t("navigation.askForms")}
221
+ className={cn(
222
+ "flex h-10 w-10 items-center justify-center rounded-md transition-colors",
223
+ location.pathname === "/ask" || location.pathname === "/"
224
+ ? "bg-accent text-accent-foreground"
225
+ : "text-muted-foreground hover:bg-accent/50 hover:text-foreground",
226
+ )}
227
+ >
228
+ <IconMessageCircle className="h-4 w-4" />
229
+ </Link>
230
+ </TooltipTrigger>
231
+ <TooltipContent side="right">
232
+ {t("navigation.askForms")}
233
+ </TooltipContent>
234
+ </Tooltip>
235
+
236
+ <Tooltip>
237
+ <TooltipTrigger asChild>
238
+ <Link
239
+ to="/forms"
240
+ aria-label={t("navigation.allForms")}
241
+ className={cn(
242
+ "flex h-10 w-10 items-center justify-center rounded-md transition-colors",
243
+ location.pathname.startsWith("/forms")
244
+ ? "bg-accent text-accent-foreground"
245
+ : "text-muted-foreground hover:bg-accent/50 hover:text-foreground",
246
+ )}
247
+ >
248
+ <IconForms className="h-4 w-4" />
249
+ </Link>
250
+ </TooltipTrigger>
251
+ <TooltipContent side="right">
252
+ {t("navigation.allForms")}
253
+ </TooltipContent>
254
+ </Tooltip>
255
+
256
+ <Popover open={popoverOpen} onOpenChange={setPopoverOpen}>
257
+ <Tooltip>
258
+ <TooltipTrigger asChild>
259
+ <PopoverTrigger asChild>
260
+ <button
261
+ type="button"
262
+ aria-label={t("sidebar.newForm")}
263
+ className="flex h-10 w-10 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground"
264
+ >
265
+ <IconPlus className="h-4 w-4" />
266
+ </button>
267
+ </PopoverTrigger>
268
+ </TooltipTrigger>
269
+ <TooltipContent side="right">
270
+ {t("sidebar.newForm")}
271
+ </TooltipContent>
272
+ </Tooltip>
273
+ {newFormPopover}
274
+ </Popover>
275
+
276
+ <Tooltip>
277
+ <TooltipTrigger asChild>
278
+ <Link
279
+ to="/settings"
280
+ aria-label={t("navigation.settings")}
281
+ className={cn(
282
+ "flex h-10 w-10 items-center justify-center rounded-md transition-colors",
283
+ location.pathname === "/settings"
284
+ ? "bg-accent text-accent-foreground"
285
+ : "text-muted-foreground hover:bg-accent/50 hover:text-foreground",
286
+ )}
287
+ >
288
+ <IconSettings className="h-4 w-4" />
289
+ </Link>
290
+ </TooltipTrigger>
291
+ <TooltipContent side="right">
292
+ {t("navigation.settings")}
293
+ </TooltipContent>
294
+ </Tooltip>
295
+ </nav>
296
+ </TooltipProvider>
297
+ </div>
298
+ ) : (
174
299
  <div
175
300
  className={cn(
176
- "agent-layout-left-drawer flex h-screen w-60 min-w-0 shrink-0 flex-col overflow-hidden border-e border-border bg-muted/30",
301
+ "agent-layout-left-drawer flex h-screen w-60 min-w-0 shrink-0 flex-col overflow-hidden border-e border-border bg-muted/30 transition-[width] duration-200 ease-out",
177
302
  isMobile && "w-full",
178
303
  )}
179
304
  >
@@ -185,7 +310,7 @@ export function Sidebar() {
185
310
  <button
186
311
  type="button"
187
312
  aria-label={t("sidebar.openAskFullScreen")}
188
- className="flex min-w-0 items-center gap-2 rounded-md text-base font-semibold tracking-tight text-foreground transition-colors hover:text-foreground/80 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
313
+ className="flex min-w-0 items-center gap-2 rounded-md text-base font-semibold tracking-tight text-muted-foreground/80 transition-colors hover:text-foreground/80 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
189
314
  onClick={toggleLogoView}
190
315
  >
191
316
  <img
@@ -218,6 +343,24 @@ export function Sidebar() {
218
343
  <IconX size={18} />
219
344
  </Button>
220
345
  )}
346
+ {!isMobile && (
347
+ <Tooltip>
348
+ <TooltipTrigger asChild>
349
+ <Button
350
+ variant="ghost"
351
+ size="icon"
352
+ className="h-8 w-8 text-muted-foreground/55 hover:bg-accent/50 hover:text-muted-foreground"
353
+ onClick={() => setCollapsed(true)}
354
+ aria-label={t("sidebar.collapseSidebar")}
355
+ >
356
+ <IconLayoutSidebarLeftCollapse className="h-4 w-4 rtl:-scale-x-100" />
357
+ </Button>
358
+ </TooltipTrigger>
359
+ <TooltipContent side="right">
360
+ {t("sidebar.collapseSidebar")}
361
+ </TooltipContent>
362
+ </Tooltip>
363
+ )}
221
364
  </div>
222
365
 
223
366
  <ScrollArea className="min-h-0 min-w-0 flex-1">
@@ -267,7 +410,7 @@ export function Sidebar() {
267
410
  </ScrollArea>
268
411
 
269
412
  {/* Pinned nav + footer */}
270
- <div className="shrink-0 border-t border-border px-3 py-1.5">
413
+ <div className="shrink-0 px-3 py-1.5">
271
414
  <Link
272
415
  to="/settings"
273
416
  onClick={() => isMobile && setMobileOpen(false)}
@@ -284,12 +427,12 @@ export function Sidebar() {
284
427
  </div>
285
428
 
286
429
  {/* Tools */}
287
- <div className="shrink-0 border-t border-border px-1.5 py-1.5">
430
+ <div className="shrink-0 px-1.5 py-1.5">
288
431
  <ExtensionsSidebarSection />
289
432
  </div>
290
433
 
291
434
  {/* Footer */}
292
- <div className="shrink-0 space-y-2 border-t border-border px-3 py-2">
435
+ <div className="shrink-0 space-y-2 px-3 py-2">
293
436
  <OrgSwitcher />
294
437
  <DevDatabaseLink />
295
438
  <div className="flex items-center gap-2">
@@ -43,6 +43,8 @@ const messages = {
43
43
  suggestionExport: "صدر الردود إلى CSV",
44
44
  },
45
45
  sidebar: {
46
+ collapseSidebar: "طي الشريط الجانبي",
47
+ expandSidebar: "توسيع الشريط الجانبي",
46
48
  formGenerationStale:
47
49
  "يستغرق إنشاء النموذج وقتا أطول من المتوقع. يمكنك المحاولة مرة أخرى.",
48
50
  untitledForm: "نموذج بلا عنوان",
@@ -44,6 +44,8 @@ const messages = {
44
44
  suggestionExport: "Antworten als CSV exportieren",
45
45
  },
46
46
  sidebar: {
47
+ collapseSidebar: "Seitenleiste einklappen",
48
+ expandSidebar: "Seitenleiste erweitern",
47
49
  formGenerationStale:
48
50
  "Die Formularerstellung dauert langer als erwartet. Du kannst es erneut versuchen.",
49
51
  untitledForm: "Unbenanntes Formular",
@@ -44,6 +44,8 @@ const messages = {
44
44
  suggestionExport: "Export responses to CSV",
45
45
  },
46
46
  sidebar: {
47
+ collapseSidebar: "Collapse sidebar",
48
+ expandSidebar: "Expand sidebar",
47
49
  formGenerationStale:
48
50
  "Form generation is taking longer than expected. You can try again.",
49
51
  untitledForm: "Untitled Form",
@@ -44,6 +44,8 @@ const messages = {
44
44
  suggestionExport: "Exportar respuestas a CSV",
45
45
  },
46
46
  sidebar: {
47
+ collapseSidebar: "Contraer barra lateral",
48
+ expandSidebar: "Expandir barra lateral",
47
49
  formGenerationStale:
48
50
  "La generacion del formulario tarda mas de lo esperado. Puedes intentarlo otra vez.",
49
51
  untitledForm: "Formulario sin titulo",
@@ -44,6 +44,8 @@ const messages = {
44
44
  suggestionExport: "Exporter les reponses en CSV",
45
45
  },
46
46
  sidebar: {
47
+ collapseSidebar: "Réduire la barre latérale",
48
+ expandSidebar: "Développer la barre latérale",
47
49
  formGenerationStale:
48
50
  "La generation du formulaire prend plus de temps que prevu. Vous pouvez reessayer.",
49
51
  untitledForm: "Formulaire sans titre",
@@ -43,6 +43,8 @@ const messages = {
43
43
  suggestionExport: "Responses को CSV में export करें",
44
44
  },
45
45
  sidebar: {
46
+ collapseSidebar: "साइडबार समेटें",
47
+ expandSidebar: "साइडबार फैलाएं",
46
48
  formGenerationStale:
47
49
  "Form generation उम्मीद से ज्यादा समय ले रहा है। आप फिर कोशिश कर सकते हैं।",
48
50
  untitledForm: "शीर्षक रहित प्रपत्र",
@@ -44,6 +44,8 @@ const messages = {
44
44
  suggestionExport: "回答を CSV にエクスポート",
45
45
  },
46
46
  sidebar: {
47
+ collapseSidebar: "サイドバーを折りたたむ",
48
+ expandSidebar: "サイドバーを展開",
47
49
  formGenerationStale:
48
50
  "フォーム生成に予想より時間がかかっています。もう一度試せます。",
49
51
  untitledForm: "無題のフォーム",
@@ -44,6 +44,8 @@ const messages = {
44
44
  suggestionExport: "응답을 CSV로 내보내기",
45
45
  },
46
46
  sidebar: {
47
+ collapseSidebar: "사이드바 접기",
48
+ expandSidebar: "사이드바 펼치기",
47
49
  formGenerationStale:
48
50
  "양식 생성이 예상보다 오래 걸립니다. 다시 시도할 수 있습니다.",
49
51
  untitledForm: "제목 없는 양식",
@@ -44,6 +44,8 @@ const messages = {
44
44
  suggestionExport: "Exportar respostas para CSV",
45
45
  },
46
46
  sidebar: {
47
+ collapseSidebar: "Recolher barra lateral",
48
+ expandSidebar: "Expandir barra lateral",
47
49
  formGenerationStale:
48
50
  "A geracao do formulario esta demorando mais que o esperado. Voce pode tentar de novo.",
49
51
  untitledForm: "Formulario sem titulo",