@agent-native/core 0.92.10 → 0.92.11

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 (334) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +23 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/agent/production-agent.ts +181 -15
  5. package/corpus/core/src/agent/run-manager.ts +31 -4
  6. package/corpus/core/src/agent/run-store.ts +80 -0
  7. package/corpus/core/src/cli/design-connect.ts +433 -151
  8. package/corpus/core/src/cli/skills.ts +14 -0
  9. package/corpus/core/src/client/AssistantChat.tsx +25 -0
  10. package/corpus/core/src/client/MultiTabAssistantChat.tsx +40 -6
  11. package/corpus/core/src/client/agent-chat.ts +165 -1
  12. package/corpus/core/src/client/chat/index.ts +9 -1
  13. package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +38 -2
  14. package/corpus/core/src/client/index.ts +5 -0
  15. package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +18 -7
  16. package/corpus/core/src/collab/awareness-store.ts +23 -12
  17. package/corpus/core/src/collab/client.ts +16 -5
  18. package/corpus/core/src/collab/index.ts +4 -0
  19. package/corpus/core/src/collab/recent-edits.ts +65 -2
  20. package/corpus/core/src/index.browser.ts +1 -0
  21. package/corpus/core/src/server/agent-chat-plugin.ts +98 -11
  22. package/corpus/core/src/server/builder-design-systems.ts +30 -4
  23. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +1 -1
  24. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +12 -6
  25. package/corpus/templates/clips/AGENTS.md +4 -0
  26. package/corpus/templates/clips/actions/create-recording.ts +2 -0
  27. package/corpus/templates/clips/actions/lib/create-recording-schema.ts +5 -3
  28. package/corpus/templates/clips/actions/request-transcript.ts +102 -33
  29. package/corpus/templates/clips/app/components/library/library-grid.tsx +1 -0
  30. package/corpus/templates/clips/app/components/player/share-dialog.tsx +59 -19
  31. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +48 -4
  32. package/corpus/templates/clips/app/components/player/video-player.tsx +17 -12
  33. package/corpus/templates/clips/app/i18n/ar-SA.ts +1 -0
  34. package/corpus/templates/clips/app/i18n/de-DE.ts +1 -0
  35. package/corpus/templates/clips/app/i18n/en-US.ts +1 -0
  36. package/corpus/templates/clips/app/i18n/es-ES.ts +1 -0
  37. package/corpus/templates/clips/app/i18n/fr-FR.ts +1 -0
  38. package/corpus/templates/clips/app/i18n/hi-IN.ts +1 -0
  39. package/corpus/templates/clips/app/i18n/ja-JP.ts +1 -0
  40. package/corpus/templates/clips/app/i18n/ko-KR.ts +1 -0
  41. package/corpus/templates/clips/app/i18n/pt-BR.ts +1 -0
  42. package/corpus/templates/clips/app/i18n/zh-CN.ts +1 -0
  43. package/corpus/templates/clips/app/i18n/zh-TW.ts +1 -0
  44. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +70 -37
  45. package/corpus/templates/clips/app/routes/record.tsx +17 -4
  46. package/corpus/templates/clips/app/routes/share.$shareId.tsx +2 -0
  47. package/corpus/templates/clips/changelog/2026-07-09-desktop-popover-sits-closer-to-the-menu-bar.md +6 -0
  48. package/corpus/templates/clips/changelog/2026-07-09-desktop-recording-optimization-progress-stays-visible-until-the-clip-opens.md +6 -0
  49. package/corpus/templates/clips/changelog/2026-07-09-fixed-large-video-file-uploads-failing-before-their-resumabl.md +6 -0
  50. package/corpus/templates/clips/changelog/2026-07-09-fixed-new-video-uploads-defaulting-to-private.md +6 -0
  51. package/corpus/templates/clips/changelog/2026-07-09-long-recordings-now-get-enough-time-to-download-their-media-.md +6 -0
  52. package/corpus/templates/clips/changelog/2026-07-09-meeting-notes-no-longer-lowers-your-microphone-volume-for-ot.md +6 -0
  53. package/corpus/templates/clips/changelog/2026-07-09-on-mobile-tapping-a-playing-clip-reveals-playback-controls-w.md +6 -0
  54. package/corpus/templates/clips/changelog/2026-07-09-regenerate-any-clip-transcript-from-its-saved-recording-or-r.md +6 -0
  55. package/corpus/templates/clips/changelog/2026-07-09-slack-previews-now-show-the-clip-length-alongside-its-descri.md +6 -0
  56. package/corpus/templates/clips/desktop/src/app.tsx +12 -2
  57. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +8 -1
  58. package/corpus/templates/clips/desktop/src/lib/recorder.ts +8 -5
  59. package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +5 -5
  60. package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +3 -0
  61. package/corpus/templates/clips/desktop/src/styles.css +6 -3
  62. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +29 -11
  63. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +1 -1
  64. package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +103 -21
  65. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +117 -39
  66. package/corpus/templates/clips/server/lib/slack-unfurls.ts +20 -1
  67. package/corpus/templates/clips/server/lib/streaming-upload-mode.ts +10 -4
  68. package/corpus/templates/clips/shared/recording-core.ts +12 -0
  69. package/corpus/templates/content/AGENTS.md +7 -6
  70. package/corpus/templates/content/actions/_document-flush.ts +132 -17
  71. package/corpus/templates/content/actions/_notion-action-utils.ts +15 -0
  72. package/corpus/templates/content/actions/create-and-link-notion-page.ts +2 -0
  73. package/corpus/templates/content/actions/link-notion-page.ts +2 -0
  74. package/corpus/templates/content/actions/pull-document.ts +5 -7
  75. package/corpus/templates/content/actions/pull-notion-page.ts +2 -0
  76. package/corpus/templates/content/actions/push-notion-page.ts +10 -0
  77. package/corpus/templates/content/actions/resolve-notion-sync-conflict.ts +2 -0
  78. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +88 -23
  79. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +32 -2
  80. package/corpus/templates/content/app/hooks/use-notion.ts +6 -6
  81. package/corpus/templates/content/app/i18n/zh-TW.ts +1 -0
  82. package/corpus/templates/content/app/i18n-data.ts +18 -0
  83. package/corpus/templates/content/changelog/2026-07-09-notion-conflict-choices-and-version-restores-preserve-docume.md +6 -0
  84. package/corpus/templates/content/server/lib/notion-sync.ts +80 -64
  85. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +29 -2
  86. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +86 -0
  87. package/corpus/templates/design/.agents/skills/export-handoff/SKILL.md +57 -0
  88. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +11 -0
  89. package/corpus/templates/design/AGENTS.md +45 -10
  90. package/corpus/templates/design/actions/add-localhost-screens.ts +66 -13
  91. package/corpus/templates/design/actions/apply-component-prop-edit.ts +45 -36
  92. package/corpus/templates/design/actions/apply-motion-edit.ts +25 -31
  93. package/corpus/templates/design/actions/apply-shader-fill.ts +29 -42
  94. package/corpus/templates/design/actions/detach-component-instance.ts +337 -0
  95. package/corpus/templates/design/actions/export-design-as-figma-svg.ts +219 -0
  96. package/corpus/templates/design/actions/generate-design.ts +79 -12
  97. package/corpus/templates/design/actions/generate-screens.ts +57 -12
  98. package/corpus/templates/design/actions/get-figma-styles.ts +115 -0
  99. package/corpus/templates/design/actions/go-to-main-component.ts +254 -0
  100. package/corpus/templates/design/actions/grant-localhost-write-consent.ts +4 -3
  101. package/corpus/templates/design/actions/import-design-source.ts +4 -31
  102. package/corpus/templates/design/actions/import-figma-clipboard.ts +134 -0
  103. package/corpus/templates/design/actions/import-figma-frame.ts +95 -0
  104. package/corpus/templates/design/actions/index-design-system-with-builder.ts +16 -1
  105. package/corpus/templates/design/actions/list-design-components.ts +104 -0
  106. package/corpus/templates/design/actions/list-figma-library-assets.ts +1 -24
  107. package/corpus/templates/design/actions/open-component-source.ts +2 -4
  108. package/corpus/templates/design/actions/present-design-variants.ts +412 -16
  109. package/corpus/templates/design/actions/preview-source-edit.ts +14 -1
  110. package/corpus/templates/design/actions/run-design-audit.ts +25 -3
  111. package/corpus/templates/design/actions/show-design-questions.ts +10 -0
  112. package/corpus/templates/design/actions/swap-component-instance.ts +544 -0
  113. package/corpus/templates/design/actions/take-design-screenshot.ts +45 -60
  114. package/corpus/templates/design/actions/write-local-file.ts +25 -1
  115. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +152 -0
  116. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +1077 -58
  117. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +5 -5
  118. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +73 -21
  119. package/corpus/templates/design/app/components/design/EditPanel.tsx +16 -11
  120. package/corpus/templates/design/app/components/design/KeyboardShortcutsPanel.tsx +364 -0
  121. package/corpus/templates/design/app/components/design/LayersPanel.tsx +180 -53
  122. package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +0 -2
  123. package/corpus/templates/design/app/components/design/MotionDock.tsx +144 -21
  124. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1152 -167
  125. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +27 -5
  126. package/corpus/templates/design/app/components/design/ReviewPanel.tsx +23 -2
  127. package/corpus/templates/design/app/components/design/TokensPanel.tsx +63 -49
  128. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1293 -54
  129. package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +7 -0
  130. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +6 -1
  131. package/corpus/templates/design/app/components/design/bridge/motion-preview.bridge.ts +23 -6
  132. package/corpus/templates/design/app/components/design/bridge/sample.bridge.ts +7 -0
  133. package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +5 -0
  134. package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +14 -2
  135. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +37 -2
  136. package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open-guard.ts +25 -0
  137. package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open.ts +19 -1
  138. package/corpus/templates/design/app/components/design/code-workbench/model-registry.ts +43 -5
  139. package/corpus/templates/design/app/components/design/code-workbench/search/SearchView.tsx +27 -2
  140. package/corpus/templates/design/app/components/design/code-workbench/search/search-engine.ts +10 -1
  141. package/corpus/templates/design/app/components/design/code-workbench/store.tsx +19 -2
  142. package/corpus/templates/design/app/components/design/design-canvas/annotation-snapshot.ts +265 -0
  143. package/corpus/templates/design/app/components/design/design-canvas/annotation-submit.ts +16 -5
  144. package/corpus/templates/design/app/components/design/design-canvas/coordinate-transforms.ts +16 -2
  145. package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +7 -2
  146. package/corpus/templates/design/app/components/design/design-canvas/iframe-events.ts +3 -1
  147. package/corpus/templates/design/app/components/design/edit-panel/code-inspect-helpers.tsx +78 -8
  148. package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +451 -73
  149. package/corpus/templates/design/app/components/design/edit-panel/document-colors.ts +12 -4
  150. package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +398 -272
  151. package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +41 -7
  152. package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +16 -3
  153. package/corpus/templates/design/app/components/design/edit-panel/field-primitives.tsx +24 -4
  154. package/corpus/templates/design/app/components/design/edit-panel/fill-gradient-helpers.ts +222 -4
  155. package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +171 -78
  156. package/corpus/templates/design/app/components/design/edit-panel/inspector-controls.tsx +45 -5
  157. package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +299 -28
  158. package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +120 -150
  159. package/corpus/templates/design/app/components/design/edit-panel/position-helpers.ts +53 -1
  160. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +284 -117
  161. package/corpus/templates/design/app/components/design/edit-panel/selection-helpers.ts +81 -0
  162. package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +19 -14
  163. package/corpus/templates/design/app/components/design/edit-panel/style-options.ts +7 -0
  164. package/corpus/templates/design/app/components/design/edit-panel/typography-helpers.ts +155 -0
  165. package/corpus/templates/design/app/components/design/edit-panel/typography-properties.tsx +268 -46
  166. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +350 -31
  167. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +13 -4
  168. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +233 -23
  169. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +72 -2
  170. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +51 -11
  171. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +84 -11
  172. package/corpus/templates/design/app/components/design/inspector/index.ts +3 -0
  173. package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +552 -0
  174. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +157 -0
  175. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +53 -0
  176. package/corpus/templates/design/app/components/design/multi-screen/overview-layout.ts +184 -0
  177. package/corpus/templates/design/app/components/design/multi-screen/primitive-drop-target.ts +403 -26
  178. package/corpus/templates/design/app/components/design/multi-screen/types.ts +20 -1
  179. package/corpus/templates/design/app/components/design/types.ts +33 -0
  180. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +59 -7
  181. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +119 -17
  182. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +275 -63
  183. package/corpus/templates/design/app/hooks/use-question-flow.ts +14 -3
  184. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +67 -10
  185. package/corpus/templates/design/app/i18n/zh-TW.ts +91 -1
  186. package/corpus/templates/design/app/i18n-data.ts +1217 -10
  187. package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +577 -0
  188. package/corpus/templates/design/app/lib/agent-chat.ts +23 -0
  189. package/corpus/templates/design/app/lib/design-import.ts +24 -0
  190. package/corpus/templates/design/app/lib/figma-clipboard.ts +157 -0
  191. package/corpus/templates/design/app/lib/figma-svg-copy.ts +221 -0
  192. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +143 -30
  193. package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +15 -0
  194. package/corpus/templates/design/app/pages/design-editor/editor-session.ts +33 -0
  195. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +38 -0
  196. package/corpus/templates/design/app/pages/design-editor/overview-annotation-context.ts +157 -0
  197. package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +62 -6
  198. package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +245 -0
  199. package/corpus/templates/design/app/pages/design-editor/react-semantic-handoff.ts +586 -0
  200. package/corpus/templates/design/app/pages/design-editor/screen-auto-layout.ts +169 -0
  201. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +201 -1
  202. package/corpus/templates/design/changelog/2026-07-09-added-underline-strikethrough-and-text-case-uppercase-lowerc.md +6 -0
  203. package/corpus/templates/design/changelog/2026-07-09-annotate-now-draws-across-the-all-screens-canvas-without-swi.md +6 -0
  204. package/corpus/templates/design/changelog/2026-07-09-auto-layout-children-can-now-be-dragged-into-freeform-screen.md +6 -0
  205. package/corpus/templates/design/changelog/2026-07-09-board-shapes-now-stay-visible-and-nest-correctly-across-the-.md +6 -0
  206. package/corpus/templates/design/changelog/2026-07-09-component-source-navigation-now-opens-reliably-from-the-insp.md +6 -0
  207. package/corpus/templates/design/changelog/2026-07-09-cross-screen-local-react-layer-moves-now-hand-off-exact-sour.md +6 -0
  208. package/corpus/templates/design/changelog/2026-07-09-cross-screen-moves-undo-and-redo-now-keep-both-screens-stabl.md +6 -0
  209. package/corpus/templates/design/changelog/2026-07-09-detach-a-component-instance-into-plain-editable-eleme.md +6 -0
  210. package/corpus/templates/design/changelog/2026-07-09-dragging-layers-into-auto-layout-now-respects-ignore-auto-la.md +6 -0
  211. package/corpus/templates/design/changelog/2026-07-09-drawing-annotations-sent-to-the-agent-now-include-a-rendered.md +6 -0
  212. package/corpus/templates/design/changelog/2026-07-09-editor-sidebars-now-use-figma-matched-default-widths-for-a-r.md +6 -0
  213. package/corpus/templates/design/changelog/2026-07-09-empty-frames-and-rectangles-now-expose-full-auto-layout-cont.md +6 -0
  214. package/corpus/templates/design/changelog/2026-07-09-export-any-design-screen-as-a-real-vector-svg-for-figma-with.md +6 -0
  215. package/corpus/templates/design/changelog/2026-07-09-grid-auto-layout-now-uses-true-responsive-rows-and-columns-w.md +6 -0
  216. package/corpus/templates/design/changelog/2026-07-09-hidden-and-locked-screens-now-behave-consistently-between-la.md +6 -0
  217. package/corpus/templates/design/changelog/2026-07-09-image-fills-now-preserve-valid-urls-and-layered-fit-settings.md +6 -0
  218. package/corpus/templates/design/changelog/2026-07-09-import-figma-frames-as-pixel-accurate-design-screens-via-a-s.md +6 -0
  219. package/corpus/templates/design/changelog/2026-07-09-inspect-code-now-hides-internal-styling-metadata-and-wraps-l.md +6 -0
  220. package/corpus/templates/design/changelog/2026-07-09-inspector-blur-and-shadow-effects-now-preserve-other-effects.md +6 -0
  221. package/corpus/templates/design/changelog/2026-07-09-jump-to-a-components-other-instances-from-the-inspecto.md +6 -0
  222. package/corpus/templates/design/changelog/2026-07-09-keyboard-shortcuts-are-now-discoverable-in-a-figma-style-bot.md +6 -0
  223. package/corpus/templates/design/changelog/2026-07-09-layer-selection-now-keeps-cmd-or-ctrl-toggles-and-shift-rang.md +6 -0
  224. package/corpus/templates/design/changelog/2026-07-09-layers-dropped-into-auto-layout-now-participate-correctly-in.md +6 -0
  225. package/corpus/templates/design/changelog/2026-07-09-local-live-edit-screens-now-enter-and-leave-full-view-withou.md +6 -0
  226. package/corpus/templates/design/changelog/2026-07-09-local-preview-urls-now-live-in-the-inspector-instead-of-taki.md +6 -0
  227. package/corpus/templates/design/changelog/2026-07-09-local-react-layers-can-now-be-hidden-and-locked-from-layers-.md +6 -0
  228. package/corpus/templates/design/changelog/2026-07-09-local-react-layers-now-keep-exact-source-provenance-and-supp.md +6 -0
  229. package/corpus/templates/design/changelog/2026-07-09-local-react-visual-editing-now-loads-reliably-and-shows-live.md +6 -0
  230. package/corpus/templates/design/changelog/2026-07-09-paste-from-figma-cmd-v-now-imports-exact-editable-nodes-when.md +6 -0
  231. package/corpus/templates/design/changelog/2026-07-09-pressing-escape-after-selecting-a-screen-now-reveals-page-pr.md +6 -0
  232. package/corpus/templates/design/changelog/2026-07-09-right-click-overlapping-or-nested-objects-to-choose-the-exac.md +6 -0
  233. package/corpus/templates/design/changelog/2026-07-09-scale-edge-stretch-and-center-constraints-now-preserve-layer.md +6 -0
  234. package/corpus/templates/design/changelog/2026-07-09-screen-rows-can-now-be-reordered-in-layers-with-matching-can.md +6 -0
  235. package/corpus/templates/design/changelog/2026-07-09-screen-selection-stays-responsive-in-designs-with-hundreds-o.md +6 -0
  236. package/corpus/templates/design/changelog/2026-07-09-shift-a-now-enables-auto-layout-on-a-selected-screen-with-fl.md +6 -0
  237. package/corpus/templates/design/changelog/2026-07-09-swap-a-component-instance-for-another-from-the-libra.md +6 -0
  238. package/corpus/templates/design/changelog/2026-07-10-drawing-annotations-now-stay-available-to-retry-when-the.md +6 -0
  239. package/corpus/templates/design/e2e/global-setup.ts +3 -6
  240. package/corpus/templates/design/e2e/helpers.ts +27 -6
  241. package/corpus/templates/design/server/lib/design-to-figma-svg.ts +1412 -0
  242. package/corpus/templates/design/server/lib/figma-clipboard-match.ts +196 -0
  243. package/corpus/templates/design/server/lib/figma-node-import.ts +311 -0
  244. package/corpus/templates/design/server/lib/figma-node-to-html.ts +1334 -0
  245. package/corpus/templates/design/server/lib/figma-paste-fallback.ts +64 -0
  246. package/corpus/templates/design/server/lib/playwright-runtime.ts +78 -0
  247. package/corpus/templates/design/server/plugins/db.ts +41 -0
  248. package/corpus/templates/design/server/source-workspace.ts +64 -0
  249. package/corpus/templates/design/shared/board-file.ts +13 -2
  250. package/corpus/templates/design/shared/canvas-math.ts +231 -33
  251. package/corpus/templates/design/shared/code-layer.ts +122 -8
  252. package/corpus/templates/design/shared/component-library.ts +161 -0
  253. package/corpus/templates/design/shared/db-conflict.ts +27 -0
  254. package/corpus/templates/design/shared/design-source-capabilities.ts +2 -1
  255. package/corpus/templates/design/shared/figma-url.ts +149 -0
  256. package/corpus/templates/design/shared/pen-path.ts +16 -7
  257. package/corpus/templates/design/shared/source-mode.ts +1 -0
  258. package/corpus/templates/plan/app/components/plan/CanvasArea.tsx +7 -19
  259. package/corpus/templates/plan/changelog/2026-07-09-canvas-panning-now-keeps-zoom-fixed-even-at-the-edges.md +6 -0
  260. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +16 -1
  261. package/corpus/templates/slides/app/context/DeckContext.tsx +311 -70
  262. package/corpus/templates/slides/changelog/2026-07-09-fixed-the-slide-rail-going-permanently-stale-during-a-long-a.md +6 -0
  263. package/dist/agent/production-agent.d.ts +79 -6
  264. package/dist/agent/production-agent.d.ts.map +1 -1
  265. package/dist/agent/production-agent.js +161 -14
  266. package/dist/agent/production-agent.js.map +1 -1
  267. package/dist/agent/run-manager.d.ts.map +1 -1
  268. package/dist/agent/run-manager.js +29 -5
  269. package/dist/agent/run-manager.js.map +1 -1
  270. package/dist/agent/run-store.d.ts +46 -0
  271. package/dist/agent/run-store.d.ts.map +1 -1
  272. package/dist/agent/run-store.js +61 -0
  273. package/dist/agent/run-store.js.map +1 -1
  274. package/dist/cli/design-connect.d.ts +6 -0
  275. package/dist/cli/design-connect.d.ts.map +1 -1
  276. package/dist/cli/design-connect.js +336 -139
  277. package/dist/cli/design-connect.js.map +1 -1
  278. package/dist/cli/skills.d.ts.map +1 -1
  279. package/dist/cli/skills.js +14 -0
  280. package/dist/cli/skills.js.map +1 -1
  281. package/dist/client/AssistantChat.d.ts +2 -0
  282. package/dist/client/AssistantChat.d.ts.map +1 -1
  283. package/dist/client/AssistantChat.js +19 -3
  284. package/dist/client/AssistantChat.js.map +1 -1
  285. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  286. package/dist/client/MultiTabAssistantChat.js +38 -18
  287. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  288. package/dist/client/agent-chat.d.ts +60 -0
  289. package/dist/client/agent-chat.d.ts.map +1 -1
  290. package/dist/client/agent-chat.js +122 -1
  291. package/dist/client/agent-chat.js.map +1 -1
  292. package/dist/client/chat/index.d.ts +1 -1
  293. package/dist/client/chat/index.d.ts.map +1 -1
  294. package/dist/client/chat/index.js +1 -1
  295. package/dist/client/chat/index.js.map +1 -1
  296. package/dist/client/extensions/EmbeddedExtension.d.ts +12 -0
  297. package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
  298. package/dist/client/extensions/EmbeddedExtension.js +36 -2
  299. package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
  300. package/dist/client/index.d.ts +1 -1
  301. package/dist/client/index.d.ts.map +1 -1
  302. package/dist/client/index.js +1 -1
  303. package/dist/client/index.js.map +1 -1
  304. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
  305. package/dist/client/rich-markdown-editor/useCollabReconcile.js +18 -6
  306. package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
  307. package/dist/collab/awareness-store.d.ts +5 -0
  308. package/dist/collab/awareness-store.d.ts.map +1 -1
  309. package/dist/collab/awareness-store.js +19 -12
  310. package/dist/collab/awareness-store.js.map +1 -1
  311. package/dist/collab/client.d.ts.map +1 -1
  312. package/dist/collab/client.js +13 -5
  313. package/dist/collab/client.js.map +1 -1
  314. package/dist/collab/index.d.ts +1 -0
  315. package/dist/collab/index.d.ts.map +1 -1
  316. package/dist/collab/index.js +1 -0
  317. package/dist/collab/index.js.map +1 -1
  318. package/dist/collab/recent-edits.d.ts +3 -1
  319. package/dist/collab/recent-edits.d.ts.map +1 -1
  320. package/dist/collab/recent-edits.js +57 -2
  321. package/dist/collab/recent-edits.js.map +1 -1
  322. package/dist/index.browser.d.ts +1 -1
  323. package/dist/index.browser.d.ts.map +1 -1
  324. package/dist/index.browser.js +1 -1
  325. package/dist/index.browser.js.map +1 -1
  326. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  327. package/dist/server/agent-chat-plugin.js +87 -10
  328. package/dist/server/agent-chat-plugin.js.map +1 -1
  329. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  330. package/dist/server/builder-design-systems.d.ts +15 -0
  331. package/dist/server/builder-design-systems.d.ts.map +1 -1
  332. package/dist/server/builder-design-systems.js +9 -4
  333. package/dist/server/builder-design-systems.js.map +1 -1
  334. package/package.json +1 -1
