@kortix/ui 0.14.8 → 0.14.10
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/README.md +2 -2
- package/dist/_vendor/kortix-shared.js +116 -3
- package/dist/_vendor/shared/app-config.d.ts +175 -0
- package/dist/_vendor/shared/artifact-comments.d.ts +235 -0
- package/dist/_vendor/shared/channel-descriptors.d.ts +96 -0
- package/dist/_vendor/shared/channel-message.d.ts +45 -5
- package/dist/_vendor/shared/index.d.ts +2 -0
- package/dist/_vendor/shared/space-slug.d.ts +37 -0
- package/dist/access/access/access-detail-shell.js +1 -1
- package/dist/access/access/principal-picker.d.ts +11 -0
- package/dist/access/access/principal-picker.js +3 -2
- package/dist/apps/app-preview-pool.d.ts +7 -2
- package/dist/apps/app-preview-pool.js +30 -7
- package/dist/apps/app-shared.d.ts +22 -15
- package/dist/apps/app-shared.js +37 -19
- package/dist/apps/index.d.ts +2 -2
- package/dist/apps/index.js +2 -2
- package/dist/artifacts/artifact-frame.d.ts +16 -0
- package/dist/artifacts/artifact-frame.js +55 -0
- package/dist/artifacts/artifact-session.d.ts +18 -0
- package/dist/artifacts/artifact-session.js +101 -0
- package/dist/artifacts/frame-policy.d.ts +30 -0
- package/dist/artifacts/frame-policy.js +61 -0
- package/dist/artifacts/index.d.ts +3 -0
- package/dist/artifacts/index.js +5 -0
- package/dist/browser/sandbox-browser-chrome.d.ts +4 -1
- package/dist/browser/sandbox-browser-chrome.js +2 -2
- package/dist/customize/agents/agent-grant-pages.d.ts +5 -1
- package/dist/customize/agents/agent-grant-pages.js +30 -4
- package/dist/customize/agents/agent-page.js +3 -1
- package/dist/customize/agents/agent-policy-sets.d.ts +43 -0
- package/dist/customize/agents/agent-policy-sets.js +72 -0
- package/dist/customize/agents/agent-triggers-section.js +2 -1
- package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.d.ts +6 -1
- package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.js +10 -4
- package/dist/customize/connectors/agent-access.d.ts +35 -0
- package/dist/customize/connectors/agent-access.js +77 -0
- package/dist/customize/connectors/catalog/browse-sections.d.ts +2 -29
- package/dist/customize/connectors/catalog/browse-sections.js +7 -74
- package/dist/customize/connectors/catalog/catalog-entry.d.ts +18 -37
- package/dist/customize/connectors/catalog/catalog-entry.js +28 -40
- package/dist/customize/connectors/catalog/connector-browse.d.ts +3 -32
- package/dist/customize/connectors/catalog/connector-browse.js +19 -50
- package/dist/customize/connectors/catalog/use-catalog.d.ts +20 -59
- package/dist/customize/connectors/catalog/use-catalog.js +48 -175
- package/dist/customize/connectors/connector-identity.d.ts +9 -11
- package/dist/customize/connectors/connector-identity.js +13 -42
- package/dist/customize/connectors/connector-moves-banner.d.ts +2 -1
- package/dist/customize/connectors/connector-moves-banner.js +4 -6
- package/dist/customize/connectors/connector-routes.d.ts +21 -9
- package/dist/customize/connectors/connector-routes.js +29 -20
- package/dist/customize/connectors/connectors-page.js +53 -82
- package/dist/customize/connectors/detail/app-page.js +226 -98
- package/dist/customize/connectors/detail/computer-app-page.d.ts +16 -0
- package/dist/customize/connectors/detail/computer-app-page.js +39 -0
- package/dist/customize/connectors/detail/connector-accounts.js +3 -1
- package/dist/customize/connectors/detail/connector-advanced-tools.d.ts +4 -1
- package/dist/customize/connectors/detail/connector-advanced-tools.js +2 -2
- package/dist/customize/connectors/detail/connector-agents.d.ts +14 -0
- package/dist/customize/connectors/detail/connector-agents.js +69 -0
- package/dist/customize/connectors/detail/connector-detail-tabs.js +2 -1
- package/dist/customize/connectors/detail/connector-move-row.d.ts +8 -5
- package/dist/customize/connectors/detail/connector-move-row.js +23 -14
- package/dist/customize/connectors/detail/connector-page.d.ts +4 -1
- package/dist/customize/connectors/detail/connector-page.js +14 -10
- package/dist/customize/connectors/detail/connector-policy-sets.d.ts +28 -0
- package/dist/customize/connectors/detail/connector-policy-sets.js +203 -0
- package/dist/customize/connectors/detail/connector-settings.d.ts +4 -1
- package/dist/customize/connectors/detail/connector-settings.js +7 -3
- package/dist/customize/connectors/detail/connector-status.d.ts +19 -6
- package/dist/customize/connectors/detail/connector-status.js +34 -10
- package/dist/customize/connectors/detail/connector-tabs.d.ts +4 -1
- package/dist/customize/connectors/detail/connector-tabs.js +8 -2
- package/dist/customize/connectors/detail/connector-tools.d.ts +3 -3
- package/dist/customize/connectors/detail/connector-tools.js +105 -48
- package/dist/customize/connectors/detail/email-inboxes.d.ts +43 -0
- package/dist/customize/connectors/detail/email-inboxes.js +184 -0
- package/dist/customize/connectors/detail/provider-info.d.ts +1 -1
- package/dist/customize/connectors/detail/provider-info.js +2 -2
- package/dist/customize/connectors/detail/status-badge.d.ts +1 -1
- package/dist/customize/connectors/detail/status-badge.js +4 -5
- package/dist/customize/connectors/detail/use-connector-detail.d.ts +6 -0
- package/dist/customize/connectors/detail/use-connector-detail.js +14 -4
- package/dist/customize/connectors/install/install-dialog.d.ts +23 -0
- package/dist/customize/connectors/install/install-dialog.js +40 -0
- package/dist/customize/connectors/install/install.d.ts +13 -2
- package/dist/customize/connectors/install/install.js +9 -4
- package/dist/customize/connectors/install/use-install.d.ts +19 -2
- package/dist/customize/connectors/install/use-install.js +65 -37
- package/dist/customize/connectors/install/way-kind.d.ts +5 -0
- package/dist/customize/connectors/install/way-kind.js +16 -0
- package/dist/customize/connectors/provider-label.d.ts +2 -1
- package/dist/customize/connectors/provider-label.js +13 -3
- package/dist/customize/connectors/tools/pattern-rule-draft.d.ts +4 -0
- package/dist/customize/connectors/tools/pattern-rule-draft.js +12 -3
- package/dist/customize/connectors/tools/policy-sets.d.ts +27 -0
- package/dist/customize/connectors/tools/policy-sets.js +41 -0
- package/dist/customize/connectors/tools/tool-groups.d.ts +32 -9
- package/dist/customize/connectors/tools/tool-groups.js +78 -16
- package/dist/customize/connectors/tools/tool-policy-control.d.ts +11 -10
- package/dist/customize/connectors/tools/tool-policy-control.js +15 -16
- package/dist/customize/connectors/tools/tool-policy-labels.d.ts +6 -5
- package/dist/customize/connectors/tools/tool-policy-labels.js +17 -16
- package/dist/customize/connectors/tools/tool-policy.d.ts +50 -4
- package/dist/customize/connectors/tools/tool-policy.js +74 -8
- package/dist/customize/connectors/use-agent-access.d.ts +85 -0
- package/dist/customize/connectors/use-agent-access.js +72 -0
- package/dist/customize/migrate-to-v2/index.d.ts +1 -2
- package/dist/customize/migrate-to-v2/index.js +1 -2
- package/dist/customize/migrate-to-v2/migration-prompt.d.ts +12 -25
- package/dist/customize/migrate-to-v2/migration-prompt.js +34 -236
- package/dist/customize/migrate-to-v2/upgrade-defs.d.ts +1 -1
- package/dist/customize/migrate-to-v2/upgrade-defs.js +7 -6
- package/dist/customize/migrate-to-v2/upgrade-view.js +7 -7
- package/dist/customize/migrate-to-v2/use-run-upgrade.d.ts +3 -3
- package/dist/customize/providers/provider-accordion.js +17 -2
- package/dist/customize/sections/component/channel-access-panel.d.ts +16 -0
- package/dist/customize/sections/component/channel-access-panel.js +146 -0
- package/dist/customize/sections/component/channel-connect-hero.d.ts +3 -2
- package/dist/customize/sections/component/channel-connect-hero.js +3 -2
- package/dist/customize/sections/component/channel-hero-frame.d.ts +31 -0
- package/dist/customize/sections/component/channel-hero-frame.js +40 -0
- package/dist/customize/sections/component/channel-mocks.d.ts +6 -0
- package/dist/customize/sections/component/channel-mocks.js +46 -0
- package/dist/customize/sections/component/channel-row.d.ts +13 -3
- package/dist/customize/sections/component/channel-row.js +10 -4
- package/dist/customize/sections/component/email-connect-form.d.ts +27 -0
- package/dist/customize/sections/component/email-connect-form.js +183 -0
- package/dist/customize/sections/component/slack-connect-card.d.ts +7 -0
- package/dist/customize/sections/component/slack-connect-card.js +2 -3
- package/dist/customize/sections/component/teams-connect-card.d.ts +7 -0
- package/dist/customize/sections/component/teams-connect-card.js +2 -3
- package/dist/customize/sections/component/telegram-channel-row.js +21 -28
- package/dist/customize/sections/connectors-view.d.ts +1 -15
- package/dist/customize/sections/connectors-view.js +81 -314
- package/dist/customize/sections/view/agent-editor-catalog.js +10 -0
- package/dist/customize/sections/view/channels-view.d.ts +6 -1
- package/dist/customize/sections/view/channels-view.js +72 -81
- package/dist/customize/sections/view/gateway/gateway-overview.js +10 -2
- package/dist/customize/settings/rail.js +9 -0
- package/dist/customize/settings/settings-tabs.d.ts +1 -1
- package/dist/customize/settings/settings-tabs.js +1 -0
- package/dist/customize/settings/tabs/chrome-connections-tab.d.ts +6 -0
- package/dist/customize/settings/tabs/chrome-connections-tab.js +99 -0
- package/dist/customize/settings/tabs/experimental-tab.js +35 -16
- package/dist/customize/shared/catalog/catalog-empty-state.d.ts +4 -15
- package/dist/customize/shared/catalog/catalog-empty-state.js +9 -7
- package/dist/customize/shared/channels-switch-dialog.d.ts +18 -0
- package/dist/customize/shared/channels-switch-dialog.js +30 -0
- package/dist/customize/shared/feature-gate-screen.js +27 -9
- package/dist/customize/shared/use-customize-prefetch.d.ts +2 -3
- package/dist/customize/shared/use-customize-prefetch.js +9 -27
- package/dist/customize/triggers/schedule/post-to-field.d.ts +18 -0
- package/dist/customize/triggers/schedule/post-to-field.js +49 -0
- package/dist/customize/triggers/schedule/schedule-copy.d.ts +10 -6
- package/dist/customize/triggers/schedule/schedule-copy.js +42 -11
- package/dist/customize/triggers/schedule/schedule-detail-sheet.js +2 -1
- package/dist/customize/triggers/schedule/trigger-composer-logic.d.ts +22 -0
- package/dist/customize/triggers/schedule/trigger-composer-logic.js +25 -0
- package/dist/customize/triggers/schedule/trigger-composer.d.ts +5 -0
- package/dist/customize/triggers/schedule/trigger-composer.js +23 -14
- package/dist/customize/triggers/schedule/trigger-edit-logic.js +3 -0
- package/dist/customize/triggers/schedule/trigger-filter.js +1 -1
- package/dist/customize/triggers/schedule/trigger-runs-logic.d.ts +2 -2
- package/dist/customize/triggers/schedule/trigger-runs-panel.js +1 -0
- package/dist/customize/triggers/schedule/trigger-toast.js +2 -1
- package/dist/customize/triggers/schedule-view.js +5 -2
- package/dist/files/index.d.ts +1 -0
- package/dist/files/index.js +1 -0
- package/dist/files/project/change-request-recovery.d.ts +1 -26
- package/dist/files/project/change-request-recovery.js +1 -59
- package/dist/files/project/components/change-request-detail-dialog.js +13 -3
- package/dist/files/project/components/drive-explorer.js +15 -15
- package/dist/files/project/components/drive-toolbar.d.ts +16 -2
- package/dist/files/project/components/drive-toolbar.js +14 -5
- package/dist/files/project/hooks/use-change-request-recovery.js +3 -19
- package/dist/files/project/hooks/use-change-requests.d.ts +1 -0
- package/dist/files/project/hooks/use-change-requests.js +11 -2
- package/dist/files/renderers/image-frame.d.ts +48 -0
- package/dist/files/renderers/image-frame.js +59 -0
- package/dist/files/renderers/image-renderer.d.ts +11 -1
- package/dist/files/renderers/image-renderer.js +13 -3
- package/dist/files/renderers/pdf/pdf-clipboard.d.ts +2 -0
- package/dist/files/renderers/pdf/pdf-clipboard.js +21 -0
- package/dist/files/renderers/pdf/pdf-viewer.js +4 -2
- package/dist/files/renderers/show-content-renderer.d.ts +9 -1
- package/dist/files/renderers/show-content-renderer.js +56 -14
- package/dist/files/runtime/file-source.js +2 -0
- package/dist/files/runtime/hooks/use-binary-blob.d.ts +10 -1
- package/dist/files/runtime/hooks/use-binary-blob.js +10 -4
- package/dist/files/runtime/hooks/use-shared-image.d.ts +41 -0
- package/dist/files/runtime/hooks/use-shared-image.js +177 -0
- package/dist/files/viewer/file-content-renderer.d.ts +22 -1
- package/dist/files/viewer/file-content-renderer.js +50 -7
- package/dist/files/viewer/file-header.d.ts +7 -3
- package/dist/files/viewer/file-header.js +20 -11
- package/dist/files/viewer/file-preview-modal.d.ts +1 -1
- package/dist/files/viewer/file-preview-modal.js +10 -22
- package/dist/files/viewer/file-source.d.ts +13 -0
- package/dist/files/viewer/use-file-content-state.d.ts +2 -0
- package/dist/files/viewer/use-file-content-state.js +28 -10
- package/dist/files/viewer/viewer-actions.d.ts +3 -1
- package/dist/files/viewer/viewer-actions.js +2 -2
- package/dist/hooks/use-media-query.d.ts +1 -0
- package/dist/hooks/use-mobile.d.ts +5 -0
- package/dist/hooks/use-mobile.js +8 -0
- package/dist/i18n/en.d.ts +1062 -85
- package/dist/i18n/en.js +1078 -101
- package/dist/i18n/ui-catalog/localize-ui-catalog.js +4 -0
- package/dist/i18n/ui-catalog/remaining-ui-translation-keys.generated.js +15 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/internal/account-hub/account-settings-sidebar.js +1 -1
- package/dist/internal/account-hub/hub-sheet.d.ts +9 -1
- package/dist/internal/account-hub/hub-sheet.js +21 -5
- package/dist/internal/account-hub/sections.d.ts +1 -1
- package/dist/internal/account-hub/sections.js +2 -1
- package/dist/internal/apps-and-extensions/apps-modal.d.ts +9 -0
- package/dist/internal/apps-and-extensions/apps-modal.js +107 -0
- package/dist/internal/auth/auth-card-shell.js +3 -3
- package/dist/internal/chrome/browser-icon.d.ts +24 -0
- package/dist/internal/chrome/browser-icon.js +58 -0
- package/dist/internal/chrome/chrome-card-state.d.ts +16 -0
- package/dist/internal/chrome/chrome-card-state.js +9 -0
- package/dist/internal/chrome/chrome-connect.d.ts +69 -0
- package/dist/internal/chrome/chrome-connect.js +178 -0
- package/dist/internal/chrome/chrome-mock.d.ts +4 -0
- package/dist/internal/chrome/chrome-mock.js +15 -0
- package/dist/internal/chrome/chrome-names.d.ts +15 -0
- package/dist/internal/chrome/chrome-names.js +35 -0
- package/dist/internal/chrome/extension.d.ts +47 -0
- package/dist/internal/chrome/extension.js +91 -0
- package/dist/internal/chrome/use-chrome-offered.d.ts +11 -0
- package/dist/internal/chrome/use-chrome-offered.js +22 -0
- package/dist/internal/components/agent-mark.js +5 -2
- package/dist/internal/connector-logo/connector-logo-source.d.ts +64 -0
- package/dist/internal/connector-logo/connector-logo-source.js +49 -0
- package/dist/internal/connector-logo/connector-logo.d.ts +39 -0
- package/dist/internal/connector-logo/connector-logo.js +56 -0
- package/dist/internal/connector-logo/connector-mark-files.d.ts +11 -0
- package/dist/internal/connector-logo/connector-mark-files.js +35 -0
- package/dist/internal/files/file-read-retry.d.ts +13 -0
- package/dist/internal/files/file-read-retry.js +23 -3
- package/dist/internal/files/session-drive-files.d.ts +5 -1
- package/dist/internal/files/session-drive-files.js +7 -2
- package/dist/internal/hooks/channels/use-channels-installations.d.ts +32 -5
- package/dist/internal/hooks/channels/use-channels-installations.js +55 -7
- package/dist/internal/hooks/channels/use-email-inboxes.d.ts +19 -0
- package/dist/internal/hooks/channels/use-email-inboxes.js +48 -0
- package/dist/internal/hooks/connectors/use-add-account.js +1 -1
- package/dist/internal/hooks/index.d.ts +1 -1
- package/dist/internal/hooks/index.js +1 -1
- package/dist/internal/hooks/projects/use-new-project-session.d.ts +9 -0
- package/dist/internal/hooks/projects/use-new-project-session.js +28 -12
- package/dist/internal/hooks/use-auto-scroll.d.ts +8 -1
- package/dist/internal/hooks/use-auto-scroll.js +4 -4
- package/dist/internal/icons/edge.d.ts +5 -0
- package/dist/internal/icons/edge.js +10 -0
- package/dist/internal/icons/telegram.d.ts +5 -0
- package/dist/internal/icons/telegram.js +6 -1
- package/dist/internal/layout/nav-hover-card.d.ts +35 -0
- package/dist/internal/layout/nav-hover-card.js +84 -0
- package/dist/internal/layout/project-nav-row.d.ts +3 -1
- package/dist/internal/layout/project-nav-row.js +3 -2
- package/dist/internal/layout/project-page-header.d.ts +4 -2
- package/dist/internal/layout/project-page-header.js +4 -3
- package/dist/internal/layout/project-settings-nav.js +59 -2
- package/dist/internal/lib/browser-error-noise.d.ts +1 -1
- package/dist/internal/lib/browser-error-noise.js +1 -1
- package/dist/internal/lib/browser-noise/rules/extensions.js +17 -3
- package/dist/internal/lib/browser-noise/rules/injected-scripts.d.ts +7 -0
- package/dist/internal/lib/browser-noise/rules/injected-scripts.js +15 -0
- package/dist/internal/lib/detect-os.d.ts +43 -0
- package/dist/internal/lib/detect-os.js +70 -0
- package/dist/internal/lib/manifest-version.d.ts +1 -1
- package/dist/internal/lib/manifest-version.js +2 -2
- package/dist/internal/lib/memory-href.d.ts +16 -0
- package/dist/internal/lib/memory-href.js +46 -0
- package/dist/internal/lib/use-project-feature-flags.js +13 -9
- package/dist/internal/lib/utils/heic-convert.d.ts +1 -1
- package/dist/internal/lib/utils/heic-convert.js +3 -4
- package/dist/internal/lib/web-notifications.d.ts +20 -0
- package/dist/internal/lib/web-notifications.js +48 -4
- package/dist/internal/notifications/notification-bell.d.ts +4 -1
- package/dist/internal/notifications/notification-bell.js +2 -2
- package/dist/internal/selection/selection-bar.d.ts +2 -1
- package/dist/internal/selection/selection-bar.js +1 -1
- package/dist/internal/stores/apps-modal-store.d.ts +8 -0
- package/dist/internal/stores/apps-modal-store.js +6 -0
- package/dist/internal/stores/composer-prefill-store.d.ts +12 -5
- package/dist/internal/stores/file-preview-store.d.ts +29 -2
- package/dist/internal/stores/file-preview-store.js +19 -1
- package/dist/internal/stores/kortix-computer-store.js +3 -0
- package/dist/internal/stores/sidebar-nav-store.d.ts +1 -1
- package/dist/internal/stores/sidebar-nav-store.js +3 -1
- package/dist/lib/routes.d.ts +13 -1
- package/dist/lib/routes.js +13 -0
- package/dist/markdown/index.d.ts +2 -1
- package/dist/markdown/index.js +2 -1
- package/dist/markdown/setup-links/approval-decision.d.ts +1 -0
- package/dist/markdown/setup-links/approval-decision.js +9 -3
- package/dist/markdown/setup-links/connector-handshake.d.ts +3 -1
- package/dist/markdown/setup-links/connector-handshake.js +12 -10
- package/dist/markdown/setup-links/secret-intake-form.d.ts +0 -10
- package/dist/markdown/setup-links/secret-intake-form.js +1 -1
- package/dist/markdown/setup-links/show-connect-hero.d.ts +28 -0
- package/dist/markdown/setup-links/show-connect-hero.js +91 -0
- package/dist/markdown/unified-markdown.js +5 -5
- package/dist/primitives/badge.d.ts +1 -1
- package/dist/primitives/badge.js +2 -0
- package/dist/primitives/disclosure.js +14 -2
- package/dist/primitives/empty-art.d.ts +12 -0
- package/dist/primitives/empty-art.js +11 -0
- package/dist/primitives/empty-state.d.ts +2 -2
- package/dist/primitives/empty-state.js +6 -5
- package/dist/primitives/mermaid-renderer.d.ts +2 -0
- package/dist/primitives/mermaid-renderer.js +21 -15
- package/dist/primitives/resizable.js +6 -1
- package/dist/primitives/resize-seam.d.ts +11 -0
- package/dist/primitives/resize-seam.js +12 -0
- package/dist/primitives/sidebar-panel.js +4 -7
- package/dist/primitives/tabs.d.ts +14 -1
- package/dist/primitives/tabs.js +1 -1
- package/dist/providers/ui-provider.d.ts +9 -0
- package/dist/session/composer/ComposerAboveCard.d.ts +1 -1
- package/dist/session/composer/ComposerAboveCard.js +2 -2
- package/dist/session/composer/ComposerCard.d.ts +1 -1
- package/dist/session/composer/ComposerCard.js +3 -3
- package/dist/session/composer/agent-selector.d.ts +13 -1
- package/dist/session/composer/agent-selector.js +25 -5
- package/dist/session/composer/composer-agent-access.d.ts +15 -0
- package/dist/session/composer/composer-agent-access.js +27 -0
- package/dist/session/composer/composer-chat-input.d.ts +8 -2
- package/dist/session/composer/composer-chat-input.js +8 -6
- package/dist/session/composer/composer-logic.d.ts +16 -0
- package/dist/session/composer/composer-logic.js +12 -0
- package/dist/session/composer/composer-underbar.d.ts +3 -1
- package/dist/session/composer/composer-underbar.js +4 -3
- package/dist/session/composer/composer.d.ts +15 -1
- package/dist/session/composer/composer.js +19 -1
- package/dist/session/composer/draft/composer-draft.d.ts +6 -2
- package/dist/session/composer/draft/composer-draft.js +5 -1
- package/dist/session/composer/reasoning-effort-selector.js +1 -1
- package/dist/session/models/chatgpt-connection-button.d.ts +11 -0
- package/dist/session/models/chatgpt-connection-button.js +54 -0
- package/dist/session/models/model-selector.js +5 -2
- package/dist/session/models/use-model-connection-gate.d.ts +5 -5
- package/dist/session/models/use-model-connection-gate.js +5 -5
- package/dist/session/outcomes/jump-to-outcome.d.ts +10 -0
- package/dist/session/outcomes/jump-to-outcome.js +11 -0
- package/dist/session/outcomes/session-outcomes-bridge.d.ts +14 -0
- package/dist/session/outcomes/session-outcomes-bridge.js +12 -0
- package/dist/session/outcomes/session-outcomes-provider.d.ts +3 -1
- package/dist/session/outcomes/session-outcomes-provider.js +33 -3
- package/dist/session/panel/easy/app-preview.d.ts +10 -0
- package/dist/session/panel/easy/app-preview.js +31 -12
- package/dist/session/panel/easy/change-requests-card.d.ts +7 -0
- package/dist/session/panel/easy/change-requests-card.js +17 -0
- package/dist/session/panel/easy/easy-panel-logic.js +7 -1
- package/dist/session/panel/easy/easy-panel.js +5 -2
- package/dist/session/panel/easy/file-preview.js +1 -1
- package/dist/session/panel/easy/outputs-card.d.ts +2 -1
- package/dist/session/panel/easy/outputs-card.js +3 -2
- package/dist/session/panel/mobile-tool-drawer.js +7 -1
- package/dist/session/panel/session-audit-panel.js +9 -2
- package/dist/session/panel/session-audit-shared.js +3 -1
- package/dist/session/panel/session-detail-panel.js +9 -3
- package/dist/session/panel/session-files-explorer.d.ts +9 -0
- package/dist/session/panel/session-files-explorer.js +12 -3
- package/dist/session/panel/session-panel-provider.d.ts +15 -1
- package/dist/session/panel/session-panel-provider.js +32 -7
- package/dist/session/panel/shared/derive-panels.d.ts +8 -1
- package/dist/session/panel/shared/derive-panels.js +12 -2
- package/dist/session/panel/shared/output-priority.js +2 -0
- package/dist/session/participants/session-participants.d.ts +8 -2
- package/dist/session/participants/session-participants.js +11 -4
- package/dist/session/prompts/approval-request.d.ts +5 -0
- package/dist/session/prompts/approval-request.js +9 -1
- package/dist/session/prompts/session-approval-review.d.ts +9 -0
- package/dist/session/prompts/session-approval-review.js +18 -0
- package/dist/session/status/session-error-banner.js +2 -49
- package/dist/session/status/session-starting-loader.d.ts +14 -2
- package/dist/session/status/session-starting-loader.js +16 -4
- package/dist/session/thread/after-first-prompt.d.ts +7 -0
- package/dist/session/thread/after-first-prompt.js +8 -0
- package/dist/session/thread/detect-command.d.ts +12 -0
- package/dist/session/thread/detect-command.js +20 -0
- package/dist/session/thread/session-chat.d.ts +3 -1
- package/dist/session/thread/session-chat.js +377 -252
- package/dist/session/thread/session-thread.d.ts +15 -1
- package/dist/session/thread/session-thread.js +20 -3
- package/dist/session/thread/session-transcript-class.d.ts +5 -1
- package/dist/session/thread/session-transcript-class.js +5 -1
- package/dist/session/thread/thread-boot-rows.d.ts +36 -0
- package/dist/session/thread/thread-boot-rows.js +89 -0
- package/dist/session/thread/transcript-rows.d.ts +31 -0
- package/dist/session/thread/transcript-rows.js +3 -0
- package/dist/session/thread/transcript.d.ts +0 -9
- package/dist/session/thread/transcript.js +104 -19
- package/dist/session/tool/shared/infrastructure-contexts.d.ts +28 -0
- package/dist/session/tool/shared/infrastructure-contexts.js +31 -3
- package/dist/session/tool/tool-part-renderer.d.ts +5 -4
- package/dist/session/tool/tool-part-renderer.js +8 -3
- package/dist/session/tool/tools/bash-tool.js +7 -6
- package/dist/session/tool/tools/channel-send-card.d.ts +1 -2
- package/dist/session/tool/tools/channel-send.d.ts +2 -1
- package/dist/session/tool/tools/codemode-tool.js +1 -1
- package/dist/session/tool/tools/connector-tools.js +1 -1
- package/dist/session/tool/tools/image-gen-tool.d.ts +1 -1
- package/dist/session/tool/tools/image-gen-tool.js +241 -53
- package/dist/session/tool/tools/show-tool.js +19 -8
- package/dist/session/turn/channel-brand.d.ts +8 -3
- package/dist/session/turn/channel-brand.js +20 -4
- package/dist/session/turn/message-author.d.ts +8 -0
- package/dist/session/turn/message-author.js +24 -0
- package/dist/session/turn/message-row.d.ts +52 -0
- package/dist/session/turn/message-row.js +44 -0
- package/dist/session/turn/plan-anchor.d.ts +1 -1
- package/dist/session/turn/plan-anchor.js +1 -1
- package/dist/session/turn/user-message.d.ts +14 -6
- package/dist/session/turn/user-message.js +35 -15
- package/dist/styles.css +1 -1
- package/dist/workspace/home/access-requests-bell.d.ts +9 -2
- package/dist/workspace/home/access-requests-bell.js +20 -6
- package/dist/workspace/home/first-chat.d.ts +8 -21
- package/dist/workspace/home/first-chat.js +22 -72
- package/dist/workspace/index.d.ts +6 -0
- package/dist/workspace/index.js +6 -0
- package/dist/workspace/layout/project-home.d.ts +14 -2
- package/dist/workspace/layout/project-home.js +60 -21
- package/dist/workspace/layout/use-project-home-send.d.ts +9 -1
- package/dist/workspace/layout/use-project-home-send.js +82 -3
- package/dist/workspace/memory/body-doc.d.ts +17 -0
- package/dist/workspace/memory/body-doc.js +208 -0
- package/dist/workspace/memory/body-extensions.d.ts +38 -0
- package/dist/workspace/memory/body-extensions.js +103 -0
- package/dist/workspace/memory/company-memory-page.d.ts +8 -0
- package/dist/workspace/memory/company-memory-page.js +16 -0
- package/dist/workspace/memory/memory-all.d.ts +20 -0
- package/dist/workspace/memory/memory-all.js +27 -0
- package/dist/workspace/memory/memory-body.d.ts +19 -0
- package/dist/workspace/memory/memory-body.js +139 -0
- package/dist/workspace/memory/memory-empty.d.ts +13 -0
- package/dist/workspace/memory/memory-empty.js +28 -0
- package/dist/workspace/memory/memory-history.d.ts +27 -0
- package/dist/workspace/memory/memory-history.js +108 -0
- package/dist/workspace/memory/memory-labels.d.ts +16 -0
- package/dist/workspace/memory/memory-labels.js +47 -0
- package/dist/workspace/memory/memory-page-list.d.ts +34 -0
- package/dist/workspace/memory/memory-page-list.js +156 -0
- package/dist/workspace/memory/memory-reader.d.ts +58 -0
- package/dist/workspace/memory/memory-reader.js +123 -0
- package/dist/workspace/memory/memory-view.d.ts +21 -0
- package/dist/workspace/memory/memory-view.js +124 -0
- package/dist/workspace/memory/remember-popover.d.ts +19 -0
- package/dist/workspace/memory/remember-popover.js +61 -0
- package/dist/workspace/memory/remember-this.d.ts +12 -0
- package/dist/workspace/memory/remember-this.js +89 -0
- package/dist/workspace/memory/source-mark.d.ts +18 -0
- package/dist/workspace/memory/source-mark.js +79 -0
- package/dist/workspace/memory/used-memory-chip.d.ts +14 -0
- package/dist/workspace/memory/used-memory-chip.js +61 -0
- package/dist/workspace/new/advanced-fields.d.ts +2 -1
- package/dist/workspace/new/advanced-fields.js +2 -2
- package/dist/workspace/new/source-param.d.ts +1 -1
- package/dist/workspace/new/source-param.js +3 -1
- package/dist/workspace/new/use-create-workspace.d.ts +8 -10
- package/dist/workspace/new/use-create-workspace.js +3 -3
- package/dist/workspace/projects/onboarding/app-logo.d.ts +7 -2
- package/dist/workspace/projects/onboarding/app-logo.js +6 -13
- package/dist/workspace/projects/policies-panel.js +5 -3
- package/dist/workspace/review/review-actions.d.ts +4 -2
- package/dist/workspace/review/review-actions.js +8 -2
- package/dist/workspace/review/review-center.js +11 -7
- package/dist/workspace/review/review-detail.d.ts +10 -0
- package/dist/workspace/review/review-detail.js +101 -13
- package/dist/workspace/saved-session-skeleton.d.ts +2 -2
- package/dist/workspace/saved-session-skeleton.js +3 -3
- package/dist/workspace/session-workspace.js +15 -13
- package/dist/workspace/sessions/project-sessions-view.js +3 -2
- package/dist/workspace/sessions/session-label-badges.js +2 -1
- package/dist/workspace/sessions/sessions-toolbar.d.ts +3 -1
- package/dist/workspace/sessions/sessions-toolbar.js +2 -2
- package/dist/workspace/sidebar/footer/project-apps-nav.d.ts +5 -0
- package/dist/workspace/sidebar/footer/project-apps-nav.js +41 -2
- package/dist/workspace/sidebar/footer/project-artifacts-nav.d.ts +6 -0
- package/dist/workspace/sidebar/footer/project-artifacts-nav.js +22 -0
- package/dist/workspace/sidebar/footer/project-chrome-nav.d.ts +10 -0
- package/dist/workspace/sidebar/footer/project-chrome-nav.js +56 -0
- package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.js +13 -13
- package/dist/workspace/sidebar/footer/project-memory-nav.d.ts +7 -0
- package/dist/workspace/sidebar/footer/project-memory-nav.js +19 -0
- package/dist/workspace/sidebar/nav-row-meta.js +14 -2
- package/dist/workspace/sidebar/project-nav-items.js +3 -0
- package/dist/workspace/sidebar/project-session-list.js +68 -56
- package/dist/workspace/sidebar/project-sidebar.js +13 -2
- package/dist/workspace/sidebar/project-spaces-nav.d.ts +8 -0
- package/dist/workspace/sidebar/project-spaces-nav.js +69 -0
- package/dist/workspace/sidebar/session-group-order.d.ts +9 -0
- package/dist/workspace/sidebar/session-group-order.js +25 -0
- package/dist/workspace/sidebar/session-group-sections.d.ts +62 -0
- package/dist/workspace/sidebar/session-group-sections.js +267 -0
- package/dist/workspace/sidebar/session-list-chrome.d.ts +28 -0
- package/dist/workspace/sidebar/session-list-chrome.js +50 -0
- package/dist/workspace/spaces/channel-glyph.d.ts +5 -0
- package/dist/workspace/spaces/channel-glyph.js +6 -0
- package/dist/workspace/spaces/channel-setup.d.ts +16 -0
- package/dist/workspace/spaces/channel-setup.js +105 -0
- package/dist/workspace/spaces/channels-onboarding.d.ts +13 -0
- package/dist/workspace/spaces/channels-onboarding.js +37 -0
- package/dist/workspace/spaces/create-channel-dialog.d.ts +16 -0
- package/dist/workspace/spaces/create-channel-dialog.js +158 -0
- package/dist/workspace/spaces/private-channels-not-in.d.ts +9 -0
- package/dist/workspace/spaces/private-channels-not-in.js +69 -0
- package/dist/workspace/spaces/space-agents.d.ts +10 -0
- package/dist/workspace/spaces/space-agents.js +10 -0
- package/dist/workspace/spaces/space-details-dialog.d.ts +20 -0
- package/dist/workspace/spaces/space-details-dialog.js +176 -0
- package/dist/workspace/spaces/space-link-label.d.ts +49 -0
- package/dist/workspace/spaces/space-link-label.js +73 -0
- package/dist/workspace/spaces/space-links.d.ts +19 -0
- package/dist/workspace/spaces/space-links.js +230 -0
- package/dist/workspace/spaces/space-members.d.ts +46 -0
- package/dist/workspace/spaces/space-members.js +182 -0
- package/dist/workspace/spaces/space-roster.d.ts +15 -0
- package/dist/workspace/spaces/space-roster.js +44 -0
- package/dist/workspace/spaces/space-threads-tab.d.ts +56 -0
- package/dist/workspace/spaces/space-threads-tab.js +156 -0
- package/dist/workspace/spaces/space-timeline-view.d.ts +254 -0
- package/dist/workspace/spaces/space-timeline-view.js +235 -0
- package/dist/workspace/spaces/space-timeline.d.ts +106 -0
- package/dist/workspace/spaces/space-timeline.js +183 -0
- package/dist/workspace/spaces/space-triggers.d.ts +13 -0
- package/dist/workspace/spaces/space-triggers.js +78 -0
- package/dist/workspace/spaces/space-view.d.ts +37 -0
- package/dist/workspace/spaces/space-view.js +436 -0
- package/package.json +67 -36
- package/skills/kortix-ui/SKILL.md +3 -3
- package/skills/kortix-ui/references/custom-dashboard.md +3 -3
- package/skills/kortix-ui/references/modules.md +29 -5
- package/skills/kortix-ui/references/theming.md +1 -1
- package/dist/customize/connectors/catalog/merge-search.d.ts +0 -10
- package/dist/customize/connectors/catalog/merge-search.js +0 -26
- package/dist/customize/connectors/detail/find-easy-connect-app.d.ts +0 -29
- package/dist/customize/connectors/detail/find-easy-connect-app.js +0 -22
- package/dist/customize/migrate-to-v2/use-migrate-to-v2.d.ts +0 -9
- package/dist/customize/migrate-to-v2/use-migrate-to-v2.js +0 -24
- package/dist/customize/sections/connector-connection-header.d.ts +0 -36
- package/dist/customize/sections/connector-connection-header.js +0 -33
- package/dist/customize/sections/connector-connection-modal.d.ts +0 -34
- package/dist/customize/sections/connector-connection-modal.js +0 -72
- package/dist/customize/sections/discover-catalogue-card.d.ts +0 -19
- package/dist/customize/sections/discover-catalogue-card.js +0 -26
- package/dist/customize/sections/discover-catalogue-detail.d.ts +0 -15
- package/dist/customize/sections/discover-catalogue-detail.js +0 -24
- package/dist/customize/sections/discover-catalogue.d.ts +0 -17
- package/dist/customize/sections/discover-catalogue.js +0 -132
- package/dist/customize/sections/llm-provider/provider-access-menu.d.ts +0 -10
- package/dist/customize/sections/llm-provider/provider-access-menu.js +0 -23
- package/dist/files/project/components/drive-empty-art.d.ts +0 -2
- package/dist/files/project/components/drive-empty-art.js +0 -5
- package/dist/internal/hooks/use-media-query.d.ts +0 -2
- package/dist/internal/share/public-share-link-button.d.ts +0 -14
- package/dist/internal/share/public-share-link-button.js +0 -17
- package/dist/markdown/setup-links/app-credentials-form.d.ts +0 -12
- package/dist/markdown/setup-links/app-credentials-form.js +0 -115
- /package/dist/{internal/hooks → hooks}/use-media-query.js +0 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Email inboxes as ACCOUNTS on the `kortix_email` connector profile. One
|
|
5
|
+
* profile, many inboxes: each Resend inbox is an account with a name, an owner
|
|
6
|
+
* (you only, or shared) and a default, like every other connector's accounts.
|
|
7
|
+
* What only email adds lives here: the "Add inbox" dialog (the standard
|
|
8
|
+
* account fields, then where the inbox lives and its address), who may email
|
|
9
|
+
* an inbox, and the Email hero that counts the inboxes.
|
|
10
|
+
*/
|
|
11
|
+
import { CaretRightIcon } from '@phosphor-icons/react';
|
|
12
|
+
import { getProjectDetail } from '@kortix/sdk';
|
|
13
|
+
import { contract, qk, useProjectAccountId } from '@kortix/sdk/react';
|
|
14
|
+
import { useQuery } from '@tanstack/react-query';
|
|
15
|
+
import { useState } from 'react';
|
|
16
|
+
import { grantConnectionAccess } from '../../../access/access/access-dialog-share.js';
|
|
17
|
+
import { useTranslations } from '../../../i18n/index.js';
|
|
18
|
+
import { useEmailInboxes, useUpdateEmailInbox, } from '../../../internal/hooks/channels/use-email-inboxes.js';
|
|
19
|
+
import { PROJECT_ACTIONS } from '../../../internal/lib/project-actions.js';
|
|
20
|
+
import { useProjectCan } from '../../../internal/lib/use-project-can.js';
|
|
21
|
+
import { Button } from '../../../primitives/button.js';
|
|
22
|
+
import { Checkbox } from '../../../primitives/checkbox.js';
|
|
23
|
+
import { Field } from '../../../primitives/field.js';
|
|
24
|
+
import { InfoBanner } from '../../../primitives/info-banner.js';
|
|
25
|
+
import { Input } from '../../../primitives/input.js';
|
|
26
|
+
import { Label } from '../../../primitives/label.js';
|
|
27
|
+
import Loading from '../../../primitives/loading.js';
|
|
28
|
+
import { Modal, ModalBody, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalTitle, } from '../../../primitives/modal.js';
|
|
29
|
+
import { errorToast, successToast } from '../../../primitives/toast.js';
|
|
30
|
+
import { UiLink as Link } from '../../../providers/ui-provider.js';
|
|
31
|
+
import { AddAccountFields } from '../../sections/add-account-fields.js';
|
|
32
|
+
import { ChannelHeroFrame, ChannelHeroStatus } from '../../sections/component/channel-hero-frame.js';
|
|
33
|
+
import { EmailThreadMock } from '../../sections/component/channel-mocks.js';
|
|
34
|
+
import { EmailConnectForm } from '../../sections/component/email-connect-form.js';
|
|
35
|
+
import { newAccountGrantees, newAccountLabelTaken, } from '../../sections/view/connector-connections.js';
|
|
36
|
+
import { proposeAccountLabel } from '../install/install.js';
|
|
37
|
+
import { connectorHref } from '../connector-routes.js';
|
|
38
|
+
/** The one connector profile every inbox is an account on. */
|
|
39
|
+
export const EMAIL_CONNECTOR_SLUG = 'kortix_email';
|
|
40
|
+
/** "Kortix managed" or "Your Resend account": where an inbox lives. */
|
|
41
|
+
export function EmailInboxHome({ inbox }) {
|
|
42
|
+
const t = useTranslations('emailInboxes');
|
|
43
|
+
return _jsx("span", { children: inbox.managed ? t('homeManaged') : t('homeOwn') });
|
|
44
|
+
}
|
|
45
|
+
/** The sender policy in the editor's shape, whatever casing the wire used. */
|
|
46
|
+
export function inboxSenderPolicy(inbox) {
|
|
47
|
+
const raw = (inbox?.sender_policy ?? {});
|
|
48
|
+
const list = (camel, snake) => {
|
|
49
|
+
const value = raw[camel] ?? raw[snake];
|
|
50
|
+
return Array.isArray(value) ? value.map(String) : [];
|
|
51
|
+
};
|
|
52
|
+
const regex = raw.allowedRegex ?? raw.allowed_regex;
|
|
53
|
+
return {
|
|
54
|
+
mode: raw.mode === 'restricted' ? 'restricted' : 'allow_all',
|
|
55
|
+
allowedEmails: list('allowedEmails', 'allowed_emails'),
|
|
56
|
+
allowedDomains: list('allowedDomains', 'allowed_domains'),
|
|
57
|
+
allowedRegex: typeof regex === 'string' && regex ? regex : null,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** What the account half of "Add inbox" needs: may the viewer share, and "Everyone in {project}". */
|
|
61
|
+
function useInboxAccountAccess(projectId) {
|
|
62
|
+
const tSharing = useTranslations('accessSharing');
|
|
63
|
+
const accountId = useProjectAccountId(projectId);
|
|
64
|
+
const canManageConnections = useProjectCan(projectId, PROJECT_ACTIONS.PROJECT_CONNECTOR_CONNECTIONS_MANAGE, { accountId }).allowed === true;
|
|
65
|
+
const projectQuery = useQuery({
|
|
66
|
+
queryKey: qk.project.detail(projectId),
|
|
67
|
+
queryFn: () => getProjectDetail(projectId),
|
|
68
|
+
...contract('config'),
|
|
69
|
+
});
|
|
70
|
+
const projectName = projectQuery.data?.project?.name ?? '';
|
|
71
|
+
const everyoneLabel = projectName ? tSharing('everyone', { project: projectName }) : tSharing('visibilityEveryone');
|
|
72
|
+
return { accountId, canManageConnections, everyoneLabel };
|
|
73
|
+
}
|
|
74
|
+
const EMPTY_DRAFT = { label: '', audience: 'project', picked: { memberIds: [], groupIds: [] } };
|
|
75
|
+
/**
|
|
76
|
+
* "Add inbox": the account's name and who can use it (`AddAccountFields`, the
|
|
77
|
+
* same fields every connector's Add account asks), then the inbox itself
|
|
78
|
+
* (`EmailConnectForm`). Picked people get the account shared with them after
|
|
79
|
+
* it exists, exactly like `useAddAccount`.
|
|
80
|
+
*/
|
|
81
|
+
export function AddEmailInboxDialog({ projectId, open, onOpenChange, existing, onAdded, }) {
|
|
82
|
+
const t = useTranslations('emailInboxes');
|
|
83
|
+
const { accountId, canManageConnections, everyoneLabel } = useInboxAccountAccess(projectId);
|
|
84
|
+
const [draft, setDraft] = useState(EMPTY_DRAFT);
|
|
85
|
+
const [opened, setOpened] = useState(false);
|
|
86
|
+
// Each opening starts from a free name; a shared account needs the right to share.
|
|
87
|
+
if (open && !opened) {
|
|
88
|
+
setOpened(true);
|
|
89
|
+
setDraft({
|
|
90
|
+
...EMPTY_DRAFT,
|
|
91
|
+
audience: canManageConnections ? 'project' : 'private',
|
|
92
|
+
label: proposeAccountLabel(t('defaultLabel'), existing.map((row) => row.label)),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
if (!open && opened)
|
|
96
|
+
setOpened(false);
|
|
97
|
+
const labelTaken = newAccountLabelTaken(draft, existing);
|
|
98
|
+
const share = draft.audience === 'private' ? 'me' : 'project';
|
|
99
|
+
const ready = draft.label.trim().length > 0 &&
|
|
100
|
+
!labelTaken &&
|
|
101
|
+
(draft.audience !== 'members' || draft.picked.memberIds.length + draft.picked.groupIds.length > 0);
|
|
102
|
+
return (_jsx(Modal, { open: open, onOpenChange: onOpenChange, children: _jsxs(ModalContent, { className: "lg:max-w-2xl", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: t('addTitle') }), _jsx(ModalDescription, { children: t('addDescription') })] }), _jsxs(ModalBody, { className: "max-h-[75vh] space-y-6 overflow-y-auto", children: [_jsx("section", { className: "space-y-4", children: _jsx(AddAccountFields, { projectId: projectId, value: draft, onChange: setDraft, labelTaken: labelTaken, canManageConnections: canManageConnections, accountId: accountId, everyoneLabel: everyoneLabel, hint: t('labelHint'), autoFocus: true }) }), ready ? (_jsx(EmailConnectForm, { projectId: projectId, account: { label: draft.label, share }, onConnected: async (inbox) => {
|
|
103
|
+
if (draft.audience === 'members' && accountId) {
|
|
104
|
+
await grantConnectionAccess(accountId, projectId, inbox.connection_id, newAccountGrantees(draft.picked)).catch((e) => errorToast(e.message));
|
|
105
|
+
}
|
|
106
|
+
successToast(t('added', { address: inbox.email }));
|
|
107
|
+
onAdded(inbox);
|
|
108
|
+
onOpenChange(false);
|
|
109
|
+
} })) : (_jsx("p", { className: "text-muted-foreground text-sm", children: t('nameFirst') }))] })] }) }));
|
|
110
|
+
}
|
|
111
|
+
function splitPolicyList(value) {
|
|
112
|
+
return Array.from(new Set(value
|
|
113
|
+
.split(/[\n,]+/)
|
|
114
|
+
.map((item) => item.trim().toLowerCase())
|
|
115
|
+
.filter(Boolean)));
|
|
116
|
+
}
|
|
117
|
+
/** "Who can email" for one inbox: anyone, or only the listed senders. */
|
|
118
|
+
export function EmailSenderPolicyDialog({ projectId, inbox, open, onOpenChange, }) {
|
|
119
|
+
const t = useTranslations('emailInboxes');
|
|
120
|
+
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
121
|
+
const update = useUpdateEmailInbox();
|
|
122
|
+
const initial = inboxSenderPolicy(inbox);
|
|
123
|
+
const [restricted, setRestricted] = useState(initial.mode === 'restricted');
|
|
124
|
+
const [emails, setEmails] = useState(initial.allowedEmails.join('\n'));
|
|
125
|
+
const [domains, setDomains] = useState(initial.allowedDomains.join('\n'));
|
|
126
|
+
const [regex, setRegex] = useState(initial.allowedRegex ?? '');
|
|
127
|
+
const [error, setError] = useState(null);
|
|
128
|
+
// Each inbox opened starts from its own saved policy.
|
|
129
|
+
const [syncedId, setSyncedId] = useState(null);
|
|
130
|
+
if (inbox && open && inbox.connection_id !== syncedId) {
|
|
131
|
+
setSyncedId(inbox.connection_id);
|
|
132
|
+
setRestricted(initial.mode === 'restricted');
|
|
133
|
+
setEmails(initial.allowedEmails.join('\n'));
|
|
134
|
+
setDomains(initial.allowedDomains.join('\n'));
|
|
135
|
+
setRegex(initial.allowedRegex ?? '');
|
|
136
|
+
setError(null);
|
|
137
|
+
}
|
|
138
|
+
if (!open && syncedId)
|
|
139
|
+
setSyncedId(null);
|
|
140
|
+
const save = () => {
|
|
141
|
+
if (!inbox)
|
|
142
|
+
return;
|
|
143
|
+
setError(null);
|
|
144
|
+
const sender_policy = {
|
|
145
|
+
mode: restricted ? 'restricted' : 'allow_all',
|
|
146
|
+
allowedEmails: splitPolicyList(emails),
|
|
147
|
+
allowedDomains: splitPolicyList(domains).map((domain) => domain.replace(/^@+/, '')),
|
|
148
|
+
allowedRegex: regex.trim() || null,
|
|
149
|
+
};
|
|
150
|
+
if (sender_policy.allowedRegex) {
|
|
151
|
+
try {
|
|
152
|
+
new RegExp(sender_policy.allowedRegex);
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
setError(t('regexInvalid'));
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
update.mutate({ projectId, connectionId: inbox.connection_id, sender_policy }, {
|
|
160
|
+
onSuccess: () => {
|
|
161
|
+
successToast(t('policySaved'));
|
|
162
|
+
onOpenChange(false);
|
|
163
|
+
},
|
|
164
|
+
onError: (e) => setError(e.message),
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
return (_jsx(Modal, { open: open, onOpenChange: (next) => !update.isPending && onOpenChange(next), children: _jsxs(ModalContent, { className: "lg:max-w-lg", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: t('policyTitle', { address: inbox?.email ?? '' }) }), _jsx(ModalDescription, { children: t('policyDescription') })] }), _jsx(ModalBody, { className: "space-y-3", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Checkbox, { id: "email-inbox-restricted", checked: restricted, onCheckedChange: (checked) => setRestricted(Boolean(checked)), className: "mt-0.5" }), _jsxs("div", { className: "min-w-0 flex-1 space-y-3", children: [_jsxs("div", { children: [_jsx(Label, { htmlFor: "email-inbox-restricted", children: tI18nComplete.raw('texta48c89f63885') }), _jsx("p", { className: "text-muted-foreground mt-1 text-xs", children: tI18nComplete.raw('text8c67b476d59b') })] }), restricted ? (_jsxs("div", { className: "grid gap-3", children: [_jsx(Field, { children: _jsx(Input, { value: emails, onChange: (e) => setEmails(e.target.value), placeholder: tI18nComplete.raw('text542d24012988') }) }), _jsx(Field, { children: _jsx(Input, { value: domains, onChange: (e) => setDomains(e.target.value), placeholder: tI18nComplete.raw('texta379a6f6eeaf') }) }), _jsx(Field, { children: _jsx(Input, { value: regex, onChange: (e) => setRegex(e.target.value), placeholder: tI18nComplete.raw('text8b21058f3253'), spellCheck: false }) })] })) : null, error ? _jsx(InfoBanner, { tone: "destructive", children: error }) : null] })] }) }), _jsxs(ModalFooter, { className: "sm:justify-between", children: [_jsx(Button, { variant: "outline-ghost", onClick: () => onOpenChange(false), disabled: update.isPending, children: tI18nComplete.raw('text19766ed6ccb2') }), _jsxs(Button, { onClick: save, disabled: update.isPending, children: [update.isPending ? _jsx(Loading, { className: "size-4 shrink-0" }) : null, tI18nComplete.raw('text1509f561f241')] })] })] }) }));
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* The Email hero (Channels tab, the Email page): the pitch until a first inbox
|
|
171
|
+
* exists, then how many inboxes there are, their addresses, and Manage (the
|
|
172
|
+
* connector page with the account list) or Add another inbox. Like ComputerHero.
|
|
173
|
+
*/
|
|
174
|
+
export function EmailHero({ projectId, canWrite }) {
|
|
175
|
+
const t = useTranslations('emailInboxes');
|
|
176
|
+
const tPages = useTranslations('connectorPages');
|
|
177
|
+
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
178
|
+
const inboxes = useEmailInboxes(projectId);
|
|
179
|
+
const [addOpen, setAddOpen] = useState(false);
|
|
180
|
+
const list = inboxes.data ?? [];
|
|
181
|
+
const connected = list.length > 0;
|
|
182
|
+
const addresses = list.map((inbox) => inbox.email).join(', ');
|
|
183
|
+
return (_jsxs(_Fragment, { children: [_jsx(ChannelHeroFrame, { app: "email", title: connected ? t('heroCount', { count: list.length }) : tPages('emailHeroTitle'), lede: tPages('emailHeroLede'), status: connected ? (_jsx(ChannelHeroStatus, { label: tI18nComplete.raw('text22965568d22a'), detail: addresses || null })) : undefined, actions: connected ? (_jsxs(_Fragment, { children: [_jsx(Button, { size: "sm", asChild: true, children: _jsxs(Link, { href: connectorHref(projectId, EMAIL_CONNECTOR_SLUG), children: [t('heroManage'), _jsx(CaretRightIcon, { className: "size-3.5 shrink-0" })] }) }), canWrite ? (_jsx(Button, { size: "sm", variant: "secondary", onClick: () => setAddOpen(true), children: t('heroAddAnother') })) : null] })) : canWrite ? (_jsx(Button, { className: "transition-transform active:scale-96", onClick: () => setAddOpen(true), children: t('heroAdd') })) : null, preview: _jsx(EmailThreadMock, {}) }), _jsx(AddEmailInboxDialog, { projectId: projectId, open: addOpen, onOpenChange: setAddOpen, existing: list.map((inbox) => ({ label: inbox.label, owner_type: inbox.owner_type })), onAdded: () => void inboxes.refetch() })] }));
|
|
184
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** The Provider value:
|
|
1
|
+
/** The Provider value: the managed partner (Composio), else the app itself. */
|
|
2
2
|
export declare function providerName(appName: string, managedBy: string | null): string;
|
|
3
3
|
/**
|
|
4
4
|
* The info button on the Provider label that explains who manages what.
|
|
@@ -4,9 +4,9 @@ import { InfoIcon } from '@phosphor-icons/react';
|
|
|
4
4
|
import { Button } from '../../../primitives/button.js';
|
|
5
5
|
import { HoverCard, HoverCardContent, HoverCardTrigger } from '../../../primitives/hover-card.js';
|
|
6
6
|
import { useTranslations } from '../../../i18n/index.js';
|
|
7
|
-
/** The Provider value:
|
|
7
|
+
/** The Provider value: the managed partner (Composio), else the app itself. */
|
|
8
8
|
export function providerName(appName, managedBy) {
|
|
9
|
-
return managedBy
|
|
9
|
+
return managedBy ?? appName;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* The info button on the Provider label that explains who manages what.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ConnectorStatusTone } from './connector-status.js';
|
|
2
|
-
/** A connector's state as a Badge with its dot:
|
|
2
|
+
/** A connector's state as a Badge with its dot: Connected, Needs account or Error. */
|
|
3
3
|
export declare function ConnectorStatusBadge({ tone }: {
|
|
4
4
|
tone: ConnectorStatusTone;
|
|
5
5
|
}): import("react").JSX.Element;
|
|
@@ -4,13 +4,12 @@ import { useTranslations } from '../../../i18n/index.js';
|
|
|
4
4
|
import { cn } from '../../../internal/lib/utils.js';
|
|
5
5
|
import { STATUS_DOT, STATUS_WORD } from './connector-status.js';
|
|
6
6
|
const STATUS_BADGE = {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
connected: 'success',
|
|
8
|
+
account: 'warning',
|
|
9
9
|
error: 'destructive',
|
|
10
|
-
setup: 'warning',
|
|
11
10
|
};
|
|
12
|
-
/** A connector's state as a Badge with its dot:
|
|
11
|
+
/** A connector's state as a Badge with its dot: Connected, Needs account or Error. */
|
|
13
12
|
export function ConnectorStatusBadge({ tone }) {
|
|
14
13
|
const t = useTranslations('connectorPages');
|
|
15
|
-
return (_jsxs(Badge, { variant: STATUS_BADGE[tone], size: "sm", children: [_jsx("span", { "data-slot": "status-dot", "aria-hidden": true, className: cn('rounded', STATUS_DOT[tone]) }), t(STATUS_WORD[tone])] }));
|
|
14
|
+
return (_jsxs(Badge, { variant: STATUS_BADGE[tone], size: "sm", children: [_jsx("span", { "data-slot": "status-dot", "aria-hidden": true, className: cn('rounded-full', STATUS_DOT[tone]) }), t(STATUS_WORD[tone])] }));
|
|
16
15
|
}
|
|
@@ -35,3 +35,9 @@ export declare function useConnectorDetail({ projectId, connector, canWrite, onC
|
|
|
35
35
|
computerOpen: boolean;
|
|
36
36
|
setComputerOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
37
37
|
};
|
|
38
|
+
/**
|
|
39
|
+
* A connector's accounts in a project's connection list: its rows minus
|
|
40
|
+
* revoked ones and the server's empty shared slot. The Accounts tab, the
|
|
41
|
+
* header and the Connectors list all count these, so they agree.
|
|
42
|
+
*/
|
|
43
|
+
export declare function connectorAccounts(connections: readonly Connection[] | undefined, connector: AdminConnector): Connection[];
|
|
@@ -21,7 +21,9 @@ import { connectorUsable } from './connector-status.js';
|
|
|
21
21
|
*/
|
|
22
22
|
export function useConnectorDetail({ projectId, connector, canWrite, onChanged, }) {
|
|
23
23
|
const isManagedProvider = isManagedConnectorProvider(connector.provider);
|
|
24
|
-
|
|
24
|
+
// Email is a channel whose accounts are inboxes: it lists and adds accounts
|
|
25
|
+
// like any connector, so only the single-install channels count here.
|
|
26
|
+
const isChannel = connector.provider === 'channel' && connector.platform !== 'email';
|
|
25
27
|
const isComputer = connector.provider === 'computer';
|
|
26
28
|
const displayName = connectorDisplayName(connector);
|
|
27
29
|
const [credentialTarget, setCredentialTarget] = useState(null);
|
|
@@ -41,9 +43,7 @@ export function useConnectorDetail({ projectId, connector, canWrite, onChanged,
|
|
|
41
43
|
// whose only shared account had just been disconnected).
|
|
42
44
|
// The server's empty shared slot is a placeholder, not an account: it is
|
|
43
45
|
// not listed or counted (see `emptyProjectSlot`).
|
|
44
|
-
const
|
|
45
|
-
const slot = emptyProjectSlot(connector, rows);
|
|
46
|
-
const accounts = rows.filter((connection) => connection !== slot && connection.status !== 'revoked');
|
|
46
|
+
const accounts = connectorAccounts(connectionsQuery.data?.connections, connector);
|
|
47
47
|
const soleAccount = accounts.length === 1 ? accounts[0] : null;
|
|
48
48
|
// Server-computed and account-aware: `needs_auth` means no reachable account
|
|
49
49
|
// holds a usable credential, whatever the owner type.
|
|
@@ -132,3 +132,13 @@ export function useConnectorDetail({ projectId, connector, canWrite, onChanged,
|
|
|
132
132
|
setComputerOpen,
|
|
133
133
|
};
|
|
134
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* A connector's accounts in a project's connection list: its rows minus
|
|
137
|
+
* revoked ones and the server's empty shared slot. The Accounts tab, the
|
|
138
|
+
* header and the Connectors list all count these, so they agree.
|
|
139
|
+
*/
|
|
140
|
+
export function connectorAccounts(connections, connector) {
|
|
141
|
+
const rows = connectorConnectionRows(connections, connector.slug);
|
|
142
|
+
const slot = emptyProjectSlot(connector, rows);
|
|
143
|
+
return rows.filter((connection) => connection !== slot && connection.status !== 'revoked');
|
|
144
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useTranslations } from '../../../i18n/index.js';
|
|
2
|
+
import { type WayKind } from './way-kind.js';
|
|
3
|
+
/** One way to connect, as the Install dialog describes it. */
|
|
4
|
+
export interface InstallWay {
|
|
5
|
+
kind: WayKind;
|
|
6
|
+
oneClick: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Install → this dialog → the connector. The text says which way it
|
|
10
|
+
* connects, so a Composio app or an API key never comes as a surprise. The
|
|
11
|
+
* name is the app's; Rename opens the field for the rare second install.
|
|
12
|
+
* Who may use an account is chosen next, in Add account.
|
|
13
|
+
*/
|
|
14
|
+
export declare function InstallDialog({ appName, way, open, pending, onOpenChange, onConfirm, }: {
|
|
15
|
+
appName: string;
|
|
16
|
+
way: InstallWay;
|
|
17
|
+
open: boolean;
|
|
18
|
+
pending: boolean;
|
|
19
|
+
onOpenChange: (open: boolean) => void;
|
|
20
|
+
onConfirm: (name: string) => void;
|
|
21
|
+
}): import("react").JSX.Element;
|
|
22
|
+
/** What connecting this way means for the user, in one or two sentences. */
|
|
23
|
+
export declare function wayDescription(t: ReturnType<typeof useTranslations>, way: InstallWay, appName: string): string;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId, useState } from 'react';
|
|
4
|
+
import { Badge } from '../../../primitives/badge.js';
|
|
5
|
+
import { Button } from '../../../primitives/button.js';
|
|
6
|
+
import { Field, FieldDescription, FieldLabel } from '../../../primitives/field.js';
|
|
7
|
+
import { Input } from '../../../primitives/input.js';
|
|
8
|
+
import Loading from '../../../primitives/loading.js';
|
|
9
|
+
import { Modal, ModalBody, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalTitle, } from '../../../primitives/modal.js';
|
|
10
|
+
import { useTranslations } from '../../../i18n/index.js';
|
|
11
|
+
import { wayKindLabel } from './way-kind.js';
|
|
12
|
+
/**
|
|
13
|
+
* Install → this dialog → the connector. The text says which way it
|
|
14
|
+
* connects, so a Composio app or an API key never comes as a surprise. The
|
|
15
|
+
* name is the app's; Rename opens the field for the rare second install.
|
|
16
|
+
* Who may use an account is chosen next, in Add account.
|
|
17
|
+
*/
|
|
18
|
+
export function InstallDialog({ appName, way, open, pending, onOpenChange, onConfirm, }) {
|
|
19
|
+
const t = useTranslations('connectorPages');
|
|
20
|
+
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
21
|
+
const id = useId();
|
|
22
|
+
const [name, setName] = useState(appName);
|
|
23
|
+
const [renaming, setRenaming] = useState(false);
|
|
24
|
+
const valid = /[a-z0-9]/i.test(name);
|
|
25
|
+
return (_jsx(Modal, { open: open, onOpenChange: (next) => !pending && onOpenChange(next), children: _jsxs(ModalContent, { className: "lg:max-w-md", children: [_jsxs(ModalHeader, { children: [_jsxs(ModalTitle, { className: "flex items-center gap-2", children: [t('installTitle', { name: appName }), _jsx(Badge, { variant: "muted", size: "xs", children: wayKindLabel(way.kind) })] }), _jsx(ModalDescription, { children: wayDescription(t, way, appName) })] }), _jsxs("form", { onSubmit: (event) => {
|
|
26
|
+
event.preventDefault();
|
|
27
|
+
if (valid && !pending)
|
|
28
|
+
onConfirm(name.trim());
|
|
29
|
+
}, children: [_jsx(ModalBody, { className: "space-y-4", children: renaming ? (_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: `${id}-name`, children: t('installNameLabel') }), _jsx(Input, { id: `${id}-name`, value: name, onChange: (event) => setName(event.target.value), autoComplete: "off", disabled: pending, autoFocus: true }), _jsx(FieldDescription, { children: t('installProfileHint') })] })) : (_jsxs("p", { className: "text-muted-foreground flex flex-wrap items-center gap-x-2 text-sm text-pretty", children: [t('installNextStep', { name: appName }), _jsx(Button, { type: "button", variant: "text", size: "sm", className: "h-auto px-0", onClick: () => setRenaming(true), disabled: pending, children: t('installRename') })] })) }), _jsxs(ModalFooter, { className: "sm:justify-between", children: [_jsx(Button, { type: "button", variant: "outline-ghost", onClick: () => onOpenChange(false), disabled: pending, children: tI18nComplete.raw('text19766ed6ccb2') }), _jsxs(Button, { type: "submit", disabled: !valid || pending, children: [pending ? _jsx(Loading, { className: "size-4 shrink-0" }) : null, t('install')] })] })] })] }) }));
|
|
30
|
+
}
|
|
31
|
+
/** What connecting this way means for the user, in one or two sentences. */
|
|
32
|
+
export function wayDescription(t, way, appName) {
|
|
33
|
+
if (way.kind === 'composio')
|
|
34
|
+
return t('wayComposio', { name: appName });
|
|
35
|
+
if (way.kind === 'kortix')
|
|
36
|
+
return t('wayChannel', { name: appName });
|
|
37
|
+
if (way.kind === 'mcp')
|
|
38
|
+
return way.oneClick ? t('wayMcpOneClick', { name: appName }) : t('wayMcpSetup', { name: appName });
|
|
39
|
+
return t('wayApi', { name: appName, kind: wayKindLabel(way.kind) });
|
|
40
|
+
}
|
|
@@ -41,13 +41,18 @@ export declare function proposeAccountLabel(appName: string, taken: readonly str
|
|
|
41
41
|
export interface InstallDeps {
|
|
42
42
|
createConnector(projectId: string, draft: ConnectorDraftInput): Promise<{
|
|
43
43
|
sync?: ConnectorSyncResult;
|
|
44
|
+
existing?: boolean;
|
|
45
|
+
slug?: string;
|
|
44
46
|
}>;
|
|
45
47
|
/** Slug suffix source; injectable so tests are deterministic. */
|
|
46
48
|
random?: () => string;
|
|
47
49
|
}
|
|
48
|
-
export type InstallResult =
|
|
50
|
+
export type InstallResult =
|
|
51
|
+
/** `existing`: the project already had this profile, and Install opened it. */
|
|
52
|
+
{
|
|
49
53
|
status: 'installed';
|
|
50
54
|
slug: string;
|
|
55
|
+
existing?: boolean;
|
|
51
56
|
}
|
|
52
57
|
/** The profile exists; its page shows the error and Retry. */
|
|
53
58
|
| {
|
|
@@ -62,10 +67,16 @@ export type InstallResult = {
|
|
|
62
67
|
* A profile is always the project's: the app, its config and its rules (a
|
|
63
68
|
* `kortix.yaml` entry). Who may use it is a property of each ACCOUNT, chosen
|
|
64
69
|
* when one is added (`useAddAccount`), never here. When the project already
|
|
65
|
-
* has a profile for this app and surface, Install reuses it
|
|
70
|
+
* has a profile for this app and surface, Install reuses it, unless the user
|
|
71
|
+
* asked for another profile (`asNewProfile`). A server that finds the profile
|
|
72
|
+
* itself answers `existing: true` with its slug.
|
|
66
73
|
*/
|
|
67
74
|
export declare function runInstall(deps: InstallDeps, input: {
|
|
68
75
|
projectId: string;
|
|
69
76
|
target: InstallTarget;
|
|
70
77
|
connectors: readonly Pick<AdminConnector, 'slug' | 'provider' | 'name'>[];
|
|
78
|
+
/** The profile's name, as the user chose it. Default: the app's name. */
|
|
79
|
+
name?: string;
|
|
80
|
+
/** Add a second profile of the same app and way (Settings → Install as another profile). */
|
|
81
|
+
asNewProfile?: boolean;
|
|
71
82
|
}): Promise<InstallResult>;
|
|
@@ -76,17 +76,22 @@ export function proposeAccountLabel(appName, taken) {
|
|
|
76
76
|
* A profile is always the project's: the app, its config and its rules (a
|
|
77
77
|
* `kortix.yaml` entry). Who may use it is a property of each ACCOUNT, chosen
|
|
78
78
|
* when one is added (`useAddAccount`), never here. When the project already
|
|
79
|
-
* has a profile for this app and surface, Install reuses it
|
|
79
|
+
* has a profile for this app and surface, Install reuses it, unless the user
|
|
80
|
+
* asked for another profile (`asNewProfile`). A server that finds the profile
|
|
81
|
+
* itself answers `existing: true` with its slug.
|
|
80
82
|
*/
|
|
81
83
|
export async function runInstall(deps, input) {
|
|
82
|
-
const { projectId,
|
|
84
|
+
const { projectId, connectors } = input;
|
|
85
|
+
const target = input.name?.trim() ? { ...input.target, appName: input.name.trim() } : input.target;
|
|
83
86
|
const existing = connectors.find((connector) => connectorInstalledFrom(connector, target.appName, target.provider));
|
|
84
|
-
if (existing)
|
|
85
|
-
return { status: 'installed', slug: existing.slug };
|
|
87
|
+
if (existing && !input.asNewProfile)
|
|
88
|
+
return { status: 'installed', slug: existing.slug, existing: true };
|
|
86
89
|
const slugs = connectors.map((connector) => connector.slug);
|
|
87
90
|
const slug = proposeConnectorConnectionSlug(target.appName, slugs, deps.random);
|
|
88
91
|
const name = proposeConnectorConnectionName(target.appName, slugs);
|
|
89
92
|
const result = await deps.createConnector(projectId, target.buildDraft({ slug, name }));
|
|
93
|
+
if (result.existing && result.slug)
|
|
94
|
+
return { status: 'installed', slug: result.slug, existing: true };
|
|
90
95
|
const syncError = connectorSyncErrorForSlug(result, slug);
|
|
91
96
|
// An MCP server that signs in with OAuth answers its first tools/list with
|
|
92
97
|
// 401 or 403: that is the sign-in still to do, not a broken install.
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import { type AdminConnector } from '@kortix/sdk';
|
|
2
|
-
import type
|
|
2
|
+
import { type CatalogEntry } from '../catalog/catalog-entry.js';
|
|
3
3
|
import { type AppRef } from '../connector-routes.js';
|
|
4
4
|
import { type InstallTarget } from './install.js';
|
|
5
|
-
import {
|
|
5
|
+
import type { InstallWay } from './install-dialog.js';
|
|
6
|
+
import type { McpServerApp } from './mcp-first.js';
|
|
7
|
+
/** An Install waiting for the user to name the profile (`InstallDialog`). */
|
|
8
|
+
export interface InstallRequest {
|
|
9
|
+
target: InstallTarget;
|
|
10
|
+
way: InstallWay;
|
|
11
|
+
connectors: readonly AdminConnector[];
|
|
12
|
+
app: AppRef | null;
|
|
13
|
+
addAccount?: boolean;
|
|
14
|
+
asNewProfile?: boolean;
|
|
15
|
+
}
|
|
6
16
|
/**
|
|
7
17
|
* Install one app: add its connector profile to the project, then open the
|
|
8
18
|
* connector page with "Add account" showing. Who may use an account is chosen
|
|
@@ -21,8 +31,15 @@ export declare function useInstall(projectId: string, options?: {
|
|
|
21
31
|
/** Open "Add account" on the connector page. False for a server with
|
|
22
32
|
* nothing to sign in to: its project account is the connection. */
|
|
23
33
|
addAccount?: boolean;
|
|
34
|
+
/** The profile's name, as the user chose it. */
|
|
35
|
+
name?: string;
|
|
36
|
+
asNewProfile?: boolean;
|
|
24
37
|
}) => void;
|
|
25
38
|
installEntry: (entry: CatalogEntry, connectors: readonly AdminConnector[]) => void;
|
|
39
|
+
ask: (next: InstallRequest) => void;
|
|
40
|
+
confirm: (name: string) => void;
|
|
41
|
+
request: InstallRequest | null;
|
|
42
|
+
setRequest: import("react").Dispatch<import("react").SetStateAction<InstallRequest | null>>;
|
|
26
43
|
pendingKey: string | null;
|
|
27
44
|
setPendingKey: import("react").Dispatch<import("react").SetStateAction<string | null>>;
|
|
28
45
|
};
|
|
@@ -5,10 +5,10 @@ import { useQueryClient } from '@tanstack/react-query';
|
|
|
5
5
|
import { useUiRouter } from '../../../providers/ui-provider.js';
|
|
6
6
|
import { useCallback, useState } from 'react';
|
|
7
7
|
import { errorToast, successToast, warningToast } from '../../../primitives/toast.js';
|
|
8
|
+
import { connectToolkitApp } from '../catalog/catalog-entry.js';
|
|
8
9
|
import { appHref, appRefFromEntry, connectorHref, } from '../connector-routes.js';
|
|
9
10
|
import { useTranslations } from '../../../i18n/index.js';
|
|
10
11
|
import { discoverInstallTarget, easyConnectInstallTarget, runInstall, } from './install.js';
|
|
11
|
-
import { mcpServerFor } from './mcp-first.js';
|
|
12
12
|
import { pickSurface } from './pick-surface.js';
|
|
13
13
|
const sdkInstallDeps = { createConnector };
|
|
14
14
|
/**
|
|
@@ -27,11 +27,18 @@ export function useInstall(projectId, options = {}) {
|
|
|
27
27
|
const router = useUiRouter();
|
|
28
28
|
const queryClient = useQueryClient();
|
|
29
29
|
const [pendingKey, setPendingKey] = useState(null);
|
|
30
|
+
const [request, setRequest] = useState(null);
|
|
30
31
|
const install = useCallback((target, options) => {
|
|
31
32
|
/** Settles when every invalidated query has refetched. Never rejects. */
|
|
32
33
|
const refresh = () => invalidateConnections(queryClient, projectId);
|
|
33
34
|
setPendingKey(options.app?.slug ?? target.appName);
|
|
34
|
-
void runInstall(sdkInstallDeps, {
|
|
35
|
+
void runInstall(sdkInstallDeps, {
|
|
36
|
+
projectId,
|
|
37
|
+
target,
|
|
38
|
+
connectors: options.connectors,
|
|
39
|
+
name: options.name,
|
|
40
|
+
asNewProfile: options.asNewProfile,
|
|
41
|
+
})
|
|
35
42
|
.then(async (result) => {
|
|
36
43
|
// Before the navigation: the connector page reads the fresh list.
|
|
37
44
|
await refresh();
|
|
@@ -41,8 +48,11 @@ export function useInstall(projectId, options = {}) {
|
|
|
41
48
|
if (failed) {
|
|
42
49
|
warningToast(t('installedSyncFailed', { name: result.name, error: result.error }));
|
|
43
50
|
}
|
|
51
|
+
else if (result.existing) {
|
|
52
|
+
successToast(t('installedAlready', { name: options.name?.trim() || target.appName }));
|
|
53
|
+
}
|
|
44
54
|
else {
|
|
45
|
-
successToast(t('installed', { name: target.appName }));
|
|
55
|
+
successToast(t('installed', { name: options.name?.trim() || target.appName }));
|
|
46
56
|
}
|
|
47
57
|
router.push(connectorHref(projectId, result.slug, {
|
|
48
58
|
app: options.app,
|
|
@@ -58,30 +68,35 @@ export function useInstall(projectId, options = {}) {
|
|
|
58
68
|
})
|
|
59
69
|
.finally(() => setPendingKey(null));
|
|
60
70
|
}, [projectId, queryClient, router, t, tI18nComplete]);
|
|
61
|
-
/**
|
|
71
|
+
/** Ask for the profile's name, then install (`confirm`). */
|
|
72
|
+
const ask = useCallback((next) => {
|
|
73
|
+
setPendingKey(null);
|
|
74
|
+
setRequest(next);
|
|
75
|
+
}, []);
|
|
76
|
+
/** The user named the profile in `InstallDialog`: install it. */
|
|
77
|
+
const confirm = useCallback((name) => {
|
|
78
|
+
if (!request)
|
|
79
|
+
return;
|
|
80
|
+
setRequest(null);
|
|
81
|
+
install(request.target, {
|
|
82
|
+
connectors: request.connectors,
|
|
83
|
+
app: request.app,
|
|
84
|
+
addAccount: request.addAccount,
|
|
85
|
+
asNewProfile: request.asNewProfile,
|
|
86
|
+
name,
|
|
87
|
+
});
|
|
88
|
+
}, [install, request]);
|
|
89
|
+
/** Install straight from a catalogue card: its recommended way, after the
|
|
90
|
+
* user names the profile. A one-click MCP server opens the MCP dialog. */
|
|
62
91
|
const installEntry = useCallback((entry, connectors) => {
|
|
63
92
|
const app = appRefFromEntry(entry);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
setPendingKey(app?.slug ?? entry.app.name);
|
|
70
|
-
void mcpServerFor(projectId, entry.app).then((server) => {
|
|
71
|
-
if (server) {
|
|
72
|
-
setPendingKey(null);
|
|
73
|
-
onMcpServer(server);
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
install(easyConnectInstallTarget(entry.app), { connectors, app });
|
|
77
|
-
}
|
|
78
|
-
});
|
|
93
|
+
// What Kortix built is set up on its own page, not installed.
|
|
94
|
+
if (entry.connector.kind === 'kortix') {
|
|
95
|
+
router.push(appHref(projectId, app));
|
|
79
96
|
return;
|
|
80
97
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// A Discover card does not carry its surfaces; the detail does. Direct
|
|
84
|
-
// providers open no provider window, so this fetch costs no click.
|
|
98
|
+
// A Discover card does not carry its ways to connect; the detail does,
|
|
99
|
+
// best first, with the recommended one marked.
|
|
85
100
|
setPendingKey(app.slug);
|
|
86
101
|
void queryClient
|
|
87
102
|
.fetchQuery({
|
|
@@ -90,7 +105,17 @@ export function useInstall(projectId, options = {}) {
|
|
|
90
105
|
staleTime: 15 * 60_000,
|
|
91
106
|
})
|
|
92
107
|
.then(async (detail) => {
|
|
93
|
-
const
|
|
108
|
+
const recommended = detail.variants.find((variant) => variant.recommended);
|
|
109
|
+
if (recommended?.kind === 'composio' && recommended.composio) {
|
|
110
|
+
ask({
|
|
111
|
+
target: easyConnectInstallTarget(connectToolkitApp(recommended.composio)),
|
|
112
|
+
way: { kind: 'composio', oneClick: true },
|
|
113
|
+
connectors,
|
|
114
|
+
app,
|
|
115
|
+
});
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const variant = pickSurface(recommended ? [recommended] : detail.variants);
|
|
94
119
|
if (!variant) {
|
|
95
120
|
// Nothing installable from here: the app page shows its surfaces.
|
|
96
121
|
setPendingKey(null);
|
|
@@ -98,29 +123,32 @@ export function useInstall(projectId, options = {}) {
|
|
|
98
123
|
return;
|
|
99
124
|
}
|
|
100
125
|
const mcpUrl = variant.kind === 'mcp' ? variant.template.url : undefined;
|
|
101
|
-
// A Kortix catalogue app
|
|
102
|
-
// a one-click sign-in opens the one-step MCP dialog
|
|
103
|
-
//
|
|
104
|
-
|
|
126
|
+
// A Kortix catalogue app or a one-click server is the vendor's MCP
|
|
127
|
+
// server: a one-click sign-in opens the one-step MCP dialog (which
|
|
128
|
+
// names the profile too); anything else asks for the name first.
|
|
129
|
+
const oneClickServer = entry.connector.feeds.includes('kortix') || recommended?.oneClick === true || entry.connector.oneClick === true;
|
|
130
|
+
let addAccount;
|
|
131
|
+
if (oneClickServer && mcpUrl && onMcpServer) {
|
|
105
132
|
const check = await checkMcpServerSignIn(projectId, mcpUrl).catch(() => null);
|
|
106
133
|
if (check?.one_click) {
|
|
107
134
|
setPendingKey(null);
|
|
108
135
|
onMcpServer({ name: entry.name, url: mcpUrl });
|
|
109
136
|
return;
|
|
110
137
|
}
|
|
111
|
-
|
|
112
|
-
connectors,
|
|
113
|
-
app,
|
|
114
|
-
addAccount: check?.requires_sign_in !== false,
|
|
115
|
-
});
|
|
116
|
-
return;
|
|
138
|
+
addAccount = check?.requires_sign_in !== false;
|
|
117
139
|
}
|
|
118
|
-
|
|
140
|
+
ask({
|
|
141
|
+
target: discoverInstallTarget(entry.name, variant),
|
|
142
|
+
way: { kind: variant.kind, oneClick: recommended?.oneClick === true },
|
|
143
|
+
connectors,
|
|
144
|
+
app,
|
|
145
|
+
...(addAccount !== undefined ? { addAccount } : {}),
|
|
146
|
+
});
|
|
119
147
|
})
|
|
120
148
|
.catch((error) => {
|
|
121
149
|
setPendingKey(null);
|
|
122
150
|
errorToast(error.message || tI18nComplete.raw('texta34a2714da91'));
|
|
123
151
|
});
|
|
124
|
-
}, [
|
|
125
|
-
return { install, installEntry, pendingKey, setPendingKey };
|
|
152
|
+
}, [ask, onMcpServer, projectId, queryClient, router, tI18nComplete]);
|
|
153
|
+
return { install, installEntry, ask, confirm, request, setRequest, pendingKey, setPendingKey };
|
|
126
154
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DiscoverConnectorVariant } from '@kortix/sdk';
|
|
2
|
+
/** How one way to connect an app works: its catalogue kind, or the managed partner. */
|
|
3
|
+
export type WayKind = DiscoverConnectorVariant['kind'] | 'pipedream';
|
|
4
|
+
/** The badge a way to connect carries everywhere: cards, the app page, Install. */
|
|
5
|
+
export declare function wayKindLabel(kind: WayKind): string;
|