@agent-native/core 0.92.10 → 0.92.12

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 (354) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +29 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/agent/production-agent.ts +214 -17
  5. package/corpus/core/src/agent/run-manager.ts +72 -14
  6. package/corpus/core/src/agent/run-store.ts +152 -27
  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-adapter.ts +56 -12
  12. package/corpus/core/src/client/agent-chat.ts +165 -1
  13. package/corpus/core/src/client/chat/index.ts +9 -1
  14. package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +38 -2
  15. package/corpus/core/src/client/index.ts +5 -0
  16. package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +18 -7
  17. package/corpus/core/src/collab/awareness-store.ts +23 -12
  18. package/corpus/core/src/collab/client.ts +16 -5
  19. package/corpus/core/src/collab/index.ts +4 -0
  20. package/corpus/core/src/collab/recent-edits.ts +65 -2
  21. package/corpus/core/src/index.browser.ts +1 -0
  22. package/corpus/core/src/server/agent-chat-plugin.ts +98 -11
  23. package/corpus/core/src/server/builder-design-systems.ts +30 -4
  24. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +1 -1
  25. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +12 -6
  26. package/corpus/templates/clips/AGENTS.md +4 -0
  27. package/corpus/templates/clips/actions/create-recording.ts +2 -0
  28. package/corpus/templates/clips/actions/lib/create-recording-schema.ts +5 -3
  29. package/corpus/templates/clips/actions/request-transcript.ts +102 -33
  30. package/corpus/templates/clips/app/components/library/library-grid.tsx +1 -0
  31. package/corpus/templates/clips/app/components/player/share-dialog.tsx +59 -19
  32. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +75 -9
  33. package/corpus/templates/clips/app/components/player/video-player.tsx +17 -12
  34. package/corpus/templates/clips/app/hooks/use-player-shortcuts.ts +1 -0
  35. package/corpus/templates/clips/app/i18n/ar-SA.ts +1 -0
  36. package/corpus/templates/clips/app/i18n/de-DE.ts +1 -0
  37. package/corpus/templates/clips/app/i18n/en-US.ts +1 -0
  38. package/corpus/templates/clips/app/i18n/es-ES.ts +1 -0
  39. package/corpus/templates/clips/app/i18n/fr-FR.ts +1 -0
  40. package/corpus/templates/clips/app/i18n/hi-IN.ts +1 -0
  41. package/corpus/templates/clips/app/i18n/ja-JP.ts +1 -0
  42. package/corpus/templates/clips/app/i18n/ko-KR.ts +1 -0
  43. package/corpus/templates/clips/app/i18n/pt-BR.ts +1 -0
  44. package/corpus/templates/clips/app/i18n/zh-CN.ts +1 -0
  45. package/corpus/templates/clips/app/i18n/zh-TW.ts +1 -0
  46. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +70 -37
  47. package/corpus/templates/clips/app/routes/record.tsx +17 -4
  48. package/corpus/templates/clips/app/routes/share.$shareId.tsx +2 -0
  49. package/corpus/templates/clips/changelog/2026-07-09-desktop-popover-sits-closer-to-the-menu-bar.md +6 -0
  50. package/corpus/templates/clips/changelog/2026-07-09-desktop-recording-optimization-progress-stays-visible-until-the-clip-opens.md +6 -0
  51. package/corpus/templates/clips/changelog/2026-07-09-fixed-large-video-file-uploads-failing-before-their-resumabl.md +6 -0
  52. package/corpus/templates/clips/changelog/2026-07-09-fixed-new-video-uploads-defaulting-to-private.md +6 -0
  53. package/corpus/templates/clips/changelog/2026-07-09-long-recordings-now-get-enough-time-to-download-their-media-.md +6 -0
  54. package/corpus/templates/clips/changelog/2026-07-09-meeting-notes-no-longer-lowers-your-microphone-volume-for-ot.md +6 -0
  55. package/corpus/templates/clips/changelog/2026-07-09-on-mobile-tapping-a-playing-clip-reveals-playback-controls-w.md +6 -0
  56. package/corpus/templates/clips/changelog/2026-07-09-regenerate-any-clip-transcript-from-its-saved-recording-or-r.md +6 -0
  57. package/corpus/templates/clips/changelog/2026-07-09-slack-previews-now-show-the-clip-length-alongside-its-descri.md +6 -0
  58. package/corpus/templates/clips/changelog/2026-07-10-fixed-copying-agent-responses-and-transcript-text-from-recor.md +6 -0
  59. package/corpus/templates/clips/desktop/src/app.tsx +12 -2
  60. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +8 -1
  61. package/corpus/templates/clips/desktop/src/lib/recorder.ts +8 -5
  62. package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +5 -5
  63. package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +3 -0
  64. package/corpus/templates/clips/desktop/src/styles.css +6 -3
  65. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +29 -11
  66. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +1 -1
  67. package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +103 -21
  68. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +117 -39
  69. package/corpus/templates/clips/server/lib/slack-unfurls.ts +20 -1
  70. package/corpus/templates/clips/server/lib/streaming-upload-mode.ts +10 -4
  71. package/corpus/templates/clips/shared/recording-core.ts +12 -0
  72. package/corpus/templates/content/AGENTS.md +7 -6
  73. package/corpus/templates/content/actions/_builder-cms-read-client.ts +82 -7
  74. package/corpus/templates/content/actions/_database-source-utils.ts +149 -30
  75. package/corpus/templates/content/actions/_document-flush.ts +132 -17
  76. package/corpus/templates/content/actions/_notion-action-utils.ts +15 -0
  77. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +4 -7
  78. package/corpus/templates/content/actions/attach-content-database-source.ts +41 -17
  79. package/corpus/templates/content/actions/change-content-database-source-role.ts +46 -8
  80. package/corpus/templates/content/actions/create-and-link-notion-page.ts +2 -0
  81. package/corpus/templates/content/actions/link-notion-page.ts +2 -0
  82. package/corpus/templates/content/actions/pull-document.ts +5 -7
  83. package/corpus/templates/content/actions/pull-notion-page.ts +2 -0
  84. package/corpus/templates/content/actions/push-notion-page.ts +10 -0
  85. package/corpus/templates/content/actions/resolve-notion-sync-conflict.ts +2 -0
  86. package/corpus/templates/content/actions/suggest-source-join-key.ts +8 -1
  87. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +88 -23
  88. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +32 -2
  89. package/corpus/templates/content/app/hooks/use-notion.ts +6 -6
  90. package/corpus/templates/content/app/i18n/zh-TW.ts +1 -0
  91. package/corpus/templates/content/app/i18n-data.ts +18 -0
  92. package/corpus/templates/content/changelog/2026-07-09-builder-source-refreshes-now-keep-mapped-fields-such-as-topi.md +6 -0
  93. package/corpus/templates/content/changelog/2026-07-09-notion-conflict-choices-and-version-restores-preserve-docume.md +6 -0
  94. package/corpus/templates/content/server/lib/notion-sync.ts +80 -64
  95. package/corpus/templates/content/shared/api.ts +1 -0
  96. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +29 -2
  97. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +86 -0
  98. package/corpus/templates/design/.agents/skills/export-handoff/SKILL.md +57 -0
  99. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +11 -0
  100. package/corpus/templates/design/AGENTS.md +45 -10
  101. package/corpus/templates/design/actions/add-localhost-screens.ts +66 -13
  102. package/corpus/templates/design/actions/apply-component-prop-edit.ts +45 -36
  103. package/corpus/templates/design/actions/apply-motion-edit.ts +25 -31
  104. package/corpus/templates/design/actions/apply-shader-fill.ts +29 -42
  105. package/corpus/templates/design/actions/detach-component-instance.ts +337 -0
  106. package/corpus/templates/design/actions/export-design-as-figma-svg.ts +219 -0
  107. package/corpus/templates/design/actions/generate-design.ts +79 -12
  108. package/corpus/templates/design/actions/generate-screens.ts +57 -12
  109. package/corpus/templates/design/actions/get-figma-styles.ts +115 -0
  110. package/corpus/templates/design/actions/go-to-main-component.ts +254 -0
  111. package/corpus/templates/design/actions/grant-localhost-write-consent.ts +4 -3
  112. package/corpus/templates/design/actions/import-design-source.ts +4 -31
  113. package/corpus/templates/design/actions/import-figma-clipboard.ts +134 -0
  114. package/corpus/templates/design/actions/import-figma-frame.ts +95 -0
  115. package/corpus/templates/design/actions/index-design-system-with-builder.ts +16 -1
  116. package/corpus/templates/design/actions/list-design-components.ts +104 -0
  117. package/corpus/templates/design/actions/list-figma-library-assets.ts +1 -24
  118. package/corpus/templates/design/actions/open-component-source.ts +2 -4
  119. package/corpus/templates/design/actions/present-design-variants.ts +412 -16
  120. package/corpus/templates/design/actions/preview-source-edit.ts +14 -1
  121. package/corpus/templates/design/actions/run-design-audit.ts +25 -3
  122. package/corpus/templates/design/actions/show-design-questions.ts +10 -0
  123. package/corpus/templates/design/actions/swap-component-instance.ts +544 -0
  124. package/corpus/templates/design/actions/take-design-screenshot.ts +45 -60
  125. package/corpus/templates/design/actions/write-local-file.ts +25 -1
  126. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +152 -0
  127. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +1077 -58
  128. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +5 -5
  129. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +73 -21
  130. package/corpus/templates/design/app/components/design/EditPanel.tsx +16 -11
  131. package/corpus/templates/design/app/components/design/KeyboardShortcutsPanel.tsx +364 -0
  132. package/corpus/templates/design/app/components/design/LayersPanel.tsx +180 -53
  133. package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +0 -2
  134. package/corpus/templates/design/app/components/design/MotionDock.tsx +144 -21
  135. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1152 -167
  136. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +27 -5
  137. package/corpus/templates/design/app/components/design/ReviewPanel.tsx +23 -2
  138. package/corpus/templates/design/app/components/design/TokensPanel.tsx +63 -49
  139. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1293 -54
  140. package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +7 -0
  141. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +6 -1
  142. package/corpus/templates/design/app/components/design/bridge/motion-preview.bridge.ts +23 -6
  143. package/corpus/templates/design/app/components/design/bridge/sample.bridge.ts +7 -0
  144. package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +5 -0
  145. package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +14 -2
  146. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +37 -2
  147. package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open-guard.ts +25 -0
  148. package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open.ts +19 -1
  149. package/corpus/templates/design/app/components/design/code-workbench/model-registry.ts +43 -5
  150. package/corpus/templates/design/app/components/design/code-workbench/search/SearchView.tsx +27 -2
  151. package/corpus/templates/design/app/components/design/code-workbench/search/search-engine.ts +10 -1
  152. package/corpus/templates/design/app/components/design/code-workbench/store.tsx +19 -2
  153. package/corpus/templates/design/app/components/design/design-canvas/annotation-snapshot.ts +265 -0
  154. package/corpus/templates/design/app/components/design/design-canvas/annotation-submit.ts +16 -5
  155. package/corpus/templates/design/app/components/design/design-canvas/coordinate-transforms.ts +16 -2
  156. package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +7 -2
  157. package/corpus/templates/design/app/components/design/design-canvas/iframe-events.ts +3 -1
  158. package/corpus/templates/design/app/components/design/edit-panel/code-inspect-helpers.tsx +78 -8
  159. package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +451 -73
  160. package/corpus/templates/design/app/components/design/edit-panel/document-colors.ts +12 -4
  161. package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +398 -272
  162. package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +41 -7
  163. package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +16 -3
  164. package/corpus/templates/design/app/components/design/edit-panel/field-primitives.tsx +24 -4
  165. package/corpus/templates/design/app/components/design/edit-panel/fill-gradient-helpers.ts +222 -4
  166. package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +171 -78
  167. package/corpus/templates/design/app/components/design/edit-panel/inspector-controls.tsx +45 -5
  168. package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +299 -28
  169. package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +120 -150
  170. package/corpus/templates/design/app/components/design/edit-panel/position-helpers.ts +53 -1
  171. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +284 -117
  172. package/corpus/templates/design/app/components/design/edit-panel/selection-helpers.ts +81 -0
  173. package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +19 -14
  174. package/corpus/templates/design/app/components/design/edit-panel/style-options.ts +7 -0
  175. package/corpus/templates/design/app/components/design/edit-panel/typography-helpers.ts +155 -0
  176. package/corpus/templates/design/app/components/design/edit-panel/typography-properties.tsx +268 -46
  177. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +350 -31
  178. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +13 -4
  179. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +233 -23
  180. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +72 -2
  181. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +51 -11
  182. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +84 -11
  183. package/corpus/templates/design/app/components/design/inspector/index.ts +3 -0
  184. package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +552 -0
  185. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +157 -0
  186. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +53 -0
  187. package/corpus/templates/design/app/components/design/multi-screen/overview-layout.ts +184 -0
  188. package/corpus/templates/design/app/components/design/multi-screen/primitive-drop-target.ts +403 -26
  189. package/corpus/templates/design/app/components/design/multi-screen/types.ts +20 -1
  190. package/corpus/templates/design/app/components/design/types.ts +33 -0
  191. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +59 -7
  192. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +119 -17
  193. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +275 -63
  194. package/corpus/templates/design/app/hooks/use-question-flow.ts +14 -3
  195. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +67 -10
  196. package/corpus/templates/design/app/i18n/zh-TW.ts +91 -1
  197. package/corpus/templates/design/app/i18n-data.ts +1217 -10
  198. package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +577 -0
  199. package/corpus/templates/design/app/lib/agent-chat.ts +23 -0
  200. package/corpus/templates/design/app/lib/design-import.ts +24 -0
  201. package/corpus/templates/design/app/lib/figma-clipboard.ts +157 -0
  202. package/corpus/templates/design/app/lib/figma-svg-copy.ts +221 -0
  203. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +143 -30
  204. package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +15 -0
  205. package/corpus/templates/design/app/pages/design-editor/editor-session.ts +33 -0
  206. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +38 -0
  207. package/corpus/templates/design/app/pages/design-editor/overview-annotation-context.ts +157 -0
  208. package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +62 -6
  209. package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +245 -0
  210. package/corpus/templates/design/app/pages/design-editor/react-semantic-handoff.ts +586 -0
  211. package/corpus/templates/design/app/pages/design-editor/screen-auto-layout.ts +169 -0
  212. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +201 -1
  213. package/corpus/templates/design/changelog/2026-07-09-added-underline-strikethrough-and-text-case-uppercase-lowerc.md +6 -0
  214. package/corpus/templates/design/changelog/2026-07-09-annotate-now-draws-across-the-all-screens-canvas-without-swi.md +6 -0
  215. package/corpus/templates/design/changelog/2026-07-09-auto-layout-children-can-now-be-dragged-into-freeform-screen.md +6 -0
  216. package/corpus/templates/design/changelog/2026-07-09-board-shapes-now-stay-visible-and-nest-correctly-across-the-.md +6 -0
  217. package/corpus/templates/design/changelog/2026-07-09-component-source-navigation-now-opens-reliably-from-the-insp.md +6 -0
  218. package/corpus/templates/design/changelog/2026-07-09-cross-screen-local-react-layer-moves-now-hand-off-exact-sour.md +6 -0
  219. package/corpus/templates/design/changelog/2026-07-09-cross-screen-moves-undo-and-redo-now-keep-both-screens-stabl.md +6 -0
  220. package/corpus/templates/design/changelog/2026-07-09-detach-a-component-instance-into-plain-editable-eleme.md +6 -0
  221. package/corpus/templates/design/changelog/2026-07-09-dragging-layers-into-auto-layout-now-respects-ignore-auto-la.md +6 -0
  222. package/corpus/templates/design/changelog/2026-07-09-drawing-annotations-sent-to-the-agent-now-include-a-rendered.md +6 -0
  223. package/corpus/templates/design/changelog/2026-07-09-editor-sidebars-now-use-figma-matched-default-widths-for-a-r.md +6 -0
  224. package/corpus/templates/design/changelog/2026-07-09-empty-frames-and-rectangles-now-expose-full-auto-layout-cont.md +6 -0
  225. package/corpus/templates/design/changelog/2026-07-09-export-any-design-screen-as-a-real-vector-svg-for-figma-with.md +6 -0
  226. package/corpus/templates/design/changelog/2026-07-09-grid-auto-layout-now-uses-true-responsive-rows-and-columns-w.md +6 -0
  227. package/corpus/templates/design/changelog/2026-07-09-hidden-and-locked-screens-now-behave-consistently-between-la.md +6 -0
  228. package/corpus/templates/design/changelog/2026-07-09-image-fills-now-preserve-valid-urls-and-layered-fit-settings.md +6 -0
  229. package/corpus/templates/design/changelog/2026-07-09-import-figma-frames-as-pixel-accurate-design-screens-via-a-s.md +6 -0
  230. package/corpus/templates/design/changelog/2026-07-09-inspect-code-now-hides-internal-styling-metadata-and-wraps-l.md +6 -0
  231. package/corpus/templates/design/changelog/2026-07-09-inspector-blur-and-shadow-effects-now-preserve-other-effects.md +6 -0
  232. package/corpus/templates/design/changelog/2026-07-09-jump-to-a-components-other-instances-from-the-inspecto.md +6 -0
  233. package/corpus/templates/design/changelog/2026-07-09-keyboard-shortcuts-are-now-discoverable-in-a-figma-style-bot.md +6 -0
  234. package/corpus/templates/design/changelog/2026-07-09-layer-selection-now-keeps-cmd-or-ctrl-toggles-and-shift-rang.md +6 -0
  235. package/corpus/templates/design/changelog/2026-07-09-layers-dropped-into-auto-layout-now-participate-correctly-in.md +6 -0
  236. package/corpus/templates/design/changelog/2026-07-09-local-live-edit-screens-now-enter-and-leave-full-view-withou.md +6 -0
  237. package/corpus/templates/design/changelog/2026-07-09-local-preview-urls-now-live-in-the-inspector-instead-of-taki.md +6 -0
  238. package/corpus/templates/design/changelog/2026-07-09-local-react-layers-can-now-be-hidden-and-locked-from-layers-.md +6 -0
  239. package/corpus/templates/design/changelog/2026-07-09-local-react-layers-now-keep-exact-source-provenance-and-supp.md +6 -0
  240. package/corpus/templates/design/changelog/2026-07-09-local-react-visual-editing-now-loads-reliably-and-shows-live.md +6 -0
  241. package/corpus/templates/design/changelog/2026-07-09-paste-from-figma-cmd-v-now-imports-exact-editable-nodes-when.md +6 -0
  242. package/corpus/templates/design/changelog/2026-07-09-pressing-escape-after-selecting-a-screen-now-reveals-page-pr.md +6 -0
  243. package/corpus/templates/design/changelog/2026-07-09-right-click-overlapping-or-nested-objects-to-choose-the-exac.md +6 -0
  244. package/corpus/templates/design/changelog/2026-07-09-scale-edge-stretch-and-center-constraints-now-preserve-layer.md +6 -0
  245. package/corpus/templates/design/changelog/2026-07-09-screen-rows-can-now-be-reordered-in-layers-with-matching-can.md +6 -0
  246. package/corpus/templates/design/changelog/2026-07-09-screen-selection-stays-responsive-in-designs-with-hundreds-o.md +6 -0
  247. package/corpus/templates/design/changelog/2026-07-09-shift-a-now-enables-auto-layout-on-a-selected-screen-with-fl.md +6 -0
  248. package/corpus/templates/design/changelog/2026-07-09-swap-a-component-instance-for-another-from-the-libra.md +6 -0
  249. package/corpus/templates/design/changelog/2026-07-10-drawing-annotations-now-stay-available-to-retry-when-the.md +6 -0
  250. package/corpus/templates/design/e2e/global-setup.ts +3 -6
  251. package/corpus/templates/design/e2e/helpers.ts +27 -6
  252. package/corpus/templates/design/server/lib/design-to-figma-svg.ts +1412 -0
  253. package/corpus/templates/design/server/lib/figma-clipboard-match.ts +196 -0
  254. package/corpus/templates/design/server/lib/figma-node-import.ts +311 -0
  255. package/corpus/templates/design/server/lib/figma-node-to-html.ts +1334 -0
  256. package/corpus/templates/design/server/lib/figma-paste-fallback.ts +64 -0
  257. package/corpus/templates/design/server/lib/playwright-runtime.ts +78 -0
  258. package/corpus/templates/design/server/plugins/db.ts +41 -0
  259. package/corpus/templates/design/server/source-workspace.ts +64 -0
  260. package/corpus/templates/design/shared/board-file.ts +13 -2
  261. package/corpus/templates/design/shared/canvas-math.ts +231 -33
  262. package/corpus/templates/design/shared/code-layer.ts +122 -8
  263. package/corpus/templates/design/shared/component-library.ts +161 -0
  264. package/corpus/templates/design/shared/db-conflict.ts +27 -0
  265. package/corpus/templates/design/shared/design-source-capabilities.ts +2 -1
  266. package/corpus/templates/design/shared/figma-url.ts +149 -0
  267. package/corpus/templates/design/shared/pen-path.ts +16 -7
  268. package/corpus/templates/design/shared/source-mode.ts +1 -0
  269. package/corpus/templates/plan/app/components/plan/CanvasArea.tsx +7 -19
  270. package/corpus/templates/plan/changelog/2026-07-09-canvas-panning-now-keeps-zoom-fixed-even-at-the-edges.md +6 -0
  271. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +16 -1
  272. package/corpus/templates/slides/app/context/DeckContext.tsx +311 -70
  273. package/corpus/templates/slides/changelog/2026-07-09-fixed-the-slide-rail-going-permanently-stale-during-a-long-a.md +6 -0
  274. package/dist/agent/production-agent.d.ts +82 -7
  275. package/dist/agent/production-agent.d.ts.map +1 -1
  276. package/dist/agent/production-agent.js +180 -17
  277. package/dist/agent/production-agent.js.map +1 -1
  278. package/dist/agent/run-manager.d.ts.map +1 -1
  279. package/dist/agent/run-manager.js +63 -14
  280. package/dist/agent/run-manager.js.map +1 -1
  281. package/dist/agent/run-store.d.ts +46 -0
  282. package/dist/agent/run-store.d.ts.map +1 -1
  283. package/dist/agent/run-store.js +129 -22
  284. package/dist/agent/run-store.js.map +1 -1
  285. package/dist/cli/design-connect.d.ts +6 -0
  286. package/dist/cli/design-connect.d.ts.map +1 -1
  287. package/dist/cli/design-connect.js +336 -139
  288. package/dist/cli/design-connect.js.map +1 -1
  289. package/dist/cli/skills.d.ts.map +1 -1
  290. package/dist/cli/skills.js +14 -0
  291. package/dist/cli/skills.js.map +1 -1
  292. package/dist/client/AssistantChat.d.ts +2 -0
  293. package/dist/client/AssistantChat.d.ts.map +1 -1
  294. package/dist/client/AssistantChat.js +19 -3
  295. package/dist/client/AssistantChat.js.map +1 -1
  296. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  297. package/dist/client/MultiTabAssistantChat.js +38 -18
  298. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  299. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  300. package/dist/client/agent-chat-adapter.js +48 -12
  301. package/dist/client/agent-chat-adapter.js.map +1 -1
  302. package/dist/client/agent-chat.d.ts +60 -0
  303. package/dist/client/agent-chat.d.ts.map +1 -1
  304. package/dist/client/agent-chat.js +122 -1
  305. package/dist/client/agent-chat.js.map +1 -1
  306. package/dist/client/chat/index.d.ts +1 -1
  307. package/dist/client/chat/index.d.ts.map +1 -1
  308. package/dist/client/chat/index.js +1 -1
  309. package/dist/client/chat/index.js.map +1 -1
  310. package/dist/client/extensions/EmbeddedExtension.d.ts +12 -0
  311. package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
  312. package/dist/client/extensions/EmbeddedExtension.js +36 -2
  313. package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
  314. package/dist/client/index.d.ts +1 -1
  315. package/dist/client/index.d.ts.map +1 -1
  316. package/dist/client/index.js +1 -1
  317. package/dist/client/index.js.map +1 -1
  318. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
  319. package/dist/client/rich-markdown-editor/useCollabReconcile.js +18 -6
  320. package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
  321. package/dist/collab/awareness-store.d.ts +5 -0
  322. package/dist/collab/awareness-store.d.ts.map +1 -1
  323. package/dist/collab/awareness-store.js +19 -12
  324. package/dist/collab/awareness-store.js.map +1 -1
  325. package/dist/collab/awareness.d.ts +2 -2
  326. package/dist/collab/awareness.d.ts.map +1 -1
  327. package/dist/collab/client.d.ts.map +1 -1
  328. package/dist/collab/client.js +13 -5
  329. package/dist/collab/client.js.map +1 -1
  330. package/dist/collab/index.d.ts +1 -0
  331. package/dist/collab/index.d.ts.map +1 -1
  332. package/dist/collab/index.js +1 -0
  333. package/dist/collab/index.js.map +1 -1
  334. package/dist/collab/recent-edits.d.ts +3 -1
  335. package/dist/collab/recent-edits.d.ts.map +1 -1
  336. package/dist/collab/recent-edits.js +57 -2
  337. package/dist/collab/recent-edits.js.map +1 -1
  338. package/dist/collab/struct-routes.d.ts +1 -1
  339. package/dist/index.browser.d.ts +1 -1
  340. package/dist/index.browser.d.ts.map +1 -1
  341. package/dist/index.browser.js +1 -1
  342. package/dist/index.browser.js.map +1 -1
  343. package/dist/observability/routes.d.ts +5 -5
  344. package/dist/progress/routes.d.ts +1 -1
  345. package/dist/resources/handlers.d.ts +3 -3
  346. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  347. package/dist/server/agent-chat-plugin.js +87 -10
  348. package/dist/server/agent-chat-plugin.js.map +1 -1
  349. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  350. package/dist/server/builder-design-systems.d.ts +15 -0
  351. package/dist/server/builder-design-systems.d.ts.map +1 -1
  352. package/dist/server/builder-design-systems.js +9 -4
  353. package/dist/server/builder-design-systems.js.map +1 -1
  354. package/package.json +1 -1
