@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
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { sessionIdFromPath, uiRoutes } from '../../lib/routes.js';
|
|
4
4
|
import { useTranslations } from '../../i18n/index.js';
|
|
5
5
|
import { HoverPrefetchLink } from '../../internal/components/hover-prefetch-link.js';
|
|
6
|
-
import {
|
|
6
|
+
import { matchesSourceFilters, matchesStatusFilters, sessionCanBeStopped, sessionDisplayStatus, sessionIsShared, sessionSource, } from '../../session/actions/session-label.js';
|
|
7
7
|
import { SessionSharedIcon } from '../projects/session-shared-icon.js';
|
|
8
8
|
import { Button } from '../../primitives/button.js';
|
|
9
9
|
import { CountBadge } from '../../primitives/count-badge.js';
|
|
@@ -23,6 +23,7 @@ import { SessionStarterMark, useSessionStarter, } from '../sessions/session-star
|
|
|
23
23
|
import { SessionsEmptyState } from '../sessions/sessions-empty-state.js';
|
|
24
24
|
import { RenameSessionModal } from './modal/rename-session-modal.js';
|
|
25
25
|
import { SessionDeleteModal } from '../../session/actions/session-delete-modal.js';
|
|
26
|
+
import { subagentTitle } from '../../session/agents/agent-model.js';
|
|
26
27
|
import { SessionLabelsModal } from './modal/session-labels-modal.js';
|
|
27
28
|
import { ShareSessionModal } from './modal/share-session-modal.js';
|
|
28
29
|
import { getSessionDisplayTitle, groupChangeRequestsBySession, projectSessionsRefetchInterval, resolveSessionListViewState, shortRelative, starterSectionOf, } from '../../session/actions/project-session-list-helpers.js';
|
|
@@ -42,11 +43,11 @@ import { selectCollapsedSections, selectGroupMode, selectHiddenSections, selectL
|
|
|
42
43
|
import { shouldBeginSessionSwitch, useSessionSwitchStore } from '../../internal/stores/session-switch-store.js';
|
|
43
44
|
import { directSubsessions, createProjectSession, listChangeRequests, restartProjectSession, sessionParentId, stopProjectSession, } from '@kortix/sdk';
|
|
44
45
|
import { qk, useProjectSession, useProjectSessions, useRuntimeSupports, useSessionChildren, useFeatureFlag, useProjectSessionGroups, useSessionGoal, } from '@kortix/sdk/react';
|
|
45
|
-
import { ArchiveIcon, ArrowsSplitIcon, CaretRightIcon, CheckIcon, DotsThreeIcon, FolderSimpleIcon, FolderSimpleMinusIcon, FolderSimplePlusIcon, PushPinIcon, PushPinSlashIcon, RobotIcon, GitForkIcon, PencilSimpleIcon, ArrowCounterClockwiseIcon as RotateCcw, ShareIcon as Share,
|
|
46
|
+
import { ArchiveIcon, ArrowsSplitIcon, CaretRightIcon, CheckIcon, DotsThreeIcon, FolderSimpleIcon, FolderSimpleMinusIcon, FolderSimplePlusIcon, PushPinIcon, PushPinSlashIcon, RobotIcon, GitForkIcon, PencilSimpleIcon, ArrowCounterClockwiseIcon as RotateCcw, ShareIcon as Share, TargetIcon, SquareIcon as Square, TagIcon, TrashIcon, TreeViewIcon, } from '@phosphor-icons/react';
|
|
46
47
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
47
48
|
import { formatDistanceToNowStrict } from 'date-fns';
|
|
48
49
|
import { useUiPathname, useUiRouter, useUiSearchParams, useUiViewerId } from '../../providers/ui-provider.js';
|
|
49
|
-
import { useEffect, useId, useMemo, useState } from 'react';
|
|
50
|
+
import { useEffect, useId, useMemo, useRef, useState } from 'react';
|
|
50
51
|
import { useSessionListActions } from '../../session/actions/use-session-list-actions.js';
|
|
51
52
|
import { Separator } from '../../primitives/separator.js';
|
|
52
53
|
const SESSION_RELATIVE_TIME_CLASS = 'text-muted-foreground block w-10 min-w-10 max-w-10 shrink-0 truncate text-right text-xs tabular-nums';
|
|
@@ -76,6 +77,8 @@ const SESSION_RELATIVE_TIME_CLASS = 'text-muted-foreground block w-10 min-w-10 m
|
|
|
76
77
|
const SESSION_MENU_TRIGGER_TOUCH_CLASS = cn("max-md:pointer-events-auto max-md:relative max-md:size-8 max-md:translate-y-0 max-md:opacity-100 max-md:after:absolute max-md:after:-inset-2 max-md:after:content-['']", "[@media(hover:none)]:pointer-events-auto [@media(hover:none)]:relative [@media(hover:none)]:size-8 [@media(hover:none)]:translate-y-0 [@media(hover:none)]:opacity-100 [@media(hover:none)]:after:absolute [@media(hover:none)]:after:-inset-2 [@media(hover:none)]:after:content-['']", "pointer-coarse:pointer-events-auto pointer-coarse:relative pointer-coarse:size-8 pointer-coarse:translate-y-0 pointer-coarse:opacity-100 pointer-coarse:after:absolute pointer-coarse:after:-inset-2 pointer-coarse:after:content-['']");
|
|
77
78
|
/** The Pinned section's id in the collapsed-sections store: open unless closed. */
|
|
78
79
|
const PINNED_SECTION_ID = 'section:pinned';
|
|
80
|
+
/** The whole Sessions list, collapsed from its header (same store as the sections). */
|
|
81
|
+
const SESSIONS_SECTION_ID = 'section:sessions';
|
|
79
82
|
/** The newest change requests the session briefs read: one server page. */
|
|
80
83
|
const SIDEBAR_CHANGE_REQUEST_LIMIT = 50;
|
|
81
84
|
// Staggered (unique) widths so the loading state reads as a list of rows, not a
|
|
@@ -198,6 +201,27 @@ export function ProjectSessionList({ projectId }) {
|
|
|
198
201
|
if (activeSection)
|
|
199
202
|
setExpanded(projectId, `section:${activeSection}`, true);
|
|
200
203
|
}, [projectId, activeParentId, activeSection, setExpanded]);
|
|
204
|
+
// The session you are in opens when it spawns a session, so the new row is
|
|
205
|
+
// in view. Only a rise while you watch opens it: a row you closed stays
|
|
206
|
+
// closed on every later read.
|
|
207
|
+
const activeChildCount = [sessions, pinnedQuery.sessions, sharedQuery.sessions, automatedQuery.sessions]
|
|
208
|
+
.flat()
|
|
209
|
+
.find((session) => session.session_id === activeSessionId)?.child_count ?? null;
|
|
210
|
+
const seenChildCount = useRef({
|
|
211
|
+
sessionId: null,
|
|
212
|
+
count: null,
|
|
213
|
+
});
|
|
214
|
+
useEffect(() => {
|
|
215
|
+
const seen = seenChildCount.current;
|
|
216
|
+
if (activeSessionId &&
|
|
217
|
+
seen.sessionId === activeSessionId &&
|
|
218
|
+
seen.count !== null &&
|
|
219
|
+
activeChildCount !== null &&
|
|
220
|
+
activeChildCount > seen.count) {
|
|
221
|
+
setExpanded(projectId, activeSessionId, true);
|
|
222
|
+
}
|
|
223
|
+
seenChildCount.current = { sessionId: activeSessionId ?? null, count: activeChildCount };
|
|
224
|
+
}, [projectId, activeSessionId, activeChildCount, setExpanded]);
|
|
201
225
|
// The brief is a session record, not a Review Center inbox. It therefore
|
|
202
226
|
// loads every CR state, not only the ones awaiting review: the newest
|
|
203
227
|
// SIDEBAR_CHANGE_REQUEST_LIMIT of them, which belong to the recent sessions
|
|
@@ -311,7 +335,7 @@ export function ProjectSessionList({ projectId }) {
|
|
|
311
335
|
if (shouldBeginSessionSwitch(event, session.session_id, activeSessionId)) {
|
|
312
336
|
beginSessionSwitch(session.session_id);
|
|
313
337
|
}
|
|
314
|
-
}, displayTitle: getSessionDisplayTitle(session), inSharedGroup: inSharedGroup, spawned: nested, subagentCount: children.length, spawnedCount: spawnedCount, childRunsOpen: childRunsOpen, onToggleChildRuns: () => toggleExpanded(projectId, session.session_id), reviewCount: needsYouBySession[session.session_id] ?? 0, awaitingAnswer: awaitingAnswer.has(session.session_id), changeRequests: changeRequestsBySession.get(session.session_id) ?? [], canShowHoverCard: canShowSessionHoverCard, onDelete: (id, label) => setSessionToDelete({ id, label }), onPin: (id, pinned) => void listActions.setPinned(id, pinned), onArchive: (id, archived) => void listActions.setArchived(id, archived), onShare: (s) => setSessionToShare(s), onRename: (id, name) => setSessionToRename({ id, name }), onEditLabels: setSessionToLabel,
|
|
338
|
+
}, displayTitle: nested ? subagentTitle(getSessionDisplayTitle(session)) : getSessionDisplayTitle(session), inSharedGroup: inSharedGroup, spawned: nested, subagentCount: children.length, spawnedCount: spawnedCount, childRunsOpen: childRunsOpen, onToggleChildRuns: () => toggleExpanded(projectId, session.session_id), reviewCount: needsYouBySession[session.session_id] ?? 0, awaitingAnswer: awaitingAnswer.has(session.session_id), changeRequests: changeRequestsBySession.get(session.session_id) ?? [], canShowHoverCard: canShowSessionHoverCard, onDelete: (id, label) => setSessionToDelete({ id, label }), onPin: (id, pinned) => void listActions.setPinned(id, pinned), onArchive: (id, archived) => void listActions.setArchived(id, archived), onShare: (s) => setSessionToShare(s), onRename: (id, name) => setSessionToRename({ id, name }), onEditLabels: setSessionToLabel,
|
|
315
339
|
// Top-level sessions only: a spawned session stays with its parent,
|
|
316
340
|
// also where it shows on its own (Pinned).
|
|
317
341
|
groups: groupsEnabled && !nested && sessionParentId(session) === null ? groups : undefined, onMoveToGroup: (id, groupId) => void groupActions.move(id, groupId, { toast: true }), onNewGroupFor: (id) => setGroupCreate({ fileSessionId: id }), onDragStart: groupsEnabled && !nested && sessionParentId(session) === null
|
|
@@ -374,7 +398,7 @@ export function ProjectSessionList({ projectId }) {
|
|
|
374
398
|
!sharedQuery.hasNextPage &&
|
|
375
399
|
!automatedQuery.hasNextPage && (_jsx(FirstChatRow, { projectId: projectId, isActive: pathname === uiRoutes().project(projectId) && isFirstChatRequested(searchParams) }))] }));
|
|
376
400
|
}
|
|
377
|
-
return (_jsxs("div", { className: "flex h-full min-h-0 flex-col space-y-px", children: [_jsx(SessionListHeader, { projectId: projectId, sessions: sessions, reviewCountBySession: needsYouBySession, onMenuOpenChange: holdPeek, onNewGroup: groupsEnabled ? () => setGroupCreate({ fileSessionId: null }) : undefined }), _jsx(
|
|
401
|
+
return (_jsxs("div", { className: "flex h-full min-h-0 flex-col space-y-px", children: [_jsxs(Disclosure, { open: !collapsedSectionIds.has(SESSIONS_SECTION_ID), onOpenChange: () => toggleSectionCollapsed(projectId, SESSIONS_SECTION_ID), className: "group/sessions flex min-h-0 flex-1 flex-col space-y-px", transition: { duration: 0.15, ease: 'easeOut' }, children: [_jsx(SessionListHeader, { projectId: projectId, sessions: sessions, reviewCountBySession: needsYouBySession, onMenuOpenChange: holdPeek, onNewGroup: groupsEnabled ? () => setGroupCreate({ fileSessionId: null }) : undefined }), _jsx(DisclosureContent, { className: "flex min-h-0 flex-1 flex-col", contentClassName: "flex min-h-0 flex-1 flex-col overflow-hidden", children: renderBody() })] }), _jsx(ShareSessionModal, { projectId: projectId, session: sessionToShare, open: !!sessionToShare, onOpenChange: (open) => !open && setSessionToShare(null), onSaved: () => queryClient.invalidateQueries({ queryKey: qk.project.sessionsScope(projectId) }) }), _jsx(SessionLabelsModal, { projectId: projectId, session: sessionToLabel, open: !!sessionToLabel, onOpenChange: (open) => !open && setSessionToLabel(null) }), _jsx(RenameSessionModal, { projectId: projectId, sessionId: sessionToRename?.id ?? null, currentName: sessionToRename?.name, open: !!sessionToRename, onOpenChange: (open) => !open && setSessionToRename(null) }), groupsEnabled && (_jsx(SessionGroupNameModal, { projectId: projectId, group: groupToRename, open: !!groupToRename || !!groupCreate, onOpenChange: (open) => {
|
|
378
402
|
if (open)
|
|
379
403
|
return;
|
|
380
404
|
setGroupToRename(null);
|
|
@@ -389,14 +413,14 @@ export function ProjectSessionList({ projectId }) {
|
|
|
389
413
|
* — because everything it needs (the session list, the review summary, the
|
|
390
414
|
* filter facets) is already read by `ProjectSessionList`; hoisting it up meant
|
|
391
415
|
* a second `qk.project.sessions(projectId)` query and two files owning the
|
|
392
|
-
* same horizontal padding. The label
|
|
393
|
-
*
|
|
394
|
-
*
|
|
416
|
+
* same horizontal padding. The label is the trigger of the list's disclosure
|
|
417
|
+
* (a caret on hover, the sidebar row's rounded hover fill); the full sessions
|
|
418
|
+
* page is the first item of the `⋯` menu (`SessionFilterMenu`), which appears
|
|
419
|
+
* whenever there is at least one session. */
|
|
395
420
|
function SessionListHeader({ projectId, sessions, reviewCountBySession, onMenuOpenChange, onNewGroup, }) {
|
|
396
421
|
const t = useTranslations('sidebar');
|
|
397
422
|
const tGroups = useTranslations('sidebar.sessionGroups');
|
|
398
|
-
|
|
399
|
-
return (_jsxs("div", { className: cn('flex w-full shrink-0 flex-row items-center gap-1 px-2', SESSION_ROW_HEIGHT_CLASS), children: [sessionsHref ? (_jsx(HoverPrefetchLink, { href: sessionsHref, className: "text-muted-foreground hover:text-sidebar-foreground flex min-w-0 flex-1 flex-row items-center self-stretch text-sm font-medium", children: _jsx("span", { className: "truncate", children: t('sessions') }) })) : (_jsx("span", { className: "text-muted-foreground flex min-w-0 flex-1 flex-row items-center self-stretch text-sm font-medium", children: _jsx("span", { className: "truncate", children: t('sessions') }) })), onNewGroup && (_jsx(Hint, { side: "top", label: tGroups('newGroup'), children: _jsx(Button, { variant: "ghost", size: "icon-xs", type: "button", "aria-label": tGroups('newGroup'), className: SESSION_MENU_TRIGGER_CLASS, onClick: onNewGroup, children: _jsx(FolderSimplePlusIcon, { className: "size-4" }) }) })), sessions.length > 0 && (_jsxs(DropdownMenu, { onOpenChange: onMenuOpenChange, children: [_jsx(SessionFilterMenu, { projectId: projectId, sessions: sessions, reviewCountBySession: reviewCountBySession, align: "start" }), _jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-xs", type: "button", "aria-label": t('sessionViewOptions'), className: SESSION_MENU_TRIGGER_CLASS, children: _jsx(DotsThreeIcon, { className: "size-4" }) }) })] }))] }));
|
|
423
|
+
return (_jsxs("div", { className: cn('group/sessions-header hover:bg-sidebar-row flex w-full shrink-0 flex-row items-center gap-1 rounded-md px-2 transition-colors', SESSION_ROW_HEIGHT_CLASS), children: [_jsx(DisclosureTrigger, { children: _jsxs("div", { className: "text-muted-foreground group-hover/sessions-header:text-sidebar-foreground flex min-w-0 flex-1 cursor-pointer flex-row items-center gap-1 self-stretch text-sm font-medium focus-visible:outline-none", children: [_jsx("span", { className: "truncate", children: t('sessions') }), _jsx(CaretRightIcon, { "aria-hidden": true, className: "duration-normal size-3 shrink-0 opacity-0 transition-transform ease-out group-hover/sessions-header:opacity-100 group-data-[state=open]/sessions:rotate-90" })] }) }), onNewGroup && (_jsx(Hint, { side: "top", label: tGroups('newGroup'), children: _jsx(Button, { variant: "ghost", size: "icon-xs", type: "button", "aria-label": tGroups('newGroup'), className: SESSION_MENU_TRIGGER_CLASS, onClick: onNewGroup, children: _jsx(FolderSimplePlusIcon, { className: "size-4" }) }) })), sessions.length > 0 && (_jsxs(DropdownMenu, { onOpenChange: onMenuOpenChange, children: [_jsx(SessionFilterMenu, { projectId: projectId, sessions: sessions, reviewCountBySession: reviewCountBySession, align: "start" }), _jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-xs", type: "button", "aria-label": t('sessionViewOptions'), className: SESSION_MENU_TRIGGER_CLASS, children: _jsx(DotsThreeIcon, { className: "size-4" }) }) })] }))] }));
|
|
400
424
|
}
|
|
401
425
|
/** Non-sticky by design: FadedScrollArea masks its own edges, and a sticky
|
|
402
426
|
* header fights that mask.
|
|
@@ -535,7 +559,6 @@ function ProjectSessionRow({ session, href, isActive, isSwitching, onNavigate, d
|
|
|
535
559
|
requestAnimationFrame(() => fn());
|
|
536
560
|
};
|
|
537
561
|
const source = sessionSource(session, tI18nComplete);
|
|
538
|
-
const isMeta = isMetaCoordinatorSession(session);
|
|
539
562
|
// The conversation the runtime can fork: the pinned root conversation id,
|
|
540
563
|
// not the project-session id — `POST /session/{id}/fork` addresses the
|
|
541
564
|
// runtime's own id space (`ses_…`). canFork already guarantees one.
|
|
@@ -558,7 +581,7 @@ function ProjectSessionRow({ session, href, isActive, isSwitching, onNavigate, d
|
|
|
558
581
|
// same `reviewCount` prop, so they agree by construction rather than by luck.
|
|
559
582
|
const displayStatus = sessionDisplayStatus(session, reviewCount);
|
|
560
583
|
const waitingOn = awaitingAnswer ? 'answer' : 'review';
|
|
561
|
-
const sessionLink = (_jsxs(HoverPrefetchLink, { href: href, prefetch: true, onClick: onNavigate, ...openIntent, "aria-busy": isSwitching || undefined, "aria-current": isActive ? 'page' : undefined, "aria-describedby": descriptionId, className: "focus-visible:ring-kortix-base flex min-w-0 flex-1 items-center gap-2 self-stretch rounded-md py-1 focus-visible:ring-[0.6px] focus-visible:outline-none", children: [_jsx("div", { className: "size-4 shrink-0", children: spawned ? (_jsx(ArrowsSplitIcon, { "aria-hidden": true, className: "text-muted-foreground size-4" })) : (_jsx(SessionStatusDot, { session: session, reviewCount: reviewCount, waitingOn: waitingOn, changeRequests: changeRequests })) }), _jsx(SessionGoalMark, { projectId: session.project_id, sessionId: session.session_id }),
|
|
584
|
+
const sessionLink = (_jsxs(HoverPrefetchLink, { href: href, prefetch: true, onClick: onNavigate, ...openIntent, "aria-busy": isSwitching || undefined, "aria-current": isActive ? 'page' : undefined, "aria-describedby": descriptionId, className: "focus-visible:ring-kortix-base flex min-w-0 flex-1 items-center gap-2 self-stretch rounded-md py-1 focus-visible:ring-[0.6px] focus-visible:outline-none", children: [_jsx("div", { className: "size-4 shrink-0", children: spawned ? (_jsx(ArrowsSplitIcon, { "aria-hidden": true, className: "text-muted-foreground size-4" })) : (_jsx(SessionStatusDot, { session: session, reviewCount: reviewCount, waitingOn: waitingOn, changeRequests: changeRequests })) }), _jsx(SessionGoalMark, { projectId: session.project_id, sessionId: session.session_id }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx(SessionTitle, { title: displayTitle, className: cn('min-w-0', isActive && 'font-medium') }), _jsx("span", { className: "hidden max-md:block pointer-coarse:block [@media(hover:none)]:block", "aria-hidden": true, "data-session-mobile-created-at": "true", children: _jsx(MobileSessionCreatedTime, { createdAt: session.created_at }) })] }), subagentCount + spawnedCount > 0 && onToggleChildRuns && (_jsx(ChildRunsToggle, { count: subagentCount + spawnedCount, open: childRunsOpen, onToggle: onToggleChildRuns, clearOfMenu: !hasIndicators })), hasIndicators && (_jsxs("div", { className: cn('flex shrink-0 items-center gap-0 transition-none', 'max-md:hidden pointer-coarse:hidden [@media(hover:none)]:hidden', 'group-hover/session-list:pointer-events-none group-hover/session-list:opacity-0', 'group-has-data-[state=open]/session-list:pointer-events-none group-has-data-[state=open]/session-list:opacity-0'), "data-session-indicators": "true", children: [showStarter && (_jsx("span", { className: "flex size-5 shrink-0 items-center justify-center", "data-session-source": "true", "data-session-starter": starter.type, children: _jsx(Hint, { side: "top", label: t('startedByLabel', { name: starter.label }), children: _jsx("span", { className: "text-muted-foreground flex size-5 items-center justify-center", children: _jsx(SessionStarterMark, { session: session, starter: starter, iconClassName: "size-3", avatarClassName: "size-5" }) }) }) })), !inSharedGroup && _jsx(SessionSharedIcon, { session: session })] }))] }));
|
|
562
585
|
return (_jsx("div", { className: "group/session-list block", onDragStart: onDragStart, children: _jsxs("div", { className: cn(
|
|
563
586
|
// --session-row-surface paints the row AND the title fade in the same
|
|
564
587
|
// style pass. Do not transition background — transition-colors made the
|
|
@@ -10,10 +10,11 @@ import { ComputerConnectModal } from '../../internal/tunnel/computer-connect.js'
|
|
|
10
10
|
import { ConnectMcpModal } from '../../internal/layout/connect-mcp-modal.js';
|
|
11
11
|
import { ProjectMcpNavItem } from './footer/project-mcp-nav.js';
|
|
12
12
|
import { ProjectComputerNavItem } from './footer/project-computer-nav.js';
|
|
13
|
-
import {
|
|
13
|
+
import { ProjectManifestIssuesAlert } from './footer/project-manifest-issues-alert.js';
|
|
14
14
|
import { ProjectSandboxAlert } from './footer/project-sandbox-alert.js';
|
|
15
15
|
import { ProjectRepositoryDisconnectedAlert } from '../repository-disconnected.js';
|
|
16
16
|
import { CustomizeSidebarModal } from './customize-sidebar-modal.js';
|
|
17
|
+
import { NewAgentModalProvider } from './new-agent-modal-provider.js';
|
|
17
18
|
import { ProjectMemoryNavItem } from './footer/project-memory-nav.js';
|
|
18
19
|
import { ProjectNavItems } from './project-nav-items.js';
|
|
19
20
|
import { ProjectSessionList } from './project-session-list.js';
|
|
@@ -95,7 +96,9 @@ export function ProjectSidebar({ projectId, menu, onOpenSearch, }) {
|
|
|
95
96
|
window.addEventListener('keydown', handler);
|
|
96
97
|
return () => window.removeEventListener('keydown', handler);
|
|
97
98
|
}, [channels, handleNewSession]);
|
|
98
|
-
return (
|
|
99
|
+
return (
|
|
100
|
+
// The New agent modal mounts beside <Sidebar>, outside the mobile sheet.
|
|
101
|
+
_jsxs(NewAgentModalProvider, { projectId: projectId, children: [_jsxs(Sidebar, { collapsible: "offcanvas", variant: "inset",
|
|
99
102
|
// No background here. This className lands on the sidebar CONTAINER —
|
|
100
103
|
// the square positioning box — while the visible card is the rounded
|
|
101
104
|
// inner box, which already carries `bg-sidebar`. Painting it twice put a
|
|
@@ -108,5 +111,5 @@ export function ProjectSidebar({ projectId, menu, onOpenSearch, }) {
|
|
|
108
111
|
// box clears the 44px floor with the vertical-only extension —
|
|
109
112
|
// vertical-only because this titlebar row packs several
|
|
110
113
|
// controls side by side (KRTX-2004).
|
|
111
|
-
className: "shrink-0 hit-area-y-3", children: _jsx(MagnifyingGlassIcon, { className: "size-4" }) }) })), isMobile && (_jsx(Button, { type: "button", "aria-label": tCommon('close'), variant: "ghost", size: "icon", onClick: () => setOpenMobile(false), className: "shrink-0 hit-area-y-3", children: _jsx(Close, {}) })), !isMobile && !peek && (_jsx(Hint, { side: "bottom", label: _jsxs("span", { className: "flex items-center gap-1.5", children: [isExpanded ? t('collapse') : t('pin'), _jsxs(KbdGroup, { children: [_jsx(Kbd, { className: "font-mono", children: modSymbol }), _jsx(Kbd, { className: "font-mono", children: "B" })] })] }), children: _jsx(Button, { type: "button", "aria-label": isExpanded ? t('collapse') : t('pin'), variant: "ghost", size: "icon", onClick: toggleSidebar, className: "shrink-0", children: _jsx(PanelLeft, { className: "cn-rtl-flip" }) }) }))] })] }) }), _jsx(SidebarContent, { className: "relative min-h-0 flex-1 [scrollbar-width:'none'] overflow-hidden [-ms-overflow-style:'none'] [&::-webkit-scrollbar]:hidden [&_[data-sidebar=menu-button]]:pl-2", children: _jsxs("div", { className: "flex h-full min-h-0 flex-col space-y-2", children: [_jsx(SidebarGroup, { className: "py-0", children: _jsxs(SidebarMenu, { children: [channels ? null : (_jsx(SidebarMenuItem, { children: creatingSession ? (_jsx(SidebarMenuButton, { disabled: true, "aria-busy": true, className: "group/menu-button text-sidebar-foreground relative", children: newSessionRowBody })) : (_jsx(SidebarMenuButton, { asChild: true, className: "group/menu-button text-sidebar-foreground relative", children: _jsx(Link, { href: uiRoutes().project(projectId), prefetch: true, onClick: handleNewSessionClick, children: newSessionRowBody }) })) })), channels ? _jsx(ProjectMemoryNavItem, { projectId: projectId }) : null, _jsx(ProjectNavItems, { projectId: projectId })] }) }), _jsx(SidebarGroup, { className: "min-h-0 flex-1 flex-col py-0", ref: sessionsGroupRef, children: channels ? (_jsx(ProjectSpacesNav, { projectId: projectId })) : (_jsx(ProjectSessionList, { projectId: projectId })) }), _jsx(SidebarGroup, { className: "mt-auto", children: _jsxs(SidebarMenu, { className: "gap-1", children: [_jsx(ProjectRepositoryDisconnectedAlert, { projectId: projectId }), _jsx(ProjectSandboxAlert, { projectId: projectId }), _jsx(
|
|
114
|
+
className: "shrink-0 hit-area-y-3", children: _jsx(MagnifyingGlassIcon, { className: "size-4" }) }) })), isMobile && (_jsx(Button, { type: "button", "aria-label": tCommon('close'), variant: "ghost", size: "icon", onClick: () => setOpenMobile(false), className: "shrink-0 hit-area-y-3", children: _jsx(Close, {}) })), !isMobile && !peek && (_jsx(Hint, { side: "bottom", label: _jsxs("span", { className: "flex items-center gap-1.5", children: [isExpanded ? t('collapse') : t('pin'), _jsxs(KbdGroup, { children: [_jsx(Kbd, { className: "font-mono", children: modSymbol }), _jsx(Kbd, { className: "font-mono", children: "B" })] })] }), children: _jsx(Button, { type: "button", "aria-label": isExpanded ? t('collapse') : t('pin'), variant: "ghost", size: "icon", onClick: toggleSidebar, className: "shrink-0", children: _jsx(PanelLeft, { className: "cn-rtl-flip" }) }) }))] })] }) }), _jsx(SidebarContent, { className: "relative min-h-0 flex-1 [scrollbar-width:'none'] overflow-hidden [-ms-overflow-style:'none'] [&::-webkit-scrollbar]:hidden [&_[data-sidebar=menu-button]]:pl-2", children: _jsxs("div", { className: "flex h-full min-h-0 flex-col space-y-2", children: [_jsx(SidebarGroup, { className: "py-0", children: _jsxs(SidebarMenu, { children: [channels ? null : (_jsx(SidebarMenuItem, { children: creatingSession ? (_jsx(SidebarMenuButton, { disabled: true, "aria-busy": true, className: "group/menu-button text-sidebar-foreground relative", children: newSessionRowBody })) : (_jsx(SidebarMenuButton, { asChild: true, className: "group/menu-button text-sidebar-foreground relative", children: _jsx(Link, { href: uiRoutes().project(projectId), prefetch: true, onClick: handleNewSessionClick, children: newSessionRowBody }) })) })), channels ? _jsx(ProjectMemoryNavItem, { projectId: projectId }) : null, _jsx(ProjectNavItems, { projectId: projectId })] }) }), _jsx(SidebarGroup, { className: "min-h-0 flex-1 flex-col py-0", ref: sessionsGroupRef, children: channels ? (_jsx(ProjectSpacesNav, { projectId: projectId })) : (_jsx(ProjectSessionList, { projectId: projectId })) }), _jsx(SidebarGroup, { className: "mt-auto", children: _jsxs(SidebarMenu, { className: "gap-1", children: [_jsx(ProjectRepositoryDisconnectedAlert, { projectId: projectId }), _jsx(ProjectSandboxAlert, { projectId: projectId }), _jsx(ProjectManifestIssuesAlert, { projectId: projectId }), _jsx(SidebarBalanceWarning, { accountId: accountId }), _jsx("li", { className: "not-has-[li]:hidden", children: _jsxs(SidebarMenu, { className: "gap-px [&>li:not(:first-child)>[data-sidebar=menu-button]]:rounded-t-sm [&>li:not(:last-child)>[data-sidebar=menu-button]]:rounded-b-sm", children: [_jsx(ProjectMcpNavItem, { onOpenConnect: () => setConnectMcpOpen(true) }), _jsx(ProjectComputerNavItem, { projectId: projectId, onOpenConnect: () => setComputerConnectOpen(true) }), chrome ? (_jsx(ProjectChromeNavItem, { onOpenConnect: () => useAppsModalStore.getState().setOpen(true) })) : null] }) }), _jsx(SidebarUpgradeButton, { accountId: accountId })] }) })] }) }), _jsx(SidebarRail, { "aria-label": t('resize'), title: t('resizeHelp') })] }), _jsx(ComputerConnectModal, { projectId: projectId, open: computerConnectOpen, onOpenChange: setComputerConnectOpen }), _jsx(AppsModal, { chrome: chrome, onOpenComputer: () => setComputerConnectOpen(true), onOpenMcp: () => setConnectMcpOpen(true) }), _jsx(ConnectMcpModal, { open: connectMcpOpen, onOpenChange: setConnectMcpOpen }), _jsx(CustomizeSidebarModal, { projectId: projectId })] }));
|
|
112
115
|
}
|
|
@@ -112,6 +112,7 @@ export function SessionFilterMenu({ projectId, sessions, align = 'start', side =
|
|
|
112
112
|
const t = useTranslations('sidebar.filter');
|
|
113
113
|
const tPinArchive = useTranslations('sidebar.pinArchive');
|
|
114
114
|
const tDeleted = useTranslations('sidebar.recentlyDeleted');
|
|
115
|
+
const sessionsHref = uiRoutes().sessions(projectId);
|
|
115
116
|
const archivedHref = uiRoutes().sessions(projectId, 'archived');
|
|
116
117
|
const deletedHref = uiRoutes().sessions(projectId, 'deleted');
|
|
117
118
|
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
@@ -240,7 +241,7 @@ export function SessionFilterMenu({ projectId, sessions, align = 'start', side =
|
|
|
240
241
|
}) })), showAccessFacet && (_jsx(FilterSubmenu, { trigger: _jsxs(_Fragment, { children: [_jsx("span", { className: "min-w-0 flex-1 truncate", children: t('access') }), activeAccess.length > 0 && _jsx(FacetActiveDot, {})] }), className: "w-52 p-1", children: accessOptions.map((option) => {
|
|
241
242
|
const OptionIcon = SESSION_ACCESS_ICONS[option.value];
|
|
242
243
|
return (_jsxs(FilterCheckboxItem, { checked: accessFilterSet.has(option.value), onCheckedChange: () => toggleAccessFilter(projectId, option.value, surface), children: [_jsx(OptionIcon, { className: "size-4" }), _jsx("span", { className: "min-w-0 flex-1 truncate", children: accessLabels[option.value] }), _jsx(CountBadge, { count: option.count, className: "ml-auto" })] }, option.value));
|
|
243
|
-
}) })), ' '] })), _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuItem, { className: "cursor-pointer", onSelect: () => collapseAllSections(projectId, resolveRenderedSectionIds(sessions, groupMode, orderMode, hiddenSections, tI18nComplete, reviewCountBySession, ownerLabels), surface), children: t('collapseAll') }), !pageFacets && archivedHref && deletedHref && (_jsxs(_Fragment, { children: [_jsx(DropdownMenuItem, { asChild: true, className: "cursor-pointer", children: _jsx(Link, { href: archivedHref, children: tPinArchive('showArchived') }) }), _jsx(DropdownMenuItem, { asChild: true, className: "cursor-pointer", children: _jsx(Link, { href: deletedHref, children: tDeleted('view') }) })] }))] }));
|
|
244
|
+
}) })), ' '] })), _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuItem, { className: "cursor-pointer", onSelect: () => collapseAllSections(projectId, resolveRenderedSectionIds(sessions, groupMode, orderMode, hiddenSections, tI18nComplete, reviewCountBySession, ownerLabels), surface), children: t('collapseAll') }), !pageFacets && sessionsHref && archivedHref && deletedHref && (_jsxs(_Fragment, { children: [_jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuItem, { asChild: true, className: "cursor-pointer", children: _jsx(Link, { href: sessionsHref, children: tI18nComplete.raw('text78648d4d6649') }) }), _jsx(DropdownMenuItem, { asChild: true, className: "cursor-pointer", children: _jsx(Link, { href: archivedHref, children: tPinArchive('showArchived') }) }), _jsx(DropdownMenuItem, { asChild: true, className: "cursor-pointer", children: _jsx(Link, { href: deletedHref, children: tDeleted('view') }) })] }))] }));
|
|
244
245
|
}
|
|
245
246
|
function FilterSubmenu({ trigger, className, children, }) {
|
|
246
247
|
return (_jsxs(DropdownMenuSub, { children: [_jsx(DropdownMenuSubTrigger, { children: trigger }), _jsx(DropdownMenuSubContent, { className: className, children: children })] }));
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { SpaceBlock } from '@kortix/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* A space's board tab, rendered as a simple responsive grid of blocks.
|
|
4
|
+
*
|
|
5
|
+
* A board is agent-configurable: the agent declares the tab's `blocks` in
|
|
6
|
+
* `kortix.yaml` (`spaces.<slug>.tabs[]`, `type: board`), and this renderer
|
|
7
|
+
* lays them out — it does not decide what a board contains. v1 is deliberately flat: one card per block, two columns on
|
|
8
|
+
* `sm`, each card showing the block's `label` and its embed. No drag, no
|
|
9
|
+
* resize, no nesting — the grid IS the layout (Marko: "simple & elegant, not
|
|
10
|
+
* overwhelming").
|
|
11
|
+
*
|
|
12
|
+
* Every embed degrades gracefully: a block with its payload missing (an iframe
|
|
13
|
+
* with no `url`, an artifact with no `path`, an `app` slug that resolves to no
|
|
14
|
+
* App) renders a muted "nothing here yet" line rather than an empty frame or a
|
|
15
|
+
* crash, because the config is authored by an agent mid-edit as often as a
|
|
16
|
+
* finished one.
|
|
17
|
+
*
|
|
18
|
+
* Block renderers: `text` is markdown, `iframe` a sandboxed frame, `artifact`
|
|
19
|
+
* opens the Files viewer, `app` the live pooled `AppPreview` for the resolved
|
|
20
|
+
* slug, `chat` the project room named `room` (`SpaceRoom`, flag `agent_rooms`).
|
|
21
|
+
*/
|
|
22
|
+
export declare function SpaceBlocks({ projectId, blocks, }: {
|
|
23
|
+
projectId: string;
|
|
24
|
+
blocks: SpaceBlock[];
|
|
25
|
+
}): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useAppAccess, useProjectApps } from '@kortix/sdk/react';
|
|
4
|
+
import { AppWindowIcon, ChatCircleIcon, FileTextIcon, GlobeIcon, TextAaIcon, } from '@phosphor-icons/react';
|
|
5
|
+
import { AppPreview } from '../../apps/app-preview.js';
|
|
6
|
+
import { useTranslations } from '../../i18n/index.js';
|
|
7
|
+
import { appCan } from '../../apps/app-shared.js';
|
|
8
|
+
import { UnifiedMarkdown } from '../../markdown/index.js';
|
|
9
|
+
import Loading from '../../primitives/loading.js';
|
|
10
|
+
import { useFilePreviewStore } from '../../internal/stores/file-preview-store.js';
|
|
11
|
+
import { framePolicy } from '../../files/viewer/preview-policy.js';
|
|
12
|
+
import { cn } from '../../lib/utils.js';
|
|
13
|
+
import { SpaceRoom } from './space-room.js';
|
|
14
|
+
/**
|
|
15
|
+
* A space's board tab, rendered as a simple responsive grid of blocks.
|
|
16
|
+
*
|
|
17
|
+
* A board is agent-configurable: the agent declares the tab's `blocks` in
|
|
18
|
+
* `kortix.yaml` (`spaces.<slug>.tabs[]`, `type: board`), and this renderer
|
|
19
|
+
* lays them out — it does not decide what a board contains. v1 is deliberately flat: one card per block, two columns on
|
|
20
|
+
* `sm`, each card showing the block's `label` and its embed. No drag, no
|
|
21
|
+
* resize, no nesting — the grid IS the layout (Marko: "simple & elegant, not
|
|
22
|
+
* overwhelming").
|
|
23
|
+
*
|
|
24
|
+
* Every embed degrades gracefully: a block with its payload missing (an iframe
|
|
25
|
+
* with no `url`, an artifact with no `path`, an `app` slug that resolves to no
|
|
26
|
+
* App) renders a muted "nothing here yet" line rather than an empty frame or a
|
|
27
|
+
* crash, because the config is authored by an agent mid-edit as often as a
|
|
28
|
+
* finished one.
|
|
29
|
+
*
|
|
30
|
+
* Block renderers: `text` is markdown, `iframe` a sandboxed frame, `artifact`
|
|
31
|
+
* opens the Files viewer, `app` the live pooled `AppPreview` for the resolved
|
|
32
|
+
* slug, `chat` the project room named `room` (`SpaceRoom`, flag `agent_rooms`).
|
|
33
|
+
*/
|
|
34
|
+
export function SpaceBlocks({ projectId, blocks, }) {
|
|
35
|
+
if (!blocks.length)
|
|
36
|
+
return null;
|
|
37
|
+
return (_jsx("div", { className: "grid w-full gap-4 sm:grid-cols-2", children: blocks.map((block, index) => (_jsx(SpaceBlockCard, { projectId: projectId, block: block }, index))) }));
|
|
38
|
+
}
|
|
39
|
+
const TYPE_ICON = {
|
|
40
|
+
chat: ChatCircleIcon,
|
|
41
|
+
artifact: FileTextIcon,
|
|
42
|
+
app: AppWindowIcon,
|
|
43
|
+
iframe: GlobeIcon,
|
|
44
|
+
text: TextAaIcon,
|
|
45
|
+
};
|
|
46
|
+
const TYPE_FALLBACK_LABEL = {
|
|
47
|
+
chat: 'Chat',
|
|
48
|
+
artifact: 'Artifact',
|
|
49
|
+
app: 'App',
|
|
50
|
+
iframe: 'Embed',
|
|
51
|
+
text: 'Note',
|
|
52
|
+
};
|
|
53
|
+
// In flow on the page: the page surface and a hairline (color.md, in-flow section).
|
|
54
|
+
const PANEL = 'bg-background flex min-w-0 flex-col overflow-hidden rounded-md border';
|
|
55
|
+
function SpaceBlockCard({ projectId, block }) {
|
|
56
|
+
const openPreview = useFilePreviewStore((state) => state.openPreview);
|
|
57
|
+
const Icon = TYPE_ICON[block.type];
|
|
58
|
+
const label = block.label?.trim() || TYPE_FALLBACK_LABEL[block.type];
|
|
59
|
+
const t = useTranslations('spaces');
|
|
60
|
+
// A chat block is a room: the host's room panel draws its own frame.
|
|
61
|
+
if (block.type === 'chat') {
|
|
62
|
+
return block.room?.trim() ? (_jsx(SpaceRoom, { projectId: projectId, roomName: block.room.trim(), className: "min-w-0" })) : (_jsxs("div", { className: PANEL, children: [_jsx("div", { className: "flex items-center gap-2 px-4 py-2.5", children: _jsx(BlockTitle, { icon: Icon, label: label }) }), _jsx(EmptyLine, { children: t('noRoom') })] }));
|
|
63
|
+
}
|
|
64
|
+
// A clickable artifact is its own `<button>` (whole card opens the file), so
|
|
65
|
+
// the header is shared by the rest and skipped there.
|
|
66
|
+
if (block.type === 'artifact') {
|
|
67
|
+
if (!block.path)
|
|
68
|
+
return _jsx(EmptyBlock, { icon: Icon, label: label });
|
|
69
|
+
return (_jsxs("button", { type: "button", onClick: () => openPreview(block.path), className: cn(PANEL, 'hover:bg-hover items-start gap-1.5 px-4 py-3 text-left transition-colors'), children: [_jsx(BlockTitle, { icon: Icon, label: label }), _jsx("span", { className: "text-muted-foreground w-full truncate font-mono text-xs", children: block.path })] }));
|
|
70
|
+
}
|
|
71
|
+
return (_jsxs("div", { className: PANEL, children: [_jsx("div", { className: "flex items-center gap-2 px-4 py-2.5", children: _jsx(BlockTitle, { icon: Icon, label: label }) }), _jsx(BlockBody, { projectId: projectId, block: block })] }));
|
|
72
|
+
}
|
|
73
|
+
function BlockTitle({ icon: Icon, label, }) {
|
|
74
|
+
return (_jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Icon, { className: "text-muted-foreground size-4 shrink-0" }), _jsx("span", { className: "text-foreground truncate text-sm font-medium", children: label })] }));
|
|
75
|
+
}
|
|
76
|
+
function BlockBody({ projectId, block }) {
|
|
77
|
+
const t = useTranslations('spaces');
|
|
78
|
+
switch (block.type) {
|
|
79
|
+
case 'text':
|
|
80
|
+
return block.text?.trim() ? (_jsx("div", { className: "border-border border-t px-4 py-3", children: _jsx(UnifiedMarkdown, { content: block.text, trust: "agent" }) })) : (_jsx(EmptyLine, { children: t('blocks.noContent') }));
|
|
81
|
+
case 'iframe':
|
|
82
|
+
return block.url ? (_jsx("iframe", { src: block.url, title: block.label || 'Embed',
|
|
83
|
+
// A Kortix origin (the app, the API, the sandbox proxy) gets an opaque origin: the
|
|
84
|
+
// frame can never reach the page's tokens. Any other site keeps its own origin.
|
|
85
|
+
sandbox: framePolicy('app', block.url).sandbox, className: "border-border h-64 w-full border-t" })) : (_jsx(EmptyLine, { children: t('blocks.noUrl') }));
|
|
86
|
+
case 'app':
|
|
87
|
+
return block.app ? (_jsx(SpaceAppBlock, { projectId: projectId, slug: block.app })) : (_jsx(EmptyLine, { children: t('blocks.noApp') }));
|
|
88
|
+
default:
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The live App preview for an `app` block. Resolves the block's slug against
|
|
94
|
+
* the project's App inventory, mints a short-lived access session for an App
|
|
95
|
+
* the viewer may open, and renders the same pooled `AppPreview` thumbnail the
|
|
96
|
+
* Apps page and the session browser use. Every not-ready state degrades to a
|
|
97
|
+
* muted line or `AppPreview`'s own notice — it never crashes a Space.
|
|
98
|
+
*/
|
|
99
|
+
function SpaceAppBlock({ projectId, slug }) {
|
|
100
|
+
const t = useTranslations('spaces');
|
|
101
|
+
const apps = useProjectApps(projectId);
|
|
102
|
+
const app = apps.data?.find((a) => a.slug === slug);
|
|
103
|
+
// A card thumbnail only needs the SESSION, and only for an App that is live
|
|
104
|
+
// and the viewer may open — matching the Apps grid, which fires neither the
|
|
105
|
+
// policy read nor the access-session mint for an App it only lists.
|
|
106
|
+
const live = !!app && !!app.active_deployment_id && appCan(app, 'preview') && app.viewer_can_access !== false;
|
|
107
|
+
const access = useAppAccess(projectId, live && app ? app.app_id : null, {
|
|
108
|
+
policy: false,
|
|
109
|
+
session: live,
|
|
110
|
+
});
|
|
111
|
+
if (apps.isLoading) {
|
|
112
|
+
return (_jsx(EmptyLine, { children: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(Loading, { className: "size-4 shrink-0" }), t('blocks.loadingApp')] }) }));
|
|
113
|
+
}
|
|
114
|
+
if (!app)
|
|
115
|
+
return _jsx(EmptyLine, { children: t('missing.app', { slug }) });
|
|
116
|
+
return (_jsx("div", { className: "border-border border-t", children: _jsx(AppPreview, { app: app, url: access.session.data?.url ?? null, accessError: access.session.isError, interactive: false }) }));
|
|
117
|
+
}
|
|
118
|
+
function EmptyLine({ children }) {
|
|
119
|
+
return (_jsx("div", { className: "border-border border-t px-4 py-3", children: _jsx("span", { className: "text-muted-foreground text-xs", children: children }) }));
|
|
120
|
+
}
|
|
121
|
+
function EmptyBlock({ icon: Icon, label, }) {
|
|
122
|
+
const t = useTranslations('spaces');
|
|
123
|
+
return (_jsxs("div", { className: PANEL, children: [_jsx("div", { className: "flex items-center gap-2 px-4 py-2.5", children: _jsx(BlockTitle, { icon: Icon, label: label }) }), _jsx(EmptyLine, { children: t('blocks.noFile') })] }));
|
|
124
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type SpaceGroup, type ManifestSpace } from '@kortix/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* The space filter of a list page (Goals, Artifacts): `All`, one tab per
|
|
4
|
+
* space of the project (an empty one included, with 0), then `Project-wide`.
|
|
5
|
+
* Built from the spaces, not from the items, so the selected space always has
|
|
6
|
+
* a tab. Renders nothing for a project without spaces.
|
|
7
|
+
*/
|
|
8
|
+
export declare function SpaceFilterTabs<T>({ spaces, groups, value, onValueChange, }: {
|
|
9
|
+
/** `listSpaces(config)`. */
|
|
10
|
+
spaces: ManifestSpace[];
|
|
11
|
+
/** `groupBySpace(items, …)`: the counts. */
|
|
12
|
+
groups: Array<SpaceGroup<T>>;
|
|
13
|
+
value: string;
|
|
14
|
+
onValueChange: (value: string) => void;
|
|
15
|
+
}): import("react").JSX.Element | null;
|
|
16
|
+
/** The name a filtered empty state shows for `value`. */
|
|
17
|
+
export declare function spaceFilterLabel(value: string, spaces: ManifestSpace[], projectWide: string): string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { PROJECT_WIDE_SPACE } from '@kortix/sdk';
|
|
4
|
+
import { ALL_SPACES } from '../../customize/shared/catalog/catalog-space-tabs.js';
|
|
5
|
+
import { useTranslations } from '../../i18n/index.js';
|
|
6
|
+
import { CountBadge } from '../../primitives/count-badge.js';
|
|
7
|
+
import { Tabs, TabsListCompact, TabsTriggerCompact } from '../../primitives/tabs.js';
|
|
8
|
+
/**
|
|
9
|
+
* The space filter of a list page (Goals, Artifacts): `All`, one tab per
|
|
10
|
+
* space of the project (an empty one included, with 0), then `Project-wide`.
|
|
11
|
+
* Built from the spaces, not from the items, so the selected space always has
|
|
12
|
+
* a tab. Renders nothing for a project without spaces.
|
|
13
|
+
*/
|
|
14
|
+
export function SpaceFilterTabs({ spaces, groups, value, onValueChange, }) {
|
|
15
|
+
const t = useTranslations('spaces');
|
|
16
|
+
if (spaces.length === 0 && value === ALL_SPACES)
|
|
17
|
+
return null;
|
|
18
|
+
const counts = new Map(groups.map((group) => [group.name, group.items.length]));
|
|
19
|
+
const tabs = [
|
|
20
|
+
...spaces.map((space) => ({ name: space.name, label: space.label || space.name })),
|
|
21
|
+
{ name: PROJECT_WIDE_SPACE, label: t('projectWide') },
|
|
22
|
+
];
|
|
23
|
+
return (_jsx(Tabs, { value: value, onValueChange: onValueChange, className: "max-w-full overflow-x-auto", children: _jsxs(TabsListCompact, { "aria-label": t('filter'), children: [_jsx(TabsTriggerCompact, { value: ALL_SPACES, children: t('all') }), tabs.map((tab) => (_jsxs(TabsTriggerCompact, { value: tab.name, children: [tab.label, _jsx(CountBadge, { count: counts.get(tab.name) ?? 0, tone: "neutral" })] }, tab.name)))] }) }));
|
|
24
|
+
}
|
|
25
|
+
/** The name a filtered empty state shows for `value`. */
|
|
26
|
+
export function spaceFilterLabel(value, spaces, projectWide) {
|
|
27
|
+
if (value === PROJECT_WIDE_SPACE)
|
|
28
|
+
return projectWide;
|
|
29
|
+
const space = spaces.find((candidate) => candidate.name === value);
|
|
30
|
+
return space?.label || space?.name || value;
|
|
31
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ManifestSpace, type SpaceTab } from '@kortix/sdk';
|
|
2
|
+
/** The key of the room tab, always first. */
|
|
3
|
+
export declare const ROOM_TAB = "room";
|
|
4
|
+
/** The tabs a viewer sees, in order: a tab of a feature the project has off is hidden. */
|
|
5
|
+
export declare function visibleSpaceTabs(space: ManifestSpace, flags: {
|
|
6
|
+
goals: boolean;
|
|
7
|
+
artifacts: boolean;
|
|
8
|
+
}): Array<{
|
|
9
|
+
key: string;
|
|
10
|
+
tab: SpaceTab;
|
|
11
|
+
index: number;
|
|
12
|
+
}>;
|
|
13
|
+
/**
|
|
14
|
+
* /projects/[id]/spaces/[slug]: a space is a channel. One header block: the
|
|
15
|
+
* title bar names it and shows what `spaces.<slug>.header` picks (its agents,
|
|
16
|
+
* the people in its room, the sessions that wait on you, and the actions),
|
|
17
|
+
* and the tabs sit directly under it. The first tab is always the room; the
|
|
18
|
+
* tabs after it come from `spaces.<slug>.tabs`. `?tab=` deep links a tab.
|
|
19
|
+
* The "+" menu and Edit tabs write the same manifest list.
|
|
20
|
+
*/
|
|
21
|
+
export declare function SpacePage({ projectId, slug }: {
|
|
22
|
+
projectId: string;
|
|
23
|
+
slug: string;
|
|
24
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { MY_KORTIX_AGENT_NAME } from '../../_vendor/kortix-shared.js';
|
|
4
|
+
import { agentsInSpace, listSpaces, spaceHeader, spaceTabKey, spaceTabs, } from '@kortix/sdk';
|
|
5
|
+
import { sessionNeedsInputCount, useFeatureFlag, useProjectConfig, useProjectSessions, useRoom, useSessionsNeedingInput, useSpaceRoom, } from '@kortix/sdk/react';
|
|
6
|
+
import { HashIcon, PlusIcon } from '@phosphor-icons/react';
|
|
7
|
+
import { useConfigureThread } from '../../customize/use-configure-thread.js';
|
|
8
|
+
import { useTranslations } from '../../i18n/index.js';
|
|
9
|
+
import { AgentMark } from '../../internal/components/agent-mark.js';
|
|
10
|
+
import { ProjectPageHeader } from '../../internal/layout/project-page-header.js';
|
|
11
|
+
import { SidebarToggle } from '../../internal/layout/sidebar-toggle.js';
|
|
12
|
+
import { agentHref } from '../../internal/lib/capability-tab-routes.js';
|
|
13
|
+
import { PROJECT_ACTIONS } from '../../internal/lib/project-actions.js';
|
|
14
|
+
import { useProjectCan } from '../../internal/lib/use-project-can.js';
|
|
15
|
+
import { useActiveSpace } from '../../internal/stores/active-space-store.js';
|
|
16
|
+
import { uiRoutes } from '../../lib/routes.js';
|
|
17
|
+
import { UiLink as Link, useUiPathname, useUiRouter, useUiSearchParams } from '../../providers/ui-provider.js';
|
|
18
|
+
import { Button } from '../../primitives/button.js';
|
|
19
|
+
import { CountBadge } from '../../primitives/count-badge.js';
|
|
20
|
+
import { EmptyState } from '../../primitives/empty-state.js';
|
|
21
|
+
import { useOptionalSidebar } from '../../primitives/sidebar.js';
|
|
22
|
+
import { Tabs, TabsList, TabsTrigger } from '../../primitives/tabs.js';
|
|
23
|
+
import { UserAvatar } from '../../primitives/user-avatar.js';
|
|
24
|
+
import { SpaceTabMenu } from './space-tab-menu.js';
|
|
25
|
+
import { SpaceTabPanel, useTabLabel } from './space-tab-panels.js';
|
|
26
|
+
/** The key of the room tab, always first. */
|
|
27
|
+
export const ROOM_TAB = 'room';
|
|
28
|
+
/** How many faces a pile shows before "+N". */
|
|
29
|
+
const PILE = 4;
|
|
30
|
+
/** The tabs a viewer sees, in order: a tab of a feature the project has off is hidden. */
|
|
31
|
+
export function visibleSpaceTabs(space, flags) {
|
|
32
|
+
return spaceTabs(space)
|
|
33
|
+
.map((tab, index) => ({ key: spaceTabKey(tab, index), tab, index }))
|
|
34
|
+
.filter(({ tab }) => {
|
|
35
|
+
if (tab.type === 'goals')
|
|
36
|
+
return flags.goals;
|
|
37
|
+
if (tab.type === 'artifacts' || tab.type === 'artifact')
|
|
38
|
+
return flags.artifacts;
|
|
39
|
+
return true;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* /projects/[id]/spaces/[slug]: a space is a channel. One header block: the
|
|
44
|
+
* title bar names it and shows what `spaces.<slug>.header` picks (its agents,
|
|
45
|
+
* the people in its room, the sessions that wait on you, and the actions),
|
|
46
|
+
* and the tabs sit directly under it. The first tab is always the room; the
|
|
47
|
+
* tabs after it come from `spaces.<slug>.tabs`. `?tab=` deep links a tab.
|
|
48
|
+
* The "+" menu and Edit tabs write the same manifest list.
|
|
49
|
+
*/
|
|
50
|
+
export function SpacePage({ projectId, slug }) {
|
|
51
|
+
const t = useTranslations('spaces');
|
|
52
|
+
const config = useProjectConfig(projectId);
|
|
53
|
+
const goalsOn = useFeatureFlag(projectId, 'goals').enabled;
|
|
54
|
+
const artifactsOn = useFeatureFlag(projectId, 'artifacts').enabled;
|
|
55
|
+
const canWrite = useProjectCan(projectId, PROJECT_ACTIONS.PROJECT_FILE_WRITE).allowed === true;
|
|
56
|
+
const router = useUiRouter();
|
|
57
|
+
const pathname = useUiPathname();
|
|
58
|
+
const params = useUiSearchParams();
|
|
59
|
+
const space = config ? listSpaces(config).find((candidate) => candidate.name === slug) : undefined;
|
|
60
|
+
if (!config)
|
|
61
|
+
return _jsx(ProjectPageHeader, { title: `# ${slug}` });
|
|
62
|
+
if (!space) {
|
|
63
|
+
return (_jsxs("div", { className: "flex h-svh flex-col overflow-hidden", children: [_jsx(ProjectPageHeader, { title: `# ${slug}` }), _jsx("div", { className: "flex flex-1 items-center justify-center px-4", children: _jsx(EmptyState, { title: t('gone.title'), description: t('gone.hint'), action: _jsx(Button, { asChild: true, size: "sm", variant: "outline", children: _jsx(Link, { href: uiRoutes().project(projectId), children: t('gone.back') }) }) }) })] }));
|
|
64
|
+
}
|
|
65
|
+
const tabs = visibleSpaceTabs(space, { goals: goalsOn, artifacts: artifactsOn });
|
|
66
|
+
const requested = params.get('tab');
|
|
67
|
+
const active = tabs.some((entry) => entry.key === requested) ? requested : ROOM_TAB;
|
|
68
|
+
const selectTab = (key) => {
|
|
69
|
+
router.replace(key === ROOM_TAB ? pathname : `${pathname}?tab=${encodeURIComponent(key)}`);
|
|
70
|
+
};
|
|
71
|
+
return (_jsxs("div", { className: "flex h-svh flex-col overflow-hidden", children: [_jsx(SpaceHeader, { projectId: projectId, space: space }), _jsxs(Tabs, { value: active, onValueChange: selectTab, className: "flex min-h-0 flex-1 flex-col gap-0", children: [_jsxs(TabsList, { type: "underline", className: "w-full shrink-0 justify-start overflow-x-auto px-5", children: [_jsx(TabsTrigger, { value: ROOM_TAB, className: "w-fit flex-none", children: t('tabs.room') }), tabs.map((entry) => (_jsx(SpaceTabTrigger, { value: entry.key, tab: entry.tab }, entry.key))), canWrite ? (_jsx(SpaceTabMenu, { projectId: projectId, space: space, onAdded: selectTab, children: _jsx(Button, { size: "icon-xs", variant: "ghost", "aria-label": t('addTab'), className: "ml-1 shrink-0", children: _jsx(PlusIcon, {}) }) })) : null] }), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", children: _jsx(SpaceTabPanel, { projectId: projectId, space: space, tab: active === ROOM_TAB ? null : (tabs.find((entry) => entry.key === active)?.tab ?? null) }) })] })] }));
|
|
72
|
+
}
|
|
73
|
+
function SpaceTabTrigger({ value, tab }) {
|
|
74
|
+
const label = useTabLabel(tab);
|
|
75
|
+
return (_jsx(TabsTrigger, { value: value, className: "w-fit flex-none", children: label }));
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The space's one header row, in the title bar: `#` and the name (the page's
|
|
79
|
+
* `<h1>`), the description beside it when the row has room, then the items
|
|
80
|
+
* `spaces.<slug>.header` picks, in its order. It wears the title-bar classes
|
|
81
|
+
* of `ProjectPageHeader`, so it clears the desktop window controls the same
|
|
82
|
+
* way. Below `@3xl` the action buttons drop their labels.
|
|
83
|
+
*/
|
|
84
|
+
function SpaceHeader({ projectId, space }) {
|
|
85
|
+
const config = useProjectConfig(projectId);
|
|
86
|
+
const sidebar = useOptionalSidebar();
|
|
87
|
+
const roomsOn = useFeatureFlag(projectId, 'agent_rooms').enabled;
|
|
88
|
+
// `builtin_agents.my_kortix: false` turns My Kortix off: no Ask button then.
|
|
89
|
+
const items = spaceHeader(space).filter((item) => item !== 'ask_my_kortix' || config?.builtin_agents?.my_kortix !== false);
|
|
90
|
+
const agents = agentsInSpace(space.name, config?.agents ?? []);
|
|
91
|
+
const strip = [];
|
|
92
|
+
for (const item of items) {
|
|
93
|
+
if (item === 'agents' && agents.length)
|
|
94
|
+
strip.push(_jsx(SpaceAgents, { projectId: projectId, agents: agents }, item));
|
|
95
|
+
if (item === 'members' && roomsOn)
|
|
96
|
+
strip.push(_jsx(SpaceMembers, { projectId: projectId, slug: space.name }, item));
|
|
97
|
+
if (item === 'needs_you')
|
|
98
|
+
strip.push(_jsx(SpaceNeedsYou, { projectId: projectId, agents: agents }, item));
|
|
99
|
+
}
|
|
100
|
+
// The primary action sits on the trailing edge, whatever the config order.
|
|
101
|
+
const actions = [
|
|
102
|
+
items.includes('ask_my_kortix') ? _jsx(AskMyKortix, { projectId: projectId, space: space }, "ask") : null,
|
|
103
|
+
items.includes('new_session') ? _jsx(NewSessionInSpace, { projectId: projectId, slug: space.name }, "new") : null,
|
|
104
|
+
].filter(Boolean);
|
|
105
|
+
return (_jsxs("header", { className: "kx-titlebar-row kx-capability-titlebar @container/space-header relative flex shrink-0 items-center gap-1 px-2", "data-sidebar-collapsed": sidebar?.state === 'collapsed' || undefined, children: [_jsx(SidebarToggle, {}), _jsxs("div", { className: "kx-titlebar-tabs flex h-10 min-w-0 flex-1 items-center gap-2.5 px-3", children: [_jsxs("h1", { className: "text-foreground flex min-w-0 shrink-0 items-center gap-1 text-sm font-medium", children: [_jsx(HashIcon, { "aria-hidden": true, className: "text-muted-foreground size-4 shrink-0" }), _jsx("span", { className: "max-w-60 truncate", children: space.label || space.name })] }), space.description ? (_jsx("p", { className: "text-muted-foreground hidden min-w-0 truncate text-xs @2xl/space-header:block", children: space.description })) : null] }), strip.length || actions.length ? (_jsxs("div", { className: "flex shrink-0 items-center gap-3 pr-1", children: [strip, actions.length ? _jsx("div", { className: "flex items-center gap-1", children: actions }) : null] })) : null] }));
|
|
106
|
+
}
|
|
107
|
+
function SpaceAgents({ projectId, agents }) {
|
|
108
|
+
const t = useTranslations('spaces');
|
|
109
|
+
return (_jsxs("span", { role: "group", "aria-label": t('agents'), className: "flex items-center -space-x-1", children: [agents.slice(0, PILE).map((name) => (_jsx(Link, { href: agentHref(projectId, name), className: "rounded-sm", "aria-label": t('openAgent', { name }), children: _jsx(AgentMark, { slug: name, tile: 22, className: "ring-background ring-2" }) }, name))), agents.length > PILE ? _jsx(PileMore, { count: agents.length - PILE }) : null] }));
|
|
110
|
+
}
|
|
111
|
+
function PileMore({ count }) {
|
|
112
|
+
return (_jsxs("span", { className: "bg-muted text-muted-foreground ring-background relative flex h-6 min-w-6 items-center justify-center rounded-sm px-1 text-xs tabular-nums ring-2", children: ["+", count] }));
|
|
113
|
+
}
|
|
114
|
+
/** The people in the space's room, as a face pile. Nothing before the room exists. */
|
|
115
|
+
function SpaceMembers({ projectId, slug }) {
|
|
116
|
+
const t = useTranslations('spaces');
|
|
117
|
+
const room = useSpaceRoom(projectId, slug);
|
|
118
|
+
const detail = useRoom(projectId, room.data?.room_id ?? null);
|
|
119
|
+
const people = (detail.data?.members ?? []).filter((member) => member.kind === 'person');
|
|
120
|
+
if (!people.length)
|
|
121
|
+
return null;
|
|
122
|
+
return (_jsxs("span", { role: "group", "aria-label": t('members', { count: people.length }), className: "flex items-center -space-x-1", children: [people.slice(0, PILE).map((person) => (_jsx(UserAvatar, { name: person.label, email: person.user_id ?? person.label, size: "sm", ring: true, hint: person.label }, person.member_id))), people.length > PILE ? _jsx(PileMore, { count: people.length - PILE }) : null] }));
|
|
123
|
+
}
|
|
124
|
+
/** The sessions of the space's agents that wait on the viewer. Hidden at 0. */
|
|
125
|
+
function SpaceNeedsYou({ projectId, agents }) {
|
|
126
|
+
const t = useTranslations('spaces');
|
|
127
|
+
const summary = useSessionsNeedingInput(projectId, { enabled: agents.length > 0 });
|
|
128
|
+
const { sessions } = useProjectSessions(projectId, { enabled: agents.length > 0 && !!summary.data?.total });
|
|
129
|
+
const count = sessions
|
|
130
|
+
.filter((session) => session.agent_name && agents.includes(session.agent_name))
|
|
131
|
+
.reduce((sum, session) => sum + sessionNeedsInputCount(summary.data, session), 0);
|
|
132
|
+
if (!count)
|
|
133
|
+
return null;
|
|
134
|
+
const href = uiRoutes().sessions(projectId);
|
|
135
|
+
const body = (_jsxs(_Fragment, { children: [_jsx(CountBadge, { count: count, tone: "waiting" }), _jsx("span", { className: "text-foreground text-xs", children: t('needsYou') })] }));
|
|
136
|
+
return href ? (_jsx(Link, { href: href, className: "hover:bg-hover flex h-7 items-center gap-1.5 rounded-md px-1.5 transition-colors", children: body })) : (_jsx("span", { className: "flex items-center gap-1.5", children: body }));
|
|
137
|
+
}
|
|
138
|
+
function NewSessionInSpace({ projectId, slug }) {
|
|
139
|
+
const t = useTranslations('spaces');
|
|
140
|
+
const router = useUiRouter();
|
|
141
|
+
const [, setActive] = useActiveSpace(projectId);
|
|
142
|
+
return (_jsxs(Button, { size: "sm", "aria-label": t('newSession'), onClick: () => {
|
|
143
|
+
// The project home with the space active: the composer starts only this space's agents.
|
|
144
|
+
setActive(slug);
|
|
145
|
+
router.push(uiRoutes().project(projectId));
|
|
146
|
+
}, children: [_jsx(PlusIcon, {}), _jsx("span", { className: "hidden @3xl/space-header:inline", children: t('newSession') })] }));
|
|
147
|
+
}
|
|
148
|
+
function AskMyKortix({ projectId, space }) {
|
|
149
|
+
const t = useTranslations('spaces');
|
|
150
|
+
const configure = useConfigureThread(projectId);
|
|
151
|
+
return (_jsxs(Button, { size: "sm", variant: "ghost", "aria-label": t('askMyKortix'), disabled: configure.pending, "aria-busy": configure.pending || undefined, onClick: () => configure.start({
|
|
152
|
+
text: t('askPrompt', { name: space.label || space.name, slug: space.name }),
|
|
153
|
+
agent: MY_KORTIX_AGENT_NAME,
|
|
154
|
+
model: null,
|
|
155
|
+
variant: null,
|
|
156
|
+
}), children: [_jsx(AgentMark, { slug: MY_KORTIX_AGENT_NAME }), _jsx("span", { className: "hidden @3xl/space-header:inline", children: t('askMyKortix') })] }));
|
|
157
|
+
}
|