@agent-native/core 0.79.27 → 0.80.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (497) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +34 -0
  3. package/corpus/core/docs/content/locales/ar-SA/skills-guide.mdx +5 -0
  4. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +55 -1
  5. package/corpus/core/docs/content/locales/de-DE/skills-guide.mdx +5 -0
  6. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +66 -1
  7. package/corpus/core/docs/content/locales/es-ES/skills-guide.mdx +5 -0
  8. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +65 -1
  9. package/corpus/core/docs/content/locales/fr-FR/skills-guide.mdx +5 -0
  10. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +64 -1
  11. package/corpus/core/docs/content/locales/hi-IN/skills-guide.mdx +5 -0
  12. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +59 -1
  13. package/corpus/core/docs/content/locales/ja-JP/skills-guide.mdx +5 -0
  14. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +62 -1
  15. package/corpus/core/docs/content/locales/ko-KR/skills-guide.mdx +5 -0
  16. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +58 -1
  17. package/corpus/core/docs/content/locales/pt-BR/skills-guide.mdx +5 -0
  18. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +62 -1
  19. package/corpus/core/docs/content/locales/zh-CN/skills-guide.mdx +5 -0
  20. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +50 -1
  21. package/corpus/core/docs/content/locales/zh-TW/skills-guide.mdx +5 -0
  22. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +52 -1
  23. package/corpus/core/docs/content/skills-guide.mdx +5 -0
  24. package/corpus/core/docs/content/template-design.mdx +59 -1
  25. package/corpus/core/package.json +2 -1
  26. package/corpus/core/src/agent/engine/index.ts +1 -0
  27. package/corpus/core/src/agent/engine/registry.ts +40 -0
  28. package/corpus/core/src/agent/production-agent.ts +6 -2
  29. package/corpus/core/src/application-state/handlers.ts +1 -1
  30. package/corpus/core/src/brand-kit/index.ts +1 -1
  31. package/corpus/core/src/cli/design-connect.ts +490 -0
  32. package/corpus/core/src/cli/index.ts +16 -0
  33. package/corpus/core/src/cli/skills.ts +144 -3
  34. package/corpus/core/src/client/AgentPanel.tsx +1 -1
  35. package/corpus/core/src/client/AssistantChat.tsx +43 -7
  36. package/corpus/core/src/client/MultiTabAssistantChat.tsx +1 -1
  37. package/corpus/core/src/client/agent-chat.ts +27 -3
  38. package/corpus/core/src/client/blocks/library/MermaidBlock.tsx +1 -1
  39. package/corpus/core/src/client/blocks/library/diagram.tsx +2 -2
  40. package/corpus/core/src/client/blocks/library/wireframe.tsx +1 -1
  41. package/corpus/core/src/client/chat/message-components.tsx +1 -1
  42. package/corpus/core/src/client/chat-model-groups.ts +1 -2
  43. package/corpus/core/src/client/components/LiveCursorOverlay.tsx +33 -66
  44. package/corpus/core/src/client/composer/TiptapComposer.tsx +99 -24
  45. package/corpus/core/src/client/composer/useVoiceDictation.ts +429 -260
  46. package/corpus/core/src/client/extensions/portable-extension.ts +1 -1
  47. package/corpus/core/src/client/frame-protocol.ts +17 -2
  48. package/corpus/core/src/client/rich-markdown-editor/RegistryBlockNode.tsx +2 -2
  49. package/corpus/core/src/client/sharing/ShareButton.tsx +20 -15
  50. package/corpus/core/src/client/use-agent-engine-configured.ts +80 -28
  51. package/corpus/core/src/code-agents/transcript-normalizer.ts +1 -1
  52. package/corpus/core/src/extensions/path.ts +1 -4
  53. package/corpus/core/src/integrations/a2a-continuation-processor.ts +1 -1
  54. package/corpus/core/src/mcp/build-server.ts +1 -1
  55. package/corpus/core/src/org/handlers.ts +5 -5
  56. package/corpus/core/src/org/plugin.ts +2 -2
  57. package/corpus/core/src/scripts/call-agent.ts +1 -1
  58. package/corpus/core/src/scripts/db/safety.ts +1 -1
  59. package/corpus/core/src/server/auth.ts +3 -0
  60. package/corpus/core/src/server/builder-design-systems.ts +308 -0
  61. package/corpus/core/src/server/core-routes-plugin.ts +29 -3
  62. package/corpus/core/src/server/index.ts +8 -0
  63. package/corpus/core/src/server/transcribe-voice.ts +57 -22
  64. package/corpus/core/src/shared/mcp-embed-headers.ts +23 -1
  65. package/corpus/core/src/styles/agent-native.css +60 -4
  66. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  67. package/corpus/core/src/usage/store.ts +2 -2
  68. package/corpus/core/src/vite/client.ts +2 -0
  69. package/corpus/core/src/voice/index.ts +18 -0
  70. package/corpus/core/src/voice/voice-cleanup-prompt.ts +38 -0
  71. package/corpus/core/src/voice/voice-context.ts +217 -0
  72. package/corpus/core/src/voice/voice-replacements.ts +75 -0
  73. package/corpus/templates/analytics/AGENTS.md +4 -3
  74. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +298 -15
  75. package/corpus/templates/analytics/actions/get-sql-dashboard.ts +9 -4
  76. package/corpus/templates/analytics/actions/list-session-recordings.ts +6 -1
  77. package/corpus/templates/analytics/actions/mutate-dashboard.ts +18 -2
  78. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +12 -2
  79. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +557 -400
  80. package/corpus/templates/analytics/app/global.css +0 -4
  81. package/corpus/templates/analytics/app/hooks/use-replay-storage-status.ts +66 -0
  82. package/corpus/templates/analytics/app/i18n/zh-TW.ts +39 -0
  83. package/corpus/templates/analytics/app/i18n-data.ts +424 -0
  84. package/corpus/templates/analytics/app/pages/Settings.tsx +333 -0
  85. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +2 -1
  86. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/dashboard-layout.ts +121 -3
  87. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +82 -34
  88. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +7 -0
  89. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +144 -36
  90. package/corpus/templates/analytics/changelog/2026-06-28-ask-tab-now-matches-the-darker-app-background.md +6 -0
  91. package/corpus/templates/analytics/changelog/2026-06-28-dashboard-email-reports-now-use-cleaner-light-mode-snapshots.md +6 -0
  92. package/corpus/templates/analytics/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  93. package/corpus/templates/analytics/changelog/2026-06-28-sessions-now-show-only-signed-in-recordings-with-playable-re.md +6 -0
  94. package/corpus/templates/analytics/changelog/2026-06-29-analytics-agents-can-now-place-new-charts-into-requested-das.md +6 -0
  95. package/corpus/templates/analytics/changelog/2026-06-29-analytics-queries-now-report-failed-source-query-errors-inst.md +6 -0
  96. package/corpus/templates/analytics/changelog/2026-06-29-charts-can-now-be-dropped-between-full-dashboard-rows-to-cre.md +6 -0
  97. package/corpus/templates/analytics/changelog/2026-06-29-dashboard-email-reports-include-the-full-dashboard-image-wit.md +6 -0
  98. package/corpus/templates/analytics/changelog/2026-06-29-main-surface-border-reaches-the-top.md +6 -0
  99. package/corpus/templates/analytics/changelog/2026-06-29-session-replay-now-records-playable-sessions-in-production-a.md +6 -0
  100. package/corpus/templates/analytics/changelog/2026-06-29-set-up-session-replay-storage-from-settings-connect-builder-.md +6 -0
  101. package/corpus/templates/analytics/scripts/cleanup-empty-session-recordings.ts +102 -0
  102. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +3 -3
  103. package/corpus/templates/analytics/server/lib/dashboard-report.ts +75 -30
  104. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +5 -2
  105. package/corpus/templates/analytics/server/lib/real-data-actions.ts +81 -20
  106. package/corpus/templates/analytics/server/lib/replay-storage.ts +79 -0
  107. package/corpus/templates/analytics/server/lib/s3-upload-provider.ts +255 -0
  108. package/corpus/templates/analytics/server/lib/session-replay.ts +53 -12
  109. package/corpus/templates/analytics/server/plugins/agent-chat.ts +11 -2
  110. package/corpus/templates/analytics/server/plugins/onboarding.ts +97 -0
  111. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +4 -4
  112. package/corpus/templates/assets/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  113. package/corpus/templates/brain/app/components/layout/Layout.tsx +29 -2
  114. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +131 -42
  115. package/corpus/templates/brain/app/i18n/zh-TW.ts +2 -0
  116. package/corpus/templates/brain/app/i18n-data.ts +20 -0
  117. package/corpus/templates/brain/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  118. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +29 -1
  119. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +417 -299
  120. package/corpus/templates/calendar/app/i18n/zh-TW.ts +2 -0
  121. package/corpus/templates/calendar/app/i18n-data.ts +20 -0
  122. package/corpus/templates/calendar/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  123. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +6 -19
  124. package/corpus/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  125. package/corpus/templates/clips/AGENTS.md +4 -0
  126. package/corpus/templates/clips/actions/cleanup-transcript.ts +39 -9
  127. package/corpus/templates/clips/actions/finalize-meeting.ts +81 -12
  128. package/corpus/templates/clips/actions/lib/agents-md-context.ts +4 -1
  129. package/corpus/templates/clips/app/components/library/library-layout.tsx +3 -3
  130. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +1 -1
  131. package/corpus/templates/clips/app/components/player/share-dialog.tsx +2 -2
  132. package/corpus/templates/clips/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
  133. package/corpus/templates/clips/desktop/src/lib/personal-vocabulary.ts +13 -8
  134. package/corpus/templates/clips/desktop/src/lib/recorder.ts +24 -0
  135. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +105 -5
  136. package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +60 -1
  137. package/corpus/templates/content/actions/set-image-alt-text.ts +1 -1
  138. package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +1 -1
  139. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +1 -1
  140. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -5
  141. package/corpus/templates/content/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  142. package/corpus/templates/content/shared/document-export.ts +1 -1
  143. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +8 -18
  144. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +154 -0
  145. package/corpus/templates/design/AGENTS.md +95 -5
  146. package/corpus/templates/design/DESIGN.md +82 -0
  147. package/corpus/templates/design/DEVELOPING.md +43 -0
  148. package/corpus/templates/design/actions/add-localhost-screens.ts +453 -0
  149. package/corpus/templates/design/actions/apply-shader.ts +277 -0
  150. package/corpus/templates/design/actions/apply-visual-edit.ts +303 -0
  151. package/corpus/templates/design/actions/connect-localhost.ts +183 -0
  152. package/corpus/templates/design/actions/edit-design.ts +195 -42
  153. package/corpus/templates/design/actions/generate-design.ts +71 -1
  154. package/corpus/templates/design/actions/generate-screens.ts +193 -0
  155. package/corpus/templates/design/actions/get-code-layer-projection.ts +191 -0
  156. package/corpus/templates/design/actions/get-shader.ts +119 -0
  157. package/corpus/templates/design/actions/index-design-system-with-builder.ts +259 -0
  158. package/corpus/templates/design/actions/list-localhost-connections.ts +95 -0
  159. package/corpus/templates/design/actions/navigate.ts +55 -2
  160. package/corpus/templates/design/actions/update-file.ts +9 -2
  161. package/corpus/templates/design/actions/view-screen.ts +68 -1
  162. package/corpus/templates/design/agent-native.app-skill.json +10 -0
  163. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +719 -0
  164. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +2120 -103
  165. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +74 -38
  166. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +401 -0
  167. package/corpus/templates/design/app/components/design/EditPanel.tsx +3966 -440
  168. package/corpus/templates/design/app/components/design/LayersPanel.tsx +1473 -0
  169. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +3940 -147
  170. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +700 -13
  171. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +105 -63
  172. package/corpus/templates/design/app/components/design/index.ts +0 -5
  173. package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +353 -0
  174. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +1589 -0
  175. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +511 -0
  176. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +395 -0
  177. package/corpus/templates/design/app/components/design/inspector/FigmaColorPicker.tsx +2010 -0
  178. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +601 -0
  179. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +242 -0
  180. package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +420 -0
  181. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +238 -0
  182. package/corpus/templates/design/app/components/design/inspector/ShaderControls.stories.tsx +71 -0
  183. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +575 -0
  184. package/corpus/templates/design/app/components/design/inspector/ShaderEffectRow.tsx +106 -0
  185. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +423 -0
  186. package/corpus/templates/design/app/components/design/inspector/figma-icons.tsx +741 -0
  187. package/corpus/templates/design/app/components/design/inspector/index.ts +87 -0
  188. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +201 -0
  189. package/corpus/templates/design/app/components/design/types.ts +23 -0
  190. package/corpus/templates/design/app/components/layout/Layout.tsx +24 -13
  191. package/corpus/templates/design/app/components/layout/Sidebar.tsx +4 -4
  192. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +474 -36
  193. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +22 -5
  194. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +24 -11
  195. package/corpus/templates/design/app/global.css +149 -5
  196. package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -0
  197. package/corpus/templates/design/app/hooks/use-navigation-state.ts +130 -8
  198. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +329 -0
  199. package/corpus/templates/design/app/i18n/zh-TW.ts +277 -0
  200. package/corpus/templates/design/app/i18n-data.ts +3028 -1
  201. package/corpus/templates/design/app/pages/DesignEditor.tsx +5831 -904
  202. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +57 -221
  203. package/corpus/templates/design/changelog/2026-06-28-annotate-mode-now-combines-drawing-and-comment-pins-in-one-c.md +6 -0
  204. package/corpus/templates/design/changelog/2026-06-28-design-editor-panel-borders-are-cleaner-so-the-canvas-edge-s.md +6 -0
  205. package/corpus/templates/design/changelog/2026-06-28-drawing-prompts-now-reliably-open-and-submit-to-the-design-a.md +6 -0
  206. package/corpus/templates/design/changelog/2026-06-28-editor-app-menus-now-use-an-outline-agent-native-mark-with-b.md +6 -0
  207. package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +6 -0
  208. package/corpus/templates/design/changelog/2026-06-28-layer-selection-now-updates-chat-context-without-opening-the.md +6 -0
  209. package/corpus/templates/design/changelog/2026-06-28-layer-selections-now-preserve-hidden-and-locked-canvas-state.md +6 -0
  210. package/corpus/templates/design/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  211. package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +6 -0
  212. package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +6 -0
  213. package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-handles-zooming-drawing-opening-and-dele.md +6 -0
  214. package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-selects-screens-on-click-and-opens-them-.md +6 -0
  215. package/corpus/templates/design/changelog/2026-06-28-screen-overview-zooms-into-the-active-screen-with-smoother-e.md +6 -0
  216. package/corpus/templates/design/changelog/2026-06-28-selected-element-chips-in-chat-are-shorter-and-easier-to-sca.md +6 -0
  217. package/corpus/templates/design/changelog/2026-06-28-the-design-editor-toolbar-is-more-compact-and-the-app-menu-m.md +6 -0
  218. package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-at-the-top-of-the-design-sidebar-instead-of-.md +6 -0
  219. package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-in-the-right-inspector-beside-the-design-tab.md +6 -0
  220. package/corpus/templates/design/changelog/2026-06-29-active-sidebar-rows-use-soft-highlights.md +6 -0
  221. package/corpus/templates/design/changelog/2026-06-29-agents-can-now-open-screen-overview-focus-screens-and-add.md +6 -0
  222. package/corpus/templates/design/changelog/2026-06-29-canvas-selection-no-longer-flashes-broken-prototype-html-whe.md +6 -0
  223. package/corpus/templates/design/changelog/2026-06-29-command-menu-selections-are-clearer-in-dark-mode.md +6 -0
  224. package/corpus/templates/design/changelog/2026-06-29-design-agents-now-edit-broad-copy-changes-more-reliably.md +6 -0
  225. package/corpus/templates/design/changelog/2026-06-29-design-editor-extensions-now-run-inline-beside-the-artboard.md +6 -0
  226. package/corpus/templates/design/changelog/2026-06-29-design-mode-top-chrome-now-groups-collaborators-preview-shar.md +6 -0
  227. package/corpus/templates/design/changelog/2026-06-29-element-selection-now-stays-on-the-intended-layer-after-sele.md +6 -0
  228. package/corpus/templates/design/changelog/2026-06-29-screen-overview-full-view-controls-now-sit-above-frames-inst.md +6 -0
  229. package/corpus/templates/design/changelog/2026-06-29-screen-overview-tools-can-draw-shapes-create-screens-and-kee.md +6 -0
  230. package/corpus/templates/design/changelog/2026-06-29-sidebars-use-darker-chrome-and-chat-warns-immediately.md +6 -0
  231. package/corpus/templates/design/changelog/2026-06-29-the-pen-tool-now-creates-anchor-based-bezier-vectors-with-ha.md +6 -0
  232. package/corpus/templates/design/changelog/2026-06-29-visual-edit-can-open-localhost-routes-as-url-backed-screens.md +6 -0
  233. package/corpus/templates/design/package.json +1 -0
  234. package/corpus/templates/design/server/db/schema.ts +26 -0
  235. package/corpus/templates/design/server/handlers/import-figma-system.ts +38 -85
  236. package/corpus/templates/design/server/lib/design-snapshot.ts +9 -1
  237. package/corpus/templates/design/server/plugins/agent-chat.ts +3 -0
  238. package/corpus/templates/design/shared/api.ts +27 -0
  239. package/corpus/templates/design/shared/canvas-frames.ts +103 -0
  240. package/corpus/templates/design/shared/canvas-math.ts +1058 -0
  241. package/corpus/templates/design/shared/code-layer.ts +2412 -0
  242. package/corpus/templates/design/shared/color-utils.ts +180 -0
  243. package/corpus/templates/design/shared/generation-session.ts +61 -0
  244. package/corpus/templates/design/shared/html-content.ts +21 -0
  245. package/corpus/templates/design/shared/pen-path.ts +207 -0
  246. package/corpus/templates/design/shared/shader-presets.ts +782 -0
  247. package/corpus/templates/design/shared/shader-safety.ts +137 -0
  248. package/corpus/templates/design/shared/source-mode.ts +237 -0
  249. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +149 -6
  250. package/corpus/templates/forms/app/i18n/ar-SA.ts +2 -0
  251. package/corpus/templates/forms/app/i18n/de-DE.ts +2 -0
  252. package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
  253. package/corpus/templates/forms/app/i18n/es-ES.ts +2 -0
  254. package/corpus/templates/forms/app/i18n/fr-FR.ts +2 -0
  255. package/corpus/templates/forms/app/i18n/hi-IN.ts +2 -0
  256. package/corpus/templates/forms/app/i18n/ja-JP.ts +2 -0
  257. package/corpus/templates/forms/app/i18n/ko-KR.ts +2 -0
  258. package/corpus/templates/forms/app/i18n/pt-BR.ts +2 -0
  259. package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
  260. package/corpus/templates/forms/app/i18n/zh-TW.ts +2 -0
  261. package/corpus/templates/forms/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  262. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +2 -2
  263. package/corpus/templates/macros/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
  264. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +408 -247
  265. package/corpus/templates/mail/app/i18n/ar-SA.ts +4 -0
  266. package/corpus/templates/mail/app/i18n/de-DE.ts +4 -0
  267. package/corpus/templates/mail/app/i18n/en-US.ts +4 -0
  268. package/corpus/templates/mail/app/i18n/es-ES.ts +4 -0
  269. package/corpus/templates/mail/app/i18n/fr-FR.ts +4 -0
  270. package/corpus/templates/mail/app/i18n/hi-IN.ts +4 -0
  271. package/corpus/templates/mail/app/i18n/ja-JP.ts +4 -0
  272. package/corpus/templates/mail/app/i18n/ko-KR.ts +4 -0
  273. package/corpus/templates/mail/app/i18n/pt-BR.ts +4 -0
  274. package/corpus/templates/mail/app/i18n/zh-CN.ts +4 -0
  275. package/corpus/templates/mail/app/i18n/zh-TW.ts +4 -0
  276. package/corpus/templates/mail/app/lib/utils.ts +2 -2
  277. package/corpus/templates/mail/changelog/2026-06-28-pinned-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  278. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +6 -8
  279. package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +1 -1
  280. package/corpus/templates/plan/app/global.css +61 -78
  281. package/corpus/templates/plan/app/pages/PlansPage.tsx +8 -0
  282. package/corpus/templates/plan/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  283. package/corpus/templates/plan/changelog/2026-06-28-plans-use-the-shared-neutral-light-and-dark-theme.md +6 -0
  284. package/corpus/templates/plan/changelog/2026-06-28-sending-open-feedback-from-a-plan-now-opens-the-inline-plan-.md +6 -0
  285. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +9 -10
  286. package/corpus/templates/slides/AGENTS.md +3 -2
  287. package/corpus/templates/slides/actions/import-file.ts +26 -17
  288. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +259 -0
  289. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +35 -167
  290. package/corpus/templates/slides/app/components/design-system/fig-import-response.ts +9 -13
  291. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +5 -5
  292. package/corpus/templates/slides/app/context/DeckContext.tsx +1 -1
  293. package/corpus/templates/slides/app/i18n/ar-SA.ts +9 -37
  294. package/corpus/templates/slides/app/i18n/de-DE.ts +10 -25
  295. package/corpus/templates/slides/app/i18n/en-US.ts +9 -26
  296. package/corpus/templates/slides/app/i18n/es-ES.ts +10 -28
  297. package/corpus/templates/slides/app/i18n/fr-FR.ts +10 -28
  298. package/corpus/templates/slides/app/i18n/hi-IN.ts +9 -26
  299. package/corpus/templates/slides/app/i18n/ja-JP.ts +10 -22
  300. package/corpus/templates/slides/app/i18n/ko-KR.ts +9 -23
  301. package/corpus/templates/slides/app/i18n/pt-BR.ts +10 -28
  302. package/corpus/templates/slides/app/i18n/zh-CN.ts +9 -22
  303. package/corpus/templates/slides/app/i18n/zh-TW.ts +9 -22
  304. package/corpus/templates/slides/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  305. package/corpus/templates/slides/server/handlers/import-figma-system.ts +44 -12
  306. package/corpus/templates/slides/server/lib/chat-attachments.ts +1 -1
  307. package/corpus/templates/videos/app/components/NewCompositionPopover.tsx +1 -1
  308. package/corpus/templates/videos/app/components/Sidebar.tsx +2 -2
  309. package/corpus/templates/videos/app/components/layout/Layout.tsx +29 -2
  310. package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +113 -30
  311. package/corpus/templates/videos/app/i18n/ar-SA.ts +2 -0
  312. package/corpus/templates/videos/app/i18n/de-DE.ts +2 -0
  313. package/corpus/templates/videos/app/i18n/en-US.ts +2 -0
  314. package/corpus/templates/videos/app/i18n/es-ES.ts +2 -0
  315. package/corpus/templates/videos/app/i18n/fr-FR.ts +2 -0
  316. package/corpus/templates/videos/app/i18n/hi-IN.ts +2 -0
  317. package/corpus/templates/videos/app/i18n/ja-JP.ts +2 -0
  318. package/corpus/templates/videos/app/i18n/ko-KR.ts +2 -0
  319. package/corpus/templates/videos/app/i18n/pt-BR.ts +2 -0
  320. package/corpus/templates/videos/app/i18n/zh-CN.ts +2 -0
  321. package/corpus/templates/videos/app/i18n/zh-TW.ts +2 -0
  322. package/corpus/templates/videos/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  323. package/dist/agent/engine/index.d.ts +1 -1
  324. package/dist/agent/engine/index.d.ts.map +1 -1
  325. package/dist/agent/engine/index.js +1 -1
  326. package/dist/agent/engine/index.js.map +1 -1
  327. package/dist/agent/engine/registry.d.ts +9 -0
  328. package/dist/agent/engine/registry.d.ts.map +1 -1
  329. package/dist/agent/engine/registry.js +37 -0
  330. package/dist/agent/engine/registry.js.map +1 -1
  331. package/dist/agent/production-agent.d.ts.map +1 -1
  332. package/dist/agent/production-agent.js +4 -3
  333. package/dist/agent/production-agent.js.map +1 -1
  334. package/dist/application-state/handlers.js +1 -1
  335. package/dist/application-state/handlers.js.map +1 -1
  336. package/dist/brand-kit/index.d.ts +1 -1
  337. package/dist/brand-kit/index.js +1 -1
  338. package/dist/brand-kit/index.js.map +1 -1
  339. package/dist/cli/design-connect.d.ts +52 -0
  340. package/dist/cli/design-connect.d.ts.map +1 -0
  341. package/dist/cli/design-connect.js +409 -0
  342. package/dist/cli/design-connect.js.map +1 -0
  343. package/dist/cli/index.js +15 -0
  344. package/dist/cli/index.js.map +1 -1
  345. package/dist/cli/skills.d.ts +3 -0
  346. package/dist/cli/skills.d.ts.map +1 -1
  347. package/dist/cli/skills.js +139 -3
  348. package/dist/cli/skills.js.map +1 -1
  349. package/dist/client/AgentPanel.js +1 -1
  350. package/dist/client/AgentPanel.js.map +1 -1
  351. package/dist/client/AssistantChat.d.ts.map +1 -1
  352. package/dist/client/AssistantChat.js +38 -8
  353. package/dist/client/AssistantChat.js.map +1 -1
  354. package/dist/client/MultiTabAssistantChat.js +1 -1
  355. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  356. package/dist/client/agent-chat.d.ts +6 -0
  357. package/dist/client/agent-chat.d.ts.map +1 -1
  358. package/dist/client/agent-chat.js +17 -3
  359. package/dist/client/agent-chat.js.map +1 -1
  360. package/dist/client/blocks/library/MermaidBlock.js +1 -1
  361. package/dist/client/blocks/library/MermaidBlock.js.map +1 -1
  362. package/dist/client/blocks/library/diagram.js +1 -1
  363. package/dist/client/blocks/library/diagram.js.map +1 -1
  364. package/dist/client/blocks/library/wireframe.js +1 -1
  365. package/dist/client/blocks/library/wireframe.js.map +1 -1
  366. package/dist/client/chat/message-components.js +1 -1
  367. package/dist/client/chat/message-components.js.map +1 -1
  368. package/dist/client/chat-model-groups.d.ts.map +1 -1
  369. package/dist/client/chat-model-groups.js +1 -2
  370. package/dist/client/chat-model-groups.js.map +1 -1
  371. package/dist/client/components/LiveCursorOverlay.d.ts +1 -2
  372. package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -1
  373. package/dist/client/components/LiveCursorOverlay.js +19 -40
  374. package/dist/client/components/LiveCursorOverlay.js.map +1 -1
  375. package/dist/client/composer/TiptapComposer.d.ts +3 -1
  376. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  377. package/dist/client/composer/TiptapComposer.js +86 -24
  378. package/dist/client/composer/TiptapComposer.js.map +1 -1
  379. package/dist/client/composer/useVoiceDictation.d.ts +9 -0
  380. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  381. package/dist/client/composer/useVoiceDictation.js +154 -32
  382. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  383. package/dist/client/extensions/portable-extension.d.ts +1 -1
  384. package/dist/client/extensions/portable-extension.d.ts.map +1 -1
  385. package/dist/client/extensions/portable-extension.js.map +1 -1
  386. package/dist/client/frame-protocol.d.ts +17 -2
  387. package/dist/client/frame-protocol.d.ts.map +1 -1
  388. package/dist/client/frame-protocol.js.map +1 -1
  389. package/dist/client/rich-markdown-editor/RegistryBlockNode.js +2 -2
  390. package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -1
  391. package/dist/client/sharing/ShareButton.d.ts +2 -0
  392. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  393. package/dist/client/sharing/ShareButton.js +7 -6
  394. package/dist/client/sharing/ShareButton.js.map +1 -1
  395. package/dist/client/use-agent-engine-configured.d.ts +5 -0
  396. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  397. package/dist/client/use-agent-engine-configured.js +51 -25
  398. package/dist/client/use-agent-engine-configured.js.map +1 -1
  399. package/dist/code-agents/transcript-normalizer.js +1 -1
  400. package/dist/code-agents/transcript-normalizer.js.map +1 -1
  401. package/dist/collab/routes.d.ts +1 -1
  402. package/dist/extensions/path.d.ts +1 -1
  403. package/dist/extensions/path.d.ts.map +1 -1
  404. package/dist/extensions/path.js.map +1 -1
  405. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  406. package/dist/integrations/a2a-continuation-processor.js +1 -1
  407. package/dist/integrations/a2a-continuation-processor.js.map +1 -1
  408. package/dist/mcp/build-server.d.ts +1 -1
  409. package/dist/mcp/build-server.d.ts.map +1 -1
  410. package/dist/mcp/build-server.js.map +1 -1
  411. package/dist/notifications/routes.d.ts +3 -3
  412. package/dist/observability/routes.d.ts +5 -5
  413. package/dist/org/handlers.js +5 -5
  414. package/dist/org/handlers.js.map +1 -1
  415. package/dist/org/plugin.js +2 -2
  416. package/dist/org/plugin.js.map +1 -1
  417. package/dist/scripts/call-agent.js +1 -1
  418. package/dist/scripts/call-agent.js.map +1 -1
  419. package/dist/scripts/db/safety.js +1 -1
  420. package/dist/scripts/db/safety.js.map +1 -1
  421. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  422. package/dist/server/auth.d.ts.map +1 -1
  423. package/dist/server/auth.js +3 -0
  424. package/dist/server/auth.js.map +1 -1
  425. package/dist/server/builder-design-systems.d.ts +28 -0
  426. package/dist/server/builder-design-systems.d.ts.map +1 -0
  427. package/dist/server/builder-design-systems.js +217 -0
  428. package/dist/server/builder-design-systems.js.map +1 -0
  429. package/dist/server/core-routes-plugin.d.ts +1 -0
  430. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  431. package/dist/server/core-routes-plugin.js +20 -3
  432. package/dist/server/core-routes-plugin.js.map +1 -1
  433. package/dist/server/index.d.ts +1 -0
  434. package/dist/server/index.d.ts.map +1 -1
  435. package/dist/server/index.js +1 -0
  436. package/dist/server/index.js.map +1 -1
  437. package/dist/server/transcribe-voice.d.ts +1 -1
  438. package/dist/server/transcribe-voice.d.ts.map +1 -1
  439. package/dist/server/transcribe-voice.js +40 -24
  440. package/dist/server/transcribe-voice.js.map +1 -1
  441. package/dist/shared/mcp-embed-headers.d.ts +1 -0
  442. package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
  443. package/dist/shared/mcp-embed-headers.js +20 -1
  444. package/dist/shared/mcp-embed-headers.js.map +1 -1
  445. package/dist/styles/agent-native.css +60 -4
  446. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  447. package/dist/usage/store.js +2 -2
  448. package/dist/usage/store.js.map +1 -1
  449. package/dist/vite/client.d.ts.map +1 -1
  450. package/dist/vite/client.js +2 -0
  451. package/dist/vite/client.js.map +1 -1
  452. package/dist/voice/index.d.ts +5 -0
  453. package/dist/voice/index.d.ts.map +1 -0
  454. package/dist/voice/index.js +4 -0
  455. package/dist/voice/index.js.map +1 -0
  456. package/dist/voice/voice-cleanup-prompt.d.ts +6 -0
  457. package/dist/voice/voice-cleanup-prompt.d.ts.map +1 -0
  458. package/dist/voice/voice-cleanup-prompt.js +26 -0
  459. package/dist/voice/voice-cleanup-prompt.js.map +1 -0
  460. package/dist/voice/voice-context.d.ts +25 -0
  461. package/dist/voice/voice-context.d.ts.map +1 -0
  462. package/dist/voice/voice-context.js +156 -0
  463. package/dist/voice/voice-context.js.map +1 -0
  464. package/dist/voice/voice-replacements.d.ts +4 -0
  465. package/dist/voice/voice-replacements.d.ts.map +1 -0
  466. package/dist/voice/voice-replacements.js +52 -0
  467. package/dist/voice/voice-replacements.js.map +1 -0
  468. package/docs/content/locales/ar-SA/skills-guide.mdx +5 -0
  469. package/docs/content/locales/ar-SA/template-design.mdx +55 -1
  470. package/docs/content/locales/de-DE/skills-guide.mdx +5 -0
  471. package/docs/content/locales/de-DE/template-design.mdx +66 -1
  472. package/docs/content/locales/es-ES/skills-guide.mdx +5 -0
  473. package/docs/content/locales/es-ES/template-design.mdx +65 -1
  474. package/docs/content/locales/fr-FR/skills-guide.mdx +5 -0
  475. package/docs/content/locales/fr-FR/template-design.mdx +64 -1
  476. package/docs/content/locales/hi-IN/skills-guide.mdx +5 -0
  477. package/docs/content/locales/hi-IN/template-design.mdx +59 -1
  478. package/docs/content/locales/ja-JP/skills-guide.mdx +5 -0
  479. package/docs/content/locales/ja-JP/template-design.mdx +62 -1
  480. package/docs/content/locales/ko-KR/skills-guide.mdx +5 -0
  481. package/docs/content/locales/ko-KR/template-design.mdx +58 -1
  482. package/docs/content/locales/pt-BR/skills-guide.mdx +5 -0
  483. package/docs/content/locales/pt-BR/template-design.mdx +62 -1
  484. package/docs/content/locales/zh-CN/skills-guide.mdx +5 -0
  485. package/docs/content/locales/zh-CN/template-design.mdx +50 -1
  486. package/docs/content/locales/zh-TW/skills-guide.mdx +5 -0
  487. package/docs/content/locales/zh-TW/template-design.mdx +52 -1
  488. package/docs/content/skills-guide.mdx +5 -0
  489. package/docs/content/template-design.mdx +59 -1
  490. package/package.json +2 -1
  491. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  492. package/corpus/templates/design/actions/import-figma-file.ts +0 -166
  493. package/corpus/templates/design/app/components/design/DesignToolbar.tsx +0 -339
  494. package/corpus/templates/design/app/components/design/PresentMode.tsx +0 -68
  495. package/corpus/templates/design/app/components/design/ViewportTabs.tsx +0 -149
  496. package/corpus/templates/design/app/components/design/ZoomControls.tsx +0 -157
  497. package/corpus/templates/slides/server/lib/fig-design-system.ts +0 -110
