@kortix/ui 0.14.8 → 0.14.10
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 +116 -3
- package/dist/_vendor/shared/app-config.d.ts +175 -0
- package/dist/_vendor/shared/artifact-comments.d.ts +235 -0
- package/dist/_vendor/shared/channel-descriptors.d.ts +96 -0
- package/dist/_vendor/shared/channel-message.d.ts +45 -5
- package/dist/_vendor/shared/index.d.ts +2 -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 +30 -7
- 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 +55 -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 +21 -28
- 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 +10 -0
- package/dist/customize/sections/view/channels-view.d.ts +6 -1
- package/dist/customize/sections/view/channels-view.js +72 -81
- package/dist/customize/sections/view/gateway/gateway-overview.js +10 -2
- package/dist/customize/settings/rail.js +9 -0
- package/dist/customize/settings/settings-tabs.d.ts +1 -1
- package/dist/customize/settings/settings-tabs.js +1 -0
- package/dist/customize/settings/tabs/chrome-connections-tab.d.ts +6 -0
- package/dist/customize/settings/tabs/chrome-connections-tab.js +99 -0
- package/dist/customize/settings/tabs/experimental-tab.js +35 -16
- package/dist/customize/shared/catalog/catalog-empty-state.d.ts +4 -15
- package/dist/customize/shared/catalog/catalog-empty-state.js +9 -7
- 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 +48 -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 +1062 -85
- package/dist/i18n/en.js +1078 -101
- 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/apps-and-extensions/apps-modal.d.ts +9 -0
- package/dist/internal/apps-and-extensions/apps-modal.js +107 -0
- package/dist/internal/auth/auth-card-shell.js +3 -3
- package/dist/internal/chrome/browser-icon.d.ts +24 -0
- package/dist/internal/chrome/browser-icon.js +58 -0
- package/dist/internal/chrome/chrome-card-state.d.ts +16 -0
- package/dist/internal/chrome/chrome-card-state.js +9 -0
- package/dist/internal/chrome/chrome-connect.d.ts +69 -0
- package/dist/internal/chrome/chrome-connect.js +178 -0
- package/dist/internal/chrome/chrome-mock.d.ts +4 -0
- package/dist/internal/chrome/chrome-mock.js +15 -0
- package/dist/internal/chrome/chrome-names.d.ts +15 -0
- package/dist/internal/chrome/chrome-names.js +35 -0
- package/dist/internal/chrome/extension.d.ts +47 -0
- package/dist/internal/chrome/extension.js +91 -0
- package/dist/internal/chrome/use-chrome-offered.d.ts +11 -0
- package/dist/internal/chrome/use-chrome-offered.js +22 -0
- package/dist/internal/components/agent-mark.js +5 -2
- package/dist/internal/connector-logo/connector-logo-source.d.ts +64 -0
- package/dist/internal/connector-logo/connector-logo-source.js +49 -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/edge.d.ts +5 -0
- package/dist/internal/icons/edge.js +10 -0
- 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/extensions.js +17 -3
- 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/detect-os.d.ts +43 -0
- package/dist/internal/lib/detect-os.js +70 -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 +13 -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/apps-modal-store.d.ts +8 -0
- package/dist/internal/stores/apps-modal-store.js +6 -0
- package/dist/internal/stores/composer-prefill-store.d.ts +12 -5
- 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 +9 -3
- 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/empty-state.d.ts +2 -2
- package/dist/primitives/empty-state.js +6 -5
- 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-audit-shared.js +3 -1
- 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 +8 -2
- package/dist/session/participants/session-participants.js +11 -4
- package/dist/session/prompts/approval-request.d.ts +5 -0
- package/dist/session/prompts/approval-request.js +9 -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 +15 -1
- package/dist/session/thread/session-thread.js +20 -3
- package/dist/session/thread/session-transcript-class.d.ts +5 -1
- package/dist/session/thread/session-transcript-class.js +5 -1
- 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 +241 -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 +14 -6
- package/dist/session/turn/user-message.js +35 -15
- 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/session-label-badges.js +2 -1
- 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-chrome-nav.d.ts +10 -0
- package/dist/workspace/sidebar/footer/project-chrome-nav.js +56 -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 +13 -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 +67 -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 +29 -5
- 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
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface ImageFrameProps {
|
|
3
|
+
/** CSS `aspect-ratio` before the image loads (`"3 / 2"`); the image's natural size replaces it on load. */
|
|
4
|
+
aspectRatio: string;
|
|
5
|
+
src: string | null;
|
|
6
|
+
alt: string;
|
|
7
|
+
/** The image does not exist yet, or its bytes are on the way. */
|
|
8
|
+
pending: boolean;
|
|
9
|
+
/** Centered over the frame: the busy line, or a note. */
|
|
10
|
+
label?: ReactNode;
|
|
11
|
+
/** Makes the image a button (open it in the file viewer). */
|
|
12
|
+
onOpen?: () => void;
|
|
13
|
+
className?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Fill the parent's box (a tile of a layout) and crop the image to it
|
|
16
|
+
* (`object-cover`), in place of holding `aspectRatio` and fitting the image.
|
|
17
|
+
*/
|
|
18
|
+
fill?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* The tallest the frame may be (`'60vh'`): it narrows to keep its ratio,
|
|
21
|
+
* so it never crops more and never letterboxes. Unset: the full width.
|
|
22
|
+
*/
|
|
23
|
+
maxHeight?: string;
|
|
24
|
+
/** The image button's accessible name; `alt` when unset. */
|
|
25
|
+
openLabel?: string;
|
|
26
|
+
/** The image's natural ratio when another surface already measured it (`"<w> / <h>"`), so a remount starts at it. */
|
|
27
|
+
naturalRatio?: string | null;
|
|
28
|
+
/** Reports the image's natural size once it decoded. */
|
|
29
|
+
onNaturalSize?: (width: number, height: number) => void;
|
|
30
|
+
/** Drawn over the frame's own box (an overlay on the image's corner), which narrows with `maxHeight`. */
|
|
31
|
+
children?: ReactNode;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The box an image takes before, while and after it exists: a flat `bg-muted`
|
|
35
|
+
* surface that holds the requested aspect ratio before any pixel arrives, so
|
|
36
|
+
* the layout does not jump when the image lands, then fades the image in.
|
|
37
|
+
* The frame itself never moves: the busy signal is the label (one waiting
|
|
38
|
+
* channel, kortix-brand `layout.md` States).
|
|
39
|
+
*/
|
|
40
|
+
export declare function ImageFrame({ aspectRatio, src, alt, pending, label, onOpen, className, fill, maxHeight, openLabel, naturalRatio, onNaturalSize, children, }: ImageFrameProps): import("react").JSX.Element;
|
|
41
|
+
/**
|
|
42
|
+
* An image whose file could not be read: "Image unavailable" and Try again,
|
|
43
|
+
* centered in the frame. Never the read's own error text (R38): that is
|
|
44
|
+
* internal (a status line, a path, a stack), not something a reader can act on.
|
|
45
|
+
*/
|
|
46
|
+
export declare function ImageUnavailable({ onRetry }: {
|
|
47
|
+
onRetry: () => void;
|
|
48
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useTranslations } from '../../i18n/index.js';
|
|
4
|
+
import { Button } from '../../primitives/button.js';
|
|
5
|
+
import { cn } from '../../lib/utils.js';
|
|
6
|
+
import { useEffect, useRef, useState } from 'react';
|
|
7
|
+
/** `'3 / 2'` → `1.5`; anything unreadable → `1`. */
|
|
8
|
+
function ratioValue(ratio) {
|
|
9
|
+
const [w, h] = ratio.split('/').map((part) => Number(part.trim()));
|
|
10
|
+
return w && h ? w / h : 1;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The box an image takes before, while and after it exists: a flat `bg-muted`
|
|
14
|
+
* surface that holds the requested aspect ratio before any pixel arrives, so
|
|
15
|
+
* the layout does not jump when the image lands, then fades the image in.
|
|
16
|
+
* The frame itself never moves: the busy signal is the label (one waiting
|
|
17
|
+
* channel, kortix-brand `layout.md` States).
|
|
18
|
+
*/
|
|
19
|
+
export function ImageFrame({ aspectRatio, src, alt, pending, label, onOpen, className, fill = false, maxHeight, openLabel, naturalRatio = null, onNaturalSize, children, }) {
|
|
20
|
+
const img = useRef(null);
|
|
21
|
+
const [loaded, setLoaded] = useState(false);
|
|
22
|
+
const [natural, setNatural] = useState(naturalRatio);
|
|
23
|
+
// A new source starts hidden at the requested ratio again; a cached one may
|
|
24
|
+
// be complete before React sees `load`.
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
const el = img.current;
|
|
27
|
+
const complete = !!el?.complete && el.naturalWidth > 0;
|
|
28
|
+
setLoaded(complete);
|
|
29
|
+
setNatural(complete && el ? `${el.naturalWidth} / ${el.naturalHeight}` : naturalRatio);
|
|
30
|
+
// The ratio is the cached one until this source decodes; a new source is measured on load.
|
|
31
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
32
|
+
}, [src]);
|
|
33
|
+
const onLoad = () => {
|
|
34
|
+
const el = img.current;
|
|
35
|
+
if (el?.naturalWidth && el.naturalHeight) {
|
|
36
|
+
setNatural(`${el.naturalWidth} / ${el.naturalHeight}`);
|
|
37
|
+
onNaturalSize?.(el.naturalWidth, el.naturalHeight);
|
|
38
|
+
}
|
|
39
|
+
setLoaded(true);
|
|
40
|
+
};
|
|
41
|
+
const image = src ? (
|
|
42
|
+
// eslint-disable-next-line @next/next/no-img-element -- a blob: URL of a sandbox file; the Next loader cannot fetch it
|
|
43
|
+
_jsx("img", { ref: img, src: src, alt: alt, onLoad: onLoad, className: cn('size-full transition-[opacity,filter] duration-moderate ease-out motion-reduce:blur-none', fill ? 'object-cover' : 'object-contain', loaded ? 'opacity-100 blur-none' : 'opacity-0 blur-xs') })) : null;
|
|
44
|
+
return (_jsxs("div", { "aria-busy": pending, className: cn('bg-muted relative w-full overflow-hidden rounded-md', fill && 'h-full', className), style: fill
|
|
45
|
+
? undefined
|
|
46
|
+
: {
|
|
47
|
+
aspectRatio: natural ?? aspectRatio,
|
|
48
|
+
...(maxHeight && { width: `min(100%, calc(${maxHeight} * ${ratioValue(natural ?? aspectRatio)}))` }),
|
|
49
|
+
}, children: [image && onOpen ? (_jsx("button", { type: "button", onClick: onOpen, "aria-label": openLabel ?? alt, className: "focus-visible:ring-kortix-base block size-full cursor-zoom-in rounded-md focus-visible:ring-2 focus-visible:outline-none focus-visible:ring-inset", children: image })) : (image), label ? (_jsx("div", { className: "absolute inset-0 flex items-center justify-center p-4 text-center", children: label })) : null, children] }));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* An image whose file could not be read: "Image unavailable" and Try again,
|
|
53
|
+
* centered in the frame. Never the read's own error text (R38): that is
|
|
54
|
+
* internal (a status line, a path, a stack), not something a reader can act on.
|
|
55
|
+
*/
|
|
56
|
+
export function ImageUnavailable({ onRetry }) {
|
|
57
|
+
const t = useTranslations('imageGen');
|
|
58
|
+
return (_jsxs("span", { className: "text-muted-foreground flex flex-col items-center gap-2 text-xs", children: [t('unavailable'), _jsx(Button, { type: "button", variant: "secondary", size: "sm", className: "active:scale-[0.96]", onClick: onRetry, children: t('tryAgain') })] }));
|
|
59
|
+
}
|
|
@@ -24,6 +24,16 @@ interface ImageRendererProps {
|
|
|
24
24
|
/** Add the backdrop swatches to the shelf (see `ImageBackdrop`). Off by
|
|
25
25
|
* default — an opaque JPEG has exactly one meaningful background. */
|
|
26
26
|
backdrop?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* The image's details toggle (ⓘ), last on the shelf: shown only when the
|
|
29
|
+
* host has details for this image (a generated image's prompt and model).
|
|
30
|
+
* It is a `DisclosureTrigger`: the host renders this renderer inside the
|
|
31
|
+
* `Disclosure` whose content holds the details.
|
|
32
|
+
*/
|
|
33
|
+
info?: {
|
|
34
|
+
pressed: boolean;
|
|
35
|
+
label: string;
|
|
36
|
+
};
|
|
27
37
|
}
|
|
28
|
-
export declare function ImageRenderer({ url, className, fileName, controls, backdrop: showBackdrop, }: ImageRendererProps): React.JSX.Element;
|
|
38
|
+
export declare function ImageRenderer({ url, className, fileName, controls, backdrop: showBackdrop, info, }: ImageRendererProps): React.JSX.Element;
|
|
29
39
|
export {};
|
|
@@ -6,10 +6,20 @@ import { Button } from '../../primitives/button.js';
|
|
|
6
6
|
import { ButtonGroup, ButtonGroupSeparator } from '../../primitives/button-group.js';
|
|
7
7
|
import Hint from '../../primitives/hint.js';
|
|
8
8
|
import Loading from '../../primitives/loading.js';
|
|
9
|
+
import { IconInfo } from '../../primitives/kortix-icons.js';
|
|
10
|
+
import { DisclosureTrigger } from '../../primitives/disclosure.js';
|
|
9
11
|
import { usePreviewFit } from '../viewer/preview-fit.js';
|
|
10
12
|
import { cn } from '../../lib/utils.js';
|
|
11
13
|
import { ImageBrokenIcon as ImageOff, ArrowClockwiseIcon as RotateCw, MagnifyingGlassPlusIcon as ZoomIn, MagnifyingGlassMinusIcon as ZoomOut, } from '@phosphor-icons/react';
|
|
12
14
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
15
|
+
/**
|
|
16
|
+
* The details toggle: a `DisclosureTrigger` (toggle, Enter/Space,
|
|
17
|
+
* `aria-expanded`) around the shelf's button. Props and ref pass through, so
|
|
18
|
+
* the tooltip trigger around it still works.
|
|
19
|
+
*/
|
|
20
|
+
function InfoTrigger({ pressed, label, ...props }) {
|
|
21
|
+
return (_jsx(DisclosureTrigger, { children: _jsx(Button, { ...props, variant: "secondary", size: "icon-base", "aria-label": label, "aria-pressed": pressed, "data-image-info": "", children: _jsx(IconInfo, { className: "size-4", weight: pressed ? 'fill' : 'regular' }) }) }));
|
|
22
|
+
}
|
|
13
23
|
const MAX_RETRIES = 3;
|
|
14
24
|
const RETRY_DELAYS = [500, 1500, 3000]; // ms — escalating backoff
|
|
15
25
|
const MIN_ZOOM = 0.25;
|
|
@@ -43,7 +53,7 @@ const BACKDROPS = [
|
|
|
43
53
|
{ value: 'white', label: 'White' },
|
|
44
54
|
{ value: 'black', label: 'Black' },
|
|
45
55
|
];
|
|
46
|
-
export function ImageRenderer({ url, className, fileName, controls = 'hover', backdrop: showBackdrop = false, }) {
|
|
56
|
+
export function ImageRenderer({ url, className, fileName, controls = 'hover', backdrop: showBackdrop = false, info, }) {
|
|
47
57
|
const tHardcodedUi = useTranslations('hardcodedUi');
|
|
48
58
|
const backdrops = useLocalizedUiCatalog(BACKDROPS);
|
|
49
59
|
// `null` outside a <PreviewFitProvider> (Advanced-mode viewer, /projects
|
|
@@ -230,8 +240,8 @@ export function ImageRenderer({ url, className, fileName, controls = 'hover', ba
|
|
|
230
240
|
: [
|
|
231
241
|
'top-1 opacity-0 transition-opacity duration-200 ease-out',
|
|
232
242
|
'group-hover:opacity-100 focus-within:opacity-100',
|
|
233
|
-
showInfo && 'opacity-100',
|
|
234
|
-
]), children: _jsxs(ButtonGroup, { children: [_jsx(Hint, { label: zoomOutLabel, side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon-base", onClick: handleZoomOut, disabled: zoom <= MIN_ZOOM, "aria-label": zoomOutLabel, children: _jsx(ZoomOut, { className: "size-4" }) }) }), _jsx(Hint, { label: tHardcodedUi.raw('i18nComplete.textce89ae822e8b'), side: "bottom", children: _jsxs(Button, { variant: "secondary", size: "sm", className: "min-w-14 tabular-nums", onClick: handleResetZoom, "aria-label": tHardcodedUi.raw('i18nComplete.textce89ae822e8b'), children: [Math.round(zoom * 100), "%"] }) }), _jsx(Hint, { label: zoomInLabel, side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon-base", onClick: handleZoomIn, disabled: zoom >= MAX_ZOOM, "aria-label": zoomInLabel, children: _jsx(ZoomIn, { className: "size-4" }) }) }), _jsx(Hint, { label: tHardcodedUi.raw('i18nComplete.textc3613b1704f5'), side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon-base", onClick: handleRotate, "aria-label": tHardcodedUi.raw('i18nComplete.text9dc6b57eecba'), children: _jsx(RotateCw, { className: "size-4" }) }) }), showBackdrop && (_jsxs(_Fragment, { children: [_jsx(ButtonGroupSeparator, {}), backdrops.map(({ value, label }) => (_jsx(Hint, { label: `${label} background`, side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon-base", onClick: () => setBackdrop(value), "aria-label": `${label} background`, "aria-pressed": backdrop === value, children: _jsx("span", { className: cn(
|
|
243
|
+
(showInfo || info?.pressed) && 'opacity-100',
|
|
244
|
+
]), children: _jsxs(ButtonGroup, { children: [_jsx(Hint, { label: zoomOutLabel, side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon-base", onClick: handleZoomOut, disabled: zoom <= MIN_ZOOM, "aria-label": zoomOutLabel, children: _jsx(ZoomOut, { className: "size-4" }) }) }), _jsx(Hint, { label: tHardcodedUi.raw('i18nComplete.textce89ae822e8b'), side: "bottom", children: _jsxs(Button, { variant: "secondary", size: "sm", className: "min-w-14 tabular-nums", onClick: handleResetZoom, "aria-label": tHardcodedUi.raw('i18nComplete.textce89ae822e8b'), children: [Math.round(zoom * 100), "%"] }) }), _jsx(Hint, { label: zoomInLabel, side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon-base", onClick: handleZoomIn, disabled: zoom >= MAX_ZOOM, "aria-label": zoomInLabel, children: _jsx(ZoomIn, { className: "size-4" }) }) }), _jsx(Hint, { label: tHardcodedUi.raw('i18nComplete.textc3613b1704f5'), side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon-base", onClick: handleRotate, "aria-label": tHardcodedUi.raw('i18nComplete.text9dc6b57eecba'), children: _jsx(RotateCw, { className: "size-4" }) }) }), info ? (_jsx(Hint, { label: info.label, side: "bottom", children: _jsx(InfoTrigger, { pressed: info.pressed, label: info.label }) })) : null, showBackdrop && (_jsxs(_Fragment, { children: [_jsx(ButtonGroupSeparator, {}), backdrops.map(({ value, label }) => (_jsx(Hint, { label: `${label} background`, side: "bottom", children: _jsx(Button, { variant: "secondary", size: "icon-base", onClick: () => setBackdrop(value), "aria-label": `${label} background`, "aria-pressed": backdrop === value, children: _jsx("span", { className: cn(
|
|
235
245
|
// A hairline on every swatch, not just the white one:
|
|
236
246
|
// without it the white chip vanishes on a light
|
|
237
247
|
// toolbar and the black one on a dark toolbar.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useSelectionCapability } from '@embedpdf/plugin-selection/react';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import { errorToast } from '../../../primitives/toast.js';
|
|
4
|
+
import { useTranslations } from '../../../i18n/index.js';
|
|
5
|
+
import { copyToClipboard } from '../../../internal/lib/utils/clipboard.js';
|
|
6
|
+
/** The upstream React utility leaves denied clipboard writes unhandled. */
|
|
7
|
+
export function PdfClipboard() {
|
|
8
|
+
const { provides: selection } = useSelectionCapability();
|
|
9
|
+
const t = useTranslations('commandPalette');
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (!selection)
|
|
12
|
+
return;
|
|
13
|
+
return selection.onCopyToClipboard(({ text }) => {
|
|
14
|
+
void copyToClipboard(text).then((copied) => {
|
|
15
|
+
if (!copied)
|
|
16
|
+
errorToast(t('copyFailed'));
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
}, [selection, t]);
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
@@ -9,7 +9,8 @@ import { RenderLayer, RenderPluginPackage } from '@embedpdf/plugin-render/react'
|
|
|
9
9
|
import { Rotate, RotatePluginPackage } from '@embedpdf/plugin-rotate/react';
|
|
10
10
|
import { ScrollPluginPackage, ScrollStrategy, useScroll, useScrollPlugin, } from '@embedpdf/plugin-scroll/react';
|
|
11
11
|
import { SearchLayer, SearchPluginPackage, useSearch } from '@embedpdf/plugin-search/react';
|
|
12
|
-
import {
|
|
12
|
+
import { SelectionPluginPackage } from '@embedpdf/plugin-selection';
|
|
13
|
+
import { useSelectionCapability, useSelectionPlugin, } from '@embedpdf/plugin-selection/react';
|
|
13
14
|
import { ThumbImg, ThumbnailPluginPackage, useThumbnailCapability, useThumbnailPlugin, } from '@embedpdf/plugin-thumbnail/react';
|
|
14
15
|
import { TilingLayer, TilingPluginPackage } from '@embedpdf/plugin-tiling/react';
|
|
15
16
|
import { useIsViewportGated, useViewportCapability, useViewportElement, useViewportRef, ViewportElementContext, ViewportPluginPackage, } from '@embedpdf/plugin-viewport/react';
|
|
@@ -36,6 +37,7 @@ import { cn } from '../../../lib/utils.js';
|
|
|
36
37
|
import { downloadBlob } from '../../../internal/lib/utils/download.js';
|
|
37
38
|
import { loadSharedPdfEngine } from './pdf-engine-loader.js';
|
|
38
39
|
import { SidebarGlyph as PanelLeft } from '../../../icons/sidebar-toggle.js';
|
|
40
|
+
import { PdfClipboard } from './pdf-clipboard.js';
|
|
39
41
|
const DEFAULT_ZOOM = 1;
|
|
40
42
|
const ZOOM_OPTIONS = [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2];
|
|
41
43
|
const PAGE_GAP = 24;
|
|
@@ -1218,7 +1220,7 @@ function PDFViewerInner({ viewerRef, pdfFile, documentId, document: pdfDocument,
|
|
|
1218
1220
|
}, children: _jsx(CircleMinus, { className: "size-4" }) }) }), _jsxs(Select, { value: String(currentZoomLevel), onValueChange: (value) => zoom?.requestZoom(Number(value)), disabled: controlsDisabled, modal: false, children: [_jsx(SelectTrigger, { size: "sm", className: "w-[84px] min-w-[84px] tabular-nums", children: _jsxs(SelectValue, { placeholder: tI18nComplete.raw('text509c517ede79'), children: [Math.round(currentZoomLevel * 100), "%"] }) }), _jsx(SelectContent, { alignItemWithTrigger: false, children: ZOOM_OPTIONS.map((option) => (_jsxs(SelectItem, { value: String(option), children: [Math.round(option * 100), "%"] }, option))) })] }), _jsx(ToolbarTooltip, { label: tI18nComplete.raw('text0e47f09a748f'), children: _jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", className: "transition-transform active:scale-[0.96]", "aria-label": tI18nComplete.raw('text0e47f09a748f'), disabled: controlsDisabled || currentZoomLevel >= ZOOM_OPTIONS[ZOOM_OPTIONS.length - 1], onClick: () => {
|
|
1219
1221
|
const nextZoom = ZOOM_OPTIONS.find((option) => option > currentZoomLevel);
|
|
1220
1222
|
zoom?.requestZoom(nextZoom ?? ZOOM_OPTIONS[ZOOM_OPTIONS.length - 1]);
|
|
1221
|
-
}, children: _jsx(CirclePlus, { className: "size-4" }) }) })] }), _jsx(Separator, { orientation: "vertical", className: "mx-1 h-4 self-center" }), _jsx(PDFViewerSearchControl, { documentId: documentId, controlsDisabled: controlsDisabled, initialSearch: findText }, documentId), toolbarActions ? (_jsxs(_Fragment, { children: [_jsx(Separator, { orientation: "vertical", className: "mx-1 h-4 self-center" }), toolbarActions] })) : null, showDownload || showUpload ? (_jsxs(_Fragment, { children: [_jsx(Separator, { orientation: "vertical", className: "mx-1 h-4 self-center" }), _jsx(PDFViewerFileActionsMenu, { onUploadFile: handleUpload, showUpload: showUpload }), showDownload ? (_jsx(ViewerDownloadButton, { disabled: controlsDisabled, pending: isPreparingDownload, onDownload: () => void handleDownload() })) : null] })) : null] }) })] })) : null, _jsxs("div", { ref: viewerShellRef, className: "bg-muted/30 relative flex min-h-0 flex-1 overflow-hidden", children: [isLoading ? (_jsx(PDFViewerLoadingSkeleton, { sidebarInline: sidebarInline, sidebarOpen: sidebarOpen })) : null, _jsxs("div", { className: "flex h-full max-h-full min-h-0 w-full flex-1 overflow-hidden", children: [_jsx(DocumentViewerThumbnailSidebar, { closedInlineClassName: THUMBNAIL_SIDEBAR_CLOSED_CLASS, inline: sidebarInline, open: thumbnailSidebarVisible, widthClassName: THUMBNAIL_SIDEBAR_WIDTH_CLASS, children: thumbnailSidebarVisible ? (_jsx(PDFViewerThumbnails, { basePageRotations: basePageRotations, documentId: documentId, activePage: activePage, pageCount: numPages, pageRotationDeltas: pageRotationDeltas, pdfDocument: pdfDocument, selectedPageIndexes: selectedPageIndexes, onSelectPage: selectThumbnailPage })) : null }), _jsxs(PDFViewerScrollAreaViewport, { documentId: documentId, className: "relative h-full max-h-full min-h-0 min-w-0 flex-1", children: [_jsx(PDFViewerViewportBridge, { viewportElementRef: viewportElementRef }), _jsx(PDFViewerSelectionCopyShortcut, { documentId: documentId }), _jsx(PDFViewerSelectionReleaseGuard, { documentId: documentId }), _jsx(GlobalPointerProvider, { documentId: documentId, children: _jsx(PDFViewerScroller, { basePageRotations: basePageRotations, documentId: documentId, pageRotationDeltas: pageRotationDeltas, renderPage: renderPage }) }), _jsx(
|
|
1223
|
+
}, children: _jsx(CirclePlus, { className: "size-4" }) }) })] }), _jsx(Separator, { orientation: "vertical", className: "mx-1 h-4 self-center" }), _jsx(PDFViewerSearchControl, { documentId: documentId, controlsDisabled: controlsDisabled, initialSearch: findText }, documentId), toolbarActions ? (_jsxs(_Fragment, { children: [_jsx(Separator, { orientation: "vertical", className: "mx-1 h-4 self-center" }), toolbarActions] })) : null, showDownload || showUpload ? (_jsxs(_Fragment, { children: [_jsx(Separator, { orientation: "vertical", className: "mx-1 h-4 self-center" }), _jsx(PDFViewerFileActionsMenu, { onUploadFile: handleUpload, showUpload: showUpload }), showDownload ? (_jsx(ViewerDownloadButton, { disabled: controlsDisabled, pending: isPreparingDownload, onDownload: () => void handleDownload() })) : null] })) : null] }) })] })) : null, _jsxs("div", { ref: viewerShellRef, className: "bg-muted/30 relative flex min-h-0 flex-1 overflow-hidden", children: [isLoading ? (_jsx(PDFViewerLoadingSkeleton, { sidebarInline: sidebarInline, sidebarOpen: sidebarOpen })) : null, _jsxs("div", { className: "flex h-full max-h-full min-h-0 w-full flex-1 overflow-hidden", children: [_jsx(DocumentViewerThumbnailSidebar, { closedInlineClassName: THUMBNAIL_SIDEBAR_CLOSED_CLASS, inline: sidebarInline, open: thumbnailSidebarVisible, widthClassName: THUMBNAIL_SIDEBAR_WIDTH_CLASS, children: thumbnailSidebarVisible ? (_jsx(PDFViewerThumbnails, { basePageRotations: basePageRotations, documentId: documentId, activePage: activePage, pageCount: numPages, pageRotationDeltas: pageRotationDeltas, pdfDocument: pdfDocument, selectedPageIndexes: selectedPageIndexes, onSelectPage: selectThumbnailPage })) : null }), _jsxs(PDFViewerScrollAreaViewport, { documentId: documentId, className: "relative h-full max-h-full min-h-0 min-w-0 flex-1", children: [_jsx(PDFViewerViewportBridge, { viewportElementRef: viewportElementRef }), _jsx(PDFViewerSelectionCopyShortcut, { documentId: documentId }), _jsx(PDFViewerSelectionReleaseGuard, { documentId: documentId }), _jsx(GlobalPointerProvider, { documentId: documentId, children: _jsx(PDFViewerScroller, { basePageRotations: basePageRotations, documentId: documentId, pageRotationDeltas: pageRotationDeltas, renderPage: renderPage }) }), _jsx(PdfClipboard, {})] })] })] })] }));
|
|
1222
1224
|
}
|
|
1223
1225
|
function PDFViewerDocumentLoader({ pdfFile, onDocumentLoadSuccess, ...innerProps }) {
|
|
1224
1226
|
const { provides: documentManager } = useDocumentManagerCapability();
|
|
@@ -44,6 +44,12 @@ export interface ShowContentProps {
|
|
|
44
44
|
* blob would run agent-authored script inside the app.
|
|
45
45
|
*/
|
|
46
46
|
attachment?: string;
|
|
47
|
+
/**
|
|
48
|
+
* The sha256 of the file's bytes, from the `show` output (R38): an image
|
|
49
|
+
* already loaded under another path (the generated original of a Drive
|
|
50
|
+
* copy) draws at once from the shared image store.
|
|
51
|
+
*/
|
|
52
|
+
sha256?: string;
|
|
47
53
|
/** Optional: render a proxied localhost iframe. Caller provides this component. */
|
|
48
54
|
LocalhostPreview?: React.ComponentType<{
|
|
49
55
|
url: string;
|
|
@@ -74,7 +80,7 @@ export interface ShowContentProps {
|
|
|
74
80
|
*/
|
|
75
81
|
toolbarActions?: React.ReactNode;
|
|
76
82
|
}
|
|
77
|
-
export declare function ShowContentRenderer({ type, title, description, path, url, content, language, aspectRatio, attachment, LocalhostPreview, fill, onStatusChange, toolbarActions, }: ShowContentProps): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
|
|
83
|
+
export declare function ShowContentRenderer({ type, title, description, path, url, content, language, aspectRatio, attachment, sha256, LocalhostPreview, fill, onStatusChange, toolbarActions, }: ShowContentProps): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
|
|
78
84
|
export interface ShowCarouselItem {
|
|
79
85
|
type: string;
|
|
80
86
|
title?: string;
|
|
@@ -86,6 +92,8 @@ export interface ShowCarouselItem {
|
|
|
86
92
|
aspect_ratio?: string;
|
|
87
93
|
/** Stored copy of `path` from saved history — see `ShowContentProps.attachment`. */
|
|
88
94
|
attachment?: string;
|
|
95
|
+
/** The bytes' sha256 from the `show` output — see `ShowContentProps.sha256`. */
|
|
96
|
+
sha256?: string;
|
|
89
97
|
/** `pending`: a grouped `show` call whose payload has not arrived yet. The
|
|
90
98
|
* slot holds its place so the card does not jump when it lands. */
|
|
91
99
|
status?: 'pending' | 'ready' | 'error';
|
|
@@ -36,6 +36,7 @@ import Loading from '../../primitives/loading.js';
|
|
|
36
36
|
import { TextShimmer } from '../../primitives/text-shimmer.js';
|
|
37
37
|
import { framePolicy } from '../viewer/preview-policy.js';
|
|
38
38
|
import { useBinaryBlob } from '../runtime/hooks/use-binary-blob.js';
|
|
39
|
+
import { useSharedImage } from '../runtime/hooks/use-shared-image.js';
|
|
39
40
|
import { sessionDriveMountPath } from '../../internal/files/session-drive-files.js';
|
|
40
41
|
import { useFileContent } from '../runtime/hooks/use-file-content.js';
|
|
41
42
|
import { useHeicBlob } from '../../internal/hooks/use-heic-url.js';
|
|
@@ -49,10 +50,14 @@ import { buildStaticFileLocalUrl, isSessionAttachmentRef } from '@kortix/sdk';
|
|
|
49
50
|
import { WarningIcon as AlertTriangle, CaretLeftIcon as ChevronLeft, CaretRightIcon as ChevronRight, ArrowSquareOutIcon as ExternalLink, FileIcon, FileTextIcon as FileText, FileXIcon as FileWarning, GlobeIcon as Globe, MusicNotesIcon as Music, } from '@phosphor-icons/react';
|
|
50
51
|
import { lazy, Suspense, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
51
52
|
import { ImageRenderer } from './image-renderer.js';
|
|
53
|
+
import { ImageFrame, ImageUnavailable } from './image-frame.js';
|
|
52
54
|
import { MermaidDiagram } from './mermaid/mermaid-diagram.js';
|
|
53
55
|
import { ViewerFrame } from './shared/viewer-frame.js';
|
|
54
56
|
import { resolveShowType, shouldRenderFromSandboxFile } from './show-type-utils.js';
|
|
55
57
|
import { VideoRenderer } from './video-renderer.js';
|
|
58
|
+
import { ShowConnectHero, showConnectTarget } from '../../markdown/setup-links/show-connect-hero.js';
|
|
59
|
+
import { ShowArtifactCard } from '../../artifacts/artifact-session.js';
|
|
60
|
+
import { parseArtifactUrl } from '../../artifacts/frame-policy.js';
|
|
56
61
|
// ── Lazy-load heavy renderers ──────────────────────────────────────────────
|
|
57
62
|
const PdfRenderer = lazy(() => import('./pdf/pdf-renderer.js').then((m) => ({ default: m.PdfRenderer })));
|
|
58
63
|
const CsvRenderer = lazy(() => import('./csv/csv-renderer.js').then((m) => ({ default: m.CsvRenderer })));
|
|
@@ -84,6 +89,35 @@ export function showDomain(url) {
|
|
|
84
89
|
return url;
|
|
85
90
|
}
|
|
86
91
|
}
|
|
92
|
+
const SHOW_LINK_COPY = { open: 'Open' };
|
|
93
|
+
/**
|
|
94
|
+
* The `url` show: one card, centered in the panel.
|
|
95
|
+
*
|
|
96
|
+
* A connect URL (a Kortix link or a provider's sign-in page) is not a page to
|
|
97
|
+
* visit: it renders the connect step, `ShowConnectHero`. Every other URL is a link card:
|
|
98
|
+
* favicon, title, domain, the agent's sentence, and an explicit Open action.
|
|
99
|
+
*/
|
|
100
|
+
function ShowLink({ url, title, description }) {
|
|
101
|
+
const connect = showConnectTarget(url, title);
|
|
102
|
+
if (connect) {
|
|
103
|
+
return _jsx(ShowConnectHero, { url: url, target: connect, title: title, description: description });
|
|
104
|
+
}
|
|
105
|
+
// A Kortix artifact's link shows the artifact (a session page opens it in its panel,
|
|
106
|
+
// like an App link); a link the viewer cannot open stays a link.
|
|
107
|
+
if (parseArtifactUrl(url)) {
|
|
108
|
+
return _jsx(ShowArtifactCard, { url: url, fallback: _jsx(ShowLinkCard, { url: url, title: title, description: description }) });
|
|
109
|
+
}
|
|
110
|
+
return _jsx(ShowLinkCard, { url: url, title: title, description: description });
|
|
111
|
+
}
|
|
112
|
+
function ShowLinkCard({ url, title, description }) {
|
|
113
|
+
const copy = useLocalizedUiCatalog(SHOW_LINK_COPY);
|
|
114
|
+
const favicon = showFavicon(url);
|
|
115
|
+
const domain = showDomain(url);
|
|
116
|
+
const [faviconFailed, setFaviconFailed] = useState(false);
|
|
117
|
+
return (_jsxs("a", { href: url, target: "_blank", rel: "noopener noreferrer", "data-testid": "show-link-card", className: "group border-border bg-card hover:bg-hover flex w-full max-w-xl items-start gap-3 rounded-lg border p-4 transition-colors", children: [_jsx("span", { className: "bg-muted flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-md", children: favicon && !faviconFailed ? (
|
|
118
|
+
/* eslint-disable-next-line @next/next/no-img-element */
|
|
119
|
+
_jsx("img", { src: favicon, alt: "", className: "size-5 rounded-sm", onError: () => setFaviconFailed(true) })) : (_jsx(Globe, { className: "text-muted-foreground size-4" })) }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "text-foreground block truncate text-sm font-medium", children: title || domain }), _jsx("span", { className: "text-muted-foreground block truncate text-xs", children: domain }), description ? (_jsx("span", { className: "text-muted-foreground mt-2 line-clamp-3 block text-sm text-pretty", children: description })) : null] }), _jsxs("span", { className: "text-muted-foreground group-hover:text-foreground flex shrink-0 items-center gap-1 text-xs font-medium transition-colors", children: [copy.open, _jsx(ExternalLink, { className: "size-3.5" })] })] }));
|
|
120
|
+
}
|
|
87
121
|
export function showAspectRatioToCSS(ar) {
|
|
88
122
|
if (!ar || ar === 'auto')
|
|
89
123
|
return undefined;
|
|
@@ -138,8 +172,9 @@ function FileCard({ title, fileName, path }) {
|
|
|
138
172
|
return (_jsxs("div", { className: "flex items-center gap-4 px-5 py-5", children: [_jsx("div", { className: "bg-muted/20 flex size-12 items-center justify-center rounded-xl", children: _jsx(FileText, { className: "text-muted-foreground/40 size-6" }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-foreground truncate text-sm font-medium", children: title || fileName }), _jsx("div", { className: "text-muted-foreground/50 mt-0.5 truncate font-mono text-xs", children: path })] })] }));
|
|
139
173
|
}
|
|
140
174
|
// ── Component ──────────────────────────────────────────────────────────────
|
|
141
|
-
export function ShowContentRenderer({ type, title = '', description = '', path = '', url = '', content = '', language = '', aspectRatio = '', attachment, LocalhostPreview, fill = false, onStatusChange, toolbarActions, }) {
|
|
175
|
+
export function ShowContentRenderer({ type, title = '', description = '', path = '', url = '', content = '', language = '', aspectRatio = '', attachment, sha256, LocalhostPreview, fill = false, onStatusChange, toolbarActions, }) {
|
|
142
176
|
const tI18nComplete = useTranslations('hardcodedUi.i18nComplete');
|
|
177
|
+
const tImageGen = useTranslations('imageGen');
|
|
143
178
|
const arCSS = showAspectRatioToCSS(aspectRatio);
|
|
144
179
|
// ── Height presets — fill the panel vs. the compact inline card ──
|
|
145
180
|
// `mediaH` → visual media (image/video/pdf/sheets/docs/generic file)
|
|
@@ -220,9 +255,16 @@ export function ShowContentRenderer({ type, title = '', description = '', path =
|
|
|
220
255
|
// its sandbox read is a base64 text read, but a stored copy is bytes.
|
|
221
256
|
const storedCopy = isSessionAttachmentRef(attachment) ? attachment : null;
|
|
222
257
|
const blobFilePath = showBlobSource({ effectiveType, attachment, sandboxPath });
|
|
223
|
-
const { blobUrl, blob: rawBlob, isLoading: blobLoading, error: blobError, } = useBinaryBlob(blobFilePath);
|
|
224
258
|
// HEIC conversion — converts the raw blob to renderable JPEG
|
|
225
259
|
const isHeic = isImage && isHeicFile(fileName);
|
|
260
|
+
// Every other image draws from the page's shared image store (R38): by its
|
|
261
|
+
// sha256 when another surface already loaded those bytes, else read once.
|
|
262
|
+
const sharedImage = useSharedImage(isImage && !isHeic ? blobFilePath : null, isImage && !isHeic ? sha256 : null);
|
|
263
|
+
const binary = useBinaryBlob(isImage && !isHeic ? null : blobFilePath);
|
|
264
|
+
const { blob: rawBlob } = binary;
|
|
265
|
+
const blobUrl = isImage && !isHeic ? sharedImage.url : binary.blobUrl;
|
|
266
|
+
const blobLoading = isImage && !isHeic ? sharedImage.loading : binary.isLoading;
|
|
267
|
+
const blobError = isImage && !isHeic ? sharedImage.error : binary.error;
|
|
226
268
|
const { url: heicImageUrl, isConverting: heicConverting } = useHeicBlob(isHeic ? rawBlob : null, fileName);
|
|
227
269
|
// PDF: base64 content via SDK, decoded by PdfRenderer into a Blob URL.
|
|
228
270
|
const pdfLoadPath = isPdf && sandboxPath && !storedCopy ? sandboxPath : null;
|
|
@@ -352,13 +394,7 @@ export function ShowContentRenderer({ type, title = '', description = '', path =
|
|
|
352
394
|
if (!safeExternalUrl) {
|
|
353
395
|
return (_jsx("div", { className: "px-5 py-4", children: _jsxs("div", { className: "text-muted-foreground flex items-center gap-2 truncate font-mono text-xs", children: [_jsx(Globe, { className: "size-3.5 shrink-0" }), url] }) }));
|
|
354
396
|
}
|
|
355
|
-
|
|
356
|
-
const domain = showDomain(safeExternalUrl);
|
|
357
|
-
return (_jsx("div", { className: cn('px-5 py-5', fill && 'flex h-full items-center'), children: _jsxs("a", { href: safeExternalUrl, target: "_blank", rel: "noopener noreferrer", className: "group border-border/30 bg-muted/5 hover:bg-muted/20 flex w-full items-center gap-4 rounded-2xl border p-4 transition-colors", children: [_jsx("div", { className: "bg-muted/30 flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-lg", children: favicon ? (
|
|
358
|
-
/* eslint-disable-next-line @next/next/no-img-element */
|
|
359
|
-
_jsx("img", { src: favicon, alt: "", className: "size-6 rounded", onError: (e) => {
|
|
360
|
-
e.target.style.display = 'none';
|
|
361
|
-
} })) : (_jsx(Globe, { className: "text-muted-foreground/50 size-5" })) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-foreground group-hover:text-primary truncate text-sm font-medium transition-colors", children: title || domain }), _jsx("div", { className: "text-muted-foreground/60 mt-0.5 truncate font-mono text-xs", children: domain }), description && (_jsx("div", { className: "text-muted-foreground mt-1 line-clamp-2 text-xs", children: description }))] }), _jsx(ExternalLink, { className: "text-muted-foreground/30 group-hover:text-muted-foreground/60 size-4 shrink-0 transition-colors" })] }) }));
|
|
397
|
+
return (_jsx("div", { className: cn('flex justify-center px-5 py-5', fill && 'h-full items-center'), children: _jsx(ShowLink, { url: safeExternalUrl, title: title, description: description }) }));
|
|
362
398
|
}
|
|
363
399
|
// ═════════════════════════════════════════════════════════════════════════
|
|
364
400
|
// Image — loaded via useBinaryBlob → blobUrl → ImageRenderer
|
|
@@ -369,10 +405,16 @@ export function ShowContentRenderer({ type, title = '', description = '', path =
|
|
|
369
405
|
// it an image had no way to open in the side panel.
|
|
370
406
|
// ═════════════════════════════════════════════════════════════════════════
|
|
371
407
|
if (isImage && path) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
408
|
+
// The same frame the image_gen card draws while its image is on the way,
|
|
409
|
+
// inside the same header the loaded image gets, so nothing grows on load.
|
|
410
|
+
// Never a bare path.
|
|
411
|
+
if (blobLoading || heicConverting) {
|
|
412
|
+
return framed(_jsx("div", { className: mediaH, children: _jsx(ImageFrame, { aspectRatio: "auto", src: null, alt: title || fileName, pending: true, label: _jsxs("span", { className: "text-muted-foreground flex items-center gap-2 text-xs", children: [_jsx(Loading, { className: "size-4 shrink-0" }), tImageGen('loading')] }), className: "h-full rounded-none" }) }));
|
|
413
|
+
}
|
|
414
|
+
// Never the read's raw error text on an image (R38): a short note and Try again.
|
|
415
|
+
if (blobError) {
|
|
416
|
+
return framed(_jsx("div", { className: mediaH, children: _jsx(ImageFrame, { aspectRatio: "auto", src: null, alt: title || fileName, pending: false, label: _jsx(ImageUnavailable, { onRetry: sharedImage.retry }), className: "h-full rounded-none" }) }));
|
|
417
|
+
}
|
|
376
418
|
// HEIC: use the converted JPEG URL
|
|
377
419
|
const imageUrl = isHeic ? heicImageUrl : blobUrl;
|
|
378
420
|
if (imageUrl) {
|
|
@@ -695,7 +737,7 @@ export function ShowCarousel({ items, LocalhostPreview, onIndexChange, fill = fa
|
|
|
695
737
|
return (_jsxs("div", { role: "group", className: cn('outline-none', fill && 'flex h-full flex-col'),
|
|
696
738
|
// -1: a click on the content focuses the card, so ←/→ page it next,
|
|
697
739
|
// without adding a Tab stop. Tab still reaches the chevrons inside.
|
|
698
|
-
tabIndex: fill || count < 2 ? undefined : -1, onKeyDown: fill || count < 2 ? undefined : (e) => handleArrowKey(e), children: [_jsx("div", { className: cn(fill ? 'min-h-0 flex-1 overflow-hidden' : 'min-h-[420px]'), children: currentItem.status === 'pending' ? (_jsxs("div", { className: cn('flex items-center justify-center gap-3', fill ? 'h-full' : 'min-h-[420px]'), children: [_jsx(Loading, { className: "text-muted-foreground size-4" }), _jsx(TextShimmer, { duration: 1, spread: 2, className: "text-sm", children: tHardcodedUi.raw('componentsSessionToolRenderers.line4935JsxTextPreparingOutput') })] })) : (_jsx(ShowContentRenderer, { type: currentItem.type, title: currentItem.title, description: currentItem.description, path: currentItem.path, url: currentItem.url, content: currentItem.content, language: currentItem.language, aspectRatio: currentItem.aspect_ratio, attachment: currentItem.attachment, LocalhostPreview: LocalhostPreview, toolbarActions: toolbarActions, fill: fill })) }), count > 1 && !hideNav && (_jsxs("div", { className: "border-border flex shrink-0 items-center gap-2 border-t px-2 py-1.5 pr-3.5", children: [_jsxs("div", { className: "flex shrink-0 items-center", children: [_jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: prev, className: "hit-area-2 hit-area-r-0 transition-transform active:scale-[0.96]", disabled: currentIndex === 0, "aria-label": tI18nComplete.raw('text81b35f1b4332'), children: _jsx(ChevronLeft, { className: "size-4" }) }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: next, className: "hit-area-2 hit-area-l-0 transition-transform active:scale-[0.96]", disabled: currentIndex >= count - 1, "aria-label": tI18nComplete.raw('text1e47d4f7a1a3'), children: _jsx(ChevronRight, { className: "size-4" }) })] }), _jsx(FadedScrollArea, { ref: stripRef, orientation: "horizontal", fadeColor: "from-secondary", className: "min-w-0 flex-1 overscroll-x-contain", children: _jsx("div", { className: "flex w-max min-w-0 items-center gap-1", children: items.map((item, i) => {
|
|
740
|
+
tabIndex: fill || count < 2 ? undefined : -1, onKeyDown: fill || count < 2 ? undefined : (e) => handleArrowKey(e), children: [_jsx("div", { className: cn(fill ? 'min-h-0 flex-1 overflow-hidden' : 'min-h-[420px]'), children: currentItem.status === 'pending' ? (_jsxs("div", { className: cn('flex items-center justify-center gap-3', fill ? 'h-full' : 'min-h-[420px]'), children: [_jsx(Loading, { className: "text-muted-foreground size-4" }), _jsx(TextShimmer, { duration: 1, spread: 2, className: "text-sm", children: tHardcodedUi.raw('componentsSessionToolRenderers.line4935JsxTextPreparingOutput') })] })) : (_jsx(ShowContentRenderer, { type: currentItem.type, title: currentItem.title, description: currentItem.description, path: currentItem.path, url: currentItem.url, content: currentItem.content, language: currentItem.language, aspectRatio: currentItem.aspect_ratio, attachment: currentItem.attachment, sha256: currentItem.sha256, LocalhostPreview: LocalhostPreview, toolbarActions: toolbarActions, fill: fill })) }), count > 1 && !hideNav && (_jsxs("div", { className: "border-border flex shrink-0 items-center gap-2 border-t px-2 py-1.5 pr-3.5", children: [_jsxs("div", { className: "flex shrink-0 items-center", children: [_jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: prev, className: "hit-area-2 hit-area-r-0 transition-transform active:scale-[0.96]", disabled: currentIndex === 0, "aria-label": tI18nComplete.raw('text81b35f1b4332'), children: _jsx(ChevronLeft, { className: "size-4" }) }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: next, className: "hit-area-2 hit-area-l-0 transition-transform active:scale-[0.96]", disabled: currentIndex >= count - 1, "aria-label": tI18nComplete.raw('text1e47d4f7a1a3'), children: _jsx(ChevronRight, { className: "size-4" }) })] }), _jsx(FadedScrollArea, { ref: stripRef, orientation: "horizontal", fadeColor: "from-secondary", className: "min-w-0 flex-1 overscroll-x-contain", children: _jsx("div", { className: "flex w-max min-w-0 items-center gap-1", children: items.map((item, i) => {
|
|
699
741
|
const label = labels[i] ?? 'Item';
|
|
700
742
|
const isPortLabel = label.startsWith(':');
|
|
701
743
|
return (_jsx("button", { ref: (el) => {
|
|
@@ -3,6 +3,7 @@ import { downloadFile, uploadFile } from '../../internal/files/runtime-files.js'
|
|
|
3
3
|
import { useFileContent } from './hooks/index.js';
|
|
4
4
|
import { useBinaryBlob } from './hooks/use-binary-blob.js';
|
|
5
5
|
import { useFileRefresh } from './hooks/use-file-refresh.js';
|
|
6
|
+
import { useViewerImage } from './hooks/use-shared-image.js';
|
|
6
7
|
// Do not import this component through the project-files barrel. The barrel
|
|
7
8
|
// reaches useGitStatus through useChangeRequests and re-enters packages/ui/src/files/runtime.
|
|
8
9
|
// Webpack cannot evaluate that async cycle while building this module constant.
|
|
@@ -19,4 +20,5 @@ export const workspaceFileSource = {
|
|
|
19
20
|
upload: uploadFile,
|
|
20
21
|
Breadcrumbs: FilePathBreadcrumbs,
|
|
21
22
|
useRefresh: useFileRefresh,
|
|
23
|
+
useSharedImage: useViewerImage,
|
|
22
24
|
};
|
|
@@ -21,9 +21,18 @@ export { binaryBlobKeys };
|
|
|
21
21
|
* renders its bytes instead of waiting on a box that is not coming. A stored
|
|
22
22
|
* copy is immutable, so it is never refetched and never polled.
|
|
23
23
|
*/
|
|
24
|
-
export declare function useBinaryBlob(filePath: string | null
|
|
24
|
+
export declare function useBinaryBlob(filePath: string | null, options?: {
|
|
25
|
+
/**
|
|
26
|
+
* An image tile's wait (R38): a runtime still starting is polled with a
|
|
27
|
+
* backoff and given up after about 2 min (`imageWakingRefetchInterval`),
|
|
28
|
+
* instead of the viewer's open-ended waking poll.
|
|
29
|
+
*/
|
|
30
|
+
imageWait?: boolean;
|
|
31
|
+
}): {
|
|
25
32
|
blobUrl: string | null;
|
|
26
33
|
blob: Blob | null;
|
|
27
34
|
isLoading: boolean;
|
|
28
35
|
error: string | null;
|
|
36
|
+
/** The image wait gave up (`options.imageWait`): show it unavailable, with Try again. */
|
|
37
|
+
waitedOut: boolean;
|
|
29
38
|
};
|
|
@@ -6,7 +6,7 @@ import { useEffect, useMemo, useState } from 'react';
|
|
|
6
6
|
import { readRuntimeFileWithRetry } from '../../../internal/files/runtime-file-read.js';
|
|
7
7
|
import { readFileAsBlob } from '../../../internal/files/runtime-files.js';
|
|
8
8
|
import { keepBlobIfUnchanged } from './blob-identity.js';
|
|
9
|
-
import { sandboxWakingRefetchInterval } from '../../../internal/files/file-read-retry.js';
|
|
9
|
+
import { imageWaitedOut, imageWakingRefetchInterval, sandboxWakingRefetchInterval, } from '../../../internal/files/file-read-retry.js';
|
|
10
10
|
import { useServerHealth } from './use-server-health.js';
|
|
11
11
|
// ── Query keys ─────────────────────────────────────────────────────────────
|
|
12
12
|
// Keyed by the SDK factory: the live event stream invalidates it on
|
|
@@ -34,7 +34,8 @@ export { binaryBlobKeys };
|
|
|
34
34
|
* renders its bytes instead of waiting on a box that is not coming. A stored
|
|
35
35
|
* copy is immutable, so it is never refetched and never polled.
|
|
36
36
|
*/
|
|
37
|
-
export function useBinaryBlob(filePath) {
|
|
37
|
+
export function useBinaryBlob(filePath, options) {
|
|
38
|
+
const imageWait = !!options?.imageWait;
|
|
38
39
|
const serverUrl = useRuntimeStore((s) => s.getActiveServerUrl());
|
|
39
40
|
// Asleep, not booting — the re-read below takes the slow lane.
|
|
40
41
|
const { parked } = useServerHealth();
|
|
@@ -72,7 +73,11 @@ export function useBinaryBlob(filePath) {
|
|
|
72
73
|
// A readiness 503 is a pending state, not a failure. A booting box earns the
|
|
73
74
|
// fast cadence; a parked one is watched slowly. See the helper. A stored
|
|
74
75
|
// copy has no box to wait for.
|
|
75
|
-
refetchInterval: (query) => stored
|
|
76
|
+
refetchInterval: (query) => stored
|
|
77
|
+
? false
|
|
78
|
+
: imageWait
|
|
79
|
+
? imageWakingRefetchInterval(query.state.error, query.state.errorUpdateCount)
|
|
80
|
+
: sandboxWakingRefetchInterval(query.state.error, parked),
|
|
76
81
|
});
|
|
77
82
|
const cachedBlob = query.data ?? null;
|
|
78
83
|
// ── Blob URL — derived per-mount, revoked on unmount/change ─────────
|
|
@@ -98,5 +103,6 @@ export function useBinaryBlob(filePath) {
|
|
|
98
103
|
blob: cachedBlob,
|
|
99
104
|
isLoading: query.isLoading,
|
|
100
105
|
error: query.error?.message ?? null,
|
|
101
|
-
|
|
106
|
+
waitedOut: imageWait && imageWaitedOut(query.error, query.errorUpdateCount),
|
|
107
|
+
}), [blobUrl, cachedBlob, query.isLoading, query.error, query.errorUpdateCount, imageWait]);
|
|
102
108
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drops every shared image: the digests, and the URL of every image no surface
|
|
3
|
+
* draws (the rest go when their surface unmounts). Runs on a sign-out and an
|
|
4
|
+
* account switch.
|
|
5
|
+
*/
|
|
6
|
+
export declare function clearSharedImages(): void;
|
|
7
|
+
export interface SharedImage {
|
|
8
|
+
/** The image's object URL; null until its bytes are in. */
|
|
9
|
+
url: string | null;
|
|
10
|
+
/** `"<w> / <h>"` once any surface measured the image. */
|
|
11
|
+
naturalRatio: string | null;
|
|
12
|
+
/**
|
|
13
|
+
* The bytes are on the way: a read in flight, or the session runtime still
|
|
14
|
+
* starting (its URL not pinned yet, a waking 503), polled with a backoff for
|
|
15
|
+
* about 2 min.
|
|
16
|
+
*/
|
|
17
|
+
loading: boolean;
|
|
18
|
+
/** A genuine read failure, or a wait that ran out. A host shows "Image unavailable" and `retry`, never this text. */
|
|
19
|
+
error: string | null;
|
|
20
|
+
/** Reads the file again, from a fresh wait. */
|
|
21
|
+
retry: () => void;
|
|
22
|
+
/** Records the image's natural size for the next surface that draws it. */
|
|
23
|
+
onNaturalSize: (width: number, height: number) => void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The image at `path` (a sandbox path or a stored attachment ref), or the
|
|
27
|
+
* bytes with digest `sha256`. A digest already in `byDigest` draws at once and
|
|
28
|
+
* reads nothing. Otherwise the file is read through its one shared query, and
|
|
29
|
+
* bytes whose digest matches `sha256` join `byDigest`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function useSharedImage(path: string | null, sha256?: string | null, options?: {
|
|
32
|
+
/**
|
|
33
|
+
* Keep the path's query mounted under a digest hit: the digest's bytes draw
|
|
34
|
+
* at once, and the file's own bytes replace them once read and found
|
|
35
|
+
* different. The viewer passes it, so its Refresh and `file.edited` always
|
|
36
|
+
* refetch the file, also when a card's caption named a digest for the path.
|
|
37
|
+
*/
|
|
38
|
+
revalidate?: boolean;
|
|
39
|
+
}): SharedImage;
|
|
40
|
+
/** The full-screen viewer's image (`FileSource.useSharedImage`): a digest draws at once, the file is always read too. */
|
|
41
|
+
export declare function useViewerImage(path: string | null, sha256?: string | null): SharedImage;
|