@@ -46,6 +46,25 @@ export type AutoLayoutDirection = "horizontal" | "vertical";
46
46
  export type AutoLayoutWrap = "nowrap" | "wrap";
47
47
  export type AutoLayoutSizing = "hug" | "fill" | "fixed";
48
48
  export type AutoLayoutSizingAxis = "horizontal" | "vertical";
49
+ export type AutoLayoutGridTrackSizing = "fill" | "hug" | "fixed" | "custom";
50
+
51
+ export interface AutoLayoutGridValue {
52
+ columns: number;
53
+ rows: number;
54
+ columnSizing: AutoLayoutGridTrackSizing;
55
+ rowSizing: AutoLayoutGridTrackSizing;
56
+ columnSize?: number;
57
+ rowSize?: number;
58
+ /** Exact authored values, retained for non-uniform/custom templates. */
59
+ columnTemplate?: string;
60
+ rowTemplate?: string;
61
+ columnGap: number;
62
+ rowGap: number;
63
+ columnsMixed?: boolean;
64
+ rowsMixed?: boolean;
65
+ columnGapMixed?: boolean;
66
+ rowGapMixed?: boolean;
67
+ }
49
68
 
50
69
  /** Round to one decimal place — matches the `precision={1}` ScrubInput fields
51
70
  * advertise (e.g. X/Y position, stroke weight) so W/H commit sub-pixel values
@@ -59,6 +78,7 @@ function roundToOneDecimal(value: number): number {
59
78
  * non-flex containers; the other four map to flex direction + wrap state.
60
79
  */
