@agent-native/core 0.79.27 → 0.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +26 -0
  3. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +41 -0
  4. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +51 -0
  5. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +50 -0
  6. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +49 -0
  7. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +44 -0
  8. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +46 -0
  9. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +44 -0
  10. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +48 -0
  11. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +36 -0
  12. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +38 -0
  13. package/corpus/core/docs/content/template-design.mdx +45 -0
  14. package/corpus/core/package.json +2 -1
  15. package/corpus/core/src/agent/engine/index.ts +1 -0
  16. package/corpus/core/src/agent/engine/registry.ts +40 -0
  17. package/corpus/core/src/agent/production-agent.ts +6 -2
  18. package/corpus/core/src/cli/design-connect.ts +490 -0
  19. package/corpus/core/src/cli/index.ts +16 -0
  20. package/corpus/core/src/cli/skills.ts +126 -3
  21. package/corpus/core/src/client/AssistantChat.tsx +43 -7
  22. package/corpus/core/src/client/agent-chat.ts +27 -3
  23. package/corpus/core/src/client/blocks/library/MermaidBlock.tsx +1 -1
  24. package/corpus/core/src/client/blocks/library/diagram.tsx +2 -2
  25. package/corpus/core/src/client/blocks/library/wireframe.tsx +1 -1
  26. package/corpus/core/src/client/chat/message-components.tsx +1 -1
  27. package/corpus/core/src/client/chat-model-groups.ts +1 -2
  28. package/corpus/core/src/client/components/LiveCursorOverlay.tsx +33 -66
  29. package/corpus/core/src/client/composer/TiptapComposer.tsx +99 -24
  30. package/corpus/core/src/client/composer/useVoiceDictation.ts +429 -260
  31. package/corpus/core/src/client/frame-protocol.ts +17 -2
  32. package/corpus/core/src/client/rich-markdown-editor/RegistryBlockNode.tsx +2 -2
  33. package/corpus/core/src/client/sharing/ShareButton.tsx +20 -15
  34. package/corpus/core/src/client/use-agent-engine-configured.ts +80 -28
  35. package/corpus/core/src/server/transcribe-voice.ts +57 -22
  36. package/corpus/core/src/shared/mcp-embed-headers.ts +23 -1
  37. package/corpus/core/src/styles/agent-native.css +56 -7
  38. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  39. package/corpus/core/src/vite/client.ts +2 -0
  40. package/corpus/core/src/voice/index.ts +18 -0
  41. package/corpus/core/src/voice/voice-cleanup-prompt.ts +38 -0
  42. package/corpus/core/src/voice/voice-context.ts +217 -0
  43. package/corpus/core/src/voice/voice-replacements.ts +75 -0
  44. package/corpus/templates/analytics/AGENTS.md +4 -3
  45. package/corpus/templates/analytics/actions/list-session-recordings.ts +6 -1
  46. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +557 -400
  47. package/corpus/templates/analytics/app/global.css +0 -4
  48. package/corpus/templates/analytics/app/i18n/zh-TW.ts +2 -0
  49. package/corpus/templates/analytics/app/i18n-data.ts +20 -0
  50. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +33 -8
  51. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +7 -0
  52. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +7 -0
  53. package/corpus/templates/analytics/changelog/2026-06-28-ask-tab-now-matches-the-darker-app-background.md +6 -0
  54. package/corpus/templates/analytics/changelog/2026-06-28-dashboard-email-reports-now-use-cleaner-light-mode-snapshots.md +6 -0
  55. package/corpus/templates/analytics/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  56. package/corpus/templates/analytics/changelog/2026-06-28-sessions-now-show-only-signed-in-recordings-with-playable-re.md +6 -0
  57. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +3 -3
  58. package/corpus/templates/analytics/server/lib/dashboard-report.ts +29 -7
  59. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +5 -2
  60. package/corpus/templates/analytics/server/lib/session-replay.ts +24 -4
  61. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +4 -4
  62. package/corpus/templates/assets/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  63. package/corpus/templates/brain/app/components/layout/Layout.tsx +29 -2
  64. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +131 -42
  65. package/corpus/templates/brain/app/i18n/zh-TW.ts +2 -0
  66. package/corpus/templates/brain/app/i18n-data.ts +20 -0
  67. package/corpus/templates/brain/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  68. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +29 -1
  69. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +417 -299
  70. package/corpus/templates/calendar/app/i18n/zh-TW.ts +2 -0
  71. package/corpus/templates/calendar/app/i18n-data.ts +20 -0
  72. package/corpus/templates/calendar/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  73. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +6 -19
  74. package/corpus/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  75. package/corpus/templates/clips/AGENTS.md +4 -0
  76. package/corpus/templates/clips/actions/cleanup-transcript.ts +39 -9
  77. package/corpus/templates/clips/actions/finalize-meeting.ts +81 -12
  78. package/corpus/templates/clips/actions/lib/agents-md-context.ts +4 -1
  79. package/corpus/templates/clips/app/components/library/library-layout.tsx +3 -3
  80. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +1 -1
  81. package/corpus/templates/clips/app/components/player/share-dialog.tsx +2 -2
  82. package/corpus/templates/clips/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
  83. package/corpus/templates/clips/desktop/src/lib/personal-vocabulary.ts +13 -8
  84. package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +60 -1
  85. package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +1 -1
  86. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +1 -1
  87. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -5
  88. package/corpus/templates/content/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  89. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +137 -0
  90. package/corpus/templates/design/AGENTS.md +95 -5
  91. package/corpus/templates/design/DESIGN.md +82 -0
  92. package/corpus/templates/design/DEVELOPING.md +43 -0
  93. package/corpus/templates/design/actions/add-localhost-screens.ts +426 -0
  94. package/corpus/templates/design/actions/apply-shader.ts +277 -0
  95. package/corpus/templates/design/actions/apply-visual-edit.ts +303 -0
  96. package/corpus/templates/design/actions/connect-localhost.ts +183 -0
  97. package/corpus/templates/design/actions/edit-design.ts +195 -42
  98. package/corpus/templates/design/actions/generate-design.ts +71 -1
  99. package/corpus/templates/design/actions/generate-screens.ts +193 -0
  100. package/corpus/templates/design/actions/get-code-layer-projection.ts +191 -0
  101. package/corpus/templates/design/actions/get-shader.ts +119 -0
  102. package/corpus/templates/design/actions/list-localhost-connections.ts +95 -0
  103. package/corpus/templates/design/actions/navigate.ts +55 -2
  104. package/corpus/templates/design/actions/view-screen.ts +68 -1
  105. package/corpus/templates/design/agent-native.app-skill.json +10 -0
  106. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +761 -0
  107. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +2057 -103
  108. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +74 -38
  109. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +399 -0
  110. package/corpus/templates/design/app/components/design/EditPanel.tsx +3185 -439
  111. package/corpus/templates/design/app/components/design/LayersPanel.tsx +1124 -0
  112. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +3116 -147
  113. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +700 -13
  114. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +107 -63
  115. package/corpus/templates/design/app/components/design/index.ts +0 -5
  116. package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +286 -0
  117. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +699 -0
  118. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +461 -0
  119. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +166 -0
  120. package/corpus/templates/design/app/components/design/inspector/FigmaColorPicker.tsx +1420 -0
  121. package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +420 -0
  122. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +215 -0
  123. package/corpus/templates/design/app/components/design/inspector/ShaderControls.stories.tsx +71 -0
  124. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +518 -0
  125. package/corpus/templates/design/app/components/design/inspector/ShaderEffectRow.tsx +106 -0
  126. package/corpus/templates/design/app/components/design/inspector/figma-icons.tsx +361 -0
  127. package/corpus/templates/design/app/components/design/inspector/index.ts +60 -0
  128. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +201 -0
  129. package/corpus/templates/design/app/components/design/types.ts +23 -0
  130. package/corpus/templates/design/app/components/layout/Layout.tsx +24 -13
  131. package/corpus/templates/design/app/components/layout/Sidebar.tsx +4 -4
  132. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +474 -36
  133. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +22 -5
  134. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +24 -11
  135. package/corpus/templates/design/app/global.css +121 -3
  136. package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -0
  137. package/corpus/templates/design/app/hooks/use-navigation-state.ts +130 -8
  138. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +329 -0
  139. package/corpus/templates/design/app/i18n/zh-TW.ts +264 -0
  140. package/corpus/templates/design/app/i18n-data.ts +2790 -1
  141. package/corpus/templates/design/app/pages/DesignEditor.tsx +5108 -851
  142. package/corpus/templates/design/changelog/2026-06-28-annotate-mode-now-combines-drawing-and-comment-pins-in-one-c.md +6 -0
  143. package/corpus/templates/design/changelog/2026-06-28-design-editor-panel-borders-are-cleaner-so-the-canvas-edge-s.md +6 -0
  144. package/corpus/templates/design/changelog/2026-06-28-drawing-prompts-now-reliably-open-and-submit-to-the-design-a.md +6 -0
  145. package/corpus/templates/design/changelog/2026-06-28-editor-app-menus-now-use-an-outline-agent-native-mark-with-b.md +6 -0
  146. package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +6 -0
  147. package/corpus/templates/design/changelog/2026-06-28-layer-selection-now-updates-chat-context-without-opening-the.md +6 -0
  148. package/corpus/templates/design/changelog/2026-06-28-layer-selections-now-preserve-hidden-and-locked-canvas-state.md +6 -0
  149. package/corpus/templates/design/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  150. package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +6 -0
  151. package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +6 -0
  152. package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-handles-zooming-drawing-opening-and-dele.md +6 -0
  153. package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-selects-screens-on-click-and-opens-them-.md +6 -0
  154. package/corpus/templates/design/changelog/2026-06-28-screen-overview-zooms-into-the-active-screen-with-smoother-e.md +6 -0
  155. package/corpus/templates/design/changelog/2026-06-28-selected-element-chips-in-chat-are-shorter-and-easier-to-sca.md +6 -0
  156. package/corpus/templates/design/changelog/2026-06-28-the-design-editor-toolbar-is-more-compact-and-the-app-menu-m.md +6 -0
  157. package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-at-the-top-of-the-design-sidebar-instead-of-.md +6 -0
  158. package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-in-the-right-inspector-beside-the-design-tab.md +6 -0
  159. package/corpus/templates/design/changelog/2026-06-29-active-sidebar-rows-use-soft-highlights.md +6 -0
  160. package/corpus/templates/design/changelog/2026-06-29-agents-can-now-open-screen-overview-focus-screens-and-add.md +6 -0
  161. package/corpus/templates/design/changelog/2026-06-29-design-agents-now-edit-broad-copy-changes-more-reliably.md +6 -0
  162. package/corpus/templates/design/changelog/2026-06-29-design-editor-extensions-now-run-inline-beside-the-artboard.md +6 -0
  163. package/corpus/templates/design/changelog/2026-06-29-sidebars-use-darker-chrome-and-chat-warns-immediately.md +6 -0
  164. package/corpus/templates/design/changelog/2026-06-29-visual-edit-can-open-localhost-routes-as-url-backed-screens.md +6 -0
  165. package/corpus/templates/design/package.json +1 -0
  166. package/corpus/templates/design/server/db/schema.ts +26 -0
  167. package/corpus/templates/design/server/lib/design-snapshot.ts +1 -1
  168. package/corpus/templates/design/server/plugins/agent-chat.ts +3 -0
  169. package/corpus/templates/design/shared/api.ts +27 -0
  170. package/corpus/templates/design/shared/canvas-frames.ts +103 -0
  171. package/corpus/templates/design/shared/canvas-math.ts +1058 -0
  172. package/corpus/templates/design/shared/code-layer.ts +2212 -0
  173. package/corpus/templates/design/shared/color-utils.ts +180 -0
  174. package/corpus/templates/design/shared/generation-session.ts +61 -0
  175. package/corpus/templates/design/shared/shader-presets.ts +782 -0
  176. package/corpus/templates/design/shared/shader-safety.ts +137 -0
  177. package/corpus/templates/design/shared/source-mode.ts +237 -0
  178. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +149 -6
  179. package/corpus/templates/forms/app/i18n/ar-SA.ts +2 -0
  180. package/corpus/templates/forms/app/i18n/de-DE.ts +2 -0
  181. package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
  182. package/corpus/templates/forms/app/i18n/es-ES.ts +2 -0
  183. package/corpus/templates/forms/app/i18n/fr-FR.ts +2 -0
  184. package/corpus/templates/forms/app/i18n/hi-IN.ts +2 -0
  185. package/corpus/templates/forms/app/i18n/ja-JP.ts +2 -0
  186. package/corpus/templates/forms/app/i18n/ko-KR.ts +2 -0
  187. package/corpus/templates/forms/app/i18n/pt-BR.ts +2 -0
  188. package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
  189. package/corpus/templates/forms/app/i18n/zh-TW.ts +2 -0
  190. package/corpus/templates/forms/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  191. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +2 -2
  192. package/corpus/templates/macros/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
  193. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +408 -247
  194. package/corpus/templates/mail/app/i18n/ar-SA.ts +4 -0
  195. package/corpus/templates/mail/app/i18n/de-DE.ts +4 -0
  196. package/corpus/templates/mail/app/i18n/en-US.ts +4 -0
  197. package/corpus/templates/mail/app/i18n/es-ES.ts +4 -0
  198. package/corpus/templates/mail/app/i18n/fr-FR.ts +4 -0
  199. package/corpus/templates/mail/app/i18n/hi-IN.ts +4 -0
  200. package/corpus/templates/mail/app/i18n/ja-JP.ts +4 -0
  201. package/corpus/templates/mail/app/i18n/ko-KR.ts +4 -0
  202. package/corpus/templates/mail/app/i18n/pt-BR.ts +4 -0
  203. package/corpus/templates/mail/app/i18n/zh-CN.ts +4 -0
  204. package/corpus/templates/mail/app/i18n/zh-TW.ts +4 -0
  205. package/corpus/templates/mail/changelog/2026-06-28-pinned-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  206. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +6 -8
  207. package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +1 -1
  208. package/corpus/templates/plan/app/global.css +61 -78
  209. package/corpus/templates/plan/app/pages/PlansPage.tsx +8 -0
  210. package/corpus/templates/plan/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  211. package/corpus/templates/plan/changelog/2026-06-28-plans-use-the-shared-neutral-light-and-dark-theme.md +6 -0
  212. package/corpus/templates/plan/changelog/2026-06-28-sending-open-feedback-from-a-plan-now-opens-the-inline-plan-.md +6 -0
  213. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +5 -5
  214. package/corpus/templates/slides/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  215. package/corpus/templates/videos/app/components/Sidebar.tsx +2 -2
  216. package/corpus/templates/videos/app/components/layout/Layout.tsx +29 -2
  217. package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +113 -30
  218. package/corpus/templates/videos/app/i18n/ar-SA.ts +2 -0
  219. package/corpus/templates/videos/app/i18n/de-DE.ts +2 -0
  220. package/corpus/templates/videos/app/i18n/en-US.ts +2 -0
  221. package/corpus/templates/videos/app/i18n/es-ES.ts +2 -0
  222. package/corpus/templates/videos/app/i18n/fr-FR.ts +2 -0
  223. package/corpus/templates/videos/app/i18n/hi-IN.ts +2 -0
  224. package/corpus/templates/videos/app/i18n/ja-JP.ts +2 -0
  225. package/corpus/templates/videos/app/i18n/ko-KR.ts +2 -0
  226. package/corpus/templates/videos/app/i18n/pt-BR.ts +2 -0
  227. package/corpus/templates/videos/app/i18n/zh-CN.ts +2 -0
  228. package/corpus/templates/videos/app/i18n/zh-TW.ts +2 -0
  229. package/corpus/templates/videos/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  230. package/dist/agent/engine/index.d.ts +1 -1
  231. package/dist/agent/engine/index.d.ts.map +1 -1
  232. package/dist/agent/engine/index.js +1 -1
  233. package/dist/agent/engine/index.js.map +1 -1
  234. package/dist/agent/engine/registry.d.ts +9 -0
  235. package/dist/agent/engine/registry.d.ts.map +1 -1
  236. package/dist/agent/engine/registry.js +37 -0
  237. package/dist/agent/engine/registry.js.map +1 -1
  238. package/dist/agent/production-agent.d.ts.map +1 -1
  239. package/dist/agent/production-agent.js +4 -3
  240. package/dist/agent/production-agent.js.map +1 -1
  241. package/dist/cli/design-connect.d.ts +52 -0
  242. package/dist/cli/design-connect.d.ts.map +1 -0
  243. package/dist/cli/design-connect.js +409 -0
  244. package/dist/cli/design-connect.js.map +1 -0
  245. package/dist/cli/index.js +15 -0
  246. package/dist/cli/index.js.map +1 -1
  247. package/dist/cli/skills.d.ts +3 -0
  248. package/dist/cli/skills.d.ts.map +1 -1
  249. package/dist/cli/skills.js +121 -3
  250. package/dist/cli/skills.js.map +1 -1
  251. package/dist/client/AssistantChat.d.ts.map +1 -1
  252. package/dist/client/AssistantChat.js +38 -8
  253. package/dist/client/AssistantChat.js.map +1 -1
  254. package/dist/client/agent-chat.d.ts +6 -0
  255. package/dist/client/agent-chat.d.ts.map +1 -1
  256. package/dist/client/agent-chat.js +17 -3
  257. package/dist/client/agent-chat.js.map +1 -1
  258. package/dist/client/blocks/library/MermaidBlock.js +1 -1
  259. package/dist/client/blocks/library/MermaidBlock.js.map +1 -1
  260. package/dist/client/blocks/library/diagram.js +1 -1
  261. package/dist/client/blocks/library/diagram.js.map +1 -1
  262. package/dist/client/blocks/library/wireframe.js +1 -1
  263. package/dist/client/blocks/library/wireframe.js.map +1 -1
  264. package/dist/client/chat/message-components.js +1 -1
  265. package/dist/client/chat/message-components.js.map +1 -1
  266. package/dist/client/chat-model-groups.d.ts.map +1 -1
  267. package/dist/client/chat-model-groups.js +1 -2
  268. package/dist/client/chat-model-groups.js.map +1 -1
  269. package/dist/client/components/LiveCursorOverlay.d.ts +1 -2
  270. package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -1
  271. package/dist/client/components/LiveCursorOverlay.js +19 -40
  272. package/dist/client/components/LiveCursorOverlay.js.map +1 -1
  273. package/dist/client/composer/TiptapComposer.d.ts +3 -1
  274. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  275. package/dist/client/composer/TiptapComposer.js +86 -24
  276. package/dist/client/composer/TiptapComposer.js.map +1 -1
  277. package/dist/client/composer/useVoiceDictation.d.ts +9 -0
  278. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  279. package/dist/client/composer/useVoiceDictation.js +154 -32
  280. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  281. package/dist/client/frame-protocol.d.ts +17 -2
  282. package/dist/client/frame-protocol.d.ts.map +1 -1
  283. package/dist/client/frame-protocol.js.map +1 -1
  284. package/dist/client/rich-markdown-editor/RegistryBlockNode.js +2 -2
  285. package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -1
  286. package/dist/client/sharing/ShareButton.d.ts +2 -0
  287. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  288. package/dist/client/sharing/ShareButton.js +7 -6
  289. package/dist/client/sharing/ShareButton.js.map +1 -1
  290. package/dist/client/use-agent-engine-configured.d.ts +5 -0
  291. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  292. package/dist/client/use-agent-engine-configured.js +51 -25
  293. package/dist/client/use-agent-engine-configured.js.map +1 -1
  294. package/dist/collab/awareness.d.ts +2 -2
  295. package/dist/collab/awareness.d.ts.map +1 -1
  296. package/dist/collab/routes.d.ts +1 -1
  297. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  298. package/dist/notifications/routes.d.ts +3 -3
  299. package/dist/observability/routes.d.ts +8 -8
  300. package/dist/progress/routes.d.ts +1 -1
  301. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  302. package/dist/server/transcribe-voice.d.ts.map +1 -1
  303. package/dist/server/transcribe-voice.js +40 -24
  304. package/dist/server/transcribe-voice.js.map +1 -1
  305. package/dist/shared/mcp-embed-headers.d.ts +1 -0
  306. package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
  307. package/dist/shared/mcp-embed-headers.js +20 -1
  308. package/dist/shared/mcp-embed-headers.js.map +1 -1
  309. package/dist/styles/agent-native.css +56 -7
  310. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  311. package/dist/vite/client.d.ts.map +1 -1
  312. package/dist/vite/client.js +2 -0
  313. package/dist/vite/client.js.map +1 -1
  314. package/dist/voice/index.d.ts +5 -0
  315. package/dist/voice/index.d.ts.map +1 -0
  316. package/dist/voice/index.js +4 -0
  317. package/dist/voice/index.js.map +1 -0
  318. package/dist/voice/voice-cleanup-prompt.d.ts +6 -0
  319. package/dist/voice/voice-cleanup-prompt.d.ts.map +1 -0
  320. package/dist/voice/voice-cleanup-prompt.js +26 -0
  321. package/dist/voice/voice-cleanup-prompt.js.map +1 -0
  322. package/dist/voice/voice-context.d.ts +25 -0
  323. package/dist/voice/voice-context.d.ts.map +1 -0
  324. package/dist/voice/voice-context.js +156 -0
  325. package/dist/voice/voice-context.js.map +1 -0
  326. package/dist/voice/voice-replacements.d.ts +4 -0
  327. package/dist/voice/voice-replacements.d.ts.map +1 -0
  328. package/dist/voice/voice-replacements.js +52 -0
  329. package/dist/voice/voice-replacements.js.map +1 -0
  330. package/docs/content/locales/ar-SA/template-design.mdx +41 -0
  331. package/docs/content/locales/de-DE/template-design.mdx +51 -0
  332. package/docs/content/locales/es-ES/template-design.mdx +50 -0
  333. package/docs/content/locales/fr-FR/template-design.mdx +49 -0
  334. package/docs/content/locales/hi-IN/template-design.mdx +44 -0
  335. package/docs/content/locales/ja-JP/template-design.mdx +46 -0
  336. package/docs/content/locales/ko-KR/template-design.mdx +44 -0
  337. package/docs/content/locales/pt-BR/template-design.mdx +48 -0
  338. package/docs/content/locales/zh-CN/template-design.mdx +36 -0
  339. package/docs/content/locales/zh-TW/template-design.mdx +38 -0
  340. package/docs/content/template-design.mdx +45 -0
  341. package/package.json +2 -1
  342. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  343. package/corpus/templates/design/app/components/design/DesignToolbar.tsx +0 -339
  344. package/corpus/templates/design/app/components/design/PresentMode.tsx +0 -68
  345. package/corpus/templates/design/app/components/design/ViewportTabs.tsx +0 -149
  346. package/corpus/templates/design/app/components/design/ZoomControls.tsx +0 -157
