@agent-native/core 0.79.27 → 0.80.1
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 +34 -0
- package/corpus/core/docs/content/locales/ar-SA/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +55 -1
- package/corpus/core/docs/content/locales/de-DE/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/de-DE/template-design.mdx +66 -1
- package/corpus/core/docs/content/locales/es-ES/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/es-ES/template-design.mdx +65 -1
- package/corpus/core/docs/content/locales/fr-FR/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +64 -1
- package/corpus/core/docs/content/locales/hi-IN/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +59 -1
- package/corpus/core/docs/content/locales/ja-JP/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +62 -1
- package/corpus/core/docs/content/locales/ko-KR/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +58 -1
- package/corpus/core/docs/content/locales/pt-BR/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +62 -1
- package/corpus/core/docs/content/locales/zh-CN/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +50 -1
- package/corpus/core/docs/content/locales/zh-TW/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +52 -1
- package/corpus/core/docs/content/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/template-design.mdx +59 -1
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/agent/engine/index.ts +1 -0
- package/corpus/core/src/agent/engine/registry.ts +40 -0
- package/corpus/core/src/agent/production-agent.ts +6 -2
- package/corpus/core/src/application-state/handlers.ts +1 -1
- package/corpus/core/src/brand-kit/index.ts +1 -1
- package/corpus/core/src/cli/design-connect.ts +490 -0
- package/corpus/core/src/cli/index.ts +16 -0
- package/corpus/core/src/cli/skills.ts +144 -3
- package/corpus/core/src/client/AgentPanel.tsx +1 -1
- package/corpus/core/src/client/AssistantChat.tsx +43 -7
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +1 -1
- package/corpus/core/src/client/agent-chat.ts +27 -3
- package/corpus/core/src/client/blocks/library/MermaidBlock.tsx +1 -1
- package/corpus/core/src/client/blocks/library/diagram.tsx +2 -2
- package/corpus/core/src/client/blocks/library/wireframe.tsx +1 -1
- package/corpus/core/src/client/chat/message-components.tsx +1 -1
- package/corpus/core/src/client/chat-model-groups.ts +1 -2
- package/corpus/core/src/client/components/LiveCursorOverlay.tsx +33 -66
- package/corpus/core/src/client/composer/TiptapComposer.tsx +99 -24
- package/corpus/core/src/client/composer/useVoiceDictation.ts +429 -260
- package/corpus/core/src/client/extensions/portable-extension.ts +1 -1
- package/corpus/core/src/client/frame-protocol.ts +17 -2
- package/corpus/core/src/client/rich-markdown-editor/RegistryBlockNode.tsx +2 -2
- package/corpus/core/src/client/sharing/ShareButton.tsx +20 -15
- package/corpus/core/src/client/use-agent-engine-configured.ts +80 -28
- package/corpus/core/src/code-agents/transcript-normalizer.ts +1 -1
- package/corpus/core/src/extensions/path.ts +1 -4
- package/corpus/core/src/integrations/a2a-continuation-processor.ts +1 -1
- package/corpus/core/src/mcp/build-server.ts +1 -1
- package/corpus/core/src/org/handlers.ts +5 -5
- package/corpus/core/src/org/plugin.ts +2 -2
- package/corpus/core/src/scripts/call-agent.ts +1 -1
- package/corpus/core/src/scripts/db/safety.ts +1 -1
- package/corpus/core/src/server/auth.ts +3 -0
- package/corpus/core/src/server/builder-design-systems.ts +308 -0
- package/corpus/core/src/server/core-routes-plugin.ts +29 -3
- package/corpus/core/src/server/index.ts +8 -0
- package/corpus/core/src/server/transcribe-voice.ts +57 -22
- package/corpus/core/src/shared/mcp-embed-headers.ts +23 -1
- package/corpus/core/src/styles/agent-native.css +60 -4
- package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
- package/corpus/core/src/usage/store.ts +2 -2
- package/corpus/core/src/vite/client.ts +2 -0
- package/corpus/core/src/voice/index.ts +18 -0
- package/corpus/core/src/voice/voice-cleanup-prompt.ts +38 -0
- package/corpus/core/src/voice/voice-context.ts +217 -0
- package/corpus/core/src/voice/voice-replacements.ts +75 -0
- package/corpus/templates/analytics/AGENTS.md +4 -3
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +298 -15
- package/corpus/templates/analytics/actions/get-sql-dashboard.ts +9 -4
- package/corpus/templates/analytics/actions/list-session-recordings.ts +6 -1
- package/corpus/templates/analytics/actions/mutate-dashboard.ts +18 -2
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +12 -2
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +557 -400
- package/corpus/templates/analytics/app/global.css +0 -4
- package/corpus/templates/analytics/app/hooks/use-replay-storage-status.ts +66 -0
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +39 -0
- package/corpus/templates/analytics/app/i18n-data.ts +424 -0
- package/corpus/templates/analytics/app/pages/Settings.tsx +333 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +2 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/dashboard-layout.ts +121 -3
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +82 -34
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +7 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +144 -36
- package/corpus/templates/analytics/changelog/2026-06-28-ask-tab-now-matches-the-darker-app-background.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-28-dashboard-email-reports-now-use-cleaner-light-mode-snapshots.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-28-sessions-now-show-only-signed-in-recordings-with-playable-re.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-analytics-agents-can-now-place-new-charts-into-requested-das.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-analytics-queries-now-report-failed-source-query-errors-inst.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-charts-can-now-be-dropped-between-full-dashboard-rows-to-cre.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-dashboard-email-reports-include-the-full-dashboard-image-wit.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-main-surface-border-reaches-the-top.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-session-replay-now-records-playable-sessions-in-production-a.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-set-up-session-replay-storage-from-settings-connect-builder-.md +6 -0
- package/corpus/templates/analytics/scripts/cleanup-empty-session-recordings.ts +102 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +3 -3
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +75 -30
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +5 -2
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +81 -20
- package/corpus/templates/analytics/server/lib/replay-storage.ts +79 -0
- package/corpus/templates/analytics/server/lib/s3-upload-provider.ts +255 -0
- package/corpus/templates/analytics/server/lib/session-replay.ts +53 -12
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +11 -2
- package/corpus/templates/analytics/server/plugins/onboarding.ts +97 -0
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +4 -4
- package/corpus/templates/assets/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/brain/app/components/layout/Layout.tsx +29 -2
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +131 -42
- package/corpus/templates/brain/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/brain/app/i18n-data.ts +20 -0
- package/corpus/templates/brain/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +29 -1
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +417 -299
- package/corpus/templates/calendar/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/calendar/app/i18n-data.ts +20 -0
- package/corpus/templates/calendar/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +6 -19
- package/corpus/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/clips/AGENTS.md +4 -0
- package/corpus/templates/clips/actions/cleanup-transcript.ts +39 -9
- package/corpus/templates/clips/actions/finalize-meeting.ts +81 -12
- package/corpus/templates/clips/actions/lib/agents-md-context.ts +4 -1
- package/corpus/templates/clips/app/components/library/library-layout.tsx +3 -3
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +1 -1
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +2 -2
- package/corpus/templates/clips/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
- package/corpus/templates/clips/desktop/src/lib/personal-vocabulary.ts +13 -8
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +24 -0
- package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +105 -5
- package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +60 -1
- package/corpus/templates/content/actions/set-image-alt-text.ts +1 -1
- package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +1 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +1 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -5
- package/corpus/templates/content/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/content/shared/document-export.ts +1 -1
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +8 -18
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +154 -0
- package/corpus/templates/design/AGENTS.md +95 -5
- package/corpus/templates/design/DESIGN.md +82 -0
- package/corpus/templates/design/DEVELOPING.md +43 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +453 -0
- package/corpus/templates/design/actions/apply-shader.ts +277 -0
- package/corpus/templates/design/actions/apply-visual-edit.ts +303 -0
- package/corpus/templates/design/actions/connect-localhost.ts +183 -0
- package/corpus/templates/design/actions/edit-design.ts +195 -42
- package/corpus/templates/design/actions/generate-design.ts +71 -1
- package/corpus/templates/design/actions/generate-screens.ts +193 -0
- package/corpus/templates/design/actions/get-code-layer-projection.ts +191 -0
- package/corpus/templates/design/actions/get-shader.ts +119 -0
- package/corpus/templates/design/actions/index-design-system-with-builder.ts +259 -0
- package/corpus/templates/design/actions/list-localhost-connections.ts +95 -0
- package/corpus/templates/design/actions/navigate.ts +55 -2
- package/corpus/templates/design/actions/update-file.ts +9 -2
- package/corpus/templates/design/actions/view-screen.ts +68 -1
- package/corpus/templates/design/agent-native.app-skill.json +10 -0
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +719 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +2120 -103
- package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +74 -38
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +401 -0
- package/corpus/templates/design/app/components/design/EditPanel.tsx +3966 -440
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +1473 -0
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +3940 -147
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +700 -13
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +105 -63
- package/corpus/templates/design/app/components/design/index.ts +0 -5
- package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +353 -0
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +1589 -0
- package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +511 -0
- package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +395 -0
- package/corpus/templates/design/app/components/design/inspector/FigmaColorPicker.tsx +2010 -0
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +601 -0
- package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +242 -0
- package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +420 -0
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +238 -0
- package/corpus/templates/design/app/components/design/inspector/ShaderControls.stories.tsx +71 -0
- package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +575 -0
- package/corpus/templates/design/app/components/design/inspector/ShaderEffectRow.tsx +106 -0
- package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +423 -0
- package/corpus/templates/design/app/components/design/inspector/figma-icons.tsx +741 -0
- package/corpus/templates/design/app/components/design/inspector/index.ts +87 -0
- package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +201 -0
- package/corpus/templates/design/app/components/design/types.ts +23 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +24 -13
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +4 -4
- package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +474 -36
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +22 -5
- package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +24 -11
- package/corpus/templates/design/app/global.css +149 -5
- package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -0
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +130 -8
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +329 -0
- package/corpus/templates/design/app/i18n/zh-TW.ts +277 -0
- package/corpus/templates/design/app/i18n-data.ts +3028 -1
- package/corpus/templates/design/app/pages/DesignEditor.tsx +5831 -904
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +57 -221
- package/corpus/templates/design/changelog/2026-06-28-annotate-mode-now-combines-drawing-and-comment-pins-in-one-c.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-design-editor-panel-borders-are-cleaner-so-the-canvas-edge-s.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-drawing-prompts-now-reliably-open-and-submit-to-the-design-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-editor-app-menus-now-use-an-outline-agent-native-mark-with-b.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-layer-selection-now-updates-chat-context-without-opening-the.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-layer-selections-now-preserve-hidden-and-locked-canvas-state.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-handles-zooming-drawing-opening-and-dele.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-selects-screens-on-click-and-opens-them-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-screen-overview-zooms-into-the-active-screen-with-smoother-e.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-selected-element-chips-in-chat-are-shorter-and-easier-to-sca.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-the-design-editor-toolbar-is-more-compact-and-the-app-menu-m.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-at-the-top-of-the-design-sidebar-instead-of-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-in-the-right-inspector-beside-the-design-tab.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-active-sidebar-rows-use-soft-highlights.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-agents-can-now-open-screen-overview-focus-screens-and-add.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-canvas-selection-no-longer-flashes-broken-prototype-html-whe.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-command-menu-selections-are-clearer-in-dark-mode.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-agents-now-edit-broad-copy-changes-more-reliably.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-editor-extensions-now-run-inline-beside-the-artboard.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-mode-top-chrome-now-groups-collaborators-preview-shar.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-element-selection-now-stays-on-the-intended-layer-after-sele.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-full-view-controls-now-sit-above-frames-inst.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-tools-can-draw-shapes-create-screens-and-kee.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-sidebars-use-darker-chrome-and-chat-warns-immediately.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-the-pen-tool-now-creates-anchor-based-bezier-vectors-with-ha.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-visual-edit-can-open-localhost-routes-as-url-backed-screens.md +6 -0
- package/corpus/templates/design/package.json +1 -0
- package/corpus/templates/design/server/db/schema.ts +26 -0
- package/corpus/templates/design/server/handlers/import-figma-system.ts +38 -85
- package/corpus/templates/design/server/lib/design-snapshot.ts +9 -1
- package/corpus/templates/design/server/plugins/agent-chat.ts +3 -0
- package/corpus/templates/design/shared/api.ts +27 -0
- package/corpus/templates/design/shared/canvas-frames.ts +103 -0
- package/corpus/templates/design/shared/canvas-math.ts +1058 -0
- package/corpus/templates/design/shared/code-layer.ts +2412 -0
- package/corpus/templates/design/shared/color-utils.ts +180 -0
- package/corpus/templates/design/shared/generation-session.ts +61 -0
- package/corpus/templates/design/shared/html-content.ts +21 -0
- package/corpus/templates/design/shared/pen-path.ts +207 -0
- package/corpus/templates/design/shared/shader-presets.ts +782 -0
- package/corpus/templates/design/shared/shader-safety.ts +137 -0
- package/corpus/templates/design/shared/source-mode.ts +237 -0
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +149 -6
- package/corpus/templates/forms/app/i18n/ar-SA.ts +2 -0
- package/corpus/templates/forms/app/i18n/de-DE.ts +2 -0
- package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
- package/corpus/templates/forms/app/i18n/es-ES.ts +2 -0
- package/corpus/templates/forms/app/i18n/fr-FR.ts +2 -0
- package/corpus/templates/forms/app/i18n/hi-IN.ts +2 -0
- package/corpus/templates/forms/app/i18n/ja-JP.ts +2 -0
- package/corpus/templates/forms/app/i18n/ko-KR.ts +2 -0
- package/corpus/templates/forms/app/i18n/pt-BR.ts +2 -0
- package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
- package/corpus/templates/forms/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/forms/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +2 -2
- package/corpus/templates/macros/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +408 -247
- package/corpus/templates/mail/app/i18n/ar-SA.ts +4 -0
- package/corpus/templates/mail/app/i18n/de-DE.ts +4 -0
- package/corpus/templates/mail/app/i18n/en-US.ts +4 -0
- package/corpus/templates/mail/app/i18n/es-ES.ts +4 -0
- package/corpus/templates/mail/app/i18n/fr-FR.ts +4 -0
- package/corpus/templates/mail/app/i18n/hi-IN.ts +4 -0
- package/corpus/templates/mail/app/i18n/ja-JP.ts +4 -0
- package/corpus/templates/mail/app/i18n/ko-KR.ts +4 -0
- package/corpus/templates/mail/app/i18n/pt-BR.ts +4 -0
- package/corpus/templates/mail/app/i18n/zh-CN.ts +4 -0
- package/corpus/templates/mail/app/i18n/zh-TW.ts +4 -0
- package/corpus/templates/mail/app/lib/utils.ts +2 -2
- package/corpus/templates/mail/changelog/2026-06-28-pinned-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +6 -8
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +1 -1
- package/corpus/templates/plan/app/global.css +61 -78
- package/corpus/templates/plan/app/pages/PlansPage.tsx +8 -0
- package/corpus/templates/plan/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/plan/changelog/2026-06-28-plans-use-the-shared-neutral-light-and-dark-theme.md +6 -0
- package/corpus/templates/plan/changelog/2026-06-28-sending-open-feedback-from-a-plan-now-opens-the-inline-plan-.md +6 -0
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +9 -10
- package/corpus/templates/slides/AGENTS.md +3 -2
- package/corpus/templates/slides/actions/import-file.ts +26 -17
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +259 -0
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +35 -167
- package/corpus/templates/slides/app/components/design-system/fig-import-response.ts +9 -13
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +5 -5
- package/corpus/templates/slides/app/context/DeckContext.tsx +1 -1
- package/corpus/templates/slides/app/i18n/ar-SA.ts +9 -37
- package/corpus/templates/slides/app/i18n/de-DE.ts +10 -25
- package/corpus/templates/slides/app/i18n/en-US.ts +9 -26
- package/corpus/templates/slides/app/i18n/es-ES.ts +10 -28
- package/corpus/templates/slides/app/i18n/fr-FR.ts +10 -28
- package/corpus/templates/slides/app/i18n/hi-IN.ts +9 -26
- package/corpus/templates/slides/app/i18n/ja-JP.ts +10 -22
- package/corpus/templates/slides/app/i18n/ko-KR.ts +9 -23
- package/corpus/templates/slides/app/i18n/pt-BR.ts +10 -28
- package/corpus/templates/slides/app/i18n/zh-CN.ts +9 -22
- package/corpus/templates/slides/app/i18n/zh-TW.ts +9 -22
- package/corpus/templates/slides/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/slides/server/handlers/import-figma-system.ts +44 -12
- package/corpus/templates/slides/server/lib/chat-attachments.ts +1 -1
- package/corpus/templates/videos/app/components/NewCompositionPopover.tsx +1 -1
- package/corpus/templates/videos/app/components/Sidebar.tsx +2 -2
- package/corpus/templates/videos/app/components/layout/Layout.tsx +29 -2
- package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +113 -30
- package/corpus/templates/videos/app/i18n/ar-SA.ts +2 -0
- package/corpus/templates/videos/app/i18n/de-DE.ts +2 -0
- package/corpus/templates/videos/app/i18n/en-US.ts +2 -0
- package/corpus/templates/videos/app/i18n/es-ES.ts +2 -0
- package/corpus/templates/videos/app/i18n/fr-FR.ts +2 -0
- package/corpus/templates/videos/app/i18n/hi-IN.ts +2 -0
- package/corpus/templates/videos/app/i18n/ja-JP.ts +2 -0
- package/corpus/templates/videos/app/i18n/ko-KR.ts +2 -0
- package/corpus/templates/videos/app/i18n/pt-BR.ts +2 -0
- package/corpus/templates/videos/app/i18n/zh-CN.ts +2 -0
- package/corpus/templates/videos/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/videos/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/dist/agent/engine/index.d.ts +1 -1
- package/dist/agent/engine/index.d.ts.map +1 -1
- package/dist/agent/engine/index.js +1 -1
- package/dist/agent/engine/index.js.map +1 -1
- package/dist/agent/engine/registry.d.ts +9 -0
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +37 -0
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +4 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/application-state/handlers.js +1 -1
- package/dist/application-state/handlers.js.map +1 -1
- package/dist/brand-kit/index.d.ts +1 -1
- package/dist/brand-kit/index.js +1 -1
- package/dist/brand-kit/index.js.map +1 -1
- package/dist/cli/design-connect.d.ts +52 -0
- package/dist/cli/design-connect.d.ts.map +1 -0
- package/dist/cli/design-connect.js +409 -0
- package/dist/cli/design-connect.js.map +1 -0
- package/dist/cli/index.js +15 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills.d.ts +3 -0
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +139 -3
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AgentPanel.js +1 -1
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +38 -8
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +1 -1
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat.d.ts +6 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +17 -3
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/blocks/library/MermaidBlock.js +1 -1
- package/dist/client/blocks/library/MermaidBlock.js.map +1 -1
- package/dist/client/blocks/library/diagram.js +1 -1
- package/dist/client/blocks/library/diagram.js.map +1 -1
- package/dist/client/blocks/library/wireframe.js +1 -1
- package/dist/client/blocks/library/wireframe.js.map +1 -1
- package/dist/client/chat/message-components.js +1 -1
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat-model-groups.d.ts.map +1 -1
- package/dist/client/chat-model-groups.js +1 -2
- package/dist/client/chat-model-groups.js.map +1 -1
- package/dist/client/components/LiveCursorOverlay.d.ts +1 -2
- package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -1
- package/dist/client/components/LiveCursorOverlay.js +19 -40
- package/dist/client/components/LiveCursorOverlay.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +3 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +86 -24
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/useVoiceDictation.d.ts +9 -0
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
- package/dist/client/composer/useVoiceDictation.js +154 -32
- package/dist/client/composer/useVoiceDictation.js.map +1 -1
- package/dist/client/extensions/portable-extension.d.ts +1 -1
- package/dist/client/extensions/portable-extension.d.ts.map +1 -1
- package/dist/client/extensions/portable-extension.js.map +1 -1
- package/dist/client/frame-protocol.d.ts +17 -2
- package/dist/client/frame-protocol.d.ts.map +1 -1
- package/dist/client/frame-protocol.js.map +1 -1
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js +2 -2
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts +2 -0
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +7 -6
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/use-agent-engine-configured.d.ts +5 -0
- package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
- package/dist/client/use-agent-engine-configured.js +51 -25
- package/dist/client/use-agent-engine-configured.js.map +1 -1
- package/dist/code-agents/transcript-normalizer.js +1 -1
- package/dist/code-agents/transcript-normalizer.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/extensions/path.d.ts +1 -1
- package/dist/extensions/path.d.ts.map +1 -1
- package/dist/extensions/path.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/integrations/a2a-continuation-processor.js +1 -1
- package/dist/integrations/a2a-continuation-processor.js.map +1 -1
- package/dist/mcp/build-server.d.ts +1 -1
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +5 -5
- package/dist/org/handlers.js +5 -5
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/plugin.js +2 -2
- package/dist/org/plugin.js.map +1 -1
- package/dist/scripts/call-agent.js +1 -1
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/scripts/db/safety.js +1 -1
- package/dist/scripts/db/safety.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +3 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/builder-design-systems.d.ts +28 -0
- package/dist/server/builder-design-systems.d.ts.map +1 -0
- package/dist/server/builder-design-systems.js +217 -0
- package/dist/server/builder-design-systems.js.map +1 -0
- package/dist/server/core-routes-plugin.d.ts +1 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +20 -3
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +40 -24
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/shared/mcp-embed-headers.d.ts +1 -0
- package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
- package/dist/shared/mcp-embed-headers.js +20 -1
- package/dist/shared/mcp-embed-headers.js.map +1 -1
- package/dist/styles/agent-native.css +60 -4
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
- package/dist/usage/store.js +2 -2
- package/dist/usage/store.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +2 -0
- package/dist/vite/client.js.map +1 -1
- package/dist/voice/index.d.ts +5 -0
- package/dist/voice/index.d.ts.map +1 -0
- package/dist/voice/index.js +4 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/voice-cleanup-prompt.d.ts +6 -0
- package/dist/voice/voice-cleanup-prompt.d.ts.map +1 -0
- package/dist/voice/voice-cleanup-prompt.js +26 -0
- package/dist/voice/voice-cleanup-prompt.js.map +1 -0
- package/dist/voice/voice-context.d.ts +25 -0
- package/dist/voice/voice-context.d.ts.map +1 -0
- package/dist/voice/voice-context.js +156 -0
- package/dist/voice/voice-context.js.map +1 -0
- package/dist/voice/voice-replacements.d.ts +4 -0
- package/dist/voice/voice-replacements.d.ts.map +1 -0
- package/dist/voice/voice-replacements.js +52 -0
- package/dist/voice/voice-replacements.js.map +1 -0
- package/docs/content/locales/ar-SA/skills-guide.mdx +5 -0
- package/docs/content/locales/ar-SA/template-design.mdx +55 -1
- package/docs/content/locales/de-DE/skills-guide.mdx +5 -0
- package/docs/content/locales/de-DE/template-design.mdx +66 -1
- package/docs/content/locales/es-ES/skills-guide.mdx +5 -0
- package/docs/content/locales/es-ES/template-design.mdx +65 -1
- package/docs/content/locales/fr-FR/skills-guide.mdx +5 -0
- package/docs/content/locales/fr-FR/template-design.mdx +64 -1
- package/docs/content/locales/hi-IN/skills-guide.mdx +5 -0
- package/docs/content/locales/hi-IN/template-design.mdx +59 -1
- package/docs/content/locales/ja-JP/skills-guide.mdx +5 -0
- package/docs/content/locales/ja-JP/template-design.mdx +62 -1
- package/docs/content/locales/ko-KR/skills-guide.mdx +5 -0
- package/docs/content/locales/ko-KR/template-design.mdx +58 -1
- package/docs/content/locales/pt-BR/skills-guide.mdx +5 -0
- package/docs/content/locales/pt-BR/template-design.mdx +62 -1
- package/docs/content/locales/zh-CN/skills-guide.mdx +5 -0
- package/docs/content/locales/zh-CN/template-design.mdx +50 -1
- package/docs/content/locales/zh-TW/skills-guide.mdx +5 -0
- package/docs/content/locales/zh-TW/template-design.mdx +52 -1
- package/docs/content/skills-guide.mdx +5 -0
- package/docs/content/template-design.mdx +59 -1
- package/package.json +2 -1
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
- package/corpus/templates/design/actions/import-figma-file.ts +0 -166
- package/corpus/templates/design/app/components/design/DesignToolbar.tsx +0 -339
- package/corpus/templates/design/app/components/design/PresentMode.tsx +0 -68
- package/corpus/templates/design/app/components/design/ViewportTabs.tsx +0 -149
- package/corpus/templates/design/app/components/design/ZoomControls.tsx +0 -157
- package/corpus/templates/slides/server/lib/fig-design-system.ts +0 -110
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { FeatureNotConfiguredError } from "./credential-provider.js";
|
|
2
|
+
import {
|
|
3
|
+
getBuilderProxyOrigin,
|
|
4
|
+
resolveBuilderCredentials,
|
|
5
|
+
} from "./credential-provider.js";
|
|
6
|
+
|
|
7
|
+
const DEFAULT_TIMEOUT_MS = 120_000;
|
|
8
|
+
|
|
9
|
+
export interface BuilderDesignSystemIndexFile {
|
|
10
|
+
name: string;
|
|
11
|
+
data: Uint8Array;
|
|
12
|
+
mimeType?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface BuilderDesignSystemIndexOptions {
|
|
16
|
+
projectName?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
githubRepoUrl?: string;
|
|
19
|
+
connectedProjectId?: string;
|
|
20
|
+
files?: BuilderDesignSystemIndexFile[];
|
|
21
|
+
selection?: Record<string, string[]>;
|
|
22
|
+
devToolsVersion?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface BuilderDesignSystemIndexResult {
|
|
26
|
+
ok: true;
|
|
27
|
+
source: "builder";
|
|
28
|
+
projectId: string;
|
|
29
|
+
jobId: string;
|
|
30
|
+
designSystemId: string;
|
|
31
|
+
suggestedTitle: string | null;
|
|
32
|
+
builderUrl: string;
|
|
33
|
+
status: "in-progress";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface BuilderDesignSystemCredentials {
|
|
37
|
+
privateKey: string;
|
|
38
|
+
publicKey: string;
|
|
39
|
+
userId: string | null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface UploadStartResponse {
|
|
43
|
+
uploads?: Array<{ idx: number; uploadUrl: string; uploadToken: string }>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface GenerateResponse {
|
|
47
|
+
projectId?: string;
|
|
48
|
+
jobId?: string;
|
|
49
|
+
designSystemId?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function trimTrailingSlash(value: string): string {
|
|
53
|
+
return value.replace(/\/+$/, "");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function getBuilderDesignSystemsBaseUrl(): string {
|
|
57
|
+
return (
|
|
58
|
+
process.env.BUILDER_DESIGN_SYSTEMS_BASE_URL ||
|
|
59
|
+
`${trimTrailingSlash(getBuilderProxyOrigin())}/design-systems/v1`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function getBuilderAppHost(): string {
|
|
64
|
+
return (
|
|
65
|
+
process.env.BUILDER_APP_HOST ||
|
|
66
|
+
process.env.BUILDER_PUBLIC_APP_HOST ||
|
|
67
|
+
"https://builder.io"
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function makeBuilderDesignSystemUrl(
|
|
72
|
+
path: string,
|
|
73
|
+
credentials: BuilderDesignSystemCredentials,
|
|
74
|
+
): URL {
|
|
75
|
+
const base = `${trimTrailingSlash(getBuilderDesignSystemsBaseUrl())}/`;
|
|
76
|
+
const url = new URL(path.replace(/^\/+/, ""), base);
|
|
77
|
+
url.searchParams.set("apiKey", credentials.publicKey);
|
|
78
|
+
if (credentials.userId) url.searchParams.set("userId", credentials.userId);
|
|
79
|
+
return url;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function makeBuilderHeaders(
|
|
83
|
+
credentials: BuilderDesignSystemCredentials,
|
|
84
|
+
): Record<string, string> {
|
|
85
|
+
return {
|
|
86
|
+
Authorization: `Bearer ${credentials.privateKey}`,
|
|
87
|
+
"x-builder-api-key": credentials.publicKey,
|
|
88
|
+
...(credentials.userId ? { "x-builder-user-id": credentials.userId } : {}),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function resolveBuilderDesignSystemCredentials(): Promise<BuilderDesignSystemCredentials> {
|
|
93
|
+
const credentials = await resolveBuilderCredentials();
|
|
94
|
+
if (!credentials.privateKey || !credentials.publicKey) {
|
|
95
|
+
throw new FeatureNotConfiguredError({
|
|
96
|
+
requiredCredential: "BUILDER_PRIVATE_KEY",
|
|
97
|
+
message:
|
|
98
|
+
"Connect Builder.io before indexing a design system from Figma or code.",
|
|
99
|
+
builderConnectUrl: "/_agent-native/builder/connect",
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
privateKey: credentials.privateKey,
|
|
104
|
+
publicKey: credentials.publicKey,
|
|
105
|
+
userId: credentials.userId ?? null,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function mimeTypeForFile(file: BuilderDesignSystemIndexFile): string {
|
|
110
|
+
if (file.mimeType?.trim()) return file.mimeType.trim();
|
|
111
|
+
const lower = file.name.toLowerCase();
|
|
112
|
+
if (lower.endsWith(".fig")) return "application/octet-stream";
|
|
113
|
+
if (lower.endsWith(".pdf")) return "application/pdf";
|
|
114
|
+
if (lower.endsWith(".md") || lower.endsWith(".markdown"))
|
|
115
|
+
return "text/markdown";
|
|
116
|
+
if (lower.endsWith(".json")) return "application/json";
|
|
117
|
+
if (lower.endsWith(".css")) return "text/css";
|
|
118
|
+
return "text/plain";
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function makeBody(bytes: Uint8Array, mimeType: string): BodyInit {
|
|
122
|
+
return typeof Blob !== "undefined"
|
|
123
|
+
? new Blob([bytes as unknown as BlobPart], { type: mimeType })
|
|
124
|
+
: (bytes as unknown as BodyInit);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function fetchWithTimeout(
|
|
128
|
+
url: string | URL,
|
|
129
|
+
init: RequestInit,
|
|
130
|
+
timeoutMs = DEFAULT_TIMEOUT_MS,
|
|
131
|
+
): Promise<Response> {
|
|
132
|
+
const controller = new AbortController();
|
|
133
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
134
|
+
try {
|
|
135
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
136
|
+
} finally {
|
|
137
|
+
clearTimeout(timer);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async function parseErrorBody(response: Response): Promise<string> {
|
|
142
|
+
const text = await response.text().catch(() => "");
|
|
143
|
+
if (!text) return response.statusText || `HTTP ${response.status}`;
|
|
144
|
+
try {
|
|
145
|
+
const json = JSON.parse(text) as { error?: unknown };
|
|
146
|
+
if (typeof json.error === "string") return json.error;
|
|
147
|
+
if (json.error && typeof json.error === "object") {
|
|
148
|
+
return JSON.stringify(json.error).slice(0, 500);
|
|
149
|
+
}
|
|
150
|
+
} catch {}
|
|
151
|
+
return text.replace(/\s+/g, " ").trim().slice(0, 500);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function assertOk(response: Response, label: string): Promise<void> {
|
|
155
|
+
if (response.ok) return;
|
|
156
|
+
throw new Error(
|
|
157
|
+
`${label} (${response.status}): ${await parseErrorBody(response)}`,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async function uploadToResumableUrl(
|
|
162
|
+
slot: { uploadUrl: string },
|
|
163
|
+
file: BuilderDesignSystemIndexFile,
|
|
164
|
+
): Promise<void> {
|
|
165
|
+
const mimeType = mimeTypeForFile(file);
|
|
166
|
+
const bytes = file.data;
|
|
167
|
+
const start = await fetchWithTimeout(slot.uploadUrl, {
|
|
168
|
+
method: "POST",
|
|
169
|
+
headers: {
|
|
170
|
+
"x-goog-resumable": "start",
|
|
171
|
+
"x-goog-content-length-range": `0,${bytes.byteLength}`,
|
|
172
|
+
"Content-Type": mimeType,
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
await assertOk(start, "Builder design-system upload session failed");
|
|
176
|
+
const sessionUrl = start.headers.get("Location");
|
|
177
|
+
if (!sessionUrl) {
|
|
178
|
+
throw new Error("Builder design-system upload session returned no URL.");
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const response = await fetchWithTimeout(sessionUrl, {
|
|
182
|
+
method: "PUT",
|
|
183
|
+
headers: {
|
|
184
|
+
"Content-Range": `bytes 0-${bytes.byteLength - 1}/${bytes.byteLength}`,
|
|
185
|
+
"Content-Type": mimeType,
|
|
186
|
+
},
|
|
187
|
+
body: makeBody(bytes, mimeType),
|
|
188
|
+
});
|
|
189
|
+
await assertOk(response, "Builder design-system file upload failed");
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function nonEmptyFiles(
|
|
193
|
+
files: BuilderDesignSystemIndexFile[] | undefined,
|
|
194
|
+
): BuilderDesignSystemIndexFile[] {
|
|
195
|
+
return (files ?? []).filter((file) => file.data.byteLength > 0);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function builderDesignSystemUrl(designSystemId?: string | null): string {
|
|
199
|
+
const host = trimTrailingSlash(getBuilderAppHost());
|
|
200
|
+
return designSystemId
|
|
201
|
+
? `${host}/app/design-system-intelligence/${encodeURIComponent(
|
|
202
|
+
designSystemId,
|
|
203
|
+
)}`
|
|
204
|
+
: `${host}/app/design-system-intelligence`;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export async function startBuilderDesignSystemIndex(
|
|
208
|
+
options: BuilderDesignSystemIndexOptions,
|
|
209
|
+
): Promise<BuilderDesignSystemIndexResult> {
|
|
210
|
+
const files = nonEmptyFiles(options.files);
|
|
211
|
+
const description = options.description?.trim();
|
|
212
|
+
if (description) {
|
|
213
|
+
files.unshift({
|
|
214
|
+
name: "additional-context.txt",
|
|
215
|
+
data: new TextEncoder().encode(description),
|
|
216
|
+
mimeType: "text/plain",
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
if (
|
|
220
|
+
files.length === 0 &&
|
|
221
|
+
!options.githubRepoUrl &&
|
|
222
|
+
!options.connectedProjectId
|
|
223
|
+
) {
|
|
224
|
+
throw new Error(
|
|
225
|
+
"Provide at least one .fig/code/text file or a GitHub repository URL to index with Builder.",
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const credentials = await resolveBuilderDesignSystemCredentials();
|
|
230
|
+
let uploadTokens: string[] = [];
|
|
231
|
+
if (files.length > 0) {
|
|
232
|
+
const uploadStart = await fetchWithTimeout(
|
|
233
|
+
makeBuilderDesignSystemUrl("upload/start", credentials),
|
|
234
|
+
{
|
|
235
|
+
method: "POST",
|
|
236
|
+
headers: {
|
|
237
|
+
...makeBuilderHeaders(credentials),
|
|
238
|
+
"Content-Type": "application/json",
|
|
239
|
+
},
|
|
240
|
+
body: JSON.stringify({
|
|
241
|
+
attachments: files.map((file) => ({
|
|
242
|
+
name: file.name,
|
|
243
|
+
mimetype: mimeTypeForFile(file),
|
|
244
|
+
declaredSize: file.data.byteLength,
|
|
245
|
+
})),
|
|
246
|
+
}),
|
|
247
|
+
},
|
|
248
|
+
);
|
|
249
|
+
await assertOk(uploadStart, "Builder design-system upload start failed");
|
|
250
|
+
const uploadJson = (await uploadStart.json()) as UploadStartResponse;
|
|
251
|
+
const slots = [...(uploadJson.uploads ?? [])].sort((a, b) => a.idx - b.idx);
|
|
252
|
+
if (slots.length !== files.length) {
|
|
253
|
+
throw new Error("Builder did not return upload slots for all files.");
|
|
254
|
+
}
|
|
255
|
+
for (let i = 0; i < slots.length; i++) {
|
|
256
|
+
if (slots[i].idx !== i) {
|
|
257
|
+
throw new Error(`Builder upload slot mismatch: expected ${i}.`);
|
|
258
|
+
}
|
|
259
|
+
await uploadToResumableUrl(slots[i], files[i]);
|
|
260
|
+
}
|
|
261
|
+
uploadTokens = slots.map((slot) => slot.uploadToken);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const generate = await fetchWithTimeout(
|
|
265
|
+
makeBuilderDesignSystemUrl("generate", credentials),
|
|
266
|
+
{
|
|
267
|
+
method: "POST",
|
|
268
|
+
headers: {
|
|
269
|
+
...makeBuilderHeaders(credentials),
|
|
270
|
+
"Content-Type": "application/json",
|
|
271
|
+
},
|
|
272
|
+
body: JSON.stringify({
|
|
273
|
+
uploads: uploadTokens,
|
|
274
|
+
...(options.projectName?.trim()
|
|
275
|
+
? { projectName: options.projectName.trim() }
|
|
276
|
+
: {}),
|
|
277
|
+
...(options.githubRepoUrl?.trim()
|
|
278
|
+
? { githubRepoUrl: options.githubRepoUrl.trim() }
|
|
279
|
+
: {}),
|
|
280
|
+
...(options.connectedProjectId?.trim()
|
|
281
|
+
? { connectedProjectId: options.connectedProjectId.trim() }
|
|
282
|
+
: {}),
|
|
283
|
+
...(options.selection ? { selection: options.selection } : {}),
|
|
284
|
+
...(options.devToolsVersion?.trim()
|
|
285
|
+
? { devToolsVersion: options.devToolsVersion.trim() }
|
|
286
|
+
: {}),
|
|
287
|
+
}),
|
|
288
|
+
},
|
|
289
|
+
);
|
|
290
|
+
await assertOk(generate, "Builder design-system indexing failed");
|
|
291
|
+
const generated = (await generate.json()) as GenerateResponse;
|
|
292
|
+
if (!generated.projectId || !generated.jobId || !generated.designSystemId) {
|
|
293
|
+
throw new Error(
|
|
294
|
+
"Builder design-system indexing returned an incomplete response.",
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return {
|
|
299
|
+
ok: true,
|
|
300
|
+
source: "builder",
|
|
301
|
+
projectId: generated.projectId,
|
|
302
|
+
jobId: generated.jobId,
|
|
303
|
+
designSystemId: generated.designSystemId,
|
|
304
|
+
suggestedTitle: options.projectName?.trim() || null,
|
|
305
|
+
builderUrl: builderDesignSystemUrl(generated.designSystemId),
|
|
306
|
+
status: "in-progress",
|
|
307
|
+
};
|
|
308
|
+
}
|
|
@@ -383,6 +383,31 @@ function parseBuilderCallbackBoolean(
|
|
|
383
383
|
// inlines them in the DOM. Mirrors SAFE_DATA_IMAGE in sanitize-html.ts.
|
|
384
384
|
export const AVATAR_RASTER_MIME = /^data:image\/(png|jpe?g|gif|webp);/i;
|
|
385
385
|
|
|
386
|
+
export function resolveAvatarEmailParam(
|
|
387
|
+
pathname: string,
|
|
388
|
+
appBasePath = "",
|
|
389
|
+
): string {
|
|
390
|
+
const base = appBasePath.replace(/\/+$/, "");
|
|
391
|
+
const avatarPaths = Array.from(
|
|
392
|
+
new Set([`${base}/_agent-native/avatar/`, "/_agent-native/avatar/"]),
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
for (const avatarPath of avatarPaths) {
|
|
396
|
+
const avatarIndex = pathname.indexOf(avatarPath);
|
|
397
|
+
if (avatarIndex >= 0) {
|
|
398
|
+
return pathname
|
|
399
|
+
.slice(avatarIndex + avatarPath.length)
|
|
400
|
+
.replace(/^\/+/, "")
|
|
401
|
+
.split("/")[0];
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const firstSegment = pathname.replace(/^\/+/, "").split("/")[0] ?? "";
|
|
406
|
+
if (!firstSegment || firstSegment === "_agent-native") return "";
|
|
407
|
+
if (base && firstSegment === base.replace(/^\/+/, "")) return "";
|
|
408
|
+
return firstSegment;
|
|
409
|
+
}
|
|
410
|
+
|
|
386
411
|
async function detectUsageEngineName(
|
|
387
412
|
event: H3Event,
|
|
388
413
|
userEmail: string | undefined,
|
|
@@ -3010,9 +3035,10 @@ export function createCoreRoutesPlugin(
|
|
|
3010
3035
|
`${P}/avatar`,
|
|
3011
3036
|
defineEventHandler(async (event: H3Event) => {
|
|
3012
3037
|
const method = getMethod(event);
|
|
3013
|
-
const emailParam = (
|
|
3014
|
-
.
|
|
3015
|
-
|
|
3038
|
+
const emailParam = resolveAvatarEmailParam(
|
|
3039
|
+
event.url?.pathname || "",
|
|
3040
|
+
getConfiguredAppBasePath(),
|
|
3041
|
+
);
|
|
3016
3042
|
|
|
3017
3043
|
if (method === "GET") {
|
|
3018
3044
|
if (!emailParam) {
|
|
@@ -386,6 +386,14 @@ export {
|
|
|
386
386
|
deleteBuilderCredentials,
|
|
387
387
|
resolveSecret,
|
|
388
388
|
} from "./credential-provider.js";
|
|
389
|
+
export {
|
|
390
|
+
builderDesignSystemUrl,
|
|
391
|
+
getBuilderDesignSystemsBaseUrl,
|
|
392
|
+
startBuilderDesignSystemIndex,
|
|
393
|
+
type BuilderDesignSystemIndexFile,
|
|
394
|
+
type BuilderDesignSystemIndexOptions,
|
|
395
|
+
type BuilderDesignSystemIndexResult,
|
|
396
|
+
} from "./builder-design-systems.js";
|
|
389
397
|
export {
|
|
390
398
|
getBuilderBranchProjectId,
|
|
391
399
|
isBuilderBranchingEnabled,
|
|
@@ -30,6 +30,13 @@ import { createBuilderEngine } from "../agent/engine/builder-engine.js";
|
|
|
30
30
|
import { appStateGet } from "../application-state/store.js";
|
|
31
31
|
import { getOrgContext } from "../org/context.js";
|
|
32
32
|
import { transcribeWithBuilder } from "../transcription/builder-transcription.js";
|
|
33
|
+
import {
|
|
34
|
+
applyVoiceContextReplacements,
|
|
35
|
+
buildVoiceGuidanceBlock,
|
|
36
|
+
parseVoiceContextPack,
|
|
37
|
+
voiceContextTermsOnly,
|
|
38
|
+
type VoiceContextPack,
|
|
39
|
+
} from "../voice/index.js";
|
|
33
40
|
import { getSession } from "./auth.js";
|
|
34
41
|
import {
|
|
35
42
|
resolveHasBuilderPrivateKey,
|
|
@@ -146,6 +153,20 @@ export function createTranscribeVoiceHandler() {
|
|
|
146
153
|
Buffer.from(instructionsPart.data).toString("utf8"),
|
|
147
154
|
)
|
|
148
155
|
: undefined;
|
|
156
|
+
const voiceContextPart = parts?.find(
|
|
157
|
+
(p) => p.name === "voiceContext" || p.name === "contextPack",
|
|
158
|
+
);
|
|
159
|
+
const voiceContext = voiceContextPart?.data
|
|
160
|
+
? parseVoiceContextPack(
|
|
161
|
+
Buffer.from(voiceContextPart.data).toString("utf8"),
|
|
162
|
+
)
|
|
163
|
+
: undefined;
|
|
164
|
+
const voiceGuidance = buildVoiceGuidanceBlock({
|
|
165
|
+
instructions,
|
|
166
|
+
contextPack: voiceContextTermsOnly(voiceContext),
|
|
167
|
+
});
|
|
168
|
+
const applyVoiceContext = (value: string) =>
|
|
169
|
+
applyVoiceContextReplacements(value, voiceContext).trim();
|
|
149
170
|
|
|
150
171
|
// Resolve provider preference. Per-request "provider" form field takes
|
|
151
172
|
// precedence (the desktop client sends it on every dictation press),
|
|
@@ -220,7 +241,7 @@ export function createTranscribeVoiceHandler() {
|
|
|
220
241
|
// does not want audio uploaded to any external provider. The client
|
|
221
242
|
// shouldn't hit this endpoint when "browser" is selected; this is a
|
|
222
243
|
// defense-in-depth refusal.
|
|
223
|
-
if (providerPref === "browser") {
|
|
244
|
+
if (providerPref === "browser" && !transcriptText) {
|
|
224
245
|
setResponseStatus(event, 400);
|
|
225
246
|
return {
|
|
226
247
|
error:
|
|
@@ -238,7 +259,8 @@ export function createTranscribeVoiceHandler() {
|
|
|
238
259
|
return await cleanupTranscriptText({
|
|
239
260
|
event,
|
|
240
261
|
text: transcriptText,
|
|
241
|
-
instructions,
|
|
262
|
+
instructions: voiceGuidance,
|
|
263
|
+
contextPack: voiceContext,
|
|
242
264
|
providerPref,
|
|
243
265
|
hasBuilderPrivateKey,
|
|
244
266
|
withRequestContext,
|
|
@@ -282,9 +304,9 @@ export function createTranscribeVoiceHandler() {
|
|
|
282
304
|
mimeType: mime,
|
|
283
305
|
apiKey: geminiKey,
|
|
284
306
|
language: language || undefined,
|
|
285
|
-
instructions,
|
|
307
|
+
instructions: voiceGuidance,
|
|
286
308
|
});
|
|
287
|
-
const trimmed = text
|
|
309
|
+
const trimmed = applyVoiceContext(text);
|
|
288
310
|
if (!trimmed) {
|
|
289
311
|
setResponseStatus(event, 502);
|
|
290
312
|
return { error: "Gemini returned an empty transcript." };
|
|
@@ -318,9 +340,9 @@ export function createTranscribeVoiceHandler() {
|
|
|
318
340
|
? BUILDER_GEMINI_TRANSCRIPTION_MODEL
|
|
319
341
|
: undefined,
|
|
320
342
|
language: language || undefined,
|
|
321
|
-
instructions,
|
|
343
|
+
instructions: voiceGuidance,
|
|
322
344
|
});
|
|
323
|
-
return { text: (result.text ?? "")
|
|
345
|
+
return { text: applyVoiceContext(result.text ?? "") };
|
|
324
346
|
} catch (err) {
|
|
325
347
|
const message = (err as Error)?.message ?? String(err);
|
|
326
348
|
if (message.includes("credits exhausted")) {
|
|
@@ -352,7 +374,8 @@ export function createTranscribeVoiceHandler() {
|
|
|
352
374
|
audioBytes,
|
|
353
375
|
mime,
|
|
354
376
|
language,
|
|
355
|
-
instructions,
|
|
377
|
+
instructions: voiceGuidance,
|
|
378
|
+
contextPack: voiceContext,
|
|
356
379
|
});
|
|
357
380
|
}
|
|
358
381
|
|
|
@@ -368,9 +391,9 @@ export function createTranscribeVoiceHandler() {
|
|
|
368
391
|
mimeType: mime,
|
|
369
392
|
model: BUILDER_GEMINI_TRANSCRIPTION_MODEL,
|
|
370
393
|
language: language || undefined,
|
|
371
|
-
instructions,
|
|
394
|
+
instructions: voiceGuidance,
|
|
372
395
|
});
|
|
373
|
-
return { text: (result.text ?? "")
|
|
396
|
+
return { text: applyVoiceContext(result.text ?? "") };
|
|
374
397
|
} catch (err) {
|
|
375
398
|
const message = (err as Error)?.message ?? String(err);
|
|
376
399
|
// Surface 402 (credits exhausted) as a 402 so the client can show
|
|
@@ -395,9 +418,9 @@ export function createTranscribeVoiceHandler() {
|
|
|
395
418
|
mimeType: mime,
|
|
396
419
|
apiKey: geminiKey,
|
|
397
420
|
language: language || undefined,
|
|
398
|
-
instructions,
|
|
421
|
+
instructions: voiceGuidance,
|
|
399
422
|
});
|
|
400
|
-
const trimmed = text
|
|
423
|
+
const trimmed = applyVoiceContext(text);
|
|
401
424
|
if (trimmed) {
|
|
402
425
|
console.log(`[transcribe-voice] Gemini → ${trimmed.length} chars`);
|
|
403
426
|
return { text: trimmed };
|
|
@@ -465,7 +488,8 @@ export function createTranscribeVoiceHandler() {
|
|
|
465
488
|
audioBytes,
|
|
466
489
|
mime,
|
|
467
490
|
language,
|
|
468
|
-
instructions,
|
|
491
|
+
instructions: voiceGuidance,
|
|
492
|
+
contextPack: voiceContext,
|
|
469
493
|
});
|
|
470
494
|
});
|
|
471
495
|
}
|
|
@@ -484,6 +508,7 @@ async function callWhisperCompat({
|
|
|
484
508
|
mime,
|
|
485
509
|
language,
|
|
486
510
|
instructions,
|
|
511
|
+
contextPack,
|
|
487
512
|
}: {
|
|
488
513
|
event: H3Event;
|
|
489
514
|
provider: {
|
|
@@ -496,6 +521,7 @@ async function callWhisperCompat({
|
|
|
496
521
|
mime: string;
|
|
497
522
|
language?: string;
|
|
498
523
|
instructions?: string;
|
|
524
|
+
contextPack?: VoiceContextPack;
|
|
499
525
|
}): Promise<{ text: string } | { error: string }> {
|
|
500
526
|
const ext = pickExtension(mime);
|
|
501
527
|
const filename = `composer-voice.${ext}`;
|
|
@@ -531,7 +557,12 @@ async function callWhisperCompat({
|
|
|
531
557
|
};
|
|
532
558
|
}
|
|
533
559
|
const data = (await res.json()) as { text?: string };
|
|
534
|
-
return {
|
|
560
|
+
return {
|
|
561
|
+
text: applyVoiceContextReplacements(
|
|
562
|
+
(data.text ?? "").trim(),
|
|
563
|
+
contextPack,
|
|
564
|
+
).trim(),
|
|
565
|
+
};
|
|
535
566
|
} catch (err) {
|
|
536
567
|
setResponseStatus(event, 502);
|
|
537
568
|
return {
|
|
@@ -549,6 +580,7 @@ async function cleanupTranscriptText({
|
|
|
549
580
|
event,
|
|
550
581
|
text,
|
|
551
582
|
instructions,
|
|
583
|
+
contextPack,
|
|
552
584
|
providerPref,
|
|
553
585
|
hasBuilderPrivateKey,
|
|
554
586
|
withRequestContext,
|
|
@@ -557,6 +589,7 @@ async function cleanupTranscriptText({
|
|
|
557
589
|
event: H3Event;
|
|
558
590
|
text: string;
|
|
559
591
|
instructions?: string;
|
|
592
|
+
contextPack?: VoiceContextPack;
|
|
560
593
|
providerPref?: string;
|
|
561
594
|
hasBuilderPrivateKey: () => Promise<boolean>;
|
|
562
595
|
withRequestContext: <T>(fn: () => Promise<T>) => Promise<T>;
|
|
@@ -564,9 +597,11 @@ async function cleanupTranscriptText({
|
|
|
564
597
|
}): Promise<{ text: string } | { error: string }> {
|
|
565
598
|
const original = text.trim();
|
|
566
599
|
if (!original) return { text: "" };
|
|
600
|
+
const finalizeText = (value: string) =>
|
|
601
|
+
applyVoiceContextReplacements(value || original, contextPack).trim();
|
|
567
602
|
|
|
568
603
|
if (providerPref === "browser") {
|
|
569
|
-
return { text: original };
|
|
604
|
+
return { text: finalizeText(original) };
|
|
570
605
|
}
|
|
571
606
|
|
|
572
607
|
if (providerPref === "builder" || providerPref === "builder-gemini") {
|
|
@@ -581,7 +616,7 @@ async function cleanupTranscriptText({
|
|
|
581
616
|
const cleaned = await withRequestContext(() =>
|
|
582
617
|
cleanupWithBuilder({ text: original, instructions }),
|
|
583
618
|
);
|
|
584
|
-
return { text: cleaned || original };
|
|
619
|
+
return { text: finalizeText(cleaned || original) };
|
|
585
620
|
} catch (err) {
|
|
586
621
|
setResponseStatus(event, 502);
|
|
587
622
|
return {
|
|
@@ -605,7 +640,7 @@ async function cleanupTranscriptText({
|
|
|
605
640
|
apiKey: geminiKey,
|
|
606
641
|
instructions,
|
|
607
642
|
});
|
|
608
|
-
return { text: cleaned || original };
|
|
643
|
+
return { text: finalizeText(cleaned || original) };
|
|
609
644
|
} catch (err) {
|
|
610
645
|
setResponseStatus(event, 502);
|
|
611
646
|
return {
|
|
@@ -631,7 +666,7 @@ async function cleanupTranscriptText({
|
|
|
631
666
|
apiKey,
|
|
632
667
|
instructions,
|
|
633
668
|
});
|
|
634
|
-
return { text: cleaned || original };
|
|
669
|
+
return { text: finalizeText(cleaned || original) };
|
|
635
670
|
} catch (err) {
|
|
636
671
|
setResponseStatus(event, 502);
|
|
637
672
|
return {
|
|
@@ -645,7 +680,7 @@ async function cleanupTranscriptText({
|
|
|
645
680
|
const cleaned = await withRequestContext(() =>
|
|
646
681
|
cleanupWithBuilder({ text: original, instructions }),
|
|
647
682
|
);
|
|
648
|
-
if (cleaned) return { text: cleaned };
|
|
683
|
+
if (cleaned) return { text: finalizeText(cleaned) };
|
|
649
684
|
} catch {
|
|
650
685
|
// Fall through to BYOK providers, then raw text.
|
|
651
686
|
}
|
|
@@ -659,7 +694,7 @@ async function cleanupTranscriptText({
|
|
|
659
694
|
apiKey: geminiKey,
|
|
660
695
|
instructions,
|
|
661
696
|
});
|
|
662
|
-
if (cleaned) return { text: cleaned };
|
|
697
|
+
if (cleaned) return { text: finalizeText(cleaned) };
|
|
663
698
|
} catch {
|
|
664
699
|
// Fall through.
|
|
665
700
|
}
|
|
@@ -674,7 +709,7 @@ async function cleanupTranscriptText({
|
|
|
674
709
|
apiKey: groqKey,
|
|
675
710
|
instructions,
|
|
676
711
|
});
|
|
677
|
-
if (cleaned) return { text: cleaned };
|
|
712
|
+
if (cleaned) return { text: finalizeText(cleaned) };
|
|
678
713
|
} catch {
|
|
679
714
|
// Fall through.
|
|
680
715
|
}
|
|
@@ -689,13 +724,13 @@ async function cleanupTranscriptText({
|
|
|
689
724
|
apiKey: openaiKey,
|
|
690
725
|
instructions,
|
|
691
726
|
});
|
|
692
|
-
if (cleaned) return { text: cleaned };
|
|
727
|
+
if (cleaned) return { text: finalizeText(cleaned) };
|
|
693
728
|
} catch {
|
|
694
729
|
// Fall through.
|
|
695
730
|
}
|
|
696
731
|
}
|
|
697
732
|
|
|
698
|
-
return { text: original };
|
|
733
|
+
return { text: finalizeText(original) };
|
|
699
734
|
}
|
|
700
735
|
|
|
701
736
|
async function cleanupWithBuilder({
|
|
@@ -87,6 +87,27 @@ export function isAgentNativeFirstPartyAppOrigin(
|
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
export function isBuilderIoEmbedOrigin(
|
|
91
|
+
origin: string | null | undefined,
|
|
92
|
+
): boolean {
|
|
93
|
+
if (!origin) return false;
|
|
94
|
+
try {
|
|
95
|
+
const url = new URL(origin);
|
|
96
|
+
const hostname = url.hostname.toLowerCase();
|
|
97
|
+
return (
|
|
98
|
+
url.protocol === "https:" &&
|
|
99
|
+
!url.username &&
|
|
100
|
+
!url.password &&
|
|
101
|
+
(hostname === "builder.io" ||
|
|
102
|
+
hostname.endsWith(".builder.io") ||
|
|
103
|
+
hostname === "builder.my" ||
|
|
104
|
+
hostname.endsWith(".builder.my"))
|
|
105
|
+
);
|
|
106
|
+
} catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
90
111
|
export function isMcpEmbedCorsOrigin(
|
|
91
112
|
origin: string | null | undefined,
|
|
92
113
|
): boolean {
|
|
@@ -96,7 +117,8 @@ export function isMcpEmbedCorsOrigin(
|
|
|
96
117
|
isClaudeMcpContentOrigin(origin) ||
|
|
97
118
|
isChatGptMcpSandboxOrigin(origin) ||
|
|
98
119
|
isMcpProductHostOrigin(origin) ||
|
|
99
|
-
isAgentNativeFirstPartyAppOrigin(origin)
|
|
120
|
+
isAgentNativeFirstPartyAppOrigin(origin) ||
|
|
121
|
+
isBuilderIoEmbedOrigin(origin)
|
|
100
122
|
);
|
|
101
123
|
}
|
|
102
124
|
|