@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
|
@@ -59,6 +59,11 @@ export interface WebNotificationPayload {
|
|
|
59
59
|
notificationCenter?: boolean;
|
|
60
60
|
}
|
|
61
61
|
export declare function setServerPushPreferences(kinds: NotificationPreferences['kinds'] | null | undefined): void;
|
|
62
|
+
/**
|
|
63
|
+
* The payload names a project and the URL shows a different one. Both sides
|
|
64
|
+
* must be known: on a page outside any project this answers false.
|
|
65
|
+
*/
|
|
66
|
+
export declare function isOtherProject(projectId: string | null | undefined): boolean;
|
|
62
67
|
/**
|
|
63
68
|
* Check if the user is NOT actively looking at the app — either switched
|
|
64
69
|
* to another Chrome tab (`document.hidden`) or switched to another app
|
|
@@ -79,6 +84,12 @@ export declare function spacesThreadHref(location: {
|
|
|
79
84
|
sessionId: string;
|
|
80
85
|
projectId: string | null | undefined;
|
|
81
86
|
}, cache: QueryClient): string | null;
|
|
87
|
+
/**
|
|
88
|
+
* Report a session as on screen while a surface shows it outside its route,
|
|
89
|
+
* such as a side sheet. Takes the Kortix `session_id`. Returns the cleanup. A
|
|
90
|
+
* session registered twice stays on screen until both cleanups run.
|
|
91
|
+
*/
|
|
92
|
+
export declare function markSessionOnScreen(sessionId: string): () => void;
|
|
82
93
|
/**
|
|
83
94
|
* Check if the user is currently viewing a specific session.
|
|
84
95
|
* Checks the tab store (dashboard session tabs) and the current URL
|
|
@@ -92,6 +103,35 @@ export declare function isViewingSession(sessionId: string): boolean;
|
|
|
92
103
|
* Check if the browser supports the Notification API.
|
|
93
104
|
*/
|
|
94
105
|
export declare function isNotificationSupported(): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* The one policy for the in-app channels and the OS gate. `os` answers only
|
|
108
|
+
* for what is on screen and which project it is: `sendWebNotification` keeps
|
|
109
|
+
* the permission, preference, kind and `onlyWhenHidden` gates.
|
|
110
|
+
*
|
|
111
|
+
* - Another project wins: no toast and no sound. A finished or failed turn
|
|
112
|
+
* marks the favicon dot. The OS fires only while the window is in the
|
|
113
|
+
* background.
|
|
114
|
+
* - The session on screen gets no toast of any kind, with or without focus:
|
|
115
|
+
* the chat shows it. A question or a permission keeps its sound: the agent
|
|
116
|
+
* is blocked.
|
|
117
|
+
* - The dot needs a session id, because the attention store is per session.
|
|
118
|
+
*/
|
|
119
|
+
export declare function notificationChannels(input: {
|
|
120
|
+
type: WebNotificationType;
|
|
121
|
+
/** The payload names a session. */
|
|
122
|
+
hasSession: boolean;
|
|
123
|
+
/** That session is on screen, whichever window has focus. */
|
|
124
|
+
sessionOnScreen: boolean;
|
|
125
|
+
/** The window is visible and has focus (`!isTabHidden()`). */
|
|
126
|
+
windowFocused: boolean;
|
|
127
|
+
/** `isOtherProject(payload.projectId)`. */
|
|
128
|
+
otherProject: boolean;
|
|
129
|
+
}): {
|
|
130
|
+
toast: boolean;
|
|
131
|
+
sound: boolean;
|
|
132
|
+
attention: boolean;
|
|
133
|
+
os: boolean;
|
|
134
|
+
};
|
|
95
135
|
/**
|
|
96
136
|
* Send a browser web notification, respecting user preferences.
|
|
97
137
|
*
|
|
@@ -100,6 +140,26 @@ export declare function isNotificationSupported(): boolean;
|
|
|
100
140
|
export declare function sendWebNotification(payload: WebNotificationPayload,
|
|
101
141
|
/** Skip all preference/permission gates (used for test notifications) */
|
|
102
142
|
force?: boolean): Notification | null;
|
|
143
|
+
/** What a toast on screen is about. */
|
|
144
|
+
type ToastSubject = {
|
|
145
|
+
sessionId?: string | null;
|
|
146
|
+
projectId?: string | null;
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Whether a toast on screen no longer qualifies: its session is on screen, or
|
|
150
|
+
* its project is another project. A toast about another session of the project
|
|
151
|
+
* on screen stays. Pure: `view` answers for the screen.
|
|
152
|
+
*/
|
|
153
|
+
export declare function isStaleToast(toast: ToastSubject, view: {
|
|
154
|
+
onScreen: (sessionId: string) => boolean;
|
|
155
|
+
otherProject: (projectId: string | null | undefined) => boolean;
|
|
156
|
+
}): boolean;
|
|
157
|
+
/**
|
|
158
|
+
* Dismiss every notification toast that no longer qualifies, after the screen
|
|
159
|
+
* moved to another route or tab. A stack drops those items: the rest stay as a
|
|
160
|
+
* stack, or as a single toast when one remains.
|
|
161
|
+
*/
|
|
162
|
+
export declare function dismissStaleNotificationToasts(): void;
|
|
103
163
|
/** The in-app toast alone — no sound, badge or OS notification (an inbox arrival). */
|
|
104
164
|
export declare const showInAppNotification: (payload: WebNotificationPayload) => void;
|
|
105
165
|
/**
|
|
@@ -118,10 +178,11 @@ export declare function sessionDisplayName(sessionTitle: string | undefined, ses
|
|
|
118
178
|
* never receives its own broadcast, so nothing doubles locally.
|
|
119
179
|
*/
|
|
120
180
|
export declare function notifyTaskComplete(sessionId: string, sessionTitle: string | undefined, tI18nComplete: UiTranslator,
|
|
121
|
-
/**
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
|
|
181
|
+
/** `projectId`: the session's project, from the SDK's live stream or its
|
|
182
|
+
* turn-end watch. The page on screen may belong to another project.
|
|
183
|
+
* `watchedSinceMs`: set only when the watch found this end, because the
|
|
184
|
+
* session page was not mounted here: when the watch started. */
|
|
185
|
+
extra?: {
|
|
125
186
|
watchedSinceMs?: number;
|
|
126
187
|
projectId?: string;
|
|
127
188
|
}): void;
|
|
@@ -135,13 +196,18 @@ export declare function notifyTaskCompleteFor({ sessionId, sessionTitle, project
|
|
|
135
196
|
* Notify that a session encountered an error.
|
|
136
197
|
*/
|
|
137
198
|
export declare function notifySessionError(sessionId: string, errorTitle: string, sessionTitle: string | undefined, tI18nComplete: UiTranslator,
|
|
138
|
-
/** The session's project, from the SDK
|
|
139
|
-
|
|
199
|
+
/** The session's project, from the SDK (see `notifyTaskComplete`). */
|
|
200
|
+
projectId?: string): void;
|
|
140
201
|
/**
|
|
141
202
|
* Notify that Kortix is asking the user a question.
|
|
142
203
|
*/
|
|
143
|
-
export declare function notifyQuestion(sessionId: string, questionText: string, sessionTitle: string | undefined, tI18nComplete: UiTranslator
|
|
204
|
+
export declare function notifyQuestion(sessionId: string, questionText: string, sessionTitle: string | undefined, tI18nComplete: UiTranslator,
|
|
205
|
+
/** The session's project, from the SDK (see `notifyTaskComplete`). */
|
|
206
|
+
projectId?: string): void;
|
|
144
207
|
/**
|
|
145
208
|
* Notify that Kortix needs a permission grant.
|
|
146
209
|
*/
|
|
147
|
-
export declare function notifyPermissionRequest(sessionId: string, toolName: string, sessionTitle: string | undefined, tI18nComplete: UiTranslator
|
|
210
|
+
export declare function notifyPermissionRequest(sessionId: string, toolName: string, sessionTitle: string | undefined, tI18nComplete: UiTranslator,
|
|
211
|
+
/** The session's project, from the SDK (see `notifyTaskComplete`). */
|
|
212
|
+
projectId?: string): void;
|
|
213
|
+
export {};
|
|
@@ -5,12 +5,12 @@ import { createElement } from 'react';
|
|
|
5
5
|
* Provides a thin wrapper around the browser Notification API that respects
|
|
6
6
|
* the user's preferences stored in the web-notification-store.
|
|
7
7
|
*
|
|
8
|
-
* All notification dispatching flows through `sendWebNotification()`.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* in-app
|
|
12
|
-
* profile must still see that a turn
|
|
13
|
-
* additionally checks:
|
|
8
|
+
* All notification dispatching flows through `sendWebNotification()`.
|
|
9
|
+
* `notificationChannels()` decides the toast, the sound, the favicon dot and
|
|
10
|
+
* the OS gate from one table: a toast belongs to the project on screen, and
|
|
11
|
+
* never to the session on screen. The in-app channels have no permission or
|
|
12
|
+
* preference prerequisite: a default profile must still see that a turn
|
|
13
|
+
* finished. The native OS notification additionally checks:
|
|
14
14
|
* 1. Browser support for the Notification API
|
|
15
15
|
* 2. Permission is granted
|
|
16
16
|
* 3. Master enable toggle is on
|
|
@@ -41,6 +41,7 @@ import { broadcastTurnComplete, noteTurnCompleteShown, turnCompleteShownSince, }
|
|
|
41
41
|
import { getSharedQueryClient } from './query-client-singleton.js';
|
|
42
42
|
import { playSound } from './sounds.js';
|
|
43
43
|
import { openTabAndNavigate, useTabStore } from '../stores/tab-store.js';
|
|
44
|
+
import { projectIdFromPathname } from '../stores/project-switch-store.js';
|
|
44
45
|
import { useTurnAttentionStore } from '../stores/turn-attention-store.js';
|
|
45
46
|
import { useWebNotificationStore } from '../stores/web-notification-store.js';
|
|
46
47
|
import { listChangeRequests, normalizeAppPathname, } from '@kortix/sdk';
|
|
@@ -113,19 +114,32 @@ const TYPE_TO_SOUND = {
|
|
|
113
114
|
// Core
|
|
114
115
|
// ============================================================================
|
|
115
116
|
/**
|
|
116
|
-
* The project
|
|
117
|
-
*
|
|
117
|
+
* The project in the URL. The fallback for an event that names no project: the
|
|
118
|
+
* SDK names the project whenever its stream knows it, because the URL may
|
|
119
|
+
* already show the next project when the event lands.
|
|
118
120
|
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
121
|
+
* It is read when the notification is RAISED, not when it is clicked. By the
|
|
122
|
+
* time they click, minutes later, the person may be anywhere, so reading the
|
|
123
|
+
* path at click time would resolve the wrong project or none at all.
|
|
124
|
+
*
|
|
125
|
+
* An optional two-letter locale segment leads (`/de/projects/…`).
|
|
126
|
+
* `/projects/new` and `/projects/start` are pages, not projects.
|
|
123
127
|
*/
|
|
124
128
|
function currentProjectId() {
|
|
125
129
|
if (typeof window === 'undefined')
|
|
126
130
|
return null;
|
|
127
|
-
const
|
|
128
|
-
return
|
|
131
|
+
const path = normalizeAppPathname(window.location.pathname);
|
|
132
|
+
return projectIdFromPathname(path.replace(/^\/[a-z]{2}(?=\/projects(?:\/|$))/, ''));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The payload names a project and the URL shows a different one. Both sides
|
|
136
|
+
* must be known: on a page outside any project this answers false.
|
|
137
|
+
*/
|
|
138
|
+
export function isOtherProject(projectId) {
|
|
139
|
+
if (!projectId)
|
|
140
|
+
return false;
|
|
141
|
+
const current = currentProjectId();
|
|
142
|
+
return current !== null && current !== projectId;
|
|
129
143
|
}
|
|
130
144
|
/**
|
|
131
145
|
* Navigate to a session by opening/activating its tab and navigating to it.
|
|
@@ -197,6 +211,24 @@ export function spacesThreadHref(location, session, cache) {
|
|
|
197
211
|
params.set('thread', session.sessionId);
|
|
198
212
|
return `${location.pathname}?${params.toString()}`;
|
|
199
213
|
}
|
|
214
|
+
/** Mounts per session of a surface that shows it outside its route. */
|
|
215
|
+
const sessionsOnScreen = new Map();
|
|
216
|
+
/**
|
|
217
|
+
* Report a session as on screen while a surface shows it outside its route,
|
|
218
|
+
* such as a side sheet. Takes the Kortix `session_id`. Returns the cleanup. A
|
|
219
|
+
* session registered twice stays on screen until both cleanups run.
|
|
220
|
+
*/
|
|
221
|
+
export function markSessionOnScreen(sessionId) {
|
|
222
|
+
sessionsOnScreen.set(sessionId, (sessionsOnScreen.get(sessionId) ?? 0) + 1);
|
|
223
|
+
dismissStaleNotificationToasts();
|
|
224
|
+
return () => {
|
|
225
|
+
const count = (sessionsOnScreen.get(sessionId) ?? 1) - 1;
|
|
226
|
+
if (count > 0)
|
|
227
|
+
sessionsOnScreen.set(sessionId, count);
|
|
228
|
+
else
|
|
229
|
+
sessionsOnScreen.delete(sessionId);
|
|
230
|
+
};
|
|
231
|
+
}
|
|
200
232
|
/**
|
|
201
233
|
* Check if the user is currently viewing a specific session.
|
|
202
234
|
* Checks the tab store (dashboard session tabs) and the current URL
|
|
@@ -206,6 +238,9 @@ export function spacesThreadHref(location, session, cache) {
|
|
|
206
238
|
* whatever session the user is looking at.
|
|
207
239
|
*/
|
|
208
240
|
export function isViewingSession(sessionId) {
|
|
241
|
+
// A mounted surface whose session id is in neither the URL nor the tab store.
|
|
242
|
+
if (sessionsOnScreen.has(sessionId))
|
|
243
|
+
return true;
|
|
209
244
|
// Dashboard: the active tab ID is the session ID for session tabs. The
|
|
210
245
|
// persisted tab ID can outlive navigation (the store never clears it when
|
|
211
246
|
// the user clicks elsewhere), so only trust it while the URL still agrees
|
|
@@ -241,6 +276,41 @@ export function isViewingSession(sessionId) {
|
|
|
241
276
|
export function isNotificationSupported() {
|
|
242
277
|
return typeof window !== 'undefined' && 'Notification' in window;
|
|
243
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* The one policy for the in-app channels and the OS gate. `os` answers only
|
|
281
|
+
* for what is on screen and which project it is: `sendWebNotification` keeps
|
|
282
|
+
* the permission, preference, kind and `onlyWhenHidden` gates.
|
|
283
|
+
*
|
|
284
|
+
* - Another project wins: no toast and no sound. A finished or failed turn
|
|
285
|
+
* marks the favicon dot. The OS fires only while the window is in the
|
|
286
|
+
* background.
|
|
287
|
+
* - The session on screen gets no toast of any kind, with or without focus:
|
|
288
|
+
* the chat shows it. A question or a permission keeps its sound: the agent
|
|
289
|
+
* is blocked.
|
|
290
|
+
* - The dot needs a session id, because the attention store is per session.
|
|
291
|
+
*/
|
|
292
|
+
export function notificationChannels(input) {
|
|
293
|
+
const { type, hasSession, windowFocused } = input;
|
|
294
|
+
const completion = type === 'completion';
|
|
295
|
+
const error = type === 'error';
|
|
296
|
+
if (input.otherProject) {
|
|
297
|
+
return {
|
|
298
|
+
toast: false,
|
|
299
|
+
sound: false,
|
|
300
|
+
attention: hasSession && (completion || error),
|
|
301
|
+
os: !windowFocused,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
const blocking = type === 'question' || type === 'permission';
|
|
305
|
+
const onScreen = hasSession && input.sessionOnScreen;
|
|
306
|
+
const watching = windowFocused && (onScreen || !hasSession);
|
|
307
|
+
return {
|
|
308
|
+
toast: !onScreen && (error || !watching),
|
|
309
|
+
sound: blocking || !watching,
|
|
310
|
+
attention: hasSession && completion && !watching,
|
|
311
|
+
os: !(windowFocused && onScreen),
|
|
312
|
+
};
|
|
313
|
+
}
|
|
244
314
|
/**
|
|
245
315
|
* Send a browser web notification, respecting user preferences.
|
|
246
316
|
*
|
|
@@ -251,34 +321,30 @@ export function sendWebNotification(payload,
|
|
|
251
321
|
force = false) {
|
|
252
322
|
const { preferences } = useWebNotificationStore.getState();
|
|
253
323
|
const notificationCenter = fromNotificationCenter(payload);
|
|
254
|
-
//
|
|
255
|
-
//
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
324
|
+
// `force` (the settings test button) never counts as on screen, focused or
|
|
325
|
+
// another project: it exists to prove the channels work.
|
|
326
|
+
const { sessionId } = payload;
|
|
327
|
+
const channels = notificationChannels({
|
|
328
|
+
type: payload.type,
|
|
329
|
+
hasSession: !!sessionId,
|
|
330
|
+
sessionOnScreen: !force && !!sessionId && isViewingSession(sessionId),
|
|
331
|
+
windowFocused: !force && !isTabHidden(),
|
|
332
|
+
otherProject: !force && isOtherProject(payload.projectId),
|
|
333
|
+
});
|
|
259
334
|
// The in-app channels come first and answer to nobody: the toast is the one
|
|
260
335
|
// channel that works on a default profile — permission untouched, browser
|
|
261
336
|
// notifications disabled — which is exactly where the completion signal
|
|
262
337
|
// used to die (the old permission gates returned before the toast ran).
|
|
263
|
-
|
|
264
|
-
// error is noticed. A finished turn does not: the chat already shows it.
|
|
265
|
-
if (!watching || payload.type === 'error')
|
|
338
|
+
if (channels.toast)
|
|
266
339
|
showInAppToast(payload);
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
useTurnAttentionStore.getState().markTurnComplete(payload.sessionId);
|
|
272
|
-
}
|
|
340
|
+
// The toast fades after 8 s; the favicon badge is what a returning user
|
|
341
|
+
// still sees.
|
|
342
|
+
if (channels.attention && sessionId) {
|
|
343
|
+
useTurnAttentionStore.getState().markTurnComplete(sessionId);
|
|
273
344
|
}
|
|
274
345
|
// Sound plays independently of browser notification preferences — the sound
|
|
275
|
-
// store has its own pack/event/volume settings to control it.
|
|
276
|
-
|
|
277
|
-
// session (the agent is blocked); everything else only plays when the
|
|
278
|
-
// session is not being watched.
|
|
279
|
-
const isBlockingType = payload.type === 'question' || payload.type === 'permission';
|
|
280
|
-
const skipSound = !isBlockingType && watching;
|
|
281
|
-
if (!skipSound && (force || preferences.playSound !== false)) {
|
|
346
|
+
// store has its own pack/event/volume settings to control it.
|
|
347
|
+
if (channels.sound && (force || preferences.playSound !== false)) {
|
|
282
348
|
playSound(TYPE_TO_SOUND[payload.type]);
|
|
283
349
|
}
|
|
284
350
|
// The OS notification keeps every gate it had: a browser without the
|
|
@@ -303,12 +369,9 @@ force = false) {
|
|
|
303
369
|
if (prefKey && !preferences[prefKey])
|
|
304
370
|
return null;
|
|
305
371
|
}
|
|
306
|
-
//
|
|
307
|
-
|
|
308
|
-
// inline in the chat).
|
|
309
|
-
if (payload.sessionId && !isTabHidden() && isViewingSession(payload.sessionId)) {
|
|
372
|
+
// On-screen and other-project check: see `notificationChannels`.
|
|
373
|
+
if (!channels.os)
|
|
310
374
|
return null;
|
|
311
|
-
}
|
|
312
375
|
// Visibility check — questions and permissions always show since the
|
|
313
376
|
// agent is blocked waiting for user input
|
|
314
377
|
const isBlocking = payload.type === 'question' || payload.type === 'permission';
|
|
@@ -436,6 +499,48 @@ function openPayload(payload, forceNavigation) {
|
|
|
436
499
|
softNavigate(payload.href);
|
|
437
500
|
}
|
|
438
501
|
}
|
|
502
|
+
/**
|
|
503
|
+
* Whether a toast on screen no longer qualifies: its session is on screen, or
|
|
504
|
+
* its project is another project. A toast about another session of the project
|
|
505
|
+
* on screen stays. Pure: `view` answers for the screen.
|
|
506
|
+
*/
|
|
507
|
+
export function isStaleToast(toast, view) {
|
|
508
|
+
return (!!toast.sessionId && view.onScreen(toast.sessionId)) || view.otherProject(toast.projectId);
|
|
509
|
+
}
|
|
510
|
+
const toastView = () => ({ onScreen: isViewingSession, otherProject: isOtherProject });
|
|
511
|
+
/**
|
|
512
|
+
* The bound of `liveToasts`. A toast that never mounts never closes, so its
|
|
513
|
+
* entry would stay: the oldest entry leaves first.
|
|
514
|
+
*/
|
|
515
|
+
const MAX_LIVE_TOASTS = 32;
|
|
516
|
+
/** The generic notification toasts on screen. Session cards: `shownSessionToasts`. */
|
|
517
|
+
const liveToasts = new Map();
|
|
518
|
+
function trackLiveToast(toast) {
|
|
519
|
+
// Nothing can make it stale.
|
|
520
|
+
if (!toast.sessionId && !toast.projectId)
|
|
521
|
+
return;
|
|
522
|
+
liveToasts.delete(toast.id);
|
|
523
|
+
liveToasts.set(toast.id, toast);
|
|
524
|
+
if (liveToasts.size > MAX_LIVE_TOASTS)
|
|
525
|
+
liveToasts.delete(liveToasts.keys().next().value);
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Dismiss every notification toast that no longer qualifies, after the screen
|
|
529
|
+
* moved to another route or tab. A stack drops those items: the rest stay as a
|
|
530
|
+
* stack, or as a single toast when one remains.
|
|
531
|
+
*/
|
|
532
|
+
export function dismissStaleNotificationToasts() {
|
|
533
|
+
const view = toastView();
|
|
534
|
+
for (const toast of [...liveToasts.values()]) {
|
|
535
|
+
if (!isStaleToast(toast, view))
|
|
536
|
+
continue;
|
|
537
|
+
liveToasts.delete(toast.id);
|
|
538
|
+
dismissToast(toast.id);
|
|
539
|
+
}
|
|
540
|
+
const kept = shownSessionToasts.filter((item) => !isStaleToast(item, view));
|
|
541
|
+
if (kept.length !== shownSessionToasts.length)
|
|
542
|
+
renderSessionToasts(kept);
|
|
543
|
+
}
|
|
439
544
|
/**
|
|
440
545
|
* Show an in-app toast notification.
|
|
441
546
|
* This always works regardless of OS notification settings.
|
|
@@ -449,8 +554,10 @@ function showInAppToast(payload) {
|
|
|
449
554
|
const id = `web-notification-${payload.tag ?? Date.now()}`;
|
|
450
555
|
const { sessionId, href, actionLabel } = payload;
|
|
451
556
|
const automation = payload.type === 'automation_failed' || payload.type === 'automation_recovered';
|
|
557
|
+
trackLiveToast({ id, sessionId, projectId: payload.projectId });
|
|
452
558
|
TOAST_BY_VARIANT[NOTIFICATION_TOAST_VARIANT[payload.type]](payload.inAppTitle ?? payload.title, {
|
|
453
559
|
id,
|
|
560
|
+
onClose: () => liveToasts.delete(id),
|
|
454
561
|
// With an entity row the subject is named there; the body is only the detail.
|
|
455
562
|
description: payload.entityLabel ? payload.preview : payload.body,
|
|
456
563
|
entity: payload.entityLabel
|
|
@@ -487,50 +594,72 @@ const SESSION_STACK_ID = 'web-notification-session-stack';
|
|
|
487
594
|
const singleSessionToastId = (sessionId) => `web-notification-session-${sessionId}`;
|
|
488
595
|
/**
|
|
489
596
|
* Show a finished (entity toast) or failed (agent card) turn. While one is on
|
|
490
|
-
* screen, the next turn replaces it with a stack listing both.
|
|
597
|
+
* screen, the next turn replaces it with a stack listing both. An item that no
|
|
598
|
+
* longer qualifies stays out of the stack.
|
|
491
599
|
*/
|
|
492
600
|
function showSessionToast(payload, sessionId) {
|
|
493
|
-
const
|
|
494
|
-
const
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
601
|
+
const view = toastView();
|
|
602
|
+
const previous = shownSessionToasts.filter((item) => item.sessionId !== sessionId && !isStaleToast(item, view));
|
|
603
|
+
renderSessionToasts([
|
|
604
|
+
...previous,
|
|
605
|
+
{
|
|
606
|
+
sessionId,
|
|
607
|
+
projectId: payload.projectId,
|
|
608
|
+
label: payload.entityLabel ?? payload.title,
|
|
609
|
+
failed: payload.type === 'error',
|
|
610
|
+
at: Date.now(),
|
|
611
|
+
payload,
|
|
612
|
+
},
|
|
613
|
+
]);
|
|
614
|
+
}
|
|
615
|
+
function openSessionToast(target) {
|
|
616
|
+
openPayload(target.payload, false);
|
|
617
|
+
target.payload.onClick?.();
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* Put `items` on screen: nothing, one single toast, or one stack. Any other
|
|
621
|
+
* session toast on screen leaves.
|
|
622
|
+
*/
|
|
623
|
+
function renderSessionToasts(items) {
|
|
624
|
+
const before = shownSessionToasts;
|
|
501
625
|
const generation = ++sessionToastGeneration;
|
|
502
626
|
const onClose = () => {
|
|
503
627
|
if (generation === sessionToastGeneration)
|
|
504
628
|
shownSessionToasts = [];
|
|
505
629
|
};
|
|
506
|
-
shownSessionToasts =
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
const openLabel = payload.actionLabel ?? 'Open';
|
|
512
|
-
if (previous.length > 0) {
|
|
513
|
-
for (const shown of previous)
|
|
630
|
+
shownSessionToasts = items;
|
|
631
|
+
const only = items.length === 1 ? items[0] : null;
|
|
632
|
+
// A dismissal lands a frame later, so the toast about to show is not dismissed.
|
|
633
|
+
for (const shown of before) {
|
|
634
|
+
if (shown.sessionId !== only?.sessionId)
|
|
514
635
|
dismissToast(singleSessionToastId(shown.sessionId));
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
onOpen: (id) => {
|
|
521
|
-
const target = items.find((shown) => shown.sessionId === id);
|
|
522
|
-
if (target)
|
|
523
|
-
open(target);
|
|
524
|
-
},
|
|
525
|
-
onDismiss: dismiss,
|
|
526
|
-
})), { id: SESSION_STACK_ID, duration: NOTIFICATION_VISIBLE_MS, onClose });
|
|
636
|
+
}
|
|
637
|
+
if (before.length > 1 && items.length < 2)
|
|
638
|
+
dismissToast(SESSION_STACK_ID);
|
|
639
|
+
if (only) {
|
|
640
|
+
showSingleSessionToast(only, onClose);
|
|
527
641
|
return;
|
|
528
642
|
}
|
|
643
|
+
if (items.length === 0)
|
|
644
|
+
return;
|
|
645
|
+
const { payload } = items[items.length - 1];
|
|
646
|
+
const openLabel = payload.actionLabel ?? 'Open';
|
|
647
|
+
customToast((dismiss) => (createElement(SessionStackCard, {
|
|
648
|
+
title: payload.stackTitle?.(items.length) ?? `${items.length} tasks finished`,
|
|
649
|
+
items,
|
|
650
|
+
openLabel,
|
|
651
|
+
onOpen: (id) => {
|
|
652
|
+
const target = items.find((shown) => shown.sessionId === id);
|
|
653
|
+
if (target)
|
|
654
|
+
openSessionToast(target);
|
|
655
|
+
},
|
|
656
|
+
onDismiss: dismiss,
|
|
657
|
+
})), { id: SESSION_STACK_ID, duration: NOTIFICATION_VISIBLE_MS, onClose });
|
|
658
|
+
}
|
|
659
|
+
function showSingleSessionToast(item, onClose) {
|
|
660
|
+
const { payload, sessionId } = item;
|
|
661
|
+
const openLabel = payload.actionLabel ?? 'Open';
|
|
529
662
|
const id = singleSessionToastId(sessionId);
|
|
530
|
-
// A toast for the session on screen (it fired while the window had no
|
|
531
|
-
// focus) names nothing and opens nothing: the person is already there.
|
|
532
|
-
// Read at render, so it follows where the person is now.
|
|
533
|
-
const elsewhere = () => !isViewingSession(sessionId);
|
|
534
663
|
const cr = payload.changeRequest;
|
|
535
664
|
// `?cr=` opens the change request's review dialog on the session page.
|
|
536
665
|
const review = () => {
|
|
@@ -543,10 +672,10 @@ function showSessionToast(payload, sessionId) {
|
|
|
543
672
|
if (item.failed) {
|
|
544
673
|
customToast((dismiss) => createElement(SessionFailedCard, {
|
|
545
674
|
title: payload.inAppTitle ?? payload.title,
|
|
546
|
-
label:
|
|
675
|
+
label: item.label,
|
|
547
676
|
detail: payload.preview,
|
|
548
677
|
openLabel,
|
|
549
|
-
onOpen:
|
|
678
|
+
onOpen: () => openSessionToast(item),
|
|
550
679
|
onDismiss: dismiss,
|
|
551
680
|
}), { id, duration: NOTIFICATION_VISIBLE_MS, onClose });
|
|
552
681
|
return;
|
|
@@ -555,23 +684,17 @@ function showSessionToast(payload, sessionId) {
|
|
|
555
684
|
message: payload.inAppTitle ?? payload.title,
|
|
556
685
|
icon: toastIcon('success'),
|
|
557
686
|
variant: 'success',
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
},
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
{ label: payload.openSessionLabel ?? openLabel, onClick: () => open(item) },
|
|
570
|
-
],
|
|
571
|
-
}
|
|
572
|
-
: cr
|
|
573
|
-
? { description: cr.detail }
|
|
574
|
-
: undefined,
|
|
687
|
+
options: {
|
|
688
|
+
entity: {
|
|
689
|
+
icon: cr ? createElement(GitPullRequestIcon, { className: 'size-3.5' }) : undefined,
|
|
690
|
+
label: item.label,
|
|
691
|
+
},
|
|
692
|
+
description: cr?.detail,
|
|
693
|
+
actions: [
|
|
694
|
+
...(cr ? [{ label: cr.reviewLabel, onClick: review }] : []),
|
|
695
|
+
{ label: payload.openSessionLabel ?? openLabel, onClick: () => openSessionToast(item) },
|
|
696
|
+
],
|
|
697
|
+
},
|
|
575
698
|
onDismiss: dismiss,
|
|
576
699
|
}), { id, duration: NOTIFICATION_VISIBLE_MS, onClose });
|
|
577
700
|
}
|
|
@@ -599,19 +722,20 @@ export function sessionDisplayName(sessionTitle, sessionId) {
|
|
|
599
722
|
* never receives its own broadcast, so nothing doubles locally.
|
|
600
723
|
*/
|
|
601
724
|
export function notifyTaskComplete(sessionId, sessionTitle, tI18nComplete,
|
|
602
|
-
/**
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
|
|
725
|
+
/** `projectId`: the session's project, from the SDK's live stream or its
|
|
726
|
+
* turn-end watch. The page on screen may belong to another project.
|
|
727
|
+
* `watchedSinceMs`: set only when the watch found this end, because the
|
|
728
|
+
* session page was not mounted here: when the watch started. */
|
|
729
|
+
extra) {
|
|
606
730
|
// Another tab's stream already announced this end and its relay reached
|
|
607
731
|
// this tab: the watch is the second announcer of the same end.
|
|
608
|
-
const since =
|
|
732
|
+
const since = extra?.watchedSinceMs;
|
|
609
733
|
if (since !== undefined && turnCompleteShownSince(sessionId, since))
|
|
610
734
|
return;
|
|
611
|
-
//
|
|
612
|
-
//
|
|
613
|
-
//
|
|
614
|
-
const projectId =
|
|
735
|
+
// Resolved here and relayed whole: a receiving tab may be on a page whose
|
|
736
|
+
// path holds no project id, and may never have loaded the project's
|
|
737
|
+
// `notification_center` flag.
|
|
738
|
+
const projectId = extra?.projectId ?? currentProjectId();
|
|
615
739
|
const msg = {
|
|
616
740
|
sessionId,
|
|
617
741
|
sessionTitle,
|
|
@@ -691,8 +815,8 @@ function openChangeRequestOf(projectId, sessionId) {
|
|
|
691
815
|
* Notify that a session encountered an error.
|
|
692
816
|
*/
|
|
693
817
|
export function notifySessionError(sessionId, errorTitle, sessionTitle, tI18nComplete,
|
|
694
|
-
/** The session's project, from the SDK
|
|
695
|
-
|
|
818
|
+
/** The session's project, from the SDK (see `notifyTaskComplete`). */
|
|
819
|
+
projectId) {
|
|
696
820
|
const name = sessionDisplayName(sessionTitle, sessionId);
|
|
697
821
|
const label = sessionTitle ? `"${name.slice(0, 50)}"` : name;
|
|
698
822
|
sendWebNotification({
|
|
@@ -705,17 +829,21 @@ projectIdOverride) {
|
|
|
705
829
|
tag: `error:${sessionId}`,
|
|
706
830
|
sessionId,
|
|
707
831
|
actionLabel: tI18nComplete.raw('texted077f3d8125'),
|
|
708
|
-
|
|
709
|
-
projectId: projectIdOverride ?? currentProjectId(),
|
|
832
|
+
projectId: projectId ?? currentProjectId(),
|
|
710
833
|
});
|
|
711
834
|
}
|
|
835
|
+
/** The session as a question or a permission names it in its body. */
|
|
836
|
+
function blockedSessionLabel(sessionTitle, sessionId) {
|
|
837
|
+
const name = sessionDisplayName(sessionTitle, sessionId);
|
|
838
|
+
return sessionTitle ? `"${name.slice(0, 40)}"` : name;
|
|
839
|
+
}
|
|
712
840
|
/**
|
|
713
841
|
* Notify that Kortix is asking the user a question.
|
|
714
842
|
*/
|
|
715
|
-
export function notifyQuestion(sessionId, questionText, sessionTitle, tI18nComplete
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
843
|
+
export function notifyQuestion(sessionId, questionText, sessionTitle, tI18nComplete,
|
|
844
|
+
/** The session's project, from the SDK (see `notifyTaskComplete`). */
|
|
845
|
+
projectId) {
|
|
846
|
+
const label = blockedSessionLabel(sessionTitle, sessionId);
|
|
719
847
|
sendWebNotification({
|
|
720
848
|
type: 'question',
|
|
721
849
|
title: tI18nComplete.raw('text6e8c98a8560e'),
|
|
@@ -723,17 +851,16 @@ export function notifyQuestion(sessionId, questionText, sessionTitle, tI18nCompl
|
|
|
723
851
|
tag: `question:${sessionId}`,
|
|
724
852
|
sessionId,
|
|
725
853
|
actionLabel: tI18nComplete.raw('texted077f3d8125'),
|
|
726
|
-
|
|
727
|
-
projectId: currentProjectId(),
|
|
854
|
+
projectId: projectId ?? currentProjectId(),
|
|
728
855
|
});
|
|
729
856
|
}
|
|
730
857
|
/**
|
|
731
858
|
* Notify that Kortix needs a permission grant.
|
|
732
859
|
*/
|
|
733
|
-
export function notifyPermissionRequest(sessionId, toolName, sessionTitle, tI18nComplete
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
860
|
+
export function notifyPermissionRequest(sessionId, toolName, sessionTitle, tI18nComplete,
|
|
861
|
+
/** The session's project, from the SDK (see `notifyTaskComplete`). */
|
|
862
|
+
projectId) {
|
|
863
|
+
const label = blockedSessionLabel(sessionTitle, sessionId);
|
|
737
864
|
sendWebNotification({
|
|
738
865
|
type: 'permission',
|
|
739
866
|
title: tI18nComplete.raw('text7e497182c7ed'),
|
|
@@ -741,7 +868,6 @@ export function notifyPermissionRequest(sessionId, toolName, sessionTitle, tI18n
|
|
|
741
868
|
tag: `permission:${sessionId}`,
|
|
742
869
|
sessionId,
|
|
743
870
|
actionLabel: tI18nComplete.raw('texted077f3d8125'),
|
|
744
|
-
|
|
745
|
-
projectId: currentProjectId(),
|
|
871
|
+
projectId: projectId ?? currentProjectId(),
|
|
746
872
|
});
|
|
747
873
|
}
|