@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
|
@@ -47,7 +47,7 @@ export interface ShareButtonProps {
|
|
|
47
47
|
variant?: "compact" | "label";
|
|
48
48
|
/** Optional trigger style. Defaults to the Google-Docs-style "Share" label. */
|
|
49
49
|
trigger?: "label" | "icon";
|
|
50
|
-
/**
|
|
50
|
+
/** @deprecated Label triggers no longer render a visibility/share glyph. */
|
|
51
51
|
hideTriggerIcon?: boolean;
|
|
52
52
|
/** Optional className applied to the trigger button. */
|
|
53
53
|
triggerClassName?: string;
|
|
@@ -298,23 +298,8 @@ export function ShareButton(props: ShareButtonProps) {
|
|
|
298
298
|
});
|
|
299
299
|
};
|
|
300
300
|
|
|
301
|
-
// The default trigger
|
|
302
|
-
// current visibility (lock / building / globe), matching Google Docs.
|
|
303
|
-
// While the query is loading and we don't know the visibility yet,
|
|
304
|
-
// render a skeleton placeholder in the icon slot instead of guessing.
|
|
301
|
+
// The default trigger stays text-only; the icon trigger keeps the share glyph.
|
|
305
302
|
const iconOnly = props.trigger === "icon";
|
|
306
|
-
const loaded = sharesQuery.data !== undefined;
|
|
307
|
-
const serverVisibility =
|
|
308
|
-
(sharesQuery.data?.visibility as Visibility | null) ?? "private";
|
|
309
|
-
const currentVisibility = pendingVisibility ?? serverVisibility;
|
|
310
|
-
const VisibilityIcon =
|
|
311
|
-
currentVisibility === "public"
|
|
312
|
-
? IconWorld
|
|
313
|
-
: currentVisibility === "org"
|
|
314
|
-
? IconBuilding
|
|
315
|
-
: IconLock;
|
|
316
|
-
const showTriggerIcon = iconOnly || !props.hideTriggerIcon;
|
|
317
|
-
const TriggerIcon = iconOnly ? IconShare3 : VisibilityIcon;
|
|
318
303
|
|
|
319
304
|
return (
|
|
320
305
|
<Popover open={open} onOpenChange={handleOpenChange}>
|
|
@@ -327,16 +312,7 @@ export function ShareButton(props: ShareButtonProps) {
|
|
|
327
312
|
)}
|
|
328
313
|
aria-label={iconOnly ? "Share" : undefined}
|
|
329
314
|
>
|
|
330
|
-
{
|
|
331
|
-
loaded || iconOnly ? (
|
|
332
|
-
<TriggerIcon size={16} strokeWidth={1.75} />
|
|
333
|
-
) : (
|
|
334
|
-
<span
|
|
335
|
-
aria-hidden
|
|
336
|
-
className="inline-block h-4 w-4 rounded-sm bg-muted animate-pulse"
|
|
337
|
-
/>
|
|
338
|
-
)
|
|
339
|
-
) : null}
|
|
315
|
+
{iconOnly ? <IconShare3 size={16} strokeWidth={1.75} /> : null}
|
|
340
316
|
{!iconOnly && <span>Share</span>}
|
|
341
317
|
</button>
|
|
342
318
|
</PopoverTrigger>
|
|
@@ -639,6 +639,20 @@ function renderConnectPage(params: {
|
|
|
639
639
|
}
|
|
640
640
|
.primary:hover:not(:disabled) { background: #e4e4e7; }
|
|
641
641
|
.primary:disabled { opacity: 0.55; cursor: default; }
|
|
642
|
+
.primary.is-loading {
|
|
643
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
644
|
+
gap: 0.55rem; opacity: 1;
|
|
645
|
+
}
|
|
646
|
+
.primary.is-loading::before {
|
|
647
|
+
content: ""; width: 1rem; height: 1rem; flex: 0 0 auto;
|
|
648
|
+
border-radius: 999px; border: 2px solid rgba(0,0,0,0.22);
|
|
649
|
+
border-top-color: var(--accent-fg);
|
|
650
|
+
animation: spin 0.75s linear infinite;
|
|
651
|
+
}
|
|
652
|
+
@keyframes spin { to { transform: rotate(360deg); } }
|
|
653
|
+
@media (prefers-reduced-motion: reduce) {
|
|
654
|
+
.primary.is-loading::before { animation: none; }
|
|
655
|
+
}
|
|
642
656
|
.ghost {
|
|
643
657
|
background: transparent; color: var(--muted);
|
|
644
658
|
border: 1px solid var(--border-strong); padding: 0.35rem 0.7rem;
|
|
@@ -900,7 +914,7 @@ function renderConnectPage(params: {
|
|
|
900
914
|
<span class="chev" aria-hidden="true"></span>
|
|
901
915
|
</summary>
|
|
902
916
|
<div class="static-token-body">
|
|
903
|
-
<div id="msg" class="msg"></div>
|
|
917
|
+
<div id="msg" class="msg" role="status" aria-live="polite"></div>
|
|
904
918
|
<div id="mintForm">
|
|
905
919
|
<button id="authorizeBtn" class="primary">${safeUserCode ? "Authorize device" : "Create connection token"}</button>
|
|
906
920
|
${tokenAdvancedOptionsHtml}
|
|
@@ -983,6 +997,21 @@ function renderConnectPage(params: {
|
|
|
983
997
|
}
|
|
984
998
|
function clearMsg() { msgEl.className = "msg"; msgEl.textContent = ""; }
|
|
985
999
|
|
|
1000
|
+
function setButtonLoading(btn, text) {
|
|
1001
|
+
if (!btn.dataset.idleText) btn.dataset.idleText = btn.textContent || "";
|
|
1002
|
+
btn.textContent = text;
|
|
1003
|
+
btn.classList.add("is-loading");
|
|
1004
|
+
btn.setAttribute("aria-busy", "true");
|
|
1005
|
+
btn.disabled = true;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
function resetButtonLoading(btn) {
|
|
1009
|
+
btn.disabled = false;
|
|
1010
|
+
btn.classList.remove("is-loading");
|
|
1011
|
+
btn.removeAttribute("aria-busy");
|
|
1012
|
+
if (btn.dataset.idleText) btn.textContent = btn.dataset.idleText;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
986
1015
|
function renderResult(data) {
|
|
987
1016
|
document.getElementById("mintForm").classList.add("hidden");
|
|
988
1017
|
var entry = {};
|
|
@@ -1060,13 +1089,13 @@ function renderConnectPage(params: {
|
|
|
1060
1089
|
|
|
1061
1090
|
document.getElementById("authorizeBtn").onclick = async function () {
|
|
1062
1091
|
var btn = this;
|
|
1063
|
-
btn
|
|
1092
|
+
setButtonLoading(btn, USER_CODE ? "Authorizing device..." : "Creating token...");
|
|
1064
1093
|
clearMsg();
|
|
1065
1094
|
try {
|
|
1066
1095
|
if (USER_CODE) {
|
|
1067
1096
|
var a = await postJson("/device/authorize", { user_code: USER_CODE });
|
|
1068
1097
|
if (!a.ok) {
|
|
1069
|
-
btn
|
|
1098
|
+
resetButtonLoading(btn);
|
|
1070
1099
|
showMsg((a.data && a.data.error) || "Could not authorize this device code.");
|
|
1071
1100
|
return;
|
|
1072
1101
|
}
|
|
@@ -1128,7 +1157,7 @@ function renderConnectPage(params: {
|
|
|
1128
1157
|
var ttlDays = ttlEl ? parseInt(ttlEl.value, 10) || undefined : undefined;
|
|
1129
1158
|
var m = await postJson("/token", { label: label, ttlDays: ttlDays });
|
|
1130
1159
|
if (!m.ok) {
|
|
1131
|
-
btn
|
|
1160
|
+
resetButtonLoading(btn);
|
|
1132
1161
|
showMsg((m.data && m.data.error) || "Could not create token.");
|
|
1133
1162
|
return;
|
|
1134
1163
|
}
|
|
@@ -1136,7 +1165,7 @@ function renderConnectPage(params: {
|
|
|
1136
1165
|
}
|
|
1137
1166
|
loadTokens();
|
|
1138
1167
|
} catch (e) {
|
|
1139
|
-
btn
|
|
1168
|
+
resetButtonLoading(btn);
|
|
1140
1169
|
showMsg("Network error. Please try again.");
|
|
1141
1170
|
}
|
|
1142
1171
|
};
|
|
@@ -216,6 +216,10 @@ function preserveActionFlags(entry: Record<string, any>): Partial<ActionEntry> {
|
|
|
216
216
|
) {
|
|
217
217
|
out.chatUI = entry.chatUI;
|
|
218
218
|
}
|
|
219
|
+
if (typeof entry.timeoutMs === "number") out.timeoutMs = entry.timeoutMs;
|
|
220
|
+
if (typeof entry.maxResultChars === "number") {
|
|
221
|
+
out.maxResultChars = entry.maxResultChars;
|
|
222
|
+
}
|
|
219
223
|
if (
|
|
220
224
|
typeof entry.needsApproval === "boolean" ||
|
|
221
225
|
typeof entry.needsApproval === "function"
|
|
@@ -36,6 +36,7 @@ import { DEFAULT_ANTHROPIC_MODEL } from "../agent/default-model.js";
|
|
|
36
36
|
import {
|
|
37
37
|
AGENT_CHAT_PROCESS_RUN_PATH,
|
|
38
38
|
extractProcessRunId,
|
|
39
|
+
isInBackgroundFunctionRuntime,
|
|
39
40
|
prepareProcessRunRequest,
|
|
40
41
|
} from "../agent/durable-background.js";
|
|
41
42
|
import {
|
|
@@ -2567,6 +2568,12 @@ export interface AgentChatPluginOptions {
|
|
|
2567
2568
|
* timeout. When reached, long runs continue through the hidden continuation
|
|
2568
2569
|
* path instead of surfacing a timeout warning. */
|
|
2569
2570
|
runSoftTimeoutMs?: number;
|
|
2571
|
+
/**
|
|
2572
|
+
* Opt this app into Netlify durable background-function agent-chat runs. This
|
|
2573
|
+
* gives hosted agent turns the 15-minute async-function budget when the app's
|
|
2574
|
+
* Netlify build also emits the background function.
|
|
2575
|
+
*/
|
|
2576
|
+
durableBackgroundRuns?: boolean;
|
|
2570
2577
|
/** Anthropic API key. Falls back to ANTHROPIC_API_KEY env var */
|
|
2571
2578
|
apiKey?: string;
|
|
2572
2579
|
/**
|
|
@@ -4837,6 +4844,11 @@ export function createAgentChatPlugin(
|
|
|
4837
4844
|
signal: controller.signal,
|
|
4838
4845
|
},
|
|
4839
4846
|
options?.runSoftTimeoutMs,
|
|
4847
|
+
{
|
|
4848
|
+
backgroundFunction:
|
|
4849
|
+
options?.durableBackgroundRuns === true &&
|
|
4850
|
+
isInBackgroundFunctionRuntime(),
|
|
4851
|
+
},
|
|
4840
4852
|
);
|
|
4841
4853
|
|
|
4842
4854
|
const { responseText, finalText } = assembleA2AFinalResponse(
|
|
@@ -5035,6 +5047,11 @@ export function createAgentChatPlugin(
|
|
|
5035
5047
|
signal: controller.signal,
|
|
5036
5048
|
},
|
|
5037
5049
|
options?.runSoftTimeoutMs,
|
|
5050
|
+
{
|
|
5051
|
+
backgroundFunction:
|
|
5052
|
+
options?.durableBackgroundRuns === true &&
|
|
5053
|
+
isInBackgroundFunctionRuntime(),
|
|
5054
|
+
},
|
|
5038
5055
|
);
|
|
5039
5056
|
|
|
5040
5057
|
return accumulatedText || "(no response)";
|
|
@@ -5712,6 +5729,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5712
5729
|
appId: options?.appId,
|
|
5713
5730
|
apiKey: options?.apiKey,
|
|
5714
5731
|
runSoftTimeoutMs: options?.runSoftTimeoutMs,
|
|
5732
|
+
durableBackgroundRuns: options?.durableBackgroundRuns,
|
|
5715
5733
|
finalResponseGuard: options?.finalResponseGuard,
|
|
5716
5734
|
prepareRequest: async (details) => {
|
|
5717
5735
|
// Stash the threadId on runCtx so systemPrompt can check isNewThread().
|
|
@@ -5802,6 +5820,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5802
5820
|
appId: options?.appId,
|
|
5803
5821
|
apiKey: options?.apiKey,
|
|
5804
5822
|
runSoftTimeoutMs: options?.runSoftTimeoutMs,
|
|
5823
|
+
durableBackgroundRuns: options?.durableBackgroundRuns,
|
|
5805
5824
|
finalResponseGuard: options?.finalResponseGuard,
|
|
5806
5825
|
prepareRequest: options?.prepareRequest,
|
|
5807
5826
|
skipFilesContext: true,
|
|
@@ -5932,6 +5951,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5932
5951
|
appId: options?.appId,
|
|
5933
5952
|
apiKey: options?.apiKey,
|
|
5934
5953
|
runSoftTimeoutMs: options?.runSoftTimeoutMs,
|
|
5954
|
+
durableBackgroundRuns: options?.durableBackgroundRuns,
|
|
5935
5955
|
finalResponseGuard: options?.finalResponseGuard,
|
|
5936
5956
|
prepareRequest: options?.prepareRequest,
|
|
5937
5957
|
skipFilesContext,
|
|
@@ -101,6 +101,22 @@ const REGISTRY_KEY = "__agentNativeShareableResources__";
|
|
|
101
101
|
type RegistryStore = Map<string, ShareableResourceRegistration>;
|
|
102
102
|
const globalRegistry: { [K in typeof REGISTRY_KEY]?: RegistryStore } =
|
|
103
103
|
globalThis as any;
|
|
104
|
+
|
|
105
|
+
function isTestRuntime(): boolean {
|
|
106
|
+
return (
|
|
107
|
+
process.env.NODE_ENV === "test" ||
|
|
108
|
+
process.env.VITEST === "true" ||
|
|
109
|
+
process.env.VITEST === "1"
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function registrationCameFromTestFile(): boolean {
|
|
114
|
+
const stack = new Error().stack ?? "";
|
|
115
|
+
return /[./\\](?:[^/\\]+[.-])(?:test|spec)\.[cm]?[jt]sx?(?::\d+)?(?::\d+)?/.test(
|
|
116
|
+
stack,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
104
120
|
function getRegistry(): RegistryStore {
|
|
105
121
|
let r = globalRegistry[REGISTRY_KEY];
|
|
106
122
|
if (!r) {
|
|
@@ -113,6 +129,7 @@ function getRegistry(): RegistryStore {
|
|
|
113
129
|
export function registerShareableResource(
|
|
114
130
|
entry: ShareableResourceRegistration,
|
|
115
131
|
): void {
|
|
132
|
+
if (!isTestRuntime() && registrationCameFromTestFile()) return;
|
|
116
133
|
getRegistry().set(entry.type, entry);
|
|
117
134
|
}
|
|
118
135
|
|
|
@@ -277,6 +277,14 @@ export function validateDashboardConfig(
|
|
|
277
277
|
if (typeof config.name !== "string" || config.name.trim().length === 0) {
|
|
278
278
|
return "config.name is required (non-empty string) — without it the dashboard renders as a blank row in the sidebar";
|
|
279
279
|
}
|
|
280
|
+
if (config.parentId !== undefined && config.parentId !== null) {
|
|
281
|
+
if (
|
|
282
|
+
typeof config.parentId !== "string" ||
|
|
283
|
+
config.parentId.trim().length === 0
|
|
284
|
+
) {
|
|
285
|
+
return "config.parentId must be a non-empty dashboard id (or omitted) — it nests this dashboard under that parent in the sidebar";
|
|
286
|
+
}
|
|
287
|
+
}
|
|
280
288
|
// Filter ID collisions cause two controls to read/write the same URL param.
|
|
281
289
|
// For paired start/end dates use a single date-range filter — the FilterBar
|
|
282
290
|
// expands it to <id>Start / <id>End at runtime, so the SQL can still
|
|
@@ -30,7 +30,14 @@ import {
|
|
|
30
30
|
type QueryKey,
|
|
31
31
|
} from "@tanstack/react-query";
|
|
32
32
|
import { useTheme } from "next-themes";
|
|
33
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
useState,
|
|
35
|
+
useEffect,
|
|
36
|
+
useCallback,
|
|
37
|
+
useRef,
|
|
38
|
+
useMemo,
|
|
39
|
+
Fragment,
|
|
40
|
+
} from "react";
|
|
34
41
|
import { Link, useLocation, useNavigate } from "react-router";
|
|
35
42
|
import { toast } from "sonner";
|
|
36
43
|
|
|
@@ -51,6 +58,8 @@ type SidebarDashboard = {
|
|
|
51
58
|
subviews?: DashboardSubview[];
|
|
52
59
|
source: "static" | "sql";
|
|
53
60
|
visibility?: Visibility;
|
|
61
|
+
/** Id of the dashboard this one nests under in the sidebar, if any. */
|
|
62
|
+
parentId?: string;
|
|
54
63
|
};
|
|
55
64
|
import {
|
|
56
65
|
DevDatabaseLink,
|
|
@@ -1026,6 +1035,7 @@ type SqlDashboardListItem = {
|
|
|
1026
1035
|
id: string;
|
|
1027
1036
|
name: string;
|
|
1028
1037
|
visibility?: Visibility;
|
|
1038
|
+
parentId?: string;
|
|
1029
1039
|
};
|
|
1030
1040
|
|
|
1031
1041
|
async function fetchSqlDashboards(
|
|
@@ -1045,6 +1055,10 @@ async function fetchSqlDashboards(
|
|
|
1045
1055
|
d.visibility === "org" || d.visibility === "public"
|
|
1046
1056
|
? (d.visibility as Visibility)
|
|
1047
1057
|
: ("private" as Visibility),
|
|
1058
|
+
parentId:
|
|
1059
|
+
typeof d.parentId === "string" && d.parentId.trim().length > 0
|
|
1060
|
+
? d.parentId
|
|
1061
|
+
: undefined,
|
|
1048
1062
|
}));
|
|
1049
1063
|
} catch {
|
|
1050
1064
|
return [];
|
|
@@ -1445,6 +1459,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1445
1459
|
name: d.name,
|
|
1446
1460
|
source: "sql",
|
|
1447
1461
|
visibility: d.visibility,
|
|
1462
|
+
parentId: d.parentId,
|
|
1448
1463
|
}));
|
|
1449
1464
|
const all = [...staticItems, ...sqlItems];
|
|
1450
1465
|
if (dashboardSortMode === "alphabetical") {
|
|
@@ -1482,12 +1497,54 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1482
1497
|
[visibleDashboards, dashFilter],
|
|
1483
1498
|
);
|
|
1484
1499
|
|
|
1500
|
+
// Group dashboards that declare a parentId beneath their parent. Nesting is
|
|
1501
|
+
// intentionally one level deep: a dashboard only nests when its parent is
|
|
1502
|
+
// itself top-level. Orphans (parent missing/filtered out), self-references,
|
|
1503
|
+
// cycles, and deeper descendants all fall back to top level so nothing is
|
|
1504
|
+
// ever hidden.
|
|
1505
|
+
const dashboardChildren = useMemo<Map<string, SidebarDashboard[]>>(() => {
|
|
1506
|
+
const byId = new Map(filteredDashboards.map((d) => [d.id, d]));
|
|
1507
|
+
const hasValidParent = (d: SidebarDashboard) =>
|
|
1508
|
+
!!d.parentId && d.parentId !== d.id && byId.has(d.parentId);
|
|
1509
|
+
const byParent = new Map<string, SidebarDashboard[]>();
|
|
1510
|
+
for (const d of filteredDashboards) {
|
|
1511
|
+
if (!hasValidParent(d)) continue;
|
|
1512
|
+
const parent = byId.get(d.parentId as string);
|
|
1513
|
+
if (!parent || hasValidParent(parent)) continue;
|
|
1514
|
+
const arr = byParent.get(d.parentId as string) ?? [];
|
|
1515
|
+
arr.push(d);
|
|
1516
|
+
byParent.set(d.parentId as string, arr);
|
|
1517
|
+
}
|
|
1518
|
+
return byParent;
|
|
1519
|
+
}, [filteredDashboards]);
|
|
1520
|
+
|
|
1521
|
+
const topLevelDashboards = useMemo(() => {
|
|
1522
|
+
const childIds = new Set<string>();
|
|
1523
|
+
for (const arr of dashboardChildren.values())
|
|
1524
|
+
for (const c of arr) childIds.add(c.id);
|
|
1525
|
+
return filteredDashboards.filter((d) => !childIds.has(d.id));
|
|
1526
|
+
}, [filteredDashboards, dashboardChildren]);
|
|
1527
|
+
|
|
1485
1528
|
const displayedDashboards = useMemo(
|
|
1486
1529
|
() =>
|
|
1487
1530
|
dashShowAll
|
|
1488
|
-
?
|
|
1489
|
-
:
|
|
1490
|
-
[
|
|
1531
|
+
? topLevelDashboards
|
|
1532
|
+
: topLevelDashboards.slice(0, SIDEBAR_PREVIEW_COUNT),
|
|
1533
|
+
[topLevelDashboards, dashShowAll],
|
|
1534
|
+
);
|
|
1535
|
+
|
|
1536
|
+
// The flattened id order exactly as rendered (each parent immediately
|
|
1537
|
+
// followed by its nested children). Drag reordering must use this so the
|
|
1538
|
+
// arrayMove indices match what the user sees; the raw `visibleDashboards`
|
|
1539
|
+
// order interleaves children at their sorted positions and would move the
|
|
1540
|
+
// wrong rows once a dashboard is nested.
|
|
1541
|
+
const dashboardRenderOrderIds = useMemo(
|
|
1542
|
+
() =>
|
|
1543
|
+
topLevelDashboards.flatMap((d) => [
|
|
1544
|
+
d.id,
|
|
1545
|
+
...(dashboardChildren.get(d.id) ?? []).map((c) => c.id),
|
|
1546
|
+
]),
|
|
1547
|
+
[topLevelDashboards, dashboardChildren],
|
|
1491
1548
|
);
|
|
1492
1549
|
|
|
1493
1550
|
const handleDashboardDelete = useCallback(
|
|
@@ -1801,18 +1858,16 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1801
1858
|
(event: DragEndEvent) => {
|
|
1802
1859
|
const { active, over } = event;
|
|
1803
1860
|
if (!over || active.id === over.id) return;
|
|
1861
|
+
const ids = dashboardRenderOrderIds;
|
|
1862
|
+
const oldIndex = ids.indexOf(active.id as string);
|
|
1863
|
+
const newIndex = ids.indexOf(over.id as string);
|
|
1864
|
+
if (oldIndex === -1 || newIndex === -1) return;
|
|
1804
1865
|
setDashboardSortMode("manual");
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
const newIndex = ids.indexOf(over.id as string);
|
|
1809
|
-
if (oldIndex === -1 || newIndex === -1) return prev;
|
|
1810
|
-
const newOrder = arrayMove(ids, oldIndex, newIndex);
|
|
1811
|
-
setDashboardOrder(newOrder);
|
|
1812
|
-
return newOrder;
|
|
1813
|
-
});
|
|
1866
|
+
const newOrder = arrayMove(ids, oldIndex, newIndex);
|
|
1867
|
+
setDashboardOrder(newOrder);
|
|
1868
|
+
setDashboardOrderState(newOrder);
|
|
1814
1869
|
},
|
|
1815
|
-
[setDashboardSortMode,
|
|
1870
|
+
[setDashboardSortMode, dashboardRenderOrderIds],
|
|
1816
1871
|
);
|
|
1817
1872
|
|
|
1818
1873
|
const handleAnalysisDragEnd = useCallback(
|
|
@@ -2169,27 +2224,56 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2169
2224
|
onDragEnd={handleDashboardDragEnd}
|
|
2170
2225
|
>
|
|
2171
2226
|
<SortableContext
|
|
2172
|
-
items={displayedDashboards.
|
|
2227
|
+
items={displayedDashboards.flatMap((d) => [
|
|
2228
|
+
d.id,
|
|
2229
|
+
...(dashboardChildren.get(d.id) ?? []).map((c) => c.id),
|
|
2230
|
+
])}
|
|
2173
2231
|
strategy={verticalListSortingStrategy}
|
|
2174
2232
|
>
|
|
2175
2233
|
<div className="ms-4 min-w-0 space-y-0.5">
|
|
2176
|
-
{displayedDashboards.map((d) =>
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2234
|
+
{displayedDashboards.map((d) => {
|
|
2235
|
+
const children = dashboardChildren.get(d.id) ?? [];
|
|
2236
|
+
return (
|
|
2237
|
+
<Fragment key={d.id}>
|
|
2238
|
+
<SortableDashboardItem
|
|
2239
|
+
d={d}
|
|
2240
|
+
isActive={activeDashboardId === d.id}
|
|
2241
|
+
location={location}
|
|
2242
|
+
favoriteIds={favoriteIds}
|
|
2243
|
+
onToggleFavorite={toggleFavorite}
|
|
2244
|
+
onDelete={handleDashboardDelete}
|
|
2245
|
+
onRename={handleDashboardRename}
|
|
2246
|
+
onArchive={handleDashboardArchive}
|
|
2247
|
+
onSetVisibility={handleDashboardSetVisibility}
|
|
2248
|
+
onPrefetch={prefetchDashboard}
|
|
2249
|
+
views={allViewsMap[d.id]}
|
|
2250
|
+
/>
|
|
2251
|
+
{children.length > 0 && (
|
|
2252
|
+
<div className="ms-3 space-y-0.5 border-s border-sidebar-border/60 ps-1">
|
|
2253
|
+
{children.map((child) => (
|
|
2254
|
+
<SortableDashboardItem
|
|
2255
|
+
key={child.id}
|
|
2256
|
+
d={child}
|
|
2257
|
+
isActive={activeDashboardId === child.id}
|
|
2258
|
+
location={location}
|
|
2259
|
+
favoriteIds={favoriteIds}
|
|
2260
|
+
onToggleFavorite={toggleFavorite}
|
|
2261
|
+
onDelete={handleDashboardDelete}
|
|
2262
|
+
onRename={handleDashboardRename}
|
|
2263
|
+
onArchive={handleDashboardArchive}
|
|
2264
|
+
onSetVisibility={
|
|
2265
|
+
handleDashboardSetVisibility
|
|
2266
|
+
}
|
|
2267
|
+
onPrefetch={prefetchDashboard}
|
|
2268
|
+
views={allViewsMap[child.id]}
|
|
2269
|
+
/>
|
|
2270
|
+
))}
|
|
2271
|
+
</div>
|
|
2272
|
+
)}
|
|
2273
|
+
</Fragment>
|
|
2274
|
+
);
|
|
2275
|
+
})}
|
|
2276
|
+
{topLevelDashboards.length > SIDEBAR_PREVIEW_COUNT && (
|
|
2193
2277
|
<button
|
|
2194
2278
|
onClick={() => setDashShowAll(!dashShowAll)}
|
|
2195
2279
|
className="flex items-center gap-1 px-3 py-1 text-[11px] text-muted-foreground/70 hover:text-primary"
|
|
@@ -2198,7 +2282,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2198
2282
|
? t("sidebar.showLess")
|
|
2199
2283
|
: t("sidebar.showMore", {
|
|
2200
2284
|
count:
|
|
2201
|
-
|
|
2285
|
+
topLevelDashboards.length -
|
|
2202
2286
|
SIDEBAR_PREVIEW_COUNT,
|
|
2203
2287
|
})}
|
|
2204
2288
|
</button>
|
|
@@ -379,6 +379,10 @@ async function fetchDashboard(id: string): Promise<FetchedDashboard | null> {
|
|
|
379
379
|
config: {
|
|
380
380
|
name: data.name ?? "Untitled Dashboard",
|
|
381
381
|
description: data.description,
|
|
382
|
+
parentId:
|
|
383
|
+
typeof data.parentId === "string" && data.parentId.trim().length > 0
|
|
384
|
+
? data.parentId
|
|
385
|
+
: undefined,
|
|
382
386
|
catalog: parseDashboardCatalogMetadata(data.catalog),
|
|
383
387
|
demo: parseDashboardDemoMetadata(data.demo),
|
|
384
388
|
filters: data.filters,
|
|
@@ -114,6 +114,13 @@ export interface SqlPanel {
|
|
|
114
114
|
export interface SqlDashboardConfig {
|
|
115
115
|
name: string;
|
|
116
116
|
description?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Optional id of another dashboard this one nests under. When set, the
|
|
119
|
+
* sidebar renders this dashboard indented beneath its parent instead of at
|
|
120
|
+
* the top level. Orphans (parent missing/inaccessible) fall back to the top
|
|
121
|
+
* level. Self-references and cycles are ignored by the renderer.
|
|
122
|
+
*/
|
|
123
|
+
parentId?: string;
|
|
117
124
|
catalog?: {
|
|
118
125
|
templateId?: string;
|
|
119
126
|
templateVersion?: string;
|
|
@@ -22,6 +22,8 @@ import { readImageModelDefault } from "./_image-model-default.js";
|
|
|
22
22
|
import generateImage from "./generate-image.js";
|
|
23
23
|
import { upsertVariantSlot } from "./variant-slots.js";
|
|
24
24
|
|
|
25
|
+
const IMAGE_GENERATION_TOOL_TIMEOUT_MS = 12 * 60_000;
|
|
26
|
+
|
|
25
27
|
export default defineAction({
|
|
26
28
|
description:
|
|
27
29
|
"Generate several brand-consistent images in parallel from one brand kit/library. Use @brand-kit mentions as libraryId and @preset mentions as presetId when present. This is synchronous for images: one call waits for every slot and returns final image artifacts. Use this for slide decks, landing pages, and multi-slot design work. Do not call get-generation-run or refresh-generation-run after a normal image batch result.",
|
|
@@ -74,6 +76,7 @@ export default defineAction({
|
|
|
74
76
|
),
|
|
75
77
|
}),
|
|
76
78
|
parallelSafe: true,
|
|
79
|
+
timeoutMs: IMAGE_GENERATION_TOOL_TIMEOUT_MS,
|
|
77
80
|
run: async ({ slots, ...inputBase }, context?: ActionRunContext) => {
|
|
78
81
|
const imageModelDefault = await readImageModelDefault();
|
|
79
82
|
const libraryId = inputBase.libraryId;
|
|
@@ -46,6 +46,8 @@ import {
|
|
|
46
46
|
import { readImageModelDefault } from "./_image-model-default.js";
|
|
47
47
|
import { upsertVariantSlot, wasVariantSlotDismissed } from "./variant-slots.js";
|
|
48
48
|
|
|
49
|
+
const IMAGE_GENERATION_TOOL_TIMEOUT_MS = 12 * 60_000;
|
|
50
|
+
|
|
49
51
|
function resolveModelForTier(
|
|
50
52
|
tier: ImageQualityTier | undefined,
|
|
51
53
|
category: ImageCategory | undefined,
|
|
@@ -125,6 +127,7 @@ export default defineAction({
|
|
|
125
127
|
),
|
|
126
128
|
}),
|
|
127
129
|
parallelSafe: true,
|
|
130
|
+
timeoutMs: IMAGE_GENERATION_TOOL_TIMEOUT_MS,
|
|
128
131
|
run: async (input, context?: ActionRunContext) => {
|
|
129
132
|
const imageModelDefault = await readImageModelDefault();
|
|
130
133
|
const libraryId = input.libraryId;
|
|
@@ -8,9 +8,9 @@ functions = "templates/assets/.netlify/functions-internal"
|
|
|
8
8
|
GA_MEASUREMENT_ID = "G-ESF7FYXGN9"
|
|
9
9
|
NITRO_PRESET = "netlify"
|
|
10
10
|
NPM_CONFIG_PRODUCTION = "false"
|
|
11
|
+
AGENT_CHAT_DURABLE_BACKGROUND = "true"
|
|
11
12
|
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
# slides' generous timeout so multi-image runs don't get killed mid-flight.
|
|
13
|
+
# Emit the Netlify background function used by Assets' durable agent-chat opt-in.
|
|
14
|
+
# The normal server timeout still protects non-agent image/video HTTP handlers.
|
|
15
15
|
[functions."*"]
|
|
16
16
|
timeout = 300
|
|
@@ -10,6 +10,8 @@ import actionsRegistry from "../../.generated/actions-registry.js";
|
|
|
10
10
|
import { getDb, schema } from "../db/index.js";
|
|
11
11
|
import "../register-secrets.js";
|
|
12
12
|
|
|
13
|
+
const ASSETS_BACKGROUND_RUN_SOFT_TIMEOUT_MS = 13 * 60_000;
|
|
14
|
+
|
|
13
15
|
const INITIAL_TOOL_NAMES = [
|
|
14
16
|
"view-screen",
|
|
15
17
|
"list-libraries",
|
|
@@ -240,5 +242,6 @@ export default createAgentChatPlugin({
|
|
|
240
242
|
},
|
|
241
243
|
},
|
|
242
244
|
},
|
|
243
|
-
|
|
245
|
+
durableBackgroundRuns: true,
|
|
246
|
+
runSoftTimeoutMs: ASSETS_BACKGROUND_RUN_SOFT_TIMEOUT_MS,
|
|
244
247
|
});
|