@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
@@ -84,6 +84,10 @@ export interface PresentationModeMessage {
84
84
  data: { active: boolean };
85
85
  }
86
86
 
87
+ export interface DesignCloseMessage {
88
+ type: "design:close";
89
+ }
90
+
87
91
  export type AppToFrameMessage =
88
92
  | AppReadyMessage
89
93
  | SubmitChatMessage
@@ -97,7 +101,8 @@ export type AppToFrameMessage =
97
101
  | EnterStyleEditingMessage
98
102
  | EnterTextEditingMessage
99
103
  | ExitSelectionModeMessage
100
- | PresentationModeMessage;
104
+ | PresentationModeMessage
105
+ | DesignCloseMessage;
101
106
 
102
107
  // ---------------------------------------------------------------------------
103
108
  // Messages FROM frame TO app
@@ -138,13 +143,23 @@ export interface SidebarModeMessage {
138
143
  };
139
144
  }
140
145
 
146
+ export interface DesignInitMessage {
147
+ type: "design:init";
148
+ data: {
149
+ previewUrl: string;
150
+ themeVars?: Record<string, string>;
151
+ context?: { projectId?: string; branchId?: string; orgId?: string };
152
+ };
153
+ }
154
+
141
155
  export type FrameToAppMessage =
142
156
  | FrameOriginMessage
143
157
  | ChatRunningMessage
144
158
  | UserInfoMessage
145
159
  | CodeCompleteMessage
146
160
  | SidebarModeMessage
147
- | PresentationModeMessage;
161
+ | PresentationModeMessage
162
+ | DesignInitMessage;
148
163
 
149
164
  // ---------------------------------------------------------------------------
150
165
  // All message types
