@agent-native/core 0.80.8 → 0.80.10
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 +2 -2
- package/corpus/core/CHANGELOG.md +19 -0
- package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +6 -0
- package/corpus/core/docs/content/locales/de-DE/template-design.mdx +8 -0
- package/corpus/core/docs/content/locales/es-ES/template-design.mdx +10 -2
- package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +10 -2
- package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +7 -0
- package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +7 -0
- package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +7 -0
- package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +9 -2
- package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +6 -0
- package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +6 -0
- package/corpus/core/docs/content/template-design.mdx +9 -2
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/design-connect.ts +28 -2
- package/corpus/core/src/cli/mcp.ts +10 -0
- package/corpus/core/src/cli/skills.ts +103 -36
- package/corpus/core/src/client/error-format.ts +25 -0
- package/corpus/core/src/client/extensions/ExtensionViewer.tsx +13 -11
- package/corpus/core/src/client/guided-questions.tsx +32 -4
- package/corpus/core/src/client/onboarding/OnboardingPanel.tsx +33 -1
- package/corpus/core/src/client/resources/BuiltinCapabilityDetail.tsx +8 -0
- package/corpus/core/src/client/resources/use-builtin-capabilities.ts +4 -2
- package/corpus/core/src/client/session-replay.ts +34 -0
- package/corpus/core/src/client/sharing/ShareButton.tsx +106 -21
- package/corpus/core/src/coding-tools/index.ts +1 -1
- package/corpus/core/src/mcp/index.ts +2 -0
- package/corpus/core/src/mcp/screen-memory-stdio.ts +290 -0
- package/corpus/core/src/mcp-client/builtin-capabilities.ts +13 -1
- package/corpus/core/src/mcp-client/index.ts +9 -0
- package/corpus/core/src/mcp-client/screen-memory-local.ts +461 -0
- package/corpus/core/src/onboarding/types.ts +7 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +25 -0
- package/corpus/core/src/server/agents-bundle.ts +35 -7
- package/corpus/core/src/styles/agent-native.css +5 -0
- package/corpus/core/src/templates/default/app/global.css +35 -35
- package/corpus/templates/analytics/AGENTS.md +6 -0
- package/corpus/templates/analytics/actions/github-repo-files.ts +9 -0
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +4 -4
- package/corpus/templates/analytics/app/global.css +144 -40
- package/corpus/templates/analytics/app/pages/adhoc/explorer/index.tsx +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/ChartCard.tsx +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +1 -1
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +4 -4
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +9 -9
- package/corpus/templates/analytics/changelog/2026-06-29-agents-can-search-and-read-connected-github-repositories-whe.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-sessions-and-explorer-layouts-adapt-when-the-agent-sidebar-is.md +6 -0
- package/corpus/templates/assets/app/components/layout/Layout.tsx +3 -1
- package/corpus/templates/assets/app/components/library/LibraryPresetGrid.tsx +1 -1
- package/corpus/templates/assets/app/global.css +99 -35
- package/corpus/templates/assets/app/routes/asset.$id.tsx +2 -2
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +4 -4
- package/corpus/templates/assets/app/routes/library.tsx +4 -4
- package/corpus/templates/assets/changelog/2026-06-29-asset-library-and-detail-layouts-adapt-when-the-agent-sidebar.md +6 -0
- package/corpus/templates/brain/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/brain/app/global.css +63 -35
- package/corpus/templates/brain/app/routes/search.tsx +1 -1
- package/corpus/templates/brain/app/routes/settings.tsx +1 -1
- package/corpus/templates/brain/app/routes/sources.tsx +2 -2
- package/corpus/templates/brain/changelog/2026-06-29-search-settings-and-source-layouts-adapt-when-the-agent-sidebar.md +6 -0
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +4 -4
- package/corpus/templates/calendar/app/components/calendar/FindTimePanel.tsx +3 -2
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +4 -2
- package/corpus/templates/calendar/app/global.css +69 -35
- package/corpus/templates/calendar/changelog/2026-06-29-event-and-find-time-layouts-adapt-when-the-agent-sidebar-is.md +6 -0
- package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/chat/app/global.css +35 -35
- package/corpus/templates/chat/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
- package/corpus/templates/clips/AGENTS.md +13 -0
- package/corpus/templates/clips/actions/get-screen-memory-status.ts +12 -0
- package/corpus/templates/clips/actions/query-screen-memory-context.ts +29 -0
- package/corpus/templates/clips/actions/view-screen.ts +2 -2
- package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
- package/corpus/templates/clips/app/global.css +47 -35
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +3 -3
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +45 -18
- package/corpus/templates/clips/changelog/2026-06-29-meeting-detail-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-29-screen-memory-keeps-a-local-rolling-screen-buffer-for-agent-context.md +5 -0
- package/corpus/templates/clips/changelog/2026-06-29-video-chat-is-easier-to-find-on-recording-pages-and-s3-setup.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/styles.css +39 -39
- package/corpus/templates/clips/desktop/src/app.tsx +290 -1
- package/corpus/templates/clips/desktop/src/shared/config.ts +83 -0
- package/corpus/templates/clips/desktop/src/styles.css +67 -52
- package/corpus/templates/clips/desktop/src-tauri/src/config.rs +50 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +17 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +13 -13
- package/corpus/templates/clips/desktop/src-tauri/src/screen_memory.rs +990 -0
- package/corpus/templates/clips/server/plugins/onboarding.ts +2 -0
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +3 -3
- package/corpus/templates/content/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/content/app/global.css +29 -15
- package/corpus/templates/content/changelog/2026-06-29-database-gallery-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +25 -20
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +8 -0
- package/corpus/templates/design/.agents/skills/export-handoff/SKILL.md +8 -0
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +13 -0
- package/corpus/templates/design/AGENTS.md +20 -12
- package/corpus/templates/design/CODE_NATIVE_DESIGN_STUDIO_IMPLEMENTATION_PLAN.md +1054 -0
- package/corpus/templates/design/DESIGN-STUDIO-PLAN.md +717 -0
- package/corpus/templates/design/actions/add-breakpoint.ts +143 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +5 -0
- package/corpus/templates/design/actions/apply-a11y-fix.ts +317 -0
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +433 -0
- package/corpus/templates/design/actions/apply-design-state.ts +200 -0
- package/corpus/templates/design/actions/apply-design-token-edit.ts +202 -0
- package/corpus/templates/design/actions/apply-motion-edit.ts +450 -0
- package/corpus/templates/design/actions/apply-shader-fill.ts +404 -0
- package/corpus/templates/design/actions/apply-visual-edit.ts +214 -8
- package/corpus/templates/design/actions/capture-design-state.ts +224 -0
- package/corpus/templates/design/actions/connect-builder-app.ts +162 -0
- package/corpus/templates/design/actions/create-component.ts +447 -0
- package/corpus/templates/design/actions/create-design-branch.ts +263 -0
- package/corpus/templates/design/actions/create-design-state.ts +162 -0
- package/corpus/templates/design/actions/delete-design-state.ts +55 -0
- package/corpus/templates/design/actions/deploy-design-preview.ts +275 -0
- package/corpus/templates/design/actions/export-coding-handoff.ts +12 -4
- package/corpus/templates/design/actions/generate-design.ts +6 -21
- package/corpus/templates/design/actions/generate-screens.ts +43 -2
- package/corpus/templates/design/actions/get-component-details.ts +242 -0
- package/corpus/templates/design/actions/get-design-branch-diff.ts +362 -0
- package/corpus/templates/design/actions/get-design-review.ts +314 -0
- package/corpus/templates/design/actions/get-design-surface-index.ts +582 -0
- package/corpus/templates/design/actions/get-design.ts +1 -0
- package/corpus/templates/design/actions/get-motion-timeline.ts +99 -0
- package/corpus/templates/design/actions/index-components.ts +258 -0
- package/corpus/templates/design/actions/index-design-tokens.ts +273 -0
- package/corpus/templates/design/actions/list-design-extensions.ts +309 -0
- package/corpus/templates/design/actions/list-design-source-capabilities.ts +153 -0
- package/corpus/templates/design/actions/list-design-states.ts +72 -0
- package/corpus/templates/design/actions/migrate-inline-design-to-app.ts +298 -0
- package/corpus/templates/design/actions/open-component-source.ts +237 -0
- package/corpus/templates/design/actions/present-design-variants.ts +355 -30
- package/corpus/templates/design/actions/preview-component-prop-edit.ts +254 -0
- package/corpus/templates/design/actions/preview-design-token-edit.ts +113 -0
- package/corpus/templates/design/actions/preview-shader-fill.ts +189 -0
- package/corpus/templates/design/actions/remove-breakpoint.ts +103 -0
- package/corpus/templates/design/actions/remove-motion-timeline.ts +196 -0
- package/corpus/templates/design/actions/run-design-audit.ts +421 -0
- package/corpus/templates/design/actions/run-design-extension-action.ts +284 -0
- package/corpus/templates/design/actions/set-active-breakpoint.ts +39 -0
- package/corpus/templates/design/actions/view-screen.ts +75 -31
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +1738 -135
- package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +1 -1
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +632 -43
- package/corpus/templates/design/app/components/design/DrawOverlay.tsx +1 -1
- package/corpus/templates/design/app/components/design/EditPanel.tsx +1873 -132
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +384 -219
- package/corpus/templates/design/app/components/design/LocalSourceEditBanner.tsx +157 -0
- package/corpus/templates/design/app/components/design/MotionDock.tsx +1062 -0
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +2103 -295
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +83 -206
- package/corpus/templates/design/app/components/design/ReviewPanel.tsx +759 -0
- package/corpus/templates/design/app/components/design/StatesPanel.tsx +579 -0
- package/corpus/templates/design/app/components/design/TokensPanel.tsx +573 -0
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +1 -1
- package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +241 -0
- package/corpus/templates/design/app/components/design/index.ts +16 -1
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +238 -137
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +188 -14
- package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +24 -5
- package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +57 -1
- package/corpus/templates/design/app/components/design/inspector/InspectorAiActions.tsx +145 -0
- package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +42 -12
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +37 -12
- package/corpus/templates/design/app/components/design/inspector/index.ts +1 -0
- package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +12 -5
- package/corpus/templates/design/app/components/design/types.ts +9 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +23 -5
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +1 -1
- package/corpus/templates/design/app/global.css +77 -49
- package/corpus/templates/design/app/hooks/use-question-flow.ts +2 -2
- package/corpus/templates/design/app/hooks/useAgentEditRequest.ts +131 -0
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +11 -2
- package/corpus/templates/design/app/i18n/zh-TW.ts +34 -0
- package/corpus/templates/design/app/i18n-data.ts +314 -3
- package/corpus/templates/design/app/pages/DesignEditor.tsx +4929 -892
- package/corpus/templates/design/app/root.tsx +1 -1
- package/corpus/templates/design/changelog/2026-06-29-added-a-review-panel-in-the-design-editor-s-inspector-with-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-containers-no-longer-block-selecting-nested-elements-and-nor.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-copying-and-pasting-layers-no-longer-shows-success-notificat.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-agents-now-generate-and-refine-variants-from-stronger.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-inspector-controls-now-match-figmas-softer-dark-chrome.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-questions-now-appear-as-a-cleaner-canvas-intake-with-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-variant-directions-now-appear-as-board-screens-with-chat-buttons.md +5 -0
- package/corpus/templates/design/changelog/2026-06-29-device-presets-in-all-screens-view-resize-the-selected-previ.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-element-selection-no-longer-snaps-back-to-the-previous-layer.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-frame-resize-measurements-now-stay-beside-the-cursor-while-d.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-inspector-number-fields-have-cleaner-tooltips-and-draggable-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-layer-and-canvas-drags-keep-the-layer-list-stable-while-chan.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-layer-locking-layer-nesting-generated-question-intake-and-im.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-layer-moves-can-be-undone-and-redone-without-flashing-the-ca.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-layer-names-in-the-sidebar-can-scroll-horizontally-instead-o.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-layer-nesting-in-the-sidebar-now-uses-tighter-spacing-so-nam.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-layers-no-longer-repeat-document-wrapper-rows-when-a-screen-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-overview-previews-now-keep-element-hover-and-selection-tied-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-pressing-escape-now-cancels-a-stuck-screen-drag-in-the-overv.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-is-easier-to-find-and-named-screens-open-dir.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-only-highlights-screens-when-the-frame-or-ti.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-previews-now-resize-to-match-the-selected-de.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-selection-now-uses-a-pointer-cursor-instead-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-selection-outlines-now-stay-locked-to-the-se.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-zoom-now-reports-real-screen-scale-separatel.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-zooming-feels-smoother-and-selection-outline.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-zooming-now-stays-on-the-overview-canvas-ins.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-previews-use-a-single-blue-hover-border-in-all-screen.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-selected-containers-show-draggable-padding-and-gap-guides-on.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-selecting-a-nested-layer-from-all-screens-now-keeps-you-in-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-share-now-groups-link-sharing-exports-and-agent-handoff.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-the-design-editor-adds-a-studio-layer-with-tokens-respon.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-the-design-editor-loading-skeleton-now-uses-a-softer-charcoa.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-the-device-preview-menu-now-sits-next-to-the-preview-button-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-the-inspector-stays-read-only-while-an-empty-design-is-still.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-the-missing-design-view-now-matches-the-rest-of-the-editor-c.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-the-pen-tool-icon-and-tool-option-menus-better-match-the-edi.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-typography-controls-now-keep-the-font-name-visible-and-move-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-accessibility-findings-now-offer-a-one-click-fix.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-component-instances-now-have-editable-props-in-the-inspe.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-inspect-code-now-shows-the-elements-opening-tag-at-a-gla.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-shader-fill-presets-can-now-be-applied-to-an-element.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-motion-timeline-can-now-add-a-track-to-any-element-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-visual-editor-selection-layer-paint-and-drawing-controls-are-more-reliable.md +6 -0
- package/corpus/templates/design/e2e/README.md +3 -3
- package/corpus/templates/design/e2e/global-setup.ts +11 -22
- package/corpus/templates/design/e2e/helpers.ts +128 -11
- package/corpus/templates/design/playwright.config.ts +9 -3
- package/corpus/templates/design/server/db/schema.ts +123 -0
- package/corpus/templates/design/server/lib/coding-handoff.ts +126 -2
- package/corpus/templates/design/server/plugins/core-routes.ts +1 -2
- package/corpus/templates/design/server/plugins/db.ts +90 -0
- package/corpus/templates/design/server/routes/api/design-handoff/[id].zip.get.ts +86 -0
- package/corpus/templates/design/shared/builder-app.ts +297 -0
- package/corpus/templates/design/shared/capability-resolver.ts +123 -0
- package/corpus/templates/design/shared/capture-sanitize.ts +70 -0
- package/corpus/templates/design/shared/code-layer.ts +1141 -93
- package/corpus/templates/design/shared/component-model.ts +239 -0
- package/corpus/templates/design/shared/design-review.ts +275 -0
- package/corpus/templates/design/shared/design-source-capabilities.ts +286 -0
- package/corpus/templates/design/shared/design-state.ts +112 -0
- package/corpus/templates/design/shared/design-surface-index.ts +258 -0
- package/corpus/templates/design/shared/generation-session.ts +41 -0
- package/corpus/templates/design/shared/motion-compiler.ts +278 -0
- package/corpus/templates/design/shared/motion-timeline.ts +193 -0
- package/corpus/templates/design/shared/responsive-classes.ts +452 -0
- package/corpus/templates/design/shared/shader-fill.ts +323 -0
- package/corpus/templates/design/shared/source-mode.ts +245 -0
- package/corpus/templates/dispatch/app/global.css +79 -35
- package/corpus/templates/dispatch/app/routes/integrations.tsx +8 -7
- package/corpus/templates/dispatch/changelog/2026-06-29-integration-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
- package/corpus/templates/forms/app/components/layout/Layout.tsx +6 -2
- package/corpus/templates/forms/app/global.css +64 -35
- package/corpus/templates/forms/app/pages/FormsListPage.tsx +2 -2
- package/corpus/templates/forms/app/pages/ResponseInsightsPage.tsx +3 -3
- package/corpus/templates/forms/changelog/2026-06-29-form-list-and-insight-layouts-adapt-when-the-agent-sidebar.md +6 -0
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +3 -1
- package/corpus/templates/macros/app/global.css +25 -9
- package/corpus/templates/macros/changelog/2026-06-29-macro-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +6 -2
- package/corpus/templates/mail/app/global.css +42 -36
- package/corpus/templates/mail/app/pages/InboxPage.tsx +1 -1
- package/corpus/templates/mail/changelog/2026-06-29-the-contact-panel-now-adapts-to-the-available-mail-pane-width.md +6 -0
- package/corpus/templates/plan/app/components/layout/Layout.tsx +3 -1
- package/corpus/templates/plan/app/components/plan/CanvasArea.tsx +6 -2
- package/corpus/templates/plan/app/components/plan/DocumentArea.tsx +6 -7
- package/corpus/templates/plan/app/global.css +74 -42
- package/corpus/templates/plan/changelog/2026-06-29-plan-canvases-open-without-an-initial-pan-and-zoom-flicker.md +6 -0
- package/corpus/templates/plan/changelog/2026-06-29-plan-document-blocks-adapt-to-the-available-document-width.md +6 -0
- package/corpus/templates/plan/changelog/2026-06-29-plan-titles-and-summaries-can-be-edited-inline-without-focus.md +6 -0
- package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -1
- package/corpus/templates/slides/app/global.css +49 -33
- package/corpus/templates/slides/changelog/2026-06-29-slide-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
- package/corpus/templates/videos/app/components/layout/Layout.tsx +3 -1
- package/corpus/templates/videos/app/global.css +35 -35
- package/corpus/templates/videos/changelog/2026-06-29-video-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +28 -2
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/mcp.d.ts.map +1 -1
- package/dist/cli/mcp.js +10 -0
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +95 -33
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +17 -0
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionViewer.js +3 -4
- package/dist/client/extensions/ExtensionViewer.js.map +1 -1
- package/dist/client/guided-questions.d.ts +4 -0
- package/dist/client/guided-questions.d.ts.map +1 -1
- package/dist/client/guided-questions.js +16 -7
- package/dist/client/guided-questions.js.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.js +26 -1
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/resources/BuiltinCapabilityDetail.d.ts.map +1 -1
- package/dist/client/resources/BuiltinCapabilityDetail.js +1 -1
- package/dist/client/resources/BuiltinCapabilityDetail.js.map +1 -1
- package/dist/client/resources/use-builtin-capabilities.d.ts +1 -1
- package/dist/client/resources/use-builtin-capabilities.d.ts.map +1 -1
- package/dist/client/resources/use-builtin-capabilities.js +2 -1
- package/dist/client/resources/use-builtin-capabilities.js.map +1 -1
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +31 -0
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts +14 -0
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +36 -7
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/coding-tools/index.js +1 -1
- package/dist/coding-tools/index.js.map +1 -1
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -0
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/screen-memory-stdio.d.ts +6 -0
- package/dist/mcp/screen-memory-stdio.d.ts.map +1 -0
- package/dist/mcp/screen-memory-stdio.js +213 -0
- package/dist/mcp/screen-memory-stdio.js.map +1 -0
- package/dist/mcp-client/builtin-capabilities.d.ts +1 -1
- package/dist/mcp-client/builtin-capabilities.d.ts.map +1 -1
- package/dist/mcp-client/builtin-capabilities.js +10 -0
- package/dist/mcp-client/builtin-capabilities.js.map +1 -1
- package/dist/mcp-client/index.d.ts +1 -0
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +1 -0
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/mcp-client/screen-memory-local.d.ts +61 -0
- package/dist/mcp-client/screen-memory-local.d.ts.map +1 -0
- package/dist/mcp-client/screen-memory-local.js +336 -0
- package/dist/mcp-client/screen-memory-local.js.map +1 -0
- package/dist/observability/routes.d.ts +3 -3
- package/dist/onboarding/types.d.ts +7 -0
- package/dist/onboarding/types.d.ts.map +1 -1
- package/dist/onboarding/types.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +26 -0
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agents-bundle.d.ts.map +1 -1
- package/dist/server/agents-bundle.js +22 -7
- package/dist/server/agents-bundle.js.map +1 -1
- package/dist/styles/agent-native.css +5 -0
- package/dist/templates/default/app/global.css +35 -35
- package/docs/content/locales/ar-SA/template-design.mdx +6 -0
- package/docs/content/locales/de-DE/template-design.mdx +8 -0
- package/docs/content/locales/es-ES/template-design.mdx +10 -2
- package/docs/content/locales/fr-FR/template-design.mdx +10 -2
- package/docs/content/locales/hi-IN/template-design.mdx +7 -0
- package/docs/content/locales/ja-JP/template-design.mdx +7 -0
- package/docs/content/locales/ko-KR/template-design.mdx +7 -0
- package/docs/content/locales/pt-BR/template-design.mdx +9 -2
- package/docs/content/locales/zh-CN/template-design.mdx +6 -0
- package/docs/content/locales/zh-TW/template-design.mdx +6 -0
- package/docs/content/template-design.mdx +9 -2
- package/package.json +1 -1
- package/src/templates/default/app/global.css +35 -35
- package/corpus/templates/design/app/components/design/VariantGrid.tsx +0 -189
- package/corpus/templates/design/app/components/design/VariantHandoffCard.tsx +0 -115
- package/corpus/templates/design/app/hooks/use-variant-flow.ts +0 -342
|
@@ -14,6 +14,7 @@ import type { ShaderDescriptor } from "@shared/shader-presets";
|
|
|
14
14
|
import { IconChevronDown, IconColorPicker } from "@tabler/icons-react";
|
|
15
15
|
import {
|
|
16
16
|
useEffect,
|
|
17
|
+
useMemo,
|
|
17
18
|
useRef,
|
|
18
19
|
useState,
|
|
19
20
|
type JSX,
|
|
@@ -27,6 +28,13 @@ import {
|
|
|
27
28
|
PopoverContent,
|
|
28
29
|
PopoverTrigger,
|
|
29
30
|
} from "@/components/ui/popover";
|
|
31
|
+
import {
|
|
32
|
+
Select,
|
|
33
|
+
SelectContent,
|
|
34
|
+
SelectItem,
|
|
35
|
+
SelectTrigger,
|
|
36
|
+
SelectValue,
|
|
37
|
+
} from "@/components/ui/select";
|
|
30
38
|
import {
|
|
31
39
|
Tooltip,
|
|
32
40
|
TooltipContent,
|
|
@@ -130,6 +138,7 @@ export interface DesignColorPickerProps {
|
|
|
130
138
|
value: string;
|
|
131
139
|
onChange: (value: string) => void;
|
|
132
140
|
onPaintValueChange?: (value: string) => void;
|
|
141
|
+
onImageFillChange?: (value: ImageFillValue) => void;
|
|
133
142
|
label?: string;
|
|
134
143
|
opacity?: number;
|
|
135
144
|
onOpacityChange?: (opacity: number) => void;
|
|
@@ -191,6 +200,87 @@ interface HsvaColor {
|
|
|
191
200
|
|
|
192
201
|
const FALLBACK_COLOR: RgbaColor = { r: 0, g: 0, b: 0, a: 1 };
|
|
193
202
|
|
|
203
|
+
// ─── Extended CSS color parser ──────────────────────────────────────────────────
|
|
204
|
+
//
|
|
205
|
+
// `parseCssColor` from color-utils handles hex, comma-separated rgb/rgba, and
|
|
206
|
+
// hsl/hsla. Browsers increasingly emit modern CSS Level 4 formats from
|
|
207
|
+
// getComputedStyle: space-separated `rgb(R G B)`, `rgb(R G B / A)`, and
|
|
208
|
+
// opaque formats like `oklch(...)` or `color(display-p3 ...)`.
|
|
209
|
+
//
|
|
210
|
+
// This local wrapper extends the parser to cover those cases so that colors
|
|
211
|
+
// arriving from the canvas's computed-style bridge are always usable.
|
|
212
|
+
|
|
213
|
+
const MODERN_RGB_PATTERN =
|
|
214
|
+
/^rgba?\(\s*([0-9.]+)\s+([0-9.]+)\s+([0-9.]+)(?:\s*\/\s*([0-9.]+%?))?\s*\)$/i;
|
|
215
|
+
|
|
216
|
+
/** Canvas element reused across calls for DOM-based color resolution. */
|
|
217
|
+
let _resolverCanvas: HTMLCanvasElement | null = null;
|
|
218
|
+
let _resolverCtx: CanvasRenderingContext2D | null = null;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Parses a CSS color string into RgbaColor, extending the base parser with:
|
|
222
|
+
* - Modern space-separated `rgb(R G B)` / `rgb(R G B / A)` syntax
|
|
223
|
+
* - Opaque formats (oklch, color, etc.) resolved via a hidden canvas
|
|
224
|
+
*
|
|
225
|
+
* Falls back to null if the value is unparseable and the DOM is unavailable.
|
|
226
|
+
*/
|
|
227
|
+
function parseCssColorExtended(value: string): RgbaColor | null {
|
|
228
|
+
// 1. Try the standard parser first (handles hex, comma rgb/rgba, hsl/hsla).
|
|
229
|
+
const standard = parseCssColor(value);
|
|
230
|
+
if (standard) return standard;
|
|
231
|
+
|
|
232
|
+
const trimmed = value.trim();
|
|
233
|
+
if (!trimmed || trimmed === "transparent" || trimmed === "none") return null;
|
|
234
|
+
|
|
235
|
+
// 2. Modern space-separated rgb/rgba — CSS Level 4.
|
|
236
|
+
const modernRgb = trimmed.match(MODERN_RGB_PATTERN);
|
|
237
|
+
if (modernRgb) {
|
|
238
|
+
const parseAlphaLocal = (v: string | undefined): number => {
|
|
239
|
+
if (!v) return 1;
|
|
240
|
+
if (v.endsWith("%"))
|
|
241
|
+
return Math.max(0, Math.min(1, Number(v.slice(0, -1)) / 100));
|
|
242
|
+
return Math.max(0, Math.min(1, Number(v)));
|
|
243
|
+
};
|
|
244
|
+
return {
|
|
245
|
+
r: Math.round(Math.max(0, Math.min(255, Number(modernRgb[1])))),
|
|
246
|
+
g: Math.round(Math.max(0, Math.min(255, Number(modernRgb[2])))),
|
|
247
|
+
b: Math.round(Math.max(0, Math.min(255, Number(modernRgb[3])))),
|
|
248
|
+
a: parseAlphaLocal(modernRgb[4]),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// 3. DOM-based resolver for oklch, color(display-p3 ...), hsl (modern), etc.
|
|
253
|
+
// Uses a hidden 1×1 canvas to resolve any valid CSS color to rgb().
|
|
254
|
+
if (typeof document === "undefined") return null;
|
|
255
|
+
try {
|
|
256
|
+
if (!_resolverCanvas) {
|
|
257
|
+
_resolverCanvas = document.createElement("canvas");
|
|
258
|
+
_resolverCanvas.width = 1;
|
|
259
|
+
_resolverCanvas.height = 1;
|
|
260
|
+
}
|
|
261
|
+
if (!_resolverCtx) {
|
|
262
|
+
_resolverCtx = _resolverCanvas.getContext("2d", {
|
|
263
|
+
willReadFrequently: true,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
const ctx = _resolverCtx;
|
|
267
|
+
if (!ctx) return null;
|
|
268
|
+
// Detect invalid color values: save fillStyle before and after assignment.
|
|
269
|
+
// If the browser rejects the value, fillStyle won't change.
|
|
270
|
+
const prev = ctx.fillStyle;
|
|
271
|
+
ctx.fillStyle = trimmed;
|
|
272
|
+
const next = ctx.fillStyle; // browser normalises to rgb/hex on accept
|
|
273
|
+
// If the value was rejected, fillStyle stays at the previous value.
|
|
274
|
+
if (next === prev) return null;
|
|
275
|
+
ctx.clearRect(0, 0, 1, 1);
|
|
276
|
+
ctx.fillRect(0, 0, 1, 1);
|
|
277
|
+
const [r, g, b, a] = ctx.getImageData(0, 0, 1, 1).data;
|
|
278
|
+
return { r, g, b, a: a / 255 };
|
|
279
|
+
} catch {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
194
284
|
const DEFAULT_LABELS: DesignColorPickerLabels = {
|
|
195
285
|
trigger: "Open color picker", // i18n-ignore fallback component label
|
|
196
286
|
hex: "Hex", // i18n-ignore fallback component label
|
|
@@ -568,6 +658,24 @@ const NOISE_FALLBACK_CSS =
|
|
|
568
658
|
"repeating-conic-gradient(#0000 0% 25%, #00000010 0% 50%) 0 0 / 6px 6px, #8a8a8a";
|
|
569
659
|
const PATTERN_FALLBACK_CSS =
|
|
570
660
|
"repeating-linear-gradient(45deg, #00000014 0 6px, #ffffff14 6px 12px), #9aa0a6";
|
|
661
|
+
const BLEND_MODE_OPTIONS = [
|
|
662
|
+
{ value: "normal", label: "Normal" },
|
|
663
|
+
{ value: "multiply", label: "Multiply" },
|
|
664
|
+
{ value: "screen", label: "Screen" },
|
|
665
|
+
{ value: "overlay", label: "Overlay" },
|
|
666
|
+
{ value: "darken", label: "Darken" },
|
|
667
|
+
{ value: "lighten", label: "Lighten" },
|
|
668
|
+
{ value: "color-dodge", label: "Color dodge" }, // i18n-ignore design blend mode label
|
|
669
|
+
{ value: "color-burn", label: "Color burn" }, // i18n-ignore design blend mode label
|
|
670
|
+
{ value: "hard-light", label: "Hard light" }, // i18n-ignore design blend mode label
|
|
671
|
+
{ value: "soft-light", label: "Soft light" }, // i18n-ignore design blend mode label
|
|
672
|
+
{ value: "difference", label: "Difference" },
|
|
673
|
+
{ value: "exclusion", label: "Exclusion" },
|
|
674
|
+
{ value: "hue", label: "Hue" },
|
|
675
|
+
{ value: "saturation", label: "Saturation" },
|
|
676
|
+
{ value: "color", label: "Color" },
|
|
677
|
+
{ value: "luminosity", label: "Luminosity" },
|
|
678
|
+
] as const;
|
|
571
679
|
|
|
572
680
|
// ─── Main component ────────────────────────────────────────────────────────────
|
|
573
681
|
|
|
@@ -575,12 +683,13 @@ export function DesignColorPicker({
|
|
|
575
683
|
value,
|
|
576
684
|
onChange,
|
|
577
685
|
onPaintValueChange,
|
|
686
|
+
onImageFillChange,
|
|
578
687
|
label: _label,
|
|
579
688
|
opacity,
|
|
580
689
|
onOpacityChange,
|
|
581
|
-
blendMode
|
|
582
|
-
onBlendModeChange
|
|
583
|
-
showBlendMode
|
|
690
|
+
blendMode,
|
|
691
|
+
onBlendModeChange,
|
|
692
|
+
showBlendMode = false,
|
|
584
693
|
fillRows: _fillRows,
|
|
585
694
|
selectedFillId: _selectedFillId,
|
|
586
695
|
onFillSelect: _onFillSelect,
|
|
@@ -605,10 +714,15 @@ export function DesignColorPicker({
|
|
|
605
714
|
className,
|
|
606
715
|
}: DesignColorPickerProps) {
|
|
607
716
|
const copy = { ...DEFAULT_LABELS, ...labels };
|
|
608
|
-
const color =
|
|
717
|
+
const color = parseCssColorExtended(value) ?? FALLBACK_COLOR;
|
|
609
718
|
const hsv = rgbaToHsv(color);
|
|
610
719
|
const hsl = rgbaToHsl(color);
|
|
611
720
|
const effectiveOpacity = opacity ?? alphaToOpacity(color.a);
|
|
721
|
+
const blendModeValue = BLEND_MODE_OPTIONS.some(
|
|
722
|
+
(option) => option.value === blendMode,
|
|
723
|
+
)
|
|
724
|
+
? blendMode
|
|
725
|
+
: "normal";
|
|
612
726
|
|
|
613
727
|
const [mode, setMode] = useState<DesignColorMode>("hex");
|
|
614
728
|
const [hexDraft, setHexDraft] = useState(() => toDisplayHex(color));
|
|
@@ -651,16 +765,24 @@ export function DesignColorPicker({
|
|
|
651
765
|
|
|
652
766
|
// Resolve the active gradient: prefer EditPanel-driven props; otherwise parse
|
|
653
767
|
// the live CSS value, falling back to local edit state.
|
|
654
|
-
const parsedGradient =
|
|
768
|
+
const parsedGradient = useMemo(
|
|
769
|
+
() => parseGradientCss(value, gradientType ?? "linear"),
|
|
770
|
+
[gradientType, value],
|
|
771
|
+
);
|
|
772
|
+
const fallbackGradient = useMemo(
|
|
773
|
+
() =>
|
|
774
|
+
GRADIENT_TYPES.has(effectivePaintType)
|
|
775
|
+
? defaultGradient(
|
|
776
|
+
effectivePaintType as GradientKind,
|
|
777
|
+
toCssColor(color) || "#000000",
|
|
778
|
+
)
|
|
779
|
+
: null,
|
|
780
|
+
[color.r, color.g, color.b, color.a, effectivePaintType],
|
|
781
|
+
);
|
|
655
782
|
const activeGradient: GradientValue | null = GRADIENT_TYPES.has(
|
|
656
783
|
effectivePaintType,
|
|
657
784
|
)
|
|
658
|
-
? (localGradient ??
|
|
659
|
-
parsedGradient ??
|
|
660
|
-
defaultGradient(
|
|
661
|
-
effectivePaintType as GradientKind,
|
|
662
|
-
toCssColor(color) || "#000000",
|
|
663
|
-
))
|
|
785
|
+
? (localGradient ?? parsedGradient ?? fallbackGradient)
|
|
664
786
|
: null;
|
|
665
787
|
|
|
666
788
|
useEffect(() => {
|
|
@@ -754,7 +876,8 @@ export function DesignColorPicker({
|
|
|
754
876
|
|
|
755
877
|
// The 2D field edits the selected gradient stop's color when in gradient mode.
|
|
756
878
|
const fieldColor: RgbaColor = activeGradient
|
|
757
|
-
? (
|
|
879
|
+
? (parseCssColorExtended(selectedStop?.color ?? "#000000") ??
|
|
880
|
+
FALLBACK_COLOR)
|
|
758
881
|
: color;
|
|
759
882
|
const rawFieldHsv = rgbaToHsv(fieldColor);
|
|
760
883
|
// Preserve the last non-zero hue so dragging through gray doesn't lose it.
|
|
@@ -771,7 +894,7 @@ export function DesignColorPicker({
|
|
|
771
894
|
const selectedStopColor = selectedStop?.color;
|
|
772
895
|
useEffect(() => {
|
|
773
896
|
if (!activeGradient || !selectedStopColor) return;
|
|
774
|
-
const parsed =
|
|
897
|
+
const parsed = parseCssColorExtended(selectedStopColor);
|
|
775
898
|
if (parsed) setHexDraft(toDisplayHex(parsed));
|
|
776
899
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
777
900
|
}, [selectedStopColor, selectedStopId]);
|
|
@@ -807,6 +930,10 @@ export function DesignColorPicker({
|
|
|
807
930
|
|
|
808
931
|
const emitImageFill = (next: ImageFillValue) => {
|
|
809
932
|
setImageFill(next);
|
|
933
|
+
if (onImageFillChange) {
|
|
934
|
+
onImageFillChange(next);
|
|
935
|
+
return;
|
|
936
|
+
}
|
|
810
937
|
emitPaintValue(imageFillToCss(next));
|
|
811
938
|
};
|
|
812
939
|
|
|
@@ -860,6 +987,10 @@ export function DesignColorPicker({
|
|
|
860
987
|
return;
|
|
861
988
|
}
|
|
862
989
|
if (nextType === "image") {
|
|
990
|
+
if (onImageFillChange && imageFill.url) {
|
|
991
|
+
onImageFillChange(imageFill);
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
863
994
|
emitPaintValue(imageFill.url ? imageFillToCss(imageFill) : "transparent");
|
|
864
995
|
return;
|
|
865
996
|
}
|
|
@@ -1060,8 +1191,18 @@ export function DesignColorPicker({
|
|
|
1060
1191
|
align="start"
|
|
1061
1192
|
sideOffset={8}
|
|
1062
1193
|
className="z-[10000] w-[252px] p-0 shadow-xl"
|
|
1194
|
+
// Keep the picker open when the style change triggered by a paint-type
|
|
1195
|
+
// switch causes the canvas to re-project the element. Without this,
|
|
1196
|
+
// Radix treats the resulting focus shift as an "interact outside" event
|
|
1197
|
+
// and closes the popover before the type switch is visible.
|
|
1198
|
+
onInteractOutside={(e) => {
|
|
1199
|
+
// Allow closing only for genuine pointer clicks on the canvas area
|
|
1200
|
+
// (the user clicked somewhere else). Programmatic focus changes from
|
|
1201
|
+
// the canvas bridge (element re-projection) should not close the picker.
|
|
1202
|
+
if (e.type === "focusoutside") e.preventDefault();
|
|
1203
|
+
}}
|
|
1063
1204
|
>
|
|
1064
|
-
<div className="
|
|
1205
|
+
<div className="rounded-md bg-popover text-popover-foreground">
|
|
1065
1206
|
{view === "shader" ? (
|
|
1066
1207
|
<ShaderFillsPanel
|
|
1067
1208
|
descriptor={shaderDescriptor ?? undefined}
|
|
@@ -1395,6 +1536,39 @@ export function DesignColorPicker({
|
|
|
1395
1536
|
</div>
|
|
1396
1537
|
)}
|
|
1397
1538
|
|
|
1539
|
+
{showBlendMode && onBlendModeChange && (
|
|
1540
|
+
<div className="border-t border-border/70 px-3 py-2.5">
|
|
1541
|
+
<div className="flex items-center gap-1.5">
|
|
1542
|
+
<span className="min-w-0 flex-1 text-[11px] text-muted-foreground">
|
|
1543
|
+
{copy.blendMode}
|
|
1544
|
+
</span>
|
|
1545
|
+
<Select
|
|
1546
|
+
value={blendModeValue}
|
|
1547
|
+
disabled={disabled}
|
|
1548
|
+
onValueChange={onBlendModeChange}
|
|
1549
|
+
>
|
|
1550
|
+
<SelectTrigger
|
|
1551
|
+
aria-label={copy.blendMode}
|
|
1552
|
+
className="h-6 min-w-0 flex-1 rounded-md border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] px-1.5 text-[11px] shadow-none focus:ring-1 focus:ring-[var(--design-editor-accent-color)]"
|
|
1553
|
+
>
|
|
1554
|
+
<SelectValue />
|
|
1555
|
+
</SelectTrigger>
|
|
1556
|
+
<SelectContent>
|
|
1557
|
+
{BLEND_MODE_OPTIONS.map((option) => (
|
|
1558
|
+
<SelectItem
|
|
1559
|
+
key={option.value}
|
|
1560
|
+
value={option.value}
|
|
1561
|
+
className="text-[11px]"
|
|
1562
|
+
>
|
|
1563
|
+
{option.label}
|
|
1564
|
+
</SelectItem>
|
|
1565
|
+
))}
|
|
1566
|
+
</SelectContent>
|
|
1567
|
+
</Select>
|
|
1568
|
+
</div>
|
|
1569
|
+
</div>
|
|
1570
|
+
)}
|
|
1571
|
+
|
|
1398
1572
|
{/* ── Document colors ──────────────────────────────────────── */}
|
|
1399
1573
|
{/* Renders the palette of colors already used in the design.
|
|
1400
1574
|
When `documentColors` is provided, those swatches are shown;
|
|
@@ -57,6 +57,9 @@ const DEFAULT_LABELS: ExportSettingsPanelLabels = {
|
|
|
57
57
|
|
|
58
58
|
const DEFAULT_FORMATS: ExportFormat[] = ["png", "jpg", "svg", "pdf", "webp"];
|
|
59
59
|
|
|
60
|
+
const controlChromeClass =
|
|
61
|
+
"border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] text-foreground shadow-none hover:bg-[var(--design-editor-panel-raised-bg)] hover:text-foreground focus:ring-1 focus:ring-[var(--design-editor-accent-color)] focus:ring-offset-0 focus-visible:ring-1 focus-visible:ring-[var(--design-editor-accent-color)] focus-visible:ring-offset-0";
|
|
62
|
+
|
|
60
63
|
// Export scale bounds — must match the clamp in DesignEditor's PNG/SVG export
|
|
61
64
|
// handlers so the panel never promises a range the exporter won't render.
|
|
62
65
|
const MIN_EXPORT_SCALE = 0.1;
|
|
@@ -135,7 +138,12 @@ function ScaleSelect({
|
|
|
135
138
|
}
|
|
136
139
|
}}
|
|
137
140
|
>
|
|
138
|
-
<SelectTrigger
|
|
141
|
+
<SelectTrigger
|
|
142
|
+
className={cn(
|
|
143
|
+
"h-6 w-14 shrink-0 px-1.5 text-[11px]",
|
|
144
|
+
controlChromeClass,
|
|
145
|
+
)}
|
|
146
|
+
>
|
|
139
147
|
<SelectValue />
|
|
140
148
|
</SelectTrigger>
|
|
141
149
|
<SelectContent>
|
|
@@ -267,7 +275,7 @@ export function ExportSettingsPanel({
|
|
|
267
275
|
variant="outline"
|
|
268
276
|
disabled={isDisabled}
|
|
269
277
|
onClick={handleExport}
|
|
270
|
-
className="h-6 w-full px-2 text-[11px]"
|
|
278
|
+
className={cn("h-6 w-full px-2 text-[11px]", controlChromeClass)}
|
|
271
279
|
>
|
|
272
280
|
<IconDownload className="size-3.5" />
|
|
273
281
|
{copy.export}
|
|
@@ -324,7 +332,10 @@ function ExportRow({
|
|
|
324
332
|
onPatchRow(row.id, { customScale: false });
|
|
325
333
|
}
|
|
326
334
|
}}
|
|
327
|
-
className=
|
|
335
|
+
className={cn(
|
|
336
|
+
"h-6 w-14 shrink-0 px-1.5 text-[11px] tabular-nums",
|
|
337
|
+
controlChromeClass,
|
|
338
|
+
)}
|
|
328
339
|
aria-label="Scale"
|
|
329
340
|
// eslint-disable-next-line jsx-a11y/no-autofocus
|
|
330
341
|
autoFocus
|
|
@@ -352,7 +363,12 @@ function ExportRow({
|
|
|
352
363
|
onPatchRow(row.id, { format: format as ExportFormat })
|
|
353
364
|
}
|
|
354
365
|
>
|
|
355
|
-
<SelectTrigger
|
|
366
|
+
<SelectTrigger
|
|
367
|
+
className={cn(
|
|
368
|
+
"h-6 min-w-0 flex-1 px-1.5 text-[11px]",
|
|
369
|
+
controlChromeClass,
|
|
370
|
+
)}
|
|
371
|
+
>
|
|
356
372
|
<SelectValue />
|
|
357
373
|
</SelectTrigger>
|
|
358
374
|
<SelectContent>
|
|
@@ -376,7 +392,10 @@ function ExportRow({
|
|
|
376
392
|
disabled={isDisabled}
|
|
377
393
|
onChange={(e) => onPatchRow(row.id, { suffix: e.target.value })}
|
|
378
394
|
placeholder={labels.suffix}
|
|
379
|
-
className=
|
|
395
|
+
className={cn(
|
|
396
|
+
"h-6 min-w-0 flex-1 px-1.5 text-[11px]",
|
|
397
|
+
controlChromeClass,
|
|
398
|
+
)}
|
|
380
399
|
aria-label={labels.suffix}
|
|
381
400
|
/>
|
|
382
401
|
|
|
@@ -80,6 +80,59 @@ export function imageFillToCss(value: ImageFillValue): string {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
export function imageFillToBackgroundStyles(
|
|
84
|
+
value: ImageFillValue,
|
|
85
|
+
): Record<
|
|
86
|
+
| "backgroundImage"
|
|
87
|
+
| "backgroundSize"
|
|
88
|
+
| "backgroundRepeat"
|
|
89
|
+
| "backgroundPosition",
|
|
90
|
+
string
|
|
91
|
+
> {
|
|
92
|
+
const url = value.url.trim();
|
|
93
|
+
if (!url) {
|
|
94
|
+
return {
|
|
95
|
+
backgroundImage: "none",
|
|
96
|
+
backgroundSize: "auto",
|
|
97
|
+
backgroundRepeat: "no-repeat",
|
|
98
|
+
backgroundPosition: "center",
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
const safeUrl = url.replace(/["')]/g, encodeURIComponent);
|
|
102
|
+
const backgroundImage = `url("${safeUrl}")`;
|
|
103
|
+
switch (value.fit) {
|
|
104
|
+
case "fit":
|
|
105
|
+
return {
|
|
106
|
+
backgroundImage,
|
|
107
|
+
backgroundSize: "contain",
|
|
108
|
+
backgroundRepeat: "no-repeat",
|
|
109
|
+
backgroundPosition: "center",
|
|
110
|
+
};
|
|
111
|
+
case "tile":
|
|
112
|
+
return {
|
|
113
|
+
backgroundImage,
|
|
114
|
+
backgroundSize: "auto",
|
|
115
|
+
backgroundRepeat: "repeat",
|
|
116
|
+
backgroundPosition: "top left",
|
|
117
|
+
};
|
|
118
|
+
case "crop":
|
|
119
|
+
return {
|
|
120
|
+
backgroundImage,
|
|
121
|
+
backgroundSize: "cover",
|
|
122
|
+
backgroundRepeat: "no-repeat",
|
|
123
|
+
backgroundPosition: "center",
|
|
124
|
+
};
|
|
125
|
+
case "fill":
|
|
126
|
+
default:
|
|
127
|
+
return {
|
|
128
|
+
backgroundImage,
|
|
129
|
+
backgroundSize: "cover",
|
|
130
|
+
backgroundRepeat: "no-repeat",
|
|
131
|
+
backgroundPosition: "center",
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
83
136
|
// Matches url() in three forms:
|
|
84
137
|
// group 1 — double-quoted: url("...anything...")
|
|
85
138
|
// group 2 — single-quoted: url('...anything...')
|
|
@@ -249,7 +302,10 @@ export function ImageFillControls({
|
|
|
249
302
|
onValueChange={(v) => onChange({ ...value, fit: v as ImageFitMode })}
|
|
250
303
|
disabled={disabled}
|
|
251
304
|
>
|
|
252
|
-
<SelectTrigger
|
|
305
|
+
<SelectTrigger
|
|
306
|
+
aria-label={"Fill" /* i18n-ignore image fit selector */}
|
|
307
|
+
className="h-6 w-full rounded-md border border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] px-2 text-[11px] shadow-none focus:ring-0 focus:ring-offset-0 focus-visible:ring-2 focus-visible:ring-ring [&>svg]:size-3 [&>svg]:shrink-0"
|
|
308
|
+
>
|
|
253
309
|
<SelectValue />
|
|
254
310
|
</SelectTrigger>
|
|
255
311
|
<SelectContent className="text-[11px]">
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { useT } from "@agent-native/core/client";
|
|
2
|
+
import {
|
|
3
|
+
IconClipboard,
|
|
4
|
+
IconChevronDown,
|
|
5
|
+
IconSparkles,
|
|
6
|
+
} from "@tabler/icons-react";
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
|
|
9
|
+
import { Button } from "@/components/ui/button";
|
|
10
|
+
import {
|
|
11
|
+
Collapsible,
|
|
12
|
+
CollapsibleContent,
|
|
13
|
+
CollapsibleTrigger,
|
|
14
|
+
} from "@/components/ui/collapsible";
|
|
15
|
+
import { Textarea } from "@/components/ui/textarea";
|
|
16
|
+
import { useAgentEditRequest } from "@/hooks/useAgentEditRequest";
|
|
17
|
+
import { cn } from "@/lib/utils";
|
|
18
|
+
|
|
19
|
+
export interface InspectorAiActionsProps {
|
|
20
|
+
/** CSS selector for the currently-selected element, if any. */
|
|
21
|
+
selector?: string;
|
|
22
|
+
/** Source id (data-code-layer-id) of the selected element, if any. */
|
|
23
|
+
sourceId?: string;
|
|
24
|
+
/** Active file id. */
|
|
25
|
+
fileId?: string;
|
|
26
|
+
/** Active file name (e.g. "index.html"). */
|
|
27
|
+
filename?: string;
|
|
28
|
+
/** The design id. */
|
|
29
|
+
designId?: string;
|
|
30
|
+
/** When false, the controls are disabled. */
|
|
31
|
+
canEdit: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Compact inspector block that lets the user type a freeform AI edit request
|
|
36
|
+
* and either route it to the agent chat sidebar ("Apply with AI") or copy the
|
|
37
|
+
* prompt to the clipboard ("Copy prompt").
|
|
38
|
+
*
|
|
39
|
+
* Collapsed by default to keep the inspector clean.
|
|
40
|
+
*/
|
|
41
|
+
export function InspectorAiActions({
|
|
42
|
+
selector,
|
|
43
|
+
sourceId,
|
|
44
|
+
fileId,
|
|
45
|
+
filename,
|
|
46
|
+
designId,
|
|
47
|
+
canEdit,
|
|
48
|
+
}: InspectorAiActionsProps) {
|
|
49
|
+
const t = useT();
|
|
50
|
+
const { sendEdit, copyPrompt } = useAgentEditRequest();
|
|
51
|
+
const [open, setOpen] = useState(false);
|
|
52
|
+
const [request, setRequest] = useState("");
|
|
53
|
+
|
|
54
|
+
const args = {
|
|
55
|
+
message: request,
|
|
56
|
+
selector,
|
|
57
|
+
sourceId,
|
|
58
|
+
fileId,
|
|
59
|
+
filename,
|
|
60
|
+
designId,
|
|
61
|
+
};
|
|
62
|
+
const disabled = !canEdit || !request.trim();
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<Collapsible open={open} onOpenChange={setOpen} className="w-full">
|
|
66
|
+
<CollapsibleTrigger asChild>
|
|
67
|
+
<button
|
|
68
|
+
type="button"
|
|
69
|
+
className={cn(
|
|
70
|
+
"flex w-full items-center justify-between gap-1 rounded px-2 py-1.5 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-foreground transition-colors",
|
|
71
|
+
)}
|
|
72
|
+
>
|
|
73
|
+
<span className="flex items-center gap-1.5">
|
|
74
|
+
<IconSparkles className="size-3.5 shrink-0" />
|
|
75
|
+
{t("designEditor.localSourceEdit.askAi")}
|
|
76
|
+
</span>
|
|
77
|
+
<IconChevronDown
|
|
78
|
+
className={cn(
|
|
79
|
+
"size-3.5 shrink-0 transition-transform duration-150",
|
|
80
|
+
open && "rotate-180",
|
|
81
|
+
)}
|
|
82
|
+
/>
|
|
83
|
+
</button>
|
|
84
|
+
</CollapsibleTrigger>
|
|
85
|
+
<CollapsibleContent className="overflow-hidden data-[state=closed]:animate-none">
|
|
86
|
+
<div className="flex flex-col gap-2 px-1 pb-2 pt-1">
|
|
87
|
+
<Textarea
|
|
88
|
+
value={request}
|
|
89
|
+
onChange={(e) => setRequest(e.target.value)}
|
|
90
|
+
placeholder={
|
|
91
|
+
selector
|
|
92
|
+
? t("designEditor.localSourceEdit.describeElementChange")
|
|
93
|
+
: t("designEditor.localSourceEdit.describeChange")
|
|
94
|
+
}
|
|
95
|
+
className="min-h-[64px] resize-none text-xs"
|
|
96
|
+
disabled={!canEdit}
|
|
97
|
+
onKeyDown={(e) => {
|
|
98
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey) && !disabled) {
|
|
99
|
+
e.preventDefault();
|
|
100
|
+
void sendEdit(args);
|
|
101
|
+
setRequest("");
|
|
102
|
+
setOpen(false);
|
|
103
|
+
}
|
|
104
|
+
}}
|
|
105
|
+
/>
|
|
106
|
+
<div className="flex gap-1.5">
|
|
107
|
+
<Button
|
|
108
|
+
size="sm"
|
|
109
|
+
variant="default"
|
|
110
|
+
className="flex-1 gap-1.5 text-xs"
|
|
111
|
+
disabled={disabled}
|
|
112
|
+
onClick={() => {
|
|
113
|
+
void sendEdit(args);
|
|
114
|
+
setRequest("");
|
|
115
|
+
setOpen(false);
|
|
116
|
+
}}
|
|
117
|
+
>
|
|
118
|
+
<IconSparkles className="size-3.5 shrink-0" />
|
|
119
|
+
{t("designEditor.localSourceEdit.applyWithAi")}
|
|
120
|
+
</Button>
|
|
121
|
+
<Button
|
|
122
|
+
size="sm"
|
|
123
|
+
variant="outline"
|
|
124
|
+
className="gap-1.5 text-xs"
|
|
125
|
+
disabled={disabled}
|
|
126
|
+
onClick={() => {
|
|
127
|
+
void copyPrompt(args);
|
|
128
|
+
}}
|
|
129
|
+
title={t("designEditor.localSourceEdit.copyPromptTooltip")}
|
|
130
|
+
>
|
|
131
|
+
<IconClipboard className="size-3.5 shrink-0" />
|
|
132
|
+
{t("designEditor.localSourceEdit.copyPrompt")}
|
|
133
|
+
</Button>
|
|
134
|
+
</div>
|
|
135
|
+
{selector && (
|
|
136
|
+
<p className="text-[10px] leading-tight text-muted-foreground truncate">
|
|
137
|
+
{t("designEditor.localSourceEdit.targeting")}{" "}
|
|
138
|
+
<code className="font-mono">{selector}</code>
|
|
139
|
+
</p>
|
|
140
|
+
)}
|
|
141
|
+
</div>
|
|
142
|
+
</CollapsibleContent>
|
|
143
|
+
</Collapsible>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
@@ -6,6 +6,30 @@ right spot plus copy-pasteable code to insert or replace.
|
|
|
6
6
|
|
|
7
7
|
Do NOT rely on line numbers — they drift. Use the search strings instead.
|
|
8
8
|
|
|
9
|
+
## Status: shader fills are user-reachable and applyable
|
|
10
|
+
|
|
11
|
+
The **Shader Fills** card in `DesignExtensionsPanel.tsx` (inspector slot
|
|
12
|
+
`design.editor.inspector`) is the live entry point: open it, **Browse Shaders**,
|
|
13
|
+
pick a preset, tune it with `ShaderControls`, and the iframe previews the fill as
|
|
14
|
+
a CSS gradient (`preview-shader-fill`). With an element selected on the canvas, the
|
|
15
|
+
card's **Apply fill** button persists that fill via the `apply-shader-fill` action.
|
|
16
|
+
|
|
17
|
+
`apply-shader-fill` is **no longer gated** — it is SAFETY-gated, not Builder-gated:
|
|
18
|
+
|
|
19
|
+
- It asserts **editor** access on the target design (`accessFilter` read +
|
|
20
|
+
`assertAccess("design", id, "editor")`) before any write.
|
|
21
|
+
- It only persists **HTML design-file** sources. localhost / fusion / inline-html
|
|
22
|
+
sources return the preview value and write nothing.
|
|
23
|
+
- It writes a single inline-style `background` onto the target node through the
|
|
24
|
+
deterministic HTML editor (`applyVisualEdit`, the same persist path as
|
|
25
|
+
`apply-visual-edit`), reusing the strict CSS-colour allowlist from
|
|
26
|
+
`shared/shader-fill.ts` so `descriptor.colors` can never inject CSS.
|
|
27
|
+
|
|
28
|
+
Sections (a), (b), (d), and (f) below remain optional ways to surface shaders in
|
|
29
|
+
_other_ inspector seams (the colour picker fill type, the effects panel, the
|
|
30
|
+
artboard WebGL bridge, design-system tokens) and are not required for the
|
|
31
|
+
card-based apply path that ships today.
|
|
32
|
+
|
|
9
33
|
---
|
|
10
34
|
|
|
11
35
|
## (a) DesignColorPicker.tsx — Add `"shader"` fill type
|
|
@@ -351,20 +375,17 @@ if (fill.type === "shader") {
|
|
|
351
375
|
|
|
352
376
|
---
|
|
353
377
|
|
|
354
|
-
## (e) Changelog entry
|
|
355
|
-
|
|
356
|
-
The shader feature is not yet user-reachable — it still needs all seam files wired.
|
|
357
|
-
Do NOT add a changelog entry yet.
|
|
378
|
+
## (e) Changelog entry
|
|
358
379
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
panel), run:
|
|
380
|
+
The shader-fills card is now user-reachable and the apply path persists, so a
|
|
381
|
+
user-facing changelog entry is warranted. From the `templates/design/` directory:
|
|
362
382
|
|
|
363
383
|
```bash
|
|
364
|
-
agent-native changelog add "Add GPU shader fills
|
|
384
|
+
agent-native changelog add "Add GPU shader fills — 8 presets (MeshGradient, GrainGradient, Voronoi, Metaballs, Warp, GodRays, Dithering, PaperTexture) with live preview and one-click apply to the selected element" --type added
|
|
365
385
|
```
|
|
366
386
|
|
|
367
|
-
from the
|
|
387
|
+
(The effects-panel surface from section (b) is still optional; scope the changelog
|
|
388
|
+
line to what actually ships.)
|
|
368
389
|
|
|
369
390
|
---
|
|
370
391
|
|
|
@@ -407,14 +428,23 @@ shader token picker.
|
|
|
407
428
|
|
|
408
429
|
## Integration Checklist
|
|
409
430
|
|
|
431
|
+
Shipped (card-based preview + apply path):
|
|
432
|
+
|
|
433
|
+
- [x] `DesignExtensionsPanel.tsx` — Shader Fills card opens `ShaderFillsPanel`
|
|
434
|
+
- [x] `DesignExtensionsPanel.tsx` — "Apply fill" persists via `apply-shader-fill`
|
|
435
|
+
- [x] `actions/apply-shader-fill.ts` — persists fill as CSS background (editor-gated)
|
|
436
|
+
- [x] `actions/preview-shader-fill.ts` — preview-only CSS (unchanged)
|
|
437
|
+
- [x] `actions/apply-shader.ts` exists (planning/codegen snippet)
|
|
438
|
+
- [x] `actions/get-shader.ts` exists
|
|
439
|
+
|
|
440
|
+
Optional follow-ups (other inspector seams):
|
|
441
|
+
|
|
410
442
|
- [ ] `DesignColorPicker.tsx` — `DesignFillType` includes `"shader"`
|
|
411
443
|
- [ ] `DesignColorPicker.tsx` — `DesignPaintType` includes `"shader"`
|
|
412
444
|
- [ ] `DesignColorPicker.tsx` — shader button renders in paint-type row
|
|
413
445
|
- [ ] `DesignColorPicker.tsx` — `ShaderControls` renders when `paintType === "shader"`
|
|
414
446
|
- [ ] `EditPanel.tsx` — `ShaderEffectRow` renders in `EffectsProperties`
|
|
415
447
|
- [ ] `EditPanel.tsx` — "Add Shader" option in effects dropdown
|
|
416
|
-
- [ ] `actions/apply-shader.ts` exists
|
|
417
|
-
- [ ] `actions/get-shader.ts` exists
|
|
418
448
|
- [ ] `DesignCanvas.tsx` — shader bridge script injected into artboard
|
|
419
449
|
- [ ] `DesignCanvas.tsx` — `data-shader` attribute serialized for shader fills
|
|
420
|
-
- [ ] Changelog entry added (
|
|
450
|
+
- [ ] Changelog entry added (see section (e))
|