@@ -0,0 +1,5 @@
1
+ export type { VoiceContextMode, VoiceContextPack, VoiceContextSnippet, VoiceTerm, } from "./voice-context.js";
2
+ export { formatVoiceContextPackForPrompt, parseVoiceContextPack, sanitizeVoiceContextPack, voiceContextHasContent, voiceContextTermsOnly, } from "./voice-context.js";
3
+ export { buildVoiceGuidanceBlock } from "./voice-cleanup-prompt.js";
4
+ export { applyVoiceContextReplacements, applyVoiceTermReplacements, } from "./voice-replacements.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/voice/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,GACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,+BAA+B,EAC/B,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { formatVoiceContextPackForPrompt, parseVoiceContextPack, sanitizeVoiceContextPack, voiceContextHasContent, voiceContextTermsOnly, } from "./voice-context.js";
2
+ export { buildVoiceGuidanceBlock } from "./voice-cleanup-prompt.js";
3
+ export { applyVoiceContextReplacements, applyVoiceTermReplacements, } from "./voice-replacements.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/voice/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,+BAA+B,EAC/B,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC","sourcesContent":["export type {\n VoiceContextMode,\n VoiceContextPack,\n VoiceContextSnippet,\n VoiceTerm,\n} from \"./voice-context.js\";\nexport {\n formatVoiceContextPackForPrompt,\n parseVoiceContextPack,\n sanitizeVoiceContextPack,\n voiceContextHasContent,\n voiceContextTermsOnly,\n} from \"./voice-context.js\";\nexport { buildVoiceGuidanceBlock } from \"./voice-cleanup-prompt.js\";\nexport {\n applyVoiceContextReplacements,\n applyVoiceTermReplacements,\n} from \"./voice-replacements.js\";\n"]}
@@ -0,0 +1,6 @@
1
+ import { type VoiceContextPack } from "./voice-context.js";
2
+ export declare function buildVoiceGuidanceBlock({ instructions, contextPack, }: {
3
+ instructions?: string;
4
+ contextPack?: VoiceContextPack | null;
5
+ }): string | undefined;
6
+ //# sourceMappingURL=voice-cleanup-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-cleanup-prompt.d.ts","sourceRoot":"","sources":["../../src/voice/voice-cleanup-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAU5B,wBAAgB,uBAAuB,CAAC,EACtC,YAAY,EACZ,WAAW,GACZ,EAAE;IACD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;CACvC,GAAG,MAAM,GAAG,SAAS,CAkBrB"}
@@ -0,0 +1,26 @@
1
+ import { formatVoiceContextPackForPrompt, } from "./voice-context.js";
2
+ const MAX_CUSTOM_INSTRUCTIONS_CHARS = 4_000;
3
+ function cleanInstructions(value) {
4
+ const trimmed = value?.replace(/\0/g, "").trim();
5
+ if (!trimmed)
6
+ return undefined;
7
+ return trimmed.slice(0, MAX_CUSTOM_INSTRUCTIONS_CHARS);
8
+ }
9
+ export function buildVoiceGuidanceBlock({ instructions, contextPack, }) {
10
+ const customInstructions = cleanInstructions(instructions);
11
+ const formattedContext = formatVoiceContextPackForPrompt(contextPack);
12
+ if (!customInstructions && !formattedContext)
13
+ return undefined;
14
+ const sections = [
15
+ "Use the following voice guidance only to improve transcription, cleanup, terminology, casing, punctuation, and formatting.",
16
+ "Never add facts or content that are not present in the audio or transcript.",
17
+ ];
18
+ if (customInstructions) {
19
+ sections.push(`User instructions:\n${customInstructions}`);
20
+ }
21
+ if (formattedContext) {
22
+ sections.push(`Voice context:\n${formattedContext}`);
23
+ }
24
+ return sections.join("\n\n");
25
+ }
26
+ //# sourceMappingURL=voice-cleanup-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-cleanup-prompt.js","sourceRoot":"","sources":["../../src/voice/voice-cleanup-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,+BAA+B,GAEhC,MAAM,oBAAoB,CAAC;AAE5B,MAAM,6BAA6B,GAAG,KAAK,CAAC;AAE5C,SAAS,iBAAiB,CAAC,KAAyB;IAClD,MAAM,OAAO,GAAG,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACjD,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,6BAA6B,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,EACtC,YAAY,EACZ,WAAW,GAIZ;IACC,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC3D,MAAM,gBAAgB,GAAG,+BAA+B,CAAC,WAAW,CAAC,CAAC;IACtE,IAAI,CAAC,kBAAkB,IAAI,CAAC,gBAAgB;QAAE,OAAO,SAAS,CAAC;IAE/D,MAAM,QAAQ,GAAG;QACf,4HAA4H;QAC5H,6EAA6E;KAC9E,CAAC;IAEF,IAAI,kBAAkB,EAAE,CAAC;QACvB,QAAQ,CAAC,IAAI,CAAC,uBAAuB,kBAAkB,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,gBAAgB,EAAE,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,mBAAmB,gBAAgB,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC","sourcesContent":["import {\n formatVoiceContextPackForPrompt,\n type VoiceContextPack,\n} from \"./voice-context.js\";\n\nconst MAX_CUSTOM_INSTRUCTIONS_CHARS = 4_000;\n\nfunction cleanInstructions(value: string | undefined): string | undefined {\n const trimmed = value?.replace(/\\0/g, \"\").trim();\n if (!trimmed) return undefined;\n return trimmed.slice(0, MAX_CUSTOM_INSTRUCTIONS_CHARS);\n}\n\nexport function buildVoiceGuidanceBlock({\n instructions,\n contextPack,\n}: {\n instructions?: string;\n contextPack?: VoiceContextPack | null;\n}): string | undefined {\n const customInstructions = cleanInstructions(instructions);\n const formattedContext = formatVoiceContextPackForPrompt(contextPack);\n if (!customInstructions && !formattedContext) return undefined;\n\n const sections = [\n \"Use the following voice guidance only to improve transcription, cleanup, terminology, casing, punctuation, and formatting.\",\n \"Never add facts or content that are not present in the audio or transcript.\",\n ];\n\n if (customInstructions) {\n sections.push(`User instructions:\\n${customInstructions}`);\n }\n if (formattedContext) {\n sections.push(`Voice context:\\n${formattedContext}`);\n }\n\n return sections.join(\"\\n\\n\");\n}\n"]}
@@ -0,0 +1,25 @@
1
+ export type VoiceContextMode = "dictation" | "cleanup" | "transcript" | "title" | "summary" | "meeting";
2
+ export interface VoiceContextSnippet {
3
+ label: string;
4
+ value: string;
5
+ }
6
+ export interface VoiceTerm {
7
+ term: string;
8
+ replacement?: string;
9
+ confidence?: number;
10
+ source?: string;
11
+ scope?: string;
12
+ }
13
+ export interface VoiceContextPack {
14
+ surface?: string;
15
+ mode?: VoiceContextMode | string;
16
+ snippets?: VoiceContextSnippet[];
17
+ terms?: VoiceTerm[];
18
+ metadata?: Record<string, string | number | boolean | null | undefined>;
19
+ }
20
+ export declare function sanitizeVoiceContextPack(input: unknown): VoiceContextPack | undefined;
21
+ export declare function parseVoiceContextPack(value: string): VoiceContextPack | undefined;
22
+ export declare function voiceContextHasContent(pack: VoiceContextPack | undefined): boolean;
23
+ export declare function voiceContextTermsOnly(input: unknown): VoiceContextPack | undefined;
24
+ export declare function formatVoiceContextPackForPrompt(input: unknown): string;
25
+ //# sourceMappingURL=voice-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-context.d.ts","sourceRoot":"","sources":["../../src/voice/voice-context.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GACxB,WAAW,GACX,SAAS,GACT,YAAY,GACZ,OAAO,GACP,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CACzE;AAsBD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,GACb,gBAAgB,GAAG,SAAS,CAoF9B;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GACZ,gBAAgB,GAAG,SAAS,CAQ9B;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,gBAAgB,GAAG,SAAS,GACjC,OAAO,CAQT;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,GACb,gBAAgB,GAAG,SAAS,CAI9B;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CA+CtE"}
@@ -0,0 +1,156 @@
1
+ const MAX_CONTEXT_PACK_CHARS = 64_000;
2
+ const MAX_SNIPPETS = 8;
3
+ const MAX_SNIPPET_VALUE_CHARS = 1_800;
4
+ const MAX_TERMS = 80;
5
+ const MAX_TERM_CHARS = 120;
6
+ const MAX_METADATA_KEYS = 12;
7
+ const MAX_METADATA_VALUE_CHARS = 160;
8
+ function cleanString(value, maxChars) {
9
+ if (typeof value !== "string")
10
+ return undefined;
11
+ const trimmed = value.replace(/\0/g, "").trim();
12
+ if (!trimmed)
13
+ return undefined;
14
+ return trimmed.slice(0, maxChars);
15
+ }
16
+ function cleanNumber(value) {
17
+ if (typeof value !== "number" || !Number.isFinite(value))
18
+ return undefined;
19
+ return Math.min(1, Math.max(0, value));
20
+ }
21
+ export function sanitizeVoiceContextPack(input) {
22
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
23
+ return undefined;
24
+ }
25
+ const raw = input;
26
+ const surface = cleanString(raw.surface, 80);
27
+ const mode = cleanString(raw.mode, 40);
28
+ const snippets = Array.isArray(raw.snippets)
29
+ ? raw.snippets
30
+ .slice(0, MAX_SNIPPETS)
31
+ .map((snippet) => {
32
+ if (!snippet || typeof snippet !== "object")
33
+ return null;
34
+ const candidate = snippet;
35
+ const label = cleanString(candidate.label, 80);
36
+ const value = cleanString(candidate.value, MAX_SNIPPET_VALUE_CHARS);
37
+ return label && value ? { label, value } : null;
38
+ })
39
+ .filter((snippet) => snippet !== null)
40
+ : undefined;
41
+ const terms = Array.isArray(raw.terms)
42
+ ? raw.terms
43
+ .slice(0, MAX_TERMS)
44
+ .map((term) => {
45
+ if (!term || typeof term !== "object")
46
+ return null;
47
+ const candidate = term;
48
+ const rawTerm = cleanString(candidate.term, MAX_TERM_CHARS);
49
+ if (!rawTerm || rawTerm.length < 2)
50
+ return null;
51
+ const replacement = cleanString(candidate.replacement, MAX_TERM_CHARS);
52
+ const source = cleanString(candidate.source, 40);
53
+ const scope = cleanString(candidate.scope, 40);
54
+ const confidence = cleanNumber(candidate.confidence);
55
+ return {
56
+ term: rawTerm,
57
+ ...(replacement ? { replacement } : {}),
58
+ ...(confidence !== undefined ? { confidence } : {}),
59
+ ...(source ? { source } : {}),
60
+ ...(scope ? { scope } : {}),
61
+ };
62
+ })
63
+ .filter((term) => term !== null)
64
+ : undefined;
65
+ const metadata = raw.metadata &&
66
+ typeof raw.metadata === "object" &&
67
+ !Array.isArray(raw.metadata)
68
+ ? Object.fromEntries(Object.entries(raw.metadata)
69
+ .slice(0, MAX_METADATA_KEYS)
70
+ .flatMap(([key, value]) => {
71
+ const cleanKey = cleanString(key, 60);
72
+ if (!cleanKey)
73
+ return [];
74
+ if (typeof value === "string" ||
75
+ typeof value === "number" ||
76
+ typeof value === "boolean" ||
77
+ value === null) {
78
+ const cleanValue = typeof value === "string"
79
+ ? cleanString(value, MAX_METADATA_VALUE_CHARS)
80
+ : value;
81
+ return cleanValue === undefined ? [] : [[cleanKey, cleanValue]];
82
+ }
83
+ return [];
84
+ }))
85
+ : undefined;
86
+ const pack = {
87
+ ...(surface ? { surface } : {}),
88
+ ...(mode ? { mode } : {}),
89
+ ...(snippets?.length ? { snippets } : {}),
90
+ ...(terms?.length ? { terms } : {}),
91
+ ...(metadata && Object.keys(metadata).length > 0 ? { metadata } : {}),
92
+ };
93
+ return voiceContextHasContent(pack) ? pack : undefined;
94
+ }
95
+ export function parseVoiceContextPack(value) {
96
+ const trimmed = value.replace(/\0/g, "").trim();
97
+ if (!trimmed || trimmed.length > MAX_CONTEXT_PACK_CHARS)
98
+ return undefined;
99
+ try {
100
+ return sanitizeVoiceContextPack(JSON.parse(trimmed));
101
+ }
102
+ catch {
103
+ return undefined;
104
+ }
105
+ }
106
+ export function voiceContextHasContent(pack) {
107
+ return Boolean(pack?.surface ||
108
+ pack?.mode ||
109
+ pack?.snippets?.length ||
110
+ pack?.terms?.length ||
111
+ (pack?.metadata && Object.keys(pack.metadata).length > 0));
112
+ }
113
+ export function voiceContextTermsOnly(input) {
114
+ const pack = sanitizeVoiceContextPack(input);
115
+ if (!pack?.terms?.length)
116
+ return undefined;
117
+ return { terms: pack.terms };
118
+ }
119
+ export function formatVoiceContextPackForPrompt(input) {
120
+ const pack = sanitizeVoiceContextPack(input);
121
+ if (!pack)
122
+ return "";
123
+ const sections = [];
124
+ if (pack.surface)
125
+ sections.push(`Surface: ${pack.surface}`);
126
+ if (pack.mode)
127
+ sections.push(`Mode: ${pack.mode}`);
128
+ if (pack.snippets?.length) {
129
+ sections.push([
130
+ "Context snippets:",
131
+ ...pack.snippets.map((snippet) => `- ${snippet.label}: ${snippet.value}`),
132
+ ].join("\n"));
133
+ }
134
+ if (pack.terms?.length) {
135
+ sections.push([
136
+ "Preferred vocabulary and casing:",
137
+ ...pack.terms.map((term) => {
138
+ const replacement = term.replacement && term.replacement !== term.term
139
+ ? ` -> ${term.replacement}`
140
+ : "";
141
+ const source = term.source ? ` (${term.source})` : "";
142
+ return `- ${term.term}${replacement}${source}`;
143
+ }),
144
+ ].join("\n"));
145
+ }
146
+ if (pack.metadata && Object.keys(pack.metadata).length > 0) {
147
+ sections.push([
148
+ "Metadata:",
149
+ ...Object.entries(pack.metadata).map(([key, value]) => {
150
+ return `- ${key}: ${String(value)}`;
151
+ }),
152
+ ].join("\n"));
153
+ }
154
+ return sections.join("\n\n");
155
+ }
156
+ //# sourceMappingURL=voice-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-context.js","sourceRoot":"","sources":["../../src/voice/voice-context.ts"],"names":[],"mappings":"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","sourcesContent":["export type VoiceContextMode =\n | \"dictation\"\n | \"cleanup\"\n | \"transcript\"\n | \"title\"\n | \"summary\"\n | \"meeting\";\n\nexport interface VoiceContextSnippet {\n label: string;\n value: string;\n}\n\nexport interface VoiceTerm {\n term: string;\n replacement?: string;\n confidence?: number;\n source?: string;\n scope?: string;\n}\n\nexport interface VoiceContextPack {\n surface?: string;\n mode?: VoiceContextMode | string;\n snippets?: VoiceContextSnippet[];\n terms?: VoiceTerm[];\n metadata?: Record<string, string | number | boolean | null | undefined>;\n}\n\nconst MAX_CONTEXT_PACK_CHARS = 64_000;\nconst MAX_SNIPPETS = 8;\nconst MAX_SNIPPET_VALUE_CHARS = 1_800;\nconst MAX_TERMS = 80;\nconst MAX_TERM_CHARS = 120;\nconst MAX_METADATA_KEYS = 12;\nconst MAX_METADATA_VALUE_CHARS = 160;\n\nfunction cleanString(value: unknown, maxChars: number): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.replace(/\\0/g, \"\").trim();\n if (!trimmed) return undefined;\n return trimmed.slice(0, maxChars);\n}\n\nfunction cleanNumber(value: unknown): number | undefined {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return undefined;\n return Math.min(1, Math.max(0, value));\n}\n\nexport function sanitizeVoiceContextPack(\n input: unknown,\n): VoiceContextPack | undefined {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) {\n return undefined;\n }\n\n const raw = input as VoiceContextPack;\n const surface = cleanString(raw.surface, 80);\n const mode = cleanString(raw.mode, 40);\n\n const snippets = Array.isArray(raw.snippets)\n ? raw.snippets\n .slice(0, MAX_SNIPPETS)\n .map((snippet) => {\n if (!snippet || typeof snippet !== \"object\") return null;\n const candidate = snippet as Partial<VoiceContextSnippet>;\n const label = cleanString(candidate.label, 80);\n const value = cleanString(candidate.value, MAX_SNIPPET_VALUE_CHARS);\n return label && value ? { label, value } : null;\n })\n .filter((snippet): snippet is VoiceContextSnippet => snippet !== null)\n : undefined;\n\n const terms = Array.isArray(raw.terms)\n ? raw.terms\n .slice(0, MAX_TERMS)\n .map((term) => {\n if (!term || typeof term !== \"object\") return null;\n const candidate = term as Partial<VoiceTerm>;\n const rawTerm = cleanString(candidate.term, MAX_TERM_CHARS);\n if (!rawTerm || rawTerm.length < 2) return null;\n const replacement = cleanString(\n candidate.replacement,\n MAX_TERM_CHARS,\n );\n const source = cleanString(candidate.source, 40);\n const scope = cleanString(candidate.scope, 40);\n const confidence = cleanNumber(candidate.confidence);\n return {\n term: rawTerm,\n ...(replacement ? { replacement } : {}),\n ...(confidence !== undefined ? { confidence } : {}),\n ...(source ? { source } : {}),\n ...(scope ? { scope } : {}),\n };\n })\n .filter((term): term is VoiceTerm => term !== null)\n : undefined;\n\n const metadata =\n raw.metadata &&\n typeof raw.metadata === \"object\" &&\n !Array.isArray(raw.metadata)\n ? Object.fromEntries(\n Object.entries(raw.metadata)\n .slice(0, MAX_METADATA_KEYS)\n .flatMap(([key, value]) => {\n const cleanKey = cleanString(key, 60);\n if (!cleanKey) return [];\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n value === null\n ) {\n const cleanValue =\n typeof value === \"string\"\n ? cleanString(value, MAX_METADATA_VALUE_CHARS)\n : value;\n return cleanValue === undefined ? [] : [[cleanKey, cleanValue]];\n }\n return [];\n }),\n )\n : undefined;\n\n const pack: VoiceContextPack = {\n ...(surface ? { surface } : {}),\n ...(mode ? { mode } : {}),\n ...(snippets?.length ? { snippets } : {}),\n ...(terms?.length ? { terms } : {}),\n ...(metadata && Object.keys(metadata).length > 0 ? { metadata } : {}),\n };\n\n return voiceContextHasContent(pack) ? pack : undefined;\n}\n\nexport function parseVoiceContextPack(\n value: string,\n): VoiceContextPack | undefined {\n const trimmed = value.replace(/\\0/g, \"\").trim();\n if (!trimmed || trimmed.length > MAX_CONTEXT_PACK_CHARS) return undefined;\n try {\n return sanitizeVoiceContextPack(JSON.parse(trimmed));\n } catch {\n return undefined;\n }\n}\n\nexport function voiceContextHasContent(\n pack: VoiceContextPack | undefined,\n): boolean {\n return Boolean(\n pack?.surface ||\n pack?.mode ||\n pack?.snippets?.length ||\n pack?.terms?.length ||\n (pack?.metadata && Object.keys(pack.metadata).length > 0),\n );\n}\n\nexport function voiceContextTermsOnly(\n input: unknown,\n): VoiceContextPack | undefined {\n const pack = sanitizeVoiceContextPack(input);\n if (!pack?.terms?.length) return undefined;\n return { terms: pack.terms };\n}\n\nexport function formatVoiceContextPackForPrompt(input: unknown): string {\n const pack = sanitizeVoiceContextPack(input);\n if (!pack) return \"\";\n\n const sections: string[] = [];\n if (pack.surface) sections.push(`Surface: ${pack.surface}`);\n if (pack.mode) sections.push(`Mode: ${pack.mode}`);\n\n if (pack.snippets?.length) {\n sections.push(\n [\n \"Context snippets:\",\n ...pack.snippets.map(\n (snippet) => `- ${snippet.label}: ${snippet.value}`,\n ),\n ].join(\"\\n\"),\n );\n }\n\n if (pack.terms?.length) {\n sections.push(\n [\n \"Preferred vocabulary and casing:\",\n ...pack.terms.map((term) => {\n const replacement =\n term.replacement && term.replacement !== term.term\n ? ` -> ${term.replacement}`\n : \"\";\n const source = term.source ? ` (${term.source})` : \"\";\n return `- ${term.term}${replacement}${source}`;\n }),\n ].join(\"\\n\"),\n );\n }\n\n if (pack.metadata && Object.keys(pack.metadata).length > 0) {\n sections.push(\n [\n \"Metadata:\",\n ...Object.entries(pack.metadata).map(([key, value]) => {\n return `- ${key}: ${String(value)}`;\n }),\n ].join(\"\\n\"),\n );\n }\n\n return sections.join(\"\\n\\n\");\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import { type VoiceContextPack, type VoiceTerm } from "./voice-context.js";
2
+ export declare function applyVoiceTermReplacements(text: string, terms: readonly VoiceTerm[] | undefined): string;
3
+ export declare function applyVoiceContextReplacements(text: string, contextPack: VoiceContextPack | undefined): string;
4
+ //# sourceMappingURL=voice-replacements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-replacements.d.ts","sourceRoot":"","sources":["../../src/voice/voice-replacements.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACf,MAAM,oBAAoB,CAAC;AA4B5B,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,GACtC,MAAM,CA+BR;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,gBAAgB,GAAG,SAAS,GACxC,MAAM,CAGR"}
@@ -0,0 +1,52 @@
1
+ import { sanitizeVoiceContextPack, } from "./voice-context.js";
2
+ function escapeRegExp(value) {
3
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4
+ }
5
+ function isAlphaNumeric(value) {
6
+ return value != null && /[\p{L}\p{N}_]/u.test(value);
7
+ }
8
+ function isSafeVoiceReplacementBoundary(text, index, direction) {
9
+ const char = text[index];
10
+ if (char == null)
11
+ return true;
12
+ if (isAlphaNumeric(char))
13
+ return false;
14
+ if (char === "@" || char === "/" || char === "\\" || char === ":") {
15
+ return false;
16
+ }
17
+ if (char === "." || char === "-" || char === "+") {
18
+ const neighbor = direction === "before" ? text[index - 1] : text[index + 1];
19
+ return !isAlphaNumeric(neighbor);
20
+ }
21
+ return true;
22
+ }
23
+ export function applyVoiceTermReplacements(text, terms) {
24
+ if (!text || !terms?.length)
25
+ return text;
26
+ let next = text;
27
+ const replacements = terms
28
+ .filter((term) => term.term.trim().length >= 2 &&
29
+ term.replacement?.trim() &&
30
+ term.replacement.trim() !== term.term.trim())
31
+ .sort((a, b) => b.term.length - a.term.length);
32
+ for (const term of replacements) {
33
+ const source = escapeRegExp(term.term.trim());
34
+ const replacement = term.replacement?.trim() ?? "";
35
+ const pattern = new RegExp(source, "giu");
36
+ next = next.replace(pattern, (match, offset) => {
37
+ const start = offset;
38
+ const end = offset + match.length;
39
+ if (!isSafeVoiceReplacementBoundary(next, start - 1, "before") ||
40
+ !isSafeVoiceReplacementBoundary(next, end, "after")) {
41
+ return match;
42
+ }
43
+ return replacement;
44
+ });
45
+ }
46
+ return next;
47
+ }
48
+ export function applyVoiceContextReplacements(text, contextPack) {
49
+ const pack = sanitizeVoiceContextPack(contextPack);
50
+ return applyVoiceTermReplacements(text, pack?.terms);
51
+ }
52
+ //# sourceMappingURL=voice-replacements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-replacements.js","sourceRoot":"","sources":["../../src/voice/voice-replacements.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n sanitizeVoiceContextPack,\n type VoiceContextPack,\n type VoiceTerm,\n} from \"./voice-context.js\";\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction isAlphaNumeric(value: string | undefined): boolean {\n return value != null && /[\\p{L}\\p{N}_]/u.test(value);\n}\n\nfunction isSafeVoiceReplacementBoundary(\n text: string,\n index: number,\n direction: \"before\" | \"after\",\n): boolean {\n const char = text[index];\n if (char == null) return true;\n if (isAlphaNumeric(char)) return false;\n if (char === \"@\" || char === \"/\" || char === \"\\\\\" || char === \":\") {\n return false;\n }\n if (char === \".\" || char === \"-\" || char === \"+\") {\n const neighbor = direction === \"before\" ? text[index - 1] : text[index + 1];\n return !isAlphaNumeric(neighbor);\n }\n return true;\n}\n\nexport function applyVoiceTermReplacements(\n text: string,\n terms: readonly VoiceTerm[] | undefined,\n): string {\n if (!text || !terms?.length) return text;\n\n let next = text;\n const replacements = terms\n .filter(\n (term) =>\n term.term.trim().length >= 2 &&\n term.replacement?.trim() &&\n term.replacement.trim() !== term.term.trim(),\n )\n .sort((a, b) => b.term.length - a.term.length);\n\n for (const term of replacements) {\n const source = escapeRegExp(term.term.trim());\n const replacement = term.replacement?.trim() ?? \"\";\n const pattern = new RegExp(source, \"giu\");\n next = next.replace(pattern, (match, offset: number) => {\n const start = offset;\n const end = offset + match.length;\n if (\n !isSafeVoiceReplacementBoundary(next, start - 1, \"before\") ||\n !isSafeVoiceReplacementBoundary(next, end, \"after\")\n ) {\n return match;\n }\n return replacement;\n });\n }\n\n return next;\n}\n\nexport function applyVoiceContextReplacements(\n text: string,\n contextPack: VoiceContextPack | undefined,\n): string {\n const pack = sanitizeVoiceContextPack(contextPack);\n return applyVoiceTermReplacements(text, pack?.terms);\n}\n"]}
@@ -350,6 +350,47 @@ pnpm dev
350
350
 