61
80
  export type AutoLayoutFlow = "normal" | "vertical" | "horizontal" | "grid";
81
+ type ResolvedAutoLayoutFlow = AutoLayoutFlow | "mixed";
62
82
 
63
83
  export interface AutoLayoutPadding {
64
84
  top: number;
@@ -71,10 +91,12 @@ export interface AutoLayoutMatrixValue {
71
91
  direction: AutoLayoutDirection;
72
92
  wrap: AutoLayoutWrap;
73
93
  alignment: AlignmentMatrixValue;
94
+ alignmentMixed?: boolean;
74
95
  gap: number;
75
96
  padding: AutoLayoutPadding;
76
97
  paddingLinked: boolean;
77
98
  clipContent?: boolean;
99
+ clipContentMixed?: boolean;
78
100
  resolvedSize?: {
79
101
  horizontal?: number;
80
102
  vertical?: number;
@@ -83,6 +105,32 @@ export interface AutoLayoutMatrixValue {
83
105
  horizontal?: boolean;
84
106
  vertical?: boolean;
85
107
  };
108
+ /**
109
+ * Set when a multi-selection has differing `gap` values across elements.
110
+ * Mirrors the edit-panel `MIXED_VALUE`/`isMixedValue` sentinel pattern used
111
+ * for other fields: rather than silently coercing an unparseable "Mixed"
112
+ * CSS value down to `0` (which reads as "no gap" and would clobber every
113
+ * selected element's real gap the moment the user touches the field), the
114
+ * Gap ScrubInput renders the "Mixed" placeholder instead of a numeric 0.
115
+ * Optional so existing single-selection callers are unaffected.
116
+ */
117
+ gapMixed?: boolean;
118
+ gapModeMixed?: boolean;
119
+ /** Explicit CSS-grid tracks. Grid is a separate flow, never flex-wrap. */
120
+ grid?: AutoLayoutGridValue;
121
+ /**
122
+ * Per-side mixed flags for `padding`, same rationale as `gapMixed`. Each
123
+ * side is independent because a multi-selection can have matching top/bottom
124
+ * padding but differing left/right (or any other combination) — collapsing
125
+ * to one boolean would either over- or under-report "Mixed" for the linked
126
+ * 2-field view. Optional so existing single-selection callers are unaffected.
127
+ */
128
+ paddingMixed?: {
129
+ top?: boolean;
130
+ right?: boolean;
131
+ bottom?: boolean;
132
+ left?: boolean;
133
+ };
86
134
  childSizing: {
87
135
  horizontal: AutoLayoutSizing;
88
136
  vertical: AutoLayoutSizing;
@@ -102,7 +150,11 @@ export interface AutoLayoutMatrixValue {
102
150
  * treated as disabled. Defaults to flex when omitted so existing callers are
103
151
  * unaffected.
104
152
  */
105
- display?: "flex" | "block";
153
+ display?: "flex" | "grid" | "block";
154
+ /** True when a multi-selection disagrees on display/direction/wrap. No flow
155
+ * segment is shown as active and the row explicitly says Mixed until the
156
+ * user chooses one common flow. */
157
+ flowMixed?: boolean;
106
158
  /**
107
159
  * When true, the gap mode is "Auto" (CSS `justify-content: space-between`).
108
160
  * When false or omitted, gap mode is "Fixed" (a numeric gap value).
@@ -162,6 +214,10 @@ export interface AutoLayoutMatrixProps {
162
214
  * nothing until reselect).
163
215
  */
164
216
  onGapChange: (gap: number, meta?: ScrubInputChangeMeta) => void;
217
+ onGridChange?: (
218
+ grid: AutoLayoutGridValue,
219
+ meta?: ScrubInputChangeMeta,
220
+ ) => void;
165
221
  onPaddingChange: (
166
222
  padding: AutoLayoutPadding,
167
223
  meta?: ScrubInputChangeMeta,
@@ -204,13 +260,20 @@ export interface AutoLayoutMatrixProps {
204
260
  * no variable collections exist.
205
261
  */
206
262
  onApplyVariable?: (axis: AutoLayoutSizingAxis) => void;
263
+ /**
264
+ * Optional atomic Flow callback. Inspector hosts that persist code should
265
+ * use this to commit display + direction + wrap in one source/history step.
266
+ * Without it, the component falls back to the individual callbacks for
267
+ * backwards compatibility.
268
+ */
269
+ onFlowChange?: (flow: AutoLayoutFlow) => void;
207
270
  /**
208
271
  * Emitted when the user picks a flow that changes the layout mode between
209
272
  * normal-flow (block) and flex. Pass this so selecting the first ("normal")
210
273
  * flow icon can turn auto layout off, and selecting a flex flow can turn it
211
274
  * on. Optional — when omitted the control still works in pure-flex mode.
212
275
  */
213
- onDisplayChange?: (display: "flex" | "block") => void;
276
+ onDisplayChange?: (display: "flex" | "grid" | "block") => void;
214
277
  availableChildSizing?: Partial<
215
278
  Record<AutoLayoutSizingAxis, AutoLayoutSizing[]>
216
279
  >;
@@ -261,9 +324,10 @@ export const DEFAULT_AUTO_LAYOUT_LABELS: AutoLayoutMatrixLabels = {
261
324
  const SIZING_OPTIONS: AutoLayoutSizing[] = ["hug", "fill", "fixed"];
262
325
 
263
326
  /** Derive the active flow option from display + direction + wrap state. */
264
- function getFlowOption(value: AutoLayoutMatrixValue): AutoLayoutFlow {
327
+ function getFlowOption(value: AutoLayoutMatrixValue): ResolvedAutoLayoutFlow {
328
+ if (value.flowMixed) return "mixed";
265
329
  if (value.display === "block") return "normal";
266
- if (value.wrap === "wrap") return "grid";
330
+ if (value.display === "grid") return "grid";
267
331
  if (value.direction === "vertical") return "vertical";
268
332
  return "horizontal";
269
333
  }
@@ -274,6 +338,7 @@ export function AutoLayoutMatrix({
274
338
  onWrapChange,
275
339
  onAlignmentChange,
276
340
  onGapChange,
341
+ onGridChange,
277
342
  onPaddingChange,
278
343
  onPaddingLinkedChange,
279
344
  onClipContentChange,
@@ -282,6 +347,7 @@ export function AutoLayoutMatrix({
282
347
  onChildSizingChange,
283
348
  onChildMinMaxChange,
284
349
  onApplyVariable,
350
+ onFlowChange,
285
351
  onDisplayChange,
286
352
  onChildSizeChange,
287
353
  availableChildSizing,
@@ -300,18 +366,32 @@ export function AutoLayoutMatrix({
300
366
  // the user's intent without a silent lossy round-trip through the average.
301
367
  const horizontalPaddingValue = value.padding.left;
302
368
  const verticalPaddingValue = value.padding.top;
369
+ // The linked view shows one field per axis representing both sides, so it
370
+ // must report "Mixed" whenever *either* side of that axis differs across
371
+ // the selection — otherwise a selection with equal left/right but mixed
372
+ // top/bottom (or vice versa) would silently show a real-looking number.
373
+ const horizontalPaddingMixed = Boolean(
374
+ value.paddingMixed?.left || value.paddingMixed?.right,
375
+ );
376
+ const verticalPaddingMixed = Boolean(
377
+ value.paddingMixed?.top || value.paddingMixed?.bottom,
378
+ );
303
379
 
304
380
  const activeFlow = getFlowOption(value);
305
381
  const isBlock = activeFlow === "normal";
306
382
 
307
383
  /** Apply a flow choice, coordinating display + direction + wrap. */
308
384
  const selectFlow = (flow: AutoLayoutFlow) => {
385
+ if (onFlowChange) {
386
+ onFlowChange(flow);
387
+ return;
388
+ }
309
389
  if (flow === "normal") {
310
390
  onDisplayChange?.("block");
311
391
  return;
312
392
  }
313
- // Any flex flow turns auto layout on.
314
- onDisplayChange?.("flex");
393
+ // Grid is a distinct layout model; horizontal/vertical use flexbox.
394
+ onDisplayChange?.(flow === "grid" ? "grid" : "flex");
315
395
  if (flow === "vertical") {
316
396
  onDirectionChange("vertical");
317
397
  onWrapChange("nowrap");
@@ -319,9 +399,7 @@ export function AutoLayoutMatrix({
319
399
  onDirectionChange("horizontal");
320
400
  onWrapChange("nowrap");
321
401
  } else {
322
- // grid horizontal direction with wrap
323
- onDirectionChange("horizontal");
324
- onWrapChange("wrap");
402
+ // Grid tracks are controlled independently below.
325
403
  }
326
404
  };
327
405
 
@@ -331,12 +409,22 @@ export function AutoLayoutMatrix({
331
409
  {/* ── Flow ── */}
332
410
  {showChildLayoutControls ? (
333
411
  <div className="space-y-1.5">
334
- <ControlLabel>
335
- {"Flow" /* i18n-ignore design inspector label */}
336
- </ControlLabel>
412
+ <div className="flex items-center justify-between gap-2">
413
+ <ControlLabel>
414
+ {"Flow" /* i18n-ignore design inspector label */}
415
+ </ControlLabel>
416
+ {value.flowMixed ? (
417
+ <span className="!text-[11px] text-muted-foreground">
418
+ {"Mixed" /* i18n-ignore design mixed value */}
419
+ </span>
420
+ ) : null}
421
+ </div>
337
422
  <div className="flex items-center gap-1.5">
338
423
  {/* 4-segment flow bar: normal / vertical / horizontal / grid */}
339
- <div className="flex h-7 flex-1 items-center gap-0.5 rounded-md bg-[var(--design-editor-control-bg)] p-0.5">
424
+ <div
425
+ data-flow-value={activeFlow}
426
+ className="flex h-7 flex-1 items-center gap-0.5 rounded-md bg-[var(--design-editor-control-bg)] p-0.5"
427
+ >
340
428
  <FlowButton
341
429
  label={"Normal flow" /* i18n-ignore design inspector label */}
342
430
  active={activeFlow === "normal"}
@@ -487,11 +575,19 @@ export function AutoLayoutMatrix({
487
575
  {showChildLayoutControls && !isBlock ? (
488
576
  <div className="grid grid-cols-[78px_1fr] items-start gap-3">
489
577
  <div className="space-y-1.5">
490
- <ControlLabel>
491
- {"Alignment" /* i18n-ignore design inspector label */}
492
- </ControlLabel>
578
+ <div className="flex items-center justify-between gap-2">
579
+ <ControlLabel>
580
+ {"Alignment" /* i18n-ignore design inspector label */}
581
+ </ControlLabel>
582
+ {value.alignmentMixed ? (
583
+ <span className="!text-[11px] text-muted-foreground">
584
+ {"Mixed" /* i18n-ignore design mixed value */}
585
+ </span>
586
+ ) : null}
587
+ </div>
493
588
  <CompactAlignmentMatrix
494
589
  value={value.alignment}
590
+ mixed={value.alignmentMixed}
495
591
  onChange={onAlignmentChange}
496
592
  direction={value.direction}
497
593
  disabled={disabled}
@@ -499,19 +595,42 @@ export function AutoLayoutMatrix({
499
595
  />
500
596
  </div>
501
597
 
502
- <div className="space-y-1.5">
503
- <ControlLabel>{copy.gap}</ControlLabel>
504
- <GapField
505
- value={value.gap}
506
- onGapChange={onGapChange}
507
- onDistribute={onDistribute}
508
- onGapModeChange={onGapModeChange}
509
- label={copy.gap}
598
+ {activeFlow === "grid" && value.grid ? (
599
+ <GridControls
600
+ value={value.grid}
601
+ onChange={onGridChange}
510
602
  disabled={disabled}
511
- direction={value.direction}
512
- gapMode={value.spaceBetween ? "auto" : "fixed"}
513
603
  />
514
- </div>
604
+ ) : (
605
+ <div className="space-y-1.5">
606
+ <ControlLabel>{copy.gap}</ControlLabel>
607
+ <GapField
608
+ value={value.gap}
609
+ mixed={value.gapMixed}
610
+ onGapChange={onGapChange}
611
+ onDistribute={onDistribute}
612
+ onGapModeChange={onGapModeChange}
613
+ label={copy.gap}
614
+ disabled={disabled}
615
+ direction={value.direction}
616
+ gapMode={value.spaceBetween ? "auto" : "fixed"}
617
+ gapModeMixed={value.gapModeMixed}
618
+ />
619
+ {activeFlow === "horizontal" ? (
620
+ <label className="flex items-center gap-2 !text-[11px] text-foreground">
621
+ <Checkbox
622
+ checked={value.wrap === "wrap"}
623
+ disabled={disabled}
624
+ onCheckedChange={(checked) =>
625
+ onWrapChange(checked === true ? "wrap" : "nowrap")
626
+ }
627
+ className="size-3.5 rounded-[3px]"
628
+ />
629
+ <span>{copy.wrap}</span>
630
+ </label>
631
+ ) : null}
632
+ </div>
633
+ )}
515
634
  </div>
516
635
  ) : null}
517
636
 
@@ -526,6 +645,7 @@ export function AutoLayoutMatrix({
526
645
  icon={IconPaddingHorizontal}
527
646
  ariaLabel={copy.paddingLeft + " / " + copy.paddingRight}
528
647
  value={horizontalPaddingValue}
648
+ mixed={horizontalPaddingMixed}
529
649
  onChange={(next, meta) =>
530
650
  onPaddingChange(
531
651
  {
@@ -543,6 +663,7 @@ export function AutoLayoutMatrix({
543
663
  icon={IconPaddingVertical}
544
664
  ariaLabel={copy.paddingTop + " / " + copy.paddingBottom}
545
665
  value={verticalPaddingValue}
666
+ mixed={verticalPaddingMixed}
546
667
  onChange={(next, meta) =>
547
668
  onPaddingChange(
548
669
  {
@@ -572,6 +693,7 @@ export function AutoLayoutMatrix({
572
693
  icon={IconPaddingTopMini}
573
694
  ariaLabel={copy.paddingTop}
574
695
  value={value.padding.top}
696
+ mixed={value.paddingMixed?.top}
575
697
  onChange={(next, meta) =>
576
698
  onPaddingChange({ ...value.padding, top: next }, meta)
577
699
  }
@@ -581,6 +703,7 @@ export function AutoLayoutMatrix({
581
703
  icon={IconPaddingRightMini}
582
704
  ariaLabel={copy.paddingRight}
583
705
  value={value.padding.right}
706
+ mixed={value.paddingMixed?.right}
584
707
  onChange={(next, meta) =>
585
708
  onPaddingChange({ ...value.padding, right: next }, meta)
586
709
  }
@@ -590,6 +713,7 @@ export function AutoLayoutMatrix({
590
713
  icon={IconPaddingBottomMini}
591
714
  ariaLabel={copy.paddingBottom}
592
715
  value={value.padding.bottom}
716
+ mixed={value.paddingMixed?.bottom}
593
717
  onChange={(next, meta) =>
594
718
  onPaddingChange({ ...value.padding, bottom: next }, meta)
595
719
  }
@@ -599,6 +723,7 @@ export function AutoLayoutMatrix({
599
723
  icon={IconPaddingLeftMini}
600
724
  ariaLabel={copy.paddingLeft}
601
725
  value={value.padding.left}
726
+ mixed={value.paddingMixed?.left}
602
727
  onChange={(next, meta) =>
603
728
  onPaddingChange({ ...value.padding, left: next }, meta)
604
729
  }
@@ -621,7 +746,11 @@ export function AutoLayoutMatrix({
621
746
  {showChildLayoutControls ? (
622
747
  <label className="flex h-6 cursor-pointer items-center gap-2 !text-[11px] text-foreground">
623
748
  <Checkbox
624
- checked={Boolean(value.clipContent)}
749
+ checked={
750
+ value.clipContentMixed
751
+ ? "indeterminate"
752
+ : Boolean(value.clipContent)
753
+ }
625
754
  disabled={disabled}
626
755
  onCheckedChange={(checked) =>
627
756
  onClipContentChange?.(checked === true)
@@ -668,6 +797,179 @@ const ALIGNMENT_CELLS: Array<{
668
797
  // Sub-components
669
798
  // ─────────────────────────────────────────────────
670
799
 
800
+ function GridControls({
801
+ value,
802
+ onChange,
803
+ disabled,
804
+ }: {
805
+ value: AutoLayoutGridValue;
806
+ onChange?: (value: AutoLayoutGridValue, meta?: ScrubInputChangeMeta) => void;
807
+ disabled: boolean;
808
+ }) {
809
+ const update = (
810
+ patch: Partial<AutoLayoutGridValue>,
811
+ meta?: ScrubInputChangeMeta,
812
+ ) => onChange?.({ ...value, ...patch }, meta);
813
+
814
+ return (
815
+ <div className="space-y-1.5">
816
+ <ControlLabel>
817
+ {"Grid" /* i18n-ignore design inspector label */}
818
+ </ControlLabel>
819
+ <div className="grid grid-cols-2 gap-1.5">
820
+ <GridNumberField
821
+ label={"Columns" /* i18n-ignore design inspector label */}
822
+ value={value.columns}
823
+ mixed={value.columnsMixed}
824
+ min={1}
825
+ max={24}
826
+ onChange={(columns, meta) => update({ columns }, meta)}
827
+ disabled={disabled || !onChange}
828
+ />
829
+ <GridNumberField
830
+ label={"Rows" /* i18n-ignore design inspector label */}
831
+ value={value.rows}
832
+ mixed={value.rowsMixed}
833
+ min={1}
834
+ max={24}
835
+ onChange={(rows, meta) => update({ rows }, meta)}
836
+ disabled={disabled || !onChange}
837
+ />
838
+ <GridTrackPicker
839
+ label={"Column sizing" /* i18n-ignore design inspector label */}
840
+ value={value.columnSizing}
841
+ fixedSize={value.columnSize}
842
+ disabled={disabled || !onChange}
843
+ onChange={(columnSizing) => update({ columnSizing })}
844
+ onFixedSizeChange={(columnSize, meta) => update({ columnSize }, meta)}
845
+ />
846
+ <GridTrackPicker
847
+ label={"Row sizing" /* i18n-ignore design inspector label */}
848
+ value={value.rowSizing}
849
+ fixedSize={value.rowSize}
850
+ disabled={disabled || !onChange}
851
+ onChange={(rowSizing) => update({ rowSizing })}
852
+ onFixedSizeChange={(rowSize, meta) => update({ rowSize }, meta)}
853
+ />
854
+ <GridNumberField
855
+ label={"Column gap" /* i18n-ignore design inspector label */}
856
+ value={value.columnGap}
857
+ mixed={value.columnGapMixed}
858
+ min={0}
859
+ unit="px"
860
+ onChange={(columnGap, meta) => update({ columnGap }, meta)}
861
+ disabled={disabled || !onChange}
862
+ />
863
+ <GridNumberField
864
+ label={"Row gap" /* i18n-ignore design inspector label */}
865
+ value={value.rowGap}
866
+ mixed={value.rowGapMixed}
867
+ min={0}
868
+ unit="px"
869
+ onChange={(rowGap, meta) => update({ rowGap }, meta)}
870
+ disabled={disabled || !onChange}
871
+ />
872
+ </div>
873
+ </div>
874
+ );
875
+ }
876
+
877
+ function GridNumberField({
878
+ label,
879
+ value,
880
+ mixed,
881
+ min,
882
+ max,
883
+ unit,
884
+ onChange,
885
+ disabled,
886
+ }: {
887
+ label: string;
888
+ value: number;
889
+ mixed?: boolean;
890
+ min: number;
891
+ max?: number;
892
+ unit?: string;
893
+ onChange: (value: number, meta: ScrubInputChangeMeta) => void;
894
+ disabled: boolean;
895
+ }) {
896
+ return (
897
+ <ScrubInput
898
+ label={label}
899
+ ariaLabel={label}
900
+ tooltipLabel={label}
901
+ value={value}
902
+ mixed={mixed}
903
+ onChange={onChange}
904
+ unit={unit}
905
+ min={min}
906
+ max={max}
907
+ step={1}
908
+ precision={0}
909
+ disabled={disabled}
910
+ className="min-w-0 gap-0 rounded-md bg-[var(--design-editor-control-bg)]"
911
+ labelClassName="h-7 w-6 justify-center overflow-hidden px-1 !text-[9px] text-muted-foreground [&>svg]:hidden"
912
+ inputClassName="h-7 border-0 bg-transparent px-1 !text-[11px] shadow-none focus-visible:ring-0"
913
+ />
914
+ );
915
+ }
916
+
917
+ function GridTrackPicker({
918
+ label,
919
+ value,
920
+ fixedSize = 100,
921
+ disabled,
922
+ onChange,
923
+ onFixedSizeChange,
924
+ }: {
925
+ label: string;
926
+ value: AutoLayoutGridTrackSizing;
927
+ fixedSize?: number;
928
+ disabled: boolean;
929
+ onChange: (value: AutoLayoutGridTrackSizing) => void;
930
+ onFixedSizeChange: (value: number, meta: ScrubInputChangeMeta) => void;
931
+ }) {
932
+ return (
933
+ <div className="flex min-w-0 rounded-md bg-[var(--design-editor-control-bg)]">
934
+ <DropdownMenu>
935
+ <DropdownMenuTrigger asChild>
936
+ <Button
937
+ type="button"
938
+ variant="ghost"
939
+ disabled={disabled}
940
+ aria-label={label}
941
+ className="h-7 min-w-0 flex-1 justify-start rounded-md px-2 !text-[11px] font-normal capitalize"
942
+ >
943
+ {value}
944
+ </Button>
945
+ </DropdownMenuTrigger>
946
+ <DropdownMenuContent align="start">
947
+ {(["fill", "hug", "fixed", "custom"] as const).map((option) => (
948
+ <DropdownMenuItem key={option} onSelect={() => onChange(option)}>
949
+ <span className="capitalize">{option}</span>
950
+ </DropdownMenuItem>
951
+ ))}
952
+ </DropdownMenuContent>
953
+ </DropdownMenu>
954
+ {value === "fixed" ? (
955
+ <ScrubInput
956
+ label={label}
957
+ ariaLabel={`${label} size`}
958
+ value={fixedSize}
959
+ onChange={onFixedSizeChange}
960
+ unit="px"
961
+ min={0}
962
+ precision={0}
963
+ disabled={disabled}
964
+ className="w-14 min-w-0 gap-0"
965
+ labelClassName="hidden"
966
+ inputClassName="h-7 border-0 bg-transparent px-1 !text-[11px] shadow-none focus-visible:ring-0"
967
+ />
968
+ ) : null}
969
+ </div>
970
+ );
971
+ }
972
+
671
973
  /**
672
974
  * Compact 3×3 alignment grid (no border box). Inactive cells show a faint dot;
673
975
  * the active cell shows accent bars oriented by flow — horizontal bars for a
@@ -677,12 +979,14 @@ const ALIGNMENT_CELLS: Array<{
677
979
  */
678
980
  function CompactAlignmentMatrix({
679
981
  value,
982
+ mixed = false,
680
983
  onChange,
681
984
  direction,
682
985
  disabled,
683
986
  onDistribute,
684
987
  }: {
685
988
  value: AlignmentMatrixValue;
989
+ mixed?: boolean;
686
990
  onChange: (value: AlignmentMatrixValue) => void;
687
991
  direction: AutoLayoutDirection;
688
992
  disabled: boolean;
@@ -695,6 +999,7 @@ function CompactAlignmentMatrix({
695
999
  <div className={cn("grid w-fit grid-cols-3 rounded-md")}>
696
1000
  {ALIGNMENT_CELLS.map((cell) => {
697
1001
  const active =
1002
+ !mixed &&
698
1003
  cell.horizontal === value.horizontal &&
699
1004
  cell.vertical === value.vertical;
700
1005
  return (
@@ -917,6 +1222,7 @@ function FlowButton({
917
1222
  */
918
1223
  function GapField({
919
1224
  value,
1225
+ mixed = false,
920
1226
  onGapChange,
921
1227
  onDistribute,
922
1228
  onGapModeChange,
@@ -924,8 +1230,11 @@ function GapField({
924
1230
  disabled,
925
1231
  direction,
926
1232
  gapMode = "fixed",
1233
+ gapModeMixed = false,
927
1234
  }: {
928
1235
  value: number;
1236
+ /** Set for a multi-selection with differing gap values — see AutoLayoutMatrixValue.gapMixed. */
1237
+ mixed?: boolean;
929
1238
  /** Forwards ScrubInput's gesture meta — see AutoLayoutMatrixProps.onGapChange. */
930
1239
  onGapChange: (gap: number, meta?: ScrubInputChangeMeta) => void;
931
1240
  onDistribute?: (axis: DistributionAxis) => void;
@@ -934,6 +1243,7 @@ function GapField({
934
1243
  disabled: boolean;
935
1244
  direction: AutoLayoutDirection;
936
1245
  gapMode?: "fixed" | "auto";
1246
+ gapModeMixed?: boolean;
937
1247
  }) {
938
1248
  return (
939
1249
  <div className="flex items-center gap-1.5">
@@ -950,6 +1260,7 @@ function GapField({
950
1260
  tooltipLabel={label}
951
1261
  icon={IconGap}
952
1262
  value={value}
1263
+ mixed={mixed}
953
1264
  onChange={(next, meta) => onGapChange(next, meta)}
954
1265
  unit="px"
955
1266
  min={0}
@@ -967,7 +1278,11 @@ function GapField({
967
1278
  <DropdownMenuTrigger asChild>
968
1279
  <button
969
1280
  type="button"
970
- aria-label={"Gap mode" /* i18n-ignore inspector tooltip */}
1281
+ aria-label={
1282
+ gapModeMixed
1283
+ ? "Gap mode: Mixed" /* i18n-ignore inspector tooltip */
1284
+ : "Gap mode" /* i18n-ignore inspector tooltip */
1285
+ }
971
1286
  disabled={disabled}
972
1287
  className={cn(
973
1288
  "flex h-7 w-6 shrink-0 items-center justify-center rounded-r-md",
@@ -990,14 +1305,14 @@ function GapField({
990
1305
  sideOffset={4}
991
1306
  >
992
1307
  <DropdownMenuCheckboxItem
993
- checked={gapMode !== "auto"}
1308
+ checked={!gapModeMixed && gapMode !== "auto"}
994
1309
  className="text-[12px]"
995
1310
  onSelect={() => onGapModeChange?.("fixed", direction)}
996
1311
  >
997
1312
  {"Fixed" /* i18n-ignore design gap mode label */}
998
1313
  </DropdownMenuCheckboxItem>
999
1314
  <DropdownMenuCheckboxItem
1000
- checked={gapMode === "auto"}
1315
+ checked={!gapModeMixed && gapMode === "auto"}
1001
1316
  className="text-[12px]"
1002
1317
  onSelect={() => {
1003
1318
  if (onGapModeChange) {
@@ -1043,12 +1358,15 @@ function PaddingField({
1043
1358
  icon: Icon,
1044
1359
  ariaLabel,
1045
1360
  value,
1361
+ mixed = false,
1046
1362
  onChange,
1047
1363
  disabled,
1048
1364
  }: {
1049
1365
  icon: (props: { className?: string }) => ReactNode;
1050
1366
  ariaLabel: string;
1051
1367
  value: number;
1368
+ /** Set for a multi-selection with differing padding on this side — see AutoLayoutMatrixValue.paddingMixed. */
1369
+ mixed?: boolean;
1052
1370
  /** Forwards ScrubInput's gesture meta — see AutoLayoutMatrixProps.onPaddingChange. */
1053
1371
  onChange: (value: number, meta?: ScrubInputChangeMeta) => void;
1054
1372
  disabled: boolean;
@@ -1066,6 +1384,7 @@ function PaddingField({
1066
1384
  tooltipLabel={ariaLabel}
1067
1385
  icon={Icon}
1068
1386
  value={value}
1387
+ mixed={mixed}
1069
1388
  onChange={(next, meta) => onChange(next, meta)}
1070
1389
  unit="px"
1071
1390
  min={0}