@agent-native/core 0.80.4 → 0.80.5
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 +21 -2
- package/corpus/core/docs/content/locales/ar-SA/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/real-time-collaboration.mdx +3 -3
- package/corpus/core/docs/content/locales/de-DE/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/es-ES/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +1 -1
- package/corpus/core/docs/content/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/template-design.mdx +1 -1
- package/corpus/core/package.json +3 -7
- package/corpus/core/src/action.ts +21 -0
- package/corpus/core/src/agent/durable-background.ts +32 -11
- package/corpus/core/src/agent/production-agent.ts +11 -1
- package/corpus/core/src/agent/run-loop-with-resume.ts +3 -1
- package/corpus/core/src/brand-kit/fig/index.ts +17 -37
- package/corpus/core/src/cli/index.ts +1 -1
- package/corpus/core/src/cli/mcp-config-writers.ts +187 -51
- package/corpus/core/src/cli/skills.ts +18 -3
- package/corpus/core/src/client/AssistantChat.tsx +11 -1
- package/corpus/core/src/client/agent-chat.ts +12 -1
- package/corpus/core/src/client/composer/PromptComposer.tsx +100 -41
- package/corpus/core/src/client/org/OrgSwitcher.tsx +1 -1
- package/corpus/core/src/client/sharing/ShareButton.tsx +3 -27
- package/corpus/core/src/collab/presence.ts +1 -1
- package/corpus/core/src/mcp/connect-route.ts +34 -5
- package/corpus/core/src/server/action-discovery.ts +4 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +20 -0
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +2 -0
- package/corpus/templates/analytics/actions/update-dashboard.ts +8 -0
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +117 -33
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +4 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +7 -0
- package/corpus/templates/analytics/changelog/2026-06-27-dashboards-can-now-nest-under-a-parent-in-the-sidebar-via-a-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-analytics-pages-now-sit-closer-under-the-header-with-tighter.md +6 -0
- package/corpus/templates/assets/actions/generate-image-batch.ts +3 -0
- package/corpus/templates/assets/actions/generate-image.ts +3 -0
- package/corpus/templates/assets/changelog/2026-06-29-longer-agent-generation-window.md +6 -0
- package/corpus/templates/assets/netlify.toml +3 -3
- package/corpus/templates/assets/server/plugins/agent-chat.ts +4 -1
- package/corpus/templates/clips/app/components/capture-install-options.tsx +7 -8
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +1 -1
- package/corpus/templates/content/AGENTS.md +12 -0
- package/corpus/templates/content/app/blocks/BuilderDocsBlocks.tsx +10 -0
- package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +1 -0
- package/corpus/templates/content/app/components/editor/ContentReferencePreview.tsx +185 -0
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +3 -0
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +19 -0
- package/corpus/templates/content/app/components/editor/extensions/ContentReferenceNode.tsx +82 -0
- package/corpus/templates/content/app/global.css +9 -0
- package/corpus/templates/content/app/i18n/zh-TW.ts +12 -0
- package/corpus/templates/content/app/i18n-data.ts +140 -0
- package/corpus/templates/content/changelog/2026-06-29-reusable-mdx-references-now-preview-linked-local-documents-i.md +6 -0
- package/corpus/templates/content/shared/builder-docs-blocks.ts +8 -0
- package/corpus/templates/content/shared/builder-mdx.ts +141 -4
- package/corpus/templates/content/shared/nfm.ts +62 -0
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +10 -11
- package/corpus/templates/design/AGENTS.md +5 -0
- package/corpus/templates/design/_gitignore +7 -0
- package/corpus/templates/design/actions/apply-visual-edit.ts +22 -12
- package/corpus/templates/design/actions/create-design-system.ts +15 -4
- package/corpus/templates/design/actions/create-file.ts +20 -1
- package/corpus/templates/design/actions/delete-design-system.ts +2 -2
- package/corpus/templates/design/actions/duplicate-design.ts +35 -9
- package/corpus/templates/design/actions/generate-design.ts +146 -69
- package/corpus/templates/design/actions/generate-screens.ts +51 -19
- package/corpus/templates/design/actions/get-design-snapshot.ts +5 -1
- package/corpus/templates/design/actions/get-design.ts +2 -0
- package/corpus/templates/design/actions/import-design-project.ts +28 -9
- package/corpus/templates/design/actions/import-document.ts +22 -8
- package/corpus/templates/design/actions/index-design-system-with-builder.ts +6 -153
- package/corpus/templates/design/actions/navigate.ts +105 -54
- package/corpus/templates/design/actions/set-default-design-system.ts +17 -3
- package/corpus/templates/design/actions/show-design-questions.ts +2 -0
- package/corpus/templates/design/actions/update-design.ts +2 -1
- package/corpus/templates/design/actions/view-screen.ts +12 -6
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +4 -4
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +159 -41
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +8 -4
- package/corpus/templates/design/app/components/design/DrawOverlay.tsx +37 -42
- package/corpus/templates/design/app/components/design/EditPanel.tsx +336 -183
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +153 -34
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +135 -33
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +6 -0
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +2 -1
- package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +4 -10
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +84 -43
- package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +4 -4
- package/corpus/templates/design/app/components/design/inspector/{FigmaColorPicker.tsx → DesignColorPicker.tsx} +89 -62
- package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +14 -26
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +40 -12
- package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +13 -4
- package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +13 -13
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +13 -9
- package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +13 -4
- package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +6 -6
- package/corpus/templates/design/app/components/design/inspector/{figma-icons.tsx → design-icons.tsx} +2 -2
- package/corpus/templates/design/app/components/design/inspector/index.ts +12 -12
- package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +5 -2
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +3 -3
- package/corpus/templates/design/app/components/layout/Layout.tsx +5 -2
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +167 -91
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +16 -3
- package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +15 -0
- package/corpus/templates/design/app/global.css +4 -0
- package/corpus/templates/design/app/hooks/use-design-system.ts +4 -1
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +38 -3
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +9 -2
- package/corpus/templates/design/app/i18n/zh-TW.ts +22 -0
- package/corpus/templates/design/app/i18n-data.ts +527 -0
- package/corpus/templates/design/app/lib/design-systems.ts +6 -4
- package/corpus/templates/design/app/lib/design-templates.ts +15 -3
- package/corpus/templates/design/app/pages/DesignEditor.tsx +641 -158
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +42 -34
- package/corpus/templates/design/app/pages/VisualEdit.tsx +100 -0
- package/corpus/templates/design/app/root.tsx +42 -9
- package/corpus/templates/design/app/routes/visual-edit.tsx +7 -0
- package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +1 -1
- package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +1 -1
- package/corpus/templates/design/changelog/2026-06-28-visual-code-design-mode.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-generation-prompts-now-show-connect-ai-before-sending.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-mode-top-chrome-now-groups-collaborators-preview-shar.md +1 -1
- package/corpus/templates/design/changelog/2026-06-29-fixed-design-editor-exports-and-gradient-edits-so-multi-scre.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-longer-hosted-agent-turns.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-png-export-handles-modern-css-color-functions-more-reliably.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-png-export-now-ignores-duplicate-clicks-while-a-download-is-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-public-visual-edit-and-shared-design-links-now-invite-visito.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-visual-edit-actions-now-reject-missing-design-targets-before.md +6 -0
- package/corpus/templates/design/e2e/README.md +71 -0
- package/corpus/templates/design/e2e/global-setup.ts +157 -0
- package/corpus/templates/design/e2e/helpers.ts +148 -0
- package/corpus/templates/design/netlify.toml +3 -4
- package/corpus/templates/design/package.json +5 -1
- package/corpus/templates/design/playwright.config.ts +51 -0
- package/corpus/templates/design/server/handlers/index-design-system-with-builder.ts +121 -0
- package/corpus/templates/design/server/handlers/uploads.ts +89 -38
- package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +181 -0
- package/corpus/templates/design/server/lib/coding-handoff.ts +33 -4
- package/corpus/templates/design/server/lib/design-export.ts +35 -8
- package/corpus/templates/design/server/plugins/agent-chat.ts +4 -0
- package/corpus/templates/design/server/plugins/auth.ts +10 -1
- package/corpus/templates/design/server/routes/api/index-design-system-with-builder.post.ts +1 -0
- package/corpus/templates/design/shared/api.ts +2 -0
- package/corpus/templates/design/shared/apply-edits.ts +12 -8
- package/corpus/templates/design/shared/canvas-math.ts +19 -1
- package/corpus/templates/design/shared/code-layer.ts +87 -28
- package/corpus/templates/design/shared/generation-session.ts +1 -0
- package/corpus/templates/design/shared/resolve-tweaks.ts +4 -3
- package/corpus/templates/design/shared/shader-presets.ts +10 -0
- package/corpus/templates/design/shared/source-mode.ts +9 -0
- package/corpus/templates/design/vitest.config.ts +2 -1
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +1 -1
- package/corpus/templates/plan/.agents/skills/visual-plan/references/canvas.md +1 -1
- package/corpus/templates/plan/AGENTS.md +1 -1
- package/corpus/templates/plan/actions/create-plan-design.ts +1 -1
- package/corpus/templates/plan/actions/validate-local-plan-source.ts +2 -10
- package/corpus/templates/plan/app/pages/PlansPage.tsx +1 -0
- package/corpus/templates/plan/docs/commenting-ux-plan.md +2 -2
- package/corpus/templates/plan/server/plan-content.ts +1 -1
- package/corpus/templates/plan/server/ui-plan-html.ts +2 -2
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +6 -153
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +53 -38
- package/corpus/templates/slides/app/components/design-system/{fig-import-response.ts → builder-index-response.ts} +9 -6
- package/corpus/templates/slides/app/components/visual-editor/MultiSelectChip.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-06-29-design-system-setup-now-indexes-uploaded-design-files-throug.md +6 -0
- package/corpus/templates/slides/changelog/2026-06-29-longer-hosted-agent-turns.md +6 -0
- package/corpus/templates/slides/netlify.toml +3 -6
- package/corpus/templates/slides/server/handlers/index-design-system-with-builder.ts +116 -0
- package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +179 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -1
- package/corpus/templates/slides/server/routes/api/index-design-system-with-builder.post.ts +1 -0
- package/dist/action.d.ts +15 -0
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +6 -0
- package/dist/action.js.map +1 -1
- package/dist/agent/durable-background.d.ts +9 -7
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +27 -11
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/production-agent.d.ts +7 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +4 -1
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-loop-with-resume.d.ts +2 -1
- package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
- package/dist/agent/run-loop-with-resume.js +2 -2
- package/dist/agent/run-loop-with-resume.js.map +1 -1
- package/dist/brand-kit/fig/index.d.ts +4 -4
- package/dist/brand-kit/fig/index.d.ts.map +1 -1
- package/dist/brand-kit/fig/index.js +14 -27
- package/dist/brand-kit/fig/index.js.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-config-writers.d.ts +15 -7
- package/dist/cli/mcp-config-writers.d.ts.map +1 -1
- package/dist/cli/mcp-config-writers.js +198 -45
- package/dist/cli/mcp-config-writers.js.map +1 -1
- package/dist/cli/skills.d.ts +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +18 -3
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +11 -1
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +15 -2
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +35 -1
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/org/OrgSwitcher.js +1 -1
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts +1 -1
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +2 -15
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/collab/presence.d.ts +1 -1
- package/dist/collab/presence.js +1 -1
- package/dist/collab/presence.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/mcp/connect-route.d.ts.map +1 -1
- package/dist/mcp/connect-route.js +34 -5
- package/dist/mcp/connect-route.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +3 -3
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +5 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +6 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +12 -3
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/docs/content/locales/ar-SA/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/ar-SA/template-design.mdx +1 -1
- package/docs/content/locales/de-DE/real-time-collaboration.mdx +3 -3
- package/docs/content/locales/de-DE/template-design.mdx +1 -1
- package/docs/content/locales/es-ES/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/es-ES/template-design.mdx +1 -1
- package/docs/content/locales/fr-FR/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/fr-FR/template-design.mdx +1 -1
- package/docs/content/locales/hi-IN/template-design.mdx +1 -1
- package/docs/content/locales/ja-JP/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/ja-JP/template-design.mdx +1 -1
- package/docs/content/locales/ko-KR/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/ko-KR/template-design.mdx +1 -1
- package/docs/content/locales/pt-BR/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/pt-BR/template-design.mdx +1 -1
- package/docs/content/locales/zh-CN/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/zh-CN/template-design.mdx +1 -1
- package/docs/content/locales/zh-TW/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/zh-TW/template-design.mdx +1 -1
- package/docs/content/real-time-collaboration.mdx +2 -2
- package/docs/content/template-design.mdx +1 -1
- package/package.json +3 -7
- package/corpus/core/src/brand-kit/fig/decode.ts +0 -410
- package/corpus/core/src/brand-kit/fig/extract-design-system.ts +0 -947
- package/corpus/core/src/brand-kit/fig/fig-to-html.ts +0 -1906
- package/corpus/templates/design/actions/import-figma.ts +0 -55
- package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +0 -6
- package/corpus/templates/design/server/handlers/import-figma-system.ts +0 -86
- package/corpus/templates/design/server/routes/api/import-figma-system.post.ts +0 -1
- package/corpus/templates/slides/server/handlers/import-figma-system.ts +0 -101
- package/corpus/templates/slides/server/routes/api/import-figma-system.post.ts +0 -1
- package/dist/brand-kit/fig/decode.d.ts +0 -33
- package/dist/brand-kit/fig/decode.d.ts.map +0 -1
- package/dist/brand-kit/fig/decode.js +0 -358
- package/dist/brand-kit/fig/decode.js.map +0 -1
- package/dist/brand-kit/fig/extract-design-system.d.ts +0 -44
- package/dist/brand-kit/fig/extract-design-system.d.ts.map +0 -1
- package/dist/brand-kit/fig/extract-design-system.js +0 -752
- package/dist/brand-kit/fig/extract-design-system.js.map +0 -1
- package/dist/brand-kit/fig/fig-to-html.d.ts +0 -246
- package/dist/brand-kit/fig/fig-to-html.d.ts.map +0 -1
- package/dist/brand-kit/fig/fig-to-html.js +0 -1506
- package/dist/brand-kit/fig/fig-to-html.js.map +0 -1
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { defineAction, embedApp } from "@agent-native/core";
|
|
2
|
+
import {
|
|
3
|
+
deleteAppState,
|
|
4
|
+
readAppState,
|
|
5
|
+
writeAppState,
|
|
6
|
+
} from "@agent-native/core/application-state";
|
|
2
7
|
import {
|
|
3
8
|
hasCollabState,
|
|
4
9
|
applyText,
|
|
@@ -18,6 +23,10 @@ import {
|
|
|
18
23
|
mergeCanvasFramePlacements,
|
|
19
24
|
type CanvasFramePlacement,
|
|
20
25
|
} from "../shared/canvas-frames.js";
|
|
26
|
+
import {
|
|
27
|
+
designGenerationSessionKey,
|
|
28
|
+
type DesignGenerationSession,
|
|
29
|
+
} from "../shared/generation-session.js";
|
|
21
30
|
|
|
22
31
|
/** Editor deep link so external agents can surface "Open design". */
|
|
23
32
|
function designDeepLink(designId: string): string {
|
|
@@ -28,6 +37,50 @@ function designDeepLink(designId: string): string {
|
|
|
28
37
|
});
|
|
29
38
|
}
|
|
30
39
|
|
|
40
|
+
function isRenderableDesignFile(file: {
|
|
41
|
+
fileType?: string | null;
|
|
42
|
+
content?: string | null;
|
|
43
|
+
}): boolean {
|
|
44
|
+
const fileType = file.fileType ?? "html";
|
|
45
|
+
return (
|
|
46
|
+
(fileType === "html" || fileType === "jsx") && Boolean(file.content?.trim())
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function updateGenerationSessionForSavedFiles(
|
|
51
|
+
designId: string,
|
|
52
|
+
savedFilenames: string[],
|
|
53
|
+
) {
|
|
54
|
+
const key = designGenerationSessionKey(designId);
|
|
55
|
+
const rawSession = await readAppState(key).catch(() => null);
|
|
56
|
+
if (!rawSession || typeof rawSession !== "object") return;
|
|
57
|
+
const session = rawSession as unknown as DesignGenerationSession;
|
|
58
|
+
if (session.designId !== designId || !Array.isArray(session.frames)) return;
|
|
59
|
+
|
|
60
|
+
const saved = new Set(savedFilenames);
|
|
61
|
+
const frames = session.frames.map((frame) =>
|
|
62
|
+
frame.filename && saved.has(frame.filename)
|
|
63
|
+
? {
|
|
64
|
+
...frame,
|
|
65
|
+
status: "done" as const,
|
|
66
|
+
step: "Saved",
|
|
67
|
+
progress: 1,
|
|
68
|
+
}
|
|
69
|
+
: frame,
|
|
70
|
+
);
|
|
71
|
+
const allDone = frames.every((frame) => frame.status === "done");
|
|
72
|
+
if (allDone) {
|
|
73
|
+
await deleteAppState(key);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
await writeAppState(key, {
|
|
78
|
+
...session,
|
|
79
|
+
status: "generating",
|
|
80
|
+
frames,
|
|
81
|
+
} as unknown as Record<string, unknown>);
|
|
82
|
+
}
|
|
83
|
+
|
|
31
84
|
export default defineAction({
|
|
32
85
|
description:
|
|
33
86
|
"Save generated design content to a design project. " +
|
|
@@ -181,19 +234,6 @@ export default defineAction({
|
|
|
181
234
|
}
|
|
182
235
|
}
|
|
183
236
|
|
|
184
|
-
const hasRenderableFile = files.some((file) => {
|
|
185
|
-
const fileType = file.fileType ?? "html";
|
|
186
|
-
return (
|
|
187
|
-
(fileType === "html" || fileType === "jsx") &&
|
|
188
|
-
file.content.trim().length > 0
|
|
189
|
-
);
|
|
190
|
-
});
|
|
191
|
-
if (!hasRenderableFile) {
|
|
192
|
-
throw new Error(
|
|
193
|
-
"generate-design requires at least one non-empty HTML or JSX file before the design can be reported as ready",
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
237
|
const savedFiles: Array<{
|
|
198
238
|
id: string;
|
|
199
239
|
filename: string;
|
|
@@ -206,6 +246,15 @@ export default defineAction({
|
|
|
206
246
|
.from(schema.designFiles)
|
|
207
247
|
.where(eq(schema.designFiles.designId, designId));
|
|
208
248
|
|
|
249
|
+
const hasRenderableFile =
|
|
250
|
+
files.some(isRenderableDesignFile) ||
|
|
251
|
+
existingFiles.some(isRenderableDesignFile);
|
|
252
|
+
if (!hasRenderableFile) {
|
|
253
|
+
throw new Error(
|
|
254
|
+
"generate-design requires at least one non-empty HTML or JSX file before the design can be reported as ready",
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
209
258
|
const existingByName = new Map(existingFiles.map((f) => [f.filename, f]));
|
|
210
259
|
|
|
211
260
|
for (const file of files) {
|
|
@@ -270,6 +319,19 @@ export default defineAction({
|
|
|
270
319
|
agentLeaveDocument(fileId);
|
|
271
320
|
}
|
|
272
321
|
|
|
322
|
+
// Update the in-memory map so a second entry with the same filename
|
|
323
|
+
// in the same `files` array hits the UPDATE branch instead of
|
|
324
|
+
// inserting a duplicate row.
|
|
325
|
+
existingByName.set(file.filename, {
|
|
326
|
+
id: fileId,
|
|
327
|
+
designId,
|
|
328
|
+
filename: file.filename,
|
|
329
|
+
fileType: file.fileType ?? "html",
|
|
330
|
+
content: file.content,
|
|
331
|
+
createdAt: now,
|
|
332
|
+
updatedAt: now,
|
|
333
|
+
});
|
|
334
|
+
|
|
273
335
|
savedFiles.push({
|
|
274
336
|
id: fileId,
|
|
275
337
|
filename: file.filename,
|
|
@@ -290,31 +352,12 @@ export default defineAction({
|
|
|
290
352
|
// Merge with existing data so tweak definitions survive content updates.
|
|
291
353
|
// The data column is a free-form JSON blob; we own these keys here and
|
|
292
354
|
// leave anything else intact.
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
try {
|
|
300
|
-
const parsed = JSON.parse(existingDesign.data);
|
|
301
|
-
if (parsed && typeof parsed === "object") prevData = parsed;
|
|
302
|
-
} catch {
|
|
303
|
-
// Stale or invalid JSON — start fresh.
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
const mergedData: Record<string, unknown> = {
|
|
307
|
-
...prevData,
|
|
308
|
-
lastPrompt: prompt,
|
|
309
|
-
generatedAt: now,
|
|
310
|
-
fileCount: files.length,
|
|
311
|
-
};
|
|
312
|
-
if (tweaks !== undefined) {
|
|
313
|
-
mergedData.tweaks = tweaks.map((tweak) => ({
|
|
314
|
-
...tweak,
|
|
315
|
-
type: tweak.type === "color-swatches" ? "color-swatch" : tweak.type,
|
|
316
|
-
}));
|
|
317
|
-
}
|
|
355
|
+
//
|
|
356
|
+
// Wrapped in a transaction so that concurrent generate-design calls for the
|
|
357
|
+
// same design (e.g. the parallel fan-out from generate-screens) each read
|
|
358
|
+
// the latest canvasFrames and merge their own placement on top, rather than
|
|
359
|
+
// all reading the same stale snapshot and the last writer silently
|
|
360
|
+
// discarding the others' frame coordinates.
|
|
318
361
|
let placedFrames:
|
|
319
362
|
| Array<{
|
|
320
363
|
fileId: string;
|
|
@@ -322,39 +365,73 @@ export default defineAction({
|
|
|
322
365
|
frame: CanvasFramePlacement;
|
|
323
366
|
}>
|
|
324
367
|
| undefined;
|
|
325
|
-
|
|
326
|
-
const
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
368
|
+
await db.transaction(async (tx) => {
|
|
369
|
+
const [existingDesign] = await tx
|
|
370
|
+
.select({ data: schema.designs.data })
|
|
371
|
+
.from(schema.designs)
|
|
372
|
+
.where(eq(schema.designs.id, designId));
|
|
373
|
+
let prevData: Record<string, unknown> = {};
|
|
374
|
+
if (existingDesign?.data) {
|
|
375
|
+
try {
|
|
376
|
+
const parsed = JSON.parse(existingDesign.data);
|
|
377
|
+
if (parsed && typeof parsed === "object") prevData = parsed;
|
|
378
|
+
} catch {
|
|
379
|
+
// Stale or invalid JSON — start fresh.
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
const mergedData: Record<string, unknown> = {
|
|
383
|
+
...prevData,
|
|
384
|
+
lastPrompt: prompt,
|
|
385
|
+
generatedAt: now,
|
|
386
|
+
fileCount: files.length,
|
|
387
|
+
};
|
|
388
|
+
if (tweaks !== undefined) {
|
|
389
|
+
mergedData.tweaks = tweaks.map((tweak) => ({
|
|
390
|
+
...tweak,
|
|
391
|
+
type: tweak.type === "color-swatches" ? "color-swatch" : tweak.type,
|
|
392
|
+
}));
|
|
393
|
+
}
|
|
394
|
+
if (canvasFrames !== undefined) {
|
|
395
|
+
const savedByFileId = new Map(
|
|
396
|
+
savedFiles.map((file) => [file.id, file]),
|
|
397
|
+
);
|
|
398
|
+
const savedByFilename = new Map(
|
|
399
|
+
savedFiles.map((file) => [file.filename, file]),
|
|
400
|
+
);
|
|
401
|
+
const existingByFileId = new Map(
|
|
402
|
+
existingFiles.map((file) => [file.id, file]),
|
|
403
|
+
);
|
|
404
|
+
const merged = mergeCanvasFramePlacements({
|
|
405
|
+
existing: prevData.canvasFrames,
|
|
406
|
+
placements: canvasFrames,
|
|
407
|
+
resolveFileId: (placement) => {
|
|
408
|
+
if (placement.fileId) {
|
|
409
|
+
return savedByFileId.has(placement.fileId) ||
|
|
410
|
+
existingByFileId.has(placement.fileId)
|
|
411
|
+
? placement.fileId
|
|
412
|
+
: undefined;
|
|
413
|
+
}
|
|
414
|
+
return placement.filename
|
|
415
|
+
? (savedByFilename.get(placement.filename)?.id ??
|
|
416
|
+
existingByName.get(placement.filename)?.id)
|
|
341
417
|
: undefined;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
});
|
|
349
|
-
mergedData.canvasFrames = merged.canvasFrames;
|
|
350
|
-
placedFrames = merged.placedFrames;
|
|
351
|
-
}
|
|
352
|
-
designUpdates.data = JSON.stringify(mergedData);
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
mergedData.canvasFrames = merged.canvasFrames;
|
|
421
|
+
placedFrames = merged.placedFrames;
|
|
422
|
+
}
|
|
423
|
+
designUpdates.data = JSON.stringify(mergedData);
|
|
353
424
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
425
|
+
await tx
|
|
426
|
+
.update(schema.designs)
|
|
427
|
+
.set(designUpdates)
|
|
428
|
+
.where(eq(schema.designs.id, designId));
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
await updateGenerationSessionForSavedFiles(
|
|
432
|
+
designId,
|
|
433
|
+
savedFiles.map((file) => file.filename),
|
|
434
|
+
);
|
|
358
435
|
|
|
359
436
|
return {
|
|
360
437
|
designId,
|
|
@@ -42,16 +42,27 @@ function designDeepLink(designId: string): string {
|
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
const requestedScreenSchema = z
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
45
|
+
const requestedScreenSchema = z
|
|
46
|
+
.object({
|
|
47
|
+
frameId: z.string().optional(),
|
|
48
|
+
title: z.string().min(1),
|
|
49
|
+
filename: z
|
|
50
|
+
.string()
|
|
51
|
+
.optional()
|
|
52
|
+
.describe("Target filename for this screen, such as onboarding.html"),
|
|
53
|
+
role: z.enum(["screen", "variant"]).optional().default("screen"),
|
|
54
|
+
variantOf: z.string().optional(),
|
|
55
|
+
})
|
|
56
|
+
.superRefine((screen, ctx) => {
|
|
57
|
+
if (screen.role === "variant" && !screen.variantOf) {
|
|
58
|
+
ctx.addIssue({
|
|
59
|
+
code: z.ZodIssueCode.custom,
|
|
60
|
+
path: ["variantOf"],
|
|
61
|
+
message:
|
|
62
|
+
"variant screens require variantOf to identify the base screen",
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
});
|
|
55
66
|
|
|
56
67
|
export default defineAction({
|
|
57
68
|
description:
|
|
@@ -101,10 +112,39 @@ export default defineAction({
|
|
|
101
112
|
origin: { x: 0, y: 0 },
|
|
102
113
|
columns: screens.length <= 3 ? screens.length : 3,
|
|
103
114
|
});
|
|
115
|
+
|
|
116
|
+
const seenFilenames = new Map<string, number>();
|
|
117
|
+
// Dedupe any filename (explicit or auto-generated) so two screens can never
|
|
118
|
+
// resolve to the same target file — otherwise generate-design silently
|
|
119
|
+
// overwrites the first screen's output with the second's.
|
|
120
|
+
const dedupeFilename = (base: string): string => {
|
|
121
|
+
if (!seenFilenames.has(base)) {
|
|
122
|
+
seenFilenames.set(base, 1);
|
|
123
|
+
return base;
|
|
124
|
+
}
|
|
125
|
+
const count = seenFilenames.get(base)! + 1;
|
|
126
|
+
seenFilenames.set(base, count);
|
|
127
|
+
const dot = base.lastIndexOf(".");
|
|
128
|
+
return dot > 0
|
|
129
|
+
? `${base.slice(0, dot)}-${count}${base.slice(dot)}`
|
|
130
|
+
: `${base}-${count}`;
|
|
131
|
+
};
|
|
132
|
+
const requestedTargets = screens.map((screen, index) => {
|
|
133
|
+
if (screen.filename) return dedupeFilename(screen.filename);
|
|
134
|
+
const slug =
|
|
135
|
+
screen.title
|
|
136
|
+
.toLowerCase()
|
|
137
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
138
|
+
.replace(/^-+|-+$/g, "")
|
|
139
|
+
.slice(0, 48) || `screen-${index + 1}`;
|
|
140
|
+
return dedupeFilename(`${slug}.html`);
|
|
141
|
+
});
|
|
142
|
+
|
|
104
143
|
const frames: DesignGenerationFrame[] = screens.map((screen, index) => {
|
|
105
144
|
const frameId = screen.frameId ?? nanoid();
|
|
106
145
|
return {
|
|
107
146
|
frameId,
|
|
147
|
+
filename: requestedTargets[index],
|
|
108
148
|
agentId: `agent-${frameId}`,
|
|
109
149
|
agentName: AGENT_NAMES[index % AGENT_NAMES.length] ?? "Agent",
|
|
110
150
|
agentColor:
|
|
@@ -142,15 +182,7 @@ export default defineAction({
|
|
|
142
182
|
|
|
143
183
|
const targets = frames.map((frame, index) => {
|
|
144
184
|
const requested = screens[index]!;
|
|
145
|
-
const filename =
|
|
146
|
-
requested.filename ??
|
|
147
|
-
`${
|
|
148
|
-
requested.title
|
|
149
|
-
.toLowerCase()
|
|
150
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
151
|
-
.replace(/^-+|-+$/g, "")
|
|
152
|
-
.slice(0, 48) || `screen-${index + 1}`
|
|
153
|
-
}.html`;
|
|
185
|
+
const filename = requestedTargets[index]!;
|
|
154
186
|
return {
|
|
155
187
|
frameId: frame.frameId,
|
|
156
188
|
title: requested.title,
|
|
@@ -43,7 +43,11 @@ export default defineAction({
|
|
|
43
43
|
run: async ({ designId }) => {
|
|
44
44
|
const access = await resolveAccess("design", designId);
|
|
45
45
|
if (!access) {
|
|
46
|
-
|
|
46
|
+
const err = new Error("Design not found") as Error & {
|
|
47
|
+
statusCode: number;
|
|
48
|
+
};
|
|
49
|
+
err.statusCode = 404;
|
|
50
|
+
throw err;
|
|
47
51
|
}
|
|
48
52
|
const design = access.resource as typeof schema.designs.$inferSelect;
|
|
49
53
|
|
|
@@ -13,6 +13,7 @@ export default defineAction({
|
|
|
13
13
|
id: z.string().describe("Design ID"),
|
|
14
14
|
}),
|
|
15
15
|
readOnly: true,
|
|
16
|
+
requiresAuth: false,
|
|
16
17
|
http: { method: "GET" },
|
|
17
18
|
run: async ({ id }) => {
|
|
18
19
|
const access = await resolveAccess("design", id);
|
|
@@ -39,6 +40,7 @@ export default defineAction({
|
|
|
39
40
|
visibility: row.visibility,
|
|
40
41
|
createdAt: row.createdAt,
|
|
41
42
|
updatedAt: row.updatedAt,
|
|
43
|
+
accessRole: access.role,
|
|
42
44
|
files: files.map((f) => ({
|
|
43
45
|
id: f.id,
|
|
44
46
|
filename: f.filename,
|
|
@@ -12,15 +12,28 @@ export default defineAction({
|
|
|
12
12
|
"has good styling (CSS custom properties, fonts, colors), this extracts those " +
|
|
13
13
|
"into reusable design tokens. Alternatively, import from an existing design system " +
|
|
14
14
|
"for cloning/forking. Returns extracted tokens plus raw CSS for agent refinement.",
|
|
15
|
-
schema: z
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
schema: z
|
|
16
|
+
.object({
|
|
17
|
+
designId: z
|
|
18
|
+
.string()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("Design project ID to extract tokens from"),
|
|
21
|
+
designSystemId: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe(
|
|
25
|
+
"If provided, import from this existing design system instead of extracting from the design project",
|
|
26
|
+
),
|
|
27
|
+
})
|
|
28
|
+
.superRefine((args, ctx) => {
|
|
29
|
+
if (!args.designId && !args.designSystemId) {
|
|
30
|
+
ctx.addIssue({
|
|
31
|
+
code: z.ZodIssueCode.custom,
|
|
32
|
+
path: ["designId"],
|
|
33
|
+
message: "designId or designSystemId is required",
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}),
|
|
24
37
|
readOnly: true,
|
|
25
38
|
http: { method: "GET" },
|
|
26
39
|
run: async ({ designId, designSystemId }) => {
|
|
@@ -55,6 +68,12 @@ export default defineAction({
|
|
|
55
68
|
};
|
|
56
69
|
}
|
|
57
70
|
|
|
71
|
+
if (!designId) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
"designId is required when designSystemId is not provided",
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
58
77
|
// Extract tokens from the design project
|
|
59
78
|
await assertAccess("design", designId, "viewer");
|
|
60
79
|
|
|
@@ -8,6 +8,9 @@ import {
|
|
|
8
8
|
} from "@agent-native/core/server/design-token-utils";
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
|
|
11
|
+
const DOC_MAX_FILES = 20;
|
|
12
|
+
const DOC_MAX_TEXT_BYTES = 500 * 1024;
|
|
13
|
+
|
|
11
14
|
export default defineAction({
|
|
12
15
|
description:
|
|
13
16
|
"Process uploaded document metadata (DOCX, PPTX, PDF, XLSX) and return " +
|
|
@@ -44,16 +47,29 @@ export default defineAction({
|
|
|
44
47
|
}),
|
|
45
48
|
readOnly: true,
|
|
46
49
|
run: async ({ files }) => {
|
|
47
|
-
const
|
|
50
|
+
const capped = files.slice(0, DOC_MAX_FILES);
|
|
51
|
+
const processedFiles = capped.map((file) => {
|
|
48
52
|
const contentType = classifyFile(file.fileType);
|
|
49
|
-
|
|
53
|
+
|
|
54
|
+
// Truncate textContent before regex scanning to bound CPU/memory usage.
|
|
55
|
+
let text = file.textContent;
|
|
56
|
+
if (text) {
|
|
57
|
+
const encoded = new TextEncoder().encode(text);
|
|
58
|
+
if (encoded.byteLength > DOC_MAX_TEXT_BYTES) {
|
|
59
|
+
text = new TextDecoder().decode(
|
|
60
|
+
encoded.subarray(0, DOC_MAX_TEXT_BYTES),
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const hasText = !!text && text.trim().length > 0;
|
|
50
66
|
|
|
51
67
|
let likelyColors: string[] = [];
|
|
52
68
|
let likelyFonts: string[] = [];
|
|
53
69
|
|
|
54
|
-
if (
|
|
55
|
-
likelyColors = extractDocumentColors(
|
|
56
|
-
likelyFonts = extractDocumentFonts(
|
|
70
|
+
if (text) {
|
|
71
|
+
likelyColors = extractDocumentColors(text);
|
|
72
|
+
likelyFonts = extractDocumentFonts(text);
|
|
57
73
|
}
|
|
58
74
|
|
|
59
75
|
if (file.metadata) {
|
|
@@ -80,9 +96,7 @@ export default defineAction({
|
|
|
80
96
|
likelyColors,
|
|
81
97
|
likelyFonts,
|
|
82
98
|
contentType,
|
|
83
|
-
extractedText:
|
|
84
|
-
? file.textContent.slice(0, 2000)
|
|
85
|
-
: undefined,
|
|
99
|
+
extractedText: text ? text.slice(0, 2000) : undefined,
|
|
86
100
|
suggestions,
|
|
87
101
|
},
|
|
88
102
|
};
|
|
@@ -7,11 +7,9 @@ import {
|
|
|
7
7
|
getRequestOrgId,
|
|
8
8
|
getRequestUserEmail,
|
|
9
9
|
} from "@agent-native/core/server/request-context";
|
|
10
|
-
import { eq } from "drizzle-orm";
|
|
11
|
-
import { nanoid } from "nanoid";
|
|
12
10
|
import { z } from "zod";
|
|
13
11
|
|
|
14
|
-
import {
|
|
12
|
+
import { upsertBuilderProxyDesignSystem } from "../server/lib/builder-design-system-proxy.js";
|
|
15
13
|
|
|
16
14
|
const MAX_CODE_FILES = 50;
|
|
17
15
|
const MAX_TOTAL_CODE_BYTES = 2 * 1024 * 1024;
|
|
@@ -52,83 +50,6 @@ function makeFiles(
|
|
|
52
50
|
return files;
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
function localBuilderDesignSystemId(builderDesignSystemId: string): string {
|
|
56
|
-
const slug = builderDesignSystemId
|
|
57
|
-
.replace(/[^a-zA-Z0-9_-]+/g, "-")
|
|
58
|
-
.replace(/^-+|-+$/g, "")
|
|
59
|
-
.slice(0, 96);
|
|
60
|
-
return `builder-${slug || "design-system"}`;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function builderProxyData({
|
|
64
|
-
builderDesignSystemId,
|
|
65
|
-
jobId,
|
|
66
|
-
builderUrl,
|
|
67
|
-
projectName,
|
|
68
|
-
description,
|
|
69
|
-
}: {
|
|
70
|
-
builderDesignSystemId: string;
|
|
71
|
-
jobId: string;
|
|
72
|
-
builderUrl: string;
|
|
73
|
-
projectName?: string;
|
|
74
|
-
description?: string;
|
|
75
|
-
}) {
|
|
76
|
-
return JSON.stringify({
|
|
77
|
-
source: "builder",
|
|
78
|
-
builderDesignSystemId,
|
|
79
|
-
builderJobId: jobId,
|
|
80
|
-
builderUrl,
|
|
81
|
-
colors: {
|
|
82
|
-
primary: "var(--primary)",
|
|
83
|
-
secondary: "var(--secondary)",
|
|
84
|
-
accent: "var(--accent)",
|
|
85
|
-
background: "var(--background)",
|
|
86
|
-
surface: "var(--card)",
|
|
87
|
-
text: "var(--foreground)",
|
|
88
|
-
textMuted: "var(--muted-foreground)",
|
|
89
|
-
},
|
|
90
|
-
typography: {
|
|
91
|
-
headingFont: "inherit",
|
|
92
|
-
bodyFont: "inherit",
|
|
93
|
-
headingWeight: "700",
|
|
94
|
-
bodyWeight: "400",
|
|
95
|
-
headingSizes: { h1: "48px", h2: "32px", h3: "24px" },
|
|
96
|
-
},
|
|
97
|
-
spacing: { elementGap: "24px", pagePadding: "48px" },
|
|
98
|
-
borders: { radius: "12px", accentWidth: "1px" },
|
|
99
|
-
logos: [],
|
|
100
|
-
notes: [
|
|
101
|
-
"This is a local proxy for a Builder-indexed design system.",
|
|
102
|
-
`Builder design system id: ${builderDesignSystemId}`,
|
|
103
|
-
`Builder indexing job id: ${jobId}`,
|
|
104
|
-
`Builder URL: ${builderUrl}`,
|
|
105
|
-
projectName ? `Requested name: ${projectName}` : "",
|
|
106
|
-
description ? `Context: ${description}` : "",
|
|
107
|
-
"Use Builder as the source of truth for extracted tokens and guidance.",
|
|
108
|
-
]
|
|
109
|
-
.filter(Boolean)
|
|
110
|
-
.join("\n"),
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function builderProxyInstructions({
|
|
115
|
-
builderDesignSystemId,
|
|
116
|
-
jobId,
|
|
117
|
-
builderUrl,
|
|
118
|
-
}: {
|
|
119
|
-
builderDesignSystemId: string;
|
|
120
|
-
jobId: string;
|
|
121
|
-
builderUrl: string;
|
|
122
|
-
}) {
|
|
123
|
-
return [
|
|
124
|
-
"This design system is indexed and owned by Builder.",
|
|
125
|
-
`Builder design system id: ${builderDesignSystemId}`,
|
|
126
|
-
`Builder job id: ${jobId}`,
|
|
127
|
-
`Builder URL: ${builderUrl}`,
|
|
128
|
-
"When generating designs, treat Builder as the source of truth for the final extracted tokens, assets, and guidance.",
|
|
129
|
-
].join("\n");
|
|
130
|
-
}
|
|
131
|
-
|
|
132
53
|
export default defineAction({
|
|
133
54
|
description:
|
|
134
55
|
"Start Builder design-system indexing from a GitHub repository and/or code files. " +
|
|
@@ -174,86 +95,18 @@ export default defineAction({
|
|
|
174
95
|
const ownerEmail = getRequestUserEmail();
|
|
175
96
|
if (!ownerEmail) throw new Error("no authenticated user");
|
|
176
97
|
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
result.designSystemId,
|
|
182
|
-
);
|
|
183
|
-
const title = projectName?.trim() || "Builder indexed design system";
|
|
184
|
-
const localData = builderProxyData({
|
|
185
|
-
builderDesignSystemId: result.designSystemId,
|
|
186
|
-
jobId: result.jobId,
|
|
187
|
-
builderUrl: result.builderUrl,
|
|
98
|
+
const proxy = await upsertBuilderProxyDesignSystem({
|
|
99
|
+
result,
|
|
100
|
+
ownerEmail,
|
|
101
|
+
orgId: getRequestOrgId(),
|
|
188
102
|
projectName,
|
|
189
103
|
description,
|
|
190
104
|
});
|
|
191
|
-
const customInstructions = builderProxyInstructions({
|
|
192
|
-
builderDesignSystemId: result.designSystemId,
|
|
193
|
-
jobId: result.jobId,
|
|
194
|
-
builderUrl: result.builderUrl,
|
|
195
|
-
});
|
|
196
|
-
const [existing] = await db
|
|
197
|
-
.select({
|
|
198
|
-
id: schema.designSystems.id,
|
|
199
|
-
ownerEmail: schema.designSystems.ownerEmail,
|
|
200
|
-
})
|
|
201
|
-
.from(schema.designSystems)
|
|
202
|
-
.where(eq(schema.designSystems.id, baseLocalDesignSystemId))
|
|
203
|
-
.limit(1);
|
|
204
|
-
const localDesignSystemId =
|
|
205
|
-
existing && existing.ownerEmail !== ownerEmail
|
|
206
|
-
? `${baseLocalDesignSystemId}-${nanoid(8)}`
|
|
207
|
-
: baseLocalDesignSystemId;
|
|
208
|
-
if (existing && existing.ownerEmail === ownerEmail) {
|
|
209
|
-
await db
|
|
210
|
-
.update(schema.designSystems)
|
|
211
|
-
.set({
|
|
212
|
-
title,
|
|
213
|
-
description:
|
|
214
|
-
description ??
|
|
215
|
-
`Builder indexed design system ${result.designSystemId}`,
|
|
216
|
-
data: localData,
|
|
217
|
-
assets: "[]",
|
|
218
|
-
customInstructions,
|
|
219
|
-
updatedAt: now,
|
|
220
|
-
})
|
|
221
|
-
.where(eq(schema.designSystems.id, existing.id));
|
|
222
|
-
} else {
|
|
223
|
-
const [ownedSystem] = await db
|
|
224
|
-
.select({ id: schema.designSystems.id })
|
|
225
|
-
.from(schema.designSystems)
|
|
226
|
-
.where(eq(schema.designSystems.ownerEmail, ownerEmail))
|
|
227
|
-
.limit(1);
|
|
228
|
-
await db.insert(schema.designSystems).values({
|
|
229
|
-
id: localDesignSystemId,
|
|
230
|
-
title,
|
|
231
|
-
description:
|
|
232
|
-
description ??
|
|
233
|
-
`Builder indexed design system ${result.designSystemId}`,
|
|
234
|
-
data: localData,
|
|
235
|
-
assets: "[]",
|
|
236
|
-
customInstructions,
|
|
237
|
-
isDefault: !ownedSystem,
|
|
238
|
-
ownerEmail,
|
|
239
|
-
orgId,
|
|
240
|
-
createdAt: now,
|
|
241
|
-
updatedAt: now,
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
105
|
|
|
245
106
|
return {
|
|
246
107
|
...result,
|
|
247
|
-
|
|
108
|
+
...proxy,
|
|
248
109
|
uploadedFileCount: files.length,
|
|
249
|
-
instructions: [
|
|
250
|
-
"Builder design-system indexing has started.",
|
|
251
|
-
`Builder design system: ${result.designSystemId}`,
|
|
252
|
-
`Local selectable design system: ${localDesignSystemId}`,
|
|
253
|
-
`Builder job: ${result.jobId}`,
|
|
254
|
-
`Open: ${result.builderUrl}`,
|
|
255
|
-
"Use the local design system id in Design flows; Builder remains the source of truth for the indexed brand kit.",
|
|
256
|
-
].join("\n"),
|
|
257
110
|
};
|
|
258
111
|
},
|
|
259
112
|
});
|