@agent-native/core 0.90.1 → 0.90.2
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 +14 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/AgentPanel.tsx +1 -1
- package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +11 -6
- package/corpus/core/src/client/use-action.ts +39 -2
- package/corpus/core/src/client/use-db-sync.ts +44 -18
- package/corpus/core/src/db/create-get-db.ts +32 -2
- package/corpus/core/src/server/framework-request-handler.ts +52 -4
- package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +5 -0
- package/corpus/templates/assets/.agents/skills/logo-composite/SKILL.md +34 -6
- package/corpus/templates/assets/AGENTS.md +23 -4
- package/corpus/templates/assets/actions/_generation-preset-settings.ts +48 -0
- package/corpus/templates/assets/actions/_helpers.ts +8 -1
- package/corpus/templates/assets/actions/_preset-skeleton-validation.ts +64 -0
- package/corpus/templates/assets/actions/create-generation-preset.ts +11 -3
- package/corpus/templates/assets/actions/generate-image-batch.ts +7 -2
- package/corpus/templates/assets/actions/generate-image.ts +342 -25
- package/corpus/templates/assets/actions/get-library.ts +4 -3
- package/corpus/templates/assets/actions/navigate.ts +2 -1
- package/corpus/templates/assets/actions/refresh-generation-run.ts +5 -1
- package/corpus/templates/assets/actions/update-asset.ts +1 -0
- package/corpus/templates/assets/actions/update-generation-preset.ts +8 -1
- package/corpus/templates/assets/actions/view-screen.ts +8 -1
- package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +9 -1
- package/corpus/templates/assets/app/hooks/use-image-model-menu.ts +1 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +11 -0
- package/corpus/templates/assets/app/i18n/zh-TW.ts +64 -0
- package/corpus/templates/assets/app/i18n-data.ts +650 -0
- package/corpus/templates/assets/app/routes/asset.$id.tsx +2 -1
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +44 -33
- package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +1474 -0
- package/corpus/templates/assets/app/routes/library.tsx +43 -1
- package/corpus/templates/assets/server/lib/generation.ts +366 -44
- package/corpus/templates/assets/server/lib/image-processing.ts +252 -0
- package/corpus/templates/assets/server/lib/preset-skeleton.ts +137 -0
- package/corpus/templates/assets/shared/api.ts +47 -0
- package/corpus/templates/clips/app/components/library/library-layout.tsx +7 -2
- package/corpus/templates/clips/app/components/library/sort-menu.tsx +1 -1
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +114 -33
- package/corpus/templates/clips/app/routes/_app.library._index.tsx +27 -1
- package/corpus/templates/clips/app/routes/record.tsx +157 -68
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +5 -5
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +20 -3
- package/corpus/templates/clips/shared/finalize-recovery.ts +23 -3
- package/corpus/templates/content/AGENTS.md +52 -52
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +188 -8
- package/corpus/templates/content/actions/_builder-docs-client.ts +41 -3
- package/corpus/templates/content/actions/_database-source-utils.ts +998 -160
- package/corpus/templates/content/actions/_database-utils.ts +44 -4
- package/corpus/templates/content/actions/_notion-action-utils.ts +6 -2
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +23 -1
- package/corpus/templates/content/actions/attach-content-database-source.ts +85 -12
- package/corpus/templates/content/actions/change-content-database-source-role.ts +9 -1
- package/corpus/templates/content/actions/delete-content-database.ts +1 -0
- package/corpus/templates/content/actions/get-document.ts +11 -2
- package/corpus/templates/content/actions/list-content-databases.ts +57 -9
- package/corpus/templates/content/actions/prepare-builder-source-review.ts +23 -6
- package/corpus/templates/content/actions/refresh-content-database-source.ts +26 -3
- package/corpus/templates/content/actions/restore-content-database.ts +1 -0
- package/corpus/templates/content/actions/update-document.ts +43 -0
- package/corpus/templates/content/app/components/editor/BuilderBodySyncingNotice.tsx +21 -0
- package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +0 -1
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +70 -28
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +69 -17
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +4 -4
- package/corpus/templates/content/app/components/editor/body-hydration.ts +112 -0
- package/corpus/templates/content/app/components/editor/builder-body-hydration-pump.ts +52 -0
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +9076 -2876
- package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +41 -1
- package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +36 -11
- package/corpus/templates/content/app/components/editor/previewDocumentSaveController.ts +21 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +11 -1
- package/corpus/templates/content/app/components/sidebar/DocumentTreeItem.tsx +11 -8
- package/corpus/templates/content/app/global.css +41 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +346 -42
- package/corpus/templates/content/app/hooks/use-db-sync.ts +9 -0
- package/corpus/templates/content/app/hooks/use-documents.ts +47 -0
- package/corpus/templates/content/app/hooks/use-notion.ts +12 -10
- package/corpus/templates/content/app/i18n/zh-TW.ts +35 -0
- package/corpus/templates/content/app/i18n-data.ts +355 -0
- package/corpus/templates/content/app/root.tsx +22 -0
- package/corpus/templates/content/changelog/2026-07-01-builder-database-sources-keep-loading-rows-in-the-background.md +6 -0
- package/corpus/templates/content/changelog/2026-07-01-builder-source-attach-starts-with-usable-rows.md +6 -0
- package/corpus/templates/content/changelog/2026-07-01-builder-source-attachment-now-stays-connected-after-large.md +6 -0
- package/corpus/templates/content/changelog/2026-07-01-builder-source-refreshes-now-show-progress-for-large-docs-blog.md +6 -0
- package/corpus/templates/content/changelog/2026-07-01-database-pages-now-delete-to-trash-without-route-errors.md +6 -0
- package/corpus/templates/content/changelog/2026-07-02-builder-source-refreshes-recover-from-stalled-background-row.md +6 -0
- package/corpus/templates/content/changelog/2026-07-02-builder-sourced-rows-open-with-sync-protection.md +6 -0
- package/corpus/templates/content/changelog/2026-07-02-database-rows-and-pages-open-faster-from-recently-loaded-dat.md +6 -0
- package/corpus/templates/content/changelog/2026-07-02-preview-panels-close-reliably-narrow-sidebar-row-actions-sta.md +6 -0
- package/corpus/templates/content/changelog/2026-07-06-builder-sync-progress-no-longer-shows-continue.md +6 -0
- package/corpus/templates/content/shared/api.ts +13 -0
- package/corpus/templates/content/shared/builder-mdx.ts +16 -3
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +23 -13
- package/corpus/templates/design/.agents/skills/responsive-breakpoints/SKILL.md +98 -0
- package/corpus/templates/design/.agents/skills/shader-fills/SKILL.md +162 -0
- package/corpus/templates/design/AGENTS.md +9 -2
- package/corpus/templates/design/actions/add-breakpoint.ts +6 -3
- package/corpus/templates/design/actions/apply-a11y-fix.ts +57 -37
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +41 -20
- package/corpus/templates/design/actions/apply-motion-edit.ts +251 -38
- package/corpus/templates/design/actions/apply-shader-fill.ts +90 -66
- package/corpus/templates/design/actions/apply-visual-edit.ts +282 -55
- package/corpus/templates/design/actions/create-component.ts +29 -60
- package/corpus/templates/design/actions/create-file.ts +9 -2
- package/corpus/templates/design/actions/duplicate-design.ts +31 -2
- package/corpus/templates/design/actions/edit-design.ts +36 -38
- package/corpus/templates/design/actions/generate-design-title.ts +87 -0
- package/corpus/templates/design/actions/generate-design.ts +53 -18
- package/corpus/templates/design/actions/generate-screens.ts +108 -4
- package/corpus/templates/design/actions/get-motion-timeline.ts +35 -7
- package/corpus/templates/design/actions/insert-asset.ts +34 -29
- package/corpus/templates/design/actions/insert-design-native-asset.ts +129 -32
- package/corpus/templates/design/actions/insert-figma-library-asset.ts +35 -30
- package/corpus/templates/design/actions/present-design-variants.ts +7 -2
- package/corpus/templates/design/actions/remove-motion-timeline.ts +31 -36
- package/corpus/templates/design/actions/update-file.ts +190 -75
- package/corpus/templates/design/app/components/design/BreakpointBar.tsx +403 -0
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +469 -222
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +708 -53
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +83 -3
- package/corpus/templates/design/app/components/design/EditPanel.tsx +1091 -6948
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +419 -85
- package/corpus/templates/design/app/components/design/MotionDock.tsx +1124 -103
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +2610 -1398
- package/corpus/templates/design/app/components/design/ReadOnlyDesignBanner.tsx +22 -0
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2182 -235
- package/corpus/templates/design/app/components/design/bridge/motion-preview.bridge.ts +187 -11
- package/corpus/templates/design/app/components/design/bridge/shader-fill-preview.bridge.ts +376 -1
- package/corpus/templates/design/app/components/design/bridge/shader-runtime.bridge.ts +746 -0
- package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +17 -0
- package/corpus/templates/design/app/components/design/code-workbench/SideBar.tsx +1 -1
- package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +1 -3
- package/corpus/templates/design/app/components/design/code-workbench/quickinput/QuickInput.tsx +1 -1
- package/corpus/templates/design/app/components/design/edit-panel/appearance-properties.tsx +518 -0
- package/corpus/templates/design/app/components/design/edit-panel/code-inspect-helpers.tsx +562 -0
- package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +763 -0
- package/corpus/templates/design/app/components/design/edit-panel/document-colors.ts +94 -0
- package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +780 -0
- package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +446 -0
- package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +79 -0
- package/corpus/templates/design/app/components/design/edit-panel/field-primitives.tsx +315 -0
- package/corpus/templates/design/app/components/design/edit-panel/fill-gradient-helpers.ts +344 -0
- package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +594 -0
- package/corpus/templates/design/app/components/design/edit-panel/frame-presets-panel.tsx +119 -0
- package/corpus/templates/design/app/components/design/edit-panel/inspector-controls.tsx +248 -0
- package/corpus/templates/design/app/components/design/edit-panel/interaction-state-helpers.ts +45 -0
- package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +693 -0
- package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +724 -0
- package/corpus/templates/design/app/components/design/edit-panel/position-helpers.ts +207 -0
- package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +628 -0
- package/corpus/templates/design/app/components/design/edit-panel/selection-helpers.ts +91 -0
- package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +649 -0
- package/corpus/templates/design/app/components/design/edit-panel/style-change-types.ts +118 -0
- package/corpus/templates/design/app/components/design/edit-panel/style-options.ts +88 -0
- package/corpus/templates/design/app/components/design/edit-panel/transform-helpers.ts +100 -0
- package/corpus/templates/design/app/components/design/edit-panel/typography-helpers.ts +117 -0
- package/corpus/templates/design/app/components/design/edit-panel/typography-properties.tsx +501 -0
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +91 -40
- package/corpus/templates/design/app/components/design/inspector/BreakpointOverrideIndicator.tsx +82 -0
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +189 -87
- package/corpus/templates/design/app/components/design/inspector/GlslShaderPanel.tsx +1097 -0
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +44 -0
- package/corpus/templates/design/app/components/design/inspector/InteractionStatePanel.tsx +258 -0
- package/corpus/templates/design/app/components/design/inspector/MotionKeyframeDiamond.tsx +144 -0
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +99 -9
- package/corpus/templates/design/app/components/design/inspector/frame-size-presets.ts +116 -0
- package/corpus/templates/design/app/components/design/inspector/index.ts +26 -0
- package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +29 -0
- package/corpus/templates/design/app/components/design/multi-screen/alt-hover-measurement.ts +171 -0
- package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +220 -0
- package/corpus/templates/design/app/components/design/multi-screen/chrome-transitions.ts +35 -0
- package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +134 -0
- package/corpus/templates/design/app/components/design/multi-screen/culling.ts +185 -0
- package/corpus/templates/design/app/components/design/multi-screen/gradient-overlay-geometry.ts +120 -0
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +892 -0
- package/corpus/templates/design/app/components/design/multi-screen/vector-edit-geometry.ts +21 -0
- package/corpus/templates/design/app/components/design/types.ts +15 -0
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +109 -5
- package/corpus/templates/design/app/global.css +8 -8
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +259 -2
- package/corpus/templates/design/app/i18n/zh-TW.ts +163 -9
- package/corpus/templates/design/app/i18n-breakpoints.ts +205 -0
- package/corpus/templates/design/app/i18n-data.ts +1664 -152
- package/corpus/templates/design/app/i18n-motion.ts +563 -0
- package/corpus/templates/design/app/lib/design-import.ts +73 -0
- package/corpus/templates/design/app/pages/Index.tsx +41 -22
- package/corpus/templates/design/changelog/2026-06-29-design-inspector-controls-now-match-figmas-softer-dark-chrome.md +1 -1
- package/corpus/templates/design/changelog/2026-06-30-design-now-has-a-figma-style-left-rail-for-file-agent-assets.md +1 -1
- package/corpus/templates/design/changelog/2026-06-30-design-tools-now-use-a-quieter-figma-style-list-layout.md +1 -1
- package/corpus/templates/design/changelog/2026-06-30-multi-select-outlines-now-stay-consistent-across-all-screens.md +1 -1
- package/corpus/templates/design/changelog/2026-07-03-canvas-interactions-now-match-figma-rotation-aware-resizing-.md +1 -1
- package/corpus/templates/design/changelog/2026-07-03-layers-panel-matches-figma-top-layer-on-top-drag-with-auto-s.md +1 -1
- package/corpus/templates/design/changelog/2026-07-05-designs-get-ai-generated-names-from-your-prompt.md +6 -0
- package/corpus/templates/design/changelog/2026-07-05-local-code-screens-keep-their-connection-when-duplicated-and.md +6 -0
- package/corpus/templates/design/changelog/2026-07-05-press-a-to-draw-screens-on-the-canvas-inside-a-screen-it-dr.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-3d-rotation-and-perspective-controls-on-every-element.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-ai-generated-and-duplicated-screens-now-get-their-editor-sel.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-applying-shaders-and-fills-in-quick-succession-can-no-longer.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-breakpoint-frames-in-the-overview-now-support-click-to-selec.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-breakpoint-segments-in-the-inspector-now-show-a-device-icon-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-breakpoint-targeting-now-lives-in-one-compact-control-in-the.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-canvas-edits-can-no-longer-be-overwritten-by-stale-collabora.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-canvas-edits-inside-screens-save-reliably-again.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-cleaner-inspector-removed-the-ask-ai-box-from-the-design-tab.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-clicking-empty-canvas-space-now-deselects-an-element-inside-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-dragging-an-element-onto-a-rectangle-now-nests-it-inside-wit.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-dragging-screens-and-objects-on-the-canvas-is-now-much-smoot.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-drawing-a-shape-or-text-on-the-canvas-no-longer-flashes-away.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-dropping-an-element-between-two-others-inside-a-screen-now-s.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-duplicating-a-screen-now-places-the-copy-exactly-where-you-d.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-edit-gradients-directly-on-elements-inside-screens-scale-str.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-edits-from-collaborators-and-the-agent-now-update-the-canvas.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-fixed-a-bug-where-most-style-position-and-text-edits-briefly.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-fixed-a-confusing-raw-error-message-when-a-file-upload-fails.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-fixed-a-rare-case-where-an-edit-could-be-silently-overwritte.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-fixed-inserted-assets-sometimes-disappearing-reappearing-or-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-fixed-inspector-value-scrubbing-producing-erratic-numbers-an.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-fixed-padding-gap-and-min-max-size-scrubbing-not-updating-th.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-fixed-text-stroke-color-turning-black-and-glyphs-disappearin.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-fixed-the-collapsed-effects-and-stroke-inspector-sections-sh.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-fixed-the-new-design-dialog-closing-unexpectedly-when-using-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-fixed-the-typography-section-missing-when-selecting-text-nes.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-full-view-no-longer-flashes-back-to-the-overview-on-entry-no.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-keyframe-animation-timeline-per-property-keyframes-easing-cu.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-moving-restyling-and-scrubbing-values-on-elements-in-ai-gene.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-padding-and-corner-radius-value-scrubbing-now-snaps-to-whole.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-padding-handles-now-only-resize-on-the-handle-line-itself-sh.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-preview-and-edit-hover-focus-and-pressed-states-with-real-cs.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-promoting-an-element-to-a-component-now-works-correctly-for-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-reduced-url-history-churn-and-selection-overlay-flicker-whil.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-removed-the-decorative-dot-before-screen-names-in-the-overvi.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-responsive-breakpoints-edit-at-any-width-with-cascading-over.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-screen-labels-no-longer-turn-blue-when-you-hover-inside-the-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-scrolling-a-screen-with-an-element-selected-stays-smooth-on-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-selecting-multiple-elements-and-dragging-now-moves-the-whole.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-selection-borders-handles-and-value-readouts-now-stay-the-sa.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-selection-handles-and-editing-chrome-now-stay-a-constant-siz.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-shader-fills-and-effects-ai-authored-or-preset-glsl-shaders-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-text-drawn-on-the-canvas-now-defaults-to-white-and-inter-in-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-text-dropped-into-a-shape-now-stays-readable-instead-of-disa.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-the-add-tweak-controls-prompt-no-longer-jumps-to-the-corner-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-the-padding-value-readout-now-stays-visible-while-you-hover-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-the-selected-element-attachment-now-clears-from-the-chat-com.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-the-zoom-menu-is-more-compact-with-tight-rows-and-right-alig.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-undo-and-redo-no-longer-flash-the-screen-changes-now-apply-i.md +6 -0
- package/corpus/templates/design/changelog/2026-07-06-zoom-presets-like-zoom-to-50-now-stay-on-the-focused-screen-.md +6 -0
- package/corpus/templates/design/server/lib/import-design-files.ts +11 -2
- package/corpus/templates/design/server/source-workspace.ts +139 -59
- package/corpus/templates/design/shared/board-file.ts +11 -2
- package/corpus/templates/design/shared/breakpoint-media.ts +543 -0
- package/corpus/templates/design/shared/canvas-math.ts +354 -35
- package/corpus/templates/design/shared/code-layer.ts +277 -8
- package/corpus/templates/design/shared/design-state.ts +11 -4
- package/corpus/templates/design/shared/interaction-states.ts +548 -0
- package/corpus/templates/design/shared/motion-compiler.ts +186 -23
- package/corpus/templates/design/shared/motion-easing.ts +294 -0
- package/corpus/templates/design/shared/motion-timeline.ts +400 -34
- package/corpus/templates/design/shared/prompt-title.ts +95 -0
- package/corpus/templates/design/shared/responsive-classes.ts +448 -10
- package/corpus/templates/design/shared/screen-annotation.ts +46 -0
- package/corpus/templates/design/shared/shader-fills.ts +1009 -0
- package/corpus/templates/design/shared/shader-presets.ts +852 -4
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +15 -2
- package/corpus/templates/slides/app/components/editor/ImportButton.tsx +10 -1
- package/corpus/templates/slides/app/lib/upload-response.ts +71 -0
- package/dist/client/AgentPanel.js +1 -1
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.js +11 -6
- package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
- package/dist/client/use-action.d.ts +3 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +34 -3
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/use-db-sync.d.ts +4 -0
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +37 -18
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/create-get-db.d.ts +25 -0
- package/dist/db/create-get-db.d.ts.map +1 -1
- package/dist/db/create-get-db.js +25 -2
- package/dist/db/create-get-db.js.map +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +37 -1
- package/dist/server/framework-request-handler.js.map +1 -1
- package/package.json +1 -1
- package/corpus/templates/design/app/components/design/inspector/InspectorAiActions.tsx +0 -153
- package/corpus/templates/design/app/hooks/useAgentEditRequest.ts +0 -133
- package/corpus/templates/design/app/pages/DesignEditor.tsx +0 -22924
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isSafeCssUrlReference,
|
|
3
|
+
removeBreakpointMediaDeclaration,
|
|
4
|
+
setBreakpointMediaDeclaration,
|
|
5
|
+
} from "./breakpoint-media.js";
|
|
1
6
|
import {
|
|
2
7
|
isComponentInstance,
|
|
3
8
|
instanceFromNode,
|
|
@@ -8,6 +13,8 @@ import {
|
|
|
8
13
|
getPropertyClasses,
|
|
9
14
|
parseClassGroups,
|
|
10
15
|
parseClassToken,
|
|
16
|
+
removeMaxWidthPropertyClass,
|
|
17
|
+
setMaxWidthPropertyClass,
|
|
11
18
|
setPropertyClass,
|
|
12
19
|
removePropertyClass,
|
|
13
20
|
utilityStem,
|
|
@@ -64,6 +71,9 @@ export type VisualStyleProperty =
|
|
|
64
71
|
| "background"
|
|
65
72
|
| "background-color"
|
|
66
73
|
| "background-image"
|
|
74
|
+
| "background-size"
|
|
75
|
+
| "background-repeat"
|
|
76
|
+
| "background-position"
|
|
67
77
|
| "background-blend-mode"
|
|
68
78
|
| "fill"
|
|
69
79
|
| "fill-opacity"
|
|
@@ -103,6 +113,8 @@ export type VisualStyleProperty =
|
|
|
103
113
|
| "outline-style"
|
|
104
114
|
| "outline-color"
|
|
105
115
|
| "outline-offset"
|
|
116
|
+
| "-webkit-text-stroke-width"
|
|
117
|
+
| "-webkit-text-stroke-color"
|
|
106
118
|
| "box-shadow"
|
|
107
119
|
| "text-shadow"
|
|
108
120
|
| "filter"
|
|
@@ -235,6 +247,22 @@ export type EditCapability =
|
|
|
235
247
|
confidence: number;
|
|
236
248
|
reason?: string;
|
|
237
249
|
}
|
|
250
|
+
| {
|
|
251
|
+
/**
|
|
252
|
+
* Breakpoint-scoped raw style editing (§6.4) — the `@media` fallback
|
|
253
|
+
* for values responsive class prefixes can't express. Writes into the
|
|
254
|
+
* managed `<style data-agent-native-breakpoints>` block via
|
|
255
|
+
* `breakpoint-media.ts`, targeting the node's stable
|
|
256
|
+
* `data-agent-native-node-id`.
|
|
257
|
+
*/
|
|
258
|
+
kind: "breakpoint-style";
|
|
259
|
+
/** Inclusive upper viewport bound (px) the edit was applied below. */
|
|
260
|
+
maxWidthPx: number;
|
|
261
|
+
operations: Array<"set" | "remove">;
|
|
262
|
+
properties: string[];
|
|
263
|
+
confidence: number;
|
|
264
|
+
reason?: string;
|
|
265
|
+
}
|
|
238
266
|
| {
|
|
239
267
|
kind: "text";
|
|
240
268
|
operations: Array<"setTextContent">;
|
|
@@ -246,6 +274,13 @@ export type EditCapability =
|
|
|
246
274
|
operations: Array<"moveNode">;
|
|
247
275
|
confidence: number;
|
|
248
276
|
reason?: string;
|
|
277
|
+
}
|
|
278
|
+
| {
|
|
279
|
+
/** Single plain-attribute writes (see AttributeEditIntent). */
|
|
280
|
+
kind: "attribute";
|
|
281
|
+
operations: Array<"set">;
|
|
282
|
+
confidence: number;
|
|
283
|
+
reason?: string;
|
|
249
284
|
};
|
|
250
285
|
|
|
251
286
|
export interface CodeLayerNode {
|
|
@@ -390,6 +425,24 @@ export interface TextEditIntent {
|
|
|
390
425
|
html?: string;
|
|
391
426
|
}
|
|
392
427
|
|
|
428
|
+
/**
|
|
429
|
+
* Node-id integrity (id-on-demand): sets or replaces a single plain HTML
|
|
430
|
+
* attribute on the target element. Introduced so the host can persist the
|
|
431
|
+
* bridge's minted `pendingNodeId` (see ElementInfo.pendingNodeId) as the
|
|
432
|
+
* element's real `data-agent-native-node-id` the moment an id-less node is
|
|
433
|
+
* selected — every subsequent id-keyed operation (move/reorder, style
|
|
434
|
+
* commits, motion tracks, scrub) then resolves normally. Not limited to that
|
|
435
|
+
* attribute name; kept general so other single-attribute host writes can
|
|
436
|
+
* reuse the same deterministic path instead of a full-document
|
|
437
|
+
* find/replace-and-resave.
|
|
438
|
+
*/
|
|
439
|
+
export interface AttributeEditIntent {
|
|
440
|
+
kind: "attribute";
|
|
441
|
+
target: EditIntentTarget;
|
|
442
|
+
name: string;
|
|
443
|
+
value: string;
|
|
444
|
+
}
|
|
445
|
+
|
|
393
446
|
export interface MoveNodeEditIntent {
|
|
394
447
|
kind: "moveNode";
|
|
395
448
|
target: EditIntentTarget;
|
|
@@ -485,17 +538,50 @@ export interface ResponsiveClassEditIntent {
|
|
|
485
538
|
* rejected as `"conflict"` rather than applied. Ignored for `"remove"`.
|
|
486
539
|
*/
|
|
487
540
|
from?: string;
|
|
541
|
+
/**
|
|
542
|
+
* Framer-style desktop-down scope (§6.4 breakpoint bar). When set, the
|
|
543
|
+
* edit writes a `max-[<maxWidthPx>px]:` scoped token instead of a
|
|
544
|
+
* min-width `prefix` token, and `prefix` is ignored. The bound comes from
|
|
545
|
+
* `breakpointUpperBoundPx` (just below the next-wider frame). `from`
|
|
546
|
+
* guards are not applied to max-width scopes.
|
|
547
|
+
*/
|
|
548
|
+
maxWidthPx?: number;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Breakpoint-scoped raw style edit — the `@media` fallback for values that
|
|
553
|
+
* responsive class prefixes can't express (exact px positions from canvas
|
|
554
|
+
* drags, rgb()/calc() values, …). Persists into the managed
|
|
555
|
+
* `<style data-agent-native-breakpoints>` block as a
|
|
556
|
+
* `@media (max-width: <maxWidthPx>px)` rule targeting the element's
|
|
557
|
+
* `data-agent-native-node-id` (stamped automatically when missing).
|
|
558
|
+
*
|
|
559
|
+
* - `operation: "set"` (default) writes/overwrites the declaration.
|
|
560
|
+
* - `operation: "remove"` deletes it, falling back to the base value.
|
|
561
|
+
*/
|
|
562
|
+
export interface BreakpointStyleEditIntent {
|
|
563
|
+
kind: "breakpoint-style";
|
|
564
|
+
target: EditIntentTarget;
|
|
565
|
+
/** Inclusive upper viewport bound (px) the override applies below. */
|
|
566
|
+
maxWidthPx: number;
|
|
567
|
+
/** CSS property (camelCase or kebab-case). */
|
|
568
|
+
property: string;
|
|
569
|
+
/** CSS value. Required for `"set"`; ignored for `"remove"`. */
|
|
570
|
+
value?: string;
|
|
571
|
+
operation?: "set" | "remove";
|
|
488
572
|
}
|
|
489
573
|
|
|
490
574
|
export type EditIntent =
|
|
491
575
|
| StyleEditIntent
|
|
492
576
|
| ClassEditIntent
|
|
493
577
|
| TextEditIntent
|
|
578
|
+
| AttributeEditIntent
|
|
494
579
|
| MoveNodeEditIntent
|
|
495
580
|
| WrapNodesEditIntent
|
|
496
581
|
| UnwrapEditIntent
|
|
497
582
|
| AutoLayoutEditIntent
|
|
498
|
-
| ResponsiveClassEditIntent
|
|
583
|
+
| ResponsiveClassEditIntent
|
|
584
|
+
| BreakpointStyleEditIntent;
|
|
499
585
|
|
|
500
586
|
export interface EditIntentResolution {
|
|
501
587
|
status: "resolved" | "conflict" | "unsupported";
|
|
@@ -598,6 +684,9 @@ const STYLE_PROPERTIES = [
|
|
|
598
684
|
"background",
|
|
599
685
|
"background-color",
|
|
600
686
|
"background-image",
|
|
687
|
+
"background-size",
|
|
688
|
+
"background-repeat",
|
|
689
|
+
"background-position",
|
|
601
690
|
"background-blend-mode",
|
|
602
691
|
"fill",
|
|
603
692
|
"fill-opacity",
|
|
@@ -637,6 +726,8 @@ const STYLE_PROPERTIES = [
|
|
|
637
726
|
"outline-style",
|
|
638
727
|
"outline-color",
|
|
639
728
|
"outline-offset",
|
|
729
|
+
"-webkit-text-stroke-width",
|
|
730
|
+
"-webkit-text-stroke-color",
|
|
640
731
|
"box-shadow",
|
|
641
732
|
"text-shadow",
|
|
642
733
|
"filter",
|
|
@@ -696,6 +787,12 @@ const STYLE_PROPERTY_ALIASES: Record<string, VisualStyleProperty> = {
|
|
|
696
787
|
shadow: "box-shadow",
|
|
697
788
|
};
|
|
698
789
|
|
|
790
|
+
// Matches url(...) in double-quoted, single-quoted, or unquoted form so each
|
|
791
|
+
// reference inside a (possibly multi-layer) background-image value can be
|
|
792
|
+
// checked individually against isSafeCssUrlReference.
|
|
793
|
+
const URL_IN_VALUE_RE =
|
|
794
|
+
/\burl\s*\(\s*(?:"([^"]*)"|'([^']*)'|([^)'"]*?))\s*\)/gi;
|
|
795
|
+
|
|
699
796
|
const VOID_TAGS = new Set([
|
|
700
797
|
"area",
|
|
701
798
|
"base",
|
|
@@ -1084,16 +1181,55 @@ function normalizeStyleProperty(property: string): VisualStyleProperty | null {
|
|
|
1084
1181
|
return normalized as VisualStyleProperty;
|
|
1085
1182
|
}
|
|
1086
1183
|
|
|
1184
|
+
/**
|
|
1185
|
+
* `background-image` is the one property where `url(...)` is a legitimate,
|
|
1186
|
+
* expected value (image fills — see `ImageFillControls`/
|
|
1187
|
+
* `imageFillToBackgroundStyles`). Every `url(...)` reference in the value is
|
|
1188
|
+
* checked with the same scheme allowlist the breakpoint-scoped media-block
|
|
1189
|
+
* path uses (`isSafeCssUrlReference`, which itself rejects control
|
|
1190
|
+
* characters and `<>"'`): http(s), protocol-relative, relative/root paths,
|
|
1191
|
+
* and `data:image/...` are allowed; `javascript:` and other non-image
|
|
1192
|
+
* schemes are not. The `background` shorthand is deliberately NOT included
|
|
1193
|
+
* here — keep it on the strict no-url path below.
|
|
1194
|
+
*
|
|
1195
|
+
* A `data:image/...` URI legitimately contains a `;` before `base64,`, so a
|
|
1196
|
+
* validated `url(...)` is excised before the generic `<>{};` breakout check
|
|
1197
|
+
* below runs — that check only ever sees the CSS around the reference.
|
|
1198
|
+
*/
|
|
1199
|
+
function isSafeBackgroundImageValue(value: string): string | false {
|
|
1200
|
+
URL_IN_VALUE_RE.lastIndex = 0;
|
|
1201
|
+
let match: RegExpExecArray | null;
|
|
1202
|
+
let lastIndex = 0;
|
|
1203
|
+
let withoutValidatedParts = "";
|
|
1204
|
+
while ((match = URL_IN_VALUE_RE.exec(value))) {
|
|
1205
|
+
const raw = match[1] ?? match[2] ?? match[3] ?? "";
|
|
1206
|
+
if (!isSafeCssUrlReference(raw)) return false;
|
|
1207
|
+
withoutValidatedParts += value.slice(lastIndex, match.index);
|
|
1208
|
+
lastIndex = URL_IN_VALUE_RE.lastIndex;
|
|
1209
|
+
}
|
|
1210
|
+
withoutValidatedParts += value.slice(lastIndex);
|
|
1211
|
+
// Anything left that still looks like "url(" wasn't matched by the
|
|
1212
|
+
// well-formed pattern above (malformed/unterminated) — reject.
|
|
1213
|
+
if (/url\s*\(/i.test(withoutValidatedParts)) return false;
|
|
1214
|
+
return withoutValidatedParts;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1087
1217
|
function isSafeStyleValue(
|
|
1088
1218
|
property: VisualStyleProperty,
|
|
1089
1219
|
value: string,
|
|
1090
1220
|
): boolean {
|
|
1091
1221
|
const trimmed = value.trim();
|
|
1092
1222
|
if (!trimmed) return false;
|
|
1093
|
-
if (/[<>{};]/.test(trimmed)) return false;
|
|
1094
1223
|
if (/expression\s*\(/i.test(trimmed)) return false;
|
|
1095
1224
|
if (/javascript\s*:/i.test(trimmed)) return false;
|
|
1096
|
-
if (/url\s*\(/i.test(trimmed))
|
|
1225
|
+
if (/url\s*\(/i.test(trimmed)) {
|
|
1226
|
+
if (property !== "background-image") return false;
|
|
1227
|
+
const withoutValidatedUrls = isSafeBackgroundImageValue(trimmed);
|
|
1228
|
+
if (withoutValidatedUrls === false) return false;
|
|
1229
|
+
if (/[<>{};]/.test(withoutValidatedUrls)) return false;
|
|
1230
|
+
} else if (/[<>{};]/.test(trimmed)) {
|
|
1231
|
+
return false;
|
|
1232
|
+
}
|
|
1097
1233
|
if (property === "display") {
|
|
1098
1234
|
return [
|
|
1099
1235
|
"block",
|
|
@@ -2625,6 +2761,31 @@ function applyClassEdit(
|
|
|
2625
2761
|
};
|
|
2626
2762
|
}
|
|
2627
2763
|
|
|
2764
|
+
// Same shape as the bridge's own attributeOverrides guard (editor-chrome.bridge.ts)
|
|
2765
|
+
// — alphanumeric/dash/colon/dot/underscore, must start with a letter, never an
|
|
2766
|
+
// `on*` event handler. Deliberately conservative: this path is for host-side
|
|
2767
|
+
// bookkeeping writes (pending node-id persistence today), not general-purpose
|
|
2768
|
+
// attribute editing, so unknown/unsafe names are rejected rather than guessed at.
|
|
2769
|
+
const SAFE_ATTRIBUTE_NAME = /^(?!on)[a-zA-Z][a-zA-Z0-9:_.-]*$/;
|
|
2770
|
+
|
|
2771
|
+
function applyAttributeEdit(
|
|
2772
|
+
html: string,
|
|
2773
|
+
element: ParsedElement,
|
|
2774
|
+
intent: AttributeEditIntent,
|
|
2775
|
+
): { content: string; capability: EditCapability } | PatchResultStatus {
|
|
2776
|
+
if (!intent.name || !SAFE_ATTRIBUTE_NAME.test(intent.name)) {
|
|
2777
|
+
return "unsupported";
|
|
2778
|
+
}
|
|
2779
|
+
return {
|
|
2780
|
+
content: replaceOrInsertAttribute(html, element, intent.name, intent.value),
|
|
2781
|
+
capability: {
|
|
2782
|
+
kind: "attribute",
|
|
2783
|
+
operations: ["set"],
|
|
2784
|
+
confidence: 0.95,
|
|
2785
|
+
},
|
|
2786
|
+
};
|
|
2787
|
+
}
|
|
2788
|
+
|
|
2628
2789
|
function sanitizeTextEditHtml(html: string): string {
|
|
2629
2790
|
return html
|
|
2630
2791
|
.replace(
|
|
@@ -2724,6 +2885,12 @@ function applyResponsiveClassEdit(
|
|
|
2724
2885
|
intent: ResponsiveClassEditIntent,
|
|
2725
2886
|
): { content: string; capability: EditCapability } | PatchResultStatus {
|
|
2726
2887
|
const currentClass = attributeValue(element, "class") ?? "";
|
|
2888
|
+
const maxWidthPx =
|
|
2889
|
+
intent.maxWidthPx !== undefined &&
|
|
2890
|
+
Number.isFinite(intent.maxWidthPx) &&
|
|
2891
|
+
intent.maxWidthPx > 0
|
|
2892
|
+
? Math.round(intent.maxWidthPx)
|
|
2893
|
+
: undefined;
|
|
2727
2894
|
|
|
2728
2895
|
let nextClass: string;
|
|
2729
2896
|
if (intent.operation === "remove") {
|
|
@@ -2732,15 +2899,19 @@ function applyResponsiveClassEdit(
|
|
|
2732
2899
|
return "unsupported";
|
|
2733
2900
|
}
|
|
2734
2901
|
if (!isSafeClassToken(intent.stem)) return "unsupported";
|
|
2735
|
-
nextClass =
|
|
2902
|
+
nextClass =
|
|
2903
|
+
maxWidthPx !== undefined
|
|
2904
|
+
? removeMaxWidthPropertyClass(currentClass, maxWidthPx, intent.stem)
|
|
2905
|
+
: removePropertyClass(currentClass, intent.prefix, intent.stem);
|
|
2736
2906
|
} else {
|
|
2737
|
-
// "add" and "replace" both use
|
|
2907
|
+
// "add" and "replace" both use the same replace-if-same-stem setter.
|
|
2738
2908
|
if (!intent.utility) return "unsupported";
|
|
2739
2909
|
if (!isSafeClassToken(intent.utility)) return "unsupported";
|
|
2740
|
-
if (intent.from) {
|
|
2910
|
+
if (intent.from && maxWidthPx === undefined) {
|
|
2741
2911
|
// `from` guard: the utility the caller expects to be effective at this
|
|
2742
2912
|
// prefix. On mismatch (stale selection / wrong element) reject instead
|
|
2743
|
-
// of silently overwriting whatever is actually there.
|
|
2913
|
+
// of silently overwriting whatever is actually there. Max-width scopes
|
|
2914
|
+
// skip the guard — the desktop-down cascade has no prefix analog.
|
|
2744
2915
|
if (!isSafeClassToken(intent.from)) return "unsupported";
|
|
2745
2916
|
const effective = effectivePropertyUtilities(
|
|
2746
2917
|
currentClass,
|
|
@@ -2749,7 +2920,10 @@ function applyResponsiveClassEdit(
|
|
|
2749
2920
|
);
|
|
2750
2921
|
if (!effective.includes(intent.from)) return "conflict";
|
|
2751
2922
|
}
|
|
2752
|
-
nextClass =
|
|
2923
|
+
nextClass =
|
|
2924
|
+
maxWidthPx !== undefined
|
|
2925
|
+
? setMaxWidthPropertyClass(currentClass, maxWidthPx, intent.utility)
|
|
2926
|
+
: setPropertyClass(currentClass, intent.prefix, intent.utility);
|
|
2753
2927
|
}
|
|
2754
2928
|
|
|
2755
2929
|
if (nextClass === currentClass) {
|
|
@@ -2780,6 +2954,97 @@ function applyResponsiveClassEdit(
|
|
|
2780
2954
|
};
|
|
2781
2955
|
}
|
|
2782
2956
|
|
|
2957
|
+
/**
|
|
2958
|
+
* Apply a breakpoint-style edit intent: persist (or remove) one raw CSS
|
|
2959
|
+
* declaration for the element inside the managed
|
|
2960
|
+
* `<style data-agent-native-breakpoints>` block, scoped to
|
|
2961
|
+
* `@media (max-width: <maxWidthPx>px)`.
|
|
2962
|
+
*
|
|
2963
|
+
* The rule targets the element's `data-agent-native-node-id`; when the
|
|
2964
|
+
* element doesn't carry one yet it is stamped first (stable hash of the
|
|
2965
|
+
* node's identity, mirroring `ensureCodeLayerNodeIdsInHtml`), so the media
|
|
2966
|
+
* rule and the element stay linked across future edits.
|
|
2967
|
+
*/
|
|
2968
|
+
function applyBreakpointStyleEdit(
|
|
2969
|
+
html: string,
|
|
2970
|
+
element: ParsedElement,
|
|
2971
|
+
node: CodeLayerNode,
|
|
2972
|
+
intent: BreakpointStyleEditIntent,
|
|
2973
|
+
): { content: string; capability: EditCapability } | PatchResultStatus {
|
|
2974
|
+
const property = normalizeStyleProperty(intent.property);
|
|
2975
|
+
if (!property) return "unsupported";
|
|
2976
|
+
if (!Number.isFinite(intent.maxWidthPx) || intent.maxWidthPx <= 0) {
|
|
2977
|
+
return "unsupported";
|
|
2978
|
+
}
|
|
2979
|
+
const maxWidthPx = Math.round(intent.maxWidthPx);
|
|
2980
|
+
const operation = intent.operation ?? "set";
|
|
2981
|
+
|
|
2982
|
+
// Resolve the stable node id, stamping one when missing so the managed
|
|
2983
|
+
// rule has a durable anchor.
|
|
2984
|
+
const existingId = attributeValue(
|
|
2985
|
+
element,
|
|
2986
|
+
"data-agent-native-node-id",
|
|
2987
|
+
)?.trim();
|
|
2988
|
+
let nodeId = existingId || stableAttributeValueForNode(node);
|
|
2989
|
+
let content = html;
|
|
2990
|
+
if (!existingId) {
|
|
2991
|
+
if (content.includes(`data-agent-native-node-id="${nodeId}"`)) {
|
|
2992
|
+
// Extremely unlikely hash collision with another stamped node — derive
|
|
2993
|
+
// a distinct id from the element's source span.
|
|
2994
|
+
nodeId = `an-${hashStable(`${nodeId}:${element.start}:${element.end}`)}`;
|
|
2995
|
+
}
|
|
2996
|
+
content = replaceOrInsertAttribute(
|
|
2997
|
+
content,
|
|
2998
|
+
element,
|
|
2999
|
+
"data-agent-native-node-id",
|
|
3000
|
+
nodeId,
|
|
3001
|
+
);
|
|
3002
|
+
}
|
|
3003
|
+
|
|
3004
|
+
if (operation === "remove") {
|
|
3005
|
+
const next = removeBreakpointMediaDeclaration(content, {
|
|
3006
|
+
nodeId,
|
|
3007
|
+
maxWidthPx,
|
|
3008
|
+
property,
|
|
3009
|
+
});
|
|
3010
|
+
return {
|
|
3011
|
+
content: next,
|
|
3012
|
+
capability: {
|
|
3013
|
+
kind: "breakpoint-style",
|
|
3014
|
+
maxWidthPx,
|
|
3015
|
+
operations: ["remove"],
|
|
3016
|
+
properties: [property],
|
|
3017
|
+
confidence: 0.9,
|
|
3018
|
+
},
|
|
3019
|
+
};
|
|
3020
|
+
}
|
|
3021
|
+
|
|
3022
|
+
if (intent.value === undefined || !isSafeStyleValue(property, intent.value)) {
|
|
3023
|
+
return "unsupported";
|
|
3024
|
+
}
|
|
3025
|
+
try {
|
|
3026
|
+
const next = setBreakpointMediaDeclaration(content, {
|
|
3027
|
+
nodeId,
|
|
3028
|
+
maxWidthPx,
|
|
3029
|
+
property,
|
|
3030
|
+
value: intent.value.trim(),
|
|
3031
|
+
});
|
|
3032
|
+
return {
|
|
3033
|
+
content: next,
|
|
3034
|
+
capability: {
|
|
3035
|
+
kind: "breakpoint-style",
|
|
3036
|
+
maxWidthPx,
|
|
3037
|
+
operations: ["set"],
|
|
3038
|
+
properties: [property],
|
|
3039
|
+
confidence: 0.9,
|
|
3040
|
+
},
|
|
3041
|
+
};
|
|
3042
|
+
} catch {
|
|
3043
|
+
// setBreakpointMediaDeclaration throws on unsafe property/value.
|
|
3044
|
+
return "unsupported";
|
|
3045
|
+
}
|
|
3046
|
+
}
|
|
3047
|
+
|
|
2783
3048
|
function applyMoveNodeEdit(
|
|
2784
3049
|
html: string,
|
|
2785
3050
|
element: ParsedElement,
|
|
@@ -3608,8 +3873,12 @@ export function applyVisualEdit(
|
|
|
3608
3873
|
edit = applyClassEdit(html, element, intent);
|
|
3609
3874
|
} else if (intent.kind === "textContent") {
|
|
3610
3875
|
edit = applyTextEdit(html, element, intent);
|
|
3876
|
+
} else if (intent.kind === "attribute") {
|
|
3877
|
+
edit = applyAttributeEdit(html, element, intent);
|
|
3611
3878
|
} else if (intent.kind === "responsive-class") {
|
|
3612
3879
|
edit = applyResponsiveClassEdit(html, element, intent);
|
|
3880
|
+
} else if (intent.kind === "breakpoint-style") {
|
|
3881
|
+
edit = applyBreakpointStyleEdit(html, element, beforeNode, intent);
|
|
3613
3882
|
} else {
|
|
3614
3883
|
const anchorResolution = resolveTarget(initial, intent.anchor);
|
|
3615
3884
|
if (anchorResolution.status !== "resolved" || !anchorResolution.node) {
|
|
@@ -27,12 +27,14 @@ export interface BreakpointDefinition {
|
|
|
27
27
|
id: string;
|
|
28
28
|
/** Human-readable label shown in the canvas header (e.g. "Mobile", "Tablet"). */
|
|
29
29
|
label: string;
|
|
30
|
-
/** Frame width in pixels (e.g. 390,
|
|
30
|
+
/** Frame width in pixels (e.g. 390, 810, 1200). */
|
|
31
31
|
widthPx: number;
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
33
|
+
* Legacy min-width Tailwind prefix derived from `widthPx` at creation time
|
|
34
|
+
* (informational). The breakpoint bar's Framer cascade does NOT use this:
|
|
35
|
+
* edit scopes are desktop-down max-width bounds computed from the frame
|
|
36
|
+
* widths via `breakpointUpperBoundPx` in `responsive-classes.ts`
|
|
37
|
+
* (overrides apply just below the next-wider frame and cascade down).
|
|
36
38
|
*/
|
|
37
39
|
prefix: TailwindBreakpointPrefix;
|
|
38
40
|
}
|
|
@@ -40,6 +42,11 @@ export interface BreakpointDefinition {
|
|
|
40
42
|
/**
|
|
41
43
|
* The ordered set of breakpoint frames rendered side-by-side for a screen.
|
|
42
44
|
* Frames are ordered Mobile → Tablet → Desktop (left to right).
|
|
45
|
+
*
|
|
46
|
+
* Every frame renders the SAME document (single DOM tree) at its own
|
|
47
|
+
* viewport width — Framer model, never per-breakpoint copies. Width-scoped
|
|
48
|
+
* overrides persist as `max-[<bound>px]:` classes or managed
|
|
49
|
+
* `@media (max-width: <bound>px)` rules (see `breakpoint-media.ts`).
|
|
43
50
|
*/
|
|
44
51
|
export interface BreakpointSet {
|
|
45
52
|
id: string;
|