351
351
  نظرًا لأن التصميم هو مجرد ملفات HTML/JSX مستقلة، يقوم الوكيل بتحرير نفس المصدر الذي يعرضه iframe ويأتي منه كل تصدير - لا يوجد تنسيق "AI mockup" منفصل لترجمته. يوفر نظام التصميم المرتبط الرموز المميزة ويكرم الوكيل `custom_instructions` في كل تذكرة جيل. حدد نصًا أو منطقة في المعاينة واضغط على Cmd+I لتركيز الوكيل على هذا الجزء بالضبط.
352
352
 
353
+ ### نموذج المحرر
354
+
355
+ يعتمد Design على النظرة العامة أولاً عند العمل على شاشات متعددة. بعد الإنشاء
356
+ أو التحديثات الواسعة، يفتح المحرر النظرة العامة للشاشات: لوحة لا نهائية تكون
357
+ فيها كل شاشة إطارًا ثابتًا يمكن تحديده أو نقله أو تغيير حجمه أو إسقاطه أو
358
+ تكراره. انقر نقرًا مزدوجًا على إطار للتركيز على شاشة واحدة.
359
+
360
+ وضع الشاشة الواحدة مخصص للتمرير، والتفاعل مع سلوك النموذج الأولي، وتحرير
361
+ طبقات DOM/الكود داخل ملف واحد معروض. تعكس لوحة الطبقات هذا التقسيم: الشاشات
362
+ إطارات من المستوى الأعلى، وتحت الشاشة النشطة تظهر طبقات DOM/الكود المتداخلة.
363
+
364
+ لأسماء طبقات مستقرة، أضف `data-agent-native-layer-name` إلى العناصر المهمة.
365
+ يستخدمه Design قبل البدائل الدلالية/النصية، ويمكنه حفظ إعادة تسمية الطبقات عبر
366
+ تحرير هذا السمة. يدعم HTML المضمن تحرير طبقات الكود محليًا للنصوص والأصناف
367
+ والأنماط والسمات وترتيب المصدر والتغييرات البنيوية الصغيرة؛ وتقتصر التعديلات
368
+ المرئية لطبقات الكود حاليًا على HTML. يستطيع وضع مصدر localhost تسجيل لوحات
369
+ عمل المسارات المحلية وحلها، لكن قراءة/كتابة الملفات المحلية تبقى عقد جسر إلى
370
+ أن يتم تعزيز عناصر التحكم الصريحة في الأذونات.
371
+
372
+ ### ملحقات محرر Design
373
+
374
+ يتضمن المحرر علامة تبويب المفتش **Extensions** بعد **Tweaks**. تعمل
375
+ كمسار إضافات خاص بـ Design: يمكن للمستخدمين النقر على **+ Extension** ليطلبوا
376
+ من الوكيل بناء ملحق، أو تثبيت ملحق يعلن فتحة `design.editor.inspector`.
377
+
378
+ تُعرض ملحقات Design مضمّنة بجانب لوحة العمل عبر صندوق رمل الملحقات القياسي.
379
+ يمرر المضيف تحديثات `window.slotContext` و`window.onSlotContext(...)` مع
380
+ `designId` الحالي، والملف النشط، وقائمة الشاشات، ومعرفات الشاشات المحددة،
381
+ وبيانات العنصر المحدد، ووضع العرض، والتكبير، والأداة النشطة، وقيم التعديلات.
382
+ يسمح ذلك للملحق بعرض معلومات عن التحديد الحالي، أو تقديم عناصر تحكم في النمط،
383
+ أو بناء تدفقات عمل صغيرة حول التصميم المفتوح.
384
+
385
+ للعمل الحتمي، يمكن للملحقات استدعاء إجراءات التطبيق من خلال جسر الملحقات.
386
+ وللتغييرات المدفوعة بالذكاء الاصطناعي، اجعل الملحق يستدعي
387
+ `agentNative.chat.send(...)` مع محدد العنصر/معرف المصدر والتغيير المطلوب. يجب
388
+ أن يستدعي الوكيل `view-screen` أولاً، ثم يستخدم `apply-visual-edit` لتغييرات
389
+ نمط العنصر أو الصنف أو النص أو الحركة، أو يستخدم `update-design` /
390
+ `generate-design` مع `canvasFrames` لتغييرات موضع لوحة العمل. راجع
391
+ [Extensions](/docs/extensions#what-an-extension-can-do) لمعرفة صندوق الرمل
392
+ والحالة المستمرة وواجهات جسر الملحقات.
393
+
353
394
  ### تخصيصه
354
395
 
355
396
  التصميم عبارة عن قالب كامل وقابل للاستنساخ. بعض الأفكار الإضافية العملية:
@@ -348,6 +348,57 @@ Der Agent weiß immer, was Sie offen haben. Das aktuelle Design, die geöffnete
348
348
 
349
349
  Da es sich bei einem Design lediglich um eigenständige HTML/JSX-Dateien handelt, bearbeitet der Agent dieselbe Quelle, die der Iframe rendert, und jeder Export stammt aus – es gibt kein separates „AI-Mockup“-Format zum Übersetzen. Ein verknüpftes Designsystem liefert Token und `custom_instructions`, die der Agent bei jedem Generationsdurchlauf ehrt. Wählen Sie in der Vorschau Text oder einen Bereich aus und drücken Sie Befehl+I, um den Agenten genau auf diesen Teil zu konzentrieren.
350
350
 
351
+ ### Editor-Modell
352
+
353
+ Design ist bei Arbeit mit mehreren Bildschirmen übersichtsorientiert. Nach der
354
+ Generierung oder größeren Aktualisierungen öffnet der Editor die
355
+ Bildschirmübersicht: eine unendliche Arbeitsfläche, auf der jeder Bildschirm ein
356
+ statischer Rahmen ist, den Sie auswählen, verschieben, skalieren, ablegen oder
357
+ duplizieren können. Verwenden Sie die Vollansicht-Schaltfläche des Rahmens, wenn ein Bildschirm
358
+ fokussiertes Scrollen oder Prototypinteraktion benötigt.
359
+
360
+ Der Einzelbildschirmmodus ist für Scrollen, Interaktion mit Prototypverhalten
361
+ und Bearbeitung der DOM-/Code-Ebenen in einer gerenderten Datei gedacht. Das
362
+ Ebenenfenster spiegelt diese Trennung wider: Bildschirme sind Rahmen der
363
+ obersten Ebene, darunter liegen die DOM-/Code-Ebenen des aktiven Bildschirms.
364
+
365
+ Für stabile Ebenennamen fügen Sie wichtigen Elementen
366
+ `data-agent-native-layer-name` hinzu. Design verwendet dies vor
367
+ semantischen/textbasierten Fallbacks und kann Umbenennungen durch Bearbeiten
368
+ dieses Attributs speichern. Inline-HTML unterstützt lokale Code-Ebenen-Edits
369
+ für Text, Klassen, Stile, Attribute, Quellreihenfolge und kleine strukturelle
370
+ Änderungen; visuelle Code-Ebenen-Edits sind heute HTML-only. Der
371
+ localhost-Quellmodus kann lokale Routen-Artboards registrieren und auflösen,
372
+ aber lokale Datei-Lese-/Schreibvorgänge bleiben ein Bridge-Vertrag, bis
373
+ explizite Berechtigungskontrollen gehärtet sind.
374
+
375
+ ### Erweiterungen im Design-Editor
376
+
377
+ Der Editor enthält nach **Tweaks** eine **Extensions**-Inspektorregisterkarte.
378
+ Sie funktioniert wie eine Design-spezifische Plugin-Spur: Benutzer können auf
379
+ **+ Extension** klicken, um den Agenten eine Erweiterung erstellen zu lassen,
380
+ oder eine Erweiterung installieren, die den Slot `design.editor.inspector`
381
+ deklariert.
382
+
383
+ Design-Erweiterungen werden über die Standard-Erweiterungssandbox inline neben
384
+ der Arbeitsfläche gerendert. Der Host übergibt `window.slotContext` und
385
+ `window.onSlotContext(...)`-Updates mit der aktuellen `designId`, der aktiven
386
+ Datei, der Bildschirmliste, ausgewählten Bildschirm-IDs, Metadaten des
387
+ ausgewählten Elements, Ansichtsmodus, Zoom, aktivem Werkzeug und Tweak-Werten.
388
+ So kann eine Erweiterung Informationen zur aktuellen Auswahl anzeigen,
389
+ Stilsteuerungen anbieten oder kompakte Workflows rund um das geöffnete Design
390
+ erstellen.
391
+
392
+ Für deterministische Arbeit können Erweiterungen App-Aktionen über die
393
+ Erweiterungsbrücke aufrufen. Für KI-gesteuerte Änderungen sollte die Erweiterung
394
+ `agentNative.chat.send(...)` mit dem Selektor/Quell-ID des ausgewählten Elements
395
+ und der gewünschten Änderung aufrufen. Der Agent sollte zuerst `view-screen`
396
+ aufrufen und dann `apply-visual-edit` für Stil-, Klassen-, Text- oder
397
+ Verschiebungsänderungen an Elementen verwenden, oder `update-design` /
398
+ `generate-design` mit `canvasFrames` für Änderungen an der Platzierung der
399
+ Arbeitsfläche. Siehe [Extensions](/docs/extensions#what-an-extension-can-do)
400
+ für Sandbox, persistente Daten und Bridge-APIs.
401
+
351
402
  ### Anpassen
352
403
 
353
404
  Design ist eine vollständige, klonbare Vorlage. Einige praktische Erweiterungsideen:
@@ -348,6 +348,56 @@ El agente siempre sabe lo que tienes abierto. `view-screen` devuelve el diseño
348
348
 
349
349
  Debido a que un diseño son solo archivos HTML/JSX independientes, el agente edita la misma fuente que representa el iframe y de donde proviene cada exportación; no hay un formato de "maqueta de IA" independiente para traducir. Un sistema de diseño vinculado proporciona tokens y `custom_instructions` el agente honra en cada paso de generación. Seleccione texto o una región en la vista previa y presione Cmd+I para enfocar al agente exactamente en esa parte.
350
350
 
351
+ ### Modelo del editor
352
+
353
+ Design prioriza la vista general para el trabajo con varias pantallas. Después
354
+ de generar o aplicar actualizaciones amplias, el editor abre la vista general de
355
+ pantallas: un lienzo infinito donde cada pantalla es un marco estático que se
356
+ puede seleccionar, mover, redimensionar, soltar o duplicar. Usa el botón de vista completa del marco cuando una pantalla necesite
357
+ desplazamiento enfocado o interacción de prototipo.
358
+
359
+ El modo de una sola pantalla sirve para desplazarse, interactuar con el
360
+ comportamiento del prototipo y editar las capas DOM/código dentro de un archivo
361
+ renderizado. El panel de capas refleja esa división: las pantallas son marcos de
362
+ nivel superior, con capas DOM/código anidadas para la pantalla activa.
363
+
364
+ Para nombres de capa estables, agrega `data-agent-native-layer-name` a los
365
+ elementos importantes. Design lo usa antes de los respaldos semánticos/de texto
366
+ y puede persistir cambios de nombre editando ese atributo. HTML inline admite
367
+ ediciones locales de capas de código para texto, clases, estilos, atributos,
368
+ orden del código fuente y pequeños cambios estructurales; las ediciones visuales
369
+ de capas de código solo admiten HTML por ahora. El modo de fuente localhost
370
+ puede registrar y resolver artboards de rutas locales, pero las lecturas y
371
+ escrituras de archivos locales siguen siendo un contrato de puente hasta que se
372
+ endurezcan los controles explícitos de permisos.
373
+
374
+ ### Extensiones del editor de Design
375
+
376
+ El editor incluye una pestaña de inspector **Extensions** después de
377
+ **Tweaks**. Funciona como un carril de plugins específico de Design: los
378
+ usuarios pueden hacer clic en **+ Extension** para pedirle al agente que cree
379
+ una extensión, o instalar una extensión que declare el slot
380
+ `design.editor.inspector`.
381
+
382
+ Las extensiones de Design se renderizan en línea junto al artboard mediante el
383
+ sandbox estándar de extensiones. El host pasa actualizaciones de
384
+ `window.slotContext` y `window.onSlotContext(...)` con el `designId` actual, el
385
+ archivo activo, la lista de pantallas, los ids de pantalla seleccionados, los
386
+ metadatos del elemento seleccionado, el modo de vista, el zoom, la herramienta
387
+ activa y los valores de tweaks. Eso permite que una extensión muestre
388
+ información sobre la selección actual, ofrezca controles de estilo o construya
389
+ flujos compactos alrededor del diseño abierto.
390
+
391
+ Para trabajo determinista, las extensiones pueden llamar acciones de la app a
392
+ través del puente de extensiones. Para cambios impulsados por IA, haz que la
393
+ extensión llame `agentNative.chat.send(...)` con el selector/id de origen del
394
+ elemento seleccionado y el cambio solicitado. El agente debe llamar primero
395
+ `view-screen`, luego usar `apply-visual-edit` para cambios de estilo, clase,
396
+ texto o movimiento de elementos, o `update-design` / `generate-design` con
397
+ `canvasFrames` para cambios de colocación del artboard. Consulta
398
+ [Extensions](/docs/extensions#what-an-extension-can-do) para el sandbox, el
399
+ estado persistente y las APIs del puente.
400
+
351
401
  ### Personalizarlo
352
402
 
353
403
  El diseño es una plantilla completa y clonable. Algunas ideas prácticas de extensión:
@@ -348,6 +348,55 @@ L'agent sait toujours ce que vous avez ouvert. La conception actuelle, le fichie
348
348
 
349
349
  Étant donné qu'une conception n'est constituée que de fichiers HTML/JSX autonomes, l'agent édite la même source que celle du rendu iframe et celle d'où provient chaque exportation : il n'existe pas de format de « maquette IA » distinct à traduire. Un système de conception lié fournit des jetons et `custom_instructions` que l'agent honore à chaque passage de génération. Sélectionnez du texte ou une région dans l'aperçu et appuyez sur Cmd+I pour concentrer l'agent exactement sur cette partie.
350
350
 
351
+ ### Modèle d'éditeur
352
+
353
+ Design privilégie la vue d'ensemble pour le travail multi-écran. Après une
354
+ génération ou une mise à jour large, l'éditeur ouvre la vue d'ensemble des
355
+ écrans : un canevas infini où chaque écran est un cadre statique que vous pouvez
356
+ sélectionner, déplacer, redimensionner, déposer ou dupliquer. Utilisez le bouton de vue complète du cadre lorsqu’un écran nécessite un
357
+ défilement ciblé ou une interaction de prototype.
358
+
359
+ Le mode écran unique sert à faire défiler, interagir avec le comportement du
360
+ prototype et modifier les couches DOM/code dans un fichier rendu. Le panneau des
361
+ couches reflète cette séparation : les écrans sont des cadres de niveau
362
+ supérieur, avec les couches DOM/code imbriquées pour l'écran actif.
363
+
364
+ Pour des noms de couche stables, ajoutez `data-agent-native-layer-name` aux
365
+ éléments importants. Design l'utilise avant les replis sémantiques/textuels et
366
+ peut persister les renommages en modifiant cet attribut. Le HTML inline prend en
367
+ charge les modifications locales de couches de code pour le texte, les classes,
368
+ les styles, les attributs, l'ordre source et les petits changements structurels;
369
+ les modifications visuelles de couches de code sont uniquement HTML aujourd'hui.
370
+ Le mode source localhost peut enregistrer et résoudre des artboards de routes
371
+ locales, mais les lectures/écritures de fichiers locaux restent un contrat de
372
+ pont jusqu'au durcissement des contrôles d'autorisation explicites.
373
+
374
+ ### Extensions de l'éditeur Design
375
+
376
+ L'éditeur inclut un onglet d'inspecteur **Extensions** après **Tweaks**. Il
377
+ fonctionne comme une piste de plugins propre à Design : les utilisateurs peuvent
378
+ cliquer sur **+ Extension** pour demander à l'agent de créer une extension, ou
379
+ installer une extension qui déclare le slot `design.editor.inspector`.
380
+
381
+ Les extensions Design s'affichent en ligne à côté de l'artboard via le bac à
382
+ sable standard des extensions. L'hôte transmet les mises à jour
383
+ `window.slotContext` et `window.onSlotContext(...)` avec le `designId` actuel,
384
+ le fichier actif, la liste des écrans, les ids d'écran sélectionnés, les
385
+ métadonnées de l'élément sélectionné, le mode d'affichage, le zoom, l'outil
386
+ actif et les valeurs de tweaks. Cela permet à une extension d'afficher des
387
+ informations sur la sélection actuelle, d'offrir des contrôles de style ou de
388
+ créer des workflows compacts autour du design ouvert.
389
+
390
+ Pour un travail déterministe, les extensions peuvent appeler les actions de
391
+ l'app via le pont d'extension. Pour les changements pilotés par l'IA,
392
+ l'extension doit appeler `agentNative.chat.send(...)` avec le sélecteur/id source
393
+ de l'élément sélectionné et la modification demandée. L'agent doit d'abord
394
+ appeler `view-screen`, puis utiliser `apply-visual-edit` pour les changements de
395
+ style, classe, texte ou déplacement d'élément, ou `update-design` /
396
+ `generate-design` avec `canvasFrames` pour les changements de placement de
397
+ l'artboard. Consultez [Extensions](/docs/extensions#what-an-extension-can-do)
398
+ pour le bac à sable, l'état persistant et les APIs du pont.
399
+
351
400
  ### Le personnaliser
352
401
 
353
402
  Design est un modèle complet et clonable. Quelques idées d'extension pratiques :