@agent-native/core 0.80.4 → 0.80.6
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 +28 -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/create.ts +1 -0
- 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/core/src/sharing/registry.ts +17 -0
- package/corpus/core/src/templates/default/pnpm-workspace.yaml +1 -0
- package/corpus/core/src/templates/workspace-root/pnpm-workspace.yaml +1 -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 +57 -44
- package/corpus/templates/content/README.md +16 -0
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +125 -0
- package/corpus/templates/content/actions/_builder-cms-source-adapter.ts +28 -6
- package/corpus/templates/content/actions/_builder-cms-write-adapter.ts +238 -69
- package/corpus/templates/content/actions/_builder-cms-write-settings.ts +125 -43
- package/corpus/templates/content/actions/_database-source-utils.ts +746 -97
- package/corpus/templates/content/actions/_database-utils.ts +17 -14
- package/corpus/templates/content/actions/_federation-join.ts +14 -2
- package/corpus/templates/content/actions/_join-suggestion.ts +89 -14
- package/corpus/templates/content/actions/_local-file-documents.ts +2 -1
- package/corpus/templates/content/actions/attach-content-database-source.ts +124 -5
- package/corpus/templates/content/actions/bind-content-database-source-field.ts +256 -0
- package/corpus/templates/content/actions/change-content-database-source-role.ts +420 -0
- package/corpus/templates/content/actions/create-document.ts +8 -0
- package/corpus/templates/content/actions/execute-builder-source-batch.ts +282 -0
- package/corpus/templates/content/actions/execute-builder-source-execution.ts +220 -8
- package/corpus/templates/content/actions/get-content-database.ts +10 -2
- package/corpus/templates/content/actions/prepare-builder-source-execution.ts +19 -2
- package/corpus/templates/content/actions/prepare-builder-source-review.ts +47 -15
- package/corpus/templates/content/actions/refresh-content-database-source.ts +11 -4
- package/corpus/templates/content/actions/review-content-database-source-change-set.ts +6 -2
- package/corpus/templates/content/actions/set-content-database-source-write-mode.ts +32 -12
- package/corpus/templates/content/actions/stage-builder-revision.ts +14 -10
- package/corpus/templates/content/actions/validate-builder-source-execution.ts +25 -3
- 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/DocumentDatabase.tsx +1520 -553
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +3 -0
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +150 -1
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +19 -0
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +647 -66
- package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +543 -204
- 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/hooks/use-content-database.ts +62 -0
- package/corpus/templates/content/app/i18n/zh-TW.ts +76 -0
- package/corpus/templates/content/app/i18n-data.ts +924 -0
- package/corpus/templates/content/changelog/2026-06-29-builder-review-checks-now-preserve-publish-and-unpublish-cho.md +6 -0
- package/corpus/templates/content/changelog/2026-06-29-database-sources-can-now-be-added-as-more-rows-or-matched.md +6 -0
- package/corpus/templates/content/changelog/2026-06-29-fixed-loading-the-final-rows-in-larger-databases-without-bre.md +6 -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/api.ts +91 -1
- 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/content/vite.config.ts +14 -7
- 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/create.d.ts.map +1 -1
- package/dist/cli/create.js +1 -0
- package/dist/cli/create.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/file-upload/actions/upload-image.d.ts +2 -2
- 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 +2 -2
- package/dist/observability/routes.d.ts +8 -8
- 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/dist/sharing/registry.d.ts.map +1 -1
- package/dist/sharing/registry.js +11 -0
- package/dist/sharing/registry.js.map +1 -1
- package/dist/templates/default/pnpm-workspace.yaml +1 -0
- package/dist/templates/workspace-root/pnpm-workspace.yaml +1 -0
- 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/src/templates/default/pnpm-workspace.yaml +1 -0
- package/src/templates/workspace-root/pnpm-workspace.yaml +1 -0
- 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
|
@@ -17,12 +17,12 @@ import type {
|
|
|
17
17
|
} from "../shared/api.js";
|
|
18
18
|
import {
|
|
19
19
|
buildBuilderCmsExecutionPlan,
|
|
20
|
+
resolveBuilderCmsWriteEffect,
|
|
20
21
|
validateBuilderCmsExecutionDryRun,
|
|
21
22
|
} from "./_builder-cms-write-adapter.js";
|
|
22
23
|
import {
|
|
23
24
|
findOpenSourceChangeSet,
|
|
24
|
-
|
|
25
|
-
getExistingSource,
|
|
25
|
+
getContentDatabaseSourceSnapshotForWrite,
|
|
26
26
|
resolveDatabaseForSourceMutation,
|
|
27
27
|
sourceChangeSetKey,
|
|
28
28
|
} from "./_database-source-utils.js";
|
|
@@ -103,6 +103,10 @@ export function buildBuilderSourceReviewPayload(args: {
|
|
|
103
103
|
riskLevel: changeSet.riskLevel,
|
|
104
104
|
riskReasons: changeSet.riskReasons,
|
|
105
105
|
conflictState: changeSet.conflictState,
|
|
106
|
+
effect: resolveBuilderCmsWriteEffect({
|
|
107
|
+
source: args.source,
|
|
108
|
+
changeSet,
|
|
109
|
+
}),
|
|
106
110
|
execution: latestExecution,
|
|
107
111
|
};
|
|
108
112
|
});
|
|
@@ -270,6 +274,8 @@ async function upsertExecutionGate(args: {
|
|
|
270
274
|
source: ContentDatabaseSource;
|
|
271
275
|
changeSet: ContentDatabaseSourceChangeSet;
|
|
272
276
|
pushModeConfirmation?: ContentDatabaseSourcePushMode;
|
|
277
|
+
publicationTransition?: PrepareBuilderSourceReviewRequest["publicationTransition"];
|
|
278
|
+
confirmUnpublish?: boolean;
|
|
273
279
|
ownerEmail: string;
|
|
274
280
|
now: string;
|
|
275
281
|
}) {
|
|
@@ -277,6 +283,8 @@ async function upsertExecutionGate(args: {
|
|
|
277
283
|
source: args.source,
|
|
278
284
|
changeSet: args.changeSet,
|
|
279
285
|
pushModeConfirmation: args.pushModeConfirmation,
|
|
286
|
+
publicationTransition: args.publicationTransition,
|
|
287
|
+
confirmUnpublish: args.confirmUnpublish,
|
|
280
288
|
});
|
|
281
289
|
const db = getDb();
|
|
282
290
|
const [existing] = await db
|
|
@@ -360,10 +368,22 @@ export default defineAction({
|
|
|
360
368
|
schema: z.object({
|
|
361
369
|
databaseId: z.string().optional().describe("Database ID"),
|
|
362
370
|
documentId: z.string().optional().describe("Database document/page ID"),
|
|
371
|
+
sourceId: z
|
|
372
|
+
.string()
|
|
373
|
+
.optional()
|
|
374
|
+
.describe("Target source ID (defaults to the primary source)"),
|
|
363
375
|
pushModeConfirmation: z
|
|
364
376
|
.enum(["autosave", "draft", "publish"])
|
|
365
377
|
.optional()
|
|
366
378
|
.describe("Explicit push mode confirmation for the planned write"),
|
|
379
|
+
publicationTransition: z
|
|
380
|
+
.enum(["publish", "unpublish"])
|
|
381
|
+
.optional()
|
|
382
|
+
.describe("Explicit publication transition to validate at write time"),
|
|
383
|
+
confirmUnpublish: z
|
|
384
|
+
.boolean()
|
|
385
|
+
.optional()
|
|
386
|
+
.describe("Required explicit confirmation for unpublish transitions"),
|
|
367
387
|
}),
|
|
368
388
|
run: async (
|
|
369
389
|
args: PrepareBuilderSourceReviewRequest,
|
|
@@ -372,13 +392,13 @@ export default defineAction({
|
|
|
372
392
|
if (!database) throw new Error("Database not found.");
|
|
373
393
|
await assertAccess("document", database.documentId, "editor");
|
|
374
394
|
|
|
375
|
-
const
|
|
376
|
-
|
|
395
|
+
const snapshot = await getContentDatabaseSourceSnapshotForWrite(
|
|
396
|
+
database,
|
|
397
|
+
args.sourceId,
|
|
398
|
+
);
|
|
399
|
+
if (!snapshot || snapshot.sourceType !== "builder-cms") {
|
|
377
400
|
throw new Error("Attach a Builder CMS source before reviewing updates.");
|
|
378
401
|
}
|
|
379
|
-
|
|
380
|
-
const snapshot = await getContentDatabaseSourceSnapshot(database);
|
|
381
|
-
if (!snapshot) throw new Error("Attach a source before reviewing updates.");
|
|
382
402
|
const reviewableChanges = snapshot.changeSets.filter(
|
|
383
403
|
(changeSet) =>
|
|
384
404
|
changeSet.direction === "outbound" &&
|
|
@@ -397,7 +417,7 @@ export default defineAction({
|
|
|
397
417
|
for (const changeSet of reviewableChanges) {
|
|
398
418
|
approvedIds.push(
|
|
399
419
|
await approveChangeSetForReview({
|
|
400
|
-
sourceId:
|
|
420
|
+
sourceId: snapshot.id,
|
|
401
421
|
ownerEmail: database.ownerEmail,
|
|
402
422
|
changeSet,
|
|
403
423
|
reviewerEmail,
|
|
@@ -406,7 +426,10 @@ export default defineAction({
|
|
|
406
426
|
);
|
|
407
427
|
}
|
|
408
428
|
|
|
409
|
-
const approvedSnapshot = await
|
|
429
|
+
const approvedSnapshot = await getContentDatabaseSourceSnapshotForWrite(
|
|
430
|
+
database,
|
|
431
|
+
args.sourceId,
|
|
432
|
+
);
|
|
410
433
|
if (!approvedSnapshot) throw new Error("Builder source disappeared.");
|
|
411
434
|
const approvedChangeSets = approvedSnapshot.changeSets.filter(
|
|
412
435
|
(changeSet) =>
|
|
@@ -417,6 +440,8 @@ export default defineAction({
|
|
|
417
440
|
source: approvedSnapshot,
|
|
418
441
|
changeSet,
|
|
419
442
|
pushModeConfirmation: args.pushModeConfirmation,
|
|
443
|
+
publicationTransition: args.publicationTransition,
|
|
444
|
+
confirmUnpublish: args.confirmUnpublish,
|
|
420
445
|
ownerEmail: database.ownerEmail,
|
|
421
446
|
now,
|
|
422
447
|
});
|
|
@@ -425,19 +450,26 @@ export default defineAction({
|
|
|
425
450
|
await getDb()
|
|
426
451
|
.update(schema.contentDatabaseSources)
|
|
427
452
|
.set({ updatedAt: now })
|
|
428
|
-
.where(eq(schema.contentDatabaseSources.id,
|
|
453
|
+
.where(eq(schema.contentDatabaseSources.id, snapshot.id));
|
|
429
454
|
|
|
430
|
-
const
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
455
|
+
const reviewedSnapshot = await getContentDatabaseSourceSnapshotForWrite(
|
|
456
|
+
database,
|
|
457
|
+
args.sourceId,
|
|
458
|
+
);
|
|
459
|
+
if (!reviewedSnapshot) throw new Error("Builder source disappeared.");
|
|
460
|
+
// Build the review payload from the TARGET source snapshot, not
|
|
461
|
+
// response.source (which is always the primary). Re-read after the gate
|
|
462
|
+
// upsert so newly validated/blocked/stale execution rows are visible to
|
|
463
|
+
// the returned review payload.
|
|
464
|
+
const reviewedChangeSets = reviewedSnapshot.changeSets.filter((changeSet) =>
|
|
434
465
|
approvedIds.includes(changeSet.id),
|
|
435
466
|
);
|
|
467
|
+
const response = await getContentDatabaseResponse(database.id);
|
|
436
468
|
|
|
437
469
|
return {
|
|
438
470
|
...response,
|
|
439
471
|
review: buildBuilderSourceReviewPayload({
|
|
440
|
-
source,
|
|
472
|
+
source: reviewedSnapshot,
|
|
441
473
|
changeSets: reviewedChangeSets,
|
|
442
474
|
}),
|
|
443
475
|
};
|
|
@@ -4,8 +4,8 @@ import { z } from "zod";
|
|
|
4
4
|
|
|
5
5
|
import type { ContentDatabaseSourceStatusResponse } from "../shared/api.js";
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
getContentDatabaseSourceSnapshotForWrite,
|
|
8
|
+
getExistingSourceForWrite,
|
|
9
9
|
resyncBuilderCmsSourceSnapshot,
|
|
10
10
|
resyncMockSourceSnapshot,
|
|
11
11
|
resolveDatabaseForSourceMutation,
|
|
@@ -18,13 +18,17 @@ export default defineAction({
|
|
|
18
18
|
schema: z.object({
|
|
19
19
|
databaseId: z.string().optional().describe("Database ID"),
|
|
20
20
|
documentId: z.string().optional().describe("Database document/page ID"),
|
|
21
|
+
sourceId: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("Target source ID (defaults to the primary source)"),
|
|
21
25
|
}),
|
|
22
26
|
run: async (args): Promise<ContentDatabaseSourceStatusResponse> => {
|
|
23
27
|
const database = await resolveDatabaseForSourceMutation(args);
|
|
24
28
|
if (!database) throw new Error("Database not found.");
|
|
25
29
|
await assertAccess("document", database.documentId, "editor");
|
|
26
30
|
|
|
27
|
-
const source = await
|
|
31
|
+
const source = await getExistingSourceForWrite(database.id, args.sourceId);
|
|
28
32
|
if (!source) {
|
|
29
33
|
return {
|
|
30
34
|
database: serializeDatabase(database),
|
|
@@ -45,7 +49,10 @@ export default defineAction({
|
|
|
45
49
|
} else {
|
|
46
50
|
throw new Error(`Unsupported source type "${source.sourceType}".`);
|
|
47
51
|
}
|
|
48
|
-
const snapshot = await
|
|
52
|
+
const snapshot = await getContentDatabaseSourceSnapshotForWrite(
|
|
53
|
+
database,
|
|
54
|
+
args.sourceId,
|
|
55
|
+
);
|
|
49
56
|
|
|
50
57
|
return {
|
|
51
58
|
database: serializeDatabase(database),
|
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
ReviewContentDatabaseSourceChangeSetRequest,
|
|
11
11
|
} from "../shared/api.js";
|
|
12
12
|
import {
|
|
13
|
-
|
|
13
|
+
getExistingSourceForWrite,
|
|
14
14
|
resolveDatabaseForSourceMutation,
|
|
15
15
|
} from "./_database-source-utils.js";
|
|
16
16
|
import { getContentDatabaseResponse } from "./_database-utils.js";
|
|
@@ -28,6 +28,10 @@ export default defineAction({
|
|
|
28
28
|
schema: z.object({
|
|
29
29
|
databaseId: z.string().optional().describe("Database ID"),
|
|
30
30
|
documentId: z.string().optional().describe("Database document/page ID"),
|
|
31
|
+
sourceId: z
|
|
32
|
+
.string()
|
|
33
|
+
.optional()
|
|
34
|
+
.describe("Target source ID (defaults to the primary source)"),
|
|
31
35
|
changeSetId: z.string().describe("Source change-set ID"),
|
|
32
36
|
decision: z
|
|
33
37
|
.enum(["approve", "reject"])
|
|
@@ -41,7 +45,7 @@ export default defineAction({
|
|
|
41
45
|
if (!database) throw new Error("Database not found.");
|
|
42
46
|
await assertAccess("document", database.documentId, "editor");
|
|
43
47
|
|
|
44
|
-
const source = await
|
|
48
|
+
const source = await getExistingSourceForWrite(database.id, args.sourceId);
|
|
45
49
|
if (!source) throw new Error("Attach a source before reviewing changes.");
|
|
46
50
|
|
|
47
51
|
const [changeSet] = await getDb()
|
|
@@ -1,22 +1,31 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
2
|
import { assertAccess } from "@agent-native/core/sharing";
|
|
3
|
-
import {
|
|
3
|
+
import { eq } from "drizzle-orm";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
6
6
|
import { getDb, schema } from "../server/db/index.js";
|
|
7
7
|
import {
|
|
8
8
|
type ContentDatabaseResponse,
|
|
9
9
|
type ContentDatabaseSourcePushMode,
|
|
10
|
+
type ContentDatabaseSourceWriteMode,
|
|
10
11
|
type SetContentDatabaseSourceWriteModeRequest,
|
|
11
12
|
} from "../shared/api.js";
|
|
12
13
|
import {
|
|
13
14
|
buildBuilderCmsWriteModeJson,
|
|
14
15
|
type BuilderCmsLiveWriteMode,
|
|
15
16
|
} from "./_builder-cms-write-settings.js";
|
|
16
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
getExistingSourceForWrite,
|
|
19
|
+
resolveDatabaseForSourceMutation,
|
|
20
|
+
} from "./_database-source-utils.js";
|
|
17
21
|
import { getContentDatabaseResponse } from "./_database-utils.js";
|
|
18
22
|
|
|
19
|
-
const
|
|
23
|
+
const legacyWriteModeSchema = z.enum(["autosave", "draft", "publish"]);
|
|
24
|
+
const sourceWriteModeSchema = z.enum([
|
|
25
|
+
"read_only",
|
|
26
|
+
"stage_only",
|
|
27
|
+
"publish_updates",
|
|
28
|
+
]);
|
|
20
29
|
|
|
21
30
|
function executableWriteModes(
|
|
22
31
|
modes: readonly ContentDatabaseSourcePushMode[] | undefined,
|
|
@@ -29,17 +38,31 @@ function executableWriteModes(
|
|
|
29
38
|
|
|
30
39
|
export default defineAction({
|
|
31
40
|
description:
|
|
32
|
-
"
|
|
41
|
+
"Set the tiered Builder CMS write mode for one source. Writes stay off by default and can only be enabled for the safe Builder test collection.",
|
|
33
42
|
schema: z.object({
|
|
34
43
|
databaseId: z.string().optional().describe("Database ID"),
|
|
35
44
|
documentId: z.string().optional().describe("Database document/page ID"),
|
|
45
|
+
sourceId: z
|
|
46
|
+
.string()
|
|
47
|
+
.optional()
|
|
48
|
+
.describe("Target source ID (defaults to the primary source)"),
|
|
36
49
|
liveWritesEnabled: z
|
|
37
50
|
.boolean()
|
|
51
|
+
.optional()
|
|
38
52
|
.describe("Whether this source may execute guarded live Builder writes"),
|
|
53
|
+
writeMode: sourceWriteModeSchema
|
|
54
|
+
.optional()
|
|
55
|
+
.describe("Tiered Builder write mode for this source"),
|
|
56
|
+
allowPublicationTransitions: z
|
|
57
|
+
.boolean()
|
|
58
|
+
.optional()
|
|
59
|
+
.describe(
|
|
60
|
+
"Allow explicit per-item publish/unpublish transitions in publish updates mode",
|
|
61
|
+
),
|
|
39
62
|
allowedWriteModes: z
|
|
40
|
-
.array(
|
|
63
|
+
.array(legacyWriteModeSchema)
|
|
41
64
|
.optional()
|
|
42
|
-
.describe("
|
|
65
|
+
.describe("Legacy Builder write modes allowed for this source"),
|
|
43
66
|
allowDraftWrites: z
|
|
44
67
|
.boolean()
|
|
45
68
|
.optional()
|
|
@@ -59,12 +82,7 @@ export default defineAction({
|
|
|
59
82
|
await assertAccess("document", database.documentId, "editor");
|
|
60
83
|
|
|
61
84
|
const db = getDb();
|
|
62
|
-
const
|
|
63
|
-
.select()
|
|
64
|
-
.from(schema.contentDatabaseSources)
|
|
65
|
-
.where(eq(schema.contentDatabaseSources.databaseId, database.id))
|
|
66
|
-
.orderBy(asc(schema.contentDatabaseSources.createdAt))
|
|
67
|
-
.limit(1);
|
|
85
|
+
const source = await getExistingSourceForWrite(database.id, args.sourceId);
|
|
68
86
|
if (!source) {
|
|
69
87
|
throw new Error(
|
|
70
88
|
"Attach a Builder CMS source before changing write mode.",
|
|
@@ -82,6 +100,8 @@ export default defineAction({
|
|
|
82
100
|
capabilitiesJson: source.capabilitiesJson,
|
|
83
101
|
metadataJson: source.metadataJson,
|
|
84
102
|
liveWritesEnabled: args.liveWritesEnabled,
|
|
103
|
+
writeMode: args.writeMode as ContentDatabaseSourceWriteMode | undefined,
|
|
104
|
+
allowPublicationTransitions: args.allowPublicationTransitions,
|
|
85
105
|
allowedWriteModes: executableWriteModes(args.allowedWriteModes),
|
|
86
106
|
allowDraftWrites: args.allowDraftWrites,
|
|
87
107
|
allowPublishWrites: args.allowPublishWrites,
|
|
@@ -7,8 +7,7 @@ import { getDb, schema } from "../server/db/index.js";
|
|
|
7
7
|
import type { ContentDatabaseResponse } from "../shared/api.js";
|
|
8
8
|
import {
|
|
9
9
|
findOpenSourceChangeSet,
|
|
10
|
-
|
|
11
|
-
getExistingSource,
|
|
10
|
+
getContentDatabaseSourceSnapshotForWrite,
|
|
12
11
|
resolveDatabaseForSourceMutation,
|
|
13
12
|
sourceChangeSetKey,
|
|
14
13
|
} from "./_database-source-utils.js";
|
|
@@ -20,24 +19,29 @@ export default defineAction({
|
|
|
20
19
|
schema: z.object({
|
|
21
20
|
databaseId: z.string().optional().describe("Database ID"),
|
|
22
21
|
documentId: z.string().optional().describe("Database document/page ID"),
|
|
22
|
+
sourceId: z
|
|
23
|
+
.string()
|
|
24
|
+
.optional()
|
|
25
|
+
.describe("Target source ID (defaults to the primary source)"),
|
|
23
26
|
}),
|
|
24
27
|
run: async (args): Promise<ContentDatabaseResponse> => {
|
|
25
28
|
const database = await resolveDatabaseForSourceMutation(args);
|
|
26
29
|
if (!database) throw new Error("Database not found.");
|
|
27
30
|
await assertAccess("document", database.documentId, "editor");
|
|
28
31
|
|
|
29
|
-
const source = await
|
|
32
|
+
const source = await getContentDatabaseSourceSnapshotForWrite(
|
|
33
|
+
database,
|
|
34
|
+
args.sourceId,
|
|
35
|
+
);
|
|
30
36
|
if (!source || source.sourceType !== "builder-cms") {
|
|
31
37
|
throw new Error("Attach a Builder CMS source before staging a revision.");
|
|
32
38
|
}
|
|
33
39
|
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
changeSet.state === "pending_push",
|
|
40
|
-
) ?? [];
|
|
40
|
+
const pendingOutboundChanges = source.changeSets.filter(
|
|
41
|
+
(changeSet) =>
|
|
42
|
+
changeSet.direction === "outbound" &&
|
|
43
|
+
changeSet.state === "pending_push",
|
|
44
|
+
);
|
|
41
45
|
|
|
42
46
|
if (pendingOutboundChanges.length === 0) {
|
|
43
47
|
throw new Error("No pending local Builder changes to stage.");
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
validateBuilderCmsExecutionDryRun,
|
|
15
15
|
} from "./_builder-cms-write-adapter.js";
|
|
16
16
|
import {
|
|
17
|
-
|
|
17
|
+
getContentDatabaseSourceSnapshotForWrite,
|
|
18
18
|
resolveDatabaseForSourceMutation,
|
|
19
19
|
} from "./_database-source-utils.js";
|
|
20
20
|
import { getContentDatabaseResponse } from "./_database-utils.js";
|
|
@@ -36,11 +36,27 @@ export default defineAction({
|
|
|
36
36
|
schema: z.object({
|
|
37
37
|
databaseId: z.string().optional().describe("Database ID"),
|
|
38
38
|
documentId: z.string().optional().describe("Database document/page ID"),
|
|
39
|
+
sourceId: z
|
|
40
|
+
.string()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe("Target source ID (defaults to the primary source)"),
|
|
39
43
|
changeSetId: z.string().describe("Approved source change-set ID"),
|
|
40
44
|
idempotencyKey: z
|
|
41
45
|
.string()
|
|
42
46
|
.optional()
|
|
43
47
|
.describe("Optional execution idempotency key to validate"),
|
|
48
|
+
pushModeConfirmation: z
|
|
49
|
+
.enum(["autosave", "draft", "publish"])
|
|
50
|
+
.optional()
|
|
51
|
+
.describe("Explicit push mode confirmation for the validated write"),
|
|
52
|
+
publicationTransition: z
|
|
53
|
+
.enum(["publish", "unpublish"])
|
|
54
|
+
.optional()
|
|
55
|
+
.describe("Explicit publication transition to validate at write time"),
|
|
56
|
+
confirmUnpublish: z
|
|
57
|
+
.boolean()
|
|
58
|
+
.optional()
|
|
59
|
+
.describe("Required explicit confirmation for unpublish transitions"),
|
|
44
60
|
}),
|
|
45
61
|
run: async (
|
|
46
62
|
args: ValidateBuilderSourceExecutionRequest,
|
|
@@ -49,7 +65,10 @@ export default defineAction({
|
|
|
49
65
|
if (!database) throw new Error("Database not found.");
|
|
50
66
|
await assertAccess("document", database.documentId, "editor");
|
|
51
67
|
|
|
52
|
-
const source = await
|
|
68
|
+
const source = await getContentDatabaseSourceSnapshotForWrite(
|
|
69
|
+
database,
|
|
70
|
+
args.sourceId,
|
|
71
|
+
);
|
|
53
72
|
if (!source || source.sourceType !== "builder-cms") {
|
|
54
73
|
throw new Error(
|
|
55
74
|
"Attach a Builder CMS source before validating execution.",
|
|
@@ -64,7 +83,10 @@ export default defineAction({
|
|
|
64
83
|
const plan = buildBuilderCmsExecutionPlan({
|
|
65
84
|
source,
|
|
66
85
|
changeSet,
|
|
67
|
-
pushModeConfirmation:
|
|
86
|
+
pushModeConfirmation:
|
|
87
|
+
args.pushModeConfirmation ?? changeSet.pushMode ?? undefined,
|
|
88
|
+
publicationTransition: args.publicationTransition,
|
|
89
|
+
confirmUnpublish: args.confirmUnpublish,
|
|
68
90
|
});
|
|
69
91
|
const expectedKey = builderCmsExecutionIdempotencyKey({
|
|
70
92
|
sourceId: source.id,
|
|
@@ -26,6 +26,8 @@ import {
|
|
|
26
26
|
} from "@tabler/icons-react";
|
|
27
27
|
import { useState } from "react";
|
|
28
28
|
|
|
29
|
+
import { ContentReferencePreview } from "@/components/editor/ContentReferencePreview";
|
|
30
|
+
|
|
29
31
|
function SidecarBadge({ rawRef }: { rawRef: string }) {
|
|
30
32
|
return (
|
|
31
33
|
<div className="mt-2 truncate text-[11px] text-muted-foreground">
|
|
@@ -180,7 +182,15 @@ export function BuilderSymbolRead({
|
|
|
180
182
|
</div>
|
|
181
183
|
<div className="mt-1 text-xs text-muted-foreground">
|
|
182
184
|
{data.model || "model unknown"} / {data.entry || "entry unknown"}
|
|
185
|
+
{data.dynamic ? " / dynamic" : ""}
|
|
183
186
|
</div>
|
|
187
|
+
{data.source ? (
|
|
188
|
+
<ContentReferencePreview
|
|
189
|
+
sourcePath={data.source}
|
|
190
|
+
title="Symbol source"
|
|
191
|
+
className="mb-0"
|
|
192
|
+
/>
|
|
193
|
+
) : null}
|
|
184
194
|
<SidecarBadge rawRef={data.rawRef} />
|
|
185
195
|
</section>
|
|
186
196
|
);
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { useT } from "@agent-native/core/client";
|
|
2
|
+
import { IconExternalLink, IconFileText } from "@tabler/icons-react";
|
|
3
|
+
import { lazy, Suspense, useMemo } from "react";
|
|
4
|
+
import { useNavigate } from "react-router";
|
|
5
|
+
|
|
6
|
+
import { Button } from "@/components/ui/button";
|
|
7
|
+
import { useDocument, useDocuments } from "@/hooks/use-documents";
|
|
8
|
+
import { cn } from "@/lib/utils";
|
|
9
|
+
|
|
10
|
+
const ReadonlyReferenceEditor = lazy(async () => {
|
|
11
|
+
const module = await import("./VisualEditor");
|
|
12
|
+
return { default: module.VisualEditor };
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const MAX_CONTENT_REFERENCE_PREVIEW_DEPTH = 1;
|
|
16
|
+
|
|
17
|
+
function trimSlashes(path: string) {
|
|
18
|
+
return path.replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/+$/, "");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function dirname(path: string) {
|
|
22
|
+
const normalized = trimSlashes(path);
|
|
23
|
+
const index = normalized.lastIndexOf("/");
|
|
24
|
+
return index >= 0 ? normalized.slice(0, index) : "";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function normalizePathParts(path: string) {
|
|
28
|
+
const parts: string[] = [];
|
|
29
|
+
for (const part of path.split("/")) {
|
|
30
|
+
if (!part || part === ".") continue;
|
|
31
|
+
if (part === "..") {
|
|
32
|
+
if (parts.length === 0) return null;
|
|
33
|
+
parts.pop();
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
parts.push(part);
|
|
37
|
+
}
|
|
38
|
+
return parts.join("/");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function resolveContentReferencePath(
|
|
42
|
+
sourcePath: string | null | undefined,
|
|
43
|
+
currentPath?: string | null,
|
|
44
|
+
) {
|
|
45
|
+
if (typeof sourcePath !== "string" || !sourcePath.trim()) return null;
|
|
46
|
+
const normalized = sourcePath.replace(/\\/g, "/").trim();
|
|
47
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(normalized)) return null;
|
|
48
|
+
const base =
|
|
49
|
+
normalized.startsWith("./") || normalized.startsWith("../")
|
|
50
|
+
? dirname(currentPath ?? "")
|
|
51
|
+
: "";
|
|
52
|
+
return normalizePathParts(base ? `${base}/${normalized}` : normalized);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function ContentReferencePreview({
|
|
56
|
+
sourcePath,
|
|
57
|
+
currentPath,
|
|
58
|
+
title,
|
|
59
|
+
className,
|
|
60
|
+
referenceDepth = 0,
|
|
61
|
+
}: {
|
|
62
|
+
sourcePath?: string | null;
|
|
63
|
+
currentPath?: string | null;
|
|
64
|
+
title?: string | null;
|
|
65
|
+
className?: string;
|
|
66
|
+
referenceDepth?: number;
|
|
67
|
+
}) {
|
|
68
|
+
const t = useT();
|
|
69
|
+
const navigate = useNavigate();
|
|
70
|
+
const documentsQuery = useDocuments();
|
|
71
|
+
const resolvedPath = useMemo(
|
|
72
|
+
() => resolveContentReferencePath(sourcePath, currentPath),
|
|
73
|
+
[currentPath, sourcePath],
|
|
74
|
+
);
|
|
75
|
+
const document = useMemo(() => {
|
|
76
|
+
if (!resolvedPath) return null;
|
|
77
|
+
return (documentsQuery.data ?? []).find(
|
|
78
|
+
(candidate) =>
|
|
79
|
+
candidate.source?.mode === "local-files" &&
|
|
80
|
+
trimSlashes(candidate.source.path ?? "") === resolvedPath,
|
|
81
|
+
);
|
|
82
|
+
}, [documentsQuery.data, resolvedPath]);
|
|
83
|
+
const documentQuery = useDocument(document?.id ?? null);
|
|
84
|
+
const body = documentQuery.data?.content ?? "";
|
|
85
|
+
const displayTitle =
|
|
86
|
+
title?.trim() ||
|
|
87
|
+
documentQuery.data?.title ||
|
|
88
|
+
document?.title ||
|
|
89
|
+
t("editor.reference.defaultTitle");
|
|
90
|
+
const isSelfReference =
|
|
91
|
+
!!resolvedPath &&
|
|
92
|
+
!!currentPath &&
|
|
93
|
+
resolvedPath === trimSlashes(currentPath);
|
|
94
|
+
const isNestedTooDeep = referenceDepth >= MAX_CONTENT_REFERENCE_PREVIEW_DEPTH;
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<section
|
|
98
|
+
className={cn(
|
|
99
|
+
"content-reference-preview my-4 rounded-md border border-dashed bg-muted/20 text-sm",
|
|
100
|
+
className,
|
|
101
|
+
)}
|
|
102
|
+
data-content-reference={resolvedPath ?? sourcePath ?? ""}
|
|
103
|
+
>
|
|
104
|
+
<div className="flex min-h-10 items-center gap-2 border-b px-3 py-2">
|
|
105
|
+
<IconFileText className="size-4 shrink-0 text-muted-foreground" />
|
|
106
|
+
<div className="min-w-0 flex-1">
|
|
107
|
+
<div className="truncate font-medium text-foreground">
|
|
108
|
+
{displayTitle}
|
|
109
|
+
</div>
|
|
110
|
+
<div className="truncate text-xs text-muted-foreground">
|
|
111
|
+
{resolvedPath ?? sourcePath ?? t("editor.reference.pathMissing")}
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
{document ? (
|
|
115
|
+
<Button
|
|
116
|
+
type="button"
|
|
117
|
+
size="sm"
|
|
118
|
+
variant="ghost"
|
|
119
|
+
className="h-8 gap-1.5 px-2 text-xs"
|
|
120
|
+
onClick={() =>
|
|
121
|
+
navigate(`/page/${document.id}`, { flushSync: true })
|
|
122
|
+
}
|
|
123
|
+
>
|
|
124
|
+
<IconExternalLink className="size-3.5" />
|
|
125
|
+
{t("editor.reference.open")}
|
|
126
|
+
</Button>
|
|
127
|
+
) : null}
|
|
128
|
+
</div>
|
|
129
|
+
<div className="max-h-[520px] overflow-auto px-3 py-3">
|
|
130
|
+
{!resolvedPath ? (
|
|
131
|
+
<div className="text-sm text-muted-foreground">
|
|
132
|
+
{t("editor.reference.missingPath")}
|
|
133
|
+
</div>
|
|
134
|
+
) : isSelfReference ? (
|
|
135
|
+
<div className="text-sm text-muted-foreground">
|
|
136
|
+
{t("editor.reference.selfReference")}
|
|
137
|
+
</div>
|
|
138
|
+
) : documentsQuery.isLoading ? (
|
|
139
|
+
<div className="text-sm text-muted-foreground">
|
|
140
|
+
{t("editor.reference.loading")}
|
|
141
|
+
</div>
|
|
142
|
+
) : !document ? (
|
|
143
|
+
<div className="text-sm text-muted-foreground">
|
|
144
|
+
{t("editor.reference.notFound")}
|
|
145
|
+
</div>
|
|
146
|
+
) : documentQuery.isLoading ? (
|
|
147
|
+
<div className="text-sm text-muted-foreground">
|
|
148
|
+
{t("editor.reference.loading")}
|
|
149
|
+
</div>
|
|
150
|
+
) : documentQuery.isError ? (
|
|
151
|
+
<div className="text-sm text-muted-foreground">
|
|
152
|
+
{t("editor.reference.loadError")}
|
|
153
|
+
</div>
|
|
154
|
+
) : isNestedTooDeep ? (
|
|
155
|
+
<div className="text-sm text-muted-foreground">
|
|
156
|
+
{t("editor.reference.nestedSkipped")}
|
|
157
|
+
</div>
|
|
158
|
+
) : body.trim() ? (
|
|
159
|
+
<Suspense
|
|
160
|
+
fallback={
|
|
161
|
+
<div className="text-sm text-muted-foreground">
|
|
162
|
+
{t("editor.reference.loading")}
|
|
163
|
+
</div>
|
|
164
|
+
}
|
|
165
|
+
>
|
|
166
|
+
<ReadonlyReferenceEditor
|
|
167
|
+
key={document.id}
|
|
168
|
+
documentId={document.id}
|
|
169
|
+
content={body}
|
|
170
|
+
onChange={() => {}}
|
|
171
|
+
editable={false}
|
|
172
|
+
localFileMode
|
|
173
|
+
localFilePath={resolvedPath}
|
|
174
|
+
referenceDepth={referenceDepth + 1}
|
|
175
|
+
/>
|
|
176
|
+
</Suspense>
|
|
177
|
+
) : (
|
|
178
|
+
<div className="text-sm text-muted-foreground">
|
|
179
|
+
{t("editor.reference.empty")}
|
|
180
|
+
</div>
|
|
181
|
+
)}
|
|
182
|
+
</div>
|
|
183
|
+
</section>
|
|
184
|
+
);
|
|
185
|
+
}
|