@@ -0,0 +1,308 @@
1
+ import { FeatureNotConfiguredError } from "./credential-provider.js";
2
+ import {
3
+ getBuilderProxyOrigin,
4
+ resolveBuilderCredentials,
5
+ } from "./credential-provider.js";
6
+
7
+ const DEFAULT_TIMEOUT_MS = 120_000;
8
+
9
+ export interface BuilderDesignSystemIndexFile {
10
+ name: string;
11
+ data: Uint8Array;
12
+ mimeType?: string;
13
+ }
14
+
15
+ export interface BuilderDesignSystemIndexOptions {
16
+ projectName?: string;
17
+ description?: string;
18
+ githubRepoUrl?: string;
19
+ connectedProjectId?: string;
20
+ files?: BuilderDesignSystemIndexFile[];
21
+ selection?: Record<string, string[]>;
22
+ devToolsVersion?: string;
23
+ }
24
+
25
+ export interface BuilderDesignSystemIndexResult {
26
+ ok: true;
27
+ source: "builder";
28
+ projectId: string;
29
+ jobId: string;
30
+ designSystemId: string;
31
+ suggestedTitle: string | null;
32
+ builderUrl: string;
33
+ status: "in-progress";
34
+ }
35
+
36
+ interface BuilderDesignSystemCredentials {
37
+ privateKey: string;
38
+ publicKey: string;
39
+ userId: string | null;
40
+ }
41
+
42
+ interface UploadStartResponse {
43
+ uploads?: Array<{ idx: number; uploadUrl: string; uploadToken: string }>;
44
+ }
45
+
46
+ interface GenerateResponse {
47
+ projectId?: string;
48
+ jobId?: string;
49
+ designSystemId?: string;
50
+ }
51
+
52
+ function trimTrailingSlash(value: string): string {
53
+ return value.replace(/\/+$/, "");
54
+ }
55
+
56
+ export function getBuilderDesignSystemsBaseUrl(): string {
57
+ return (
58
+ process.env.BUILDER_DESIGN_SYSTEMS_BASE_URL ||
59
+ `${trimTrailingSlash(getBuilderProxyOrigin())}/design-systems/v1`
60
+ );
61
+ }
62
+
63
+ function getBuilderAppHost(): string {
64
+ return (
65
+ process.env.BUILDER_APP_HOST ||
66
+ process.env.BUILDER_PUBLIC_APP_HOST ||
67
+ "https://builder.io"
68
+ );
69
+ }
70
+
71
+ function makeBuilderDesignSystemUrl(
72
+ path: string,
73
+ credentials: BuilderDesignSystemCredentials,
74
+ ): URL {
75
+ const base = `${trimTrailingSlash(getBuilderDesignSystemsBaseUrl())}/`;
76
+ const url = new URL(path.replace(/^\/+/, ""), base);
77
+ url.searchParams.set("apiKey", credentials.publicKey);
78
+ if (credentials.userId) url.searchParams.set("userId", credentials.userId);
79
+ return url;
80
+ }
81
+
82
+ function makeBuilderHeaders(
83
+ credentials: BuilderDesignSystemCredentials,
84
+ ): Record<string, string> {
85
+ return {
86
+ Authorization: `Bearer ${credentials.privateKey}`,
87
+ "x-builder-api-key": credentials.publicKey,
88
+ ...(credentials.userId ? { "x-builder-user-id": credentials.userId } : {}),
89
+ };
90
+ }
91
+
92
+ async function resolveBuilderDesignSystemCredentials(): Promise<BuilderDesignSystemCredentials> {
93
+ const credentials = await resolveBuilderCredentials();
94
+ if (!credentials.privateKey || !credentials.publicKey) {
95
+ throw new FeatureNotConfiguredError({
96
+ requiredCredential: "BUILDER_PRIVATE_KEY",
97
+ message:
98
+ "Connect Builder.io before indexing a design system from Figma or code.",
99
+ builderConnectUrl: "/_agent-native/builder/connect",
100
+ });
101
+ }
102
+ return {
103
+ privateKey: credentials.privateKey,
104
+ publicKey: credentials.publicKey,
105
+ userId: credentials.userId ?? null,
106
+ };
107
+ }
108
+
109
+ function mimeTypeForFile(file: BuilderDesignSystemIndexFile): string {
110
+ if (file.mimeType?.trim()) return file.mimeType.trim();
111
+ const lower = file.name.toLowerCase();
112
+ if (lower.endsWith(".fig")) return "application/octet-stream";
113
+ if (lower.endsWith(".pdf")) return "application/pdf";
114
+ if (lower.endsWith(".md") || lower.endsWith(".markdown"))
115
+ return "text/markdown";
116
+ if (lower.endsWith(".json")) return "application/json";
117
+ if (lower.endsWith(".css")) return "text/css";
118
+ return "text/plain";
119
+ }
120
+
121
+ function makeBody(bytes: Uint8Array, mimeType: string): BodyInit {
122
+ return typeof Blob !== "undefined"
123
+ ? new Blob([bytes as unknown as BlobPart], { type: mimeType })
124
+ : (bytes as unknown as BodyInit);
125
+ }
126
+
127
+ async function fetchWithTimeout(
128
+ url: string | URL,
129
+ init: RequestInit,
130
+ timeoutMs = DEFAULT_TIMEOUT_MS,
131
+ ): Promise<Response> {
132
+ const controller = new AbortController();
133
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
134
+ try {
135
+ return await fetch(url, { ...init, signal: controller.signal });
136
+ } finally {
137
+ clearTimeout(timer);
138
+ }
139
+ }
140
+
141
+ async function parseErrorBody(response: Response): Promise<string> {
142
+ const text = await response.text().catch(() => "");
143
+ if (!text) return response.statusText || `HTTP ${response.status}`;
144
+ try {
145
+ const json = JSON.parse(text) as { error?: unknown };
146
+ if (typeof json.error === "string") return json.error;
147
+ if (json.error && typeof json.error === "object") {
148
+ return JSON.stringify(json.error).slice(0, 500);
149
+ }
150
+ } catch {}
151
+ return text.replace(/\s+/g, " ").trim().slice(0, 500);
152
+ }
153
+
154
+ async function assertOk(response: Response, label: string): Promise<void> {
155
+ if (response.ok) return;
156
+ throw new Error(
157
+ `${label} (${response.status}): ${await parseErrorBody(response)}`,
158
+ );
159
+ }
160
+
161
+ async function uploadToResumableUrl(
162
+ slot: { uploadUrl: string },
163
+ file: BuilderDesignSystemIndexFile,
164
+ ): Promise<void> {
165
+ const mimeType = mimeTypeForFile(file);
166
+ const bytes = file.data;
167
+ const start = await fetchWithTimeout(slot.uploadUrl, {
168
+ method: "POST",
169
+ headers: {
170
+ "x-goog-resumable": "start",
171
+ "x-goog-content-length-range": `0,${bytes.byteLength}`,
172
+ "Content-Type": mimeType,
173
+ },
174
+ });
175
+ await assertOk(start, "Builder design-system upload session failed");
176
+ const sessionUrl = start.headers.get("Location");
177
+ if (!sessionUrl) {
178
+ throw new Error("Builder design-system upload session returned no URL.");
179
+ }
180
+
181
+ const response = await fetchWithTimeout(sessionUrl, {
182
+ method: "PUT",
183
+ headers: {
184
+ "Content-Range": `bytes 0-${bytes.byteLength - 1}/${bytes.byteLength}`,
185
+ "Content-Type": mimeType,
186
+ },
187
+ body: makeBody(bytes, mimeType),
188
+ });
189
+ await assertOk(response, "Builder design-system file upload failed");
190
+ }
191
+
192
+ function nonEmptyFiles(
193
+ files: BuilderDesignSystemIndexFile[] | undefined,
194
+ ): BuilderDesignSystemIndexFile[] {
195
+ return (files ?? []).filter((file) => file.data.byteLength > 0);
196
+ }
197
+
198
+ export function builderDesignSystemUrl(designSystemId?: string | null): string {
199
+ const host = trimTrailingSlash(getBuilderAppHost());
200
+ return designSystemId
201
+ ? `${host}/app/design-system-intelligence/${encodeURIComponent(
202
+ designSystemId,
203
+ )}`
204
+ : `${host}/app/design-system-intelligence`;
205
+ }
206
+
207
+ export async function startBuilderDesignSystemIndex(
208
+ options: BuilderDesignSystemIndexOptions,
209
+ ): Promise<BuilderDesignSystemIndexResult> {
210
+ const files = nonEmptyFiles(options.files);
211
+ const description = options.description?.trim();
212
+ if (description) {
213
+ files.unshift({
214
+ name: "additional-context.txt",
215
+ data: new TextEncoder().encode(description),
216
+ mimeType: "text/plain",
217
+ });
218
+ }
219
+ if (
220
+ files.length === 0 &&
221
+ !options.githubRepoUrl &&
222
+ !options.connectedProjectId
223
+ ) {
224
+ throw new Error(
225
+ "Provide at least one .fig/code/text file or a GitHub repository URL to index with Builder.",
226
+ );
227
+ }
228
+
229
+ const credentials = await resolveBuilderDesignSystemCredentials();
230
+ let uploadTokens: string[] = [];
231
+ if (files.length > 0) {
232
+ const uploadStart = await fetchWithTimeout(
233
+ makeBuilderDesignSystemUrl("upload/start", credentials),
234
+ {
235
+ method: "POST",
236
+ headers: {
237
+ ...makeBuilderHeaders(credentials),
238
+ "Content-Type": "application/json",
239
+ },
240
+ body: JSON.stringify({
241
+ attachments: files.map((file) => ({
242
+ name: file.name,
243
+ mimetype: mimeTypeForFile(file),
244
+ declaredSize: file.data.byteLength,
245
+ })),
246
+ }),
247
+ },
248
+ );
249
+ await assertOk(uploadStart, "Builder design-system upload start failed");
250
+ const uploadJson = (await uploadStart.json()) as UploadStartResponse;
251
+ const slots = [...(uploadJson.uploads ?? [])].sort((a, b) => a.idx - b.idx);
252
+ if (slots.length !== files.length) {
253
+ throw new Error("Builder did not return upload slots for all files.");
254
+ }
255
+ for (let i = 0; i < slots.length; i++) {
256
+ if (slots[i].idx !== i) {
257
+ throw new Error(`Builder upload slot mismatch: expected ${i}.`);
258
+ }
259
+ await uploadToResumableUrl(slots[i], files[i]);
260
+ }
261
+ uploadTokens = slots.map((slot) => slot.uploadToken);
262
+ }
263
+
264
+ const generate = await fetchWithTimeout(
265
+ makeBuilderDesignSystemUrl("generate", credentials),
266
+ {
267
+ method: "POST",
268
+ headers: {
269
+ ...makeBuilderHeaders(credentials),
270
+ "Content-Type": "application/json",
271
+ },
272
+ body: JSON.stringify({
273
+ uploads: uploadTokens,
274
+ ...(options.projectName?.trim()
275
+ ? { projectName: options.projectName.trim() }
276
+ : {}),
277
+ ...(options.githubRepoUrl?.trim()
278
+ ? { githubRepoUrl: options.githubRepoUrl.trim() }
279
+ : {}),
280
+ ...(options.connectedProjectId?.trim()
281
+ ? { connectedProjectId: options.connectedProjectId.trim() }
282
+ : {}),
283
+ ...(options.selection ? { selection: options.selection } : {}),
284
+ ...(options.devToolsVersion?.trim()
285
+ ? { devToolsVersion: options.devToolsVersion.trim() }
286
+ : {}),
287
+ }),
288
+ },
289
+ );
290
+ await assertOk(generate, "Builder design-system indexing failed");
291
+ const generated = (await generate.json()) as GenerateResponse;
292
+ if (!generated.projectId || !generated.jobId || !generated.designSystemId) {
293
+ throw new Error(
294
+ "Builder design-system indexing returned an incomplete response.",
295
+ );
296
+ }
297
+
298
+ return {
299
+ ok: true,
300
+ source: "builder",
301
+ projectId: generated.projectId,
302
+ jobId: generated.jobId,
303
+ designSystemId: generated.designSystemId,
304
+ suggestedTitle: options.projectName?.trim() || null,
305
+ builderUrl: builderDesignSystemUrl(generated.designSystemId),
306
+ status: "in-progress",
307
+ };
308
+ }
@@ -383,6 +383,31 @@ function parseBuilderCallbackBoolean(
383
383
  // inlines them in the DOM. Mirrors SAFE_DATA_IMAGE in sanitize-html.ts.
384
384
  export const AVATAR_RASTER_MIME = /^data:image\/(png|jpe?g|gif|webp);/i;
385
385
 
386
+ export function resolveAvatarEmailParam(
387
+ pathname: string,
388
+ appBasePath = "",
389
+ ): string {
390
+ const base = appBasePath.replace(/\/+$/, "");
391
+ const avatarPaths = Array.from(
392
+ new Set([`${base}/_agent-native/avatar/`, "/_agent-native/avatar/"]),
393
+ );
394
+
395
+ for (const avatarPath of avatarPaths) {
396
+ const avatarIndex = pathname.indexOf(avatarPath);
397
+ if (avatarIndex >= 0) {
398
+ return pathname
399
+ .slice(avatarIndex + avatarPath.length)
400
+ .replace(/^\/+/, "")
401
+ .split("/")[0];
402
+ }
403
+ }
404
+
405
+ const firstSegment = pathname.replace(/^\/+/, "").split("/")[0] ?? "";
406
+ if (!firstSegment || firstSegment === "_agent-native") return "";
407
+ if (base && firstSegment === base.replace(/^\/+/, "")) return "";
408
+ return firstSegment;
409
+ }
410
+
386
411
  async function detectUsageEngineName(
387
412
  event: H3Event,
388
413
  userEmail: string | undefined,
@@ -3010,9 +3035,10 @@ export function createCoreRoutesPlugin(
3010
3035
  `${P}/avatar`,
3011
3036
  defineEventHandler(async (event: H3Event) => {
3012
3037
  const method = getMethod(event);
3013
- const emailParam = (event.url?.pathname || "")
3014
- .replace(/^\/+/, "")
3015
- .split("/")[0];
3038
+ const emailParam = resolveAvatarEmailParam(
3039
+ event.url?.pathname || "",
3040
+ getConfiguredAppBasePath(),
3041
+ );
3016
3042
 
3017
3043
  if (method === "GET") {
3018
3044
  if (!emailParam) {
@@ -386,6 +386,14 @@ export {
386
386
  deleteBuilderCredentials,
387
387
  resolveSecret,
388
388
  } from "./credential-provider.js";
389
+ export {
390
+ builderDesignSystemUrl,
391
+ getBuilderDesignSystemsBaseUrl,
392
+ startBuilderDesignSystemIndex,
393
+ type BuilderDesignSystemIndexFile,
394
+ type BuilderDesignSystemIndexOptions,
395
+ type BuilderDesignSystemIndexResult,
396
+ } from "./builder-design-systems.js";
389
397
  export {
390
398
  getBuilderBranchProjectId,
391
399
  isBuilderBranchingEnabled,
@@ -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