@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
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* index-components — read action.
|
|
3
|
+
*
|
|
4
|
+
* Scans the design's HTML for `data-agent-native-component` annotations and
|
|
5
|
+
* returns the component list plus detected instances.
|
|
6
|
+
*
|
|
7
|
+
* **Inline / Alpine tier:** parses the design HTML directly using the
|
|
8
|
+
* code-layer projection. Writes discovered component definitions into the
|
|
9
|
+
* `component_index` table so subsequent reads (get-component-details) can
|
|
10
|
+
* resolve persisted metadata.
|
|
11
|
+
*
|
|
12
|
+
* **Real-app tier (localhost / fusion):** `indexComponents` capability is
|
|
13
|
+
* required. When the source does not yet advertise it, the action returns an
|
|
14
|
+
* empty list with a `ctaRequired: true` flag and a human-readable `ctaMessage`
|
|
15
|
+
* prompting the user to Connect Builder (see DESIGN-STUDIO-PLAN.md §6.1).
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { defineAction } from "@agent-native/core";
|
|
19
|
+
import { getText, hasCollabState } from "@agent-native/core/collab";
|
|
20
|
+
import { getRequestUserEmail } from "@agent-native/core/server/request-context";
|
|
21
|
+
import { accessFilter, assertAccess } from "@agent-native/core/sharing";
|
|
22
|
+
import { and, eq } from "drizzle-orm";
|
|
23
|
+
import { z } from "zod";
|
|
24
|
+
|
|
25
|
+
import { getDb, schema } from "../server/db/index.js";
|
|
26
|
+
import "../server/db/index.js"; // ensure registerShareableResource runs
|
|
27
|
+
import { resolveSourceCapabilities } from "../shared/capability-resolver.js";
|
|
28
|
+
import { buildCodeLayerProjection } from "../shared/code-layer.js";
|
|
29
|
+
import type { CodeLayerSource } from "../shared/code-layer.js";
|
|
30
|
+
import {
|
|
31
|
+
detectInstances,
|
|
32
|
+
buildDefinitions,
|
|
33
|
+
type ComponentDefinition,
|
|
34
|
+
type ComponentInstance,
|
|
35
|
+
} from "../shared/component-model.js";
|
|
36
|
+
import { hasCapability } from "../shared/design-source-capabilities.js";
|
|
37
|
+
import { normalizeDesignSourceType } from "../shared/source-mode.js";
|
|
38
|
+
|
|
39
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
40
|
+
|
|
41
|
+
async function liveContent(
|
|
42
|
+
fileId: string,
|
|
43
|
+
storedContent: string,
|
|
44
|
+
): Promise<string> {
|
|
45
|
+
try {
|
|
46
|
+
if (await hasCollabState(fileId)) {
|
|
47
|
+
const live = await getText(fileId, "content");
|
|
48
|
+
if (typeof live === "string") return live;
|
|
49
|
+
}
|
|
50
|
+
} catch {
|
|
51
|
+
// Collab reads are best-effort; SQL content is the fallback.
|
|
52
|
+
}
|
|
53
|
+
return storedContent;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function componentIndexId(designId: string, name: string): string {
|
|
57
|
+
// Stable deterministic id — same component name on the same design always
|
|
58
|
+
// maps to the same row so upsert is safe.
|
|
59
|
+
return `ci_${designId}_${name.toLowerCase().replace(/[^a-z0-9]/g, "_")}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ─── Action ───────────────────────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
export default defineAction({
|
|
65
|
+
description:
|
|
66
|
+
"Scan the design's HTML for component annotations " +
|
|
67
|
+
"(`data-agent-native-component`) and return the component list plus " +
|
|
68
|
+
"detected instances. For inline/Alpine designs, parses the HTML directly " +
|
|
69
|
+
"and persists the discovered components into component_index. For real-app " +
|
|
70
|
+
"sources (localhost / fusion), the indexComponents capability must be " +
|
|
71
|
+
"available; if not, returns an empty list with ctaRequired=true and a " +
|
|
72
|
+
"message prompting the user to Connect Builder.",
|
|
73
|
+
schema: z.object({
|
|
74
|
+
designId: z.string().describe("Design project ID to index components for"),
|
|
75
|
+
fileId: z
|
|
76
|
+
.string()
|
|
77
|
+
.optional()
|
|
78
|
+
.describe(
|
|
79
|
+
"Specific design file id. Defaults to the primary index.html when omitted.",
|
|
80
|
+
),
|
|
81
|
+
}),
|
|
82
|
+
readOnly: false,
|
|
83
|
+
http: { method: "POST" },
|
|
84
|
+
run: async ({ designId, fileId }) => {
|
|
85
|
+
const db = getDb();
|
|
86
|
+
|
|
87
|
+
// ── Access check ────────────────────────────────────────────────────────
|
|
88
|
+
// This action writes component_index rows — require editor access.
|
|
89
|
+
const access = await assertAccess("design", designId, "editor");
|
|
90
|
+
|
|
91
|
+
// ── Source type + capability check ──────────────────────────────────────
|
|
92
|
+
let rawSourceType: unknown = "inline";
|
|
93
|
+
const rawData = (access.resource as { data?: unknown }).data;
|
|
94
|
+
if (typeof rawData === "string") {
|
|
95
|
+
try {
|
|
96
|
+
const parsed: unknown = JSON.parse(rawData);
|
|
97
|
+
if (
|
|
98
|
+
parsed !== null &&
|
|
99
|
+
typeof parsed === "object" &&
|
|
100
|
+
"sourceType" in (parsed as object)
|
|
101
|
+
) {
|
|
102
|
+
rawSourceType = (parsed as { sourceType: unknown }).sourceType;
|
|
103
|
+
}
|
|
104
|
+
} catch {
|
|
105
|
+
// Stale JSON — default to inline.
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const sourceType = normalizeDesignSourceType(rawSourceType) ?? "inline";
|
|
110
|
+
const caps = resolveSourceCapabilities(sourceType);
|
|
111
|
+
|
|
112
|
+
// Real-app sources gate on `indexComponents`. For inline designs this
|
|
113
|
+
// capability is `unavailable` by default (the plan marks it as a real-app
|
|
114
|
+
// feature for deep TS/cva parse) but the *annotation scan* still works
|
|
115
|
+
// from the DOM — we always run it. The flag tells callers whether the
|
|
116
|
+
// full real-app index is live or whether they see only annotations.
|
|
117
|
+
const hasFullIndex = hasCapability(caps, "indexComponents");
|
|
118
|
+
const ctaRequired =
|
|
119
|
+
sourceType !== "inline" && !hasCapability(caps, "indexComponents");
|
|
120
|
+
|
|
121
|
+
if (ctaRequired) {
|
|
122
|
+
return {
|
|
123
|
+
designId,
|
|
124
|
+
sourceType,
|
|
125
|
+
ctaRequired: true,
|
|
126
|
+
ctaMessage:
|
|
127
|
+
"Full component indexing (prop types, cva variants, Storybook " +
|
|
128
|
+
"stories, jump-to-source) requires a connected Builder app. " +
|
|
129
|
+
"Connect Builder via the Make it real CTA to unlock this feature.",
|
|
130
|
+
components: [] as ComponentDefinition[],
|
|
131
|
+
instances: [] as ComponentInstance[],
|
|
132
|
+
totalComponents: 0,
|
|
133
|
+
totalInstances: 0,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ── Fetch the design file ────────────────────────────────────────────────
|
|
138
|
+
const conditions = [
|
|
139
|
+
accessFilter(schema.designs, schema.designShares),
|
|
140
|
+
eq(schema.designFiles.designId, designId),
|
|
141
|
+
fileId
|
|
142
|
+
? eq(schema.designFiles.id, fileId)
|
|
143
|
+
: eq(schema.designFiles.filename, "index.html"),
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
const [file] = await db
|
|
147
|
+
.select({
|
|
148
|
+
id: schema.designFiles.id,
|
|
149
|
+
designId: schema.designFiles.designId,
|
|
150
|
+
filename: schema.designFiles.filename,
|
|
151
|
+
content: schema.designFiles.content,
|
|
152
|
+
})
|
|
153
|
+
.from(schema.designFiles)
|
|
154
|
+
.innerJoin(
|
|
155
|
+
schema.designs,
|
|
156
|
+
eq(schema.designFiles.designId, schema.designs.id),
|
|
157
|
+
)
|
|
158
|
+
.where(and(...conditions))
|
|
159
|
+
.limit(1);
|
|
160
|
+
|
|
161
|
+
if (!file) throw new Error("Design HTML file not found.");
|
|
162
|
+
|
|
163
|
+
const html = await liveContent(file.id, file.content ?? "");
|
|
164
|
+
|
|
165
|
+
// ── Projection + detection ───────────────────────────────────────────────
|
|
166
|
+
const codeLayerSource: CodeLayerSource = {
|
|
167
|
+
kind: "design-file",
|
|
168
|
+
designId: file.designId,
|
|
169
|
+
fileId: file.id,
|
|
170
|
+
filename: file.filename,
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const projection = buildCodeLayerProjection(html, {
|
|
174
|
+
source: codeLayerSource,
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const instances = detectInstances(projection.nodes);
|
|
178
|
+
const definitions = buildDefinitions(instances);
|
|
179
|
+
|
|
180
|
+
// ── Persist discovered components ────────────────────────────────────────
|
|
181
|
+
// Write each distinct component name into component_index so that
|
|
182
|
+
// get-component-details can resolve metadata by node id.
|
|
183
|
+
const now = new Date().toISOString();
|
|
184
|
+
// Derive the owner from the request user, falling back to the design's
|
|
185
|
+
// owner. Never stamp an empty-string owner (an unowned row): require a real
|
|
186
|
+
// owner before writing a new component_index row.
|
|
187
|
+
const designOwner = (access.resource as { ownerEmail?: unknown })
|
|
188
|
+
.ownerEmail;
|
|
189
|
+
const ownerEmail =
|
|
190
|
+
getRequestUserEmail() ??
|
|
191
|
+
(typeof designOwner === "string" && designOwner ? designOwner : null);
|
|
192
|
+
if (!ownerEmail) throw new Error("no authenticated user");
|
|
193
|
+
|
|
194
|
+
for (const def of definitions) {
|
|
195
|
+
const id = componentIndexId(designId, def.name);
|
|
196
|
+
const existing = await db
|
|
197
|
+
.select({ id: schema.componentIndex.id })
|
|
198
|
+
.from(schema.componentIndex)
|
|
199
|
+
.where(eq(schema.componentIndex.id, id))
|
|
200
|
+
.limit(1);
|
|
201
|
+
|
|
202
|
+
if (existing.length === 0) {
|
|
203
|
+
await db.insert(schema.componentIndex).values({
|
|
204
|
+
id,
|
|
205
|
+
designId,
|
|
206
|
+
name: def.name,
|
|
207
|
+
runtimeSelectors: JSON.stringify(
|
|
208
|
+
def.instanceNodeIds.map(
|
|
209
|
+
(nodeId) => `[data-agent-native-node-id="${nodeId}"]`,
|
|
210
|
+
),
|
|
211
|
+
),
|
|
212
|
+
ownerEmail,
|
|
213
|
+
createdAt: now,
|
|
214
|
+
updatedAt: now,
|
|
215
|
+
});
|
|
216
|
+
} else {
|
|
217
|
+
await db
|
|
218
|
+
.update(schema.componentIndex)
|
|
219
|
+
.set({
|
|
220
|
+
runtimeSelectors: JSON.stringify(
|
|
221
|
+
def.instanceNodeIds.map(
|
|
222
|
+
(nodeId) => `[data-agent-native-node-id="${nodeId}"]`,
|
|
223
|
+
),
|
|
224
|
+
),
|
|
225
|
+
updatedAt: now,
|
|
226
|
+
})
|
|
227
|
+
.where(eq(schema.componentIndex.id, id));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Annotate instances with their component_index id.
|
|
232
|
+
const indexMap = new Map(
|
|
233
|
+
definitions.map((def) => [
|
|
234
|
+
def.name,
|
|
235
|
+
componentIndexId(designId, def.name),
|
|
236
|
+
]),
|
|
237
|
+
);
|
|
238
|
+
const annotatedInstances = instances.map((inst) => ({
|
|
239
|
+
...inst,
|
|
240
|
+
componentIndexId: indexMap.get(inst.name),
|
|
241
|
+
}));
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
designId,
|
|
245
|
+
sourceType,
|
|
246
|
+
ctaRequired: false,
|
|
247
|
+
hasFullIndex,
|
|
248
|
+
components: definitions,
|
|
249
|
+
instances: annotatedInstances,
|
|
250
|
+
totalComponents: definitions.length,
|
|
251
|
+
totalInstances: instances.length,
|
|
252
|
+
note:
|
|
253
|
+
sourceType === "inline"
|
|
254
|
+
? "Showing annotated Alpine components from data-agent-native-component attributes. Connect Builder for full TS prop types and cva variants."
|
|
255
|
+
: undefined,
|
|
256
|
+
};
|
|
257
|
+
},
|
|
258
|
+
});
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core";
|
|
2
|
+
import { extractCssVars } from "@agent-native/core/server/design-token-utils";
|
|
3
|
+
import { resolveAccess } from "@agent-native/core/sharing";
|
|
4
|
+
import { eq } from "drizzle-orm";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
|
|
7
|
+
import { getDb, schema } from "../server/db/index.js";
|
|
8
|
+
import "../server/db/index.js"; // ensure registerShareableResource runs
|
|
9
|
+
import type { DesignSystemData } from "../shared/api.js";
|
|
10
|
+
import { resolveTweaksToCssVars } from "../shared/resolve-tweaks.js";
|
|
11
|
+
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Token type classification
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
function classifyVar(
|
|
17
|
+
name: string,
|
|
18
|
+
value: string,
|
|
19
|
+
): "color" | "typography" | "spacing" | "radius" | "shadow" | "other" {
|
|
20
|
+
const n = name.toLowerCase();
|
|
21
|
+
if (
|
|
22
|
+
/color|bg|background|text|border|accent|primary|secondary|surface|muted|foreground|fill|stroke/i.test(
|
|
23
|
+
n,
|
|
24
|
+
) ||
|
|
25
|
+
/^(#[0-9a-fA-F]{3,8}|rgba?\(|hsla?\(|oklch\(|color\()/.test(value.trim())
|
|
26
|
+
) {
|
|
27
|
+
return "color";
|
|
28
|
+
}
|
|
29
|
+
if (/font|size|leading|tracking|weight|heading|body|type/i.test(n)) {
|
|
30
|
+
return "typography";
|
|
31
|
+
}
|
|
32
|
+
if (/radius|rounded/i.test(n)) {
|
|
33
|
+
return "radius";
|
|
34
|
+
}
|
|
35
|
+
if (/spacing|gap|padding|margin|space/i.test(n)) {
|
|
36
|
+
return "spacing";
|
|
37
|
+
}
|
|
38
|
+
if (/shadow|blur|drop/i.test(n)) {
|
|
39
|
+
return "shadow";
|
|
40
|
+
}
|
|
41
|
+
return "other";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Derive a friendly display name from a CSS var name like `--primary-color`. */
|
|
45
|
+
function friendlyName(cssVar: string): string {
|
|
46
|
+
return cssVar
|
|
47
|
+
.replace(/^--/, "")
|
|
48
|
+
.replace(/[-_]/g, " ")
|
|
49
|
+
.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Token entry shape
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
export interface DesignToken {
|
|
57
|
+
/** Human-readable display name, e.g. "Primary Color". */
|
|
58
|
+
name: string;
|
|
59
|
+
/** CSS custom property, e.g. "--primary-color". */
|
|
60
|
+
cssVar: string;
|
|
61
|
+
/** Resolved string value, e.g. "#3B82F6" or "0.5rem". */
|
|
62
|
+
value: string;
|
|
63
|
+
/** Semantic token category. */
|
|
64
|
+
type: "color" | "typography" | "spacing" | "radius" | "shadow" | "other";
|
|
65
|
+
/** Opaque source chip label, e.g. "globals.css" or "Brand Kit". */
|
|
66
|
+
source: string;
|
|
67
|
+
/**
|
|
68
|
+
* True when the value comes from the design's own tweak selections (i.e.
|
|
69
|
+
* the user has already customised this token in the editor).
|
|
70
|
+
*/
|
|
71
|
+
isTweakOverride?: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Action
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
|
|
78
|
+
export default defineAction({
|
|
79
|
+
description:
|
|
80
|
+
"Index the design tokens for a design as a friendly { name, cssVar, " +
|
|
81
|
+
"value, type, source } list. Parses CSS custom properties from the " +
|
|
82
|
+
"design's HTML :root block, the linked Brand Kit / design system, and " +
|
|
83
|
+
"the user's applied tweak selections. Returns tokens grouped by type " +
|
|
84
|
+
"(color, typography, spacing, radius, shadow, other).",
|
|
85
|
+
schema: z.object({
|
|
86
|
+
designId: z.string().describe("Design project ID"),
|
|
87
|
+
}),
|
|
88
|
+
readOnly: true,
|
|
89
|
+
http: { method: "GET" },
|
|
90
|
+
run: async ({ designId }) => {
|
|
91
|
+
const access = await resolveAccess("design", designId);
|
|
92
|
+
if (!access) {
|
|
93
|
+
throw new Error("Design not found");
|
|
94
|
+
}
|
|
95
|
+
const design = access.resource;
|
|
96
|
+
const db = getDb();
|
|
97
|
+
|
|
98
|
+
// ------------------------------------------------------------------
|
|
99
|
+
// 1. Parse tokens from the design's own HTML files (:root vars)
|
|
100
|
+
// ------------------------------------------------------------------
|
|
101
|
+
const files = await db
|
|
102
|
+
.select({
|
|
103
|
+
filename: schema.designFiles.filename,
|
|
104
|
+
content: schema.designFiles.content,
|
|
105
|
+
})
|
|
106
|
+
.from(schema.designFiles)
|
|
107
|
+
.where(eq(schema.designFiles.designId, designId));
|
|
108
|
+
|
|
109
|
+
/** cssVar -> { value, source } */
|
|
110
|
+
const rawTokens: Map<string, { value: string; source: string }> = new Map();
|
|
111
|
+
|
|
112
|
+
for (const file of files) {
|
|
113
|
+
const state = {
|
|
114
|
+
colors: {} as Record<string, string>,
|
|
115
|
+
cssCustomProperties: {} as Record<string, string>,
|
|
116
|
+
fonts: [],
|
|
117
|
+
spacing: {} as Record<string, string>,
|
|
118
|
+
borderRadius: {} as Record<string, string>,
|
|
119
|
+
stylingFramework: null,
|
|
120
|
+
rawExtracts: [],
|
|
121
|
+
seenFonts: new Set<string>(),
|
|
122
|
+
};
|
|
123
|
+
extractCssVars(state, file.content);
|
|
124
|
+
for (const [k, v] of Object.entries(state.cssCustomProperties)) {
|
|
125
|
+
rawTokens.set(k, { value: v, source: file.filename });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ------------------------------------------------------------------
|
|
130
|
+
// 2. Overlay tokens from the linked Brand Kit / design system
|
|
131
|
+
// ------------------------------------------------------------------
|
|
132
|
+
if (design.designSystemId) {
|
|
133
|
+
// Design systems are their own access boundary (same pattern as
|
|
134
|
+
// get-design-system.ts). A user who can read the design but has no
|
|
135
|
+
// access to the linked design system must NOT receive its tokens.
|
|
136
|
+
const dsAccess = await resolveAccess(
|
|
137
|
+
"design-system",
|
|
138
|
+
design.designSystemId,
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
const [dsRow] = dsAccess
|
|
142
|
+
? await db
|
|
143
|
+
.select({ data: schema.designSystems.data })
|
|
144
|
+
.from(schema.designSystems)
|
|
145
|
+
.where(eq(schema.designSystems.id, design.designSystemId))
|
|
146
|
+
.limit(1)
|
|
147
|
+
: [];
|
|
148
|
+
|
|
149
|
+
if (dsRow?.data) {
|
|
150
|
+
try {
|
|
151
|
+
const dsData = JSON.parse(dsRow.data) as Partial<DesignSystemData>;
|
|
152
|
+
// Flatten the Brand Kit's known token fields into CSS vars
|
|
153
|
+
const brandColors = dsData.colors ?? {};
|
|
154
|
+
const colorRoleMap: Record<string, string> = {
|
|
155
|
+
primary: "--color-primary",
|
|
156
|
+
secondary: "--color-secondary",
|
|
157
|
+
accent: "--color-accent",
|
|
158
|
+
background: "--color-background",
|
|
159
|
+
surface: "--color-surface",
|
|
160
|
+
text: "--color-text",
|
|
161
|
+
textMuted: "--color-text-muted",
|
|
162
|
+
};
|
|
163
|
+
for (const [role, cssVar] of Object.entries(colorRoleMap)) {
|
|
164
|
+
const v = (brandColors as Record<string, string>)[role];
|
|
165
|
+
if (v) rawTokens.set(cssVar, { value: v, source: "Brand Kit" });
|
|
166
|
+
}
|
|
167
|
+
// Border radius
|
|
168
|
+
if (dsData.borders?.radius) {
|
|
169
|
+
rawTokens.set("--radius", {
|
|
170
|
+
value: dsData.borders.radius,
|
|
171
|
+
source: "Brand Kit",
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
// Spacing
|
|
175
|
+
if (dsData.spacing?.elementGap) {
|
|
176
|
+
rawTokens.set("--spacing-element-gap", {
|
|
177
|
+
value: dsData.spacing.elementGap,
|
|
178
|
+
source: "Brand Kit",
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
if (dsData.spacing?.pagePadding) {
|
|
182
|
+
rawTokens.set("--spacing-page-padding", {
|
|
183
|
+
value: dsData.spacing.pagePadding,
|
|
184
|
+
source: "Brand Kit",
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
} catch {
|
|
188
|
+
// Malformed JSON — skip Brand Kit overlay silently.
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// ------------------------------------------------------------------
|
|
194
|
+
// 3. Overlay tweak-resolved values (user customisations win)
|
|
195
|
+
// ------------------------------------------------------------------
|
|
196
|
+
let designData: Record<string, unknown> = {};
|
|
197
|
+
try {
|
|
198
|
+
designData = design.data
|
|
199
|
+
? (JSON.parse(design.data) as Record<string, unknown>)
|
|
200
|
+
: {};
|
|
201
|
+
} catch {
|
|
202
|
+
// ignore
|
|
203
|
+
}
|
|
204
|
+
const tweaks = Array.isArray(designData.tweaks)
|
|
205
|
+
? (designData.tweaks as Array<{
|
|
206
|
+
id: string;
|
|
207
|
+
cssVar?: string;
|
|
208
|
+
defaultValue: unknown;
|
|
209
|
+
}>)
|
|
210
|
+
: [];
|
|
211
|
+
const tweakSelections =
|
|
212
|
+
designData.tweakSelections &&
|
|
213
|
+
typeof designData.tweakSelections === "object" &&
|
|
214
|
+
!Array.isArray(designData.tweakSelections)
|
|
215
|
+
? (designData.tweakSelections as Record<
|
|
216
|
+
string,
|
|
217
|
+
string | number | boolean
|
|
218
|
+
>)
|
|
219
|
+
: {};
|
|
220
|
+
|
|
221
|
+
// Cast tweaks array to the shape resolveTweaksToCssVars expects
|
|
222
|
+
type TweakDef = Parameters<typeof resolveTweaksToCssVars>[0][number];
|
|
223
|
+
const resolvedOverrides = resolveTweaksToCssVars(
|
|
224
|
+
tweaks as TweakDef[],
|
|
225
|
+
tweakSelections,
|
|
226
|
+
);
|
|
227
|
+
const tweakCssVars = new Set(
|
|
228
|
+
tweaks.map((t) => t.cssVar).filter(Boolean) as string[],
|
|
229
|
+
);
|
|
230
|
+
for (const [cssVar, value] of Object.entries(resolvedOverrides)) {
|
|
231
|
+
rawTokens.set(cssVar, { value, source: "Tweaks" });
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// ------------------------------------------------------------------
|
|
235
|
+
// 4. Build friendly token list
|
|
236
|
+
// ------------------------------------------------------------------
|
|
237
|
+
const tokens: DesignToken[] = [];
|
|
238
|
+
for (const [cssVar, { value, source }] of rawTokens) {
|
|
239
|
+
tokens.push({
|
|
240
|
+
name: friendlyName(cssVar),
|
|
241
|
+
cssVar,
|
|
242
|
+
value,
|
|
243
|
+
type: classifyVar(cssVar, value),
|
|
244
|
+
source,
|
|
245
|
+
isTweakOverride: tweakCssVars.has(cssVar),
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Group by type for the panel
|
|
250
|
+
type TokenGroup = { type: DesignToken["type"]; tokens: DesignToken[] };
|
|
251
|
+
const ORDER: DesignToken["type"][] = [
|
|
252
|
+
"color",
|
|
253
|
+
"typography",
|
|
254
|
+
"spacing",
|
|
255
|
+
"radius",
|
|
256
|
+
"shadow",
|
|
257
|
+
"other",
|
|
258
|
+
];
|
|
259
|
+
const byType = new Map<DesignToken["type"], DesignToken[]>(
|
|
260
|
+
ORDER.map((t) => [t, []]),
|
|
261
|
+
);
|
|
262
|
+
for (const tok of tokens) {
|
|
263
|
+
byType.get(tok.type)!.push(tok);
|
|
264
|
+
}
|
|
265
|
+
const groups: TokenGroup[] = [];
|
|
266
|
+
for (const type of ORDER) {
|
|
267
|
+
const toks = byType.get(type)!;
|
|
268
|
+
if (toks.length > 0) groups.push({ type, tokens: toks });
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return { designId, tokenCount: tokens.length, groups, tokens };
|
|
272
|
+
},
|
|
273
|
+
});
|