@@ -344,7 +344,7 @@ export function RegistryBlockNodeView(props: NodeViewProps) {
344
344
  data-plan-interactive
345
345
  aria-label={`Edit ${spec.label}`}
346
346
  onClick={() => setPanelOpen(true)}
347
- className="an-block-edit-trigger flex size-7 items-center justify-center rounded-md border border-border bg-background/85 text-muted-foreground opacity-0 shadow-sm backdrop-blur transition-opacity hover:bg-muted hover:text-foreground focus-visible:opacity-100 data-[visible=true]:opacity-100"
347
+ className="an-block-edit-trigger flex size-7 items-center justify-center rounded-md border border-border bg-background text-muted-foreground opacity-0 shadow-sm transition-opacity hover:bg-muted hover:text-foreground focus-visible:opacity-100 data-[visible=true]:opacity-100"
348
348
  data-visible={panelOpen || shellHovered}
349
349
  >
350
350
  <IconPencil className="size-4" />
@@ -485,7 +485,7 @@ export function LegacyJsonEditSurface({
485
485
  data-plan-interactive
486
486
  aria-label={`Edit ${block.title ?? "block"}`}
487
487
  onClick={() => onOpenChange(true)}
488
- className="an-block-edit-trigger flex size-7 items-center justify-center rounded-md border border-border bg-background/85 text-muted-foreground opacity-0 shadow-sm backdrop-blur transition-opacity hover:bg-muted hover:text-foreground focus-visible:opacity-100 data-[visible=true]:opacity-100"
488
+ className="an-block-edit-trigger flex size-7 items-center justify-center rounded-md border border-border bg-background text-muted-foreground opacity-0 shadow-sm transition-opacity hover:bg-muted hover:text-foreground focus-visible:opacity-100 data-[visible=true]:opacity-100"
489
489
  data-visible={selected || open}
490
490
  >
491
491
  <IconPencil className="size-4" />
@@ -47,6 +47,8 @@ export interface ShareButtonProps {
47
47
  variant?: "compact" | "label";
48
48
  /** Optional trigger style. Defaults to the Google-Docs-style "Share" label. */
49
49
  trigger?: "label" | "icon";
50
+ /** Hide the visibility/share glyph in the label trigger. */
51
+ hideTriggerIcon?: boolean;
50
52
  /** Optional className applied to the trigger button. */
51
53
  triggerClassName?: string;
52
54
  /** Notified when the share popover opens or closes. Hosts that render the
@@ -154,7 +156,7 @@ const BUTTON_GHOST_ICON = cn(
154
156
  "h-7 w-7 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground",
155
157
  );
156
158
  const SHARE_POPOVER_SURFACE =
157
- "border-[hsl(var(--sidebar-border,var(--border)))] bg-[hsl(var(--sidebar-background,var(--popover)))]";
159
+ "border border-border bg-popover text-popover-foreground";
158
160
  const MEMBER_SUGGESTION_LIMIT = 25;
159
161
  const MEMBER_SEARCH_DEBOUNCE_MS = 140;
160
162
 
@@ -311,6 +313,7 @@ export function ShareButton(props: ShareButtonProps) {
311
313
  : currentVisibility === "org"
312
314
  ? IconBuilding
313
315
  : IconLock;
316
+ const showTriggerIcon = iconOnly || !props.hideTriggerIcon;
314
317
  const TriggerIcon = iconOnly ? IconShare3 : VisibilityIcon;
315
318
 
316
319
  return (
@@ -324,14 +327,16 @@ export function ShareButton(props: ShareButtonProps) {
324
327
  )}
325
328
  aria-label={iconOnly ? "Share" : undefined}
326
329
  >
327
- {loaded || iconOnly ? (
328
- <TriggerIcon size={16} strokeWidth={1.75} />
329
- ) : (
330
- <span
331
- aria-hidden
332
- className="inline-block h-4 w-4 rounded-sm bg-muted animate-pulse"
333
- />
334
- )}
330
+ {showTriggerIcon ? (
331
+ loaded || iconOnly ? (
332
+ <TriggerIcon size={16} strokeWidth={1.75} />
333
+ ) : (
334
+ <span
335
+ aria-hidden
336
+ className="inline-block h-4 w-4 rounded-sm bg-muted animate-pulse"
337
+ />
338
+ )
339
+ ) : null}
335
340
  {!iconOnly && <span>Share</span>}
336
341
  </button>
337
342
  </PopoverTrigger>
@@ -1029,7 +1034,7 @@ function AdvancedAccessPopover({
1029
1034
  disabled={!canManage || control.pending}
1030
1035
  onClick={onToggle}
1031
1036
  className={cn(
1032
- "flex w-full items-start gap-3 rounded-md border border-border/70 bg-background px-3 py-2.5 text-start transition-colors hover:bg-accent/45 disabled:cursor-not-allowed disabled:opacity-60",
1037
+ "flex w-full items-start gap-3 rounded-md border border-border/70 bg-card px-3 py-2.5 text-start transition-colors hover:bg-accent/45 disabled:cursor-not-allowed disabled:opacity-60",
1033
1038
  control.checked && "border-border bg-accent/35 text-foreground",
1034
1039
  )}
1035
1040
  >
@@ -1042,7 +1047,7 @@ function AdvancedAccessPopover({
1042
1047
  >
1043
1048
  <span
1044
1049
  className={cn(
1045
- "ml-0.5 size-4 rounded-full bg-background shadow-sm transition-transform",
1050
+ "ml-0.5 size-4 rounded-full bg-popover shadow-sm transition-transform",
1046
1051
  control.checked && "translate-x-4",
1047
1052
  )}
1048
1053
  />
@@ -1210,7 +1215,7 @@ function MemberAutocomplete({
1210
1215
  }}
1211
1216
  onKeyDown={handleKeyDown}
1212
1217
  autoComplete="off"
1213
- className="h-9 w-full min-w-0 rounded-md border border-input bg-background ps-8 pe-8 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background"
1218
+ className="h-9 w-full min-w-0 rounded-md border border-input bg-card ps-8 pe-8 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background"
1214
1219
  />
1215
1220
  {search.isLoading ? (
1216
1221
  <IconLoader2
@@ -1355,13 +1360,13 @@ function CopyLinkField({
1355
1360
  <input
1356
1361
  readOnly
1357
1362
  value={value}
1358
- className="h-9 min-w-0 flex-1 rounded-md border border-input bg-background px-3 text-sm text-muted-foreground outline-none"
1363
+ className="h-9 min-w-0 flex-1 rounded-md border border-input bg-card px-3 text-sm text-muted-foreground outline-none"
1359
1364
  onFocus={(event) => event.currentTarget.select()}
1360
1365
  />
1361
1366
  <button
1362
1367
  type="button"
1363
1368
  onClick={handleCopy}
1364
- className="inline-flex h-9 shrink-0 items-center gap-2 rounded-md border border-input bg-background px-3 text-sm font-medium text-foreground hover:bg-accent"
1369
+ className="inline-flex h-9 shrink-0 items-center gap-2 rounded-md border border-input bg-card px-3 text-sm font-medium text-foreground hover:bg-accent"
1365
1370
  >
1366
1371
  {copied ? <IconCheck size={15} /> : <IconCopy size={15} />}
1367
1372
  {copied ? "Copied" : "Copy"}
@@ -1439,7 +1444,7 @@ function RoleSelect(props: {
1439
1444
  )
1440
1445
  : cn(
1441
1446
  BUTTON_BASE,
1442
- "h-9 px-3 border border-input bg-background hover:bg-accent hover:text-accent-foreground",
1447
+ "h-9 px-3 border border-input bg-card hover:bg-accent hover:text-accent-foreground",
1443
1448
  )
1444
1449
  }
1445
1450
  aria-label="Role"
@@ -14,6 +14,83 @@ export interface UseAgentEngineConfiguredResult {
14
14
  state: AgentEngineConfiguredState;
15
15
  }
16
16
 
17
+ export interface FetchAgentEngineConfiguredStateOptions {
18
+ missingFallback?: boolean;
19
+ timeoutMs?: number;
20
+ }
21
+
22
+ const DEFAULT_STATUS_CHECK_TIMEOUT_MS = 2500;
23
+
24
+ async function fetchStatusJson(
25
+ path: string,
26
+ timeoutMs: number,
27
+ ): Promise<unknown | null> {
28
+ const controller =
29
+ typeof AbortController !== "undefined" ? new AbortController() : null;
30
+ let timeoutId: ReturnType<typeof setTimeout> | undefined;
31
+ const timeout = new Promise<null>((resolve) => {
32
+ timeoutId = setTimeout(() => {
33
+ controller?.abort();
34
+ resolve(null);
35
+ }, timeoutMs);
36
+ });
37
+
38
+ const request = fetch(
39
+ agentNativePath(path),
40
+ controller ? { signal: controller.signal } : undefined,
41
+ )
42
+ .then((r) => (r.ok ? r.json() : null))
43
+ .catch(() => null)
44
+ .finally(() => {
45
+ if (timeoutId !== undefined) clearTimeout(timeoutId);
46
+ });
47
+
48
+ return Promise.race([request, timeout]);
49
+ }
50
+
51
+ function hasConfiguredFlag(value: unknown): value is { configured: boolean } {
52
+ return (
53
+ typeof value === "object" &&
54
+ value !== null &&
55
+ "configured" in value &&
56
+ typeof (value as { configured?: unknown }).configured === "boolean"
57
+ );
58
+ }
59
+
60
+ export async function fetchAgentEngineConfiguredState(
61
+ enabled = true,
62
+ options?: FetchAgentEngineConfiguredStateOptions,
63
+ ): Promise<AgentEngineConfiguredState> {
64
+ if (!enabled) return "configured";
65
+
66
+ const timeoutMs =
67
+ typeof options?.timeoutMs === "number" && options.timeoutMs > 0
68
+ ? options.timeoutMs
69
+ : DEFAULT_STATUS_CHECK_TIMEOUT_MS;
70
+ const [envKeys, builderStatus, engineStatus] = await Promise.all([
71
+ fetchStatusJson("/_agent-native/env-status", timeoutMs),
72
+ fetchStatusJson("/_agent-native/builder/status", timeoutMs),
73
+ fetchStatusJson("/_agent-native/agent-engine/status", timeoutMs),
74
+ ]);
75
+
76
+ // All three failed — likely a flaky network; keep the caller in unknown
77
+ // unless this check is reacting to an explicit missing-key stream event.
78
+ if (envKeys == null && builderStatus == null && engineStatus == null) {
79
+ return options?.missingFallback ? "missing" : "unknown";
80
+ }
81
+
82
+ const keys = (envKeys ?? []) as Array<{
83
+ key: string;
84
+ configured: boolean;
85
+ }>;
86
+ const llmKeys = keys.filter((k) => PROVIDER_ENV_VAR_SET.has(k.key));
87
+ const anyConfigured =
88
+ llmKeys.some((k) => k.configured) ||
89
+ (hasConfiguredFlag(builderStatus) && builderStatus.configured) ||
90
+ (hasConfiguredFlag(engineStatus) && engineStatus.configured);
91
+ return anyConfigured ? "configured" : "missing";
92
+ }
93
+
17
94
  /**
18
95
  * Shared "can the agent run?" gate — the single source of truth for the sidebar
19
96
  * composer and app prompt boxes. Checks the env-key / Builder / BYOK status
@@ -29,37 +106,12 @@ export function useAgentEngineConfigured(
29
106
  useEffect(() => {
30
107
  let cancelled = false;
31
108
  const check = async (options?: { missingFallback?: boolean }) => {
32
- if (!enabled) {
33
- setState("configured");
34
- return;
35
- }
36
- const [envKeys, builderStatus, engineStatus] = await Promise.all([
37
- fetch(agentNativePath("/_agent-native/env-status"))
38
- .then((r) => (r.ok ? r.json() : null))
39
- .catch(() => null),
40
- fetch(agentNativePath("/_agent-native/builder/status"))
41
- .then((r) => (r.ok ? r.json() : null))
42
- .catch(() => null),
43
- fetch(agentNativePath("/_agent-native/agent-engine/status"))
44
- .then((r) => (r.ok ? r.json() : null))
45
- .catch(() => null),
46
- ]);
109
+ const nextState = await fetchAgentEngineConfiguredState(enabled, options);
47
110
  if (cancelled) return;
48
- // All three failed — likely a flaky network; keep the current state.
49
- if (envKeys == null && builderStatus == null && engineStatus == null) {
50
- if (options?.missingFallback) setState("missing");
111
+ if (nextState === "unknown") {
51
112
  return;
52
113
  }
53
- const keys = (envKeys ?? []) as Array<{
54
- key: string;
55
- configured: boolean;
56
- }>;
57
- const llmKeys = keys.filter((k) => PROVIDER_ENV_VAR_SET.has(k.key));
58
- const anyConfigured =
59
- llmKeys.some((k) => k.configured) ||
60
- builderStatus?.configured === true ||
61
- engineStatus?.configured === true;
62
- setState(anyConfigured ? "configured" : "missing");
114
+ setState(nextState);
63
115
  };
64
116
  const onConfiguredChanged = () => {
65
117
  void check();
@@ -30,6 +30,13 @@ import { createBuilderEngine } from "../agent/engine/builder-engine.js";
30
30
  import { appStateGet } from "../application-state/store.js";
31
31
  import { getOrgContext } from "../org/context.js";
32
32
  import { transcribeWithBuilder } from "../transcription/builder-transcription.js";
33
+ import {
34
+ applyVoiceContextReplacements,
35
+ buildVoiceGuidanceBlock,
36
+ parseVoiceContextPack,
37
+ voiceContextTermsOnly,
38
+ type VoiceContextPack,
39
+ } from "../voice/index.js";
33
40
  import { getSession } from "./auth.js";
34
41
  import {
35
42
  resolveHasBuilderPrivateKey,
@@ -146,6 +153,20 @@ export function createTranscribeVoiceHandler() {
146
153
  Buffer.from(instructionsPart.data).toString("utf8"),
147
154
  )
148
155
  : undefined;
156
+ const voiceContextPart = parts?.find(
157
+ (p) => p.name === "voiceContext" || p.name === "contextPack",
158
+ );
159
+ const voiceContext = voiceContextPart?.data
160
+ ? parseVoiceContextPack(
161
+ Buffer.from(voiceContextPart.data).toString("utf8"),
162
+ )
163
+ : undefined;
164
+ const voiceGuidance = buildVoiceGuidanceBlock({
165
+ instructions,
166
+ contextPack: voiceContextTermsOnly(voiceContext),
167
+ });
168
+ const applyVoiceContext = (value: string) =>
169
+ applyVoiceContextReplacements(value, voiceContext).trim();
149
170
 
150
171
  // Resolve provider preference. Per-request "provider" form field takes
151
172
  // precedence (the desktop client sends it on every dictation press),
@@ -220,7 +241,7 @@ export function createTranscribeVoiceHandler() {
220
241
  // does not want audio uploaded to any external provider. The client
221
242
  // shouldn't hit this endpoint when "browser" is selected; this is a
222
243
  // defense-in-depth refusal.
223
- if (providerPref === "browser") {
244
+ if (providerPref === "browser" && !transcriptText) {
224
245
  setResponseStatus(event, 400);
225
246
  return {
226
247
  error:
@@ -238,7 +259,8 @@ export function createTranscribeVoiceHandler() {
238
259
  return await cleanupTranscriptText({
239
260
  event,
240
261
  text: transcriptText,
241
- instructions,
262
+ instructions: voiceGuidance,
263
+ contextPack: voiceContext,
242
264
  providerPref,
243
265
  hasBuilderPrivateKey,
244
266
  withRequestContext,
@@ -282,9 +304,9 @@ export function createTranscribeVoiceHandler() {
282
304
  mimeType: mime,
283
305
  apiKey: geminiKey,
284
306
  language: language || undefined,
285
- instructions,
307
+ instructions: voiceGuidance,
286
308
  });
287
- const trimmed = text.trim();
309
+ const trimmed = applyVoiceContext(text);
288
310
  if (!trimmed) {
289
311
  setResponseStatus(event, 502);
290
312
  return { error: "Gemini returned an empty transcript." };
@@ -318,9 +340,9 @@ export function createTranscribeVoiceHandler() {
318
340
  ? BUILDER_GEMINI_TRANSCRIPTION_MODEL
319
341
  : undefined,
320
342
  language: language || undefined,
321
- instructions,
343
+ instructions: voiceGuidance,
322
344
  });
323
- return { text: (result.text ?? "").trim() };
345
+ return { text: applyVoiceContext(result.text ?? "") };
324
346
  } catch (err) {
325
347
  const message = (err as Error)?.message ?? String(err);
326
348
  if (message.includes("credits exhausted")) {
@@ -352,7 +374,8 @@ export function createTranscribeVoiceHandler() {
352
374
  audioBytes,
353
375
  mime,
354
376
  language,
355
- instructions,
377
+ instructions: voiceGuidance,
378
+ contextPack: voiceContext,
356
379
  });
357
380
  }
358
381
 
@@ -368,9 +391,9 @@ export function createTranscribeVoiceHandler() {
368
391
  mimeType: mime,
369
392
  model: BUILDER_GEMINI_TRANSCRIPTION_MODEL,
370
393
  language: language || undefined,
371
- instructions,
394
+ instructions: voiceGuidance,
372
395
  });
373
- return { text: (result.text ?? "").trim() };
396
+ return { text: applyVoiceContext(result.text ?? "") };
374
397
  } catch (err) {
375
398
  const message = (err as Error)?.message ?? String(err);
376
399
  // Surface 402 (credits exhausted) as a 402 so the client can show
@@ -395,9 +418,9 @@ export function createTranscribeVoiceHandler() {
395
418
  mimeType: mime,
396
419
  apiKey: geminiKey,
397
420
  language: language || undefined,
398
- instructions,
421
+ instructions: voiceGuidance,
399
422
  });
400
- const trimmed = text.trim();
423
+ const trimmed = applyVoiceContext(text);
401
424
  if (trimmed) {
402
425
  console.log(`[transcribe-voice] Gemini → ${trimmed.length} chars`);
403
426
  return { text: trimmed };
@@ -465,7 +488,8 @@ export function createTranscribeVoiceHandler() {
465
488
  audioBytes,
466
489
  mime,
467
490
  language,
468
- instructions,
491
+ instructions: voiceGuidance,
492
+ contextPack: voiceContext,
469
493
  });
470
494
  });
471
495
  }
@@ -484,6 +508,7 @@ async function callWhisperCompat({
484
508
  mime,
485
509
  language,
486
510
  instructions,
511
+ contextPack,
487
512
  }: {
488
513
  event: H3Event;
489
514
  provider: {
@@ -496,6 +521,7 @@ async function callWhisperCompat({
496
521
  mime: string;
497
522
  language?: string;
498
523
  instructions?: string;
524
+ contextPack?: VoiceContextPack;
499
525
  }): Promise<{ text: string } | { error: string }> {
500
526
  const ext = pickExtension(mime);
501
527
  const filename = `composer-voice.${ext}`;
@@ -531,7 +557,12 @@ async function callWhisperCompat({
531
557
  };
532
558
  }
533
559
  const data = (await res.json()) as { text?: string };
534
- return { text: (data.text ?? "").trim() };
560
+ return {
561
+ text: applyVoiceContextReplacements(
562
+ (data.text ?? "").trim(),
563
+ contextPack,
564
+ ).trim(),
565
+ };
535
566
  } catch (err) {
536
567
  setResponseStatus(event, 502);
537
568
  return {
@@ -549,6 +580,7 @@ async function cleanupTranscriptText({
549
580
  event,
550
581
  text,
551
582
  instructions,
583
+ contextPack,
552
584
  providerPref,
553
585
  hasBuilderPrivateKey,
554
586
  withRequestContext,
@@ -557,6 +589,7 @@ async function cleanupTranscriptText({
557
589
  event: H3Event;
558
590
  text: string;
559
591
  instructions?: string;
592
+ contextPack?: VoiceContextPack;
560
593
  providerPref?: string;
561
594
  hasBuilderPrivateKey: () => Promise<boolean>;
562
595
  withRequestContext: <T>(fn: () => Promise<T>) => Promise<T>;
@@ -564,9 +597,11 @@ async function cleanupTranscriptText({
564
597
  }): Promise<{ text: string } | { error: string }> {
565
598
  const original = text.trim();
566
599
  if (!original) return { text: "" };
600
+ const finalizeText = (value: string) =>
601
+ applyVoiceContextReplacements(value || original, contextPack).trim();
567
602
 
568
603
  if (providerPref === "browser") {
569
- return { text: original };
604
+ return { text: finalizeText(original) };
570
605
  }
571
606
 
572
607
  if (providerPref === "builder" || providerPref === "builder-gemini") {
@@ -581,7 +616,7 @@ async function cleanupTranscriptText({
581
616
  const cleaned = await withRequestContext(() =>
582
617
  cleanupWithBuilder({ text: original, instructions }),
583
618
  );
584
- return { text: cleaned || original };
619
+ return { text: finalizeText(cleaned || original) };
585
620
  } catch (err) {
586
621
  setResponseStatus(event, 502);
587
622
  return {
@@ -605,7 +640,7 @@ async function cleanupTranscriptText({
605
640
  apiKey: geminiKey,
606
641
  instructions,
607
642
  });
608
- return { text: cleaned || original };
643
+ return { text: finalizeText(cleaned || original) };
609
644
  } catch (err) {
610
645
  setResponseStatus(event, 502);
611
646
  return {
@@ -631,7 +666,7 @@ async function cleanupTranscriptText({
631
666
  apiKey,
632
667
  instructions,
633
668
  });
634
- return { text: cleaned || original };
669
+ return { text: finalizeText(cleaned || original) };
635
670
  } catch (err) {
636
671
  setResponseStatus(event, 502);
637
672
  return {
@@ -645,7 +680,7 @@ async function cleanupTranscriptText({
645
680
  const cleaned = await withRequestContext(() =>
646
681
  cleanupWithBuilder({ text: original, instructions }),
647
682
  );
648
- if (cleaned) return { text: cleaned };
683
+ if (cleaned) return { text: finalizeText(cleaned) };
649
684
  } catch {
650
685
  // Fall through to BYOK providers, then raw text.
651
686
  }
@@ -659,7 +694,7 @@ async function cleanupTranscriptText({
659
694
  apiKey: geminiKey,
660
695
  instructions,
661
696
  });
662
- if (cleaned) return { text: cleaned };
697
+ if (cleaned) return { text: finalizeText(cleaned) };
663
698
  } catch {
664
699
  // Fall through.
665
700
  }
@@ -674,7 +709,7 @@ async function cleanupTranscriptText({
674
709
  apiKey: groqKey,
675
710
  instructions,
676
711
  });
677
- if (cleaned) return { text: cleaned };
712
+ if (cleaned) return { text: finalizeText(cleaned) };
678
713
  } catch {
679
714
  // Fall through.
680
715
  }
@@ -689,13 +724,13 @@ async function cleanupTranscriptText({
689
724
  apiKey: openaiKey,
690
725
  instructions,
691
726
  });
692
- if (cleaned) return { text: cleaned };
727
+ if (cleaned) return { text: finalizeText(cleaned) };
693
728
  } catch {
694
729
  // Fall through.
695
730
  }
696
731
  }
697
732
 
698
- return { text: original };
733
+ return { text: finalizeText(original) };
699
734
  }
700
735
 
701
736
  async function cleanupWithBuilder({
@@ -87,6 +87,27 @@ export function isAgentNativeFirstPartyAppOrigin(
87
87
  }
88
88
  }
89
89
 
90
+ export function isBuilderIoEmbedOrigin(
91
+ origin: string | null | undefined,
92
+ ): boolean {
93
+ if (!origin) return false;
94
+ try {
95
+ const url = new URL(origin);
96
+ const hostname = url.hostname.toLowerCase();
97
+ return (
98
+ url.protocol === "https:" &&
99
+ !url.username &&
100
+ !url.password &&
101
+ (hostname === "builder.io" ||
102
+ hostname.endsWith(".builder.io") ||
103
+ hostname === "builder.my" ||
104
+ hostname.endsWith(".builder.my"))
105
+ );
106
+ } catch {
107
+ return false;
108
+ }
109
+ }
110
+
90
111
  export function isMcpEmbedCorsOrigin(
91
112
  origin: string | null | undefined,
92
113
  ): boolean {
@@ -96,7 +117,8 @@ export function isMcpEmbedCorsOrigin(
96
117
  isClaudeMcpContentOrigin(origin) ||
97
118
  isChatGptMcpSandboxOrigin(origin) ||
98
119
  isMcpProductHostOrigin(origin) ||
99
- isAgentNativeFirstPartyAppOrigin(origin)
120
+ isAgentNativeFirstPartyAppOrigin(origin) ||
121
+ isBuilderIoEmbedOrigin(origin)
100
122
  );
101
123
  }
102
124
 
@@ -59,6 +59,8 @@
59
59
  --agent-native-card-surface: hsl(var(--card));
60
60
  --agent-native-raised-border: hsl(var(--border));
61
61
  --agent-native-raised-radius: 8px;
62
+ --agent-native-raised-outline: inset 0 0 0 1px
63
+ var(--agent-native-raised-border);
62
64
  --agent-native-raised-shadow-left: -1px 0 3px rgb(0 0 0 / 0.018);
63
65
  --agent-native-raised-shadow-right: 1px 0 3px rgb(0 0 0 / 0.018);
64
66
  background: var(--agent-native-lower-surface);
@@ -111,6 +113,21 @@
111
113
  background: var(--agent-native-lower-surface) !important;
112
114
  }
113
115
 
116
+ .agent-layout-left-drawer[data-collapsed] {
117
+ overflow: clip;
118
+ width: var(--agent-layout-left-drawer-width, auto);
119
+ will-change: width;
120
+ transition: width 260ms cubic-bezier(0.32, 0.72, 0, 1);
121
+ }
122
+
123
+ .agent-layout-left-drawer[data-collapsed="true"] {
124
+ width: var(--agent-layout-left-drawer-collapsed-width, 3.5rem);
125
+ }
126
+
127
+ .agent-layout-left-drawer[data-collapsed="false"] {
128
+ width: var(--agent-layout-left-drawer-expanded-width, 14rem);
129
+ }
130
+
114
131
  .agent-layout-left-drawer .bg-sidebar {
115
132
  background: var(--agent-native-lower-surface) !important;
116
133
  }
@@ -196,23 +213,23 @@
196
213
  .agent-layout-shell > .agent-sidebar-shell > .agent-sidebar-main-surface {
197
214
  border-start-start-radius: var(--agent-native-raised-radius);
198
215
  border-end-start-radius: var(--agent-native-raised-radius);
199
- border-inline-start: 1px solid var(--agent-native-raised-border);
200
- border-inline-end: 1px solid var(--agent-native-raised-border);
201
- box-shadow: var(--agent-native-raised-shadow-left);
216
+ box-shadow:
217
+ var(--agent-native-raised-outline), var(--agent-native-raised-shadow-left);
202
218
  }
203
219
 
204
220
  .agent-sidebar-main-surface[data-agent-sidebar-main-state="open"][data-agent-sidebar-main-position="right"] {
205
221
  border-start-end-radius: var(--agent-native-raised-radius);
206
222
  border-end-end-radius: var(--agent-native-raised-radius);
207
- border-inline-end: 1px solid var(--agent-native-raised-border);
208
- box-shadow: var(--agent-native-raised-shadow-right);
223
+ box-shadow:
224
+ var(--agent-native-raised-outline),
225
+ var(--agent-native-raised-shadow-right);
209
226
  }
210
227
 
211
228
  .agent-sidebar-main-surface[data-agent-sidebar-main-state="open"][data-agent-sidebar-main-position="left"] {
212
229
  border-start-start-radius: var(--agent-native-raised-radius);
213
230
  border-end-start-radius: var(--agent-native-raised-radius);
214
- border-inline-start: 1px solid var(--agent-native-raised-border);
215
- box-shadow: var(--agent-native-raised-shadow-left);
231
+ box-shadow:
232
+ var(--agent-native-raised-outline), var(--agent-native-raised-shadow-left);
216
233
  }
217
234
  }
218
235
 
@@ -291,6 +308,7 @@
291
308
  }
292
309
 
293
310
  @media (prefers-reduced-motion: reduce) {
311
+ .agent-layout-left-drawer[data-collapsed],
294
312
  .agent-sidebar-panel[data-agent-sidebar-animation],
295
313
  .agent-sidebar-panel[data-agent-sidebar-animation="desktop"]
296
314
  > .agent-sidebar-panel-inner,
@@ -560,6 +578,37 @@
560
578
  }
561
579
 
562
580
  @media (prefers-reduced-motion: no-preference) {
581
+ @supports ((background-clip: text) or (-webkit-background-clip: text)) {
582
+ .agent-thinking-indicator__text {
583
+ color: transparent;
584
+ background: linear-gradient(
585
+ 90deg,
586
+ hsl(var(--muted-foreground) / 0.7) 0%,
587
+ hsl(var(--muted-foreground) / 0.7) 36%,
588
+ hsl(var(--foreground) / 0.95) 50%,
589
+ hsl(var(--muted-foreground) / 0.78) 64%,
590
+ hsl(var(--muted-foreground) / 0.7) 100%
591
+ );
592
+ background-size: 14rem 100%;
593
+ background-position: 0 0;
594
+ background-repeat: repeat;
595
+ background-clip: text;
596
+ -webkit-background-clip: text;
597
+ -webkit-text-fill-color: transparent;
598
+ animation: agent-thinking-shine 2.6s linear infinite;
599
+ }
600
+ }
601
+
602
+ @keyframes agent-thinking-shine {
603
+ 0% {
604
+ background-position: 0 0;
605
+ }
606
+
607
+ 100% {
608
+ background-position: 14rem 0;
609
+ }
610
+ }
611
+
563
612
  @supports (view-transition-name: agent-native-chat) {
564
613
  .agent-native-chat-view-transition {
565
614
  contain: layout;