@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,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one scope contract every resource catalog takes, so a single component
|
|
3
|
+
* serves two surfaces (Marko, 2026-10-24):
|
|
4
|
+
*
|
|
5
|
+
* - **global** — the full project catalog, the Customize/Project-Admin tab.
|
|
6
|
+
* Every connector, skill, model the project has. No grant.
|
|
7
|
+
* - **agent** — the SAME catalog scoped to one agent on its config page. Each
|
|
8
|
+
* card carries a grant control; toggling it grants or revokes the resource
|
|
9
|
+
* for THIS agent by writing `agents.<name>.<set>` in kortix.yaml.
|
|
10
|
+
*
|
|
11
|
+
* A page reads `scope.kind` to pick its heading, and in `agent` scope reads the
|
|
12
|
+
* `AgentGrant` to draw and drive the per-card checkbox. One component, two
|
|
13
|
+
* variants — not two pages that drift.
|
|
14
|
+
*/
|
|
15
|
+
import type { AgentCapabilityGrant, AgentGrantSetV2 } from '@kortix/sdk';
|
|
16
|
+
/** Which surface a resource catalog renders for. */
|
|
17
|
+
export type ResourceScope = {
|
|
18
|
+
kind: 'global';
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'agent';
|
|
21
|
+
agentName: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* All · Specific · None, the agent's grant over one resource set. `all` and
|
|
25
|
+
* `none` decide every row; `specific` is the explicit pick list. `undefined`,
|
|
26
|
+
* `'none'` and `[]` all read as None.
|
|
27
|
+
*/
|
|
28
|
+
export type GrantMode = 'all' | 'specific' | 'none';
|
|
29
|
+
export interface AgentGrant {
|
|
30
|
+
/** The raw stored value (`agents.<name>.connectors` etc.). */
|
|
31
|
+
value: AgentGrantSetV2 | undefined;
|
|
32
|
+
mode: GrantMode;
|
|
33
|
+
/** Is `id` granted right now — true for every id in `all` mode. */
|
|
34
|
+
isGranted: (id: string) => boolean;
|
|
35
|
+
/** Add or remove one id from the pick list (only meaningful in `specific`). */
|
|
36
|
+
toggle: (id: string) => void;
|
|
37
|
+
setMode: (mode: GrantMode) => void;
|
|
38
|
+
/** Write the whole grant (a row switch under All keeps the rest: `plainGrantSwitch`). */
|
|
39
|
+
set?: (next: AgentGrantSetV2) => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Drives an {@link AgentGrant} off a draft value and its setter. Mirrors
|
|
43
|
+
* `GrantModeField`'s transitions, including the empty-pick nuance: switching to
|
|
44
|
+
* Specific with nothing picked stays Specific (not None) via a local intent
|
|
45
|
+
* flag, so the checklist is reachable before the first pick.
|
|
46
|
+
*/
|
|
47
|
+
export declare function useAgentGrant(value: AgentGrantSetV2 | undefined, onChange: (next: AgentGrantSetV2) => void): AgentGrant;
|
|
48
|
+
/**
|
|
49
|
+
* The grant over a known catalog: All → Specific keeps every id that is on
|
|
50
|
+
* (all of them), instead of an empty pick list that reads back as None.
|
|
51
|
+
*/
|
|
52
|
+
export declare function withCatalog(grant: AgentGrant, ids: readonly string[]): AgentGrant;
|
|
53
|
+
/**
|
|
54
|
+
* The ids a Specific grant names that the catalog no longer holds: a resource
|
|
55
|
+
* deleted or renamed after the grant was written. The agent page lists them
|
|
56
|
+
* beside the catalog with a Missing mark, so the editor can see each one and
|
|
57
|
+
* revoke it. All and None name no id, so they have none.
|
|
58
|
+
*/
|
|
59
|
+
export declare function grantOrphans(value: AgentGrantSetV2 | undefined, known: Iterable<string>): string[];
|
|
60
|
+
/**
|
|
61
|
+
* The agent's grant-mode selector, the catalog's primary control in `agent`
|
|
62
|
+
* scope: one All · Specific · None segmented control, then one muted line
|
|
63
|
+
* that says what the mode means, so the decision never reads as a list
|
|
64
|
+
* filter. It takes its own row: a catalog's list filters (All | Connected)
|
|
65
|
+
* sit with the list they filter, never beside it. `agentName` names the agent
|
|
66
|
+
* in the control's label outside an embedded resource screen.
|
|
67
|
+
*/
|
|
68
|
+
export declare function GrantModeTabs({ grant, label, agentName, }: {
|
|
69
|
+
grant: AgentGrant;
|
|
70
|
+
label: string;
|
|
71
|
+
agentName?: string;
|
|
72
|
+
}): import("react").JSX.Element;
|
|
73
|
+
/**
|
|
74
|
+
* A grant in the plain All · Specific · None form. `{ exclude }` exists only
|
|
75
|
+
* on skills and extensions, which the capability switches edit; a screen
|
|
76
|
+
* without switches reads it as All.
|
|
77
|
+
*/
|
|
78
|
+
export declare function plainGrant(value: AgentCapabilityGrant | undefined): AgentGrantSetV2 | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* One switch over a plain grant (connectors, secrets, Apps): All reads every
|
|
81
|
+
* row on, and turning one off under All keeps every other id, so the grant
|
|
82
|
+
* becomes Specific instead of losing the rest. The last one off is None.
|
|
83
|
+
*/
|
|
84
|
+
export declare function plainGrantSwitch(value: AgentGrantSetV2 | undefined, ids: readonly string[], onChange: (next: AgentGrantSetV2) => void): (id: string) => {
|
|
85
|
+
checked: boolean;
|
|
86
|
+
onCheckedChange: (on: boolean) => void;
|
|
87
|
+
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { useTranslations } from '../../i18n/index.js';
|
|
5
|
+
import { agentDisplayName } from '../../internal/components/agent-mark.js';
|
|
6
|
+
import { Tabs, TabsList, TabsTrigger } from '../../primitives/tabs.js';
|
|
7
|
+
import { useCapabilityShellEmbed } from './capability-page-shell.js';
|
|
8
|
+
/**
|
|
9
|
+
* Drives an {@link AgentGrant} off a draft value and its setter. Mirrors
|
|
10
|
+
* `GrantModeField`'s transitions, including the empty-pick nuance: switching to
|
|
11
|
+
* Specific with nothing picked stays Specific (not None) via a local intent
|
|
12
|
+
* flag, so the checklist is reachable before the first pick.
|
|
13
|
+
*/
|
|
14
|
+
export function useAgentGrant(value, onChange) {
|
|
15
|
+
const [wantSpecific, setWantSpecific] = useState(() => Array.isArray(value) && value.length > 0);
|
|
16
|
+
const mode = value === 'all'
|
|
17
|
+
? 'all'
|
|
18
|
+
: Array.isArray(value) && (value.length > 0 || wantSpecific)
|
|
19
|
+
? 'specific'
|
|
20
|
+
: 'none';
|
|
21
|
+
const selected = new Set(Array.isArray(value) ? value : []);
|
|
22
|
+
return {
|
|
23
|
+
value,
|
|
24
|
+
mode,
|
|
25
|
+
isGranted: (id) => (mode === 'all' ? true : selected.has(id)),
|
|
26
|
+
toggle: (id) => {
|
|
27
|
+
const next = new Set(selected);
|
|
28
|
+
if (next.has(id))
|
|
29
|
+
next.delete(id);
|
|
30
|
+
else
|
|
31
|
+
next.add(id);
|
|
32
|
+
onChange([...next]);
|
|
33
|
+
},
|
|
34
|
+
setMode: (next) => {
|
|
35
|
+
setWantSpecific(next === 'specific');
|
|
36
|
+
if (next === 'all')
|
|
37
|
+
return onChange('all');
|
|
38
|
+
if (next === 'none')
|
|
39
|
+
return onChange('none');
|
|
40
|
+
onChange(Array.isArray(value) ? value : []);
|
|
41
|
+
},
|
|
42
|
+
set: (next) => {
|
|
43
|
+
setWantSpecific(Array.isArray(next) && next.length > 0);
|
|
44
|
+
onChange(next);
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The grant over a known catalog: All → Specific keeps every id that is on
|
|
50
|
+
* (all of them), instead of an empty pick list that reads back as None.
|
|
51
|
+
*/
|
|
52
|
+
export function withCatalog(grant, ids) {
|
|
53
|
+
return {
|
|
54
|
+
...grant,
|
|
55
|
+
setMode: (next) => next === 'specific' && grant.value === 'all' && grant.set && ids.length > 0
|
|
56
|
+
? grant.set([...ids])
|
|
57
|
+
: grant.setMode(next),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The ids a Specific grant names that the catalog no longer holds: a resource
|
|
62
|
+
* deleted or renamed after the grant was written. The agent page lists them
|
|
63
|
+
* beside the catalog with a Missing mark, so the editor can see each one and
|
|
64
|
+
* revoke it. All and None name no id, so they have none.
|
|
65
|
+
*/
|
|
66
|
+
export function grantOrphans(value, known) {
|
|
67
|
+
if (!Array.isArray(value))
|
|
68
|
+
return [];
|
|
69
|
+
const have = new Set(known);
|
|
70
|
+
return value.filter((id) => !have.has(id));
|
|
71
|
+
}
|
|
72
|
+
const GRANT_MODE_TABS = [
|
|
73
|
+
{ value: 'all', labelKey: 'modeAll' },
|
|
74
|
+
{ value: 'specific', labelKey: 'modeSpecific' },
|
|
75
|
+
{ value: 'none', labelKey: 'modeNone' },
|
|
76
|
+
];
|
|
77
|
+
/**
|
|
78
|
+
* The agent's grant-mode selector, the catalog's primary control in `agent`
|
|
79
|
+
* scope: one All · Specific · None segmented control, then one muted line
|
|
80
|
+
* that says what the mode means, so the decision never reads as a list
|
|
81
|
+
* filter. It takes its own row: a catalog's list filters (All | Connected)
|
|
82
|
+
* sit with the list they filter, never beside it. `agentName` names the agent
|
|
83
|
+
* in the control's label outside an embedded resource screen.
|
|
84
|
+
*/
|
|
85
|
+
export function GrantModeTabs({ grant, label, agentName, }) {
|
|
86
|
+
const t = useTranslations('agentScope');
|
|
87
|
+
const tTabs = useTranslations('agentEditor.tabs');
|
|
88
|
+
const embed = useCapabilityShellEmbed();
|
|
89
|
+
const name = agentName ?? embed?.agentName;
|
|
90
|
+
const hint = grant.mode === 'all'
|
|
91
|
+
? tTabs('grantAllHint')
|
|
92
|
+
: grant.mode === 'specific'
|
|
93
|
+
? tTabs('grantSpecificHint')
|
|
94
|
+
: tTabs('grantNoneHint');
|
|
95
|
+
const control = (_jsx(Tabs, { value: grant.mode, onValueChange: (next) => grant.setMode(next), title: embed?.titled ? hint : undefined, children: _jsx(TabsList, { variant: "segmented", size: "sm", "aria-label": name ? `${tTabs('canUse', { name: agentDisplayName(name) })} ${label}` : label, children: GRANT_MODE_TABS.map((tab) => (_jsx(TabsTrigger, { value: tab.value, children: t(tab.labelKey) }, tab.value))) }) }));
|
|
96
|
+
// Beside the view's title (the rail layout): the control alone, its meaning on hover.
|
|
97
|
+
if (embed?.titled)
|
|
98
|
+
return control;
|
|
99
|
+
return (_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1", children: [control, _jsx("p", { className: "text-muted-foreground min-w-0 text-sm text-pretty", children: hint })] }));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* A grant in the plain All · Specific · None form. `{ exclude }` exists only
|
|
103
|
+
* on skills and extensions, which the capability switches edit; a screen
|
|
104
|
+
* without switches reads it as All.
|
|
105
|
+
*/
|
|
106
|
+
export function plainGrant(value) {
|
|
107
|
+
return value === undefined || typeof value === 'string' || Array.isArray(value) ? value : 'all';
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* One switch over a plain grant (connectors, secrets, Apps): All reads every
|
|
111
|
+
* row on, and turning one off under All keeps every other id, so the grant
|
|
112
|
+
* becomes Specific instead of losing the rest. The last one off is None.
|
|
113
|
+
*/
|
|
114
|
+
export function plainGrantSwitch(value, ids, onChange) {
|
|
115
|
+
const picked = value === 'all' ? [...ids] : Array.isArray(value) ? value : [];
|
|
116
|
+
return (id) => ({
|
|
117
|
+
checked: value === 'all' || picked.includes(id),
|
|
118
|
+
onCheckedChange: (on) => {
|
|
119
|
+
const next = on ? [...picked.filter((x) => x !== id), id] : picked.filter((x) => x !== id);
|
|
120
|
+
onChange(next.length > 0 ? next : 'none');
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills, Tools and Extensions: ONE component each, in two modes (Marko,
|
|
3
|
+
* 2026-10-27: "no double components, one component with either mode,
|
|
4
|
+
* agent-based or project-wide").
|
|
5
|
+
*
|
|
6
|
+
* - **Project** (Project admin): the project's catalog. The project's own
|
|
7
|
+
* items first, then what Kortix ships in a quiet fold. Skills adds New,
|
|
8
|
+
* each skill's files, and Remove.
|
|
9
|
+
* - **Agent** (the agent page's Access tab): the same list, plus the
|
|
10
|
+
* All · Specific · None row and one switch per row writing the agent's
|
|
11
|
+
* grant (`skills`, `tools`, `extensions`) into the page's draft. One item
|
|
12
|
+
* off under All is `{ exclude: [id] }`, never an expanded list.
|
|
13
|
+
*
|
|
14
|
+
* The catalog is the project's (`GET /projects/:id/capabilities`): the same
|
|
15
|
+
* list in both modes, so the two can never disagree.
|
|
16
|
+
*/
|
|
17
|
+
import { type AgentCapabilityGrant } from '@kortix/sdk';
|
|
18
|
+
import { type ReactNode } from 'react';
|
|
19
|
+
import type { AgentDraft } from '../sections/view/agent-editor.js';
|
|
20
|
+
import { type AgentGrant } from './agent-resource-scope.js';
|
|
21
|
+
export type CapabilityView = 'skills' | 'tools' | 'extensions';
|
|
22
|
+
/** Agent mode: whose grant the switches write, and the page's draft that holds it. */
|
|
23
|
+
export interface CapabilityAgent {
|
|
24
|
+
name: string;
|
|
25
|
+
editor: AgentDraft;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The All · Specific · None select over a capability grant. `{ exclude }`
|
|
29
|
+
* reads as All. Specific keeps every id that is on now, so a built-in row
|
|
30
|
+
* that was on stays on.
|
|
31
|
+
*/
|
|
32
|
+
export declare function capabilityModeGrant(value: AgentCapabilityGrant | undefined, ids: readonly string[], omitted: 'all' | 'none', onChange: (next: AgentCapabilityGrant) => void): AgentGrant;
|
|
33
|
+
/** Skills, Tools or Extensions, project-wide or for one agent. */
|
|
34
|
+
export declare function CapabilityLibrary({ projectId, view, agent, footer, }: {
|
|
35
|
+
projectId: string;
|
|
36
|
+
view: CapabilityView;
|
|
37
|
+
/** Absent: the project's catalog (Project admin). Present: this agent's grant over it. */
|
|
38
|
+
agent?: CapabilityAgent;
|
|
39
|
+
/** Below the list: Tools' approval rules on an agent's page. */
|
|
40
|
+
footer?: ReactNode;
|
|
41
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Skills, Tools and Extensions: ONE component each, in two modes (Marko,
|
|
5
|
+
* 2026-10-27: "no double components, one component with either mode,
|
|
6
|
+
* agent-based or project-wide").
|
|
7
|
+
*
|
|
8
|
+
* - **Project** (Project admin): the project's catalog. The project's own
|
|
9
|
+
* items first, then what Kortix ships in a quiet fold. Skills adds New,
|
|
10
|
+
* each skill's files, and Remove.
|
|
11
|
+
* - **Agent** (the agent page's Access tab): the same list, plus the
|
|
12
|
+
* All · Specific · None row and one switch per row writing the agent's
|
|
13
|
+
* grant (`skills`, `tools`, `extensions`) into the page's draft. One item
|
|
14
|
+
* off under All is `{ exclude: [id] }`, never an expanded list.
|
|
15
|
+
*
|
|
16
|
+
* The catalog is the project's (`GET /projects/:id/capabilities`): the same
|
|
17
|
+
* list in both modes, so the two can never disagree.
|
|
18
|
+
*/
|
|
19
|
+
import { capabilityGranted, getProjectDetail, setCapabilityGranted, } from '@kortix/sdk';
|
|
20
|
+
import { contract, qk, useProjectAccountId } from '@kortix/sdk/react';
|
|
21
|
+
import { MagnifyingGlassIcon } from '@phosphor-icons/react';
|
|
22
|
+
import { useQuery } from '@tanstack/react-query';
|
|
23
|
+
import { useMemo, useState } from 'react';
|
|
24
|
+
import { useTranslations as useI18nTranslations } from '../../i18n/index.js';
|
|
25
|
+
import { useProjectCapabilities } from '../../internal/hooks/projects/use-agent-config.js';
|
|
26
|
+
import { PROJECT_ACTIONS } from '../../internal/lib/project-actions.js';
|
|
27
|
+
import { useProjectCan } from '../../internal/lib/use-project-can.js';
|
|
28
|
+
import { adminPath } from '../../lib/routes.js';
|
|
29
|
+
import { Button } from '../../primitives/button.js';
|
|
30
|
+
import { ErrorState } from '../../primitives/error-state.js';
|
|
31
|
+
import { InputGroupSearch, InputGroupSearchClear, InputGroupSearchIcon, InputGroupSearchInput, } from '../../primitives/input-group.js';
|
|
32
|
+
import { Skeleton } from '../../primitives/skeleton.js';
|
|
33
|
+
import { UiLink as Link } from '../../providers/ui-provider.js';
|
|
34
|
+
import { Tabs, TabsList, TabsTrigger } from '../../primitives/tabs.js';
|
|
35
|
+
import { cn } from '../../internal/lib/utils.js';
|
|
36
|
+
import { BuiltinSkillModal } from '../skills/builtin-skill-modal.js';
|
|
37
|
+
import { CatalogCard } from './catalog/catalog-card.js';
|
|
38
|
+
import { GRID_CLASSNAME } from './catalog/catalog-grid-tokens.js';
|
|
39
|
+
import { AccessGroup, AccessList, BuiltinGroup } from './access-list.js';
|
|
40
|
+
import { EditorList } from '../sections/view/agent-editor-primitives.js';
|
|
41
|
+
import { NewSkillModal } from '../skills/new-skill-modal.js';
|
|
42
|
+
import { newConfigPrompt, useConfigureThread } from '../use-configure-thread.js';
|
|
43
|
+
import { GrantModeTabs } from './agent-resource-scope.js';
|
|
44
|
+
import { CapabilityPageShell, useCapabilityShellEmbed } from './capability-page-shell.js';
|
|
45
|
+
import { detailSelection } from './detail-selection.js';
|
|
46
|
+
import { EntityDetailModal } from './entity/entity-modal.js';
|
|
47
|
+
import { NewEntityMenu } from './new-entity-menu.js';
|
|
48
|
+
import { toolRule } from './tool-rules.js';
|
|
49
|
+
/** What an omitted grant means: every tool, no v3 skill or extension. */
|
|
50
|
+
const OMITTED = { tools: 'all', skills: 'none', extensions: 'none' };
|
|
51
|
+
/** Built-in tools in the order an agent reaches for them. */
|
|
52
|
+
const BUILTIN_TOOL_GROUPS = ['workspace', 'interaction', 'kortix'];
|
|
53
|
+
/**
|
|
54
|
+
* The All · Specific · None select over a capability grant. `{ exclude }`
|
|
55
|
+
* reads as All. Specific keeps every id that is on now, so a built-in row
|
|
56
|
+
* that was on stays on.
|
|
57
|
+
*/
|
|
58
|
+
export function capabilityModeGrant(value, ids, omitted, onChange) {
|
|
59
|
+
const current = value ?? omitted;
|
|
60
|
+
const mode = Array.isArray(current) ? (current.length > 0 ? 'specific' : 'none') : current === 'none' ? 'none' : 'all';
|
|
61
|
+
return {
|
|
62
|
+
value: Array.isArray(current) || typeof current === 'string' ? current : 'all',
|
|
63
|
+
mode,
|
|
64
|
+
isGranted: (id) => capabilityGranted(value, id, omitted),
|
|
65
|
+
toggle: (id) => onChange(setCapabilityGranted(value, id, !capabilityGranted(value, id, omitted), omitted)),
|
|
66
|
+
setMode: (next) => {
|
|
67
|
+
if (next === 'all')
|
|
68
|
+
return onChange('all');
|
|
69
|
+
if (next === 'none')
|
|
70
|
+
return onChange('none');
|
|
71
|
+
const on = ids.filter((id) => capabilityGranted(value, id, omitted));
|
|
72
|
+
onChange(on.length > 0 ? on : 'none');
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/** One row per catalog item, in the order the view draws them: the project's, then Kortix's. */
|
|
77
|
+
function catalogRows(view, catalog, t, agentMode) {
|
|
78
|
+
if (view === 'skills') {
|
|
79
|
+
const item = (skill) => ({ id: skill.id, description: skill.description, disabled: !skill.available });
|
|
80
|
+
return {
|
|
81
|
+
project: catalog.skills.filter((s) => s.group === 'project').map(item),
|
|
82
|
+
builtin: catalog.skills.filter((s) => s.group === 'builtin').map(item),
|
|
83
|
+
// Specific names only skills a session can load: a flagged skill whose flag is off is not one.
|
|
84
|
+
ids: catalog.skills.filter((s) => s.available).map((s) => s.id),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (view === 'tools') {
|
|
88
|
+
const item = (tool) => ({
|
|
89
|
+
id: tool.id,
|
|
90
|
+
description: tool.group === 'project'
|
|
91
|
+
? t('projectTool', { path: tool.source ?? '' })
|
|
92
|
+
: tool.source
|
|
93
|
+
? `${tool.description ?? ''} ${t('replacedBy', { path: tool.source })}`
|
|
94
|
+
: tool.description,
|
|
95
|
+
});
|
|
96
|
+
return {
|
|
97
|
+
project: catalog.tools.filter((tool) => tool.group === 'project').map(item),
|
|
98
|
+
builtin: BUILTIN_TOOL_GROUPS.flatMap((group) => catalog.tools.filter((tool) => tool.group === group).map(item)),
|
|
99
|
+
ids: catalog.tools.map((tool) => tool.id),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const item = (ext) => ({
|
|
103
|
+
id: ext.id,
|
|
104
|
+
// "Follows the agent tool switch" only where that switch is on screen.
|
|
105
|
+
description: ext.controlled_by && agentMode ? `${ext.description ?? ''} ${t('followsTool', { tool: ext.controlled_by })}` : ext.description,
|
|
106
|
+
status: ext.required ? _jsx("span", { className: "text-muted-foreground text-xs", children: t('alwaysOn') }) : undefined,
|
|
107
|
+
});
|
|
108
|
+
// A required platform extension (permission rules on script calls, the show
|
|
109
|
+
// tool's part, the turn's date) is plumbing, not a choice: it is not listed.
|
|
110
|
+
return {
|
|
111
|
+
project: catalog.extensions.filter((ext) => ext.group === 'project').map(item),
|
|
112
|
+
builtin: catalog.extensions.filter((ext) => ext.group === 'platform' && !ext.required).map(item),
|
|
113
|
+
ids: catalog.extensions.filter((ext) => ext.group === 'project').map((ext) => ext.id),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Agent mode: give each row its switch. A tool switch carries its aliases,
|
|
118
|
+
* and codemode also clears `codemode: off`. A platform extension follows its
|
|
119
|
+
* tool's switch; a required one has none.
|
|
120
|
+
*/
|
|
121
|
+
function withSwitches(view, rows, catalog, editor) {
|
|
122
|
+
const toolSwitch = (id, aliases) => {
|
|
123
|
+
const value = editor.draft.tools;
|
|
124
|
+
const codemodeOff = id === 'codemode' && editor.draft.codemode === 'off';
|
|
125
|
+
return {
|
|
126
|
+
checked: !codemodeOff && capabilityGranted(value, id, OMITTED.tools),
|
|
127
|
+
onCheckedChange: (on) => {
|
|
128
|
+
editor.set('tools', setCapabilityGranted(value, [id, ...aliases], on, OMITTED.tools));
|
|
129
|
+
if (on && codemodeOff)
|
|
130
|
+
editor.set('codemode', undefined);
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
return rows.map((row) => {
|
|
135
|
+
if (view === 'tools') {
|
|
136
|
+
const tool = catalog.tools.find((x) => x.id === row.id);
|
|
137
|
+
return { ...row, ...toolSwitch(row.id, tool?.aliases ?? []) };
|
|
138
|
+
}
|
|
139
|
+
if (view === 'extensions') {
|
|
140
|
+
const ext = catalog.extensions.find((x) => x.id === row.id);
|
|
141
|
+
if (!ext || ext.required)
|
|
142
|
+
return row;
|
|
143
|
+
if (ext.group === 'platform') {
|
|
144
|
+
const tool = catalog.tools.find((x) => x.id === ext.controlled_by);
|
|
145
|
+
return tool ? { ...row, ...toolSwitch(tool.id, tool.aliases) } : row;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const key = view === 'skills' ? 'skills' : 'extensions';
|
|
149
|
+
const value = editor.draft[key];
|
|
150
|
+
return {
|
|
151
|
+
...row,
|
|
152
|
+
checked: !row.disabled && capabilityGranted(value, row.id, OMITTED[view]),
|
|
153
|
+
onCheckedChange: (on) => editor.set(key, setCapabilityGranted(value, row.id, on, OMITTED[view])),
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const VIEW_COPY = {
|
|
158
|
+
skills: { titleKey: 'skillsTitle', access: 'skillsAccess' },
|
|
159
|
+
tools: { titleKey: 'toolsTitle', access: 'toolsAccess' },
|
|
160
|
+
extensions: { titleKey: 'extensionsTitle', access: 'extensionsAccess' },
|
|
161
|
+
};
|
|
162
|
+
/** Skills, Tools or Extensions, project-wide or for one agent. */
|
|
163
|
+
export function CapabilityLibrary({ projectId, view, agent, footer, }) {
|
|
164
|
+
const t = useI18nTranslations('agentCapabilities');
|
|
165
|
+
const tTabs = useI18nTranslations('agentEditor.tabs');
|
|
166
|
+
const embed = useCapabilityShellEmbed();
|
|
167
|
+
const query = useProjectCapabilities(projectId);
|
|
168
|
+
const catalog = query.data;
|
|
169
|
+
const [search, setSearch] = useState('');
|
|
170
|
+
// Project admin's filter: the project's own items, Kortix's built-in ones, or both.
|
|
171
|
+
const [scope, setScope] = useState('all');
|
|
172
|
+
// A built-in skill's card opens it here (it is not a file in the project).
|
|
173
|
+
const [builtinSkill, setBuiltinSkill] = useState(null);
|
|
174
|
+
const skills = useSkillManagement(projectId, view === 'skills');
|
|
175
|
+
const rows = useMemo(() => (catalog ? catalogRows(view, catalog, t, !!agent) : null), [catalog, view, t, agent]);
|
|
176
|
+
const match = (row) => {
|
|
177
|
+
const q = search.trim().toLowerCase();
|
|
178
|
+
return !q || row.id.toLowerCase().includes(q) || String(row.description ?? '').toLowerCase().includes(q);
|
|
179
|
+
};
|
|
180
|
+
let project = rows?.project.filter(match) ?? [];
|
|
181
|
+
let builtin = rows?.builtin.filter(match) ?? [];
|
|
182
|
+
if (view === 'skills') {
|
|
183
|
+
// A flagged built-in skill whose flag is off says so, with the way to turn it on.
|
|
184
|
+
builtin = builtin.map((row) => row.disabled
|
|
185
|
+
? {
|
|
186
|
+
...row,
|
|
187
|
+
description: (_jsxs(_Fragment, { children: [t('flagOff'), ' ', _jsx(Link, { href: adminPath(projectId, 'feature-flags'), className: "text-foreground underline underline-offset-2", children: t('flagSettings') })] })),
|
|
188
|
+
}
|
|
189
|
+
: row);
|
|
190
|
+
project = project.map((row) => ({ ...row, onOpen: skills.open(row.id) }));
|
|
191
|
+
}
|
|
192
|
+
if (agent && catalog) {
|
|
193
|
+
project = withSwitches(view, project, catalog, agent.editor);
|
|
194
|
+
builtin = withSwitches(view, builtin, catalog, agent.editor);
|
|
195
|
+
}
|
|
196
|
+
const grant = agent && rows && (view !== 'extensions' || rows.project.length > 0)
|
|
197
|
+
? capabilityModeGrant(agent.editor.draft[view], rows.ids, OMITTED[view], (next) => agent.editor.set(view, next))
|
|
198
|
+
: null;
|
|
199
|
+
const empty = view === 'skills' ? t('emptyProjectSkills') : view === 'tools' ? t('emptyProjectTools') : t('emptyProjectExtensions');
|
|
200
|
+
// The agent page's rail layout: one card of every row, the project's first;
|
|
201
|
+
// each tool carries its approval rule, an off one a dash.
|
|
202
|
+
const railCard = !!agent && !!embed?.titled;
|
|
203
|
+
const ruleLabel = (rule) => rule === 'allow' ? tTabs('ruleAllow') : rule === 'ask' ? tTabs('ruleAsk') : rule === 'deny' ? tTabs('ruleDeny') : rule === 'custom' ? tTabs('ruleCustom') : '';
|
|
204
|
+
const cardRows = railCard
|
|
205
|
+
? [...project, ...builtin].map((row) => view === 'tools' && agent
|
|
206
|
+
? { ...row, control: row.checked ? ruleLabel(toolRule(agent.editor.oc.permission, row.id)) : '—' }
|
|
207
|
+
: row)
|
|
208
|
+
: [];
|
|
209
|
+
// The agent's own view: the project's items, then Kortix's, folded.
|
|
210
|
+
const agentSections = (_jsxs(_Fragment, { children: [_jsx(AccessGroup, { title: t('groups.project'), items: project, empty: search ? t('noMatch') : empty }), _jsx(BuiltinGroup, { items: builtin, defaultOpen: project.length === 0 || !!search.trim() })] }));
|
|
211
|
+
// Project admin. Skills: the All / Project / Kortix filter, Kortix's skills as cards.
|
|
212
|
+
// Tools and Extensions: no filter; the project's own group only when it has
|
|
213
|
+
// items, then the built-ins under the API's real groups.
|
|
214
|
+
let projectSections;
|
|
215
|
+
if (view === 'skills') {
|
|
216
|
+
projectSections = (_jsxs(_Fragment, { children: [scope !== 'kortix' ? (_jsx(AccessGroup, { title: t('groups.project'), items: project, empty: search ? t('noMatch') : empty })) : null, scope !== 'project' ? (_jsxs("section", { className: "space-y-3", children: [_jsx("h3", { className: "text-foreground text-sm font-medium", children: t('groups.kortix') }), builtin.length > 0 ? (_jsx("div", { className: GRID_CLASSNAME, children: builtin.map((row) => (_jsx(CatalogCard, { title: _jsx("span", { className: "font-mono !tracking-normal", children: row.id }), description: row.disabled ? t('flagOff') : typeof row.description === 'string' ? row.description : undefined, className: cn(row.disabled && 'opacity-60'), onClick: () => setBuiltinSkill(row.id) }, row.id))) })) : (_jsx("p", { className: "text-muted-foreground text-sm text-pretty", children: t('noMatch') }))] })) : null] }));
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
const builtinGroups = view === 'tools'
|
|
220
|
+
? BUILTIN_TOOL_GROUPS.map((group) => ({
|
|
221
|
+
group,
|
|
222
|
+
items: builtin.filter((row) => catalog?.tools.find((tool) => tool.id === row.id)?.group === group),
|
|
223
|
+
}))
|
|
224
|
+
: [{ group: 'platform', items: builtin }];
|
|
225
|
+
const shown = builtinGroups.filter((g) => g.items.length > 0);
|
|
226
|
+
projectSections = (_jsxs(_Fragment, { children: [project.length > 0 ? _jsx(AccessGroup, { title: t('groups.project'), items: project }) : null, shown.map((g) => (_jsx(AccessGroup, { title: t(`groups.${g.group}`), items: g.items }, g.group))), project.length === 0 && shown.length === 0 ? (_jsx("p", { className: "text-muted-foreground text-sm text-pretty", children: search ? t('noMatch') : empty })) : null] }));
|
|
227
|
+
}
|
|
228
|
+
const body = catalog && railCard ? (_jsx("div", { "data-testid": `capability-library-${view}`, "data-grant": JSON.stringify(agent?.editor.draft[view] ?? null), children: cardRows.length > 0 ? (_jsx(AccessList, { items: cardRows })) : (_jsx("p", { className: "text-muted-foreground text-sm text-pretty", children: search ? t('noMatch') : empty })) })) : catalog ? (_jsx("div", { className: "space-y-6", "data-testid": `capability-library-${view}`, "data-grant": agent ? JSON.stringify(agent.editor.draft[view] ?? null) : undefined, children: agent ? agentSections : projectSections })) : query.isError ? (_jsx(ErrorState, { size: "sm", title: t('loadError'), action: _jsx(Button, { variant: "outline", size: "sm", onClick: () => void query.refetch(), children: t('retry') }) })) : (_jsx(EditorList, { children: [0, 1, 2, 3].map((i) => (_jsx("li", { className: "flex min-h-12 items-center gap-3 px-4 py-2", children: _jsx(Skeleton, { className: "h-4 w-40 rounded-sm" }) }, i))) }));
|
|
229
|
+
return (_jsxs(CapabilityPageShell, { title: t(VIEW_COPY[view].titleKey), description: agent ? t(`${view}Description`) : t(`${view}ProjectDescription`), action: skills.createButton, search: _jsxs(InputGroupSearch, { children: [_jsx(InputGroupSearchIcon, { children: _jsx(MagnifyingGlassIcon, {}) }), _jsx(InputGroupSearchInput, { placeholder: t(`${view}Search`), value: search, onChange: (event) => setSearch(event.target.value), size: "sm" }), search ? _jsx(InputGroupSearchClear, { onClick: () => setSearch('') }) : null] }), filters: agent ? (grant ? _jsx(GrantModeTabs, { grant: grant, label: t(VIEW_COPY[view].access), agentName: agent.name }) : undefined) : view !== 'skills' ? undefined : (_jsx(Tabs, { value: scope, onValueChange: (next) => setScope(next), children: _jsxs(TabsList, { "aria-label": t(VIEW_COPY[view].titleKey), children: [_jsx(TabsTrigger, { value: "all", children: t('scopeAll') }), _jsx(TabsTrigger, { value: "project", children: t('groups.project') }), _jsx(TabsTrigger, { value: "kortix", children: t('groups.kortix') })] }) })), children: [body, footer, skills.modals, view === 'skills' && !agent ? (_jsx(BuiltinSkillModal, { projectId: projectId, name: builtinSkill, description: (() => {
|
|
230
|
+
const d = rows?.builtin.find((row) => row.id === builtinSkill)?.description;
|
|
231
|
+
return typeof d === 'string' ? d : null;
|
|
232
|
+
})(), onOpenChange: (open) => !open && setBuiltinSkill(null) })) : null] }));
|
|
233
|
+
}
|
|
234
|
+
/** Skills' own controls, in both modes: New (chat or form), each skill's files, Remove. */
|
|
235
|
+
function useSkillManagement(projectId, on) {
|
|
236
|
+
const tI18nComplete = useI18nTranslations('hardcodedUi.i18nComplete');
|
|
237
|
+
const accountId = useProjectAccountId(projectId);
|
|
238
|
+
const canWrite = useProjectCan(projectId, PROJECT_ACTIONS.PROJECT_SKILL_WRITE, { accountId }).allowed === true;
|
|
239
|
+
const configure = useConfigureThread(projectId);
|
|
240
|
+
const [selectedName, setSelectedName] = useState(null);
|
|
241
|
+
const [formOpen, setFormOpen] = useState(false);
|
|
242
|
+
const detailQuery = useQuery({
|
|
243
|
+
queryKey: qk.project.detail(projectId),
|
|
244
|
+
queryFn: () => getProjectDetail(projectId),
|
|
245
|
+
enabled: on,
|
|
246
|
+
...contract('config'),
|
|
247
|
+
});
|
|
248
|
+
const skills = detailQuery.data?.config.skills ?? [];
|
|
249
|
+
const detail = detailSelection({
|
|
250
|
+
selection: selectedName,
|
|
251
|
+
record: skills.find((skill) => skill.name === selectedName),
|
|
252
|
+
isSuccess: detailQuery.isSuccess,
|
|
253
|
+
});
|
|
254
|
+
// The config came back without this skill: it really was removed or renamed.
|
|
255
|
+
if (detail.isMissing)
|
|
256
|
+
setSelectedName(null);
|
|
257
|
+
if (!on)
|
|
258
|
+
return { createButton: undefined, modals: null, open: () => undefined };
|
|
259
|
+
return {
|
|
260
|
+
open: (name) => () => setSelectedName(name),
|
|
261
|
+
createButton: canWrite ? (_jsx(NewEntityMenu, { label: tI18nComplete('text18fdd549b2ed'), pending: configure.pending, onChat: () => configure.start(newConfigPrompt('skill')), manual: {
|
|
262
|
+
label: tI18nComplete.raw('texta38668224f1a'),
|
|
263
|
+
description: tI18nComplete.raw('textedac6130dac7'),
|
|
264
|
+
onSelect: () => setFormOpen(true),
|
|
265
|
+
} })) : undefined,
|
|
266
|
+
modals: (_jsxs(_Fragment, { children: [_jsx(EntityDetailModal, { projectId: projectId, entity: detail.record, kind: "skill", removable: true, open: detail.open, isResolving: detail.isResolving, onOpenChange: (next) => {
|
|
267
|
+
if (!next)
|
|
268
|
+
setSelectedName(null);
|
|
269
|
+
} }), _jsx(NewSkillModal, { projectId: projectId, open: formOpen, onOpenChange: setFormOpen })] })),
|
|
270
|
+
};
|
|
271
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
2
|
interface CapabilityPageShellProps {
|
|
3
3
|
title: string;
|
|
4
4
|
/** One line. Longer explanations go in `titleAddon` (an info hover card). */
|
|
@@ -23,6 +23,23 @@ interface CapabilityPageShellProps {
|
|
|
23
23
|
stacked?: boolean;
|
|
24
24
|
children: ReactNode;
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Set by the agent page around a resource screen it shows in agent scope
|
|
28
|
+
* (Access > Connectors, Runtime > Model, Triggers). The shell then drops its
|
|
29
|
+
* own title (the agent page's tabs name the view), runs full width on the
|
|
30
|
+
* agent page's gutter, and draws `lead` (the Access view switcher) as the
|
|
31
|
+
* first row inside its scroller, so the switcher scrolls with the content.
|
|
32
|
+
*/
|
|
33
|
+
export interface CapabilityShellEmbed {
|
|
34
|
+
agentName: string;
|
|
35
|
+
lead?: ReactNode;
|
|
36
|
+
/** The column class, so every Access and Runtime view shares one width. */
|
|
37
|
+
className?: string;
|
|
38
|
+
/** Show the screen's title over its description: the view sits beside a rail that does not name it. */
|
|
39
|
+
titled?: boolean;
|
|
40
|
+
}
|
|
41
|
+
export declare const CapabilityShellEmbedProvider: import("react").Provider<CapabilityShellEmbed | null>;
|
|
42
|
+
export declare function useCapabilityShellEmbed(): CapabilityShellEmbed | null;
|
|
26
43
|
/**
|
|
27
44
|
* Shared page shell for the three capability routes (agents, connectors,
|
|
28
45
|
* skills). `max-w-5xl` is a deliberate departure from
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { SidebarToggle } from '../../internal/layout/sidebar-toggle.js';
|
|
4
|
+
import { useInCustomizeFrame } from './customize-tab-bar.js';
|
|
3
5
|
import { cn } from '../../internal/lib/utils.js';
|
|
6
|
+
import { createContext, useContext } from 'react';
|
|
7
|
+
import { SettingsSectionHeader } from '../../primitives/settings-section-header.js';
|
|
4
8
|
import { CapabilityScrollRootProvider, useCapabilityScrollRootRef } from './capability-scroll-root.js';
|
|
9
|
+
const CapabilityShellEmbedContext = createContext(null);
|
|
10
|
+
export const CapabilityShellEmbedProvider = CapabilityShellEmbedContext.Provider;
|
|
11
|
+
export function useCapabilityShellEmbed() {
|
|
12
|
+
return useContext(CapabilityShellEmbedContext);
|
|
13
|
+
}
|
|
5
14
|
/**
|
|
6
15
|
* Shared page shell for the three capability routes (agents, connectors,
|
|
7
16
|
* skills). `max-w-5xl` is a deliberate departure from
|
|
@@ -20,7 +29,18 @@ import { CapabilityScrollRootProvider, useCapabilityScrollRootRef } from './capa
|
|
|
20
29
|
*/
|
|
21
30
|
export function CapabilityPageShell({ title, description, titleAddon, action, search, filters, wide = false, stacked = false, children, }) {
|
|
22
31
|
const scrollRef = useCapabilityScrollRootRef();
|
|
32
|
+
const embed = useCapabilityShellEmbed();
|
|
33
|
+
const framed = useInCustomizeFrame();
|
|
34
|
+
if (embed?.titled) {
|
|
35
|
+
// Beside the agent page's rail: the view's title left (no sentence under
|
|
36
|
+
// it, the Settings dialect), its grant control (`filters`) right; search
|
|
37
|
+
// and the view's own action in one row under them.
|
|
38
|
+
return (_jsx("div", { ref: scrollRef, className: "min-h-0 flex-1 overflow-y-auto", "data-capability-embed": "", children: _jsxs("div", { className: cn('w-full space-y-5 px-4 pt-5 pb-24 md:px-8', embed.className), children: [embed.lead, _jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-end md:justify-between", children: [_jsx(SettingsSectionHeader, { title: title, className: "min-w-0" }), filters ? _jsx("div", { className: "shrink-0", children: filters }) : null] }), search || action ? (_jsxs("div", { className: "flex items-center gap-2", children: [search ? _jsx("div", { className: "min-w-0 flex-1", children: search }) : null, action] })) : null, _jsx(CapabilityScrollRootProvider, { scrollRef: scrollRef, children: children })] }) }));
|
|
39
|
+
}
|
|
40
|
+
if (embed) {
|
|
41
|
+
return (_jsx("div", { ref: scrollRef, className: "min-h-0 flex-1 overflow-y-auto", "data-capability-embed": "", children: _jsxs("div", { className: cn('w-full space-y-5 px-4 pt-5 pb-24 md:px-8', embed.className), children: [embed.lead, _jsxs("header", { className: cn('flex flex-col gap-3', !stacked && 'md:flex-row md:items-center md:justify-between'), children: [_jsx("h2", { className: "sr-only", children: title }), _jsx("p", { className: "text-muted-foreground min-w-0 text-sm text-pretty md:max-w-xl", children: description }), search || action ? (_jsxs("div", { className: cn('flex w-full shrink-0 items-center gap-2', !stacked && 'md:w-auto'), children: [search ? _jsx("div", { className: cn('min-w-0 flex-1', !stacked && 'md:w-64 md:flex-none'), children: search }) : null, action] })) : null] }), filters ? _jsx("div", { className: "flex flex-wrap items-center justify-between gap-2", children: filters }) : null, _jsx(CapabilityScrollRootProvider, { scrollRef: scrollRef, children: children })] }) }));
|
|
42
|
+
}
|
|
23
43
|
return (_jsx("div", { ref: scrollRef, className: "min-h-0 flex-1 overflow-y-auto", children: _jsxs("div", { className: wide
|
|
24
44
|
? 'mx-auto w-full max-w-7xl space-y-5 px-4 py-10 pb-20 md:px-8 lg:py-14'
|
|
25
|
-
: 'mx-auto w-full max-w-5xl space-y-5 px-4 py-10 pb-20 lg:py-14', children: [_jsxs("header", { className: cn('flex flex-col gap-3', !stacked && 'sm:flex-row sm:items-start sm:justify-between'), children: [_jsxs("div", { className: "space-y-1 sm:max-w-md", children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("h1", { className: "text-foreground text-xl font-medium text-balance", children: title }), titleAddon] }), _jsx("p", { className: "text-muted-foreground text-sm text-balance", children: description })] }), search || action ? (_jsxs("div", { className: cn('flex w-full shrink-0 items-center gap-2', !stacked && 'sm:w-auto'), children: [search ? (_jsx("div", { className: cn('min-w-0 flex-1', !stacked && 'sm:w-64 sm:flex-none'), children: search })) : null, action] })) : null] }), filters ? (_jsx("div", { className: "flex flex-wrap items-center justify-between gap-2", children: filters })) : null, _jsx(CapabilityScrollRootProvider, { scrollRef: scrollRef, children: children })] }) }));
|
|
45
|
+
: 'mx-auto w-full max-w-5xl space-y-5 px-4 py-10 pb-20 lg:py-14', children: [_jsxs("header", { className: cn('flex flex-col gap-3', !stacked && 'sm:flex-row sm:items-start sm:justify-between'), children: [_jsxs("div", { className: "space-y-1 sm:max-w-md", children: [_jsxs("div", { className: "flex items-center gap-1", children: [framed ? null : _jsx(SidebarToggle, { className: "-ml-2" }), _jsx("h1", { className: "text-foreground text-xl font-medium text-balance", children: title }), titleAddon] }), _jsx("p", { className: "text-muted-foreground text-sm text-balance", children: description })] }), search || action ? (_jsxs("div", { className: cn('flex w-full shrink-0 items-center gap-2', !stacked && 'sm:w-auto'), children: [search ? (_jsx("div", { className: cn('min-w-0 flex-1', !stacked && 'sm:w-64 sm:flex-none'), children: search })) : null, action] })) : null] }), filters ? (_jsx("div", { className: "flex flex-wrap items-center justify-between gap-2", children: filters })) : null, _jsx(CapabilityScrollRootProvider, { scrollRef: scrollRef, children: children })] }) }));
|
|
26
46
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SpaceGroup } from '@kortix/sdk';
|
|
2
|
+
/** The sentinel filter value that shows every space (grouped). */
|
|
3
|
+
export declare const ALL_SPACES = "all";
|
|
4
|
+
/**
|
|
5
|
+
* A compact segmented filter over a project's spaces: `All` plus one chip per
|
|
6
|
+
* space, each with its count. Selecting a space scopes the catalog to it;
|
|
7
|
+
* `All` shows the grouped sections. Pairs with `groupBySpace` + the catalog
|
|
8
|
+
* views. Renders nothing when there is only the Project-wide bucket.
|
|
9
|
+
*/
|
|
10
|
+
export declare function CatalogSpaceTabs<T>({ groups, value, onValueChange, }: {
|
|
11
|
+
groups: Array<SpaceGroup<T>>;
|
|
12
|
+
value: string;
|
|
13
|
+
onValueChange: (value: string) => void;
|
|
14
|
+
}): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslations } from '../../../i18n/index.js';
|
|
3
|
+
import { CountBadge } from '../../../primitives/count-badge.js';
|
|
4
|
+
import { Tabs, TabsListCompact, TabsTriggerCompact } from '../../../primitives/tabs.js';
|
|
5
|
+
/** The sentinel filter value that shows every space (grouped). */
|
|
6
|
+
export const ALL_SPACES = 'all';
|
|
7
|
+
/**
|
|
8
|
+
* A compact segmented filter over a project's spaces: `All` plus one chip per
|
|
9
|
+
* space, each with its count. Selecting a space scopes the catalog to it;
|
|
10
|
+
* `All` shows the grouped sections. Pairs with `groupBySpace` + the catalog
|
|
11
|
+
* views. Renders nothing when there is only the Project-wide bucket.
|
|
12
|
+
*/
|
|
13
|
+
export function CatalogSpaceTabs({ groups, value, onValueChange, }) {
|
|
14
|
+
const t = useTranslations('spaces');
|
|
15
|
+
// Only worth a filter when the project actually splits into spaces.
|
|
16
|
+
const hasRealSplit = groups.some((g) => !g.isDefault);
|
|
17
|
+
if (!hasRealSplit)
|
|
18
|
+
return null;
|
|
19
|
+
return (_jsx(Tabs, { value: value, onValueChange: onValueChange, children: _jsxs(TabsListCompact, { "aria-label": t('filter'), children: [_jsx(TabsTriggerCompact, { value: ALL_SPACES, children: t('all') }), groups.map((group) => (_jsxs(TabsTriggerCompact, { value: group.name, children: [group.label, _jsx(CountBadge, { count: group.items.length, tone: "neutral" })] }, group.name)))] }) }));
|
|
20
|
+
}
|