@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,6 +1,7 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
2
|
import {
|
|
3
3
|
hasCollabState,
|
|
4
|
+
getText,
|
|
4
5
|
applyText,
|
|
5
6
|
seedFromText,
|
|
6
7
|
} from "@agent-native/core/collab";
|
|
@@ -10,6 +11,8 @@ import { and, eq, sql } from "drizzle-orm";
|
|
|
10
11
|
import { z } from "zod";
|
|
11
12
|
|
|
12
13
|
import { getDb, schema } from "../server/db/index.js";
|
|
14
|
+
import { withSourceFileWriteLock } from "../server/source-workspace.js";
|
|
15
|
+
import { sourceContentHash } from "../shared/source-workspace.js";
|
|
13
16
|
|
|
14
17
|
function rowsAffected(result: unknown): number | undefined {
|
|
15
18
|
const candidate = result as {
|
|
@@ -22,6 +25,24 @@ function rowsAffected(result: unknown): number | undefined {
|
|
|
22
25
|
return typeof value === "number" ? value : undefined;
|
|
23
26
|
}
|
|
24
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Returns `{ id, updated: true }` on success, matching the pre-existing
|
|
30
|
+
* contract — callers that only check `result.updated === true` see no
|
|
31
|
+
* behavior change.
|
|
32
|
+
*
|
|
33
|
+
* `skippedStaleMirror?: true` is added to the result ONLY in the narrow
|
|
34
|
+
* SQL-mirror-only staleness case: `content` was provided, `syncCollab` was
|
|
35
|
+
* explicitly `false`, a live collaboration document exists for this file,
|
|
36
|
+
* and the caller's `expectedVersionHash` no longer matches that live text.
|
|
37
|
+
* In that case the content column is intentionally left untouched (the live
|
|
38
|
+
* collab document remains the source of truth) while any `filename`/
|
|
39
|
+
* `fileType` updates in the same call still apply, and the action returns
|
|
40
|
+
* success instead of throwing. The field is omitted (not `false`) in every
|
|
41
|
+
* other case, so existing callers that don't check for it observe no
|
|
42
|
+
* difference. When `expectedVersionHash` is omitted entirely, or the hash
|
|
43
|
+
* matches, or `syncCollab` is left at its default `true`, or no collab state
|
|
44
|
+
* exists yet for the file, this skip path never triggers.
|
|
45
|
+
*/
|
|
25
46
|
export default defineAction({
|
|
26
47
|
description:
|
|
27
48
|
"Update an existing file in a design project. " +
|
|
@@ -42,8 +63,26 @@ export default defineAction({
|
|
|
42
63
|
.describe(
|
|
43
64
|
"Whether to mirror content updates into the live collaboration document.",
|
|
44
65
|
),
|
|
66
|
+
expectedVersionHash: z
|
|
67
|
+
.string()
|
|
68
|
+
.optional()
|
|
69
|
+
.describe(
|
|
70
|
+
"Optional optimistic-concurrency guard for content updates: the " +
|
|
71
|
+
"sourceContentHash of the live content this write was computed " +
|
|
72
|
+
"from (same semantics as apply-source-edit / read-source-file). " +
|
|
73
|
+
"When provided and the file changed since that read, the write " +
|
|
74
|
+
"fails loud instead of silently merging a stale full document " +
|
|
75
|
+
"into the collaboration state.",
|
|
76
|
+
),
|
|
45
77
|
}),
|
|
46
|
-
run: async ({
|
|
78
|
+
run: async ({
|
|
79
|
+
id,
|
|
80
|
+
content,
|
|
81
|
+
filename,
|
|
82
|
+
fileType,
|
|
83
|
+
syncCollab,
|
|
84
|
+
expectedVersionHash,
|
|
85
|
+
}) => {
|
|
47
86
|
// Path traversal guard on filename
|
|
48
87
|
if (
|
|
49
88
|
filename &&
|
|
@@ -82,96 +121,172 @@ export default defineAction({
|
|
|
82
121
|
|
|
83
122
|
await assertAccess("design", file.designId, "editor");
|
|
84
123
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
124
|
+
// Optimistic-concurrency guard (cross-pipeline write-race fix): a content
|
|
125
|
+
// update here is a FULL-document write that, when syncCollab runs, is
|
|
126
|
+
// char-diffed against the live collaboration text (applyText). If the
|
|
127
|
+
// caller computed `content` from a since-stale read — e.g. a base Fill
|
|
128
|
+
// style commit queued while a shader apply-source-edit landed for the
|
|
129
|
+
// same file — that silent diff-merge is exactly how the shader/fill
|
|
130
|
+
// interleave corrupted or lost screen content. When the caller supplies
|
|
131
|
+
// the hash of the content it based this write on, verify the file still
|
|
132
|
+
// matches before writing and fail loud otherwise, mirroring
|
|
133
|
+
// writeInlineSourceFile's expectedVersionHash contract.
|
|
134
|
+
//
|
|
135
|
+
// TOCTOU fix: the hash check alone is NOT enough — two concurrent
|
|
136
|
+
// update-file calls can each read the same live text, each pass the hash
|
|
137
|
+
// check, and then both proceed to write, with the second one silently
|
|
138
|
+
// winning over a base it never actually re-validated against. Route the
|
|
139
|
+
// whole hash-check -> write -> collab-sync critical section through the
|
|
140
|
+
// SAME per-file in-process lock writeInlineSourceFile uses
|
|
141
|
+
// (withSourceFileWriteLock, server/source-workspace.ts), keyed by file
|
|
142
|
+
// id, so a second guarded caller's hash check runs AFTER the first
|
|
143
|
+
// caller's write has fully landed and observes the true current state
|
|
144
|
+
// (and is rejected by the hash guard instead of interleaving). Callers
|
|
145
|
+
// that don't pass a hash keep today's last-write-wins behavior for the
|
|
146
|
+
// VALUE they write, but the write itself is still serialized under the
|
|
147
|
+
// same lock so it can't interleave with a concurrent guarded writer's own
|
|
148
|
+
// read-check-write.
|
|
149
|
+
let skippedStaleMirror = false;
|
|
150
|
+
|
|
151
|
+
await withSourceFileWriteLock(id, async () => {
|
|
152
|
+
// SQL-mirror-only skip path: when the caller explicitly opted OUT of
|
|
153
|
+
// collab sync (syncCollab: false) and supplied an expectedVersionHash
|
|
154
|
+
// that no longer matches the LIVE collab text, and a live collab doc
|
|
155
|
+
// actually exists for this file, the caller's `content` was computed
|
|
156
|
+
// from a base that a live editor has since moved past. Overwriting the
|
|
157
|
+
// SQL mirror column with that stale content here would silently regress
|
|
158
|
+
// it out from under the live document (which stays the source of
|
|
159
|
+
// truth) the next time it's read back out of SQL. Skip the content
|
|
160
|
+
// write instead of throwing: filename/fileType updates in the same call
|
|
161
|
+
// still proceed, and the caller gets `skippedStaleMirror: true` back
|
|
162
|
+
// instead of a thrown error, because they explicitly said they weren't
|
|
163
|
+
// trying to sync into collab in the first place. Every other
|
|
164
|
+
// expectedVersionHash combination (syncCollab true/default, or no live
|
|
165
|
+
// collab state, or a matching hash, or no hash at all) is UNCHANGED.
|
|
166
|
+
let skipContentWrite = false;
|
|
167
|
+
if (expectedVersionHash !== undefined && content !== undefined) {
|
|
168
|
+
const collabExists = await hasCollabState(id);
|
|
169
|
+
let liveContent: string;
|
|
170
|
+
if (collabExists) {
|
|
171
|
+
liveContent = await getText(id, "content");
|
|
172
|
+
} else {
|
|
173
|
+
const [current] = await db
|
|
174
|
+
.select({ content: schema.designFiles.content })
|
|
175
|
+
.from(schema.designFiles)
|
|
176
|
+
.where(eq(schema.designFiles.id, id))
|
|
177
|
+
.limit(1);
|
|
178
|
+
liveContent = current?.content ?? "";
|
|
112
179
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
180
|
+
if (sourceContentHash(liveContent) !== expectedVersionHash) {
|
|
181
|
+
if (syncCollab === false && collabExists) {
|
|
182
|
+
skipContentWrite = true;
|
|
183
|
+
skippedStaleMirror = true;
|
|
184
|
+
} else {
|
|
185
|
+
throw new Error(
|
|
186
|
+
"File changed since it was read. Re-read the file and retry.",
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const updates: Record<string, unknown> = { updatedAt: now };
|
|
193
|
+
if (content !== undefined && !skipContentWrite) updates.content = content;
|
|
194
|
+
if (filename !== undefined) updates.filename = filename;
|
|
195
|
+
if (fileType !== undefined) updates.fileType = fileType;
|
|
196
|
+
|
|
197
|
+
if (filename !== undefined && isPostgres()) {
|
|
198
|
+
await db.transaction(async (tx) => {
|
|
199
|
+
// Postgres evaluates concurrent NOT EXISTS updates under MVCC, so a
|
|
200
|
+
// guarded UPDATE alone can still race. Serialize design-file renames in
|
|
201
|
+
// this rare path without using SQLite's fragile async savepoint wrapper.
|
|
202
|
+
await (
|
|
203
|
+
tx as unknown as { execute: (query: unknown) => Promise<unknown> }
|
|
204
|
+
).execute(sql`LOCK TABLE design_files IN SHARE ROW EXCLUSIVE MODE`);
|
|
205
|
+
const [collision] = await tx
|
|
206
|
+
.select({ id: schema.designFiles.id })
|
|
207
|
+
.from(schema.designFiles)
|
|
208
|
+
.where(
|
|
209
|
+
and(
|
|
210
|
+
eq(schema.designFiles.designId, file.designId),
|
|
211
|
+
eq(schema.designFiles.filename, filename),
|
|
212
|
+
),
|
|
213
|
+
)
|
|
214
|
+
.limit(1);
|
|
215
|
+
if (collision && collision.id !== id) {
|
|
216
|
+
throw new Error(
|
|
217
|
+
`File "${filename}" already exists in design ${file.designId}`,
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
await tx
|
|
221
|
+
.update(schema.designFiles)
|
|
222
|
+
.set(updates)
|
|
223
|
+
.where(eq(schema.designFiles.id, id));
|
|
224
|
+
});
|
|
225
|
+
} else {
|
|
226
|
+
// Reject colliding SQLite renames as part of the write. SQLite's local
|
|
227
|
+
// async transaction wrapper can fail under concurrent editor/collab writes,
|
|
228
|
+
// so keep this to one guarded UPDATE instead of a SELECT-then-UPDATE window.
|
|
229
|
+
const updateWhere =
|
|
230
|
+
filename === undefined
|
|
231
|
+
? eq(schema.designFiles.id, id)
|
|
232
|
+
: and(
|
|
233
|
+
eq(schema.designFiles.id, id),
|
|
234
|
+
sql`NOT EXISTS (
|
|
128
235
|
SELECT 1 FROM design_files AS sibling
|
|
129
236
|
WHERE sibling.design_id = ${file.designId}
|
|
130
237
|
AND sibling.filename = ${filename}
|
|
131
238
|
AND sibling.id <> ${id}
|
|
132
239
|
)`,
|
|
133
|
-
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
const updateResult = await db
|
|
243
|
+
.update(schema.designFiles)
|
|
244
|
+
.set(updates)
|
|
245
|
+
.where(updateWhere);
|
|
134
246
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (collision && collision.id !== id) {
|
|
152
|
-
throw new Error(
|
|
153
|
-
`File "${filename}" already exists in design ${file.designId}`,
|
|
154
|
-
);
|
|
247
|
+
if (filename !== undefined && rowsAffected(updateResult) === 0) {
|
|
248
|
+
const [collision] = await db
|
|
249
|
+
.select({ id: schema.designFiles.id })
|
|
250
|
+
.from(schema.designFiles)
|
|
251
|
+
.where(
|
|
252
|
+
and(
|
|
253
|
+
eq(schema.designFiles.designId, file.designId),
|
|
254
|
+
eq(schema.designFiles.filename, filename),
|
|
255
|
+
),
|
|
256
|
+
)
|
|
257
|
+
.limit(1);
|
|
258
|
+
if (collision && collision.id !== id) {
|
|
259
|
+
throw new Error(
|
|
260
|
+
`File "${filename}" already exists in design ${file.designId}`,
|
|
261
|
+
);
|
|
262
|
+
}
|
|
155
263
|
}
|
|
156
264
|
}
|
|
157
|
-
}
|
|
158
265
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
266
|
+
// Push content through the collab layer so live editors see the change
|
|
267
|
+
if (content !== undefined && syncCollab) {
|
|
268
|
+
const collabExists = await hasCollabState(id);
|
|
269
|
+
if (collabExists) {
|
|
270
|
+
await applyText(id, content, "content", "agent");
|
|
271
|
+
} else {
|
|
272
|
+
await seedFromText(id, content);
|
|
273
|
+
}
|
|
166
274
|
}
|
|
167
|
-
}
|
|
275
|
+
});
|
|
168
276
|
|
|
169
|
-
// Update the parent design's updatedAt timestamp
|
|
277
|
+
// Update the parent design's updatedAt timestamp. This still runs even
|
|
278
|
+
// when the content write was skipped (skippedStaleMirror): filename/
|
|
279
|
+
// fileType may have changed in the same call, and even a content-only
|
|
280
|
+
// call that hit the skip path still represents a real request the design
|
|
281
|
+
// was touched by, matching this action's existing unconditional-bump
|
|
282
|
+
// contract for every other call shape.
|
|
170
283
|
await db
|
|
171
284
|
.update(schema.designs)
|
|
172
285
|
.set({ updatedAt: now })
|
|
173
286
|
.where(eq(schema.designs.id, file.designId));
|
|
174
287
|
|
|
175
|
-
return
|
|
288
|
+
return skippedStaleMirror
|
|
289
|
+
? { id, updated: true, skippedStaleMirror: true }
|
|
290
|
+
: { id, updated: true };
|
|
176
291
|
},
|
|
177
292
|
});
|