@agent-native/core 0.141.7 → 0.144.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/agent-native.eject.json +9 -0
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/provider-api/SKILL.md +19 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/analytics/AGENTS.md +35 -38
- package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +1 -1
- package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +17 -22
- package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +1 -1
- package/corpus/templates/analytics/actions/navigate.ts +4 -5
- package/corpus/templates/analytics/actions/provider-api-register.ts +50 -0
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +44 -11
- package/corpus/templates/analytics/actions/test-custom-api-connection.ts +106 -0
- package/corpus/templates/analytics/app/components/CustomApiCard.tsx +430 -0
- package/corpus/templates/analytics/app/i18n-data.ts +680 -0
- package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +6 -0
- package/corpus/templates/analytics/app/lib/sql-query.ts +33 -6
- package/corpus/templates/analytics/app/pages/DataSources.tsx +4 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-load-reliably-during-background-data-sw.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-remain-responsive-while-historical-data.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-query-results-now-render-as-a-table-with-csv-downl.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-connect-public-https-custom-apis-and-hand-tested-endpoints-t.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-durable-agent-worker-memory.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-live-dashboard-panels-use-the-shared-query-timeout.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-on-demand-billing-is-available-as-a-native-dashboard-with-ta.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-visible-dashboard-names-are-unique.md +6 -0
- package/corpus/templates/analytics/netlify.toml +7 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +4 -0
- package/corpus/templates/analytics/server/db/index.ts +27 -0
- package/corpus/templates/analytics/server/db/schema.ts +10 -0
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +227 -60
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +156 -45
- package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +227 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
- package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +1 -0
- package/corpus/templates/analytics/server/plugins/db.ts +52 -18
- package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +28 -2
- package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +16 -1
- package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/assets/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/assets/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/brain/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/brain/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/brain/actions/list-connection-providers.ts +24 -3
- package/corpus/templates/brain/app/lib/dispatch-links.ts +44 -0
- package/corpus/templates/brain/app/routes/sources.tsx +15 -7
- package/corpus/templates/brain/changelog/2026-08-06-brain-provider-setup-links-open-dispatch-correctly-in-standa.md +6 -0
- package/corpus/templates/brain/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +26 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/calendar/AGENTS.md +11 -32
- package/corpus/templates/calendar/actions/update-event.ts +107 -1
- package/corpus/templates/calendar/app/components/calendar/EventCalendarSelect.tsx +83 -0
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +57 -0
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +59 -73
- package/corpus/templates/calendar/app/hooks/use-events.ts +4 -1
- package/corpus/templates/calendar/app/i18n-data.ts +20 -0
- package/corpus/templates/calendar/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-06-existing-events-can-move-between-connected-google-account-ca.md +6 -0
- package/corpus/templates/calendar/server/lib/google-calendar.ts +101 -0
- package/corpus/templates/calendar/server/plugins/agent-chat.ts +7 -1
- package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/clips/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/clips/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +9 -24
- package/corpus/templates/clips/app/components/editor/timeline-geometry.ts +15 -0
- package/corpus/templates/clips/app/components/editor/waveform.tsx +4 -17
- package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +14 -3
- package/corpus/templates/clips/app/components/player/player-controls.tsx +0 -3
- package/corpus/templates/clips/app/components/player/scrubber.tsx +2 -33
- package/corpus/templates/clips/app/components/player/video-player.tsx +58 -11
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +28 -38
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +21 -27
- package/corpus/templates/clips/changelog/2026-08-06-clips-recovers-from-stalled-recording-setup-without-requirin.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-clips-starts-faster-after-a-deploy-or-idle-period-startup-no.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-deleting-a-recording-returns-cleanly-to-the-library-and-fit-.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-hide-clip-insights-from-viewers-without-analytics-access.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-trimmed-clips-play-on-a-clean-timeline-without-cut-markers.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +48 -20
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +275 -74
- package/corpus/templates/clips/desktop/src/lib/recording-start-guard.ts +84 -0
- package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +14 -4
- package/corpus/templates/clips/server/plugins/db.ts +214 -26
- package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/content/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/content/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/crm/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/crm/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/crm/changelog/2026-08-06-crm-starts-faster-after-a-deploy-or-idle-period-one-time-dat.md +6 -0
- package/corpus/templates/crm/server/plugins/db.ts +11 -8
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +36 -1
- package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/design/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/design/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/design/actions/import-from-url.ts +1 -1
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +27 -18
- package/corpus/templates/design/app/pages/Index.tsx +6 -2
- package/corpus/templates/design/changelog/2026-08-05-deleting-a-design-from-the-home-page-no-longer-leaves-the-ap.md +6 -0
- package/corpus/templates/design/changelog/2026-08-05-renaming-a-layer-now-focuses-its-name-field-automatically.md +6 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/dispatch/AGENTS.md +8 -1
- package/corpus/templates/dispatch/app/dispatch-extensions.tsx +1 -0
- package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +30 -15
- package/corpus/templates/dispatch/app/i18n-data.ts +131 -0
- package/corpus/templates/dispatch/app/routes/admin._index.tsx +4 -0
- package/corpus/templates/dispatch/app/routes/admin.agents.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.approvals.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.apps.$appId.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.apps.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.audit.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.automations.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.destinations.tsx +4 -0
- package/corpus/templates/dispatch/app/routes/admin.dreams.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.identities.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.integrations.tsx +4 -0
- package/corpus/templates/dispatch/app/routes/admin.messaging.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.metrics.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.new-app.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.operations.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.thread-debug.tsx +4 -0
- package/corpus/templates/dispatch/app/routes/admin.transactional-email.$appId.$id.tsx +4 -0
- package/corpus/templates/dispatch/app/routes/admin.transactional-email.tsx +4 -0
- package/corpus/templates/dispatch/app/routes/admin.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.vault.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.workspace.tsx +1 -0
- package/corpus/templates/dispatch/changelog/2026-08-06-dispatch-keeps-everyday-navigation-focused-while-management-.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-06-ready-workspace-apps-stay-one-click-away-in-a-compact-dispat.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-06-shared-vault-values-and-management-are-now-restricted-to-wor.md +6 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/factory/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/factory/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/forms/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/forms/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/forms/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/forms/server/plugins/agent-chat.ts +4 -0
- package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/macros/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/macros/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/mail/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/mail/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/mail/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/plan/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/plan/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +48 -5
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +37 -1
- package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +6 -0
- package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +15 -2
- package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +29 -24
- package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/slides/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/slides/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/slides/AGENTS.md +17 -21
- package/corpus/templates/slides/_gitignore +1 -0
- package/corpus/templates/slides/actions/export-pptx.ts +470 -36
- package/corpus/templates/slides/actions/get-deck.ts +12 -0
- package/corpus/templates/slides/actions/import-file.ts +175 -139
- package/corpus/templates/slides/actions/import-google-slides-reference.ts +271 -12
- package/corpus/templates/slides/actions/import-pptx.ts +193 -68
- package/corpus/templates/slides/actions/patch-deck.ts +51 -0
- package/corpus/templates/slides/actions/update-slide.ts +29 -3
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -13
- package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +5 -1
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +25 -12
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +112 -57
- package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +202 -0
- package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +26 -14
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +173 -0
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +182 -141
- package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +1 -0
- package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +18 -0
- package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +85 -0
- package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -0
- package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +15 -0
- package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +27 -1
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +72 -11
- package/corpus/templates/slides/app/lib/deck-preview-frame.ts +15 -0
- package/corpus/templates/slides/app/lib/deck-share-links.ts +9 -0
- package/corpus/templates/slides/app/lib/export-pptx-client.ts +89 -0
- package/corpus/templates/slides/app/lib/import-uploaded-deck.ts +89 -0
- package/corpus/templates/slides/app/lib/slide-animation-elements.ts +3 -0
- package/corpus/templates/slides/app/pages/Index.tsx +172 -15
- package/corpus/templates/slides/changelog/2026-08-06-clicking-the-gray-canvas-around-a-slide-clears-its-selection.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-deck-thumbnails-keep-a-consistent-listing-frame-across-aspec.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-deep-linked-decks-open-directly-instead-of-being-interrupted.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-google-slides-exports-now-show-clear-import-steps-when-direc.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-import-pdf-google-slides-and-powerpoint-decks-directly-from-.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-imported-powerpoint-exports-keep-text-and-images-editable-an.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-presentation-prompts-continue-adding-rendered-slides-until-t.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-public-decks-now-share-read-only-presentation-links-by-defau.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-slides-offers-a-direct-connect-google-button-when-a-drive-co.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-slides-preserve-uploaded-pdf-layouts-accept-larger-reference.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-styled-words-stay-part-of-their-text-box-instead-of-becoming.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-uploaded-decks-keep-their-slides-and-visuals-when-you-improv.md +6 -0
- package/corpus/templates/slides/server/handlers/google-docs-auth.ts +7 -20
- package/corpus/templates/slides/server/handlers/import/html-converter.ts +247 -13
- package/corpus/templates/slides/server/handlers/import/pptx-assets.ts +67 -0
- package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +2 -0
- package/corpus/templates/slides/server/handlers/uploads.ts +7 -3
- package/corpus/templates/slides/server/lib/chat-attachments.ts +7 -4
- package/corpus/templates/slides/server/lib/emails.ts +7 -2
- package/corpus/templates/slides/server/lib/google-docs-error.ts +50 -0
- package/corpus/templates/slides/server/lib/google-docs-oauth.ts +1 -0
- package/corpus/templates/slides/server/lib/import-asset-storage.ts +127 -0
- package/corpus/templates/slides/server/lib/source-import.ts +167 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +12 -3
- package/corpus/templates/slides/server/routes/api/import-assets/[token].get.ts +70 -0
- package/corpus/templates/slides/shared/upload-types.ts +3 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/agent/production-agent.d.ts +17 -0
- package/dist/agent/production-agent.js +72 -1
- package/dist/cli/agent-plugin.d.ts +112 -0
- package/dist/cli/agent-plugin.js +1081 -0
- package/dist/cli/app-skill.js +39 -1
- package/dist/cli/code-agent-executor.d.ts +3 -0
- package/dist/cli/code-agent-executor.js +51 -13
- package/dist/cli/index.js +13 -0
- package/dist/cli/templates-meta.js +1 -1
- package/dist/client/AgentPanel.d.ts +3 -1
- package/dist/client/AgentPanel.js +9 -2
- package/dist/client/AssistantChat.d.ts +8 -0
- package/dist/client/AssistantChat.js +23 -8
- package/dist/client/NewWorkspaceAppFlow.js +1 -0
- package/dist/client/agent-chat-adapter.js +123 -4
- package/dist/client/assistant-ui-recovery.d.ts +2 -1
- package/dist/client/assistant-ui-recovery.js +7 -3
- package/dist/client/onboarding/FirstRunOnboarding.js +11 -4
- package/dist/client/org/TeamPage.js +1 -1
- package/dist/client/require-session.js +1 -1
- package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
- package/dist/client/resources/McpConnectionSuggestion.js +27 -10
- package/dist/client/resources/McpIntegrationDialog.js +77 -45
- package/dist/client/resources/mcp-integration-catalog.d.ts +13 -1
- package/dist/client/resources/mcp-integration-catalog.js +255 -2
- package/dist/client/resources/mcp-integration-logos.js +18 -2
- package/dist/client/settings/AccountSettingsCard.js +2 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/client.d.ts +9 -0
- package/dist/db/client.js +51 -16
- package/dist/db/create-get-db.js +2 -2
- package/dist/db/ddl-guard.d.ts +11 -10
- package/dist/db/ddl-guard.js +40 -12
- package/dist/deploy/build.d.ts +2 -0
- package/dist/deploy/build.js +97 -4
- package/dist/deploy/workspace-deploy.js +0 -2
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/guards/no-env-credentials.js +9 -0
- package/dist/ingestion/index.d.ts +1 -1
- package/dist/ingestion/pptx.d.ts +68 -0
- package/dist/ingestion/pptx.js +660 -213
- package/dist/integrations/plugin.js +9 -6
- package/dist/jobs/scheduler.js +79 -23
- package/dist/localization/default-messages.d.ts +54 -0
- package/dist/localization/default-messages.js +57 -2
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/mcp-client/oauth-routes.d.ts +2 -0
- package/dist/mcp-client/oauth-routes.js +73 -6
- package/dist/observability/routes.d.ts +5 -5
- package/dist/onboarding/app-profile.js +11 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/resources/store.js +15 -1
- package/dist/scripts/call-agent.js +34 -4
- package/dist/secrets/routes.d.ts +3 -3
- package/dist/server/agent-chat/action-filters-a2a.d.ts +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +36 -1
- package/dist/server/agent-chat-plugin.js +29 -8
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.js +47 -11
- package/dist/server/better-auth-instance.js +5 -3
- package/dist/server/core-routes-plugin.d.ts +8 -1
- package/dist/server/core-routes-plugin.js +28 -3
- package/dist/server/credential-provider.d.ts +3 -3
- package/dist/server/credential-provider.js +90 -4
- package/dist/server/onboarding-html.d.ts +2 -0
- package/dist/server/onboarding-html.js +115 -29
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/self-dispatch.d.ts +5 -4
- package/dist/server/self-dispatch.js +25 -14
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.js +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/cache-control.d.ts +26 -2
- package/dist/shared/cache-control.js +43 -2
- package/dist/shared/password-policy.d.ts +3 -0
- package/dist/shared/password-policy.js +3 -0
- package/dist/sharing/actions/set-resource-visibility.js +16 -4
- package/dist/sharing/registry.d.ts +14 -0
- package/dist/styles/agent-native.css +6 -0
- package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/workspace-root/AGENTS.md +7 -0
- package/dist/user-profile/actions/change-password.js +8 -3
- package/dist/user-profile/actions/set-password.js +5 -1
- package/dist/vite/action-types-plugin.js +59 -0
- package/docs/content/creating-templates.mdx +1 -1
- package/docs/content/getting-started-actions.mdx +38 -189
- package/docs/content/getting-started-database.mdx +80 -164
- package/docs/content/getting-started-pages.mdx +44 -155
- package/docs/content/getting-started.mdx +26 -106
- package/docs/content/skills-guide.mdx +13 -0
- package/package.json +6 -2
- package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/workspace-root/AGENTS.md +7 -0
|
@@ -8,6 +8,7 @@ type AssistantUiStaleIndexErrorBoundaryProps = {
|
|
|
8
8
|
/** Remount children when the recovery scope changes. */
|
|
9
9
|
remountOnResetKey?: boolean;
|
|
10
10
|
componentName?: string;
|
|
11
|
+
fallback?: React.ReactNode;
|
|
11
12
|
children: React.ReactNode;
|
|
12
13
|
};
|
|
13
14
|
type AssistantUiStaleIndexErrorBoundaryState = {
|
|
@@ -26,7 +27,7 @@ export declare class AssistantUiStaleIndexErrorBoundary extends React.Component<
|
|
|
26
27
|
componentDidCatch(error: unknown, info: React.ErrorInfo): void;
|
|
27
28
|
componentDidUpdate(prevProps: AssistantUiStaleIndexErrorBoundaryProps, prevState: AssistantUiStaleIndexErrorBoundaryState): void;
|
|
28
29
|
componentWillUnmount(): void;
|
|
29
|
-
render(): React.JSX.Element | null;
|
|
30
|
+
render(): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | Iterable<React.ReactNode> | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | React.ReactPortal | null | undefined> | null;
|
|
30
31
|
}
|
|
31
32
|
export declare function AssistantMessageListErrorBoundary({ resetKey, children, }: {
|
|
32
33
|
resetKey: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { IconLoader2 } from "@tabler/icons-react";
|
|
2
3
|
import React from "react";
|
|
3
4
|
import { captureError } from "./analytics.js";
|
|
4
5
|
export function assistantUiRecoverableRenderErrorKind(error) {
|
|
@@ -114,7 +115,7 @@ export class AssistantUiStaleIndexErrorBoundary extends React.Component {
|
|
|
114
115
|
this.state.recovery.retryCount > MAX_ASSISTANT_UI_RECOVERABLE_RETRIES) {
|
|
115
116
|
throw this.state.error;
|
|
116
117
|
}
|
|
117
|
-
return null;
|
|
118
|
+
return this.props.fallback ?? null;
|
|
118
119
|
}
|
|
119
120
|
const fragmentKey = this.props.remountOnResetKey === false
|
|
120
121
|
? String(this.state.retryToken)
|
|
@@ -123,5 +124,8 @@ export class AssistantUiStaleIndexErrorBoundary extends React.Component {
|
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
export function AssistantMessageListErrorBoundary({ resetKey, children, }) {
|
|
126
|
-
return (_jsx(AssistantUiStaleIndexErrorBoundary, { resetKey: resetKey, remountOnResetKey: false, componentName: "AssistantMessageList", children: children }));
|
|
127
|
+
return (_jsx(AssistantUiStaleIndexErrorBoundary, { resetKey: resetKey, remountOnResetKey: false, componentName: "AssistantMessageList", fallback: _jsx(AssistantUiRecoverableRenderFallback, {}), children: children }));
|
|
128
|
+
}
|
|
129
|
+
function AssistantUiRecoverableRenderFallback() {
|
|
130
|
+
return (_jsxs("div", { "aria-label": "Updating chat", className: "flex min-h-8 items-center justify-center text-muted-foreground", role: "status", children: [_jsx(IconLoader2, { className: "size-3.5 animate-spin", "aria-hidden": "true" }), _jsx("span", { className: "sr-only", children: "Updating chat..." })] }));
|
|
127
131
|
}
|
|
@@ -4,7 +4,7 @@ import { IconArrowRight, IconBrandGithub, IconCheck, IconExternalLink, IconInfoC
|
|
|
4
4
|
import React, { useMemo, useState } from "react";
|
|
5
5
|
import { appPath } from "../api-path.js";
|
|
6
6
|
import { Tooltip, TooltipContent, TooltipTrigger, } from "../components/ui/tooltip.js";
|
|
7
|
-
import { buildMcpOAuthStartUrl, filterMcpIntegrations, getDefaultMcpIntegrations, navigateToMcpOAuthStart, } from "../resources/mcp-integration-catalog.js";
|
|
7
|
+
import { buildMcpOAuthStartUrl, filterMcpIntegrations, getDefaultMcpIntegrations, navigateToMcpOAuthStart, shouldOfferMcpIntegrationOrganizationScope, } from "../resources/mcp-integration-catalog.js";
|
|
8
8
|
import { McpIntegrationDialog } from "../resources/McpIntegrationDialog.js";
|
|
9
9
|
import { formatMcpServerError, useCreateMcpServer, useMcpServers, } from "../resources/use-mcp-servers.js";
|
|
10
10
|
import { useBuilderConnectFlow } from "../settings/useBuilderStatus.js";
|
|
@@ -112,6 +112,10 @@ export function FirstRunOnboarding({ skipIntegrations = shouldSkipFirstRunIntegr
|
|
|
112
112
|
connectingIntegrationId === integration.id) {
|
|
113
113
|
return;
|
|
114
114
|
}
|
|
115
|
+
if (shouldOfferMcpIntegrationOrganizationScope(integration, hasOrg, canCreateOrgMcp)) {
|
|
116
|
+
setIntegrationDialogId(integration.id);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
115
119
|
if (integration.authMode === "none" &&
|
|
116
120
|
integration.connectionMode === "direct") {
|
|
117
121
|
setConnectingIntegrationId(integration.id);
|
|
@@ -165,7 +169,7 @@ export function FirstRunOnboarding({ skipIntegrations = shouldSkipFirstRunIntegr
|
|
|
165
169
|
return (_jsx(OnboardingShell, { profile: profile, screen: "intro", children: _jsxs("div", { className: "mx-auto flex w-full max-w-lg flex-col items-center text-center", children: [_jsxs("h1", { className: "text-3xl font-semibold tracking-[-0.05em] sm:text-4xl", children: ["Free forever.", _jsx("br", {}), _jsx("span", { className: "text-primary", children: "Open source for life." })] }), _jsxs("div", { className: "mt-7 grid w-full gap-2 text-left sm:grid-cols-3", children: [_jsxs("div", { className: "rounded-lg border border-border bg-card px-3 py-3", children: [_jsx("p", { className: "text-xs font-medium", children: "Fully customizable" }), _jsx("p", { className: "mt-1 text-[11px] leading-4 text-muted-foreground", children: "Change the UI, code, and behavior." })] }), _jsxs("div", { className: "rounded-lg border border-border bg-card px-3 py-3", children: [_jsx("p", { className: "text-xs font-medium", children: "Bring your own keys" }), _jsx("p", { className: "mt-1 text-[11px] leading-4 text-muted-foreground", children: "Use your own providers and accounts." })] }), _jsxs("div", { className: "rounded-lg border border-border bg-card px-3 py-3", children: [_jsx("p", { className: "text-xs font-medium", children: "Build your own" }), _jsx("p", { className: "mt-1 text-[11px] leading-4 text-muted-foreground", children: "Mix and match toolkit pieces in your own apps." })] })] }), _jsxs("button", { type: "button", className: cn(primaryButtonClass, "mt-6"), onClick: () => setScreen("choice"), children: ["Continue", _jsx(IconArrowRight, { size: 15 })] }), _jsxs("a", { href: "https://github.com/builderio/agent-native", target: "_blank", rel: "noreferrer", className: "mt-3 inline-flex items-center gap-1.5 text-xs text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: [_jsx(IconBrandGithub, { size: 14 }), _jsx("span", { children: "View source" }), _jsx(IconExternalLink, { size: 13 })] })] }) }));
|
|
166
170
|
}
|
|
167
171
|
if (screen === "choice") {
|
|
168
|
-
return (_jsx(OnboardingShell, { profile: profile, screen: "choice", children: _jsxs("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-4", children: [_jsx("h1", { className: "text-center text-xl font-semibold tracking-[-0.04em] sm:text-2xl", children: "Choose your setup." }), _jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [_jsxs("section", { className: "rounded-xl border border-primary/50 bg-primary/[0.06] p-4 shadow-sm", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-sm font-semibold", children: "Connect Builder.io free credits" }), _jsxs("p", { className: "mt-1 max-w-xs text-xs leading-5 text-muted-foreground", children: ["One click connects", " ", _jsx("a", { href: "https://www.builder.io/", target: "_blank", rel: "noreferrer", className: "text-foreground underline decoration-border underline-offset-2 hover:decoration-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: "Builder.io free credits" }), " ", "with the services this app needs."] })] }), _jsx(IconArrowRight, { className: "mt-0.5 text-primary", size: 17 })] }), _jsxs("div", { className: "mt-5 border-t border-primary/15 pt-3", children: [_jsx("p", { className: "text-[11px] font-medium text-muted-foreground", children: "Included with Builder.io free credits" }), _jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-1.5 gap-y-1 text-[11px]", children: [builderCapabilities.map((capability, index) => (_jsxs(React.Fragment, { children: [index > 0 && (_jsx("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u00B7" })), _jsx("span", { children: capability.label })] }, capability.id))), _jsx("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u00B7" }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: "text-primary underline-offset-2 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", "aria-label": `See ${BUILDER_MORE_SERVICES.length} more services included with Builder.io free credits`, children: ["+", BUILDER_MORE_SERVICES.length, " more"] }) }), _jsxs(TooltipContent, { side: "top", className: "max-w-sm text-xs", children: [_jsx("p", { className: "font-medium", children: "Also included with Builder.io free credits" }), _jsx("p", { className: "mt-1 leading-5", children: BUILDER_MORE_SERVICES.join(" · ") })] })] })] })] }), _jsxs("button", { type: "button", "data-testid": "first-run-connect-builder", className: cn(primaryButtonClass, "mt-5 w-full"), onClick: handleBuilder, children: ["Connect Builder.io free credits", _jsx(IconArrowRight, { size: 15 })] })] }), _jsxs("div", { role: "button", tabIndex: 0, "aria-label": "Use my own keys", "data-testid": "first-run-use-own-keys", className: "rounded-xl border border-border bg-card p-4 text-left transition-colors hover:border-foreground/30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: () => setScreen("manual"), onKeyDown: (event) => {
|
|
172
|
+
return (_jsx(OnboardingShell, { profile: profile, screen: "choice", children: _jsxs("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-4", children: [_jsx("h1", { className: "text-center text-xl font-semibold tracking-[-0.04em] sm:text-2xl", children: "Choose your setup." }), _jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [_jsxs("section", { className: "rounded-xl border border-primary/50 bg-primary/[0.06] p-4 shadow-sm", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-sm font-semibold", children: "Connect Builder.io free credits" }), _jsxs("p", { className: "mt-1 max-w-xs text-xs leading-5 text-muted-foreground", children: ["One click connects", " ", _jsx("a", { href: "https://www.builder.io/", target: "_blank", rel: "noreferrer", className: "text-foreground underline decoration-border underline-offset-2 hover:decoration-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: "Builder.io free credits" }), " ", "with the services this app needs."] })] }), _jsx(IconArrowRight, { className: "mt-0.5 text-primary", size: 17 })] }), _jsxs("div", { className: "mt-5 border-t border-primary/15 pt-3", children: [_jsx("p", { className: "text-[11px] font-medium text-muted-foreground", children: "Included with Builder.io free credits" }), _jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-1.5 gap-y-1 text-[11px]", children: [builderCapabilities.map((capability, index) => (_jsxs(React.Fragment, { children: [index > 0 && (_jsx("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u00B7" })), _jsxs("span", { className: "inline-flex items-center gap-0.5", children: [_jsx("span", { children: capability.label }), capability.id === "design-system-intelligence" && (_jsx(CapabilityInfoButton, { capability: capability, ariaLabel: `About ${capability.label}` }))] })] }, capability.id))), _jsx("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u00B7" }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: "text-primary underline-offset-2 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", "aria-label": `See ${BUILDER_MORE_SERVICES.length} more services included with Builder.io free credits`, children: ["+", BUILDER_MORE_SERVICES.length, " more"] }) }), _jsxs(TooltipContent, { side: "top", className: "max-w-sm text-xs", children: [_jsx("p", { className: "font-medium", children: "Also included with Builder.io free credits" }), _jsx("p", { className: "mt-1 leading-5", children: BUILDER_MORE_SERVICES.join(" · ") })] })] })] })] }), _jsxs("button", { type: "button", "data-testid": "first-run-connect-builder", className: cn(primaryButtonClass, "mt-5 w-full"), onClick: handleBuilder, children: ["Connect Builder.io free credits", _jsx(IconArrowRight, { size: 15 })] })] }), _jsxs("div", { role: "button", tabIndex: 0, "aria-label": "Use my own keys", "data-testid": "first-run-use-own-keys", className: "rounded-xl border border-border bg-card p-4 text-left transition-colors hover:border-foreground/30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: () => setScreen("manual"), onKeyDown: (event) => {
|
|
169
173
|
if (event.key !== "Enter" && event.key !== " ")
|
|
170
174
|
return;
|
|
171
175
|
event.preventDefault();
|
|
@@ -179,7 +183,7 @@ export function FirstRunOnboarding({ skipIntegrations = shouldSkipFirstRunIntegr
|
|
|
179
183
|
return (_jsxs(OnboardingShell, { profile: profile, screen: "tools", footer: _jsxs("div", { "data-testid": "onboarding-tools-footer", className: "mx-auto flex w-full max-w-3xl flex-wrap items-center justify-end gap-2", children: [_jsx("button", { type: "button", className: secondaryButtonClass, onClick: handleFinish, children: "Skip for now" }), _jsxs("button", { type: "button", className: primaryButtonClass, onClick: handleFinish, children: ["Continue", _jsx(IconArrowRight, { size: 15 })] })] }), children: [_jsxs("div", { className: "mx-auto flex w-full max-w-4xl flex-col gap-5", children: [_jsxs("div", { className: "text-center", children: [_jsx("div", { className: "mx-auto flex size-11 items-center justify-center rounded-2xl bg-primary/10 text-primary", children: _jsx(IconPlugConnected, { size: 22 }) }), _jsx("h1", { className: "mt-5 text-2xl font-semibold tracking-[-0.05em] sm:text-3xl", children: "This app is an agent." }), _jsx("p", { className: "mt-3 text-sm leading-6 text-muted-foreground", children: "Search the catalog and connect what you need. The onboarding stays open while you add integrations." })] }), _jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-col gap-3 border-b border-border pb-4", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx("p", { className: "text-sm font-medium text-foreground", children: "Agent integrations" }), _jsxs("span", { className: "text-xs text-muted-foreground", children: [mcpIntegrations.length, " of ", mcpCatalog.length] })] }), _jsxs("label", { className: "relative", children: [_jsx(IconSearch, { className: "pointer-events-none absolute start-3 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" }), _jsx("input", { value: integrationQuery, onChange: (event) => setIntegrationQuery(event.target.value), className: "h-9 w-full rounded-md border border-border bg-background pe-3 ps-8 text-[13px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-ring", placeholder: "Search integrations", "aria-label": "Search integrations" })] }), connectError && (_jsx("p", { className: "text-xs leading-5 text-destructive", children: connectError }))] }), _jsx("div", { children: mcpIntegrations.length > 0 ? (_jsx("div", { className: "grid gap-x-8 sm:grid-cols-2", children: mcpIntegrations.map((integration) => (_jsx(McpIntegrationCard, { integration: integration, connected: connectedUrls.has(compareUrl(integration.url)), busy: connectingIntegrationId === integration.id, onConnect: connectIntegration }, integration.id))) })) : (_jsx("div", { className: "border-y border-dashed border-border px-4 py-8 text-center text-xs text-muted-foreground", children: "No integrations match." })) })] })] }), integrationDialogId && (_jsx(McpIntegrationDialog, { open: true, onOpenChange: (open) => {
|
|
180
184
|
if (!open)
|
|
181
185
|
setIntegrationDialogId(null);
|
|
182
|
-
}, initialIntegrationId: integrationDialogId, defaultScope:
|
|
186
|
+
}, initialIntegrationId: integrationDialogId, defaultScope: "user", canCreateOrgMcp: canCreateOrgMcp, hasOrg: hasOrg, onCreateMcpServer: createMcpServer.mutateAsync }))] }));
|
|
183
187
|
}
|
|
184
188
|
if (screen === "connecting") {
|
|
185
189
|
return (_jsx(OnboardingShell, { profile: profile, screen: "choice", children: _jsxs("div", { className: "mx-auto flex w-full max-w-md flex-col items-center text-center", children: [_jsx("div", { className: "flex size-10 items-center justify-center rounded-full bg-primary/10 text-primary", children: _jsx(IconLoader2, { className: "animate-spin", size: 19 }) }), _jsx("h1", { className: "mt-5 text-xl font-semibold tracking-[-0.04em]", children: "Connecting Builder.io free credits" }), _jsx("p", { className: "mt-2 text-sm text-muted-foreground", children: "Finish the one-click connection in the new window." }), _jsxs("div", { className: "mt-7 w-full rounded-xl border border-border bg-card p-4 text-left", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx(Skeleton, { className: "h-3 w-28" }), _jsx(Skeleton, { className: "h-5 w-16 rounded-full" })] }), _jsx(Skeleton, { className: "mt-4 h-8 w-full" }), _jsxs("div", { className: "mt-3 grid grid-cols-3 gap-2", children: [_jsx(Skeleton, { className: "h-7 w-full" }), _jsx(Skeleton, { className: "h-7 w-full" }), _jsx(Skeleton, { className: "h-7 w-full" })] })] }), connectFlow.error && (_jsxs("div", { className: "mt-4 flex flex-col items-center gap-2", children: [_jsx("p", { className: "text-xs text-destructive", children: connectFlow.error }), _jsx("button", { type: "button", className: secondaryButtonClass, onClick: () => setScreen("choice"), children: "Try again" })] }))] }) }));
|
|
@@ -231,7 +235,10 @@ function McpIntegrationCard({ integration, connected, busy, onConnect, }) {
|
|
|
231
235
|
} })] }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("h3", { className: "truncate text-sm font-medium text-foreground", children: integration.name }), connected ? (_jsx("span", { className: "rounded-full border border-border bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: "Connected" })) : null] }), _jsx("p", { className: "mt-1 line-clamp-2 text-[11px] leading-4 text-muted-foreground", children: integration.description })] })] }), _jsxs("button", { type: "button", onClick: () => onConnect(integration), disabled: connected || busy, "aria-label": `${actionLabel} ${integration.name}`, className: "inline-flex min-h-8 shrink-0 items-center justify-center gap-1.5 rounded-md border border-border bg-background px-3 text-[11px] font-medium text-foreground transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50", children: [busy ? _jsx(IconLoader2, { className: "animate-spin", size: 13 }) : null, connected ? "Connected" : actionLabel] })] }));
|
|
232
236
|
}
|
|
233
237
|
function CapabilityRow({ capability, compact, }) {
|
|
234
|
-
return (_jsxs("div", { className: cn("flex items-start justify-between gap-3", compact ? "py-2" : "py-3"), children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: cn("font-medium", compact ? "text-[11px]" : "text-sm"), children: capability.label }),
|
|
238
|
+
return (_jsxs("div", { className: cn("flex items-start justify-between gap-3", compact ? "py-2" : "py-3"), children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: cn("font-medium", compact ? "text-[11px]" : "text-sm"), children: capability.label }), _jsx(CapabilityInfoButton, { capability: capability, ariaLabel: `Why ${capability.label} is needed` })] }), _jsx("p", { className: "mt-1 text-[11px] leading-4 text-muted-foreground", children: capability.keySummary })] }), _jsx("span", { className: cn("shrink-0 text-[10px] uppercase tracking-[0.08em]", capability.required ? "text-primary" : "text-muted-foreground"), children: capability.required ? "Required" : "Optional" })] }));
|
|
239
|
+
}
|
|
240
|
+
function CapabilityInfoButton({ capability, ariaLabel, }) {
|
|
241
|
+
return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": ariaLabel, className: "inline-flex size-4 items-center justify-center rounded-full text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: (event) => event.stopPropagation(), onKeyDown: (event) => event.stopPropagation(), children: _jsx(IconInfoCircle, { size: 13 }) }) }), _jsx(TooltipContent, { side: "top", className: "max-w-xs text-xs", children: capability.why })] }));
|
|
235
242
|
}
|
|
236
243
|
const primaryButtonClass = "inline-flex min-h-9 items-center justify-center gap-2 rounded-lg bg-primary px-4 text-xs font-medium text-primary-foreground shadow-sm transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";
|
|
237
244
|
const secondaryButtonClass = "inline-flex min-h-9 items-center justify-center gap-2 rounded-lg border border-border bg-background px-4 text-xs font-medium text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";
|
|
@@ -25,7 +25,7 @@ function ErrorText({ error }) {
|
|
|
25
25
|
return (_jsx("p", { className: "text-xs text-destructive", children: error instanceof Error ? error.message : String(error) }));
|
|
26
26
|
}
|
|
27
27
|
function OrganizationHelpIcon({ content, docsUrl, }) {
|
|
28
|
-
return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", "aria-label": "More information", className: "inline-flex size-3.5 shrink-0 items-center justify-center rounded-full text-muted-foreground/70 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", children: _jsx(IconHelpCircle, { className: "size-3" }) }) }), _jsxs(TooltipContent, { className: "max-w-xs leading-5", children: [_jsx("p", { children: content }), docsUrl ? (_jsx("a", { href: docsUrl, target: "_blank", rel: "noreferrer", className: "mt-1 inline-block underline underline-offset-2", children: "Learn more" })) : null] })] }));
|
|
28
|
+
return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { type: "button", "aria-label": "More information", className: "inline-flex size-3.5 shrink-0 items-center justify-center rounded-full text-muted-foreground/70 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring [&_svg]:!size-3", children: _jsx(IconHelpCircle, { className: "size-3" }) }) }), _jsxs(TooltipContent, { className: "max-w-xs leading-5", children: [_jsx("p", { children: content }), docsUrl ? (_jsx("a", { href: docsUrl, target: "_blank", rel: "noreferrer", className: "mt-1 inline-block underline underline-offset-2", children: "Learn more" })) : null] })] }));
|
|
29
29
|
}
|
|
30
30
|
function OrganizationDescription({ children, help, docsUrl, }) {
|
|
31
31
|
return (_jsxs("span", { className: "inline-flex max-w-full items-center gap-1.5", children: [_jsx("span", { children: children }), help ? _jsx(OrganizationHelpIcon, { content: help, docsUrl: docsUrl }) : null] }));
|
|
@@ -113,5 +113,5 @@ function ResolvedSessionGate({ children, fallback, redirect = true, signedOut, }
|
|
|
113
113
|
return _jsx(_Fragment, { children: children });
|
|
114
114
|
}
|
|
115
115
|
function SessionUnavailableNotice({ retry }) {
|
|
116
|
-
return (_jsxs("div", { className: "flex h-screen w-full flex-col items-center justify-center gap-4 px-6 text-center", children: [_jsx("p", { className: "max-w-md text-sm text-muted-foreground", children: "We couldn't reach the server to confirm
|
|
116
|
+
return (_jsxs("div", { className: "flex h-screen w-full flex-col items-center justify-center gap-4 px-6 text-center", children: [_jsx("p", { className: "max-w-md text-sm text-muted-foreground", children: "We couldn't reach the server to confirm your session. This is usually temporary." }), _jsx("p", { className: "max-w-md text-xs text-muted-foreground", children: "Retry connection checks your session here. Reload page starts the app over." }), _jsxs("div", { className: "flex gap-2", children: [_jsx("button", { type: "button", onClick: retry, className: "rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground", children: "Retry connection" }), _jsx("button", { type: "button", onClick: () => window.location.reload(), className: "rounded-md border border-border px-3 py-1.5 text-sm font-medium", children: "Reload page" })] })] }));
|
|
117
117
|
}
|
|
@@ -7,4 +7,5 @@ export interface McpConnectionSuggestionProps {
|
|
|
7
7
|
integrations?: DefaultMcpIntegration[];
|
|
8
8
|
}
|
|
9
9
|
export declare function findMcpConnectionSuggestionIntegration({ text, contextText, variant, integrations, }: McpConnectionSuggestionProps): DefaultMcpIntegration | null;
|
|
10
|
+
export declare function shouldRenderMcpIntegrationFallback(logoUrl: string, logoLoadFailed: boolean): boolean;
|
|
10
11
|
export declare function McpConnectionSuggestion({ text, contextText, variant, integrations: integrationOptions, }: McpConnectionSuggestionProps): import("react").JSX.Element | null;
|
|
@@ -5,12 +5,15 @@ import { agentNativePath } from "../api-path.js";
|
|
|
5
5
|
import { openAgentSettings } from "../CommandMenu.js";
|
|
6
6
|
import { useT } from "../i18n.js";
|
|
7
7
|
import { clearMcpConnectionResume, notifyMcpConnectionComplete, saveMcpConnectionResume, } from "./mcp-connection-resume.js";
|
|
8
|
-
import { buildMcpOAuthStartUrl, findMcpIntegrationForText, getMcpIntegrationApiFallback, getDefaultMcpIntegrations, isMcpConnectionFailureText, navigateToMcpOAuthStart, } from "./mcp-integration-catalog.js";
|
|
8
|
+
import { buildMcpOAuthStartUrl, findMcpIntegrationForText, getMcpIntegrationApiFallback, getDefaultMcpIntegrations, isMcpConnectionFailureText, navigateToMcpOAuthStart, shouldOfferMcpIntegrationOrganizationScope, } from "./mcp-integration-catalog.js";
|
|
9
9
|
import { McpIntegrationDialog } from "./McpIntegrationDialog.js";
|
|
10
10
|
import { useCreateMcpServer, useMcpServers, } from "./use-mcp-servers.js";
|
|
11
11
|
export function findMcpConnectionSuggestionIntegration({ text, contextText = "", variant = "composer", integrations = getDefaultMcpIntegrations(), }) {
|
|
12
12
|
return findMcpIntegrationForText(variant === "response" ? contextText : text, integrations);
|
|
13
13
|
}
|
|
14
|
+
export function shouldRenderMcpIntegrationFallback(logoUrl, logoLoadFailed) {
|
|
15
|
+
return !logoUrl || logoLoadFailed;
|
|
16
|
+
}
|
|
14
17
|
function compareUrl(value) {
|
|
15
18
|
try {
|
|
16
19
|
const url = new URL(value.trim());
|
|
@@ -33,8 +36,9 @@ function returnUrl() {
|
|
|
33
36
|
}
|
|
34
37
|
function canStartOAuth(integration) {
|
|
35
38
|
return (integration.authMode === "oauth" &&
|
|
36
|
-
integration.connectionMode === "oauth" &&
|
|
37
|
-
|
|
39
|
+
((integration.connectionMode === "oauth" &&
|
|
40
|
+
integration.availability === "ready") ||
|
|
41
|
+
integration.managedOAuth === true));
|
|
38
42
|
}
|
|
39
43
|
function hasApiFallback(apiFallback) {
|
|
40
44
|
return Boolean(apiFallback);
|
|
@@ -47,6 +51,7 @@ export function McpConnectionSuggestion({ text, contextText = "", variant = "com
|
|
|
47
51
|
const [dismissedId, setDismissedId] = useState(null);
|
|
48
52
|
const [connecting, setConnecting] = useState(false);
|
|
49
53
|
const [error, setError] = useState(null);
|
|
54
|
+
const [logoLoadFailed, setLogoLoadFailed] = useState(false);
|
|
50
55
|
const integrations = useMemo(() => integrationOptions ?? getDefaultMcpIntegrations(), [integrationOptions]);
|
|
51
56
|
const integration = useMemo(() => findMcpConnectionSuggestionIntegration({
|
|
52
57
|
text,
|
|
@@ -62,6 +67,12 @@ export function McpConnectionSuggestion({ text, contextText = "", variant = "com
|
|
|
62
67
|
...(mcpServersQuery.data?.org ?? []),
|
|
63
68
|
], [mcpServersQuery.data]);
|
|
64
69
|
const connected = integration ? isConnected(integration, servers) : false;
|
|
70
|
+
const hasOrg = Boolean(mcpServersQuery.data?.orgId);
|
|
71
|
+
const canCreateOrgMcp = Boolean(hasOrg &&
|
|
72
|
+
(mcpServersQuery.data?.role === "owner" ||
|
|
73
|
+
mcpServersQuery.data?.role === "admin"));
|
|
74
|
+
const shouldChooseScope = Boolean(integration &&
|
|
75
|
+
shouldOfferMcpIntegrationOrganizationScope(integration, hasOrg, canCreateOrgMcp));
|
|
65
76
|
const shouldSuggest = mcpServersQuery.isSuccess &&
|
|
66
77
|
integration &&
|
|
67
78
|
!connected &&
|
|
@@ -70,7 +81,8 @@ export function McpConnectionSuggestion({ text, contextText = "", variant = "com
|
|
|
70
81
|
useEffect(() => {
|
|
71
82
|
setError(null);
|
|
72
83
|
setConnecting(false);
|
|
73
|
-
|
|
84
|
+
setLogoLoadFailed(false);
|
|
85
|
+
}, [integration?.id, integration?.logoUrl, variant]);
|
|
74
86
|
if (!shouldSuggest)
|
|
75
87
|
return null;
|
|
76
88
|
const connect = async () => {
|
|
@@ -81,6 +93,11 @@ export function McpConnectionSuggestion({ text, contextText = "", variant = "com
|
|
|
81
93
|
openAgentSettings(`secrets:${apiFallback.secretKey}`);
|
|
82
94
|
return;
|
|
83
95
|
}
|
|
96
|
+
if (shouldChooseScope) {
|
|
97
|
+
saveMcpConnectionResume(variant === "response" ? contextText : text);
|
|
98
|
+
setDialogOpen(true);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
84
101
|
if (canStartOAuth(integration)) {
|
|
85
102
|
setConnecting(true);
|
|
86
103
|
saveMcpConnectionResume(variant === "response" ? contextText : text);
|
|
@@ -128,20 +145,20 @@ export function McpConnectionSuggestion({ text, contextText = "", variant = "com
|
|
|
128
145
|
? t("mcpIntegrations.viewSetup")
|
|
129
146
|
: t("mcpIntegrations.connect");
|
|
130
147
|
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: variant === "response"
|
|
131
|
-
? "mt-3 flex max-w-[520px] items-center gap-2 rounded-lg border border-primary/20 bg-primary/5 px-3 py-2 text-[12px]"
|
|
132
|
-
: "mx-auto mb-2 flex w-[min(calc(100%_-_1.5rem),
|
|
133
|
-
event.currentTarget.hidden = true;
|
|
134
|
-
} }))] }), _jsx("span", { className: "min-w-0 flex-1 leading-snug text-foreground", children: t(hasApiFallback(apiFallback)
|
|
148
|
+
? "agent-mcp-connection-suggestion agent-mcp-connection-suggestion--response mt-3 flex max-w-[520px] items-center gap-2 rounded-lg border border-primary/20 bg-primary/5 px-3 py-2 text-[12px]"
|
|
149
|
+
: "agent-mcp-connection-suggestion agent-mcp-connection-suggestion--composer mx-auto mb-2 flex w-[min(calc(100%_-_1.5rem),684px)] items-center gap-2 rounded-lg border border-primary/20 bg-primary/5 px-3 py-2 text-[12px]", "data-mcp-connection-suggestion": integration.id, "data-mcp-connection-suggestion-variant": variant, children: [_jsxs("div", { className: "relative flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden rounded-md border border-border bg-background text-[10px] font-semibold text-muted-foreground", children: [shouldRenderMcpIntegrationFallback(integration.logoUrl, logoLoadFailed) ? (_jsx("span", { "aria-hidden": "true", children: integration.name.slice(0, 1) })) : null, integration.logoUrl && (_jsx("img", { src: integration.logoUrl, alt: "", className: `absolute h-5 w-5 object-contain${logoLoadFailed ? " hidden" : ""}`, onError: () => setLogoLoadFailed(true) }))] }), _jsx("span", { className: "min-w-0 flex-1 leading-snug text-foreground", children: t(hasApiFallback(apiFallback)
|
|
135
150
|
? "mcpIntegrations.connectSuggestionWithApiToken"
|
|
136
151
|
: "mcpIntegrations.connectSuggestion", { name: integration.name }) }), _jsxs("button", { type: "button", onClick: () => void connect(), disabled: connecting, "aria-busy": connecting, className: "inline-flex shrink-0 items-center gap-1 rounded-md bg-primary px-2.5 py-1.5 text-[11px] font-medium text-primary-foreground hover:bg-primary/90 disabled:pointer-events-none disabled:opacity-60", children: [connecting && _jsx(IconLoader2, { className: "h-3 w-3 animate-spin" }), !connecting &&
|
|
137
152
|
canStartOAuth(integration) &&
|
|
138
153
|
!hasApiFallback(apiFallback) && (_jsx(IconPlugConnected, { className: "h-3 w-3" })), !connecting && hasApiFallback(apiFallback) && (_jsx(IconPlugConnected, { className: "h-3 w-3" })), actionLabel, !connecting &&
|
|
139
154
|
!canStartOAuth(integration) &&
|
|
140
|
-
!hasApiFallback(apiFallback) && (_jsx(IconArrowUpRight, { className: "h-3 w-3" }))] }), _jsx("button", { type: "button", onClick: () => setDismissedId(integration.id), className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-background hover:text-foreground", "aria-label": t("mcpIntegrations.dismissSuggestion"), children: _jsx(IconX, { className: "h-3.5 w-3.5" }) })] }), error && (_jsx("div", { className:
|
|
155
|
+
!hasApiFallback(apiFallback) && (_jsx(IconArrowUpRight, { className: "h-3 w-3" }))] }), _jsx("button", { type: "button", onClick: () => setDismissedId(integration.id), className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-background hover:text-foreground", "aria-label": t("mcpIntegrations.dismissSuggestion"), children: _jsx(IconX, { className: "h-3.5 w-3.5" }) })] }), error && (_jsx("div", { className: variant === "response"
|
|
156
|
+
? "agent-mcp-connection-suggestion-error agent-mcp-connection-suggestion-error--response mt-1 max-w-[520px] text-[11px] text-destructive"
|
|
157
|
+
: "agent-mcp-connection-suggestion-error agent-mcp-connection-suggestion-error--composer mx-auto mb-2 w-[min(calc(100%_-_1.5rem),684px)] text-[11px] text-destructive", children: error })), _jsx(McpIntegrationDialog, { open: dialogOpen, onOpenChange: (open) => {
|
|
141
158
|
setDialogOpen(open);
|
|
142
159
|
if (!open)
|
|
143
160
|
clearMcpConnectionResume();
|
|
144
|
-
}, initialIntegrationId: integration.id, defaultScope: "user", canCreateOrgMcp:
|
|
161
|
+
}, initialIntegrationId: integration.id, defaultScope: "user", canCreateOrgMcp: canCreateOrgMcp, hasOrg: hasOrg, onCreateMcpServer: (args) => createMcpServer.mutateAsync(args), onCreated: () => {
|
|
145
162
|
setDismissedId(integration.id);
|
|
146
163
|
saveMcpConnectionResume(variant === "response" ? contextText : text);
|
|
147
164
|
notifyMcpConnectionComplete();
|
|
@@ -7,7 +7,7 @@ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, }
|
|
|
7
7
|
import { Tooltip, TooltipContent, TooltipTrigger, } from "../components/ui/tooltip.js";
|
|
8
8
|
import { useT } from "../i18n.js";
|
|
9
9
|
import { cn } from "../utils.js";
|
|
10
|
-
import { buildMcpOAuthStartUrl, createMcpIntegrationFormDefaults, filterMcpIntegrations, getMcpIntegrationApiFallback, getDefaultMcpIntegrations, isCustomMcpIntegrationEnabled, navigateToMcpOAuthStart, resolveMcpIntegrationScope, shouldOfferMcpOrganizationScope, } from "./mcp-integration-catalog.js";
|
|
10
|
+
import { buildMcpOAuthStartUrl, createMcpIntegrationFormDefaults, filterMcpIntegrations, getMcpIntegrationApiFallback, getDefaultMcpIntegrations, isCustomMcpIntegrationEnabled, navigateToMcpOAuthStart, resolveMcpIntegrationScope, shouldOfferMcpIntegrationOrganizationScope, shouldOfferMcpOrganizationScope, } from "./mcp-integration-catalog.js";
|
|
11
11
|
import { formatMcpServerError, getMcpUrlValidationError, testMcpServerUrl, useMcpServers, } from "./use-mcp-servers.js";
|
|
12
12
|
function IntegrationLogo({ name, logoUrl }) {
|
|
13
13
|
const [loaded, setLoaded] = useState(false);
|
|
@@ -51,6 +51,17 @@ function compareUrl(value) {
|
|
|
51
51
|
return value.trim().replace(/\/+$/, "");
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
+
function requiresMcpIntegrationSetup(integration) {
|
|
55
|
+
return Boolean(!integration.managedOAuth &&
|
|
56
|
+
(integration.connectionMode === "manual" ||
|
|
57
|
+
integration.availability === "provider-setup" ||
|
|
58
|
+
integration.availability === "client-restricted"));
|
|
59
|
+
}
|
|
60
|
+
function resolveIntegrationScope(integration, defaultScope, hasOrg, canCreateOrgMcp) {
|
|
61
|
+
return resolveMcpIntegrationScope(defaultScope, hasOrg, canCreateOrgMcp, !integration ||
|
|
62
|
+
(integration.supportsOrganizationScope === true &&
|
|
63
|
+
integration.managedOAuth !== true));
|
|
64
|
+
}
|
|
54
65
|
export function McpIntegrationDialog({ open, onOpenChange, initialIntegrationId = null, defaultScope, canCreateOrgMcp, hasOrg, onCreateMcpServer, onCreated, integrations, }) {
|
|
55
66
|
const t = useT();
|
|
56
67
|
const [mode, setMode] = useState("catalog");
|
|
@@ -84,10 +95,7 @@ export function McpIntegrationDialog({ open, onOpenChange, initialIntegrationId
|
|
|
84
95
|
.map((server) => compareUrl(server.url)));
|
|
85
96
|
}, [mcpServersQuery.data]);
|
|
86
97
|
const filteredIntegrations = useMemo(() => filterMcpIntegrations(query, defaultIntegrations), [defaultIntegrations, query]);
|
|
87
|
-
const selectedRequiresSetup = Boolean(selected &&
|
|
88
|
-
(selected.connectionMode === "manual" ||
|
|
89
|
-
selected.availability === "provider-setup" ||
|
|
90
|
-
selected.availability === "client-restricted"));
|
|
98
|
+
const selectedRequiresSetup = Boolean(selected && requiresMcpIntegrationSetup(selected));
|
|
91
99
|
useEffect(() => {
|
|
92
100
|
if (!open)
|
|
93
101
|
return;
|
|
@@ -98,7 +106,7 @@ export function McpIntegrationDialog({ open, onOpenChange, initialIntegrationId
|
|
|
98
106
|
setMode(initialIntegration || !showCatalog ? "form" : "catalog");
|
|
99
107
|
setQuery("");
|
|
100
108
|
setSelected(initialIntegration ?? null);
|
|
101
|
-
setScope(
|
|
109
|
+
setScope(resolveIntegrationScope(initialIntegration, defaultScope, hasOrg, canCreateOrgMcp));
|
|
102
110
|
setName(initialDefaults.name);
|
|
103
111
|
setUrl(initialDefaults.url);
|
|
104
112
|
setDescription(initialDefaults.description);
|
|
@@ -110,6 +118,9 @@ export function McpIntegrationDialog({ open, onOpenChange, initialIntegrationId
|
|
|
110
118
|
}, [
|
|
111
119
|
defaultIntegrations,
|
|
112
120
|
initialIntegrationId,
|
|
121
|
+
canCreateOrgMcp,
|
|
122
|
+
defaultScope,
|
|
123
|
+
hasOrg,
|
|
113
124
|
open,
|
|
114
125
|
safeDefaultScope,
|
|
115
126
|
showCatalog,
|
|
@@ -127,7 +138,7 @@ export function McpIntegrationDialog({ open, onOpenChange, initialIntegrationId
|
|
|
127
138
|
const openForm = (integration) => {
|
|
128
139
|
const defaults = createMcpIntegrationFormDefaults(integration);
|
|
129
140
|
setSelected(integration ?? null);
|
|
130
|
-
setScope(
|
|
141
|
+
setScope(resolveIntegrationScope(integration, defaultScope, hasOrg, canCreateOrgMcp));
|
|
131
142
|
setName(defaults.name);
|
|
132
143
|
setUrl(defaults.url);
|
|
133
144
|
setDescription(defaults.description);
|
|
@@ -154,7 +165,7 @@ export function McpIntegrationDialog({ open, onOpenChange, initialIntegrationId
|
|
|
154
165
|
name: args.name,
|
|
155
166
|
url: args.url,
|
|
156
167
|
description: args.description,
|
|
157
|
-
scope,
|
|
168
|
+
scope: options?.scope ?? scope,
|
|
158
169
|
returnUrl,
|
|
159
170
|
})));
|
|
160
171
|
};
|
|
@@ -162,7 +173,13 @@ export function McpIntegrationDialog({ open, onOpenChange, initialIntegrationId
|
|
|
162
173
|
name: integration.name,
|
|
163
174
|
url: integration.url,
|
|
164
175
|
description: integration.description,
|
|
165
|
-
},
|
|
176
|
+
}, {
|
|
177
|
+
...options,
|
|
178
|
+
scope: integration.supportsOrganizationScope === true &&
|
|
179
|
+
integration.managedOAuth !== true
|
|
180
|
+
? scope
|
|
181
|
+
: "user",
|
|
182
|
+
});
|
|
166
183
|
const connectCustomWithOAuth = () => {
|
|
167
184
|
if (!name.trim()) {
|
|
168
185
|
setError(t("mcpIntegrations.serverNameRequired"));
|
|
@@ -212,10 +229,12 @@ export function McpIntegrationDialog({ open, onOpenChange, initialIntegrationId
|
|
|
212
229
|
});
|
|
213
230
|
};
|
|
214
231
|
const quickConnect = (integration) => {
|
|
215
|
-
if (integration
|
|
216
|
-
integration
|
|
232
|
+
if (shouldOfferMcpIntegrationOrganizationScope(integration, hasOrg, canCreateOrgMcp)) {
|
|
233
|
+
openForm(integration);
|
|
217
234
|
return;
|
|
218
235
|
}
|
|
236
|
+
if (requiresMcpIntegrationSetup(integration))
|
|
237
|
+
return;
|
|
219
238
|
if (integration.authMode === "oauth") {
|
|
220
239
|
connectWithOAuth(integration, { quickId: integration.id });
|
|
221
240
|
return;
|
|
@@ -225,7 +244,7 @@ export function McpIntegrationDialog({ open, onOpenChange, initialIntegrationId
|
|
|
225
244
|
return;
|
|
226
245
|
}
|
|
227
246
|
void createServer({
|
|
228
|
-
scope:
|
|
247
|
+
scope: resolveIntegrationScope(integration, defaultScope, hasOrg, canCreateOrgMcp),
|
|
229
248
|
name: integration.name,
|
|
230
249
|
url: integration.url,
|
|
231
250
|
description: integration.description,
|
|
@@ -263,13 +282,20 @@ export function McpIntegrationDialog({ open, onOpenChange, initialIntegrationId
|
|
|
263
282
|
}
|
|
264
283
|
};
|
|
265
284
|
const renderScopeSelector = () => {
|
|
266
|
-
if (
|
|
285
|
+
if (selected?.managedOAuth)
|
|
286
|
+
return null;
|
|
287
|
+
const canSelectScope = selected
|
|
288
|
+
? shouldOfferMcpIntegrationOrganizationScope(selected, hasOrg, canCreateOrgMcp)
|
|
289
|
+
: shouldOfferMcpOrganizationScope(hasOrg, canCreateOrgMcp);
|
|
290
|
+
if (!canSelectScope)
|
|
267
291
|
return null;
|
|
268
|
-
return (_jsxs("div", { className: "flex gap-1 rounded-md border border-border bg-background p-0.5", children: [_jsx("button", { type: "button", onClick: () => setScope("user"), className: cn("flex-1 rounded px-2 py-1.5 text-[11px] font-medium", scope === "user"
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
292
|
+
return (_jsxs("div", { className: "space-y-1.5", children: [_jsx("p", { className: "text-[11px] font-medium text-foreground", children: t("mcpIntegrations.scopeQuestion") }), _jsxs("div", { className: "flex gap-1 rounded-md border border-border bg-background p-0.5", children: [_jsx("button", { type: "button", onClick: () => setScope("user"), "aria-pressed": scope === "user", className: cn("flex-1 rounded px-2 py-1.5 text-[11px] font-medium", scope === "user"
|
|
293
|
+
? "bg-accent text-foreground"
|
|
294
|
+
: "text-muted-foreground hover:text-foreground"), children: t("mcpIntegrations.personal") }), _jsx("button", { type: "button", onClick: () => setScope("org"), "aria-pressed": scope === "org", className: cn("flex-1 rounded px-2 py-1.5 text-[11px] font-medium", scope === "org"
|
|
295
|
+
? "bg-accent text-foreground"
|
|
296
|
+
: "text-muted-foreground hover:text-foreground"), children: t("mcpIntegrations.sharedWithWorkspace") })] }), _jsx("p", { className: "text-[11px] leading-relaxed text-muted-foreground", children: t(scope === "user"
|
|
297
|
+
? "mcpIntegrations.personalDescription"
|
|
298
|
+
: "mcpIntegrations.organizationDescription") })] }));
|
|
273
299
|
};
|
|
274
300
|
if (!showCatalog && !customIntegrationEnabled)
|
|
275
301
|
return null;
|
|
@@ -279,9 +305,7 @@ export function McpIntegrationDialog({ open, onOpenChange, initialIntegrationId
|
|
|
279
305
|
const apiFallback = getMcpIntegrationApiFallback(integration);
|
|
280
306
|
const connected = connectedUrls.has(compareUrl(integration.url));
|
|
281
307
|
const requiresHeaders = integration.authMode === "headers";
|
|
282
|
-
const setupOnly = integration
|
|
283
|
-
integration.availability === "provider-setup" ||
|
|
284
|
-
integration.availability === "client-restricted";
|
|
308
|
+
const setupOnly = requiresMcpIntegrationSetup(integration);
|
|
285
309
|
return (_jsxs("article", { className: "flex min-h-[128px] flex-col rounded-md border border-border bg-card p-4 transition-colors hover:border-border/80 hover:bg-accent/20", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(IntegrationLogo, { name: integration.name, logoUrl: integration.logoUrl }), _jsxs("div", { className: "min-w-0", children: [_jsx("h3", { className: "truncate text-[13px] font-semibold text-foreground", children: integration.name }), integration.availability !== "ready" && (_jsx("span", { className: "mt-0.5 inline-flex rounded-full border border-border/70 bg-muted/40 px-1.5 py-0.5 text-[9px] font-medium text-muted-foreground", children: integration.availability === "beta"
|
|
286
310
|
? t("mcpIntegrations.status.beta")
|
|
287
311
|
: integration.availability ===
|
|
@@ -291,7 +315,7 @@ export function McpIntegrationDialog({ open, onOpenChange, initialIntegrationId
|
|
|
291
315
|
? t("mcpIntegrations.status.verified")
|
|
292
316
|
: integration.verification === "restricted"
|
|
293
317
|
? t("mcpIntegrations.status.restricted")
|
|
294
|
-
: t("mcpIntegrations.status.preflightOnly") })] })] }), _jsx("p", { className: "mt-1 line-clamp-2 flex-1 text-[12px] leading-relaxed text-muted-foreground", children: t(integration.descriptionKey) }), _jsxs("div", { className: "mt-3 flex items-center gap-2", children: [connected ? (_jsx("button", { type: "button", disabled: true, className: "inline-flex h-8 flex-1 cursor-not-allowed items-center justify-center gap-1.5 rounded-md border border-border bg-muted px-2.5 text-[12px] font-medium text-muted-foreground opacity-70", children: t("mcpIntegrations.connected") })) : setupOnly ? (_jsxs(_Fragment, { children: [apiFallback && (_jsx("button", { type: "button", onClick: () => openAgentSettings(`secrets:${apiFallback.secretKey}`), className: "inline-flex h-8 flex-1 items-center justify-center gap-1.5 rounded-md bg-primary px-2.5 text-[12px] font-medium text-primary-foreground hover:bg-primary/90", children: t("mcpIntegrations.useApiToken") })),
|
|
318
|
+
: t("mcpIntegrations.status.preflightOnly") })] })] }), _jsx("p", { className: "mt-1 line-clamp-2 flex-1 text-[12px] leading-relaxed text-muted-foreground", children: t(integration.descriptionKey) }), _jsxs("div", { className: "mt-3 flex items-center gap-2", children: [connected ? (_jsx("button", { type: "button", disabled: true, className: "inline-flex h-8 flex-1 cursor-not-allowed items-center justify-center gap-1.5 rounded-md border border-border bg-muted px-2.5 text-[12px] font-medium text-muted-foreground opacity-70", children: t("mcpIntegrations.connected") })) : setupOnly ? (_jsxs(_Fragment, { children: [apiFallback && (_jsx("button", { type: "button", onClick: () => openAgentSettings(`secrets:${apiFallback.secretKey}`), className: "inline-flex h-8 flex-1 items-center justify-center gap-1.5 rounded-md bg-primary px-2.5 text-[12px] font-medium text-primary-foreground hover:bg-primary/90", children: t("mcpIntegrations.useApiToken") })), _jsx("button", { type: "button", onClick: () => openForm(integration), className: "inline-flex h-8 flex-1 items-center justify-center gap-1.5 rounded-md border border-border bg-background px-2.5 text-[12px] font-medium text-foreground hover:bg-accent", children: t("mcpIntegrations.viewSetup") })] })) : (_jsxs("button", { type: "button", onClick: () => quickConnect(integration), disabled: busy, "aria-busy": quickBusyId === integration.id, className: cn("inline-flex h-8 flex-1 items-center justify-center gap-1.5 rounded-md bg-primary px-2.5 text-[12px] font-medium text-primary-foreground hover:bg-primary/90", busy && "cursor-not-allowed opacity-70"), children: [quickBusyId === integration.id ? (_jsx(IconLoader2, { className: "h-3.5 w-3.5 animate-spin" })) : null, integration.authMode === "oauth"
|
|
295
319
|
? t("mcpIntegrations.connectWithOAuth")
|
|
296
320
|
: requiresHeaders
|
|
297
321
|
? t("mcpIntegrations.configure")
|
|
@@ -304,29 +328,37 @@ export function McpIntegrationDialog({ open, onOpenChange, initialIntegrationId
|
|
|
304
328
|
clearFeedback();
|
|
305
329
|
setMode("catalog");
|
|
306
330
|
}, className: cn("mb-1 inline-flex w-fit items-center gap-1 text-[11px] text-muted-foreground hover:text-foreground", !showCatalog && "hidden"), children: [_jsx(IconArrowLeft, { className: "h-3 w-3 rtl:-scale-x-100" }), t("mcpIntegrations.backToIntegrations")] }), _jsx(DialogTitle, { children: selected
|
|
307
|
-
?
|
|
308
|
-
|
|
309
|
-
|
|
331
|
+
? selectedRequiresSetup
|
|
332
|
+
? t("mcpIntegrations.setupTitle", {
|
|
333
|
+
name: selected.name,
|
|
334
|
+
})
|
|
335
|
+
: t("mcpIntegrations.configureTitle", {
|
|
336
|
+
name: selected.name,
|
|
337
|
+
})
|
|
310
338
|
: t("mcpIntegrations.customTitle") }), _jsx(DialogDescription, { children: selected
|
|
311
|
-
?
|
|
312
|
-
? t("mcpIntegrations.
|
|
313
|
-
:
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
339
|
+
? selectedRequiresSetup
|
|
340
|
+
? t("mcpIntegrations.providerSetupFormDescription")
|
|
341
|
+
: selected.authMode === "none"
|
|
342
|
+
? t("mcpIntegrations.presetNoAuthDescription")
|
|
343
|
+
: t("mcpIntegrations.presetAuthDescription")
|
|
344
|
+
: t("mcpIntegrations.customDescription") })] }), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-7 py-5", children: _jsxs("div", { className: "space-y-3", children: [renderScopeSelector(), selected?.setupNoteKey && (_jsx("div", { className: "rounded-md border border-border bg-muted/40 px-3 py-2 text-[11px] leading-relaxed text-muted-foreground", children: t(selected.setupNoteKey) })), selectedRequiresSetup && selected && (_jsxs("div", { className: "rounded-md border border-border bg-muted/40 px-3 py-2 text-[11px] leading-relaxed", children: [_jsx("p", { className: "font-medium text-foreground", children: t("mcpIntegrations.providerSetupRequired") }), _jsx("p", { className: "mt-0.5 text-muted-foreground", children: t("mcpIntegrations.providerSetupDescription", {
|
|
345
|
+
name: selected.name,
|
|
346
|
+
}) })] })), !selectedRequiresSetup && (_jsxs(_Fragment, { children: [selected?.authMode === "oauth" && (_jsx("div", { className: "rounded-md border border-primary/20 bg-primary/5 px-3 py-2 text-[11px] leading-relaxed text-primary", children: t("mcpIntegrations.oauthNotice") })), _jsxs("label", { className: "block", children: [_jsx("span", { className: "mb-1 block text-[10px] font-medium text-muted-foreground", children: t("mcpIntegrations.serverName") }), _jsx("input", { ref: inputRef, value: name, onChange: (event) => {
|
|
347
|
+
setName(event.target.value);
|
|
348
|
+
clearFeedback();
|
|
349
|
+
}, className: "w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-[13px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-ring", placeholder: t("mcpIntegrations.serverNamePlaceholder") })] }), _jsxs("label", { className: "block", children: [_jsx("span", { className: "mb-1 block text-[10px] font-medium text-muted-foreground", children: t("mcpIntegrations.url") }), _jsx("input", { value: url, onChange: (event) => {
|
|
350
|
+
setUrl(event.target.value);
|
|
351
|
+
clearFeedback();
|
|
352
|
+
}, className: "w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-[13px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-ring", placeholder: t("mcpIntegrations.urlPlaceholder") })] }), _jsxs("label", { className: "block", children: [_jsx("span", { className: "mb-1 block text-[10px] font-medium text-muted-foreground", children: t("mcpIntegrations.fieldDescription") }), _jsx("input", { value: description, onChange: (event) => {
|
|
353
|
+
setDescription(event.target.value);
|
|
354
|
+
clearFeedback();
|
|
355
|
+
}, className: "w-full rounded-md border border-border bg-background px-2.5 py-1.5 text-[13px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-ring", placeholder: t("mcpIntegrations.descriptionPlaceholder") })] }), selected?.authMode !== "oauth" && (_jsxs("label", { className: "block", children: [_jsx("span", { className: "mb-1 block text-[10px] font-medium text-muted-foreground", children: t("mcpIntegrations.headers") }), _jsx("textarea", { value: headersText, onChange: (event) => {
|
|
356
|
+
setHeadersText(event.target.value);
|
|
357
|
+
clearFeedback();
|
|
358
|
+
}, rows: 3, className: "w-full resize-y rounded-md border border-border bg-background px-2.5 py-1.5 text-[12px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-ring", style: {
|
|
359
|
+
fontFamily: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace',
|
|
360
|
+
}, placeholder: selected?.headerPlaceholder ??
|
|
361
|
+
t("mcpIntegrations.headersPlaceholder") })] })), selected?.docsUrl && (_jsxs("a", { href: selected.docsUrl, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 text-[11px] text-muted-foreground underline hover:text-foreground", children: [t("mcpIntegrations.openSetupDocs"), _jsx(IconExternalLink, { className: "h-3 w-3" })] }))] })), testResult && (_jsxs("div", { className: cn("flex items-start gap-1 rounded-md px-3 py-2 text-[11px] leading-snug", testResult.ok
|
|
330
362
|
? "bg-green-500/5 text-green-600 dark:text-green-400"
|
|
331
|
-
: "bg-red-500/5 text-red-600 dark:text-red-400"), children: [testResult.ok && (_jsx(IconCheck, { className: "mt-0.5 h-3 w-3 shrink-0" })), _jsx("span", { className: "min-w-0 break-words", children: testResult.message })] })), error && (_jsx("div", { className: "break-words rounded-md bg-red-500/5 px-3 py-2 text-[11px] leading-snug text-red-600 dark:text-red-400", children: error }))] }) }), _jsxs("div", { className: "flex shrink-0 items-center justify-between gap-2 border-t border-border px-7 py-4", children: [!selectedRequiresSetup && (_jsx("button", { type: "button", onClick: runTest, disabled: !url.trim() || busy, className: "rounded-md border border-border bg-background px-3 py-1.5 text-[12px] font-medium text-foreground hover:bg-accent disabled:pointer-events-none disabled:opacity-40", children: t("mcpIntegrations.test") })), !selected ? (_jsxs("button", { type: "button", onClick: connectCustomWithOAuth, disabled: !name.trim() || !url.trim() || busy, "aria-busy": busy, className: "rounded-md border border-border bg-background px-3 py-1.5 text-[12px] font-medium text-foreground hover:bg-accent disabled:pointer-events-none disabled:opacity-40", children: [busy && (_jsx(IconLoader2, { className: "me-1.5 inline h-3.5 w-3.5 animate-spin" })), t("mcpIntegrations.connectWithOAuth")] })) : null, selectedRequiresSetup ? (selected?.docsUrl ? (_jsxs("a", { href: selected.docsUrl, target: "_blank", rel: "noopener noreferrer", className: "
|
|
363
|
+
: "bg-red-500/5 text-red-600 dark:text-red-400"), children: [testResult.ok && (_jsx(IconCheck, { className: "mt-0.5 h-3 w-3 shrink-0" })), _jsx("span", { className: "min-w-0 break-words", children: testResult.message })] })), error && (_jsx("div", { className: "break-words rounded-md bg-red-500/5 px-3 py-2 text-[11px] leading-snug text-red-600 dark:text-red-400", children: error }))] }) }), _jsxs("div", { className: "flex shrink-0 items-center justify-between gap-2 border-t border-border px-7 py-4", children: [!selectedRequiresSetup && (_jsx("button", { type: "button", onClick: runTest, disabled: !url.trim() || busy, className: "rounded-md border border-border bg-background px-3 py-1.5 text-[12px] font-medium text-foreground hover:bg-accent disabled:pointer-events-none disabled:opacity-40", children: t("mcpIntegrations.test") })), !selected ? (_jsxs("button", { type: "button", onClick: connectCustomWithOAuth, disabled: !name.trim() || !url.trim() || busy, "aria-busy": busy, className: "rounded-md border border-border bg-background px-3 py-1.5 text-[12px] font-medium text-foreground hover:bg-accent disabled:pointer-events-none disabled:opacity-40", children: [busy && (_jsx(IconLoader2, { className: "me-1.5 inline h-3.5 w-3.5 animate-spin" })), t("mcpIntegrations.connectWithOAuth")] })) : null, selectedRequiresSetup ? (_jsxs("div", { className: "ms-auto flex items-center gap-2", children: [selected?.docsUrl ? (_jsxs("a", { href: selected.docsUrl, target: "_blank", rel: "noopener noreferrer", className: "inline-flex min-w-[92px] items-center justify-center gap-1.5 rounded-md border border-border bg-background px-3 py-1.5 text-[12px] font-medium text-foreground hover:bg-accent", children: [t("mcpIntegrations.viewSetup"), _jsx(IconExternalLink, { className: "h-3 w-3" })] })) : null, selected?.authMode === "oauth" && (_jsxs("button", { type: "button", onClick: () => connectWithOAuth(selected), disabled: busy, "aria-busy": busy, className: "inline-flex min-w-[132px] items-center justify-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-[12px] font-medium text-primary-foreground hover:bg-primary/90 disabled:pointer-events-none disabled:opacity-40", children: [busy && (_jsx(IconLoader2, { className: "h-3.5 w-3.5 animate-spin" })), t("mcpIntegrations.continueToConnect")] }))] })) : selected?.authMode === "oauth" ? (_jsxs("button", { type: "button", onClick: () => connectWithOAuth(selected), disabled: !name.trim() || !url.trim() || busy, "aria-busy": busy, className: "inline-flex min-w-[92px] items-center justify-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-[12px] font-medium text-primary-foreground hover:bg-primary/90 disabled:pointer-events-none disabled:opacity-40", children: [busy && _jsx(IconLoader2, { className: "h-3.5 w-3.5 animate-spin" }), t("mcpIntegrations.connectWithOAuth")] })) : (_jsxs("button", { type: "button", onClick: submitForm, disabled: !name.trim() || !url.trim() || busy, className: "inline-flex min-w-[92px] items-center justify-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-[12px] font-medium text-primary-foreground hover:bg-primary/90 disabled:pointer-events-none disabled:opacity-40", children: [busy && _jsx(IconLoader2, { className: "h-3.5 w-3.5 animate-spin" }), t("mcpIntegrations.connect")] }))] })] })) }) }));
|
|
332
364
|
}
|
|
@@ -17,6 +17,17 @@ export interface DefaultMcpIntegration {
|
|
|
17
17
|
availability: McpIntegrationAvailability;
|
|
18
18
|
verification: McpIntegrationVerification;
|
|
19
19
|
logoUrl: string;
|
|
20
|
+
/**
|
|
21
|
+
* The server has a first-party OAuth client configured for this provider.
|
|
22
|
+
* Keep the connection user-scoped even when the client itself is shared.
|
|
23
|
+
*/
|
|
24
|
+
managedOAuth?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* The provider supports a workspace connection whose access can be shared
|
|
27
|
+
* with permitted workspace members. Keep this opt-in until provider scope
|
|
28
|
+
* semantics are verified.
|
|
29
|
+
*/
|
|
30
|
+
supportsOrganizationScope?: boolean;
|
|
20
31
|
docsUrl?: string;
|
|
21
32
|
setupNoteKey?: string;
|
|
22
33
|
apiFallback?: {
|
|
@@ -51,8 +62,9 @@ export declare function isMcpIntegrationCatalogAvailable(config?: McpIntegration
|
|
|
51
62
|
export declare function mcpIntegrationAuthLabel(mode: McpIntegrationAuthMode): string;
|
|
52
63
|
export declare function buildMcpOAuthStartUrl({ name, url, description, scope, returnUrl, }: McpOAuthStartParams): string;
|
|
53
64
|
export declare function navigateToMcpOAuthStart(url: string): void;
|
|
54
|
-
export declare function resolveMcpIntegrationScope(defaultScope: "user" | "org", hasOrg: boolean, canCreateOrgMcp: boolean): "user" | "org";
|
|
65
|
+
export declare function resolveMcpIntegrationScope(defaultScope: "user" | "org", hasOrg: boolean, canCreateOrgMcp: boolean, supportsOrganizationScope?: boolean): "user" | "org";
|
|
55
66
|
export declare function shouldOfferMcpOrganizationScope(hasOrg: boolean, canCreateOrgMcp: boolean): boolean;
|
|
67
|
+
export declare function shouldOfferMcpIntegrationOrganizationScope(integration: DefaultMcpIntegration, hasOrg: boolean, canCreateOrgMcp: boolean): boolean;
|
|
56
68
|
export declare function filterMcpIntegrations(query: string, integrations?: DefaultMcpIntegration[]): DefaultMcpIntegration[];
|
|
57
69
|
export declare function findMcpIntegrationForText(text: string, integrations?: DefaultMcpIntegration[]): DefaultMcpIntegration | null;
|
|
58
70
|
/**
|