@@ -1,10 +1,15 @@
1
1
  import { hashString } from "./board-surface-html";
2
- import { screenLocalRectToBoardGeometry } from "./coordinate-transforms";
2
+ import {
3
+ boardPointToScreenLocalPoint,
4
+ screenLocalRectToBoardGeometry,
5
+ } from "./coordinate-transforms";
3
6
  import {
4
7
  geometryContainsGeometry,
5
8
  geometryContainsPoint,
6
9
  } from "./frame-geometry";
7
10
  import type {
11
+ CrossScreenDropAxis,
12
+ CrossScreenDropPlacement,
8
13
  FrameGeometry,
9
14
  FrameGeometryById,
10
15
  Point,
@@ -15,16 +20,164 @@ export interface PrimitiveDropTarget {
15
20
  nodeId: string;
16
21
  screenId: string;
17
22
  boardRect: FrameGeometry;
23
+ /**
24
+ * Set when the drop resolves to a flow-insert slot between two auto-layout
25
+ * (flex/grid) children instead of a plain "append inside" drop — mirrors
26
+ * the cross-screen hit-test's placement/axis contract (see
27
+ * getCrossScreenDropGuideForHitTest) so the overview canvas draws the same
28
+ * Figma-style insertion LINE, and the same anchor + placement can be
29
+ * threaded straight through onPrimitiveReparent. Undefined means "inside"
30
+ * (append as the last/only child of `nodeId`), matching pre-existing
31
+ * behavior.
32
+ */
33
+ placement?: CrossScreenDropPlacement;
34
+ axis?: CrossScreenDropAxis;
35
+ /**
36
+ * The sibling node to anchor a before/after flow-insert against. Only set
37
+ * when `placement` is "before" or "after" — `nodeId` still identifies the
38
+ * containing auto-layout primitive so callers can resolve the drop's
39
+ * screen/highlight, while `anchorNodeId` is what the actual moveNode/
40
+ * moveNodeBetweenDocuments call should target as its anchor.
41
+ */
42
+ anchorNodeId?: string;
18
43
  }
19
44
 
20
45
  export interface ParsedScreenPrimitive {
21
46
  nodeId: string;
22
47
  screenId: string;
48
+ /** data-agent-native-node-id of the nearest ancestor primitive, if any. */
49
+ parentNodeId?: string;
23
50
  localLeft: number;
24
51
  localTop: number;
25
52
  localWidth: number;
26
53
  localHeight: number;
27
54
  isContainer: boolean;
55
+ /**
56
+ * Set when this primitive is itself an auto-layout (flex/grid) container,
57
+ * to the flow axis new children are inserted along ("x" for a row flex/
58
+ * multi-column grid, "y" for column flex/single-column grid). Undefined
59
+ * for plain absolute/canvas-frame containers, which only ever accept an
60
+ * "inside" (append) drop.
61
+ */
62
+ autoLayoutAxis?: CrossScreenDropAxis;
63
+ }
64
+
65
+ /**
66
+ * Mirrors hit-test.bridge.ts's parentFlowAxis: resolves the flow axis new
67
+ * children are inserted along for a flex/grid container, or undefined when
68
+ * the element isn't an auto-layout container at all. Kept in sync with that
69
+ * bridge implementation (which runs against live computed styles inside the
70
+ * iframe) — this version only has the authored inline style available, which
71
+ * is sufficient since auto-layout is always inspector-authored inline CSS.
72
+ */
73
+ function computeAutoLayoutAxis(style: {
74
+ display: string;
75
+ flexDirection: string;
76
+ flexWrap: string;
77
+ gridTemplateColumns: string;
78
+ }): CrossScreenDropAxis | undefined {
79
+ if (style.display === "flex" || style.display === "inline-flex") {
80
+ const direction = style.flexDirection || "row";
81
+ const wraps =
82
+ style.flexWrap === "wrap" || style.flexWrap === "wrap-reverse";
83
+ const isRow = direction.startsWith("row");
84
+ return isRow && !wraps ? "x" : "y";
85
+ }
86
+ if (style.display === "grid" || style.display === "inline-grid") {
87
+ const columns = (style.gridTemplateColumns || "")
88
+ .split(" ")
89
+ .filter(Boolean).length;
90
+ return columns > 1 ? "x" : "y";
91
+ }
92
+ return undefined;
93
+ }
94
+
95
+ /**
96
+ * Resolves a between-children flow-insert slot inside `container` from a
97
+ * screen-local drop point — the nearest child (by flow-axis center) becomes
98
+ * the anchor with before/after placement, exactly mirroring hit-test.bridge.
99
+ * ts's nearestChildInsertionTarget so overview-canvas drag-drop and in-iframe
100
+ * cross-screen drag-drop produce the same Figma-style insertion behavior.
101
+ * Returns null when the container isn't auto-layout or has no eligible
102
+ * children (callers fall back to "inside" append).
103
+ */
104
+ export function findAutoLayoutInsertionAnchor(
105
+ container: ParsedScreenPrimitive,
106
+ screenPrimitives: ParsedScreenPrimitive[],
107
+ localPoint: Point,
108
+ excludeNodeId: string | null,
109
+ ): { anchorNodeId: string; placement: "before" | "after" } | null {
110
+ const axis = container.autoLayoutAxis;
111
+ if (!axis) return null;
112
+ let best: ParsedScreenPrimitive | null = null;
113
+ let bestDistance = Infinity;
114
+ let placement: "before" | "after" = "after";
115
+ for (const sibling of screenPrimitives) {
116
+ if (sibling.parentNodeId !== container.nodeId) continue;
117
+ if (excludeNodeId && sibling.nodeId === excludeNodeId) continue;
118
+ const center =
119
+ axis === "x"
120
+ ? sibling.localLeft + sibling.localWidth / 2
121
+ : sibling.localTop + sibling.localHeight / 2;
122
+ const pointer = axis === "x" ? localPoint.x : localPoint.y;
123
+ const distance = Math.abs(pointer - center);
124
+ if (distance < bestDistance) {
125
+ bestDistance = distance;
126
+ best = sibling;
127
+ placement = pointer < center ? "before" : "after";
128
+ }
129
+ }
130
+ if (!best) return null;
131
+ return { anchorNodeId: best.nodeId, placement };
132
+ }
133
+
134
+ export function getPrimitiveLowZoomHitRect(
135
+ primitive: ParsedScreenPrimitive,
136
+ zoom: number,
137
+ minimumScreenPixels = 6,
138
+ ): FrameGeometry {
139
+ const scale = Math.max(0.0001, zoom / 100);
140
+ const minimumWorldSize = minimumScreenPixels / scale;
141
+ const width = Math.max(primitive.localWidth, minimumWorldSize);
142
+ const height = Math.max(primitive.localHeight, minimumWorldSize);
143
+ return {
144
+ x: primitive.localLeft - (width - primitive.localWidth) / 2,
145
+ y: primitive.localTop - (height - primitive.localHeight) / 2,
146
+ width,
147
+ height,
148
+ };
149
+ }
150
+
151
+ export function isPrimitiveContainer(args: {
152
+ tagName: string;
153
+ primitiveKind: string;
154
+ display: string;
155
+ borderRadius: string;
156
+ }): boolean {
157
+ const isDiv = args.tagName.toLowerCase() === "div";
158
+ const primitiveKind = args.primitiveKind.toLowerCase();
159
+ const isEllipse =
160
+ args.borderRadius === "50%" || args.borderRadius === "50% 50% 50% 50%";
161
+ const isTextAutoSize = args.display === "inline-block";
162
+ const isAutoLayout =
163
+ args.display === "flex" ||
164
+ args.display === "inline-flex" ||
165
+ args.display === "grid" ||
166
+ args.display === "inline-grid";
167
+ // Canvas frames are structural containers even before Auto layout is
168
+ // enabled. Treating only rectangles as freeform containers made a freshly
169
+ // drawn frame reject child drops until the user changed its display mode.
170
+ const isCanvasContainer =
171
+ isDiv &&
172
+ (primitiveKind === "rectangle" ||
173
+ primitiveKind === "rect" ||
174
+ primitiveKind === "frame");
175
+ return (
176
+ isDiv &&
177
+ !isEllipse &&
178
+ !isTextAutoSize &&
179
+ (isAutoLayout || isCanvasContainer)
180
+ );
28
181
  }
29
182
 
30
183
  export const primitiveParseCache = new Map<string, ParsedScreenPrimitive[]>();
@@ -60,6 +213,175 @@ export function __getPrimitiveParseCacheSizesForTests() {
60
213
  };
61
214
  }
