@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,242 @@
1
+ import { IconPhotoPlus, IconX } from "@tabler/icons-react";
2
+ import { useRef, useState } from "react";
3
+
4
+ import { Input } from "@/components/ui/input";
5
+ import {
6
+ Select,
7
+ SelectContent,
8
+ SelectItem,
9
+ SelectTrigger,
10
+ SelectValue,
11
+ } from "@/components/ui/select";
12
+ import {
13
+ Tooltip,
14
+ TooltipContent,
15
+ TooltipTrigger,
16
+ } from "@/components/ui/tooltip";
17
+ import { cn } from "@/lib/utils";
18
+
19
+ // ─── Types ───────────────────────────────────────────────────────────────────
20
+
21
+ export type ImageFitMode = "fill" | "fit" | "crop" | "tile";
22
+
23
+ export interface ImageFillValue {
24
+ url: string;
25
+ fit: ImageFitMode;
26
+ }
27
+
28
+ const FIT_MODES: Array<{ mode: ImageFitMode; label: string }> = [
29
+ { mode: "fill", label: "Fill" }, // i18n-ignore image fit mode
30
+ { mode: "fit", label: "Fit" }, // i18n-ignore image fit mode
31
+ { mode: "crop", label: "Crop" }, // i18n-ignore image fit mode
32
+ { mode: "tile", label: "Tile" }, // i18n-ignore image fit mode
33
+ ];
34
+
35
+ // ─── CSS serialization ─────────────────────────────────────────────────────────
36
+
37
+ const CHECKER_A = "#d4d4d4";
38
+ const CHECKERBOARD_IMAGE = `linear-gradient(45deg, ${CHECKER_A} 25%, transparent 25%), linear-gradient(-45deg, ${CHECKER_A} 25%, transparent 25%), linear-gradient(45deg, transparent 75%, ${CHECKER_A} 75%), linear-gradient(-45deg, transparent 75%, ${CHECKER_A} 75%)`;
39
+ const FIT_MARKER_RE =
40
+ /\/\*\s*agent-native-image-fit:(fill|fit|crop|tile)\s*\*\//i;
41
+
42
+ function imageFitMarker(fit: ImageFitMode): string {
43
+ return `/* agent-native-image-fit:${fit} */`;
44
+ }
45
+
46
+ /**
47
+ * Build the CSS `background` shorthand for an image fill.
48
+ * Maps Figma's fit semantics onto background-size / background-repeat:
49
+ * - Fill → cover, no-repeat
50
+ * - Fit → contain, no-repeat
51
+ * - Crop → cover, no-repeat (cropped to the box; identical CSS to Fill but
52
+ * kept distinct so the selection round-trips)
53
+ * - Tile → auto, repeat
54
+ */
55
+ export function imageFillToCss(value: ImageFillValue): string {
56
+ const url = value.url.trim();
57
+ if (!url) return "transparent";
58
+ const safeUrl = url.replace(/["')]/g, encodeURIComponent);
59
+ const image = `url("${safeUrl}")`;
60
+ switch (value.fit) {
61
+ case "fit":
62
+ return `${image} center / contain no-repeat ${imageFitMarker("fit")}`;
63
+ case "tile":
64
+ return `${image} top left / auto repeat ${imageFitMarker("tile")}`;
65
+ case "crop":
66
+ return `${image} center / cover no-repeat ${imageFitMarker("crop")}`;
67
+ case "fill":
68
+ default:
69
+ return `${image} center / cover no-repeat ${imageFitMarker("fill")}`;
70
+ }
71
+ }
72
+
73
+ const URL_RE = /url\((['"]?)([^'")]+)\1\)/i;
74
+
75
+ /** Extract the URL + fit mode from a CSS background value, if present. */
76
+ export function parseImageFillCss(value: string): ImageFillValue | null {
77
+ const match = value.match(URL_RE);
78
+ if (!match) return null;
79
+ const url = match[2];
80
+ const marker = value.match(FIT_MARKER_RE)?.[1] as ImageFitMode | undefined;
81
+ if (marker) return { url, fit: marker };
82
+ let fit: ImageFitMode = "fill";
83
+ if (/contain/i.test(value)) fit = "fit";
84
+ else if (/repeat(?!\s+no)/i.test(value) && !/no-repeat/i.test(value))
85
+ fit = "tile";
86
+ else if (/cover/i.test(value)) fit = "fill";
87
+ return { url, fit };
88
+ }
89
+
90
+ // ─── Component ─────────────────────────────────────────────────────────────────
91
+
92
+ export interface ImageFillControlsProps {
93
+ value: ImageFillValue;
94
+ onChange: (value: ImageFillValue) => void;
95
+ disabled?: boolean;
96
+ className?: string;
97
+ }
98
+
99
+ export function ImageFillControls({
100
+ value,
101
+ onChange,
102
+ disabled = false,
103
+ className,
104
+ }: ImageFillControlsProps) {
105
+ const fileInputRef = useRef<HTMLInputElement>(null);
106
+ const [urlDraft, setUrlDraft] = useState(value.url);
107
+
108
+ const commitUrl = () => {
109
+ onChange({ ...value, url: urlDraft.trim() });
110
+ };
111
+
112
+ const handleFilePick = (event: React.ChangeEvent<HTMLInputElement>) => {
113
+ const file = event.target.files?.[0];
114
+ if (!file) return;
115
+ const reader = new FileReader();
116
+ reader.onload = () => {
117
+ const dataUrl = typeof reader.result === "string" ? reader.result : "";
118
+ if (dataUrl) {
119
+ setUrlDraft(dataUrl);
120
+ onChange({ ...value, url: dataUrl });
121
+ }
122
+ };
123
+ reader.readAsDataURL(file);
124
+ // Allow re-selecting the same file later.
125
+ event.target.value = "";
126
+ };
127
+
128
+ return (
129
+ <div className={cn("space-y-1.5 px-3 pt-2 pb-2", className)}>
130
+ {/* ── Preview / drop target ─────────────────────────────────────────── */}
131
+ <div
132
+ className="relative h-24 w-full overflow-hidden rounded-md border border-border/60"
133
+ style={{
134
+ backgroundImage: value.url
135
+ ? `url("${value.url}")`
136
+ : CHECKERBOARD_IMAGE,
137
+ backgroundSize: value.url
138
+ ? value.fit === "fit"
139
+ ? "contain"
140
+ : value.fit === "tile"
141
+ ? "auto"
142
+ : "cover"
143
+ : "8px 8px, 8px 8px, 8px 8px, 8px 8px",
144
+ backgroundRepeat: value.fit === "tile" ? "repeat" : "no-repeat",
145
+ backgroundPosition: "center",
146
+ }}
147
+ >
148
+ {!value.url && (
149
+ <div className="absolute inset-0 flex flex-col items-center justify-center gap-1 text-muted-foreground">
150
+ <IconPhotoPlus className="size-5" />
151
+ <span className="text-[10px]">
152
+ {"Upload or paste a URL" /* i18n-ignore */}
153
+ </span>
154
+ </div>
155
+ )}
156
+ {value.url && (
157
+ <Tooltip>
158
+ <TooltipTrigger asChild>
159
+ <button
160
+ type="button"
161
+ aria-label={"Remove image" /* i18n-ignore */}
162
+ disabled={disabled}
163
+ onClick={() => {
164
+ setUrlDraft("");
165
+ onChange({ ...value, url: "" });
166
+ }}
167
+ className="absolute right-1 top-1 flex size-5 items-center justify-center rounded bg-black/50 text-white hover:bg-black/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
168
+ >
169
+ <IconX className="size-3" />
170
+ </button>
171
+ </TooltipTrigger>
172
+ <TooltipContent>{"Remove image" /* i18n-ignore */}</TooltipContent>
173
+ </Tooltip>
174
+ )}
175
+ </div>
176
+
177
+ {/* ── URL input + upload ────────────────────────────────────────────── */}
178
+ <div className="flex items-center gap-1">
179
+ <Input
180
+ value={urlDraft}
181
+ disabled={disabled}
182
+ placeholder={"Image URL" /* i18n-ignore */}
183
+ aria-label={"Image URL" /* i18n-ignore */}
184
+ spellCheck={false}
185
+ className="h-6 min-w-0 flex-1 rounded-md border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] px-2 text-[11px]"
186
+ onChange={(event) => setUrlDraft(event.target.value)}
187
+ onBlur={commitUrl}
188
+ onKeyDown={(event) => {
189
+ if (event.key === "Enter") {
190
+ event.preventDefault();
191
+ commitUrl();
192
+ event.currentTarget.blur();
193
+ }
194
+ }}
195
+ />
196
+ <Tooltip>
197
+ <TooltipTrigger asChild>
198
+ <button
199
+ type="button"
200
+ disabled={disabled}
201
+ aria-label={"Upload image" /* i18n-ignore */}
202
+ onClick={() => fileInputRef.current?.click()}
203
+ className={cn(
204
+ "flex size-6 shrink-0 items-center justify-center rounded-md border border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] text-muted-foreground hover:text-foreground",
205
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
206
+ disabled && "pointer-events-none opacity-40",
207
+ )}
208
+ >
209
+ <IconPhotoPlus className="size-3.5" />
210
+ </button>
211
+ </TooltipTrigger>
212
+ <TooltipContent>{"Upload image" /* i18n-ignore */}</TooltipContent>
213
+ </Tooltip>
214
+ <input
215
+ ref={fileInputRef}
216
+ type="file"
217
+ accept="image/*"
218
+ className="hidden"
219
+ onChange={handleFilePick}
220
+ />
221
+ </div>
222
+
223
+ {/* ── Fit mode dropdown ─────────────────────────────────────────────── */}
224
+ <Select
225
+ value={value.fit}
226
+ onValueChange={(v) => onChange({ ...value, fit: v as ImageFitMode })}
227
+ disabled={disabled}
228
+ >
229
+ <SelectTrigger className="h-6 w-full rounded-md border border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] px-2 text-[11px] shadow-none focus:ring-0 focus:ring-offset-0 focus-visible:ring-2 focus-visible:ring-ring [&>svg]:size-3 [&>svg]:shrink-0">
230
+ <SelectValue />
231
+ </SelectTrigger>
232
+ <SelectContent className="text-[11px]">
233
+ {FIT_MODES.map(({ mode, label }) => (
234
+ <SelectItem key={mode} value={mode} className="text-[11px]">
235
+ {label}
236
+ </SelectItem>
237
+ ))}
238
+ </SelectContent>
239
+ </Select>
240
+ </div>
241
+ );
242
+ }
@@ -0,0 +1,420 @@
1
+ # Shader Feature Integration Guide
2
+
3
+ This guide covers the five seam files that need edits to wire the GPU shader feature
4
+ into the design template. Each section gives the exact search string to locate the
5
+ right spot plus copy-pasteable code to insert or replace.
6
+
7
+ Do NOT rely on line numbers — they drift. Use the search strings instead.
8
+
9
+ ---
10
+
11
+ ## (a) FigmaColorPicker.tsx — Add `"shader"` fill type
12
+
13
+ **File:** `app/components/design/inspector/FigmaColorPicker.tsx`
14
+
15
+ ### 1. Extend `FigmaFillType`
16
+
17
+ Search for:
18
+
19
+ ```ts
20
+ export type FigmaFillType = "solid" | "gradient" | "image";
21
+ ```
22
+
23
+ Replace with:
24
+
25
+ ```ts
26
+ export type FigmaFillType = "solid" | "gradient" | "image" | "shader";
27
+ ```
28
+
29
+ ### 2. Extend `FigmaPaintType`
30
+
31
+ Search for:
32
+
33
+ ```ts
34
+ export type FigmaPaintType =
35
+ | "solid"
36
+ | "linear"
37
+ | "radial"
38
+ | "angular"
39
+ | "diamond"
40
+ | "none";
41
+ ```
42
+
43
+ Replace with:
44
+
45
+ ```ts
46
+ export type FigmaPaintType =
47
+ | "solid"
48
+ | "linear"
49
+ | "radial"
50
+ | "angular"
51
+ | "diamond"
52
+ | "none"
53
+ | "shader";
54
+ ```
55
+
56
+ ### 3. Add `canUseShaders` prop to `FigmaColorPickerProps`
57
+
58
+ Search for:
59
+
60
+ ```ts
61
+ canUseGradients?: boolean
62
+ ```
63
+
64
+ After that line, add:
65
+
66
+ ```ts
67
+ canUseShaders?: boolean
68
+ ```
69
+
70
+ ### 4. Add shader button to the paint-type button row
71
+
72
+ Search for:
73
+
74
+ ```tsx
75
+ {canUseGradients && (
76
+ ```
77
+
78
+ After the closing `)}` of that block, add:
79
+
80
+ ```tsx
81
+ {
82
+ canUseShaders && (
83
+ <button
84
+ type="button"
85
+ className={cn(
86
+ "flex h-6 w-6 items-center justify-center rounded transition-colors",
87
+ paintType === "shader"
88
+ ? "bg-white/20 text-white"
89
+ : "text-white/50 hover:text-white",
90
+ )}
91
+ onClick={() => onPaintTypeChange?.("shader")}
92
+ title="Shader"
93
+ >
94
+ <IconSparkles size={14} />
95
+ </button>
96
+ );
97
+ }
98
+ ```
99
+
100
+ Add the import at the top of the file alongside the existing Tabler icon imports:
101
+
102
+ ```ts
103
+ import { IconSparkles } from "@tabler/icons-react";
104
+ ```
105
+
106
+ ### 5. Render `ShaderControls` when `paintType === "shader"`
107
+
108
+ Search for the block that renders gradient or color controls based on `paintType`.
109
+ It will look something like:
110
+
111
+ ```tsx
112
+ {paintType === "gradient" ? (
113
+ // gradient controls
114
+ ) : (
115
+ // solid color controls
116
+ )}
117
+ ```
118
+
119
+ Extend it to a three-way branch:
120
+
121
+ ```tsx
122
+ {paintType === "shader" ? (
123
+ <ShaderControls
124
+ descriptor={
125
+ (() => {
126
+ try {
127
+ return JSON.parse(value ?? "{}");
128
+ } catch {
129
+ return { preset: "MeshGradient", params: {}, colors: [], speed: 1, frame: 0, fit: "contain" };
130
+ }
131
+ })()
132
+ }
133
+ onChange={(descriptor) => {
134
+ onValueChange?.(JSON.stringify(descriptor));
135
+ }}
136
+ />
137
+ ) : paintType === "gradient" ? (
138
+ // existing gradient controls
139
+ ) : (
140
+ // existing solid color controls
141
+ )}
142
+ ```
143
+
144
+ Add the import near the other local inspector imports:
145
+
146
+ ```ts
147
+ import { ShaderControls } from "./ShaderControls";
148
+ ```
149
+
150
+ The fill row's `value` field holds the serialized `ShaderDescriptor` JSON when
151
+ `type === "shader"`. No schema change is needed — it reuses the existing `value: string`
152
+ slot.
153
+
154
+ ---
155
+
156
+ ## (b) EditPanel.tsx — Add `ShaderEffectRow` to `EffectsProperties`
157
+
158
+ **File:** `app/components/design/inspector/EditPanel.tsx`
159
+
160
+ ### 1. Add imports
161
+
162
+ Search for the block that imports `ShadowEffectRow` (or the effects-related imports).
163
+ Add alongside those:
164
+
165
+ ```ts
166
+ import { ShaderEffectRow } from "./inspector/ShaderEffectRow";
167
+ import type { ShaderDescriptor } from "../../shared/shader-presets";
168
+ ```
169
+
170
+ If `EditPanel.tsx` is itself inside the `inspector/` folder, drop the `inspector/` prefix:
171
+
172
+ ```ts
173
+ import { ShaderEffectRow } from "./ShaderEffectRow";
174
+ ```
175
+
176
+ ### 2. Extend `EffectsProperties` props
177
+
178
+ Search for the `EffectsProperties` function signature. It will include props like
179
+ `shadowLayers` and `blurLayers`. Add:
180
+
181
+ ```ts
182
+ shaderLayers?: ShaderDescriptor[];
183
+ onShaderLayersChange?: (layers: ShaderDescriptor[]) => void;
184
+ ```
185
+
186
+ ### 3. Render shader effect rows
187
+
188
+ Search for:
189
+
190
+ ```tsx
191
+ {shadowLayers.map(
192
+ ```
193
+
194
+ After the `shadowLayers.map(...)` block and the `blurLayers.map(...)` block
195
+ (whichever comes last), add:
196
+
197
+ ```tsx
198
+ {
199
+ (shaderLayers ?? []).map((layer, i) => (
200
+ <ShaderEffectRow
201
+ key={layer.id ?? i}
202
+ descriptor={layer}
203
+ onChange={(updated) => {
204
+ const next = [...(shaderLayers ?? [])];
205
+ next[i] = updated;
206
+ onShaderLayersChange?.(next);
207
+ }}
208
+ onRemove={() => {
209
+ const next = (shaderLayers ?? []).filter((_, j) => j !== i);
210
+ onShaderLayersChange?.(next);
211
+ }}
212
+ />
213
+ ));
214
+ }
215
+ ```
216
+
217
+ ### 4. Add "Add Shader" option to the effects dropdown
218
+
219
+ Search for the "Add effect" button or the dropdown that lets users add shadow/blur.
220
+ It will contain strings like `"Drop Shadow"` or `"Add Shadow"`. Add a shader option:
221
+
222
+ ```tsx
223
+ <DropdownMenuItem
224
+ onSelect={() => {
225
+ onShaderLayersChange?.([
226
+ ...(shaderLayers ?? []),
227
+ {
228
+ preset: "MeshGradient",
229
+ params: { distortion: 0.8, swirl: 0.1 },
230
+ colors: ["#e0eaff", "#241d9a", "#f75092", "#9f50d3"],
231
+ speed: 1,
232
+ frame: 0,
233
+ fit: "contain",
234
+ },
235
+ ]);
236
+ }}
237
+ >
238
+ Shader
239
+ </DropdownMenuItem>
240
+ ```
241
+
242
+ ---
243
+
244
+ ## (c) Register apply-shader and get-shader actions
245
+
246
+ No registration step is required. The actions directory is auto-discovered by the
247
+ framework at startup. Confirm both files exist:
248
+
249
+ ```
250
+ templates/design/actions/apply-shader.ts ✓
251
+ templates/design/actions/get-shader.ts ✓
252
+ ```
253
+
254
+ If either is missing, the agent won't have access to shader tools. The `defineAction`
255
+ export at the top of each file is all that's needed for automatic discovery.
256
+
257
+ ---
258
+
259
+ ## (d) DesignCanvas.tsx — Alpine/inline artboard shader bridge
260
+
261
+ **File:** `app/components/design/canvas/DesignCanvas.tsx` (or similar canvas file)
262
+
263
+ ### 1. Locate the bridge scripts injection point
264
+
265
+ Search for:
266
+
267
+ ```
268
+ // === BRIDGE SCRIPTS ===
269
+ ```
270
+
271
+ Or search for the injected HTML string that wires up the Alpine bridge. It will
272
+ contain `<script` tags being concatenated into a string that gets injected into the
273
+ artboard iframe.
274
+
275
+ ### 2. Add the shader mount script
276
+
277
+ Append the following after the existing bridge scripts (inside the same injected
278
+ content string):
279
+
280
+ ```js
281
+ const shaderBridgeScript = `
282
+ <script type="module">
283
+ import { ShaderMount } from 'https://esm.sh/@paper-design/shaders@0.0.76/dist/index.js';
284
+
285
+ function mountShaders() {
286
+ document.querySelectorAll('[data-shader]').forEach(el => {
287
+ if (el.__shaderMounted) return;
288
+ el.__shaderMounted = true;
289
+ try {
290
+ const descriptor = JSON.parse(el.getAttribute('data-shader') || '{}');
291
+ if (!descriptor.preset) return;
292
+ const canvas = document.createElement('canvas');
293
+ canvas.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;pointer-events:none;';
294
+ el.style.position = 'relative';
295
+ el.prepend(canvas);
296
+ // ShaderMount takes { canvas, preset, uniforms } — map descriptor.params to uniforms:
297
+ new ShaderMount({
298
+ canvas,
299
+ preset: descriptor.preset,
300
+ uniforms: {
301
+ ...(descriptor.params ?? {}),
302
+ colors: descriptor.colors ?? [],
303
+ speed: descriptor.speed ?? 1,
304
+ },
305
+ });
306
+ console.log('[shader bridge] mounted', descriptor.preset, 'on', el);
307
+ } catch (e) {
308
+ console.warn('[shader bridge] mount failed:', e);
309
+ }
310
+ });
311
+ }
312
+
313
+ document.addEventListener('DOMContentLoaded', mountShaders);
314
+ // Re-run on mutations (new elements added dynamically):
315
+ new MutationObserver(mountShaders).observe(document.body, { childList: true, subtree: true });
316
+ <\/script>
317
+ `;
318
+ ```
319
+
320
+ Concatenate `shaderBridgeScript` into the injected HTML alongside the other bridge
321
+ scripts. The exact concatenation point depends on how the existing bridge is assembled
322
+ — look for where the other `<script>` strings are joined.
323
+
324
+ ### 3. Add vanilla shaders package dependency
325
+
326
+ The bridge imports from `esm.sh` at runtime, so no local dep is strictly required
327
+ for the iframe bridge. However, if you want type-safe access in the canvas component
328
+ itself, add:
329
+
330
+ ```bash
331
+ pnpm add @paper-design/shaders
332
+ ```
333
+
334
+ in the `templates/design/` directory. The package provides both the React components
335
+ (already used via `@paper-design/shaders-react`) and the vanilla `ShaderMount` class.
336
+
337
+ ### 4. Ensure artboard elements carry `data-shader`
338
+
339
+ When the canvas renders an element whose fill type is `"shader"`, it must serialize
340
+ the `ShaderDescriptor` onto the DOM element as `data-shader`. Search for the artboard
341
+ render path (likely a function that serializes fills to inline styles or HTML
342
+ attributes) and add:
343
+
344
+ ```ts
345
+ if (fill.type === "shader") {
346
+ attrs["data-shader"] = JSON.stringify(fill.descriptor);
347
+ // Optionally set a placeholder background so the element is visible before mount:
348
+ styles["background"] = fill.descriptor.colors?.[0] ?? "transparent";
349
+ }
350
+ ```
351
+
352
+ ---
353
+
354
+ ## (e) Changelog entry (DEFERRED)
355
+
356
+ The shader feature is not yet user-reachable — it still needs all seam files wired.
357
+ Do NOT add a changelog entry yet.
358
+
359
+ Once the seam files are integrated and the feature is accessible from the UI (a user
360
+ can apply a shader fill from the fill picker or add a shader effect from the effects
361
+ panel), run:
362
+
363
+ ```bash
364
+ agent-native changelog add "Add GPU shader fills and effects — 8 presets (MeshGradient, GrainGradient, Voronoi, Metaballs, Warp, GodRays, Dithering, PaperTexture) with live preview and agent-tunable params" --type added
365
+ ```
366
+
367
+ from the `templates/design/` directory.
368
+
369
+ ---
370
+
371
+ ## (f) Design-system token shape (for Phase 6)
372
+
373
+ The design system `data` blob (returned by the `get-design-system` action) can be
374
+ extended to store shader tokens without any migration — `data` is already an untyped
375
+ JSON blob.
376
+
377
+ Search for `update-design-system.ts` and locate the `DesignSystemData` interface (or
378
+ wherever the `data` field is typed). Add:
379
+
380
+ ```ts
381
+ interface DesignSystemData {
382
+ // ... existing fields (colors, typography, spacing, etc.) ...
383
+ tokens?: {
384
+ shaders?: Array<{
385
+ id: string;
386
+ name: string;
387
+ descriptor: ShaderDescriptor;
388
+ }>;
389
+ };
390
+ }
391
+ ```
392
+
393
+ Import `ShaderDescriptor` from:
394
+
395
+ ```ts
396
+ import type { ShaderDescriptor } from "../shared/shader-presets";
397
+ ```
398
+
399
+ (Adjust the relative path based on where `update-design-system.ts` lives relative to
400
+ the `shared/` folder — typically `../../shared/shader-presets` from inside `actions/`.)
401
+
402
+ This shape lets the agent call `update-design-system` to persist named shader presets
403
+ as reusable design tokens, and `get-design-system` to retrieve them for display in a
404
+ shader token picker.
405
+
406
+ ---
407
+
408
+ ## Integration Checklist
409
+
410
+ - [ ] `FigmaColorPicker.tsx` — `FigmaFillType` includes `"shader"`
411
+ - [ ] `FigmaColorPicker.tsx` — `FigmaPaintType` includes `"shader"`
412
+ - [ ] `FigmaColorPicker.tsx` — shader button renders in paint-type row
413
+ - [ ] `FigmaColorPicker.tsx` — `ShaderControls` renders when `paintType === "shader"`
414
+ - [ ] `EditPanel.tsx` — `ShaderEffectRow` renders in `EffectsProperties`
415
+ - [ ] `EditPanel.tsx` — "Add Shader" option in effects dropdown
416
+ - [ ] `actions/apply-shader.ts` exists
417
+ - [ ] `actions/get-shader.ts` exists
418
+ - [ ] `DesignCanvas.tsx` — shader bridge script injected into artboard
419
+ - [ ] `DesignCanvas.tsx` — `data-shader` attribute serialized for shader fills
420
+ - [ ] Changelog entry added (after feature is user-reachable)