@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
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
useLoaderData,
|
|
39
39
|
useLocation,
|
|
40
40
|
useNavigate,
|
|
41
|
+
useNavigation,
|
|
41
42
|
useRouteLoaderData,
|
|
42
43
|
useRouteError,
|
|
43
44
|
} from "react-router";
|
|
@@ -209,6 +210,26 @@ function AppSetup() {
|
|
|
209
210
|
return null;
|
|
210
211
|
}
|
|
211
212
|
|
|
213
|
+
function RouteTransitionIndicator() {
|
|
214
|
+
const navigation = useNavigation();
|
|
215
|
+
const pending = navigation.state !== "idle";
|
|
216
|
+
|
|
217
|
+
return (
|
|
218
|
+
<div
|
|
219
|
+
className="pointer-events-none fixed inset-x-0 top-0 z-[100] h-0.5 overflow-hidden"
|
|
220
|
+
aria-hidden={!pending}
|
|
221
|
+
role="progressbar"
|
|
222
|
+
data-pending={pending ? "true" : undefined}
|
|
223
|
+
>
|
|
224
|
+
<div
|
|
225
|
+
className={`h-full bg-primary shadow-[0_0_12px_hsl(var(--primary)/0.45)] transition-all duration-200 ${
|
|
226
|
+
pending ? "w-2/3 opacity-100" : "w-0 opacity-0"
|
|
227
|
+
}`}
|
|
228
|
+
/>
|
|
229
|
+
</div>
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
212
233
|
function ThemeToggleItem() {
|
|
213
234
|
const { theme, setTheme } = useTheme();
|
|
214
235
|
const t = useT();
|
|
@@ -585,6 +606,7 @@ export default function Root() {
|
|
|
585
606
|
>
|
|
586
607
|
<AppSetup />
|
|
587
608
|
<Toaster />
|
|
609
|
+
<RouteTransitionIndicator />
|
|
588
610
|
<ContentCommandMenu open={cmdkOpen} onOpenChange={setCmdkOpen} />
|
|
589
611
|
<Outlet />
|
|
590
612
|
</AppProviders>
|
|
@@ -98,6 +98,8 @@ export interface DocumentUpdateRequest {
|
|
|
98
98
|
content?: string;
|
|
99
99
|
icon?: string | null;
|
|
100
100
|
isFavorite?: boolean;
|
|
101
|
+
loadedUpdatedAt?: string;
|
|
102
|
+
loadedContentWasEmpty?: boolean;
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
export interface DocumentUpdateResponse extends Document {
|
|
@@ -587,6 +589,12 @@ export interface ContentDatabaseSource {
|
|
|
587
589
|
liveReadConfigured?: boolean;
|
|
588
590
|
lastReadEntryCount?: number;
|
|
589
591
|
lastReadMatchedRowCount?: number;
|
|
592
|
+
lastReadLimit?: number;
|
|
593
|
+
lastReadFetchedEntryCount?: number;
|
|
594
|
+
lastReadPartial?: boolean;
|
|
595
|
+
lastReadHasMore?: boolean;
|
|
596
|
+
lastReadNextOffset?: number;
|
|
597
|
+
sourceFetchState?: "idle" | "fetching" | "error";
|
|
590
598
|
allowDraftWrites?: boolean;
|
|
591
599
|
allowPublishWrites?: boolean;
|
|
592
600
|
allowedWriteModes?: ContentDatabaseSourcePushMode[];
|
|
@@ -814,6 +822,7 @@ export interface RefreshContentDatabaseSourceRequest {
|
|
|
814
822
|
databaseId?: string;
|
|
815
823
|
documentId?: string;
|
|
816
824
|
sourceId?: string;
|
|
825
|
+
fullRefresh?: boolean;
|
|
817
826
|
}
|
|
818
827
|
|
|
819
828
|
export interface DisconnectContentDatabaseSourceRequest {
|
|
@@ -826,6 +835,8 @@ export interface AddContentDatabaseSourceFieldPropertyRequest {
|
|
|
826
835
|
databaseId?: string;
|
|
827
836
|
documentId?: string;
|
|
828
837
|
sourceFieldId: string;
|
|
838
|
+
sourceId?: string;
|
|
839
|
+
sourceFieldKey?: string;
|
|
829
840
|
}
|
|
830
841
|
|
|
831
842
|
export interface BindContentDatabaseSourceFieldRequest {
|
|
@@ -962,6 +973,8 @@ export interface ContentDatabaseSourceReviewPayload {
|
|
|
962
973
|
summary: string;
|
|
963
974
|
sourceName: string;
|
|
964
975
|
sourceTable: string;
|
|
976
|
+
totalRowCount?: number;
|
|
977
|
+
preparedRowLimit?: number;
|
|
965
978
|
pushMode: ContentDatabaseSourcePushMode;
|
|
966
979
|
dryRunOnly: boolean;
|
|
967
980
|
liveWritesEnabled: boolean;
|
|
@@ -929,6 +929,16 @@ function rawRefData(args: {
|
|
|
929
929
|
};
|
|
930
930
|
}
|
|
931
931
|
|
|
932
|
+
function escapeBuilderMdxText(value: string) {
|
|
933
|
+
return value.replace(/(^|[^\\])([<{}])/g, (_match, prefix, character) => {
|
|
934
|
+
return `${prefix}\\${character}`;
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
function unescapeBuilderMdxText(value: string) {
|
|
939
|
+
return value.replace(/\\([<{}])/g, "$1");
|
|
940
|
+
}
|
|
941
|
+
|
|
932
942
|
interface BlocksToMdxContext {
|
|
933
943
|
rawRoot: string;
|
|
934
944
|
files: Record<string, string>;
|
|
@@ -988,7 +998,9 @@ async function builderBlockToMdx(
|
|
|
988
998
|
if (name === "Text") {
|
|
989
999
|
const data: BuilderTextData = {
|
|
990
1000
|
...raw,
|
|
991
|
-
body:
|
|
1001
|
+
body: escapeBuilderMdxText(
|
|
1002
|
+
htmlToMarkdown(String(options.text ?? "")).trim(),
|
|
1003
|
+
),
|
|
992
1004
|
};
|
|
993
1005
|
return serializeRegistryBlockToMdx("builder-text", {
|
|
994
1006
|
id,
|
|
@@ -1831,14 +1843,15 @@ function applyTextData(
|
|
|
1831
1843
|
const block = rawBlockForData(data, sidecars);
|
|
1832
1844
|
const rawOptions = componentOptions(block);
|
|
1833
1845
|
const originalBody = htmlToMarkdown(String(rawOptions.text ?? ""));
|
|
1846
|
+
const body = unescapeBuilderMdxText(data.body);
|
|
1834
1847
|
if (
|
|
1835
|
-
normalizeMarkdownForCompare(
|
|
1848
|
+
normalizeMarkdownForCompare(body) ===
|
|
1836
1849
|
normalizeMarkdownForCompare(originalBody)
|
|
1837
1850
|
) {
|
|
1838
1851
|
return block;
|
|
1839
1852
|
}
|
|
1840
1853
|
const options = ensureComponentOptions(block, data.componentName ?? "Text");
|
|
1841
|
-
options.text = markdownToBuilderTextHtml(
|
|
1854
|
+
options.text = markdownToBuilderTextHtml(body);
|
|
1842
1855
|
return block;
|
|
1843
1856
|
}
|
|
1844
1857
|
|
|
@@ -196,6 +196,8 @@ pnpm action show-design-questions \
|
|
|
196
196
|
--questions '[{"id":"form_factor","type":"text-options","question":"What form factor?","options":[{"label":"Desktop web app","value":"desktop"},{"label":"Mobile app","value":"mobile"},{"label":"Both / responsive","value":"responsive"},{"label":"Decide for me","value":"decide"}],"allowOther":true}]'
|
|
197
197
|
```
|
|
198
198
|
|
|
199
|
+
**Carry the form-factor answer through to generation — do not just ask and discard it.** A "Desktop web app" answer means the generated screen's canvas frame must be desktop-sized (~1440×1024), not left at whatever a screen with no placement falls back to. Map the answer to real frame geometry: pass `deviceType` (`"mobile"` / `"tablet"` / `"desktop"`) per screen to `generate-screens`, explicit `width`/`height` per variant to `present-design-variants`, or an explicit `canvasFrames` entry to `generate-design` — see Phase 2 and Phase 3 below. For "Both / responsive," generate at desktop width and rely on the responsive breakpoint system (see `responsive-breakpoints` skill) rather than guessing a size.
|
|
200
|
+
|
|
199
201
|
### Phase 2 — Generate side-by-side variations (2-5, three by default)
|
|
200
202
|
|
|
201
203
|
For new designs, default to **three** variations (`present-design-variants`
|
|
@@ -209,15 +211,17 @@ screen name.
|
|
|
209
211
|
"designId": "<the design id>",
|
|
210
212
|
"prompt": "Pick a direction",
|
|
211
213
|
"variants": [
|
|
212
|
-
{ "id": "a", "label": "Editorial Serif", "content": "<!DOCTYPE html>...full self-contained HTML..." },
|
|
213
|
-
{ "id": "b", "label": "Bold Brutalist", "content": "<!DOCTYPE html>..." },
|
|
214
|
-
{ "id": "c", "label": "Soft & Spacious", "content": "<!DOCTYPE html>..." }
|
|
214
|
+
{ "id": "a", "label": "Editorial Serif", "width": 1440, "height": 1024, "content": "<!DOCTYPE html>...full self-contained HTML..." },
|
|
215
|
+
{ "id": "b", "label": "Bold Brutalist", "width": 1440, "height": 1024, "content": "<!DOCTYPE html>..." },
|
|
216
|
+
{ "id": "c", "label": "Soft & Spacious", "width": 1440, "height": 1024, "content": "<!DOCTYPE html>..." }
|
|
215
217
|
]
|
|
216
218
|
}
|
|
217
219
|
```
|
|
218
220
|
|
|
219
221
|
Each `content` is a complete, self-contained document (Alpine.js + Tailwind via CDN, full `<head>`, CSS variables in `:root`). Variations should be **stylistically/structurally distinct** — different typography schools, layout grammars, color moods — never just color swaps. Label them with concrete style names ("Editorial Serif", not "Variant A").
|
|
220
222
|
|
|
223
|
+
Pass `width`/`height` on every variant to match the form-factor answer (mobile ≈ 390×844, tablet ≈ 768×1024, desktop ≈ 1440×1024) — the example above is desktop-sized. When `content` is omitted, `present-design-variants` infers a size from the prompt/label/description text and the width/height you pass still wins when given.
|
|
224
|
+
|
|
221
225
|
Wait for the user's pick before refining. Once they choose, keep the selected
|
|
222
226
|
screen, delete the unchosen variant screens with `delete-file`, and continue
|
|
223
227
|
from the kept screen by calling `get-design-snapshot` with the selected
|
|
@@ -241,9 +245,12 @@ pnpm action generate-design \
|
|
|
241
245
|
--designId "<id>" \
|
|
242
246
|
--prompt "Description of the design" \
|
|
243
247
|
--files '[{"filename":"index.html","content":"<full HTML>","fileType":"html"}]' \
|
|
244
|
-
--tweaks '[{"id":"accent","label":"Accent","type":"color-swatch","options":[...],"defaultValue":"#0EA5E9","cssVar":"--color-accent"}]'
|
|
248
|
+
--tweaks '[{"id":"accent","label":"Accent","type":"color-swatch","options":[...],"defaultValue":"#0EA5E9","cssVar":"--color-accent"}]' \
|
|
249
|
+
--canvasFrames '[{"filename":"index.html","x":0,"y":0,"width":1440,"height":1024}]'
|
|
245
250
|
```
|
|
246
251
|
|
|
252
|
+
Always pass `canvasFrames` with an explicit `width`/`height` matching the form-factor answer (mobile ≈ 390×844, tablet ≈ 768×1024, desktop ≈ 1440×1024 as above) — a screen saved without a placement falls back to a generic default that won't match a desktop-intended design. For multiple screens generated together, call `generate-screens` first and pass `deviceType` (`"mobile"` / `"tablet"` / `"desktop"`) per screen; it returns the matching `canvasFrame` to forward to each `generate-design` call.
|
|
253
|
+
|
|
247
254
|
### Phase 4 — Always ship tweaks with the design
|
|
248
255
|
|
|
249
256
|
`generate-design` accepts a `--tweaks` array — pass 3-6 of the most impactful knobs bound to CSS custom properties the design's `:root` block actually defines. Surface controls users will actually want to adjust (accent color, density, radius, dark-mode toggle, font choice). Don't ship a generic preset; let the design's structure pick the knobs.
|
|
@@ -661,15 +668,18 @@ token layer, typography, nav, and footer stay identical.
|
|
|
661
668
|
|
|
662
669
|
## Breakpoints & screen states
|
|
663
670
|
|
|
664
|
-
- **Breakpoints**: `add-breakpoint` adds a device-width frame (
|
|
665
|
-
Tablet
|
|
666
|
-
stored in `designs.data`;
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
breakpoint
|
|
672
|
-
|
|
671
|
+
- **Breakpoints**: `add-breakpoint` adds a device-width frame (Framer
|
|
672
|
+
defaults Phone 390 / Tablet 810 / Desktop 1200, or a custom width) to the
|
|
673
|
+
design's breakpoint set stored in `designs.data`; duplicate widths are
|
|
674
|
+
ignored. `remove-breakpoint` removes one by id. `set-active-breakpoint`
|
|
675
|
+
sets which frame is the current edit scope. Breakpoint frames are ONE
|
|
676
|
+
document rendered at different widths with a Framer-style cascade: the
|
|
677
|
+
primary (widest) frame is the base, and edits at a narrower active
|
|
678
|
+
breakpoint persist as width-scoped overrides (`max-[<bound>px]:` classes
|
|
679
|
+
or managed `@media` rules) that cascade down. Always check the active
|
|
680
|
+
breakpoint before a responsive-only edit, and pass `activeFrameWidthPx`
|
|
681
|
+
to `apply-visual-edit` so the write lands at the right scope. Read the
|
|
682
|
+
`responsive-breakpoints` skill for the full model.
|
|
673
683
|
- **Design states**: `create-design-state` creates a named alternate
|
|
674
684
|
DOM/Alpine snapshot (`kind: "state"` — Loading, Empty, Error), a static data
|
|
675
685
|
fixture (`kind: "fixture"`), or a placeholder for a live capture
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: responsive-breakpoints
|
|
3
|
+
description: >-
|
|
4
|
+
Framer-style responsive breakpoint editing in Design: one DOM tree per
|
|
5
|
+
screen with cascading width-scoped overrides. Use when adding/removing
|
|
6
|
+
breakpoints, editing a design at a specific device width, resolving which
|
|
7
|
+
value renders at a width, or persisting responsive style changes.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Responsive Breakpoints
|
|
11
|
+
|
|
12
|
+
Design uses the **Framer model**: every screen is ONE document (one DOM
|
|
13
|
+
tree). Breakpoint frames are the SAME document rendered at different
|
|
14
|
+
viewport widths — never separate copies. Edits cascade:
|
|
15
|
+
|
|
16
|
+
- The **base** is the primary (widest) frame. Base edits are plain
|
|
17
|
+
unprefixed classes / inline styles and cascade down to every narrower
|
|
18
|
+
breakpoint unless overridden there.
|
|
19
|
+
- Edits made while a **narrower breakpoint is active** persist as
|
|
20
|
+
width-scoped overrides that apply from just below the next-wider frame
|
|
21
|
+
down to zero. Narrower breakpoints layer their own overrides on top.
|
|
22
|
+
|
|
23
|
+
The bound for an override is `next-wider frame width - 1` (e.g. breakpoints
|
|
24
|
+
390/810 with a 1280 primary: editing 810 scopes to `≤ 1279px`, editing 390
|
|
25
|
+
scopes to `≤ 809px`). `breakpointUpperBoundPx` in
|
|
26
|
+
`shared/responsive-classes.ts` is the canonical implementation.
|
|
27
|
+
|
|
28
|
+
## Managing breakpoints
|
|
29
|
+
|
|
30
|
+
- `add-breakpoint` — adds a device-width frame to `designs.data.breakpointSet`
|
|
31
|
+
(Framer defaults: Desktop 1200 / Tablet 810 / Phone 390, or custom 320-3840).
|
|
32
|
+
Duplicate widths are ignored.
|
|
33
|
+
- `remove-breakpoint` — removes one by id (overrides already written stay in
|
|
34
|
+
the document until removed).
|
|
35
|
+
- `set-active-breakpoint` — persists the active edit scope to application
|
|
36
|
+
state (`design-active-breakpoint:<designId>`); the UI mirrors it in the
|
|
37
|
+
`design-selection` state (`activeBreakpointId`). Check the active
|
|
38
|
+
breakpoint via `view-screen` before making responsive-only edits.
|
|
39
|
+
|
|
40
|
+
The UI's breakpoint bar (chips above the focused screen) and the overview's
|
|
41
|
+
side-by-side linked frames drive the same state — a chip click changes the
|
|
42
|
+
iframe viewport width AND calls `set-active-breakpoint`.
|
|
43
|
+
|
|
44
|
+
## Editing responsively (agent parity)
|
|
45
|
+
|
|
46
|
+
Use `apply-visual-edit` with `activeFrameWidthPx` set to the ACTIVE
|
|
47
|
+
breakpoint frame width. This scopes BOTH `class` and `style` intents
|
|
48
|
+
uniformly through one class-vs-media decision:
|
|
49
|
+
|
|
50
|
+
- Values that are Tailwind utilities (`text-lg`, `p-4`) become width-scoped
|
|
51
|
+
classes: `max-[809px]:text-lg` (arbitrary max-width variants the Tailwind
|
|
52
|
+
CDN JIT compiles to `@media (max-width: 809px)`).
|
|
53
|
+
- Raw CSS values (`137px`, `rgb(...)`, `calc(...)`) persist into the managed
|
|
54
|
+
`<style data-agent-native-breakpoints>` block as
|
|
55
|
+
`@media (max-width: <bound>px)` rules targeting the element's
|
|
56
|
+
`data-agent-native-node-id`. The block is deterministic (wider buckets
|
|
57
|
+
first so narrower ranges win by source order) and readable/editable in the
|
|
58
|
+
Code panel.
|
|
59
|
+
|
|
60
|
+
Other targeting options:
|
|
61
|
+
|
|
62
|
+
- `maxWidthPx` — explicit desktop-down bound, overrides derivation.
|
|
63
|
+
- `intent.kind: "breakpoint-style"` — direct managed-media write/remove:
|
|
64
|
+
`{ target, maxWidthPx, property, value, operation: "set" | "remove" }`.
|
|
65
|
+
- `activeBreakpoint: "md"` etc. — LEGACY min-width prefix scoping for class
|
|
66
|
+
edits only (mobile-first `md:text-lg`). Still supported for documents
|
|
67
|
+
authored mobile-first; prefer `activeFrameWidthPx` for breakpoint-bar
|
|
68
|
+
parity.
|
|
69
|
+
|
|
70
|
+
When the design has no breakpoint set, `activeFrameWidthPx` falls back to
|
|
71
|
+
the legacy min-width prefix behaviour for class edits. When the active frame
|
|
72
|
+
IS the widest context, edits are base writes (correct — the widest frame is
|
|
73
|
+
the base).
|
|
74
|
+
|
|
75
|
+
## Resolving and inspecting overrides
|
|
76
|
+
|
|
77
|
+
- `effectiveUtilityAtWidth(className, stem, widthPx)` — which utility
|
|
78
|
+
renders at a width (narrowest applicable max-width scope wins, then
|
|
79
|
+
min-width prefixes, then base).
|
|
80
|
+
- `getBreakpointOverrideState({ className, html, nodeId, property,
|
|
81
|
+
breakpointWidths, baseWidthPx, activeWidthPx })` from
|
|
82
|
+
`shared/breakpoint-media.ts` — aggregates class + media overrides for the
|
|
83
|
+
inspector's overridden-at-this-breakpoint indicators.
|
|
84
|
+
- To RESET an override: remove the scoped class
|
|
85
|
+
(`responsive-class` remove with `maxWidthPx` + stem) or the media rule
|
|
86
|
+
(`breakpoint-style` with `operation: "remove"`); the base value cascades
|
|
87
|
+
back down.
|
|
88
|
+
|
|
89
|
+
## Cautions
|
|
90
|
+
|
|
91
|
+
- Managed media rules anchor on `data-agent-native-node-id`. Inline (SQL)
|
|
92
|
+
designs keep these ids; localhost write-back strips them — for local-file
|
|
93
|
+
sources prefer scoped classes.
|
|
94
|
+
- Never rewrite the managed block wholesale by hand; use the edit intents so
|
|
95
|
+
same-property writes replace instead of accumulate. The parser tolerates
|
|
96
|
+
Code-panel edits but unknown selectors are ignored.
|
|
97
|
+
- Adding a breakpoint between two existing widths changes the bound for NEW
|
|
98
|
+
overrides only; previously written overrides keep their original bounds.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shader-fills
|
|
3
|
+
description: >-
|
|
4
|
+
Code-backed GLSL shader fills and shader effects: authoring WGSL-free,
|
|
5
|
+
WebGL1 GLSL fragment shaders that persist as readable source in the screen
|
|
6
|
+
HTML with uniform knobs in the inspector. Use when the user asks for a
|
|
7
|
+
shader fill or shader effect, sends "Create a custom shader fill." from the
|
|
8
|
+
fill picker, wants an animated/procedural background (waves, noise, mesh
|
|
9
|
+
gradients, caustics, grain, halftone), or wants to edit an existing
|
|
10
|
+
shader's GLSL or uniforms.
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Code-Backed Shader Fills & Effects
|
|
14
|
+
|
|
15
|
+
Shaders in Design are **code, not opaque assets**. Each shader is a GLSL
|
|
16
|
+
fragment source + JSON uniforms manifest persisted directly in the screen
|
|
17
|
+
HTML, rendered live by a self-contained WebGL runtime that is embedded in the
|
|
18
|
+
same HTML — so shaders work in the editor, in shared links, and in exported
|
|
19
|
+
standalone files. Users see and edit the GLSL in the Code panel; uniform
|
|
20
|
+
knobs appear automatically in the inspector (Fill → Shader paint type, and
|
|
21
|
+
Effects → Shader).
|
|
22
|
+
|
|
23
|
+
The canonical format module is `shared/shader-fills.ts`. Always prefer its
|
|
24
|
+
helpers over hand-assembling markup.
|
|
25
|
+
|
|
26
|
+
## Persisted format (v1)
|
|
27
|
+
|
|
28
|
+
One definition block per shader (place before `</body>`):
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<script type="application/x-agent-native-shader"
|
|
32
|
+
data-shader-id="an-shader-x1y2z3ab"
|
|
33
|
+
data-shader-name="Aurora Drift"
|
|
34
|
+
data-shader-mode="fill">
|
|
35
|
+
/*! an-shader v1
|
|
36
|
+
{
|
|
37
|
+
"uniforms": {
|
|
38
|
+
"u_speed": { "type": "float", "value": 1, "min": 0, "max": 4, "step": 0.01, "label": "Speed" },
|
|
39
|
+
"u_color_a": { "type": "color", "value": "#4f2d8f", "label": "Base" },
|
|
40
|
+
"u_center": { "type": "vec2", "value": [0.5, 0.5], "label": "Center" }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
*/
|
|
44
|
+
precision highp float;
|
|
45
|
+
uniform vec2 u_resolution;
|
|
46
|
+
uniform float u_time;
|
|
47
|
+
uniform float u_speed;
|
|
48
|
+
uniform vec3 u_color_a;
|
|
49
|
+
uniform vec2 u_center;
|
|
50
|
+
void main() {
|
|
51
|
+
vec2 uv = gl_FragCoord.xy / u_resolution;
|
|
52
|
+
gl_FragColor = vec4(u_color_a * (0.6 + 0.4 * sin(u_time * u_speed + distance(uv, u_center) * 8.0)), 1.0);
|
|
53
|
+
}
|
|
54
|
+
</script>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Element references (both can coexist on one element, like Figma):
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
<!-- Fill: canvas rendered BEHIND the element's content. Keep a static
|
|
61
|
+
fallback background so the artifact renders without JS/WebGL. -->
|
|
62
|
+
<div data-agent-native-node-id="hero"
|
|
63
|
+
data-an-shader-fill="an-shader-x1y2z3ab"
|
|
64
|
+
data-an-shader-uniforms='{"u_speed":2}'
|
|
65
|
+
style="background: #4f2d8f">…</div>
|
|
66
|
+
|
|
67
|
+
<!-- Effect: transparent overlay canvas ABOVE the content. Per-element
|
|
68
|
+
overrides live in a separate attribute. -->
|
|
69
|
+
<div data-an-shader-effect="an-shader-grain001"
|
|
70
|
+
data-an-shader-effect-uniforms='{"u_intensity":0.2}'>…</div>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The runtime must be embedded once per document as
|
|
74
|
+
`<script data-agent-native-shader-runtime data-runtime-version="1">…` —
|
|
75
|
+
`ensureShaderRuntime()` / `applyShaderToHtml()` handle this.
|
|
76
|
+
|
|
77
|
+
## Applying a shader (preferred path)
|
|
78
|
+
|
|
79
|
+
Use the pure helpers + the source-edit actions. From `templates/design/`:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
// script: apply-shader.ts — run with: pnpm exec tsx apply-shader.ts
|
|
83
|
+
import { applyShaderToHtml, newShaderId } from "./shared/shader-fills";
|
|
84
|
+
import { getGlslShaderPreset } from "./shared/shader-presets";
|
|
85
|
+
|
|
86
|
+
const preset = getGlslShaderPreset("water-caustics")!;
|
|
87
|
+
const result = applyShaderToHtml(currentHtml /* from read-source-file */, {
|
|
88
|
+
nodeId: "hero", // the element's data-agent-native-node-id
|
|
89
|
+
def: {
|
|
90
|
+
id: newShaderId(),
|
|
91
|
+
name: preset.label,
|
|
92
|
+
mode: preset.mode, // "fill" | "effect"
|
|
93
|
+
glsl: preset.glsl,
|
|
94
|
+
uniforms: preset.uniforms,
|
|
95
|
+
},
|
|
96
|
+
fallbackColor: "#06283d", // fills only — static no-JS fallback
|
|
97
|
+
});
|
|
98
|
+
if (result.errors.length) throw new Error(result.errors.join("; "));
|
|
99
|
+
// result.html → write back via apply-source-edit (full-replace) with the
|
|
100
|
+
// versionHash you got from read-source-file.
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Action flow: `read-source-file` → transform → `apply-source-edit`
|
|
104
|
+
(`edit: { kind: "full-replace", content }`, pass `expectedVersionHash`).
|
|
105
|
+
For a small hand-edit (e.g. tweaking one uniform value in the manifest),
|
|
106
|
+
`edit-design` search/replace on the exact block text is also fine.
|
|
107
|
+
|
|
108
|
+
To remove: `removeShaderFromNode(html, nodeId, mode?)` — clears the
|
|
109
|
+
annotation and garbage-collects unreferenced definition blocks.
|
|
110
|
+
|
|
111
|
+
## Handling "Create a custom shader fill." from the picker
|
|
112
|
+
|
|
113
|
+
The fill picker's **Create new (AI)** tile prefills this prompt with hidden
|
|
114
|
+
context lines (`designId`, `fileId`, `target nodeId`, `mode`). Then:
|
|
115
|
+
|
|
116
|
+
1. Ask what look they want only if the user gave no description at all.
|
|
117
|
+
2. Write ORIGINAL GLSL for the request (do not just re-apply a preset), with
|
|
118
|
+
2–5 well-chosen uniforms exposed as knobs. Name the knobs the way the
|
|
119
|
+
user described the controls.
|
|
120
|
+
3. Apply it via the helper flow above, targeting the provided nodeId.
|
|
121
|
+
4. Report the shader name, its knobs, and that the GLSL is editable in the
|
|
122
|
+
Code panel.
|
|
123
|
+
|
|
124
|
+
## GLSL rules (WebGL1 / GLSL ES 1.00)
|
|
125
|
+
|
|
126
|
+
- Start with `precision highp float;`. Write to `gl_FragColor`.
|
|
127
|
+
- Declare `uniform vec2 u_resolution;` and `uniform float u_time;` when used
|
|
128
|
+
— the runtime drives them automatically (`u_time` is seconds; it stays 0
|
|
129
|
+
under `prefers-reduced-motion`). Never put builtins in the manifest.
|
|
130
|
+
- Every manifest uniform MUST be declared in the GLSL with the mapped type:
|
|
131
|
+
`float` → `uniform float`, `vec2` → `uniform vec2`, `color` → `uniform
|
|
132
|
+
vec3` (colors arrive normalized 0–1 RGB). Validation rejects unused knobs.
|
|
133
|
+
- Uniform names match `u_[A-Za-z0-9_]+`; ≤ 16 uniforms; float knobs need
|
|
134
|
+
`min`/`max`/`step`; color values are `#rrggbb` hex.
|
|
135
|
+
- Loop bounds must be compile-time constant (`for (int i = 0; i < 5; i++)`).
|
|
136
|
+
- Effects are composited over content: output premultiplication is off, so
|
|
137
|
+
`gl_FragColor = vec4(color, alpha)` with alpha < 1 overlays cleanly.
|
|
138
|
+
- Never include `</script`, `<script`, or `*/`-breaking sequences in GLSL,
|
|
139
|
+
names, or labels — `validateShaderDef()` enforces this; run it (or
|
|
140
|
+
`applyShaderToHtml`, which calls it) before writing.
|
|
141
|
+
|
|
142
|
+
## Preset library
|
|
143
|
+
|
|
144
|
+
`GLSL_SHADER_PRESETS` in `shared/shader-presets.ts` ships 12 curated
|
|
145
|
+
presets — fills: `mesh-gradient`, `glowing-wave`, `water-caustics`,
|
|
146
|
+
`fractal-noise`, `clouds`, `nebula`, `moire`, `concentric-rings`,
|
|
147
|
+
`pattern-grid`; effects: `film-grain`, `halftone`, `scanlines`. Applying a
|
|
148
|
+
preset stamps a fresh copy (new id) into the design; after that it is the
|
|
149
|
+
user's code to edit.
|
|
150
|
+
|
|
151
|
+
## Fills vs effects
|
|
152
|
+
|
|
153
|
+
| | Fill (`data-an-shader-fill`) | Effect (`data-an-shader-effect`) |
|
|
154
|
+
|---|---|---|
|
|
155
|
+
| Canvas position | Behind content (negative z-index in an isolated stacking context, above the element's own background) | Overlay above content, `pointer-events: none` |
|
|
156
|
+
| Output | Opaque pixels (a material) | Transparent overlay (alpha compositing) |
|
|
157
|
+
| Fallback | Element keeps a static `background` color | Degrades to no overlay |
|
|
158
|
+
| Overrides attr | `data-an-shader-uniforms` | `data-an-shader-effect-uniforms` |
|
|
159
|
+
|
|
160
|
+
Failures (no WebGL, compile error, > 8 mounts per screen) remove the canvas
|
|
161
|
+
and record the reason in `data-an-shader-error` on the element — check that
|
|
162
|
+
attribute when a shader "isn't showing".
|
|
@@ -259,8 +259,10 @@ patterns live in `.agents/skills/`.
|
|
|
259
259
|
skill's Phase 5 for when to run these.
|
|
260
260
|
- **Breakpoints**: `add-breakpoint`, `remove-breakpoint`, and
|
|
261
261
|
`set-active-breakpoint` manage the design's device-width frame set and which
|
|
262
|
-
frame new edits target.
|
|
263
|
-
|
|
262
|
+
frame new edits target. Breakpoint frames are one document with a
|
|
263
|
+
Framer-style cascade (base = widest frame; narrower-frame edits persist as
|
|
264
|
+
width-scoped overrides via `apply-visual-edit` + `activeFrameWidthPx`).
|
|
265
|
+
Read the `responsive-breakpoints` skill before responsive edits.
|
|
264
266
|
- **Design states**: `create-design-state`, `apply-design-state`,
|
|
265
267
|
`capture-design-state`, `list-design-states`, and `delete-design-state`
|
|
266
268
|
manage named DOM/Alpine states (Loading/Empty/Error), static data fixtures,
|
|
@@ -338,9 +340,14 @@ and requires Builder connected. See `full-app-build` skill for the full flow.
|
|
|
338
340
|
Read the relevant skill before deeper work:
|
|
339
341
|
|
|
340
342
|
- `design-generation` for creating/editing prototype HTML and variant flows.
|
|
343
|
+
- `responsive-breakpoints` for Framer-style breakpoint editing (single DOM,
|
|
344
|
+
cascading width-scoped overrides, the managed breakpoints media block).
|
|
341
345
|
- `design-systems` for tokens, brand extraction, and linked systems.
|
|
342
346
|
- `export-handoff` for HTML/PNG/SVG/ZIP/code handoff.
|
|
343
347
|
- `full-app-build` for flag-gated fusion-backed full app building.
|
|
348
|
+
- `shader-fills` for code-backed GLSL shader fills/effects (editable source
|
|
349
|
+
in screen HTML, uniform knobs, preset library, and the picker's "Create a
|
|
350
|
+
custom shader fill." prompt).
|
|
344
351
|
- `frontend-design` and `shadcn-ui` for app UI changes.
|
|
345
352
|
- `actions`, `delegate-to-agent`, `security`, and `self-modifying-code` for
|
|
346
353
|
framework patterns.
|
|
@@ -63,9 +63,12 @@ export default defineAction({
|
|
|
63
63
|
description:
|
|
64
64
|
"Add a breakpoint frame to the design's breakpoint set. " +
|
|
65
65
|
"The breakpoint set is stored in designs.data and controls which side-by-side " +
|
|
66
|
-
"device widths are shown in the overview canvas
|
|
67
|
-
"
|
|
68
|
-
"
|
|
66
|
+
"device widths are shown in the overview canvas and the editor's breakpoint bar " +
|
|
67
|
+
"(Framer defaults: Phone 390 / Tablet 810 / Desktop 1200, or a custom width). " +
|
|
68
|
+
"Every frame renders the SAME document at its own viewport width (Framer model); " +
|
|
69
|
+
"edits made at a narrower active frame persist as width-scoped overrides that " +
|
|
70
|
+
"cascade down (see the responsive-breakpoints skill). The legacy Tailwind prefix " +
|
|
71
|
+
"is derived automatically from the width. Duplicate widths are silently ignored.",
|
|
69
72
|
schema: z.object({
|
|
70
73
|
designId: z.string().describe("Design project ID"),
|
|
71
74
|
label: z
|