62
215
 
216
+ type InlineNumericProperty =
217
+ | "width"
218
+ | "height"
219
+ | "left"
220
+ | "top"
221
+ | "paddingLeft"
222
+ | "paddingTop"
223
+ | "marginLeft"
224
+ | "marginRight"
225
+ | "marginTop"
226
+ | "marginBottom"
227
+ | "gap";
228
+
229
+ function inlineNumber(element: Element, property: InlineNumericProperty) {
230
+ const value = (element as HTMLElement).style[property];
231
+ const parsed = Number.parseFloat(String(value || ""));
232
+ return Number.isFinite(parsed) ? parsed : 0;
233
+ }
234
+
235
+ function elementInlineSize(element: Element, axis: "x" | "y") {
236
+ return inlineNumber(element, axis === "x" ? "width" : "height");
237
+ }
238
+
239
+ function cssPixelNumber(value: string | null | undefined) {
240
+ const match = String(value || "")
241
+ .trim()
242
+ .match(/^(-?\d+(?:\.\d+)?)px$/i);
243
+ const parsed = match?.[1] ? Number(match[1]) : Number.NaN;
244
+ return Number.isFinite(parsed) ? parsed : 0;
245
+ }
246
+
247
+ function estimatedTextLineWidth(
248
+ text: string,
249
+ fontSize: number,
250
+ letterSpacing: number,
251
+ ) {
252
+ let width = 0;
253
+ for (const character of Array.from(text)) {
254
+ if (/\s/.test(character)) width += fontSize * 0.33;
255
+ else if (/[MW@#%&]/.test(character)) width += fontSize * 0.82;
256
+ else if (/[ilI1|.,'`:;]/.test(character)) width += fontSize * 0.3;
257
+ else if (character.codePointAt(0)! > 0xff) width += fontSize;
258
+ else width += fontSize * 0.56;
259
+ }
260
+ return Math.max(
261
+ 1,
262
+ width + Math.max(0, Array.from(text).length - 1) * letterSpacing,
263
+ );
264
+ }
265
+
266
+ /**
267
+ * Deterministic, string/inline-style-only bounds for drawn auto-sized text.
268
+ * This intentionally avoids layout APIs so the same fallback works in SSR,
269
+ * tests, and before the live iframe answers. It is conservative enough for
270
+ * hit testing while honoring the authored typography and wrap contract.
271
+ */
272
+ export function authoredTextIntrinsicSize(element: Element) {
273
+ const style = (element as HTMLElement).style;
274
+ const fontSize = Math.max(1, cssPixelNumber(style.fontSize) || 16);
275
+ const numericLineHeight = Number.parseFloat(style.lineHeight);
276
+ const lineHeight = Math.max(
277
+ 1,
278
+ cssPixelNumber(style.lineHeight) ||
279
+ (Number.isFinite(numericLineHeight) && numericLineHeight > 0
280
+ ? numericLineHeight * fontSize
281
+ : fontSize * 1.2),
282
+ );
283
+ const letterSpacing = cssPixelNumber(style.letterSpacing);
284
+ const whiteSpace = style.whiteSpace || "normal";
285
+ const preservesLines = /^(?:pre|pre-wrap|pre-line|break-spaces)$/.test(
286
+ whiteSpace,
287
+ );
288
+ const rawText = element.textContent || "";
289
+ const lines = preservesLines
290
+ ? rawText.split(/\r?\n/)
291
+ : [rawText.replace(/\s+/g, " ").trim()];
292
+ const lineWidths = lines.map((line) =>
293
+ estimatedTextLineWidth(line, fontSize, letterSpacing),
294
+ );
295
+ const authoredWidth = cssPixelNumber(style.width);
296
+ const maxWidth = cssPixelNumber(style.maxWidth);
297
+ const wrapWidth = authoredWidth || maxWidth;
298
+ const mayWrap =
299
+ wrapWidth > 0 && whiteSpace !== "nowrap" && whiteSpace !== "pre";
300
+ const visualLineCount = lineWidths.reduce(
301
+ (count, width) =>
302
+ count + (mayWrap ? Math.max(1, Math.ceil(width / wrapWidth)) : 1),
303
+ 0,
304
+ );
305
+ const naturalWidth = Math.max(1, ...lineWidths);
306
+ return {
307
+ width: Math.max(
308
+ 1,
309
+ authoredWidth ||
310
+ (maxWidth ? Math.min(naturalWidth, maxWidth) : naturalWidth),
311
+ ),
312
+ height: Math.max(
313
+ 1,
314
+ cssPixelNumber(style.height) || Math.max(1, visualLineCount) * lineHeight,
315
+ ),
316
+ };
317
+ }
318
+
319
+ /**
320
+ * Approximates an authored node's screen-local position from inline layout.
321
+ * This parser is the no-iframe fallback used while a live bridge is absent;
322
+ * absolute descendants must accumulate positioned ancestors, and common
323
+ * single-line flex/block flows need their preceding siblings accounted for.
324
+ *
325
+ * Exported so DesignEditor.tsx's getAbsolutePositioningForNodeInHtml can
326
+ * reuse the same ancestor-walking logic instead of reading a node's own
327
+ * inline left/top in isolation (which is only correct for direct children of
328
+ * the screen root — see that function's call sites for the nested-container
329
+ * reparent fix this enables).
330
+ */
331
+ export function authoredElementPosition(element: Element): Point {
332
+ let x = 0;
333
+ let y = 0;
334
+ let cursor: Element | null = element;
335
+
336
+ while (cursor && cursor.parentElement) {
337
+ const htmlCursor = cursor as HTMLElement;
338
+ const style = htmlCursor.style;
339
+ const parent: Element = cursor.parentElement;
340
+ if (style.position === "fixed") {
341
+ x += inlineNumber(cursor, "left");
342
+ y += inlineNumber(cursor, "top");
343
+ break;
344
+ }
345
+ if (style.position === "absolute") {
346
+ x += inlineNumber(cursor, "left");
347
+ y += inlineNumber(cursor, "top");
348
+ } else {
349
+ const parentStyle = (parent as HTMLElement).style;
350
+ x += inlineNumber(parent, "paddingLeft");
351
+ y += inlineNumber(parent, "paddingTop");
352
+ const siblings: Element[] = Array.from(parent.children);
353
+ const index = siblings.indexOf(cursor);
354
+ if (index > 0) {
355
+ const previous = siblings.slice(0, index);
356
+ const gap = inlineNumber(parent, "gap");
357
+ const display = parentStyle.display;
358
+ const isFlex = display === "flex" || display === "inline-flex";
359
+ const isRow =
360
+ isFlex && !(parentStyle.flexDirection || "row").startsWith("column");
361
+ for (const sibling of previous as Element[]) {
362
+ if (isRow) {
363
+ x +=
364
+ elementInlineSize(sibling, "x") +
365
+ inlineNumber(sibling, "marginLeft") +
366
+ inlineNumber(sibling, "marginRight") +
367
+ gap;
368
+ } else {
369
+ y +=
370
+ elementInlineSize(sibling, "y") +
371
+ inlineNumber(sibling, "marginTop") +
372
+ inlineNumber(sibling, "marginBottom") +
373
+ (isFlex ? gap : 0);
374
+ }
375
+ }
376
+ }
377
+ }
378
+ cursor = parent;
379
+ if (cursor.tagName.toLowerCase() === "body") break;
380
+ }
381
+
382
+ return { x, y };
383
+ }
384
+
63
385
  export function parsePrimitivesFromScreen(
64
386
  screen: ScreenFile,
65
387
  ): ParsedScreenPrimitive[] {
@@ -93,40 +415,50 @@ export function parsePrimitivesFromScreen(
93
415
  const primitiveKind = (
94
416
  element.getAttribute("data-an-primitive") || ""
95
417
  ).toLowerCase();
96
- if (style.position !== "absolute") return;
97
-
98
- const left = parseFloat(style.left) || 0;
99
- const top = parseFloat(style.top) || 0;
100
- const width = parseFloat(style.width) || 0;
101
- const height = parseFloat(style.height) || 0;
418
+ const position = authoredElementPosition(element);
419
+ const intrinsicTextSize =
420
+ primitiveKind === "text" ? authoredTextIntrinsicSize(element) : null;
421
+ const width = parseFloat(style.width) || intrinsicTextSize?.width || 0;
422
+ const height = parseFloat(style.height) || intrinsicTextSize?.height || 0;
102
423
  if (width <= 0 || height <= 0) return;
103
424
 
104
- const isDiv = tag === "div";
105
- const isEllipse =
106
- style.borderRadius === "50%" ||
107
- style.borderRadius === "50% 50% 50% 50%";
108
- const isTextAutoSize = style.display === "inline-block";
109
- const isAutoLayout =
110
- style.display === "flex" ||
111
- style.display === "inline-flex" ||
112
- style.display === "grid" ||
113
- style.display === "inline-grid";
114
- const isCanvasRectangle =
115
- isDiv && (primitiveKind === "rectangle" || primitiveKind === "rect");
116
- const isContainer =
117
- isDiv &&
118
- !isEllipse &&
119
- !isTextAutoSize &&
120
- (isAutoLayout || isCanvasRectangle);
425
+ const isContainer = isPrimitiveContainer({
426
+ tagName: tag,
427
+ primitiveKind,
428
+ display: style.display,
429
+ borderRadius: style.borderRadius,
430
+ });
431
+ const autoLayoutAxis = computeAutoLayoutAxis({
432
+ display: style.display,
433
+ flexDirection: style.flexDirection,
434
+ flexWrap: style.flexWrap,
435
+ gridTemplateColumns: style.gridTemplateColumns,
436
+ });
437
+
438
+ // Nearest ancestor primitive id, used to resolve direct children of a
439
+ // container for auto-layout before/after anchor resolution — see
440
+ // findAutoLayoutInsertionAnchor.
441
+ let parentNodeId: string | undefined;
442
+ let ancestor: Element | null = element.parentElement;
443
+ while (ancestor && ancestor.tagName.toLowerCase() !== "body") {
444
+ const ancestorId = ancestor.getAttribute("data-agent-native-node-id");
445
+ if (ancestorId) {
446
+ parentNodeId = ancestorId;
447
+ break;
448
+ }
449
+ ancestor = ancestor.parentElement;
450
+ }
121
451
 
122
452
  result.push({
123
453
  nodeId,
124
454
  screenId: screen.id,
125
- localLeft: left,
126
- localTop: top,
455
+ parentNodeId,
456
+ localLeft: position.x,
457
+ localTop: position.y,
127
458
  localWidth: width,
128
459
  localHeight: height,
129
460
  isContainer,
461
+ autoLayoutAxis,
130
462
  });
131
463
  });
132
464
  } catch {
@@ -266,6 +598,51 @@ export function getPrimitiveDropTargetForPoint(
266
598
  };
267
599
  }
268
600
  }
601
+
602
+ // Auto-layout drop participation: when the winning container is itself a
603
+ // flex/grid container, resolve the nearest before/after sibling slot
604
+ // instead of always appending "inside" — matches the cross-screen
605
+ // hit-test's nearestChildInsertionTarget so overview-canvas primitive
606
+ // drags into an existing auto-layout screen get the same Figma insertion
607
+ // index/indicator behavior.
608
+ if (best) {
609
+ const containerPrimitive = primitives.find(
610
+ (primitive) => primitive.nodeId === best!.nodeId,
611
+ );
612
+ if (containerPrimitive?.autoLayoutAxis) {
613
+ const localPoint = options.identityCoordinateScreenIds?.has(
614
+ topScreen.screen.id,
615
+ )
616
+ ? point
617
+ : boardPointToScreenLocalPoint(point, topScreen.geometry, metadata);
618
+ const anchor = findAutoLayoutInsertionAnchor(
619
+ containerPrimitive,
620
+ primitives,
621
+ localPoint,
622
+ draggedNodeId,
623
+ );
624
+ if (anchor) {
625
+ const anchorPrimitive = primitives.find(
626
+ (primitive) => primitive.nodeId === anchor.anchorNodeId,
627
+ );
628
+ if (anchorPrimitive) {
629
+ best = {
630
+ nodeId: containerPrimitive.nodeId,
631
+ screenId: topScreen.screen.id,
632
+ boardRect: toBoardRect(
633
+ anchorPrimitive,
634
+ topScreen.geometry,
635
+ metadata,
636
+ ),
637
+ anchorNodeId: anchor.anchorNodeId,
638
+ placement: anchor.placement,
639
+ axis: containerPrimitive.autoLayoutAxis,
640
+ };
641
+ }
642
+ }
643
+ }
644
+ }
645
+
269
646
  return best;
270
647
  }
271
648
 
@@ -118,6 +118,12 @@ export interface MultiScreenCanvasProps {
118
118
  zoom: number;
119
119
  activeId?: string | null;
120
120
  selectedScreenIds?: string[];
121
+ /** Hidden screen/file rows retain geometry but do not render or participate
122
+ * in overview hit testing, fit, or selection until shown again. */
123
+ hiddenScreenIds?: ReadonlySet<string> | readonly string[];
124
+ /** Locked screen/file rows remain visible but cannot be selected or
125
+ * transformed directly from the overview canvas. */
126
+ lockedScreenIds?: ReadonlySet<string> | readonly string[];
121
127
  fullViewScreenIds?: string[];
122
128
  activeScreenHasHoveredChild?: boolean;
123
129
  hoveredChildScreenId?: string | null;
@@ -149,9 +155,22 @@ export interface MultiScreenCanvasProps {
149
155
  onPrimitiveReparent?: (args: {
150
156
  sourceNodeId: string;
151
157
  sourceScreenId: string;
158
+ /**
159
+ * The moveNode/moveNodeBetweenDocuments anchor: the containing primitive
160
+ * itself when `placement` is "inside" (append), or a sibling child of
161
+ * that container when `placement` is "before"/"after" (flow-insert at a
162
+ * specific index) — see PrimitiveDropTarget.anchorNodeId in
163
+ * primitive-drop-target.ts, which resolves which one to pass.
164
+ */
152
165
  targetNodeId: string;
153
166
  targetScreenId: string;
154
- placement: "inside";
167
+ /**
168
+ * "inside" appends into the target container (absolute-drop parity with
169
+ * the historic behavior). "before"/"after" flow-inserts next to
170
+ * `targetNodeId` at the resolved auto-layout index, mirroring
171
+ * onCrossScreenElementDrop's targetAnchorPlacement contract.
172
+ */
173
+ placement: "before" | "after" | "inside";
155
174
  }) => void;
156
175
  onCreateScreenFrame?: (geometry: FrameGeometry) => void;
157
176
  onDeleteSelection?: (ids: string[]) => boolean | void;
@@ -1,3 +1,5 @@
1
+ import type { ElementProvenance } from "@shared/source-mode";
2
+
1
3
  export interface PortableStyleSnapshotNode {
2
4
  sourceId?: string;
3
5
  path: number[];
@@ -10,11 +12,26 @@ export interface PortableStyleSnapshot {
10
12
  nodes: PortableStyleSnapshotNode[];
11
13
  }
12
14
 
15
+ export interface RuntimeStructureMoveRequest {
16
+ requestId: number;
17
+ subject: { selector: string; sourceId?: string | null };
18
+ anchor: { selector: string; sourceId?: string | null };
19
+ placement: "before" | "after" | "inside";
20
+ }
21
+
13
22
  export interface ElementInfo {
14
23
  tagName: string;
15
24
  componentName?: string;
16
25
  id?: string;
17
26
  sourceId?: string;
27
+ /**
28
+ * Source location reported by the canvas bridge. React development builds
29
+ * derive this from jsxDEV/Fiber debug frames; instrumented runtimes may emit
30
+ * the equivalent data-source-* attributes. This is provenance only, not a
31
+ * stable source identity: callers must still verify the file contents and
32
+ * location before any write.
33
+ */
34
+ provenance?: ElementProvenance;
18
35
  /**
19
36
  * Node-id integrity (id-on-demand): a durable candidate id the bridge minted
20
37
  * for this element because it has no stable `data-agent-native-node-id`
@@ -51,6 +68,15 @@ export interface ElementInfo {
51
68
  primitiveKind?: string;
52
69
  portableStyleSnapshot?: PortableStyleSnapshot;
53
70
  boundingRect: { x: number; y: number; width: number; height: number };
71
+ /** Exact bounds of the selected element's direct parent in the same
72
+ * document coordinate space as `boundingRect`. Constraint edits use this
73
+ * to preserve edge gaps, center offsets, and proportional Scale geometry. */
74
+ parentBoundingRect?: {
75
+ x: number;
76
+ y: number;
77
+ width: number;
78
+ height: number;
79
+ };
54
80
  textContent?: string;
55
81
  htmlContent?: string;
56
82
  /** Direct element children; text nodes are ignored. */
@@ -97,6 +123,13 @@ export interface ElementSelectionIntent {
97
123
  ctrlKey?: boolean;
98
124
  }
99
125
 
126
+ export interface CanvasLayerHitCandidate {
127
+ key: string;
128
+ label: string;
129
+ screenId?: string;
130
+ info: ElementInfo;
131
+ }
132
+
100
133
  export type DeviceFrameType = "none" | "desktop" | "tablet" | "mobile";
101
134
 
102
135
  export const DEVICE_FRAME_VIEWPORTS = {