@kortix/ui 0.14.12 → 0.14.14
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 +1 -1
- package/dist/_vendor/kortix-shared.js +521 -7045
- package/dist/_vendor/shared/app-config.d.ts +8 -0
- package/dist/_vendor/shared/artifact-annotations.d.ts +708 -0
- package/dist/_vendor/shared/artifact-comments.d.ts +327 -0
- package/dist/_vendor/shared/index.d.ts +3 -1
- package/dist/_vendor/shared/my-kortix-agent.d.ts +40 -0
- package/dist/_vendor/shared/peer-message-prompt.d.ts +35 -0
- package/dist/_vendor/shared/pixel-mark.d.ts +11 -0
- package/dist/_vendor/shared/prompt-attachments.d.ts +1 -0
- package/dist/_vendor/shared/reminder-prompt.d.ts +8 -2
- package/dist/_vendor/shared/runtime-versions.d.ts +8 -0
- package/dist/artifacts/artifact-frame.d.ts +1 -0
- package/dist/artifacts/artifact-frame.js +18 -5
- package/dist/artifacts/frame-policy.d.ts +1 -1
- package/dist/artifacts/frame-policy.js +10 -5
- package/dist/customize/agents/agent-access-text.d.ts +16 -0
- package/dist/customize/agents/agent-access-text.js +54 -0
- package/dist/customize/agents/agent-approval-rules.d.ts +8 -0
- package/dist/customize/agents/agent-approval-rules.js +26 -0
- package/dist/customize/agents/agent-authority-card.js +4 -1
- package/dist/customize/agents/agent-cover-card.d.ts +4 -1
- package/dist/customize/agents/agent-cover-card.js +2 -2
- package/dist/customize/agents/agent-detail-aside.d.ts +1 -2
- package/dist/customize/agents/agent-detail-aside.js +8 -11
- package/dist/customize/agents/agent-drives-section.d.ts +23 -7
- package/dist/customize/agents/agent-drives-section.js +107 -41
- package/dist/customize/agents/agent-instructions.d.ts +11 -0
- package/dist/customize/agents/agent-instructions.js +114 -0
- package/dist/customize/agents/agent-model-view.d.ts +17 -0
- package/dist/customize/agents/agent-model-view.js +67 -0
- package/dist/customize/agents/agent-overview.d.ts +53 -0
- package/dist/customize/agents/agent-overview.js +242 -0
- package/dist/customize/agents/agent-page-chrome.d.ts +128 -0
- package/dist/customize/agents/agent-page-chrome.js +145 -0
- package/dist/customize/agents/agent-page.d.ts +13 -1
- package/dist/customize/agents/agent-page.js +478 -367
- package/dist/customize/agents/agent-pin-button.d.ts +10 -0
- package/dist/customize/agents/agent-pin-button.js +20 -0
- package/dist/customize/agents/agent-policy-sets-section.d.ts +16 -0
- package/dist/customize/agents/agent-policy-sets-section.js +80 -0
- package/dist/customize/agents/agent-policy-sets.js +1 -1
- package/dist/customize/agents/agent-section-rail.d.ts +21 -0
- package/dist/customize/agents/agent-section-rail.js +23 -0
- package/dist/customize/agents/agent-share-control.d.ts +4 -3
- package/dist/customize/agents/agent-share-control.js +15 -16
- package/dist/customize/agents/{agent-people-section.d.ts → agent-share-dialog.d.ts} +3 -1
- package/dist/customize/agents/{agent-people-section.js → agent-share-dialog.js} +21 -21
- package/dist/customize/agents/agent-tabs.d.ts +95 -0
- package/dist/customize/agents/agent-tabs.js +199 -0
- package/dist/customize/agents/agents-page.d.ts +0 -21
- package/dist/customize/agents/agents-page.js +104 -118
- package/dist/customize/agents/connectors-required.d.ts +16 -0
- package/dist/customize/agents/connectors-required.js +19 -0
- package/dist/customize/agents/create-agent-modal.d.ts +19 -0
- package/dist/customize/agents/create-agent-modal.js +94 -0
- package/dist/customize/connectors/agent-access.d.ts +4 -4
- package/dist/customize/connectors/agent-access.js +7 -10
- package/dist/customize/connectors/connector-identity.d.ts +12 -0
- package/dist/customize/connectors/connector-identity.js +15 -2
- package/dist/customize/connectors/connector-routes.js +2 -2
- package/dist/customize/connectors/connectors-page.d.ts +14 -1
- package/dist/customize/connectors/connectors-page.js +101 -32
- package/dist/customize/connectors/detail/app-page.js +1 -1
- package/dist/customize/connectors/detail/connector-agents.js +0 -3
- package/dist/customize/connectors/detail/connector-page.d.ts +1 -1
- package/dist/customize/connectors/detail/connector-page.js +5 -2
- package/dist/customize/connectors/detail/connector-policy-sets.js +1 -1
- package/dist/customize/connectors/detail/connector-triggers.js +2 -2
- package/dist/customize/connectors/use-agent-access.d.ts +7 -5
- package/dist/customize/connectors/use-agent-access.js +2 -6
- package/dist/customize/models/models-page.d.ts +7 -1
- package/dist/customize/models/models-page.js +2 -2
- package/dist/customize/project-settings/project-admin-sections.d.ts +63 -0
- package/dist/customize/project-settings/project-admin-sections.js +80 -0
- package/dist/customize/project-settings/project-settings-page.d.ts +1 -1
- package/dist/customize/project-settings/project-settings-page.js +4 -13
- package/dist/customize/project-settings/project-settings-sections.d.ts +5 -5
- package/dist/customize/project-settings/project-settings-sections.js +6 -20
- package/dist/customize/providers/provider-accordion.js +29 -17
- package/dist/customize/providers/provider-connect.js +1 -1
- package/dist/customize/providers/provider-sheet.d.ts +4 -1
- package/dist/customize/providers/provider-sheet.js +15 -5
- package/dist/customize/secrets/secrets-page.d.ts +5 -1
- package/dist/customize/secrets/secrets-page.js +2 -2
- package/dist/customize/sections/gateway-view.d.ts +10 -2
- package/dist/customize/sections/gateway-view.js +16 -4
- package/dist/customize/sections/llm-provider/chatgpt-subscription-connect.d.ts +12 -5
- package/dist/customize/sections/llm-provider/chatgpt-subscription-connect.js +131 -8
- package/dist/customize/sections/llm-provider/claude-code-step.d.ts +10 -0
- package/dist/customize/sections/llm-provider/claude-code-step.js +32 -0
- package/dist/customize/sections/llm-provider/models-tab.js +5 -1
- package/dist/customize/sections/view/account-secret-resources-panel.d.ts +5 -3
- package/dist/customize/sections/view/account-secret-resources-panel.js +122 -19
- package/dist/customize/sections/view/agent-editor-access-fields.d.ts +1 -1
- package/dist/customize/sections/view/agent-editor-access-fields.js +8 -4
- package/dist/customize/sections/view/agent-editor-basics-fields.d.ts +4 -1
- package/dist/customize/sections/view/agent-editor-basics-fields.js +33 -4
- package/dist/customize/sections/view/agent-editor-catalog.d.ts +2 -2
- package/dist/customize/sections/view/agent-editor-catalog.js +10 -12
- package/dist/customize/sections/view/agent-editor-primitives.d.ts +1 -1
- package/dist/customize/sections/view/agent-editor-primitives.js +4 -4
- package/dist/customize/sections/view/agent-editor.d.ts +37 -26
- package/dist/customize/sections/view/agent-editor.js +19 -19
- package/dist/customize/sections/view/grant-mode-field.d.ts +8 -20
- package/dist/customize/sections/view/grant-mode-field.js +31 -57
- package/dist/customize/sections/view/permission-editor.d.ts +3 -1
- package/dist/customize/sections/view/permission-editor.js +19 -10
- package/dist/customize/sections/view/review-view.d.ts +8 -0
- package/dist/customize/sections/view/review-view.js +12 -1
- package/dist/customize/sections/view/secret-delivery.js +1 -4
- package/dist/customize/sections/view/secrets-view.d.ts +7 -1
- package/dist/customize/sections/view/secrets-view.js +42 -6
- package/dist/customize/settings/rail.js +2 -8
- package/dist/customize/settings/settings-tabs.d.ts +2 -2
- package/dist/customize/settings/settings-tabs.js +17 -19
- package/dist/customize/settings/tabs/experimental-tab.d.ts +3 -0
- package/dist/customize/settings/tabs/experimental-tab.js +6 -1
- package/dist/customize/settings/tabs/sandbox-tab.d.ts +4 -6
- package/dist/customize/settings/tabs/sandbox-tab.js +9 -9
- package/dist/customize/shared/access-list.d.ts +39 -0
- package/dist/customize/shared/access-list.js +62 -0
- package/dist/customize/shared/agent-resource-scope.d.ts +87 -0
- package/dist/customize/shared/agent-resource-scope.js +123 -0
- package/dist/customize/shared/capability-library.d.ts +41 -0
- package/dist/customize/shared/capability-library.js +271 -0
- package/dist/customize/shared/capability-page-shell.d.ts +18 -1
- package/dist/customize/shared/capability-page-shell.js +21 -1
- package/dist/customize/shared/catalog/catalog-space-tabs.d.ts +14 -0
- package/dist/customize/shared/catalog/catalog-space-tabs.js +20 -0
- package/dist/customize/shared/customize-tab-bar.d.ts +13 -0
- package/dist/customize/shared/customize-tab-bar.js +95 -0
- package/dist/customize/shared/entity/entity-modal.d.ts +17 -1
- package/dist/customize/shared/entity/entity-modal.js +10 -9
- package/dist/customize/shared/leave-guard.d.ts +23 -0
- package/dist/customize/shared/leave-guard.js +87 -0
- package/dist/customize/shared/standalone-settings-nav.js +4 -1
- package/dist/customize/shared/tool-rules.d.ts +11 -0
- package/dist/customize/shared/tool-rules.js +29 -0
- package/dist/customize/skills/builtin-skill-modal.d.ts +6 -0
- package/dist/customize/skills/builtin-skill-modal.js +41 -0
- package/dist/customize/skills/skills-page.d.ts +21 -18
- package/dist/customize/skills/skills-page.js +16 -110
- package/dist/customize/triggers/runtime-triggers.d.ts +17 -0
- package/dist/customize/triggers/runtime-triggers.js +57 -0
- package/dist/customize/triggers/schedule/event-trigger-copy.js +2 -2
- package/dist/customize/triggers/schedule/post-to-field.js +2 -2
- package/dist/customize/triggers/schedule/schedule-copy.d.ts +11 -6
- package/dist/customize/triggers/schedule/schedule-copy.js +29 -8
- package/dist/customize/triggers/schedule/schedule-detail-sheet.js +7 -3
- package/dist/customize/triggers/schedule/trigger-composer-logic.d.ts +26 -1
- package/dist/customize/triggers/schedule/trigger-composer-logic.js +64 -3
- package/dist/customize/triggers/schedule/trigger-composer.js +57 -20
- package/dist/customize/triggers/schedule/trigger-edit-logic.js +18 -5
- package/dist/customize/triggers/schedule/trigger-filter.d.ts +10 -0
- package/dist/customize/triggers/schedule/trigger-filter.js +16 -0
- 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/use-trigger-mutations.d.ts +1 -1
- package/dist/customize/triggers/schedule/use-trigger-mutations.js +1 -1
- package/dist/customize/triggers/schedule/when-app.d.ts +15 -0
- package/dist/customize/triggers/schedule/when-app.js +21 -0
- package/dist/customize/triggers/schedule/when-change-request.d.ts +10 -0
- package/dist/customize/triggers/schedule/when-change-request.js +15 -0
- package/dist/customize/triggers/schedule-view.d.ts +17 -3
- package/dist/customize/triggers/schedule-view.js +46 -16
- package/dist/customize/triggers/triggers-page.d.ts +3 -3
- package/dist/customize/triggers/triggers-page.js +2 -2
- package/dist/customize/use-configure-thread.d.ts +8 -2
- package/dist/customize/use-configure-thread.js +30 -18
- package/dist/files/project/components/change-request-detail-dialog.js +2 -3
- package/dist/files/project/components/drive-explorer.js +6 -5
- package/dist/files/project/explorer-source.d.ts +3 -0
- package/dist/files/project/upload-batch.d.ts +3 -3
- package/dist/files/project/upload-batch.js +7 -6
- package/dist/files/runtime/sandbox-explorer-source.js +3 -3
- package/dist/i18n/en.d.ts +1330 -53
- package/dist/i18n/en.js +1422 -145
- package/dist/i18n/ui-catalog/remaining-ui-translation-keys.generated.js +16 -7
- package/dist/internal/auth/auth-primitives.d.ts +1 -3
- package/dist/internal/auth/auth-primitives.js +2 -2
- package/dist/internal/billing/session-cost-format.d.ts +1 -0
- package/dist/internal/billing/session-cost-format.js +11 -0
- package/dist/internal/components/agent-mark.d.ts +12 -1
- package/dist/internal/components/agent-mark.js +34 -11
- package/dist/internal/components/nav-rail.d.ts +22 -0
- package/dist/internal/components/nav-rail.js +16 -0
- package/dist/internal/components/repository-disconnected.js +2 -2
- package/dist/internal/goals/goal-meta.d.ts +15 -1
- package/dist/internal/goals/goal-meta.js +42 -2
- package/dist/internal/hooks/projects/use-agent-config.d.ts +11 -7
- package/dist/internal/hooks/projects/use-agent-config.js +28 -11
- package/dist/internal/hooks/use-slash-focus.d.ts +7 -1
- package/dist/internal/hooks/use-slash-focus.js +9 -3
- package/dist/internal/layout/project-capability-nav.d.ts +24 -0
- package/dist/internal/layout/project-capability-nav.js +86 -0
- package/dist/internal/layout/project-page-header.d.ts +1 -1
- package/dist/internal/layout/project-page-header.js +1 -1
- package/dist/internal/layout/project-settings-nav.d.ts +3 -2
- package/dist/internal/layout/project-settings-nav.js +5 -3
- package/dist/internal/lib/browser-noise/rules/old-browsers.js +1 -1
- package/dist/internal/lib/capability-tab-routes.d.ts +34 -3
- package/dist/internal/lib/capability-tab-routes.js +76 -8
- package/dist/internal/lib/manifest-health.d.ts +10 -0
- package/dist/internal/lib/manifest-health.js +20 -0
- package/dist/internal/lib/pixel-mark.d.ts +4 -1
- package/dist/internal/lib/pixel-mark.js +33 -6
- package/dist/internal/lib/project-actions.d.ts +1 -1
- package/dist/internal/lib/project-actions.js +0 -4
- package/dist/internal/lib/provider-branding.js +2 -0
- package/dist/internal/lib/space-scope.d.ts +29 -0
- package/dist/internal/lib/space-scope.js +28 -0
- package/dist/internal/lib/use-project-feature-flags.js +3 -3
- package/dist/internal/lib/web-notifications.d.ts +74 -8
- package/dist/internal/lib/web-notifications.js +243 -117
- package/dist/internal/notifications/notification-rows.d.ts +14 -7
- package/dist/internal/notifications/notification-rows.js +21 -14
- package/dist/internal/notifications/session-toast-cards.d.ts +2 -2
- package/dist/internal/reminders/reminder-format.d.ts +6 -2
- package/dist/internal/reminders/reminder-format.js +7 -1
- package/dist/internal/stores/active-space-store.d.ts +35 -0
- package/dist/internal/stores/active-space-store.js +29 -0
- package/dist/internal/stores/kortix-computer-store.js +13 -4
- package/dist/internal/stores/pinned-agents-store.d.ts +26 -0
- package/dist/internal/stores/pinned-agents-store.js +20 -0
- package/dist/internal/stores/session-panel-memory-store.js +3 -0
- package/dist/internal/stores/turn-attention-store.d.ts +5 -4
- package/dist/lib/routes.d.ts +16 -1
- package/dist/lib/routes.js +15 -3
- package/dist/markdown/doc-editor/doc-embed.d.ts +31 -0
- package/dist/markdown/doc-editor/doc-embed.js +168 -0
- package/dist/markdown/doc-editor/doc-extensions.d.ts +26 -0
- package/dist/markdown/doc-editor/doc-extensions.js +149 -0
- package/dist/markdown/doc-editor/doc-menus.d.ts +9 -0
- package/dist/markdown/doc-editor/doc-menus.js +56 -0
- package/dist/markdown/doc-editor/markdown.d.ts +12 -0
- package/dist/markdown/doc-editor/markdown.js +140 -0
- package/dist/markdown/genui/components/inline.d.ts +1 -1
- package/dist/primitives/badge.d.ts +1 -1
- package/dist/primitives/button.d.ts +1 -1
- package/dist/primitives/pixel-kortix-mark.d.ts +5 -4
- package/dist/primitives/pixel-kortix-mark.js +5 -15
- package/dist/primitives/tag.d.ts +1 -1
- package/dist/primitives/textarea.js +14 -0
- package/dist/primitives/toast.d.ts +2 -0
- package/dist/primitives/toast.js +4 -2
- package/dist/providers/ui-provider.d.ts +16 -0
- package/dist/session/actions/session-label.d.ts +1 -1
- package/dist/session/actions/session-label.js +3 -3
- package/dist/session/agents/agent-model.d.ts +92 -0
- package/dist/session/agents/agent-model.js +123 -0
- package/dist/session/agents/agent-state-mark.d.ts +10 -0
- package/dist/session/agents/agent-state-mark.js +22 -0
- package/dist/session/agents/agent-strip.d.ts +58 -0
- package/dist/session/agents/agent-strip.js +259 -0
- package/dist/session/agents/held-messages.d.ts +33 -0
- package/dist/session/agents/held-messages.js +50 -0
- package/dist/session/agents/legacy-subagent-chat.d.ts +11 -0
- package/dist/session/agents/legacy-subagent-chat.js +19 -0
- package/dist/session/agents/session-peek.d.ts +20 -0
- package/dist/session/agents/session-peek.js +67 -0
- package/dist/session/agents/session-prompt.d.ts +13 -0
- package/dist/session/agents/session-prompt.js +18 -0
- package/dist/session/agents/steer-session.d.ts +13 -0
- package/dist/session/agents/steer-session.js +29 -0
- package/dist/session/agents/subagent-dialog-content.d.ts +11 -0
- package/dist/session/agents/subagent-dialog-content.js +115 -0
- package/dist/session/agents/subagent-view.d.ts +8 -0
- package/dist/session/agents/subagent-view.js +18 -0
- package/dist/session/agents/tasks-panel.d.ts +13 -0
- package/dist/session/agents/tasks-panel.js +41 -0
- package/dist/session/agents/workflow-run-controls.d.ts +43 -0
- package/dist/session/agents/workflow-run-controls.js +141 -0
- package/dist/session/composer/ComposerCard.d.ts +1 -1
- package/dist/session/composer/ComposerCard.js +3 -3
- package/dist/session/composer/agent-selector.js +13 -19
- package/dist/session/composer/composer-underbar.d.ts +3 -1
- package/dist/session/composer/composer-underbar.js +2 -2
- package/dist/session/composer/composer.d.ts +5 -0
- package/dist/session/composer/composer.js +16 -10
- package/dist/session/composer/editor/composer-editor.js +19 -8
- package/dist/session/composer/editor/ultracode.d.ts +34 -0
- package/dist/session/composer/editor/ultracode.js +127 -0
- package/dist/session/composer/send-blockers.d.ts +1 -11
- package/dist/session/composer/send-blockers.js +1 -11
- package/dist/session/composer/session-composer-readiness.d.ts +1 -28
- package/dist/session/composer/session-composer-readiness.js +5 -16
- package/dist/session/header/reminder-parts.d.ts +1 -1
- package/dist/session/header/session-site-header.js +6 -3
- package/dist/session/header/subagent-hover-card.d.ts +0 -2
- package/dist/session/header/subagent-hover-card.js +1 -4
- package/dist/session/models/claude-connection-slot.d.ts +11 -0
- package/dist/session/models/claude-connection-slot.js +30 -0
- package/dist/session/models/model-availability.d.ts +3 -1
- package/dist/session/models/model-availability.js +3 -0
- package/dist/session/models/model-selector.js +11 -12
- package/dist/session/models/model-tags.d.ts +9 -0
- package/dist/session/models/model-tags.js +8 -0
- package/dist/session/panel/easy/easy-panel.js +1 -1
- package/dist/session/panel/easy/step-icon.js +5 -1
- package/dist/session/panel/mobile-tool-drawer.js +1 -1
- package/dist/session/panel/session-action-panel-column.js +1 -1
- package/dist/session/panel/session-desktop.js +41 -14
- package/dist/session/panel/session-panel-provider.d.ts +1 -1
- package/dist/session/panel/session-panel-provider.js +7 -11
- package/dist/session/prompts/question-prompt.js +3 -1
- package/dist/session/status/session-error-banner.js +4 -1
- package/dist/session/thread/session-chat.js +286 -296
- package/dist/session/thread/session-context-modal.js +29 -10
- package/dist/session/thread/session-context-spawned-sessions.d.ts +13 -0
- package/dist/session/thread/session-context-spawned-sessions.js +44 -0
- package/dist/session/thread/session-context-sub-sessions.js +3 -8
- package/dist/session/thread/transcript.d.ts +3 -0
- package/dist/session/thread/transcript.js +32 -8
- package/dist/session/tool/shared/full-view-action.d.ts +29 -0
- package/dist/session/tool/shared/full-view-action.js +43 -0
- package/dist/session/tool/tool-part-renderer.js +10 -2
- package/dist/session/tool/tools/agent-message-tool.js +2 -2
- package/dist/session/tool/tools/agent-spawn-tool.js +2 -2
- package/dist/session/tool/tools/agent-status-tool.js +2 -2
- package/dist/session/tool/tools/kortix-action-tool.d.ts +2 -0
- package/dist/session/tool/tools/kortix-action-tool.js +148 -0
- package/dist/session/tool/tools/kortix-tool-card.d.ts +83 -0
- package/dist/session/tool/tools/kortix-tool-card.js +186 -0
- package/dist/session/tool/tools/multi-agent-tool-bodies.d.ts +11 -0
- package/dist/session/tool/tools/multi-agent-tool-bodies.js +141 -0
- package/dist/session/tool/tools/multi-agent-tool-data.d.ts +63 -0
- package/dist/session/tool/tools/multi-agent-tool-data.js +118 -0
- package/dist/session/tool/tools/multi-agent-tools.d.ts +9 -0
- package/dist/session/tool/tools/multi-agent-tools.js +38 -0
- package/dist/session/tool/tools/question-tool.js +1 -1
- package/dist/session/tool/tools/register.d.ts +3 -0
- package/dist/session/tool/tools/register.js +3 -0
- package/dist/session/tool/tools/session-spawn-tool.js +2 -2
- package/dist/session/tool/tools/task-tool.d.ts +1 -1
- package/dist/session/tool/tools/task-tool.js +29 -41
- package/dist/session/tool/tools/workflow-progress.d.ts +34 -0
- package/dist/session/tool/tools/workflow-progress.js +186 -0
- package/dist/session/tool/tools/workflow-run.d.ts +128 -0
- package/dist/session/tool/tools/workflow-run.js +251 -0
- package/dist/session/tool/tools/workflow-tool.d.ts +9 -0
- package/dist/session/tool/tools/workflow-tool.js +253 -0
- package/dist/session/turn/notice-batch-group.d.ts +12 -0
- package/dist/session/turn/notice-batch-group.js +17 -0
- package/dist/session/turn/peer-message-row.d.ts +14 -0
- package/dist/session/turn/peer-message-row.js +57 -0
- package/dist/session/turn/subagent-notice-row.d.ts +4 -0
- package/dist/session/turn/subagent-notice-row.js +50 -0
- package/dist/session/turn/subagent-notice.d.ts +58 -0
- package/dist/session/turn/subagent-notice.js +111 -0
- package/dist/session/turn/user-message.js +24 -5
- package/dist/styles/tokens.css +2 -0
- package/dist/styles.css +1 -1
- package/dist/terminal/session-terminal-connect-bar.js +1 -1
- package/dist/workspace/admin/project-admin-dashboard.d.ts +53 -0
- package/dist/workspace/admin/project-admin-dashboard.js +252 -0
- package/dist/workspace/admin/project-admin-nav.d.ts +20 -0
- package/dist/workspace/admin/project-admin-nav.js +41 -0
- package/dist/workspace/home/welcome-body.js +25 -3
- package/dist/workspace/index.d.ts +6 -2
- package/dist/workspace/index.js +12 -2
- package/dist/workspace/layout/new-session-create.js +3 -3
- package/dist/workspace/layout/project-home.js +3 -3
- package/dist/workspace/memory/memory-labels.js +5 -0
- package/dist/workspace/repository-disconnected.js +2 -2
- package/dist/workspace/sessions/board-dispatch.d.ts +52 -0
- package/dist/workspace/sessions/board-dispatch.js +110 -0
- package/dist/workspace/sessions/board-grouping.d.ts +63 -0
- package/dist/workspace/sessions/board-grouping.js +141 -0
- package/dist/workspace/sessions/board-peek.d.ts +15 -0
- package/dist/workspace/sessions/board-peek.js +54 -0
- package/dist/workspace/sessions/board-state-mark.d.ts +15 -0
- package/dist/workspace/sessions/board-state-mark.js +24 -0
- package/dist/workspace/sessions/project-sessions-view.js +42 -31
- package/dist/workspace/sessions/sessions-board.d.ts +12 -0
- package/dist/workspace/sessions/sessions-board.js +214 -0
- package/dist/workspace/sidebar/footer/project-manifest-issues-alert.d.ts +46 -0
- package/dist/workspace/sidebar/footer/project-manifest-issues-alert.js +85 -0
- package/dist/workspace/sidebar/footer/sidebar-alert.js +1 -1
- package/dist/workspace/sidebar/new-agent-modal-provider.d.ts +12 -0
- package/dist/workspace/sidebar/new-agent-modal-provider.js +19 -0
- package/dist/workspace/sidebar/project-nav-items.d.ts +3 -1
- package/dist/workspace/sidebar/project-nav-items.js +53 -5
- package/dist/workspace/sidebar/project-session-list.js +35 -12
- package/dist/workspace/sidebar/project-sidebar.js +6 -3
- package/dist/workspace/sidebar/session-filter-menu.js +2 -1
- package/dist/workspace/space/space-blocks.d.ts +25 -0
- package/dist/workspace/space/space-blocks.js +124 -0
- package/dist/workspace/space/space-filter-tabs.d.ts +17 -0
- package/dist/workspace/space/space-filter-tabs.js +31 -0
- package/dist/workspace/space/space-page.d.ts +24 -0
- package/dist/workspace/space/space-page.js +157 -0
- package/dist/workspace/space/space-room.d.ts +20 -0
- package/dist/workspace/space/space-room.js +27 -0
- package/dist/workspace/space/space-tab-menu.d.ts +14 -0
- package/dist/workspace/space/space-tab-menu.js +127 -0
- package/dist/workspace/space/space-tab-panels.d.ts +9 -0
- package/dist/workspace/space/space-tab-panels.js +203 -0
- package/dist/workspace/space/space-templates.d.ts +34 -0
- package/dist/workspace/space/space-templates.js +71 -0
- package/dist/workspace/space/use-space-filter.d.ts +10 -0
- package/dist/workspace/space/use-space-filter.js +40 -0
- package/dist/workspace/space/use-space-manifest.d.ts +8 -0
- package/dist/workspace/space/use-space-manifest.js +27 -0
- package/dist/workspace/spaces/space-timeline.js +2 -2
- package/package.json +56 -53
- package/skills/kortix-ui/SKILL.md +1 -1
- package/skills/kortix-ui/references/custom-dashboard.md +10 -4
- package/skills/kortix-ui/references/modules.md +10 -8
- package/dist/_vendor/shared/meta-agent.d.ts +0 -7
- package/dist/customize/agents/agent-grant-pages.d.ts +0 -37
- package/dist/customize/agents/agent-grant-pages.js +0 -226
- package/dist/customize/agents/agent-triggers-section.d.ts +0 -17
- package/dist/customize/agents/agent-triggers-section.js +0 -109
- package/dist/customize/migrate-to-v2/index.d.ts +0 -5
- package/dist/customize/migrate-to-v2/index.js +0 -5
- package/dist/customize/migrate-to-v2/migration-prompt.d.ts +0 -16
- package/dist/customize/migrate-to-v2/migration-prompt.js +0 -59
- package/dist/customize/migrate-to-v2/upgrade-defs.d.ts +0 -30
- package/dist/customize/migrate-to-v2/upgrade-defs.js +0 -43
- package/dist/customize/migrate-to-v2/upgrade-view.d.ts +0 -32
- package/dist/customize/migrate-to-v2/upgrade-view.js +0 -152
- package/dist/customize/migrate-to-v2/use-run-upgrade.d.ts +0 -18
- package/dist/customize/migrate-to-v2/use-run-upgrade.js +0 -16
- package/dist/customize/shared/capability-tabs.d.ts +0 -3
- package/dist/customize/shared/capability-tabs.js +0 -137
- package/dist/customize/skills/skill-scope.d.ts +0 -14
- package/dist/customize/skills/skill-scope.js +0 -18
- package/dist/internal/lib/manifest-version.d.ts +0 -21
- package/dist/internal/lib/manifest-version.js +0 -55
- package/dist/session/composer/hooks/use-composer-escape-stop.d.ts +0 -6
- package/dist/session/composer/hooks/use-composer-escape-stop.js +0 -28
- package/dist/session/thread/sub-session-modal-content.d.ts +0 -8
- package/dist/session/thread/sub-session-modal-content.js +0 -23
- package/dist/session/thread/sub-session-modal.d.ts +0 -2
- package/dist/session/thread/sub-session-modal.js +0 -14
- package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.d.ts +0 -13
- package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.js +0 -48
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* New agent. Three ways to start, the agent-first one first: describe the
|
|
5
|
+
* work to My Kortix (it drafts the agent with only the access the work
|
|
6
|
+
* needs), start blank, or copy another agent. Each one opens a session of My
|
|
7
|
+
* Kortix that writes `agents.<name>` and opens a change request: there is no
|
|
8
|
+
* write path that skips review, so the modal never claims one.
|
|
9
|
+
*
|
|
10
|
+
* From `lg` the modal has two panes: the form, and a live preview of the
|
|
11
|
+
* agent it makes (its mark, name, `agents.<name>` key, description, and what
|
|
12
|
+
* it starts with). Below `lg` it is a bottom sheet capped at 90% of the
|
|
13
|
+
* window, form only. Its body scrolls and its footer stays pinned, so Create
|
|
14
|
+
* agent is reachable at 720×480.
|
|
15
|
+
*/
|
|
16
|
+
import { slugifySlug } from '../../_vendor/kortix-shared.js';
|
|
17
|
+
import { isMyKortixAgentName } from '../../_vendor/kortix-shared.js';
|
|
18
|
+
import { useState } from 'react';
|
|
19
|
+
import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
|
|
20
|
+
import { AgentMark, agentDisplayName } from '../../internal/components/agent-mark.js';
|
|
21
|
+
import { cn } from '../../internal/lib/utils.js';
|
|
22
|
+
import { Button } from '../../primitives/button.js';
|
|
23
|
+
import { Input } from '../../primitives/input.js';
|
|
24
|
+
import { Label } from '../../primitives/label.js';
|
|
25
|
+
import { Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ModalTitle, } from '../../primitives/modal.js';
|
|
26
|
+
import { RadioGroup, RadioGroupItem } from '../../primitives/radio-group.js';
|
|
27
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../primitives/select.js';
|
|
28
|
+
import { StatusDot } from '../../primitives/status.js';
|
|
29
|
+
import { Textarea } from '../../primitives/textarea.js';
|
|
30
|
+
import { useConfigureThread } from '../use-configure-thread.js';
|
|
31
|
+
/** A phone's footer clears the home indicator: the device inset, at least the footer's own py-3. */
|
|
32
|
+
const FOOTER_SAFE_AREA = 'max-lg:pb-[max(0.75rem,env(safe-area-inset-bottom))]'; // audit:allow device safe-area inset, not a spacing step
|
|
33
|
+
/** The request My Kortix receives. English, like every configure prompt. */
|
|
34
|
+
export function createAgentPrompt(input) {
|
|
35
|
+
const review = 'Then open a change request so I can review and merge it.';
|
|
36
|
+
const desc = input.description.trim();
|
|
37
|
+
if (input.start === 'duplicate' && input.from) {
|
|
38
|
+
return (`Create a new agent named "${input.name}" in kortix.yaml as a copy of the "${input.from.name}" agent ` +
|
|
39
|
+
`(its config lives at \`${input.from.path}\`)${desc ? `, with the description "${desc}"` : ''}. ${review}`);
|
|
40
|
+
}
|
|
41
|
+
if (input.start === 'blank') {
|
|
42
|
+
return (`Create a new agent named "${input.name}" in kortix.yaml${desc ? ` with the description "${desc}"` : ''}, ` +
|
|
43
|
+
`no grants (write \`tools: none\`) and empty instructions. ${review}`);
|
|
44
|
+
}
|
|
45
|
+
return (`Create a new agent named "${input.name}" in kortix.yaml. What it does: ${desc || 'ask me.'} ` +
|
|
46
|
+
`Write its instructions and give it only the tools, skills, connectors, secrets and permissions this work needs. ` +
|
|
47
|
+
`Always write its \`tools:\` key: a list of the tools it needs, or \`all\`. ${review}`);
|
|
48
|
+
}
|
|
49
|
+
/** One fact of the preview: a label left, its value right. */
|
|
50
|
+
function PreviewFact({ label, children }) {
|
|
51
|
+
return (_jsxs("div", { className: "flex items-center justify-between gap-3 text-sm", children: [_jsx("span", { className: "text-muted-foreground", children: label }), _jsx("span", { className: "text-foreground flex min-w-0 items-center gap-1.5 truncate", children: children })] }));
|
|
52
|
+
}
|
|
53
|
+
export function CreateAgentModal({ open, onOpenChange, projectId, config, }) {
|
|
54
|
+
const t = useI18nTranslations('agentEditor.tabs');
|
|
55
|
+
const tPage = useI18nTranslations('agentEditor.page');
|
|
56
|
+
const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
|
|
57
|
+
const configure = useConfigureThread(projectId);
|
|
58
|
+
const agents = (config?.agents ?? []).filter((a) => !a.platform);
|
|
59
|
+
const [start, setStart] = useState('describe');
|
|
60
|
+
const [name, setName] = useState('');
|
|
61
|
+
const [description, setDescription] = useState('');
|
|
62
|
+
const [from, setFrom] = useState('');
|
|
63
|
+
const slug = name.trim() ? slugifySlug(name, '') : '';
|
|
64
|
+
// Every declared agent and the built-in ones: a new agent can never take a
|
|
65
|
+
// platform agent's key. `agents` (the Duplicate sources) leaves them out.
|
|
66
|
+
const taken = (config?.agents ?? []).some((a) => a.name === slug) || isMyKortixAgentName(slug);
|
|
67
|
+
const source = agents.find((a) => a.name === from);
|
|
68
|
+
const ready = slug.length > 0 && !taken && (start !== 'duplicate' || source !== undefined);
|
|
69
|
+
const submit = () => {
|
|
70
|
+
if (!ready || configure.pending)
|
|
71
|
+
return;
|
|
72
|
+
configure.start(createAgentPrompt({
|
|
73
|
+
start,
|
|
74
|
+
name: slug,
|
|
75
|
+
description,
|
|
76
|
+
from: source ? { name: source.name, path: source.path } : undefined,
|
|
77
|
+
}));
|
|
78
|
+
};
|
|
79
|
+
const choices = [
|
|
80
|
+
{ key: 'describe', title: t('startDescribe'), help: t('startDescribeHelp') },
|
|
81
|
+
{ key: 'blank', title: t('startBlank'), help: t('startBlankHelp') },
|
|
82
|
+
{ key: 'duplicate', title: t('startDuplicate'), help: t('startDuplicateHelp') },
|
|
83
|
+
];
|
|
84
|
+
// What the new agent starts with, per way to start.
|
|
85
|
+
const startsWith = {
|
|
86
|
+
describe: { instructions: t('previewDrafted'), access: t('previewAccessScoped') },
|
|
87
|
+
blank: { instructions: t('previewEmpty'), access: t('previewAccessNone') },
|
|
88
|
+
duplicate: { instructions: t('previewCopied'), access: t('previewCopied') },
|
|
89
|
+
}[start];
|
|
90
|
+
return (_jsx(Modal, { open: open, onOpenChange: onOpenChange, children: _jsx(ModalContent, { className: "flex flex-col space-y-0 overflow-hidden lg:max-w-4xl", children: _jsxs("form", { className: "flex min-h-0 flex-1 flex-col", onSubmit: (event) => {
|
|
91
|
+
event.preventDefault();
|
|
92
|
+
submit();
|
|
93
|
+
}, children: [_jsxs("div", { className: "flex min-h-0 flex-1", children: [_jsxs("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: [_jsx(ModalHeader, { className: "shrink-0 pb-4", children: _jsx(ModalTitle, { children: t('newAgent') }) }), _jsxs(ModalBody, { className: "min-h-0 overflow-y-auto", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "new-agent-name", children: t('name') }), _jsx(Input, { id: "new-agent-name", value: name, placeholder: t('namePlaceholder'), onChange: (e) => setName(e.target.value), autoFocus: true }), taken ? (_jsxs("p", { className: "text-foreground flex items-center gap-1.5 text-xs", children: [_jsx(StatusDot, { tone: "destructive" }), t('nameTaken')] })) : null] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("p", { className: "text-foreground text-sm font-medium", children: t('howToStart') }), _jsx(RadioGroup, { "aria-label": t('howToStart'), value: start, onValueChange: (next) => setStart(next), className: "gap-1", children: choices.map((choice) => (_jsx(RadioGroupItem, { value: choice.key, label: choice.title, description: choice.help, size: "lg" }, choice.key))) })] }), start === 'duplicate' ? (_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { children: t('copyOf') }), _jsxs(Select, { value: from, onValueChange: setFrom, children: [_jsx(SelectTrigger, { "aria-label": t('copyOf'), className: "w-full", children: _jsx(SelectValue, { placeholder: t('pickAgent') }) }), _jsx(SelectContent, { children: agents.map((agent) => (_jsx(SelectItem, { value: agent.name, children: _jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [_jsx(AgentMark, { slug: agent.name }), _jsx("span", { className: "truncate", children: agentDisplayName(agent.name) })] }) }, agent.name))) })] })] })) : null, _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "new-agent-description", children: start === 'describe' ? t('whatItDoes') : tI18nComplete.raw('text526e0087cc3f') }), _jsx(Textarea, { id: "new-agent-description", value: description, placeholder: start === 'describe' ? t('whatItDoesPlaceholder') : t('descriptionPlaceholderShort'), onChange: (e) => setDescription(e.target.value), minHeight: start === 'describe' ? 90 : 52 })] })] })] }), _jsxs("aside", { "aria-label": t('preview'), className: "bg-background hidden w-96 shrink-0 flex-col gap-4 overflow-y-auto border-l p-5 lg:flex", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t('preview') }), _jsxs("div", { className: "space-y-1", children: [_jsx("div", { className: "pb-3", children: _jsx(AgentMark, { slug: slug || 'new-agent', size: 42 }) }), _jsx("p", { className: cn('truncate text-lg font-medium', slug ? 'text-foreground' : 'text-muted-foreground'), children: agentDisplayName(slug || t('namePlaceholder')) }), _jsx("p", { className: "text-muted-foreground truncate font-mono text-xs", children: `agents.${slug || t('namePlaceholder')}` }), description.trim() ? (_jsx("p", { className: "text-foreground line-clamp-3 pt-1 text-sm text-pretty", children: description.trim() })) : null] }), _jsxs("div", { className: "space-y-2.5 border-t pt-4", children: [start === 'duplicate' && source ? (_jsxs(PreviewFact, { label: t('copyOf'), children: [_jsx(AgentMark, { slug: source.name }), _jsx("span", { className: "truncate", children: agentDisplayName(source.name) })] })) : null, _jsx(PreviewFact, { label: tPage('instructions'), children: startsWith.instructions }), _jsx(PreviewFact, { label: t('tabAccess'), children: startsWith.access })] })] })] }), _jsxs(ModalFooter, { className: cn('shrink-0 border-t py-3', FOOTER_SAFE_AREA), children: [_jsx("p", { className: "text-muted-foreground mr-auto hidden text-xs sm:block", children: t('composerNote') }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "w-full sm:w-auto", onClick: () => onOpenChange(false), children: tI18nComplete.raw('text19766ed6ccb2') }), _jsx(Button, { type: "submit", size: "sm", className: "w-full sm:w-auto", disabled: !ready || configure.pending, "aria-busy": configure.pending || undefined, children: t('createAgent') })] })] }) }) }));
|
|
94
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AgentGrantSet } from '@kortix/sdk';
|
|
2
2
|
/**
|
|
3
3
|
* Which agents can use which connector, and with which rule set, read from
|
|
4
|
-
* the root kortix.yaml
|
|
4
|
+
* the root kortix.yaml: `agents.<a>.connectors` is the grant and
|
|
5
5
|
* `agents.<a>.policy_sets.<slug>` the set. The connector page's Agents tab and
|
|
6
6
|
* the Rules matrix both read this, and both write through `setAgentScope`.
|
|
7
7
|
*
|
|
@@ -14,12 +14,12 @@ export interface AgentConnectorAccess {
|
|
|
14
14
|
policySet: string | null;
|
|
15
15
|
}
|
|
16
16
|
export interface AgentGrants {
|
|
17
|
-
/** `all`, or the granted slugs. An absent grant is none (
|
|
17
|
+
/** `all`, or the granted slugs. An absent grant is none (deny by default). */
|
|
18
18
|
connectors: 'all' | string[];
|
|
19
19
|
policySets: Record<string, string>;
|
|
20
20
|
}
|
|
21
|
-
/** Every declared agent's connector grant and sets, by agent name.
|
|
22
|
-
export declare function manifestAgentGrants(manifestRaw: string | null | undefined): Record<string, AgentGrants
|
|
21
|
+
/** Every declared agent's connector grant and sets, by agent name. Empty when there is no manifest or it does not parse. */
|
|
22
|
+
export declare function manifestAgentGrants(manifestRaw: string | null | undefined): Record<string, AgentGrants>;
|
|
23
23
|
export declare function agentConnectorAccess(grants: AgentGrants | undefined, slug: string): AgentConnectorAccess;
|
|
24
24
|
/**
|
|
25
25
|
* The agent's connector grant after giving or taking one connector. Taking one
|
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
import { parseManifestText } from '../../_vendor/kortix-shared.js';
|
|
2
|
-
/** Every declared agent's connector grant and sets, by agent name.
|
|
2
|
+
/** Every declared agent's connector grant and sets, by agent name. Empty when there is no manifest or it does not parse. */
|
|
3
3
|
export function manifestAgentGrants(manifestRaw) {
|
|
4
4
|
if (!manifestRaw)
|
|
5
|
-
return
|
|
5
|
+
return {};
|
|
6
6
|
let manifest;
|
|
7
7
|
try {
|
|
8
|
-
manifest = parseManifestText(manifestRaw
|
|
8
|
+
manifest = parseManifestText(manifestRaw);
|
|
9
9
|
}
|
|
10
10
|
catch {
|
|
11
|
-
return
|
|
11
|
+
return {};
|
|
12
12
|
}
|
|
13
|
-
const version = Number(manifest.kortix_version);
|
|
14
13
|
const agents = manifest.agents;
|
|
15
|
-
if (!(version >= 2))
|
|
16
|
-
return null;
|
|
17
14
|
if (!agents || typeof agents !== 'object' || Array.isArray(agents))
|
|
18
15
|
return {};
|
|
19
16
|
const out = Object.create(null);
|
|
@@ -53,12 +50,12 @@ export function withConnectorGrant(grants, slug, on, allSlugs) {
|
|
|
53
50
|
}
|
|
54
51
|
/** Each connector's rule sets (`connectors[].policy_sets`) with their agent count, by slug. */
|
|
55
52
|
export function connectorRuleSetUsage(manifestRaw) {
|
|
56
|
-
|
|
57
|
-
if (!grants || !manifestRaw)
|
|
53
|
+
if (!manifestRaw)
|
|
58
54
|
return {};
|
|
55
|
+
const grants = manifestAgentGrants(manifestRaw);
|
|
59
56
|
let manifest;
|
|
60
57
|
try {
|
|
61
|
-
manifest = parseManifestText(manifestRaw
|
|
58
|
+
manifest = parseManifestText(manifestRaw);
|
|
62
59
|
}
|
|
63
60
|
catch {
|
|
64
61
|
return {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AdminConnector } from '@kortix/sdk';
|
|
2
|
+
import type { ConnectorLogoSource } from '../../internal/connector-logo/connector-logo-source.js';
|
|
2
3
|
/**
|
|
3
4
|
* How a connector presents its status — the connected mark and the status
|
|
4
5
|
* pill. Its logo is `ConnectorLogo` (`connector-logo.tsx`), shared by every
|
|
@@ -31,3 +32,14 @@ export declare function ConnectorStatusBadge({ connector, accountCount, }: {
|
|
|
31
32
|
connector: AdminConnector;
|
|
32
33
|
accountCount?: number;
|
|
33
34
|
}): import("react").JSX.Element | null;
|
|
35
|
+
/**
|
|
36
|
+
* A project connector's logo with its state on it, the way a Slack or Teams
|
|
37
|
+
* app tile shows one: a dot on the bottom-right corner (green Connected,
|
|
38
|
+
* orange Needs account, red Error). The word is for screen readers; the dot
|
|
39
|
+
* carries it on screen.
|
|
40
|
+
*/
|
|
41
|
+
export declare function ConnectorStatusLogo({ connector, source, accountCount, }: {
|
|
42
|
+
connector: AdminConnector;
|
|
43
|
+
source: ConnectorLogoSource;
|
|
44
|
+
accountCount?: number;
|
|
45
|
+
}): import("react").JSX.Element;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { CheckIcon, } from '@phosphor-icons/react';
|
|
4
|
-
import {
|
|
4
|
+
import { useTranslations } from '../../i18n/index.js';
|
|
5
|
+
import { ConnectorLogo } from '../../internal/connector-logo/connector-logo.js';
|
|
6
|
+
import { STATUS_DOT, STATUS_WORD, connectorStatusTone } from './detail/connector-status.js';
|
|
5
7
|
import { ConnectorStatusBadge as ToneBadge } from './detail/status-badge.js';
|
|
6
8
|
import { cn } from '../../internal/lib/utils.js';
|
|
7
9
|
/**
|
|
@@ -36,3 +38,14 @@ export function ConnectorStatusBadge({ connector, accountCount, }) {
|
|
|
36
38
|
const tone = connectorStatusTone(connector, accountCount);
|
|
37
39
|
return tone === 'connected' ? null : _jsx(ToneBadge, { tone: tone });
|
|
38
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* A project connector's logo with its state on it, the way a Slack or Teams
|
|
43
|
+
* app tile shows one: a dot on the bottom-right corner (green Connected,
|
|
44
|
+
* orange Needs account, red Error). The word is for screen readers; the dot
|
|
45
|
+
* carries it on screen.
|
|
46
|
+
*/
|
|
47
|
+
export function ConnectorStatusLogo({ connector, source, accountCount, }) {
|
|
48
|
+
const t = useTranslations('connectorPages');
|
|
49
|
+
const tone = connectorStatusTone(connector, accountCount);
|
|
50
|
+
return (_jsxs("span", { className: "relative flex shrink-0", children: [_jsx(ConnectorLogo, { source: source, size: "lg" }), _jsx("span", { "aria-hidden": true, className: "bg-background absolute -right-1 -bottom-1 flex size-3 items-center justify-center rounded-full", children: _jsx("span", { className: cn('size-2 rounded-full', STATUS_DOT[tone]) }) }), _jsx("span", { className: "sr-only", children: t(STATUS_WORD[tone]) })] }));
|
|
51
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { adminPath } from '../../lib/routes.js';
|
|
2
2
|
/**
|
|
3
3
|
* The app segment of a connector reached without an app: the Connected tab, a
|
|
4
4
|
* custom connector, a computer. Its back link goes to the Connected tab.
|
|
@@ -7,7 +7,7 @@ export const CONNECTED_APP_SEGMENT = 'connected';
|
|
|
7
7
|
/** The id of the native Computer entry: it has its own page (`ComputerAppPage`). */
|
|
8
8
|
export const COMPUTER_APP_ID = 'native:computer';
|
|
9
9
|
function base(projectId) {
|
|
10
|
-
return
|
|
10
|
+
return adminPath(encodeURIComponent(projectId), 'connectors');
|
|
11
11
|
}
|
|
12
12
|
function withQuery(path, params) {
|
|
13
13
|
const query = params.toString();
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type AgentGrant, type ResourceScope } from '../shared/agent-resource-scope.js';
|
|
1
3
|
/**
|
|
2
4
|
* /projects/[id]/connectors — the standalone Connectors catalogue.
|
|
3
5
|
*
|
|
@@ -35,6 +37,17 @@
|
|
|
35
37
|
* `legacyDetailRedirect` forwards it, so an OAuth grant that started before
|
|
36
38
|
* the change still lands on the right connector.
|
|
37
39
|
*/
|
|
38
|
-
export declare function ConnectorsPage({ projectId }: {
|
|
40
|
+
export declare function ConnectorsPage({ projectId, surface, grant, agentPanel, rowControl, }: {
|
|
39
41
|
projectId: string;
|
|
42
|
+
/** `global` (default) is the project catalogue; `agent` scopes the same page
|
|
43
|
+
* to one agent and turns each connector card into a grant control. */
|
|
44
|
+
surface?: ResourceScope;
|
|
45
|
+
/** Required in `agent` scope: the agent's `connectors` grant, driven by the
|
|
46
|
+
* page's draft. Ignored in `global` scope. */
|
|
47
|
+
grant?: AgentGrant;
|
|
48
|
+
/** Agent scope only: agent settings that belong with its connectors (the
|
|
49
|
+
* per-connector policy sets), shown above the catalogue. */
|
|
50
|
+
agentPanel?: ReactNode;
|
|
51
|
+
/** Agent scope only: a granted connector's own rule control (its policy-set picker), in its row. */
|
|
52
|
+
rowControl?: (slug: string) => ReactNode | undefined;
|
|
40
53
|
}): import("react").JSX.Element;
|
|
@@ -5,7 +5,7 @@ import { newConfigPrompt, useConfigureThread, } from '../use-configure-thread.js
|
|
|
5
5
|
import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
|
|
6
6
|
import { getProjectDetail, listConnectors } from '@kortix/sdk';
|
|
7
7
|
import { contract, FRESHNESS, qk, useProjectAccountId } from '@kortix/sdk/react';
|
|
8
|
-
import { CaretDownIcon, MagnifyingGlassIcon,
|
|
8
|
+
import { CaretDownIcon, MagnifyingGlassIcon, PlugsConnectedIcon, ShieldIcon } from '@phosphor-icons/react';
|
|
9
9
|
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
|
10
10
|
import { lazyClient } from '../../lib/lazy-client.js';
|
|
11
11
|
import { useUiPathname, useUiRouter, useUiSearchParams, useUiShallowNavigate, } from '../../providers/ui-provider.js';
|
|
@@ -23,21 +23,26 @@ import { Skeleton } from '../../primitives/skeleton.js';
|
|
|
23
23
|
import { SplitSheet, SplitSheetBody, SplitSheetContent, SplitSheetDescription, SplitSheetHeader, SplitSheetMain, SplitSheetTitle, } from '../../primitives/split-sheet.js';
|
|
24
24
|
import { Tabs, TabsList, TabsTrigger } from '../../primitives/tabs.js';
|
|
25
25
|
import { EmptyState } from '../../primitives/empty-state.js';
|
|
26
|
-
import { connectorConnectionQueryKeys,
|
|
26
|
+
import { connectorConnectionQueryKeys, } from '../sections/connector-connection-form.js';
|
|
27
27
|
import { PROJECT_ACTIONS } from '../../internal/lib/project-actions.js';
|
|
28
28
|
import { useProjectCan } from '../../internal/lib/use-project-can.js';
|
|
29
|
-
import {
|
|
29
|
+
import { ConnectorStatusBadge, ConnectorStatusLogo } from './connector-identity.js';
|
|
30
|
+
import { CatalogCard } from '../shared/catalog/catalog-card.js';
|
|
31
|
+
import { DENSE_GRID_CLASSNAME, DENSE_GRID_CONTAINER_CLASSNAME } from '../shared/catalog/catalog-grid-tokens.js';
|
|
30
32
|
import { ConnectorLogo } from '../../internal/connector-logo/connector-logo.js';
|
|
31
33
|
import { installedConnectorLogoSource } from '../../internal/connector-logo/connector-logo-source.js';
|
|
32
34
|
import { providerLabel } from './provider-label.js';
|
|
33
35
|
import { connectedCatalogKeys, } from './catalog/catalog-entry.js';
|
|
34
36
|
import { ConnectorBrowse } from './catalog/connector-browse.js';
|
|
35
37
|
import { useCatalog } from './catalog/use-catalog.js';
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
+
import { GrantModeTabs, withCatalog } from '../shared/agent-resource-scope.js';
|
|
39
|
+
import { CapabilityPageShell, useCapabilityShellEmbed } from '../shared/capability-page-shell.js';
|
|
40
|
+
import { plainGrantSwitch } from '../shared/access-list.js';
|
|
41
|
+
import { EditorList } from '../sections/view/agent-editor-primitives.js';
|
|
42
|
+
import { ErrorState } from '../../primitives/error-state.js';
|
|
43
|
+
import { EmptyArt } from '../../primitives/empty-art.js';
|
|
38
44
|
import { catalogEmptyKind } from '../shared/catalog/catalog-empty.js';
|
|
39
45
|
import { CatalogNoMatch } from '../shared/catalog/catalog-empty-state.js';
|
|
40
|
-
import { CatalogGrid } from '../shared/catalog/catalog-grid.js';
|
|
41
46
|
import { useTunnelConnections } from '@kortix/sdk/react';
|
|
42
47
|
import { useSlashFocus } from '../../internal/hooks/index.js';
|
|
43
48
|
import { connectorDisplayName, connectorSummary, filterConnectors, } from './connector-filter.js';
|
|
@@ -173,8 +178,14 @@ function parseScope(value) {
|
|
|
173
178
|
* `legacyDetailRedirect` forwards it, so an OAuth grant that started before
|
|
174
179
|
* the change still lands on the right connector.
|
|
175
180
|
*/
|
|
176
|
-
export function ConnectorsPage({ projectId }) {
|
|
181
|
+
export function ConnectorsPage({ projectId, surface = { kind: 'global' }, grant, agentPanel, rowControl, }) {
|
|
177
182
|
const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
|
|
183
|
+
const tAgentScope = useI18nTranslations('agentScope');
|
|
184
|
+
const tTabs = useI18nTranslations('agentEditor.tabs');
|
|
185
|
+
const agentScoped = surface.kind === 'agent' && grant !== undefined;
|
|
186
|
+
// The agent page's rail layout: Add sits in the footer card, not the header.
|
|
187
|
+
const embed = useCapabilityShellEmbed();
|
|
188
|
+
const railLayout = agentScoped && embed?.titled === true;
|
|
178
189
|
// `accountId` comes off the detail this page already loads. Without it
|
|
179
190
|
// `useProjectCan` fetches the project a second time under its own key AND
|
|
180
191
|
// holds the IAM probe disabled until that lands — so Add and every write
|
|
@@ -269,7 +280,11 @@ export function ConnectorsPage({ projectId }) {
|
|
|
269
280
|
// form. Channels has its own primary action already — the Slack hero owns
|
|
270
281
|
// it — so it needs neither, and leaving them on screen would offer to search
|
|
271
282
|
// a list that is not there.
|
|
272
|
-
|
|
283
|
+
// Channels is the inbound side (who can reach the agent), not a connector
|
|
284
|
+
// the agent is granted — so it is not part of the agent-scoped view.
|
|
285
|
+
const channelsActive = scope === 'channels' && !agentScoped;
|
|
286
|
+
// Channels is a project-wide inbound surface, so an agent's page leaves it out.
|
|
287
|
+
const visibleScopes = SCOPES.filter((s) => !agentScoped || s !== 'channels');
|
|
273
288
|
// The machine list answers 503 on a deployment with computers disabled, so
|
|
274
289
|
// the Computer card shows only where a computer can be connected.
|
|
275
290
|
const computersEnabled = useTunnelConnections({ refetchInterval: false }).isSuccess;
|
|
@@ -287,9 +302,38 @@ export function ConnectorsPage({ projectId }) {
|
|
|
287
302
|
// already carries them (and a machineless one is not in `connectors`).
|
|
288
303
|
const ownMatches = useMemo(() => filtered.filter((connector) => connector.provider !== 'computer'), [filtered]);
|
|
289
304
|
const emptyKind = catalogEmptyKind(connectors.length, filtered.length);
|
|
290
|
-
// One
|
|
291
|
-
//
|
|
292
|
-
|
|
305
|
+
// One row shape for the project's connectors in both modes (the shared
|
|
306
|
+
// Access row): logo, name, what it is, the exception mark, and in agent
|
|
307
|
+
// mode the switch that grants it. The name opens the connector's page.
|
|
308
|
+
const connectorRows = (list) => {
|
|
309
|
+
const slugs = connectors.map((connector) => connector.slug);
|
|
310
|
+
const toggle = agentScoped && grant?.set ? plainGrantSwitch(grant.value, slugs, grant.set) : null;
|
|
311
|
+
return list.map((connector) => {
|
|
312
|
+
const switched = toggle ? toggle(connector.slug) : {};
|
|
313
|
+
return {
|
|
314
|
+
id: connector.slug,
|
|
315
|
+
title: connectorDisplayName(connector),
|
|
316
|
+
leading: _jsx(ConnectorLogo, { source: installedConnectorLogoSource(connector), size: "sm" }),
|
|
317
|
+
description: describeConnector(connector),
|
|
318
|
+
status: _jsx(ConnectorStatusBadge, { connector: connector }),
|
|
319
|
+
onOpen: () => router.push(connectorHref(projectId, connector.slug)),
|
|
320
|
+
...switched,
|
|
321
|
+
...(rowControl ? { control: (switched.checked && rowControl(connector.slug)) || '—' } : {}),
|
|
322
|
+
};
|
|
323
|
+
});
|
|
324
|
+
};
|
|
325
|
+
// The project's own connectors, the way All apps shows the catalogue: logo
|
|
326
|
+
// tiles in a grid, the state as a dot on the logo (`ConnectorStatusLogo`)
|
|
327
|
+
// instead of a pill. In an agent's view each tile also carries the grant
|
|
328
|
+
// switch and, while granted, its policy set, beside the link.
|
|
329
|
+
const ownConnectors = (list) => {
|
|
330
|
+
const rows = new Map(connectorRows(list).map((row) => [row.id, row]));
|
|
331
|
+
return (_jsx("div", { className: DENSE_GRID_CONTAINER_CLASSNAME, children: _jsx("div", { className: DENSE_GRID_CLASSNAME, children: list.map((connector) => {
|
|
332
|
+
const row = rows.get(connector.slug);
|
|
333
|
+
const toggle = agentScoped && row?.onCheckedChange ? (_jsxs("span", { className: "flex items-center gap-2", children: [row.checked && row.control && row.control !== '—' ? row.control : null, _jsx(Switch, { "aria-label": connectorDisplayName(connector), checked: row.checked === true, onCheckedChange: row.onCheckedChange, disabled: row.disabled })] })) : undefined;
|
|
334
|
+
return (_jsx(CatalogCard, { variant: "plain", href: connectorHref(projectId, connector.slug), leading: _jsx(ConnectorStatusLogo, { connector: connector, source: installedConnectorLogoSource(connector) }), title: connectorDisplayName(connector), subtitle: _jsx("span", { className: "text-muted-foreground truncate text-xs", children: describeConnector(connector) }), trailing: toggle, trailingInteractive: toggle !== undefined, className: cn(agentScoped && row?.checked === false && 'opacity-60 hover:opacity-100') }, connector.slug));
|
|
335
|
+
}) }) }));
|
|
336
|
+
};
|
|
293
337
|
// Quiet on purpose: a filter, not a second tab strip.
|
|
294
338
|
const catalogFilters = (_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "text", size: "sm", className: cn('gap-1 px-0 transition-colors', kindFilter !== 'all' && 'text-foreground'), "aria-label": tPages('typeFilterLabel'), children: [kindFilter === 'all'
|
|
295
339
|
? tPages('typeFilterAll')
|
|
@@ -309,11 +353,50 @@ export function ConnectorsPage({ projectId }) {
|
|
|
309
353
|
// jumps back to it (`useSlashFocus`).
|
|
310
354
|
const searchRef = useRef(null);
|
|
311
355
|
useSlashFocus(searchRef, !channelsActive && !rulesOpen);
|
|
356
|
+
// The catalogue scope strip. Rendered immediately, not behind `settled`:
|
|
357
|
+
// static labels over a scope read out of the URL have nothing to wait for.
|
|
358
|
+
// Project scope shows it in the filter row; agent scope shows it on the
|
|
359
|
+
// heading of the list it narrows, below the grant sentence.
|
|
360
|
+
const scopeTabs = visibleScopes.length > 1 ? (_jsx(Tabs, { value: scope, onValueChange: (value) => setScope(value), children: _jsx(TabsList, { children: visibleScopes.map((value) => (_jsx(TabsTrigger, { value: value, children: SCOPE_LABEL[value] }, value))) }) })) : null;
|
|
361
|
+
// The project's connectors as rows, with the page-level states: loading,
|
|
362
|
+
// a failed load, nothing yet, nothing matching.
|
|
363
|
+
const listBody = (list) => {
|
|
364
|
+
if (!settled) {
|
|
365
|
+
return (_jsx(EditorList, { children: [0, 1, 2].map((i) => (_jsxs("li", { className: "flex min-h-12 items-center gap-3 px-4 py-2", children: [_jsx(Skeleton, { className: "size-6 rounded-sm" }), _jsx(Skeleton, { className: "h-4 w-40 rounded-sm" })] }, i))) }));
|
|
366
|
+
}
|
|
367
|
+
if (isError) {
|
|
368
|
+
return (_jsx(ErrorState, { size: "sm", title: tI18nComplete.raw('text51ae0a7e3783'), action: _jsx(Button, { variant: "outline", size: "sm", onClick: retry, children: tPages('retry') }) }));
|
|
369
|
+
}
|
|
370
|
+
if (list.length > 0)
|
|
371
|
+
return ownConnectors(list);
|
|
372
|
+
if (query.trim())
|
|
373
|
+
return _jsx(CatalogNoMatch, { query: query });
|
|
374
|
+
return (_jsx(EmptyState, { media: _jsx(EmptyArt, { icon: PlugsConnectedIcon }), title: tI18nComplete.raw('text51ae0a7e3783'), description: tI18nComplete.raw('texta3487dfc2132') }));
|
|
375
|
+
};
|
|
376
|
+
// The project's connectors over the whole catalogue: the All tab in
|
|
377
|
+
// project mode, and the agent view in agent mode (rows carry its switch).
|
|
378
|
+
const catalogSection = (_jsxs(_Fragment, { children: [ownMatches.length > 0 ? (_jsxs("div", { className: "space-y-3", children: [_jsx("h2", { className: "text-sm font-medium", children: tPages('yourConnectors') }), ownConnectors(ownMatches)] })) : null, _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-4 gap-y-2", children: [_jsx("h2", { className: "text-sm font-medium", children: tPages('allApps') }), _jsx("div", { className: "flex flex-wrap items-center gap-4", children: catalogFilters })] }), _jsx(ConnectorBrowse, { state: catalog, connectedKeys: connectedKeys, hrefFor: catalogHref, install: catalogInstall, emptyTitle: tI18nComplete.raw('text3a63271cafc1'), emptyDescription: tI18nComplete.raw('textf652a621153e'),
|
|
379
|
+
// A slug search that only the project's own connector answers
|
|
380
|
+
// must not ALSO read "No matches" under its card (KRTX-2531).
|
|
381
|
+
suppressNoMatch: ownMatches.length > 0 })] }));
|
|
382
|
+
const addMenu = canWrite && !channelsActive ? (_jsx(NewEntityMenu, { label: railLayout ? tTabs('addConnector') : tI18nComplete.raw('text18fdd549b2ed'), pending: configure.pending, onChat: () => configure.start(newConfigPrompt('connector')), quick: {
|
|
383
|
+
icon: PlugsConnectedIcon,
|
|
384
|
+
label: tPages('addMcpMenu'),
|
|
385
|
+
description: tPages('addMcpMenuHint'),
|
|
386
|
+
onSelect: () => {
|
|
387
|
+
setMcpApp(null);
|
|
388
|
+
setPanel('mcp');
|
|
389
|
+
},
|
|
390
|
+
}, manual: {
|
|
391
|
+
label: tI18nComplete.raw('text90ccaee30bdc'),
|
|
392
|
+
description: tI18nComplete.raw('textb0fbe9dc1fcc'),
|
|
393
|
+
onSelect: () => setPanel('custom'),
|
|
394
|
+
} })) : undefined;
|
|
312
395
|
return (
|
|
313
396
|
// Global rules open in a SplitSheet: the page narrows to make room instead
|
|
314
397
|
// of being covered. `PoliciesPanel` is a long CRUD list whose save bar
|
|
315
398
|
// sticks to the body's bottom edge, so the body is the only scroller.
|
|
316
|
-
_jsxs(SplitSheet, { open: rulesOpen, onOpenChange: setRulesOpen, size: "lg", className: "flex-1", children: [_jsx(SplitSheetMain, { children: _jsxs(CapabilityPageShell, { title: tI18nComplete.raw('textc3d2e79ebdd0'), description: SCOPE_DESCRIPTION[scope], search: channelsActive ? undefined : (_jsxs(InputGroupSearch, { children: [_jsx(InputGroupSearchIcon, { children: _jsx(MagnifyingGlassIcon, {}) }), _jsx(InputGroupSearchInput, { ref: searchRef, placeholder: tI18nComplete.raw('textc386cb852691'), value: query, onChange: (event) => setQuery(event.target.value), variant: "popover", size: "sm" })] })), action:
|
|
399
|
+
_jsxs(SplitSheet, { open: rulesOpen, onOpenChange: setRulesOpen, size: "lg", className: "flex-1", children: [_jsx(SplitSheetMain, { children: _jsxs(CapabilityPageShell, { title: tI18nComplete.raw('textc3d2e79ebdd0'), description: agentScoped ? tAgentScope('connectorsDescription') : SCOPE_DESCRIPTION[scope], search: channelsActive ? undefined : (_jsxs(InputGroupSearch, { children: [_jsx(InputGroupSearchIcon, { children: _jsx(MagnifyingGlassIcon, {}) }), _jsx(InputGroupSearchInput, { ref: searchRef, placeholder: agentScoped ? tAgentScope('connectorsSearch') : tI18nComplete.raw('textc386cb852691'), value: query, onChange: (event) => setQuery(event.target.value), variant: "popover", size: "sm" })] })), action:
|
|
317
400
|
/* The page's one header action, and it carries its label: a bare `+`
|
|
318
401
|
square made the reader guess, and what it opens — a custom-connector
|
|
319
402
|
form, not the catalogue — is not guessable from a glyph. Default
|
|
@@ -321,29 +404,15 @@ export function ConnectorsPage({ projectId }) {
|
|
|
321
404
|
lines up with the search field beside it. `aria-label` keeps the
|
|
322
405
|
full sentence for screen readers; it opens with the visible "Add",
|
|
323
406
|
so the accessible name still contains the visible label. */
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
setMcpApp(null);
|
|
330
|
-
setPanel('mcp');
|
|
331
|
-
},
|
|
332
|
-
}, manual: {
|
|
333
|
-
label: tI18nComplete.raw('text90ccaee30bdc'),
|
|
334
|
-
description: tI18nComplete.raw('textb0fbe9dc1fcc'),
|
|
335
|
-
onSelect: () => setPanel('custom'),
|
|
336
|
-
} })) : undefined, filters: (_jsxs(_Fragment, { children: [_jsx(Tabs, { value: scope, onValueChange: (value) => setScope(value), children: _jsx(TabsList, { children: SCOPES.map((value) => (_jsx(TabsTrigger, { value: value, children: SCOPE_LABEL[value] }, value))) }) }), _jsx(Button, { type: "button", variant: "text", size: "sm", onClick: () => setRulesOpen(true), className: "ml-auto px-0 transition-colors", children: tI18nComplete.raw('text1d59a5e09714') })] })), children: [channelsActive ? (
|
|
407
|
+
railLayout ? undefined : addMenu, filters: agentScoped && grant ? (_jsx(GrantModeTabs, { grant: withCatalog(grant, connectors.map((c) => c.slug)), label: tAgentScope('connectorsAccess') })) : visibleScopes.length > 1 ? (_jsxs(_Fragment, { children: [scopeTabs, _jsx(Button, { type: "button", variant: "text", size: "sm", onClick: () => setRulesOpen(true), className: "ml-auto px-0 transition-colors", children: tI18nComplete.raw('text1d59a5e09714') })] })) : undefined, children: [agentScoped ? (
|
|
408
|
+
/* Agent mode: the same catalogue as project mode (the project's
|
|
409
|
+
connectors, one switch each, then every app), then the agent's
|
|
410
|
+
rule sets. One library, two modes (Marko, 2026-10-28). */
|
|
411
|
+
_jsxs("div", { className: "space-y-6", children: [settled && !isError ? catalogSection : listBody(ownMatches), agentPanel, railLayout ? (_jsxs("div", { className: "bg-popover flex items-center gap-3 rounded-lg px-4 py-3", children: [_jsx(ShieldIcon, { className: "text-muted-foreground size-4 shrink-0" }), _jsx("p", { className: "text-muted-foreground min-w-0 flex-1 text-xs text-pretty", children: tTabs.rich('policySetsNote', { file: () => _jsx("code", { className: "text-foreground font-mono", children: "kortix.yaml" }) }) }), addMenu] })) : null] })) : channelsActive ? (
|
|
337
412
|
/* The whole of what used to be `/projects/<id>/channels`, minus the
|
|
338
413
|
shell it used to bring — this page's `CapabilityPageShell` is the
|
|
339
414
|
one column, the one heading and the one scroll container now. */
|
|
340
|
-
_jsx(ChannelsSection, { projectId: projectId })) : catalogActive ? (_jsxs(_Fragment, { children: [
|
|
341
|
-
// A slug search that only the project's own connector answers
|
|
342
|
-
// must not ALSO read "No matches" under its card (KRTX-2531).
|
|
343
|
-
suppressNoMatch: ownMatches.length > 0 })] })) : (_jsxs(_Fragment, { children: [_jsx(ConnectorMovesBanner, { projectId: projectId }), _jsx(CatalogGrid, { dense: true,
|
|
344
|
-
// `!settled`, not `connectorsQuery.isLoading`: the empty state's
|
|
345
|
-
// wording depends on `projectQuery` too. Same gate as the filter row.
|
|
346
|
-
isLoading: !settled, isError: isError, error: connectorsQuery.error ?? projectQuery.error, onRetry: retry, isEmpty: emptyKind !== null, empty: emptyKind === 'no-match' ? (_jsx(CatalogNoMatch, { query: query })) : (_jsx(EmptyState, { icon: PlugIcon, size: "sm", title: tI18nComplete.raw('text51ae0a7e3783'), description: tI18nComplete.raw('texta3487dfc2132'), action: _jsx(Button, { size: "sm", variant: "secondary", onClick: () => setScope('all'), children: tI18nComplete.raw('text45bfe4f17af7') }) })), children: filtered.map(ownConnectorCard) })] })), _jsx(AddMcpServerDialog, { projectId: projectId, app: mcpApp, open: panel === 'mcp', onOpenChange: (open) => setPanel(open ? 'mcp' : null), takenSlugs: connectors.map((connector) => connector.slug), onAdded: invalidate }, mcpApp?.url ?? 'paste'), installRequest ? (_jsx(InstallDialog, { appName: installRequest.target.appName, way: installRequest.way, open: true, pending: false, onOpenChange: (open) => !open && setInstallRequest(null), onConfirm: confirmInstall }, installRequest.target.appName)) : null, _jsx(Modal, { open: panel === 'custom', onOpenChange: (open) => !open && setPanel(null), children: _jsxs(ModalContent, { className: "lg:max-w-3xl", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: tI18nComplete.raw('text90ccaee30bdc') }), _jsx(ModalDescription, { children: tI18nComplete.raw('textd2f3be0047c4') })] }), _jsx(ModalBody, { className: "max-h-[75vh] overflow-y-auto", children: _jsx(CustomConnectorForm, { projectId: projectId, onAdded: (slug, { addAccount }) => {
|
|
415
|
+
_jsx(ChannelsSection, { projectId: projectId })) : catalogActive ? (catalogSection) : (_jsxs(_Fragment, { children: [_jsx(ConnectorMovesBanner, { projectId: projectId }), listBody(filtered)] })), _jsx(AddMcpServerDialog, { projectId: projectId, app: mcpApp, open: panel === 'mcp', onOpenChange: (open) => setPanel(open ? 'mcp' : null), takenSlugs: connectors.map((connector) => connector.slug), onAdded: invalidate }, mcpApp?.url ?? 'paste'), installRequest ? (_jsx(InstallDialog, { appName: installRequest.target.appName, way: installRequest.way, open: true, pending: false, onOpenChange: (open) => !open && setInstallRequest(null), onConfirm: confirmInstall }, installRequest.target.appName)) : null, _jsx(Modal, { open: panel === 'custom', onOpenChange: (open) => !open && setPanel(null), children: _jsxs(ModalContent, { className: "lg:max-w-3xl", children: [_jsxs(ModalHeader, { children: [_jsx(ModalTitle, { children: tI18nComplete.raw('text90ccaee30bdc') }), _jsx(ModalDescription, { children: tI18nComplete.raw('textd2f3be0047c4') })] }), _jsx(ModalBody, { className: "max-h-[75vh] overflow-y-auto", children: _jsx(CustomConnectorForm, { projectId: projectId, onAdded: (slug, { addAccount }) => {
|
|
347
416
|
invalidate();
|
|
348
417
|
setPanel(null);
|
|
349
418
|
router.push(connectorHref(projectId, slug, { addAccount }));
|
|
@@ -47,7 +47,7 @@ const surfaceLabel = (kind) => wayKindLabel(kind);
|
|
|
47
47
|
/** Tools shown before "Show all". */
|
|
48
48
|
const TOOLS_PREVIEW = 40;
|
|
49
49
|
/**
|
|
50
|
-
* `/projects/<id>/
|
|
50
|
+
* `/projects/<id>/admin/connectors/<app>` — one catalogue app: what it is,
|
|
51
51
|
* the one Install button, the connectors this project already has for it, and
|
|
52
52
|
* the other ways to connect it.
|
|
53
53
|
*
|
|
@@ -51,9 +51,6 @@ export function ConnectorAgents({ projectId, connector }) {
|
|
|
51
51
|
if (access.isError) {
|
|
52
52
|
return (_jsx(ErrorState, { size: "sm", title: t('agentsLoadFailed'), description: access.error instanceof Error ? access.error.message : undefined, action: _jsx(Button, { variant: "outline", size: "sm", onClick: () => void access.refetch(), children: tSets('retry') }) }));
|
|
53
53
|
}
|
|
54
|
-
if (!access.supported) {
|
|
55
|
-
return _jsx("p", { className: "text-muted-foreground text-sm text-pretty", children: t('agentsNeedsV2') });
|
|
56
|
-
}
|
|
57
54
|
if (access.agents.length === 0) {
|
|
58
55
|
return _jsx(EmptyState, { icon: RobotIcon, size: "sm", title: t('agentsEmpty') });
|
|
59
56
|
}
|
|
@@ -3,7 +3,7 @@ import { type ReactNode } from 'react';
|
|
|
3
3
|
import { type AppRef } from '../connector-routes.js';
|
|
4
4
|
/** The column `CapabilityPageShell` gives the list page beside this one. */
|
|
5
5
|
/**
|
|
6
|
-
* `/projects/<id>/
|
|
6
|
+
* `/projects/<id>/admin/connectors/<app>/<connector>` — one connector, as
|
|
7
7
|
* a page: its accounts, its tools, its settings.
|
|
8
8
|
*
|
|
9
9
|
* `appSegment` is navigation context only. It decides where Back goes: the
|
|
@@ -43,7 +43,7 @@ import { ConnectorStatusBadge } from './status-badge.js';
|
|
|
43
43
|
import { useConnectorDetail } from './use-connector-detail.js';
|
|
44
44
|
/** The column `CapabilityPageShell` gives the list page beside this one. */
|
|
45
45
|
/**
|
|
46
|
-
* `/projects/<id>/
|
|
46
|
+
* `/projects/<id>/admin/connectors/<app>/<connector>` — one connector, as
|
|
47
47
|
* a page: its accounts, its tools, its settings.
|
|
48
48
|
*
|
|
49
49
|
* `appSegment` is navigation context only. It decides where Back goes: the
|
|
@@ -89,7 +89,10 @@ export function ConnectorPage({ projectId, appSegment, connectorSlug, }) {
|
|
|
89
89
|
isError: connectorsQuery.isError,
|
|
90
90
|
});
|
|
91
91
|
if (state === 'loading') {
|
|
92
|
-
return (
|
|
92
|
+
return (
|
|
93
|
+
// Grouped, in the loaded page's order: back link, name, the status card,
|
|
94
|
+
// the tab row, the tab body. One block per group, no line per field.
|
|
95
|
+
_jsxs(DetailPageShell, { busy: true, children: [_jsx(Skeleton, { className: "h-4 w-24 rounded-sm py-0" }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Skeleton, { className: "size-10 shrink-0 rounded-md py-0" }), _jsx(Skeleton, { className: "h-6 w-40 rounded-sm py-0" })] }), _jsx(Skeleton, { className: "h-36 w-full rounded-md py-0" }), _jsx(Skeleton, { className: "h-10 w-96 max-w-full rounded-lg py-0" }), _jsx(Skeleton, { className: "h-48 w-full rounded-md py-0" })] }));
|
|
93
96
|
}
|
|
94
97
|
if (state === 'error') {
|
|
95
98
|
return (_jsx(DetailPageShell, { children: _jsx(ErrorState, { size: "sm", title: tI18nComplete.raw('textbda9de7688c0'), description: connectorsQuery.error instanceof Error
|
|
@@ -118,7 +118,7 @@ export function ConnectorPolicySetBar({ projectId, slug, canWrite, value, onChan
|
|
|
118
118
|
const ruleTotal = selected ? selected.policies.length : (baseQuery.data?.policies.length ?? 0);
|
|
119
119
|
// Agents that can take this set: every agent not on it yet.
|
|
120
120
|
const giveTo = selected ? access.agents.filter((agent) => !agents.includes(agent)) : [];
|
|
121
|
-
return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("div", { className: "min-w-0 overflow-x-auto", children: _jsx(Tabs, { value: value ?? BASE_VALUE, onValueChange: (next) => onChange(next === BASE_VALUE ? null : next), children: _jsxs(TabsListCompact, { "aria-label": t('rulesFor'), children: [_jsx(TabsTriggerCompact, { value: BASE_VALUE, children: t('baseRules') }), sets.map((set) => (_jsxs(TabsTriggerCompact, { value: set.name, title: set.name, children: [policySetLabel(set.name), _jsxs("span", { className: "text-muted-foreground", children: [' · ', t('agentCount', { count: set.agents.length })] })] }, set.name)))] }) }) }), _jsxs(Button, { variant: "ghost", size: "sm", className: "shrink-0", onClick: () => setEditor({ mode: 'create' }), children: [_jsx(PlusIcon, { className: "size-3.5 shrink-0" }), t('createTitle')] })] }), _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-4 gap-y-1", children: [_jsxs("p", { className: "text-muted-foreground min-w-0 text-xs text-pretty", children: [selected ? (_jsxs(_Fragment, { children: [selected.description ? `${selected.description} · ` : null, agents.length > 0 ? (_jsxs(_Fragment, { children: [t('usedByLead'), ' ', agents.map((agent, index) => (_jsxs(Fragment, { children: [index > 0 ? ', ' : null, _jsx(Link, { href: `${agentHref(projectId, agent)}?section=connectors`, className: "text-foreground underline-offset-4 hover:underline", children: agent })] }, agent)))] })) : (_jsxs(_Fragment, { children: [t('unusedLead'), ' ', _jsx(Link, { href: capabilityTabHref(projectId, 'agent'), className: "text-foreground underline-offset-4 hover:underline", children: t('unusedLink') })] }))] })) : (t('baseContext')), ' · ', t('ruleCount', { count: ruleTotal })] }), selected ? (_jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [access.
|
|
121
|
+
return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx("div", { className: "min-w-0 overflow-x-auto", children: _jsx(Tabs, { value: value ?? BASE_VALUE, onValueChange: (next) => onChange(next === BASE_VALUE ? null : next), children: _jsxs(TabsListCompact, { "aria-label": t('rulesFor'), children: [_jsx(TabsTriggerCompact, { value: BASE_VALUE, children: t('baseRules') }), sets.map((set) => (_jsxs(TabsTriggerCompact, { value: set.name, title: set.name, children: [policySetLabel(set.name), _jsxs("span", { className: "text-muted-foreground", children: [' · ', t('agentCount', { count: set.agents.length })] })] }, set.name)))] }) }) }), _jsxs(Button, { variant: "ghost", size: "sm", className: "shrink-0", onClick: () => setEditor({ mode: 'create' }), children: [_jsx(PlusIcon, { className: "size-3.5 shrink-0" }), t('createTitle')] })] }), _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-4 gap-y-1", children: [_jsxs("p", { className: "text-muted-foreground min-w-0 text-xs text-pretty", children: [selected ? (_jsxs(_Fragment, { children: [selected.description ? `${selected.description} · ` : null, agents.length > 0 ? (_jsxs(_Fragment, { children: [t('usedByLead'), ' ', agents.map((agent, index) => (_jsxs(Fragment, { children: [index > 0 ? ', ' : null, _jsx(Link, { href: `${agentHref(projectId, agent)}?section=connectors`, className: "text-foreground underline-offset-4 hover:underline", children: agent })] }, agent)))] })) : (_jsxs(_Fragment, { children: [t('unusedLead'), ' ', _jsx(Link, { href: capabilityTabHref(projectId, 'agent'), className: "text-foreground underline-offset-4 hover:underline", children: t('unusedLink') })] }))] })) : (t('baseContext')), ' · ', t('ruleCount', { count: ruleTotal })] }), selected ? (_jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [access.canEdit && giveTo.length > 0 ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "xs", disabled: access.pending !== null, children: [t('giveToAgent'), _jsx(CaretDownIcon, { className: "size-3 shrink-0" })] }) }), _jsxs(DropdownMenuContent, { align: "end", className: "min-w-48", children: [_jsx(DropdownMenuLabel, { children: t('giveToAgentLabel', { name: policySetLabel(selected.name) }) }), giveTo.map((agent) => {
|
|
122
122
|
const current = agentConnectorAccess(access.grantsOf(agent), slug);
|
|
123
123
|
return (_jsxs(DropdownMenuItem, { onSelect: () => void access
|
|
124
124
|
.setPolicySet(agent, slug, selected.name, allSlugs)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { adminPath } from '../../../lib/routes.js';
|
|
4
4
|
import { useProjectTriggerEventApps, useProjectTriggers } from '@kortix/sdk/react';
|
|
5
5
|
import { PlusIcon } from '@phosphor-icons/react';
|
|
6
6
|
import { UiLink as Link } from '../../../providers/ui-provider.js';
|
|
@@ -53,5 +53,5 @@ export function ConnectorTriggers({ projectId, connector, displayName, }) {
|
|
|
53
53
|
return null;
|
|
54
54
|
return (_jsxs("section", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx(Label, { children: tI18nComplete.raw('textea56119b98e2') }), controls.canCreate ? (_jsxs(Button, { size: "sm", variant: "secondary", className: "gap-1.5", onClick: () => setCreating(true), children: [_jsx(PlusIcon, { className: "size-4 shrink-0" }), tI18nComplete.raw('text1ee2cf623464')] })) : null] }), isLoading ? (_jsx(Skeleton, { className: "h-14 rounded-md" })) : rows.length === 0 ? (_jsx("p", { className: "text-muted-foreground text-xs text-pretty", children: tI18nComplete('text974e43358191', {
|
|
55
55
|
name: displayName,
|
|
56
|
-
}) })) : (_jsx("ul", { className: "space-y-2", children: rows.map((trigger) => (_jsxs("li", { className: "bg-popover flex items-center gap-3 rounded-md border px-4 py-2", children: [_jsx(TriggerTile, { trigger: trigger, surface: "bg-popover" }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Link, { href:
|
|
56
|
+
}) })) : (_jsx("ul", { className: "space-y-2", children: rows.map((trigger) => (_jsxs("li", { className: "bg-popover flex items-center gap-3 rounded-md border px-4 py-2", children: [_jsx(TriggerTile, { trigger: trigger, surface: "bg-popover" }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Link, { href: adminPath(projectId, `triggers?id=${encodeURIComponent(trigger.slug)}`), className: "min-w-0 truncate text-sm font-medium hover:underline", children: triggerName(trigger) }), _jsx(TriggerStatusBadge, { trigger: trigger })] }), _jsx("span", { className: "text-muted-foreground block truncate text-xs", children: describeWhen(trigger, eventNames) }), trigger.event ? (_jsx("span", { className: "text-muted-foreground block truncate text-xs", children: describeEventSource(trigger.event, tI18nComplete, appIndex) })) : null] })] }, trigger.slug))) })), _jsx(TriggerComposer, { projectId: projectId, open: creating, onOpenChange: setCreating, onCreated: () => setCreating(false), initialKind: "event", initialConnector: { slug: connector.slug, name: displayName } })] }));
|
|
57
57
|
}
|