@kortix/ui 0.14.8 → 0.14.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/_vendor/kortix-shared.js +63 -3
- package/dist/_vendor/shared/app-config.d.ts +175 -0
- package/dist/_vendor/shared/channel-message.d.ts +34 -5
- package/dist/_vendor/shared/index.d.ts +1 -0
- package/dist/_vendor/shared/space-slug.d.ts +37 -0
- package/dist/access/access/access-detail-shell.js +1 -1
- package/dist/access/access/principal-picker.d.ts +11 -0
- package/dist/access/access/principal-picker.js +3 -2
- package/dist/apps/app-preview-pool.d.ts +7 -2
- package/dist/apps/app-preview-pool.js +11 -5
- package/dist/apps/app-shared.d.ts +22 -15
- package/dist/apps/app-shared.js +37 -19
- package/dist/apps/index.d.ts +2 -2
- package/dist/apps/index.js +2 -2
- package/dist/artifacts/artifact-frame.d.ts +16 -0
- package/dist/artifacts/artifact-frame.js +51 -0
- package/dist/artifacts/artifact-session.d.ts +18 -0
- package/dist/artifacts/artifact-session.js +101 -0
- package/dist/artifacts/frame-policy.d.ts +30 -0
- package/dist/artifacts/frame-policy.js +61 -0
- package/dist/artifacts/index.d.ts +3 -0
- package/dist/artifacts/index.js +5 -0
- package/dist/browser/sandbox-browser-chrome.d.ts +4 -1
- package/dist/browser/sandbox-browser-chrome.js +2 -2
- package/dist/customize/agents/agent-grant-pages.d.ts +5 -1
- package/dist/customize/agents/agent-grant-pages.js +30 -4
- package/dist/customize/agents/agent-page.js +3 -1
- package/dist/customize/agents/agent-policy-sets.d.ts +43 -0
- package/dist/customize/agents/agent-policy-sets.js +72 -0
- package/dist/customize/agents/agent-triggers-section.js +2 -1
- package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.d.ts +6 -1
- package/dist/customize/connectors/add-mcp/add-mcp-server-dialog.js +10 -4
- package/dist/customize/connectors/agent-access.d.ts +35 -0
- package/dist/customize/connectors/agent-access.js +77 -0
- package/dist/customize/connectors/catalog/browse-sections.d.ts +2 -29
- package/dist/customize/connectors/catalog/browse-sections.js +7 -74
- package/dist/customize/connectors/catalog/catalog-entry.d.ts +18 -37
- package/dist/customize/connectors/catalog/catalog-entry.js +28 -40
- package/dist/customize/connectors/catalog/connector-browse.d.ts +3 -32
- package/dist/customize/connectors/catalog/connector-browse.js +19 -50
- package/dist/customize/connectors/catalog/use-catalog.d.ts +20 -59
- package/dist/customize/connectors/catalog/use-catalog.js +48 -175
- package/dist/customize/connectors/connector-identity.d.ts +9 -11
- package/dist/customize/connectors/connector-identity.js +13 -42
- package/dist/customize/connectors/connector-moves-banner.d.ts +2 -1
- package/dist/customize/connectors/connector-moves-banner.js +4 -6
- package/dist/customize/connectors/connector-routes.d.ts +21 -9
- package/dist/customize/connectors/connector-routes.js +29 -20
- package/dist/customize/connectors/connectors-page.js +53 -82
- package/dist/customize/connectors/detail/app-page.js +226 -98
- package/dist/customize/connectors/detail/computer-app-page.d.ts +16 -0
- package/dist/customize/connectors/detail/computer-app-page.js +39 -0
- package/dist/customize/connectors/detail/connector-accounts.js +3 -1
- package/dist/customize/connectors/detail/connector-advanced-tools.d.ts +4 -1
- package/dist/customize/connectors/detail/connector-advanced-tools.js +2 -2
- package/dist/customize/connectors/detail/connector-agents.d.ts +14 -0
- package/dist/customize/connectors/detail/connector-agents.js +69 -0
- package/dist/customize/connectors/detail/connector-detail-tabs.js +2 -1
- package/dist/customize/connectors/detail/connector-move-row.d.ts +8 -5
- package/dist/customize/connectors/detail/connector-move-row.js +23 -14
- package/dist/customize/connectors/detail/connector-page.d.ts +4 -1
- package/dist/customize/connectors/detail/connector-page.js +14 -10
- package/dist/customize/connectors/detail/connector-policy-sets.d.ts +28 -0
- package/dist/customize/connectors/detail/connector-policy-sets.js +203 -0
- package/dist/customize/connectors/detail/connector-settings.d.ts +4 -1
- package/dist/customize/connectors/detail/connector-settings.js +7 -3
- package/dist/customize/connectors/detail/connector-status.d.ts +19 -6
- package/dist/customize/connectors/detail/connector-status.js +34 -10
- package/dist/customize/connectors/detail/connector-tabs.d.ts +4 -1
- package/dist/customize/connectors/detail/connector-tabs.js +8 -2
- package/dist/customize/connectors/detail/connector-tools.d.ts +3 -3
- package/dist/customize/connectors/detail/connector-tools.js +105 -48
- package/dist/customize/connectors/detail/email-inboxes.d.ts +43 -0
- package/dist/customize/connectors/detail/email-inboxes.js +184 -0
- package/dist/customize/connectors/detail/provider-info.d.ts +1 -1
- package/dist/customize/connectors/detail/provider-info.js +2 -2
- package/dist/customize/connectors/detail/status-badge.d.ts +1 -1
- package/dist/customize/connectors/detail/status-badge.js +4 -5
- package/dist/customize/connectors/detail/use-connector-detail.d.ts +6 -0
- package/dist/customize/connectors/detail/use-connector-detail.js +14 -4
- package/dist/customize/connectors/install/install-dialog.d.ts +23 -0
- package/dist/customize/connectors/install/install-dialog.js +40 -0
- package/dist/customize/connectors/install/install.d.ts +13 -2
- package/dist/customize/connectors/install/install.js +9 -4
- package/dist/customize/connectors/install/use-install.d.ts +19 -2
- package/dist/customize/connectors/install/use-install.js +65 -37
- package/dist/customize/connectors/install/way-kind.d.ts +5 -0
- package/dist/customize/connectors/install/way-kind.js +16 -0
- package/dist/customize/connectors/provider-label.d.ts +2 -1
- package/dist/customize/connectors/provider-label.js +13 -3
- package/dist/customize/connectors/tools/pattern-rule-draft.d.ts +4 -0
- package/dist/customize/connectors/tools/pattern-rule-draft.js +12 -3
- package/dist/customize/connectors/tools/policy-sets.d.ts +27 -0
- package/dist/customize/connectors/tools/policy-sets.js +41 -0
- package/dist/customize/connectors/tools/tool-groups.d.ts +32 -9
- package/dist/customize/connectors/tools/tool-groups.js +78 -16
- package/dist/customize/connectors/tools/tool-policy-control.d.ts +11 -10
- package/dist/customize/connectors/tools/tool-policy-control.js +15 -16
- package/dist/customize/connectors/tools/tool-policy-labels.d.ts +6 -5
- package/dist/customize/connectors/tools/tool-policy-labels.js +17 -16
- package/dist/customize/connectors/tools/tool-policy.d.ts +50 -4
- package/dist/customize/connectors/tools/tool-policy.js +74 -8
- package/dist/customize/connectors/use-agent-access.d.ts +85 -0
- package/dist/customize/connectors/use-agent-access.js +72 -0
- package/dist/customize/migrate-to-v2/index.d.ts +1 -2
- package/dist/customize/migrate-to-v2/index.js +1 -2
- package/dist/customize/migrate-to-v2/migration-prompt.d.ts +12 -25
- package/dist/customize/migrate-to-v2/migration-prompt.js +34 -236
- package/dist/customize/migrate-to-v2/upgrade-defs.d.ts +1 -1
- package/dist/customize/migrate-to-v2/upgrade-defs.js +7 -6
- package/dist/customize/migrate-to-v2/upgrade-view.js +7 -7
- package/dist/customize/migrate-to-v2/use-run-upgrade.d.ts +3 -3
- package/dist/customize/providers/provider-accordion.js +17 -2
- package/dist/customize/sections/component/channel-access-panel.d.ts +16 -0
- package/dist/customize/sections/component/channel-access-panel.js +146 -0
- package/dist/customize/sections/component/channel-connect-hero.d.ts +3 -2
- package/dist/customize/sections/component/channel-connect-hero.js +3 -2
- package/dist/customize/sections/component/channel-hero-frame.d.ts +31 -0
- package/dist/customize/sections/component/channel-hero-frame.js +40 -0
- package/dist/customize/sections/component/channel-mocks.d.ts +6 -0
- package/dist/customize/sections/component/channel-mocks.js +46 -0
- package/dist/customize/sections/component/channel-row.d.ts +13 -3
- package/dist/customize/sections/component/channel-row.js +10 -4
- package/dist/customize/sections/component/email-connect-form.d.ts +27 -0
- package/dist/customize/sections/component/email-connect-form.js +183 -0
- package/dist/customize/sections/component/slack-connect-card.d.ts +7 -0
- package/dist/customize/sections/component/slack-connect-card.js +2 -3
- package/dist/customize/sections/component/teams-connect-card.d.ts +7 -0
- package/dist/customize/sections/component/teams-connect-card.js +2 -3
- package/dist/customize/sections/component/telegram-channel-row.js +16 -25
- package/dist/customize/sections/connectors-view.d.ts +1 -15
- package/dist/customize/sections/connectors-view.js +81 -314
- package/dist/customize/sections/view/agent-editor-catalog.js +5 -0
- package/dist/customize/sections/view/channels-view.d.ts +5 -1
- package/dist/customize/sections/view/channels-view.js +61 -75
- package/dist/customize/sections/view/gateway/gateway-overview.js +10 -2
- package/dist/customize/settings/tabs/experimental-tab.js +35 -16
- package/dist/customize/shared/catalog/catalog-empty-state.d.ts +1 -12
- package/dist/customize/shared/catalog/catalog-empty-state.js +3 -3
- package/dist/customize/shared/channels-switch-dialog.d.ts +18 -0
- package/dist/customize/shared/channels-switch-dialog.js +30 -0
- package/dist/customize/shared/feature-gate-screen.js +27 -9
- package/dist/customize/shared/use-customize-prefetch.d.ts +2 -3
- package/dist/customize/shared/use-customize-prefetch.js +9 -27
- package/dist/customize/triggers/schedule/post-to-field.d.ts +18 -0
- package/dist/customize/triggers/schedule/post-to-field.js +49 -0
- package/dist/customize/triggers/schedule/schedule-copy.d.ts +10 -6
- package/dist/customize/triggers/schedule/schedule-copy.js +42 -11
- package/dist/customize/triggers/schedule/schedule-detail-sheet.js +2 -1
- package/dist/customize/triggers/schedule/trigger-composer-logic.d.ts +22 -0
- package/dist/customize/triggers/schedule/trigger-composer-logic.js +25 -0
- package/dist/customize/triggers/schedule/trigger-composer.d.ts +5 -0
- package/dist/customize/triggers/schedule/trigger-composer.js +23 -14
- package/dist/customize/triggers/schedule/trigger-edit-logic.js +3 -0
- package/dist/customize/triggers/schedule/trigger-filter.js +1 -1
- package/dist/customize/triggers/schedule/trigger-runs-logic.d.ts +2 -2
- package/dist/customize/triggers/schedule/trigger-runs-panel.js +1 -0
- package/dist/customize/triggers/schedule/trigger-toast.js +2 -1
- package/dist/customize/triggers/schedule-view.js +5 -2
- package/dist/files/index.d.ts +1 -0
- package/dist/files/index.js +1 -0
- package/dist/files/project/change-request-recovery.d.ts +1 -26
- package/dist/files/project/change-request-recovery.js +1 -59
- package/dist/files/project/components/change-request-detail-dialog.js +13 -3
- package/dist/files/project/components/drive-explorer.js +15 -15
- package/dist/files/project/components/drive-toolbar.d.ts +16 -2
- package/dist/files/project/components/drive-toolbar.js +14 -5
- package/dist/files/project/hooks/use-change-request-recovery.js +3 -19
- package/dist/files/project/hooks/use-change-requests.d.ts +1 -0
- package/dist/files/project/hooks/use-change-requests.js +11 -2
- package/dist/files/renderers/image-frame.d.ts +46 -0
- package/dist/files/renderers/image-frame.js +59 -0
- package/dist/files/renderers/image-renderer.d.ts +11 -1
- package/dist/files/renderers/image-renderer.js +13 -3
- package/dist/files/renderers/pdf/pdf-clipboard.d.ts +2 -0
- package/dist/files/renderers/pdf/pdf-clipboard.js +21 -0
- package/dist/files/renderers/pdf/pdf-viewer.js +4 -2
- package/dist/files/renderers/show-content-renderer.d.ts +9 -1
- package/dist/files/renderers/show-content-renderer.js +56 -14
- package/dist/files/runtime/file-source.js +2 -0
- package/dist/files/runtime/hooks/use-binary-blob.d.ts +10 -1
- package/dist/files/runtime/hooks/use-binary-blob.js +10 -4
- package/dist/files/runtime/hooks/use-shared-image.d.ts +41 -0
- package/dist/files/runtime/hooks/use-shared-image.js +177 -0
- package/dist/files/viewer/file-content-renderer.d.ts +22 -1
- package/dist/files/viewer/file-content-renderer.js +50 -7
- package/dist/files/viewer/file-header.d.ts +7 -3
- package/dist/files/viewer/file-header.js +20 -11
- package/dist/files/viewer/file-preview-modal.d.ts +1 -1
- package/dist/files/viewer/file-preview-modal.js +10 -22
- package/dist/files/viewer/file-source.d.ts +13 -0
- package/dist/files/viewer/use-file-content-state.d.ts +2 -0
- package/dist/files/viewer/use-file-content-state.js +28 -10
- package/dist/files/viewer/viewer-actions.d.ts +3 -1
- package/dist/files/viewer/viewer-actions.js +2 -2
- package/dist/hooks/use-media-query.d.ts +1 -0
- package/dist/hooks/use-mobile.d.ts +5 -0
- package/dist/hooks/use-mobile.js +8 -0
- package/dist/i18n/en.d.ts +873 -85
- package/dist/i18n/en.js +888 -100
- package/dist/i18n/ui-catalog/localize-ui-catalog.js +4 -0
- package/dist/i18n/ui-catalog/remaining-ui-translation-keys.generated.js +15 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/internal/account-hub/account-settings-sidebar.js +1 -1
- package/dist/internal/account-hub/hub-sheet.d.ts +9 -1
- package/dist/internal/account-hub/hub-sheet.js +21 -5
- package/dist/internal/account-hub/sections.d.ts +1 -1
- package/dist/internal/account-hub/sections.js +2 -1
- package/dist/internal/auth/auth-card-shell.js +3 -3
- package/dist/internal/components/agent-mark.js +5 -2
- package/dist/internal/connector-logo/connector-logo-source.d.ts +63 -0
- package/dist/internal/connector-logo/connector-logo-source.js +48 -0
- package/dist/internal/connector-logo/connector-logo.d.ts +39 -0
- package/dist/internal/connector-logo/connector-logo.js +56 -0
- package/dist/internal/connector-logo/connector-mark-files.d.ts +11 -0
- package/dist/internal/connector-logo/connector-mark-files.js +35 -0
- package/dist/internal/files/file-read-retry.d.ts +13 -0
- package/dist/internal/files/file-read-retry.js +23 -3
- package/dist/internal/files/session-drive-files.d.ts +5 -1
- package/dist/internal/files/session-drive-files.js +7 -2
- package/dist/internal/hooks/channels/use-channels-installations.d.ts +32 -5
- package/dist/internal/hooks/channels/use-channels-installations.js +55 -7
- package/dist/internal/hooks/channels/use-email-inboxes.d.ts +19 -0
- package/dist/internal/hooks/channels/use-email-inboxes.js +48 -0
- package/dist/internal/hooks/connectors/use-add-account.js +1 -1
- package/dist/internal/hooks/index.d.ts +1 -1
- package/dist/internal/hooks/index.js +1 -1
- package/dist/internal/hooks/projects/use-new-project-session.d.ts +9 -0
- package/dist/internal/hooks/projects/use-new-project-session.js +28 -12
- package/dist/internal/hooks/use-auto-scroll.d.ts +8 -1
- package/dist/internal/hooks/use-auto-scroll.js +4 -4
- package/dist/internal/icons/telegram.d.ts +5 -0
- package/dist/internal/icons/telegram.js +6 -1
- package/dist/internal/layout/nav-hover-card.d.ts +35 -0
- package/dist/internal/layout/nav-hover-card.js +84 -0
- package/dist/internal/layout/project-nav-row.d.ts +3 -1
- package/dist/internal/layout/project-nav-row.js +3 -2
- package/dist/internal/layout/project-page-header.d.ts +4 -2
- package/dist/internal/layout/project-page-header.js +4 -3
- package/dist/internal/layout/project-settings-nav.js +59 -2
- package/dist/internal/lib/browser-error-noise.d.ts +1 -1
- package/dist/internal/lib/browser-error-noise.js +1 -1
- package/dist/internal/lib/browser-noise/rules/injected-scripts.d.ts +7 -0
- package/dist/internal/lib/browser-noise/rules/injected-scripts.js +15 -0
- package/dist/internal/lib/manifest-version.d.ts +1 -1
- package/dist/internal/lib/manifest-version.js +2 -2
- package/dist/internal/lib/memory-href.d.ts +16 -0
- package/dist/internal/lib/memory-href.js +46 -0
- package/dist/internal/lib/use-project-feature-flags.js +9 -9
- package/dist/internal/lib/utils/heic-convert.d.ts +1 -1
- package/dist/internal/lib/utils/heic-convert.js +3 -4
- package/dist/internal/lib/web-notifications.d.ts +20 -0
- package/dist/internal/lib/web-notifications.js +48 -4
- package/dist/internal/notifications/notification-bell.d.ts +4 -1
- package/dist/internal/notifications/notification-bell.js +2 -2
- package/dist/internal/selection/selection-bar.d.ts +2 -1
- package/dist/internal/selection/selection-bar.js +1 -1
- package/dist/internal/stores/file-preview-store.d.ts +29 -2
- package/dist/internal/stores/file-preview-store.js +19 -1
- package/dist/internal/stores/kortix-computer-store.js +3 -0
- package/dist/internal/stores/sidebar-nav-store.d.ts +1 -1
- package/dist/internal/stores/sidebar-nav-store.js +3 -1
- package/dist/lib/routes.d.ts +13 -1
- package/dist/lib/routes.js +13 -0
- package/dist/markdown/index.d.ts +2 -1
- package/dist/markdown/index.js +2 -1
- package/dist/markdown/setup-links/approval-decision.d.ts +1 -0
- package/dist/markdown/setup-links/approval-decision.js +6 -2
- package/dist/markdown/setup-links/connector-handshake.d.ts +3 -1
- package/dist/markdown/setup-links/connector-handshake.js +12 -10
- package/dist/markdown/setup-links/secret-intake-form.d.ts +0 -10
- package/dist/markdown/setup-links/secret-intake-form.js +1 -1
- package/dist/markdown/setup-links/show-connect-hero.d.ts +28 -0
- package/dist/markdown/setup-links/show-connect-hero.js +91 -0
- package/dist/markdown/unified-markdown.js +5 -5
- package/dist/primitives/badge.d.ts +1 -1
- package/dist/primitives/badge.js +2 -0
- package/dist/primitives/disclosure.js +14 -2
- package/dist/primitives/empty-art.d.ts +12 -0
- package/dist/primitives/empty-art.js +11 -0
- package/dist/primitives/mermaid-renderer.d.ts +2 -0
- package/dist/primitives/mermaid-renderer.js +21 -15
- package/dist/primitives/resizable.js +6 -1
- package/dist/primitives/resize-seam.d.ts +11 -0
- package/dist/primitives/resize-seam.js +12 -0
- package/dist/primitives/sidebar-panel.js +4 -7
- package/dist/primitives/tabs.d.ts +14 -1
- package/dist/primitives/tabs.js +1 -1
- package/dist/providers/ui-provider.d.ts +9 -0
- package/dist/session/composer/ComposerAboveCard.d.ts +1 -1
- package/dist/session/composer/ComposerAboveCard.js +2 -2
- package/dist/session/composer/ComposerCard.d.ts +1 -1
- package/dist/session/composer/ComposerCard.js +3 -3
- package/dist/session/composer/agent-selector.d.ts +13 -1
- package/dist/session/composer/agent-selector.js +25 -5
- package/dist/session/composer/composer-agent-access.d.ts +15 -0
- package/dist/session/composer/composer-agent-access.js +27 -0
- package/dist/session/composer/composer-chat-input.d.ts +8 -2
- package/dist/session/composer/composer-chat-input.js +8 -6
- package/dist/session/composer/composer-logic.d.ts +16 -0
- package/dist/session/composer/composer-logic.js +12 -0
- package/dist/session/composer/composer-underbar.d.ts +3 -1
- package/dist/session/composer/composer-underbar.js +4 -3
- package/dist/session/composer/composer.d.ts +15 -1
- package/dist/session/composer/composer.js +19 -1
- package/dist/session/composer/draft/composer-draft.d.ts +6 -2
- package/dist/session/composer/draft/composer-draft.js +5 -1
- package/dist/session/composer/reasoning-effort-selector.js +1 -1
- package/dist/session/models/chatgpt-connection-button.d.ts +11 -0
- package/dist/session/models/chatgpt-connection-button.js +54 -0
- package/dist/session/models/model-selector.js +5 -2
- package/dist/session/models/use-model-connection-gate.d.ts +5 -5
- package/dist/session/models/use-model-connection-gate.js +5 -5
- package/dist/session/outcomes/jump-to-outcome.d.ts +10 -0
- package/dist/session/outcomes/jump-to-outcome.js +11 -0
- package/dist/session/outcomes/session-outcomes-bridge.d.ts +14 -0
- package/dist/session/outcomes/session-outcomes-bridge.js +12 -0
- package/dist/session/outcomes/session-outcomes-provider.d.ts +3 -1
- package/dist/session/outcomes/session-outcomes-provider.js +33 -3
- package/dist/session/panel/easy/app-preview.d.ts +10 -0
- package/dist/session/panel/easy/app-preview.js +31 -12
- package/dist/session/panel/easy/change-requests-card.d.ts +7 -0
- package/dist/session/panel/easy/change-requests-card.js +17 -0
- package/dist/session/panel/easy/easy-panel-logic.js +7 -1
- package/dist/session/panel/easy/easy-panel.js +5 -2
- package/dist/session/panel/easy/file-preview.js +1 -1
- package/dist/session/panel/easy/outputs-card.d.ts +2 -1
- package/dist/session/panel/easy/outputs-card.js +3 -2
- package/dist/session/panel/mobile-tool-drawer.js +7 -1
- package/dist/session/panel/session-audit-panel.js +9 -2
- package/dist/session/panel/session-detail-panel.js +9 -3
- package/dist/session/panel/session-files-explorer.d.ts +9 -0
- package/dist/session/panel/session-files-explorer.js +12 -3
- package/dist/session/panel/session-panel-provider.d.ts +15 -1
- package/dist/session/panel/session-panel-provider.js +32 -7
- package/dist/session/panel/shared/derive-panels.d.ts +8 -1
- package/dist/session/panel/shared/derive-panels.js +12 -2
- package/dist/session/panel/shared/output-priority.js +2 -0
- package/dist/session/participants/session-participants.d.ts +5 -1
- package/dist/session/participants/session-participants.js +9 -2
- package/dist/session/prompts/approval-request.d.ts +5 -0
- package/dist/session/prompts/approval-request.js +7 -1
- package/dist/session/prompts/session-approval-review.d.ts +9 -0
- package/dist/session/prompts/session-approval-review.js +18 -0
- package/dist/session/status/session-error-banner.js +2 -49
- package/dist/session/status/session-starting-loader.d.ts +14 -2
- package/dist/session/status/session-starting-loader.js +16 -4
- package/dist/session/thread/after-first-prompt.d.ts +7 -0
- package/dist/session/thread/after-first-prompt.js +8 -0
- package/dist/session/thread/detect-command.d.ts +12 -0
- package/dist/session/thread/detect-command.js +20 -0
- package/dist/session/thread/session-chat.d.ts +3 -1
- package/dist/session/thread/session-chat.js +377 -252
- package/dist/session/thread/session-thread.d.ts +3 -1
- package/dist/session/thread/session-thread.js +9 -2
- package/dist/session/thread/thread-boot-rows.d.ts +36 -0
- package/dist/session/thread/thread-boot-rows.js +89 -0
- package/dist/session/thread/transcript-rows.d.ts +31 -0
- package/dist/session/thread/transcript-rows.js +3 -0
- package/dist/session/thread/transcript.d.ts +0 -9
- package/dist/session/thread/transcript.js +104 -19
- package/dist/session/tool/shared/infrastructure-contexts.d.ts +28 -0
- package/dist/session/tool/shared/infrastructure-contexts.js +31 -3
- package/dist/session/tool/tool-part-renderer.d.ts +5 -4
- package/dist/session/tool/tool-part-renderer.js +8 -3
- package/dist/session/tool/tools/bash-tool.js +7 -6
- package/dist/session/tool/tools/channel-send-card.d.ts +1 -2
- package/dist/session/tool/tools/channel-send.d.ts +2 -1
- package/dist/session/tool/tools/codemode-tool.js +1 -1
- package/dist/session/tool/tools/connector-tools.js +1 -1
- package/dist/session/tool/tools/image-gen-tool.d.ts +1 -1
- package/dist/session/tool/tools/image-gen-tool.js +240 -53
- package/dist/session/tool/tools/show-tool.js +19 -8
- package/dist/session/turn/channel-brand.d.ts +8 -3
- package/dist/session/turn/channel-brand.js +20 -4
- package/dist/session/turn/message-author.d.ts +8 -0
- package/dist/session/turn/message-author.js +24 -0
- package/dist/session/turn/message-row.d.ts +52 -0
- package/dist/session/turn/message-row.js +44 -0
- package/dist/session/turn/plan-anchor.d.ts +1 -1
- package/dist/session/turn/plan-anchor.js +1 -1
- package/dist/session/turn/user-message.d.ts +7 -1
- package/dist/session/turn/user-message.js +21 -7
- package/dist/styles.css +1 -1
- package/dist/workspace/home/access-requests-bell.d.ts +9 -2
- package/dist/workspace/home/access-requests-bell.js +20 -6
- package/dist/workspace/home/first-chat.d.ts +8 -21
- package/dist/workspace/home/first-chat.js +22 -72
- package/dist/workspace/index.d.ts +6 -0
- package/dist/workspace/index.js +6 -0
- package/dist/workspace/layout/project-home.d.ts +14 -2
- package/dist/workspace/layout/project-home.js +60 -21
- package/dist/workspace/layout/use-project-home-send.d.ts +9 -1
- package/dist/workspace/layout/use-project-home-send.js +82 -3
- package/dist/workspace/memory/body-doc.d.ts +17 -0
- package/dist/workspace/memory/body-doc.js +208 -0
- package/dist/workspace/memory/body-extensions.d.ts +38 -0
- package/dist/workspace/memory/body-extensions.js +103 -0
- package/dist/workspace/memory/company-memory-page.d.ts +8 -0
- package/dist/workspace/memory/company-memory-page.js +16 -0
- package/dist/workspace/memory/memory-all.d.ts +20 -0
- package/dist/workspace/memory/memory-all.js +27 -0
- package/dist/workspace/memory/memory-body.d.ts +19 -0
- package/dist/workspace/memory/memory-body.js +139 -0
- package/dist/workspace/memory/memory-empty.d.ts +13 -0
- package/dist/workspace/memory/memory-empty.js +28 -0
- package/dist/workspace/memory/memory-history.d.ts +27 -0
- package/dist/workspace/memory/memory-history.js +108 -0
- package/dist/workspace/memory/memory-labels.d.ts +16 -0
- package/dist/workspace/memory/memory-labels.js +47 -0
- package/dist/workspace/memory/memory-page-list.d.ts +34 -0
- package/dist/workspace/memory/memory-page-list.js +156 -0
- package/dist/workspace/memory/memory-reader.d.ts +58 -0
- package/dist/workspace/memory/memory-reader.js +123 -0
- package/dist/workspace/memory/memory-view.d.ts +21 -0
- package/dist/workspace/memory/memory-view.js +124 -0
- package/dist/workspace/memory/remember-popover.d.ts +19 -0
- package/dist/workspace/memory/remember-popover.js +61 -0
- package/dist/workspace/memory/remember-this.d.ts +12 -0
- package/dist/workspace/memory/remember-this.js +89 -0
- package/dist/workspace/memory/source-mark.d.ts +18 -0
- package/dist/workspace/memory/source-mark.js +79 -0
- package/dist/workspace/memory/used-memory-chip.d.ts +14 -0
- package/dist/workspace/memory/used-memory-chip.js +61 -0
- package/dist/workspace/new/advanced-fields.d.ts +2 -1
- package/dist/workspace/new/advanced-fields.js +2 -2
- package/dist/workspace/new/source-param.d.ts +1 -1
- package/dist/workspace/new/source-param.js +3 -1
- package/dist/workspace/new/use-create-workspace.d.ts +8 -10
- package/dist/workspace/new/use-create-workspace.js +3 -3
- package/dist/workspace/projects/onboarding/app-logo.d.ts +7 -2
- package/dist/workspace/projects/onboarding/app-logo.js +6 -13
- package/dist/workspace/projects/policies-panel.js +5 -3
- package/dist/workspace/review/review-actions.d.ts +4 -2
- package/dist/workspace/review/review-actions.js +8 -2
- package/dist/workspace/review/review-center.js +11 -7
- package/dist/workspace/review/review-detail.d.ts +10 -0
- package/dist/workspace/review/review-detail.js +101 -13
- package/dist/workspace/saved-session-skeleton.d.ts +2 -2
- package/dist/workspace/saved-session-skeleton.js +3 -3
- package/dist/workspace/session-workspace.js +15 -13
- package/dist/workspace/sessions/project-sessions-view.js +3 -2
- package/dist/workspace/sessions/sessions-toolbar.d.ts +3 -1
- package/dist/workspace/sessions/sessions-toolbar.js +2 -2
- package/dist/workspace/sidebar/footer/project-apps-nav.d.ts +5 -0
- package/dist/workspace/sidebar/footer/project-apps-nav.js +41 -2
- package/dist/workspace/sidebar/footer/project-artifacts-nav.d.ts +6 -0
- package/dist/workspace/sidebar/footer/project-artifacts-nav.js +22 -0
- package/dist/workspace/sidebar/footer/project-manifest-upgrade-alert.js +13 -13
- package/dist/workspace/sidebar/footer/project-memory-nav.d.ts +7 -0
- package/dist/workspace/sidebar/footer/project-memory-nav.js +19 -0
- package/dist/workspace/sidebar/nav-row-meta.js +14 -2
- package/dist/workspace/sidebar/project-nav-items.js +3 -0
- package/dist/workspace/sidebar/project-session-list.js +68 -56
- package/dist/workspace/sidebar/project-sidebar.js +9 -2
- package/dist/workspace/sidebar/project-spaces-nav.d.ts +8 -0
- package/dist/workspace/sidebar/project-spaces-nav.js +69 -0
- package/dist/workspace/sidebar/session-group-order.d.ts +9 -0
- package/dist/workspace/sidebar/session-group-order.js +25 -0
- package/dist/workspace/sidebar/session-group-sections.d.ts +62 -0
- package/dist/workspace/sidebar/session-group-sections.js +267 -0
- package/dist/workspace/sidebar/session-list-chrome.d.ts +28 -0
- package/dist/workspace/sidebar/session-list-chrome.js +50 -0
- package/dist/workspace/spaces/channel-glyph.d.ts +5 -0
- package/dist/workspace/spaces/channel-glyph.js +6 -0
- package/dist/workspace/spaces/channel-setup.d.ts +16 -0
- package/dist/workspace/spaces/channel-setup.js +105 -0
- package/dist/workspace/spaces/channels-onboarding.d.ts +13 -0
- package/dist/workspace/spaces/channels-onboarding.js +37 -0
- package/dist/workspace/spaces/create-channel-dialog.d.ts +16 -0
- package/dist/workspace/spaces/create-channel-dialog.js +158 -0
- package/dist/workspace/spaces/private-channels-not-in.d.ts +9 -0
- package/dist/workspace/spaces/private-channels-not-in.js +69 -0
- package/dist/workspace/spaces/space-agents.d.ts +10 -0
- package/dist/workspace/spaces/space-agents.js +10 -0
- package/dist/workspace/spaces/space-details-dialog.d.ts +20 -0
- package/dist/workspace/spaces/space-details-dialog.js +176 -0
- package/dist/workspace/spaces/space-link-label.d.ts +49 -0
- package/dist/workspace/spaces/space-link-label.js +73 -0
- package/dist/workspace/spaces/space-links.d.ts +19 -0
- package/dist/workspace/spaces/space-links.js +230 -0
- package/dist/workspace/spaces/space-members.d.ts +46 -0
- package/dist/workspace/spaces/space-members.js +182 -0
- package/dist/workspace/spaces/space-roster.d.ts +15 -0
- package/dist/workspace/spaces/space-roster.js +44 -0
- package/dist/workspace/spaces/space-threads-tab.d.ts +56 -0
- package/dist/workspace/spaces/space-threads-tab.js +156 -0
- package/dist/workspace/spaces/space-timeline-view.d.ts +254 -0
- package/dist/workspace/spaces/space-timeline-view.js +235 -0
- package/dist/workspace/spaces/space-timeline.d.ts +106 -0
- package/dist/workspace/spaces/space-timeline.js +183 -0
- package/dist/workspace/spaces/space-triggers.d.ts +13 -0
- package/dist/workspace/spaces/space-triggers.js +78 -0
- package/dist/workspace/spaces/space-view.d.ts +37 -0
- package/dist/workspace/spaces/space-view.js +436 -0
- package/package.json +27 -36
- package/skills/kortix-ui/SKILL.md +3 -3
- package/skills/kortix-ui/references/custom-dashboard.md +3 -3
- package/skills/kortix-ui/references/modules.md +28 -4
- package/skills/kortix-ui/references/theming.md +1 -1
- package/dist/customize/connectors/catalog/merge-search.d.ts +0 -10
- package/dist/customize/connectors/catalog/merge-search.js +0 -26
- package/dist/customize/connectors/detail/find-easy-connect-app.d.ts +0 -29
- package/dist/customize/connectors/detail/find-easy-connect-app.js +0 -22
- package/dist/customize/migrate-to-v2/use-migrate-to-v2.d.ts +0 -9
- package/dist/customize/migrate-to-v2/use-migrate-to-v2.js +0 -24
- package/dist/customize/sections/connector-connection-header.d.ts +0 -36
- package/dist/customize/sections/connector-connection-header.js +0 -33
- package/dist/customize/sections/connector-connection-modal.d.ts +0 -34
- package/dist/customize/sections/connector-connection-modal.js +0 -72
- package/dist/customize/sections/discover-catalogue-card.d.ts +0 -19
- package/dist/customize/sections/discover-catalogue-card.js +0 -26
- package/dist/customize/sections/discover-catalogue-detail.d.ts +0 -15
- package/dist/customize/sections/discover-catalogue-detail.js +0 -24
- package/dist/customize/sections/discover-catalogue.d.ts +0 -17
- package/dist/customize/sections/discover-catalogue.js +0 -132
- package/dist/customize/sections/llm-provider/provider-access-menu.d.ts +0 -10
- package/dist/customize/sections/llm-provider/provider-access-menu.js +0 -23
- package/dist/files/project/components/drive-empty-art.d.ts +0 -2
- package/dist/files/project/components/drive-empty-art.js +0 -5
- package/dist/internal/hooks/use-media-query.d.ts +0 -2
- package/dist/internal/share/public-share-link-button.d.ts +0 -14
- package/dist/internal/share/public-share-link-button.js +0 -17
- package/dist/markdown/setup-links/app-credentials-form.d.ts +0 -12
- package/dist/markdown/setup-links/app-credentials-form.js +0 -115
- /package/dist/{internal/hooks → hooks}/use-media-query.js +0 -0
|
@@ -12,10 +12,14 @@ import { useQueuedDraftStore, useQueuedDrafts } from '../composer/stores/queued-
|
|
|
12
12
|
import { SESSION_LOG_MINOR, SESSION_LOG_SCHEMA, listSessionPrompts, projectSessionConnection, sessionLogOfV1Rows, sessionLogPromptMessage, sessionLogRetrying, sessionLogTurns, fetchSessionAttachment, sessionLogFullTextPlan, sessionLogHarnessSwitches, sessionLogRestoreNotice, sessionLogWithFullTexts, } from '@kortix/sdk';
|
|
13
13
|
import { useProjectSession, useSessionLogOlder, useSessionLogRecord, useSessionLogThread, useSessionMessageAuthors, useSessionModelUsage, useSessionParticipants, } from '@kortix/sdk/react';
|
|
14
14
|
import { ArrowBendUpLeftIcon, CaretDownIcon, StackIcon as Layers, } from '@phosphor-icons/react';
|
|
15
|
+
import { jumpToOutcome } from '../outcomes/jump-to-outcome.js';
|
|
16
|
+
import { useIsMobile, useIsPhone } from '../../hooks/use-mobile.js';
|
|
15
17
|
import { useUiLink, useUiPathname, useUiRouter, useUiShallowNavigate, useUiSearchParams, useUiViewerId, } from '../../providers/ui-provider.js';
|
|
16
|
-
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
18
|
+
import { useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
19
|
+
import { TranscriptRowsContext } from './transcript-rows.js';
|
|
20
|
+
import { AgentBusyRow, PendingPromptRows } from './thread-boot-rows.js';
|
|
17
21
|
import { createPortal } from 'react-dom';
|
|
18
|
-
import { AUTHOR_RETRY_DELAYS_MS, authorForTurn, awaitsAgent, missingAuthorKey, resolveTranscriptAuthors, showAuthorName, stoppedByName, } from '../turn/message-author.js';
|
|
22
|
+
import { AUTHOR_RETRY_DELAYS_MS, authorForTurn, awaitsAgent, missingAuthorKey, resolveTranscriptAuthors, rewindableMessageIds, showAuthorName, stoppedByName, } from '../turn/message-author.js';
|
|
19
23
|
import { stopRefusalMessage } from '../status/stop-refusal.js';
|
|
20
24
|
import { QueuedPromptList } from '../composer/queued-prompt-list.js';
|
|
21
25
|
import { runtimePermissionLocksComposer } from '../composer/send-blockers.js';
|
|
@@ -35,7 +39,7 @@ import { ProjectFilesProvider } from '../../files/project/context.js';
|
|
|
35
39
|
import { useOptionalSessionPanel } from '../panel/session-panel-provider.js';
|
|
36
40
|
import { COMPOSER_SHELL_CLASS, Composer as SessionChatInput, } from '../composer/composer.js';
|
|
37
41
|
import { ComposerDropZone } from '../composer/composer-drop-zone.js';
|
|
38
|
-
import { resolveComposerAgent } from '../composer/composer-agent-access.js';
|
|
42
|
+
import { channelRunnableAgents, resolveComposerAgent, withChannelAgents } from '../composer/composer-agent-access.js';
|
|
39
43
|
import { acknowledgeQuoteRequests, } from '../composer/composer-logic.js';
|
|
40
44
|
import { sessionSlashFiles } from '../composer/menus/slash-files.js';
|
|
41
45
|
import { resolveFirstPromptHandover, transcriptCarriesFirstPrompt, } from './first-prompt-handover.js';
|
|
@@ -66,6 +70,7 @@ import { ChatMinimap } from './chat-minimap.js';
|
|
|
66
70
|
import { usePlanInChat } from './plan-surface.js';
|
|
67
71
|
import { SessionStartingLoader } from '../status/session-starting-loader.js';
|
|
68
72
|
import { ToolActivateContext } from '../tool/tool-renderers.js';
|
|
73
|
+
import { ReadOnlySessionContext } from '../tool/shared/infrastructure-contexts.js';
|
|
69
74
|
import { firstPromptAttachments, retainSentAttachmentPreviews, sentAttachmentsForTurn, } from '../composer/sent-attachment-previews.js';
|
|
70
75
|
import { buildOptimisticPromptTextWithUploads, promptFileParts, sentAttachmentsOf, } from '../composer/uploaded-file-refs.js';
|
|
71
76
|
import { useAutoScroll } from '../../internal/hooks/use-auto-scroll.js';
|
|
@@ -84,9 +89,9 @@ import { openTabAndNavigate, useTabStore } from '../../internal/stores/tab-store
|
|
|
84
89
|
import { projectSessionHref } from '../../internal/lib/navigation/session-href.js';
|
|
85
90
|
import { getRetryInfo } from '../../internal/session-types/index.js';
|
|
86
91
|
import { useModelPricingLookup } from '../../internal/lib/model-pricing.js';
|
|
87
|
-
import { isAbortError, latestPromptModel, turnEndNotice } from '@kortix/sdk';
|
|
92
|
+
import { isAbortError, latestPromptModel, SESSION_NOTICE, turnEndNotice } from '@kortix/sdk';
|
|
88
93
|
import { failureShownByTurn, failureSupersededByTurn, persistedFailureText, } from './persisted-turn-failure.js';
|
|
89
|
-
import { abandonOptimisticSend, applyOptimisticAbort, ascendingId, awaitAbortSettlement, beginOptimisticSend, classifySendError, clearStartStash, formatModelString, formatPromptModel, markOptimisticSendDispatched, markOptimisticSendInboxBacked, mintSessionWireMessageId, readStartStash, recoverFromSendFailure, rejectQuestion, replyToPermission, replyToQuestion, requestRuntimeReconnect, startSessionWithPrompt, useAbortRuntimeSession, useExecuteRuntimeCommand, useProjectConfig, useRuntimeAgents, useRuntimeBootStalled, useRuntimeCommands, useRuntimeConfig, useRuntimeConnectionStore, useRuntimePendingStore, useRuntimePhase, useRuntimeProviders, useRuntimeReady, useRuntimeSession, useRuntimeSessions, useRuntimeSupports, useSessionModelSelection, useSessionPrompts, useSessionStateStore, useSessionSync, useSessionTurnOutcome, useSessionWorking, useSessionWorkingStore, } from '@kortix/sdk/react';
|
|
94
|
+
import { abandonOptimisticSend, applyOptimisticAbort, ascendingId, awaitAbortSettlement, beginOptimisticSend, classifySendError, clearStartStash, formatModelString, formatPromptModel, markOptimisticSendDispatched, markOptimisticSendInboxBacked, mintSessionWireMessageId, readStartStash, recoverFromSendFailure, rejectQuestion, replyToPermission, replyToQuestion, requestRuntimeReconnect, startSessionWithPrompt, useAbortRuntimeSession, useExecuteRuntimeCommand, useProjectConfig, useRuntimeAgents, useProjectSpaces, useRuntimeBootStalled, useRuntimeCommands, useRuntimeConfig, useRuntimeConnectionStore, useRuntimePendingStore, useRuntimePhase, useRuntimeProviders, useRuntimeReady, useRuntimeSession, useRuntimeSessions, useRuntimeSupports, useSessionModelSelection, useSessionPrompts, useSessionStateStore, useSessionSync, useSessionTurnOutcome, useSessionWorking, useSessionWorkingStore, } from '@kortix/sdk/react';
|
|
90
95
|
import { useStableCallback } from '../../internal/hooks/use-stable-callback.js';
|
|
91
96
|
import { useReloadForensics } from '../status/reload-forensics.js';
|
|
92
97
|
import { resolveLastTurnWorking, serverHoldsOpenTurn, sessionComposerReadiness, } from '../composer/session-composer-readiness.js';
|
|
@@ -170,8 +175,20 @@ const TRANSCRIPT_THROTTLE_MS = 50;
|
|
|
170
175
|
/** `useSessionMessages` input when no `useSession` owns this chat: reads nothing. */
|
|
171
176
|
const DETACHED_SESSION_MESSAGES = { projectId: '', sessionId: '', runtimeSessionId: null };
|
|
172
177
|
const NO_FULL_TEXTS = new Map();
|
|
173
|
-
|
|
178
|
+
/** The composer notice in the host's words (`TranscriptRows.notices`), else the SDK's. */
|
|
179
|
+
function hostNotice(notice, notices) {
|
|
180
|
+
if (!notice || !notices)
|
|
181
|
+
return notice;
|
|
182
|
+
const key = Object.keys(SESSION_NOTICE).find((candidate) => SESSION_NOTICE[candidate] === notice);
|
|
183
|
+
return (key && notices[key]) || notice;
|
|
184
|
+
}
|
|
185
|
+
export function SessionChat({ sessionId, projectSessionId, sessionState, projectId, boundAgentName, headerLeadingAction, hideHeader, readOnly, composerPlaceholder, inputReplacement, initialScrollTop, savedHistoryScope, onContentReady, deferComposerFocus, hostQuote, }) {
|
|
174
186
|
const tHardcodedUi = useTranslations('hardcodedUi');
|
|
187
|
+
// A channel's thread panel: turns are message rows, full width, end-anchored.
|
|
188
|
+
const rowsContext = useContext(TranscriptRowsContext);
|
|
189
|
+
const transcriptRows = rowsContext !== null;
|
|
190
|
+
const isMobile = useIsMobile();
|
|
191
|
+
const isPhone = useIsPhone();
|
|
175
192
|
const tQueue = useTranslations('threads');
|
|
176
193
|
const tComposerAttachments = useTranslations('hardcodedUi.composerAttachments');
|
|
177
194
|
const onboardingActive = useOnboardingModeStore((s) => s.active);
|
|
@@ -412,7 +429,7 @@ export function SessionChat({ sessionId, projectSessionId, sessionState, project
|
|
|
412
429
|
// chat has no projectId, but runs inside the parent scope's project: its
|
|
413
430
|
// roster is that project's. Only a chat with neither falls back to the
|
|
414
431
|
// runtime's own agent list, which a pi box does not serve (KRTX-2887).
|
|
415
|
-
const { data:
|
|
432
|
+
const { data: rosterAgents } = useRuntimeAgents({
|
|
416
433
|
directory: session?.directory,
|
|
417
434
|
projectId: projectId ?? (scopeProjectId || undefined),
|
|
418
435
|
});
|
|
@@ -507,6 +524,15 @@ export function SessionChat({ sessionId, projectSessionId, sessionState, project
|
|
|
507
524
|
const projectSessionRow = useProjectSession(projectId, projectSessionId ?? undefined, {
|
|
508
525
|
enabled: !!projectId && !!projectSessionId,
|
|
509
526
|
}).data;
|
|
527
|
+
// A channel thread: whoever posts in the channel runs its agents, granted or
|
|
528
|
+
// not (the server applies the same rule).
|
|
529
|
+
const { data: projectSpaces } = useProjectSpaces(projectId, {
|
|
530
|
+
enabled: !!projectId && !!projectSessionRow?.space_id,
|
|
531
|
+
});
|
|
532
|
+
const threadChannelAgents = useMemo(() => channelRunnableAgents(projectSpaces?.find((space) => space.space_id === projectSessionRow?.space_id), projectConfig?.default_agent ?? projectConfig?.open_code_default_agent), [projectSpaces, projectSessionRow?.space_id, projectConfig?.default_agent, projectConfig?.open_code_default_agent]);
|
|
533
|
+
const agents = useMemo(() => withChannelAgents(rosterAgents, threadChannelAgents), [rosterAgents, threadChannelAgents]);
|
|
534
|
+
// Edit-and-rewind only on the viewer's own message with nobody else's after it.
|
|
535
|
+
const rewindable = useMemo(() => rewindableMessageIds(userMessageIds, transcriptAuthors.byMessage, viewerId, projectSessionRow?.created_by), [userMessageIds, transcriptAuthors.byMessage, viewerId, projectSessionRow?.created_by]);
|
|
510
536
|
// ---- Unified model/agent/variant state (1:1 port of SolidJS local.tsx) ----
|
|
511
537
|
// The composer opens on the model the session already runs (its pin, or its
|
|
512
538
|
// last prompt's model), so a session set from the CLI, the SDK or Slack does
|
|
@@ -1095,7 +1121,7 @@ export function SessionChat({ sessionId, projectSessionId, sessionState, project
|
|
|
1095
1121
|
const undoToastId = `queue-undo-${sessionId}-${removed.prompt_id}`;
|
|
1096
1122
|
undoToast(tHardcodedUi.raw('i18nComplete.text2c6041fda32c'), {
|
|
1097
1123
|
id: undoToastId,
|
|
1098
|
-
duration: 5000,
|
|
1124
|
+
duration: 5000, // audit:allow a toast lifetime in ms, not motion/react seconds
|
|
1099
1125
|
undoLabel: tHardcodedUi.raw('i18nComplete.texta737e54996f8'),
|
|
1100
1126
|
// The SAME `clientMessageId`, so an undo re-creates ONE row and a
|
|
1101
1127
|
// double-click cannot create two. A FRESH wire id, because
|
|
@@ -1166,6 +1192,7 @@ export function SessionChat({ sessionId, projectSessionId, sessionState, project
|
|
|
1166
1192
|
const messageCount = messages?.length ?? 0;
|
|
1167
1193
|
const { scrollRef, contentRef, spacerElRef, showScrollButton, scrollToBottom, smoothScrollToAbsoluteBottom, anchorTurn, startAtTop, } = useAutoScroll({
|
|
1168
1194
|
hasContent: messageCount > 0,
|
|
1195
|
+
room: !transcriptRows,
|
|
1169
1196
|
});
|
|
1170
1197
|
// Cmd/Ctrl+P prints the WHOLE conversation. The shortcut is intercepted
|
|
1171
1198
|
// because neither half of what printing needs can be done in CSS: the
|
|
@@ -1350,6 +1377,18 @@ export function SessionChat({ sessionId, projectSessionId, sessionState, project
|
|
|
1350
1377
|
const awaitingUserInput = pendingQuestions.length > 0 || pendingPermissions.length > 0;
|
|
1351
1378
|
const QUESTION_PROMPT_ANIMATION_MS = 320;
|
|
1352
1379
|
const activePendingQuestion = pendingQuestions[0] ?? null;
|
|
1380
|
+
// A new question docks over the bottom of the transcript, and answering it
|
|
1381
|
+
// needs what the agent just wrote (a long tool run can leave the reader
|
|
1382
|
+
// short of the end). Bring the end into view once per question; a reader
|
|
1383
|
+
// who scrolls up afterwards stays where they are.
|
|
1384
|
+
const shownQuestionIdRef = useRef(null);
|
|
1385
|
+
useEffect(() => {
|
|
1386
|
+
const id = activePendingQuestion?.id ?? null;
|
|
1387
|
+
if (!id || id === shownQuestionIdRef.current)
|
|
1388
|
+
return;
|
|
1389
|
+
shownQuestionIdRef.current = id;
|
|
1390
|
+
smoothScrollToAbsoluteBottom();
|
|
1391
|
+
}, [activePendingQuestion?.id, smoothScrollToAbsoluteBottom]);
|
|
1353
1392
|
const [renderedQuestion, setRenderedQuestion] = useState(null);
|
|
1354
1393
|
const [questionPromptVisible, setQuestionPromptVisible] = useState(false);
|
|
1355
1394
|
// A connector call waiting on a decision docks onto the composer the way a
|
|
@@ -1996,6 +2035,68 @@ export function SessionChat({ sessionId, projectSessionId, sessionState, project
|
|
|
1996
2035
|
scrollEl.scrollTo({ top: Math.max(0, offset), behavior: 'smooth' });
|
|
1997
2036
|
clearJumpTarget();
|
|
1998
2037
|
}, [targetMessageId, clearJumpTarget, contentRef, scrollRef]);
|
|
2038
|
+
const tChangeRequests = useTranslations('sessionChangeRequests');
|
|
2039
|
+
const mobileChangeRequests = useIsMobile();
|
|
2040
|
+
const [jumpingToOutcome, setJumpingToOutcome] = useState(false);
|
|
2041
|
+
const outcomeJumpRef = useRef({ sessionId, hasOlder, isLoadingOlder, loadOlder });
|
|
2042
|
+
useEffect(() => {
|
|
2043
|
+
outcomeJumpRef.current = { sessionId, hasOlder, isLoadingOlder, loadOlder };
|
|
2044
|
+
}, [sessionId, hasOlder, isLoadingOlder, loadOlder]);
|
|
2045
|
+
const handleJumpToOutcome = useCallback(async (resolveTurn, createdAt) => {
|
|
2046
|
+
if (jumpingToOutcome)
|
|
2047
|
+
return;
|
|
2048
|
+
setJumpingToOutcome(true);
|
|
2049
|
+
const currentSession = sessionId;
|
|
2050
|
+
const settle = () => new Promise((resolve) => requestAnimationFrame(() => resolve()));
|
|
2051
|
+
try {
|
|
2052
|
+
const earliest = Math.min(...turnSpans.flatMap((span) => span.startedAt === null ? [] : [span.startedAt]));
|
|
2053
|
+
await jumpToOutcome({
|
|
2054
|
+
needsHistory: hasOlder && (!Number.isFinite(createdAt) || createdAt < earliest),
|
|
2055
|
+
history: {
|
|
2056
|
+
readState: () => outcomeJumpRef.current.sessionId === currentSession
|
|
2057
|
+
? outcomeJumpRef.current : { hasOlder: false, isLoadingOlder: false },
|
|
2058
|
+
loadOlder: () => outcomeJumpRef.current.loadOlder(),
|
|
2059
|
+
settle,
|
|
2060
|
+
},
|
|
2061
|
+
resolve: () => outcomeJumpRef.current.sessionId === currentSession ? resolveTurn() : undefined,
|
|
2062
|
+
loadError: () => errorToast(tChangeRequests('loadError')),
|
|
2063
|
+
unavailable: () => {
|
|
2064
|
+
if (outcomeJumpRef.current.sessionId === currentSession)
|
|
2065
|
+
errorToast(tChangeRequests('unavailable'));
|
|
2066
|
+
},
|
|
2067
|
+
scroll: async (key) => {
|
|
2068
|
+
if (mobileChangeRequests) {
|
|
2069
|
+
const store = useKortixComputerStore.getState();
|
|
2070
|
+
if (store.isExpanded)
|
|
2071
|
+
store.toggleExpanded();
|
|
2072
|
+
store.setIsSidePanelOpen(false);
|
|
2073
|
+
store.setIsActionPanelOpen(false);
|
|
2074
|
+
}
|
|
2075
|
+
await settle();
|
|
2076
|
+
await settle();
|
|
2077
|
+
releaseOlderAnchor();
|
|
2078
|
+
const target = key ? Array.from(contentRef.current?.querySelectorAll('[data-turn-id]') ?? [])
|
|
2079
|
+
.find((node) => node.dataset.turnId === key) : undefined;
|
|
2080
|
+
const scroll = scrollRef.current;
|
|
2081
|
+
if (!target || !scroll) {
|
|
2082
|
+
return false;
|
|
2083
|
+
}
|
|
2084
|
+
const top = target.getBoundingClientRect().top - scroll.getBoundingClientRect().top + scroll.scrollTop;
|
|
2085
|
+
scroll.scrollTo({ top: Math.max(0, top), behavior: 'instant' });
|
|
2086
|
+
// Static feedback, not motion: keyboard and reduced-motion navigation stay instant.
|
|
2087
|
+
target.classList.add('bg-accent');
|
|
2088
|
+
window.setTimeout(() => target.classList.remove('bg-accent'), 1_000);
|
|
2089
|
+
return true;
|
|
2090
|
+
},
|
|
2091
|
+
});
|
|
2092
|
+
}
|
|
2093
|
+
catch {
|
|
2094
|
+
errorToast(tChangeRequests('loadError'));
|
|
2095
|
+
}
|
|
2096
|
+
finally {
|
|
2097
|
+
setJumpingToOutcome(false);
|
|
2098
|
+
}
|
|
2099
|
+
}, [jumpingToOutcome, sessionId, hasOlder, turnSpans, mobileChangeRequests, releaseOlderAnchor, contentRef, scrollRef, tChangeRequests]);
|
|
1999
2100
|
// Reset on session change
|
|
2000
2101
|
useEffect(() => {
|
|
2001
2102
|
clearSendReceipt();
|
|
@@ -3421,252 +3522,276 @@ export function SessionChat({ sessionId, projectSessionId, sessionState, project
|
|
|
3421
3522
|
return (_jsx("div", { className: "bg-background relative flex h-full flex-col", "data-testid": "session-chat", children: _jsx(SessionStartingLoader, { projectId: projectId, sessionId: projectSessionId }) }));
|
|
3422
3523
|
}
|
|
3423
3524
|
return (
|
|
3424
|
-
//
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
const pendingPrompt = !confirmedActive && turn.assistant.length === 0
|
|
3521
|
-
? pendingPromptsByMessageId.get(turn.id)
|
|
3522
|
-
: undefined;
|
|
3523
|
-
// A queued prompt is not in the runtime transcript yet;
|
|
3524
|
-
// its author still shows (`authorForTurn`).
|
|
3525
|
-
const turnAuthor = authorForTurn(transcriptAuthors, messageAuthors, turn.id, pendingPrompt?.wire_message_id);
|
|
3526
|
-
return (_jsx(TranscriptTurnRow
|
|
3527
|
-
// ONE element per prompt: keyed by the id the
|
|
3528
|
-
// bubble was FIRST painted under, so the swap to a
|
|
3529
|
-
// re-minted echo id re-renders this node instead
|
|
3530
|
-
// of mounting a new one (opacity keeps animating,
|
|
3531
|
-
// hover state survives, nothing jumps).
|
|
3532
|
-
, { turnId: turn.id, modelOptions: modelOptions, suppressed: suppressedFailedCompaction, continuedWith: harnessSwitches.get(turn.id)?.harness, fullTextState: loaded.state[turn.id] ?? 'idle', onLoadFullText: loadFullTexts, showBusyRow: showFallbackBusyRow &&
|
|
3533
|
-
fallbackBusyRowTurnId === turn.id,
|
|
3534
|
-
// Queued bubbles STACK: a pending turn right after
|
|
3535
|
-
// another pending turn sits close to it, like a
|
|
3536
|
-
// list of what is waiting — not a turn's width
|
|
3537
|
-
// apart as if each had been answered in between.
|
|
3538
|
-
// (Failed compaction rows need no stacking rule any
|
|
3539
|
-
// more — at most one is visible at a time.)
|
|
3540
|
-
viewportClassName: turnIndex === 0
|
|
3541
|
-
? ''
|
|
3542
|
-
: // A compaction and the work after it continue the turn above.
|
|
3543
|
-
turn.compaction || turn.continues
|
|
3544
|
-
? 'mt-6'
|
|
3545
|
-
: lastTurnWorking &&
|
|
3546
|
-
pendingTurnIds.has(turn.id) &&
|
|
3547
|
-
pendingTurnIds.has(turns[turnIndex - 1].id)
|
|
3548
|
-
? 'mt-3'
|
|
3549
|
-
: 'mt-12', turn: turn, author: turnAuthor, showAuthor: showAuthorName(turnAuthor, groupChat, viewerId), stoppedBy: stoppedByName(messageAuthors, turn.id, viewerId), servedModel: servedModelOfTurn(modelUsage, turn.id, turns[turnIndex - 1]?.id), turnOutcome: turnOutcome, isLast: turn.id === lastUserMessageId, ownsPlan: turn.id === planAnchorId, sessionId: sessionId, projectId: projectId, projectSessionId: projectSessionId, sessionStatus: sessionStatus, permissions: pendingPermissions, questions: pendingQuestions, agentNames: agentNames, isFirstTurn: turnIndex === 0,
|
|
3550
|
-
// Handed over only once the stand-in has stepped
|
|
3551
|
-
// aside — while it is up it draws these itself.
|
|
3552
|
-
pendingText: turnIndex === 0 ? firstTurnHandover?.text : undefined, pendingAttachments: sentAttachmentsForTurn({
|
|
3553
|
-
sentByMessage: sentAttachmentsByMessage,
|
|
3554
|
-
messageId: turn.id,
|
|
3555
|
-
originId: optimisticOriginOf(sessionId, turn.id),
|
|
3556
|
-
isFirstTurn: turnIndex === 0,
|
|
3557
|
-
firstTurnHandover: firstTurnHandover?.attachments,
|
|
3558
|
-
firstTurnSent: firstPromptAttachments(projectSessionId),
|
|
3559
|
-
queuedRowAttachments: inboxRowsByMessageId.get(turn.id)?.attachments,
|
|
3560
|
-
}), uploadStatus: heldSendFailures?.[turn.id]
|
|
3561
|
-
? {
|
|
3562
|
-
state: 'failed',
|
|
3563
|
-
message: heldSendFailures[turn.id].message,
|
|
3564
|
-
onRetry: () => retryHeldSend(sessionId, turn.id, resendHeldSend, (error) => classifySessionError(error).message),
|
|
3565
|
-
}
|
|
3566
|
-
: turnIndex === 0 && firstTurnHandover?.attachments.length
|
|
3567
|
-
? firstPromptUploadStatus
|
|
3568
|
-
: undefined, sessionWorking: lastTurnWorking, isWorkingTurn: turn.live, suppressBusyIndicator: suppressWorkingTurnBusy, awaitingUser: awaitingUserInput,
|
|
3569
|
-
// An idle send stays in the inbox until delivery,
|
|
3570
|
-
// but nothing runs ahead of it: queued only while
|
|
3571
|
-
// it waits behind a turn (`turnRendersQueued`).
|
|
3572
|
-
pending: turnRendersQueued({
|
|
3525
|
+
// A read-only view (the sub-session modal) offers no fix inside a tool card.
|
|
3526
|
+
_jsx(ReadOnlySessionContext.Provider, { value: !!readOnly, children: _jsx(ProjectFilesProvider, { value: { projectId: projectId ?? '', ref: outcomesBaseRef, defaultBranch: outcomesBaseRef }, children: _jsxs(ComposerDropZone, { className: cn('relative flex h-full flex-col',
|
|
3527
|
+
// Transparent in the welcome state so the root-level full-bleed wallpaper
|
|
3528
|
+
// (portaled into SessionLayout) reads through; solid once real content
|
|
3529
|
+
// takes over. Same base color either way, so non-welcome is unchanged.
|
|
3530
|
+
shouldShowWelcomeOverlay ? 'bg-transparent' : 'bg-background'), "data-testid": "session-chat", children: [isPreparingPrint && (_jsxs("div", { "data-print-hide": true, role: "status", className: "bg-popover text-muted-foreground fixed bottom-6 left-1/2 z-50 flex -translate-x-1/2 items-center gap-2 rounded-lg border px-4 py-2 text-xs shadow-lg", children: [_jsx(Loading, { className: "size-3.5 shrink-0" }), tHardcodedUi.raw('i18nComplete.text7dac2ca010fe')] })), wallpaperLayer
|
|
3531
|
+
? welcomeWallpaper && createPortal(welcomeWallpaper, wallpaperLayer)
|
|
3532
|
+
: welcomeWallpaper, !hideHeader && (_jsx(SessionSiteHeader, { sessionId: sessionId, sessionTitle: session?.title || 'Untitled', leadingAction: headerLeadingAction, parent: parentCrumb })), _jsx(SessionContextModal, { open: contextModalOpen, onOpenChange: setContextModalOpen,
|
|
3533
|
+
// A chat with no `useSession` source: the raw explorer lists the
|
|
3534
|
+
// rows `useSessionSync` read for it.
|
|
3535
|
+
detachedRows: sessionState ? undefined : hookMessages, source: sessionState ?? DETACHED_SESSION_MESSAGES, session: session, sessionRow: projectSessionRow, providers: providers, allSessions: allSessions, servedModel: sessionServedModel, billedCost: sessionBilledCost(modelUsage) }), _jsx(CompactModal, { sessionId: sessionId, open: compactModalOpen, onOpenChange: setCompactModalOpen }), _jsx(ChangeRequestDetailDialog, { crId: openCrId, onClose: () => setOpenCrId(null), onOpenChangeRequest: setOpenCrId }), _jsxs(SessionBodyRow, { actionPanel: !hideHeader && !readOnly, children: [isNotFound ? (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col items-center justify-center gap-3 px-6 text-center", children: [_jsx("div", { className: "text-muted-foreground text-sm", children: tHardcodedUi.raw('componentsSessionSessionChat.line5821JsxTextThisSessionIsNotAccessibleRightNow') }), _jsx(Button, { asChild: true, variant: "outline", size: "sm", children: _jsx(Link, { href: "/", prefetch: true, onClick: () => {
|
|
3536
|
+
try {
|
|
3537
|
+
if (sessionId)
|
|
3538
|
+
useTabStore.getState().closeTab?.(sessionId);
|
|
3539
|
+
}
|
|
3540
|
+
catch { }
|
|
3541
|
+
}, children: tHardcodedUi.raw('componentsSessionSessionChat.line5833JsxTextGoToHome') }) })] })) : (_jsxs("div", { ref: chatAreaRef, className: "relative z-10 min-h-0 flex-1", children: [_jsx("div", { ref: scrollContainerCallbackRef, className: cn(
|
|
3542
|
+
// overflow-anchor:none — this scroll area does ALL of its own
|
|
3543
|
+
// anchoring (useAutoScroll's spacer + RAF follow, the send-path
|
|
3544
|
+
// turn anchor, and the history-prepend content-space restore in
|
|
3545
|
+
// session-history-scroll.ts). The browser's native scroll
|
|
3546
|
+
// anchoring (default `overflow-anchor: auto`) tries to
|
|
3547
|
+
// compensate for the SAME prepends independently, and the two
|
|
3548
|
+
// corrections stacking is the other half of the scroll-up
|
|
3549
|
+
// teleport: ours restores the reader's position, then the
|
|
3550
|
+
// native one nudges it again.
|
|
3551
|
+
'scrollbar-hide relative z-10 h-full flex-1 overflow-y-auto [scroll-behavior:auto] [overflow-anchor:none]', shouldShowWelcomeOverlay ? 'bg-transparent' : 'bg-background'), onMouseUp: handleChatMouseUp, onMouseDown: handleChatMouseDown, onScroll: handleChatScroll, children: _jsxs("div", { ref: contentRef, role: "log",
|
|
3552
|
+
// Width and gutters live in `SESSION_TRANSCRIPT_CLASS`: the
|
|
3553
|
+
// instant shell draws this same column and the two crossfade
|
|
3554
|
+
// into each other, so a difference here is a sideways jump on
|
|
3555
|
+
// screen, not a style opinion. See session-body.tsx.
|
|
3556
|
+
//
|
|
3557
|
+
// No bottom padding, there or here: the space under the last
|
|
3558
|
+
// message is the auto-scroll spacer's job alone. The `pb-32`
|
|
3559
|
+
// that used to sit here stacked 128px of dead space on top of
|
|
3560
|
+
// it — the "extra inset at the bottom of the session".
|
|
3561
|
+
// Rows run edge to edge: each row owns its gutters and its hover fill.
|
|
3562
|
+
className: transcriptRows ? 'w-full min-w-0 pt-4' : SESSION_TRANSCRIPT_CLASS, children: [_jsxs("div", { className: "flex min-w-0 flex-col", children: [_jsx(SessionPrintHeader, { title: session?.title || 'Untitled', agentName: composerAgentName }), (hasOlder || showOlderLoading) && (_jsxs("div", { className: "mb-6 flex flex-col items-center gap-2", children: [hasOlder && (_jsx("div", { ref: olderSentinelRef, "aria-hidden": true, className: "h-px w-full" })), showOlderLoading && (_jsxs("div", { role: "status", className: "text-muted-foreground flex items-center gap-2 py-1 text-xs", children: [_jsx(Loading, { className: "size-3.5 shrink-0" }), tHardcodedUi.raw('i18nComplete.text85bf890776a7')] })), !showOlderLoading &&
|
|
3563
|
+
!olderPullFailed &&
|
|
3564
|
+
olderAutoloadExhausted({ hasOlder, autoLoadedPages }) && (_jsx(Button, { type: "button", variant: "outline-ghost", size: "sm", onClick: () => void handleLoadOlder(), children: tHardcodedUi.raw('i18nComplete.textf17671d83db0') })), olderPullFailed && !showOlderLoading && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-muted-foreground text-xs", children: tHardcodedUi.raw('i18nComplete.textb03a0041ce33') }), _jsx(Button, { type: "button", variant: "outline-ghost", size: "sm", onClick: () => void handleLoadOlder(), children: tHardcodedUi.raw('i18nComplete.text942087cc2d41') })] }))] })), restoreNotice && !restoreDismissed && (_jsx(RestoreNotice, { notice: restoreNotice, onDismiss: () => dismissRestore(historyKey, restoreNotice.generation) })), _jsx(SessionOutcomesProvider, { projectSessionId: projectSessionId, turnSpans: turnSpans, busy: effectiveBusy, onOpen: handleOpenOutcome, onJump: handleJumpToOutcome, jumping: jumpingToOutcome, children: _jsxs(ToolActivateContext.Provider, { value: toolActivate, children: [showFirstPromptPreview &&
|
|
3565
|
+
firstPromptSource &&
|
|
3566
|
+
queuedSyntheticMessages.length === 0 &&
|
|
3567
|
+
rowsContext && (
|
|
3568
|
+
// A channel thread draws the stand-in as rows, the same
|
|
3569
|
+
// rows its boot body drew (`ThreadBootRows`).
|
|
3570
|
+
_jsx(PendingPromptRows, { text: buildOptimisticPromptTextWithUploads(firstPromptSource.text, firstPromptSource.files), author: rowsContext.owner, sessionId: sessionId, busy: turns.length === 0 && (lastTurnWorking || promptInbox.prompts.some(isFirstPromptRow)) })), showFirstPromptPreview &&
|
|
3571
|
+
firstPromptSource &&
|
|
3572
|
+
queuedSyntheticMessages.length === 0 &&
|
|
3573
|
+
!rowsContext && (_jsx(OptimisticTurn, { text: buildOptimisticPromptTextWithUploads(firstPromptSource.text, firstPromptSource.files),
|
|
3574
|
+
// Preserve a real failed-send status through the
|
|
3575
|
+
// boot-shell handover without inventing upload progress.
|
|
3576
|
+
// A first prompt held on its uploads carries its own.
|
|
3577
|
+
uploadStatus: firstPromptSource.uploadStatus ?? firstPromptUploadStatus, agentNames: agentNames, onFileClick: openFileInComputer, sessionId: sessionId,
|
|
3578
|
+
// The first item of the conversation, like turn 0, which has no
|
|
3579
|
+
// top margin. `first:mt-0` misses here: the list opens with a
|
|
3580
|
+
// zero-height <header>, so the stand-in sat 44px lower than turn 0
|
|
3581
|
+
// and every swap between the two jumped the bubble (KRTX-2931).
|
|
3582
|
+
className: "mt-0",
|
|
3583
|
+
// An undelivered first prompt is a turn about to start, as the
|
|
3584
|
+
// shell above this chat shows it: busy from the first frame,
|
|
3585
|
+
// before the working projection has read the inbox (KRTX-2931).
|
|
3586
|
+
busy: turns.length === 0 && (lastTurnWorking || promptInbox.prompts.some(isFirstPromptRow)) })), turns.map((turn, turnIndex) => {
|
|
3587
|
+
// Check if this turn is a compaction summary — and
|
|
3588
|
+
// whether it actually PRODUCED one. A failed/aborted
|
|
3589
|
+
// attempt (compaction-flagged, no content, not the
|
|
3590
|
+
// working turn) renders as one slim row, draws no
|
|
3591
|
+
// divider, and stacks tight against a neighbouring
|
|
3592
|
+
// failed attempt.
|
|
3593
|
+
const compaction = turn.compaction;
|
|
3594
|
+
const hasCompaction = compaction !== null;
|
|
3595
|
+
const isTurnWorking = turn.live;
|
|
3596
|
+
// `inFlight` (message state) alongside the projection:
|
|
3597
|
+
// classifying by projection alone flipped a streaming
|
|
3598
|
+
// compaction to "failed" for the frames where the two
|
|
3599
|
+
// disagree, popping the divider in and out — a layout
|
|
3600
|
+
// bounce right where the reader is looking.
|
|
3601
|
+
const isFailedCompaction = compaction !== null &&
|
|
3602
|
+
!compaction.hasContent &&
|
|
3603
|
+
!compaction.inFlight &&
|
|
3604
|
+
!isTurnWorking;
|
|
3605
|
+
// Retries collapse to ONE visible row, GLOBALLY: a
|
|
3606
|
+
// failed attempt with ANY later compaction turn (a
|
|
3607
|
+
// retry, or the one that finally landed) is history —
|
|
3608
|
+
// it keeps its TurnViewport (stable keys, scroll
|
|
3609
|
+
// anchors) but renders no content, and an empty
|
|
3610
|
+
// TurnViewport costs 0px (turn-viewport.tsx RULE 2).
|
|
3611
|
+
// Adjacency was not enough: attempts whose error landed
|
|
3612
|
+
// on a plain assistant message used to interleave as
|
|
3613
|
+
// unclassified turns, breaking every consecutive run.
|
|
3614
|
+
const suppressedFailedCompaction = isFailedCompaction && turnIndex < lastCompactionTurnIndex;
|
|
3615
|
+
// Notification-only early-return removed: it rendered the
|
|
3616
|
+
// user's pty_* card but skipped the turn's replies,
|
|
3617
|
+
// hiding every subsequent assistant response in that turn.
|
|
3618
|
+
// Fall through to the normal turn renderer instead.
|
|
3619
|
+
const confirmedActive = turnIsConfirmedActive({
|
|
3620
|
+
isTurnWorking,
|
|
3573
3621
|
turnId: turn.id,
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3622
|
+
activeTurnId,
|
|
3623
|
+
pendingDelivery: !!working.pendingDelivery,
|
|
3624
|
+
});
|
|
3625
|
+
const pendingPrompt = !confirmedActive && turn.assistant.length === 0
|
|
3626
|
+
? pendingPromptsByMessageId.get(turn.id)
|
|
3627
|
+
: undefined;
|
|
3628
|
+
// A queued prompt is not in the runtime transcript yet;
|
|
3629
|
+
// its author still shows (`authorForTurn`).
|
|
3630
|
+
const turnAuthor = authorForTurn(transcriptAuthors, messageAuthors, turn.id, pendingPrompt?.wire_message_id);
|
|
3631
|
+
return (_jsx(TranscriptTurnRow
|
|
3632
|
+
// ONE element per prompt: keyed by the id the
|
|
3633
|
+
// bubble was FIRST painted under, so the swap to a
|
|
3634
|
+
// re-minted echo id re-renders this node instead
|
|
3635
|
+
// of mounting a new one (opacity keeps animating,
|
|
3636
|
+
// hover state survives, nothing jumps).
|
|
3637
|
+
, { turnId: turn.id, modelOptions: modelOptions, suppressed: suppressedFailedCompaction, continuedWith: harnessSwitches.get(turn.id)?.harness, fullTextState: loaded.state[turn.id] ?? 'idle', onLoadFullText: loadFullTexts, showBusyRow: showFallbackBusyRow &&
|
|
3638
|
+
fallbackBusyRowTurnId === turn.id,
|
|
3639
|
+
// Queued bubbles STACK: a pending turn right after
|
|
3640
|
+
// another pending turn sits close to it, like a
|
|
3641
|
+
// list of what is waiting — not a turn's width
|
|
3642
|
+
// apart as if each had been answered in between.
|
|
3643
|
+
// (Failed compaction rows need no stacking rule any
|
|
3644
|
+
// more — at most one is visible at a time.)
|
|
3645
|
+
viewportClassName: turnIndex === 0 || transcriptRows
|
|
3646
|
+
? ''
|
|
3647
|
+
: // A compaction and the work after it continue the turn above.
|
|
3648
|
+
turn.compaction || turn.continues
|
|
3649
|
+
? 'mt-6'
|
|
3650
|
+
: lastTurnWorking &&
|
|
3651
|
+
pendingTurnIds.has(turn.id) &&
|
|
3652
|
+
pendingTurnIds.has(turns[turnIndex - 1].id)
|
|
3653
|
+
? 'mt-3'
|
|
3654
|
+
: 'mt-12', turn: turn, author: turnAuthor, showAuthor: showAuthorName(turnAuthor, groupChat, viewerId), stoppedBy: stoppedByName(messageAuthors, turn.id, viewerId), servedModel: servedModelOfTurn(modelUsage, turn.id, turns[turnIndex - 1]?.id), turnOutcome: turnOutcome, isLast: turn.id === lastUserMessageId, ownsPlan: turn.id === planAnchorId, sessionId: sessionId, projectId: projectId, projectSessionId: projectSessionId, sessionStatus: sessionStatus, permissions: pendingPermissions, questions: pendingQuestions, agentNames: agentNames, isFirstTurn: turnIndex === 0,
|
|
3655
|
+
// Handed over only once the stand-in has stepped
|
|
3656
|
+
// aside — while it is up it draws these itself.
|
|
3657
|
+
pendingText: turnIndex === 0 ? firstTurnHandover?.text : undefined, pendingAttachments: sentAttachmentsForTurn({
|
|
3658
|
+
sentByMessage: sentAttachmentsByMessage,
|
|
3659
|
+
messageId: turn.id,
|
|
3660
|
+
originId: optimisticOriginOf(sessionId, turn.id),
|
|
3661
|
+
isFirstTurn: turnIndex === 0,
|
|
3662
|
+
firstTurnHandover: firstTurnHandover?.attachments,
|
|
3663
|
+
firstTurnSent: firstPromptAttachments(projectSessionId),
|
|
3664
|
+
queuedRowAttachments: inboxRowsByMessageId.get(turn.id)?.attachments,
|
|
3665
|
+
}), uploadStatus: heldSendFailures?.[turn.id]
|
|
3666
|
+
? {
|
|
3667
|
+
state: 'failed',
|
|
3668
|
+
message: heldSendFailures[turn.id].message,
|
|
3669
|
+
onRetry: () => retryHeldSend(sessionId, turn.id, resendHeldSend, (error) => classifySessionError(error).message),
|
|
3670
|
+
}
|
|
3671
|
+
: turnIndex === 0 && firstTurnHandover?.attachments.length
|
|
3672
|
+
? firstPromptUploadStatus
|
|
3673
|
+
: undefined, sessionWorking: lastTurnWorking, isWorkingTurn: turn.live, suppressBusyIndicator: suppressWorkingTurnBusy, awaitingUser: awaitingUserInput,
|
|
3674
|
+
// An idle send stays in the inbox until delivery,
|
|
3675
|
+
// but nothing runs ahead of it: queued only while
|
|
3676
|
+
// it waits behind a turn (`turnRendersQueued`).
|
|
3677
|
+
// The first turn, with no turn working, has
|
|
3678
|
+
// nothing ahead of it: a session's first prompt is
|
|
3679
|
+
// starting, not queued, while the computer comes up
|
|
3680
|
+
// and before the turn layer marks it queued or live.
|
|
3681
|
+
pending: turnIndex === 0 && workingTurn.workingTurnId === null && !confirmedActive
|
|
3682
|
+
? pendingPrompt?.state === 'waiting' || pendingPrompt?.state === 'failed'
|
|
3683
|
+
: turnRendersQueued({
|
|
3684
|
+
turnId: turn.id,
|
|
3685
|
+
resolution: workingTurn,
|
|
3686
|
+
sessionWorking: lastTurnWorking,
|
|
3687
|
+
confirmedActive,
|
|
3688
|
+
inboxPrompt: pendingPrompt,
|
|
3689
|
+
}), pendingPrompt: pendingPrompt, onRetryQueued: stableRetryQueued, onRemoveQueued: stableRemoveQueued, queuedPromptViewer: queuedPromptViewer, interruptedBeforeRun: interruptedTurnIds.has(turn.id), isCompaction: hasCompaction, onOpenCompactionSummary: panel ? stableOpenCompactionSummary : undefined, onOpenPastedContent: panel ? stableOpenPastedContent : undefined, providers: providers, commandMessages: commandMessagesRef.current, commands: commands, disableToolNavigation: disableToolNavigation, onPermissionReply: stablePermissionReply, onRewind: stableRewind, editingText: rewindTarget?.messageId === turn.id
|
|
3690
|
+
? rewindTarget.text
|
|
3691
|
+
: null, editPending: editSendPending || !!sessionState?.rewindPending, onEditCancel: stableEditCancel, onEditSend: stableEditSend, rewindDisabled: !!readOnly ||
|
|
3692
|
+
(rewindable !== null && !rewindable.has(turn.id)) ||
|
|
3693
|
+
!runtimeCanRewind ||
|
|
3694
|
+
!sessionState ||
|
|
3695
|
+
isBusy ||
|
|
3696
|
+
sessionState.rewindPending ||
|
|
3697
|
+
// The runtime is not idle while queued prompts
|
|
3698
|
+
// are still on their way to it — a rewind mid-
|
|
3699
|
+
// delivery fails downstream with "Session is
|
|
3700
|
+
// busy" (measured); refuse it up front instead.
|
|
3701
|
+
promptInbox.prompts.length > 0 }, turnRenderKeys.get(turn.id)));
|
|
3702
|
+
})] }) }), isOptimisticCompacting && !hasCompactionTurn && (_jsx("div", { className: turns.length > 0 ? 'mt-12' : 'mt-2', children: _jsx(CompactionMarker, { running: true }) })), [
|
|
3703
|
+
...(turnOutcome.recent_failures ?? []),
|
|
3704
|
+
...(turnOutcome.last_ended?.end_reason === 'failed' &&
|
|
3705
|
+
!turnOutcome.recent_failures?.some((failure) => failure.message_id === turnOutcome.last_ended?.message_id)
|
|
3706
|
+
? [turnOutcome.last_ended]
|
|
3707
|
+
: []),
|
|
3708
|
+
].filter((failure) => !isAbortError(failure.error) &&
|
|
3709
|
+
!failureShownByTurn(failure, turns) &&
|
|
3710
|
+
!failureSupersededByTurn(failure, turns) &&
|
|
3711
|
+
(!failure.error?.message || failure.error.message !== commandError?.message)).map((failure) => {
|
|
3712
|
+
const messageId = failure.message_id ?? 'persisted-turn-failure';
|
|
3713
|
+
// Use the SDK's settle window for a cause that may arrive
|
|
3714
|
+
// one frame later, including an unnamed failed last turn.
|
|
3715
|
+
const notice = turnEndNotice({
|
|
3716
|
+
...turnOutcome,
|
|
3717
|
+
recent_failures: [{ ...failure, message_id: messageId, error: failure.error ?? null }],
|
|
3718
|
+
}, messageId, { hasError: false, isAbort: false });
|
|
3719
|
+
return notice ? (_jsx(TurnErrorDisplay, { errorText: notice.kind === 'unexplained'
|
|
3720
|
+
? tHardcodedUi.raw('i18nComplete.text73112526c03a')
|
|
3721
|
+
: persistedFailureText(failure.error), className: "mt-2" }, messageId)) : null;
|
|
3722
|
+
}), commandError && (_jsx(TurnErrorDisplay, { error: commandError, isAbort: isAbortError(commandError.cause), modelOptions: modelOptions, className: "mt-2" })), showFallbackBusyRow && fallbackBusyRowTurnId === null && (rowsContext ? (
|
|
3723
|
+
// A channel thread waits in the agent's answer row.
|
|
3724
|
+
_jsx(AgentBusyRow, { sessionId: sessionId })) : (_jsx(SessionBusyIndicator, { sessionId: sessionId,
|
|
3725
|
+
// Matches the stand-in's row spacing under a bubble
|
|
3726
|
+
// (`OptimisticTurn`), so the crossfade into the real
|
|
3727
|
+
// transcript does not move it. Nothing above it when
|
|
3728
|
+
// the transcript is empty, so no margin there.
|
|
3729
|
+
className: turns.length === 0 ? undefined : 'mt-6' })))] }), _jsx("div", { ref: spacerElRef, "data-scroll-spacer": true })] }) }), selectionPopup && (_jsx("div", { "data-reply-popup": true, className: "absolute z-50", style: {
|
|
3730
|
+
left: `${selectionPopup.x}px`,
|
|
3731
|
+
top: `${selectionPopup.y}px`,
|
|
3732
|
+
transform: 'translate(-50%, -100%)',
|
|
3733
|
+
}, children: _jsxs(Button, { onClick: handleSelectionReply, size: "sm", className: "animate-in fade-in-0 zoom-in-95 duration-normal origin-bottom px-3 text-xs ease-out has-[>svg]:px-3", children: [tHardcodedUi.raw('i18nComplete.textc253f451bdd5'), _jsx(ArrowBendUpLeftIcon, { className: "size-4 shrink-0" })] }) })), transcriptRows ? null : (_jsx(ChatMinimap, { turns: turns, scrollRef: scrollRef, contentRef: contentRef })), _jsx("div", { className: cn('absolute inset-x-0 bottom-4 z-20 flex justify-center', !showScrollButton && 'pointer-events-none'), children: _jsx(Button, { variant: "outline", size: "icon-md", "aria-hidden": !showScrollButton, tabIndex: showScrollButton ? undefined : -1, className: cn('hit-area-2 bg-background hover:bg-muted rounded-full', 'transition-[opacity,scale] ease-[cubic-bezier(0.23,1,0.32,1)] active:scale-[0.96] motion-reduce:scale-100 motion-reduce:transition-opacity', showScrollButton
|
|
3734
|
+
? 'duration-normal scale-100 opacity-100'
|
|
3735
|
+
: 'duration-fast scale-[0.97] opacity-0'), onClick: smoothScrollToAbsoluteBottom, children: _jsx(CaretDownIcon, { className: "size-4" }) }) })] })), readOnly && inputReplacement ? (_jsx("div", { className: cn(COMPOSER_SHELL_CLASS, 'pb-4'), children: inputReplacement })) : null, !readOnly && (_jsx(_Fragment, { children: _jsx(SessionChatInput
|
|
3626
3736
|
// `undefined`, not `true`, once released: the composer's own
|
|
3627
3737
|
// viewport rule (>= 640px) still decides, so this never forces
|
|
3628
3738
|
// focus onto a phone keyboard.
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
//
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
:
|
|
3739
|
+
, {
|
|
3740
|
+
// `undefined`, not `true`, once released: the composer's own
|
|
3741
|
+
// viewport rule (>= 640px) still decides, so this never forces
|
|
3742
|
+
// focus onto a phone keyboard.
|
|
3743
|
+
autoFocus: deferComposerFocus ? false : undefined, onSend: async (text, files, mentions, attachments, placement) => {
|
|
3744
|
+
if (await queueEdit.save(text))
|
|
3745
|
+
return;
|
|
3746
|
+
// Enter while a turn runs steers it (D9.1); Cmd/Ctrl+Enter is Queue List.
|
|
3747
|
+
await handleSend(text, files, mentions, attachments, composerSendDelivery(placement ?? 'transcript', isBusyRef.current));
|
|
3748
|
+
}, prefill: composerPrefill, onPrefillApplied: (id) => {
|
|
3749
|
+
useSessionComposerPrefillStore.getState().clearPrefill(sessionId, id);
|
|
3750
|
+
},
|
|
3751
|
+
// Up from the first row takes the queue back; the placeholder
|
|
3752
|
+
// says so while there is something to take.
|
|
3753
|
+
onArrowUpAtStart: () => queueEdit.takeBack(),
|
|
3754
|
+
// A host placeholder ("Reply…") is static: the rotating tips would replace it.
|
|
3755
|
+
hint: canTakeBackQueue ? tHardcodedUi.raw('i18nComplete.text03a01dd53ffa') : composerPlaceholder,
|
|
3756
|
+
// Editing a queued message: the send saves it back into the
|
|
3757
|
+
// queue, so the control says Submit, never Stop.
|
|
3758
|
+
submitLabel: queueEdit.editing ? tQueue('submitEdit') : null, draftScope: composerDraftScope, draftActive: !deferComposerFocus, attachRequestId: attachRequestId, isBusy: isBusy,
|
|
3759
|
+
// The ONE projection, not the 300 ms busy fade: it is what
|
|
3760
|
+
// decides whether a `/` command may be dispatched, and a fade
|
|
3761
|
+
// timer that has already lapsed would let one abort a live turn.
|
|
3762
|
+
// `effectiveBusy` folds in optimistic compaction (not a turn, so
|
|
3763
|
+
// not in `working`) and the retrying-turn predicate, so this
|
|
3764
|
+
// site reads one value instead of re-OR-ing a term onto it.
|
|
3765
|
+
sessionWorking: effectiveBusy,
|
|
3766
|
+
// Gates `/` COMMANDS only. A prompt typed at a sleeping box is
|
|
3767
|
+
// an inbox row and goes out when the box answers; a command has
|
|
3768
|
+
// no row, and `runCommand` swallows it silently until the
|
|
3769
|
+
// runtime is switched.
|
|
3770
|
+
runtimeReady: runtimeReady, rewind: composerRewind, onStop: handleStop, canStop: canStop, escCount: escCount, agents: local.agent.list, selectedAgent: composerAgentName, onAgentChange: handleAgentChange, noAccessibleAgents: noAccessibleAgents, commands: chatCommands, commandsResolved: agentCommands !== undefined, slashFiles: chatSlashFiles, onOpenPastedContent: panel ? stableOpenPastedContent : undefined, onCommand: handleCommand, onHoldCommand: handleHoldCommand, models: local.model.list, selectedModel: local.model.currentKey ?? null, onModelChange: handleModelChange, modelDefaultControls: chatModelDefaultControls, variants: local.model.variant.list, selectedVariant: local.model.variant.current ?? null, onVariantChange: handleVariantChange, messages: messages, sessionId: sessionId, projectId: projectId, providers: providers, modelRequired: true, modelsLoading: providersLoading, onContextClick: handleContextClick, onCompactClick: runtimeCanCompact ? handleCompactClick : undefined, quoteRequests: quoteRequests, onQuoteRequestsApplied: handleQuoteRequestsApplied,
|
|
3771
|
+
// Only lock the input into question-answer mode while the session is
|
|
3772
|
+
// actually busy (a live question keeps the run busy). If a question
|
|
3773
|
+
// chip is ever showing while the session is idle — e.g. a dead /
|
|
3774
|
+
// abandoned question the agent left behind — the input stays unlocked
|
|
3775
|
+
// so a typed message is sent to the agent instead of being swallowed
|
|
3776
|
+
// as a custom answer.
|
|
3777
|
+
lockForQuestion: !!renderedQuestion && isBusy,
|
|
3778
|
+
// Same dead-prompt guard as questions: only lock while the agent is
|
|
3779
|
+
// actually paused on the decision (isBusy), so a stale card can't
|
|
3780
|
+
// swallow the composer on an idle session.
|
|
3781
|
+
lockForApproval: runtimePermissionLocksComposer(pendingPermissions.length, isBusy), onCustomAnswer: handleCustomAnswer, questionButtonLabel: renderedQuestion ? questionAction.label : null, questionActive: !!renderedQuestion || approvalDocked, questionCanAct: questionAction.canAct, onQuestionAction: handleQuestionAction, aboveSlot: chatAboveSlot, inputSlot: chatInputSlot, toolbarSlot: chatToolbarSlot,
|
|
3782
|
+
// The shell can now render on a cached transcript alone, i.e. before
|
|
3783
|
+
// the sandbox answers — so sending has to be gated separately from
|
|
3784
|
+
// reading. See sessionComposerReadiness.
|
|
3785
|
+
notice: hostNotice(composerReadiness.notice, rowsContext?.notices), noticeAsleep: composerReadiness.notice === SESSION_NOTICE.idle,
|
|
3786
|
+
// Inside the thread panel's bordered box, as the channel composer.
|
|
3787
|
+
// A phone keeps the row under the card; a 720px desktop window does not.
|
|
3788
|
+
underbarPlacement: transcriptRows && !isPhone ? 'inline' : undefined,
|
|
3789
|
+
// The panel's toolbar is narrow: the agent is its tile, the model keeps its name.
|
|
3790
|
+
agentPickerCompact: transcriptRows && !isPhone,
|
|
3791
|
+
// A thread panel's rows run `px-5`, and the channel composer
|
|
3792
|
+
// beside it sits `pb-4` off the window's bottom edge: the same
|
|
3793
|
+
// margins, so the two boxes line up.
|
|
3794
|
+
parentClassName: transcriptRows ? 'max-w-none px-5 pb-4' : undefined, onNoticeRetry: composerReadiness.notice && composerReadiness.retryable
|
|
3795
|
+
? requestRuntimeReconnect
|
|
3796
|
+
: undefined }) }))] })] }) }) }));
|
|
3672
3797
|
}
|