@agent-native/core 0.92.9 → 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.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +29 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +181 -15
- package/corpus/core/src/agent/run-manager.ts +31 -4
- package/corpus/core/src/agent/run-store.ts +80 -0
- package/corpus/core/src/cli/design-connect.ts +433 -151
- package/corpus/core/src/cli/skills.ts +14 -0
- package/corpus/core/src/client/AssistantChat.tsx +25 -0
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +40 -6
- package/corpus/core/src/client/agent-chat.ts +165 -1
- package/corpus/core/src/client/chat/index.ts +9 -1
- package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +38 -2
- package/corpus/core/src/client/index.ts +5 -0
- package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +18 -7
- package/corpus/core/src/collab/awareness-store.ts +23 -12
- package/corpus/core/src/collab/client.ts +16 -5
- package/corpus/core/src/collab/index.ts +4 -0
- package/corpus/core/src/collab/recent-edits.ts +65 -2
- package/corpus/core/src/deploy/build.ts +133 -5
- package/corpus/core/src/index.browser.ts +1 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +98 -11
- package/corpus/core/src/server/builder-design-systems.ts +30 -4
- package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +1 -1
- package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +12 -6
- package/corpus/templates/clips/AGENTS.md +4 -0
- package/corpus/templates/clips/actions/create-recording.ts +2 -0
- package/corpus/templates/clips/actions/lib/create-recording-schema.ts +5 -3
- package/corpus/templates/clips/actions/request-transcript.ts +102 -33
- package/corpus/templates/clips/app/components/library/library-grid.tsx +1 -0
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +59 -19
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +48 -4
- package/corpus/templates/clips/app/components/player/video-player.tsx +17 -12
- package/corpus/templates/clips/app/i18n/ar-SA.ts +1 -0
- package/corpus/templates/clips/app/i18n/de-DE.ts +1 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +1 -0
- package/corpus/templates/clips/app/i18n/es-ES.ts +1 -0
- package/corpus/templates/clips/app/i18n/fr-FR.ts +1 -0
- package/corpus/templates/clips/app/i18n/hi-IN.ts +1 -0
- package/corpus/templates/clips/app/i18n/ja-JP.ts +1 -0
- package/corpus/templates/clips/app/i18n/ko-KR.ts +1 -0
- package/corpus/templates/clips/app/i18n/pt-BR.ts +1 -0
- package/corpus/templates/clips/app/i18n/zh-CN.ts +1 -0
- package/corpus/templates/clips/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +70 -37
- package/corpus/templates/clips/app/routes/record.tsx +17 -4
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +2 -0
- package/corpus/templates/clips/changelog/2026-07-09-desktop-popover-sits-closer-to-the-menu-bar.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-desktop-recording-optimization-progress-stays-visible-until-the-clip-opens.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-fixed-large-video-file-uploads-failing-before-their-resumabl.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-fixed-new-video-uploads-defaulting-to-private.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-long-recordings-now-get-enough-time-to-download-their-media-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-meeting-notes-no-longer-lowers-your-microphone-volume-for-ot.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-on-mobile-tapping-a-playing-clip-reveals-playback-controls-w.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-regenerate-any-clip-transcript-from-its-saved-recording-or-r.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-slack-previews-now-show-the-clip-length-alongside-its-descri.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +12 -2
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +8 -1
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +8 -5
- package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +5 -5
- package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +3 -0
- package/corpus/templates/clips/desktop/src/styles.css +6 -3
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +29 -11
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +1 -1
- package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +103 -21
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +117 -39
- package/corpus/templates/clips/server/lib/slack-unfurls.ts +20 -1
- package/corpus/templates/clips/server/lib/streaming-upload-mode.ts +10 -4
- package/corpus/templates/clips/shared/recording-core.ts +12 -0
- package/corpus/templates/content/AGENTS.md +7 -6
- package/corpus/templates/content/actions/_document-flush.ts +132 -17
- package/corpus/templates/content/actions/_notion-action-utils.ts +15 -0
- package/corpus/templates/content/actions/create-and-link-notion-page.ts +2 -0
- package/corpus/templates/content/actions/link-notion-page.ts +2 -0
- package/corpus/templates/content/actions/pull-document.ts +5 -7
- package/corpus/templates/content/actions/pull-notion-page.ts +2 -0
- package/corpus/templates/content/actions/push-notion-page.ts +10 -0
- package/corpus/templates/content/actions/resolve-notion-sync-conflict.ts +2 -0
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +88 -23
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +32 -2
- package/corpus/templates/content/app/hooks/use-notion.ts +6 -6
- package/corpus/templates/content/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/content/app/i18n-data.ts +18 -0
- package/corpus/templates/content/changelog/2026-07-09-notion-conflict-choices-and-version-restores-preserve-docume.md +6 -0
- package/corpus/templates/content/server/lib/notion-sync.ts +80 -64
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +29 -2
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +86 -0
- package/corpus/templates/design/.agents/skills/export-handoff/SKILL.md +57 -0
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +11 -0
- package/corpus/templates/design/AGENTS.md +45 -10
- package/corpus/templates/design/actions/add-localhost-screens.ts +66 -13
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +45 -36
- package/corpus/templates/design/actions/apply-motion-edit.ts +25 -31
- package/corpus/templates/design/actions/apply-shader-fill.ts +29 -42
- package/corpus/templates/design/actions/detach-component-instance.ts +337 -0
- package/corpus/templates/design/actions/export-design-as-figma-svg.ts +219 -0
- package/corpus/templates/design/actions/generate-design.ts +79 -12
- package/corpus/templates/design/actions/generate-screens.ts +57 -12
- package/corpus/templates/design/actions/get-figma-styles.ts +115 -0
- package/corpus/templates/design/actions/go-to-main-component.ts +254 -0
- package/corpus/templates/design/actions/grant-localhost-write-consent.ts +4 -3
- package/corpus/templates/design/actions/import-design-source.ts +4 -31
- package/corpus/templates/design/actions/import-figma-clipboard.ts +134 -0
- package/corpus/templates/design/actions/import-figma-frame.ts +95 -0
- package/corpus/templates/design/actions/index-design-system-with-builder.ts +16 -1
- package/corpus/templates/design/actions/list-design-components.ts +104 -0
- package/corpus/templates/design/actions/list-figma-library-assets.ts +1 -24
- package/corpus/templates/design/actions/open-component-source.ts +2 -4
- package/corpus/templates/design/actions/present-design-variants.ts +412 -16
- package/corpus/templates/design/actions/preview-source-edit.ts +14 -1
- package/corpus/templates/design/actions/run-design-audit.ts +25 -3
- package/corpus/templates/design/actions/show-design-questions.ts +10 -0
- package/corpus/templates/design/actions/swap-component-instance.ts +544 -0
- package/corpus/templates/design/actions/take-design-screenshot.ts +45 -60
- package/corpus/templates/design/actions/write-local-file.ts +25 -1
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +152 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +1077 -58
- package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +5 -5
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +73 -21
- package/corpus/templates/design/app/components/design/EditPanel.tsx +16 -11
- package/corpus/templates/design/app/components/design/KeyboardShortcutsPanel.tsx +364 -0
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +180 -53
- package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +0 -2
- package/corpus/templates/design/app/components/design/MotionDock.tsx +144 -21
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1152 -167
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +27 -5
- package/corpus/templates/design/app/components/design/ReviewPanel.tsx +23 -2
- package/corpus/templates/design/app/components/design/TokensPanel.tsx +63 -49
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1293 -54
- package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +7 -0
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +6 -1
- package/corpus/templates/design/app/components/design/bridge/motion-preview.bridge.ts +23 -6
- package/corpus/templates/design/app/components/design/bridge/sample.bridge.ts +7 -0
- package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +5 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +14 -2
- package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +37 -2
- package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open-guard.ts +25 -0
- package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open.ts +19 -1
- package/corpus/templates/design/app/components/design/code-workbench/model-registry.ts +43 -5
- package/corpus/templates/design/app/components/design/code-workbench/search/SearchView.tsx +27 -2
- package/corpus/templates/design/app/components/design/code-workbench/search/search-engine.ts +10 -1
- package/corpus/templates/design/app/components/design/code-workbench/store.tsx +19 -2
- package/corpus/templates/design/app/components/design/design-canvas/annotation-snapshot.ts +265 -0
- package/corpus/templates/design/app/components/design/design-canvas/annotation-submit.ts +16 -5
- package/corpus/templates/design/app/components/design/design-canvas/coordinate-transforms.ts +16 -2
- package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +7 -2
- package/corpus/templates/design/app/components/design/design-canvas/iframe-events.ts +3 -1
- package/corpus/templates/design/app/components/design/edit-panel/code-inspect-helpers.tsx +78 -8
- package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +451 -73
- package/corpus/templates/design/app/components/design/edit-panel/document-colors.ts +12 -4
- package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +398 -272
- package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +41 -7
- package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +16 -3
- package/corpus/templates/design/app/components/design/edit-panel/field-primitives.tsx +24 -4
- package/corpus/templates/design/app/components/design/edit-panel/fill-gradient-helpers.ts +222 -4
- package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +171 -78
- package/corpus/templates/design/app/components/design/edit-panel/inspector-controls.tsx +45 -5
- package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +299 -28
- package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +120 -150
- package/corpus/templates/design/app/components/design/edit-panel/position-helpers.ts +53 -1
- package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +284 -117
- package/corpus/templates/design/app/components/design/edit-panel/selection-helpers.ts +81 -0
- package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +19 -14
- package/corpus/templates/design/app/components/design/edit-panel/style-options.ts +7 -0
- package/corpus/templates/design/app/components/design/edit-panel/typography-helpers.ts +155 -0
- package/corpus/templates/design/app/components/design/edit-panel/typography-properties.tsx +268 -46
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +350 -31
- package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +13 -4
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +233 -23
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +72 -2
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +51 -11
- package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +84 -11
- package/corpus/templates/design/app/components/design/inspector/index.ts +3 -0
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +552 -0
- package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +157 -0
- package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +53 -0
- package/corpus/templates/design/app/components/design/multi-screen/overview-layout.ts +184 -0
- package/corpus/templates/design/app/components/design/multi-screen/primitive-drop-target.ts +403 -26
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +20 -1
- package/corpus/templates/design/app/components/design/types.ts +33 -0
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +59 -7
- package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +119 -17
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +275 -63
- package/corpus/templates/design/app/hooks/use-question-flow.ts +14 -3
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +67 -10
- package/corpus/templates/design/app/i18n/zh-TW.ts +91 -1
- package/corpus/templates/design/app/i18n-data.ts +1217 -10
- package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +577 -0
- package/corpus/templates/design/app/lib/agent-chat.ts +23 -0
- package/corpus/templates/design/app/lib/design-import.ts +24 -0
- package/corpus/templates/design/app/lib/figma-clipboard.ts +157 -0
- package/corpus/templates/design/app/lib/figma-svg-copy.ts +221 -0
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +143 -30
- package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +15 -0
- package/corpus/templates/design/app/pages/design-editor/editor-session.ts +33 -0
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +38 -0
- package/corpus/templates/design/app/pages/design-editor/overview-annotation-context.ts +157 -0
- package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +62 -6
- package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +245 -0
- package/corpus/templates/design/app/pages/design-editor/react-semantic-handoff.ts +586 -0
- package/corpus/templates/design/app/pages/design-editor/screen-auto-layout.ts +169 -0
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +201 -1
- package/corpus/templates/design/changelog/2026-07-09-added-underline-strikethrough-and-text-case-uppercase-lowerc.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-annotate-now-draws-across-the-all-screens-canvas-without-swi.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-auto-layout-children-can-now-be-dragged-into-freeform-screen.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-board-shapes-now-stay-visible-and-nest-correctly-across-the-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-component-source-navigation-now-opens-reliably-from-the-insp.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-cross-screen-local-react-layer-moves-now-hand-off-exact-sour.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-cross-screen-moves-undo-and-redo-now-keep-both-screens-stabl.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-detach-a-component-instance-into-plain-editable-eleme.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-dragging-layers-into-auto-layout-now-respects-ignore-auto-la.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-drawing-annotations-sent-to-the-agent-now-include-a-rendered.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-editor-sidebars-now-use-figma-matched-default-widths-for-a-r.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-empty-frames-and-rectangles-now-expose-full-auto-layout-cont.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-export-any-design-screen-as-a-real-vector-svg-for-figma-with.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-grid-auto-layout-now-uses-true-responsive-rows-and-columns-w.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-hidden-and-locked-screens-now-behave-consistently-between-la.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-image-fills-now-preserve-valid-urls-and-layered-fit-settings.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-import-figma-frames-as-pixel-accurate-design-screens-via-a-s.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-inspect-code-now-hides-internal-styling-metadata-and-wraps-l.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-inspector-blur-and-shadow-effects-now-preserve-other-effects.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-jump-to-a-components-other-instances-from-the-inspecto.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-keyboard-shortcuts-are-now-discoverable-in-a-figma-style-bot.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-layer-selection-now-keeps-cmd-or-ctrl-toggles-and-shift-rang.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-layers-dropped-into-auto-layout-now-participate-correctly-in.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-live-edit-screens-now-enter-and-leave-full-view-withou.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-preview-urls-now-live-in-the-inspector-instead-of-taki.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-react-layers-can-now-be-hidden-and-locked-from-layers-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-react-layers-now-keep-exact-source-provenance-and-supp.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-react-visual-editing-now-loads-reliably-and-shows-live.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-paste-from-figma-cmd-v-now-imports-exact-editable-nodes-when.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-pressing-escape-after-selecting-a-screen-now-reveals-page-pr.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-right-click-overlapping-or-nested-objects-to-choose-the-exac.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-scale-edge-stretch-and-center-constraints-now-preserve-layer.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-screen-rows-can-now-be-reordered-in-layers-with-matching-can.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-screen-selection-stays-responsive-in-designs-with-hundreds-o.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-shift-a-now-enables-auto-layout-on-a-selected-screen-with-fl.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-swap-a-component-instance-for-another-from-the-libra.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-drawing-annotations-now-stay-available-to-retry-when-the.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +3 -6
- package/corpus/templates/design/e2e/helpers.ts +27 -6
- package/corpus/templates/design/server/lib/design-to-figma-svg.ts +1412 -0
- package/corpus/templates/design/server/lib/figma-clipboard-match.ts +196 -0
- package/corpus/templates/design/server/lib/figma-node-import.ts +311 -0
- package/corpus/templates/design/server/lib/figma-node-to-html.ts +1334 -0
- package/corpus/templates/design/server/lib/figma-paste-fallback.ts +64 -0
- package/corpus/templates/design/server/lib/playwright-runtime.ts +78 -0
- package/corpus/templates/design/server/plugins/db.ts +41 -0
- package/corpus/templates/design/server/source-workspace.ts +64 -0
- package/corpus/templates/design/shared/board-file.ts +13 -2
- package/corpus/templates/design/shared/canvas-math.ts +231 -33
- package/corpus/templates/design/shared/code-layer.ts +122 -8
- package/corpus/templates/design/shared/component-library.ts +161 -0
- package/corpus/templates/design/shared/db-conflict.ts +27 -0
- package/corpus/templates/design/shared/design-source-capabilities.ts +2 -1
- package/corpus/templates/design/shared/figma-url.ts +149 -0
- package/corpus/templates/design/shared/pen-path.ts +16 -7
- package/corpus/templates/design/shared/source-mode.ts +1 -0
- package/corpus/templates/plan/app/components/plan/CanvasArea.tsx +7 -19
- package/corpus/templates/plan/changelog/2026-07-09-canvas-panning-now-keeps-zoom-fixed-even-at-the-edges.md +6 -0
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +16 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +311 -70
- package/corpus/templates/slides/changelog/2026-07-09-fixed-the-slide-rail-going-permanently-stale-during-a-long-a.md +6 -0
- package/dist/agent/production-agent.d.ts +79 -6
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +161 -14
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +29 -5
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +46 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +61 -0
- package/dist/agent/run-store.js.map +1 -1
- package/dist/cli/design-connect.d.ts +6 -0
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +336 -139
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +14 -0
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +19 -3
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +38 -18
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat.d.ts +60 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +122 -1
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js +1 -1
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts +12 -0
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +36 -2
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.js +18 -6
- package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
- package/dist/collab/awareness-store.d.ts +5 -0
- package/dist/collab/awareness-store.d.ts.map +1 -1
- package/dist/collab/awareness-store.js +19 -12
- package/dist/collab/awareness-store.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +13 -5
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/index.d.ts +1 -0
- package/dist/collab/index.d.ts.map +1 -1
- package/dist/collab/index.js +1 -0
- package/dist/collab/index.js.map +1 -1
- package/dist/collab/recent-edits.d.ts +3 -1
- package/dist/collab/recent-edits.d.ts.map +1 -1
- package/dist/collab/recent-edits.js +57 -2
- package/dist/collab/recent-edits.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/deploy/build.d.ts +24 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +102 -5
- package/dist/deploy/build.js.map +1 -1
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +87 -10
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/builder-design-systems.d.ts +15 -0
- package/dist/server/builder-design-systems.d.ts.map +1 -1
- package/dist/server/builder-design-systems.js +9 -4
- package/dist/server/builder-design-systems.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { hashString } from "./board-surface-html";
|
|
2
|
-
import {
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
const
|
|
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
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
style.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
style.display
|
|
112
|
-
style.
|
|
113
|
-
style.
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
126
|
-
|
|
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
|
-
|
|
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 = {
|